npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pinput

v1.1.3

Published

Fluent API parameter validation

Downloads

14

Readme

pinput

Travis Coveralls Code Climate npm

Fluent API parameter validation with 0 dependencies

pinput was written to make working with API input easy. Get started by adding the project to your dependencies:

$ npm install pinput --save

Usage

Parameter

Parameter is typically used to validate some input from an API endpoint. Here's a basic example of using pinput in an Express app:

let Parameter = require('pinput');

let validateName = function(input) {
    // Let's say for simplicity a name is a string of alphabetic characters and spaces
    return /^[A-Z ]$/i.test(input);
};

app.get('/person/:name', function(req, res, next) {
    // Let's create a minimal Parameter to validate a name
    let name = new Parameter({
        name: 'name',
        rawInput: req.params.name,
        validate: validateName,
        errorMessage: 'your message here'
    });

    if (!name.valid) {
        // name.error is populated with some useful error information
        return next(name.error);
    }

    res.json(...);
});

What if we need to add an optional parameter? This is pretty straightforward with pinput, add optional: true to your configuration:

app.get('/my-endpoint', function(req, res, next) {
    let foo = new Parameter({
        name: 'foo',
        rawInput: req.query.foo,
        validate: fooValidationFunction,
        errorMessage: 'I was required!'
    });
    let bar = new Parameter({
        name: 'bar',
        rawInput: req.query.bar,
        validate: barValidationFunction,
        errorMessage: "Even if req.query.bar is undefined, I'll still be valid!",
        optional: true
    });

    assert.ok(foo.valid);
    assert.ok(bar.valid);

    // Send response here
});

This way, even if the user did not pass a value for 'bar', its Parameter will still be valid.

pinput also supports array input. Let's say we need an endpoint that validates a list of names. All we need to do is add to our configuration:

app.get('/my-endpoint', function(req, res, next) {
    let names = new Parameter({
        name: 'names',
        rawInput: req.query.names,
        validate: namesValidationFunction,
        errorMessage: 'your message here',
        array: true
    });

    assert.ok(Array.isArray(names.value));
});

By default, arrays are split by commas, but this can be changed by specifying the arraySeparator property.

Let's say we need to take a number as input from our API. pinput makes this very simple with the postprocess property:

let parseBase10Int = function(input) {
    return parseInt(input, 10);
};

app.get('/my-endpoint', function(req, res, next) {
    let number = new Parameter({
        name: 'number',
        rawInput: req.query.number,
        validate: validateInputCanBeParsedAsNumber,
        postprocess: parseBase10Int
    });

    assert.equal(typeof number.value, 'number');
});

Protip: Use postprocess with array: true to process a list of numbers

See the full configuration below for more options.

Contract

A Contract is a binding between to Parameters. Contracts are only applied after Parameters have been validated.

let Contract = require('pinput/contract');

router.get('/range', function(req, res, next) {
    let start = new Parameter({
        name: 'start',
        // ...
    })
    let end = new Parameter{
        name: 'end',
        // ...
    });

    if (!name.valid || !end.valid) {
        // handle invalid Parameters here
    }

    let contract = new Contract({
        names: ['start', 'end'],
        verify: (start, end) => start <= end,
        messageOnBroken: 'start must be less than or equal to end'
    });

    contract.check([start, end]);

    if (!contract.valid) {
        // handle broken contract here
    }
});

Full Reference

Parameter

Configuration

These properties are recognized by Parameter when passed as an object, e.g.

let configuration = {
    name: 'foo',
    // ...
};
let p = new Parameter(configuration);

name (string) — (required)

rawInput (string) — (required) Raw input from the user. May be undefined.

validate (function) — (required) A function that takes the raw input as a parameter and returns any value. If that value is truthy, this Parameter is considered valid. If that value is falsey, then this Parameter is considered invalid. Note that there are some exceptions to this rule. If optional is truthy and the raw input is undefined, then this function will not be called. Similarly, if defaultAllowed is truthy and this function returns a falsey value, the Parameter will be considered valid anyway.

errorMessage (string|function) — A message to be shown to the user if this Parameter is invalid. May also be a function that takes the configuration as a parameter.

errorStatus (number) — Recommended HTTP status code to send to the client if this Parameter is invalid. Defaults to 400 ("Bad Request").

optional (boolean) — If truthy, marks this Parameter as not required. Simply, if rawInput is undefined, this Parameter will be valid.

array (boolean) — If truthy, the value of this Parameter is meant to be treated as an array. Defaults to false.

arraySeparator (string) — If array, will split() the value by this string. Defaults to ','

arrayTrim (boolean) — If array, will trim() every element after splitting. Defaults to true.

defaultAllowed (boolean) — If the input is determined to be invalid, defaultValue will be used instead. Defaults to false.

defaultValue (*) — The value used if the input for this Parameter is invalid or undefined, and defaultAllowed is truthy. Defaults to null.

preprocess (function) — A one-argument function that takes the value of the Parameter and returns a modified value. If array is truthy, then this function will be called with each element of the array. Defaults a function that returns the value it's passed.

postprocess (function) — Similar to preprocess, but is only called after successful validation. Defaults to a function that returns the value it's passed.

Properties

name (string) — Copied straight from the configuration

valid (boolean)

optional (boolean) — Boolean value of the configuration's optional property. Will always be a boolean.

error (object) — Null if valid

  • error.message Copied straight from the configuration's errorMessage property
  • error.code Copied straight from the configuration's errorStatus property
  • error.data An object with one property whose key is the name of the Parameter and whose value is the value of the Parameter

Contract

Functions

apply — Takes an array of Parameters as input. Two of those Parameters must have names such that p1Name === parameter.name. Creates the valid and error properties in the Contract.

Configuration

These properties are recognized by Contract when passed as an object, e.g.

let configuration = {
    name: 'foo',
    // ...
};
let c = new Contract(configuration);

names (string[]) — (required) List of parameter names. Each value should be equal to a Parameter's name.

verify (function) — (required) Checks if the agreement between the Parameters have broken the agreement. If this function returns a truthy value, this Contract is intact. Similarly, if this function returns a falsey value, this Contract is considered broken. Arguments to this function are the values of the Parameters specified by names.

messageOnBroken (string) — (required) Value of contract.error.message when broken

statusOnBroken (number) — Value of contract.error.status when broken. Defaults to 400.

Properties

names (string[]) — Copied from the configuration

valid (boolean)

error (object) — Null if valid

  • error.message (string) — Copied from the configuration's messageOnBroken property

  • error.status (number) — Copied from the configuration's statusOnBroken property

  • error.data (object) — An object with two properties, each key being the name of the Parameter being analyzed and each value being the value of that Parameter

Contributing

pinput is built with Grunt. The default Grunt task runs the unit tests and jshint.

Legal

Copyright 2017 Matthew Dean via MIT license.

See the LICENSE file for full license.