1 |
|
2 |
|
3 |
|
4 | type Failure = {
|
5 | value: any;
|
6 | key: any;
|
7 | type: string;
|
8 | refinement: string | undefined;
|
9 | message: string;
|
10 | branch: Array<any>;
|
11 | path: Array<any>;
|
12 | };
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | declare class StructError extends TypeError {
|
22 | value: any;
|
23 | key: any;
|
24 | type: string;
|
25 | refinement: string | undefined;
|
26 | path: Array<any>;
|
27 | branch: Array<any>;
|
28 | failures: () => Array<Failure>;
|
29 | [x: string]: any;
|
30 | constructor(failure: Failure, failures: () => Generator<Failure>);
|
31 | }
|
32 | /**
|
33 | * Convert a union of type to an intersection.
|
34 | */
|
35 | type UnionToIntersection<U> = (U extends any ? (arg: U) => any : never) extends (arg: infer I) => void ? I : never;
|
36 | /**
|
37 | * Assign properties from one type to another, overwriting existing.
|
38 | */
|
39 | type Assign<T, U> = Simplify<U & Omit<T, keyof U>>;
|
40 | /**
|
41 | * A schema for enum structs.
|
42 | */
|
43 | type EnumSchema<T extends string | number | undefined> = {
|
44 | [K in NonNullable<T>]: K;
|
45 | };
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | type IsMatch<T, G> = T extends G ? (G extends T ? T : never) : never;
|
51 |
|
52 |
|
53 |
|
54 | type IsExactMatch<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U ? 1 : 2 ? T : never;
|
55 |
|
56 |
|
57 |
|
58 | type IsRecord<T> = T extends object ? string extends keyof T ? T : never : never;
|
59 |
|
60 |
|
61 |
|
62 | type IsTuple<T> = T extends [
|
63 | any
|
64 | ] ? T : T extends [
|
65 | any,
|
66 | any
|
67 | ] ? T : T extends [
|
68 | any,
|
69 | any,
|
70 | any
|
71 | ] ? T : T extends [
|
72 | any,
|
73 | any,
|
74 | any,
|
75 | any
|
76 | ] ? T : T extends [
|
77 | any,
|
78 | any,
|
79 | any,
|
80 | any,
|
81 | any
|
82 | ] ? T : never;
|
83 |
|
84 |
|
85 |
|
86 | type IsUnion<T, U extends T = T> = (T extends any ? (U extends T ? false : true) : false) extends false ? never : T;
|
87 |
|
88 |
|
89 |
|
90 | type ObjectSchema = Record<string, Struct<any, any>>;
|
91 |
|
92 |
|
93 |
|
94 | type ObjectType<S extends ObjectSchema> = Simplify<Optionalize<{
|
95 | [K in keyof S]: Infer<S[K]>;
|
96 | }>>;
|
97 |
|
98 |
|
99 |
|
100 | type OmitBy<T, V> = Omit<T, {
|
101 | [K in keyof T]: V extends Extract<T[K], V> ? K : never;
|
102 | }[keyof T]>;
|
103 |
|
104 |
|
105 |
|
106 | type Optionalize<S extends object> = OmitBy<S, undefined> & Partial<PickBy<S, undefined>>;
|
107 |
|
108 |
|
109 |
|
110 | type PartialObjectSchema<S extends ObjectSchema> = {
|
111 | [K in keyof S]: Struct<Infer<S[K]> | undefined>;
|
112 | };
|
113 |
|
114 |
|
115 |
|
116 | type PickBy<T, V> = Pick<T, {
|
117 | [K in keyof T]: V extends Extract<T[K], V> ? K : never;
|
118 | }[keyof T]>;
|
119 |
|
120 |
|
121 |
|
122 | type Simplify<T> = T extends any[] | Date ? T : {
|
123 | [K in keyof T]: T[K];
|
124 | } & {};
|
125 |
|
126 |
|
127 |
|
128 | type StructSchema<T> = [
|
129 | T
|
130 | ] extends [
|
131 | string | undefined
|
132 | ] ? [
|
133 | T
|
134 | ] extends [
|
135 | IsMatch<T, string | undefined>
|
136 | ] ? null : [
|
137 | T
|
138 | ] extends [
|
139 | IsUnion<T>
|
140 | ] ? EnumSchema<T> : T : [
|
141 | T
|
142 | ] extends [
|
143 | number | undefined
|
144 | ] ? [
|
145 | T
|
146 | ] extends [
|
147 | IsMatch<T, number | undefined>
|
148 | ] ? null : [
|
149 | T
|
150 | ] extends [
|
151 | IsUnion<T>
|
152 | ] ? EnumSchema<T> : T : [
|
153 | T
|
154 | ] extends [
|
155 | boolean
|
156 | ] ? [
|
157 | T
|
158 | ] extends [
|
159 | IsExactMatch<T, boolean>
|
160 | ] ? null : T : T extends bigint | symbol | undefined | null | Function | Date | Error | RegExp | Map<any, any> | WeakMap<any, any> | Set<any> | WeakSet<any> | Promise<any> ? null : T extends Array<infer E> ? T extends IsTuple<T> ? null : Struct<E> : T extends object ? T extends IsRecord<T> ? null : {
|
161 | [K in keyof T]: Describe<T[K]>;
|
162 | } : null;
|
163 |
|
164 |
|
165 |
|
166 | type AnyStruct = Struct<any, any>;
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 | type InferStructTuple<Tuple extends AnyStruct[], Length extends number = Tuple["length"]> = Length extends Length ? number extends Length ? Tuple : _InferTuple<Tuple, Length, [
|
174 | ]> : never;
|
175 | type _InferTuple<Tuple extends AnyStruct[], Length extends number, Accumulated extends unknown[], Index extends number = Accumulated["length"]> = Index extends Length ? Accumulated : _InferTuple<Tuple, Length, [
|
176 | ...Accumulated,
|
177 | Infer<Tuple[Index]>
|
178 | ]>;
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 | declare class Struct<T = unknown, S = unknown> {
|
185 | readonly TYPE: T;
|
186 | type: string;
|
187 | schema: S;
|
188 | coercer: (value: unknown, context: Context) => unknown;
|
189 | validator: (value: unknown, context: Context) => Iterable<Failure>;
|
190 | refiner: (value: T, context: Context) => Iterable<Failure>;
|
191 | entries: (value: unknown, context: Context) => Iterable<[
|
192 | string | number,
|
193 | unknown,
|
194 | Struct<any> | Struct<never>
|
195 | ]>;
|
196 | constructor(props: {
|
197 | type: string;
|
198 | schema: S;
|
199 | coercer?: Coercer;
|
200 | validator?: Validator;
|
201 | refiner?: Refiner<T>;
|
202 | entries?: Struct<T, S>["entries"];
|
203 | });
|
204 | /**
|
205 | * Assert that a value passes the struct's validation, throwing if it doesn't.
|
206 | */
|
207 | assert(value: unknown): asserts value is T;
|
208 | /**
|
209 | * Create a value with the struct's coercion logic, then validate it.
|
210 | */
|
211 | create(value: unknown): T;
|
212 | /**
|
213 | * Check if a value passes the struct's validation.
|
214 | */
|
215 | is(value: unknown): value is T;
|
216 | /**
|
217 | * Mask a value, coercing and validating it, but returning only the subset of
|
218 | * properties defined by the struct's schema.
|
219 | */
|
220 | mask(value: unknown): T;
|
221 | /**
|
222 | * Validate a value with the struct's validation logic, returning a tuple
|
223 | * representing the result.
|
224 | *
|
225 | * You may optionally pass `true` for the `withCoercion` argument to coerce
|
226 | * the value before attempting to validate it. If you do, the result will
|
227 | * contain the coerced result when successful.
|
228 | */
|
229 | validate(value: unknown, options?: {
|
230 | coerce?: boolean;
|
231 | }): [
|
232 | StructError,
|
233 | undefined
|
234 | ] | [
|
235 | undefined,
|
236 | T
|
237 | ];
|
238 | }
|
239 | /**
|
240 | * Assert that a value passes a struct, throwing if it doesn't.
|
241 | */
|
242 | declare function assert<T, S>(value: unknown, struct: Struct<T, S>): asserts value is T;
|
243 | /**
|
244 | * Create a value with the coercion logic of struct and validate it.
|
245 | */
|
246 | declare function create<T, S>(value: unknown, struct: Struct<T, S>): T;
|
247 | /**
|
248 | * Mask a value, returning only the subset of properties defined by a struct.
|
249 | */
|
250 | declare function mask<T, S>(value: unknown, struct: Struct<T, S>): T;
|
251 | /**
|
252 | * Check if a value passes a struct.
|
253 | */
|
254 | declare function is<T, S>(value: unknown, struct: Struct<T, S>): value is T;
|
255 | /**
|
256 | * Validate a value against a struct, returning an error if invalid, or the
|
257 | * value (with potential coercion) if valid.
|
258 | */
|
259 | declare function validate<T, S>(value: unknown, struct: Struct<T, S>, options?: {
|
260 | coerce?: boolean;
|
261 | mask?: boolean;
|
262 | }): [
|
263 | StructError,
|
264 | undefined
|
265 | ] | [
|
266 | undefined,
|
267 | T
|
268 | ];
|
269 | /**
|
270 | * A `Context` contains information about the current location of the
|
271 | * validation inside the initial input value.
|
272 | */
|
273 | type Context = {
|
274 | branch: Array<any>;
|
275 | path: Array<any>;
|
276 | };
|
277 |
|
278 |
|
279 |
|
280 | type Infer<T extends Struct<any, any>> = T["TYPE"];
|
281 |
|
282 |
|
283 |
|
284 | type Describe<T> = Struct<T, StructSchema<T>>;
|
285 |
|
286 |
|
287 |
|
288 | type Result = boolean | string | Partial<Failure> | Iterable<boolean | string | Partial<Failure>>;
|
289 |
|
290 |
|
291 |
|
292 | type Coercer<T = unknown> = (value: T, context: Context) => unknown;
|
293 |
|
294 |
|
295 |
|
296 | type Validator = (value: unknown, context: Context) => Result;
|
297 |
|
298 |
|
299 |
|
300 |
|
301 | type Refiner<T> = (value: T, context: Context) => Result;
|
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 |
|
309 |
|
310 |
|
311 |
|
312 | declare function coerce<T, S, C>(struct: Struct<T, S>, condition: Struct<C, any>, coercer: Coercer<C>): Struct<T, S>;
|
313 |
|
314 |
|
315 |
|
316 |
|
317 |
|
318 |
|
319 | declare function defaulted<T, S>(struct: Struct<T, S>, fallback: any, options?: {
|
320 | strict?: boolean;
|
321 | }): Struct<T, S>;
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 | declare function trimmed<T, S>(struct: Struct<T, S>): Struct<T, S>;
|
329 |
|
330 |
|
331 |
|
332 | declare function empty<T extends string | any[] | Map<any, any> | Set<any>, S extends any>(struct: Struct<T, S>): Struct<T, S>;
|
333 |
|
334 |
|
335 |
|
336 | declare function max<T extends number | Date, S extends any>(struct: Struct<T, S>, threshold: T, options?: {
|
337 | exclusive?: boolean;
|
338 | }): Struct<T, S>;
|
339 |
|
340 |
|
341 |
|
342 | declare function min<T extends number | Date, S extends any>(struct: Struct<T, S>, threshold: T, options?: {
|
343 | exclusive?: boolean;
|
344 | }): Struct<T, S>;
|
345 |
|
346 |
|
347 |
|
348 | declare function nonempty<T extends string | any[] | Map<any, any> | Set<any>, S extends any>(struct: Struct<T, S>): Struct<T, S>;
|
349 |
|
350 |
|
351 |
|
352 | declare function pattern<T extends string, S extends any>(struct: Struct<T, S>, regexp: RegExp): Struct<T, S>;
|
353 |
|
354 |
|
355 |
|
356 | declare function size<T extends string | number | Date | any[] | Map<any, any> | Set<any>, S extends any>(struct: Struct<T, S>, min: number, max?: number): Struct<T, S>;
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 | declare function refine<T, S>(struct: Struct<T, S>, name: string, refiner: Refiner<T>): Struct<T, S>;
|
365 |
|
366 |
|
367 |
|
368 | declare function any(): Struct<any, null>;
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
376 | declare function array<T extends Struct<any>>(Element: T): Struct<Infer<T>[], T>;
|
377 | declare function array(): Struct<unknown[], undefined>;
|
378 |
|
379 |
|
380 |
|
381 | declare function bigint(): Struct<bigint, null>;
|
382 |
|
383 |
|
384 |
|
385 | declare function boolean(): Struct<boolean, null>;
|
386 |
|
387 |
|
388 |
|
389 |
|
390 |
|
391 |
|
392 | declare function date(): Struct<Date, null>;
|
393 |
|
394 |
|
395 |
|
396 |
|
397 |
|
398 |
|
399 | declare function enums<T extends number>(values: readonly T[]): Struct<T, {
|
400 | [K in T[][number]]: K;
|
401 | }>;
|
402 | declare function enums<T extends string>(values: readonly T[]): Struct<T, {
|
403 | [K in T[][number]]: K;
|
404 | }>;
|
405 |
|
406 |
|
407 |
|
408 | declare function func(): Struct<Function, null>;
|
409 |
|
410 |
|
411 |
|
412 | declare function instance<T extends {
|
413 | new (...args: any): any;
|
414 | }>(Class: T): Struct<InstanceType<T>, null>;
|
415 |
|
416 |
|
417 |
|
418 | declare function integer(): Struct<number, null>;
|
419 |
|
420 |
|
421 |
|
422 | declare function intersection<A extends AnyStruct, B extends AnyStruct[]>(Structs: [
|
423 | A,
|
424 | ...B
|
425 | ]): Struct<Infer<A> & UnionToIntersection<InferStructTuple<B>[number]>, null>;
|
426 |
|
427 |
|
428 |
|
429 | declare function literal<T extends boolean>(constant: T): Struct<T, T>;
|
430 | declare function literal<T extends number>(constant: T): Struct<T, T>;
|
431 | declare function literal<T extends string>(constant: T): Struct<T, T>;
|
432 | declare function literal<T>(constant: T): Struct<T, null>;
|
433 |
|
434 |
|
435 |
|
436 |
|
437 | declare function map(): Struct<Map<unknown, unknown>, null>;
|
438 | declare function map<K, V>(Key: Struct<K>, Value: Struct<V>): Struct<Map<K, V>, null>;
|
439 |
|
440 |
|
441 |
|
442 | declare function never(): Struct<never, null>;
|
443 |
|
444 |
|
445 |
|
446 | declare function nullable<T, S>(struct: Struct<T, S>): Struct<T | null, S>;
|
447 |
|
448 |
|
449 |
|
450 | declare function number(): Struct<number, null>;
|
451 |
|
452 |
|
453 |
|
454 |
|
455 |
|
456 |
|
457 | declare function object(): Struct<Record<string, unknown>, null>;
|
458 | declare function object<S extends ObjectSchema>(schema: S): Struct<ObjectType<S>, S>;
|
459 |
|
460 |
|
461 |
|
462 | declare function optional<T, S>(struct: Struct<T, S>): Struct<T | undefined, S>;
|
463 |
|
464 |
|
465 |
|
466 |
|
467 |
|
468 |
|
469 | declare function record<K extends string, V>(Key: Struct<K>, Value: Struct<V>): Struct<Record<K, V>, null>;
|
470 |
|
471 |
|
472 |
|
473 |
|
474 |
|
475 |
|
476 | declare function regexp(): Struct<RegExp, null>;
|
477 |
|
478 |
|
479 |
|
480 |
|
481 | declare function set(): Struct<Set<unknown>, null>;
|
482 | declare function set<T>(Element: Struct<T>): Struct<Set<T>, null>;
|
483 |
|
484 |
|
485 |
|
486 | declare function string(): Struct<string, null>;
|
487 |
|
488 |
|
489 |
|
490 |
|
491 | declare function tuple<A extends AnyStruct, B extends AnyStruct[]>(Structs: [
|
492 | A,
|
493 | ...B
|
494 | ]): Struct<[
|
495 | Infer<A>,
|
496 | ...InferStructTuple<B>
|
497 | ], null>;
|
498 |
|
499 |
|
500 |
|
501 |
|
502 |
|
503 |
|
504 | declare function type<S extends ObjectSchema>(schema: S): Struct<ObjectType<S>, S>;
|
505 |
|
506 |
|
507 |
|
508 | declare function union<A extends AnyStruct, B extends AnyStruct[]>(Structs: [
|
509 | A,
|
510 | ...B
|
511 | ]): Struct<Infer<A> | InferStructTuple<B>[number], null>;
|
512 |
|
513 |
|
514 |
|
515 | declare function unknown(): Struct<unknown, null>;
|
516 |
|
517 |
|
518 |
|
519 |
|
520 |
|
521 |
|
522 | declare function assign<A extends ObjectSchema, B extends ObjectSchema>(A: Struct<ObjectType<A>, A>, B: Struct<ObjectType<B>, B>): Struct<ObjectType<Assign<A, B>>, Assign<A, B>>;
|
523 | declare function assign<A extends ObjectSchema, B extends ObjectSchema, C extends ObjectSchema>(A: Struct<ObjectType<A>, A>, B: Struct<ObjectType<B>, B>, C: Struct<ObjectType<C>, C>): Struct<ObjectType<Assign<Assign<A, B>, C>>, Assign<Assign<A, B>, C>>;
|
524 | declare function assign<A extends ObjectSchema, B extends ObjectSchema, C extends ObjectSchema, D extends ObjectSchema>(A: Struct<ObjectType<A>, A>, B: Struct<ObjectType<B>, B>, C: Struct<ObjectType<C>, C>, D: Struct<ObjectType<D>, D>): Struct<ObjectType<Assign<Assign<Assign<A, B>, C>, D>>, Assign<Assign<Assign<A, B>, C>, D>>;
|
525 | declare function assign<A extends ObjectSchema, B extends ObjectSchema, C extends ObjectSchema, D extends ObjectSchema, E extends ObjectSchema>(A: Struct<ObjectType<A>, A>, B: Struct<ObjectType<B>, B>, C: Struct<ObjectType<C>, C>, D: Struct<ObjectType<D>, D>, E: Struct<ObjectType<E>, E>): Struct<ObjectType<Assign<Assign<Assign<Assign<A, B>, C>, D>, E>>, Assign<Assign<Assign<Assign<A, B>, C>, D>, E>>;
|
526 |
|
527 |
|
528 |
|
529 | declare function define<T>(name: string, validator: Validator): Struct<T, null>;
|
530 |
|
531 |
|
532 |
|
533 |
|
534 | declare function deprecated<T>(struct: Struct<T>, log: (value: unknown, ctx: Context) => void): Struct<T>;
|
535 |
|
536 |
|
537 |
|
538 |
|
539 |
|
540 |
|
541 |
|
542 | declare function dynamic<T>(fn: (value: unknown, ctx: Context) => Struct<T, any>): Struct<T, null>;
|
543 |
|
544 |
|
545 |
|
546 |
|
547 |
|
548 |
|
549 |
|
550 |
|
551 | declare function lazy<T>(fn: () => Struct<T, any>): Struct<T, null>;
|
552 |
|
553 |
|
554 |
|
555 |
|
556 |
|
557 |
|
558 | declare function omit<S extends ObjectSchema, K extends keyof S>(struct: Struct<ObjectType<S>, S>, keys: K[]): Struct<ObjectType<Omit<S, K>>, Omit<S, K>>;
|
559 |
|
560 |
|
561 |
|
562 |
|
563 |
|
564 |
|
565 | declare function partial<S extends ObjectSchema>(struct: Struct<ObjectType<S>, S> | S): Struct<ObjectType<PartialObjectSchema<S>>, PartialObjectSchema<S>>;
|
566 |
|
567 |
|
568 |
|
569 |
|
570 |
|
571 |
|
572 | declare function pick<S extends ObjectSchema, K extends keyof S>(struct: Struct<ObjectType<S>, S>, keys: K[]): Struct<ObjectType<Pick<S, K>>, Pick<S, K>>;
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 | declare function struct<T>(name: string, validator: Validator): Struct<T, null>;
|
579 | export { Failure, StructError, Struct, assert, create, mask, is, validate, Context, Infer, Describe, Result, Coercer, Validator, Refiner, coerce, defaulted, trimmed, empty, max, min, nonempty, pattern, size, refine, any, array, bigint, boolean, date, enums, func, instance, integer, intersection, literal, map, never, nullable, number, object, optional, record, regexp, set, string, tuple, type, union, unknown, assign, define, deprecated, dynamic, lazy, omit, partial, pick, struct };
|