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

@sknk/object-validator

v2.0.1

Published

function argument and Schema validator, composable predicates, customizable errors, extends with external validation libraries - minimal footprint

Downloads

605

Readme

object-validator

Functional Object schema validator for objects, function arguments, UI form inputs, API request payload.
Predicates are powered by tiny-schema package

  • Composable predicates
  • Customizable native errors
  • Simple error handling
  • Integration with other validation libraries
  • Minimal footprint
  • fully typed - typescript

npm

Install: npm install @sknk/object-validator
Test: npm test
Run examples: npm run example

imports/require

// esm
import validator, {pipe, pipeArgs } from '@sknk/object-validator';
import {is, setDefault} from '@sknk/object-validator/predicates';

// commonjs
const { default: validator, pipe, pipeArgs } = require('@sknk/object-validator');
const { is, setDefault, date } = require('@sknk/object-validator/predicates')

Basic usage

import validator from '@sknk/object-validator';
// commonjs
const { default: validator } = require('@sknk/object-validator');
import 
let obj = {
  name: 'john',
  age: 24
};

let schema = {
  name: ["string", "/^.{3,8}$/"],
  age: ["number", "18-24"], };

obj = validator(obj, schema)

Throws error on validation failure. On success returns the object.

Validating function arguments

You can also use this lib to validate the function arguments. Its done through a combination of spread operator and pipeArgs utility to convert the arguments as objects for schema validation.

import validator, {pipeArgs} from '@sknk/object-validator';

function add(a, b) {
  return a + b;
};

function checkArgs(...args) {
  // convert to obj
  let [a, b, opts] = args;
  let obj = {a, b, opts}
  let schema = {
    a: ['+integer', '0-100'],
    b: ['+integer', '0-100'],
    opts: ['object', {errCb: (e) => {
      return  new TypeError('Invalid Optional argument');
    }}]
  };
  obj = validator(obj, schema)
  return Object.values(obj);
};

let strictAdd = pipeArgs(checkArgs, add);

let ans = strictAdd(10, -2, {opts: false}) ;

Lot of the validation codes can be abstracted away from the actual implementation.

Predicates & Transform pipelines

@typedef {Array<Predicate | string | ValidateOpts> | string | function} PredicateArray

Predicates can be a single|array of functions/predicates and single|array strings from tiny-schema package. checkout out their readme for more predicates.
Custom predicates are also supported.

function string(value, key='input') {
  if(typeof value === 'string') throw Error('Expecting string. Given ${key}: ${value}');
  return value;
};
let schema = {
  name: [string, maxString(8)],
  age: ["number", "18-24"],
  city: 'string', // single schema string
  address: (i) => Error('') // single  predicate function.
};
obj = validate(obj, schema);
  • key - optional, will be passed by the validator
  • predicate should return or throw error

Transforms are similar to function predicates which can tranform values

const setDefault = (def) => (value) => {
  return value || def;
};

let schema = {
  'name?': [setDefault('abc'), string, maxString(8)],
  age: ["number", "18-24"],
};
obj = validate({age: 24}, schema);

schema key validation pipelines are simple standalone functions. no dependency with the package which makes it lean and allows you to extend other validation libraries with custom errors.

Schema pipeline opts - {errCb, opt}

@typedef {{ errCb?: (i: any) => any|never, optKey?: boolean}} ValidateOpts
  • errCb : callback function that gets the error thrown by the validator from the pipeline. whatever errCb returns its thrown again by the validator internally. use this to decorateError
  • opt: 2 ways to declare a key as optional key in schema
    • using "?" at the end of the key {"name?": [sring]}
    • using {opt=true} in the pipelines opts
    • default is opt: false
let schema = {
  'name?': [setDefault('abc'), string, maxString(8)],
  age: ["number", "18-24", (errCb: (e) => {
    e.message = 'age error';
    return e; // should return error
  }, 
  opt: true
  )],
};

Errors

Errors thrown from validator are native Javascript Errors or whatever the error thrown by custom validator.
validator function adds additional properties like key, value, predicate on the Error object

  • key: object key on which validation is done
  • value: actual object key value
  • predicate: predicate function name or schema string used to perform validation

Note: Only Schema errors will be supplied with additional properties.

TypeError

TypeError: Expected {age} to satisfy {18-24} validation. Given {age: 25}
    at getError (file://tiny-schema-wrapper.js:6:11)
    ...
  predicate: '18-24',
  key: 'age',
  value: 25
}

AggregateError

AggregateError: schemaValidator Errors
    at schemaValidator (file://index.js:137:13)
    ...
  [errors]: [
    TypeError: Expected {age} to satisfy {number} validation. Given {age: 25}
        at getError (file://..tiny-schema-wrapper.js:6:11)
        ...
      predicate: 'number',
      key: 'age',
      value: '25'
    },
    TypeError: Unexpected keys [abc]
        at strictKeyMatch (file:///home/sknk/sandeep/workspace/libraries/object-validator/src/index.js:34:11)
        ...
  ]
}

API

validator(obj: object, schema: Schema, opt?: object) => object | Error

 @typedef {Record<string, any>} Object
 @typedef {Record<string, PredicateArray>} Schema
  • obj: input object to validate

  • schema: object with predicates on each key

    • PredicateArray : Predicates can be a function, schema string, or array of predicates and string with optional
    • ValidateOpts: Optional
  • opt: Optional { aggregareError=false, handleError: function, strict: true, pipeline: Predicate[]}

Validator opts

aggreagateError

Default: false when set to true it aggregates all the errors from the schema pipelines and throws an javascript Aggregate Error.
Individual errors are found in error.errors

let o = validator(obj, schema, {aggreagateError: true})

handleError

Optional. When validator throws erorr ( both aggregate and single error) this function when provided gets invoked with the error object. function's return value will the returned by the validator.

let bool = validator(obj, schema, {handleError: (e) => false})
bool // false on validation failure

strict

By default, validator throws Unexpected keys error when there are keys which are not declared in the schema. to override this use {strict: false}

let bool = validator(obj, schema, {strict: false}) // skips additional keys 

object pipeline

Post pipeline functions. these functions are run after schema validation is done. each function is passed with the object. This is similar to pipe behaviour where we can do data transform or multiple fields compare and assert checks

let o = validator(obj, schema, { 
  pipeline: [
   (o) => {
     let {startDate, endDate} = o;
     if(startDate > endDate) throw Error('startDate cannot be greater than endDate');
     return o // always return input object or the transformed one
   },
   // another fn
   // ...
  ]
}
})

Schema can only check individual fields. This pipeline opts will allows us to validate togther as an object.

Note:

  • Errors thrown from object pipeline are handled by handleError
  • other options like aggregateError, strict are only for schema validation

predicates

Library also exports some basic predicates like date, and some helper utils

import {
  is, // wrapper around tiny-schema. already included in validator
  setDefault,
  hasKeys,
  pick,
  date, toDate, minDate, maxDate, dateEquals // date methods
} from '@sknk/object-validator';

Please check the ./src/predicates/*.test.js files for the usage

pipeArgs(checkFn, fn)(input)

Used for funciton argument validation.

import { pipeArgs } form '@sknk/object-validator';

pipe([fn1, fn2, ..])(input)

Library also exports simple pipe function.

import { pipe } form '@sknk/object-validator';