Skip to content

Chainable validation library for Node.js and browsers.

License

Notifications You must be signed in to change notification settings

jagaapple/marubatsu.js

Repository files navigation

marubatsu

⭕️ Chainable validation library for Node.js and browsers. ❌

import marubatsu from "marubatsu";

const website = "https://example.com";
const isValidWebsite = marubatsu()
  .present()
  .string({ length: [7, 128] })
  .or(
    (validator) => validator().string({ startsWith: "http://" }),
    (validator) => validator().string({ startsWith: "https://" }),
  )
  .not.string({ endsWith: "/" })
  .test(website); // true
npm bundlephobia circleci codecov license @jagaapple_tech

⚠️ THIS IS EXPERIMENTAL NOW ⚠️

This is written about marubatsu features, but they may be not implemented yet.

Table of Contents

Features

⚠️ THIS IS EXPERIMENTAL NOW ⚠️

FEATURES WHAT YOU CAN DO
đź”— Chainable API Compose and share validations in your app
🌏 Universal JavaScript Works on browsers (ES Modules) and Node.js (CommonJS)
đź›  Customizable validation rules Merge new rules and create your rules
🇯🇵 Customizable validation messages Translate and set more friendly messages
🔤 Supports TypeScript Use autocomplete and type safety system

Quick Start

Requirements

  • npm or Yarn
  • Browsers or Node.js which supports ES2015+

Installation

$ npm install --save marubatsu

If you are using Yarn, use the following command.

$ yarn add marubatsu

marubatsu is created by TypeScript so you do not need to install any definitely typed packages like @types/marubatsu .

Basic Usage

The below is simple example to check some values.

import marubatsu from "marubatsu";

// Checks the value is starting with "@", and length is between 4 and 20.
marubatsu()
  .string({ length: [4, 20], startsWith: "@" })
  .test("@jagaapple"); // true


// Shares your validator.
export const userNameValidator = marubatsu().string({ length: [4, 20], startsWith: "@" });


// Combinates some operators.
marubatsu()
  .or(
    (value, validator) => validator().number({ length: 3 }).test(value),
    (value, validator) => validator().string({ length: 3 }).test(value),
  )
  .test(123); // true


// Checks all elements of array.
marubatsu()
  .array({
    length: 3,
    every: (value, validator) => validator().string({ startsWith: "#" }),
  })
  .test(["#apple", "#orange", "#grape"]); // true


// Gets validation results.
marubatsu()
  .string({ length: [4, 20], startsWith: "@" })
  .validate("@a");
// {
//   isPassed: false,
//   error: [
//     {
//       ruleName: "string-length",
//       expected: [4, 20],
//       actual: 2,
//       message: "The value should be between 4 and 20 characters in length, but @a.",
//     },
//   ],
// }


// Customizes validation messages.
marubatsu({
  rules: {
    "string-length": {
      failedMessage: (subject, actual, expected) => `The ${subject} is invalid`,
    },
  },
})
  .string({ length: [4, 20], startsWith: "@" })
  .validate("@a", "username");
// {
//   isPassed: false,
//   error: [
//     {
//       ruleName: "string-length",
//       expected: [4, 20],
//       actual: 2,
//       message: "The username is invalid.",
//     },
//   ],
// }

// Creates your rules.
marubatsu({
  rules: {
    "string-email": {
      checker: (value, tld) => new RegExp(`/^.+@.+\\.${tld}$/`).test(value),
      failedMessage: (subject, actual, expected) => `The ${actual} is invalid email address format`,
    },
  },
})
  .string({ email: "com" })
  .test("example@example.com"); // true

Executors

Executors is to execute validations.

test(value: any)

Returns true if a value passes all validations, otherwise returns false . This executor immediately stops to check rules when a validation is failed in order to improve performance.

  • value: any ... The value
marubatsu().string({ length: 3 }).test("123");  // true
marubatsu().string({ length: 3 }).test("1234"); // false

validate(value: any, subject?: string = "value")

Returns a failed rule and its error message. This executor immediately stops to check rules when a validation is failed in order to improve performance, so returns only one error message.

  • value: any ... The target value
  • subject?: string = "value" ... The name of the target value
const validator = marubatsu().string({ length: [4, 20], startsWith: "@" });

validator.validate("abcde", "username");
// {
//   isPassed: false,
//   error: {
//     ruleName: "string-startsWith",
//     expected: "@,
//     actual: "abcde",
//     message: "The username should start with @.",
//   },
// }

validator.validate("@abcde");
// {
//   isPassed: true,
// }

Operators

Operators is validation to check the value conforms specific rules.

nullary()

Checks the value is null or undefined .

const validator = marubatsu().nullary();

validator.test(null); // true
validator.test(undefined); // true
validator.test(-1); // false
validator.test(0); // false
validator.test(""); // false
validator.test(" "); // false
validator.test(false); // false
validator.test([]); // false
validator.test({}); // false

empty()

Checks the value is an empty string, an empty array, or an empty object (pure object/hash/dictionary).

const validator = marubatsu().empty();

validator.test(null); // false
validator.test(undefined); // false
validator.test(-1); // false
validator.test(0); // false
validator.test(""); // true
validator.test(" "); // false
validator.test(false); // false
validator.test([]); // true
validator.test({}); // true

blank()

Checks the value is null , undefined , an empty string, a string including only spaces, an empty array, an empty object (pure object/hash/dictionary), or false .

const validator = marubatsu().blank();

validator.test(null); // true
validator.test(undefined); // true
validator.test(-1); // false
validator.test(0); // false
validator.test(""); // true
validator.test(" "); // true
validator.test(false); // true
validator.test([]); // true
validator.test({}); // true

present()

Checks the value is NOT null , undefined , an empty string, a string including only spaces, an empty array, an empty object (pure object/hash/dictionary), or false . This operator is equal to not.blank()

string(rules: { [ruleName]: any } = {})

Checks the value conforms rules related to string.

type: boolean

Checks the value is string type.

const validator = marubatsu().string({ type: true });

validator.test("ok"); // true
validator.test(123);  // false

value: string

Checks the string is equal to a specific string.

const validator = marubatsu().string({ value: "abc" });

validator.test("abc");   // true
validator.test("abcde"); // false

length: number

Checks the string length is equal to a specific length.

const validator = marubatsu().string({ length: 3 });

validator.test("12");   // false
validator.test("123");  // true
validator.test("1234"); // false

length: [number, number]

Checks the string length is between specific length range. The first number is minimum length and the second number is maximum length.

const validator = marubatsu().string({ length: [1, 3] });

validator.test("");     // false
validator.test("1");    // true
validator.test("123");  // true
validator.test("1234"); // false

maximumLength: number

Checks the string length is no more than a specific length.

const validator = marubatsu().string({ maximumLength: 3 });

validator.test("12");   // true
validator.test("123");  // true
validator.test("1234"); // false

minimumLength: number

Checks the string length is no less than a specific length.

const validator = marubatsu().string({ minimumLength: 3 });

validator.test("12");   // false
validator.test("123");  // true
validator.test("1234"); // true

startsWith: string

Checks the string is starting with a specific string.

const validator = marubatsu().string({ startsWith: "abc" });

validator.test("abcde"); // true
validator.test("12345"); // false

endsWith: string

Checks the string is ending with a specific string.

const validator = marubatsu().string({ endsWith: "cde" });

validator.test("abcde"); // true
validator.test("12345"); // false

alphanumeric: boolean

Checks the string is alphanumeric.

const validator = marubatsu().string({ alphanumeric: true });

validator.test("123"); // true
validator.test("abc"); // true
validator.test("a12"); // true
validator.test("# @"); // false

alphanumeric: "lower-camel" | "upper-camel" | "lower-snake" | "upper-snake" | "lower-kebab" | "upper-kebab" | "lower-space" | "upper-space" | "lower-dot" | "upper-dot"

Checks the string is alphanumeric and a specific case style such as lowerCamelCase or lower_snake_case .

You can specify one of the following case style.

VALUE CASE STYLE VALID STRING
"lower-camel" Lower Camel Case "lowerCamelCase"
"upper-camel" Upper Camel Case "UpperCamelCase"
"lower-snake" Lower Snake Case "lower_snake_case"
"upper-snake" Upper Snake Case "Upper_Snake_Case"
"lower-kebab" Lower Kebab Case (Lower Chain Case) "lower-kebab-case"
"upper-kebab" Upper Kebab Case (Upper Chain Case) "Upper-Kebab-Case"
"lower-space" Lower Space Case "lower space case"
"upper-space" Upper Space Case "Upper Space Case"
"lower-dot" Lower Dot Case "lower.dot.case"
"upper-dot" Upper Dot Case "Upper.Dot.Case"
const validator = marubatsu().string({ alphanumeric: "lower-snake" });

validator.test("jagaapple");  // true
validator.test("jaga_apple"); // true
validator.test("JagaApple");  // false
validator.test("Jaga Apple"); // false
validator.test("jaga-apple"); // false
validator.test("jaga.apple"); // false

includes: string

Checks the string includes a specific string.

const validator = marubatsu().string({ includes: "am" });

validator.test("I am Jaga Apple");    // true
validator.test("This is Jaga Apple"); // false

pattern: RegExp

Checks the string conforms a specific regular expression.

const validator = marubatsu().string({ pattern: /^.+@.+$/ });

validator.test("example@example.com"); // true
validator.test("example.com");         // false

number(rules: { [ruleName]: any } = {})

Checks the value conforms rules realted to number.

type: boolean

Checks the value is string type.

const validator = marubatsu().number({ type: true });

validator.test(123);  // true
validator.test("ok"); // false

value: number

Checks the number is equal to a specific number.

const validator = marubatsu().number({ value: 123 });

validator.test(123);   // true
validator.test(12345); // false

value: [number, number]

Checks the number is between specific value range. The first number is minimum value and the second number is maximum value.

const validator = marubatsu().number({ value: [100, 200] });

validator.test(123);   // true
validator.test(12345); // false

maximumValue: number

Checks the number is equal to or less than a specific maximum value.

const validator = marubatsu().number({ maximumValue: 200 });

validator.test(123);   // true
validator.test(12345); // false

minimumValue: number

Checks the number is equal to or more than a specific minimum value.

const validator = marubatsu().number({ minimumValue: 100 });

validator.test(123); // true
validator.test(12);  // false

integer: boolean

Checks the number does not have decimal.

const validator = marubatsu().number({ integer: true });

validator.test(100);    // true
validator.test(100.0);  // true
validator.test(100.00); // true
validator.test(100.01); // false

float: boolean

Checks the number has decimal.

const validator = marubatsu().number({ float: true });

validator.test(100);    // false
validator.test(100.0);  // false
validator.test(100.00); // false
validator.test(100.01); // true

positive: boolean

Checks the number is a positive number. 0 is false .

const validator = marubatsu().number({ positive: true });

validator.test(100);  // true
validator.test(0);    // false
validator.test(-100); // false

negative: boolean

Checks the number is a negative number. 0 is false .

const validator = marubatsu().number({ negative: true });

validator.test(100);  // false
validator.test(0);    // false
validator.test(-100); // true

digits: number

Checks the number of digits is equal to a specific number.

const validator = marubatsu().number({ digits: 3 });

validator.test(12);   // false
validator.test(123);  // true
validator.test(1234); // false

digits: [number, number]

Checks the number of digits is between specific value range. The first number is minimum and the second number is maximum number of digits.

const validator = marubatsu().number({ digits: [3, 4] });

validator.test(12);    // false
validator.test(123);   // true
validator.test(1234);  // true
validator.test(12345); // false

maximumDigits: number

Checks the number of digits is equal to or less than a specific number.

const validator = marubatsu().number({ maximumDigits: 3 });

validator.test(12);   // true
validator.test(123);  // true
validator.test(1234); // false

minimumDigits: number

Checks the number of digits is equal to or more than a specific number.

const validator = marubatsu().number({ minimumDigits: 3 });

validator.test(12);   // false
validator.test(123);  // true
validator.test(1234); // true

Modifiers

not

Inverts specified rules.

const validator = marubatsu()
  .string({ endsWith: ".com" })
  .not.string({ startsWith: "https://" });

validator.test("https://example.com"); // true
validator.test("http://example.com");  // false
validator.test("https://example.jp");  // false

Receipes

Shares validators in your app

marubatsu does not execute validations until calling some executors.

// /account.validators.ts
export const accountNameValidator = marubatsu()
  .present()
  .string({ length: [4, 20], startsWith: "@" })
// /sign-up.ts
import { accountNameValidator } from "./account.validators.ts";

const # = (accountName: string) => {
  if (!accountNameValidator.test(accountName)) return;

  ...
}

// /sign-in.ts
import { accountNameValidator } from "./account.validators.ts";

const signIn = (accountName: string) => {
  if (!accountNameValidator.test(accountName)) return;

  ...
}

Migrates new rules to validator

let validator = marubatsu()
  .string({ length: 3 });

validator = validator
  .string({ startsWith: "a" });
  // Be equal to `.string({ length: 3, startsWith: "a" })`

It is possible to migrate new rules to validator and disable applied rules. To disable applied rules, pass undefined or null .

const websiteIdentifierValidator = marubatsu()
  .string({ maximumlength: 255, minimumLength: 4 });

const urlValidator = websiteIdentifierValidator
  .string({ minimumLength: undefined, startsWith: "https" });
  // Disable `minimumLength` and merge `startsWith` rule

Contributing to marubatsu

Bug reports and pull requests are welcome on GitHub at https://github.com/jagaapple/marubatsu.js. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

Please read Contributing Guidelines before development and contributing.

License

The library is available as open source under the terms of the MIT License.

Copyright 2019 Jaga Apple. All rights reserved.

About

Chainable validation library for Node.js and browsers.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published