Safen

Build Coverage Downloads Version License Language Typescript

Super Fast Object Validator
for Javascript(& Typescript).

Safen supports the syntax similar to the type script interface. This makes it easy to create validation rules.

Usage

Deno

import {
  createValidate,
  decorate,
  email,
  ip,
  lengthBetween,
  or,
  trim,
} from "https://deno.land/x/safen/mod.ts";

const typeLat = decorate(Number, between(-90, 90));
const typeLng = decorate(Number, between(-180, 180));

const v = createValidate({
  id: Number,
  email: decorate(String, [trim(), email()]),
  name: optional(String),
  password: decorate(String, lengthBetween(8, 20)),
  areas: array({
    lat: typeLat,
    lng: typeLng,
  }),
  env: {
    ip: decorate(String, ip("v4")),
    os: {
      name: or([
        "window" as const,
        "osx" as const,
        "android" as const,
        "iphone" as const,
      ]),
      version: String,
    },
    browser: {
      name: or([
        "chrome" as const,
        "firefox" as const,
        "edge" as const,
        "ie" as const,
      ]),
      version: String,
    },
  },
});

const input = {} as unknown; // some unknown value

if (v(input)) {
  /* now input type is below:
  {
    id: number;
    email: string;
    name: string | undefined;
    password: string;
    areas: {
        lat: number;
        lng: number;
    }[];
    env: {
        ip: string;
        os: {
            name: any;
            version: string;
        };
        browser: {
            name: any;
            version: string;
        };
    };
  }
  */
}

Node

npm install safen

Validate

TODO

Sanitize

TODO

Syntax

TODO

Decorator

Decorator Validate Sanitize Type Description Example
alpha string contains only letters([a-zA-Z]). alpha
alphanum string contains only letters and numbers([a-zA-Z0-9]) alphanum
ascii string contains only ascii characters. ascii
base64 string Base64. base64
between({min},{max}) string, number value is between {min} and {max}. between("aaa","zzz"), between(1,100)
creditcard string valid Credit Card number. cf. 0000-0000-0000-0000 creditcard
dateformat string valid Date string(RFC2822, ISO8601). cf. 2018-12-25, 12/25/2018, Dec 25, 2018 dateformat
email string valid E-mail string. email
hexcolor string valid Hex Color string. cf. #ffffff hexcolor
ip({version = all}) string valid UUID.
version is one of all(default), v4, and v6.
ip, ip("v4"), ip("v6")
json string valid JSON. json
length({size}) string, any[] length is {size}. length(16)
lengthBetween({min},{max}) string, any[] length is between {min} and {max}. lengthBetween(4,20)
lengthMax({max}) string, any[] length is less than {max}. lengthMax(20)
lengthMin({min}) string, any[] length is greater than {min}. lengthMin(4)
lowercase string lowercase. lowercase
macaddress string valid Mac Address. macaddress
max({max}) string, number value is less than {min}. max(5)
min({min}) string, number value is greater than {max}. min(3)
port number valid PORT(0-65535). port
re string match RegExp. re(/.+/)
trim string trim. trim
uppercase string uppercase. uppercase
url string valid URL. url
uuid({version = all}) string valid UUID.
version is one of all(default), v3, v4, and v5.
uuid, uuid("v3"), uuid("v4"), uuid("v5")

Custom Decorator

TODO

Comparison

Using another library? Safen is lot easier to use.

const typeLat = decorate(Number, between(-90, 90));
const typeLng = decorate(Number, between(-180, 180));
const s = createSanitize({
  username: optional(decorate(String, [
    trim(),
    email(),
    lengthBetween(12, 100),
  ])),
  password: decorate(String, lengthBetween(8, 20)),
  areas: array({
    lat: typeLat,
    lng: typeLng,
  }),
  env: {
    referer: decorate(String, url()),
    ip: decorate(String, ip("v4")),
    os: {
      name: or([
        "window" as const,
        "osx" as const,
        "android" as const,
        "iphone" as const,
      ]),
      version: String,
    },
    browser: {
      name: or([
        "chrome" as const,
        "firefox" as const,
        "edge" as const,
        "ie" as const,
      ]),
      version: String,
    },
  },
});

Compare with JSON Schema

Show JSON Schema Source
{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "username",
    "areas",
    "env"
  ],
  "properties": {
    "username": {
      "type": ["string", "null"],
      "format": "email",
      "minLength": 12,
      "maxLength": 100
    },
    "password": {
      "type": "string",
      "minLength": 8,
      "maxLength": 20
    },
    "areas": {
      "type": ["array", "null"],
      "items": {
        "type": "object",
        "required": [
          "lat",
          "lng"
        ],
        "properties": {
          "lat": {
            "type": "integer",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "integer",
            "minimum": -180,
            "maximum": 180
          }
        }
      }
    },
    "env": {
      "type": "object",
      "required": [
        "referer",
        "ip",
        "os",
        "browser"
      ],
      "properties": {
        "referer": {
          "type": "string",
          "format": "uri"
        },
        "ip": {
          "type": "string",
          "format": "ipv4"
        },
        "os": {
          "type": "object",
          "required": [
            "name",
            "version"
          ],
          "properties": {
            "name": {
              "type": "string",
              "enum": ["window", "osx", "android", "iphone"]
            },
            "version": {
              "type": "string",
              "pattern": "^(.*)$"
            }
          }
        },
        "browser": {
          "type": "object",
          "required": [
            "name",
            "version"
          ],
          "properties": {
            "name": {
              "type": "string",
              "enum": ["chrome", "firefox", "edge", "ie"]
            },
            "version": {
              "type": "string",
              "pattern": "^(.*)$"
            }
          }
        }
      }
    }
  }
}

Compare with JOI

JOI is the most popular object schema validation library.

Show JOI Source
Joi.object().keys({
  username: Joi.string().required().allow(null).email().min(12).max(100),
  password: Joi.string().min(8).max(20),
  areas: Joi.array().required().allow(null).min(1).items(
    Joi.object().keys({
      lat: Joi.number().required().min(-90).max(90),
      lng: Joi.number().required().min(-180).max(180),
    }),
  ),
  env: Joi.object().required().keys({
    referer: Joi.string().uri().required(),
    ip: Joi.string().required().ip({ version: ["ipv4"] }),
    os: Joi.object().required().keys({
      name: Joi.any().required().only("window", "osx", "android", "iphone"),
      version: Joi.string().required(),
    }),
    browser: Joi.object().required().keys({
      name: Joi.any().required().only("chrome", "firefox", "edge", "ie"),
      version: Joi.string().required(),
    }),
  }),
});

Old Versions