Coder Social home page Coder Social logo

pulpo's Introduction

Pulpo

Define, hydrate, and validate configurations in Node.

  • Schema: Use JSON and JS objects to define schemas
  • Types: Add new types with casting and validation
  • Casting, Transforms, and Validation: Handle config values intelligently
  • Source Hierarchy: Look for values from passed in configs, ENV variables, and CLI args
  • Self Referencing: Reference other config values via function or string interpolation
  • Self Documenting: Schema documentation can be generated automatically

Getting Started

Install Pulpo with npm by running:

npm install --save pulpo

Getting started is as simple as importing Pulpo and passing it a JSON object for the schema and hydrating with a config object:

import Pulpo from 'pulpo';

const schema = new Pulpo({
  host: {
    description: 'Host for the server',
    type: 'string',
    default: 'localhost'
  },
  port: {
    description: 'Port for dev server to run on',
    type: 'int',
    default: '3000',
    env: 'PORT'
  }
});

const config = schema.hydrate({port: 8888});

console.log(config);
// { host: 'localhost', port: 8888 }

Schema

A schema is comprised of keyed properties that are used to parse and validate configurations pulled from JSON objects, environmental variables, and command line arguments.

Constructor

import Pulpo from 'pulpo';

const schema = new Pulpo({...schema...});

The JSON object passed in is parsed and turned into a series of Properties. You can also pass in nested properties:

import Pulpo from 'pulpo';

const schema = new Pulpo({
  server: {
    host: {
      description: 'Host for the server',
      type: 'string',
      default: 'localhost'
    },
    port: {
      description: 'Port for dev server to run on',
      type: 'number',
      default: '3000',
      env: 'PORT'
    }
  }
});

const config = schema.hydrate({ server: { port: 8888 } });
console.log(config);
// { server: { host: 'localhost', port: 8888 } }

Any object keys that are in the Property reserved key list will be parsed as part of the Property definition, and all other keys will be treated as nested Properties.

Hydrate

Once an instance of a schema has been created, it can be used to build a config object using schema.hydrate:

const schema = new Pulpo({...schema...});
...

const config = schema.hydrate({ server: { port: 8888 } });

The hydrate function will also validate the values and throw any errors.

Options

Hydrate also allows for a second argument to be passed in that contains options:

  • transform (default true) - whether or not to use the property transform method on a value
  • cast (default true) - whether or not to cast the value before validating
  • validate (default true) - whether or not to validate a given value

Referencing Other Configuration Values

It is possible to reference other values in the configuration, which will be populated with resolved values found in the referenced key. This works for both default values and passed in values:

const schema = new Pulpo({...schema...});

const config = schema.hydrate({
  server: {
    port: 8888,
    hostname: 'localhost',
    host: 'http://${server.hostname}:${server.port}'
  }
});

console.log(config.server.host);
// http://localhost:8888

Using Functions for Configuration Values

When needed, a function can be passed in as a config or default value. These functions are passed two arguments: the config object and the string path of the property being resolved:

const schema = new Pulpo({...schema...});

const config = schema.hydrate({
  server: {
    port: 8888,
    hostname: 'localhost',
    host: (config) => `http://${config['server.hostname']}:${config['server.port']}`
  }
});

console.log(config.server.host);
// http://localhost:8888

Note: Configuration values are accessed through their full dot-notation strings

Properties

Properties are definitions for a given configuration key.

import Pulpo from 'pulpo';

const schema = new Pulpo({
  environment: {
    description: 'Runtime environment',
    type: 'string',
    default: 'development',
    env: 'ENV',
    argv: 'env',
    resolve: (configObj) => configObj.env,
    transform: (value) => value.toUpperCase()
  }
});

const config = schema.hydrate({env: 'test'});
console.log(config.environment); // TEST

In the above example, Pulpo is doing a few things at the time of hydrate for each property in the schema:

  1. Resolves the value in the following order, stopping once a value is found:
  2. Command line arg --env=<value>
  3. Process environment value process.env.ENV
  4. Passed in configuration object value using the given resolve function in the property, or the name of the property if a resolve method is not provided
  5. Default value defined in the property
  6. Transforms the value if a transform method has been provided for the property
  7. Casts the value using the property type provided
  8. Validates that the resolved, transformed, cast value is of type defined in the property

Definition

A property is comprised of the following keyed values:

  • description (required string) - a string to define the purpose of the property

  • type (required string) - a name for the type of value to be provided

  • default (optional value matching the type) - the value to be used if none is provided

  • required (optional boolean, defaults to false)- whether a value must be found (this is ignored if a default value is given, since a value is always provided)

  • env (optional string) - the process.env key for looking up a property value

  • argv (optional string) - the command line arg key for looking up a property value

  • resolve (optional function) - a function to look up a value from a config object in a different way than using the property name

    (configObject) => configObject.differentKey
  • transform (optional function) - a function that accepts a found value and maps it to a new value (it recieves the config as a secondary argument)

    (value, config) => parseInt(value, 10)  

Reserved Keys

When a schema is parsed, any keys that match the Property definition will be automatically used in the definition of the Property. These keys cannot be used as Property names.

Types

Types are used to validate config values.

By default Pulpo comes with a few basic types:

  • 'string'
  • 'number'
  • 'object'
  • 'boolean'
  • 'array'
  • 'path'

Adding Types

New Types can be added to Pulpo for further validation:

import Pulpo from 'pulpo';

Pulpo.addType('int', {
  validate: (value, config) => {
    if (!Number.isInteger(parseFloat(value, 10)) {
      return 'Value must be of type integer';
    }
  },
  cast: (value, config) => parseFloat(value, 10),
);

...

const schema = new Pulpo({
  port: {
    ...
    type: 'int',
    ...
  }
});

Types are comprised of a validation function that receives a value and returns either void or an error message to be displayed to the user and a cast method that transforms a value before validating.

Documenting

Schemas can be used to provide easy documentation for anyone interacting with the configurations:

const schema = new Pulpo({
  server: {
    host: {
      description: 'Host for the server',
      type: 'string',
      default: 'localhost'
    },
    port: {
      description: 'Port for dev server to run on',
      type: 'number',
      default: '3000',
      env: 'PORT'
    }
  }
});

console.log(schema.document());
// {
//   "server.host": {
//     "description": "Host for the server",
//     "type": "string",
//     "default": "localhost"
//   },
//   "server.port": {
//     "description": "Port for dev server to run on",
//     "type": "number",
//     "default": "3000",
//     "env": "PORT"
//   }
// }

License

Pulpo is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

pulpo's People

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.