@badrap/valita
Advanced tools
Comparing version 0.0.14 to 0.0.16
@@ -66,2 +66,6 @@ declare type PrettyIntersection<V> = Extract<{ | ||
}; | ||
declare function ok<T extends Literal>(value: T): { | ||
ok: true; | ||
value: T; | ||
}; | ||
declare function ok<T>(value: T): { | ||
@@ -75,42 +79,36 @@ ok: true; | ||
}; | ||
declare namespace Type { | ||
type InputFlags = "accepts_something" | "accepts_undefined" | "accepts_nothing"; | ||
type OutputFlags = "outputs_something" | "outputs_nothing"; | ||
type InputFlagsOf<T> = T extends Type<unknown, unknown, infer I, OutputFlags> ? I : never; | ||
type OutputFlagsOf<T> = T extends Type<unknown, unknown, InputFlags, infer I> ? I : never; | ||
type SomethingOutputOf<T extends Type> = T extends Type<infer I, unknown> ? I : never; | ||
type NothingOutputOf<T extends Type> = T extends Type<unknown, infer I> ? I : never; | ||
declare type DefaultOutput<Output, DefaultValue> = Type<Exclude<Output, undefined> | DefaultValue>; | ||
declare const isOptional: unique symbol; | ||
declare class Optional { | ||
protected readonly [isOptional]: true; | ||
} | ||
declare type DefaultOutput<T extends Type, DefaultValue> = Type<undefined extends Type.SomethingOutputOf<T> | ("accepts_undefined" extends Type.InputFlagsOf<T> ? never : undefined) ? DefaultValue | Exclude<Type.SomethingOutputOf<T>, undefined> : Type.SomethingOutputOf<T>, undefined extends Type.NothingOutputOf<T> | ("accepts_nothing" extends Type.InputFlagsOf<T> ? never : undefined) | ("outputs_nothing" extends Type.OutputFlagsOf<T> ? undefined : never) ? DefaultValue | Exclude<Type.NothingOutputOf<T>, undefined> : Type.NothingOutputOf<T>, "accepts_nothing" | "accepts_undefined" | "accepts_something" | Type.InputFlagsOf<T>, Exclude<Type.OutputFlagsOf<T>, "outputs_nothing"> | "outputs_something">; | ||
declare abstract class Type<SomethingOutput = unknown, NothingOutput = unknown, InputFlags extends Type.InputFlags = Type.InputFlags, OutputFlags extends Type.OutputFlags = Type.OutputFlags> { | ||
protected _types: { | ||
somethingOutput: SomethingOutput; | ||
nothingOutput: NothingOutput; | ||
inputFlags: InputFlags; | ||
outputFlags: OutputFlags; | ||
}; | ||
declare type IfOptional<T extends Type, Then, Else> = T extends Optional ? Then : Else; | ||
declare abstract class Type<Output = unknown> { | ||
abstract readonly name: string; | ||
abstract genFunc(): Func<SomethingOutput | NothingOutput>; | ||
abstract genFunc(): Func<Output>; | ||
abstract toTerminals(into: TerminalType[]): void; | ||
get func(): Func<SomethingOutput | NothingOutput>; | ||
parse<This extends this>(v: unknown, options?: Partial<ParseOptions>): Type.SomethingOutputOf<This>; | ||
optional<This extends this>(this: This): OptionalType<This>; | ||
default<T extends Literal, This extends this>(this: This, defaultValue: T): DefaultOutput<This, T>; | ||
default<T, This extends this>(this: This, defaultValue: T): DefaultOutput<This, T>; | ||
assert<T extends SomethingOutput | NothingOutput, This extends this = this>(this: This, func: ((v: SomethingOutput | NothingOutput) => v is T) | ((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">; | ||
chain<T, This extends this>(this: This, func: (v: SomethingOutput | NothingOutput) => ChainResult<T>): TransformType<This, T, Exclude<OutputFlags, "outputs_nothing"> | "outputs_something">; | ||
get func(): Func<Output>; | ||
parse<T extends Type>(this: T, v: unknown, options?: Partial<ParseOptions>): Infer<T>; | ||
optional(): Type<Output | undefined> & Optional; | ||
default<T extends Literal>(defaultValue: T): DefaultOutput<Output, T>; | ||
default<T>(defaultValue: T): DefaultOutput<Output, T>; | ||
assert<T extends Output>(func: ((v: Output) => v is T) | ((v: Output) => boolean), error?: CustomError): Type<T>; | ||
map<T extends Literal>(func: (v: Output) => T): Type<T>; | ||
map<T>(func: (v: Output) => T): Type<T>; | ||
chain<T extends Literal>(func: (v: Output) => ChainResult<T>): Type<T>; | ||
chain<T>(func: (v: Output) => ChainResult<T>): Type<T>; | ||
} | ||
declare type Optionals<T extends Record<string, Type>> = { | ||
[K in keyof T]: "outputs_nothing" | "outputs_something" extends Type.OutputFlagsOf<T[K]> ? K : never; | ||
export declare type Infer<T extends Type> = T extends Type<infer I> ? I : never; | ||
declare type ObjectShape = Record<string, Type>; | ||
declare type Optionals<T extends ObjectShape> = { | ||
[K in keyof T]: IfOptional<T[K], K, never>; | ||
}[keyof T]; | ||
declare type ObjectShape = Record<string, Type>; | ||
declare type ObjectOutput<T extends ObjectShape, R extends Type | undefined> = PrettyIntersection<{ | ||
[K in Optionals<T>]?: Type.SomethingOutputOf<T[K]> | Type.NothingOutputOf<T[K]>; | ||
[K in Optionals<T>]?: Infer<T[K]>; | ||
} & { | ||
[K in Exclude<keyof T, Optionals<T>>]: Type.SomethingOutputOf<T[K]> | Type.NothingOutputOf<T[K]>; | ||
} & (R extends Type ? { | ||
[K: string]: Type.SomethingOutputOf<R>; | ||
[K in Exclude<keyof T, Optionals<T>>]: Infer<T[K]>; | ||
} & (R extends Type<infer I> ? { | ||
[K: string]: I; | ||
} : unknown)>; | ||
declare class ObjectType<Shape extends ObjectShape = ObjectShape, Rest extends Type | undefined = Type | undefined> extends Type<ObjectOutput<Shape, Rest>, never, "accepts_something", "outputs_something"> { | ||
declare class ObjectType<Shape extends ObjectShape = ObjectShape, Rest extends Type | undefined = Type | undefined> extends Type<ObjectOutput<Shape, Rest>> { | ||
readonly shape: Shape; | ||
@@ -135,5 +133,5 @@ private readonly restType; | ||
...TupleOutput<Head>, | ||
...(Rest extends Type ? Type.SomethingOutputOf<Rest>[] : []) | ||
...(Rest extends Type ? Infer<Rest>[] : []) | ||
]; | ||
declare class ArrayType<Head extends Type[] = Type[], Rest extends Type | undefined = Type | undefined> extends Type<ArrayOutput<Head, Rest>, never, "accepts_something", "outputs_something"> { | ||
declare class ArrayType<Head extends Type[] = Type[], Rest extends Type | undefined = Type | undefined> extends Type<ArrayOutput<Head, Rest>> { | ||
readonly head: Head; | ||
@@ -146,3 +144,3 @@ readonly rest?: Rest | undefined; | ||
} | ||
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 UnionType<T extends Type[] = Type[]> extends Type<Infer<T[number]>> { | ||
readonly options: T; | ||
@@ -152,5 +150,5 @@ readonly name = "union"; | ||
toTerminals(into: TerminalType[]): void; | ||
genFunc(): Func<Type.SomethingOutputOf<T[number]>>; | ||
genFunc(): Func<Infer<T[number]>>; | ||
} | ||
declare class NeverType extends Type<never, never, never, never> { | ||
declare class NeverType extends Type<never> { | ||
readonly name = "never"; | ||
@@ -160,8 +158,3 @@ genFunc(): Func<never>; | ||
} | ||
declare class NothingType extends Type<never, never, "accepts_nothing", "outputs_nothing"> { | ||
readonly name = "nothing"; | ||
genFunc(): Func<never>; | ||
toTerminals(into: TerminalType[]): void; | ||
} | ||
declare class UnknownType extends Type<unknown, never, "accepts_undefined" | "accepts_something", "outputs_something"> { | ||
declare class UnknownType extends Type<unknown> { | ||
readonly name = "unknown"; | ||
@@ -171,3 +164,3 @@ genFunc(): Func<unknown>; | ||
} | ||
declare class NumberType extends Type<number, never, "accepts_something", "outputs_something"> { | ||
declare class NumberType extends Type<number> { | ||
readonly name = "number"; | ||
@@ -177,3 +170,3 @@ genFunc(): Func<number>; | ||
} | ||
declare class StringType extends Type<string, never, "accepts_something", "outputs_something"> { | ||
declare class StringType extends Type<string> { | ||
readonly name = "string"; | ||
@@ -183,3 +176,3 @@ genFunc(): Func<string>; | ||
} | ||
declare class BigIntType extends Type<bigint, never, "accepts_something", "outputs_something"> { | ||
declare class BigIntType extends Type<bigint> { | ||
readonly name = "bigint"; | ||
@@ -189,3 +182,3 @@ genFunc(): Func<bigint>; | ||
} | ||
declare class BooleanType extends Type<boolean, never, "accepts_something", "outputs_something"> { | ||
declare class BooleanType extends Type<boolean> { | ||
readonly name = "boolean"; | ||
@@ -195,3 +188,3 @@ genFunc(): Func<boolean>; | ||
} | ||
declare class UndefinedType extends Type<undefined, never, "accepts_undefined" | "accepts_something", "outputs_something"> { | ||
declare class UndefinedType extends Type<undefined> { | ||
readonly name = "undefined"; | ||
@@ -201,3 +194,3 @@ genFunc(): Func<undefined>; | ||
} | ||
declare class NullType extends Type<null, never, "accepts_something", "outputs_something"> { | ||
declare class NullType extends Type<null> { | ||
readonly name = "null"; | ||
@@ -207,3 +200,3 @@ genFunc(): Func<null>; | ||
} | ||
declare class LiteralType<Out extends Literal = Literal> extends Type<Out, never, "accepts_something", "outputs_something"> { | ||
declare class LiteralType<Out extends Literal = Literal> extends Type<Out> { | ||
readonly value: Out; | ||
@@ -215,17 +208,9 @@ readonly name = "literal"; | ||
} | ||
declare class OptionalType<T extends Type> extends Type<Type.SomethingOutputOf<T> | ("accepts_undefined" extends Type.InputFlagsOf<T> ? never : undefined), Type.NothingOutputOf<T> | ("accepts_nothing" extends Type.InputFlagsOf<T> ? never : undefined), "accepts_something" | "accepts_undefined" | "accepts_nothing" | Type.InputFlagsOf<T>, ("accepts_nothing" extends Type.InputFlagsOf<T> ? Type.OutputFlagsOf<T> : "outputs_nothing") | ("accepts_undefined" extends Type.InputFlagsOf<T> ? Type.OutputFlagsOf<T> : "outputs_something")> { | ||
declare class OptionalType<Output = unknown> extends Type<Output | undefined> { | ||
private readonly type; | ||
readonly name = "optional"; | ||
constructor(type: T); | ||
genFunc(): Func<Type.SomethingOutputOf<T> | ("accepts_undefined" extends Type.InputFlagsOf<T> ? never : undefined)>; | ||
constructor(type: Type<Output>); | ||
genFunc(): Func<Output>; | ||
toTerminals(into: TerminalType[]): void; | ||
} | ||
declare class TransformType<T extends Type, Out, OutputFlags extends Type.OutputFlags, X = "accepts_something" extends Type.InputFlagsOf<T> ? Out : never, Y = "accepts_nothing" extends Type.InputFlagsOf<T> ? Out : never> extends Type<X, Y, Type.InputFlagsOf<T>, OutputFlags> { | ||
protected readonly transformed: Type; | ||
protected readonly transform: Func<unknown>; | ||
readonly name = "transform"; | ||
constructor(transformed: Type, transform: Func<unknown>); | ||
genFunc(): Func<X | Y>; | ||
toTerminals(into: TerminalType[]): void; | ||
} | ||
declare function never(): NeverType; | ||
@@ -240,10 +225,10 @@ declare function unknown(): UnknownType; | ||
declare function object<T extends Record<string, Type>>(obj: T): ObjectType<T, undefined>; | ||
declare function record<T extends Type>(valueType: T): Type<Record<string, Type.SomethingOutputOf<T>>, never, "accepts_something", "outputs_something">; | ||
declare function record<T extends Type>(valueType: T): Type<Record<string, Infer<T>>>; | ||
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 = NeverType | NothingType | UnknownType | StringType | NumberType | BigIntType | BooleanType | UndefinedType | NullType | ObjectType | ArrayType | LiteralType; | ||
declare function union<T extends Type[]>(...options: T): UnionType<T> & (true extends IfOptional<T[number], true, false> ? Optional : unknown); | ||
declare type TerminalType = NeverType | UnknownType | StringType | NumberType | BigIntType | BooleanType | UndefinedType | NullType | ObjectType | ArrayType | LiteralType | OptionalType; | ||
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 }; | ||
export type { Type }; | ||
//# sourceMappingURL=index.d.ts.map |
{ | ||
"name": "@badrap/valita", | ||
"version": "0.0.14", | ||
"version": "0.0.16", | ||
"description": "A validation & parsing library for TypeScript", | ||
"main": "./dist/main/index.js", | ||
"main": "./dist/cjs/index.js", | ||
"module": "./dist/mjs/index.js", | ||
"types": "./dist/types/index.d.ts", | ||
"exports": { | ||
"node": "./dist/node/index.js", | ||
"default": "./dist/main/index.js" | ||
"node": { | ||
"module": "./dist/node-mjs/index.js", | ||
"import": "./dist/node-mjs/index.js", | ||
"require": "./dist/node-cjs/index.js" | ||
}, | ||
"default": "./dist/mjs/index.js" | ||
}, | ||
@@ -19,23 +24,28 @@ "sideEffects": false, | ||
"test": "mocha --require ts-node/register tests/**/*.test.ts", | ||
"build": "rm -rf dist/* && npm run build:types && npm run build:main && npm run build:node", | ||
"build:types": "tsc -p ./tsconfig.build.json --emitDeclarationOnly --declaration --declarationDir ./dist/types", | ||
"build:main": "tsc -p ./tsconfig.build.json --target es5 --outDir ./dist/main", | ||
"build:node": "tsc -p ./tsconfig.build.json --target es2019 --outDir ./dist/node", | ||
"build": "rm -rf dist/* && npm run build:types && npm run build:cjs && npm run build:mjs && npm run build:node-mjs && npm run build:node-cjs && echo '{\"type\": \"module\"}' > ./dist/package.json", | ||
"build:types": "tsc -p ./tsconfig.build.json --emitDeclarationOnly --declaration --declarationMap --declarationDir ./dist/types", | ||
"build:cjs": "tsc -p ./tsconfig.build.json --target es5 --module commonjs --outDir ./dist/cjs", | ||
"build:mjs": "tsc -p ./tsconfig.build.json --target es5 --module es2015 --outDir ./dist/mjs", | ||
"build:node-mjs": "tsc -p ./tsconfig.build.json --target es2019 --module es2015 --outDir ./dist/node-mjs", | ||
"build:node-cjs": "tsc -p ./tsconfig.build.json --target es2019 --module commonjs --outDir ./dist/node-cjs && echo '{\"type\": \"commonjs\"}' > ./dist/node-cjs/package.json", | ||
"prepack": "npm run build" | ||
}, | ||
"dependencies": { | ||
"tslib": "^2.3.0" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "^4.2.15", | ||
"@types/mocha": "^8.2.1", | ||
"@types/node": "^14.14.31", | ||
"@typescript-eslint/eslint-plugin": "^4.15.2", | ||
"@typescript-eslint/parser": "^4.15.2", | ||
"chai": "^4.3.0", | ||
"eslint": "^7.20.0", | ||
"eslint-config-prettier": "^8.1.0", | ||
"eslint-plugin-prettier": "^3.3.1", | ||
"mocha": "^8.3.0", | ||
"prettier": "^2.2.1", | ||
"@types/chai": "^4.2.19", | ||
"@types/mocha": "^8.2.2", | ||
"@types/node": "^16.0.0", | ||
"@typescript-eslint/eslint-plugin": "^4.28.1", | ||
"@typescript-eslint/parser": "^4.28.1", | ||
"chai": "^4.3.4", | ||
"eslint": "^7.30.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint-plugin-prettier": "^3.4.0", | ||
"mocha": "^9.0.2", | ||
"prettier": "^2.3.2", | ||
"ts-expect": "^1.3.0", | ||
"ts-node": "^9.1.1", | ||
"typescript": "^4.2.2" | ||
"ts-node": "^10.0.0", | ||
"typescript": "^4.3.5" | ||
}, | ||
@@ -42,0 +52,0 @@ "files": [ |
@@ -73,4 +73,16 @@ # @badrap/valita [![tests](https://github.com/badrap/valita/workflows/tests/badge.svg)](https://github.com/badrap/valita/actions?query=workflow%3Atests) [![npm](https://img.shields.io/npm/v/@badrap/valita.svg)](https://www.npmjs.com/package/@badrap/valita) | ||
### Custom validation functions | ||
The `.assert()`-method can be used for custom validation logic like verifying that a number is inside a certain range for example. | ||
```js | ||
import * as v from "@badrap/valita"; | ||
const schema = v | ||
.number() | ||
.assert((v) => v >= 0 && v <= 255, "Must be in between 0 or 255"); | ||
``` | ||
## License | ||
This library is licensed under the MIT license. See [LICENSE](./LICENSE). |
395
src/index.ts
@@ -243,2 +243,4 @@ // This is magic that turns object intersections to nicer-looking types. | ||
function ok<T extends Literal>(value: T): { ok: true; value: T }; | ||
function ok<T>(value: T): { ok: true; value: T }; | ||
function ok<T>(value: T): { ok: true; value: T } { | ||
@@ -254,59 +256,18 @@ return { ok: true, value }; | ||
declare namespace Type { | ||
type InputFlags = | ||
| "accepts_something" | ||
| "accepts_undefined" | ||
| "accepts_nothing"; | ||
type OutputFlags = "outputs_something" | "outputs_nothing"; | ||
type InputFlagsOf<T> = T extends Type<unknown, unknown, infer I, OutputFlags> | ||
? I | ||
: never; | ||
type OutputFlagsOf<T> = T extends Type<unknown, unknown, InputFlags, infer I> | ||
? I | ||
: never; | ||
type SomethingOutputOf<T extends Type> = T extends Type<infer I, unknown> | ||
? I | ||
: never; | ||
type NothingOutputOf<T extends Type> = T extends Type<unknown, infer I> | ||
? I | ||
: never; | ||
} | ||
type DefaultOutput<T extends Type, DefaultValue> = Type< | ||
undefined extends | ||
| Type.SomethingOutputOf<T> | ||
| ("accepts_undefined" extends Type.InputFlagsOf<T> ? never : undefined) | ||
? DefaultValue | Exclude<Type.SomethingOutputOf<T>, undefined> | ||
: Type.SomethingOutputOf<T>, | ||
undefined extends | ||
| Type.NothingOutputOf<T> | ||
| ("accepts_nothing" extends Type.InputFlagsOf<T> ? never : undefined) | ||
| ("outputs_nothing" extends Type.OutputFlagsOf<T> ? undefined : never) | ||
? DefaultValue | Exclude<Type.NothingOutputOf<T>, undefined> | ||
: Type.NothingOutputOf<T>, | ||
| "accepts_nothing" | ||
| "accepts_undefined" | ||
| "accepts_something" | ||
| Type.InputFlagsOf<T>, | ||
Exclude<Type.OutputFlagsOf<T>, "outputs_nothing"> | "outputs_something" | ||
type DefaultOutput<Output, DefaultValue> = Type< | ||
Exclude<Output, undefined> | DefaultValue | ||
>; | ||
abstract class Type< | ||
SomethingOutput = unknown, | ||
NothingOutput = unknown, | ||
InputFlags extends Type.InputFlags = Type.InputFlags, | ||
OutputFlags extends Type.OutputFlags = Type.OutputFlags | ||
> { | ||
protected declare _types: { | ||
somethingOutput: SomethingOutput; | ||
nothingOutput: NothingOutput; | ||
inputFlags: InputFlags; | ||
outputFlags: OutputFlags; | ||
}; | ||
declare const isOptional: unique symbol; | ||
declare class Optional { | ||
protected readonly [isOptional]: true; | ||
} | ||
type IfOptional<T extends Type, Then, Else> = T extends Optional ? Then : Else; | ||
abstract class Type<Output = unknown> { | ||
abstract readonly name: string; | ||
abstract genFunc(): Func<SomethingOutput | NothingOutput>; | ||
abstract genFunc(): Func<Output>; | ||
abstract toTerminals(into: TerminalType[]): void; | ||
get func(): Func<SomethingOutput | NothingOutput> { | ||
get func(): Func<Output> { | ||
const f = this.genFunc(); | ||
@@ -320,6 +281,7 @@ Object.defineProperty(this, "func", { | ||
parse<This extends this>( | ||
parse<T extends Type>( | ||
this: T, | ||
v: unknown, | ||
options?: Partial<ParseOptions> | ||
): Type.SomethingOutputOf<This> { | ||
): Infer<T> { | ||
let mode: FuncMode = FuncMode.PASS; | ||
@@ -334,5 +296,5 @@ if (options && options.mode === "strict") { | ||
if (r === true) { | ||
return v as Type.SomethingOutputOf<This>; | ||
return v as Infer<T>; | ||
} else if (r.code === "ok") { | ||
return r.value as Type.SomethingOutputOf<This>; | ||
return r.value as Infer<T>; | ||
} else { | ||
@@ -343,60 +305,39 @@ throw new ValitaError(r); | ||
optional<This extends this>(this: This): OptionalType<This> { | ||
return new OptionalType(this); | ||
optional(): Type<Output | undefined> & Optional { | ||
return new OptionalType(this) as OptionalType<Output> & Optional; | ||
} | ||
default<T extends Literal, This extends this>( | ||
this: This, | ||
defaultValue: T | ||
): DefaultOutput<This, T>; | ||
default<T extends Literal>(defaultValue: T): DefaultOutput<Output, T>; | ||
default<T>(defaultValue: T): DefaultOutput<Output, T>; | ||
default<T, This extends this>( | ||
this: This, | ||
defaultValue: T | ||
): DefaultOutput<This, T>; | ||
default<T, This extends this>( | ||
this: This, | ||
defaultValue: T | ||
): DefaultOutput<This, T> { | ||
return (this.optional().map((v) => | ||
): DefaultOutput<Output, T> { | ||
return this.optional().map((v) => | ||
v === undefined ? defaultValue : v | ||
) as unknown) as DefaultOutput<This, T>; | ||
) as unknown as DefaultOutput<Output, T>; | ||
} | ||
assert<T extends SomethingOutput | NothingOutput, This extends this = this>( | ||
this: This, | ||
func: | ||
| ((v: SomethingOutput | NothingOutput) => v is T) | ||
| ((v: SomethingOutput | NothingOutput) => boolean), | ||
assert<T extends Output>( | ||
func: ((v: Output) => v is T) | ((v: Output) => boolean), | ||
error?: CustomError | ||
): TransformType<This, T, OutputFlags> { | ||
const err = { code: "custom_error", error } as const; | ||
return new TransformType(this, (v) => | ||
func(v as SomethingOutput | NothingOutput) ? true : err | ||
); | ||
): Type<T> { | ||
const err: Issue = { code: "custom_error", error }; | ||
return new TransformType(this, (v) => (func(v as Output) ? true : err)); | ||
} | ||
map<T, This extends this>( | ||
this: This, | ||
func: (v: SomethingOutput | NothingOutput) => T | ||
): TransformType< | ||
This, | ||
T, | ||
Exclude<OutputFlags, "outputs_nothing"> | "outputs_something" | ||
> { | ||
map<T extends Literal>(func: (v: Output) => T): Type<T>; | ||
map<T>(func: (v: Output) => T): Type<T>; | ||
map<T>(func: (v: Output) => T): Type<T> { | ||
return new TransformType(this, (v) => ({ | ||
code: "ok", | ||
value: func(v as SomethingOutput | NothingOutput), | ||
value: func(v as Output), | ||
})); | ||
} | ||
chain<T, This extends this>( | ||
this: This, | ||
func: (v: SomethingOutput | NothingOutput) => ChainResult<T> | ||
): TransformType< | ||
This, | ||
T, | ||
Exclude<OutputFlags, "outputs_nothing"> | "outputs_something" | ||
> { | ||
chain<T extends Literal>(func: (v: Output) => ChainResult<T>): Type<T>; | ||
chain<T>(func: (v: Output) => ChainResult<T>): Type<T>; | ||
chain<T>(func: (v: Output) => ChainResult<T>): Type<T> { | ||
return new TransformType(this, (v) => { | ||
const r = func(v as SomethingOutput | NothingOutput); | ||
const r = func(v as Output); | ||
if (r.ok) { | ||
@@ -411,12 +352,10 @@ return { code: "ok", value: r.value }; | ||
type Optionals<T extends Record<string, Type>> = { | ||
[K in keyof T]: | ||
| "outputs_nothing" | ||
| "outputs_something" extends Type.OutputFlagsOf<T[K]> | ||
? K | ||
: never; | ||
}[keyof T]; | ||
export type Infer<T extends Type> = T extends Type<infer I> ? I : never; | ||
type ObjectShape = Record<string, Type>; | ||
type Optionals<T extends ObjectShape> = { | ||
[K in keyof T]: IfOptional<T[K], K, never>; | ||
}[keyof T]; | ||
type ObjectOutput< | ||
@@ -427,12 +366,8 @@ T extends ObjectShape, | ||
{ | ||
[K in Optionals<T>]?: | ||
| Type.SomethingOutputOf<T[K]> | ||
| Type.NothingOutputOf<T[K]>; | ||
[K in Optionals<T>]?: Infer<T[K]>; | ||
} & | ||
{ | ||
[K in Exclude<keyof T, Optionals<T>>]: | ||
| Type.SomethingOutputOf<T[K]> | ||
| Type.NothingOutputOf<T[K]>; | ||
[K in Exclude<keyof T, Optionals<T>>]: Infer<T[K]>; | ||
} & | ||
(R extends Type ? { [K: string]: Type.SomethingOutputOf<R> } : unknown) | ||
(R extends Type<infer I> ? { [K: string]: I } : unknown) | ||
>; | ||
@@ -443,8 +378,3 @@ | ||
Rest extends Type | undefined = Type | undefined | ||
> extends Type< | ||
ObjectOutput<Shape, Rest>, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
> extends Type<ObjectOutput<Shape, Rest>> { | ||
readonly name = "object"; | ||
@@ -464,3 +394,3 @@ | ||
toTerminals(into: TerminalType[]): void { | ||
into.push(this); | ||
into.push(this as ObjectType); | ||
} | ||
@@ -498,3 +428,3 @@ | ||
const isRequired = !hasTerminal(shape[key], "nothing"); | ||
const isRequired = !hasTerminal(shape[key], "optional"); | ||
required.push(isRequired); | ||
@@ -603,3 +533,3 @@ if (isRequired) { | ||
...TupleOutput<Head>, | ||
...(Rest extends Type ? Type.SomethingOutputOf<Rest>[] : []) | ||
...(Rest extends Type ? Infer<Rest>[] : []) | ||
]; | ||
@@ -610,8 +540,3 @@ | ||
Rest extends Type | undefined = Type | undefined | ||
> extends Type< | ||
ArrayOutput<Head, Rest>, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
> extends Type<ArrayOutput<Head, Rest>> { | ||
readonly name = "array"; | ||
@@ -717,7 +642,5 @@ | ||
function createObjectMatchers( | ||
t: { root: Type; terminal: TerminalType }[] | ||
): { | ||
function createObjectMatchers(t: { root: Type; terminal: TerminalType }[]): { | ||
key: string; | ||
nothing?: Type; | ||
optional?: Type; | ||
matcher: ( | ||
@@ -743,3 +666,3 @@ rootValue: unknown, | ||
const literals = new Map<unknown, number[]>(); | ||
let nothings = [] as number[]; | ||
let optionals = [] as number[]; | ||
let unknowns = [] as number[]; | ||
@@ -755,4 +678,4 @@ for (let i = 0; i < shapes.length; i++) { | ||
unknowns.push(i); | ||
} else if (terminal.name === "nothing") { | ||
nothings.push(i); | ||
} else if (terminal.name === "optional") { | ||
optionals.push(i); | ||
} else if (terminal.name === "literal") { | ||
@@ -769,4 +692,4 @@ const options = literals.get(terminal.value) || []; | ||
} | ||
nothings = dedup(nothings); | ||
if (nothings.length > 1) { | ||
optionals = dedup(optionals); | ||
if (optionals.length > 1) { | ||
return false; | ||
@@ -805,7 +728,7 @@ } | ||
); | ||
let nothing: Type | undefined = undefined; | ||
let optional: Type | undefined = undefined; | ||
for (let i = 0; i < flattened.length; i++) { | ||
const { root, terminal } = flattened[i]; | ||
if (terminal.name === "nothing") { | ||
nothing = root; | ||
if (terminal.name === "optional") { | ||
optional = root; | ||
break; | ||
@@ -816,3 +739,3 @@ } | ||
key, | ||
nothing, | ||
optional, | ||
matcher: createUnionMatcher(flattened, [key]), | ||
@@ -839,8 +762,8 @@ }; | ||
let unknowns = [] as Type[]; | ||
let nothings = [] as Type[]; | ||
let optionals = [] as Type[]; | ||
t.forEach(({ root, terminal }) => { | ||
if (terminal.name === "never") { | ||
// skip | ||
} else if (terminal.name === "nothing") { | ||
nothings.push(root); | ||
} else if (terminal.name === "optional") { | ||
optionals.push(root); | ||
} else if (terminal.name === "unknown") { | ||
@@ -870,3 +793,3 @@ unknowns.push(root); | ||
unknowns = dedup(unknowns).sort(byOrder); | ||
nothings = dedup(nothings).sort(byOrder); | ||
optionals = dedup(optionals).sort(byOrder); | ||
types.forEach((roots, type) => | ||
@@ -900,4 +823,4 @@ types.set(type, dedup(roots.concat(unknowns).sort(byOrder))) | ||
if (value === Nothing) { | ||
for (let i = 0; i < nothings.length; i++) { | ||
const r = nothings[i].func(rootValue, mode); | ||
for (let i = 0; i < optionals.length; i++) { | ||
const r = optionals[i].func(rootValue, mode); | ||
if (r === true || r.code === "ok") { | ||
@@ -950,8 +873,3 @@ return r; | ||
class UnionType<T extends Type[] = Type[]> extends Type< | ||
Type.SomethingOutputOf<T[number]>, | ||
Type.NothingOutputOf<T[number]>, | ||
Type.InputFlagsOf<T[number]>, | ||
Type.OutputFlagsOf<T[number]> | ||
> { | ||
class UnionType<T extends Type[] = Type[]> extends Type<Infer<T[number]>> { | ||
readonly name = "union"; | ||
@@ -967,3 +885,3 @@ | ||
genFunc(): Func<Type.SomethingOutputOf<T[number]>> { | ||
genFunc(): Func<Infer<T[number]>> { | ||
const flattened = flatten( | ||
@@ -980,5 +898,5 @@ this.options.map((root) => ({ root, type: root })) | ||
if (value === undefined && !(item.key in v)) { | ||
if (item.nothing) { | ||
return item.nothing.func(Nothing, mode) as Result< | ||
Type.SomethingOutputOf<T[number]> | ||
if (item.optional) { | ||
return item.optional.func(Nothing, mode) as Result< | ||
Infer<T[number]> | ||
>; | ||
@@ -988,7 +906,5 @@ } | ||
} | ||
return item.matcher(v, value, mode) as Result< | ||
Type.SomethingOutputOf<T[number]> | ||
>; | ||
return item.matcher(v, value, mode) as Result<Infer<T[number]>>; | ||
} | ||
return base(v, v, mode) as Result<Type.SomethingOutputOf<T[number]>>; | ||
return base(v, v, mode) as Result<Infer<T[number]>>; | ||
}; | ||
@@ -998,3 +914,3 @@ } | ||
class NeverType extends Type<never, never, never, never> { | ||
class NeverType extends Type<never> { | ||
readonly name = "never"; | ||
@@ -1009,23 +925,3 @@ genFunc(): Func<never> { | ||
} | ||
class NothingType extends Type< | ||
never, | ||
never, | ||
"accepts_nothing", | ||
"outputs_nothing" | ||
> { | ||
readonly name = "nothing"; | ||
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 UnknownType extends Type< | ||
unknown, | ||
never, | ||
"accepts_undefined" | "accepts_something", | ||
"outputs_something" | ||
> { | ||
class UnknownType extends Type<unknown> { | ||
readonly name = "unknown"; | ||
@@ -1039,8 +935,3 @@ genFunc(): Func<unknown> { | ||
} | ||
class NumberType extends Type< | ||
number, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
class NumberType extends Type<number> { | ||
readonly name = "number"; | ||
@@ -1055,8 +946,3 @@ genFunc(): Func<number> { | ||
} | ||
class StringType extends Type< | ||
string, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
class StringType extends Type<string> { | ||
readonly name = "string"; | ||
@@ -1071,8 +957,3 @@ genFunc(): Func<string> { | ||
} | ||
class BigIntType extends Type< | ||
bigint, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
class BigIntType extends Type<bigint> { | ||
readonly name = "bigint"; | ||
@@ -1087,8 +968,3 @@ genFunc(): Func<bigint> { | ||
} | ||
class BooleanType extends Type< | ||
boolean, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
class BooleanType extends Type<boolean> { | ||
readonly name = "boolean"; | ||
@@ -1103,8 +979,3 @@ genFunc(): Func<boolean> { | ||
} | ||
class UndefinedType extends Type< | ||
undefined, | ||
never, | ||
"accepts_undefined" | "accepts_something", | ||
"outputs_something" | ||
> { | ||
class UndefinedType extends Type<undefined> { | ||
readonly name = "undefined"; | ||
@@ -1119,8 +990,3 @@ genFunc(): Func<undefined> { | ||
} | ||
class NullType extends Type< | ||
null, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
class NullType extends Type<null> { | ||
readonly name = "null"; | ||
@@ -1135,8 +1001,3 @@ genFunc(): Func<null> { | ||
} | ||
class LiteralType<Out extends Literal = Literal> extends Type< | ||
Out, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
class LiteralType<Out extends Literal = Literal> extends Type<Out> { | ||
readonly name = "literal"; | ||
@@ -1155,42 +1016,15 @@ constructor(readonly value: Out) { | ||
} | ||
class OptionalType<T extends Type> extends Type< | ||
| Type.SomethingOutputOf<T> | ||
| ("accepts_undefined" extends Type.InputFlagsOf<T> ? never : undefined), | ||
| Type.NothingOutputOf<T> | ||
| ("accepts_nothing" extends Type.InputFlagsOf<T> ? never : undefined), | ||
| "accepts_something" | ||
| "accepts_undefined" | ||
| "accepts_nothing" | ||
| Type.InputFlagsOf<T>, | ||
| ("accepts_nothing" extends Type.InputFlagsOf<T> | ||
? Type.OutputFlagsOf<T> | ||
: "outputs_nothing") | ||
| ("accepts_undefined" extends Type.InputFlagsOf<T> | ||
? Type.OutputFlagsOf<T> | ||
: "outputs_something") | ||
> { | ||
class OptionalType<Output = unknown> extends Type<Output | undefined> { | ||
readonly name = "optional"; | ||
constructor(private readonly type: T) { | ||
constructor(private readonly type: Type<Output>) { | ||
super(); | ||
} | ||
genFunc(): Func< | ||
| Type.SomethingOutputOf<T> | ||
| ("accepts_undefined" extends Type.InputFlagsOf<T> ? never : undefined) | ||
> { | ||
genFunc(): Func<Output> { | ||
const func = this.type.func; | ||
const hasNothing = hasTerminal(this.type, "nothing"); | ||
const hasUndefined = hasTerminal(this.type, "undefined"); | ||
return (v, mode) => { | ||
if (v === Nothing && !hasNothing) { | ||
return true; | ||
} else if (v === undefined && !hasUndefined) { | ||
return true; | ||
} else { | ||
return func(v, mode) as Result<Type.SomethingOutputOf<T>>; | ||
} | ||
return v === undefined || v === Nothing ? true : func(v, mode); | ||
}; | ||
} | ||
toTerminals(into: TerminalType[]): void { | ||
into.push(nothing()); | ||
into.push(this); | ||
into.push(undefined_()); | ||
@@ -1200,10 +1034,3 @@ this.type.toTerminals(into); | ||
} | ||
class TransformType< | ||
T extends Type, | ||
Out, | ||
OutputFlags extends Type.OutputFlags, | ||
X = "accepts_something" extends Type.InputFlagsOf<T> ? Out : never, | ||
Y = "accepts_nothing" extends Type.InputFlagsOf<T> ? Out : never | ||
> extends Type<X, Y, Type.InputFlagsOf<T>, OutputFlags> { | ||
class TransformType<Output> extends Type<Output> { | ||
readonly name = "transform"; | ||
@@ -1216,4 +1043,3 @@ constructor( | ||
} | ||
genFunc(): Func<X | Y> { | ||
genFunc(): Func<Output> { | ||
const chain: Func<unknown>[] = []; | ||
@@ -1230,2 +1056,3 @@ | ||
const func = next.func; | ||
const undef = { code: "ok", value: undefined } as Result<unknown>; | ||
return (v, mode) => { | ||
@@ -1237,4 +1064,12 @@ let result = func(v, mode); | ||
let current = | ||
result === true ? (v === Nothing ? undefined : v) : result.value; | ||
let current: unknown; | ||
if (result !== true) { | ||
current = result.value; | ||
} else if (v === Nothing) { | ||
current = undefined; | ||
result = undef; | ||
} else { | ||
current = v; | ||
} | ||
for (let i = 0; i < chain.length; i++) { | ||
@@ -1250,3 +1085,3 @@ const r = chain[i](current, mode); | ||
} | ||
return result as Result<X | Y>; | ||
return result as Result<Output>; | ||
}; | ||
@@ -1262,5 +1097,2 @@ } | ||
} | ||
function nothing(): NothingType { | ||
return new NothingType(); | ||
} | ||
function unknown(): UnknownType { | ||
@@ -1292,10 +1124,3 @@ return new UnknownType(); | ||
} | ||
function record<T extends Type>( | ||
valueType: T | ||
): Type< | ||
Record<string, Type.SomethingOutputOf<T>>, | ||
never, | ||
"accepts_something", | ||
"outputs_something" | ||
> { | ||
function record<T extends Type>(valueType: T): Type<Record<string, Infer<T>>> { | ||
return new ObjectType({} as Record<string, never>, valueType); | ||
@@ -1314,4 +1139,7 @@ } | ||
} | ||
function union<T extends Type[]>(...options: T): UnionType<T> { | ||
return new UnionType(options); | ||
function union<T extends Type[]>( | ||
...options: T | ||
): UnionType<T> & | ||
(true extends IfOptional<T[number], true, false> ? Optional : unknown) { | ||
return new UnionType(options) as UnionType<T> & Optional; | ||
} | ||
@@ -1321,3 +1149,2 @@ | ||
| NeverType | ||
| NothingType | ||
| UnknownType | ||
@@ -1332,3 +1159,4 @@ | StringType | ||
| ArrayType | ||
| LiteralType; | ||
| LiteralType | ||
| OptionalType; | ||
@@ -1354,3 +1182,2 @@ export { | ||
type Infer<T extends Type> = Type.SomethingOutputOf<T>; | ||
export type { Infer, Type }; | ||
export type { Type }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
294455
16
5147
88
1
1
+ Addedtslib@^2.3.0
+ Addedtslib@2.8.1(transitive)