2017-08-14 05:01:11 +02:00
# option-chain [![Build Status](https://travis-ci.org/avajs/option-chain.svg?branch=master)](https://travis-ci.org/avajs/option-chain) [![Coverage Status](https://coveralls.io/repos/github/avajs/option-chain/badge.svg?branch=master)](https://coveralls.io/github/avajs/option-chain?branch=master)
2017-05-28 00:38:50 +02:00
2017-08-14 05:01:11 +02:00
> Use fluent property chains in lieu of options objects
2017-05-28 00:38:50 +02:00
## Install
```
$ npm install --save option-chain
```
## Usage
```js
const optionChain = require('option-chain');
const optionDefinition = {
2017-08-14 05:01:11 +02:00
defaults: {
bar: false
},
chainableMethods: {
foo: {foo: true},
notFoo: {foo: false},
bar: {bar: true}
}
2017-05-28 00:38:50 +02:00
};
function printOptionsAndArgs(options, args) {
2017-08-14 05:01:11 +02:00
console.log(options);
if (args.length) {
console.log(args);
}
2017-05-28 00:38:50 +02:00
}
const fn = optionChain(optionDefinition, printOptionsAndArgs);
fn();
//=> [{bar: false}]
fn.bar();
//=> [{bar: true}]
fn.foo.bar();
//=> [{foo: true, bar: false}]
fn.foo('a', 'b');
//=> [{foo: true, bar: false}]
//=> ['a', 'b']
```
## API
### optionChain(options, callback, [target])
#### options
##### chainableMethods
2017-08-14 05:01:11 +02:00
*Required*< br >
Type: `Object`
2017-05-28 00:38:50 +02:00
A map of chainable property names to the options set by adding property to the chain.
Given the following:
```js
const chainableMethods = {
2017-08-14 05:01:11 +02:00
foo: {foo: true},
notFoo: {foo: false},
bar: {bar: true},
both: {foo: true, bar: true}
2017-05-28 00:38:50 +02:00
}
```
Then:
- `fn.foo` would set `foo` to `true` .
- `fn.bar` would set `bar` to `true` .
- `fn.both` sets both `foo` and `bar` to `true` .
2017-08-14 05:01:11 +02:00
- The last property in the chain takes precedence, so `fn.foo.notFoo` would result in `foo` being `false` .
2017-05-28 00:38:50 +02:00
##### defaults
2017-08-14 05:01:11 +02:00
Type: `Object` < br >
2017-05-28 00:38:50 +02:00
Default: `{}`
A set of default starting properties.
##### spread
2017-08-14 05:01:11 +02:00
Type: `boolean` < br >
2017-05-28 00:38:50 +02:00
Default: `false`
By default, any arguments passed to the wrapper are passed as an array to the second argument of the wrapped function. When this is `true` , additional arguments will be spread out as additional arguments:
```js
function withoutSpread(opts, args) {
2017-08-14 05:01:11 +02:00
let foo = args[0];
let bar = args[1];
// ...
2017-05-28 00:38:50 +02:00
}
function withSpread(opts, foo, bar) {
2017-08-14 05:01:11 +02:00
// ...
2017-05-28 00:38:50 +02:00
}
```
#### callback
2017-08-14 05:01:11 +02:00
Type: `Function`
2017-05-28 00:38:50 +02:00
This callback is called with the accumulated options as the first argument. Depending on the value of `options.spread` , arguments passed to the wrapper will either be an array as the second argument or spread out as the 2nd, 3rd, 4th... arguments.
#### target
If supplied, the `target` object is extended with the property getters and returned. Otherwise a wrapper function is created for `options.defaults` , then that wrapper is extended and returned.
2017-08-14 05:01:11 +02:00
*Hint:* If you want to extend a `target` and add a method that simply uses the defaults, add a chainable method definition with an empty spec:
2017-05-28 00:38:50 +02:00
```js
const chainableMethods = {
2017-08-14 05:01:11 +02:00
defaultMethodName: {}
2017-05-28 00:38:50 +02:00
}
```
2017-08-14 05:01:11 +02:00
2017-05-28 00:38:50 +02:00
## License
2017-08-14 05:01:11 +02:00
MIT © [James Talmage ](https://github.com/jamestalmage )