Skip to main content
Deno 2 is finally here πŸŽ‰οΈ
Learn more

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