tiny-decoders
Advanced tools
Comparing version 5.0.0 to 6.0.0
236
index.d.ts
@@ -1,108 +0,134 @@ | ||
// TODO: TypeScript Version: 3.0 | ||
// Waiting for https://github.com/Microsoft/dtslint/issues/137 | ||
// Remove the `--onlyTestTsNext` workaround from `npm run dtslint`. | ||
// Turn off automatic exporting. | ||
export {}; | ||
export type Decoder<T> = (value: unknown, errors?: Array<string>) => T; | ||
type RequiredKeys<T> = { | ||
[P in keyof T]: undefined extends T[P] ? never : P; | ||
export declare type Decoder<T, U = unknown> = (value: U, errors?: Array<DecoderError>) => T; | ||
declare type WithUndefinedAsOptional<T> = T extends Record<string, unknown> ? Expand<{ | ||
[P in OptionalKeys<T>]?: T[P]; | ||
} & { | ||
[P in RequiredKeys<T>]: T[P]; | ||
}> : T; | ||
declare type RequiredKeys<T> = { | ||
[P in keyof T]: undefined extends T[P] ? never : P; | ||
}[keyof T]; | ||
type OptionalKeys<T> = { | ||
[P in keyof T]: undefined extends T[P] ? P : never; | ||
declare type OptionalKeys<T> = { | ||
[P in keyof T]: undefined extends T[P] ? P : never; | ||
}[keyof T]; | ||
// Make VSCode show `{ a: string; b?: number }` instead of `{ a: string } & { b?: number }`. | ||
type Merge<T> = { [P in keyof T]: T[P] }; | ||
export type WithUndefinedAsOptional<T> = Merge< | ||
{ [P in RequiredKeys<T>]: T[P] } & { [P in OptionalKeys<T>]?: T[P] } | ||
>; | ||
export function boolean(value: unknown): boolean; | ||
export function number(value: unknown): number; | ||
export function string(value: unknown): string; | ||
export function constant< | ||
T extends boolean | number | string | undefined | null | ||
>(constantValue: T): (value: unknown) => T; | ||
export function array<T, U = T>( | ||
decoder: Decoder<T>, | ||
mode?: "throw" | "skip" | { default: U } | ||
): Decoder<Array<T | U>>; | ||
export function dict<T, U = T>( | ||
decoder: Decoder<T>, | ||
mode?: "throw" | "skip" | { default: U } | ||
): Decoder<{ [key: string]: T | U }>; | ||
export function fields<T>( | ||
callback: ( | ||
field: <U, V = U>( | ||
key: string | number, | ||
decoder: Decoder<U>, | ||
mode?: "throw" | { default: V } | ||
) => U | V, | ||
fieldError: (key: string | number, message: string) => TypeError, | ||
obj: { readonly [key: string]: unknown }, | ||
errors?: Array<string> | ||
) => T | ||
): Decoder<T>; | ||
export function pair<T1, T2>( | ||
decoder1: Decoder<T1>, | ||
decoder2: Decoder<T2> | ||
): Decoder<[T1, T2]>; | ||
export function triple<T1, T2, T3>( | ||
decoder1: Decoder<T1>, | ||
decoder2: Decoder<T2>, | ||
decoder3: Decoder<T3> | ||
): Decoder<[T1, T2, T3]>; | ||
export function autoRecord<T>( | ||
mapping: { [P in keyof T]: Decoder<T[P]> } | ||
): Decoder<T>; | ||
export function deep<T>( | ||
path: Array<string | number>, | ||
decoder: Decoder<T> | ||
): Decoder<T>; | ||
export function optional<T>(decoder: Decoder<T>): Decoder<T | undefined>; | ||
export function optional<T, U>( | ||
decoder: (value: unknown) => T, | ||
defaultValue: U | ||
): (value: unknown) => T | U; | ||
export function map<T, U>( | ||
decoder: Decoder<T>, | ||
fn: (value: T, errors?: Array<string>) => U | ||
): Decoder<U>; | ||
export function either<T, U>( | ||
decoder1: Decoder<T>, | ||
decoder2: Decoder<U> | ||
): Decoder<T | U>; | ||
export function lazy<T>(callback: () => Decoder<T>): Decoder<T>; | ||
export const repr: { | ||
( | ||
value: unknown, | ||
options?: { | ||
recurse?: boolean; | ||
maxArrayChildren?: number; | ||
maxObjectChildren?: number; | ||
maxLength?: number; | ||
recurseMaxLength?: number; | ||
} | ||
): string; | ||
sensitive: boolean; | ||
declare type Expand<T> = T extends infer O ? { | ||
[K in keyof O]: O[K]; | ||
} : never; | ||
export declare function boolean(value: unknown): boolean; | ||
export declare function number(value: unknown): number; | ||
export declare function string(value: unknown): string; | ||
export declare function stringUnion<T extends Record<string, null>>(mapping: keyof T extends string ? keyof T extends never ? "stringUnion must have at least one key" : T : { | ||
[P in keyof T]: P extends number ? "stringUnion keys must be strings, not numbers" : T[P]; | ||
}): Decoder<keyof T>; | ||
export declare function array<T, U = never>(decoder: Decoder<T>, { mode }?: { | ||
mode?: "skip" | "throw" | { | ||
default: U; | ||
}; | ||
}): Decoder<Array<T | U>>; | ||
export declare function record<T, U = never>(decoder: Decoder<T>, { mode }?: { | ||
mode?: "skip" | "throw" | { | ||
default: U; | ||
}; | ||
}): Decoder<Record<string, T | U>>; | ||
export declare function fields<T>(callback: (field: <U, V = never>(key: string, decoder: Decoder<U>, options?: { | ||
mode?: "throw" | { | ||
default: V; | ||
}; | ||
}) => U | V, object: Record<string, unknown>, errors?: Array<DecoderError>) => T, { exact, allow, }?: { | ||
exact?: "allow extra" | "push" | "throw"; | ||
allow?: "array" | "object"; | ||
}): Decoder<WithUndefinedAsOptional<T>>; | ||
export declare function fieldsAuto<T extends Record<string, unknown>>(mapping: { | ||
[P in keyof T]: P extends "__proto__" ? never : Decoder<T[P]>; | ||
}, { exact }?: { | ||
exact?: "allow extra" | "push" | "throw"; | ||
}): Decoder<WithUndefinedAsOptional<T>>; | ||
declare type Values<T> = T[keyof T]; | ||
export declare function fieldsUnion<T extends Record<string, Decoder<unknown>>>(key: string, mapping: keyof T extends string ? keyof T extends never ? "fieldsUnion must have at least one member" : T : { | ||
[P in keyof T]: P extends number ? "fieldsUnion keys must be strings, not numbers" : T[P]; | ||
}): Decoder<Expand<Values<{ | ||
[P in keyof T]: T[P] extends Decoder<infer U, infer _> ? U : never; | ||
}>>>; | ||
export declare function tuple<T extends ReadonlyArray<unknown>>(mapping: readonly [...{ | ||
[P in keyof T]: Decoder<T[P]>; | ||
}]): Decoder<[...T]>; | ||
export declare function multi<T1 = never, T2 = never, T3 = never, T4 = never, T5 = never, T6 = never, T7 = never>(mapping: { | ||
undefined?: Decoder<T1, undefined>; | ||
null?: Decoder<T2, null>; | ||
boolean?: Decoder<T3, boolean>; | ||
number?: Decoder<T4, number>; | ||
string?: Decoder<T5, string>; | ||
array?: Decoder<T6, Array<unknown>>; | ||
object?: Decoder<T7, Record<string, unknown>>; | ||
}): Decoder<T1 | T2 | T3 | T4 | T5 | T6 | T7>; | ||
export declare function optional<T>(decoder: Decoder<T>): Decoder<T | undefined>; | ||
export declare function optional<T, U>(decoder: Decoder<T>, defaultValue: U): Decoder<T | U>; | ||
export declare function nullable<T>(decoder: Decoder<T>): Decoder<T | null>; | ||
export declare function nullable<T, U>(decoder: Decoder<T>, defaultValue: U): Decoder<T | U>; | ||
export declare function chain<T, U>(decoder: Decoder<T>, next: Decoder<U, T>): Decoder<U>; | ||
export declare type DecoderErrorVariant = { | ||
tag: "custom"; | ||
message: string; | ||
got: unknown; | ||
} | { | ||
tag: "exact fields"; | ||
knownFields: Array<string>; | ||
got: Array<string>; | ||
} | { | ||
tag: "tuple size"; | ||
expected: number; | ||
got: number; | ||
} | { | ||
tag: "unknown fieldsUnion tag"; | ||
knownTags: Array<string>; | ||
got: string; | ||
} | { | ||
tag: "unknown multi type"; | ||
knownTypes: Array<"array" | "boolean" | "null" | "number" | "object" | "string" | "undefined">; | ||
got: unknown; | ||
} | { | ||
tag: "unknown stringUnion variant"; | ||
knownVariants: Array<string>; | ||
got: string; | ||
} | { | ||
tag: "array"; | ||
got: unknown; | ||
} | { | ||
tag: "boolean"; | ||
got: unknown; | ||
} | { | ||
tag: "number"; | ||
got: unknown; | ||
} | { | ||
tag: "object"; | ||
got: unknown; | ||
} | { | ||
tag: "string"; | ||
got: unknown; | ||
}; | ||
declare type Key = number | string; | ||
export declare class DecoderError extends TypeError { | ||
path: Array<Key>; | ||
variant: DecoderErrorVariant; | ||
nullable: boolean; | ||
optional: boolean; | ||
constructor({ key, ...params }: { | ||
message: string; | ||
value: unknown; | ||
key?: Key; | ||
} | (DecoderErrorVariant & { | ||
key?: Key; | ||
})); | ||
static MISSING_VALUE: symbol; | ||
static at(error: unknown, key?: Key): DecoderError; | ||
format(options?: ReprOptions): string; | ||
} | ||
export declare type ReprOptions = { | ||
recurse?: boolean; | ||
maxArrayChildren?: number; | ||
maxObjectChildren?: number; | ||
maxLength?: number; | ||
recurseMaxLength?: number; | ||
sensitive?: boolean; | ||
}; | ||
export declare function repr(value: unknown, { recurse, maxArrayChildren, maxObjectChildren, maxLength, recurseMaxLength, sensitive, }?: ReprOptions): string; | ||
export {}; |
{ | ||
"name": "tiny-decoders", | ||
"version": "5.0.0", | ||
"version": "6.0.0", | ||
"license": "MIT", | ||
@@ -8,7 +8,11 @@ "author": "Simon Lydell", | ||
"description": "Type-safe data decoding for the minimalist.", | ||
"type": "commonjs", | ||
"module": "index.mjs", | ||
"exports": "./index.mjs", | ||
"type": "module", | ||
"main": "./index.cjs", | ||
"module": "./index.mjs", | ||
"exports": { | ||
"require": "./index.cjs", | ||
"import": "./index.mjs" | ||
}, | ||
"sideEffects": false, | ||
"keywords": ["decode", "decoders", "elm", "flow", "json", "typescript"] | ||
"keywords": ["decode", "decoders", "elm", "json", "typescript"] | ||
} |
@@ -1,63 +0,5 @@ | ||
# tiny-decoders ![no dependencies][deps-tiny-decoders] [![minified size][min-tiny-decoders]][bundlephobia-tiny-decoders] | ||
# tiny-decoders ![no dependencies](https://img.shields.io/david/lydell/tiny-decoders.svg) [![minified size](https://img.shields.io/bundlephobia/min/tiny-decoders.svg)](https://bundlephobia.com/result?p=tiny-decoders) | ||
Type-safe data decoding for the minimalist, inspired by [nvie/decoders] and [Elm’s JSON Decoders][elm-json]. | ||
Type-safe data decoding for the minimalist. | ||
Supports [TypeScript] and [Flow]. | ||
```ts | ||
import { | ||
Decoder, | ||
array, | ||
boolean, | ||
either, | ||
fields, | ||
number, | ||
optional, | ||
string, | ||
} from "tiny-decoders"; | ||
type User = { | ||
name: string; | ||
active: boolean; | ||
age: number | undefined; | ||
interests: Array<string>; | ||
id: string | number; | ||
}; | ||
const userDecoder = fields( | ||
(field): User => ({ | ||
name: field("full_name", string), | ||
active: field("is_active", boolean), | ||
age: field("age", optional(number)), | ||
interests: field("interests", array(string)), | ||
id: field("id", either(string, number)), | ||
}) | ||
); | ||
const payload: unknown = getSomeJSON(); | ||
const user: User = userDecoder(payload); | ||
/* | ||
If we get here, `user` is now a valid `User`! | ||
Otherwise, a `TypeError` is thrown. | ||
The error can look like this: | ||
TypeError: object["age"]: (optional) Expected a number, but got: "30" | ||
*/ | ||
``` | ||
[️Full example][example-readme] | ||
--- | ||
[bundlephobia-tiny-decoders]: https://bundlephobia.com/result?p=tiny-decoders | ||
[deps-tiny-decoders]: https://img.shields.io/david/lydell/tiny-decoders.svg | ||
[elm-json]: https://package.elm-lang.org/packages/elm/json/latest/Json-Decode | ||
[example-readme]: https://github.com/lydell/tiny-decoders/blob/master/examples/readme.test.js | ||
[flow]: https://flow.org/ | ||
[min-tiny-decoders]: https://img.shields.io/bundlephobia/min/tiny-decoders.svg | ||
[nvie/decoders]: https://github.com/nvie/decoders | ||
[typescript]: https://www.typescriptlang.org/ | ||
**[➡️ Full readme](https://github.com/lydell/tiny-decoders/)** | ||
**[➡️ Full readme](https://github.com/lydell/tiny-decoders/#readme)** |
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
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
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
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
1072
Yes
40666
6
5