@cleverbrush/schema 1.1.10 → 2.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.
Files changed (87) hide show
  1. package/README.md +1314 -101
  2. package/dist/builders/AnySchemaBuilder.d.ts +55 -15
  3. package/dist/builders/AnySchemaBuilder.js +2 -112
  4. package/dist/builders/AnySchemaBuilder.js.map +1 -0
  5. package/dist/builders/ArraySchemaBuilder.d.ts +124 -23
  6. package/dist/builders/ArraySchemaBuilder.js +2 -284
  7. package/dist/builders/ArraySchemaBuilder.js.map +1 -0
  8. package/dist/builders/BooleanSchemaBuilder.d.ts +95 -20
  9. package/dist/builders/BooleanSchemaBuilder.js +2 -150
  10. package/dist/builders/BooleanSchemaBuilder.js.map +1 -0
  11. package/dist/builders/DateSchemaBuilder.d.ts +135 -37
  12. package/dist/builders/DateSchemaBuilder.js +2 -433
  13. package/dist/builders/DateSchemaBuilder.js.map +1 -0
  14. package/dist/builders/ExternSchemaBuilder.d.ts +200 -0
  15. package/dist/builders/ExternSchemaBuilder.js +2 -0
  16. package/dist/builders/ExternSchemaBuilder.js.map +1 -0
  17. package/dist/builders/FunctionSchemaBuilder.d.ts +58 -15
  18. package/dist/builders/FunctionSchemaBuilder.js +2 -113
  19. package/dist/builders/FunctionSchemaBuilder.js.map +1 -0
  20. package/dist/builders/LazySchemaBuilder.d.ts +167 -0
  21. package/dist/builders/NullSchemaBuilder.d.ts +162 -0
  22. package/dist/builders/NumberSchemaBuilder.d.ts +143 -31
  23. package/dist/builders/NumberSchemaBuilder.js +2 -386
  24. package/dist/builders/NumberSchemaBuilder.js.map +1 -0
  25. package/dist/builders/ObjectSchemaBuilder.d.ts +266 -61
  26. package/dist/builders/ObjectSchemaBuilder.js +2 -589
  27. package/dist/builders/ObjectSchemaBuilder.js.map +1 -0
  28. package/dist/builders/PropertyValidationResult.d.ts +68 -0
  29. package/dist/builders/RecordSchemaBuilder.d.ts +341 -0
  30. package/dist/builders/RecordSchemaBuilder.js +2 -0
  31. package/dist/builders/RecordSchemaBuilder.js.map +1 -0
  32. package/dist/builders/SchemaBuilder.d.ts +818 -30
  33. package/dist/builders/StringSchemaBuilder.d.ts +152 -37
  34. package/dist/builders/StringSchemaBuilder.js +2 -414
  35. package/dist/builders/StringSchemaBuilder.js.map +1 -0
  36. package/dist/builders/TupleSchemaBuilder.d.ts +248 -0
  37. package/dist/builders/TupleSchemaBuilder.js +2 -0
  38. package/dist/builders/TupleSchemaBuilder.js.map +1 -0
  39. package/dist/builders/UnionSchemaBuilder.d.ts +133 -39
  40. package/dist/builders/UnionSchemaBuilder.js +2 -216
  41. package/dist/builders/UnionSchemaBuilder.js.map +1 -0
  42. package/dist/chunk-BFCMDDTX.js +2 -0
  43. package/dist/chunk-BFCMDDTX.js.map +1 -0
  44. package/dist/chunk-CTP4RHDG.js +2 -0
  45. package/dist/chunk-CTP4RHDG.js.map +1 -0
  46. package/dist/chunk-EUQ5AE3H.js +2 -0
  47. package/dist/chunk-EUQ5AE3H.js.map +1 -0
  48. package/dist/chunk-FWUEUW2N.js +2 -0
  49. package/dist/chunk-FWUEUW2N.js.map +1 -0
  50. package/dist/chunk-IJ6FO37G.js +2 -0
  51. package/dist/chunk-IJ6FO37G.js.map +1 -0
  52. package/dist/chunk-KESLT5EE.js +2 -0
  53. package/dist/chunk-KESLT5EE.js.map +1 -0
  54. package/dist/chunk-KFTO7TMB.js +2 -0
  55. package/dist/chunk-KFTO7TMB.js.map +1 -0
  56. package/dist/chunk-MKAYFPAR.js +2 -0
  57. package/dist/chunk-MKAYFPAR.js.map +1 -0
  58. package/dist/chunk-NXPH3ZUW.js +2 -0
  59. package/dist/chunk-NXPH3ZUW.js.map +1 -0
  60. package/dist/chunk-S5TC6NSU.js +2 -0
  61. package/dist/chunk-S5TC6NSU.js.map +1 -0
  62. package/dist/chunk-YWBNVHR6.js +2 -0
  63. package/dist/chunk-YWBNVHR6.js.map +1 -0
  64. package/dist/chunk-Z7QZ7IXT.js +2 -0
  65. package/dist/chunk-Z7QZ7IXT.js.map +1 -0
  66. package/dist/chunk-ZAN4ZHCJ.js +2 -0
  67. package/dist/chunk-ZAN4ZHCJ.js.map +1 -0
  68. package/dist/chunk-ZUPYV5TI.js +2 -0
  69. package/dist/chunk-ZUPYV5TI.js.map +1 -0
  70. package/dist/core.d.ts +23 -0
  71. package/dist/core.js +2 -0
  72. package/dist/core.js.map +1 -0
  73. package/dist/extension.d.ts +413 -0
  74. package/dist/extensions/array.d.ts +112 -0
  75. package/dist/extensions/enum.d.ts +190 -0
  76. package/dist/extensions/index.d.ts +108 -0
  77. package/dist/extensions/nullable.d.ts +26 -0
  78. package/dist/extensions/number.d.ts +228 -0
  79. package/dist/extensions/string.d.ts +332 -0
  80. package/dist/extensions/util.d.ts +45 -0
  81. package/dist/index.d.ts +7 -20
  82. package/dist/index.js +2 -19
  83. package/dist/index.js.map +1 -0
  84. package/dist/utils/transaction.d.ts +27 -4
  85. package/package.json +74 -6
  86. package/dist/builders/SchemaBuilder.js +0 -275
  87. package/dist/utils/transaction.js +0 -178
@@ -1,14 +1,91 @@
1
- import { Transaction } from '../utils/transaction.js';
2
- export type InferType<T> = T extends SchemaBuilder<infer TResult, infer TRequired> ? T extends {
3
- optimize: (...args: any[]) => SchemaBuilder<infer TOptimizedType, infer TOptimizedRequired>;
4
- } ? TOptimizedRequired extends true ? TOptimizedType : MakeOptional<TOptimizedType> : TRequired extends true ? TResult : MakeOptional<TResult> : T;
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ import { type Transaction } from '../utils/transaction.js';
3
+ import type { ArraySchemaBuilder } from './ArraySchemaBuilder.js';
4
+ import type { ExternSchemaBuilder } from './ExternSchemaBuilder.js';
5
+ import type { ObjectSchemaBuilder } from './ObjectSchemaBuilder.js';
6
+ /** @internal Symbol used as the key for the type brand on schema builders. */
7
+ declare const __type: unique symbol;
8
+ /** @internal */
9
+ export type SchemaTypeBrand = typeof __type;
10
+ /** @internal Symbol used as the key for the default-value brand on schema builders. */
11
+ declare const __hasDefault: unique symbol;
12
+ /** @internal */
13
+ export type HasDefaultBrand = typeof __hasDefault;
14
+ /** Symbol used as the key for branded/opaque types. */
15
+ declare const __brand: unique symbol;
16
+ /** Symbol used as the key for branded/opaque types. */
17
+ export type BRAND = typeof __brand;
18
+ /**
19
+ * Intersects a base type with a phantom brand tag.
20
+ * The brand exists only at the type level — zero runtime cost.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * type Email = Brand<string, 'Email'>;
25
+ * type UserId = Brand<number, 'UserId'>;
26
+ * ```
27
+ */
28
+ export type Brand<T, TBrand extends string | symbol> = T & {
29
+ readonly [K in BRAND]: TBrand;
30
+ };
31
+ /**
32
+ * Infers the TypeScript type that a `SchemaBuilder` instance validates.
33
+ * Takes into account type optimizations (via `optimize()`) and whether the schema is optional.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const userSchema = object({ name: string(), age: number().optional() });
38
+ * type User = InferType<typeof userSchema>;
39
+ * // { name: string; age?: number }
40
+ * ```
41
+ */
42
+ export type InferType<T> = T extends {
43
+ optimize: (...args: any[]) => {
44
+ readonly [K in SchemaTypeBrand]: infer TOptimized;
45
+ };
46
+ } ? TOptimized : T extends {
47
+ readonly [K in SchemaTypeBrand]: infer TType;
48
+ } ? TType : T;
49
+ /**
50
+ * Represents a single validation error with a human-readable error message.
51
+ */
5
52
  export type ValidationError = {
6
- path: string;
7
53
  message: string;
8
54
  };
55
+ /**
56
+ * Used to represent a validation result for nested
57
+ * objects/properties. Contains a list of errors and
58
+ * the value that caused them.
59
+ */
60
+ export type NestedValidationResult<TSchema, TRootSchema extends ObjectSchemaBuilder<any, any, any, any, any>, TParentPropertyDescriptor> = {
61
+ /**
62
+ * Value that property had and which caused error or errors
63
+ */
64
+ seenValue?: InferType<TSchema>;
65
+ /**
66
+ * A list of errors, empty if object satisfies a schema
67
+ */
68
+ errors: ReadonlyArray<string>;
69
+ /**
70
+ * Whether validation passed for this property and all of its children.
71
+ */
72
+ isValid: boolean;
73
+ get descriptor(): PropertyDescriptorInner<TRootSchema, TSchema, TParentPropertyDescriptor>;
74
+ };
75
+ /**
76
+ * Utility type that makes a value `T` optional (i.e. `T | undefined`).
77
+ * Used internally by {@link InferType} to represent optional schema fields.
78
+ */
9
79
  export type MakeOptional<T> = {
10
80
  prop?: T;
11
81
  }['prop'];
82
+ /**
83
+ * Type of the function that provides a validation error message for
84
+ * the given `seenValue` and `schema`. Can be a string or a function
85
+ * returning a string or a promise of a string.
86
+ * Should be used to provide a custom validation error message.
87
+ */
88
+ export type ValidationErrorMessageProvider<TSchema extends SchemaBuilder<any, any, any, any, any> = SchemaBuilder<any, any, any, any, any>> = string | ((seenValue: InferType<TSchema>, schema: TSchema) => string | Promise<string>);
12
89
  export type ValidationResult<T> = {
13
90
  /**
14
91
  * If `true` - object satisfies schema
@@ -21,33 +98,303 @@ export type ValidationResult<T> = {
21
98
  object?: T;
22
99
  errors?: ValidationError[];
23
100
  };
101
+ /**
102
+ * Error thrown by {@link SchemaBuilder.parse | parse()} and
103
+ * {@link SchemaBuilder.parseAsync | parseAsync()} when validation fails.
104
+ * Carries the full array of {@link ValidationError | validation errors}.
105
+ */
106
+ export declare class SchemaValidationError extends Error {
107
+ readonly errors: ValidationError[];
108
+ constructor(errors: ValidationError[]);
109
+ }
110
+ /**
111
+ * Internal result returned by the `preValidate` step of `SchemaBuilder`.
112
+ * Contains the validation context, any early errors, and the transaction
113
+ * wrapping the (possibly preprocessed) value.
114
+ */
24
115
  export type PreValidationResult<T, TTransactionType> = Omit<ValidationResult<T>, 'object'> & {
25
116
  context: ValidationContext;
26
117
  transaction?: Transaction<TTransactionType>;
118
+ rootPropertyDescriptor?: PropertyDescriptor<any, any, undefined>;
27
119
  };
28
120
  type ValidatorResult<T> = Omit<ValidationResult<T>, 'object' | 'errors'> & {
29
- errors?: Omit<ValidationError, 'path'>[];
121
+ errors?: ValidationError[];
30
122
  };
123
+ /**
124
+ * A function that transforms the value before validation.
125
+ * Preprocessors run in order before validators and can modify or replace the value.
126
+ *
127
+ * @param object - the current value to preprocess
128
+ * @returns the transformed value, or a Promise resolving to it
129
+ */
31
130
  export type Preprocessor<T> = (object: T) => Promise<T> | T;
131
+ /**
132
+ * A custom validation function that checks a value and returns a result
133
+ * indicating whether the value is valid, along with optional error messages.
134
+ *
135
+ * @param object - the value to validate
136
+ * @returns a result with `valid` boolean and optional `errors` array, or a Promise resolving to it
137
+ */
32
138
  export type Validator<T> = (object: T) => Promise<ValidatorResult<T>> | ValidatorResult<T>;
139
+ /**
140
+ * Internal wrapper that pairs a preprocessor function with metadata
141
+ * indicating whether it may mutate the value.
142
+ */
143
+ export type PreprocessorEntry<T> = {
144
+ fn: Preprocessor<T>;
145
+ mutates: boolean;
146
+ };
147
+ /**
148
+ * Internal wrapper that pairs a validator function with metadata
149
+ * indicating whether it may mutate the value.
150
+ */
151
+ export type ValidatorEntry<T> = {
152
+ fn: Validator<T>;
153
+ mutates: boolean;
154
+ };
155
+ /**
156
+ * Configuration properties used to construct a `SchemaBuilder` instance.
157
+ * Contains the schema type identifier, requirement flag, and lists of
158
+ * preprocessors and validators.
159
+ */
33
160
  export type SchemaBuilderProps<T> = {
34
161
  type: string;
35
162
  isRequired?: boolean;
36
- preprocessors: Preprocessor<T>[];
37
- validators: Validator<T>[];
163
+ isNullable?: boolean;
164
+ isReadonly?: boolean;
165
+ preprocessors: PreprocessorEntry<T>[];
166
+ validators: ValidatorEntry<T>[];
167
+ requiredValidationErrorMessageProvider?: ValidationErrorMessageProvider;
168
+ extensions?: Record<string, unknown>;
169
+ defaultValue?: T | (() => T);
170
+ catchValue?: T | (() => T);
171
+ hasCatch?: boolean;
172
+ description?: string;
38
173
  };
39
- export type ValidationContext = {
40
- /**
41
- * Path of the field. **Optional**, used to display correct error path in the {@link ValidationError}
42
- */
43
- path?: string;
174
+ export type ValidationContext<TSchema extends SchemaBuilder<any, any, any, any> = SchemaBuilder<any, any, any, any>> = {
44
175
  /**
45
176
  * Optional. By default validation will stop after the first validation error, in case if
46
177
  * you want to receive all validation erors, please set this flag to `true`.
47
178
  * You might need it to display validation errors.
48
179
  */
49
180
  doNotStopOnFirstError?: boolean;
181
+ /**
182
+ * Optional. If you define a `rootPropertyDescriptor` while validating an object,
183
+ * it will report all validation errors with the path starting from the root property.
184
+ * Normally it's used internally by the library for validation of nested objects and
185
+ * should not be used directly (but who knows, maybe you will find a use case for it).
186
+ */
187
+ rootPropertyDescriptor?: TSchema extends ObjectSchemaBuilder<any, any, any, any> ? PropertyDescriptor<TSchema, TSchema, undefined> : never;
188
+ /**
189
+ * Optional. This is a property descriptor for the current object being validated.
190
+ * This descriptor is descendant of the `rootPropertyDescriptor` and is used to provide
191
+ * a path to the current object being validated in the root object.
192
+ * Normally it's used internally by the library for validation of nested objects and
193
+ * should not be used directly (but who knows, maybe you will find a use case for it).
194
+ */
195
+ currentPropertyDescriptor?: TSchema extends ObjectSchemaBuilder<any, any, any> ? PropertyDescriptor<TSchema, TSchema, unknown> : never;
196
+ /**
197
+ * Optional. Used along with `rootPropertyDescriptor` and `currentPropertyDescriptor` to provide
198
+ * a root validation object, this object will be used to retrieve the value of properties
199
+ * using the `rootPropertyDescriptor` because the `rootPropertyDescriptor` is a property descriptor
200
+ * for the root object, and it needs the root object along with the whole structure to get the
201
+ * value of the property.
202
+ *
203
+ * Normally it's used internally by the library for validation of nested objects and
204
+ * should not be used directly (but who knows, maybe you will find a use case for it).
205
+ */
206
+ rootValidationObject?: InferType<TSchema>;
207
+ };
208
+ /**
209
+ * A symbol to mark property descriptors in the schema.
210
+ * Normally, you should not use it directly unless you want
211
+ * to develop some advanced features or extend the library.
212
+ * In normal conditions it's used internally by the library.
213
+ */
214
+ export declare const SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR: unique symbol;
215
+ /**
216
+ * A symbol that marks a schema as having sub-properties that can
217
+ * participate in property descriptor trees. When a schema exposes
218
+ * `[SYMBOL_HAS_PROPERTIES] = true` **and** its `introspect()` returns
219
+ * a `properties` record, it will be recursed into by
220
+ * `ObjectSchemaBuilder.getPropertiesFor()` — the same way nested
221
+ * `ObjectSchemaBuilder` instances are.
222
+ *
223
+ * Currently implemented by `ObjectSchemaBuilder` (always) and
224
+ * `ExternSchemaBuilder` (when created with an explicit property map).
225
+ */
226
+ export declare const SYMBOL_HAS_PROPERTIES: unique symbol;
227
+ /**
228
+ * Describes a property in a schema. And gives you
229
+ * a possibility to access property value and set it.
230
+ * suppose you have a schema like this:
231
+ * ```ts
232
+ * const schema = object({
233
+ * name: string(),
234
+ * address: object({
235
+ * city: string(),
236
+ * country: string()
237
+ * }),
238
+ * id: number()
239
+ * });
240
+ * ```
241
+ * then you can get a property descriptor for the `address.city` property
242
+ * like this:
243
+ * ```ts
244
+ * const addressCityDescriptor = object.getPropertiesFor(schema).address.city;
245
+ * ```
246
+ *
247
+ * And then you can use it to get and set the value of this property having the object:
248
+ * ```ts
249
+ * const obj = {
250
+ * name: 'Leo',
251
+ * address: {
252
+ * city: 'Kozelsk',
253
+ * country: 'Russia'
254
+ * },
255
+ * id: 123
256
+ * };
257
+ *
258
+ * const success = addressCityDescriptor.setValue(obj, 'Venyov');
259
+ * // this returns you a boolean value indicating if the value was set successfully
260
+ * ```
261
+ */
262
+ export type PropertySetterOptions = {
263
+ /**
264
+ * If set to `true`, the method will create missing structure
265
+ * in the object to set the value. For example, if you have a schema
266
+ * and property descriptor like this:
267
+ * ```ts
268
+ * const schema = object({
269
+ * address: object({
270
+ * city: string(),
271
+ * country: string()
272
+ * }),
273
+ * });
274
+ * const addressCityDescriptor = object.getPropertiesFor(schema).address.city;
275
+ * ```
276
+ * And then you try to set a new value to the `address.city` property on the object
277
+ * which does not have `address` property:
278
+ * ```ts
279
+ * const obj = {
280
+ * name: 'Leo'
281
+ * };
282
+ * const success = addressCityDescriptor.setValue(obj, 'Venyov', { createMissingStructure: true });
283
+ * // success === true
284
+ * // obj === {
285
+ * // name: 'Leo',
286
+ * // address: {
287
+ * // city: 'Venyov'
288
+ * // }
289
+ * // }
290
+ */
291
+ createMissingStructure?: boolean;
292
+ };
293
+ /**
294
+ * Extracts the inner property descriptor type from a `PropertyDescriptor`.
295
+ * Returns `undefined` if `T` is not a valid `PropertyDescriptor`.
296
+ */
297
+ export type PropertyDescriptorInnerFromPropertyDescriptor<T> = T extends PropertyDescriptor<infer TSchema, infer TPropertySchema, infer TParentPropertyDescriptor> ? PropertyDescriptorInner<TSchema, TPropertySchema, TParentPropertyDescriptor> : undefined;
298
+ export type PropertyDescriptorInner<TSchema extends ObjectSchemaBuilder<any, any, any, any, any>, TPropertySchema, TParentPropertyDescriptor> = {
299
+ /**
300
+ * Sets a new value to the property. If the process was successful,
301
+ * the method returns `true`, otherwise `false`.
302
+ * It can return `false` if the property could not be set to the object
303
+ * which can happen if the `setValue` method is called with an object
304
+ * which does not comply with the schema.
305
+ * for example, if you have a schema and property descriptopr like this:
306
+ * ```ts
307
+ * const schema = object({
308
+ * name: string(),
309
+ * address: object({
310
+ * city: string(),
311
+ * country: string()
312
+ * }),
313
+ * id: number()
314
+ * });
315
+ *
316
+ * const addressCityDescriptor = object.getPropertiesFor(schema).address.city;
317
+ * ```
318
+ * And then you try to set a new value to the `address.city` property on the object
319
+ * which does not have `address` property:
320
+ * ```ts
321
+ * const obj = {
322
+ * name: 'Leo'
323
+ * };
324
+ *
325
+ * const success = addressCityDescriptor.setValue(obj, 'Venyov');
326
+ * // success === false
327
+ * ```
328
+ *
329
+ * @param obj Object to set the value to
330
+ * @param value a new value to set to the property
331
+ * @param options additional optional parameters to control the process
332
+ * @returns
333
+ */
334
+ setValue: (obj: InferType<TSchema>, value: InferType<TPropertySchema>, options?: PropertySetterOptions) => boolean;
335
+ /**
336
+ * Gets the value of the property from the object.
337
+ * @param obj object to get the value from
338
+ * @returns an object containing a `value` and `success` properties. `value` is the value of the property
339
+ * if it was found in the object, `success` is a boolean value indicating if the property was found in the object.
340
+ */
341
+ getValue: (obj: InferType<TSchema>) => {
342
+ value?: InferType<TPropertySchema>;
343
+ success: boolean;
344
+ };
345
+ /**
346
+ * Gets the schema for the property described by the property descriptor.
347
+ * @returns a schema for the property
348
+ */
349
+ getSchema: () => TPropertySchema;
350
+ parent: PropertyDescriptorInnerFromPropertyDescriptor<TParentPropertyDescriptor>;
351
+ };
352
+ /**
353
+ * A wrapper object keyed by {@link SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR} that
354
+ * holds a {@link PropertyDescriptorInner} for a particular property within
355
+ * an object schema. Used to get/set property values on validated objects.
356
+ */
357
+ export type PropertyDescriptor<TRootSchema extends ObjectSchemaBuilder<any, any, any, any, any>, TPropertySchema, TParentPropertyDescriptor> = {
358
+ [SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]: PropertyDescriptorInner<TRootSchema, TPropertySchema, TParentPropertyDescriptor>;
50
359
  };
360
+ /**
361
+ * A tree of property descriptors for the schema.
362
+ * Has a possibility to filter properties by the type (`TAssignableTo` type parameter).
363
+ */
364
+ export type PropertyDescriptorTree<TSchema extends ObjectSchemaBuilder<any, any, any, any, any>, TRootSchema extends ObjectSchemaBuilder<any, any, any, any, any> = TSchema, TAssignableTo = any, TParentPropertyDescriptor = undefined> = PropertyDescriptor<TRootSchema, TSchema, TParentPropertyDescriptor> & (TSchema extends ObjectSchemaBuilder<infer TProperties, any, any> ? {
365
+ [K in keyof TProperties]: TProperties[K] extends ObjectSchemaBuilder<any, any, any> ? PropertyDescriptorTree<TProperties[K], TRootSchema, any, PropertyDescriptor<TRootSchema, TSchema, TParentPropertyDescriptor>> : TProperties[K] extends ExternSchemaBuilder<any, any, any, any, any, any, infer TExternResult> ? PropertyDescriptor<TRootSchema, TProperties[K], PropertyDescriptor<TRootSchema, TSchema, TParentPropertyDescriptor>> & ExternOutputPropertyDescriptors<TExternResult, TRootSchema, PropertyDescriptor<TRootSchema, TProperties[K], PropertyDescriptor<TRootSchema, TSchema, TParentPropertyDescriptor>>> : TProperties[K] extends ArraySchemaBuilder<infer TArrayElement, any, any> ? TArrayElement extends ObjectSchemaBuilder<any, any, any, any, any> ? PropertyDescriptor<TRootSchema, TProperties[K], PropertyDescriptor<TRootSchema, TSchema, TParentPropertyDescriptor>> : InferType<TProperties[K]> extends TAssignableTo ? PropertyDescriptor<TRootSchema, TProperties[K], PropertyDescriptor<TRootSchema, TSchema, TParentPropertyDescriptor>> : never : InferType<TProperties[K]> extends TAssignableTo ? PropertyDescriptor<TRootSchema, TProperties[K], PropertyDescriptor<TRootSchema, TSchema, TParentPropertyDescriptor>> : never;
366
+ } : never);
367
+ /**
368
+ * Recursively maps the keys of an extern schema's output type into
369
+ * property descriptors. When a value is a plain-object type its keys
370
+ * are expanded recursively; primitives, arrays, Dates, and functions
371
+ * are treated as leaves.
372
+ *
373
+ * @internal
374
+ */
375
+ type ExternOutputPropertyDescriptors<TOutput, TRootSchema extends ObjectSchemaBuilder<any, any, any, any, any>, TParentPropertyDescriptor> = TOutput extends Date | Function | readonly any[] | string | number | boolean | symbol | bigint | null | undefined ? {} : TOutput extends Record<string, any> ? {
376
+ [K in keyof TOutput]: PropertyDescriptor<TRootSchema, SchemaBuilder<TOutput[K], true, false, false, {}>, TParentPropertyDescriptor> & ExternOutputPropertyDescriptors<TOutput[K], TRootSchema, PropertyDescriptor<TRootSchema, SchemaBuilder<TOutput[K], true, false, false, {}>, TParentPropertyDescriptor>>;
377
+ } : {};
378
+ /**
379
+ * Creates an array augmented with non-enumerable NestedValidationResult
380
+ * properties (`seenValue`, `errors`, `isValid`, `descriptor`).
381
+ * Used by UnionSchemaBuilder and ArraySchemaBuilder to return hybrid
382
+ * arrays from `getErrorsFor()`.
383
+ */
384
+ export declare function createHybridErrorArray<T extends any[]>(items: T, seenValue: () => any, errors: () => ReadonlyArray<string>, descriptor: () => any): T;
385
+ /**
386
+ * Resolves the full output type of a schema, accounting for `TRequired` and
387
+ * `TNullable` modifiers. Mirrors the branded `[__type]` computation so that
388
+ * the `~standard` Standard Schema property carries the correct inferred type.
389
+ *
390
+ * - When `TRequired = true` and `TNullable = false` the result is `TResult`.
391
+ * - When `TRequired = true` and `TNullable = true` the result is `TResult | null`.
392
+ * - When `TRequired = false` the result is wrapped by {@link MakeOptional},
393
+ * adding `| undefined` (and `| null` when also nullable).
394
+ *
395
+ * @internal
396
+ */
397
+ type ResolvedSchemaType<TResult, TRequired extends boolean, TNullable extends boolean> = TRequired extends true ? TNullable extends true ? TResult | null : TResult : MakeOptional<TNullable extends true ? TResult | null : TResult>;
51
398
  /**
52
399
  * Base class for all schema builders. Provides basic functionality for schema building.
53
400
  *
@@ -55,45 +402,195 @@ export type ValidationContext = {
55
402
  * @typeparam TResult Type of the object that will be returned by `validate()` method.
56
403
  * @typeparam TRequired If `true`, object will be required. If `false`, object will be optional.
57
404
  */
58
- export declare abstract class SchemaBuilder<TResult = any, TRequired extends boolean = true> {
405
+ export declare abstract class SchemaBuilder<TResult = any, TRequired extends boolean = true, TNullable extends boolean = false, THasDefault extends boolean = false, TExtensions = {}> {
59
406
  #private;
60
407
  /**
61
- * Set type of schema explicitly. `notUsed` param is needed only for cas when JS is used. E.g. when you
408
+ * Type-level brand encoding the inferred type of this schema.
409
+ * Not emitted at runtime — used only by {@link InferType}.
410
+ * @internal
411
+ */
412
+ readonly [__type]: TRequired extends true ? TNullable extends true ? TResult | null : TResult : MakeOptional<TNullable extends true ? TResult | null : TResult>;
413
+ /**
414
+ * Type-level brand encoding whether this schema has a default value.
415
+ * Not emitted at runtime — used by input type inference.
416
+ * @internal
417
+ */
418
+ readonly [__hasDefault]: THasDefault;
419
+ /**
420
+ * Standard Schema v1 interface.
421
+ *
422
+ * Exposes this schema as a [Standard Schema v1](https://standardschema.dev/)
423
+ * validator, enabling out-of-the-box interoperability with any library that
424
+ * consumes the spec — including tRPC, TanStack Form, React Hook Form, T3 Env,
425
+ * Hono, Elysia, next-safe-action, and 50+ other tools.
426
+ *
427
+ * Every `SchemaBuilder` subclass (all 13 builders) inherits this property
428
+ * automatically — no additional setup required.
429
+ *
430
+ * **Shape of the returned object:**
431
+ * - `version` — always `1` (Standard Schema spec version)
432
+ * - `vendor` — `'@cleverbrush/schema'`
433
+ * - `validate(value)` — synchronous; wraps this builder's own `.validate()`
434
+ * and converts its result to the Standard Schema `Result<Output>` format:
435
+ * - Success: `{ value: <validated output> }`
436
+ * - Failure: `{ issues: [{ message: string }, …] }`
437
+ *
438
+ * The returned object is **cached** after the first access so repeated reads
439
+ * return the same reference (required by the spec).
440
+ *
441
+ * @example
442
+ * ```ts
443
+ * import { object, string, number } from '@cleverbrush/schema';
444
+ *
445
+ * const UserSchema = object({
446
+ * name: string().minLength(2),
447
+ * email: string().email(),
448
+ * age: number().min(18).optional(),
449
+ * });
450
+ *
451
+ * // Grab the Standard Schema interface
452
+ * const std = UserSchema['~standard'];
453
+ * // std.version === 1
454
+ * // std.vendor === '@cleverbrush/schema'
455
+ *
456
+ * const ok = std.validate({ name: 'Alice', email: 'alice@example.com' });
457
+ * // { value: { name: 'Alice', email: 'alice@example.com', age: undefined } }
458
+ *
459
+ * const fail = std.validate({ name: 'A', email: 'not-an-email' });
460
+ * // { issues: [{ message: 'minLength' }, { message: 'email' }] }
461
+ *
462
+ * // Pass directly to TanStack Form, T3 Env, tRPC, etc.:
463
+ * // validators: { onChange: UserSchema, onBlur: UserSchema }
464
+ * ```
465
+ *
466
+ * @see https://standardschema.dev/
467
+ */
468
+ get ['~standard'](): StandardSchemaV1.Props<ResolvedSchemaType<TResult, TRequired, TNullable>>;
469
+ /**
470
+ * Set type of schema explicitly. `notUsed` param is needed only for case when JS is used. E.g. when you
62
471
  * can't call method like `schema.hasType<Date>()`, so instead you can call `schema.hasType(new Date())`
63
472
  * with the same result.
64
473
  */
65
474
  abstract hasType<T>(notUsed?: T): any;
66
475
  /**
67
476
  * Clears type set by call to `.hasType<T>()`, default schema type inference will be used
68
- * for schema retuned by this call.
477
+ * for schema returned by this call.
69
478
  */
70
479
  abstract clearHasType(): any;
71
480
  /**
72
- * Protected method used to create an new instance of the Builder
73
- * defined by the `props` object. Should be used to instanticate new
481
+ * Protected method used to create a new instance of the Builder
482
+ * defined by the `props` object. Should be used to instantiate new
74
483
  * builders to keep builder's immutability.
75
484
  * @param props arbitrary props object
76
485
  */
77
486
  protected abstract createFromProps(props: any): this;
487
+ /**
488
+ * The string identifier of the schema type (e.g. `'string'`, `'number'`, `'object'`).
489
+ */
78
490
  protected get type(): string;
491
+ /**
492
+ * Sets the schema type identifier. Must be a non-empty string.
493
+ */
79
494
  protected set type(value: string);
80
495
  /**
81
496
  * A list of preprocessors associated with
82
497
  * the Builder
83
498
  */
84
- protected get preprocessors(): Preprocessor<TResult>[];
499
+ protected get preprocessors(): PreprocessorEntry<TResult>[];
85
500
  /**
86
501
  * A list of validators associated with
87
502
  * the Builder
88
503
  */
89
- protected get validators(): Validator<TResult>[];
504
+ protected get validators(): ValidatorEntry<TResult>[];
505
+ /**
506
+ * Whether the schema requires a non-null/non-undefined value.
507
+ */
90
508
  protected get isRequired(): TRequired;
509
+ /**
510
+ * Whether `null` is an accepted value for this schema.
511
+ */
512
+ protected get isNullable(): boolean;
513
+ /**
514
+ * Sets the requirement flag. Must be a boolean.
515
+ */
91
516
  protected set isRequired(value: boolean);
92
- protected preValidate(
93
517
  /**
94
- * Object to validate
518
+ * The error message provider used for the "is required" error.
519
+ * Exposed for fast-path validation in subclasses.
520
+ */
521
+ protected get requiredErrorMessage(): ValidationErrorMessageProvider;
522
+ /**
523
+ * Whether this schema has a default value configured via `.default()`.
524
+ * Exposed for fast-path validation in subclasses.
525
+ */
526
+ protected get hasDefault(): boolean;
527
+ /**
528
+ * Whether this schema has a catch/fallback value configured via `.catch()`.
529
+ */
530
+ protected get hasCatch(): boolean;
531
+ /**
532
+ * Resolves the catch/fallback value. If the stored value is a factory function,
533
+ * it is called to produce the value (useful for mutable fallbacks like `() => []`).
534
+ */
535
+ protected resolveCatchValue(): TResult;
536
+ /**
537
+ * Whether this schema is marked as readonly.
538
+ * Type-level only — no runtime enforcement.
539
+ */
540
+ protected get isReadonly(): boolean;
541
+ /**
542
+ * Resolves the default value. If the stored default is a function,
543
+ * it is called to produce the value (useful for mutable defaults).
544
+ */
545
+ protected resolveDefaultValue(): TResult;
546
+ /**
547
+ * Whether `preValidateSync` can be skipped entirely.
548
+ * True when there are no preprocessors and no validators,
549
+ * so the only work would be the required check and wrapping
550
+ * in a noop transaction — which subclasses can do inline.
551
+ */
552
+ protected get canSkipPreValidation(): boolean;
553
+ /**
554
+ * Whether `null` should count as a required-constraint violation.
555
+ *
556
+ * By default `null` is treated the same as `undefined` for the purposes
557
+ * of the required check — i.e. a required schema rejects both.
558
+ * Subclasses that may legally receive `null` as a value (e.g.
559
+ * `UnionSchemaBuilder` when a `NullSchemaBuilder` option is present)
560
+ * can override this to `false` so that `null` bypasses the required
561
+ * check and is passed directly to their option-validation logic.
562
+ *
563
+ * @protected
564
+ */
565
+ protected get isNullRequiredViolation(): boolean;
566
+ /**
567
+ * Synchronous version of {@link preValidateAsync}.
568
+ * Throws at runtime if any preprocessor or validator returns a Promise.
569
+ *
570
+ * @param object - the value to pre-validate
571
+ * @param context - optional validation context settings
572
+ * @returns a `PreValidationResult` containing the preprocessed transaction, context, and any errors
573
+ * @throws Error if a preprocessor or validator returns a Promise (use {@link preValidateAsync} instead)
95
574
  */
96
- object: any, context?: ValidationContext): Promise<PreValidationResult<any, {
575
+ protected preValidateSync(object: any, context?: ValidationContext): PreValidationResult<any, {
576
+ validatedObject: any;
577
+ }>;
578
+ /**
579
+ * Async version of pre-validation. Runs preprocessors, validators, and the
580
+ * required/optional check on `object`. Supports async preprocessors,
581
+ * validators, and error message providers.
582
+ *
583
+ * @param object - the value to pre-validate
584
+ * @param context - optional validation context settings
585
+ * @returns a `PreValidationResult` containing the preprocessed transaction, context, and any errors
586
+ */
587
+ protected preValidateAsync(object: any, context?: ValidationContext): Promise<PreValidationResult<any, {
588
+ validatedObject: any;
589
+ }>>;
590
+ /**
591
+ * @deprecated Use {@link preValidateAsync} instead. This alias will be removed in a future version.
592
+ */
593
+ protected preValidate(object: any, context?: ValidationContext): Promise<PreValidationResult<any, {
97
594
  validatedObject: any;
98
595
  }>>;
99
596
  /**
@@ -109,27 +606,209 @@ export declare abstract class SchemaBuilder<TResult = any, TRequired extends boo
109
606
  * will be considered as valid).
110
607
  */
111
608
  isRequired: boolean;
609
+ /**
610
+ * If set to `true`, schema values of `null` are considered valid.
611
+ */
612
+ isNullable: boolean;
613
+ /**
614
+ * If set to `true`, the inferred type is marked as readonly.
615
+ * Type-level only — no runtime enforcement.
616
+ */
617
+ isReadonly: boolean;
112
618
  /**
113
619
  * Array of preprocessor functions
114
620
  */
115
- preprocessors: readonly Preprocessor<TResult>[];
621
+ preprocessors: readonly PreprocessorEntry<TResult>[];
116
622
  /**
117
623
  * Array of validator functions
118
624
  */
119
- validators: readonly Validator<TResult>[];
625
+ validators: readonly ValidatorEntry<TResult>[];
626
+ /**
627
+ * Custom error message provider for the 'is required' validation error.
628
+ */
629
+ requiredValidationErrorMessageProvider: ValidationErrorMessageProvider<SchemaBuilder<any, any, any, any, any>>;
630
+ /**
631
+ * Extension metadata. Stores custom state set by schema extensions.
632
+ */
633
+ extensions: {
634
+ [x: string]: unknown;
635
+ };
636
+ /**
637
+ * Whether a default value (or factory) has been set on this schema.
638
+ */
639
+ hasDefault: boolean;
640
+ /**
641
+ * The default value or factory function.
642
+ */
643
+ defaultValue: TResult | (() => TResult) | undefined;
644
+ /**
645
+ * The human-readable description attached to this schema via `.describe()`,
646
+ * or `undefined` if none was set.
647
+ */
648
+ description: string | undefined;
649
+ /**
650
+ * Whether a catch/fallback value has been set on this schema via `.catch()`.
651
+ */
652
+ hasCatch: boolean;
653
+ /**
654
+ * The catch/fallback value or factory function set via `.catch()`.
655
+ */
656
+ catchValue: TResult | (() => TResult) | undefined;
120
657
  };
121
658
  /**
122
659
  * Makes schema optional (consider `null` and `undefined` as valid objects for this schema)
123
660
  */
124
661
  optional(): any;
662
+ /**
663
+ * Makes schema nullable — `null` is accepted as a valid value.
664
+ *
665
+ * Unlike `.optional()` which accepts `undefined`, `.nullable()` accepts
666
+ * `null`. The inferred type changes from `T` to `T | null`. Combine with
667
+ * `.optional()` to accept both `null` and `undefined`.
668
+ */
669
+ nullable(): any;
670
+ /**
671
+ * Removes the nullable mark — `null` is no longer accepted as a valid
672
+ * value. This is the counterpart of `.nullable()`.
673
+ */
674
+ notNullable(): any;
675
+ /**
676
+ * Sets a default value for this schema. When the input is `undefined`,
677
+ * the default value is used instead. The default is still validated
678
+ * against the schema's constraints.
679
+ *
680
+ * Accepts either a static value or a factory function (useful for
681
+ * mutable defaults like `() => new Date()` or `() => []`).
682
+ *
683
+ * @example
684
+ * ```ts
685
+ * const schema = string().default('hello');
686
+ * schema.validate(undefined); // { valid: true, object: 'hello' }
687
+ * schema.validate('world'); // { valid: true, object: 'world' }
688
+ * ```
689
+ *
690
+ * @example
691
+ * ```ts
692
+ * // Factory function for mutable defaults
693
+ * const schema = array(string()).default(() => []);
694
+ * ```
695
+ */
696
+ default(value: TResult | (() => TResult)): any;
697
+ /**
698
+ * Sets a fallback value for this schema. When validation **fails** for any reason,
699
+ * the fallback value is returned as a successful result instead of validation errors.
700
+ *
701
+ * This is useful for graceful degradation — for example, providing a safe default
702
+ * when parsing untrusted input that might not conform to the schema.
703
+ *
704
+ * Accepts either a static value or a factory function. Factory functions are called
705
+ * each time the fallback is needed (useful for mutable values like `() => []`).
706
+ *
707
+ * Unlike {@link default}, which only fires when the input is `undefined`, `.catch()`
708
+ * fires on **any** validation failure — type mismatch, constraint violation, etc.
709
+ *
710
+ * When `.catch()` is set, {@link parse} and {@link parseAsync} will **never throw**.
711
+ *
712
+ * @param value - the fallback value, or a factory function producing the fallback
713
+ *
714
+ * @example
715
+ * ```ts
716
+ * const schema = string().catch('unknown');
717
+ * schema.validate(42); // { valid: true, object: 'unknown' }
718
+ * schema.validate('hello'); // { valid: true, object: 'hello' }
719
+ * schema.parse(42); // 'unknown' (no throw)
720
+ * ```
721
+ *
722
+ * @example
723
+ * ```ts
724
+ * // Factory function for mutable fallbacks
725
+ * const schema = array(string()).catch(() => []);
726
+ * schema.validate(null); // { valid: true, object: [] }
727
+ * ```
728
+ *
729
+ * @example
730
+ * ```ts
731
+ * // Contrast with .default() — default fires only on undefined
732
+ * const d = string().default('anon');
733
+ * d.validate(undefined); // { valid: true, object: 'anon' } ← fires
734
+ * d.validate(42); // { valid: false, errors: [...] } ← does NOT fire
735
+ *
736
+ * const c = string().catch('anon');
737
+ * c.validate(undefined); // { valid: true, object: 'anon' } ← fires
738
+ * c.validate(42); // { valid: true, object: 'anon' } ← also fires
739
+ * ```
740
+ */
741
+ catch(value: TResult | (() => TResult)): this;
742
+ /**
743
+ * Removes the default value set by a previous call to `.default()`.
744
+ */
745
+ clearDefault(): any;
746
+ /**
747
+ * Attaches a human-readable description to this schema as runtime metadata.
748
+ *
749
+ * The description has no effect on validation — it is purely informational.
750
+ * It is accessible via `.introspect().description` and is emitted as the
751
+ * `description` field by `toJsonSchema()` from `@cleverbrush/schema-json`.
752
+ *
753
+ * Useful for documentation generation, form labels, and AI tool descriptions.
754
+ *
755
+ * @example
756
+ * ```ts
757
+ * const schema = object({
758
+ * name: string().describe('The user\'s full name'),
759
+ * age: number().optional().describe('Age in years'),
760
+ * }).describe('A user object');
761
+ *
762
+ * schema.introspect().description; // 'A user object'
763
+ * ```
764
+ */
765
+ describe(text: string): this;
766
+ /**
767
+ * Brands the schema with a phantom type tag, preventing structural mixing
768
+ * of semantically different values at the type level. Zero runtime cost.
769
+ *
770
+ * The optional `_name` parameter is only needed when using plain JavaScript
771
+ * (where generic type parameters are unavailable). In TypeScript, prefer
772
+ * the generic form: `schema.brand<'Email'>()`.
773
+ *
774
+ * @example
775
+ * ```ts
776
+ * const Email = string().brand<'Email'>();
777
+ * const Username = string().brand<'Username'>();
778
+ * type Email = InferType<typeof Email>; // string & { readonly [BRAND]: 'Email' }
779
+ * type Username = InferType<typeof Username>; // string & { readonly [BRAND]: 'Username' }
780
+ * ```
781
+ */
782
+ brand<TBrand extends string | symbol>(_name?: TBrand): any;
783
+ /**
784
+ * Marks the inferred type as readonly. For objects, produces `Readonly<T>`.
785
+ * For arrays, produces `ReadonlyArray<T>`. Primitives are unchanged.
786
+ * Type-level only — no runtime enforcement.
787
+ *
788
+ * @example
789
+ * ```ts
790
+ * const schema = object({ name: string(), age: number() }).readonly();
791
+ * type T = InferType<typeof schema>; // Readonly<{ name: string; age: number }>
792
+ * ```
793
+ *
794
+ * @example
795
+ * ```ts
796
+ * const schema = array(string()).readonly();
797
+ * type T = InferType<typeof schema>; // ReadonlyArray<string>
798
+ * ```
799
+ */
800
+ readonly(): any;
125
801
  /**
126
802
  * Makes schema required (consider `null` and `undefined` as invalid objects for this schema)
803
+ * @param errorMessage - optional custom error message or provider for the 'is required' validation error
127
804
  */
128
- required(): any;
805
+ required(errorMessage?: ValidationErrorMessageProvider): any;
129
806
  /**
130
807
  * Adds a `preprocessor` to a preprocessors list
131
808
  */
132
- addPreprocessor(preprocessor: Preprocessor<TResult>): this;
809
+ addPreprocessor(preprocessor: Preprocessor<TResult>, options?: {
810
+ mutates?: boolean;
811
+ }): this;
133
812
  /**
134
813
  * Remove all preprocessors for this schema.
135
814
  */
@@ -137,15 +816,53 @@ export declare abstract class SchemaBuilder<TResult = any, TRequired extends boo
137
816
  /**
138
817
  * Adds a `validator` to validators list.
139
818
  */
140
- addValidator(validator: Validator<TResult>): this;
819
+ addValidator(validator: Validator<TResult>, options?: {
820
+ mutates?: boolean;
821
+ }): this;
141
822
  /**
142
823
  * Remove all validators for this schema.
143
824
  */
144
825
  clearValidators(): this;
145
826
  /**
146
- * Perform schema validation on `object`.
827
+ * Perform synchronous schema validation on `object`.
828
+ * Throws at runtime if any preprocessor, validator, or error message
829
+ * provider returns a Promise — use {@link validateAsync} instead.
830
+ * @internal Override this in subclasses. External callers use {@link validate}.
831
+ */
832
+ protected abstract _validate(object: any, context?: ValidationContext): ValidationResult<any>;
833
+ /**
834
+ * Perform asynchronous schema validation on `object`.
835
+ * Supports async preprocessors, validators, and error message providers.
836
+ * @internal Override this in subclasses. External callers use {@link validateAsync}.
837
+ */
838
+ protected abstract _validateAsync(object: any, context?: ValidationContext): Promise<ValidationResult<any>>;
839
+ /**
840
+ * Perform synchronous schema validation on `object`.
841
+ * Throws at runtime if any preprocessor, validator, or error message
842
+ * provider returns a Promise — use {@link validateAsync} instead.
843
+ *
844
+ * If a fallback has been set via {@link catch}, a failed validation result
845
+ * is replaced by a successful result built from the fallback value, preserving
846
+ * the specialized result shape (e.g. `getErrorsFor` / `getNestedErrors` methods).
847
+ */
848
+ validate(
849
+ /**
850
+ * Object to validate
851
+ */
852
+ object: any,
853
+ /**
854
+ * Optional `ValidationContext` settings
855
+ */
856
+ context?: ValidationContext): ValidationResult<any>;
857
+ /**
858
+ * Perform asynchronous schema validation on `object`.
859
+ * Supports async preprocessors, validators, and error message providers.
860
+ *
861
+ * If a fallback has been set via {@link catch}, a failed validation result
862
+ * is replaced by a successful result built from the fallback value, preserving
863
+ * the specialized result shape (e.g. `getErrorsFor` / `getNestedErrors` methods).
147
864
  */
148
- abstract validate(
865
+ validateAsync(
149
866
  /**
150
867
  * Object to validate
151
868
  */
@@ -154,6 +871,77 @@ export declare abstract class SchemaBuilder<TResult = any, TRequired extends boo
154
871
  * Optional `ValidationContext` settings
155
872
  */
156
873
  context?: ValidationContext): Promise<ValidationResult<any>>;
874
+ /**
875
+ * Synchronously resolves a `ValidationErrorMessageProvider` to a string.
876
+ * Throws if the provider function returns a Promise.
877
+ *
878
+ * @param provider - the error message provider (string or sync function)
879
+ * @param seenValue - the value that caused the validation error
880
+ * @returns the resolved error message string
881
+ * @throws Error if the provider returns a Promise (use {@link getValidationErrorMessage} with {@link validateAsync})
882
+ */
883
+ protected getValidationErrorMessageSync(provider: ValidationErrorMessageProvider<any>, seenValue: TResult): string;
884
+ /**
885
+ * Resolves a `ValidationErrorMessageProvider` to a string error message.
886
+ * Handles both string providers and function providers (sync or async).
887
+ *
888
+ * @param provider - the error message provider (string or function)
889
+ * @param seenValue - the value that caused the validation error
890
+ * @returns the resolved error message string
891
+ */
892
+ protected getValidationErrorMessage(provider: ValidationErrorMessageProvider<any>, seenValue: TResult): Promise<string>;
893
+ /**
894
+ * Ensures a `ValidationErrorMessageProvider` is valid.
895
+ * If `provider` is `undefined`, falls back to `defaultValue`.
896
+ * Function providers are bound to `this` for access to schema state.
897
+ *
898
+ * @param provider - the provider to validate, or `undefined`
899
+ * @param defaultValue - fallback provider when `provider` is not supplied
900
+ * @returns a valid `ValidationErrorMessageProvider`
901
+ */
902
+ protected assureValidationErrorMessageProvider(provider: ValidationErrorMessageProvider<any> | undefined, defaultValue: ValidationErrorMessageProvider<any>): ValidationErrorMessageProvider<any>;
903
+ /**
904
+ * Sets extension metadata by key. Returns a new schema instance with the
905
+ * extension data stored. The data survives fluent chaining.
906
+ * @internal Used by extension authors inside `defineExtension()` callbacks.
907
+ */
908
+ withExtension(key: string, value: unknown): this;
909
+ /**
910
+ * Retrieves extension metadata by key.
911
+ * @internal Used by extension authors inside `defineExtension()` callbacks.
912
+ */
913
+ getExtension(key: string): unknown;
914
+ /**
915
+ * Synchronously validates the value and returns it if valid.
916
+ * Throws a {@link SchemaValidationError} if validation fails.
917
+ *
918
+ * @param object - the value to parse
919
+ * @param context - optional validation context
920
+ * @returns the validated value
921
+ * @throws SchemaValidationError if validation fails
922
+ * @throws Error if the schema contains async preprocessors, validators, or error message providers
923
+ */
924
+ parse(object: any, context?: ValidationContext): TResult;
925
+ /**
926
+ * Asynchronously validates the value and returns it if valid.
927
+ * Throws a {@link SchemaValidationError} if validation fails.
928
+ *
929
+ * @param object - the value to parse
930
+ * @param context - optional validation context
931
+ * @returns the validated value
932
+ * @throws SchemaValidationError if validation fails
933
+ */
934
+ parseAsync(object: any, context?: ValidationContext): Promise<TResult>;
935
+ /**
936
+ * Alias for {@link validate}. Synchronously validates and returns a result object.
937
+ * Provided for familiarity with the zod API.
938
+ */
939
+ safeParse(object: any, context?: ValidationContext): ValidationResult<TResult>;
940
+ /**
941
+ * Alias for {@link validateAsync}. Asynchronously validates and returns a result object.
942
+ * Provided for familiarity with the zod API.
943
+ */
944
+ safeParseAsync(object: any, context?: ValidationContext): Promise<ValidationResult<TResult>>;
157
945
  protected constructor(props: SchemaBuilderProps<TResult>);
158
946
  }
159
947
  export {};