Giter Site home page Giter Site logo

figgy-pudding's Introduction

figgy-pudding npm version license Travis AppVeyor Coverage Status

figgy-pudding is a small JavaScript library for managing and composing cascading options objects -- hiding what needs to be hidden from each layer, without having to do a lot of manual munging and passing of options.

The God Object is Dead!

Now Bring Us Some Figgy Pudding!

Install

$ npm install figgy-pudding

Table of Contents

Example

// print-package.js
const fetch = require('./fetch.js')
const puddin = require('figgy-pudding')

const PrintOpts = puddin({
  json: { default: false }
})

async function printPkg (name, opts) {
  // Expected pattern is to call this in every interface function. If `opts` is
  // not passed in, it will automatically create an (empty) object for it.
  opts = PrintOpts(opts)
  const uri = `https://registry.npmjs.com/${name}`
  const res = await fetch(uri, opts.concat({
    // Add or override any passed-in configs and pass them down.
    log: customLogger
  }))
  // The following would throw an error, because it's not in PrintOpts:
  // console.log(opts.log)
  if (opts.json) {
    return res.json()
  } else {
    return res.text()
  }
}

console.log(await printPkg('figgy', {
  // Pass in *all* configs at the toplevel, as a regular object.
  json: true,
  cache: './tmp-cache'
}))
// fetch.js
const puddin = require('figgy-pudding')

const FetchOpts = puddin({
  log: { default: require('npmlog') },
  cache: {}
})

module.exports = async function (..., opts) {
  opts = FetchOpts(opts)
}

Features

  • hide options from layer that didn't ask for it
  • shared multi-layer options
  • make sure opts argument is available
  • transparent key access like normal keys, through a Proxy. No need for.get()!
  • default values
  • key aliases
  • arbitrary key filter functions
  • key/value iteration
  • serialization
  • 100% test coverage using tap --100

API

> figgyPudding({ key: { default: val } | String }, [opts]) -> PuddingFactory

Defines an Options constructor that can be used to collect only the needed options.

An optional default property for specs can be used to specify default values if nothing was passed in.

If the value for a spec is a string, it will be treated as an alias to that other key.

Example
const MyAppOpts = figgyPudding({
  lg: 'log',
  log: {
    default: () => require('npmlog')
  },
  cache: {}
})

> PuddingFactory(...providers) -> FiggyPudding{}

Instantiates an options object defined by figgyPudding(), which uses providers, in order, to find requested properties.

Each provider can be either a plain object, a Map-like object (that is, one with a .get() method) or another figgyPudding Opts object.

When nesting Opts objects, their properties will not become available to the new object, but any further nested Opts that reference that property will be able to read from their grandparent, as long as they define that key. Default values for nested Opts parents will be used, if found.

Example
const ReqOpts = figgyPudding({
  follow: {}
})

const opts = ReqOpts({
  follow: true,
  log: require('npmlog')
})

opts.follow // => true
opts.log // => Error: ReqOpts does not define `log`

const MoreOpts = figgyPudding({
  log: {}
})
MoreOpts(opts).log // => npmlog object (passed in from original plain obj)
MoreOpts(opts).follow // => Error: MoreOpts does not define `follow`

> opts.get(key) -> Value

Gets a value from the options object.

Example
const opts = MyOpts(config)
opts.get('foo') // value of `foo`
opts.foo // Proxy-based access through `.get()`

> opts.concat(...moreProviders) -> FiggyPudding{}

Creates a new opts object of the same type as opts with additional providers. Providers further to the right shadow providers to the left, with properties in the original opts being shadows by the new providers.

Example
const opts = MyOpts({x: 1})
opts.get('x') // 1
opts.concat({x: 2}).get('x') // 2
opts.get('x') // 1 (original opts object left intact)

> opts.toJSON() -> Value

Converts opts to a plain, JSON-stringifiable JavaScript value. Used internally by JavaScript to get JSON.stringify() working.

Only keys that are readable by the current pudding type will be serialized.

Example
const opts = MyOpts({x: 1})
opts.toJSON() // {x: 1}
JSON.stringify(opts) // '{"x":1}'

> opts.forEach((value, key, opts) => {}, thisArg) -> undefined

Iterates over the values of opts, limited to the keys readable by the current pudding type. thisArg will be used to set the this argument when calling the fn.

Example
const opts = MyOpts({x: 1, y: 2})
opts.forEach((value, key) => console.log(key, '=', value))

> opts.entries() -> Iterator<[[key, value], ...]>

Returns an iterator that iterates over the keys and values in opts, limited to the keys readable by the current pudding type. Each iteration returns an array of [key, value].

Example
const opts = MyOpts({x: 1, y: 2})
[...opts({x: 1, y: 2}).entries()] // [['x', 1], ['y', 2]]

> opts[Symbol.iterator]() -> Iterator<[[key, value], ...]>

Returns an iterator that iterates over the keys and values in opts, limited to the keys readable by the current pudding type. Each iteration returns an array of [key, value]. Makes puddings work natively with JS iteration mechanisms.

Example
const opts = MyOpts({x: 1, y: 2})
[...opts({x: 1, y: 2})] // [['x', 1], ['y', 2]]
for (let [key, value] of opts({x: 1, y: 2})) {
  console.log(key, '=', value)
}

> opts.keys() -> Iterator<[key, ...]>

Returns an iterator that iterates over the keys in opts, limited to the keys readable by the current pudding type.

Example
const opts = MyOpts({x: 1, y: 2})
[...opts({x: 1, y: 2}).keys()] // ['x', 'y']

> opts.values() -> Iterator<[value, ...]>

Returns an iterator that iterates over the values in opts, limited to the keys readable by the current pudding type.

Example

'

const opts = MyOpts({x: 1, y: 2})
[...opts({x: 1, y: 2}).values()] // [1, 2]

figgy-pudding's People

Contributors

zkat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

figgy-pudding's Issues

An in-range update of tap is breaking the build 🚨

Version 10.3.3 of tap just got published.

Branch Build failing 🚨
Dependency tap
Current Version 10.3.2
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As tap is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details
  • continuous-integration/appveyor/branch AppVeyor build succeeded Details
  • coverage/coveralls First build on greenkeeper/tap-10.3.3 at 91.304% Details

Commits

The new version differs by 6 commits.

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.