ascertain 2.0.88 → 3.0.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.
- package/README.md +323 -153
- package/build/index.cjs +483 -180
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +231 -186
- package/build/index.js +474 -180
- package/build/index.js.map +1 -1
- package/package.json +22 -19
- package/src/index.ts +991 -0
package/build/index.d.ts
CHANGED
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Abstract base class for schema operators.
|
|
3
|
-
*
|
|
4
|
-
* Provides a common constructor that enforces having at least one schema.
|
|
5
|
-
*
|
|
6
|
-
* @template T - The type of data the operator validates.
|
|
7
|
-
* @abstract
|
|
8
|
-
* @internal
|
|
9
|
-
*/
|
|
10
|
-
declare abstract class Operator<T> {
|
|
11
|
-
readonly schemas: Schema<T>[];
|
|
12
|
-
constructor(schemas: Schema<T>[]);
|
|
13
|
-
}
|
|
14
1
|
/**
|
|
15
2
|
* Symbol for validating object keys against a schema.
|
|
16
3
|
*/
|
|
@@ -23,6 +10,33 @@ export declare const $values: unique symbol;
|
|
|
23
10
|
* Symbol for enforcing strict object validation (no extra properties allowed).
|
|
24
11
|
*/
|
|
25
12
|
export declare const $strict: unique symbol;
|
|
13
|
+
declare const $op: unique symbol;
|
|
14
|
+
declare const OR: unique symbol;
|
|
15
|
+
declare const AND: unique symbol;
|
|
16
|
+
declare const OPTIONAL: unique symbol;
|
|
17
|
+
declare const TUPLE: unique symbol;
|
|
18
|
+
declare const DISCRIMINATED: unique symbol;
|
|
19
|
+
interface OrShape<T> {
|
|
20
|
+
readonly schemas: Schema<T>[];
|
|
21
|
+
readonly [$op]: typeof OR;
|
|
22
|
+
}
|
|
23
|
+
interface AndShape<T> {
|
|
24
|
+
readonly schemas: Schema<T>[];
|
|
25
|
+
readonly [$op]: typeof AND;
|
|
26
|
+
}
|
|
27
|
+
interface OptionalShape<T> {
|
|
28
|
+
readonly schemas: Schema<T>[];
|
|
29
|
+
readonly [$op]: typeof OPTIONAL;
|
|
30
|
+
}
|
|
31
|
+
interface TupleShape<T> {
|
|
32
|
+
readonly schemas: Schema<T>[];
|
|
33
|
+
readonly [$op]: typeof TUPLE;
|
|
34
|
+
}
|
|
35
|
+
interface DiscriminatedShape<T> {
|
|
36
|
+
readonly schemas: Schema<T>[];
|
|
37
|
+
readonly [$op]: typeof DISCRIMINATED;
|
|
38
|
+
readonly key: string;
|
|
39
|
+
}
|
|
26
40
|
/**
|
|
27
41
|
* Represents a schema for validating data.
|
|
28
42
|
*
|
|
@@ -39,170 +53,61 @@ export type Schema<T> = T extends Record<string | number | symbol, unknown> ? {
|
|
|
39
53
|
} & {
|
|
40
54
|
[$strict]?: boolean;
|
|
41
55
|
} : T extends Array<infer A> ? Schema<A>[] | unknown : unknown;
|
|
42
|
-
declare class Or<T> extends Operator<T> {
|
|
43
|
-
}
|
|
44
56
|
/**
|
|
45
57
|
* Operator for validating data against any of the provided schemas (logical OR).
|
|
46
|
-
*
|
|
47
|
-
* Creates a schema that accepts data matching any one of the provided schemas.
|
|
48
|
-
* This is useful for creating union types or alternative validation paths.
|
|
49
|
-
*
|
|
50
|
-
* @template T - The type of data the operator validates.
|
|
51
|
-
* @param schemas - Multiple schemas where at least one must match the data.
|
|
52
|
-
* @returns A schema that validates data against any of the provided schemas.
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```typescript
|
|
56
|
-
* import { or, ascertain } from 'ascertain';
|
|
57
|
-
*
|
|
58
|
-
* // Create a schema that accepts either a string or number
|
|
59
|
-
* const stringOrNumber = or(String, Number);
|
|
60
|
-
*
|
|
61
|
-
* ascertain(stringOrNumber, "hello", "value"); // ✓ Valid
|
|
62
|
-
* ascertain(stringOrNumber, 42, "value"); // ✓ Valid
|
|
63
|
-
* ascertain(stringOrNumber, true, "value"); // ✗ Throws error
|
|
64
|
-
*
|
|
65
|
-
* // Union of literal values
|
|
66
|
-
* const statusSchema = or('pending', 'completed', 'failed');
|
|
67
|
-
* ascertain(statusSchema, 'pending', "status"); // ✓ Valid
|
|
68
|
-
*
|
|
69
|
-
* // Complex schema combinations
|
|
70
|
-
* const userIdSchema = or(Number, { id: Number, temp: Boolean });
|
|
71
|
-
* ascertain(userIdSchema, 123, "userId"); // ✓ Valid
|
|
72
|
-
* ascertain(userIdSchema, { id: 456, temp: true }, "userId"); // ✓ Valid
|
|
73
|
-
* ```
|
|
74
58
|
*/
|
|
75
|
-
export declare const or: <T>(...schemas: Schema<T>[]) =>
|
|
76
|
-
declare class And<T> extends Operator<T> {
|
|
77
|
-
}
|
|
59
|
+
export declare const or: <T>(...schemas: Schema<T>[]) => OrShape<T>;
|
|
78
60
|
/**
|
|
79
61
|
* Operator for validating data against all provided schemas (logical AND).
|
|
80
|
-
*
|
|
81
|
-
* Creates a schema that requires data to match every one of the provided schemas.
|
|
82
|
-
* This is useful for combining multiple validation requirements or adding constraints.
|
|
83
|
-
*
|
|
84
|
-
* @template T - The type of data the operator validates.
|
|
85
|
-
* @param schemas - Multiple schemas that all must match the data.
|
|
86
|
-
* @returns A schema that validates data against all of the provided schemas.
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```typescript
|
|
90
|
-
* import { and, ascertain } from 'ascertain';
|
|
91
|
-
*
|
|
92
|
-
* // Combine object schema with additional constraints
|
|
93
|
-
* const userSchema = and(
|
|
94
|
-
* { name: String, age: Number },
|
|
95
|
-
* { age: Number } // Additional constraint
|
|
96
|
-
* );
|
|
97
|
-
*
|
|
98
|
-
* ascertain(userSchema, { name: "John", age: 25 }, "user"); // ✓ Valid
|
|
99
|
-
*
|
|
100
|
-
* // Ensure an object is both a Date and has specific methods
|
|
101
|
-
* const validDateSchema = and(Date, { toISOString: Function });
|
|
102
|
-
* ascertain(validDateSchema, new Date(), "date"); // ✓ Valid
|
|
103
|
-
*
|
|
104
|
-
* // Multiple validation layers
|
|
105
|
-
* const positiveNumberSchema = and(Number, (n: number) => n > 0);
|
|
106
|
-
* ascertain(positiveNumberSchema, 42, "count"); // ✓ Valid
|
|
107
|
-
* ascertain(positiveNumberSchema, -5, "count"); // ✗ Throws error
|
|
108
|
-
* ```
|
|
109
62
|
*/
|
|
110
|
-
export declare const and: <T>(...schemas: Schema<T>[]) =>
|
|
111
|
-
declare class Optional<T> extends Operator<T> {
|
|
112
|
-
constructor(schema: Schema<T>);
|
|
113
|
-
}
|
|
63
|
+
export declare const and: <T>(...schemas: Schema<T>[]) => AndShape<T>;
|
|
114
64
|
/**
|
|
115
65
|
* Operator for making a schema optional (nullable).
|
|
66
|
+
*/
|
|
67
|
+
export declare const optional: <T>(schema: Schema<T>) => OptionalShape<T>;
|
|
68
|
+
/**
|
|
69
|
+
* Operator for validating data against a fixed-length tuple of schemas.
|
|
70
|
+
*/
|
|
71
|
+
export declare const tuple: <T>(...schemas: Schema<T>[]) => TupleShape<T>;
|
|
72
|
+
/**
|
|
73
|
+
* Operator for validating data against a discriminated union.
|
|
116
74
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
75
|
+
* Optimizes validation by checking the discriminant field first and only
|
|
76
|
+
* validating the matching variant. More efficient than `or()` for unions
|
|
77
|
+
* where each variant has a common field with a unique literal value.
|
|
119
78
|
*
|
|
120
|
-
* @
|
|
121
|
-
* @param
|
|
122
|
-
* @returns A schema that validates data against the provided schema or accepts null/undefined.
|
|
79
|
+
* @param schemas - Array of object schemas, each with a discriminant field containing a literal value.
|
|
80
|
+
* @param key - The name of the discriminant field present in all variants.
|
|
123
81
|
*
|
|
124
82
|
* @example
|
|
125
83
|
* ```typescript
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* nickname: optional(String),
|
|
132
|
-
* age: Number
|
|
133
|
-
* };
|
|
134
|
-
*
|
|
135
|
-
* // All of these are valid
|
|
136
|
-
* ascertain(userSchema, {
|
|
137
|
-
* name: "John",
|
|
138
|
-
* nickname: "Johnny",
|
|
139
|
-
* age: 30
|
|
140
|
-
* }, "user"); // ✓ Valid
|
|
141
|
-
*
|
|
142
|
-
* ascertain(userSchema, {
|
|
143
|
-
* name: "Jane",
|
|
144
|
-
* nickname: null,
|
|
145
|
-
* age: 25
|
|
146
|
-
* }, "user"); // ✓ Valid
|
|
147
|
-
*
|
|
148
|
-
* ascertain(userSchema, {
|
|
149
|
-
* name: "Bob",
|
|
150
|
-
* age: 35
|
|
151
|
-
* // nickname is undefined
|
|
152
|
-
* }, "user"); // ✓ Valid
|
|
153
|
-
*
|
|
154
|
-
* // Optional complex objects
|
|
155
|
-
* const profileSchema = {
|
|
156
|
-
* id: Number,
|
|
157
|
-
* settings: optional({
|
|
158
|
-
* theme: String,
|
|
159
|
-
* notifications: Boolean
|
|
160
|
-
* })
|
|
161
|
-
* };
|
|
84
|
+
* const messageSchema = discriminated([
|
|
85
|
+
* { type: 'email', address: String },
|
|
86
|
+
* { type: 'sms', phone: String },
|
|
87
|
+
* { type: 'push', token: String },
|
|
88
|
+
* ], 'type');
|
|
162
89
|
* ```
|
|
163
90
|
*/
|
|
164
|
-
export declare const
|
|
165
|
-
declare class Tuple<T> extends Operator<T> {
|
|
166
|
-
}
|
|
91
|
+
export declare const discriminated: <T>(schemas: Schema<T>[], key: string) => DiscriminatedShape<T>;
|
|
167
92
|
/**
|
|
168
|
-
*
|
|
93
|
+
* Decodes a base64-encoded string to UTF-8.
|
|
169
94
|
*
|
|
170
|
-
*
|
|
171
|
-
* This is useful for coordinate pairs, RGB values, or any fixed-structure data.
|
|
95
|
+
* Uses `Buffer` in Node.js environments and `atob` in browsers.
|
|
172
96
|
*
|
|
173
|
-
* @
|
|
174
|
-
* @
|
|
175
|
-
* @returns A schema that validates data as a tuple with the specified structure.
|
|
176
|
-
*
|
|
177
|
-
* @example
|
|
178
|
-
* ```typescript
|
|
179
|
-
* import { tuple, ascertain } from 'ascertain';
|
|
180
|
-
*
|
|
181
|
-
* // 2D coordinate tuple
|
|
182
|
-
* const pointSchema = tuple(Number, Number);
|
|
183
|
-
* ascertain(pointSchema, [10, 20], "point"); // ✓ Valid
|
|
184
|
-
* ascertain(pointSchema, [1.5, 2.7], "point"); // ✓ Valid
|
|
185
|
-
* ascertain(pointSchema, [10], "point"); // ✗ Throws error (too short)
|
|
186
|
-
* ascertain(pointSchema, [10, 20, 30], "point"); // ✗ Throws error (too long)
|
|
187
|
-
*
|
|
188
|
-
* // RGB color tuple
|
|
189
|
-
* const colorSchema = tuple(Number, Number, Number);
|
|
190
|
-
* ascertain(colorSchema, [255, 128, 0], "color"); // ✓ Valid
|
|
191
|
-
*
|
|
192
|
-
* // Mixed type tuple
|
|
193
|
-
* const userInfoSchema = tuple(String, Number, Boolean);
|
|
194
|
-
* ascertain(userInfoSchema, ["Alice", 25, true], "userInfo"); // ✓ Valid
|
|
195
|
-
*
|
|
196
|
-
* // Nested tuple
|
|
197
|
-
* const lineSchema = tuple(
|
|
198
|
-
* tuple(Number, Number), // start point
|
|
199
|
-
* tuple(Number, Number) // end point
|
|
200
|
-
* );
|
|
201
|
-
* ascertain(lineSchema, [[0, 0], [10, 10]], "line"); // ✓ Valid
|
|
202
|
-
* ```
|
|
97
|
+
* @param value - The base64-encoded string to decode.
|
|
98
|
+
* @returns The decoded UTF-8 string.
|
|
203
99
|
*/
|
|
204
|
-
export declare const tuple: <T>(...schemas: Schema<T>[]) => Tuple<T>;
|
|
205
100
|
export declare const fromBase64: (value: string) => string;
|
|
101
|
+
/**
|
|
102
|
+
* Creates a TypeError with the given message, typed as T for deferred error handling.
|
|
103
|
+
*
|
|
104
|
+
* Used by `as.*` conversion utilities to return errors that can be caught
|
|
105
|
+
* during schema validation rather than throwing immediately.
|
|
106
|
+
*
|
|
107
|
+
* @template T - The expected return type (for type compatibility with conversion functions).
|
|
108
|
+
* @param message - The error message.
|
|
109
|
+
* @returns A TypeError instance typed as T.
|
|
110
|
+
*/
|
|
206
111
|
export declare const asError: <T>(message: string) => T;
|
|
207
112
|
export declare const as: {
|
|
208
113
|
/**
|
|
@@ -215,6 +120,13 @@ export declare const as: {
|
|
|
215
120
|
/**
|
|
216
121
|
* Attempts to convert a value to a number.
|
|
217
122
|
*
|
|
123
|
+
* Supports integers, floats, scientific notation (1e10), and prefixed formats:
|
|
124
|
+
* - Hexadecimal: `0x` or `0X` (e.g., `'0xFF'` → 255)
|
|
125
|
+
* - Octal: `0o` or `0O` (e.g., `'0o77'` → 63)
|
|
126
|
+
* - Binary: `0b` or `0B` (e.g., `'0b1010'` → 10)
|
|
127
|
+
*
|
|
128
|
+
* All formats support optional leading sign (`+` or `-`).
|
|
129
|
+
*
|
|
218
130
|
* @param value - The value to convert (expected to be a string representation of a number).
|
|
219
131
|
* @returns The value as a number, or a TypeError if not a valid number.
|
|
220
132
|
*/
|
|
@@ -266,19 +178,40 @@ export declare const as: {
|
|
|
266
178
|
base64: (value: string | undefined) => string;
|
|
267
179
|
};
|
|
268
180
|
/**
|
|
269
|
-
*
|
|
181
|
+
* Validator function returned by compile().
|
|
182
|
+
* Returns true if valid, false if invalid.
|
|
183
|
+
* Access `.issues` property after validation to get error details.
|
|
184
|
+
*/
|
|
185
|
+
export interface Validator<T> {
|
|
186
|
+
(data: T): boolean;
|
|
187
|
+
issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Options for the compile function.
|
|
191
|
+
*/
|
|
192
|
+
export interface CompileOptions {
|
|
193
|
+
/**
|
|
194
|
+
* When true, collects all validation errors instead of stopping at the first.
|
|
195
|
+
* Default is false (first-error mode) for optimal performance.
|
|
196
|
+
*/
|
|
197
|
+
allErrors?: boolean;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Compiles a schema into a high-performance validation function.
|
|
201
|
+
*
|
|
202
|
+
* By default uses first-error mode which stops at the first validation failure
|
|
203
|
+
* and returns immediately. This provides optimal performance for invalid data.
|
|
270
204
|
*
|
|
271
|
-
*
|
|
272
|
-
* that can be used to validate data against the schema.
|
|
205
|
+
* Set `allErrors: true` to collect all validation errors (slower but more informative).
|
|
273
206
|
*
|
|
274
207
|
* @template T - The type of data the schema validates.
|
|
275
208
|
* @param schema - The schema to compile.
|
|
276
|
-
* @param
|
|
277
|
-
* @returns A
|
|
209
|
+
* @param options - Optional configuration (allErrors: boolean).
|
|
210
|
+
* @returns A validator function that returns boolean. Access `.issues` for error details.
|
|
278
211
|
*
|
|
279
212
|
* @example
|
|
280
213
|
* ```typescript
|
|
281
|
-
* import { compile, optional,
|
|
214
|
+
* import { compile, optional, or } from 'ascertain';
|
|
282
215
|
*
|
|
283
216
|
* const userSchema = {
|
|
284
217
|
* name: String,
|
|
@@ -287,28 +220,24 @@ export declare const as: {
|
|
|
287
220
|
* role: or('admin', 'user', 'guest')
|
|
288
221
|
* };
|
|
289
222
|
*
|
|
290
|
-
*
|
|
223
|
+
* // First-error mode (default) - fastest for invalid data
|
|
224
|
+
* const validate = compile(userSchema);
|
|
291
225
|
*
|
|
292
|
-
* //
|
|
293
|
-
*
|
|
294
|
-
* name: 'John Doe',
|
|
295
|
-
* age: 30,
|
|
296
|
-
* email: 'john@example.com',
|
|
297
|
-
* role: 'user'
|
|
298
|
-
* });
|
|
226
|
+
* // All-errors mode - collects all validation issues
|
|
227
|
+
* const validateAll = compile(userSchema, { allErrors: true });
|
|
299
228
|
*
|
|
300
|
-
* //
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
* console.
|
|
229
|
+
* // Valid data
|
|
230
|
+
* if (validate({ name: 'John', age: 30, role: 'user' })) {
|
|
231
|
+
* console.log('Valid!');
|
|
232
|
+
* }
|
|
233
|
+
*
|
|
234
|
+
* // Invalid data - check .issues for details
|
|
235
|
+
* if (!validate({ name: 123, age: 'thirty' })) {
|
|
236
|
+
* console.log(validate.issues); // Array with first validation issue
|
|
308
237
|
* }
|
|
309
238
|
* ```
|
|
310
239
|
*/
|
|
311
|
-
export declare const compile: <T>(schema: Schema<T>,
|
|
240
|
+
export declare const compile: <T>(schema: Schema<T>, options?: CompileOptions) => Validator<T>;
|
|
312
241
|
/**
|
|
313
242
|
* Asserts that data conforms to a given schema.
|
|
314
243
|
*
|
|
@@ -318,7 +247,6 @@ export declare const compile: <T>(schema: Schema<T>, rootName: string) => (data:
|
|
|
318
247
|
* @template T - The type of data the schema validates.
|
|
319
248
|
* @param schema - The schema to validate against.
|
|
320
249
|
* @param data - The data to validate.
|
|
321
|
-
* @param rootName - A name for the root of the data structure (used in error messages, defaults to '[root]').
|
|
322
250
|
* @throws `{TypeError}` If the data does not conform to the schema.
|
|
323
251
|
*
|
|
324
252
|
* @example
|
|
@@ -340,7 +268,7 @@ export declare const compile: <T>(schema: Schema<T>, rootName: string) => (data:
|
|
|
340
268
|
* };
|
|
341
269
|
*
|
|
342
270
|
* // Validate data - throws if invalid, otherwise continues silently
|
|
343
|
-
* ascertain(userSchema, userData
|
|
271
|
+
* ascertain(userSchema, userData);
|
|
344
272
|
* console.log('User data is valid!');
|
|
345
273
|
*
|
|
346
274
|
* // Example with invalid data
|
|
@@ -349,7 +277,7 @@ export declare const compile: <T>(schema: Schema<T>, rootName: string) => (data:
|
|
|
349
277
|
* name: 'Bob',
|
|
350
278
|
* age: 'twenty-five', // Invalid: should be number
|
|
351
279
|
* active: true
|
|
352
|
-
* }
|
|
280
|
+
* });
|
|
353
281
|
* } catch (error) {
|
|
354
282
|
* console.error('Validation failed:', error.message);
|
|
355
283
|
* }
|
|
@@ -361,14 +289,131 @@ export declare const compile: <T>(schema: Schema<T>, rootName: string) => (data:
|
|
|
361
289
|
* const numbersSchema = [Number];
|
|
362
290
|
* const numbers = [1, 2, 3, 4, 5];
|
|
363
291
|
*
|
|
364
|
-
* ascertain(numbersSchema, numbers
|
|
292
|
+
* ascertain(numbersSchema, numbers);
|
|
365
293
|
*
|
|
366
294
|
* // Tuple validation
|
|
367
295
|
* const coordinateSchema = tuple(Number, Number);
|
|
368
296
|
* const point = [10, 20];
|
|
369
297
|
*
|
|
370
|
-
* ascertain(coordinateSchema, point
|
|
298
|
+
* ascertain(coordinateSchema, point);
|
|
371
299
|
* ```
|
|
372
300
|
*/
|
|
373
|
-
export declare const ascertain: <T>(schema: Schema<T>, data: T
|
|
301
|
+
export declare const ascertain: <T>(schema: Schema<T>, data: T) => void;
|
|
302
|
+
/**
|
|
303
|
+
* Extracts the shape of a config object based on the schema keys.
|
|
304
|
+
* Recursively picks only the properties defined in the schema.
|
|
305
|
+
*/
|
|
306
|
+
export type ExtractShape<C, S> = {
|
|
307
|
+
[K in keyof S & keyof C]: S[K] extends object ? (C[K] extends object ? ExtractShape<C[K], S[K]> : C[K]) : C[K];
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* Creates a typed validator function for a config object.
|
|
311
|
+
*
|
|
312
|
+
* Returns a function that validates a schema against the config and returns
|
|
313
|
+
* the same config reference with a narrowed type containing only the validated fields.
|
|
314
|
+
*
|
|
315
|
+
* @template C - The type of the config object.
|
|
316
|
+
* @param config - The config object to validate against.
|
|
317
|
+
* @returns A validator function that takes a schema and returns the typed config subset.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* ```typescript
|
|
321
|
+
* import { createValidator, as } from 'ascertain';
|
|
322
|
+
*
|
|
323
|
+
* const config = {
|
|
324
|
+
* app: { name: as.string(process.env.APP_NAME) },
|
|
325
|
+
* kafka: { brokers: as.array(process.env.BROKERS, ',') },
|
|
326
|
+
* redis: { host: as.string(process.env.REDIS_HOST) },
|
|
327
|
+
* };
|
|
328
|
+
*
|
|
329
|
+
* const validate = createValidator(config);
|
|
330
|
+
*
|
|
331
|
+
* // Consumer only validates what it needs
|
|
332
|
+
* const { app, kafka } = validate({
|
|
333
|
+
* app: { name: String },
|
|
334
|
+
* kafka: { brokers: [String] },
|
|
335
|
+
* });
|
|
336
|
+
*
|
|
337
|
+
* // app.name is typed as string
|
|
338
|
+
* // kafka.brokers is typed as string[]
|
|
339
|
+
* // redis is not accessible - TypeScript error
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
342
|
+
export declare const createValidator: <C>(config: C) => <S extends Schema<Partial<C>>>(schema: S) => ExtractShape<C, S>;
|
|
343
|
+
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
344
|
+
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
345
|
+
}
|
|
346
|
+
export declare namespace StandardSchemaV1 {
|
|
347
|
+
interface Props<Input = unknown, Output = Input> {
|
|
348
|
+
readonly version: 1;
|
|
349
|
+
readonly vendor: string;
|
|
350
|
+
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
|
351
|
+
readonly types?: {
|
|
352
|
+
readonly input: Input;
|
|
353
|
+
readonly output: Output;
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
357
|
+
interface SuccessResult<Output> {
|
|
358
|
+
readonly value: Output;
|
|
359
|
+
readonly issues?: undefined;
|
|
360
|
+
}
|
|
361
|
+
interface FailureResult {
|
|
362
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
363
|
+
}
|
|
364
|
+
interface Issue {
|
|
365
|
+
readonly message: string;
|
|
366
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
367
|
+
}
|
|
368
|
+
interface PathSegment {
|
|
369
|
+
readonly key: PropertyKey;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Wraps an Ascertain schema to make it Standard Schema v1 compliant.
|
|
374
|
+
*
|
|
375
|
+
* Creates a validator that implements the Standard Schema specification,
|
|
376
|
+
* enabling interoperability with tools like tRPC, TanStack Form, and other
|
|
377
|
+
* ecosystem libraries that consume Standard Schema-compliant validators.
|
|
378
|
+
*
|
|
379
|
+
* The returned function can be used both as a regular Ascertain validator
|
|
380
|
+
* (throws on error) and as a Standard Schema validator (returns result object).
|
|
381
|
+
*
|
|
382
|
+
* @template T - The type of data the schema validates.
|
|
383
|
+
* @param schema - The Ascertain schema to wrap.
|
|
384
|
+
* @returns A function that validates data, with a `~standard` property for Standard Schema compliance.
|
|
385
|
+
*
|
|
386
|
+
* @see https://standardschema.dev/
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* ```typescript
|
|
390
|
+
* import { standardSchema, or, optional } from 'ascertain';
|
|
391
|
+
*
|
|
392
|
+
* // Create a Standard Schema-compliant validator
|
|
393
|
+
* const userValidator = standardSchema({
|
|
394
|
+
* name: String,
|
|
395
|
+
* age: Number,
|
|
396
|
+
* role: or('admin', 'user'),
|
|
397
|
+
* email: optional(String),
|
|
398
|
+
* });
|
|
399
|
+
*
|
|
400
|
+
* // Use as regular Ascertain validator (throws on error)
|
|
401
|
+
* userValidator({ name: 'Alice', age: 30, role: 'admin' });
|
|
402
|
+
*
|
|
403
|
+
* // Use Standard Schema interface (returns result object)
|
|
404
|
+
* const result = userValidator['~standard'].validate(unknownData);
|
|
405
|
+
* if (result.issues) {
|
|
406
|
+
* console.log(result.issues);
|
|
407
|
+
* } else {
|
|
408
|
+
* console.log(result.value); // typed as User
|
|
409
|
+
* }
|
|
410
|
+
*
|
|
411
|
+
* // Works with tRPC, TanStack Form, etc.
|
|
412
|
+
* ```
|
|
413
|
+
*/
|
|
414
|
+
interface StandardSchemaFn<T> {
|
|
415
|
+
(data: T): void;
|
|
416
|
+
'~standard': StandardSchemaV1.Props<T, T>;
|
|
417
|
+
}
|
|
418
|
+
export declare const standardSchema: <T>(schema: Schema<T>) => StandardSchemaFn<T>;
|
|
374
419
|
export {};
|