JSPM

  • Created
  • Published
  • Downloads 33
  • Score
    100M100P100Q80006F
  • License MIT

A fast, simple type validation library

Package Exports

  • stnl
  • stnl/build
  • stnl/build/json
  • stnl/build/json/assert
  • stnl/limit
  • stnl/regex
  • stnl/type

Readme

A simple type validator built for performance.

Features

  • Types work across languages
  • Efficient representation format
  • Fast compilation time

Builder

stnl schema builder.

import { t, l } from 'stnl';
// or
import { type, limit } from 'stnl';

Type inference

To infer payload type of a schema built using the schema builder:

const schema = t.list(t.int);

// number[]
type T = t.TInfer<typeof schema>;

Primitives

  • t.int: integer
  • t.float: floating-point number
  • t.string: string
  • t.bool: boolean
  • t.any: any type
t.int; // integer
t.float; // floating-point number
t.string; // strings
t.bool; // boolean
t.any; // any type

l.int(l.min(5)); // integer >= 5
l.int(l.max(9)); // integer <= 9
l.int(l.min(5), l.max(9)); // 5 <= integer <= 9

l.float(l.min(5)); // float >= 5
l.float(l.max(9)); // float <= 9
l.float(l.min(5), l.max(9)); // 5 <= float <= 9

l.string(l.minLen(5)); // string.length >= 5
l.string(l.maxLen(9)); // string.length <= 9
l.string(l.minLen(5), l.maxLen(9)); // 5 <= string.length <= 9

Unions

// Match 'admin' or 'user'
t.union(['admin', 'user']);

Constants

t.value() only accepts number, string, or boolean.

// Match only 0
t.value(0);

// Match only 'str'
t.value('str');

// Match only true
t.value(true);

Lists

// A list of integers
t.list(t.int);

// A list of string with list.length >= 1
t.list(t.string, l.minLen(1));

// A list of float with list.length <= 10
t.list(t.float, l.maxLen(10));

// A list of float with 1 <= list.length <= 10
t.list(t.float, l.minLen(1), l.maxLen(10));

Records

// { id: number, name: string, display_names?: string[] }
t.record(
  // Required properties
  {
    id: t.int,
    name: t.string
  },
  // Optional properties
  {
    display_names: t.list(t.string)
  }
);

Tuples

// [number, string]
t.tuple([
  t.int,
  t.string
]);

Tagged unions

// { role: 'admin', id: string } | { role: 'user', name: string }
t.tag('role', {
  admin: t.record({
    id: t.string
  }),
  user: t.record({
    name: t.string
  })
});

Nullable types

To make a schema accepts null:

// { name: string, id: number } | null
t.nullable(
  t.record({
    name: t.string,
    id: t.int
  })
);

Scopes & references

Recursive types with scope:

// interface Node { value: string, next: Node | null }
const node = t.scope(
  t.record(
    { value: t.string },
    { next: t.self } // Reference to the root type of the scope
  )
);

References defined types in scope:

const user = t.scope(
  t.record({
    name: t.ref('name')
  }),
  { name: t.limit(t.string, 3, 16) }
};

Generics with scope:

// node is an unresolved type
const node = t.record(
  { value: t.ref('type') },
  { next: t.self }
);

// This will error as not all references of node has been resolved
type Node = t.TInfer<typeof node>;

// int_node is a resolved type
const int_node = t.scope(node, {
  type: t.int
});

Compilers

stnl schema compilers.

import { build } from 'stnl';

Assert JSON

const schema = t.record({
  name: t.limit(t.string, 3, 16),
  code: t.limit(t.string, 8, 32)
});

// Build to a function
const isUser = build.json.assert.compile(schema);

// Usage:
if (isUser(user)) {
  console.log('Name', user.name);
  console.log('Code', user.code);
}

For code injection to other functions:

const schema = t.record({
  name: t.limit(t.string, 3, 16),
  code: t.limit(t.string, 8, 32)
});

// Build to code
console.log(build.json.assert.code(schema));