@ix-xs/node-comfort 1.2.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +340 -0
  2. package/README.md +137 -548
  3. package/index.js +80 -35
  4. package/package.json +161 -33
  5. package/src/Arr.js +1050 -418
  6. package/src/Async.js +817 -0
  7. package/src/Cache.js +433 -0
  8. package/src/Checker.js +1202 -539
  9. package/src/Cli.js +1293 -0
  10. package/src/Color.js +556 -0
  11. package/src/Crypto.js +1082 -0
  12. package/src/Emitter.js +356 -0
  13. package/src/Env.js +689 -0
  14. package/src/FS.js +1626 -894
  15. package/src/Func.js +823 -356
  16. package/src/Http.js +700 -0
  17. package/src/Id.js +568 -200
  18. package/src/Logger.js +963 -378
  19. package/src/Num.js +965 -360
  20. package/src/Obj.js +1077 -379
  21. package/src/SQLite.js +1629 -1005
  22. package/src/Schema.js +2101 -0
  23. package/src/Str.js +1209 -432
  24. package/src/Sys.js +654 -0
  25. package/src/Time.js +1533 -440
  26. package/src/Utils.js +342 -325
  27. package/src/errors.js +335 -0
  28. package/src/internal/shared.js +415 -0
  29. package/types/index.d.ts +735 -526
  30. package/types/src/Arr.d.ts +533 -145
  31. package/types/src/Arr.d.ts.map +1 -1
  32. package/types/src/Async.d.ts +372 -0
  33. package/types/src/Async.d.ts.map +1 -0
  34. package/types/src/Cache.d.ts +221 -0
  35. package/types/src/Cache.d.ts.map +1 -0
  36. package/types/src/Checker.d.ts +651 -232
  37. package/types/src/Checker.d.ts.map +1 -1
  38. package/types/src/Cli.d.ts +664 -0
  39. package/types/src/Cli.d.ts.map +1 -0
  40. package/types/src/Color.d.ts +300 -0
  41. package/types/src/Color.d.ts.map +1 -0
  42. package/types/src/Crypto.d.ts +620 -0
  43. package/types/src/Crypto.d.ts.map +1 -0
  44. package/types/src/Emitter.d.ts +189 -0
  45. package/types/src/Emitter.d.ts.map +1 -0
  46. package/types/src/Env.d.ts +412 -0
  47. package/types/src/Env.d.ts.map +1 -0
  48. package/types/src/FS.d.ts +717 -238
  49. package/types/src/FS.d.ts.map +1 -1
  50. package/types/src/Func.d.ts +508 -135
  51. package/types/src/Func.d.ts.map +1 -1
  52. package/types/src/Http.d.ts +444 -0
  53. package/types/src/Http.d.ts.map +1 -0
  54. package/types/src/Id.d.ts +199 -66
  55. package/types/src/Id.d.ts.map +1 -1
  56. package/types/src/Logger.d.ts +414 -46
  57. package/types/src/Logger.d.ts.map +1 -1
  58. package/types/src/Num.d.ts +514 -137
  59. package/types/src/Num.d.ts.map +1 -1
  60. package/types/src/Obj.d.ts +453 -104
  61. package/types/src/Obj.d.ts.map +1 -1
  62. package/types/src/SQLite.d.ts +754 -308
  63. package/types/src/SQLite.d.ts.map +1 -1
  64. package/types/src/Schema.d.ts +1189 -0
  65. package/types/src/Schema.d.ts.map +1 -0
  66. package/types/src/Str.d.ts +617 -166
  67. package/types/src/Str.d.ts.map +1 -1
  68. package/types/src/Sys.d.ts +314 -0
  69. package/types/src/Sys.d.ts.map +1 -0
  70. package/types/src/Time.d.ts +759 -204
  71. package/types/src/Time.d.ts.map +1 -1
  72. package/types/src/Utils.d.ts +158 -102
  73. package/types/src/Utils.d.ts.map +1 -1
  74. package/types/src/errors.d.ts +316 -0
  75. package/types/src/errors.d.ts.map +1 -0
  76. package/types/src/internal/shared.d.ts +123 -0
  77. package/types/src/internal/shared.d.ts.map +1 -0
  78. package/types/index.d.ts.map +0 -1
@@ -0,0 +1,1189 @@
1
+ declare namespace _exports {
2
+ export { Infer, Shape, Simplify, ObjectOutput, SafeParseResult, Message, RefineOptions, ParseContext, Step, JSONSchema, _JSONContext, CoerceBuilders };
3
+ }
4
+ declare namespace _exports {
5
+ export { string };
6
+ export { number };
7
+ export { boolean };
8
+ export { bigint };
9
+ export { date };
10
+ export { literal };
11
+ export { enumeration as enum };
12
+ export { array };
13
+ export { object };
14
+ export { union };
15
+ export { discriminatedUnion };
16
+ export { tuple };
17
+ export { record };
18
+ export { lazy };
19
+ export { instanceOf };
20
+ export { custom };
21
+ export { any };
22
+ export { unknown };
23
+ export { coerce };
24
+ export { Schema };
25
+ }
26
+ export = _exports;
27
+ /**
28
+ * The type a schema produces.
29
+ */
30
+ type Infer<S> = S extends Schema<infer T> ? T : never;
31
+ /**
32
+ * An object of schemas, as passed to `object()`.
33
+ */
34
+ type Shape = Record<string, Schema<any>>;
35
+ /**
36
+ * Flattens a type so editors show it nicely.
37
+ */
38
+ type Simplify<T> = { [K in keyof T]: T[K]; } & {};
39
+ /**
40
+ * The type of an object schema. Keys that accept `undefined` become optional.
41
+ */
42
+ type ObjectOutput<S extends Shape> = Simplify<{ [K in keyof S as undefined extends Infer<S[K]> ? never : K]: Infer<S[K]>; } & { [K in keyof S as undefined extends Infer<S[K]> ? K : never]?: Infer<S[K]>; }>;
43
+ /**
44
+ * What `safeParse()` returns. On failure, `issues` is the plain list and
45
+ * `error` the same thing as a `ValidationError`, built when you read it.
46
+ */
47
+ type SafeParseResult<T> = {
48
+ success: true;
49
+ data: T;
50
+ error?: undefined;
51
+ issues?: undefined;
52
+ } | {
53
+ success: false;
54
+ data?: undefined;
55
+ error: ValidationError;
56
+ issues: import("./errors").ValidationIssue[];
57
+ };
58
+ /**
59
+ * An error message: a string, or a function that gets the invalid value.
60
+ */
61
+ type Message = string | ((value: any) => string);
62
+ /**
63
+ * Options for `refine()`.
64
+ */
65
+ type RefineOptions = {
66
+ /**
67
+ * Defaults to `"Invalid value"`.
68
+ */
69
+ message?: Message | undefined;
70
+ /**
71
+ * Where to report the issue, like `["confirmPassword"]` for a cross-field check.
72
+ */
73
+ path?: (string | number)[] | undefined;
74
+ /**
75
+ * Defaults to `"custom"`.
76
+ */
77
+ code?: string | undefined;
78
+ };
79
+ type ParseContext = {
80
+ issues: import("./errors").ValidationIssue[];
81
+ path: Array<string | number>;
82
+ };
83
+ /**
84
+ * A step in a schema: a check, a transformation, a refinement or a pipe
85
+ * into another schema.
86
+ */
87
+ type Step = {
88
+ kind: "check";
89
+ test: (value: any) => boolean;
90
+ code: string;
91
+ message: Message;
92
+ details?: Record<string, unknown>;
93
+ json?: Record<string, unknown>;
94
+ } | {
95
+ kind: "transform";
96
+ fn: (value: any) => any;
97
+ } | {
98
+ kind: "refine";
99
+ test: (value: any) => boolean;
100
+ options: RefineOptions;
101
+ } | {
102
+ kind: "pipe";
103
+ schema: Schema<any>;
104
+ };
105
+ /**
106
+ * A JSON Schema, as made by `toJSONSchema()`.
107
+ */
108
+ type JSONSchema = {
109
+ [keyword: string]: any;
110
+ };
111
+ type _JSONContext = {
112
+ defs: Record<string, JSONSchema>;
113
+ names: Map<Schema<any>, string>;
114
+ };
115
+ /**
116
+ * The `s.coerce` builders.
117
+ */
118
+ type CoerceBuilders = {
119
+ /**
120
+ * A string schema that turns any value into a string first.
121
+ */
122
+ string: () => StringSchema;
123
+ /**
124
+ * A number schema that converts strings like `"42"`, booleans and dates first.
125
+ */
126
+ number: () => NumberSchema;
127
+ /**
128
+ * A boolean schema that understands `"true"`, `"1"`, `"yes"`, `"on"` and their opposites.
129
+ */
130
+ boolean: () => BooleanSchema;
131
+ /**
132
+ * A date schema that converts ISO strings and timestamps.
133
+ */
134
+ date: () => DateSchema;
135
+ /**
136
+ * A bigint schema that converts numeric strings and integers.
137
+ */
138
+ bigint: () => BigIntSchema;
139
+ };
140
+ /**
141
+ * A string schema.
142
+ *
143
+ * @example
144
+ * s.string().trim().min(1).max(100);
145
+ * s.string().email();
146
+ *
147
+ * @param {{ message?: Message }} [options] Message when the value isn't a string.
148
+ * @returns {StringSchema}
149
+ */
150
+ declare function string(options?: {
151
+ message?: Message;
152
+ }): StringSchema;
153
+ /**
154
+ * A number. `NaN` and `Infinity` are refused.
155
+ *
156
+ * @example
157
+ * s.number().int().min(0).max(120);
158
+ *
159
+ * @param {{ message?: Message }} [options] Message when the value isn't a number.
160
+ * @returns {NumberSchema}
161
+ */
162
+ declare function number(options?: {
163
+ message?: Message;
164
+ }): NumberSchema;
165
+ /**
166
+ * A boolean schema.
167
+ *
168
+ * @param {{ message?: Message }} [options]
169
+ * @returns {BooleanSchema}
170
+ */
171
+ declare function boolean(options?: {
172
+ message?: Message;
173
+ }): BooleanSchema;
174
+ /**
175
+ * A bigint schema.
176
+ *
177
+ * @param {{ message?: Message }} [options]
178
+ * @returns {BigIntSchema}
179
+ */
180
+ declare function bigint(options?: {
181
+ message?: Message;
182
+ }): BigIntSchema;
183
+ /**
184
+ * A valid `Date`.
185
+ *
186
+ * @example
187
+ * s.date().min("2024-01-01");
188
+ *
189
+ * @param {{ message?: Message }} [options]
190
+ * @returns {DateSchema}
191
+ */
192
+ declare function date(options?: {
193
+ message?: Message;
194
+ }): DateSchema;
195
+ /**
196
+ * Exactly this value.
197
+ *
198
+ * @example
199
+ * s.object({ type: s.literal("circle"), radius: s.number() });
200
+ *
201
+ * @template {string | number | boolean | bigint | null | undefined} L
202
+ * @param {L} value
203
+ * @returns {LiteralSchema<L>}
204
+ */
205
+ declare function literal<L extends string | number | boolean | bigint | null | undefined>(value: L): LiteralSchema<L>;
206
+ /**
207
+ * One of these values. The type is their union.
208
+ *
209
+ * @example
210
+ * const Role = s.enum(["admin", "editor", "viewer"]); // Schema<"admin" | "editor" | "viewer">
211
+ * Role.options; // ["admin", "editor", "viewer"]
212
+ *
213
+ * @template {string | number} V
214
+ * @param {readonly V[]} values
215
+ * @param {{ message?: Message }} [options]
216
+ * @returns {LiteralSchema<V>}
217
+ */
218
+ declare function enumeration<V extends string | number>(values: readonly V[], options?: {
219
+ message?: Message;
220
+ }): LiteralSchema<V>;
221
+ /**
222
+ * An array whose items all match `item`.
223
+ *
224
+ * @example
225
+ * s.array(s.string()).min(1).max(10).unique();
226
+ *
227
+ * @template T
228
+ * @param {Schema<T>} item
229
+ * @returns {ArraySchema<T>}
230
+ */
231
+ declare function array<T>(item: Schema<T>): ArraySchema<T>;
232
+ /**
233
+ * An object with known keys. Unknown keys are dropped; `.strict()` rejects
234
+ * them and `.passthrough()` keeps them.
235
+ *
236
+ * @example
237
+ * const Address = s.object({ street: s.string(), zip: s.string().regex(/^\d{5}$/), city: s.string() });
238
+ *
239
+ * @template {Shape} S
240
+ * @param {S} shape
241
+ * @returns {ObjectSchema<S>}
242
+ */
243
+ declare function object<S extends Shape>(shape: S): ObjectSchema<S>;
244
+ /**
245
+ * Matches any of these schemas; the first that fits wins.
246
+ *
247
+ * @example
248
+ * s.union([s.string(), s.number()]); // Schema<string | number>
249
+ *
250
+ * @template {ReadonlyArray<Schema<any>>} U
251
+ * @param {U} options
252
+ * @returns {UnionSchema<Infer<U[number]>>}
253
+ */
254
+ declare function union<U extends ReadonlyArray<Schema<any>>>(options: U): UnionSchema<Infer<U[number]>>;
255
+ /**
256
+ * A union of objects told apart by one key, like the `type` of an event.
257
+ * Unlike `union()`, it goes straight to the right schema, and a wrong
258
+ * object gets the errors of the kind it claims to be.
259
+ *
260
+ * @example
261
+ * const Event = s.discriminatedUnion("type", [
262
+ * s.object({ type: s.literal("click"), x: s.number(), y: s.number() }),
263
+ * s.object({ type: s.literal("key"), key: s.string() }),
264
+ * ]);
265
+ * Event.parse({ type: "key", key: "Enter" });
266
+ *
267
+ * @template {ReadonlyArray<ObjectSchema<any>>} U
268
+ * @param {string} key The key every option has, with a different literal in each.
269
+ * @param {U} options
270
+ * @returns {DiscriminatedUnionSchema<Infer<U[number]>>}
271
+ */
272
+ declare function discriminatedUnion<U extends ReadonlyArray<ObjectSchema<any>>>(key: string, options: U): DiscriminatedUnionSchema<Infer<U[number]>>;
273
+ /**
274
+ * A fixed-length array with one schema per position.
275
+ *
276
+ * @example
277
+ * s.tuple([s.number(), s.number()]); // Schema<[number, number]>
278
+ *
279
+ * @template {[Schema<any>, ...Schema<any>[]] | []} T
280
+ * @param {T} items
281
+ * @returns {TupleSchema<{ -readonly [K in keyof T]: Infer<T[K]> }>}
282
+ */
283
+ declare function tuple<T extends [Schema<any>, ...Schema<any>[]] | []>(items: T): TupleSchema<{ -readonly [K in keyof T]: Infer<T[K]>; }>;
284
+ /**
285
+ * An object with any keys whose values match a schema, like a dictionary.
286
+ *
287
+ * @example
288
+ * s.record(s.number()); // Record<string, number>
289
+ * s.record(s.boolean(), s.string().regex(/^[a-z]+$/)); // keys checked too
290
+ *
291
+ * @template V
292
+ * @param {Schema<V>} values
293
+ * @param {Schema<string>} [keys]
294
+ * @returns {RecordSchema<V>}
295
+ */
296
+ declare function record<V>(values: Schema<V>, keys?: Schema<string>): RecordSchema<V>;
297
+ /**
298
+ * A schema defined later, for recursive data like trees.
299
+ *
300
+ * @example
301
+ * const Category = s.object({
302
+ * name: s.string(),
303
+ * children: s.lazy(() => s.array(Category)).default([]),
304
+ * });
305
+ *
306
+ * @template T
307
+ * @param {() => Schema<T>} getter
308
+ * @returns {LazySchema<T>}
309
+ */
310
+ declare function lazy<T>(getter: () => Schema<T>): LazySchema<T>;
311
+ /**
312
+ * An instance of a class.
313
+ *
314
+ * @example
315
+ * s.instanceOf(URL);
316
+ *
317
+ * @template {new (...args: any[]) => any} C
318
+ * @param {C} ctor
319
+ * @param {Message} [message]
320
+ * @returns {CustomSchema<InstanceType<C>>}
321
+ */
322
+ declare function instanceOf<C extends new (...args: any[]) => any>(ctor: C, message?: Message): CustomSchema<InstanceType<C>>;
323
+ /**
324
+ * A schema from any test, usually a type guard.
325
+ *
326
+ * @example
327
+ * const Color = s.custom(nc.isHexColor, "Expected a hex color");
328
+ *
329
+ * @template [T=unknown]
330
+ * @param {((value: unknown) => value is T) | ((value: unknown) => boolean)} test
331
+ * @param {Message} [message]
332
+ * @returns {CustomSchema<T>}
333
+ */
334
+ declare function custom<T = unknown>(test: ((value: unknown) => value is T) | ((value: unknown) => boolean), message?: Message): CustomSchema<T>;
335
+ /**
336
+ * Anything, typed as `any`.
337
+ * @returns {Schema<any>}
338
+ */
339
+ declare function any(): Schema<any>;
340
+ /**
341
+ * Anything, typed as `unknown`.
342
+ * @returns {Schema<unknown>}
343
+ */
344
+ declare function unknown(): Schema<unknown>;
345
+ /**
346
+ * The `s.coerce` builders.
347
+ * @typedef {object} CoerceBuilders
348
+ * @property {() => StringSchema} string A string schema that turns any value into a string first.
349
+ * @property {() => NumberSchema} number A number schema that converts strings like `"42"`, booleans and dates first.
350
+ * @property {() => BooleanSchema} boolean A boolean schema that understands `"true"`, `"1"`, `"yes"`, `"on"` and their opposites.
351
+ * @property {() => DateSchema} date A date schema that converts ISO strings and timestamps.
352
+ * @property {() => BigIntSchema} bigint A bigint schema that converts numeric strings and integers.
353
+ */
354
+ /**
355
+ * Schemas that convert their input before checking it. Query strings, form
356
+ * fields and environment variables are always strings, so this is what you
357
+ * want for them.
358
+ *
359
+ * @example
360
+ * const Query = s.object({
361
+ * page: s.coerce.number().int().min(1).default(1),
362
+ * active: s.coerce.boolean().default(false),
363
+ * });
364
+ * Query.parse({ page: "2", active: "true" }); // { page: 2, active: true }
365
+ *
366
+ * @type {CoerceBuilders}
367
+ */
368
+ declare const coerce: CoerceBuilders;
369
+ /**
370
+ * The base of every schema.
371
+ *
372
+ * @template [T=unknown]
373
+ */
374
+ declare class Schema<T = unknown> {
375
+ /** @protected @type {Step[]} */
376
+ protected _steps: Step[];
377
+ /** @protected */
378
+ protected _optional: boolean;
379
+ /** @protected */
380
+ protected _nullable: boolean;
381
+ /** @protected @type {{ value: unknown } | undefined} */
382
+ protected _default: {
383
+ value: unknown;
384
+ } | undefined;
385
+ /** @protected @type {{ value: unknown } | undefined} */
386
+ protected _catch: {
387
+ value: unknown;
388
+ } | undefined;
389
+ /** @protected @type {Message | undefined} */
390
+ protected _typeMessage: Message | undefined;
391
+ /** @protected @type {string | undefined} */
392
+ protected _description: string | undefined;
393
+ /**
394
+ * Checks the type, and coerces when asked. Subclasses override it.
395
+ * @param {unknown} value
396
+ * @param {ParseContext} _ctx
397
+ * @returns {unknown}
398
+ * @protected
399
+ */
400
+ protected _check(value: unknown, _ctx: ParseContext): unknown;
401
+ /**
402
+ * @returns {this}
403
+ * @protected
404
+ */
405
+ protected _clone(): this;
406
+ /**
407
+ * @param {Step} step
408
+ * @returns {this}
409
+ * @protected
410
+ */
411
+ protected _with(step: Step): this;
412
+ /**
413
+ * @param {unknown} input
414
+ * @param {ParseContext} ctx
415
+ * @returns {unknown} The output, or `INVALID`.
416
+ * @protected
417
+ */
418
+ protected _run(input: unknown, ctx: ParseContext): unknown;
419
+ /**
420
+ * Validates a value and returns it, with defaults and transformations
421
+ * applied. Unknown object keys are dropped.
422
+ *
423
+ * @example
424
+ * const port = s.coerce.number().int().min(1).max(65535).parse(process.env.PORT);
425
+ *
426
+ * @param {unknown} value
427
+ * @returns {T}
428
+ * @throws {ValidationError} Listing every issue with its path.
429
+ */
430
+ parse(value: unknown): T;
431
+ /**
432
+ * Validates a value without throwing.
433
+ *
434
+ * @example
435
+ * const result = User.safeParse(req.body);
436
+ * if (!result.success) return res.status(400).json(result.error.flatten());
437
+ * saveUser(result.data);
438
+ *
439
+ * @param {unknown} value
440
+ * @returns {SafeParseResult<T>}
441
+ */
442
+ safeParse(value: unknown): SafeParseResult<T>;
443
+ /**
444
+ * Is the value valid? Works as a type guard, and builds no error.
445
+ *
446
+ * @example
447
+ * if (Email.is(input)) sendMail(input); // input is a string here
448
+ *
449
+ * @param {unknown} value
450
+ * @returns {value is T}
451
+ */
452
+ is(value: unknown): value is T;
453
+ /**
454
+ * Also accepts `undefined`. In an object, the key becomes optional.
455
+ *
456
+ * @example
457
+ * s.object({ nickname: s.string().optional() }); // { nickname?: string }
458
+ *
459
+ * @returns {Schema<T | undefined>}
460
+ */
461
+ optional(): Schema<T | undefined>;
462
+ /**
463
+ * Also accepts `null`.
464
+ *
465
+ * @returns {Schema<T | null>}
466
+ */
467
+ nullable(): Schema<T | null>;
468
+ /**
469
+ * Also accepts `null` and `undefined`.
470
+ *
471
+ * @returns {Schema<T | null | undefined>}
472
+ */
473
+ nullish(): Schema<T | null | undefined>;
474
+ /**
475
+ * Uses this value when the input is `undefined`. Objects are copied each
476
+ * time; pass a function to build a fresh value on every parse.
477
+ *
478
+ * @example
479
+ * s.string().default("guest");
480
+ * s.date().default(() => new Date());
481
+ *
482
+ * @param {Exclude<T, undefined> | (() => Exclude<T, undefined>)} value
483
+ * @returns {Schema<Exclude<T, undefined>>}
484
+ */
485
+ default(value: Exclude<T, undefined> | (() => Exclude<T, undefined>)): Schema<Exclude<T, undefined>>;
486
+ /**
487
+ * Returns this value instead of failing when the input is invalid.
488
+ *
489
+ * @example
490
+ * s.number().catch(0).parse("not a number"); // 0
491
+ *
492
+ * @param {T | ((input: unknown) => T)} value A value, or a function that gets the invalid input.
493
+ * @returns {Schema<T>}
494
+ */
495
+ catch(value: T | ((input: unknown) => T)): Schema<T>;
496
+ /**
497
+ * Changes the value once it's valid. Runs after the checks written before it.
498
+ *
499
+ * @example
500
+ * s.string().transform((value) => value.split(",")); // Schema<string[]>
501
+ *
502
+ * @template U
503
+ * @param {(value: T) => U} fn
504
+ * @returns {Schema<U>}
505
+ */
506
+ transform<U>(fn: (value: T) => U): Schema<U>;
507
+ /**
508
+ * Adds your own rule.
509
+ *
510
+ * @example
511
+ * s.object({ password: s.string(), confirm: s.string() })
512
+ * .refine((v) => v.password === v.confirm, { message: "Passwords don't match", path: ["confirm"] });
513
+ *
514
+ * @param {(value: T) => boolean} test Returns `true` when the value is fine.
515
+ * @param {Message | RefineOptions} [options]
516
+ * @returns {this}
517
+ */
518
+ refine(test: (value: T) => boolean, options?: Message | RefineOptions): this;
519
+ /**
520
+ * Accepts values that match this schema or another one.
521
+ *
522
+ * @example
523
+ * s.string().or(s.number()); // Schema<string | number>
524
+ *
525
+ * @template U
526
+ * @param {Schema<U>} other
527
+ * @returns {Schema<T | U>}
528
+ */
529
+ or<U>(other: Schema<U>): Schema<T | U>;
530
+ /**
531
+ * An array of this schema.
532
+ *
533
+ * @example
534
+ * s.string().email().array(); // Schema<string[]>
535
+ *
536
+ * @returns {ArraySchema<T>}
537
+ */
538
+ array(): ArraySchema<T>;
539
+ /**
540
+ * Sends the result into another schema. With `transform()` in between,
541
+ * it validates what a conversion produced.
542
+ *
543
+ * @example
544
+ * const Port = s.string().transform(Number).pipe(s.number().int().min(1).max(65535));
545
+ * Port.parse("8080"); // 8080
546
+ * Port.parse("abc"); // ValidationError: Expected number, received NaN
547
+ *
548
+ * @template U
549
+ * @param {Schema<U>} next
550
+ * @returns {Schema<U>}
551
+ */
552
+ pipe<U>(next: Schema<U>): Schema<U>;
553
+ /**
554
+ * Describes what this schema accepts as a JSON Schema (draft 2020-12).
555
+ * Use it for an OpenAPI document, a form generator, or the input of a
556
+ * tool you give to a language model. Rules that only exist in code,
557
+ * like `refine()`, `transform()` and what follows a `pipe()`, can't be
558
+ * expressed and are left out.
559
+ *
560
+ * @example
561
+ * s.object({ name: s.string().min(2), age: s.number().int().optional() }).toJSONSchema();
562
+ * // {
563
+ * // type: "object",
564
+ * // properties: { name: { type: "string", minLength: 2 }, age: { type: "integer" } },
565
+ * // required: ["name"],
566
+ * // }
567
+ *
568
+ * @returns {JSONSchema}
569
+ */
570
+ toJSONSchema(): JSONSchema;
571
+ /**
572
+ * The JSON Schema of the type itself. Subclasses override it.
573
+ * @param {_JSONContext} _ctx
574
+ * @returns {JSONSchema}
575
+ * @protected
576
+ */
577
+ protected _json(_ctx: _JSONContext): JSONSchema;
578
+ /**
579
+ * The JSON Schema with what every schema can carry: rules, `null`,
580
+ * a description, a default.
581
+ * @param {_JSONContext} ctx
582
+ * @returns {JSONSchema}
583
+ * @protected
584
+ */
585
+ protected _toJSON(ctx: _JSONContext): JSONSchema;
586
+ /**
587
+ * Attaches a description, available as `.description`. Useful to generate
588
+ * docs or forms.
589
+ *
590
+ * @param {string} text
591
+ * @returns {this}
592
+ */
593
+ describe(text: string): this;
594
+ /** The text set with `describe()`. */
595
+ get description(): string | undefined;
596
+ }
597
+ import { ValidationError } from "./errors.js";
598
+ /**
599
+ * A string schema.
600
+ *
601
+ * @extends {Schema<string>}
602
+ */
603
+ declare class StringSchema extends Schema<string> {
604
+ constructor();
605
+ /** @protected */
606
+ protected _coerce: boolean;
607
+ /**
608
+ * @param {(v: string) => boolean} test
609
+ * @param {string} code
610
+ * @param {Message} message
611
+ * @param {Record<string, unknown>} [details]
612
+ * @param {Record<string, unknown>} [json] What the rule is called in JSON Schema.
613
+ * @returns {this}
614
+ * @protected
615
+ */
616
+ protected _rule(test: (v: string) => boolean, code: string, message: Message, details?: Record<string, unknown>, json?: Record<string, unknown>): this;
617
+ /**
618
+ * At least `length` characters.
619
+ * @param {number} length
620
+ * @param {Message} [message]
621
+ * @returns {this}
622
+ */
623
+ min(length: number, message?: Message): this;
624
+ /**
625
+ * At most `length` characters.
626
+ * @param {number} length
627
+ * @param {Message} [message]
628
+ * @returns {this}
629
+ */
630
+ max(length: number, message?: Message): this;
631
+ /**
632
+ * Exactly `length` characters.
633
+ * @param {number} length
634
+ * @param {Message} [message]
635
+ * @returns {this}
636
+ */
637
+ length(length: number, message?: Message): this;
638
+ /**
639
+ * Not the empty string.
640
+ * @param {Message} [message]
641
+ * @returns {this}
642
+ */
643
+ nonempty(message?: Message): this;
644
+ /**
645
+ * A valid email address.
646
+ * @param {Message} [message]
647
+ * @returns {this}
648
+ */
649
+ email(message?: Message): this;
650
+ /**
651
+ * An absolute URL.
652
+ * @param {Message | { message?: Message, protocols?: string[] }} [options] A message, or allowed protocols (http and https by default).
653
+ * @returns {this}
654
+ */
655
+ url(options?: Message | {
656
+ message?: Message;
657
+ protocols?: string[];
658
+ }): this;
659
+ /**
660
+ * A UUID.
661
+ * @param {Message} [message]
662
+ * @returns {this}
663
+ */
664
+ uuid(message?: Message): this;
665
+ /**
666
+ * An IP address.
667
+ * @param {4 | 6 | Message} [versionOrMessage] Only IPv4 or IPv6, or a message.
668
+ * @param {Message} [message]
669
+ * @returns {this}
670
+ */
671
+ ip(versionOrMessage?: 4 | 6 | Message, message?: Message): this;
672
+ /**
673
+ * An ISO 8601 date or date-time, like `2024-01-31T10:00:00Z`.
674
+ * @param {Message} [message]
675
+ * @returns {this}
676
+ */
677
+ datetime(message?: Message): this;
678
+ /**
679
+ * Matches a regular expression.
680
+ * @param {RegExp} pattern
681
+ * @param {Message} [message]
682
+ * @returns {this}
683
+ */
684
+ regex(pattern: RegExp, message?: Message): this;
685
+ /**
686
+ * Starts with `prefix`.
687
+ * @param {string} prefix
688
+ * @param {Message} [message]
689
+ * @returns {this}
690
+ */
691
+ startsWith(prefix: string, message?: Message): this;
692
+ /**
693
+ * Ends with `suffix`.
694
+ * @param {string} suffix
695
+ * @param {Message} [message]
696
+ * @returns {this}
697
+ */
698
+ endsWith(suffix: string, message?: Message): this;
699
+ /**
700
+ * Contains `search`.
701
+ * @param {string} search
702
+ * @param {Message} [message]
703
+ * @returns {this}
704
+ */
705
+ includes(search: string, message?: Message): this;
706
+ /**
707
+ * Trims whitespace before the checks that follow.
708
+ * @returns {this}
709
+ */
710
+ trim(): this;
711
+ /**
712
+ * Lowercases before the checks that follow.
713
+ * @returns {this}
714
+ */
715
+ toLowerCase(): this;
716
+ /**
717
+ * Uppercases before the checks that follow.
718
+ * @returns {this}
719
+ */
720
+ toUpperCase(): this;
721
+ /**
722
+ * A calendar date like `2024-01-31`, without a time.
723
+ * @param {Message} [message]
724
+ * @returns {this}
725
+ */
726
+ date(message?: Message): this;
727
+ /**
728
+ * A URL slug like `my-first-post`: lowercase letters, digits and single dashes.
729
+ * @param {Message} [message]
730
+ * @returns {this}
731
+ */
732
+ slug(message?: Message): this;
733
+ /**
734
+ * Hexadecimal digits only.
735
+ * @param {Message} [message]
736
+ * @returns {this}
737
+ */
738
+ hex(message?: Message): this;
739
+ /**
740
+ * Base64 data.
741
+ * @param {Message} [message]
742
+ * @returns {this}
743
+ */
744
+ base64(message?: Message): this;
745
+ /**
746
+ * A ULID.
747
+ * @param {Message} [message]
748
+ * @returns {this}
749
+ */
750
+ ulid(message?: Message): this;
751
+ /**
752
+ * A semantic version like `1.4.0` or `2.0.0-beta.1`.
753
+ * @param {Message} [message]
754
+ * @returns {this}
755
+ */
756
+ semver(message?: Message): this;
757
+ /**
758
+ * A host name like `api.example.com`.
759
+ * @param {Message} [message]
760
+ * @returns {this}
761
+ */
762
+ hostname(message?: Message): this;
763
+ /**
764
+ * @returns {JSONSchema}
765
+ * @override
766
+ * @protected
767
+ */
768
+ protected override _json(): JSONSchema;
769
+ }
770
+ /**
771
+ * A number schema.
772
+ *
773
+ * @extends {Schema<number>}
774
+ */
775
+ declare class NumberSchema extends Schema<number> {
776
+ constructor();
777
+ /** @protected */
778
+ protected _coerce: boolean;
779
+ /**
780
+ * @param {(v: number) => boolean} test
781
+ * @param {string} code
782
+ * @param {Message} message
783
+ * @param {Record<string, unknown>} [details]
784
+ * @param {Record<string, unknown>} [json] What the rule is called in JSON Schema.
785
+ * @returns {this}
786
+ * @protected
787
+ */
788
+ protected _rule(test: (v: number) => boolean, code: string, message: Message, details?: Record<string, unknown>, json?: Record<string, unknown>): this;
789
+ /**
790
+ * At least `value`.
791
+ * @param {number} value
792
+ * @param {Message} [message]
793
+ * @returns {this}
794
+ */
795
+ min(value: number, message?: Message): this;
796
+ /**
797
+ * At most `value`.
798
+ * @param {number} value
799
+ * @param {Message} [message]
800
+ * @returns {this}
801
+ */
802
+ max(value: number, message?: Message): this;
803
+ /**
804
+ * An integer.
805
+ * @param {Message} [message]
806
+ * @returns {this}
807
+ */
808
+ int(message?: Message): this;
809
+ /**
810
+ * Greater than 0.
811
+ * @param {Message} [message]
812
+ * @returns {this}
813
+ */
814
+ positive(message?: Message): this;
815
+ /**
816
+ * 0 or more.
817
+ * @param {Message} [message]
818
+ * @returns {this}
819
+ */
820
+ nonnegative(message?: Message): this;
821
+ /**
822
+ * Less than 0.
823
+ * @param {Message} [message]
824
+ * @returns {this}
825
+ */
826
+ negative(message?: Message): this;
827
+ /**
828
+ * A multiple of `step`.
829
+ * @param {number} step
830
+ * @param {Message} [message]
831
+ * @returns {this}
832
+ */
833
+ multipleOf(step: number, message?: Message): this;
834
+ /**
835
+ * Greater than `value`, which itself is refused.
836
+ * @param {number} value
837
+ * @param {Message} [message]
838
+ * @returns {this}
839
+ */
840
+ gt(value: number, message?: Message): this;
841
+ /**
842
+ * Less than `value`, which itself is refused.
843
+ * @param {number} value
844
+ * @param {Message} [message]
845
+ * @returns {this}
846
+ */
847
+ lt(value: number, message?: Message): this;
848
+ /**
849
+ * An integer JavaScript can hold exactly: up to 2^53 - 1 either way.
850
+ * Ids from a database or an API should pass this before any arithmetic.
851
+ * @param {Message} [message]
852
+ * @returns {this}
853
+ */
854
+ safe(message?: Message): this;
855
+ /**
856
+ * @returns {JSONSchema}
857
+ * @override
858
+ * @protected
859
+ */
860
+ protected override _json(): JSONSchema;
861
+ }
862
+ /**
863
+ * A boolean schema.
864
+ *
865
+ * @extends {Schema<boolean>}
866
+ */
867
+ declare class BooleanSchema extends Schema<boolean> {
868
+ constructor();
869
+ /** @protected */
870
+ protected _coerce: boolean;
871
+ /**
872
+ * @returns {JSONSchema}
873
+ * @override
874
+ * @protected
875
+ */
876
+ protected override _json(): JSONSchema;
877
+ }
878
+ /**
879
+ * A date schema.
880
+ *
881
+ * @extends {Schema<Date>}
882
+ */
883
+ declare class DateSchema extends Schema<Date> {
884
+ constructor();
885
+ /** @protected */
886
+ protected _coerce: boolean;
887
+ /**
888
+ * On or after `date`.
889
+ * @param {Date | number | string} date
890
+ * @param {Message} [message]
891
+ * @returns {this}
892
+ */
893
+ min(date: Date | number | string, message?: Message): this;
894
+ /**
895
+ * On or before `date`.
896
+ * @param {Date | number | string} date
897
+ * @param {Message} [message]
898
+ * @returns {this}
899
+ */
900
+ max(date: Date | number | string, message?: Message): this;
901
+ /**
902
+ * @returns {JSONSchema}
903
+ * @override
904
+ * @protected
905
+ */
906
+ protected override _json(): JSONSchema;
907
+ }
908
+ /**
909
+ * A bigint schema.
910
+ *
911
+ * @extends {Schema<bigint>}
912
+ */
913
+ declare class BigIntSchema extends Schema<bigint> {
914
+ constructor();
915
+ /** @protected */
916
+ protected _coerce: boolean;
917
+ /**
918
+ * @returns {JSONSchema}
919
+ * @override
920
+ * @protected
921
+ */
922
+ protected override _json(): JSONSchema;
923
+ }
924
+ /**
925
+ * A schema that accepts a fixed set of values.
926
+ *
927
+ * @template T
928
+ * @extends {Schema<T>}
929
+ */
930
+ declare class LiteralSchema<T> extends Schema<T> {
931
+ /** @param {readonly T[]} values */
932
+ constructor(values: readonly T[]);
933
+ /** @protected */
934
+ protected _values: readonly T[];
935
+ /** @protected @type {Set<unknown>} */
936
+ protected _set: Set<unknown>;
937
+ /**
938
+ * @returns {JSONSchema}
939
+ * @override
940
+ * @protected
941
+ */
942
+ protected override _json(): JSONSchema;
943
+ /** The accepted values. */
944
+ get options(): T[];
945
+ }
946
+ /**
947
+ * An array schema.
948
+ *
949
+ * @template T
950
+ * @extends {Schema<T[]>}
951
+ */
952
+ declare class ArraySchema<T> extends Schema<T[]> {
953
+ /** @param {Schema<T>} item */
954
+ constructor(item: Schema<T>);
955
+ /** @protected */
956
+ protected _item: Schema<T>;
957
+ /**
958
+ * @param {(v: T[]) => boolean} test
959
+ * @param {string} code
960
+ * @param {Message} message
961
+ * @param {Record<string, unknown>} [details]
962
+ * @param {Record<string, unknown>} [json]
963
+ * @returns {this}
964
+ * @protected
965
+ */
966
+ protected _rule(test: (v: T[]) => boolean, code: string, message: Message, details?: Record<string, unknown>, json?: Record<string, unknown>): this;
967
+ /**
968
+ * At least `count` items.
969
+ * @param {number} count
970
+ * @param {Message} [message]
971
+ * @returns {this}
972
+ */
973
+ min(count: number, message?: Message): this;
974
+ /**
975
+ * At most `count` items.
976
+ * @param {number} count
977
+ * @param {Message} [message]
978
+ * @returns {this}
979
+ */
980
+ max(count: number, message?: Message): this;
981
+ /**
982
+ * Exactly `count` items.
983
+ * @param {number} count
984
+ * @param {Message} [message]
985
+ * @returns {this}
986
+ */
987
+ length(count: number, message?: Message): this;
988
+ /**
989
+ * At least one item.
990
+ * @param {Message} [message]
991
+ * @returns {this}
992
+ */
993
+ nonempty(message?: Message): this;
994
+ /**
995
+ * No duplicates, compared by value or by a key.
996
+ * @param {((item: T) => unknown) | Message} [keyOrMessage] A function returning the key, or a message.
997
+ * @param {Message} [message]
998
+ * @returns {this}
999
+ */
1000
+ unique(keyOrMessage?: ((item: T) => unknown) | Message, message?: Message): this;
1001
+ /** The schema of the items. */
1002
+ get element(): Schema<T>;
1003
+ }
1004
+ /**
1005
+ * An object schema.
1006
+ *
1007
+ * @template {Shape} S
1008
+ * @extends {Schema<ObjectOutput<S>>}
1009
+ */
1010
+ declare class ObjectSchema<S extends Shape> extends Schema<{ [K_1 in keyof S as undefined extends Infer<S[K_1]> ? never : K_1]: Infer<S[K_1]>; } & { [K_2 in keyof S as undefined extends Infer<S[K_2]> ? K_2 : never]?: Infer<S[K_2]> | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never> {
1011
+ /** @param {S} shape */
1012
+ constructor(shape: S);
1013
+ /** @protected @type {"strip" | "strict" | "passthrough"} */
1014
+ protected _unknown: "strip" | "strict" | "passthrough";
1015
+ /** @protected */
1016
+ protected _shape: S;
1017
+ /** @protected @type {string[]} */
1018
+ protected _keys: string[];
1019
+ /** @protected @type {Array<Schema<any>>} */
1020
+ protected _schemas: Array<Schema<any>>;
1021
+ /**
1022
+ * A schema with another shape that keeps how this one treats unknown keys.
1023
+ * @param {Shape} shape
1024
+ * @returns {any}
1025
+ * @protected
1026
+ */
1027
+ protected _reshape(shape: Shape): any;
1028
+ /** The schema of each key. */
1029
+ get shape(): S;
1030
+ /**
1031
+ * Rejects unknown keys instead of dropping them.
1032
+ * @returns {this}
1033
+ */
1034
+ strict(): this;
1035
+ /**
1036
+ * Keeps unknown keys instead of dropping them.
1037
+ * @returns {this}
1038
+ */
1039
+ passthrough(): this;
1040
+ /**
1041
+ * Adds keys, or replaces existing ones.
1042
+ * @template {Shape} M
1043
+ * @param {M} more
1044
+ * @returns {ObjectSchema<Omit<S, keyof M> & M>}
1045
+ */
1046
+ extend<M extends Shape>(more: M): ObjectSchema<Omit<S, keyof M> & M>;
1047
+ /**
1048
+ * Keeps only some keys.
1049
+ * @template {keyof S & string} K
1050
+ * @param {readonly K[]} keys
1051
+ * @returns {ObjectSchema<Pick<S, K>>}
1052
+ */
1053
+ pick<K_3 extends keyof S & string>(keys: readonly K_3[]): ObjectSchema<Pick<S, K_3>>;
1054
+ /**
1055
+ * Drops some keys.
1056
+ * @template {keyof S & string} K
1057
+ * @param {readonly K[]} keys
1058
+ * @returns {ObjectSchema<Omit<S, K>>}
1059
+ */
1060
+ omit<K_3 extends keyof S & string>(keys: readonly K_3[]): ObjectSchema<Omit<S, K_3>>;
1061
+ /**
1062
+ * Makes every key optional, which suits PATCH requests.
1063
+ * @returns {ObjectSchema<{ [K in keyof S]: Schema<Infer<S[K]> | undefined> }>}
1064
+ */
1065
+ partial(): ObjectSchema<{ [K_3 in keyof S]: Schema<Infer<S[K_3]> | undefined>; }>;
1066
+ /**
1067
+ * Makes every key required again: the opposite of `partial()`.
1068
+ * @returns {ObjectSchema<{ [K in keyof S]: Schema<Exclude<Infer<S[K]>, undefined>> }>}
1069
+ */
1070
+ required(): ObjectSchema<{ [K_3 in keyof S]: Schema<Exclude<Infer<S[K_3]>, undefined>>; }>;
1071
+ /**
1072
+ * Combines two object schemas. Keys of the other one win, and so does
1073
+ * its way of treating unknown keys.
1074
+ *
1075
+ * @example
1076
+ * const Timestamps = s.object({ createdAt: s.date(), updatedAt: s.date() });
1077
+ * const Post = s.object({ title: s.string() }).merge(Timestamps);
1078
+ *
1079
+ * @template {Shape} M
1080
+ * @param {ObjectSchema<M>} other
1081
+ * @returns {ObjectSchema<Omit<S, keyof M> & M>}
1082
+ */
1083
+ merge<M extends Shape>(other: ObjectSchema<M>): ObjectSchema<Omit<S, keyof M> & M>;
1084
+ /**
1085
+ * A schema that accepts the name of any key: handy for a `sort` or
1086
+ * `fields` query parameter.
1087
+ *
1088
+ * @example
1089
+ * const SortBy = User.keyof(); // "name" | "email" | "age" | "role"
1090
+ *
1091
+ * @returns {LiteralSchema<keyof S & string>}
1092
+ */
1093
+ keyof(): LiteralSchema<keyof S & string>;
1094
+ }
1095
+ /**
1096
+ * A schema that accepts any of several schemas.
1097
+ *
1098
+ * @template T
1099
+ * @extends {Schema<T>}
1100
+ */
1101
+ declare class UnionSchema<T> extends Schema<T> {
1102
+ /** @param {ReadonlyArray<Schema<any>>} options */
1103
+ constructor(options: ReadonlyArray<Schema<any>>);
1104
+ /** @protected */
1105
+ protected _options: readonly Schema<any>[];
1106
+ }
1107
+ /**
1108
+ * A union of objects told apart by one key.
1109
+ *
1110
+ * @template T
1111
+ * @extends {Schema<T>}
1112
+ */
1113
+ declare class DiscriminatedUnionSchema<T> extends Schema<T> {
1114
+ /**
1115
+ * @param {string} key
1116
+ * @param {ReadonlyArray<ObjectSchema<any>>} options
1117
+ */
1118
+ constructor(key: string, options: ReadonlyArray<ObjectSchema<any>>);
1119
+ /** @protected */
1120
+ protected _key: string;
1121
+ /** @protected */
1122
+ protected _options: readonly ObjectSchema<any>[];
1123
+ /** @protected @type {Map<unknown, Schema<any>>} */
1124
+ protected _byValue: Map<unknown, Schema<any>>;
1125
+ }
1126
+ /**
1127
+ * A fixed-length array schema.
1128
+ *
1129
+ * @template {any[]} T
1130
+ * @extends {Schema<T>}
1131
+ */
1132
+ declare class TupleSchema<T extends any[]> extends Schema<T> {
1133
+ /** @param {ReadonlyArray<Schema<any>>} items */
1134
+ constructor(items: ReadonlyArray<Schema<any>>);
1135
+ /** @protected */
1136
+ protected _items: readonly Schema<any>[];
1137
+ }
1138
+ /**
1139
+ * A dictionary schema.
1140
+ *
1141
+ * @template V
1142
+ * @extends {Schema<Record<string, V>>}
1143
+ */
1144
+ declare class RecordSchema<V> extends Schema<Record<string, V>> {
1145
+ /**
1146
+ * @param {Schema<V>} values
1147
+ * @param {Schema<string> | undefined} keys
1148
+ */
1149
+ constructor(values: Schema<V>, keys: Schema<string> | undefined);
1150
+ /** @protected */
1151
+ protected _values: Schema<V>;
1152
+ /** @protected */
1153
+ protected _keys: Schema<string> | undefined;
1154
+ }
1155
+ /**
1156
+ * A schema resolved on first use, for recursive data.
1157
+ *
1158
+ * @template T
1159
+ * @extends {Schema<T>}
1160
+ */
1161
+ declare class LazySchema<T> extends Schema<T> {
1162
+ /** @param {() => Schema<T>} getter */
1163
+ constructor(getter: () => Schema<T>);
1164
+ /** @protected */
1165
+ protected _getter: () => Schema<T>;
1166
+ /** @protected @type {Schema<T> | undefined} */
1167
+ protected _resolved: Schema<T> | undefined;
1168
+ }
1169
+ /**
1170
+ * A schema built from a test function.
1171
+ *
1172
+ * @template T
1173
+ * @extends {Schema<T>}
1174
+ */
1175
+ declare class CustomSchema<T> extends Schema<T> {
1176
+ /**
1177
+ * @param {(value: unknown) => boolean} test
1178
+ * @param {Message} message
1179
+ * @param {string} expected
1180
+ */
1181
+ constructor(test: (value: unknown) => boolean, message: Message, expected: string);
1182
+ /** @protected */
1183
+ protected _test: (value: unknown) => boolean;
1184
+ /** @protected */
1185
+ protected _message: Message;
1186
+ /** @protected */
1187
+ protected _expected: string;
1188
+ }
1189
+ //# sourceMappingURL=Schema.d.ts.map