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

runtime-types

v1.0.7

Published

Use flow type information at runtime. Useful for validations, mapping to an ORM, and more.

Downloads

57

Readme

runtime-types

Use flow type information at runtime. Automatically generate validation code, ORM schemas, etc from the type definition.

Installation

npm install --save runtime-types

Runtime Example

If this file is in ./example-types.js

// @flow
export type PhoneNumber = string;

export type User = {
  username: string;
  age: number;
  phone: PhoneNumber;
  created: ?Date;
}

You can import the type information as follows:

var types = require('runtime-types')
var path  = require('path')

// read the file into a runtime type description
var MyTypes = types.readFile(path.join(__dirname, '../test/example-types.js'))

// MyTypes is now equal to:
{
  PhoneNumber: { name: 'string' },

  User: {
    name: 'Object',
    properties: [
      { key: 'username', type: { name: 'string' } },
      { key: 'age',      type: { name: 'number' } },
      { key: 'phone',    type: { name: 'PhoneNumber' } },
      { key: 'created',  type: { name: 'Date', nullable: true } } 
    ]
  }
}

Validation Example

You can use the object provided by readFile to create validators for your types

var types = require('runtime-types')
var validate = require('runtime-types').validate

var MyTypes = types.readFile(path.join(__dirname, '../test/example-types.js'))

var VALIDATORS = {
  PhoneNumber: validate.validateRegex(/^\d{10}$/),
}

var validators = validate.createAll(VALIDATORS, MyTypes)

Then you can check various objects to make sure they match User at runtime.

var errs = validators.User({
  username: "bobby",
  age: 23,
  phone: "8014114399",
  created: null
})

// ==> []

Checks if fields are set

var errs = validators.User({
  age: 23,
  phone: "8014114399"
})

// ==> [ { key: 'username', value: undefined, error: 'missing' } ]
// no error for created because it is nullable

Checks correct typeof for string, number and boolean

var errs = validators.User({
  username: "bobby",
  age: "not an age",
  phone: "8014114399",
})

// ==> [ { key: 'age', value: 'not an age', error: 'expected typeof number' } ]

Checks instances for Date

var errs = validators.User({
  username: "bobby",
  age: 23,
  phone: "8014114399",
  created: 1432757991843 // was supposed to be date, not a timestamp
})

// [ { key: 'created',
//     value: 1432757991843,
//     error: 'expected instance of function Date() { [native code] }' } ]

Provided Validators: regex

var VALIDATORS:ValidatorMap = {
  PhoneNumber: validate.validateRegex(/^\d{10}$/),
}

var validators = validate.createAll(VALIDATORS, MyTypes)

var errs = validators.User({
  username: "bobby",
  age: 23,
  phone: "801-443-8899", // should be 10 digits without hyphens
})

// [ { key: 'phone',
//     value: '801-411-4399',
//     error: 'did not match /^\\d{10}$/' }, ]

Custom Validators: anything

var VALIDATORS:ValidatorMap = {
  PhoneNumber: function(value) {
    if (value.length == 10) {
      return true
    }
    else {
      return "wrong length!"
    }
  }
}

It does not try to guess validators for your type aliases. If you forget to provide one it will throw an error when you generate the validators

var VALIDATORS:ValidatorMap = {}

var validators = validate.createAll(VALIDATORS, MyTypes)

// Error: Could not find validator for type: PhoneNumber

Mapping to ORM Schemas

Coming soon. Will be similar to implementation of validate.js

API: runtime-types

readFile. See example

// read a file synchronously and return a type definition for each type alias found
// keys are the name of the alias
// values are the type description
// you should run this when your program starts

readFile(filepath:string):ObjectMap<Type>;

Property and Type

type Property = {
  key: string;
  type: Type;
  optional?: boolean;
}

type Type = {
  name: string; // number, string, boolean, Post, User, Array

  literal?: string; // for string literals

  nullable?: boolean;

  // only filled for object types
  properties?: Array<Property>;

  // only filled for generics, like Array<XX>
  params?: Array<Type>;
}

export type ObjectMap<T> = {[key: string]: T}

API: validate

See the example

This library returns ValidateObject functions: they accept an object and return an array of errors

type ValidationError = string;

type KeyedError = {
  key: string;
  value: string;
  error: ValidationError;
}

type ValidateObject = (value:Object) => Array<KeyedError>

Create a single validate function

create(map:ValidatorMap, type:Type):ValidateObject;

Create a map of validation functions, with keys equal to the name of the types

createAll(map:ValidatorMap, types:ObjectMap<Type>):ObjectMap<ValidateObject>;

Validators are the functions that you use as building blocks. They return either true or an error message

type Validator<T> = (value:T) => ValidationResult

// use === true to test
type ValidationResult = boolean | ValidationError;

Provided Validators:

validateExists():Validator;

validateTypeOf(type:string):Validator;

validateInstanceOf(type:any):Validator;

validateRegex(regex:RegExp):Validator;

The ValidationMap connects types to validators

type ValidatorMap = {[key:string]:Validator}

// the default validation map, override by passing to `create`

var VALIDATORS_BY_TYPE:ValidatorMap = {
  "string"  : validateTypeOf("string"),
  "number"  : validateTypeOf("number"),
  "boolean" : validateTypeOf("boolean"),
  "Date"    : validateInstanceOf(Date),
  "Object"  : validateExists(),
}