@badrap/valita
Advanced tools
Comparing version 0.0.9 to 0.0.10
@@ -29,3 +29,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.err = exports.ok = exports.undefined = exports.null = exports.union = exports.literal = exports.array = exports.object = exports.boolean = exports.string = exports.bigint = exports.number = exports.unknown = exports.nothing = exports.ValitaError = void 0; | ||
exports.err = exports.ok = exports.undefined = exports.null = exports.union = exports.literal = exports.tuple = exports.array = exports.record = exports.object = exports.boolean = exports.string = exports.bigint = exports.number = exports.unknown = exports.never = exports.ValitaError = void 0; | ||
function _collectIssues(tree, path, issues) { | ||
@@ -332,5 +332,6 @@ var _a; | ||
__extends(ArrayType, _super); | ||
function ArrayType(item) { | ||
function ArrayType(head, rest) { | ||
var _this = _super.call(this) || this; | ||
_this.item = item; | ||
_this.head = head; | ||
_this.rest = rest; | ||
_this.name = "array"; | ||
@@ -343,10 +344,25 @@ return _this; | ||
ArrayType.prototype.genFunc = function () { | ||
var func = this.item.func; | ||
var _a; | ||
var headFuncs = this.head.map(function (t) { return t.func; }); | ||
var restFunc = ((_a = this.rest) !== null && _a !== void 0 ? _a : never()).func; | ||
var minLength = headFuncs.length; | ||
var maxLength = this.rest ? Infinity : minLength; | ||
var invalidType = { code: "invalid_type", expected: ["array"] }; | ||
var invalidLength = { | ||
code: "invalid_length", | ||
minLength: minLength, | ||
maxLength: maxLength, | ||
}; | ||
return function (arr, mode) { | ||
if (!Array.isArray(arr)) { | ||
return { code: "invalid_type", expected: ["array"] }; | ||
return invalidType; | ||
} | ||
var length = arr.length; | ||
if (length < minLength || length > maxLength) { | ||
return invalidLength; | ||
} | ||
var issueTree = undefined; | ||
var output = arr; | ||
for (var i = 0; i < arr.length; i++) { | ||
var func = i < minLength ? headFuncs[i] : restFunc; | ||
var r = func(arr[i], mode); | ||
@@ -442,3 +458,6 @@ if (r !== true) { | ||
var terminal = terminals[j]; | ||
if (terminal.name === "unknown") { | ||
if (terminal.name === "never") { | ||
// skip | ||
} | ||
else if (terminal.name === "unknown") { | ||
unknowns.push(i); | ||
@@ -530,3 +549,6 @@ } | ||
var root = _a.root, terminal = _a.terminal; | ||
if (terminal.name === "nothing") { | ||
if (terminal.name === "never") { | ||
// skip | ||
} | ||
else if (terminal.name === "nothing") { | ||
nothings.push(root); | ||
@@ -666,2 +688,18 @@ } | ||
}(Type)); | ||
var NeverType = /** @class */ (function (_super) { | ||
__extends(NeverType, _super); | ||
function NeverType() { | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
_this.name = "never"; | ||
return _this; | ||
} | ||
NeverType.prototype.genFunc = function () { | ||
var issue = { code: "invalid_type", expected: [] }; | ||
return function (v, _mode) { return (v === Nothing ? true : issue); }; | ||
}; | ||
NeverType.prototype.toTerminals = function (into) { | ||
into.push(this); | ||
}; | ||
return NeverType; | ||
}(Type)); | ||
var NothingType = /** @class */ (function (_super) { | ||
@@ -886,6 +924,9 @@ __extends(NothingType, _super); | ||
}(Type)); | ||
function never() { | ||
return new NeverType(); | ||
} | ||
exports.never = never; | ||
function nothing() { | ||
return new NothingType(); | ||
} | ||
exports.nothing = nothing; | ||
function unknown() { | ||
@@ -923,6 +964,14 @@ return new UnknownType(); | ||
exports.object = object; | ||
function record(valueType) { | ||
return new ObjectType({}, valueType); | ||
} | ||
exports.record = record; | ||
function array(item) { | ||
return new ArrayType(item); | ||
return new ArrayType([], item); | ||
} | ||
exports.array = array; | ||
function tuple(items) { | ||
return new ArrayType(items); | ||
} | ||
exports.tuple = tuple; | ||
function literal(value) { | ||
@@ -929,0 +978,0 @@ return new LiteralType(value); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.err = exports.ok = exports.undefined = exports.null = exports.union = exports.literal = exports.array = exports.object = exports.boolean = exports.string = exports.bigint = exports.number = exports.unknown = exports.nothing = exports.ValitaError = void 0; | ||
exports.err = exports.ok = exports.undefined = exports.null = exports.union = exports.literal = exports.tuple = exports.array = exports.record = exports.object = exports.boolean = exports.string = exports.bigint = exports.number = exports.unknown = exports.never = exports.ValitaError = void 0; | ||
function _collectIssues(tree, path, issues) { | ||
@@ -278,5 +278,6 @@ var _a; | ||
class ArrayType extends Type { | ||
constructor(item) { | ||
constructor(head, rest) { | ||
super(); | ||
this.item = item; | ||
this.head = head; | ||
this.rest = rest; | ||
this.name = "array"; | ||
@@ -288,10 +289,25 @@ } | ||
genFunc() { | ||
const func = this.item.func; | ||
var _a; | ||
const headFuncs = this.head.map((t) => t.func); | ||
const restFunc = ((_a = this.rest) !== null && _a !== void 0 ? _a : never()).func; | ||
const minLength = headFuncs.length; | ||
const maxLength = this.rest ? Infinity : minLength; | ||
const invalidType = { code: "invalid_type", expected: ["array"] }; | ||
const invalidLength = { | ||
code: "invalid_length", | ||
minLength, | ||
maxLength, | ||
}; | ||
return (arr, mode) => { | ||
if (!Array.isArray(arr)) { | ||
return { code: "invalid_type", expected: ["array"] }; | ||
return invalidType; | ||
} | ||
const length = arr.length; | ||
if (length < minLength || length > maxLength) { | ||
return invalidLength; | ||
} | ||
let issueTree = undefined; | ||
let output = arr; | ||
for (let i = 0; i < arr.length; i++) { | ||
const func = i < minLength ? headFuncs[i] : restFunc; | ||
const r = func(arr[i], mode); | ||
@@ -382,3 +398,6 @@ if (r !== true) { | ||
const terminal = terminals[j]; | ||
if (terminal.name === "unknown") { | ||
if (terminal.name === "never") { | ||
// skip | ||
} | ||
else if (terminal.name === "unknown") { | ||
unknowns.push(i); | ||
@@ -465,3 +484,6 @@ } | ||
t.forEach(({ root, terminal }) => { | ||
if (terminal.name === "nothing") { | ||
if (terminal.name === "never") { | ||
// skip | ||
} | ||
else if (terminal.name === "nothing") { | ||
nothings.push(root); | ||
@@ -591,2 +613,15 @@ } | ||
} | ||
class NeverType extends Type { | ||
constructor() { | ||
super(...arguments); | ||
this.name = "never"; | ||
} | ||
genFunc() { | ||
const issue = { code: "invalid_type", expected: [] }; | ||
return (v, _mode) => (v === Nothing ? true : issue); | ||
} | ||
toTerminals(into) { | ||
into.push(this); | ||
} | ||
} | ||
class NothingType extends Type { | ||
@@ -778,6 +813,9 @@ constructor() { | ||
} | ||
function never() { | ||
return new NeverType(); | ||
} | ||
exports.never = never; | ||
function nothing() { | ||
return new NothingType(); | ||
} | ||
exports.nothing = nothing; | ||
function unknown() { | ||
@@ -815,6 +853,14 @@ return new UnknownType(); | ||
exports.object = object; | ||
function record(valueType) { | ||
return new ObjectType({}, valueType); | ||
} | ||
exports.record = record; | ||
function array(item) { | ||
return new ArrayType(item); | ||
return new ArrayType([], item); | ||
} | ||
exports.array = array; | ||
function tuple(items) { | ||
return new ArrayType(items); | ||
} | ||
exports.tuple = tuple; | ||
function literal(value) { | ||
@@ -821,0 +867,0 @@ return new LiteralType(value); |
@@ -19,2 +19,5 @@ declare type PrettyIntersection<V> = Extract<{ | ||
expected: Literal[]; | ||
}> | I<"invalid_length", { | ||
minLength: number; | ||
maxLength: number; | ||
}> | I<"missing_key", { | ||
@@ -97,4 +100,4 @@ key: Key; | ||
default<T, This extends this>(this: This, defaultValue: T): DefaultOutput<This, T>; | ||
assert<T extends SomethingOutput | NothingOutput, This extends this>(this: This, func: (v: SomethingOutput | NothingOutput) => v is T, error?: CustomError): TransformType<This, T, OutputFlags>; | ||
assert<T extends SomethingOutput | NothingOutput, This extends this>(this: This, func: (v: SomethingOutput | NothingOutput) => boolean, error?: CustomError): TransformType<This, T, OutputFlags>; | ||
assert<T extends SomethingOutput | NothingOutput, This extends this = this>(this: This, func: (v: SomethingOutput | NothingOutput) => v is T, error?: CustomError): TransformType<This, T, OutputFlags>; | ||
assert<T extends SomethingOutput | NothingOutput, This extends this = this>(this: This, func: (v: SomethingOutput | NothingOutput) => boolean, error?: CustomError): TransformType<This, T, OutputFlags>; | ||
map<T, This extends this>(this: This, func: (v: SomethingOutput | NothingOutput) => T): TransformType<This, T, Exclude<OutputFlags, "outputs_nothing"> | "outputs_something">; | ||
@@ -123,8 +126,16 @@ chain<T, This extends this>(this: This, func: (v: SomethingOutput | NothingOutput) => ChainResult<T>): TransformType<This, T, Exclude<OutputFlags, "outputs_nothing"> | "outputs_something">; | ||
} | ||
declare class ArrayType<T extends Type = Type> extends Type<Type.SomethingOutputOf<T>[], never, "accepts_something", "outputs_something"> { | ||
readonly item: T; | ||
declare type TupleOutput<T extends Type[]> = { | ||
[K in keyof T]: T[K] extends Type<infer U> ? U : never; | ||
}; | ||
declare type ArrayOutput<Head extends Type[], Rest extends Type | undefined> = [ | ||
...TupleOutput<Head>, | ||
...(Rest extends Type ? Type.SomethingOutputOf<Rest>[] : []) | ||
]; | ||
declare class ArrayType<Head extends Type[] = Type[], Rest extends Type | undefined = Type | undefined> extends Type<ArrayOutput<Head, Rest>, never, "accepts_something", "outputs_something"> { | ||
readonly head: Head; | ||
readonly rest?: Rest | undefined; | ||
readonly name = "array"; | ||
constructor(item: T); | ||
constructor(head: Head, rest?: Rest | undefined); | ||
toTerminals(into: TerminalType[]): void; | ||
genFunc(): Func<Type.SomethingOutputOf<T>[]>; | ||
genFunc(): Func<ArrayOutput<Head, Rest>>; | ||
} | ||
@@ -138,2 +149,7 @@ declare class UnionType<T extends Type[] = Type[]> extends Type<Type.SomethingOutputOf<T[number]>, Type.NothingOutputOf<T[number]>, Type.InputFlagsOf<T[number]>, Type.OutputFlagsOf<T[number]>> { | ||
} | ||
declare class NeverType extends Type<never, never, never, never> { | ||
readonly name = "never"; | ||
genFunc(): Func<never>; | ||
toTerminals(into: TerminalType[]): void; | ||
} | ||
declare class NothingType extends Type<never, never, "accepts_nothing", "outputs_nothing"> { | ||
@@ -201,3 +217,3 @@ readonly name = "nothing"; | ||
} | ||
declare function nothing(): NothingType; | ||
declare function never(): NeverType; | ||
declare function unknown(): UnknownType; | ||
@@ -211,8 +227,10 @@ declare function number(): NumberType; | ||
declare function object<T extends Record<string, Type>>(obj: T): ObjectType<T, undefined>; | ||
declare function array<T extends Type>(item: T): ArrayType<T>; | ||
declare function record<T extends Type>(valueType: T): Type<Record<string, Type.SomethingOutputOf<T>>, never, "accepts_something", "outputs_something">; | ||
declare function array<T extends Type>(item: T): ArrayType<[], T>; | ||
declare function tuple<T extends [] | [Type, ...Type[]]>(items: T): ArrayType<T, undefined>; | ||
declare function literal<T extends Literal>(value: T): LiteralType<T>; | ||
declare function union<T extends Type[]>(...options: T): UnionType<T>; | ||
declare type TerminalType = NothingType | UnknownType | StringType | NumberType | BigIntType | BooleanType | UndefinedType | NullType | ObjectType | ArrayType | LiteralType; | ||
export { nothing, unknown, number, bigint, string, boolean, object, array, literal, union, null_ as null, undefined_ as undefined, ok, err, }; | ||
declare type TerminalType = NeverType | NothingType | UnknownType | StringType | NumberType | BigIntType | BooleanType | UndefinedType | NullType | ObjectType | ArrayType | LiteralType; | ||
export { never, unknown, number, bigint, string, boolean, object, record, array, tuple, literal, union, null_ as null, undefined_ as undefined, ok, err, }; | ||
declare type Infer<T extends Type> = Type.SomethingOutputOf<T>; | ||
export type { Infer, Type }; |
{ | ||
"name": "@badrap/valita", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"description": "A validation & parsing library for TypeScript", | ||
@@ -5,0 +5,0 @@ "main": "./dist/main/index.js", |
@@ -36,2 +36,3 @@ // This is magic that turns object intersections to nicer-looking types. | ||
| I<"invalid_literal", { expected: Literal[] }> | ||
| I<"invalid_length", { minLength: number; maxLength: number }> | ||
| I<"missing_key", { key: Key }> | ||
@@ -305,3 +306,3 @@ | I<"unrecognized_key", { key: Key }> | ||
assert<T extends SomethingOutput | NothingOutput, This extends this>( | ||
assert<T extends SomethingOutput | NothingOutput, This extends this = this>( | ||
this: This, | ||
@@ -311,3 +312,3 @@ func: (v: SomethingOutput | NothingOutput) => v is T, | ||
): TransformType<This, T, OutputFlags>; | ||
assert<T extends SomethingOutput | NothingOutput, This extends this>( | ||
assert<T extends SomethingOutput | NothingOutput, This extends this = this>( | ||
this: This, | ||
@@ -317,3 +318,3 @@ func: (v: SomethingOutput | NothingOutput) => boolean, | ||
): TransformType<This, T, OutputFlags>; | ||
assert<T extends SomethingOutput | NothingOutput, This extends this>( | ||
assert<T extends SomethingOutput | NothingOutput, This extends this = this>( | ||
this: This, | ||
@@ -503,4 +504,16 @@ func: (v: SomethingOutput | NothingOutput) => boolean, | ||
class ArrayType<T extends Type = Type> extends Type< | ||
Type.SomethingOutputOf<T>[], | ||
type TupleOutput<T extends Type[]> = { | ||
[K in keyof T]: T[K] extends Type<infer U> ? U : never; | ||
}; | ||
type ArrayOutput<Head extends Type[], Rest extends Type | undefined> = [ | ||
...TupleOutput<Head>, | ||
...(Rest extends Type ? Type.SomethingOutputOf<Rest>[] : []) | ||
]; | ||
class ArrayType< | ||
Head extends Type[] = Type[], | ||
Rest extends Type | undefined = Type | undefined | ||
> extends Type< | ||
ArrayOutput<Head, Rest>, | ||
never, | ||
@@ -512,3 +525,3 @@ "accepts_something", | ||
constructor(readonly item: T) { | ||
constructor(readonly head: Head, readonly rest?: Rest) { | ||
super(); | ||
@@ -521,11 +534,28 @@ } | ||
genFunc(): Func<Type.SomethingOutputOf<T>[]> { | ||
const func = this.item.func; | ||
genFunc(): Func<ArrayOutput<Head, Rest>> { | ||
const headFuncs = this.head.map((t) => t.func); | ||
const restFunc = (this.rest ?? never()).func; | ||
const minLength = headFuncs.length; | ||
const maxLength = this.rest ? Infinity : minLength; | ||
const invalidType: Issue = { code: "invalid_type", expected: ["array"] }; | ||
const invalidLength: Issue = { | ||
code: "invalid_length", | ||
minLength, | ||
maxLength, | ||
}; | ||
return (arr, mode) => { | ||
if (!Array.isArray(arr)) { | ||
return { code: "invalid_type", expected: ["array"] }; | ||
return invalidType; | ||
} | ||
const length = arr.length; | ||
if (length < minLength || length > maxLength) { | ||
return invalidLength; | ||
} | ||
let issueTree: IssueTree | undefined = undefined; | ||
let output: Type.SomethingOutputOf<T>[] = arr; | ||
let output: unknown[] = arr; | ||
for (let i = 0; i < arr.length; i++) { | ||
const func = i < minLength ? headFuncs[i] : restFunc; | ||
const r = func(arr[i], mode); | ||
@@ -537,3 +567,3 @@ if (r !== true) { | ||
} | ||
output[i] = r.value as Type.SomethingOutputOf<T>; | ||
output[i] = r.value; | ||
} else { | ||
@@ -549,3 +579,3 @@ issueTree = joinIssues(prependPath(i, r), issueTree); | ||
} else { | ||
return { code: "ok", value: output }; | ||
return { code: "ok", value: output as ArrayOutput<Head, Rest> }; | ||
} | ||
@@ -629,3 +659,5 @@ }; | ||
const terminal = terminals[j]; | ||
if (terminal.name === "unknown") { | ||
if (terminal.name === "never") { | ||
// skip | ||
} else if (terminal.name === "unknown") { | ||
unknowns.push(i); | ||
@@ -714,3 +746,5 @@ } else if (terminal.name === "nothing") { | ||
t.forEach(({ root, terminal }) => { | ||
if (terminal.name === "nothing") { | ||
if (terminal.name === "never") { | ||
// skip | ||
} else if (terminal.name === "nothing") { | ||
nothings.push(root); | ||
@@ -863,2 +897,12 @@ } else if (terminal.name === "unknown") { | ||
class NeverType extends Type<never, never, never, never> { | ||
readonly name = "never"; | ||
genFunc(): Func<never> { | ||
const issue: Issue = { code: "invalid_type", expected: [] }; | ||
return (v, _mode) => (v === Nothing ? true : issue); | ||
} | ||
toTerminals(into: TerminalType[]): void { | ||
into.push(this); | ||
} | ||
} | ||
class NothingType extends Type< | ||
@@ -1100,2 +1144,5 @@ never, | ||
function never(): NeverType { | ||
return new NeverType(); | ||
} | ||
function nothing(): NothingType { | ||
@@ -1130,5 +1177,20 @@ return new NothingType(); | ||
} | ||
function array<T extends Type>(item: T): ArrayType<T> { | ||
return new ArrayType(item); | ||
function record<T extends Type>( | ||
valueType: T | ||
): Type< | ||
Record<string, Type.SomethingOutputOf<T>>, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
return new ObjectType({} as Record<string, never>, valueType); | ||
} | ||
function array<T extends Type>(item: T): ArrayType<[], T> { | ||
return new ArrayType([], item); | ||
} | ||
function tuple<T extends [] | [Type, ...Type[]]>( | ||
items: T | ||
): ArrayType<T, undefined> { | ||
return new ArrayType(items); | ||
} | ||
function literal<T extends Literal>(value: T): LiteralType<T> { | ||
@@ -1142,2 +1204,3 @@ return new LiteralType(value); | ||
type TerminalType = | ||
| NeverType | ||
| NothingType | ||
@@ -1156,3 +1219,3 @@ | UnknownType | ||
export { | ||
nothing, | ||
never, | ||
unknown, | ||
@@ -1164,3 +1227,5 @@ number, | ||
object, | ||
record, | ||
array, | ||
tuple, | ||
literal, | ||
@@ -1167,0 +1232,0 @@ union, |
107372
3215