• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..20-Sep-2020-

CHANGELOG.mdH A D26-Oct-19854.4 KiB15268

LICENSE.mdH A D26-Oct-1985755 1713

README.mdH A D26-Oct-19857.4 KiB261196

package.jsonH A D20-Sep-20202.3 KiB8382

README.md

1# figgy-pudding [![npm version](https://img.shields.io/npm/v/figgy-pudding.svg)](https://npm.im/figgy-pudding) [![license](https://img.shields.io/npm/l/figgy-pudding.svg)](https://npm.im/figgy-pudding) [![Travis](https://img.shields.io/travis/zkat/figgy-pudding.svg)](https://travis-ci.org/zkat/figgy-pudding) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/zkat/figgy-pudding?svg=true)](https://ci.appveyor.com/project/zkat/figgy-pudding) [![Coverage Status](https://coveralls.io/repos/github/zkat/figgy-pudding/badge.svg?branch=latest)](https://coveralls.io/github/zkat/figgy-pudding?branch=latest)
2
3[`figgy-pudding`](https://github.com/zkat/figgy-pudding) is a small JavaScript
4library for managing and composing cascading options objects -- hiding what
5needs to be hidden from each layer, without having to do a lot of manual munging
6and passing of options.
7
8### The God Object is Dead!
9### Now Bring Us Some Figgy Pudding!
10
11## Install
12
13`$ npm install figgy-pudding`
14
15## Table of Contents
16
17* [Example](#example)
18* [Features](#features)
19* [API](#api)
20  * [`figgyPudding(spec)`](#figgy-pudding)
21  * [`PuddingFactory(values)`](#pudding-factory)
22    * [`opts.get()`](#opts-get)
23    * [`opts.concat()`](#opts-concat)
24    * [`opts.toJSON()`](#opts-to-json)
25    * [`opts.forEach()`](#opts-for-each)
26    * [`opts[Symbol.iterator]()`](#opts-symbol-iterator)
27    * [`opts.entries()`](#opts-entries)
28    * [`opts.keys()`](#opts-keys)
29    * [`opts.value()`](#opts-values)
30
31### Example
32
33```javascript
34// print-package.js
35const fetch = require('./fetch.js')
36const puddin = require('figgy-pudding')
37
38const PrintOpts = puddin({
39  json: { default: false }
40})
41
42async function printPkg (name, opts) {
43  // Expected pattern is to call this in every interface function. If `opts` is
44  // not passed in, it will automatically create an (empty) object for it.
45  opts = PrintOpts(opts)
46  const uri = `https://registry.npmjs.com/${name}`
47  const res = await fetch(uri, opts.concat({
48    // Add or override any passed-in configs and pass them down.
49    log: customLogger
50  }))
51  // The following would throw an error, because it's not in PrintOpts:
52  // console.log(opts.log)
53  if (opts.json) {
54    return res.json()
55  } else {
56    return res.text()
57  }
58}
59
60console.log(await printPkg('figgy', {
61  // Pass in *all* configs at the toplevel, as a regular object.
62  json: true,
63  cache: './tmp-cache'
64}))
65```
66
67```javascript
68// fetch.js
69const puddin = require('figgy-pudding')
70
71const FetchOpts = puddin({
72  log: { default: require('npmlog') },
73  cache: {}
74})
75
76module.exports = async function (..., opts) {
77  opts = FetchOpts(opts)
78}
79```
80
81### Features
82
83* hide options from layer that didn't ask for it
84* shared multi-layer options
85* make sure `opts` argument is available
86* transparent key access like normal keys, through a Proxy. No need for`.get()`!
87* default values
88* key aliases
89* arbitrary key filter functions
90* key/value iteration
91* serialization
92* 100% test coverage using `tap --100`
93
94### API
95
96#### <a name="figgy-pudding"></a> `> figgyPudding({ key: { default: val } | String }, [opts]) -> PuddingFactory`
97
98Defines an Options constructor that can be used to collect only the needed
99options.
100
101An optional `default` property for specs can be used to specify default values
102if nothing was passed in.
103
104If the value for a spec is a string, it will be treated as an alias to that
105other key.
106
107##### Example
108
109```javascript
110const MyAppOpts = figgyPudding({
111  lg: 'log',
112  log: {
113    default: () => require('npmlog')
114  },
115  cache: {}
116})
117```
118
119#### <a name="pudding-factory"></a> `> PuddingFactory(...providers) -> FiggyPudding{}`
120
121Instantiates an options object defined by `figgyPudding()`, which uses
122`providers`, in order, to find requested properties.
123
124Each provider can be either a plain object, a `Map`-like object (that is, one
125with a `.get()` method) or another figgyPudding `Opts` object.
126
127When nesting `Opts` objects, their properties will not become available to the
128new object, but any further nested `Opts` that reference that property _will_ be
129able to read from their grandparent, as long as they define that key. Default
130values for nested `Opts` parents will be used, if found.
131
132##### Example
133
134```javascript
135const ReqOpts = figgyPudding({
136  follow: {}
137})
138
139const opts = ReqOpts({
140  follow: true,
141  log: require('npmlog')
142})
143
144opts.follow // => true
145opts.log // => Error: ReqOpts does not define `log`
146
147const MoreOpts = figgyPudding({
148  log: {}
149})
150MoreOpts(opts).log // => npmlog object (passed in from original plain obj)
151MoreOpts(opts).follow // => Error: MoreOpts does not define `follow`
152```
153
154#### <a name="opts-get"></a> `> opts.get(key) -> Value`
155
156Gets a value from the options object.
157
158##### Example
159
160```js
161const opts = MyOpts(config)
162opts.get('foo') // value of `foo`
163opts.foo // Proxy-based access through `.get()`
164```
165
166#### <a name="opts-concat"></a> `> opts.concat(...moreProviders) -> FiggyPudding{}`
167
168Creates a new opts object of the same type as `opts` with additional providers.
169Providers further to the right shadow providers to the left, with properties in
170the original `opts` being shadows by the new providers.
171
172##### Example
173
174```js
175const opts = MyOpts({x: 1})
176opts.get('x') // 1
177opts.concat({x: 2}).get('x') // 2
178opts.get('x') // 1 (original opts object left intact)
179```
180
181#### <a name="opts-to-json"></a> `> opts.toJSON() -> Value`
182
183Converts `opts` to a plain, JSON-stringifiable JavaScript value. Used internally
184by JavaScript to get `JSON.stringify()` working.
185
186Only keys that are readable by the current pudding type will be serialized.
187
188##### Example
189
190```js
191const opts = MyOpts({x: 1})
192opts.toJSON() // {x: 1}
193JSON.stringify(opts) // '{"x":1}'
194```
195
196#### <a name="opts-for-each"></a> `> opts.forEach((value, key, opts) => {}, thisArg) -> undefined`
197
198Iterates over the values of `opts`, limited to the keys readable by the current
199pudding type. `thisArg` will be used to set the `this` argument when calling the
200`fn`.
201
202##### Example
203
204```js
205const opts = MyOpts({x: 1, y: 2})
206opts.forEach((value, key) => console.log(key, '=', value))
207```
208
209#### <a name="opts-entries"></a> `> opts.entries() -> Iterator<[[key, value], ...]>`
210
211Returns an iterator that iterates over the keys and values in `opts`, limited to
212the keys readable by the current pudding type. Each iteration returns an array
213of `[key, value]`.
214
215##### Example
216
217```js
218const opts = MyOpts({x: 1, y: 2})
219[...opts({x: 1, y: 2}).entries()] // [['x', 1], ['y', 2]]
220```
221
222#### <a name="opts-symbol-iterator"></a> `> opts[Symbol.iterator]() -> Iterator<[[key, value], ...]>`
223
224Returns an iterator that iterates over the keys and values in `opts`, limited to
225the keys readable by the current pudding type. Each iteration returns an array
226of `[key, value]`. Makes puddings work natively with JS iteration mechanisms.
227
228##### Example
229
230```js
231const opts = MyOpts({x: 1, y: 2})
232[...opts({x: 1, y: 2})] // [['x', 1], ['y', 2]]
233for (let [key, value] of opts({x: 1, y: 2})) {
234  console.log(key, '=', value)
235}
236```
237
238#### <a name="opts-keys"></a> `> opts.keys() -> Iterator<[key, ...]>`
239
240Returns an iterator that iterates over the keys in `opts`, limited to the keys
241readable by the current pudding type.
242
243##### Example
244
245```js
246const opts = MyOpts({x: 1, y: 2})
247[...opts({x: 1, y: 2}).keys()] // ['x', 'y']
248```
249
250#### <a name="opts-values"></a> `> opts.values() -> Iterator<[value, ...]>`
251
252Returns an iterator that iterates over the values in `opts`, limited to the keys
253readable by the current pudding type.
254
255##### Example
256'
257```js
258const opts = MyOpts({x: 1, y: 2})
259[...opts({x: 1, y: 2}).values()] // [1, 2]
260```
261