Table of Contents
- Table of Contents
- Description
- Features
- Usage
- Basic usage
- Defining validations
- Defining schemas (objects)
- Handling unrecognized keys
- BaseValidator: methods and properties
.run(data: unknown): Result
: given a validation, you can call this method to check whether or not the.parse(data: unknown): T
: given a validations, you can call this method to check whether or not the input is valid..transform((value: T) => R): NopValidator
: adds a constraint that modifies the input:.reshape((value: T) => Result | IConstraint): NopValidator
: adds a constraint able to both validate.default(value: T | (() => T))
: transformundefined
into the given value or the callback's returned value:.optional
: a convenience method that returns a union of the type withs.undefined()
..nullable
: a convenience method that returns a union of the type withs.nullable()
..nullish
: a convenience method that returns a union of the type withs.nullish()
..array
: a convenience method that returns an ArrayValidator with the type..or
: a convenience method that returns an UnionValidator with the type. This method is also overridden in.when
: Adjust the schema based on a sibling or sinbling children fields.
- Enabling and disabling validation
- Buy us some doughnuts
- Contributors
Description
A very fast and lightweight input validation and transformation library for JavaScript.
Note: Shapeshift requires Node.js v14.0.0 or higher to work.
Features
Usage
For complete usages, please dive into our documentation
Basic usage
Creating a simple string validation
import { s } from '@sapphire/shapeshift';
const myStringValidation = s.string();
// Parse
myStringValidation.parse('sapphire'); // => returns 'sapphire'
myStringValidation.parse(12); // throws ValidationError
Creating an object schema
import { s } from '@sapphire/shapeshift';
const user = s.object({
username: s.string()
});
user.parse({ username: 'Sapphire' });
Defining validations
Primitives
import { s } from '@sapphire/shapeshift';
// Primitives
s.string();
s.number();
s.bigint();
s.boolean();
s.date();
// Empty Types
s.undefined();
s.null();
s.nullish(); // Accepts undefined | null
// Catch-all Types
s.any();
s.unknown();
// Never Type
s.never();
Literals
s.literal('sapphire');
s.literal(12);
s.literal(420n);
s.literal(true);
s.literal(new Date(1639278160000)); // s.date().equal(1639278160000);
Strings
Shapeshift includes a handful of string-specific validations:
s.string().lengthLessThan(5);
s.string().lengthLessThanOrEqual(5);
s.string().lengthGreaterThan(5);
s.string().lengthGreaterThanOrEqual(5);
s.string().lengthEqual(5);
s.string().lengthNotEqual(5);
s.string().email();
s.string().url();
s.string().uuid();
s.string().regex(regex);
s.string().ip();
s.string().ipv4();
s.string().ipv6();
s.string().phone();
Numbers
Shapeshift includes a handful of number-specific validations:
s.number().greaterThan(5); // > 5
s.number().greaterThanOrEqual(5); // >= 5
s.number().lessThan(5); // < 5
s.number().lessThanOrEqual(5); // <= 5
s.number().equal(5); // === 5
s.number().notEqual(5); // !== 5
s.number().equal(NaN); // special case: Number.isNaN
s.number().notEqual(NaN); // special case: !Number.isNaN
s.number().int(); // value must be an integer
s.number().safeInt(); // value must be a safe integer
s.number().finite(); // value must be finite
s.number().positive(); // .greaterThanOrEqual(0)
s.number().negative(); // .lessThan(0)
s.number().divisibleBy(5); // Divisible by 5
And transformations:
s.number().abs(); // Transforms the number to an absolute number
s.number().sign(); // Gets the number's sign
s.number().trunc(); // Transforms the number to the result of `Math.trunc`
s.number().floor(); // Transforms the number to the result of `Math.floor`
s.number().fround(); // Transforms the number to the result of `Math.fround`
s.number().round(); // Transforms the number to the result of `Math.round`
s.number().ceil(); // Transforms the number to the result of `Math.ceil`
BigInts
Shapeshift includes a handful of number-specific validations:
s.bigint().greaterThan(5n); // > 5n
s.bigint().greaterThanOrEqual(5n); // >= 5n
s.bigint().lessThan(5n); // < 5n
s.bigint().lessThanOrEqual(5n); // <= 5n
s.bigint().equal(5n); // === 5n
s.bigint().notEqual(5n); // !== 5n
s.bigint().positive(); // .greaterThanOrEqual(0n)
s.bigint().negative(); // .lessThan(0n)
s.bigint().divisibleBy(5n); // Divisible by 5n
And transformations:
s.bigint().abs(); // Transforms the bigint to an absolute bigint
s.bigint().intN(5); // Clamps to a bigint to a signed bigint with 5 digits, see BigInt.asIntN
s.bigint().uintN(5); // Clamps to a bigint to an unsigned bigint with 5 digits, see BigInt.asUintN
Booleans
Shapeshift includes a few boolean-specific validations:
s.boolean().true(); // value must be true
s.boolean().false(); // value must be false
s.boolean().equal(true); // s.boolean().true()
s.boolean().equal(false); // s.boolean().false()
s.boolean().notEqual(true); // s.boolean().false()
s.boolean().notEqual(false); // s.boolean().true()
Arrays
const stringArray = s.array(s.string());
const stringArray = s.string().array();
Shapeshift includes a handful of array-specific validations:
s.string().array().lengthLessThan(5); // Must have less than 5 elements
s.string().array().lengthLessThanOrEqual(5); // Must have 5 or less elements
s.string().array().lengthGreaterThan(5); // Must have more than 5 elements
s.string().array().lengthGreaterThanOrEqual(5); // Must have 5 or more elements
s.string().array().lengthEqual(5); // Must have exactly 5 elements
s.string().array().lengthNotEqual(5); // Must not have exactly 5 elements
s.string().array().lengthRange(0, 4); // Must have at least 0 elements and less than 4 elements (in math, that is [0, 4))
s.string().array().lengthRangeInclusive(0, 4); // Must have at least 0 elements and at most 4 elements (in math, that is [0, 4])
s.string().array().lengthRangeExclusive(0, 4); // Must have more than 0 element and less than 4 elements (in math, that is (0, 4))
s.string().array().unique(); // All elements must be unique. Deep equality is used to check for uniqueness.
Note: All
.length
methods define tuple types with the given amount of elements. For example,s.string().array().lengthGreaterThanOrEqual(2)
's inferred type is[string, string, ...string[]]
Tuples
Unlike arrays, tuples have a fixed number of elements and each element can have a different type:
const dish = s.tuple([
s.string(), // Dish's name
s.number().int(), // Table's number
s.date() // Date the dish was ready for delivery
]);
dish.parse(['Iberian ham', 10, new Date()]);
Unions
Shapeshift includes a built-in method for composing OR types:
const stringOrNumber = s.union([s.string(), s.number()]);
stringOrNumber.parse('Sapphire'); // => 'Sapphire'
stringOrNumber.parse(42); // => 42
stringOrNumber.parse({}); // => throws CombinedError
Enums
Enums are a convenience method that aliases s.union([s.literal(a), s.literal(b), ...])
:
s.enum(['Red', 'Green', 'Blue']);
// s.union([s.literal('Red'), s.literal('Green'), s.literal('Blue')]);
Maps
const map = s.map(s.string(), s.number());
// Map<string, number>
Sets
const set = s.set(s.number());
// Set<number>
Instances
You can use s.instance(Class)
to check that the input is an instance of a class. This is useful to validate inputs
against classes:
class User {
public constructor(public name: string) {}
}
const userInstanceValidation = s.instance(User);
userInstanceValidation.parse(new User('Sapphire')); // => User { name: 'Sapphire' }
userInstanceValidation.parse('oops'); // => throws ValidatorError