diff --git a/README.md b/README.md index fa60660..724708d 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ But sometimes you need to add stuff dynamically ### Kepi -#### constructor(data, options) +#### constructor(data, customOptions) data can be - null - an Object (see example). In may cases this is all you really need. @@ -103,10 +103,10 @@ Sets all headers in options.SAFE or options.safe, creating if needed. #### add(data) Adds data to the header value - - `List.add(...items)` for convenience, accepts an array, **or** one or more individual items + - `List.add(...items)` - _e.g._ `add('a','b')` is equivalent to `add(['a','b'])` - `Policies.add(policyName, ...items)` requires a policy name first - - `...items` may be an array, **or** one or more individual items + - **note** items will be flattened one level deep, so `add('a','b')` is equivalent to `add(['a','b'])` #### applyTo(response) Write the header to the response. You will seldom call this directly. @@ -123,7 +123,7 @@ Set the header to a "safe" value, as provided in the options. #### set(value) Sets the value - - `List.set(...items)` like add(), this accepts an array, or one or more individual items + - `List.set(...items)` like add(), items will be flattened ## Customization @@ -131,7 +131,12 @@ Sets the value You can customize or add to behavior by passing a customOptions parameter to the Kepi function. This will get `Object.assign`ed onto the default settings in defaults.js. -Since `Object.assign` is shallow, and making a deep copy is a bit of a pain, instead, provide user options in the **lowercase** +#### Simple Options + - setupNicknames (default = true) controls if nicknames are setup + - resetAfterApply (default = false) will reset to initial data after calling applyTo() + +#### Complex Options +Since `Object.assign` is shallow, and making a deep copy is a bit of a pain, instead, provide complex user options in the **lowercase** properties given at the end of defaults.js. - headerClasses allows you to add or override the class for a Header diff --git a/header.js b/header.js index a93ed8b..a47cb92 100644 --- a/header.js +++ b/header.js @@ -141,7 +141,7 @@ class Policies extends Header { } add(policyName, ...items) { - items = expandFirstArgIfArray(items); + items = flatten1(items); let policyValues = this.data[policyName]; if (policyValues) policyValues.push(...items); @@ -195,12 +195,12 @@ class List extends Header { } add(...items) { - this.data.push(...expandFirstArgIfArray(items)); + this.data.push(...flatten1(items)); return this; } set(...items) { - this.data = [...expandFirstArgIfArray(items)]; + this.data = [...flatten1(items)]; return this; } @@ -215,8 +215,9 @@ function forceArray(x) { return x ? [x] : []; } -function expandFirstArgIfArray(rest) { - return (rest.length === 1) && Array.isArray(rest[0]) ? rest[0] : rest; +// 1 level deep flatten +function flatten1(arr) { + return [].concat(...arr); } module.exports = { Header }; diff --git a/kepi.js b/kepi.js index 82bcb13..ec0350d 100644 --- a/kepi.js +++ b/kepi.js @@ -5,26 +5,28 @@ const Header = require('./header').Header; class Kepi { constructor(data, customOptions) { + data = data || {}; this.options = Object.assign({}, DEFAULTS, customOptions); - this.headers = {}; + this.resetData = this.options.resetAfterApply ? data : null; if (this.options.setupNicknames) { this._setupNicknames(this.options.NICKNAMES); this._setupNicknames(this.options.nicknames); } - if (data === 'safe') - this.safe(); - else - this._setInitialData(data || {}); + this._setData(data); } + applyTo(response) { let headerNames = Object.keys(this.headers); headerNames.forEach( (headerName) => { this.headers[headerName].applyTo(response); - }); + }); + if (this.resetData) + this._setData(this.resetData); + return this; } @@ -69,12 +71,18 @@ class Kepi { } - _setInitialData(data) { + _setData(data) { + this.headers = {}; + + if (data === 'safe') + return this.safe(); + let headerNames = Object.keys(data); headerNames.forEach( (headerName) => { let fullName = this._fullName(headerName); this.headers[headerName] = Header.create(this._headerType(fullName), fullName, data[headerName], this.options); }); + return this; } diff --git a/test/test.js b/test/test.js index a0fca10..33a03b6 100644 --- a/test/test.js +++ b/test/test.js @@ -118,14 +118,17 @@ test('delete', function(t) { }) const CLEAR_AND_ADD = '{"stringHeader":"addedstring","listHeader":"a, b, c","directiveHeader1":"foo1 newValue1 newValue2","directiveHeader2":"bar2 originalbarValue2; foo3 newfoovalue3"}'; +const CLEAR_AND_ADD_AFTER_RESET = '{"stringHeader":"originalstring","listHeader":"1, 2, 3","directiveHeader1":"foo1 originalfooValue1; bar1 originalbarValue1","directiveHeader2":"foo2 originalfooValue2; bar2 originalbarValue2"}'; -test('clear & add', function(t) { +test('clear & add & reset', function(t) { let kepi = Kepi({ stringHeader: 'originalstring', listHeader: [1,2,3], directiveHeader1: { foo1: 'originalfooValue1', bar1: 'originalbarValue1'}, directiveHeader2: { foo2: 'originalfooValue2', bar2: 'originalbarValue2'} - }); + }, + { resetAfterApply: true } + ); let res = mockResponse(); kepi.header('stringHeader').clear().add('addedstring'); @@ -135,6 +138,11 @@ test('clear & add', function(t) { kepi.applyTo(res); t.equals(res.toString(), CLEAR_AND_ADD); + + res = mockResponse(); + kepi.applyTo(res); + t.equals(res.toString(), CLEAR_AND_ADD_AFTER_RESET); + t.end(); })