@sapphire/shapeshift
Advanced tools
Comparing version 1.1.0-next.6e2c172.0 to 1.1.0-next.793648b.0
@@ -1,16 +0,89 @@ | ||
declare class ConstraintError<T = unknown> extends Error { | ||
readonly constraint: string; | ||
/// <reference types="node" /> | ||
import { InspectOptionsStylized } from 'node:util'; | ||
declare type ArrayConstraintName = `s.array(T).length${'Lt' | 'Le' | 'Gt' | 'Ge' | 'Eq' | 'Ne'}`; | ||
declare function arrayLengthLt<T>(value: number): IConstraint<T[]>; | ||
declare function arrayLengthLe<T>(value: number): IConstraint<T[]>; | ||
declare function arrayLengthGt<T>(value: number): IConstraint<T[]>; | ||
declare function arrayLengthGe<T>(value: number): IConstraint<T[]>; | ||
declare function arrayLengthEq<T>(value: number): IConstraint<T[]>; | ||
declare function arrayLengthNe<T>(value: number): IConstraint<T[]>; | ||
declare type BigIntConstraintName = `s.bigint.${'lt' | 'le' | 'gt' | 'ge' | 'eq' | 'ne' | 'divisibleBy'}`; | ||
declare function bigintLt(value: bigint): IConstraint<bigint>; | ||
declare function bigintLe(value: bigint): IConstraint<bigint>; | ||
declare function bigintGt(value: bigint): IConstraint<bigint>; | ||
declare function bigintGe(value: bigint): IConstraint<bigint>; | ||
declare function bigintEq(value: bigint): IConstraint<bigint>; | ||
declare function bigintNe(value: bigint): IConstraint<bigint>; | ||
declare function bigintDivisibleBy(divider: bigint): IConstraint<bigint>; | ||
declare type BooleanConstraintName = `s.boolean.${boolean}`; | ||
declare const booleanTrue: IConstraint<boolean, true>; | ||
declare const booleanFalse: IConstraint<boolean, false>; | ||
declare type DateConstraintName = `s.date.${'lt' | 'le' | 'gt' | 'ge' | 'eq' | 'eq(NaN)' | 'ne' | 'ne(NaN)'}`; | ||
declare function dateLt(value: Date): IConstraint<Date>; | ||
declare function dateLe(value: Date): IConstraint<Date>; | ||
declare function dateGt(value: Date): IConstraint<Date>; | ||
declare function dateGe(value: Date): IConstraint<Date>; | ||
declare function dateEq(value: Date): IConstraint<Date>; | ||
declare function dateNe(value: Date): IConstraint<Date>; | ||
declare const dateInvalid: IConstraint<Date>; | ||
declare const dateValid: IConstraint<Date>; | ||
declare type NumberConstraintName = `s.number.${'lt' | 'le' | 'gt' | 'ge' | 'eq' | 'eq(NaN)' | 'ne' | 'ne(NaN)' | 'int' | 'safeInt' | 'finite' | 'divisibleBy'}`; | ||
declare function numberLt(value: number): IConstraint<number>; | ||
declare function numberLe(value: number): IConstraint<number>; | ||
declare function numberGt(value: number): IConstraint<number>; | ||
declare function numberGe(value: number): IConstraint<number>; | ||
declare function numberEq(value: number): IConstraint<number>; | ||
declare function numberNe(value: number): IConstraint<number>; | ||
declare const numberInt: IConstraint<number>; | ||
declare const numberSafeInt: IConstraint<number>; | ||
declare const numberFinite: IConstraint<number>; | ||
declare const numberNaN: IConstraint<number>; | ||
declare const numberNeNaN: IConstraint<number>; | ||
declare function numberDivisibleBy(divider: number): IConstraint<number>; | ||
declare type StringConstraintName = `s.string.${`length${'Lt' | 'Le' | 'Gt' | 'Ge' | 'Eq' | 'Ne'}` | 'regex' | 'url' | 'uuid' | 'email' | `ip${'v4' | 'v6' | ''}`}`; | ||
declare type StringProtocol = `${string}:`; | ||
declare type StringDomain = `${string}.${string}`; | ||
interface UrlOptions { | ||
allowedProtocols?: StringProtocol[]; | ||
allowedDomains?: StringDomain[]; | ||
} | ||
declare type UUIDVersion = 1 | 3 | 4 | 5; | ||
interface StringUuidOptions { | ||
version?: UUIDVersion | `${UUIDVersion}-${UUIDVersion}` | null; | ||
nullable?: boolean; | ||
} | ||
declare function stringLengthLt(length: number): IConstraint<string>; | ||
declare function stringLengthLe(length: number): IConstraint<string>; | ||
declare function stringLengthGt(length: number): IConstraint<string>; | ||
declare function stringLengthGe(length: number): IConstraint<string>; | ||
declare function stringLengthEq(length: number): IConstraint<string>; | ||
declare function stringLengthNe(length: number): IConstraint<string>; | ||
declare const customInspectSymbol: unique symbol; | ||
declare const customInspectSymbolStackLess: unique symbol; | ||
declare abstract class BaseError extends Error { | ||
protected [customInspectSymbol](depth: number, options: InspectOptionsStylized): string; | ||
protected abstract [customInspectSymbolStackLess](depth: number, options: InspectOptionsStylized): string; | ||
} | ||
declare type ConstraintErrorNames = ArrayConstraintName | BigIntConstraintName | BooleanConstraintName | DateConstraintName | NumberConstraintName | StringConstraintName; | ||
declare class ConstraintError<T = unknown> extends BaseError { | ||
readonly constraint: ConstraintErrorNames; | ||
readonly given: T; | ||
readonly expected: unknown; | ||
constructor(validator: string, message: string, given: T, expected: unknown); | ||
readonly expected: string; | ||
constructor(constraint: ConstraintErrorNames, message: string, given: T, expected: string); | ||
toJSON(): { | ||
name: string; | ||
constraint: string; | ||
constraint: ConstraintErrorNames; | ||
given: T; | ||
expected: unknown; | ||
expected: string; | ||
}; | ||
protected [customInspectSymbolStackLess](depth: number, options: InspectOptionsStylized): string; | ||
} | ||
interface ConstraintErrorMessageBuilder<Given = unknown, Expected = unknown> { | ||
(given: Given, expected: Expected): string; | ||
} | ||
@@ -39,3 +112,16 @@ declare class Result<T, E extends Error = Error> { | ||
declare class ValidationError extends Error { | ||
declare class CombinedError extends BaseError { | ||
readonly errors: readonly BaseError[]; | ||
constructor(errors: readonly BaseError[]); | ||
protected [customInspectSymbolStackLess](depth: number, options: InspectOptionsStylized): string; | ||
} | ||
declare class CombinedPropertyError extends BaseError { | ||
readonly errors: [PropertyKey, BaseError][]; | ||
constructor(errors: [PropertyKey, BaseError][]); | ||
protected [customInspectSymbolStackLess](depth: number, options: InspectOptionsStylized): string; | ||
private static formatProperty; | ||
} | ||
declare class ValidationError extends BaseError { | ||
readonly validator: string; | ||
@@ -49,2 +135,3 @@ readonly given: unknown; | ||
}; | ||
protected [customInspectSymbolStackLess](depth: number, options: InspectOptionsStylized): string; | ||
} | ||
@@ -63,7 +150,7 @@ | ||
transform<O>(cb: (value: T) => O): BaseValidator<O>; | ||
default(value: T | (() => T)): DefaultValidator<T>; | ||
run(value: unknown): Result<T, Error>; | ||
default(value: Exclude<T, undefined> | (() => Exclude<T, undefined>)): DefaultValidator<Exclude<T, undefined>>; | ||
run(value: unknown): Result<T, BaseError>; | ||
parse(value: unknown): T; | ||
protected clone(): this; | ||
protected abstract handle(value: unknown): Result<T, ValidationError | AggregateError>; | ||
protected abstract handle(value: unknown): Result<T, ValidationError | CombinedError | CombinedPropertyError>; | ||
protected addConstraint(constraint: IConstraint<T>): this; | ||
@@ -75,5 +162,17 @@ } | ||
constructor(validator: BaseValidator<T>, constraints?: readonly IConstraint<T[]>[]); | ||
lengthLt<N extends number>(length: N): BaseValidator<ExpandSmallerTuples<UnshiftTuple<[...Tuple<T, N>]>>>; | ||
lengthLe<N extends number>(length: N): BaseValidator<ExpandSmallerTuples<[...Tuple<T, N>]>>; | ||
lengthGt<N extends number>(length: N): BaseValidator<[...Tuple<T, N>, T, ...T[]]>; | ||
lengthGe<N extends number>(length: N): BaseValidator<[...Tuple<T, N>, ...T[]]>; | ||
lengthEq<N extends number>(length: N): BaseValidator<[...Tuple<T, N>]>; | ||
lengthNe(length: number): BaseValidator<[...T[]]>; | ||
protected clone(): this; | ||
protected handle(values: unknown): Result<T[], ValidationError | AggregateError>; | ||
protected handle(values: unknown): Result<T[], ValidationError | CombinedPropertyError>; | ||
} | ||
declare type UnshiftTuple<T extends [...any[]]> = T extends [T[0], ...infer Tail] ? Tail : never; | ||
declare type ExpandSmallerTuples<T extends [...any[]]> = T extends [T[0], ...infer Tail] ? T | ExpandSmallerTuples<Tail> : []; | ||
declare type Shift<A extends Array<any>> = ((...args: A) => void) extends (...args: [A[0], ...infer R]) => void ? R : never; | ||
declare type GrowExpRev<A extends Array<any>, N extends number, P extends Array<Array<any>>> = A['length'] extends N ? A : GrowExpRev<[...A, ...P[0]][N] extends undefined ? [...A, ...P[0]] : A, N, Shift<P>>; | ||
declare type GrowExp<A extends Array<any>, N extends number, P extends Array<Array<any>>> = [...A, ...A][N] extends undefined ? GrowExp<[...A, ...A], N, [A, ...P]> : GrowExpRev<A, N, P>; | ||
declare type Tuple<T, N extends number> = number extends N ? Array<T> : N extends 0 ? [] : N extends 1 ? [T] : GrowExp<[T], N, [[]]>; | ||
@@ -89,2 +188,6 @@ declare class BigIntValidator<T extends bigint> extends BaseValidator<T> { | ||
get negative(): this; | ||
divisibleBy(number: bigint): this; | ||
get abs(): this; | ||
intN(bits: number): this; | ||
uintN(bits: number): this; | ||
protected handle(value: unknown): Result<T, ValidationError>; | ||
@@ -120,2 +223,3 @@ } | ||
}; | ||
protected [customInspectSymbolStackLess](depth: number, options: InspectOptionsStylized): string; | ||
} | ||
@@ -195,3 +299,3 @@ | ||
}>; | ||
protected handle(value: unknown): Result<T, ValidationError | AggregateError>; | ||
protected handle(value: unknown): Result<T, ValidationError | CombinedPropertyError>; | ||
protected clone(): this; | ||
@@ -214,3 +318,3 @@ private handleIgnoreStrategy; | ||
protected clone(): this; | ||
protected handle(value: unknown): Result<Record<string, T>, ValidationError | AggregateError>; | ||
protected handle(value: unknown): Result<Record<string, T>, ValidationError | CombinedPropertyError>; | ||
} | ||
@@ -222,15 +326,29 @@ | ||
protected clone(): this; | ||
protected handle(values: unknown): Result<Set<T>, ValidationError | AggregateError>; | ||
protected handle(values: unknown): Result<Set<T>, ValidationError | CombinedError>; | ||
} | ||
declare class StringValidator<T extends string> extends BaseValidator<T> { | ||
lengthLt(length: number): this; | ||
lengthLe(length: number): this; | ||
lengthLte(length: number): this; | ||
lengthGt(length: number): this; | ||
lengthGe(length: number): this; | ||
lengthGte(length: number): this; | ||
lengthEq(length: number): this; | ||
lengthNe(length: number): this; | ||
get email(): this; | ||
url(options?: UrlOptions): this; | ||
uuid(options?: StringUuidOptions): this; | ||
regex(regex: RegExp): this; | ||
get ipv4(): this; | ||
get ipv6(): this; | ||
ip(version?: 4 | 6): this; | ||
protected handle(value: unknown): Result<T, ValidationError>; | ||
} | ||
declare class TupleValidator<T extends any[]> extends BaseValidator<[...T]> { | ||
private readonly validators; | ||
constructor(validators: BaseValidator<[...T]>[], constraints?: readonly IConstraint<[...T]>[]); | ||
protected clone(): this; | ||
protected handle(values: unknown): Result<[...T], ValidationError | CombinedPropertyError>; | ||
} | ||
declare class UnionValidator<T> extends BaseValidator<T> { | ||
@@ -244,3 +362,3 @@ private validators; | ||
protected clone(): this; | ||
protected handle(value: unknown): Result<T, ValidationError | AggregateError>; | ||
protected handle(value: unknown): Result<T, ValidationError | CombinedError>; | ||
} | ||
@@ -253,10 +371,11 @@ | ||
protected clone(): this; | ||
protected handle(value: unknown): Result<Map<K, V>, ValidationError | AggregateError>; | ||
protected handle(value: unknown): Result<Map<K, V>, ValidationError | CombinedPropertyError>; | ||
} | ||
declare class DefaultValidator<T> extends BaseValidator<T | undefined> { | ||
declare class DefaultValidator<T> extends BaseValidator<T> { | ||
private readonly validator; | ||
private readonly defaultValue; | ||
private defaultValue; | ||
constructor(validator: BaseValidator<T>, value: T | (() => T), constraints?: readonly IConstraint<T>[]); | ||
protected handle(value: unknown): Result<T, ValidationError | AggregateError>; | ||
default(value: Exclude<T, undefined> | (() => Exclude<T, undefined>)): DefaultValidator<Exclude<T, undefined>>; | ||
protected handle(value: unknown): Result<T, ValidationError | CombinedError | CombinedPropertyError>; | ||
protected clone(): this; | ||
@@ -281,4 +400,5 @@ } | ||
instance<T>(expected: Constructor<T>): InstanceValidator<T>; | ||
union<T>(...validators: readonly BaseValidator<T>[]): UnionValidator<T>; | ||
union<T extends [...BaseValidator<any>[]]>(...validators: [...T]): UnionValidator<Unwrap<T[number]>>; | ||
array<T>(validator: BaseValidator<T>): ArrayValidator<T>; | ||
tuple<T extends [...BaseValidator<any>[]]>(validators: [...T]): TupleValidator<UnwrapTuple<T>>; | ||
set<T>(validator: BaseValidator<T>): SetValidator<T>; | ||
@@ -288,4 +408,6 @@ record<T>(validator: BaseValidator<T>): RecordValidator<T>; | ||
} | ||
declare type UnwrapTuple<T extends [...any[]]> = T extends [infer Head, ...infer Tail] ? [Unwrap<Head>, ...UnwrapTuple<Tail>] : []; | ||
declare type Unwrap<T> = T extends BaseValidator<infer V> ? V : never; | ||
declare class MissingPropertyError extends Error { | ||
declare class MissingPropertyError extends BaseError { | ||
readonly property: PropertyKey; | ||
@@ -297,5 +419,6 @@ constructor(property: PropertyKey); | ||
}; | ||
protected [customInspectSymbolStackLess](depth: number, options: InspectOptionsStylized): string; | ||
} | ||
declare class UnknownPropertyError extends Error { | ||
declare class UnknownPropertyError extends BaseError { | ||
readonly property: PropertyKey; | ||
@@ -309,51 +432,7 @@ readonly value: unknown; | ||
}; | ||
protected [customInspectSymbolStackLess](depth: number, options: InspectOptionsStylized): string; | ||
} | ||
declare const arrayLengthLt: (length: number) => IConstraint<unknown[], unknown[]>; | ||
declare const arrayLengthLe: (length: number) => IConstraint<unknown[], unknown[]>; | ||
declare const arrayLengthGt: (length: number) => IConstraint<unknown[], unknown[]>; | ||
declare const arrayLengthGe: (length: number) => IConstraint<unknown[], unknown[]>; | ||
declare const arrayLengthEq: (length: number) => IConstraint<unknown[], unknown[]>; | ||
declare const arrayLengthNe: (length: number) => IConstraint<unknown[], unknown[]>; | ||
declare const bigintLt: (number: bigint) => IConstraint<bigint, bigint>; | ||
declare const bigintLe: (number: bigint) => IConstraint<bigint, bigint>; | ||
declare const bigintGt: (number: bigint) => IConstraint<bigint, bigint>; | ||
declare const bigintGe: (number: bigint) => IConstraint<bigint, bigint>; | ||
declare const bigintEq: (number: bigint) => IConstraint<bigint, bigint>; | ||
declare const bigintNe: (number: bigint) => IConstraint<bigint, bigint>; | ||
declare const booleanTrue: IConstraint<boolean, true>; | ||
declare const booleanFalse: IConstraint<boolean, false>; | ||
declare const dateLt: (date: Date, number?: number | undefined) => IConstraint<Date, Date>; | ||
declare const dateLe: (date: Date, number?: number | undefined) => IConstraint<Date, Date>; | ||
declare const dateGt: (date: Date, number?: number | undefined) => IConstraint<Date, Date>; | ||
declare const dateGe: (date: Date, number?: number | undefined) => IConstraint<Date, Date>; | ||
declare const dateEq: (date: Date, number?: number | undefined) => IConstraint<Date, Date>; | ||
declare const dateNe: (date: Date, number?: number | undefined) => IConstraint<Date, Date>; | ||
declare const dateInvalid: IConstraint<Date>; | ||
declare const dateValid: IConstraint<Date>; | ||
declare const numberLt: (number: number) => IConstraint<number, number>; | ||
declare const numberLe: (number: number) => IConstraint<number, number>; | ||
declare const numberGt: (number: number) => IConstraint<number, number>; | ||
declare const numberGe: (number: number) => IConstraint<number, number>; | ||
declare const numberEq: (number: number) => IConstraint<number, number>; | ||
declare const numberNe: (number: number) => IConstraint<number, number>; | ||
declare const numberInt: IConstraint<number>; | ||
declare const numberSafeInt: IConstraint<number>; | ||
declare const numberFinite: IConstraint<number>; | ||
declare const numberNaN: IConstraint<number>; | ||
declare const numberNeNaN: IConstraint<number>; | ||
declare const stringLengthLt: (length: number) => IConstraint<string, string>; | ||
declare const stringLengthLe: (length: number) => IConstraint<string, string>; | ||
declare const stringLengthGt: (length: number) => IConstraint<string, string>; | ||
declare const stringLengthGe: (length: number) => IConstraint<string, string>; | ||
declare const stringLengthEq: (length: number) => IConstraint<string, string>; | ||
declare const stringLengthNe: (length: number) => IConstraint<string, string>; | ||
declare const s: Shapes; | ||
export { ArrayValidator, BaseValidator, BigIntValidator, BooleanValidator, ConstraintError, ConstraintErrorMessageBuilder, Constructor, DateValidator, DefaultValidator, ExpectedValidationError, IConstraint, InstanceValidator, LiteralValidator, MapValidator, MappedObjectValidator, MissingPropertyError, NeverValidator, NonNullObject, NullishValidator, NumberValidator, ObjectValidator, ObjectValidatorStrategy, PassthroughValidator, RecordValidator, Result, SetValidator, Shapes, StringValidator, Type, UnionValidator, UnknownPropertyError, ValidationError, arrayLengthEq, arrayLengthGe, arrayLengthGt, arrayLengthLe, arrayLengthLt, arrayLengthNe, bigintEq, bigintGe, bigintGt, bigintLe, bigintLt, bigintNe, booleanFalse, booleanTrue, dateEq, dateGe, dateGt, dateInvalid, dateLe, dateLt, dateNe, dateValid, numberEq, numberFinite, numberGe, numberGt, numberInt, numberLe, numberLt, numberNaN, numberNe, numberNeNaN, numberSafeInt, s, stringLengthEq, stringLengthGe, stringLengthGt, stringLengthLe, stringLengthLt, stringLengthNe }; | ||
export { ArrayConstraintName, ArrayValidator, BaseError, BaseValidator, BigIntConstraintName, BigIntValidator, BooleanConstraintName, BooleanValidator, CombinedError, CombinedPropertyError, ConstraintError, ConstraintErrorNames, Constructor, DateConstraintName, DateValidator, DefaultValidator, ExpectedValidationError, IConstraint, InstanceValidator, LiteralValidator, MapValidator, MappedObjectValidator, MissingPropertyError, NeverValidator, NonNullObject, NullishValidator, NumberConstraintName, NumberValidator, ObjectValidator, ObjectValidatorStrategy, PassthroughValidator, RecordValidator, Result, SetValidator, Shapes, StringConstraintName, StringValidator, TupleValidator, Type, UnionValidator, UnknownPropertyError, Unwrap, ValidationError, arrayLengthEq, arrayLengthGe, arrayLengthGt, arrayLengthLe, arrayLengthLt, arrayLengthNe, bigintDivisibleBy, bigintEq, bigintGe, bigintGt, bigintLe, bigintLt, bigintNe, booleanFalse, booleanTrue, dateEq, dateGe, dateGt, dateInvalid, dateLe, dateLt, dateNe, dateValid, numberDivisibleBy, numberEq, numberFinite, numberGe, numberGt, numberInt, numberLe, numberLt, numberNaN, numberNe, numberNeNaN, numberSafeInt, s, stringLengthEq, stringLengthGe, stringLengthGt, stringLengthLe, stringLengthLt, stringLengthNe }; |
@@ -8,2 +8,9 @@ var SapphireShapeshift = (() => { | ||
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); | ||
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { | ||
get: (a, b) => (typeof require !== "undefined" ? require : a)[b] | ||
}) : x)(function(x) { | ||
if (typeof require !== "undefined") | ||
return require.apply(this, arguments); | ||
throw new Error('Dynamic require of "' + x + '" is not supported'); | ||
}); | ||
var __export = (target, all) => { | ||
@@ -30,2 +37,4 @@ for (var name in all) | ||
__export(src_exports, { | ||
CombinedError: () => CombinedError, | ||
CombinedPropertyError: () => CombinedPropertyError, | ||
ConstraintError: () => ConstraintError, | ||
@@ -125,51 +134,21 @@ ExpectedValidationError: () => ExpectedValidationError, | ||
// src/lib/errors/ValidationError.ts | ||
var ValidationError = class extends Error { | ||
constructor(validator, message, given) { | ||
super(message); | ||
this.validator = validator; | ||
this.given = given; | ||
} | ||
toJSON() { | ||
return { | ||
name: this.name, | ||
validator: this.validator, | ||
given: this.given | ||
}; | ||
} | ||
}; | ||
__name(ValidationError, "ValidationError"); | ||
// src/lib/errors/ConstraintError.ts | ||
var import_node_util = __require("util"); | ||
// src/validators/ArrayValidator.ts | ||
var ArrayValidator = class extends BaseValidator { | ||
constructor(validator, constraints = []) { | ||
super(constraints); | ||
this.validator = validator; | ||
// src/lib/errors/BaseError.ts | ||
var customInspectSymbol = Symbol.for("nodejs.util.inspect.custom"); | ||
var customInspectSymbolStackLess = Symbol.for("nodejs.util.inspect.custom.stack-less"); | ||
var BaseError = class extends Error { | ||
[customInspectSymbol](depth, options) { | ||
return `${this[customInspectSymbolStackLess](depth, options)} | ||
${this.stack.slice(this.stack.indexOf("\n"))}`; | ||
} | ||
clone() { | ||
return Reflect.construct(this.constructor, [this.validator, this.constraints]); | ||
} | ||
handle(values) { | ||
if (!Array.isArray(values)) { | ||
return Result.err(new ValidationError("ArrayValidator", "Expected an array", values)); | ||
} | ||
const errors = []; | ||
const transformed = []; | ||
for (const value of values) { | ||
const result = this.validator.run(value); | ||
if (result.isOk()) | ||
transformed.push(result.value); | ||
else | ||
errors.push(result.error); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new AggregateError(errors, "Failed to validate at least one entry")); | ||
} | ||
}; | ||
__name(ArrayValidator, "ArrayValidator"); | ||
__name(BaseError, "BaseError"); | ||
// src/lib/errors/ConstraintError.ts | ||
var ConstraintError = class extends Error { | ||
constructor(validator, message, given, expected) { | ||
var ConstraintError = class extends BaseError { | ||
constructor(constraint, message, given, expected) { | ||
super(message); | ||
this.constraint = validator; | ||
this.constraint = constraint; | ||
this.given = given; | ||
@@ -186,2 +165,22 @@ this.expected = expected; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const constraint = options.stylize(this.constraint, "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[ConstraintError: ${constraint}]`, "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1 }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const given = (0, import_node_util.inspect)(this.given, newOptions).replaceAll("\n", padding); | ||
const header = `${options.stylize("ConstraintError", "special")} > ${constraint}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const expectedBlock = ` | ||
${options.stylize("Expected: ", "string")}${options.stylize(this.expected, "boolean")}`; | ||
const givenBlock = ` | ||
${options.stylize("Received:", "regexp")}${padding}${given}`; | ||
return `${header} | ||
${message} | ||
${expectedBlock} | ||
${givenBlock}`; | ||
} | ||
}; | ||
@@ -216,7 +215,162 @@ __name(ConstraintError, "ConstraintError"); | ||
// src/constraints/ArrayLengthConstraints.ts | ||
function arrayLengthComparator(comparator, name, expected, length) { | ||
return { | ||
run(input) { | ||
return comparator(input.length, length) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid Array length", input, expected)); | ||
} | ||
}; | ||
} | ||
__name(arrayLengthComparator, "arrayLengthComparator"); | ||
function arrayLengthLt(value) { | ||
const expected = `expected.length < ${value}`; | ||
return arrayLengthComparator(lt, "s.array(T).lengthLt", expected, value); | ||
} | ||
__name(arrayLengthLt, "arrayLengthLt"); | ||
function arrayLengthLe(value) { | ||
const expected = `expected.length <= ${value}`; | ||
return arrayLengthComparator(le, "s.array(T).lengthLe", expected, value); | ||
} | ||
__name(arrayLengthLe, "arrayLengthLe"); | ||
function arrayLengthGt(value) { | ||
const expected = `expected.length > ${value}`; | ||
return arrayLengthComparator(gt, "s.array(T).lengthGt", expected, value); | ||
} | ||
__name(arrayLengthGt, "arrayLengthGt"); | ||
function arrayLengthGe(value) { | ||
const expected = `expected.length >= ${value}`; | ||
return arrayLengthComparator(ge, "s.array(T).lengthGe", expected, value); | ||
} | ||
__name(arrayLengthGe, "arrayLengthGe"); | ||
function arrayLengthEq(value) { | ||
const expected = `expected.length === ${value}`; | ||
return arrayLengthComparator(eq, "s.array(T).lengthEq", expected, value); | ||
} | ||
__name(arrayLengthEq, "arrayLengthEq"); | ||
function arrayLengthNe(value) { | ||
const expected = `expected.length !== ${value}`; | ||
return arrayLengthComparator(ne, "s.array(T).lengthNe", expected, value); | ||
} | ||
__name(arrayLengthNe, "arrayLengthNe"); | ||
// src/lib/errors/CombinedPropertyError.ts | ||
var CombinedPropertyError = class extends BaseError { | ||
constructor(errors) { | ||
super("Received one or more errors"); | ||
this.errors = errors; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
if (depth < 0) { | ||
return options.stylize("[CombinedPropertyError]", "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1, compact: true }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const header = `${options.stylize("CombinedPropertyError", "special")} (${options.stylize(this.errors.length.toString(), "number")})`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const errors = this.errors.map(([key, error]) => { | ||
const property = CombinedPropertyError.formatProperty(key, options); | ||
const body = error[customInspectSymbolStackLess](depth - 1, newOptions).replaceAll("\n", padding); | ||
return ` input${property}${padding}${body}`; | ||
}).join("\n\n"); | ||
return `${header} | ||
${message} | ||
${errors}`; | ||
} | ||
static formatProperty(key, options) { | ||
if (typeof key === "string") | ||
return options.stylize(`.${key}`, "symbol"); | ||
if (typeof key === "number") | ||
return `[${options.stylize(key.toString(), "number")}]`; | ||
return `[${options.stylize("Symbol", "symbol")}(${key.description})]`; | ||
} | ||
}; | ||
__name(CombinedPropertyError, "CombinedPropertyError"); | ||
// src/lib/errors/ValidationError.ts | ||
var import_node_util2 = __require("util"); | ||
var ValidationError = class extends BaseError { | ||
constructor(validator, message, given) { | ||
super(message); | ||
this.validator = validator; | ||
this.given = given; | ||
} | ||
toJSON() { | ||
return { | ||
name: this.name, | ||
validator: this.validator, | ||
given: this.given | ||
}; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const validator = options.stylize(this.validator, "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[ValidationError: ${validator}]`, "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1, compact: true }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const given = (0, import_node_util2.inspect)(this.given, newOptions).replaceAll("\n", padding); | ||
const header = `${options.stylize("ValidationError", "special")} > ${validator}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const givenBlock = ` | ||
${options.stylize("Received:", "regexp")}${padding}${given}`; | ||
return `${header} | ||
${message} | ||
${givenBlock}`; | ||
} | ||
}; | ||
__name(ValidationError, "ValidationError"); | ||
// src/validators/ArrayValidator.ts | ||
var ArrayValidator = class extends BaseValidator { | ||
constructor(validator, constraints = []) { | ||
super(constraints); | ||
this.validator = validator; | ||
} | ||
lengthLt(length) { | ||
return this.addConstraint(arrayLengthLt(length)); | ||
} | ||
lengthLe(length) { | ||
return this.addConstraint(arrayLengthLe(length)); | ||
} | ||
lengthGt(length) { | ||
return this.addConstraint(arrayLengthGt(length)); | ||
} | ||
lengthGe(length) { | ||
return this.addConstraint(arrayLengthGe(length)); | ||
} | ||
lengthEq(length) { | ||
return this.addConstraint(arrayLengthEq(length)); | ||
} | ||
lengthNe(length) { | ||
return this.addConstraint(arrayLengthNe(length)); | ||
} | ||
clone() { | ||
return Reflect.construct(this.constructor, [this.validator, this.constraints]); | ||
} | ||
handle(values) { | ||
if (!Array.isArray(values)) { | ||
return Result.err(new ValidationError("s.array(T)", "Expected an array", values)); | ||
} | ||
const errors = []; | ||
const transformed = []; | ||
for (let i = 0; i < values.length; i++) { | ||
const result = this.validator.run(values[i]); | ||
if (result.isOk()) | ||
transformed.push(result.value); | ||
else | ||
errors.push([i, result.error]); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
}; | ||
__name(ArrayValidator, "ArrayValidator"); | ||
// src/constraints/BigIntConstraints.ts | ||
function bigintComparator(comparator, name, messageBuilder, number) { | ||
function bigintComparator(comparator, name, expected, number) { | ||
return { | ||
run(input) { | ||
return comparator(input, number) ? Result.ok(input) : Result.err(new ConstraintError(name, messageBuilder(input, number), input, number)); | ||
return comparator(input, number) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid bigint value", input, expected)); | ||
} | ||
@@ -226,8 +380,41 @@ }; | ||
__name(bigintComparator, "bigintComparator"); | ||
var bigintLt = bigintComparator.bind(null, lt, "bigintLt", (given, expected) => `Expected bigint to be less than ${expected}, but received ${given}`); | ||
var bigintLe = bigintComparator.bind(null, le, "bigintLe", (given, expected) => `Expected bigint to be less or equals than ${expected}, but received ${given}`); | ||
var bigintGt = bigintComparator.bind(null, gt, "bigintGt", (given, expected) => `Expected bigint to be greater than ${expected}, but received ${given}`); | ||
var bigintGe = bigintComparator.bind(null, ge, "bigintGe", (given, expected) => `Expected bigint to be greater or equals than ${expected}, but received ${given}`); | ||
var bigintEq = bigintComparator.bind(null, eq, "bigintEq", (given, expected) => `Expected bigint to be exactly ${expected}, but received ${given}`); | ||
var bigintNe = bigintComparator.bind(null, ne, "bigintNe", (_, expected) => `Expected bigint to not be ${expected}`); | ||
function bigintLt(value) { | ||
const expected = `expected < ${value}n`; | ||
return bigintComparator(lt, "s.bigint.lt", expected, value); | ||
} | ||
__name(bigintLt, "bigintLt"); | ||
function bigintLe(value) { | ||
const expected = `expected <= ${value}n`; | ||
return bigintComparator(le, "s.bigint.le", expected, value); | ||
} | ||
__name(bigintLe, "bigintLe"); | ||
function bigintGt(value) { | ||
const expected = `expected > ${value}n`; | ||
return bigintComparator(gt, "s.bigint.gt", expected, value); | ||
} | ||
__name(bigintGt, "bigintGt"); | ||
function bigintGe(value) { | ||
const expected = `expected >= ${value}n`; | ||
return bigintComparator(ge, "s.bigint.ge", expected, value); | ||
} | ||
__name(bigintGe, "bigintGe"); | ||
function bigintEq(value) { | ||
const expected = `expected === ${value}n`; | ||
return bigintComparator(eq, "s.bigint.eq", expected, value); | ||
} | ||
__name(bigintEq, "bigintEq"); | ||
function bigintNe(value) { | ||
const expected = `expected !== ${value}n`; | ||
return bigintComparator(ne, "s.bigint.ne", expected, value); | ||
} | ||
__name(bigintNe, "bigintNe"); | ||
function bigintDivisibleBy(divider) { | ||
const expected = `expected % ${divider}n === 0n`; | ||
return { | ||
run(input) { | ||
return input % divider === 0n ? Result.ok(input) : Result.err(new ConstraintError("s.bigint.divisibleBy", "BigInt is not divisible", input, expected)); | ||
} | ||
}; | ||
} | ||
__name(bigintDivisibleBy, "bigintDivisibleBy"); | ||
@@ -260,4 +447,16 @@ // src/validators/BigIntValidator.ts | ||
} | ||
divisibleBy(number) { | ||
return this.addConstraint(bigintDivisibleBy(number)); | ||
} | ||
get abs() { | ||
return this.transform((value) => value < 0 ? -value : value); | ||
} | ||
intN(bits) { | ||
return this.transform((value) => BigInt.asIntN(bits, value)); | ||
} | ||
uintN(bits) { | ||
return this.transform((value) => BigInt.asUintN(bits, value)); | ||
} | ||
handle(value) { | ||
return typeof value === "bigint" ? Result.ok(value) : Result.err(new ValidationError("BigIntValidator", "Expected a bigint primitive", value)); | ||
return typeof value === "bigint" ? Result.ok(value) : Result.err(new ValidationError("s.bigint", "Expected a bigint primitive", value)); | ||
} | ||
@@ -270,3 +469,3 @@ }; | ||
run(input) { | ||
return input ? Result.ok(input) : Result.err(new ConstraintError("booleanTrue", "Expected boolean to be true, but received false", input, true)); | ||
return input ? Result.ok(input) : Result.err(new ConstraintError("s.boolean.true", "Invalid boolean value", input, "true")); | ||
} | ||
@@ -276,3 +475,3 @@ }; | ||
run(input) { | ||
return input ? Result.err(new ConstraintError("booleanFalse", "Expected boolean to be false, but received true", input, false)) : Result.ok(input); | ||
return input ? Result.err(new ConstraintError("s.boolean.false", "Invalid boolean value", input, "false")) : Result.ok(input); | ||
} | ||
@@ -296,3 +495,3 @@ }; | ||
handle(value) { | ||
return typeof value === "boolean" ? Result.ok(value) : Result.err(new ValidationError("BooleanValidator", "Expected a boolean primitive", value)); | ||
return typeof value === "boolean" ? Result.ok(value) : Result.err(new ValidationError("s.boolean", "Expected a boolean primitive", value)); | ||
} | ||
@@ -303,6 +502,6 @@ }; | ||
// src/constraints/DateConstraints.ts | ||
function dateComparator(comparator, name, messageBuilder, date, number = date.getTime()) { | ||
function dateComparator(comparator, name, expected, number) { | ||
return { | ||
run(input) { | ||
return comparator(input.getTime(), number) ? Result.ok(input) : Result.err(new ConstraintError(name, messageBuilder(input, date), input, date)); | ||
return comparator(input.getTime(), number) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid Date value", input, expected)); | ||
} | ||
@@ -312,11 +511,35 @@ }; | ||
__name(dateComparator, "dateComparator"); | ||
var dateLt = dateComparator.bind(null, lt, "dateLt", (given, expected) => `Expected date to be earlier than ${expected}, but received ${given}`); | ||
var dateLe = dateComparator.bind(null, le, "dateLe", (given, expected) => `Expected date to be earlier or equals than ${expected}, but received ${given}`); | ||
var dateGt = dateComparator.bind(null, gt, "dateGt", (given, expected) => `Expected date to be later than ${expected}, but received ${given}`); | ||
var dateGe = dateComparator.bind(null, ge, "dateGe", (given, expected) => `Expected date to be later or equals than ${expected}, but received ${given}`); | ||
var dateEq = dateComparator.bind(null, eq, "dateEq", (given, expected) => `Expected date to be exactly ${expected}, but received ${given}`); | ||
var dateNe = dateComparator.bind(null, ne, "dateNe", (_, expected) => `Expected date to not be ${expected}`); | ||
function dateLt(value) { | ||
const expected = `expected < ${value.toISOString()}`; | ||
return dateComparator(lt, "s.date.lt", expected, value.getTime()); | ||
} | ||
__name(dateLt, "dateLt"); | ||
function dateLe(value) { | ||
const expected = `expected <= ${value.toISOString()}`; | ||
return dateComparator(le, "s.date.le", expected, value.getTime()); | ||
} | ||
__name(dateLe, "dateLe"); | ||
function dateGt(value) { | ||
const expected = `expected > ${value.toISOString()}`; | ||
return dateComparator(gt, "s.date.gt", expected, value.getTime()); | ||
} | ||
__name(dateGt, "dateGt"); | ||
function dateGe(value) { | ||
const expected = `expected >= ${value.toISOString()}`; | ||
return dateComparator(ge, "s.date.ge", expected, value.getTime()); | ||
} | ||
__name(dateGe, "dateGe"); | ||
function dateEq(value) { | ||
const expected = `expected === ${value.toISOString()}`; | ||
return dateComparator(eq, "s.date.eq", expected, value.getTime()); | ||
} | ||
__name(dateEq, "dateEq"); | ||
function dateNe(value) { | ||
const expected = `expected !== ${value.toISOString()}`; | ||
return dateComparator(ne, "s.date.ne", expected, value.getTime()); | ||
} | ||
__name(dateNe, "dateNe"); | ||
var dateInvalid = { | ||
run(input) { | ||
return Number.isNaN(input.getTime()) ? Result.ok(input) : Result.err(new ConstraintError("dateInvalid", `Expected Date's time to be a NaN, but received ${input}`, input, "An invalid Date")); | ||
return Number.isNaN(input.getTime()) ? Result.ok(input) : Result.err(new ConstraintError("s.date.eq(NaN)", "Invalid Date value", input, "expected === NaN")); | ||
} | ||
@@ -326,3 +549,3 @@ }; | ||
run(input) { | ||
return Number.isNaN(input.getTime()) ? Result.err(new ConstraintError("dateValid", `Expected Date's time to not be a NaN, but received ${input}`, input, "A valid Date")) : Result.ok(input); | ||
return Number.isNaN(input.getTime()) ? Result.err(new ConstraintError("s.date.ne(NaN)", "Invalid Date value", input, "expected !== NaN")) : Result.ok(input); | ||
} | ||
@@ -354,3 +577,3 @@ }; | ||
handle(value) { | ||
return value instanceof Date ? Result.ok(value) : Result.err(new ValidationError("DateValidator", "Expected a Date", value)); | ||
return value instanceof Date ? Result.ok(value) : Result.err(new ValidationError("s.date", "Expected a Date", value)); | ||
} | ||
@@ -361,2 +584,3 @@ }; | ||
// src/lib/errors/ExpectedValidationError.ts | ||
var import_node_util3 = __require("util"); | ||
var ExpectedValidationError = class extends ValidationError { | ||
@@ -375,2 +599,23 @@ constructor(validator, message, given, expected) { | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const validator = options.stylize(this.validator, "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[ExpectedValidationError: ${validator}]`, "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1 }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const expected = (0, import_node_util3.inspect)(this.expected, newOptions).replaceAll("\n", padding); | ||
const given = (0, import_node_util3.inspect)(this.given, newOptions).replaceAll("\n", padding); | ||
const header = `${options.stylize("ExpectedValidationError", "special")} > ${validator}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const expectedBlock = ` | ||
${options.stylize("Expected:", "string")}${padding}${expected}`; | ||
const givenBlock = ` | ||
${options.stylize("Received:", "regexp")}${padding}${given}`; | ||
return `${header} | ||
${message} | ||
${expectedBlock} | ||
${givenBlock}`; | ||
} | ||
}; | ||
@@ -386,3 +631,3 @@ __name(ExpectedValidationError, "ExpectedValidationError"); | ||
handle(value) { | ||
return value instanceof this.expected ? Result.ok(value) : Result.err(new ExpectedValidationError("InstanceValidator", "Expected", value, this.expected)); | ||
return value instanceof this.expected ? Result.ok(value) : Result.err(new ExpectedValidationError("s.instance(V)", "Expected", value, this.expected)); | ||
} | ||
@@ -402,3 +647,3 @@ clone() { | ||
handle(value) { | ||
return Object.is(value, this.expected) ? Result.ok(value) : Result.err(new ExpectedValidationError("LiteralValidator", "Expected", value, this.expected)); | ||
return Object.is(value, this.expected) ? Result.ok(value) : Result.err(new ExpectedValidationError("s.literal(V)", "Expected values to be equals", value, this.expected)); | ||
} | ||
@@ -414,3 +659,3 @@ clone() { | ||
handle(value) { | ||
return Result.err(new ValidationError("NeverValidator", "Expected a value to not be passed", value)); | ||
return Result.err(new ValidationError("s.never", "Expected a value to not be passed", value)); | ||
} | ||
@@ -423,3 +668,3 @@ }; | ||
handle(value) { | ||
return value === void 0 || value === null ? Result.ok(value) : Result.err(new ValidationError("NullishValidator", "Expected undefined or null", value)); | ||
return value === void 0 || value === null ? Result.ok(value) : Result.err(new ValidationError("s.nullish", "Expected undefined or null", value)); | ||
} | ||
@@ -430,6 +675,6 @@ }; | ||
// src/constraints/NumberConstraints.ts | ||
function numberComparator(comparator, name, messageBuilder, number) { | ||
function numberComparator(comparator, name, expected, number) { | ||
return { | ||
run(input) { | ||
return comparator(input, number) ? Result.ok(input) : Result.err(new ConstraintError(name, messageBuilder(input, number), input, number)); | ||
return comparator(input, number) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid number value", input, expected)); | ||
} | ||
@@ -439,11 +684,35 @@ }; | ||
__name(numberComparator, "numberComparator"); | ||
var numberLt = numberComparator.bind(null, lt, "numberLt", (given, expected) => `Expected number to be less than ${expected}, but received ${given}`); | ||
var numberLe = numberComparator.bind(null, le, "numberLe", (given, expected) => `Expected number to be less or equals than ${expected}, but received ${given}`); | ||
var numberGt = numberComparator.bind(null, gt, "numberGt", (given, expected) => `Expected number to be greater than ${expected}, but received ${given}`); | ||
var numberGe = numberComparator.bind(null, ge, "numberGe", (given, expected) => `Expected number to be greater or equals than ${expected}, but received ${given}`); | ||
var numberEq = numberComparator.bind(null, eq, "numberEq", (given, expected) => `Expected number to be exactly ${expected}, but received ${given}`); | ||
var numberNe = numberComparator.bind(null, ne, "numberNe", (_, expected) => `Expected number to not be ${expected}`); | ||
function numberLt(value) { | ||
const expected = `expected < ${value}`; | ||
return numberComparator(lt, "s.number.lt", expected, value); | ||
} | ||
__name(numberLt, "numberLt"); | ||
function numberLe(value) { | ||
const expected = `expected <= ${value}`; | ||
return numberComparator(le, "s.number.le", expected, value); | ||
} | ||
__name(numberLe, "numberLe"); | ||
function numberGt(value) { | ||
const expected = `expected > ${value}`; | ||
return numberComparator(gt, "s.number.gt", expected, value); | ||
} | ||
__name(numberGt, "numberGt"); | ||
function numberGe(value) { | ||
const expected = `expected >= ${value}`; | ||
return numberComparator(ge, "s.number.ge", expected, value); | ||
} | ||
__name(numberGe, "numberGe"); | ||
function numberEq(value) { | ||
const expected = `expected === ${value}`; | ||
return numberComparator(eq, "s.number.eq", expected, value); | ||
} | ||
__name(numberEq, "numberEq"); | ||
function numberNe(value) { | ||
const expected = `expected !== ${value}`; | ||
return numberComparator(ne, "s.number.ne", expected, value); | ||
} | ||
__name(numberNe, "numberNe"); | ||
var numberInt = { | ||
run(input) { | ||
return Number.isInteger(input) ? Result.ok(input) : Result.err(new ConstraintError("numberInt", `Expected number to be an integer, but received ${input}`, input, "An integer")); | ||
return Number.isInteger(input) ? Result.ok(input) : Result.err(new ConstraintError("s.number.int", "Given value is not an integer", input, "Number.isInteger(expected) to be true")); | ||
} | ||
@@ -453,3 +722,3 @@ }; | ||
run(input) { | ||
return Number.isSafeInteger(input) ? Result.ok(input) : Result.err(new ConstraintError("numberSafeInt", `Expected number to be a safe integer, but received ${input}`, input, "A safe integer")); | ||
return Number.isSafeInteger(input) ? Result.ok(input) : Result.err(new ConstraintError("s.number.safeInt", "Given value is not a safe integer", input, "Number.isSafeInteger(expected) to be true")); | ||
} | ||
@@ -459,3 +728,3 @@ }; | ||
run(input) { | ||
return Number.isFinite(input) ? Result.ok(input) : Result.err(new ConstraintError("numberFinite", `Expected number to be a finite number, but received ${input}`, input, "A finite number")); | ||
return Number.isFinite(input) ? Result.ok(input) : Result.err(new ConstraintError("s.number.finite", "Given value is not finite", input, "Number.isFinite(expected) to be true")); | ||
} | ||
@@ -465,3 +734,3 @@ }; | ||
run(input) { | ||
return Number.isNaN(input) ? Result.ok(input) : Result.err(new ConstraintError("numberNaN", `Expected number to be a NaN, but received ${input}`, input, "A NaN")); | ||
return Number.isNaN(input) ? Result.ok(input) : Result.err(new ConstraintError("s.number.eq(NaN)", "Invalid number value", input, "expected === NaN")); | ||
} | ||
@@ -471,10 +740,10 @@ }; | ||
run(input) { | ||
return Number.isNaN(input) ? Result.err(new ConstraintError("numberNeNaN", `Expected number to not be a NaN, but received ${input}`, input, "Not NaN")) : Result.ok(input); | ||
return Number.isNaN(input) ? Result.err(new ConstraintError("s.number.ne(NaN)", "Invalid number value", input, "expected !== NaN")) : Result.ok(input); | ||
} | ||
}; | ||
function numberDivisibleBy(divider) { | ||
const expected = `% ${divider}`; | ||
const expected = `expected % ${divider} === 0`; | ||
return { | ||
run(input) { | ||
return input % divider === 0 ? Result.ok(input) : Result.err(new ConstraintError("numberDivisibleBy", `Expected number to be divisible by ${divider}, but received ${input}`, input, expected)); | ||
return input % divider === 0 ? Result.ok(input) : Result.err(new ConstraintError("s.number.divisibleBy", "Number is not divisible", input, expected)); | ||
} | ||
@@ -545,3 +814,3 @@ }; | ||
handle(value) { | ||
return typeof value === "number" ? Result.ok(value) : Result.err(new ValidationError("NumberValidator", "Expected a number primitive", value)); | ||
return typeof value === "number" ? Result.ok(value) : Result.err(new ValidationError("s.number", "Expected a number primitive", value)); | ||
} | ||
@@ -552,5 +821,5 @@ }; | ||
// src/lib/errors/MissingPropertyError.ts | ||
var MissingPropertyError = class extends Error { | ||
var MissingPropertyError = class extends BaseError { | ||
constructor(property) { | ||
super(`Expected property "${String(property)}" is missing`); | ||
super("A required property is missing"); | ||
this.property = property; | ||
@@ -564,2 +833,12 @@ } | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const property = options.stylize(this.property.toString(), "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[MissingPropertyError: ${property}]`, "special"); | ||
} | ||
const header = `${options.stylize("MissingPropertyError", "special")} > ${property}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
return `${header} | ||
${message}`; | ||
} | ||
}; | ||
@@ -569,5 +848,6 @@ __name(MissingPropertyError, "MissingPropertyError"); | ||
// src/lib/errors/UnknownPropertyError.ts | ||
var UnknownPropertyError = class extends Error { | ||
var import_node_util4 = __require("util"); | ||
var UnknownPropertyError = class extends BaseError { | ||
constructor(property, value) { | ||
super("Unknown property received"); | ||
super("Received unexpected property"); | ||
this.property = property; | ||
@@ -583,2 +863,19 @@ this.value = value; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const property = options.stylize(this.property.toString(), "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[UnknownPropertyError: ${property}]`, "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1, compact: true }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const given = (0, import_node_util4.inspect)(this.value, newOptions).replaceAll("\n", padding); | ||
const header = `${options.stylize("UnknownPropertyError", "special")} > ${property}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const givenBlock = ` | ||
${options.stylize("Received:", "regexp")}${padding}${given}`; | ||
return `${header} | ||
${message} | ||
${givenBlock}`; | ||
} | ||
}; | ||
@@ -629,6 +926,6 @@ __name(UnknownPropertyError, "UnknownPropertyError"); | ||
if (typeOfValue !== "object") { | ||
return Result.err(new ValidationError("ObjectValidator", `Expected the value to be an object, but received ${typeOfValue} instead`, value)); | ||
return Result.err(new ValidationError("s.object(T)", `Expected the value to be an object, but received ${typeOfValue} instead`, value)); | ||
} | ||
if (value === null) { | ||
return Result.err(new ValidationError("ObjectValidator", "Expected the value to not be null", value)); | ||
return Result.err(new ValidationError("s.object(T)", "Expected the value to not be null", value)); | ||
} | ||
@@ -651,9 +948,9 @@ return this.handleStrategy(value); | ||
if (error instanceof ValidationError && error.given === void 0) { | ||
errors.push(new MissingPropertyError(key)); | ||
errors.push([key, new MissingPropertyError(key)]); | ||
} else { | ||
errors.push(error); | ||
errors.push([key, error]); | ||
} | ||
} | ||
} | ||
return errors.length === 0 ? Result.ok(entries) : Result.err(new AggregateError(errors, "Failed to match at least one of the properties")); | ||
return errors.length === 0 ? Result.ok(entries) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
@@ -674,5 +971,5 @@ handleStrictStrategy(value) { | ||
if (error instanceof ValidationError && error.given === void 0) { | ||
errors.push(new MissingPropertyError(key)); | ||
errors.push([key, new MissingPropertyError(key)]); | ||
} else { | ||
errors.push(error); | ||
errors.push([key, error]); | ||
} | ||
@@ -682,5 +979,5 @@ } | ||
} | ||
errors.push(new UnknownPropertyError(key, value[key])); | ||
errors.push([key, new UnknownPropertyError(key, value[key])]); | ||
} | ||
return errors.length === 0 ? Result.ok(finalResult) : Result.err(new AggregateError(errors, "Failed to match at least one of the properties")); | ||
return errors.length === 0 ? Result.ok(finalResult) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
@@ -714,6 +1011,6 @@ }; | ||
if (typeof value !== "object") { | ||
return Result.err(new ValidationError("RecordValidator", "Expected an object", value)); | ||
return Result.err(new ValidationError("s.record(T)", "Expected an object", value)); | ||
} | ||
if (value === null) { | ||
return Result.err(new ValidationError("RecordValidator", "Expected the value to not be null", value)); | ||
return Result.err(new ValidationError("s.record(T)", "Expected the value to not be null", value)); | ||
} | ||
@@ -727,5 +1024,5 @@ const errors = []; | ||
else | ||
errors.push(result.error); | ||
errors.push([key, result.error]); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new AggregateError(errors, "Failed to validate at least one entry")); | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
@@ -735,2 +1032,30 @@ }; | ||
// src/lib/errors/CombinedError.ts | ||
var CombinedError = class extends BaseError { | ||
constructor(errors) { | ||
super("Received one or more errors"); | ||
this.errors = errors; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
if (depth < 0) { | ||
return options.stylize("[CombinedError]", "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1, compact: true }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const header = `${options.stylize("CombinedError", "special")} (${options.stylize(this.errors.length.toString(), "number")})`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const errors = this.errors.map((error, i) => { | ||
const index = options.stylize((i + 1).toString(), "number"); | ||
const body = error[customInspectSymbolStackLess](depth - 1, newOptions).replaceAll("\n", padding); | ||
return ` ${index} ${body}`; | ||
}).join("\n\n"); | ||
return `${header} | ||
${message} | ||
${errors}`; | ||
} | ||
}; | ||
__name(CombinedError, "CombinedError"); | ||
// src/validators/SetValidator.ts | ||
@@ -747,3 +1072,3 @@ var SetValidator = class extends BaseValidator { | ||
if (!(values instanceof Set)) { | ||
return Result.err(new ValidationError("SetValidator", "Expected a set", values)); | ||
return Result.err(new ValidationError("s.set(T)", "Expected a set", values)); | ||
} | ||
@@ -759,3 +1084,3 @@ const errors = []; | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new AggregateError(errors, "Failed to validate at least one entry")); | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedError(errors)); | ||
} | ||
@@ -766,29 +1091,142 @@ }; | ||
// src/constraints/StringConstraints.ts | ||
function stringLength(comparator, name, messageBuilder, length) { | ||
var import_node_net = __require("net"); | ||
// src/constraints/util/emailValidator.ts | ||
var accountRegex = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")$/; | ||
function validateEmail(email) { | ||
if (!email) | ||
return false; | ||
const emailParts = email.split("@"); | ||
if (emailParts.length !== 2) | ||
return false; | ||
const account = emailParts[0]; | ||
if (account.length > 64) | ||
return false; | ||
const domain = emailParts[1]; | ||
if (domain.length > 255) | ||
return false; | ||
const domainParts = domain.split("."); | ||
if (domainParts.length < 2) | ||
return false; | ||
if (domainParts.some((part) => part.length > 63)) | ||
return false; | ||
return accountRegex.test(account) && validateEmailDomain(domain); | ||
} | ||
__name(validateEmail, "validateEmail"); | ||
function validateEmailDomain(domain) { | ||
try { | ||
return new URL(`http://${domain}`).hostname === domain; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
__name(validateEmailDomain, "validateEmailDomain"); | ||
// src/constraints/StringConstraints.ts | ||
function stringLengthComparator(comparator, name, expected, length) { | ||
return { | ||
run(input) { | ||
return comparator(input.length, length) ? Result.ok(input) : Result.err(new ConstraintError(name, messageBuilder(input, length), input, length)); | ||
return comparator(input.length, length) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid string length", input, expected)); | ||
} | ||
}; | ||
} | ||
__name(stringLength, "stringLength"); | ||
var stringLengthLt = stringLength.bind(null, lt, "stringLengthLt", (given, expected) => `Expected string to have less than ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthLe = stringLength.bind(null, le, "stringLengthLe", (given, expected) => `Expected string to have maximum ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthGt = stringLength.bind(null, gt, "stringLengthGt", (given, expected) => `Expected string to have more than ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthGe = stringLength.bind(null, ge, "stringLengthGe", (given, expected) => `Expected string to have at least ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthEq = stringLength.bind(null, eq, "stringLengthEq", (given, expected) => `Expected string to have exactly ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthNe = stringLength.bind(null, ne, "stringLengthNe", (given, expected) => `Expected string to not have exactly ${expected} characters, but received one with ${given.length} characters`); | ||
__name(stringLengthComparator, "stringLengthComparator"); | ||
function stringLengthLt(length) { | ||
const expected = `expected.length < ${length}`; | ||
return stringLengthComparator(lt, "s.string.lengthLt", expected, length); | ||
} | ||
__name(stringLengthLt, "stringLengthLt"); | ||
function stringLengthLe(length) { | ||
const expected = `expected.length <= ${length}`; | ||
return stringLengthComparator(le, "s.string.lengthLe", expected, length); | ||
} | ||
__name(stringLengthLe, "stringLengthLe"); | ||
function stringLengthGt(length) { | ||
const expected = `expected.length > ${length}`; | ||
return stringLengthComparator(gt, "s.string.lengthGt", expected, length); | ||
} | ||
__name(stringLengthGt, "stringLengthGt"); | ||
function stringLengthGe(length) { | ||
const expected = `expected.length >= ${length}`; | ||
return stringLengthComparator(ge, "s.string.lengthGe", expected, length); | ||
} | ||
__name(stringLengthGe, "stringLengthGe"); | ||
function stringLengthEq(length) { | ||
const expected = `expected.length === ${length}`; | ||
return stringLengthComparator(eq, "s.string.lengthEq", expected, length); | ||
} | ||
__name(stringLengthEq, "stringLengthEq"); | ||
function stringLengthNe(length) { | ||
const expected = `expected.length !== ${length}`; | ||
return stringLengthComparator(ne, "s.string.lengthNe", expected, length); | ||
} | ||
__name(stringLengthNe, "stringLengthNe"); | ||
function stringEmail() { | ||
return { | ||
run(input) { | ||
return validateEmail(input) ? Result.ok(input) : Result.err(new ConstraintError("s.string.email", "Invalid email address", input, "expected to be an email address")); | ||
} | ||
}; | ||
} | ||
__name(stringEmail, "stringEmail"); | ||
function stringRegexValidator(type, expected, regex) { | ||
return { | ||
run(input) { | ||
return regex.test(input) ? Result.ok(input) : Result.err(new ConstraintError(type, "Invalid string format", input, expected)); | ||
} | ||
}; | ||
} | ||
__name(stringRegexValidator, "stringRegexValidator"); | ||
function stringUrl(options) { | ||
return { | ||
run(input) { | ||
try { | ||
const url = new URL(input); | ||
if (options?.allowedProtocols && !options.allowedProtocols.includes(url.protocol)) { | ||
return Result.err(new ConstraintError("s.string.url", "Invalid URL protocol", input, `expected ${url.protocol} to be one of: ${options.allowedProtocols.join(", ")}`)); | ||
} | ||
if (options?.allowedDomains && !options.allowedDomains.includes(url.hostname)) { | ||
return Result.err(new ConstraintError("s.string.url", "Invalid URL domain", input, `expected ${url.hostname} to be one of: ${options.allowedDomains.join(", ")}`)); | ||
} | ||
return Result.ok(input); | ||
} catch { | ||
return Result.err(new ConstraintError("s.string.url", "Invalid URL", input, "expected to match an URL")); | ||
} | ||
} | ||
}; | ||
} | ||
__name(stringUrl, "stringUrl"); | ||
function stringIp(version) { | ||
const ipVersion = version ? `v${version}` : ""; | ||
return { | ||
run(input) { | ||
return (version === 4 ? (0, import_node_net.isIPv4)(input) : version === 6 ? (0, import_node_net.isIPv6)(input) : (0, import_node_net.isIP)(input)) ? Result.ok(input) : Result.err(new ConstraintError(`s.string.ip${ipVersion}`, `Invalid ip${ipVersion} address`, input, `expected to be an ip${ipVersion} address`)); | ||
} | ||
}; | ||
} | ||
__name(stringIp, "stringIp"); | ||
function stringRegex(regex) { | ||
return stringRegexValidator("s.string.regex", `expected ${regex}.test(expected) to be true`, regex); | ||
} | ||
__name(stringRegex, "stringRegex"); | ||
function stringUuid({ version = 4, nullable = false } = {}) { | ||
version ??= "1-5"; | ||
const regex = new RegExp(`^(?:[0-9A-F]{8}-[0-9A-F]{4}-[${version}][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}${nullable ? "|00000000-0000-0000-0000-000000000000" : ""})$`, "i"); | ||
const expected = `expected to match UUID${typeof version === "number" ? `v${version}` : ` in range of ${version}`}`; | ||
return stringRegexValidator("s.string.uuid", expected, regex); | ||
} | ||
__name(stringUuid, "stringUuid"); | ||
// src/validators/StringValidator.ts | ||
var StringValidator = class extends BaseValidator { | ||
lengthLe(length) { | ||
lengthLt(length) { | ||
return this.addConstraint(stringLengthLt(length)); | ||
} | ||
lengthLte(length) { | ||
lengthLe(length) { | ||
return this.addConstraint(stringLengthLe(length)); | ||
} | ||
lengthGe(length) { | ||
lengthGt(length) { | ||
return this.addConstraint(stringLengthGt(length)); | ||
} | ||
lengthGte(length) { | ||
lengthGe(length) { | ||
return this.addConstraint(stringLengthGe(length)); | ||
@@ -802,4 +1240,25 @@ } | ||
} | ||
get email() { | ||
return this.addConstraint(stringEmail()); | ||
} | ||
url(options) { | ||
return this.addConstraint(stringUrl(options)); | ||
} | ||
uuid(options) { | ||
return this.addConstraint(stringUuid(options)); | ||
} | ||
regex(regex) { | ||
return this.addConstraint(stringRegex(regex)); | ||
} | ||
get ipv4() { | ||
return this.ip(4); | ||
} | ||
get ipv6() { | ||
return this.ip(6); | ||
} | ||
ip(version) { | ||
return this.addConstraint(stringIp(version)); | ||
} | ||
handle(value) { | ||
return typeof value === "string" ? Result.ok(value) : Result.err(new ValidationError("StringValidator", "Expected a string primitive", value)); | ||
return typeof value === "string" ? Result.ok(value) : Result.err(new ValidationError("s.string", "Expected a string primitive", value)); | ||
} | ||
@@ -809,2 +1268,33 @@ }; | ||
// src/validators/TupleValidator.ts | ||
var TupleValidator = class extends BaseValidator { | ||
constructor(validators, constraints = []) { | ||
super(constraints); | ||
this.validators = []; | ||
this.validators = validators; | ||
} | ||
clone() { | ||
return Reflect.construct(this.constructor, [this.validators, this.constraints]); | ||
} | ||
handle(values) { | ||
if (!Array.isArray(values)) { | ||
return Result.err(new ValidationError("s.tuple(T)", "Expected an array", values)); | ||
} | ||
if (values.length !== this.validators.length) { | ||
return Result.err(new ValidationError("s.tuple(T)", `Expected an array of length ${this.validators.length}`, values)); | ||
} | ||
const errors = []; | ||
const transformed = []; | ||
for (let i = 0; i < values.length; i++) { | ||
const result = this.validators[i].run(values[i]); | ||
if (result.isOk()) | ||
transformed.push(result.value); | ||
else | ||
errors.push([i, result.error]); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
}; | ||
__name(TupleValidator, "TupleValidator"); | ||
// src/validators/UnionValidator.ts | ||
@@ -869,3 +1359,3 @@ var UnionValidator = class extends BaseValidator { | ||
} | ||
return Result.err(new AggregateError(errors, "Could not match any of the defined validators")); | ||
return Result.err(new CombinedError(errors)); | ||
} | ||
@@ -887,3 +1377,3 @@ }; | ||
if (!(value instanceof Map)) { | ||
return Result.err(new ValidationError("MapValidator", "Expected a map", value)); | ||
return Result.err(new ValidationError("s.map(K, V)", "Expected a map", value)); | ||
} | ||
@@ -897,9 +1387,9 @@ const errors = []; | ||
if (keyResult.isErr()) | ||
errors.push(keyResult.error); | ||
errors.push([key, keyResult.error]); | ||
if (valueResult.isErr()) | ||
errors.push(valueResult.error); | ||
errors.push([key, valueResult.error]); | ||
if (errors.length === length) | ||
transformed.set(keyResult.value, valueResult.value); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new AggregateError(errors, "Failed to validate at least one entry")); | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
@@ -922,2 +1412,7 @@ }; | ||
} | ||
default(value) { | ||
const clone = this.clone(); | ||
clone.defaultValue = value; | ||
return clone; | ||
} | ||
handle(value) { | ||
@@ -987,2 +1482,5 @@ return typeof value === "undefined" ? Result.ok(getValue(this.defaultValue)) : this.validator["handle"](value); | ||
} | ||
tuple(validators) { | ||
return new TupleValidator(validators); | ||
} | ||
set(validator) { | ||
@@ -989,0 +1487,0 @@ return new SetValidator(validator); |
@@ -29,2 +29,4 @@ "use strict"; | ||
__export(src_exports, { | ||
CombinedError: () => CombinedError, | ||
CombinedPropertyError: () => CombinedPropertyError, | ||
ConstraintError: () => ConstraintError, | ||
@@ -124,51 +126,21 @@ ExpectedValidationError: () => ExpectedValidationError, | ||
// src/lib/errors/ValidationError.ts | ||
var ValidationError = class extends Error { | ||
constructor(validator, message, given) { | ||
super(message); | ||
this.validator = validator; | ||
this.given = given; | ||
} | ||
toJSON() { | ||
return { | ||
name: this.name, | ||
validator: this.validator, | ||
given: this.given | ||
}; | ||
} | ||
}; | ||
__name(ValidationError, "ValidationError"); | ||
// src/lib/errors/ConstraintError.ts | ||
var import_node_util = require("util"); | ||
// src/validators/ArrayValidator.ts | ||
var ArrayValidator = class extends BaseValidator { | ||
constructor(validator, constraints = []) { | ||
super(constraints); | ||
this.validator = validator; | ||
// src/lib/errors/BaseError.ts | ||
var customInspectSymbol = Symbol.for("nodejs.util.inspect.custom"); | ||
var customInspectSymbolStackLess = Symbol.for("nodejs.util.inspect.custom.stack-less"); | ||
var BaseError = class extends Error { | ||
[customInspectSymbol](depth, options) { | ||
return `${this[customInspectSymbolStackLess](depth, options)} | ||
${this.stack.slice(this.stack.indexOf("\n"))}`; | ||
} | ||
clone() { | ||
return Reflect.construct(this.constructor, [this.validator, this.constraints]); | ||
} | ||
handle(values) { | ||
if (!Array.isArray(values)) { | ||
return Result.err(new ValidationError("ArrayValidator", "Expected an array", values)); | ||
} | ||
const errors = []; | ||
const transformed = []; | ||
for (const value of values) { | ||
const result = this.validator.run(value); | ||
if (result.isOk()) | ||
transformed.push(result.value); | ||
else | ||
errors.push(result.error); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new AggregateError(errors, "Failed to validate at least one entry")); | ||
} | ||
}; | ||
__name(ArrayValidator, "ArrayValidator"); | ||
__name(BaseError, "BaseError"); | ||
// src/lib/errors/ConstraintError.ts | ||
var ConstraintError = class extends Error { | ||
constructor(validator, message, given, expected) { | ||
var ConstraintError = class extends BaseError { | ||
constructor(constraint, message, given, expected) { | ||
super(message); | ||
this.constraint = validator; | ||
this.constraint = constraint; | ||
this.given = given; | ||
@@ -185,2 +157,22 @@ this.expected = expected; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const constraint = options.stylize(this.constraint, "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[ConstraintError: ${constraint}]`, "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1 }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const given = (0, import_node_util.inspect)(this.given, newOptions).replaceAll("\n", padding); | ||
const header = `${options.stylize("ConstraintError", "special")} > ${constraint}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const expectedBlock = ` | ||
${options.stylize("Expected: ", "string")}${options.stylize(this.expected, "boolean")}`; | ||
const givenBlock = ` | ||
${options.stylize("Received:", "regexp")}${padding}${given}`; | ||
return `${header} | ||
${message} | ||
${expectedBlock} | ||
${givenBlock}`; | ||
} | ||
}; | ||
@@ -215,7 +207,162 @@ __name(ConstraintError, "ConstraintError"); | ||
// src/constraints/ArrayLengthConstraints.ts | ||
function arrayLengthComparator(comparator, name, expected, length) { | ||
return { | ||
run(input) { | ||
return comparator(input.length, length) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid Array length", input, expected)); | ||
} | ||
}; | ||
} | ||
__name(arrayLengthComparator, "arrayLengthComparator"); | ||
function arrayLengthLt(value) { | ||
const expected = `expected.length < ${value}`; | ||
return arrayLengthComparator(lt, "s.array(T).lengthLt", expected, value); | ||
} | ||
__name(arrayLengthLt, "arrayLengthLt"); | ||
function arrayLengthLe(value) { | ||
const expected = `expected.length <= ${value}`; | ||
return arrayLengthComparator(le, "s.array(T).lengthLe", expected, value); | ||
} | ||
__name(arrayLengthLe, "arrayLengthLe"); | ||
function arrayLengthGt(value) { | ||
const expected = `expected.length > ${value}`; | ||
return arrayLengthComparator(gt, "s.array(T).lengthGt", expected, value); | ||
} | ||
__name(arrayLengthGt, "arrayLengthGt"); | ||
function arrayLengthGe(value) { | ||
const expected = `expected.length >= ${value}`; | ||
return arrayLengthComparator(ge, "s.array(T).lengthGe", expected, value); | ||
} | ||
__name(arrayLengthGe, "arrayLengthGe"); | ||
function arrayLengthEq(value) { | ||
const expected = `expected.length === ${value}`; | ||
return arrayLengthComparator(eq, "s.array(T).lengthEq", expected, value); | ||
} | ||
__name(arrayLengthEq, "arrayLengthEq"); | ||
function arrayLengthNe(value) { | ||
const expected = `expected.length !== ${value}`; | ||
return arrayLengthComparator(ne, "s.array(T).lengthNe", expected, value); | ||
} | ||
__name(arrayLengthNe, "arrayLengthNe"); | ||
// src/lib/errors/CombinedPropertyError.ts | ||
var CombinedPropertyError = class extends BaseError { | ||
constructor(errors) { | ||
super("Received one or more errors"); | ||
this.errors = errors; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
if (depth < 0) { | ||
return options.stylize("[CombinedPropertyError]", "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1, compact: true }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const header = `${options.stylize("CombinedPropertyError", "special")} (${options.stylize(this.errors.length.toString(), "number")})`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const errors = this.errors.map(([key, error]) => { | ||
const property = CombinedPropertyError.formatProperty(key, options); | ||
const body = error[customInspectSymbolStackLess](depth - 1, newOptions).replaceAll("\n", padding); | ||
return ` input${property}${padding}${body}`; | ||
}).join("\n\n"); | ||
return `${header} | ||
${message} | ||
${errors}`; | ||
} | ||
static formatProperty(key, options) { | ||
if (typeof key === "string") | ||
return options.stylize(`.${key}`, "symbol"); | ||
if (typeof key === "number") | ||
return `[${options.stylize(key.toString(), "number")}]`; | ||
return `[${options.stylize("Symbol", "symbol")}(${key.description})]`; | ||
} | ||
}; | ||
__name(CombinedPropertyError, "CombinedPropertyError"); | ||
// src/lib/errors/ValidationError.ts | ||
var import_node_util2 = require("util"); | ||
var ValidationError = class extends BaseError { | ||
constructor(validator, message, given) { | ||
super(message); | ||
this.validator = validator; | ||
this.given = given; | ||
} | ||
toJSON() { | ||
return { | ||
name: this.name, | ||
validator: this.validator, | ||
given: this.given | ||
}; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const validator = options.stylize(this.validator, "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[ValidationError: ${validator}]`, "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1, compact: true }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const given = (0, import_node_util2.inspect)(this.given, newOptions).replaceAll("\n", padding); | ||
const header = `${options.stylize("ValidationError", "special")} > ${validator}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const givenBlock = ` | ||
${options.stylize("Received:", "regexp")}${padding}${given}`; | ||
return `${header} | ||
${message} | ||
${givenBlock}`; | ||
} | ||
}; | ||
__name(ValidationError, "ValidationError"); | ||
// src/validators/ArrayValidator.ts | ||
var ArrayValidator = class extends BaseValidator { | ||
constructor(validator, constraints = []) { | ||
super(constraints); | ||
this.validator = validator; | ||
} | ||
lengthLt(length) { | ||
return this.addConstraint(arrayLengthLt(length)); | ||
} | ||
lengthLe(length) { | ||
return this.addConstraint(arrayLengthLe(length)); | ||
} | ||
lengthGt(length) { | ||
return this.addConstraint(arrayLengthGt(length)); | ||
} | ||
lengthGe(length) { | ||
return this.addConstraint(arrayLengthGe(length)); | ||
} | ||
lengthEq(length) { | ||
return this.addConstraint(arrayLengthEq(length)); | ||
} | ||
lengthNe(length) { | ||
return this.addConstraint(arrayLengthNe(length)); | ||
} | ||
clone() { | ||
return Reflect.construct(this.constructor, [this.validator, this.constraints]); | ||
} | ||
handle(values) { | ||
if (!Array.isArray(values)) { | ||
return Result.err(new ValidationError("s.array(T)", "Expected an array", values)); | ||
} | ||
const errors = []; | ||
const transformed = []; | ||
for (let i = 0; i < values.length; i++) { | ||
const result = this.validator.run(values[i]); | ||
if (result.isOk()) | ||
transformed.push(result.value); | ||
else | ||
errors.push([i, result.error]); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
}; | ||
__name(ArrayValidator, "ArrayValidator"); | ||
// src/constraints/BigIntConstraints.ts | ||
function bigintComparator(comparator, name, messageBuilder, number) { | ||
function bigintComparator(comparator, name, expected, number) { | ||
return { | ||
run(input) { | ||
return comparator(input, number) ? Result.ok(input) : Result.err(new ConstraintError(name, messageBuilder(input, number), input, number)); | ||
return comparator(input, number) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid bigint value", input, expected)); | ||
} | ||
@@ -225,8 +372,41 @@ }; | ||
__name(bigintComparator, "bigintComparator"); | ||
var bigintLt = bigintComparator.bind(null, lt, "bigintLt", (given, expected) => `Expected bigint to be less than ${expected}, but received ${given}`); | ||
var bigintLe = bigintComparator.bind(null, le, "bigintLe", (given, expected) => `Expected bigint to be less or equals than ${expected}, but received ${given}`); | ||
var bigintGt = bigintComparator.bind(null, gt, "bigintGt", (given, expected) => `Expected bigint to be greater than ${expected}, but received ${given}`); | ||
var bigintGe = bigintComparator.bind(null, ge, "bigintGe", (given, expected) => `Expected bigint to be greater or equals than ${expected}, but received ${given}`); | ||
var bigintEq = bigintComparator.bind(null, eq, "bigintEq", (given, expected) => `Expected bigint to be exactly ${expected}, but received ${given}`); | ||
var bigintNe = bigintComparator.bind(null, ne, "bigintNe", (_, expected) => `Expected bigint to not be ${expected}`); | ||
function bigintLt(value) { | ||
const expected = `expected < ${value}n`; | ||
return bigintComparator(lt, "s.bigint.lt", expected, value); | ||
} | ||
__name(bigintLt, "bigintLt"); | ||
function bigintLe(value) { | ||
const expected = `expected <= ${value}n`; | ||
return bigintComparator(le, "s.bigint.le", expected, value); | ||
} | ||
__name(bigintLe, "bigintLe"); | ||
function bigintGt(value) { | ||
const expected = `expected > ${value}n`; | ||
return bigintComparator(gt, "s.bigint.gt", expected, value); | ||
} | ||
__name(bigintGt, "bigintGt"); | ||
function bigintGe(value) { | ||
const expected = `expected >= ${value}n`; | ||
return bigintComparator(ge, "s.bigint.ge", expected, value); | ||
} | ||
__name(bigintGe, "bigintGe"); | ||
function bigintEq(value) { | ||
const expected = `expected === ${value}n`; | ||
return bigintComparator(eq, "s.bigint.eq", expected, value); | ||
} | ||
__name(bigintEq, "bigintEq"); | ||
function bigintNe(value) { | ||
const expected = `expected !== ${value}n`; | ||
return bigintComparator(ne, "s.bigint.ne", expected, value); | ||
} | ||
__name(bigintNe, "bigintNe"); | ||
function bigintDivisibleBy(divider) { | ||
const expected = `expected % ${divider}n === 0n`; | ||
return { | ||
run(input) { | ||
return input % divider === 0n ? Result.ok(input) : Result.err(new ConstraintError("s.bigint.divisibleBy", "BigInt is not divisible", input, expected)); | ||
} | ||
}; | ||
} | ||
__name(bigintDivisibleBy, "bigintDivisibleBy"); | ||
@@ -259,4 +439,16 @@ // src/validators/BigIntValidator.ts | ||
} | ||
divisibleBy(number) { | ||
return this.addConstraint(bigintDivisibleBy(number)); | ||
} | ||
get abs() { | ||
return this.transform((value) => value < 0 ? -value : value); | ||
} | ||
intN(bits) { | ||
return this.transform((value) => BigInt.asIntN(bits, value)); | ||
} | ||
uintN(bits) { | ||
return this.transform((value) => BigInt.asUintN(bits, value)); | ||
} | ||
handle(value) { | ||
return typeof value === "bigint" ? Result.ok(value) : Result.err(new ValidationError("BigIntValidator", "Expected a bigint primitive", value)); | ||
return typeof value === "bigint" ? Result.ok(value) : Result.err(new ValidationError("s.bigint", "Expected a bigint primitive", value)); | ||
} | ||
@@ -269,3 +461,3 @@ }; | ||
run(input) { | ||
return input ? Result.ok(input) : Result.err(new ConstraintError("booleanTrue", "Expected boolean to be true, but received false", input, true)); | ||
return input ? Result.ok(input) : Result.err(new ConstraintError("s.boolean.true", "Invalid boolean value", input, "true")); | ||
} | ||
@@ -275,3 +467,3 @@ }; | ||
run(input) { | ||
return input ? Result.err(new ConstraintError("booleanFalse", "Expected boolean to be false, but received true", input, false)) : Result.ok(input); | ||
return input ? Result.err(new ConstraintError("s.boolean.false", "Invalid boolean value", input, "false")) : Result.ok(input); | ||
} | ||
@@ -295,3 +487,3 @@ }; | ||
handle(value) { | ||
return typeof value === "boolean" ? Result.ok(value) : Result.err(new ValidationError("BooleanValidator", "Expected a boolean primitive", value)); | ||
return typeof value === "boolean" ? Result.ok(value) : Result.err(new ValidationError("s.boolean", "Expected a boolean primitive", value)); | ||
} | ||
@@ -302,6 +494,6 @@ }; | ||
// src/constraints/DateConstraints.ts | ||
function dateComparator(comparator, name, messageBuilder, date, number = date.getTime()) { | ||
function dateComparator(comparator, name, expected, number) { | ||
return { | ||
run(input) { | ||
return comparator(input.getTime(), number) ? Result.ok(input) : Result.err(new ConstraintError(name, messageBuilder(input, date), input, date)); | ||
return comparator(input.getTime(), number) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid Date value", input, expected)); | ||
} | ||
@@ -311,11 +503,35 @@ }; | ||
__name(dateComparator, "dateComparator"); | ||
var dateLt = dateComparator.bind(null, lt, "dateLt", (given, expected) => `Expected date to be earlier than ${expected}, but received ${given}`); | ||
var dateLe = dateComparator.bind(null, le, "dateLe", (given, expected) => `Expected date to be earlier or equals than ${expected}, but received ${given}`); | ||
var dateGt = dateComparator.bind(null, gt, "dateGt", (given, expected) => `Expected date to be later than ${expected}, but received ${given}`); | ||
var dateGe = dateComparator.bind(null, ge, "dateGe", (given, expected) => `Expected date to be later or equals than ${expected}, but received ${given}`); | ||
var dateEq = dateComparator.bind(null, eq, "dateEq", (given, expected) => `Expected date to be exactly ${expected}, but received ${given}`); | ||
var dateNe = dateComparator.bind(null, ne, "dateNe", (_, expected) => `Expected date to not be ${expected}`); | ||
function dateLt(value) { | ||
const expected = `expected < ${value.toISOString()}`; | ||
return dateComparator(lt, "s.date.lt", expected, value.getTime()); | ||
} | ||
__name(dateLt, "dateLt"); | ||
function dateLe(value) { | ||
const expected = `expected <= ${value.toISOString()}`; | ||
return dateComparator(le, "s.date.le", expected, value.getTime()); | ||
} | ||
__name(dateLe, "dateLe"); | ||
function dateGt(value) { | ||
const expected = `expected > ${value.toISOString()}`; | ||
return dateComparator(gt, "s.date.gt", expected, value.getTime()); | ||
} | ||
__name(dateGt, "dateGt"); | ||
function dateGe(value) { | ||
const expected = `expected >= ${value.toISOString()}`; | ||
return dateComparator(ge, "s.date.ge", expected, value.getTime()); | ||
} | ||
__name(dateGe, "dateGe"); | ||
function dateEq(value) { | ||
const expected = `expected === ${value.toISOString()}`; | ||
return dateComparator(eq, "s.date.eq", expected, value.getTime()); | ||
} | ||
__name(dateEq, "dateEq"); | ||
function dateNe(value) { | ||
const expected = `expected !== ${value.toISOString()}`; | ||
return dateComparator(ne, "s.date.ne", expected, value.getTime()); | ||
} | ||
__name(dateNe, "dateNe"); | ||
var dateInvalid = { | ||
run(input) { | ||
return Number.isNaN(input.getTime()) ? Result.ok(input) : Result.err(new ConstraintError("dateInvalid", `Expected Date's time to be a NaN, but received ${input}`, input, "An invalid Date")); | ||
return Number.isNaN(input.getTime()) ? Result.ok(input) : Result.err(new ConstraintError("s.date.eq(NaN)", "Invalid Date value", input, "expected === NaN")); | ||
} | ||
@@ -325,3 +541,3 @@ }; | ||
run(input) { | ||
return Number.isNaN(input.getTime()) ? Result.err(new ConstraintError("dateValid", `Expected Date's time to not be a NaN, but received ${input}`, input, "A valid Date")) : Result.ok(input); | ||
return Number.isNaN(input.getTime()) ? Result.err(new ConstraintError("s.date.ne(NaN)", "Invalid Date value", input, "expected !== NaN")) : Result.ok(input); | ||
} | ||
@@ -353,3 +569,3 @@ }; | ||
handle(value) { | ||
return value instanceof Date ? Result.ok(value) : Result.err(new ValidationError("DateValidator", "Expected a Date", value)); | ||
return value instanceof Date ? Result.ok(value) : Result.err(new ValidationError("s.date", "Expected a Date", value)); | ||
} | ||
@@ -360,2 +576,3 @@ }; | ||
// src/lib/errors/ExpectedValidationError.ts | ||
var import_node_util3 = require("util"); | ||
var ExpectedValidationError = class extends ValidationError { | ||
@@ -374,2 +591,23 @@ constructor(validator, message, given, expected) { | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const validator = options.stylize(this.validator, "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[ExpectedValidationError: ${validator}]`, "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1 }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const expected = (0, import_node_util3.inspect)(this.expected, newOptions).replaceAll("\n", padding); | ||
const given = (0, import_node_util3.inspect)(this.given, newOptions).replaceAll("\n", padding); | ||
const header = `${options.stylize("ExpectedValidationError", "special")} > ${validator}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const expectedBlock = ` | ||
${options.stylize("Expected:", "string")}${padding}${expected}`; | ||
const givenBlock = ` | ||
${options.stylize("Received:", "regexp")}${padding}${given}`; | ||
return `${header} | ||
${message} | ||
${expectedBlock} | ||
${givenBlock}`; | ||
} | ||
}; | ||
@@ -385,3 +623,3 @@ __name(ExpectedValidationError, "ExpectedValidationError"); | ||
handle(value) { | ||
return value instanceof this.expected ? Result.ok(value) : Result.err(new ExpectedValidationError("InstanceValidator", "Expected", value, this.expected)); | ||
return value instanceof this.expected ? Result.ok(value) : Result.err(new ExpectedValidationError("s.instance(V)", "Expected", value, this.expected)); | ||
} | ||
@@ -401,3 +639,3 @@ clone() { | ||
handle(value) { | ||
return Object.is(value, this.expected) ? Result.ok(value) : Result.err(new ExpectedValidationError("LiteralValidator", "Expected", value, this.expected)); | ||
return Object.is(value, this.expected) ? Result.ok(value) : Result.err(new ExpectedValidationError("s.literal(V)", "Expected values to be equals", value, this.expected)); | ||
} | ||
@@ -413,3 +651,3 @@ clone() { | ||
handle(value) { | ||
return Result.err(new ValidationError("NeverValidator", "Expected a value to not be passed", value)); | ||
return Result.err(new ValidationError("s.never", "Expected a value to not be passed", value)); | ||
} | ||
@@ -422,3 +660,3 @@ }; | ||
handle(value) { | ||
return value === void 0 || value === null ? Result.ok(value) : Result.err(new ValidationError("NullishValidator", "Expected undefined or null", value)); | ||
return value === void 0 || value === null ? Result.ok(value) : Result.err(new ValidationError("s.nullish", "Expected undefined or null", value)); | ||
} | ||
@@ -429,6 +667,6 @@ }; | ||
// src/constraints/NumberConstraints.ts | ||
function numberComparator(comparator, name, messageBuilder, number) { | ||
function numberComparator(comparator, name, expected, number) { | ||
return { | ||
run(input) { | ||
return comparator(input, number) ? Result.ok(input) : Result.err(new ConstraintError(name, messageBuilder(input, number), input, number)); | ||
return comparator(input, number) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid number value", input, expected)); | ||
} | ||
@@ -438,11 +676,35 @@ }; | ||
__name(numberComparator, "numberComparator"); | ||
var numberLt = numberComparator.bind(null, lt, "numberLt", (given, expected) => `Expected number to be less than ${expected}, but received ${given}`); | ||
var numberLe = numberComparator.bind(null, le, "numberLe", (given, expected) => `Expected number to be less or equals than ${expected}, but received ${given}`); | ||
var numberGt = numberComparator.bind(null, gt, "numberGt", (given, expected) => `Expected number to be greater than ${expected}, but received ${given}`); | ||
var numberGe = numberComparator.bind(null, ge, "numberGe", (given, expected) => `Expected number to be greater or equals than ${expected}, but received ${given}`); | ||
var numberEq = numberComparator.bind(null, eq, "numberEq", (given, expected) => `Expected number to be exactly ${expected}, but received ${given}`); | ||
var numberNe = numberComparator.bind(null, ne, "numberNe", (_, expected) => `Expected number to not be ${expected}`); | ||
function numberLt(value) { | ||
const expected = `expected < ${value}`; | ||
return numberComparator(lt, "s.number.lt", expected, value); | ||
} | ||
__name(numberLt, "numberLt"); | ||
function numberLe(value) { | ||
const expected = `expected <= ${value}`; | ||
return numberComparator(le, "s.number.le", expected, value); | ||
} | ||
__name(numberLe, "numberLe"); | ||
function numberGt(value) { | ||
const expected = `expected > ${value}`; | ||
return numberComparator(gt, "s.number.gt", expected, value); | ||
} | ||
__name(numberGt, "numberGt"); | ||
function numberGe(value) { | ||
const expected = `expected >= ${value}`; | ||
return numberComparator(ge, "s.number.ge", expected, value); | ||
} | ||
__name(numberGe, "numberGe"); | ||
function numberEq(value) { | ||
const expected = `expected === ${value}`; | ||
return numberComparator(eq, "s.number.eq", expected, value); | ||
} | ||
__name(numberEq, "numberEq"); | ||
function numberNe(value) { | ||
const expected = `expected !== ${value}`; | ||
return numberComparator(ne, "s.number.ne", expected, value); | ||
} | ||
__name(numberNe, "numberNe"); | ||
var numberInt = { | ||
run(input) { | ||
return Number.isInteger(input) ? Result.ok(input) : Result.err(new ConstraintError("numberInt", `Expected number to be an integer, but received ${input}`, input, "An integer")); | ||
return Number.isInteger(input) ? Result.ok(input) : Result.err(new ConstraintError("s.number.int", "Given value is not an integer", input, "Number.isInteger(expected) to be true")); | ||
} | ||
@@ -452,3 +714,3 @@ }; | ||
run(input) { | ||
return Number.isSafeInteger(input) ? Result.ok(input) : Result.err(new ConstraintError("numberSafeInt", `Expected number to be a safe integer, but received ${input}`, input, "A safe integer")); | ||
return Number.isSafeInteger(input) ? Result.ok(input) : Result.err(new ConstraintError("s.number.safeInt", "Given value is not a safe integer", input, "Number.isSafeInteger(expected) to be true")); | ||
} | ||
@@ -458,3 +720,3 @@ }; | ||
run(input) { | ||
return Number.isFinite(input) ? Result.ok(input) : Result.err(new ConstraintError("numberFinite", `Expected number to be a finite number, but received ${input}`, input, "A finite number")); | ||
return Number.isFinite(input) ? Result.ok(input) : Result.err(new ConstraintError("s.number.finite", "Given value is not finite", input, "Number.isFinite(expected) to be true")); | ||
} | ||
@@ -464,3 +726,3 @@ }; | ||
run(input) { | ||
return Number.isNaN(input) ? Result.ok(input) : Result.err(new ConstraintError("numberNaN", `Expected number to be a NaN, but received ${input}`, input, "A NaN")); | ||
return Number.isNaN(input) ? Result.ok(input) : Result.err(new ConstraintError("s.number.eq(NaN)", "Invalid number value", input, "expected === NaN")); | ||
} | ||
@@ -470,10 +732,10 @@ }; | ||
run(input) { | ||
return Number.isNaN(input) ? Result.err(new ConstraintError("numberNeNaN", `Expected number to not be a NaN, but received ${input}`, input, "Not NaN")) : Result.ok(input); | ||
return Number.isNaN(input) ? Result.err(new ConstraintError("s.number.ne(NaN)", "Invalid number value", input, "expected !== NaN")) : Result.ok(input); | ||
} | ||
}; | ||
function numberDivisibleBy(divider) { | ||
const expected = `% ${divider}`; | ||
const expected = `expected % ${divider} === 0`; | ||
return { | ||
run(input) { | ||
return input % divider === 0 ? Result.ok(input) : Result.err(new ConstraintError("numberDivisibleBy", `Expected number to be divisible by ${divider}, but received ${input}`, input, expected)); | ||
return input % divider === 0 ? Result.ok(input) : Result.err(new ConstraintError("s.number.divisibleBy", "Number is not divisible", input, expected)); | ||
} | ||
@@ -544,3 +806,3 @@ }; | ||
handle(value) { | ||
return typeof value === "number" ? Result.ok(value) : Result.err(new ValidationError("NumberValidator", "Expected a number primitive", value)); | ||
return typeof value === "number" ? Result.ok(value) : Result.err(new ValidationError("s.number", "Expected a number primitive", value)); | ||
} | ||
@@ -551,5 +813,5 @@ }; | ||
// src/lib/errors/MissingPropertyError.ts | ||
var MissingPropertyError = class extends Error { | ||
var MissingPropertyError = class extends BaseError { | ||
constructor(property) { | ||
super(`Expected property "${String(property)}" is missing`); | ||
super("A required property is missing"); | ||
this.property = property; | ||
@@ -563,2 +825,12 @@ } | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const property = options.stylize(this.property.toString(), "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[MissingPropertyError: ${property}]`, "special"); | ||
} | ||
const header = `${options.stylize("MissingPropertyError", "special")} > ${property}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
return `${header} | ||
${message}`; | ||
} | ||
}; | ||
@@ -568,5 +840,6 @@ __name(MissingPropertyError, "MissingPropertyError"); | ||
// src/lib/errors/UnknownPropertyError.ts | ||
var UnknownPropertyError = class extends Error { | ||
var import_node_util4 = require("util"); | ||
var UnknownPropertyError = class extends BaseError { | ||
constructor(property, value) { | ||
super("Unknown property received"); | ||
super("Received unexpected property"); | ||
this.property = property; | ||
@@ -582,2 +855,19 @@ this.value = value; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
const property = options.stylize(this.property.toString(), "string"); | ||
if (depth < 0) { | ||
return options.stylize(`[UnknownPropertyError: ${property}]`, "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1, compact: true }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const given = (0, import_node_util4.inspect)(this.value, newOptions).replaceAll("\n", padding); | ||
const header = `${options.stylize("UnknownPropertyError", "special")} > ${property}`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const givenBlock = ` | ||
${options.stylize("Received:", "regexp")}${padding}${given}`; | ||
return `${header} | ||
${message} | ||
${givenBlock}`; | ||
} | ||
}; | ||
@@ -628,6 +918,6 @@ __name(UnknownPropertyError, "UnknownPropertyError"); | ||
if (typeOfValue !== "object") { | ||
return Result.err(new ValidationError("ObjectValidator", `Expected the value to be an object, but received ${typeOfValue} instead`, value)); | ||
return Result.err(new ValidationError("s.object(T)", `Expected the value to be an object, but received ${typeOfValue} instead`, value)); | ||
} | ||
if (value === null) { | ||
return Result.err(new ValidationError("ObjectValidator", "Expected the value to not be null", value)); | ||
return Result.err(new ValidationError("s.object(T)", "Expected the value to not be null", value)); | ||
} | ||
@@ -650,9 +940,9 @@ return this.handleStrategy(value); | ||
if (error instanceof ValidationError && error.given === void 0) { | ||
errors.push(new MissingPropertyError(key)); | ||
errors.push([key, new MissingPropertyError(key)]); | ||
} else { | ||
errors.push(error); | ||
errors.push([key, error]); | ||
} | ||
} | ||
} | ||
return errors.length === 0 ? Result.ok(entries) : Result.err(new AggregateError(errors, "Failed to match at least one of the properties")); | ||
return errors.length === 0 ? Result.ok(entries) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
@@ -673,5 +963,5 @@ handleStrictStrategy(value) { | ||
if (error instanceof ValidationError && error.given === void 0) { | ||
errors.push(new MissingPropertyError(key)); | ||
errors.push([key, new MissingPropertyError(key)]); | ||
} else { | ||
errors.push(error); | ||
errors.push([key, error]); | ||
} | ||
@@ -681,5 +971,5 @@ } | ||
} | ||
errors.push(new UnknownPropertyError(key, value[key])); | ||
errors.push([key, new UnknownPropertyError(key, value[key])]); | ||
} | ||
return errors.length === 0 ? Result.ok(finalResult) : Result.err(new AggregateError(errors, "Failed to match at least one of the properties")); | ||
return errors.length === 0 ? Result.ok(finalResult) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
@@ -713,6 +1003,6 @@ }; | ||
if (typeof value !== "object") { | ||
return Result.err(new ValidationError("RecordValidator", "Expected an object", value)); | ||
return Result.err(new ValidationError("s.record(T)", "Expected an object", value)); | ||
} | ||
if (value === null) { | ||
return Result.err(new ValidationError("RecordValidator", "Expected the value to not be null", value)); | ||
return Result.err(new ValidationError("s.record(T)", "Expected the value to not be null", value)); | ||
} | ||
@@ -726,5 +1016,5 @@ const errors = []; | ||
else | ||
errors.push(result.error); | ||
errors.push([key, result.error]); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new AggregateError(errors, "Failed to validate at least one entry")); | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
@@ -734,2 +1024,30 @@ }; | ||
// src/lib/errors/CombinedError.ts | ||
var CombinedError = class extends BaseError { | ||
constructor(errors) { | ||
super("Received one or more errors"); | ||
this.errors = errors; | ||
} | ||
[customInspectSymbolStackLess](depth, options) { | ||
if (depth < 0) { | ||
return options.stylize("[CombinedError]", "special"); | ||
} | ||
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1, compact: true }; | ||
const padding = ` | ||
${options.stylize("|", "undefined")} `; | ||
const header = `${options.stylize("CombinedError", "special")} (${options.stylize(this.errors.length.toString(), "number")})`; | ||
const message = options.stylize(this.message, "regexp"); | ||
const errors = this.errors.map((error, i) => { | ||
const index = options.stylize((i + 1).toString(), "number"); | ||
const body = error[customInspectSymbolStackLess](depth - 1, newOptions).replaceAll("\n", padding); | ||
return ` ${index} ${body}`; | ||
}).join("\n\n"); | ||
return `${header} | ||
${message} | ||
${errors}`; | ||
} | ||
}; | ||
__name(CombinedError, "CombinedError"); | ||
// src/validators/SetValidator.ts | ||
@@ -746,3 +1064,3 @@ var SetValidator = class extends BaseValidator { | ||
if (!(values instanceof Set)) { | ||
return Result.err(new ValidationError("SetValidator", "Expected a set", values)); | ||
return Result.err(new ValidationError("s.set(T)", "Expected a set", values)); | ||
} | ||
@@ -758,3 +1076,3 @@ const errors = []; | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new AggregateError(errors, "Failed to validate at least one entry")); | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedError(errors)); | ||
} | ||
@@ -765,29 +1083,142 @@ }; | ||
// src/constraints/StringConstraints.ts | ||
function stringLength(comparator, name, messageBuilder, length) { | ||
var import_node_net = require("net"); | ||
// src/constraints/util/emailValidator.ts | ||
var accountRegex = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")$/; | ||
function validateEmail(email) { | ||
if (!email) | ||
return false; | ||
const emailParts = email.split("@"); | ||
if (emailParts.length !== 2) | ||
return false; | ||
const account = emailParts[0]; | ||
if (account.length > 64) | ||
return false; | ||
const domain = emailParts[1]; | ||
if (domain.length > 255) | ||
return false; | ||
const domainParts = domain.split("."); | ||
if (domainParts.length < 2) | ||
return false; | ||
if (domainParts.some((part) => part.length > 63)) | ||
return false; | ||
return accountRegex.test(account) && validateEmailDomain(domain); | ||
} | ||
__name(validateEmail, "validateEmail"); | ||
function validateEmailDomain(domain) { | ||
try { | ||
return new URL(`http://${domain}`).hostname === domain; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
__name(validateEmailDomain, "validateEmailDomain"); | ||
// src/constraints/StringConstraints.ts | ||
function stringLengthComparator(comparator, name, expected, length) { | ||
return { | ||
run(input) { | ||
return comparator(input.length, length) ? Result.ok(input) : Result.err(new ConstraintError(name, messageBuilder(input, length), input, length)); | ||
return comparator(input.length, length) ? Result.ok(input) : Result.err(new ConstraintError(name, "Invalid string length", input, expected)); | ||
} | ||
}; | ||
} | ||
__name(stringLength, "stringLength"); | ||
var stringLengthLt = stringLength.bind(null, lt, "stringLengthLt", (given, expected) => `Expected string to have less than ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthLe = stringLength.bind(null, le, "stringLengthLe", (given, expected) => `Expected string to have maximum ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthGt = stringLength.bind(null, gt, "stringLengthGt", (given, expected) => `Expected string to have more than ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthGe = stringLength.bind(null, ge, "stringLengthGe", (given, expected) => `Expected string to have at least ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthEq = stringLength.bind(null, eq, "stringLengthEq", (given, expected) => `Expected string to have exactly ${expected} characters, but received one with ${given.length} characters`); | ||
var stringLengthNe = stringLength.bind(null, ne, "stringLengthNe", (given, expected) => `Expected string to not have exactly ${expected} characters, but received one with ${given.length} characters`); | ||
__name(stringLengthComparator, "stringLengthComparator"); | ||
function stringLengthLt(length) { | ||
const expected = `expected.length < ${length}`; | ||
return stringLengthComparator(lt, "s.string.lengthLt", expected, length); | ||
} | ||
__name(stringLengthLt, "stringLengthLt"); | ||
function stringLengthLe(length) { | ||
const expected = `expected.length <= ${length}`; | ||
return stringLengthComparator(le, "s.string.lengthLe", expected, length); | ||
} | ||
__name(stringLengthLe, "stringLengthLe"); | ||
function stringLengthGt(length) { | ||
const expected = `expected.length > ${length}`; | ||
return stringLengthComparator(gt, "s.string.lengthGt", expected, length); | ||
} | ||
__name(stringLengthGt, "stringLengthGt"); | ||
function stringLengthGe(length) { | ||
const expected = `expected.length >= ${length}`; | ||
return stringLengthComparator(ge, "s.string.lengthGe", expected, length); | ||
} | ||
__name(stringLengthGe, "stringLengthGe"); | ||
function stringLengthEq(length) { | ||
const expected = `expected.length === ${length}`; | ||
return stringLengthComparator(eq, "s.string.lengthEq", expected, length); | ||
} | ||
__name(stringLengthEq, "stringLengthEq"); | ||
function stringLengthNe(length) { | ||
const expected = `expected.length !== ${length}`; | ||
return stringLengthComparator(ne, "s.string.lengthNe", expected, length); | ||
} | ||
__name(stringLengthNe, "stringLengthNe"); | ||
function stringEmail() { | ||
return { | ||
run(input) { | ||
return validateEmail(input) ? Result.ok(input) : Result.err(new ConstraintError("s.string.email", "Invalid email address", input, "expected to be an email address")); | ||
} | ||
}; | ||
} | ||
__name(stringEmail, "stringEmail"); | ||
function stringRegexValidator(type, expected, regex) { | ||
return { | ||
run(input) { | ||
return regex.test(input) ? Result.ok(input) : Result.err(new ConstraintError(type, "Invalid string format", input, expected)); | ||
} | ||
}; | ||
} | ||
__name(stringRegexValidator, "stringRegexValidator"); | ||
function stringUrl(options) { | ||
return { | ||
run(input) { | ||
try { | ||
const url = new URL(input); | ||
if (options?.allowedProtocols && !options.allowedProtocols.includes(url.protocol)) { | ||
return Result.err(new ConstraintError("s.string.url", "Invalid URL protocol", input, `expected ${url.protocol} to be one of: ${options.allowedProtocols.join(", ")}`)); | ||
} | ||
if (options?.allowedDomains && !options.allowedDomains.includes(url.hostname)) { | ||
return Result.err(new ConstraintError("s.string.url", "Invalid URL domain", input, `expected ${url.hostname} to be one of: ${options.allowedDomains.join(", ")}`)); | ||
} | ||
return Result.ok(input); | ||
} catch { | ||
return Result.err(new ConstraintError("s.string.url", "Invalid URL", input, "expected to match an URL")); | ||
} | ||
} | ||
}; | ||
} | ||
__name(stringUrl, "stringUrl"); | ||
function stringIp(version) { | ||
const ipVersion = version ? `v${version}` : ""; | ||
return { | ||
run(input) { | ||
return (version === 4 ? (0, import_node_net.isIPv4)(input) : version === 6 ? (0, import_node_net.isIPv6)(input) : (0, import_node_net.isIP)(input)) ? Result.ok(input) : Result.err(new ConstraintError(`s.string.ip${ipVersion}`, `Invalid ip${ipVersion} address`, input, `expected to be an ip${ipVersion} address`)); | ||
} | ||
}; | ||
} | ||
__name(stringIp, "stringIp"); | ||
function stringRegex(regex) { | ||
return stringRegexValidator("s.string.regex", `expected ${regex}.test(expected) to be true`, regex); | ||
} | ||
__name(stringRegex, "stringRegex"); | ||
function stringUuid({ version = 4, nullable = false } = {}) { | ||
version ??= "1-5"; | ||
const regex = new RegExp(`^(?:[0-9A-F]{8}-[0-9A-F]{4}-[${version}][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}${nullable ? "|00000000-0000-0000-0000-000000000000" : ""})$`, "i"); | ||
const expected = `expected to match UUID${typeof version === "number" ? `v${version}` : ` in range of ${version}`}`; | ||
return stringRegexValidator("s.string.uuid", expected, regex); | ||
} | ||
__name(stringUuid, "stringUuid"); | ||
// src/validators/StringValidator.ts | ||
var StringValidator = class extends BaseValidator { | ||
lengthLe(length) { | ||
lengthLt(length) { | ||
return this.addConstraint(stringLengthLt(length)); | ||
} | ||
lengthLte(length) { | ||
lengthLe(length) { | ||
return this.addConstraint(stringLengthLe(length)); | ||
} | ||
lengthGe(length) { | ||
lengthGt(length) { | ||
return this.addConstraint(stringLengthGt(length)); | ||
} | ||
lengthGte(length) { | ||
lengthGe(length) { | ||
return this.addConstraint(stringLengthGe(length)); | ||
@@ -801,4 +1232,25 @@ } | ||
} | ||
get email() { | ||
return this.addConstraint(stringEmail()); | ||
} | ||
url(options) { | ||
return this.addConstraint(stringUrl(options)); | ||
} | ||
uuid(options) { | ||
return this.addConstraint(stringUuid(options)); | ||
} | ||
regex(regex) { | ||
return this.addConstraint(stringRegex(regex)); | ||
} | ||
get ipv4() { | ||
return this.ip(4); | ||
} | ||
get ipv6() { | ||
return this.ip(6); | ||
} | ||
ip(version) { | ||
return this.addConstraint(stringIp(version)); | ||
} | ||
handle(value) { | ||
return typeof value === "string" ? Result.ok(value) : Result.err(new ValidationError("StringValidator", "Expected a string primitive", value)); | ||
return typeof value === "string" ? Result.ok(value) : Result.err(new ValidationError("s.string", "Expected a string primitive", value)); | ||
} | ||
@@ -808,2 +1260,33 @@ }; | ||
// src/validators/TupleValidator.ts | ||
var TupleValidator = class extends BaseValidator { | ||
constructor(validators, constraints = []) { | ||
super(constraints); | ||
this.validators = []; | ||
this.validators = validators; | ||
} | ||
clone() { | ||
return Reflect.construct(this.constructor, [this.validators, this.constraints]); | ||
} | ||
handle(values) { | ||
if (!Array.isArray(values)) { | ||
return Result.err(new ValidationError("s.tuple(T)", "Expected an array", values)); | ||
} | ||
if (values.length !== this.validators.length) { | ||
return Result.err(new ValidationError("s.tuple(T)", `Expected an array of length ${this.validators.length}`, values)); | ||
} | ||
const errors = []; | ||
const transformed = []; | ||
for (let i = 0; i < values.length; i++) { | ||
const result = this.validators[i].run(values[i]); | ||
if (result.isOk()) | ||
transformed.push(result.value); | ||
else | ||
errors.push([i, result.error]); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
}; | ||
__name(TupleValidator, "TupleValidator"); | ||
// src/validators/UnionValidator.ts | ||
@@ -868,3 +1351,3 @@ var UnionValidator = class extends BaseValidator { | ||
} | ||
return Result.err(new AggregateError(errors, "Could not match any of the defined validators")); | ||
return Result.err(new CombinedError(errors)); | ||
} | ||
@@ -886,3 +1369,3 @@ }; | ||
if (!(value instanceof Map)) { | ||
return Result.err(new ValidationError("MapValidator", "Expected a map", value)); | ||
return Result.err(new ValidationError("s.map(K, V)", "Expected a map", value)); | ||
} | ||
@@ -896,9 +1379,9 @@ const errors = []; | ||
if (keyResult.isErr()) | ||
errors.push(keyResult.error); | ||
errors.push([key, keyResult.error]); | ||
if (valueResult.isErr()) | ||
errors.push(valueResult.error); | ||
errors.push([key, valueResult.error]); | ||
if (errors.length === length) | ||
transformed.set(keyResult.value, valueResult.value); | ||
} | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new AggregateError(errors, "Failed to validate at least one entry")); | ||
return errors.length === 0 ? Result.ok(transformed) : Result.err(new CombinedPropertyError(errors)); | ||
} | ||
@@ -921,2 +1404,7 @@ }; | ||
} | ||
default(value) { | ||
const clone = this.clone(); | ||
clone.defaultValue = value; | ||
return clone; | ||
} | ||
handle(value) { | ||
@@ -986,2 +1474,5 @@ return typeof value === "undefined" ? Result.ok(getValue(this.defaultValue)) : this.validator["handle"](value); | ||
} | ||
tuple(validators) { | ||
return new TupleValidator(validators); | ||
} | ||
set(validator) { | ||
@@ -1004,2 +1495,4 @@ return new SetValidator(validator); | ||
0 && (module.exports = { | ||
CombinedError, | ||
CombinedPropertyError, | ||
ConstraintError, | ||
@@ -1006,0 +1499,0 @@ ExpectedValidationError, |
{ | ||
"name": "@sapphire/shapeshift", | ||
"version": "1.1.0-next.6e2c172.0", | ||
"version": "1.1.0-next.793648b.0", | ||
"description": "Blazing fast input validation and transformation ⚡", | ||
@@ -33,21 +33,21 @@ "author": "@sapphire", | ||
"devDependencies": { | ||
"@commitlint/cli": "^16.1.0", | ||
"@commitlint/config-conventional": "^16.0.0", | ||
"@commitlint/cli": "^16.2.1", | ||
"@commitlint/config-conventional": "^16.2.1", | ||
"@favware/npm-deprecate": "^1.0.4", | ||
"@favware/rollup-type-bundler": "^1.0.7", | ||
"@sapphire/eslint-config": "^4.0.11", | ||
"@sapphire/prettier-config": "^1.2.9", | ||
"@sapphire/ts-config": "^3.1.8", | ||
"@types/jest": "^27.4.0", | ||
"@sapphire/eslint-config": "^4.2.1", | ||
"@sapphire/prettier-config": "^1.3.0", | ||
"@sapphire/ts-config": "^3.3.1", | ||
"@types/jest": "^27.4.1", | ||
"@types/node": "^17.0.8", | ||
"@typescript-eslint/eslint-plugin": "^5.10.1", | ||
"@typescript-eslint/parser": "^5.10.1", | ||
"@typescript-eslint/eslint-plugin": "^5.12.1", | ||
"@typescript-eslint/parser": "^5.12.1", | ||
"cz-conventional-changelog": "^3.3.0", | ||
"eslint": "~8.8.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint": "^8.10.0", | ||
"eslint-config-prettier": "^8.4.0", | ||
"eslint-plugin-prettier": "^4.0.0", | ||
"husky": "^7.0.4", | ||
"jest": "^27.4.7", | ||
"jest-circus": "^27.4.6", | ||
"lint-staged": "^12.3.2", | ||
"jest": "^27.5.1", | ||
"jest-circus": "^27.5.1", | ||
"lint-staged": "^12.3.4", | ||
"prettier": "^2.5.1", | ||
@@ -57,5 +57,5 @@ "pretty-quick": "^3.1.3", | ||
"ts-jest": "^27.1.3", | ||
"ts-node": "^10.4.0", | ||
"tsup": "^5.11.12", | ||
"typedoc": "^0.22.11", | ||
"ts-node": "^10.5.0", | ||
"tsup": "^5.11.13", | ||
"typedoc": "^0.22.12", | ||
"typedoc-plugin-mdn-links": "^1.0.5", | ||
@@ -117,3 +117,3 @@ "typescript": "^4.5.5" | ||
"prettier": "@sapphire/prettier-config", | ||
"packageManager": "yarn@3.1.1" | ||
"packageManager": "yarn@3.2.0" | ||
} |
@@ -108,5 +108,9 @@ <div align="center"> | ||
s.string.lengthNe(5); | ||
s.string.url; // TODO | ||
s.string.uuid; // TODO | ||
s.string.regex(regex); // TODO | ||
s.string.email; | ||
s.string.url(); | ||
s.string.uuid(); | ||
s.string.regex(regex); | ||
s.string.ip(); | ||
s.string.ipv4; | ||
s.string.ipv6; | ||
``` | ||
@@ -167,3 +171,3 @@ | ||
s.bigint.divisibleBy(5n); // TODO | Divisible by 5n | ||
s.bigint.divisibleBy(5n); // Divisible by 5n | ||
``` | ||
@@ -174,6 +178,6 @@ | ||
```typescript | ||
s.bigint.abs; // TODO | Transforms the bigint to an absolute bigint | ||
s.bigint.abs; // Transforms the bigint to an absolute bigint | ||
s.bigint.intN(5); // TODO | Clamps to a bigint to a signed bigint with 5 digits, see BigInt.asIntN | ||
s.bigint.uintN(5); // TODO | Clamps to a bigint to an unsigned bigint with 5 digits, see BigInt.asUintN | ||
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 | ||
``` | ||
@@ -214,5 +218,5 @@ | ||
> **Note**: `.lengthGt` and `.lengthGe` are overloaded and change the inferred type from 1 to 10. For example, `s.string.array.lengthGe(2)`'s inferred type is `[string, string, ...string[]]` // TODO | ||
> **Note**: All `.length` methods define tuple types with the given amount of elements. For example, `s.string.array.lengthGe(2)`'s inferred type is `[string, string, ...string[]]` | ||
#### Tuples // TODO | ||
#### Tuples | ||
@@ -343,3 +347,3 @@ Unlike arrays, tuples have a fixed number of elements and each element can have a different type: | ||
tags.parse({ foo: 'bar', hello: 'world' }); // => { foo: 'bar', hello: 'world' } | ||
tags.parse({ foo: 42 }); // => throws AggregateError | ||
tags.parse({ foo: 42 }); // => throws CombinedError | ||
tags.parse('Hello'); // => throws ValidateError | ||
@@ -353,7 +357,7 @@ ``` | ||
```typescript | ||
const stringOrNumber = s.union([s.string, s.number]); | ||
const stringOrNumber = s.union(s.string, s.number); | ||
stringOrNumber.parse('Sapphire'); // => 'Sapphire' | ||
stringOrNumber.parse(42); // => 42 | ||
stringOrNumber.parse({}); // => throws AggregateError | ||
stringOrNumber.parse({}); // => throws CombinedError | ||
``` | ||
@@ -524,2 +528,3 @@ | ||
<td align="center"><a href="https://github.com/Khasms"><img src="https://avatars.githubusercontent.com/u/36800359?v=4?s=100" width="100px;" alt=""/><br /><sub><b>John</b></sub></a><br /><a href="https://github.com/sapphiredev/shapeshift/commits?author=Khasms" title="Code">💻</a></td> | ||
<td align="center"><a href="https://github.com/imranbarbhuiya"><img src="https://avatars.githubusercontent.com/u/74945038?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Parbez</b></sub></a><br /><a href="https://github.com/sapphiredev/shapeshift/commits?author=imranbarbhuiya" title="Code">💻</a> <a href="https://github.com/sapphiredev/shapeshift/commits?author=imranbarbhuiya" title="Tests">⚠️</a> <a href="https://github.com/sapphiredev/shapeshift/issues?q=author%3Aimranbarbhuiya" title="Bug reports">🐛</a> <a href="https://github.com/sapphiredev/shapeshift/commits?author=imranbarbhuiya" title="Documentation">📖</a></td> | ||
</tr> | ||
@@ -526,0 +531,0 @@ </table> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
494547
4588
535
3
1