summaryrefslogtreecommitdiff
path: root/node_modules/@sapphire/shapeshift/README.md
diff options
context:
space:
mode:
authorsowgro <tpoke.ferrari@gmail.com>2023-09-02 19:12:47 -0400
committersowgro <tpoke.ferrari@gmail.com>2023-09-02 19:12:47 -0400
commite4450c8417624b71d779cb4f41692538f9165e10 (patch)
treeb70826542223ecdf8a7a259f61b0a1abb8a217d8 /node_modules/@sapphire/shapeshift/README.md
downloadsowbot3-e4450c8417624b71d779cb4f41692538f9165e10.tar.gz
sowbot3-e4450c8417624b71d779cb4f41692538f9165e10.tar.bz2
sowbot3-e4450c8417624b71d779cb4f41692538f9165e10.zip
first commit
Diffstat (limited to 'node_modules/@sapphire/shapeshift/README.md')
-rw-r--r--node_modules/@sapphire/shapeshift/README.md934
1 files changed, 934 insertions, 0 deletions
diff --git a/node_modules/@sapphire/shapeshift/README.md b/node_modules/@sapphire/shapeshift/README.md
new file mode 100644
index 0000000..c9f113f
--- /dev/null
+++ b/node_modules/@sapphire/shapeshift/README.md
@@ -0,0 +1,934 @@
+<div align="center">
+
+![Sapphire Logo](https://raw.githubusercontent.com/sapphiredev/assets/main/banners/SapphireCommunity.png)
+
+# @sapphire/shapeshift
+
+**Shapeshift**
+
+Blazing fast input validation and transformation ⚡
+
+[![GitHub](https://img.shields.io/github/license/sapphiredev/shapeshift)](https://github.com/sapphiredev/shapeshift/blob/main/LICENSE.md)
+[![codecov](https://codecov.io/gh/sapphiredev/shapeshift/branch/main/graph/badge.svg?token=RF4mMKx6lL)](https://codecov.io/gh/sapphiredev/shapeshift)
+[![npm](https://img.shields.io/npm/v/@sapphire/shapeshift?color=crimson&logo=npm&style=flat-square)](https://www.npmjs.com/package/@sapphire/shapeshift)
+
+</div>
+
+## Table of Contents
+
+- [@sapphire/shapeshift](#sapphireshapeshift)
+ - [Table of Contents](#table-of-contents)
+ - [Description](#description)
+ - [Features](#features)
+ - [Usage](#usage)
+ - [Basic usage](#basic-usage)
+ - [Defining validations](#defining-validations)
+ - [Primitives](#primitives)
+ - [Literals](#literals)
+ - [Strings](#strings)
+ - [Numbers](#numbers)
+ - [BigInts](#bigints)
+ - [Booleans](#booleans)
+ - [Arrays](#arrays)
+ - [Tuples](#tuples)
+ - [Unions](#unions)
+ - [Enums](#enums)
+ - [Maps](#maps)
+ - [Sets](#sets)
+ - [Instances](#instances)
+ - [Records](#records)
+ - [Functions // TODO](#functions--todo)
+ - [TypedArray](#typedarray)
+ - [Defining schemas (objects)](#defining-schemas-objects)
+ - [Utility types for TypeScript](#utility-types-for-typescript)
+ - [Extracting an interface from a schema](#extracting-an-interface-from-a-schema)
+ - [Defining the structure of a schema through an interface](#defining-the-structure-of-a-schema-through-an-interface)
+ - [`.extend`:](#extend)
+ - [`.pick` / `.omit`:](#pick--omit)
+ - [`.partial`](#partial)
+ - [`.required`](#required)
+ - [Handling unrecognized keys](#handling-unrecognized-keys)
+ - [`.strict`](#strict)
+ - [`.ignore`](#ignore)
+ - [`.passthrough`](#passthrough)
+ - [BaseValidator: methods and properties](#basevalidator-methods-and-properties)
+ - [`.run`](#rundata-unknown-resultt-error-given-a-validation-you-can-call-this-method-to-check-whether-or-not-the)
+ - [`.parse`](#parsedata-unknown-t-given-a-validations-you-can-call-this-method-to-check-whether-or-not-the-input-is-valid)
+ - [`.transform`](#transformrvalue-t--r-nopvalidatorr-adds-a-constraint-that-modifies-the-input)
+ - [`.reshape`](#reshapervalue-t--resultr-error--iconstraint-nopvalidatorr-adds-a-constraint-able-to-both-validate)
+ - [`.default`](#defaultvalue-t----t-transform-undefined-into-the-given-value-or-the-callbacks-returned-value)
+ - [`.optional`](#optional-a-convenience-method-that-returns-a-union-of-the-type-with-sundefined)
+ - [`.nullable`](#nullable-a-convenience-method-that-returns-a-union-of-the-type-with-snullable)
+ - [`.nullish`](#nullish-a-convenience-method-that-returns-a-union-of-the-type-with-snullish)
+ - [`.array`](#array-a-convenience-method-that-returns-an-arrayvalidator-with-the-type)
+ - [`.or`](#or-a-convenience-method-that-returns-an-unionvalidator-with-the-type-this-method-is-also-overridden-in)
+ - [`.when`](#when-adjust-the-schema-based-on-a-sibling-or-sinbling-children-fields)
+ - [Available options for providing `is`](#available-options-for-providing-is)
+ - [Resolving of the `key` (first) parameter](#resolving-of-the-key-first-parameter)
+ - [Examples](#examples)
+ - [Enabling and disabling validation](#enabling-and-disabling-validation)
+ - [Buy us some doughnuts](#buy-us-some-doughnuts)
+ - [Contributors](#contributors)
+
+## Description
+
+[Back to top][toc]
+
+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
+
+[Back to top][toc]
+
+- TypeScript friendly
+- Offers CJS, ESM and UMD builds
+- API similar to [`zod`]
+- Faster than ⚡
+
+## Usage
+
+[Back to top][toc]
+
+**_For complete usages, please dive into our [documentation]_**
+
+### Basic usage
+
+[Back to top][toc]
+
+Creating a simple string validation
+
+```typescript
+import { s } from '@sapphire/shapeshift';
+
+const myStringValidation = s.string;
+
+// Parse
+myStringValidation.parse('sapphire'); // => returns 'sapphire'
+myStringValidation.parse(12); // throws ValidationError
+```
+
+Creating an object schema
+
+```typescript
+import { s } from '@sapphire/shapeshift';
+
+const user = s.object({
+ username: s.string
+});
+
+user.parse({ username: 'Sapphire' });
+```
+
+### Defining validations
+
+[Back to top][toc]
+
+#### Primitives
+
+[Back to top][toc]
+
+```typescript
+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
+
+[Back to top][toc]
+
+```typescript
+s.literal('sapphire');
+s.literal(12);
+s.literal(420n);
+s.literal(true);
+s.literal(new Date(1639278160000)); // s.date.equal(1639278160000);
+```
+
+#### Strings
+
+[Back to top][toc]
+
+Shapeshift includes a handful of string-specific validations:
+
+```typescript
+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
+
+[Back to top][toc]
+
+Shapeshift includes a handful of number-specific validations:
+
+```typescript
+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:
+
+```typescript
+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
+
+[Back to top][toc]
+
+Shapeshift includes a handful of number-specific validations:
+
+```typescript
+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:
+
+```typescript
+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
+
+[Back to top][toc]
+
+Shapeshift includes a few boolean-specific validations:
+
+```typescript
+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
+
+[Back to top][toc]
+
+```typescript
+const stringArray = s.array(s.string);
+const stringArray = s.string.array;
+```
+
+Shapeshift includes a handful of array-specific validations:
+
+```typescript
+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
+
+[Back to top][toc]
+
+Unlike arrays, tuples have a fixed number of elements and each element can have a different type:
+
+```typescript
+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
+
+[Back to top][toc]
+
+Shapeshift includes a built-in method for composing OR types:
+
+```typescript
+const stringOrNumber = s.union(s.string, s.number);
+
+stringOrNumber.parse('Sapphire'); // => 'Sapphire'
+stringOrNumber.parse(42); // => 42
+stringOrNumber.parse({}); // => throws CombinedError
+```
+
+#### Enums
+
+[Back to top][toc]
+
+Enums are a convenience method that aliases `s.union(s.literal(a), s.literal(b), ...)`:
+
+```typescript
+s.enum('Red', 'Green', 'Blue');
+// s.union(s.literal('Red'), s.literal('Green'), s.literal('Blue'));
+```
+
+#### Maps
+
+[Back to top][toc]
+
+```typescript
+const map = s.map(s.string, s.number);
+// Map<string, number>
+```
+
+#### Sets
+
+[Back to top][toc]
+
+```typescript
+const set = s.set(s.number);
+// Set<number>
+```
+
+#### Instances
+
+[Back to top][toc]
+
+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:
+
+```typescript
+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
+```
+
+#### Records
+
+[Back to top][toc]
+
+Record validations are similar to objects, but validate `Record<string, T>` types. Keep in mind this does not check for
+the keys, and cannot support validation for specific ones:
+
+```typescript
+const tags = s.record(s.string);
+
+tags.parse({ foo: 'bar', hello: 'world' }); // => { foo: 'bar', hello: 'world' }
+tags.parse({ foo: 42 }); // => throws CombinedError
+tags.parse('Hello'); // => throws ValidateError
+```
+
+---
+
+_**Function validation is not yet implemented and will be made available starting v2.1.0**_
+
+#### Functions // TODO
+
+[Back to top][toc]
+
+You can define function validations. This checks for whether or not an input is a function:
+
+```typescript
+s.function; // () => unknown
+```
+
+You can define arguments by passing an array as the first argument, as well as the return type as the second:
+
+```typescript
+s.function([s.string]); // (arg0: string) => unknown
+s.function([s.string, s.number], s.string); // (arg0: string, arg1: number) => string
+```
+
+> **Note**: Shapeshift will transform the given function into one with validation on arguments and output. You can
+> access the `.raw` property of the function to get the unchecked function.
+
+---
+
+#### TypedArray
+
+[Back to top][toc]
+
+```ts
+const typedArray = s.typedArray();
+const int16Array = s.int16Array;
+const uint16Array = s.uint16Array;
+const uint8ClampedArray = s.uint8ClampedArray;
+const int16Array = s.int16Array;
+const uint16Array = s.uint16Array;
+const int32Array = s.int32Array;
+const uint32Array = s.uint32Array;
+const float32Array = s.float32Array;
+const float64Array = s.float64Array;
+const bigInt64Array = s.bigInt64Array;
+const bigUint64Array = s.bigUint64Array;
+```
+
+Shapeshift includes a handful of validations specific to typed arrays.
+
+```typescript
+s.typedArray().lengthLessThan(5); // Length must be less than 5
+s.typedArray().lengthLessThanOrEqual(5); // Length must be 5 or less
+s.typedArray().lengthGreaterThan(5); // Length must be more than 5
+s.typedArray().lengthGreaterThanOrEqual(5); // Length must be 5 or more
+s.typedArray().lengthEqual(5); // Length must be exactly 5
+s.typedArray().lengthNotEqual(5); // Length must not be 5
+s.typedArray().lengthRange(0, 4); // Length L must satisfy 0 <= L < 4
+s.typedArray().lengthRangeInclusive(0, 4); // Length L must satisfy 0 <= L <= 4
+s.typedArray().lengthRangeExclusive(0, 4); // Length L must satisfy 0 < L < 4
+```
+
+Note that all of these methods have analogous methods for working with the typed array's byte length,
+`s.typedArray().byteLengthX()` - for instance, `s.typedArray().byteLengthLessThan(5)` is the same as
+`s.typedArray().lengthLessThan(5)` but for the array's byte length.
+
+---
+
+### Defining schemas (objects)
+
+[Back to top][toc]
+
+```typescript
+// Properties are required by default:
+const animal = s.object({
+ name: s.string,
+ age: s.number
+});
+```
+
+#### Utility types for TypeScript
+
+[Back to top][toc]
+
+For object validation Shapeshift exports 2 utility types that can be used to extract interfaces from schemas and define
+the structure of a schema as an interface beforehand respectively.
+
+##### Extracting an interface from a schema
+
+[Back to top][toc]
+
+You can use the `InferType` type to extract the interface from a schema, for example:
+
+```typescript
+import { InferType, s } from '@sapphire/shapeshift';
+
+const schema = s.object({
+ foo: s.string,
+ bar: s.number,
+ baz: s.boolean,
+ qux: s.bigint,
+ quux: s.date
+});
+
+type Inferredtype = InferType<typeof schema>;
+
+// Expected type:
+type Inferredtype = {
+ foo: string;
+ bar: number;
+ baz: boolean;
+ qux: bigint;
+ quux: Date;
+};
+```
+
+##### Defining the structure of a schema through an interface
+
+[Back to top][toc]
+
+You can use the `SchemaOf` type to define the structure of a schema before defining the actual schema, for example:
+
+```typescript
+import { s, SchemaOf } from '@sapphire/shapeshift';
+
+interface IIngredient {
+ ingredientId: string | undefined;
+ name: string | undefined;
+}
+
+interface IInstruction {
+ instructionId: string | undefined;
+ message: string | undefined;
+}
+
+interface IRecipe {
+ recipeId: string | undefined;
+ title: string;
+ description: string;
+ instructions: IInstruction[];
+ ingredients: IIngredient[];
+}
+
+type InstructionSchemaType = SchemaOf<IInstruction>;
+// Expected Type: ObjectValidator<IInstruction>
+
+type IngredientSchemaType = SchemaOf<IIngredient>;
+// Expected Type: ObjectValidator<IIngredient>
+
+type RecipeSchemaType = SchemaOf<IRecipe>;
+// Expected Type: ObjectValidator<IRecipe>
+
+const instructionSchema: InstructionSchemaType = s.object({
+ instructionId: s.string.optional,
+ message: s.string
+});
+
+const ingredientSchema: IngredientSchemaType = s.object({
+ ingredientId: s.string.optional,
+ name: s.string
+});
+
+const recipeSchema: RecipeSchemaType = s.object({
+ recipeId: s.string.optional,
+ title: s.string,
+ description: s.string,
+ instructions: s.array(instructionSchema),
+ ingredients: s.array(ingredientSchema)
+});
+```
+
+#### `.extend`:
+
+[Back to top][toc]
+
+You can add additional fields using either an object or an ObjectValidator, in this case, you will get a new object
+validator with the merged properties:
+
+```typescript
+const animal = s.object({
+ name: s.string.optional,
+ age: s.number
+});
+
+const pet = animal.extend({
+ owner: s.string.nullish
+});
+
+const pet = animal.extend(
+ s.object({
+ owner: s.string.nullish
+ })
+);
+```
+
+> If both schemas share keys, an error will be thrown. Please use `.omit` on the first object if you desire this
+> behaviour.
+
+#### `.pick` / `.omit`:
+
+[Back to top][toc]
+
+Inspired by TypeScript's built-in `Pick` and `Omit` utility types, all object schemas have the aforementioned methods
+that return a modifier version:
+
+```typescript
+const pkg = s.object({
+ name: s.string,
+ description: s.string,
+ dependencies: s.string.array
+});
+
+const justTheName = pkg.pick(['name']);
+// s.object({ name: s.string });
+
+const noDependencies = pkg.omit(['dependencies']);
+// s.object({ name: s.string, description: s.string });
+```
+
+#### `.partial`
+
+[Back to top][toc]
+
+Inspired by TypeScript's built-in `Partial` utility type, all object schemas have the aforementioned method that makes
+all properties optional:
+
+```typescript
+const user = s.object({
+ username: s.string,
+ password: s.string
+}).partial;
+```
+
+Which is the same as doing:
+
+```typescript
+const user = s.object({
+ username: s.string.optional,
+ password: s.string.optional
+});
+```
+
+---
+
+#### `.required`
+
+[Back to top][toc]
+
+Inspired by TypeScript's built-in `Required` utility type, all object schemas have the aforementioned method that makes
+all properties required:
+
+```typescript
+const user = s.object({
+ username: s.string.optional,
+ password: s.string.optional
+}).required;
+```
+
+Which is the same as doing:
+
+```typescript
+const user = s.object({
+ username: s.string,
+ password: s.string
+});
+```
+
+---
+
+### Handling unrecognized keys
+
+[Back to top][toc]
+
+By default, Shapeshift will not include keys that are not defined by the schema during parsing:
+
+```typescript
+const person = s.object({
+ framework: s.string
+});
+
+person.parse({
+ framework: 'Sapphire',
+ awesome: true
+});
+// => { name: 'Sapphire' }
+```
+
+#### `.strict`
+
+[Back to top][toc]
+
+You can disallow unknown keys with `.strict`. If the input includes any unknown keys, an error will be thrown.
+
+```typescript
+const person = s.object({
+ framework: s.string
+}).strict;
+
+person.parse({
+ framework: 'Sapphire',
+ awesome: true
+});
+// => throws ValidationError
+```
+
+#### `.ignore`
+
+[Back to top][toc]
+
+You can use the `.ignore` getter to reset an object schema to the default behaviour (ignoring unrecognized keys).
+
+#### `.passthrough`
+
+[Back to top][toc]
+
+You can use the `.passthrough` getter to make the validator add the unrecognized properties the shape does not have,
+from the input.
+
+---
+
+### BaseValidator: methods and properties
+
+[Back to top][toc]
+
+All validations in Shapeshift contain certain methods.
+
+- #### `.run(data: unknown): Result<T, Error>`: given a validation, you can call this method to check whether or not the
+
+ input is valid. If it is, a `Result` with `success: true` and a deep-cloned value will be returned with the given
+ constraints and transformations. Otherwise, a `Result` with `success: false` and an error is returned.
+
+- #### `.parse(data: unknown): T`: given a validations, you can call this method to check whether or not the input is valid.
+
+ If it is, a deep-cloned value will be returned with the given constraints and transformations. Otherwise, an error is
+ thrown.
+
+- #### `.transform<R>((value: T) => R): NopValidator<R>`: adds a constraint that modifies the input:
+
+```typescript
+import { s } from '@sapphire/shapeshift';
+
+const getLength = s.string.transform((value) => value.length);
+getLength.parse('Hello There'); // => 11
+```
+
+> :warning: `.transform`'s functions **must not throw**. If a validation error is desired to be thrown, `.reshape`
+> instead.
+
+- #### `.reshape<R>((value: T) => Result<R, Error> | IConstraint): NopValidator<R>`: adds a constraint able to both validate
+ and modify the input:
+
+```typescript
+import { s, Result } from '@sapphire/shapeshift';
+
+const getLength = s.string.reshape((value) => Result.ok(value.length));
+getLength.parse('Hello There'); // => 11
+```
+
+> :warning: `.reshape`'s functions **must not throw**. If a validation error is desired to be thrown, use
+> `Result.err(error)` instead.
+
+- #### `.default(value: T | (() => T))`: transform `undefined` into the given value or the callback's returned value:
+
+```typescript
+const name = s.string.default('Sapphire');
+name.parse('Hello'); // => 'Hello'
+name.parse(undefined); // => 'Sapphire'
+```
+
+```typescript
+const number = s.number.default(Math.random);
+number.parse(12); // => 12
+number.parse(undefined); // => 0.989911985608602
+number.parse(undefined); // => 0.3224350185068794
+```
+
+> :warning: The default values are not validated.
+
+- #### `.optional`: a convenience method that returns a union of the type with `s.undefined`.
+
+```typescript
+s.string.optional; // s.union(s.string, s.undefined)
+```
+
+- #### `.nullable`: a convenience method that returns a union of the type with `s.nullable`.
+
+```typescript
+s.string.nullable; // s.union(s.string, s.nullable)
+```
+
+- #### `.nullish`: a convenience method that returns a union of the type with `s.nullish`.
+
+```typescript
+s.string.nullish; // s.union(s.string, s.nullish)
+```
+
+- #### `.array`: a convenience method that returns an ArrayValidator with the type.
+
+```typescript
+s.string.array; // s.array(s.string)
+```
+
+- #### `.or`: a convenience method that returns an UnionValidator with the type. This method is also overridden in
+ UnionValidator to just append one more entry.
+
+```typescript
+s.string.or(s.number);
+// => s.union(s.string, s.number)
+
+s.object({ name: s.string }).or(s.string, s.number);
+// => s.union(s.object({ name: s.string }), s.string, s.number)
+```
+
+- #### `.when`: Adjust the schema based on a sibling or sinbling children fields.
+
+For using when you provide an object literal where the key `is` is undefined, a value, or a matcher function; `then`
+provides the schema when `is` resolves truthy, and `otherwise` provides the schema when `is` resolves falsey.
+
+##### Available options for providing `is`
+
+When `is` is not provided (`=== undefined`) it is strictly resolved as `Boolean(value)` wherein `value` is the current
+value of the referenced sibling. Note that if multiple siblings are referenced then all the values of the array need to
+resolve truthy for the `is` to resolve truthy.
+
+When `is` is a primitive literal it is strictly compared (`===`) to the current value.
+
+If you want to use a different form of equality you can provide a function like: `is: (value) => value === true`.
+
+##### Resolving of the `key` (first) parameter
+
+For resolving the `key` parameter to its respective value we use [lodash/get](https://lodash.com/docs#get). This means
+that every way that Lodash supports resolving a key to its respective value is also supported by Shapeshift. This
+includes:
+
+- Simply providing a string or number like `'name'` or `1`.
+- Providing a string or number with a dot notation like `'name.first'` (representative of a nested object structure of
+ `{ 'name': { 'first': 'Sapphire' } }` => resolves to `Sapphire`).
+- Providing a string or number with a bracket notation like `'name[0]'` (representative of an array structure of
+ `{ 'name': ['Sapphire', 'Framework'] }` => resolves to `Sapphire`).
+- Providing a string or number with a dot and bracket notation like `'name[1].first'` (representative of a nested object
+ structure of `{ 'name': [{ 'first': 'Sapphire' }, { 'first': 'Framework' }] }` => resolves to `Framework`).
+
+##### Examples
+
+Let's start with a basic example:
+
+```typescript
+const whenPredicate = s.object({
+ booleanLike: s.boolean,
+ numberLike: s.number.when('booleanLike', {
+ then: (schema) => schema.greaterThanOrEqual(5),
+ otherwise: (schema) => schema.lessThanOrEqual(5)
+ })
+});
+
+whenPredicate.parse({ booleanLike: true, numberLike: 6 });
+// => { booleanLike: true, numberLike: 6 }
+
+whenPredicate.parse({ booleanLike: true, numberLike: 4 });
+// => ExpectedConstraintError('s.number.greaterThanOrEqual', 'Invalid number value', 4, 'expected >= 5')
+
+whenPredicate.parse({ booleanLike: false, numberLike: 4 });
+// => { booleanLike: false, numberLike: 4 }
+```
+
+The provided key can also be an array of sibling children:
+
+```typescript
+const whenPredicate = s.object({
+ booleanLike: s.boolean,
+ stringLike: s.string,
+ numberLike: s.number.when(['booleanLike', 'stringLike'], {
+ is: ([booleanLikeValue, stringLikeValue]) => booleanLikeValue === true && stringLikeValue === 'foobar',
+ then: (schema) => schema.greaterThanOrEqual(5),
+ otherwise: (schema) => schema.lessThanOrEqual(5)
+ })
+});
+
+whenPredicate.parse({ booleanLike: true, stringLike: 'foobar', numberLike: 6 });
+// => { booleanLike: true, numberLike: 6 }
+
+whenPredicate.parse({ booleanLike: true, stringLike: 'barfoo', numberLike: 4 });
+// => ExpectedConstraintError('s.number.greaterThanOrEqual', 'Invalid number value', 4, 'expected >= 5')
+
+whenPredicate.parse({ booleanLike: false, stringLike: 'foobar' numberLike: 4 });
+// => ExpectedConstraintError('s.number.greaterThanOrEqual', 'Invalid number value', 4, 'expected >= 5')
+```
+
+### Enabling and disabling validation
+
+[Back to top][toc]
+
+At times, you might want to have a consistent code base with validation, but would like to keep validation to the strict
+necessities instead of the in-depth constraints available in shapeshift. By calling `setGlobalValidationEnabled` you can
+disable validation at a global level, and by calling `setValidationEnabled` you can disable validation on a
+per-validator level.
+
+> When setting the validation enabled status per-validator, you can also set it to `null` to use the global setting.
+
+```typescript
+import { setGlobalValidationEnabled } from '@sapphire/shapeshift';
+
+setGlobalValidationEnabled(false);
+```
+
+```typescript
+import { s } from '@sapphire/shapeshift';
+
+const predicate = s.string.lengthGreaterThan(5).setValidationEnabled(false);
+```
+
+## Buy us some doughnuts
+
+[Back to top][toc]
+
+Sapphire Community is and always will be open source, even if we don't get donations. That being said, we know there are
+amazing people who may still want to donate just to show their appreciation. Thank you very much in advance!
+
+We accept donations through Open Collective, Ko-fi, Paypal, Patreon and GitHub Sponsorships. You can use the buttons
+below to donate through your method of choice.
+
+| Donate With | Address |
+| :-------------: | :-------------------------------------------------: |
+| Open Collective | [Click Here](https://sapphirejs.dev/opencollective) |
+| Ko-fi | [Click Here](https://sapphirejs.dev/kofi) |
+| Patreon | [Click Here](https://sapphirejs.dev/patreon) |
+| PayPal | [Click Here](https://sapphirejs.dev/paypal) |
+
+## Contributors
+
+[Back to top][toc]
+
+Please make sure to read the [Contributing Guide][contributing] before making a pull request.
+
+Thank you to all the people who already contributed to Sapphire!
+
+<a href="https://github.com/sapphiredev/shapeshift/graphs/contributors">
+ <img src="https://contrib.rocks/image?repo=sapphiredev/shapeshift" />
+</a>
+
+[contributing]: https://github.com/sapphiredev/.github/blob/main/.github/CONTRIBUTING.md
+[`zod`]: https://github.com/colinhacks/zod
+[documentation]: https://www.sapphirejs.dev/docs/Documentation/api-shapeshift/
+[toc]: #table-of-contents