@cleverbrush/schema 2.0.0 → 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.
Files changed (87) hide show
  1. package/README.md +412 -8
  2. package/dist/builders/AnySchemaBuilder.js +1 -1
  3. package/dist/builders/ArraySchemaBuilder.d.ts +2 -0
  4. package/dist/builders/ArraySchemaBuilder.js +1 -1
  5. package/dist/builders/BooleanSchemaBuilder.d.ts +15 -0
  6. package/dist/builders/BooleanSchemaBuilder.js +1 -1
  7. package/dist/builders/DateSchemaBuilder.d.ts +20 -0
  8. package/dist/builders/DateSchemaBuilder.js +1 -1
  9. package/dist/builders/ExternSchemaBuilder.d.ts +2 -0
  10. package/dist/builders/ExternSchemaBuilder.js +1 -1
  11. package/dist/builders/FunctionSchemaBuilder.d.ts +162 -18
  12. package/dist/builders/FunctionSchemaBuilder.js +1 -1
  13. package/dist/builders/GenericSchemaBuilder.d.ts +294 -0
  14. package/dist/builders/LazySchemaBuilder.d.ts +2 -0
  15. package/dist/builders/NumberSchemaBuilder.d.ts +16 -0
  16. package/dist/builders/NumberSchemaBuilder.js +1 -1
  17. package/dist/builders/ObjectSchemaBuilder.d.ts +262 -42
  18. package/dist/builders/ObjectSchemaBuilder.js +1 -1
  19. package/dist/builders/ParseStringSchemaBuilder.d.ts +204 -0
  20. package/dist/builders/ParseStringSchemaBuilder.js +2 -0
  21. package/dist/builders/ParseStringSchemaBuilder.js.map +1 -0
  22. package/dist/builders/PromiseSchemaBuilder.d.ts +213 -0
  23. package/dist/builders/PromiseSchemaBuilder.js +2 -0
  24. package/dist/builders/PromiseSchemaBuilder.js.map +1 -0
  25. package/dist/builders/RecordSchemaBuilder.d.ts +2 -0
  26. package/dist/builders/RecordSchemaBuilder.js +1 -1
  27. package/dist/builders/SchemaBuilder.d.ts +89 -0
  28. package/dist/builders/StringSchemaBuilder.d.ts +2 -0
  29. package/dist/builders/StringSchemaBuilder.js +1 -1
  30. package/dist/builders/TupleSchemaBuilder.d.ts +2 -0
  31. package/dist/builders/TupleSchemaBuilder.js +1 -1
  32. package/dist/builders/UnionSchemaBuilder.d.ts +8 -0
  33. package/dist/builders/UnionSchemaBuilder.js +1 -1
  34. package/dist/chunk-3JMDGYDT.js +2 -0
  35. package/dist/chunk-3JMDGYDT.js.map +1 -0
  36. package/dist/{chunk-KESLT5EE.js → chunk-BUEVZ3KA.js} +2 -2
  37. package/dist/{chunk-KESLT5EE.js.map → chunk-BUEVZ3KA.js.map} +1 -1
  38. package/dist/{chunk-KFTO7TMB.js → chunk-CFIJQ4GP.js} +2 -2
  39. package/dist/{chunk-KFTO7TMB.js.map → chunk-CFIJQ4GP.js.map} +1 -1
  40. package/dist/chunk-DY7J6RNN.js +2 -0
  41. package/dist/chunk-DY7J6RNN.js.map +1 -0
  42. package/dist/{chunk-YWBNVHR6.js → chunk-EIVZX4ZO.js} +2 -2
  43. package/dist/{chunk-YWBNVHR6.js.map → chunk-EIVZX4ZO.js.map} +1 -1
  44. package/dist/chunk-GXPV6UQK.js +2 -0
  45. package/dist/chunk-GXPV6UQK.js.map +1 -0
  46. package/dist/{chunk-ZAN4ZHCJ.js → chunk-HN774HD7.js} +2 -2
  47. package/dist/chunk-K6Z47OQY.js +2 -0
  48. package/dist/chunk-K6Z47OQY.js.map +1 -0
  49. package/dist/chunk-NUW3VXZV.js +2 -0
  50. package/dist/chunk-NUW3VXZV.js.map +1 -0
  51. package/dist/{chunk-MKAYFPAR.js → chunk-PHE4LIAN.js} +2 -2
  52. package/dist/chunk-QARCEYGO.js +2 -0
  53. package/dist/chunk-QARCEYGO.js.map +1 -0
  54. package/dist/chunk-WDMJBGBD.js +2 -0
  55. package/dist/chunk-WDMJBGBD.js.map +1 -0
  56. package/dist/chunk-WQDYWDOE.js +2 -0
  57. package/dist/chunk-WQDYWDOE.js.map +1 -0
  58. package/dist/{chunk-FWUEUW2N.js → chunk-YQZHDMRF.js} +2 -2
  59. package/dist/chunk-ZC6YBKCP.js +2 -0
  60. package/dist/chunk-ZC6YBKCP.js.map +1 -0
  61. package/dist/{chunk-IJ6FO37G.js → chunk-ZFI27R3L.js} +2 -2
  62. package/dist/core.d.ts +7 -2
  63. package/dist/core.js +1 -1
  64. package/dist/extension.d.ts +10 -2
  65. package/dist/extensions/index.d.ts +5 -1
  66. package/dist/index.d.ts +4 -1
  67. package/dist/index.js +1 -1
  68. package/dist/index.js.map +1 -1
  69. package/package.json +12 -4
  70. package/dist/chunk-BFCMDDTX.js +0 -2
  71. package/dist/chunk-BFCMDDTX.js.map +0 -1
  72. package/dist/chunk-CTP4RHDG.js +0 -2
  73. package/dist/chunk-CTP4RHDG.js.map +0 -1
  74. package/dist/chunk-EUQ5AE3H.js +0 -2
  75. package/dist/chunk-EUQ5AE3H.js.map +0 -1
  76. package/dist/chunk-NXPH3ZUW.js +0 -2
  77. package/dist/chunk-NXPH3ZUW.js.map +0 -1
  78. package/dist/chunk-S5TC6NSU.js +0 -2
  79. package/dist/chunk-S5TC6NSU.js.map +0 -1
  80. package/dist/chunk-Z7QZ7IXT.js +0 -2
  81. package/dist/chunk-Z7QZ7IXT.js.map +0 -1
  82. package/dist/chunk-ZUPYV5TI.js +0 -2
  83. package/dist/chunk-ZUPYV5TI.js.map +0 -1
  84. /package/dist/{chunk-ZAN4ZHCJ.js.map → chunk-HN774HD7.js.map} +0 -0
  85. /package/dist/{chunk-MKAYFPAR.js.map → chunk-PHE4LIAN.js.map} +0 -0
  86. /package/dist/{chunk-FWUEUW2N.js.map → chunk-YQZHDMRF.js.map} +0 -0
  87. /package/dist/{chunk-IJ6FO37G.js.map → chunk-ZFI27R3L.js.map} +0 -0
@@ -0,0 +1,204 @@
1
+ import { ObjectSchemaBuilder } from './ObjectSchemaBuilder.js';
2
+ import { type BRAND, type InferType, type PropertyDescriptor, type PropertyDescriptorInner, type PropertyDescriptorTree, SchemaBuilder, type ValidationContext, type ValidationErrorMessageProvider, type ValidationResult } from './SchemaBuilder.js';
3
+ /** Descriptor for a single interpolation segment captured at creation time. */
4
+ type SegmentDef = {
5
+ /** The property schema for this segment. */
6
+ schema: SchemaBuilder<any, any, any, any, any>;
7
+ /** Dot-separated property path (e.g. `'order.id'`) — used in error messages. */
8
+ path: string;
9
+ /** The property descriptor inner — used to set parsed values on the result object. */
10
+ descriptor: PropertyDescriptorInner<any, any, any>;
11
+ };
12
+ /** Internal data captured by the `$template` tagged-template invocation. */
13
+ type ParseStringTemplateDefinition = {
14
+ /** Literal string fragments from the tagged template. */
15
+ literals: readonly string[];
16
+ /** One segment per interpolation expression, in order. */
17
+ segments: readonly SegmentDef[];
18
+ };
19
+ /**
20
+ * The typed tagged-template function passed to the `parseString`
21
+ * callback. Template expressions must be property-selector lambdas that
22
+ * navigate the {@link PropertyDescriptorTree} of the object schema.
23
+ *
24
+ * Only properties whose inferred type extends `string | number | boolean | Date`
25
+ * are selectable — nested `ObjectSchemaBuilder` children are navigable but
26
+ * not themselves endpoints.
27
+ */
28
+ export type ParseStringTemplateTag<TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>> = (strings: TemplateStringsArray, ...selectors: Array<(tree: PropertyDescriptorTree<TSchema, TSchema, string | number | boolean | Date>) => PropertyDescriptor<TSchema, any, any>>) => ParseStringTemplateDefinition;
29
+ type ParseStringSchemaBuilderCreateProps<T = any, R extends boolean = true> = Partial<ReturnType<ParseStringSchemaBuilder<T, R>['introspect']>>;
30
+ /**
31
+ * Validates a string against a template pattern and parses it
32
+ * into a strongly-typed object.
33
+ *
34
+ * Created via the {@link parseString} factory:
35
+ *
36
+ * ```ts
37
+ * const RouteSchema = parseString(
38
+ * object({ userId: string().uuid(), id: number() }),
39
+ * $t => $t`/orders/${t => t.id}/${t => t.userId}`
40
+ * );
41
+ *
42
+ * const result = RouteSchema.validate('/orders/42/550e8400-...');
43
+ * // result.object === { id: 42, userId: '550e8400-...' }
44
+ * ```
45
+ *
46
+ * @see {@link parseString}
47
+ */
48
+ export declare class ParseStringSchemaBuilder<TResult = any, TRequired extends boolean = true, TNullable extends boolean = false, THasDefault extends boolean = false, TExtensions = {}> extends SchemaBuilder<TResult, TRequired, TNullable, THasDefault, TExtensions> {
49
+ #private;
50
+ /**
51
+ * @hidden
52
+ */
53
+ static create(props: ParseStringSchemaBuilderCreateProps): ParseStringSchemaBuilder<any, true, false, false, {}>;
54
+ protected constructor(props: ParseStringSchemaBuilderCreateProps);
55
+ /**
56
+ * Return a snapshot of this builder's configuration.
57
+ *
58
+ * Includes all base-class fields plus:
59
+ * - `objectSchema` — the object schema defining the result shape.
60
+ * - `templateDefinition` — the parsed template (literals and selector segments).
61
+ */
62
+ introspect(): {
63
+ /** The object schema defining the result shape. */
64
+ objectSchema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;
65
+ /** The template definition (literals + segments). */
66
+ templateDefinition: ParseStringTemplateDefinition;
67
+ type: string;
68
+ isRequired: boolean;
69
+ isNullable: boolean;
70
+ isReadonly: boolean;
71
+ preprocessors: readonly import("./SchemaBuilder.js").PreprocessorEntry<TResult>[];
72
+ validators: readonly import("./SchemaBuilder.js").ValidatorEntry<TResult>[];
73
+ requiredValidationErrorMessageProvider: ValidationErrorMessageProvider<SchemaBuilder<any, any, any, any, any>>;
74
+ extensions: {
75
+ [x: string]: unknown;
76
+ };
77
+ hasDefault: boolean;
78
+ defaultValue: TResult | (() => TResult) | undefined;
79
+ description: string | undefined;
80
+ schemaName: string | undefined;
81
+ hasCatch: boolean;
82
+ catchValue: TResult | (() => TResult) | undefined;
83
+ example: unknown;
84
+ };
85
+ /**
86
+ * Builds a string from the template by substituting parameter values.
87
+ *
88
+ * This is the reverse of {@link validate}: where `validate` parses a
89
+ * string into a typed object, `serialize` takes a params object and
90
+ * produces the string.
91
+ *
92
+ * @param params - An object matching the template's parsed result type.
93
+ * Nested properties are resolved via dot-paths (e.g. `order.id`).
94
+ * Values are coerced to strings via `String()`.
95
+ * @returns The reconstructed string with all segments replaced.
96
+ * @throws {Error} If a required parameter is missing (`undefined`).
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const Route = parseString(
101
+ * object({ id: number().coerce() }),
102
+ * $t => $t`/todos/${t => t.id}`
103
+ * );
104
+ *
105
+ * Route.serialize({ id: 42 }); // '/todos/42'
106
+ * ```
107
+ */
108
+ serialize(params: TResult): string;
109
+ /** {@inheritDoc SchemaBuilder.validate} */
110
+ validate(object: string, context?: ValidationContext): ValidationResult<TResult>;
111
+ /** {@inheritDoc SchemaBuilder.validateAsync} */
112
+ validateAsync(object: string, context?: ValidationContext): Promise<ValidationResult<TResult>>;
113
+ protected _validate(object: any, context?: ValidationContext): ValidationResult<TResult>;
114
+ protected _validateAsync(object: any, context?: ValidationContext): Promise<ValidationResult<TResult>>;
115
+ /**
116
+ * @inheritdoc
117
+ */
118
+ hasType<T>(_notUsed?: T): ParseStringSchemaBuilder<T, true, TNullable, THasDefault, TExtensions> & TExtensions;
119
+ /**
120
+ * @inheritdoc
121
+ */
122
+ clearHasType(): ParseStringSchemaBuilder<any, TRequired, TNullable, THasDefault, TExtensions> & TExtensions;
123
+ /**
124
+ * @hidden
125
+ */
126
+ nullable(): ParseStringSchemaBuilder<TResult, TRequired, true, THasDefault, TExtensions> & TExtensions;
127
+ /**
128
+ * @hidden
129
+ */
130
+ notNullable(): ParseStringSchemaBuilder<TResult, TRequired, false, THasDefault, TExtensions> & TExtensions;
131
+ /**
132
+ * @hidden
133
+ */
134
+ required(errorMessage?: ValidationErrorMessageProvider): ParseStringSchemaBuilder<TResult, true, TNullable, THasDefault, TExtensions> & TExtensions;
135
+ /**
136
+ * @hidden
137
+ */
138
+ optional(): ParseStringSchemaBuilder<TResult, false, TNullable, THasDefault, TExtensions> & TExtensions;
139
+ /**
140
+ * @hidden
141
+ */
142
+ default(value: TResult | (() => TResult)): ParseStringSchemaBuilder<TResult, true, TNullable, true, TExtensions> & TExtensions;
143
+ /**
144
+ * @hidden
145
+ */
146
+ clearDefault(): ParseStringSchemaBuilder<TResult, TRequired, TNullable, false, TExtensions> & TExtensions;
147
+ /**
148
+ * @hidden
149
+ */
150
+ brand<TBrand extends string | symbol>(_name?: TBrand): ParseStringSchemaBuilder<TResult & {
151
+ readonly [K in BRAND]: TBrand;
152
+ }, TRequired, TNullable, THasDefault, TExtensions> & TExtensions;
153
+ /**
154
+ * @hidden
155
+ */
156
+ readonly(): ParseStringSchemaBuilder<Readonly<TResult>, TRequired, TNullable, THasDefault, TExtensions> & TExtensions;
157
+ protected createFromProps<T, TReq extends boolean>(props: ParseStringSchemaBuilderCreateProps<T, TReq>): this;
158
+ }
159
+ /**
160
+ * Creates a parse-string schema that validates a string against a
161
+ * template pattern and parses it into a strongly-typed object.
162
+ *
163
+ * The first argument defines the result shape via `object(...)`, and the
164
+ * second argument is a callback receiving a typed `$template` tagged-template
165
+ * function whose template expressions are type-safe property selectors.
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * const RouteSchema = parseString(
170
+ * object({
171
+ * userId: string().uuid(),
172
+ * id: number()
173
+ * }),
174
+ * $t => $t`/orders/${t => t.id}/${t => t.userId}`
175
+ * );
176
+ *
177
+ * const result = RouteSchema.validate('/orders/42/550e8400-e29b-41d4-a716-446655440000');
178
+ * // result.valid === true
179
+ * // result.object === { id: 42, userId: '550e8400-e29b-41d4-a716-446655440000' }
180
+ *
181
+ * type Route = InferType<typeof RouteSchema>;
182
+ * // { id: number; userId: string }
183
+ * ```
184
+ *
185
+ * @example Nested objects
186
+ * ```ts
187
+ * const schema = parseString(
188
+ * object({
189
+ * order: object({ id: number() }),
190
+ * user: object({ name: string() })
191
+ * }),
192
+ * $t => $t`/orders/${t => t.order.id}/by/${t => t.user.name}`
193
+ * );
194
+ * ```
195
+ *
196
+ * @param objectSchema - An `ObjectSchemaBuilder` defining the result type and
197
+ * per-property validation schemas.
198
+ * @param templateBuilder - Callback receiving the typed `$template`
199
+ * tagged-template function. Must return the result of invoking `$template`.
200
+ * @returns A `ParseStringSchemaBuilder` whose `validate()` accepts a
201
+ * string and whose `InferType` is the object schema's inferred type.
202
+ */
203
+ export declare function parseString<TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>>(objectSchema: TSchema, templateBuilder: ($template: ParseStringTemplateTag<TSchema>) => ParseStringTemplateDefinition): ParseStringSchemaBuilder<InferType<TSchema>>;
204
+ export {};
@@ -0,0 +1,2 @@
1
+ import{a,b}from"../chunk-DY7J6RNN.js";import"../chunk-K6Z47OQY.js";import"../chunk-3JMDGYDT.js";export{a as ParseStringSchemaBuilder,b as parseString};
2
+ //# sourceMappingURL=ParseStringSchemaBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,213 @@
1
+ import { type BRAND, type InferType, SchemaBuilder, type ValidationContext, type ValidationErrorMessageProvider, type ValidationResult } from './SchemaBuilder.js';
2
+ type PromiseSchemaBuilderCreateProps<R extends boolean = true> = Partial<ReturnType<PromiseSchemaBuilder<R>['introspect']>>;
3
+ /**
4
+ * Schema builder for promise-like values. Validates that a value is a
5
+ * thenable (for example, an actual `Promise` or any object with a `then`
6
+ * function) and optionally carries a typed resolved-value schema so that
7
+ * the inferred TypeScript type is `Promise<T>` instead of `Promise<any>`.
8
+ *
9
+ * **NOTE** this class is exported only to give opportunity to extend it
10
+ * by inheriting. It is not recommended to create an instance of this class
11
+ * directly. Use {@link promise | promise()} function instead.
12
+ *
13
+ * @example Basic validation
14
+ * ```ts
15
+ * const schema = promise();
16
+ * const result = schema.validate(Promise.resolve(42));
17
+ * // result.valid === true
18
+ * ```
19
+ *
20
+ * @example Optional promise schema
21
+ * ```ts
22
+ * const schema = promise().optional();
23
+ * const result = schema.validate(undefined);
24
+ * // result.valid === true
25
+ * // result.object === undefined
26
+ * ```
27
+ *
28
+ * @example Typed resolved value
29
+ * ```ts
30
+ * import { promise, string, InferType } from '@cleverbrush/schema';
31
+ *
32
+ * const schema = promise(string());
33
+ *
34
+ * type PromiseResult = InferType<typeof schema>;
35
+ * // → Promise<string>
36
+ *
37
+ * // Introspect at runtime
38
+ * const info = schema.introspect();
39
+ * // info.resolvedType → StringSchemaBuilder
40
+ * ```
41
+ *
42
+ * @see {@link promise}
43
+ */
44
+ export declare class PromiseSchemaBuilder<TRequired extends boolean = true, TNullable extends boolean = false, TExplicitType = undefined, THasDefault extends boolean = false, TExtensions = {}, TResolvedTypeSchema extends SchemaBuilder<any, any, any, any, any> | undefined = undefined, TResult = TExplicitType extends undefined ? TResolvedTypeSchema extends SchemaBuilder<any, any, any, any, any> ? Promise<InferType<TResolvedTypeSchema>> : Promise<any> : TExplicitType> extends SchemaBuilder<TResult, TRequired, TNullable, THasDefault, TExtensions> {
45
+ #private;
46
+ /**
47
+ * @hidden
48
+ */
49
+ static create(props: PromiseSchemaBuilderCreateProps<any>): PromiseSchemaBuilder<true, false, undefined, false, {}, undefined, Promise<any>>;
50
+ protected constructor(props: PromiseSchemaBuilderCreateProps<TRequired>);
51
+ /**
52
+ * @hidden
53
+ */
54
+ hasType<T>(_notUsed?: T): PromiseSchemaBuilder<true, TNullable, T, THasDefault, TExtensions, TResolvedTypeSchema> & TExtensions;
55
+ /**
56
+ * @hidden
57
+ */
58
+ clearHasType(): PromiseSchemaBuilder<TRequired, TNullable, undefined, THasDefault, TExtensions, TResolvedTypeSchema> & TExtensions;
59
+ /**
60
+ * Returns an object describing the current schema configuration.
61
+ *
62
+ * In addition to the base fields exposed by {@link SchemaBuilder.introspect},
63
+ * the following field is included:
64
+ *
65
+ * - `resolvedType` — the {@link SchemaBuilder} set via {@link hasResolvedType},
66
+ * or `undefined` when no resolved-type schema has been configured.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * const schema = promise(string());
71
+ *
72
+ * const info = schema.introspect();
73
+ * // info.resolvedType instanceof StringSchemaBuilder
74
+ * ```
75
+ */
76
+ introspect(): {
77
+ /** Resolved-value schema set via {@link hasResolvedType}, or `undefined` if not set. */
78
+ resolvedType: SchemaBuilder<any, any, any, any, any> | undefined;
79
+ type: string;
80
+ isRequired: boolean;
81
+ isNullable: boolean;
82
+ isReadonly: boolean;
83
+ preprocessors: readonly import("./SchemaBuilder.js").PreprocessorEntry<TResult>[];
84
+ validators: readonly import("./SchemaBuilder.js").ValidatorEntry<TResult>[];
85
+ requiredValidationErrorMessageProvider: ValidationErrorMessageProvider<SchemaBuilder<any, any, any, any, any>>;
86
+ extensions: {
87
+ [x: string]: unknown;
88
+ };
89
+ hasDefault: boolean;
90
+ defaultValue: TResult | (() => TResult) | undefined;
91
+ description: string | undefined;
92
+ schemaName: string | undefined;
93
+ hasCatch: boolean;
94
+ catchValue: TResult | (() => TResult) | undefined;
95
+ example: unknown;
96
+ };
97
+ /** {@inheritDoc SchemaBuilder.validate} */
98
+ validate(object: TResult, context?: ValidationContext): ValidationResult<TResult>;
99
+ /** {@inheritDoc SchemaBuilder.validateAsync} */
100
+ validateAsync(object: TResult, context?: ValidationContext): Promise<ValidationResult<TResult>>;
101
+ /**
102
+ * Performs synchronous validation of the schema over `object`.
103
+ * Throws if any preprocessor, validator, or error message provider returns a Promise.
104
+ * @param context Optional `ValidationContext` settings.
105
+ */
106
+ protected _validate(object: TResult, context?: ValidationContext): ValidationResult<TResult>;
107
+ /**
108
+ * Performs async validation of the schema over `object`.
109
+ * Supports async preprocessors, validators, and error message providers.
110
+ * @param context Optional `ValidationContext` settings.
111
+ */
112
+ protected _validateAsync(object: TResult, context?: ValidationContext): Promise<ValidationResult<TResult>>;
113
+ protected createFromProps<TReq extends boolean>(props: PromiseSchemaBuilderCreateProps<TReq>): this;
114
+ /**
115
+ * @hidden
116
+ */
117
+ required(errorMessage?: ValidationErrorMessageProvider): PromiseSchemaBuilder<true, TNullable, TExplicitType, THasDefault, TExtensions, TResolvedTypeSchema> & TExtensions;
118
+ /**
119
+ * @hidden
120
+ */
121
+ optional(): PromiseSchemaBuilder<false, TNullable, TExplicitType, THasDefault, TExtensions, TResolvedTypeSchema> & TExtensions;
122
+ /**
123
+ * @hidden
124
+ */
125
+ default(value: TResult | (() => TResult)): PromiseSchemaBuilder<true, TNullable, TExplicitType, true, TExtensions, TResolvedTypeSchema> & TExtensions;
126
+ /**
127
+ * @hidden
128
+ */
129
+ clearDefault(): PromiseSchemaBuilder<TRequired, TNullable, TExplicitType, false, TExtensions, TResolvedTypeSchema> & TExtensions;
130
+ /**
131
+ * @hidden
132
+ */
133
+ brand<TBrand extends string | symbol>(_name?: TBrand): PromiseSchemaBuilder<TRequired, TNullable, TResult & {
134
+ readonly [K in BRAND]: TBrand;
135
+ }, THasDefault, TExtensions, TResolvedTypeSchema> & TExtensions;
136
+ /**
137
+ * Marks the inferred type as `Readonly<Promise<T>>`. Sets the
138
+ * `isReadonly` introspection flag for tooling consistency.
139
+ *
140
+ * @see {@link SchemaBuilder.readonly}
141
+ */
142
+ readonly(): PromiseSchemaBuilder<TRequired, TNullable, Readonly<TResult>, THasDefault, TExtensions, TResolvedTypeSchema> & TExtensions;
143
+ /**
144
+ * @hidden
145
+ */
146
+ nullable(): PromiseSchemaBuilder<TRequired, true, TExplicitType, THasDefault, TExtensions, TResolvedTypeSchema> & TExtensions;
147
+ /**
148
+ * @hidden
149
+ */
150
+ notNullable(): PromiseSchemaBuilder<TRequired, false, TExplicitType, THasDefault, TExtensions, TResolvedTypeSchema> & TExtensions;
151
+ /**
152
+ * Sets the schema for the resolved value of the `Promise`.
153
+ *
154
+ * The inferred TypeScript type becomes `Promise<T>` where `T` is the type
155
+ * produced by `schema`. The schema is accessible at runtime via
156
+ * `introspect().resolvedType`.
157
+ *
158
+ * @param schema - The schema describing the resolved value of the promise.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * const schema = promise().hasResolvedType(string());
163
+ *
164
+ * type Resolved = InferType<typeof schema>;
165
+ * // → Promise<string>
166
+ *
167
+ * schema.introspect().resolvedType; // StringSchemaBuilder
168
+ * ```
169
+ */
170
+ hasResolvedType<TSchema extends SchemaBuilder<any, any, any, any, any>>(schema: TSchema): PromiseSchemaBuilder<TRequired, TNullable, TExplicitType, THasDefault, TExtensions, TSchema> & TExtensions;
171
+ }
172
+ /**
173
+ * Creates a `promise` schema that validates the value is a JavaScript `Promise`.
174
+ *
175
+ * The returned builder is immutable and fully chainable. Pass an optional
176
+ * schema to {@link promise} to annotate the type of the resolved value —
177
+ * the inferred TypeScript type becomes `Promise<T>`.
178
+ *
179
+ * Alternatively, call {@link PromiseSchemaBuilder.hasResolvedType} on the
180
+ * returned builder to set or replace the resolved-value schema at any point
181
+ * in the chain.
182
+ *
183
+ * @param resolvedTypeSchema - Optional schema describing the resolved value of
184
+ * the promise. When provided, `InferType<typeof schema>` becomes
185
+ * `Promise<InferType<typeof resolvedTypeSchema>>`.
186
+ *
187
+ * @returns A new {@link PromiseSchemaBuilder} with `isRequired` set to `true`.
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * import { promise, string, number, InferType } from '@cleverbrush/schema';
192
+ *
193
+ * // Untyped — accepts any Promise
194
+ * const anyPromise = promise();
195
+ * type AnyPromise = InferType<typeof anyPromise>; // Promise<any>
196
+ *
197
+ * anyPromise.validate(Promise.resolve(42)); // { valid: true }
198
+ * anyPromise.validate('not a promise' as any); // { valid: false }
199
+ *
200
+ * // Typed resolved value
201
+ * const stringPromise = promise(string());
202
+ * type StringPromise = InferType<typeof stringPromise>; // Promise<string>
203
+ *
204
+ * // Optional promise
205
+ * const optPromise = promise(number()).optional();
206
+ * type OptPromise = InferType<typeof optPromise>; // Promise<number> | undefined
207
+ * ```
208
+ *
209
+ * @see {@link PromiseSchemaBuilder}
210
+ */
211
+ export declare function promise(): PromiseSchemaBuilder<true>;
212
+ export declare function promise<TSchema extends SchemaBuilder<any, any, any, any, any>>(resolvedTypeSchema: TSchema): PromiseSchemaBuilder<true, false, undefined, false, {}, TSchema>;
213
+ export {};
@@ -0,0 +1,2 @@
1
+ import{a,b}from"../chunk-WDMJBGBD.js";import"../chunk-3JMDGYDT.js";export{a as PromiseSchemaBuilder,b as promise};
2
+ //# sourceMappingURL=PromiseSchemaBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -250,8 +250,10 @@ export declare class RecordSchemaBuilder<TKeySchema extends StringSchemaBuilder<
250
250
  hasDefault: boolean;
251
251
  defaultValue: TResult | (() => TResult) | undefined;
252
252
  description: string | undefined;
253
+ schemaName: string | undefined;
253
254
  hasCatch: boolean;
254
255
  catchValue: TResult | (() => TResult) | undefined;
256
+ example: unknown;
255
257
  };
256
258
  /**
257
259
  * Core sync validation. {@inheritDoc SchemaBuilder.validate}
@@ -1,2 +1,2 @@
1
- import{a,b}from"../chunk-IJ6FO37G.js";import"../chunk-CTP4RHDG.js";export{a as RecordSchemaBuilder,b as record};
1
+ import{a,b}from"../chunk-ZFI27R3L.js";import"../chunk-3JMDGYDT.js";export{a as RecordSchemaBuilder,b as record};
2
2
  //# sourceMappingURL=RecordSchemaBuilder.js.map
@@ -48,9 +48,30 @@ export type InferType<T> = T extends {
48
48
  } ? TType : T;
49
49
  /**
50
50
  * Represents a single validation error with a human-readable error message.
51
+ *
52
+ * When returned from an object-level validator (via {@link SchemaBuilder.addValidator | addValidator}),
53
+ * the optional `property` selector can route the error to a specific property
54
+ * so that {@link ObjectSchemaValidationResult.getErrorsFor | getErrorsFor()} reports it
55
+ * on that property rather than only on the root object.
56
+ *
57
+ * ```ts
58
+ * .addValidator((v) => ({
59
+ * valid: false,
60
+ * errors: [{
61
+ * message: 'Passwords do not match',
62
+ * property: (t) => t.confirmPassword
63
+ * }]
64
+ * }))
65
+ * ```
51
66
  */
52
67
  export type ValidationError = {
53
68
  message: string;
69
+ /**
70
+ * Optional property selector that targets this error to a specific
71
+ * property of the validated object. Uses the same selector signature
72
+ * as `getErrorsFor()` and react-form's `forProperty`.
73
+ */
74
+ property?: (tree: any) => any;
54
75
  };
55
76
  /**
56
77
  * Used to represent a validation result for nested
@@ -170,6 +191,8 @@ export type SchemaBuilderProps<T> = {
170
191
  catchValue?: T | (() => T);
171
192
  hasCatch?: boolean;
172
193
  description?: string;
194
+ schemaName?: string;
195
+ example?: unknown;
173
196
  };
174
197
  export type ValidationContext<TSchema extends SchemaBuilder<any, any, any, any> = SchemaBuilder<any, any, any, any>> = {
175
198
  /**
@@ -348,6 +371,19 @@ export type PropertyDescriptorInner<TSchema extends ObjectSchemaBuilder<any, any
348
371
  */
349
372
  getSchema: () => TPropertySchema;
350
373
  parent: PropertyDescriptorInnerFromPropertyDescriptor<TParentPropertyDescriptor>;
374
+ /**
375
+ * The name of this property within its parent object, or `undefined`
376
+ * for the root descriptor.
377
+ */
378
+ propertyName: string | undefined;
379
+ /**
380
+ * Returns a JSON Pointer (RFC 6901) string representing this
381
+ * property's path from the root descriptor.
382
+ *
383
+ * Property names are escaped per RFC 6901 (`~` → `~0`, `/` → `~1`).
384
+ * The root descriptor returns an empty string (`''`).
385
+ */
386
+ toJsonPointer: () => string;
351
387
  };
352
388
  /**
353
389
  * A wrapper object keyed by {@link SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR} that
@@ -646,6 +682,11 @@ export declare abstract class SchemaBuilder<TResult = any, TRequired extends boo
646
682
  * or `undefined` if none was set.
647
683
  */
648
684
  description: string | undefined;
685
+ /**
686
+ * The logical name attached to this schema via `.schemaName()`,
687
+ * or `undefined` if none was set.
688
+ */
689
+ schemaName: string | undefined;
649
690
  /**
650
691
  * Whether a catch/fallback value has been set on this schema via `.catch()`.
651
692
  */
@@ -654,6 +695,11 @@ export declare abstract class SchemaBuilder<TResult = any, TRequired extends boo
654
695
  * The catch/fallback value or factory function set via `.catch()`.
655
696
  */
656
697
  catchValue: TResult | (() => TResult) | undefined;
698
+ /**
699
+ * An example value attached to this schema via `.example()`,
700
+ * or `undefined` if none was set.
701
+ */
702
+ example: unknown;
657
703
  };
658
704
  /**
659
705
  * Makes schema optional (consider `null` and `undefined` as valid objects for this schema)
@@ -763,6 +809,49 @@ export declare abstract class SchemaBuilder<TResult = any, TRequired extends boo
763
809
  * ```
764
810
  */
765
811
  describe(text: string): this;
812
+ /**
813
+ * Attaches an example value to this schema instance.
814
+ *
815
+ * The example is purely metadata — it has no effect on validation.
816
+ * It is accessible via `.introspect().example` and is emitted as the
817
+ * `example` keyword in JSON Schema output and OpenAPI spec generation.
818
+ *
819
+ * @example
820
+ * ```ts
821
+ * import { string } from '@cleverbrush/schema';
822
+ *
823
+ * const Email = string().example('user@example.com');
824
+ *
825
+ * Email.introspect().example; // 'user@example.com'
826
+ * ```
827
+ */
828
+ example(value: TResult): this;
829
+ /**
830
+ * Attaches a logical name to this schema instance.
831
+ *
832
+ * The name is purely metadata — it has no effect on validation. It is
833
+ * accessible via `.introspect().schemaName` and can be consumed by any
834
+ * tool that introspects schemas at runtime, such as OpenAPI spec
835
+ * generators, documentation tools, form libraries, or code generators.
836
+ *
837
+ * **Uniqueness** is the responsibility of the consuming tool. Passing the
838
+ * same constant (same object reference) to multiple consumers is always
839
+ * safe; how conflicts between different instances with the same name are
840
+ * handled depends on the tool.
841
+ *
842
+ * @example
843
+ * ```ts
844
+ * import { object, string, number } from '@cleverbrush/schema';
845
+ *
846
+ * export const UserSchema = object({
847
+ * id: number(),
848
+ * name: string(),
849
+ * }).schemaName('User');
850
+ *
851
+ * UserSchema.introspect().schemaName; // 'User'
852
+ * ```
853
+ */
854
+ schemaName(name: string): this;
766
855
  /**
767
856
  * Brands the schema with a phantom type tag, preventing structural mixing
768
857
  * of semantically different values at the type level. Zero runtime cost.
@@ -135,8 +135,10 @@ export declare class StringSchemaBuilder<TResult = string, TRequired extends boo
135
135
  hasDefault: boolean;
136
136
  defaultValue: TResult | (() => TResult) | undefined;
137
137
  description: string | undefined;
138
+ schemaName: string | undefined;
138
139
  hasCatch: boolean;
139
140
  catchValue: TResult | (() => TResult) | undefined;
141
+ example: unknown;
140
142
  };
141
143
  /**
142
144
  * @inheritdoc
@@ -1,2 +1,2 @@
1
- import{a,b}from"../chunk-FWUEUW2N.js";import"../chunk-CTP4RHDG.js";export{a as StringSchemaBuilder,b as string};
1
+ import{a,b}from"../chunk-YQZHDMRF.js";import"../chunk-3JMDGYDT.js";export{a as StringSchemaBuilder,b as string};
2
2
  //# sourceMappingURL=StringSchemaBuilder.js.map
@@ -169,8 +169,10 @@ export declare class TupleSchemaBuilder<TElements extends readonly SchemaBuilder
169
169
  hasDefault: boolean;
170
170
  defaultValue: TResult | (() => TResult) | undefined;
171
171
  description: string | undefined;
172
+ schemaName: string | undefined;
172
173
  hasCatch: boolean;
173
174
  catchValue: TResult | (() => TResult) | undefined;
175
+ example: unknown;
174
176
  };
175
177
  /**
176
178
  * Sets a schema that all elements beyond the fixed positions must satisfy.
@@ -1,2 +1,2 @@
1
- import{a,b}from"../chunk-S5TC6NSU.js";import"../chunk-CTP4RHDG.js";export{a as TupleSchemaBuilder,b as tuple};
1
+ import{a,b}from"../chunk-QARCEYGO.js";import"../chunk-3JMDGYDT.js";export{a as TupleSchemaBuilder,b as tuple};
2
2
  //# sourceMappingURL=TupleSchemaBuilder.js.map
@@ -101,6 +101,12 @@ export declare class UnionSchemaBuilder<TOptions extends readonly SchemaBuilder<
101
101
  * Array of schemas participating in the union.
102
102
  */
103
103
  options: TOptions;
104
+ /**
105
+ * When the union is a discriminated union (all branches are objects
106
+ * sharing a required property with unique literal values), this is
107
+ * the name of that property. `undefined` otherwise.
108
+ */
109
+ discriminatorPropertyName: string | undefined;
104
110
  type: string;
105
111
  isRequired: boolean;
106
112
  isNullable: boolean;
@@ -114,8 +120,10 @@ export declare class UnionSchemaBuilder<TOptions extends readonly SchemaBuilder<
114
120
  hasDefault: boolean;
115
121
  defaultValue: (TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType) | (() => TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType) | undefined;
116
122
  description: string | undefined;
123
+ schemaName: string | undefined;
117
124
  hasCatch: boolean;
118
125
  catchValue: (TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType) | (() => TExplicitType extends undefined ? SchemaArrayToUnion<TOptions> : TExplicitType) | undefined;
126
+ example: unknown;
119
127
  };
120
128
  /**
121
129
  * Null is a legitimate JavaScript value that a union option (e.g.
@@ -1,2 +1,2 @@
1
- import{a,b}from"../chunk-ZUPYV5TI.js";import"../chunk-CTP4RHDG.js";export{a as UnionSchemaBuilder,b as union};
1
+ import{a,b}from"../chunk-WQDYWDOE.js";import"../chunk-3JMDGYDT.js";export{a as UnionSchemaBuilder,b as union};
2
2
  //# sourceMappingURL=UnionSchemaBuilder.js.map