web 3d图形渲染器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
7.5 KiB

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