@cleverbrush/schema 1.1.11 → 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 (98) hide show
  1. package/README.md +1721 -104
  2. package/dist/builders/AnySchemaBuilder.d.ts +54 -14
  3. package/dist/builders/AnySchemaBuilder.js +2 -112
  4. package/dist/builders/AnySchemaBuilder.js.map +1 -0
  5. package/dist/builders/ArraySchemaBuilder.d.ts +126 -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 +109 -19
  9. package/dist/builders/BooleanSchemaBuilder.js +2 -150
  10. package/dist/builders/BooleanSchemaBuilder.js.map +1 -0
  11. package/dist/builders/DateSchemaBuilder.d.ts +154 -34
  12. package/dist/builders/DateSchemaBuilder.js +2 -433
  13. package/dist/builders/DateSchemaBuilder.js.map +1 -0
  14. package/dist/builders/ExternSchemaBuilder.d.ts +202 -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 +205 -18
  18. package/dist/builders/FunctionSchemaBuilder.js +2 -113
  19. package/dist/builders/FunctionSchemaBuilder.js.map +1 -0
  20. package/dist/builders/GenericSchemaBuilder.d.ts +294 -0
  21. package/dist/builders/LazySchemaBuilder.d.ts +169 -0
  22. package/dist/builders/NullSchemaBuilder.d.ts +162 -0
  23. package/dist/builders/NumberSchemaBuilder.d.ts +159 -31
  24. package/dist/builders/NumberSchemaBuilder.js +2 -386
  25. package/dist/builders/NumberSchemaBuilder.js.map +1 -0
  26. package/dist/builders/ObjectSchemaBuilder.d.ts +486 -61
  27. package/dist/builders/ObjectSchemaBuilder.js +2 -589
  28. package/dist/builders/ObjectSchemaBuilder.js.map +1 -0
  29. package/dist/builders/ParseStringSchemaBuilder.d.ts +204 -0
  30. package/dist/builders/ParseStringSchemaBuilder.js +2 -0
  31. package/dist/builders/ParseStringSchemaBuilder.js.map +1 -0
  32. package/dist/builders/PromiseSchemaBuilder.d.ts +213 -0
  33. package/dist/builders/PromiseSchemaBuilder.js +2 -0
  34. package/dist/builders/PromiseSchemaBuilder.js.map +1 -0
  35. package/dist/builders/PropertyValidationResult.d.ts +68 -0
  36. package/dist/builders/RecordSchemaBuilder.d.ts +343 -0
  37. package/dist/builders/RecordSchemaBuilder.js +2 -0
  38. package/dist/builders/RecordSchemaBuilder.js.map +1 -0
  39. package/dist/builders/SchemaBuilder.d.ts +907 -30
  40. package/dist/builders/StringSchemaBuilder.d.ts +154 -37
  41. package/dist/builders/StringSchemaBuilder.js +2 -414
  42. package/dist/builders/StringSchemaBuilder.js.map +1 -0
  43. package/dist/builders/TupleSchemaBuilder.d.ts +250 -0
  44. package/dist/builders/TupleSchemaBuilder.js +2 -0
  45. package/dist/builders/TupleSchemaBuilder.js.map +1 -0
  46. package/dist/builders/UnionSchemaBuilder.d.ts +141 -39
  47. package/dist/builders/UnionSchemaBuilder.js +2 -216
  48. package/dist/builders/UnionSchemaBuilder.js.map +1 -0
  49. package/dist/chunk-3JMDGYDT.js +2 -0
  50. package/dist/chunk-3JMDGYDT.js.map +1 -0
  51. package/dist/chunk-BUEVZ3KA.js +2 -0
  52. package/dist/chunk-BUEVZ3KA.js.map +1 -0
  53. package/dist/chunk-CFIJQ4GP.js +2 -0
  54. package/dist/chunk-CFIJQ4GP.js.map +1 -0
  55. package/dist/chunk-DY7J6RNN.js +2 -0
  56. package/dist/chunk-DY7J6RNN.js.map +1 -0
  57. package/dist/chunk-EIVZX4ZO.js +2 -0
  58. package/dist/chunk-EIVZX4ZO.js.map +1 -0
  59. package/dist/chunk-GXPV6UQK.js +2 -0
  60. package/dist/chunk-GXPV6UQK.js.map +1 -0
  61. package/dist/chunk-HN774HD7.js +2 -0
  62. package/dist/chunk-HN774HD7.js.map +1 -0
  63. package/dist/chunk-K6Z47OQY.js +2 -0
  64. package/dist/chunk-K6Z47OQY.js.map +1 -0
  65. package/dist/chunk-NUW3VXZV.js +2 -0
  66. package/dist/chunk-NUW3VXZV.js.map +1 -0
  67. package/dist/chunk-PHE4LIAN.js +2 -0
  68. package/dist/chunk-PHE4LIAN.js.map +1 -0
  69. package/dist/chunk-QARCEYGO.js +2 -0
  70. package/dist/chunk-QARCEYGO.js.map +1 -0
  71. package/dist/chunk-WDMJBGBD.js +2 -0
  72. package/dist/chunk-WDMJBGBD.js.map +1 -0
  73. package/dist/chunk-WQDYWDOE.js +2 -0
  74. package/dist/chunk-WQDYWDOE.js.map +1 -0
  75. package/dist/chunk-YQZHDMRF.js +2 -0
  76. package/dist/chunk-YQZHDMRF.js.map +1 -0
  77. package/dist/chunk-ZC6YBKCP.js +2 -0
  78. package/dist/chunk-ZC6YBKCP.js.map +1 -0
  79. package/dist/chunk-ZFI27R3L.js +2 -0
  80. package/dist/chunk-ZFI27R3L.js.map +1 -0
  81. package/dist/core.d.ts +28 -0
  82. package/dist/core.js +2 -0
  83. package/dist/core.js.map +1 -0
  84. package/dist/extension.d.ts +421 -0
  85. package/dist/extensions/array.d.ts +112 -0
  86. package/dist/extensions/enum.d.ts +190 -0
  87. package/dist/extensions/index.d.ts +112 -0
  88. package/dist/extensions/nullable.d.ts +26 -0
  89. package/dist/extensions/number.d.ts +228 -0
  90. package/dist/extensions/string.d.ts +332 -0
  91. package/dist/extensions/util.d.ts +45 -0
  92. package/dist/index.d.ts +10 -20
  93. package/dist/index.js +2 -19
  94. package/dist/index.js.map +1 -0
  95. package/dist/utils/transaction.d.ts +27 -4
  96. package/package.json +83 -7
  97. package/dist/builders/SchemaBuilder.js +0 -275
  98. package/dist/utils/transaction.js +0 -178
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/builders/TupleSchemaBuilder.ts"],"sourcesContent":["import type {\n ObjectSchemaBuilder,\n ObjectSchemaValidationResult\n} from './ObjectSchemaBuilder.js';\nimport {\n type BRAND,\n createHybridErrorArray,\n type InferType,\n type NestedValidationResult,\n type PropertyDescriptor,\n SchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\nimport type {\n UnionSchemaBuilder,\n UnionSchemaValidationResult\n} from './UnionSchemaBuilder.js';\n\n/**\n * Maps a tuple of schema builders to a tuple of their per-position\n * validation result types.\n * Union schema elements get `UnionSchemaValidationResult`,\n * object schema elements get `ObjectSchemaValidationResult`,\n * other types get `ValidationResult`.\n */\nexport type TupleElementValidationResults<\n TElements extends readonly SchemaBuilder<any, any, any, any, any>[]\n> = {\n [K in keyof TElements]: TElements[K] extends UnionSchemaBuilder<\n infer UOptions extends readonly SchemaBuilder<\n any,\n any,\n any,\n any,\n any\n >[],\n any,\n any\n >\n ? UnionSchemaValidationResult<InferType<TElements[K]>, UOptions>\n : TElements[K] extends ObjectSchemaBuilder<any, any, any, any, any>\n ? ObjectSchemaValidationResult<InferType<TElements[K]>, TElements[K]>\n : ValidationResult<InferType<TElements[K]>>;\n};\n\n/**\n * Validation result type returned by `TupleSchemaBuilder.validate()`.\n * Extends `ValidationResult` with `getNestedErrors` for root-level tuple\n * errors and per-position validation results.\n */\nexport type TupleSchemaValidationResult<\n TResult,\n TElements extends readonly SchemaBuilder<any, any, any, any, any>[]\n> = ValidationResult<TResult> & {\n /**\n * Returns root-level tuple validation errors combined with\n * per-position validation results.\n * The returned value has both `NestedValidationResult` properties\n * (`errors`, `isValid`, `descriptor`, `seenValue`) and indexed\n * position results (`[0]`, `[1]`, etc.).\n */\n getNestedErrors(): TupleElementValidationResults<TElements> &\n NestedValidationResult<any, any, any>;\n};\n\ntype TupleSchemaBuilderCreateProps<\n TElements extends readonly SchemaBuilder<any, any, any, any, any>[],\n TRestSchema extends\n | SchemaBuilder<any, any, any, any, any>\n | undefined = undefined,\n R extends boolean = true,\n N extends boolean = false\n> = Partial<\n ReturnType<\n TupleSchemaBuilder<\n TElements,\n R,\n N,\n undefined,\n false,\n {},\n TRestSchema\n >['introspect']\n >\n>;\n\n/**\n * Fixed-length array schema builder with per-position type validation.\n * Similar to TypeScript's tuple types — each element at a specific array index\n * is validated against its own schema.\n *\n * Use it when you need to validate function arguments, CSV rows, coordinate\n * pairs, structured event payloads, or any other fixed-structure array.\n *\n * **NOTE** this class is exported only to give opportunity to extend it\n * by inheriting. It is not recommended to create an instance of this class\n * directly. Use {@link tuple | tuple()} function instead.\n *\n * @example\n * ```ts\n * const schema = tuple([string(), number(), boolean()]);\n * // Inferred TypeScript type: [string, number, boolean]\n *\n * schema.validate(['hello', 42, true]);\n * // result.valid === true\n * // result.object === ['hello', 42, true]\n *\n * schema.validate(['hello', 42]);\n * // result.valid === false (too few elements)\n *\n * schema.validate(['hello', 'oops', true]);\n * // result.valid === false (wrong type at position 1)\n * ```\n *\n * @example\n * ```ts\n * // Tuple with variadic rest elements\n * const schema = tuple([string(), number()]).rest(boolean());\n * // Inferred TypeScript type: [string, number, ...boolean[]]\n *\n * schema.validate(['hello', 42, true, false]);\n * // result.valid === true — any number of extra booleans allowed\n * ```\n *\n * @example\n * ```ts\n * // Nested tuple combining with object schemas\n * const point = tuple([number(), number()]);\n * const segment = tuple([point, point]);\n *\n * segment.validate([[0, 0], [10, 20]]);\n * // result.valid === true\n * ```\n *\n * @see {@link tuple}\n */\nexport class TupleSchemaBuilder<\n TElements extends readonly SchemaBuilder<any, any, any, any, any>[],\n TRequired extends boolean = true,\n TNullable extends boolean = false,\n TExplicitType = undefined,\n THasDefault extends boolean = false,\n TExtensions = {},\n TRestSchema extends\n | SchemaBuilder<any, any, any, any, any>\n | undefined = undefined,\n TResult = TExplicitType extends undefined\n ? TRestSchema extends SchemaBuilder<any, any, any, any, any>\n ? [\n ...{ [K in keyof TElements]: InferType<TElements[K]> },\n ...Array<InferType<TRestSchema>>\n ]\n : { [K in keyof TElements]: InferType<TElements[K]> }\n : TExplicitType\n> extends SchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n #elements!: TElements;\n #restSchema:\n | (TRestSchema & SchemaBuilder<any, any, any, any, any>)\n | undefined;\n\n /**\n * @hidden\n */\n public static create(\n props: TupleSchemaBuilderCreateProps<any, any, any, any>\n ) {\n return new TupleSchemaBuilder({\n type: 'tuple',\n ...props\n } as any);\n }\n\n protected constructor(\n props: TupleSchemaBuilderCreateProps<\n TElements,\n TRestSchema,\n TRequired,\n TNullable\n >\n ) {\n super(props as any);\n\n if (Array.isArray(props.elements)) {\n this.#elements = props.elements as TElements;\n } else {\n this.#elements = [] as unknown as TElements;\n }\n\n if (props.restSchema instanceof SchemaBuilder) {\n this.#restSchema = props.restSchema as any;\n }\n }\n\n /**\n * @inheritdoc\n */\n public hasType<T>(\n _notUsed?: T\n ): TupleSchemaBuilder<\n TElements,\n true,\n TNullable,\n T,\n THasDefault,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * @inheritdoc\n */\n public clearHasType(): TupleSchemaBuilder<\n TElements,\n TRequired,\n TNullable,\n undefined,\n THasDefault,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n #getLengthError(arr: any[]): string | null {\n if (arr.length < this.#elements.length) {\n const n = this.#elements.length;\n return `expected a tuple with at least ${n} element${n === 1 ? '' : 's'}, got ${arr.length}`;\n }\n if (\n !(this.#restSchema instanceof SchemaBuilder) &&\n arr.length !== this.#elements.length\n ) {\n const n = this.#elements.length;\n return `expected a tuple of exactly ${n} element${n === 1 ? '' : 's'}, got ${arr.length}`;\n }\n return null;\n }\n\n #createValidationSetup(\n object: TResult,\n superResult: ReturnType<TupleSchemaBuilder<any, any>['preValidateSync']>\n ) {\n const {\n valid,\n context: prevalidationContext,\n errors,\n transaction: preValidationTransaction\n } = superResult;\n\n const selfDescriptor: PropertyDescriptor<any, any, any> = {\n [SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]: {\n setValue: () => false,\n getValue: (obj: any) => ({\n success: true,\n value: obj\n }),\n getSchema: () => this,\n parent: undefined,\n propertyName: undefined,\n toJsonPointer: () => ''\n }\n };\n\n const rootErrors: string[] = [];\n const elementResults = createHybridErrorArray(\n [] as any[],\n () => object,\n () => rootErrors,\n () => selfDescriptor[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]\n );\n const getNestedErrors = (() => elementResults) as any;\n\n if (!valid) {\n rootErrors.push(\n ...(errors || []).map((e: any) => e.message || String(e))\n );\n return {\n needsElementValidation: false as const,\n result: {\n valid,\n errors,\n getNestedErrors\n } as TupleSchemaValidationResult<TResult, TElements>\n };\n }\n\n const {\n object: { validatedObject: objToValidate }\n } = preValidationTransaction!;\n\n if (\n (typeof objToValidate === 'undefined' && !this.isRequired) ||\n (objToValidate === null && (!this.isRequired || this.isNullable))\n ) {\n return {\n needsElementValidation: false as const,\n result: {\n valid: true,\n object: objToValidate,\n getNestedErrors\n } as TupleSchemaValidationResult<TResult, TElements>\n };\n }\n\n if (!Array.isArray(objToValidate)) {\n rootErrors.push('array expected');\n return {\n needsElementValidation: false as const,\n result: {\n valid: false,\n errors: [{ message: 'array expected' }],\n getNestedErrors\n } as TupleSchemaValidationResult<TResult, TElements>\n };\n }\n\n return {\n needsElementValidation: true as const,\n objToValidate,\n prevalidationContext,\n getNestedErrors,\n elementResults,\n rootErrors\n };\n }\n\n #assembleDoNotStopResults(\n results: any[],\n elementResults: any,\n getNestedErrors: any\n ) {\n let allValid = true;\n\n for (let i = 0; i < results.length; i++) {\n if (!results[i]?.valid) {\n allValid = false;\n }\n elementResults[i] = results[i] as any;\n }\n\n return Object.assign(\n {\n valid: allValid,\n getNestedErrors\n },\n allValid\n ? {}\n : {\n errors: results\n .map(r => r?.errors)\n .filter(r => r)\n .flatMap(e =>\n e?.map((r: any) => ({\n ...r\n }))\n ) as any\n },\n allValid\n ? {\n object: results.map(r => r?.object)\n }\n : {}\n ) as any;\n }\n\n /**\n * Performs synchronous validation of the schema over `object`. {@inheritDoc SchemaBuilder.validate}\n */\n public validate(\n object: TResult,\n context?: ValidationContext\n ): TupleSchemaValidationResult<TResult, TElements> {\n return super.validate(object, context) as TupleSchemaValidationResult<\n TResult,\n TElements\n >;\n }\n\n /**\n * Performs asynchronous validation of the schema over `object`. {@inheritDoc SchemaBuilder.validateAsync}\n */\n public async validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<TupleSchemaValidationResult<TResult, TElements>> {\n return super.validateAsync(object, context) as Promise<\n TupleSchemaValidationResult<TResult, TElements>\n >;\n }\n\n /**\n * Performs synchronous validation of the schema over `object`.\n * Throws if any preprocessor, validator, or error message provider returns a Promise.\n * @param context Optional `ValidationContext` settings.\n */\n protected _validate(\n object: TResult,\n context?: ValidationContext\n ): TupleSchemaValidationResult<TResult, TElements> {\n // Fast path: no preprocessors/validators, stop-on-first-error mode\n if (this.canSkipPreValidation && !context?.doNotStopOnFirstError) {\n // Handle undefined / null\n if (typeof object === 'undefined' || object === null) {\n if (typeof object === 'undefined' && this.hasDefault) {\n object = this.resolveDefaultValue();\n } else if (\n !this.isRequired ||\n (object === null && this.isNullable)\n ) {\n const self = this;\n return {\n valid: true,\n object,\n getNestedErrors() {\n return self\n .#validateTupleFull(object, context)\n .getNestedErrors();\n }\n } as any;\n } else {\n return this.#validateTupleFull(object, context);\n }\n }\n\n if (!Array.isArray(object)) {\n return this.#validateTupleFull(object, context);\n }\n\n const lengthError = this.#getLengthError(object as any[]);\n if (lengthError) {\n const self = this;\n return {\n valid: false,\n errors: [{ message: lengthError }],\n getNestedErrors() {\n return self\n .#validateTupleFull(object, context)\n .getNestedErrors();\n }\n } as any;\n }\n\n const resultArray = new Array((object as any[]).length);\n\n for (let i = 0; i < this.#elements.length; i++) {\n const result = this.#elements[i].validate((object as any)[i]);\n if (!result.valid) {\n const self = this;\n return {\n valid: false,\n errors:\n result.errors && result.errors.length > 0\n ? [result.errors[0]]\n : [],\n getNestedErrors() {\n return self\n .#validateTupleFull(object, context)\n .getNestedErrors();\n }\n } as any;\n }\n resultArray[i] = result.object;\n }\n\n if (this.#restSchema instanceof SchemaBuilder) {\n for (\n let i = this.#elements.length;\n i < (object as any[]).length;\n i++\n ) {\n const result = this.#restSchema.validate(\n (object as any)[i]\n );\n if (!result.valid) {\n const self = this;\n return {\n valid: false,\n errors:\n result.errors && result.errors.length > 0\n ? [result.errors[0]]\n : [],\n getNestedErrors() {\n return self\n .#validateTupleFull(object, context)\n .getNestedErrors();\n }\n } as any;\n }\n resultArray[i] = result.object;\n }\n }\n\n const self = this;\n return {\n valid: true,\n object: resultArray as TResult,\n getNestedErrors() {\n return self\n .#validateTupleFull(object, context)\n .getNestedErrors();\n }\n } as any;\n }\n\n return this.#validateTupleFull(object, context);\n }\n\n /**\n * Full validation path with complete setup, error handling, and nested\n * error support.\n */\n #validateTupleFull(\n object: TResult,\n context?: ValidationContext\n ): TupleSchemaValidationResult<TResult, TElements> {\n const setup = this.#createValidationSetup(\n object,\n this.preValidateSync(object, context)\n );\n\n if (!setup.needsElementValidation) return setup.result;\n\n const {\n objToValidate,\n prevalidationContext,\n getNestedErrors,\n elementResults,\n rootErrors\n } = setup;\n\n const lengthError = this.#getLengthError(objToValidate);\n if (lengthError) {\n rootErrors.push(lengthError);\n return {\n valid: false,\n errors: [{ message: lengthError }],\n getNestedErrors\n };\n }\n\n const totalLength =\n this.#restSchema instanceof SchemaBuilder\n ? objToValidate.length\n : this.#elements.length;\n\n if (prevalidationContext.doNotStopOnFirstError) {\n const results: any[] = new Array(totalLength);\n\n for (let i = 0; i < this.#elements.length; i++) {\n results[i] = this.#elements[i].validate(objToValidate[i], {\n ...prevalidationContext\n });\n }\n\n if (this.#restSchema instanceof SchemaBuilder) {\n for (\n let i = this.#elements.length;\n i < objToValidate.length;\n i++\n ) {\n results[i] = this.#restSchema.validate(objToValidate[i], {\n ...prevalidationContext\n });\n }\n }\n\n return this.#assembleDoNotStopResults(\n results,\n elementResults,\n getNestedErrors\n );\n } else {\n const resultArray = new Array(totalLength);\n\n for (let i = 0; i < this.#elements.length; i++) {\n const result = this.#elements[i].validate(objToValidate[i], {\n ...prevalidationContext\n });\n elementResults[i] = result as any;\n if (result.valid) {\n resultArray[i] = result.object;\n } else {\n return {\n valid: false,\n errors:\n Array.isArray(result.errors) &&\n result.errors.length > 0\n ? [result.errors[0]]\n : [],\n getNestedErrors\n };\n }\n }\n\n if (this.#restSchema instanceof SchemaBuilder) {\n for (\n let i = this.#elements.length;\n i < objToValidate.length;\n i++\n ) {\n const result = this.#restSchema.validate(objToValidate[i], {\n ...prevalidationContext\n });\n elementResults[i] = result as any;\n if (result.valid) {\n resultArray[i] = result.object;\n } else {\n return {\n valid: false,\n errors:\n Array.isArray(result.errors) &&\n result.errors.length > 0\n ? [result.errors[0]]\n : [],\n getNestedErrors\n };\n }\n }\n }\n\n return {\n valid: true,\n object: resultArray as TResult,\n getNestedErrors\n };\n }\n }\n\n /**\n * Performs async validation of the schema over `object`.\n * Supports async preprocessors, validators, and error message providers.\n * @param context Optional `ValidationContext` settings.\n */\n protected async _validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<TupleSchemaValidationResult<TResult, TElements>> {\n const setup = this.#createValidationSetup(\n object,\n await super.preValidateAsync(object, context)\n );\n\n if (!setup.needsElementValidation) return setup.result;\n\n const {\n objToValidate,\n prevalidationContext,\n getNestedErrors,\n elementResults,\n rootErrors\n } = setup;\n\n const lengthError = this.#getLengthError(objToValidate);\n if (lengthError) {\n rootErrors.push(lengthError);\n return {\n valid: false,\n errors: [{ message: lengthError }],\n getNestedErrors\n };\n }\n\n const totalLength =\n this.#restSchema instanceof SchemaBuilder\n ? objToValidate.length\n : this.#elements.length;\n\n if (prevalidationContext.doNotStopOnFirstError) {\n const promises: Promise<any>[] = new Array(totalLength);\n\n for (let i = 0; i < this.#elements.length; i++) {\n promises[i] = this.#elements[i].validateAsync(\n objToValidate[i],\n { ...prevalidationContext }\n );\n }\n\n if (this.#restSchema instanceof SchemaBuilder) {\n for (\n let i = this.#elements.length;\n i < objToValidate.length;\n i++\n ) {\n promises[i] = this.#restSchema.validateAsync(\n objToValidate[i],\n { ...prevalidationContext }\n );\n }\n }\n\n const results = await Promise.all(promises);\n return this.#assembleDoNotStopResults(\n results,\n elementResults,\n getNestedErrors\n );\n } else {\n const resultArray = new Array(totalLength);\n\n for (let i = 0; i < this.#elements.length; i++) {\n const result = await this.#elements[i].validateAsync(\n objToValidate[i],\n { ...prevalidationContext }\n );\n elementResults[i] = result as any;\n if (result.valid) {\n resultArray[i] = result.object;\n } else {\n return {\n valid: false,\n errors:\n Array.isArray(result.errors) &&\n result.errors.length > 0\n ? [result.errors[0]]\n : [],\n getNestedErrors\n };\n }\n }\n\n if (this.#restSchema instanceof SchemaBuilder) {\n for (\n let i = this.#elements.length;\n i < objToValidate.length;\n i++\n ) {\n const result = await this.#restSchema.validateAsync(\n objToValidate[i],\n { ...prevalidationContext }\n );\n elementResults[i] = result as any;\n if (result.valid) {\n resultArray[i] = result.object;\n } else {\n return {\n valid: false,\n errors:\n Array.isArray(result.errors) &&\n result.errors.length > 0\n ? [result.errors[0]]\n : [],\n getNestedErrors\n };\n }\n }\n }\n\n return {\n valid: true,\n object: resultArray as TResult,\n getNestedErrors\n };\n }\n }\n\n /**\n * @hidden\n */\n protected createFromProps<TReq extends boolean>(\n props: TupleSchemaBuilderCreateProps<TElements, TRestSchema, TReq>\n ): this {\n return TupleSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): TupleSchemaBuilder<\n TElements,\n true,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return super.required(errorMessage);\n }\n\n /**\n * @hidden\n */\n public optional(): TupleSchemaBuilder<\n TElements,\n false,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return super.optional();\n }\n\n /**\n * @hidden\n */\n public default(\n value: TResult | (() => TResult)\n ): TupleSchemaBuilder<\n TElements,\n true,\n TNullable,\n TExplicitType,\n true,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return super.default(value) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): TupleSchemaBuilder<\n TElements,\n TRequired,\n TNullable,\n TExplicitType,\n false,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return super.clearDefault() as any;\n }\n\n /**\n * @hidden\n */\n public brand<TBrand extends string | symbol>(\n _name?: TBrand\n ): TupleSchemaBuilder<\n TElements,\n TRequired,\n TNullable,\n TResult & { readonly [K in BRAND]: TBrand },\n THasDefault,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return super.brand(_name);\n }\n\n public introspect() {\n return {\n ...super.introspect(),\n /**\n * Per-position element schemas defining the fixed tuple structure.\n */\n elements: this.#elements,\n /**\n * Optional schema for elements beyond the fixed positions.\n * When set, additional elements are validated against this schema.\n * Mirrors TypeScript's rest element syntax: `[string, number, ...boolean[]]`.\n */\n restSchema: this.#restSchema\n };\n }\n\n /**\n * Sets a schema that all elements beyond the fixed positions must satisfy.\n * Mirrors TypeScript's variadic tuple tail: `[string, number, ...boolean[]]`.\n *\n * When set, the tuple length must be at least equal to the number of fixed\n * elements, and any additional elements are validated against `schema`.\n * When not set, the tuple length must be exactly equal to the fixed count.\n *\n * @param schema Schema that extra array elements must satisfy.\n *\n * @example\n * ```ts\n * const schema = tuple([string(), number()]).rest(boolean());\n * // Inferred TypeScript type: [string, number, ...boolean[]]\n *\n * schema.validate(['hello', 42]); // valid\n * schema.validate(['hello', 42, true]); // valid\n * schema.validate(['hello', 42, true, false]); // valid\n * schema.validate(['hello', 42, 'extra']); // invalid — 'extra' not boolean\n * ```\n */\n public rest<TSchema extends SchemaBuilder<any, any, any, any, any>>(\n schema: TSchema\n ): TupleSchemaBuilder<\n TElements,\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TSchema\n > &\n TExtensions {\n return TupleSchemaBuilder.create({\n ...this.introspect(),\n restSchema: schema\n } as any) as any;\n }\n\n /**\n * Removes the rest schema set by `rest()`. After this call, the tuple\n * length must be exactly equal to the number of fixed element schemas.\n */\n public clearRest(): TupleSchemaBuilder<\n TElements,\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n undefined\n > &\n TExtensions {\n return TupleSchemaBuilder.create({\n ...this.introspect(),\n restSchema: undefined\n } as any) as any;\n }\n\n /**\n * @hidden\n */\n public nullable(): TupleSchemaBuilder<\n TElements,\n TRequired,\n true,\n TExplicitType,\n THasDefault,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return super.nullable() as any;\n }\n\n /**\n * @hidden\n */\n public notNullable(): TupleSchemaBuilder<\n TElements,\n TRequired,\n false,\n TExplicitType,\n THasDefault,\n TExtensions,\n TRestSchema\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n}\n\n/**\n * Creates a fixed-length array schema (tuple) where each element at a\n * specific index is validated against its own schema.\n *\n * @param elements Array of per-position schemas. The length of this array\n * determines the required tuple length (unless `.rest()` is used).\n *\n * @example\n * ```ts\n * import { tuple, string, number, boolean } from '@cleverbrush/schema';\n *\n * const schema = tuple([string(), number(), boolean()]);\n * // Inferred TypeScript type: [string, number, boolean]\n *\n * schema.validate(['hello', 42, true]); // valid\n * schema.validate(['hello', 42]); // invalid — too few elements\n * schema.validate(['hello', 'oops', true]); // invalid — wrong type at [1]\n * ```\n *\n * @example\n * ```ts\n * // 2-D coordinate pair\n * const point = tuple([number(), number()]);\n * const result = point.validate([10.5, 20.3]);\n * // result.valid === true\n * // result.object === [10.5, 20.3]\n * ```\n *\n * @example\n * ```ts\n * // Optional tuple with default value\n * const schema = tuple([string(), number()])\n * .optional()\n * .default(() => ['', 0]);\n * ```\n */\nexport const tuple = <\n const TElements extends readonly SchemaBuilder<any, any, any, any, any>[]\n>(\n elements: [...TElements]\n) =>\n TupleSchemaBuilder.create({\n isRequired: true,\n elements\n }) as unknown as TupleSchemaBuilder<TElements, true>;\n"],"mappings":"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","names":["TupleSchemaBuilder","_TupleSchemaBuilder","SchemaBuilder","#elements","#restSchema","props","_notUsed","#getLengthError","arr","n","#createValidationSetup","object","superResult","valid","prevalidationContext","errors","preValidationTransaction","selfDescriptor","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","obj","rootErrors","elementResults","createHybridErrorArray","getNestedErrors","e","objToValidate","#assembleDoNotStopResults","results","allValid","i","r","context","self","#validateTupleFull","lengthError","resultArray","result","setup","totalLength","promises","errorMessage","value","_name","schema","tuple","elements"]}
@@ -0,0 +1,2 @@
1
+ import{f as i}from"./chunk-3JMDGYDT.js";var r=class s extends i{#e;static create(e){return new s({type:"promise",...e})}constructor(e){super(e),e.resolvedType instanceof i&&(this.#e=e.resolvedType)}hasType(e){return this.createFromProps({...this.introspect()})}clearHasType(){return this.createFromProps({...this.introspect()})}introspect(){return{...super.introspect(),resolvedType:this.#e}}#a(e){let{valid:a,transaction:n,errors:l}=e;if(!a)return{valid:a,errors:l};let{object:{validatedObject:t}}=n;return typeof t>"u"&&!this.isRequired||t===null&&(!this.isRequired||this.isNullable)?{valid:!0,object:t}:t==null||typeof t.then!="function"?{valid:!1,errors:[{message:`expected a Promise, but saw ${t===null?"null":typeof t}`}]}:{valid:!0,object:t}}validate(e,a){return super.validate(e,a)}async validateAsync(e,a){return super.validateAsync(e,a)}_validate(e,a){return this.#a(this.preValidateSync(e,a))}async _validateAsync(e,a){return this.#a(await super.preValidateAsync(e,a))}createFromProps(e){return s.create(e)}required(e){return super.required(e)}optional(){return super.optional()}default(e){return super.default(e)}clearDefault(){return super.clearDefault()}brand(e){return super.brand(e)}readonly(){return super.readonly()}nullable(){return super.nullable()}notNullable(){return super.notNullable()}hasResolvedType(e){return this.createFromProps({...this.introspect(),resolvedType:e})}};function o(s){return r.create({isRequired:!0,resolvedType:s})}export{r as a,o as b};
2
+ //# sourceMappingURL=chunk-WDMJBGBD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/builders/PromiseSchemaBuilder.ts"],"sourcesContent":["import {\n type BRAND,\n type InferType,\n SchemaBuilder,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\n\ntype PromiseSchemaBuilderCreateProps<R extends boolean = true> = Partial<\n ReturnType<PromiseSchemaBuilder<R>['introspect']>\n>;\n\n/**\n * Schema builder for promise-like values. Validates that a value is a\n * thenable (for example, an actual `Promise` or any object with a `then`\n * function) and optionally carries a typed resolved-value schema so that\n * the inferred TypeScript type is `Promise<T>` instead of `Promise<any>`.\n *\n * **NOTE** this class is exported only to give opportunity to extend it\n * by inheriting. It is not recommended to create an instance of this class\n * directly. Use {@link promise | promise()} function instead.\n *\n * @example Basic validation\n * ```ts\n * const schema = promise();\n * const result = schema.validate(Promise.resolve(42));\n * // result.valid === true\n * ```\n *\n * @example Optional promise schema\n * ```ts\n * const schema = promise().optional();\n * const result = schema.validate(undefined);\n * // result.valid === true\n * // result.object === undefined\n * ```\n *\n * @example Typed resolved value\n * ```ts\n * import { promise, string, InferType } from '@cleverbrush/schema';\n *\n * const schema = promise(string());\n *\n * type PromiseResult = InferType<typeof schema>;\n * // → Promise<string>\n *\n * // Introspect at runtime\n * const info = schema.introspect();\n * // info.resolvedType → StringSchemaBuilder\n * ```\n *\n * @see {@link promise}\n */\nexport class PromiseSchemaBuilder<\n TRequired extends boolean = true,\n TNullable extends boolean = false,\n TExplicitType = undefined,\n THasDefault extends boolean = false,\n TExtensions = {},\n TResolvedTypeSchema extends\n | SchemaBuilder<any, any, any, any, any>\n | undefined = undefined,\n TResult = TExplicitType extends undefined\n ? TResolvedTypeSchema extends SchemaBuilder<any, any, any, any, any>\n ? Promise<InferType<TResolvedTypeSchema>>\n : Promise<any>\n : TExplicitType\n> extends SchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n #resolvedType?: SchemaBuilder<any, any, any, any, any>;\n\n /**\n * @hidden\n */\n public static create(props: PromiseSchemaBuilderCreateProps<any>) {\n return new PromiseSchemaBuilder({\n type: 'promise',\n ...props\n });\n }\n\n protected constructor(props: PromiseSchemaBuilderCreateProps<TRequired>) {\n super(props as any);\n\n if (props.resolvedType instanceof SchemaBuilder) {\n this.#resolvedType = props.resolvedType;\n }\n }\n\n /**\n * @hidden\n */\n public hasType<T>(\n _notUsed?: T\n ): PromiseSchemaBuilder<\n true,\n TNullable,\n T,\n THasDefault,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * @hidden\n */\n public clearHasType(): PromiseSchemaBuilder<\n TRequired,\n TNullable,\n undefined,\n THasDefault,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * Returns an object describing the current schema configuration.\n *\n * In addition to the base fields exposed by {@link SchemaBuilder.introspect},\n * the following field is included:\n *\n * - `resolvedType` — the {@link SchemaBuilder} set via {@link hasResolvedType},\n * or `undefined` when no resolved-type schema has been configured.\n *\n * @example\n * ```ts\n * const schema = promise(string());\n *\n * const info = schema.introspect();\n * // info.resolvedType instanceof StringSchemaBuilder\n * ```\n */\n public introspect() {\n return {\n ...super.introspect(),\n /** Resolved-value schema set via {@link hasResolvedType}, or `undefined` if not set. */\n resolvedType: this.#resolvedType\n };\n }\n\n #buildResult(\n superResult: ReturnType<PromiseSchemaBuilder['preValidateSync']>\n ): ValidationResult<TResult> {\n const {\n valid,\n transaction: preValidationTransaction,\n errors\n } = superResult;\n\n if (!valid) {\n return { valid, errors };\n }\n\n const {\n object: { validatedObject: objToValidate }\n } = preValidationTransaction!;\n\n if (\n (typeof objToValidate === 'undefined' && !this.isRequired) ||\n (objToValidate === null && (!this.isRequired || this.isNullable))\n ) {\n return {\n valid: true,\n object: objToValidate\n };\n }\n\n if (\n objToValidate == null ||\n typeof (objToValidate as any).then !== 'function'\n ) {\n return {\n valid: false,\n errors: [\n {\n message: `expected a Promise, but saw ${objToValidate === null ? 'null' : typeof objToValidate}`\n }\n ]\n };\n }\n\n return {\n valid: true,\n object: objToValidate\n };\n }\n\n /** {@inheritDoc SchemaBuilder.validate} */\n public validate(\n object: TResult,\n context?: ValidationContext\n ): ValidationResult<TResult> {\n return super.validate(object, context) as ValidationResult<TResult>;\n }\n\n /** {@inheritDoc SchemaBuilder.validateAsync} */\n public async validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<ValidationResult<TResult>> {\n return super.validateAsync(object, context) as Promise<\n ValidationResult<TResult>\n >;\n }\n\n /**\n * Performs synchronous validation of the schema over `object`.\n * Throws if any preprocessor, validator, or error message provider returns a Promise.\n * @param context Optional `ValidationContext` settings.\n */\n protected _validate(\n object: TResult,\n context?: ValidationContext\n ): ValidationResult<TResult> {\n return this.#buildResult(this.preValidateSync(object, context));\n }\n\n /**\n * Performs async validation of the schema over `object`.\n * Supports async preprocessors, validators, and error message providers.\n * @param context Optional `ValidationContext` settings.\n */\n protected async _validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<ValidationResult<TResult>> {\n return this.#buildResult(await super.preValidateAsync(object, context));\n }\n\n protected createFromProps<TReq extends boolean>(\n props: PromiseSchemaBuilderCreateProps<TReq>\n ): this {\n return PromiseSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): PromiseSchemaBuilder<\n true,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return super.required(errorMessage);\n }\n\n /**\n * @hidden\n */\n public optional(): PromiseSchemaBuilder<\n false,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return super.optional();\n }\n\n /**\n * @hidden\n */\n public default(\n value: TResult | (() => TResult)\n ): PromiseSchemaBuilder<\n true,\n TNullable,\n TExplicitType,\n true,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return super.default(value) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): PromiseSchemaBuilder<\n TRequired,\n TNullable,\n TExplicitType,\n false,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return super.clearDefault() as any;\n }\n\n /**\n * @hidden\n */\n public brand<TBrand extends string | symbol>(\n _name?: TBrand\n ): PromiseSchemaBuilder<\n TRequired,\n TNullable,\n TResult & { readonly [K in BRAND]: TBrand },\n THasDefault,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return super.brand(_name);\n }\n\n /**\n * Marks the inferred type as `Readonly<Promise<T>>`. Sets the\n * `isReadonly` introspection flag for tooling consistency.\n *\n * @see {@link SchemaBuilder.readonly}\n */\n public readonly(): PromiseSchemaBuilder<\n TRequired,\n TNullable,\n Readonly<TResult>,\n THasDefault,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * @hidden\n */\n public nullable(): PromiseSchemaBuilder<\n TRequired,\n true,\n TExplicitType,\n THasDefault,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return super.nullable() as any;\n }\n\n /**\n * @hidden\n */\n public notNullable(): PromiseSchemaBuilder<\n TRequired,\n false,\n TExplicitType,\n THasDefault,\n TExtensions,\n TResolvedTypeSchema\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n\n /**\n * Sets the schema for the resolved value of the `Promise`.\n *\n * The inferred TypeScript type becomes `Promise<T>` where `T` is the type\n * produced by `schema`. The schema is accessible at runtime via\n * `introspect().resolvedType`.\n *\n * @param schema - The schema describing the resolved value of the promise.\n *\n * @example\n * ```ts\n * const schema = promise().hasResolvedType(string());\n *\n * type Resolved = InferType<typeof schema>;\n * // → Promise<string>\n *\n * schema.introspect().resolvedType; // StringSchemaBuilder\n * ```\n */\n public hasResolvedType<\n TSchema extends SchemaBuilder<any, any, any, any, any>\n >(\n schema: TSchema\n ): PromiseSchemaBuilder<\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect(),\n resolvedType: schema\n } as any) as any;\n }\n}\n\n/**\n * Creates a `promise` schema that validates the value is a JavaScript `Promise`.\n *\n * The returned builder is immutable and fully chainable. Pass an optional\n * schema to {@link promise} to annotate the type of the resolved value —\n * the inferred TypeScript type becomes `Promise<T>`.\n *\n * Alternatively, call {@link PromiseSchemaBuilder.hasResolvedType} on the\n * returned builder to set or replace the resolved-value schema at any point\n * in the chain.\n *\n * @param resolvedTypeSchema - Optional schema describing the resolved value of\n * the promise. When provided, `InferType<typeof schema>` becomes\n * `Promise<InferType<typeof resolvedTypeSchema>>`.\n *\n * @returns A new {@link PromiseSchemaBuilder} with `isRequired` set to `true`.\n *\n * @example\n * ```ts\n * import { promise, string, number, InferType } from '@cleverbrush/schema';\n *\n * // Untyped — accepts any Promise\n * const anyPromise = promise();\n * type AnyPromise = InferType<typeof anyPromise>; // Promise<any>\n *\n * anyPromise.validate(Promise.resolve(42)); // { valid: true }\n * anyPromise.validate('not a promise' as any); // { valid: false }\n *\n * // Typed resolved value\n * const stringPromise = promise(string());\n * type StringPromise = InferType<typeof stringPromise>; // Promise<string>\n *\n * // Optional promise\n * const optPromise = promise(number()).optional();\n * type OptPromise = InferType<typeof optPromise>; // Promise<number> | undefined\n * ```\n *\n * @see {@link PromiseSchemaBuilder}\n */\nexport function promise(): PromiseSchemaBuilder<true>;\nexport function promise<TSchema extends SchemaBuilder<any, any, any, any, any>>(\n resolvedTypeSchema: TSchema\n): PromiseSchemaBuilder<true, false, undefined, false, {}, TSchema>;\nexport function promise<TSchema extends SchemaBuilder<any, any, any, any, any>>(\n resolvedTypeSchema?: TSchema\n): PromiseSchemaBuilder<true> {\n return PromiseSchemaBuilder.create({\n isRequired: true,\n resolvedType: resolvedTypeSchema\n }) as PromiseSchemaBuilder<true>;\n}\n"],"mappings":"wCAsDO,IAAMA,EAAN,MAAMC,UAcHC,CAMR,CACEC,GAKA,OAAc,OAAOC,EAA6C,CAC9D,OAAO,IAAIH,EAAqB,CAC5B,KAAM,UACN,GAAGG,CACP,CAAC,CACL,CAEU,YAAYA,EAAmD,CACrE,MAAMA,CAAY,EAEdA,EAAM,wBAAwBF,IAC9B,KAAKC,GAAgBC,EAAM,aAEnC,CAKO,QACHC,EASY,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,CACvB,CAAQ,CACZ,CAKO,cAQS,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,CACvB,CAAQ,CACZ,CAmBO,YAAa,CAChB,MAAO,CACH,GAAG,MAAM,WAAW,EAEpB,aAAc,KAAKF,EACvB,CACJ,CAEAG,GACIC,EACyB,CACzB,GAAM,CACF,MAAAC,EACA,YAAaC,EACb,OAAAC,CACJ,EAAIH,EAEJ,GAAI,CAACC,EACD,MAAO,CAAE,MAAAA,EAAO,OAAAE,CAAO,EAG3B,GAAM,CACF,OAAQ,CAAE,gBAAiBC,CAAc,CAC7C,EAAIF,EAEJ,OACK,OAAOE,EAAkB,KAAe,CAAC,KAAK,YAC9CA,IAAkB,OAAS,CAAC,KAAK,YAAc,KAAK,YAE9C,CACH,MAAO,GACP,OAAQA,CACZ,EAIAA,GAAiB,MACjB,OAAQA,EAAsB,MAAS,WAEhC,CACH,MAAO,GACP,OAAQ,CACJ,CACI,QAAS,+BAA+BA,IAAkB,KAAO,OAAS,OAAOA,CAAa,EAClG,CACJ,CACJ,EAGG,CACH,MAAO,GACP,OAAQA,CACZ,CACJ,CAGO,SACHC,EACAC,EACyB,CACzB,OAAO,MAAM,SAASD,EAAQC,CAAO,CACzC,CAGA,MAAa,cACTD,EACAC,EACkC,CAClC,OAAO,MAAM,cAAcD,EAAQC,CAAO,CAG9C,CAOU,UACND,EACAC,EACyB,CACzB,OAAO,KAAKP,GAAa,KAAK,gBAAgBM,EAAQC,CAAO,CAAC,CAClE,CAOA,MAAgB,eACZD,EACAC,EACkC,CAClC,OAAO,KAAKP,GAAa,MAAM,MAAM,iBAAiBM,EAAQC,CAAO,CAAC,CAC1E,CAEU,gBACNT,EACI,CACJ,OAAOH,EAAqB,OAAOG,CAAY,CACnD,CAKO,SACHU,EASY,CACZ,OAAO,MAAM,SAASA,CAAY,CACtC,CAKO,UAQS,CACZ,OAAO,MAAM,SAAS,CAC1B,CAKO,QACHC,EASY,CACZ,OAAO,MAAM,QAAQA,CAAK,CAC9B,CAKO,cAQS,CACZ,OAAO,MAAM,aAAa,CAC9B,CAKO,MACHC,EASY,CACZ,OAAO,MAAM,MAAMA,CAAK,CAC5B,CAQO,UAQS,CACZ,OAAO,MAAM,SAAS,CAC1B,CAKO,UAQS,CACZ,OAAO,MAAM,SAAS,CAC1B,CAKO,aAQS,CACZ,OAAO,MAAM,YAAY,CAC7B,CAqBO,gBAGHC,EASY,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,EACnB,aAAcA,CAClB,CAAQ,CACZ,CACJ,EA6CO,SAASC,EACZC,EAC0B,CAC1B,OAAOnB,EAAqB,OAAO,CAC/B,WAAY,GACZ,aAAcmB,CAClB,CAAC,CACL","names":["PromiseSchemaBuilder","_PromiseSchemaBuilder","SchemaBuilder","#resolvedType","props","_notUsed","#buildResult","superResult","valid","preValidationTransaction","errors","objToValidate","object","context","errorMessage","value","_name","schema","promise","resolvedTypeSchema"]}
@@ -0,0 +1,2 @@
1
+ import{c as h,e as m,f as c}from"./chunk-3JMDGYDT.js";var f=class T extends c{#e;#n=null;#t=null;static create(e){return new T({type:"union",...e})}constructor(e){super(e),Array.isArray(e.options)&&(this.#e=e.options,this.#o())}#o(){let e=this.#e;if(!e||e.length<2)return;let n=[];for(let s of e){let t=s.introspect();if(t.type!=="object")return;n.push(t)}let i=n[0].properties;if(i)for(let s of Object.keys(i)){let t=new Map,a=!0;for(let o=0;o<n.length;o++){let d=n[o].properties;if(!d||!(s in d)){a=!1;break}let r=d[s].introspect();if(r.isRequired!==!0){a=!1;break}let l=r.equalsTo;if(l==null){a=!1;break}if(typeof l!="string"&&typeof l!="number"){a=!1;break}if(t.has(l)){a=!1;break}t.set(l,e[o])}if(a&&t.size===e.length){this.#n=s,this.#t=t;return}}}introspect(){return{...super.introspect(),options:this.#e,discriminatorPropertyName:this.#n??void 0}}get isNullRequiredViolation(){return!1}hasType(e){return this.createFromProps({...this.introspect()})}clearHasType(){return this.createFromProps({...this.introspect()})}#r(e,n){let{valid:i,transaction:s,context:t,errors:a}=n,o={[h]:{setValue:()=>!1,getValue:u=>({success:!0,value:u}),getSchema:()=>this,parent:void 0,propertyName:void 0,toJsonPointer:()=>""}},d=[],y=m([],()=>e,()=>d,()=>o[h]),r=(()=>y);if(!i)return d.push(...(a||[]).map(u=>u.message||String(u))),{needsOptionValidation:!1,result:{valid:i,errors:a,getNestedErrors:r}};let{object:{validatedObject:l}}=s;return typeof l>"u"&&!this.isRequired||l===null&&(!this.isRequired||this.isNullable)?{needsOptionValidation:!1,result:{valid:!0,object:l,getNestedErrors:r}}:{needsOptionValidation:!0,objToValidate:l,prevalidationContext:t,preValidationTransaction:s,getNestedErrors:r,optionResults:y,rootErrors:d}}#s(e,n,i,s,t,a){if(i[n]=e,e.valid)return{valid:!0,object:e.object,getNestedErrors:a};let o=e.errors;return Array.isArray(o)&&o.length>0&&o.length<t.minErrorsCount&&(t.resultingErrors=o,t.minErrorsCount=o.length),t.objToValidate=s.rollback().validatedObject,null}validate(e,n){return super.validate(e,n)}async validateAsync(e,n){return super.validateAsync(e,n)}_validate(e,n){if(this.canSkipPreValidation&&!n?.doNotStopOnFirstError&&!n?.rootPropertyDescriptor){if(typeof e>"u")if(this.hasDefault)e=this.resolveDefaultValue();else return this.isRequired?this.#i(!1,void 0,[{message:this.getValidationErrorMessageSync(this.requiredErrorMessage,e)}],e,n):this.#i(!0,e,void 0,e,n);else if(e===null&&(!this.isRequired||this.isNullable))return this.#i(!0,e,void 0,e,n);if(this.#n&&this.#t&&typeof e=="object"&&e!==null){let i=e[this.#n],s=this.#t.get(i);if(s){let t=s.validate(e);return this.#i(t.valid,t.valid?t.object:void 0,t.valid?void 0:t.errors,e,n)}return this.#i(!1,void 0,[{message:"value doesn't match any option in union schema"}],e,n)}if(!this.#n){let i=this.#e,s=Number.MAX_SAFE_INTEGER,t=[];for(let a=0;a<i.length;a++){let o=i[a].validate(e);if(o.valid)return this.#i(!0,o.object,void 0,e,n);let d=o.errors;Array.isArray(d)&&d.length>0&&d.length<s&&(t=d,s=d.length)}return this.#i(!1,void 0,t,e,n)}}return this.#a(e,n)}#i(e,n,i,s,t){let a=this;return e?{valid:!0,object:n,getNestedErrors(){return a.#a(s,t).getNestedErrors()}}:{valid:!1,errors:i,getNestedErrors(){return a.#a(s,t).getNestedErrors()}}}#a(e,n){let i=this.#r(e,this.preValidateSync(e,n));if(!i.needsOptionValidation)return i.result;let{prevalidationContext:s,preValidationTransaction:t,getNestedErrors:a,optionResults:o,rootErrors:d}=i;if(this.#n&&this.#t){let r=i.objToValidate;if(typeof r=="object"&&r!==null){let l=r[this.#n],u=this.#t.get(l);if(u){let p=u.validate(r,{...s,currentPropertyDescriptor:void 0,rootPropertyDescriptor:void 0});if(p.valid)return{valid:!0,object:p.object,getNestedErrors:a}}}}let y={objToValidate:i.objToValidate,minErrorsCount:Number.MAX_SAFE_INTEGER,resultingErrors:[]};for(let r=0;r<this.#e.length;r++){let l=this.#e[r].validate(y.objToValidate,{...s,currentPropertyDescriptor:void 0,rootPropertyDescriptor:void 0}),u=this.#s(l,r,o,t,y,a);if(u)return u}return d.push("value doesn't match any option in union schema"),{valid:!1,errors:y.resultingErrors,getNestedErrors:a}}async _validateAsync(e,n){let i=this.#r(e,await super.preValidateAsync(e,n));if(!i.needsOptionValidation)return i.result;let{prevalidationContext:s,preValidationTransaction:t,getNestedErrors:a,optionResults:o,rootErrors:d}=i;if(this.#n&&this.#t){let r=i.objToValidate;if(typeof r=="object"&&r!==null){let l=r[this.#n],u=this.#t.get(l);if(u){let p=await u.validateAsync(r,{...s,currentPropertyDescriptor:void 0,rootPropertyDescriptor:void 0});if(p.valid)return{valid:!0,object:p.object,getNestedErrors:a}}}}let y={objToValidate:i.objToValidate,minErrorsCount:Number.MAX_SAFE_INTEGER,resultingErrors:[]};for(let r=0;r<this.#e.length;r++){let l=await this.#e[r].validateAsync(y.objToValidate,{...s,currentPropertyDescriptor:void 0,rootPropertyDescriptor:void 0}),u=this.#s(l,r,o,t,y,a);if(u)return u}return d.push("value doesn't match any option in union schema"),{valid:!1,errors:y.resultingErrors,getNestedErrors:a}}createFromProps(e){return T.create(e)}required(e){return super.required(e)}optional(){return super.optional()}default(e){return super.default(e)}clearDefault(){return super.clearDefault()}brand(e){return super.brand(e)}readonly(){return super.readonly()}or(e){if(!(e instanceof c))throw new Error("schema must be an instance of the SchemaBuilder class");return this.createFromProps({...this.introspect(),options:[...this.#e,e]})}removeOption(e){if(typeof e!="number"||e<0||e>this.#e.length)throw new Error("index must be >= 0 and <= count of the options");return this.createFromProps({...this.introspect(),options:this.#e.filter((n,i)=>i!==e)})}removeFirstOption(){return this.removeOption(0)}reset(e){if(!(e instanceof c))throw new Error("schema must be an instance of the SchemaBuilder class");return this.createFromProps({...this.introspect(),options:[e]})}nullable(){return super.nullable()}notNullable(){return super.notNullable()}},E=T=>f.create({isRequired:!0,options:[T]});export{f as a,E as b};
2
+ //# sourceMappingURL=chunk-WQDYWDOE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/builders/UnionSchemaBuilder.ts"],"sourcesContent":["import type {\n ObjectSchemaBuilder,\n ObjectSchemaValidationResult\n} from './ObjectSchemaBuilder.js';\nimport {\n type BRAND,\n createHybridErrorArray,\n type InferType,\n type NestedValidationResult,\n type PropertyDescriptor,\n SchemaBuilder,\n SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\n\ntype UnionSchemaBuilderCreateProps<\n T extends readonly SchemaBuilder<any, any, any, any, any>[],\n R extends boolean = true\n> = Partial<ReturnType<UnionSchemaBuilder<T, R>['introspect']>>;\n\n/**\n * Mapped tuple type that converts a tuple of SchemaBuilder options into\n * a tuple of their corresponding validation results.\n * Union schema options get `UnionSchemaValidationResult` with recursive\n * `getNestedErrors` navigation; object schema options get\n * `ObjectSchemaValidationResult`; other types get `ValidationResult`.\n */\nexport type OptionValidationResults<\n TOptions extends readonly SchemaBuilder<any, any, any, any, any>[]\n> = {\n [K in keyof TOptions]: TOptions[K] extends UnionSchemaBuilder<\n infer UOptions extends readonly SchemaBuilder<\n any,\n any,\n any,\n any,\n any\n >[],\n any,\n any\n >\n ? UnionSchemaValidationResult<InferType<TOptions[K]>, UOptions>\n : TOptions[K] extends ObjectSchemaBuilder<any, any, any, any>\n ? ObjectSchemaValidationResult<InferType<TOptions[K]>, TOptions[K]>\n : ValidationResult<InferType<TOptions[K]>>;\n};\n\n/**\n * Validation result type returned by `UnionSchemaBuilder.validate()`.\n * Extends `ValidationResult` with:\n * - `getNestedErrors` for root-level union errors and per-branch validation results\n */\nexport type UnionSchemaValidationResult<\n T,\n TOptions extends readonly SchemaBuilder<any, any, any, any, any>[]\n> = ValidationResult<T> & {\n /**\n * Returns root-level union validation errors combined with\n * per-branch validation results.\n * The returned value has both `NestedValidationResult` properties\n * (`errors`, `isValid`, `descriptor`, `seenValue`) and tuple-indexed\n * branch results (`[0]`, `[1]`, etc.).\n */\n getNestedErrors(): OptionValidationResults<TOptions> &\n NestedValidationResult<any, any, any>;\n};\n\ntype SchemaArrayToUnion<\n TArr extends readonly SchemaBuilder<any, any, any, any, any>[]\n> = TArr['length'] extends 1\n ? InferType<TArr[0]>\n : TArr extends readonly [\n infer TFirst extends SchemaBuilder<any, any, any, any, any>,\n ...infer TRest extends SchemaBuilder<any, any, any, any, any>[]\n ]\n ? InferType<TFirst> | SchemaArrayToUnion<[...TRest]>\n : never;\n\ntype TakeBeforeIndex<\n TArr extends readonly SchemaBuilder<any, any, any, any, any>[],\n TIndex extends number\n> = TArr extends [\n ...infer TRest extends SchemaBuilder<any, any, any, any, any>[],\n infer _ extends SchemaBuilder<any, any, any, any, any>\n]\n ? TRest['length'] extends TIndex\n ? TRest\n : TakeBeforeIndex<TRest, TIndex>\n : never;\n\ntype TakeAfterIndex<\n TArr extends readonly SchemaBuilder<any, any, any, any, any>[],\n TIndex extends number,\n TAcc extends readonly SchemaBuilder<any, any, any, any, any>[] = []\n> = TArr extends [\n ...infer TRest extends SchemaBuilder<any, any, any, any, any>[],\n infer TLast extends SchemaBuilder<any, any, any, any, any>\n]\n ? TRest['length'] extends TIndex\n ? TAcc\n : TakeAfterIndex<TRest, TIndex, [TLast, ...TAcc]>\n : never;\n\ntype TakeExceptIndex<\n TArr extends readonly SchemaBuilder<any, any, any, any, any>[],\n TIndex extends number\n> = [...TakeBeforeIndex<TArr, TIndex>, ...TakeAfterIndex<TArr, TIndex>];\n\n/**\n * Union schema builder class. Allows to create schemas\n * containing alternatives. E.g. string | number | Date.\n * Use it when you want to define a schema for a value\n * that can be of different types. The type of the value\n * will be determined by the first schema that succeeds\n * validation. Any schema type can be supplied as variant.\n * Which means that you are not limited to primitive types and\n * can construct complex types as well, e.g. object | array.\n *\n * **NOTE** this class is exported only to give opportunity to extend it\n * by inheriting. It is not recommended to create an instance of this class\n * directly. Use {@link union | union()} function instead.\n *\n * @example\n * ```ts\n * const schema = union(string('foo')).or(string('bar'));\n * const result = schema.validate('foo');\n * // result.valid === true\n * // result.object === 'foo'\n * ```\n *\n * @example\n * ```ts\n * const schema = union(string('foo')).or(string('bar'));\n * const result = schema.validate('baz');\n * // result.valid === false\n * ```\n *\n * @example\n * ```ts\n * const schema = union(string('yes')).or(string('no')).or(number(0)).or(number(1));\n * // equals to 'yes' | 'no' | 0 | 1 in TS\n * const result = schema.validate('yes');\n * // result.valid === true\n * // result.object === 'yes'\n *\n * const result2 = schema.validate(0);\n * // result2.valid === true\n * // result2.object === 0\n *\n * const result3 = schema.validate('baz');\n * // result3.valid === false\n *\n * const result4 = schema.validate(2);\n * // result4.valid === false\n * ```\n *\n * @see {@link union}\n */\nexport class UnionSchemaBuilder<\n TOptions extends readonly SchemaBuilder<any, any, any, any, any>[],\n TRequired extends boolean = true,\n TNullable extends boolean = false,\n TExplicitType = undefined,\n THasDefault extends boolean = false,\n TExtensions = {}\n> extends SchemaBuilder<\n TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n #options!: TOptions;\n #discriminatorKey: string | null = null;\n #discriminatorMap: Map<\n string | number,\n SchemaBuilder<any, any, any, any, any>\n > | null = null;\n\n /**\n * @hidden\n */\n public static create(props: UnionSchemaBuilderCreateProps<any>) {\n return new UnionSchemaBuilder({\n type: 'union',\n ...props\n });\n }\n\n protected constructor(\n props: UnionSchemaBuilderCreateProps<TOptions, TRequired>\n ) {\n super(props as any);\n\n if (Array.isArray(props.options)) {\n this.#options = props.options;\n this.#detectDiscriminator();\n }\n }\n\n /**\n * Attempts to detect a discriminator property shared by all union options.\n * If all options are object schemas with a common required string/number\n * property that uses `equalsTo` with unique literal values, builds a Map\n * for O(1) dispatch.\n */\n #detectDiscriminator() {\n const options = this.#options;\n if (!options || options.length < 2) return;\n\n // All options must be object schemas\n const introspected: Array<{\n type: string;\n isRequired: boolean;\n properties?: Record<string, SchemaBuilder<any, any, any, any, any>>;\n [k: string]: any;\n }> = [];\n for (const option of options) {\n const info = option.introspect();\n if (info.type !== 'object') return;\n introspected.push(info);\n }\n\n // Find common property keys\n const firstProps = introspected[0].properties;\n if (!firstProps) return;\n\n for (const key of Object.keys(firstProps)) {\n const map = new Map<\n string | number,\n SchemaBuilder<any, any, any, any, any>\n >();\n let isDiscriminator = true;\n\n for (let i = 0; i < introspected.length; i++) {\n const props = introspected[i].properties;\n if (!props || !(key in props)) {\n isDiscriminator = false;\n break;\n }\n\n const propSchema = props[key];\n const propInfo = propSchema.introspect();\n\n // Must be a required string or number with equalsTo\n if (propInfo.isRequired !== true) {\n isDiscriminator = false;\n break;\n }\n\n const equalsTo = (propInfo as any).equalsTo;\n if (equalsTo === undefined || equalsTo === null) {\n isDiscriminator = false;\n break;\n }\n\n if (\n typeof equalsTo !== 'string' &&\n typeof equalsTo !== 'number'\n ) {\n isDiscriminator = false;\n break;\n }\n\n // Check for duplicate discriminator values\n if (map.has(equalsTo)) {\n isDiscriminator = false;\n break;\n }\n\n map.set(equalsTo, options[i]);\n }\n\n if (isDiscriminator && map.size === options.length) {\n this.#discriminatorKey = key;\n this.#discriminatorMap = map;\n return;\n }\n }\n }\n\n public introspect() {\n return {\n ...super.introspect(),\n /**\n * Array of schemas participating in the union.\n */\n options: this.#options,\n /**\n * When the union is a discriminated union (all branches are objects\n * sharing a required property with unique literal values), this is\n * the name of that property. `undefined` otherwise.\n */\n discriminatorPropertyName: this.#discriminatorKey ?? undefined\n };\n }\n\n /**\n * Null is a legitimate JavaScript value that a union option (e.g.\n * `NullSchemaBuilder`) may accept. Override the base-class behaviour so\n * that a required union does **not** reject `null` during pre-validation;\n * instead, each option gets the opportunity to validate it.\n * @override\n */\n protected override get isNullRequiredViolation(): boolean {\n return false;\n }\n\n /**\n * @inheritdoc\n */\n public hasType<T>(\n _notUsed?: T\n ): UnionSchemaBuilder<\n TOptions,\n true,\n TNullable,\n T,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * @inheritdoc\n */\n public clearHasType(): UnionSchemaBuilder<\n TOptions,\n TRequired,\n TNullable,\n undefined,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n #createValidationSetup(\n object: any,\n superResult: ReturnType<UnionSchemaBuilder<any>['preValidateSync']>\n ) {\n const {\n valid,\n transaction: preValidationTransaction,\n context: prevalidationContext,\n errors\n } = superResult;\n\n // Create a self-referencing property descriptor for the union root\n const selfDescriptor: PropertyDescriptor<any, any, any> = {\n [SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]: {\n setValue: () => false,\n getValue: (obj: any) => ({\n success: true,\n value: obj\n }),\n getSchema: () => this,\n parent: undefined,\n propertyName: undefined,\n toJsonPointer: () => ''\n }\n };\n\n // Root error state\n const rootErrors: string[] = [];\n\n const optionResults = createHybridErrorArray(\n [] as any[],\n () => object,\n () => rootErrors,\n () => selfDescriptor[SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR]\n );\n\n const getNestedErrors = (() => optionResults) as any;\n\n if (!valid) {\n rootErrors.push(\n ...(errors || []).map((e: any) => e.message || String(e))\n );\n return {\n needsOptionValidation: false as const,\n result: { valid, errors, getNestedErrors } as any\n };\n }\n\n const {\n object: { validatedObject: objToValidate }\n } = preValidationTransaction!;\n\n if (\n (typeof objToValidate === 'undefined' && !this.isRequired) ||\n (objToValidate === null && (!this.isRequired || this.isNullable))\n ) {\n return {\n needsOptionValidation: false as const,\n result: {\n valid: true,\n object: objToValidate,\n getNestedErrors\n } as any\n };\n }\n\n return {\n needsOptionValidation: true as const,\n objToValidate,\n prevalidationContext,\n preValidationTransaction: preValidationTransaction!,\n getNestedErrors,\n optionResults,\n rootErrors\n };\n }\n\n #processOptionResult(\n optionResult: any,\n index: number,\n optionResults: any,\n preValidationTransaction: any,\n state: {\n objToValidate: any;\n minErrorsCount: number;\n resultingErrors: any[];\n },\n getNestedErrors: any\n ): any | null {\n optionResults[index] = optionResult;\n\n if (optionResult.valid) {\n return {\n valid: true,\n object: optionResult.object as any,\n getNestedErrors\n };\n }\n\n const optErrors = optionResult.errors;\n if (\n Array.isArray(optErrors) &&\n optErrors.length > 0 &&\n optErrors.length < state.minErrorsCount\n ) {\n state.resultingErrors = optErrors as any;\n state.minErrorsCount = optErrors.length;\n }\n\n state.objToValidate =\n preValidationTransaction.rollback().validatedObject;\n return null;\n }\n\n /**\n * Performs synchronous validation of the union schema over `object`. {@inheritDoc SchemaBuilder.validate}\n */\n public validate(\n object: TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n context?: ValidationContext\n ): UnionSchemaValidationResult<\n TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n TOptions\n > {\n return super.validate(object, context) as any;\n }\n\n /**\n * Performs async validation of the union schema over `object`. {@inheritDoc SchemaBuilder.validateAsync}\n */\n public async validateAsync(\n object: TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n context?: ValidationContext\n ): Promise<\n UnionSchemaValidationResult<\n TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n TOptions\n >\n > {\n return super.validateAsync(object, context) as any;\n }\n\n /**\n * Performs synchronous validation of the union schema over `object`.\n * Throws if any preprocessor, validator, or error message provider returns a Promise.\n * @param context Optional `ValidationContext` settings.\n */\n protected _validate(\n object: TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n context?: ValidationContext\n ): UnionSchemaValidationResult<\n TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n TOptions\n > {\n // Fast path: skip preValidateSync + createValidationSetup when\n // there are no preprocessors/validators and context is default.\n if (\n this.canSkipPreValidation &&\n !context?.doNotStopOnFirstError &&\n !context?.rootPropertyDescriptor\n ) {\n // Required / optional check.\n // `undefined` is the canonical \"missing value\" signal — handle it\n // exactly as before (default, optional valid, required error).\n // `null` is a legitimate JavaScript value: for optional unions it is\n // valid without consulting options (original behaviour); for required\n // unions we fall through to option-checking so that a\n // NullSchemaBuilder option can accept it.\n if (typeof object === 'undefined') {\n if (this.hasDefault) {\n object = this.resolveDefaultValue();\n } else if (!this.isRequired) {\n return this.#fastResult(\n true,\n object,\n undefined,\n object,\n context\n );\n } else {\n return this.#fastResult(\n false,\n undefined,\n [\n {\n message: this.getValidationErrorMessageSync(\n this.requiredErrorMessage,\n object as any\n )\n }\n ],\n object,\n context\n );\n }\n } else if (\n object === null &&\n (!this.isRequired || this.isNullable)\n ) {\n // Optional union: null is valid without checking options.\n return this.#fastResult(\n true,\n object,\n undefined,\n object,\n context\n );\n }\n // null + required union: fall through to option checking below.\n\n // Discriminated union: O(1) lookup, no setup overhead\n if (this.#discriminatorKey && this.#discriminatorMap) {\n if (typeof object === 'object' && object !== null) {\n const discriminatorValue = (object as any)[\n this.#discriminatorKey\n ];\n const matchedSchema =\n this.#discriminatorMap.get(discriminatorValue);\n if (matchedSchema) {\n const optionResult = matchedSchema.validate(\n object as any\n );\n return this.#fastResult(\n optionResult.valid,\n optionResult.valid\n ? optionResult.object\n : undefined,\n optionResult.valid\n ? undefined\n : optionResult.errors,\n object,\n context\n );\n }\n // Discriminator value not in map — no option matches\n return this.#fastResult(\n false,\n undefined,\n [\n {\n message:\n \"value doesn't match any option in union schema\"\n }\n ],\n object,\n context\n );\n }\n }\n\n // Non-discriminated union: try options sequentially, no transaction overhead\n if (!this.#discriminatorKey) {\n const options = this.#options;\n let minErrorsCount = Number.MAX_SAFE_INTEGER;\n let resultingErrors: any[] = [];\n\n for (let i = 0; i < options.length; i++) {\n const optionResult = options[i].validate(object as any);\n if (optionResult.valid) {\n return this.#fastResult(\n true,\n optionResult.object,\n undefined,\n object,\n context\n );\n }\n\n const optErrors = optionResult.errors;\n if (\n Array.isArray(optErrors) &&\n optErrors.length > 0 &&\n optErrors.length < minErrorsCount\n ) {\n resultingErrors = optErrors as any;\n minErrorsCount = optErrors.length;\n }\n }\n\n return this.#fastResult(\n false,\n undefined,\n resultingErrors,\n object,\n context\n );\n }\n }\n\n return this.#validateFull(object, context) as any;\n }\n\n /**\n * Build a fast-path result with a lazy `getNestedErrors` that\n * defers to the full validation only when actually called.\n */\n #fastResult(\n valid: boolean,\n obj: any,\n errors: any[] | undefined,\n originalObject: any,\n context: ValidationContext | undefined\n ): any {\n const self = this;\n if (valid) {\n return {\n valid: true,\n object: obj,\n getNestedErrors() {\n return self\n .#validateFull(originalObject, context)\n .getNestedErrors();\n }\n };\n }\n return {\n valid: false,\n errors,\n getNestedErrors() {\n return self\n .#validateFull(originalObject, context)\n .getNestedErrors();\n }\n };\n }\n\n #validateFull(\n object: any,\n context?: ValidationContext\n ): UnionSchemaValidationResult<any, any> {\n const setup = this.#createValidationSetup(\n object,\n this.preValidateSync(object, context)\n );\n\n if (!setup.needsOptionValidation) return setup.result;\n\n const {\n prevalidationContext,\n preValidationTransaction,\n getNestedErrors,\n optionResults,\n rootErrors\n } = setup;\n\n // Fast path: discriminated union with O(1) lookup\n if (this.#discriminatorKey && this.#discriminatorMap) {\n const obj = setup.objToValidate;\n if (typeof obj === 'object' && obj !== null) {\n const discriminatorValue = obj[this.#discriminatorKey];\n const matchedSchema =\n this.#discriminatorMap.get(discriminatorValue);\n if (matchedSchema) {\n const optionResult = matchedSchema.validate(obj, {\n ...prevalidationContext,\n currentPropertyDescriptor: undefined,\n rootPropertyDescriptor: undefined\n } as any);\n if (optionResult.valid) {\n return {\n valid: true,\n object: optionResult.object as any,\n getNestedErrors\n };\n }\n }\n }\n }\n\n const state = {\n objToValidate: setup.objToValidate,\n minErrorsCount: Number.MAX_SAFE_INTEGER,\n resultingErrors: [] as any[]\n };\n\n for (let i = 0; i < this.#options.length; i++) {\n const optionResult = this.#options[i].validate(\n state.objToValidate,\n {\n ...prevalidationContext,\n currentPropertyDescriptor: undefined,\n rootPropertyDescriptor: undefined\n } as any\n );\n\n const earlyReturn = this.#processOptionResult(\n optionResult,\n i,\n optionResults,\n preValidationTransaction,\n state,\n getNestedErrors\n );\n if (earlyReturn) return earlyReturn;\n }\n\n rootErrors.push(\"value doesn't match any option in union schema\");\n\n return {\n valid: false,\n errors: state.resultingErrors,\n getNestedErrors\n };\n }\n\n /**\n * Performs async validation of the union schema over `object`.\n * Supports async preprocessors, validators, and error message providers.\n * @param context Optional `ValidationContext` settings.\n */\n protected async _validateAsync(\n object: TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n context?: ValidationContext\n ): Promise<\n UnionSchemaValidationResult<\n TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType,\n TOptions\n >\n > {\n const setup = this.#createValidationSetup(\n object,\n await super.preValidateAsync(object, context)\n );\n\n if (!setup.needsOptionValidation) return setup.result;\n\n const {\n prevalidationContext,\n preValidationTransaction,\n getNestedErrors,\n optionResults,\n rootErrors\n } = setup;\n\n // Fast path: discriminated union with O(1) lookup\n if (this.#discriminatorKey && this.#discriminatorMap) {\n const obj = setup.objToValidate;\n if (typeof obj === 'object' && obj !== null) {\n const discriminatorValue = obj[this.#discriminatorKey];\n const matchedSchema =\n this.#discriminatorMap.get(discriminatorValue);\n if (matchedSchema) {\n const optionResult = await matchedSchema.validateAsync(\n obj,\n {\n ...prevalidationContext,\n currentPropertyDescriptor: undefined,\n rootPropertyDescriptor: undefined\n } as any\n );\n if (optionResult.valid) {\n return {\n valid: true,\n object: optionResult.object as any,\n getNestedErrors\n };\n }\n }\n }\n }\n\n const state = {\n objToValidate: setup.objToValidate,\n minErrorsCount: Number.MAX_SAFE_INTEGER,\n resultingErrors: [] as any[]\n };\n\n for (let i = 0; i < this.#options.length; i++) {\n const optionResult = await this.#options[i].validateAsync(\n state.objToValidate,\n {\n ...prevalidationContext,\n currentPropertyDescriptor: undefined,\n rootPropertyDescriptor: undefined\n } as any\n );\n\n const earlyReturn = this.#processOptionResult(\n optionResult,\n i,\n optionResults,\n preValidationTransaction,\n state,\n getNestedErrors\n );\n if (earlyReturn) return earlyReturn;\n }\n\n rootErrors.push(\"value doesn't match any option in union schema\");\n\n return {\n valid: false,\n errors: state.resultingErrors,\n getNestedErrors\n };\n }\n\n protected createFromProps<\n T extends readonly SchemaBuilder<any, any, any, any, any>[],\n TReq extends boolean\n >(props: UnionSchemaBuilderCreateProps<T, TReq>): this {\n return UnionSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): UnionSchemaBuilder<\n TOptions,\n true,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.required(errorMessage);\n }\n\n /**\n * @hidden\n */\n public optional(): UnionSchemaBuilder<\n TOptions,\n false,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.optional();\n }\n\n /**\n * @hidden\n */\n public default(\n value:\n | (TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType)\n | (() => TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType)\n ): UnionSchemaBuilder<\n TOptions,\n true,\n TNullable,\n TExplicitType,\n true,\n TExtensions\n > &\n TExtensions {\n return super.default(value as any) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): UnionSchemaBuilder<\n TOptions,\n TRequired,\n TNullable,\n TExplicitType,\n false,\n TExtensions\n > &\n TExtensions {\n return super.clearDefault() as any;\n }\n\n /**\n * @hidden\n */\n public brand<TBrand extends string | symbol>(\n _name?: TBrand\n ): UnionSchemaBuilder<\n TOptions,\n TRequired,\n TNullable,\n (TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType) & { readonly [K in BRAND]: TBrand },\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.brand(_name);\n }\n\n /**\n * @hidden\n */\n public readonly(): UnionSchemaBuilder<\n TOptions,\n TRequired,\n TNullable,\n Readonly<\n TExplicitType extends undefined\n ? SchemaArrayToUnion<TOptions>\n : TExplicitType\n >,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * Adds a new schema option described by `schema`.\n * schema must be an instance of `SchemaBuilder` class ancestor.\n * @param schema schema to be added as an option.\n */\n public or<T extends SchemaBuilder<any, any, any, any, any>>(\n schema: T\n ): UnionSchemaBuilder<\n [...TOptions, T],\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n if (!(schema instanceof SchemaBuilder)) {\n throw new Error(\n 'schema must be an instance of the SchemaBuilder class'\n );\n }\n return this.createFromProps({\n ...this.introspect(),\n options: [...this.#options, schema]\n } as any) as any;\n }\n\n /**\n * Removes option by its `index`. If `index` is out of bounds,\n * an error is thrown.\n * @param index index of the option, starting from `0`.\n */\n public removeOption<T extends number>(\n index: T\n ): UnionSchemaBuilder<\n TakeExceptIndex<TOptions, T>,\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n if (\n typeof index !== 'number' ||\n index < 0 ||\n index > this.#options.length\n ) {\n throw new Error('index must be >= 0 and <= count of the options');\n }\n return this.createFromProps({\n ...this.introspect(),\n options: this.#options.filter((_v, i) => i !== index)\n } as any) as any;\n }\n\n /**\n * Removes first option from the union schema.\n */\n public removeFirstOption(): TOptions extends [\n infer _,\n ...infer TRest extends SchemaBuilder<any, any, any, any, any>[]\n ]\n ? UnionSchemaBuilder<\n TRest,\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions\n : never {\n return this.removeOption(0) as any;\n }\n\n /**\n * Removes all options and replaces them by single `schema` option.\n * Equivalent to `union(schema)` function, but could be useful in some cases.\n * @param schema schema to be added as a single option to the new schema.\n */\n public reset<T extends SchemaBuilder<any, any, any, any, any>>(\n schema: T\n ): UnionSchemaBuilder<\n [T],\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n if (!(schema instanceof SchemaBuilder)) {\n throw new Error(\n 'schema must be an instance of the SchemaBuilder class'\n );\n }\n return this.createFromProps({\n ...this.introspect(),\n options: [schema]\n } as any) as any;\n }\n\n /**\n * @hidden\n */\n public nullable(): UnionSchemaBuilder<\n TOptions,\n TRequired,\n true,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.nullable() as any;\n }\n\n /**\n * @hidden\n */\n public notNullable(): UnionSchemaBuilder<\n TOptions,\n TRequired,\n false,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n}\n\n/**\n * Creates a union schema.\n * @param schema required and will be considered as a first option for the union schema.\n */\nexport const union = <T extends SchemaBuilder<any, any, any, any, any>>(\n schema: T\n) =>\n UnionSchemaBuilder.create({\n isRequired: true,\n options: [schema]\n }) as UnionSchemaBuilder<[T]>;\n"],"mappings":"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","names":["UnionSchemaBuilder","_UnionSchemaBuilder","SchemaBuilder","#options","#discriminatorKey","#discriminatorMap","props","#detectDiscriminator","options","introspected","option","info","firstProps","key","map","isDiscriminator","i","propInfo","equalsTo","_notUsed","#createValidationSetup","object","superResult","valid","preValidationTransaction","prevalidationContext","errors","selfDescriptor","SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR","obj","rootErrors","optionResults","createHybridErrorArray","getNestedErrors","e","objToValidate","#processOptionResult","optionResult","index","state","optErrors","context","#fastResult","discriminatorValue","matchedSchema","minErrorsCount","resultingErrors","#validateFull","originalObject","self","setup","earlyReturn","errorMessage","value","_name","schema","_v","union"]}
@@ -0,0 +1,2 @@
1
+ import{f as o}from"./chunk-3JMDGYDT.js";var l=class a extends o{#t;#T=function(){return`is expected to have a length of at least ${this.#t} characters`};#n=this.#T;#i;#g=function(){return`is expected to have a length of no more than ${this.#i} characters`};#l=this.#g;#s;#c=function(e){return`is expected to be equal to "${this.#s}" but saw "${e}"`};#o=this.#c;#e;#m=function(){return`is expected to start with "${this.#e}"`};#u=this.#m;#r;#E=function(){return`is expected to end with "${this.#r}"`};#d=this.#E;#a;#f=function(){return`is expected to match the pattern ${this.#a}`};#h=this.#f;static create(e){return new a({type:"string",...e})}constructor(e){super(e),typeof e.minLength=="number"&&(this.#t=e.minLength),this.#n=this.assureValidationErrorMessageProvider(e.minLengthValidationErrorMessageProvider,this.#T),typeof e.maxLength=="number"&&(this.#i=e.maxLength),this.#l=this.assureValidationErrorMessageProvider(e.maxLengthValidationErrorMessageProvider,this.#g),(typeof e.equalsTo=="string"||typeof e.equalsTo>"u")&&(this.#s=e.equalsTo),this.#o=this.assureValidationErrorMessageProvider(e.equalsToValidationErrorMessageProvider,this.#c),typeof e.startsWith=="string"&&e.startsWith.length>0&&(this.#e=e.startsWith),this.#u=this.assureValidationErrorMessageProvider(e.startsWithValidationErrorMessageProvider,this.#m),typeof e.endsWith=="string"&&e.endsWith.length>0&&(this.#r=e.endsWith),this.#d=this.assureValidationErrorMessageProvider(e.endsWithValidationErrorMessageProvider,this.#E),e.matches instanceof RegExp&&(this.#a=e.matches),this.#h=this.assureValidationErrorMessageProvider(e.matchesValidationErrorMessageProvider,this.#f)}introspect(){return{...super.introspect(),minLength:this.#t,minLengthValidationErrorMessageProvider:this.#n,maxLength:this.#i,maxLengthValidationErrorMessageProvider:this.#l,equalsTo:this.#s,equalsToValidationErrorMessageProvider:this.#o,startsWith:this.#e,startsWithValidationErrorMessageProvider:this.#u,endsWith:this.#r,endsWithValidationErrorMessageProvider:this.#d,matches:this.#a,matchesValidationErrorMessageProvider:this.#h,preprocessors:this.preprocessors,validators:this.validators}}hasType(e){return this.createFromProps({...this.introspect()})}clearHasType(){return this.createFromProps({...this.introspect()})}#R(e){return typeof e!="string"?{message:`expected type string, but saw ${typeof e}`}:typeof this.#s<"u"&&e!==this.#s?{provider:this.#o}:typeof this.#e=="string"&&this.#e.length>0&&!e.startsWith(this.#e)?{provider:this.#u}:typeof this.#r=="string"&&this.#r.length>0&&!e.endsWith(this.#r)?{provider:this.#d}:typeof this.#t<"u"&&e.length<this.#t?{provider:this.#n}:typeof this.#i<"u"&&e.length>this.#i?{provider:this.#l}:this.#a instanceof RegExp&&!this.#a.test(e)?{provider:this.#h}:null}#p(e){let{valid:r,transaction:t,errors:i}=e;if(!r)return{done:!0,result:{valid:r,errors:i}};let{object:{validatedObject:s}}=t;if(typeof s>"u"&&!this.isRequired||s===null&&(!this.isRequired||this.isNullable))return{done:!0,result:{valid:!0,object:s}};let n=this.#R(s);return n?"message"in n?{done:!0,result:{valid:!1,errors:[{message:n.message}]}}:{done:!1,provider:n.provider,objToValidate:s}:{done:!0,result:{valid:!0,object:s}}}validate(e,r){return super.validate(e,r)}async validateAsync(e,r){return super.validateAsync(e,r)}_validate(e,r){if(this.canSkipPreValidation){if(typeof e>"u"||e===null)if(typeof e>"u"&&this.hasDefault)e=this.resolveDefaultValue();else return!this.isRequired||e===null&&this.isNullable?{valid:!0,object:e}:{valid:!1,errors:[{message:this.getValidationErrorMessageSync(this.requiredErrorMessage,e)}]};let i=this.#R(e);return i?"message"in i?{valid:!1,errors:[{message:i.message}]}:{valid:!1,errors:[{message:this.getValidationErrorMessageSync(i.provider,e)}]}:{valid:!0,object:e}}let t=this.#p(this.preValidateSync(e,r));return t.done?t.result:{valid:!1,errors:[{message:this.getValidationErrorMessageSync(t.provider,t.objToValidate)}]}}async _validateAsync(e,r){let t=this.#p(await super.preValidateAsync(e,r));return t.done?t.result:{valid:!1,errors:[{message:await this.getValidationErrorMessage(t.provider,t.objToValidate)}]}}createFromProps(e){return a.create(e)}equals(e,r){if(typeof e!="string")throw new Error("string expected");return this.createFromProps({...this.introspect(),equalsTo:e,equalsToValidationErrorMessageProvider:r})}clearEquals(){return this.createFromProps({...this.introspect(),equalsTo:void 0})}nullable(){return super.nullable()}notNullable(){return super.notNullable()}required(e){return super.required(e)}optional(){return super.optional()}default(e){return super.default(e)}clearDefault(){return super.clearDefault()}brand(e){return super.brand(e)}readonly(){return super.readonly()}minLength(e,r){if(typeof e!="number")throw new Error("length must be a number");return this.createFromProps({...this.introspect(),minLength:e,minLengthValidationErrorMessageProvider:r})}clearMinLength(){let e=this.introspect();return delete e.minLength,this.createFromProps({...e})}maxLength(e,r){if(typeof e!="number")throw new Error("length must be a number");return this.createFromProps({...this.introspect(),maxLength:e,maxLengthValidationErrorMessageProvider:r})}clearMaxLength(){let e=this.introspect();return delete e.maxLength,this.createFromProps({...e})}startsWith(e,r){if(typeof e!="string"||!e)throw new Error("non empty string expected");return this.createFromProps({...this.introspect(),startsWith:e,startsWithValidationErrorMessageProvider:r})}clearStartsWith(){let e=this.introspect();return delete e.startsWith,this.createFromProps({...e})}endsWith(e,r){if(typeof e!="string"||!e)throw new Error("non empty string expected");return this.createFromProps({...this.introspect(),endsWith:e,endsWithValidationErrorMessageProvider:r})}clearEndsWith(){let e=this.introspect();return delete e.endsWith,this.createFromProps({...e})}matches(e,r){if(!(e instanceof RegExp))throw new Error("regexp expected");return this.createFromProps({...this.introspect(),matches:e,matchesValidationErrorMessageProvider:r})}clearMatches(){let e=this.introspect();return delete e.matches,this.createFromProps({...e})}};function d(a,e){return typeof a=="string"?l.create({isRequired:!0,equalsTo:a,equalsToValidationErrorMessageProvider:e}):l.create({isRequired:!0})}export{l as a,d as b};
2
+ //# sourceMappingURL=chunk-YQZHDMRF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/builders/StringSchemaBuilder.ts"],"sourcesContent":["import {\n type BRAND,\n type PreprocessorEntry,\n SchemaBuilder,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult,\n type ValidatorEntry\n} from './SchemaBuilder.js';\n\ntype StringSchemaBuilderCreateProps<\n T = string,\n R extends boolean = true\n> = Partial<ReturnType<StringSchemaBuilder<T, R>['introspect']>>;\n\n/**\n * Allows to define a schema for a string. It can be: required or optional,\n * restricted to be equal to a certain value, restricted to have a certain\n * length, restricted to start with a certain value, restricted to end with\n * a certain value, restricted to match a certain regular expression.\n *\n * **NOTE** this class is exported only to give opportunity to extend it\n * by inheriting. It is not recommended to create an instance of this class\n * directly. Use {@link string | string()} function instead.\n *\n * @example ```ts\n * const schema = string().equals('hello');\n * const result = schema.validate('hello');\n * // result.valid === true\n * // result.object === 'hello'\n * ```\n *\n * @example ```ts\n * const schema = string().equals('hello');\n * const result = schema.validate('world');\n * // result.valid === false\n * // result.errors[0].message === \"is expected to be equal to 'hello'\"\n * ```\n *\n * @example ```ts\n * const schema = string().minLength(5);\n * const result = schema.validate('hello');\n * // result.valid === true\n * // result.object === 'hello'\n * ```\n *\n * @example ```ts\n * const schema = string().minLength(5);\n * const result = schema.validate('hi');\n * // result.valid === false\n * // result.errors[0].message === 'is expected to have a length of at least 5'\n * ```\n *\n * @example ```ts\n * const schema = string().minLength(2).maxLength(5);\n * const result = schema.validate('yes');\n * // result.valid === true\n * // result.object === 'yes'\n * ```\n *\n * @example ```ts\n * const schema = string('no');\n * const result = schema.validate('yes');\n * // result.valid === false\n * // result.errors[0].message === \"is expected to be equal to 'no'\"\n * ```\n *\n * @see {@link string}\n */\nexport class StringSchemaBuilder<\n TResult = string,\n TRequired extends boolean = true,\n TNullable extends boolean = false,\n THasDefault extends boolean = false,\n TExtensions = {}\n> extends SchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n #minLength?: number;\n #defaultMinLengthErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = function (this: StringSchemaBuilder) {\n return `is expected to have a length of at least ${this.#minLength} characters`;\n };\n #minLengthErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = this.#defaultMinLengthErrorMessageProvider;\n\n #maxLength?: number;\n #defaultMaxLengthErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = function (this: StringSchemaBuilder) {\n return `is expected to have a length of no more than ${this.#maxLength} characters`;\n };\n #maxLengthErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = this.#defaultMaxLengthErrorMessageProvider;\n\n #equalsTo?: string;\n #defaultEqualsToErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = function (this: StringSchemaBuilder, seenValue?: TResult) {\n return `is expected to be equal to \"${this.#equalsTo}\" but saw \"${seenValue}\"`;\n };\n #equalsToErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = this.#defaultEqualsToErrorMessageProvider;\n\n #startsWith?: string;\n #defaultStartsWithErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = function (this: StringSchemaBuilder) {\n return `is expected to start with \"${this.#startsWith}\"`;\n };\n #startsWithErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = this.#defaultStartsWithErrorMessageProvider;\n\n #endsWith?: string;\n #defaultEndsWithErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = function (this: StringSchemaBuilder) {\n return `is expected to end with \"${this.#endsWith}\"`;\n };\n #endsWithErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = this.#defaultEndsWithErrorMessageProvider;\n\n #matches?: RegExp;\n #defaultMatchesErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = function (this: StringSchemaBuilder) {\n return `is expected to match the pattern ${this.#matches}`;\n };\n #matchesErrorMessageProvider: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n > = this.#defaultMatchesErrorMessageProvider;\n\n /**\n * @hidden\n */\n public static create(props: StringSchemaBuilderCreateProps) {\n return new StringSchemaBuilder({\n type: 'string',\n ...props\n });\n }\n\n protected constructor(props: StringSchemaBuilderCreateProps) {\n super(props as any);\n\n if (typeof props.minLength === 'number') {\n this.#minLength = props.minLength;\n }\n\n this.#minLengthErrorMessageProvider =\n this.assureValidationErrorMessageProvider(\n props.minLengthValidationErrorMessageProvider,\n this.#defaultMinLengthErrorMessageProvider\n );\n\n if (typeof props.maxLength === 'number') {\n this.#maxLength = props.maxLength;\n }\n\n this.#maxLengthErrorMessageProvider =\n this.assureValidationErrorMessageProvider(\n props.maxLengthValidationErrorMessageProvider,\n this.#defaultMaxLengthErrorMessageProvider\n );\n\n if (\n typeof props.equalsTo === 'string' ||\n typeof props.equalsTo === 'undefined'\n ) {\n this.#equalsTo = props.equalsTo;\n }\n\n this.#equalsToErrorMessageProvider =\n this.assureValidationErrorMessageProvider(\n props.equalsToValidationErrorMessageProvider,\n this.#defaultEqualsToErrorMessageProvider\n );\n\n if (\n typeof props.startsWith === 'string' &&\n props.startsWith.length > 0\n ) {\n this.#startsWith = props.startsWith;\n }\n\n this.#startsWithErrorMessageProvider =\n this.assureValidationErrorMessageProvider(\n props.startsWithValidationErrorMessageProvider,\n this.#defaultStartsWithErrorMessageProvider\n );\n\n if (typeof props.endsWith === 'string' && props.endsWith.length > 0) {\n this.#endsWith = props.endsWith;\n }\n\n this.#endsWithErrorMessageProvider =\n this.assureValidationErrorMessageProvider(\n props.endsWithValidationErrorMessageProvider,\n this.#defaultEndsWithErrorMessageProvider\n );\n\n if (props.matches instanceof RegExp) {\n this.#matches = props.matches;\n }\n\n this.#matchesErrorMessageProvider =\n this.assureValidationErrorMessageProvider(\n props.matchesValidationErrorMessageProvider,\n this.#defaultMatchesErrorMessageProvider\n );\n }\n\n public introspect() {\n return {\n ...super.introspect(),\n /**\n * Min length of the string (if defined).\n */\n minLength: this.#minLength,\n\n /**\n * Min length validation error message provider.\n * If not provided, default error message will be used.\n */\n minLengthValidationErrorMessageProvider:\n this.#minLengthErrorMessageProvider,\n\n /**\n * Max length of the string (if defined).\n */\n maxLength: this.#maxLength,\n\n /**\n * Max length validation error message provider.\n * If not provided, default error message will be used.\n */\n maxLengthValidationErrorMessageProvider:\n this.#maxLengthErrorMessageProvider,\n\n /**\n * If set, restrict object to be equal to a certain value.\n */\n equalsTo: this.#equalsTo,\n\n /**\n * Equals validation error message provider.\n * If not provided, default error message will be used.\n */\n equalsToValidationErrorMessageProvider:\n this.#equalsToErrorMessageProvider,\n\n /**\n * If set, restrict string to start with a certain value.\n */\n startsWith: this.#startsWith,\n\n /**\n * Starts with validation error message provider.\n * If not provided, default error message will be used.\n */\n startsWithValidationErrorMessageProvider:\n this.#startsWithErrorMessageProvider,\n\n /**\n * If set, restrict string to end with a certain value.\n */\n endsWith: this.#endsWith,\n\n /**\n * Ends with validation error message provider.\n * If not provided, default error message will be used.\n */\n endsWithValidationErrorMessageProvider:\n this.#endsWithErrorMessageProvider,\n\n /**\n * If set, restrict string to match a certain regular expression.\n */\n matches: this.#matches,\n\n /**\n * Matches validation error message provider.\n * If not provided, default error message will be used.\n */\n matchesValidationErrorMessageProvider:\n this.#matchesErrorMessageProvider,\n\n /**\n * Array of preprocessor functions\n */\n preprocessors: this.preprocessors as PreprocessorEntry<TResult>[],\n\n /**\n * Array of validator functions\n */\n validators: this.validators as ValidatorEntry<TResult>[]\n };\n }\n\n /**\n * @inheritdoc\n */\n public hasType<T>(\n _notUsed?: T\n ): StringSchemaBuilder<T, true, TNullable, THasDefault, TExtensions> &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * @inheritdoc\n */\n public clearHasType(): StringSchemaBuilder<\n string,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n #getConstraintViolation(\n objToValidate: any\n ): { message: string } | { provider: any } | null {\n if (typeof objToValidate !== 'string') {\n return {\n message: `expected type string, but saw ${typeof objToValidate}`\n };\n }\n\n if (\n typeof this.#equalsTo !== 'undefined' &&\n objToValidate !== this.#equalsTo\n ) {\n return { provider: this.#equalsToErrorMessageProvider };\n }\n\n if (\n typeof this.#startsWith === 'string' &&\n this.#startsWith.length > 0 &&\n !objToValidate.startsWith(this.#startsWith)\n ) {\n return { provider: this.#startsWithErrorMessageProvider };\n }\n\n if (\n typeof this.#endsWith === 'string' &&\n this.#endsWith.length > 0 &&\n !objToValidate.endsWith(this.#endsWith)\n ) {\n return { provider: this.#endsWithErrorMessageProvider };\n }\n\n if (typeof this.#minLength !== 'undefined') {\n if (objToValidate.length < this.#minLength)\n return { provider: this.#minLengthErrorMessageProvider };\n }\n\n if (typeof this.#maxLength !== 'undefined') {\n if (objToValidate.length > this.#maxLength)\n return { provider: this.#maxLengthErrorMessageProvider };\n }\n\n if (this.#matches instanceof RegExp) {\n if (!this.#matches.test(objToValidate)) {\n return { provider: this.#matchesErrorMessageProvider };\n }\n }\n\n return null;\n }\n\n #buildResult(\n superResult: ReturnType<StringSchemaBuilder['preValidateSync']>\n ):\n | { done: true; result: ValidationResult<TResult> }\n | {\n done: false;\n provider: any;\n objToValidate: any;\n } {\n const {\n valid,\n transaction: preValidationTransaction,\n errors\n } = superResult;\n\n if (!valid) {\n return { done: true, result: { valid, errors } };\n }\n\n const {\n object: { validatedObject: objToValidate }\n } = preValidationTransaction!;\n\n if (\n (typeof objToValidate === 'undefined' && !this.isRequired) ||\n (objToValidate === null && (!this.isRequired || this.isNullable))\n ) {\n return {\n done: true,\n result: { valid: true, object: objToValidate }\n };\n }\n\n const violation = this.#getConstraintViolation(objToValidate);\n\n if (!violation) {\n return {\n done: true,\n result: { valid: true, object: objToValidate as TResult }\n };\n }\n\n if ('message' in violation) {\n return {\n done: true,\n result: {\n valid: false,\n errors: [{ message: violation.message }]\n }\n };\n }\n\n return {\n done: false,\n provider: violation.provider,\n objToValidate\n };\n }\n\n /** {@inheritDoc SchemaBuilder.validate} */\n public validate(\n object: TResult,\n context?: ValidationContext\n ): ValidationResult<TResult> {\n return super.validate(object, context) as ValidationResult<TResult>;\n }\n\n /** {@inheritDoc SchemaBuilder.validateAsync} */\n public async validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<ValidationResult<TResult>> {\n return super.validateAsync(object, context) as Promise<\n ValidationResult<TResult>\n >;\n }\n\n /**\n * Performs synchronous validation of string schema over `object`.\n * Throws if any preprocessor, validator, or error message provider returns a Promise.\n * @param context Optional `ValidationContext` settings.\n */\n protected _validate(\n object: TResult,\n context?: ValidationContext\n ): ValidationResult<TResult> {\n // Fast path: no preprocessors or custom validators — skip preValidateSync entirely\n if (this.canSkipPreValidation) {\n // Required / optional check\n if (typeof object === 'undefined' || object === null) {\n if (typeof object === 'undefined' && this.hasDefault) {\n object = this.resolveDefaultValue();\n } else if (\n !this.isRequired ||\n (object === null && this.isNullable)\n ) {\n return { valid: true, object: object };\n } else {\n return {\n valid: false,\n errors: [\n {\n message: this.getValidationErrorMessageSync(\n this.requiredErrorMessage,\n object\n )\n }\n ]\n };\n }\n }\n\n const violation = this.#getConstraintViolation(object);\n\n if (!violation) {\n return { valid: true, object: object as TResult };\n }\n\n if ('message' in violation) {\n return {\n valid: false,\n errors: [{ message: violation.message }]\n };\n }\n\n return {\n valid: false,\n errors: [\n {\n message: this.getValidationErrorMessageSync(\n violation.provider,\n object as TResult\n )\n }\n ]\n };\n }\n\n const r = this.#buildResult(this.preValidateSync(object, context));\n if (r.done) return r.result;\n return {\n valid: false,\n errors: [\n {\n message: this.getValidationErrorMessageSync(\n r.provider,\n r.objToValidate as TResult\n )\n }\n ]\n };\n }\n\n /**\n * Performs async validation of string schema over `object`.\n * Supports async preprocessors, validators, and error message providers.\n * @param context Optional `ValidationContext` settings.\n */\n protected async _validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<ValidationResult<TResult>> {\n const r = this.#buildResult(\n await super.preValidateAsync(object, context)\n );\n if (r.done) return r.result;\n return {\n valid: false,\n errors: [\n {\n message: await this.getValidationErrorMessage(\n r.provider,\n r.objToValidate as TResult\n )\n }\n ]\n };\n }\n\n protected createFromProps<T, TReq extends boolean>(\n props: StringSchemaBuilderCreateProps<T, TReq>\n ): this {\n return StringSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * Restricts string to be equal to `value`.\n */\n public equals<T extends string>(\n value: T,\n /**\n * Custom error message provider.\n */\n errorMessage?: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n >\n ) {\n if (typeof value !== 'string') throw new Error('string expected');\n return this.createFromProps({\n ...this.introspect(),\n equalsTo: value,\n equalsToValidationErrorMessageProvider: errorMessage\n }) as any as StringSchemaBuilder<\n T,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions;\n }\n\n /**\n * Cancels `equals()` call.\n */\n public clearEquals(): StringSchemaBuilder<\n string,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect(),\n equalsTo: undefined\n }) as any;\n }\n\n /**\n * @hidden\n */\n public nullable(): StringSchemaBuilder<\n TResult,\n TRequired,\n true,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.nullable() as any;\n }\n\n /**\n * @hidden\n */\n public notNullable(): StringSchemaBuilder<\n TResult,\n TRequired,\n false,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): StringSchemaBuilder<TResult, true, TNullable, THasDefault, TExtensions> &\n TExtensions {\n return super.required(errorMessage);\n }\n\n /**\n * @hidden\n */\n public optional(): StringSchemaBuilder<\n TResult,\n false,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.optional();\n }\n\n /**\n * @hidden\n */\n public default(\n value: TResult | (() => TResult)\n ): StringSchemaBuilder<TResult, true, TNullable, true, TExtensions> &\n TExtensions {\n return super.default(value) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): StringSchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n false,\n TExtensions\n > &\n TExtensions {\n return super.clearDefault() as any;\n }\n\n /**\n * @hidden\n */\n public brand<TBrand extends string | symbol>(\n _name?: TBrand\n ): StringSchemaBuilder<\n TResult & { readonly [K in BRAND]: TBrand },\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.brand(_name);\n }\n\n /**\n * Marks the inferred type as `Readonly<string>`. Since strings are\n * already immutable this is an identity operation, but it sets the\n * `isReadonly` introspection flag for tooling consistency.\n *\n * @see {@link SchemaBuilder.readonly}\n */\n public readonly(): StringSchemaBuilder<\n Readonly<TResult>,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * Set minimal length of the valid value for schema.\n * @param length minimum string length\n */\n public minLength(\n length: number,\n /**\n * Custom error message provider.\n */\n errorMessage?: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n >\n ): StringSchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n if (typeof length !== 'number')\n throw new Error('length must be a number');\n return this.createFromProps({\n ...this.introspect(),\n minLength: length,\n minLengthValidationErrorMessageProvider: errorMessage\n }) as any;\n }\n\n /**\n * Cancel `minLength()` call.\n */\n public clearMinLength(): StringSchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n const schema = this.introspect();\n delete schema.minLength;\n return this.createFromProps({\n ...schema\n }) as any;\n }\n\n /**\n * Set maximal length of the valid value for schema.\n * @param length maximum string length\n */\n public maxLength(\n length: number,\n /**\n * Custom error message provider.\n */\n errorMessage?: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n >\n ): StringSchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n if (typeof length !== 'number')\n throw new Error('length must be a number');\n return this.createFromProps({\n ...this.introspect(),\n maxLength: length,\n maxLengthValidationErrorMessageProvider: errorMessage\n }) as any;\n }\n\n /**\n * Cancel `maxLength()` call.\n */\n public clearMaxLength(): StringSchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n const schema = this.introspect();\n delete schema.maxLength;\n return this.createFromProps({\n ...schema\n }) as any;\n }\n\n /**\n * Restricts string to start with `val`.\n */\n public startsWith<T extends string>(\n val: T,\n /**\n * Custom error message provider.\n */\n errorMessage?: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n >\n ): StringSchemaBuilder<\n TResult extends string ? `${T}${TResult}` : TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n if (typeof val !== 'string' || !val)\n throw new Error('non empty string expected');\n return this.createFromProps({\n ...this.introspect(),\n startsWith: val,\n startsWithValidationErrorMessageProvider: errorMessage\n }) as any;\n }\n\n /**\n * Cancels `startsWith()` call.\n */\n public clearStartsWith(): StringSchemaBuilder<\n string,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n const schema = this.introspect();\n delete schema.startsWith;\n return this.createFromProps({\n ...schema\n }) as any;\n }\n\n /**\n * Restricts string to end with `val`.\n */\n public endsWith<T extends string>(\n val: T,\n /**\n * Custom error message provider.\n */\n errorMessage?: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n >\n ): StringSchemaBuilder<\n TResult extends string ? `${TResult}${T}` : TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n if (typeof val !== 'string' || !val)\n throw new Error('non empty string expected');\n return this.createFromProps({\n ...this.introspect(),\n endsWith: val,\n endsWithValidationErrorMessageProvider: errorMessage\n }) as any;\n }\n\n /**\n * Cancels `endsWith()` call.\n */\n public clearEndsWith(): StringSchemaBuilder<\n string,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n const schema = this.introspect();\n delete schema.endsWith;\n return this.createFromProps({\n ...schema\n }) as any;\n }\n\n /**\n * Restricts string to match `regexp`.\n * @param regexp regular expression pattern to match against\n */\n public matches(\n regexp: RegExp,\n /**\n * Custom error message provider.\n */\n errorMessage?: ValidationErrorMessageProvider<\n StringSchemaBuilder<TResult, TRequired>\n >\n ): StringSchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n if (!(regexp instanceof RegExp)) throw new Error('regexp expected');\n return this.createFromProps({\n ...this.introspect(),\n matches: regexp,\n matchesValidationErrorMessageProvider: errorMessage\n }) as any;\n }\n\n /**\n * Cancels `matches()` call.\n */\n public clearMatches(): StringSchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n const schema = this.introspect();\n delete schema.matches;\n return this.createFromProps({\n ...schema\n }) as any;\n }\n}\n\n/**\n * Creates a string schema restricted to be equal to `equals`.\n * @param equals string value the schema is restricted to\n */\nexport function string<T extends string>(\n equals: T\n): StringSchemaBuilder<T, true>;\n\n/**\n * Creates a string schema restricted to be equal to `equals` with a custom error message.\n * @param equals string value the schema is restricted to\n */\nexport function string<T extends string>(\n equals: T,\n errorMessage: ValidationErrorMessageProvider<StringSchemaBuilder<T, true>>\n): StringSchemaBuilder<T, true>;\n\nexport function string(): StringSchemaBuilder<string, true>;\n\n/**\n * Creates a string schema.\n */\nexport function string(\n equals?: string,\n errorMessage?: ValidationErrorMessageProvider<\n StringSchemaBuilder<string, true>\n >\n) {\n if (typeof equals === 'string') {\n return StringSchemaBuilder.create({\n isRequired: true,\n equalsTo: equals,\n equalsToValidationErrorMessageProvider: errorMessage\n });\n }\n return StringSchemaBuilder.create({\n isRequired: true\n });\n}\n"],"mappings":"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","names":["StringSchemaBuilder","_StringSchemaBuilder","SchemaBuilder","#minLength","#defaultMinLengthErrorMessageProvider","#minLengthErrorMessageProvider","#maxLength","#defaultMaxLengthErrorMessageProvider","#maxLengthErrorMessageProvider","#equalsTo","#defaultEqualsToErrorMessageProvider","seenValue","#equalsToErrorMessageProvider","#startsWith","#defaultStartsWithErrorMessageProvider","#startsWithErrorMessageProvider","#endsWith","#defaultEndsWithErrorMessageProvider","#endsWithErrorMessageProvider","#matches","#defaultMatchesErrorMessageProvider","#matchesErrorMessageProvider","props","_notUsed","#getConstraintViolation","objToValidate","#buildResult","superResult","valid","preValidationTransaction","errors","violation","object","context","r","value","errorMessage","_name","length","schema","val","regexp","string","equals"]}
@@ -0,0 +1,2 @@
1
+ import{f as n}from"./chunk-3JMDGYDT.js";var r=class s extends n{#e=[];#a;static create(e){return new s({type:"function",...e})}constructor(e){super(e),Array.isArray(e.parameters)&&(this.#e=e.parameters.filter(a=>a instanceof n)),e.returnType instanceof n&&(this.#a=e.returnType)}hasType(e){return this.createFromProps({...this.introspect()})}clearHasType(){return this.createFromProps({...this.introspect()})}introspect(){return{...super.introspect(),parameters:[...this.#e],returnType:this.#a}}#t(e){let{valid:a,transaction:i,errors:u}=e;if(!a)return{valid:a,errors:u};let{object:{validatedObject:t}}=i;return typeof t>"u"&&!this.isRequired||t===null&&(!this.isRequired||this.isNullable)?{valid:!0,object:t}:typeof t!="function"?{valid:!1,errors:[{message:`expected type function, but saw ${typeof t}`}]}:{valid:!0,object:t}}validate(e,a){return super.validate(e,a)}async validateAsync(e,a){return super.validateAsync(e,a)}_validate(e,a){return this.#t(this.preValidateSync(e,a))}async _validateAsync(e,a){return this.#t(await super.preValidateAsync(e,a))}createFromProps(e){return s.create(e)}required(e){return super.required(e)}optional(){return super.optional()}default(e){return super.default(e)}clearDefault(){return super.clearDefault()}brand(e){return super.brand(e)}readonly(){return super.readonly()}nullable(){return super.nullable()}addParameter(e){return this.createFromProps({...this.introspect(),parameters:[...this.#e,e]})}hasReturnType(e){return this.createFromProps({...this.introspect(),returnType:e})}notNullable(){return super.notNullable()}},T=()=>r.create({isRequired:!0});export{r as a,T as b};
2
+ //# sourceMappingURL=chunk-ZC6YBKCP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/builders/FunctionSchemaBuilder.ts"],"sourcesContent":["import {\n type BRAND,\n type InferType,\n SchemaBuilder,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\n\ntype FunctionSchemaBuilderCreateProps<R extends boolean = true> = Partial<\n ReturnType<FunctionSchemaBuilder<R>['introspect']>\n>;\n\ntype InferParameters<TParams extends SchemaBuilder<any, any, any, any, any>[]> =\n {\n [K in keyof TParams]: InferType<TParams[K]>;\n };\n\n/**\n * Schema builder for functions. Allows to define a schema for a function.\n * It can be required or optional, and may carry typed parameter and return-type\n * schemas so that the inferred TypeScript function signature is fully typed.\n *\n * **NOTE** this class is exported only to give opportunity to extend it\n * by inheriting. It is not recommended to create an instance of this class\n * directly. Use {@link func | func()} function instead.\n *\n * @example Basic validation\n * ```ts\n * const schema = func();\n * const result = schema.validate(() => {});\n * // result.valid === true\n * // result.object === () => {}\n * ```\n *\n * @example Optional function schema\n * ```ts\n * const schema = func().optional();\n * const result = schema.validate(undefined);\n * // result.valid === true\n * // result.object === undefined\n * ```\n *\n * @example Typed parameters and return type\n * ```ts\n * import { func, string, number, InferType } from '@cleverbrush/schema';\n *\n * const greet = func()\n * .addParameter(string()) // first param: string\n * .addParameter(number().optional()) // second param: number | undefined\n * .hasReturnType(string()); // return type: string\n *\n * type Greet = InferType<typeof greet>;\n * // → (param0: string, param1: number | undefined) => string\n *\n * // Introspect at runtime\n * const info = greet.introspect();\n * // info.parameters → [StringSchemaBuilder, NumberSchemaBuilder]\n * // info.returnType → StringSchemaBuilder\n * ```\n *\n * @see {@link func}\n */\nexport class FunctionSchemaBuilder<\n TRequired extends boolean = true,\n TNullable extends boolean = false,\n TExplicitType = undefined,\n THasDefault extends boolean = false,\n TExtensions = {},\n TParameters extends SchemaBuilder<any, any, any, any, any>[] = [],\n TReturnTypeSchema extends\n | SchemaBuilder<any, any, any, any, any>\n | undefined = undefined,\n TResult = TExplicitType extends undefined\n ? (\n ...args: TParameters extends []\n ? any[]\n : InferParameters<TParameters>\n ) => TReturnTypeSchema extends SchemaBuilder<any, any, any, any, any>\n ? InferType<TReturnTypeSchema>\n : any\n : TExplicitType\n> extends SchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n #parameters: SchemaBuilder<any, any, any, any, any>[] = [];\n #returnType?: SchemaBuilder<any, any, any, any, any>;\n\n /**\n * @hidden\n */\n public static create(props: FunctionSchemaBuilderCreateProps<any>) {\n return new FunctionSchemaBuilder({\n type: 'function',\n ...props\n });\n }\n\n protected constructor(props: FunctionSchemaBuilderCreateProps<TRequired>) {\n super(props as any);\n\n if (Array.isArray(props.parameters)) {\n this.#parameters = props.parameters.filter(\n p => p instanceof SchemaBuilder\n );\n }\n\n if (props.returnType instanceof SchemaBuilder) {\n this.#returnType = props.returnType;\n }\n }\n\n /**\n * @hidden\n */\n public hasType<T>(\n _notUsed?: T\n ): FunctionSchemaBuilder<\n true,\n TNullable,\n T,\n THasDefault,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * @hidden\n */\n public clearHasType(): FunctionSchemaBuilder<\n TRequired,\n TNullable,\n undefined,\n THasDefault,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * Returns an object describing the current schema configuration.\n *\n * In addition to the base fields exposed by {@link SchemaBuilder.introspect},\n * the following fields are included:\n *\n * - `parameters` — an array of {@link SchemaBuilder} instances accumulated via\n * {@link addParameter}. Each element describes one positional parameter of the\n * function in the order they were added.\n * - `returnType` — the {@link SchemaBuilder} set via {@link hasReturnType}, or\n * `undefined` when no return-type schema has been configured.\n *\n * @example\n * ```ts\n * const schema = func()\n * .addParameter(string())\n * .addParameter(number())\n * .hasReturnType(boolean());\n *\n * const info = schema.introspect();\n * // info.parameters.length === 2\n * // info.returnType instanceof BooleanSchemaBuilder\n * ```\n */\n public introspect() {\n return {\n ...super.introspect(),\n /** List of parameter schemas added via {@link addParameter}. */\n parameters: [...this.#parameters],\n /** Return type schema set via {@link hasReturnType}, or `undefined` if not set. */\n returnType: this.#returnType\n };\n }\n\n #buildResult(\n superResult: ReturnType<FunctionSchemaBuilder['preValidateSync']>\n ): ValidationResult<TResult> {\n const {\n valid,\n transaction: preValidationTransaction,\n errors\n } = superResult;\n\n if (!valid) {\n return { valid, errors };\n }\n\n const {\n object: { validatedObject: objToValidate }\n } = preValidationTransaction!;\n\n if (\n (typeof objToValidate === 'undefined' && !this.isRequired) ||\n (objToValidate === null && (!this.isRequired || this.isNullable))\n ) {\n return {\n valid: true,\n object: objToValidate\n };\n }\n\n if (typeof objToValidate !== 'function') {\n return {\n valid: false,\n errors: [\n {\n message: `expected type function, but saw ${typeof objToValidate}`\n }\n ]\n };\n }\n\n return {\n valid: true,\n object: objToValidate\n };\n }\n\n /** {@inheritDoc SchemaBuilder.validate} */\n public validate(\n object: TResult,\n context?: ValidationContext\n ): ValidationResult<TResult> {\n return super.validate(object, context) as ValidationResult<TResult>;\n }\n\n /** {@inheritDoc SchemaBuilder.validateAsync} */\n public async validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<ValidationResult<TResult>> {\n return super.validateAsync(object, context) as Promise<\n ValidationResult<TResult>\n >;\n }\n\n /**\n * Performs synchronous validation of the schema over `object`.\n * Throws if any preprocessor, validator, or error message provider returns a Promise.\n * @param context Optional `ValidationContext` settings.\n */\n protected _validate(\n object: TResult,\n context?: ValidationContext\n ): ValidationResult<TResult> {\n return this.#buildResult(this.preValidateSync(object, context));\n }\n\n /**\n * Performs async validation of the schema over `object`.\n * Supports async preprocessors, validators, and error message providers.\n * @param context Optional `ValidationContext` settings.\n */\n protected async _validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<ValidationResult<TResult>> {\n return this.#buildResult(await super.preValidateAsync(object, context));\n }\n\n protected createFromProps<TReq extends boolean>(\n props: FunctionSchemaBuilderCreateProps<TReq>\n ): this {\n return FunctionSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): FunctionSchemaBuilder<\n true,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return super.required(errorMessage);\n }\n\n /**\n * @hidden\n */\n public optional(): FunctionSchemaBuilder<\n false,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return super.optional();\n }\n\n /**\n * @hidden\n */\n public default(\n value: TResult | (() => TResult)\n ): FunctionSchemaBuilder<\n true,\n TNullable,\n TExplicitType,\n true,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return super.default(value) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): FunctionSchemaBuilder<\n TRequired,\n TNullable,\n TExplicitType,\n false,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return super.clearDefault() as any;\n }\n\n /**\n * @hidden\n */\n public brand<TBrand extends string | symbol>(\n _name?: TBrand\n ): FunctionSchemaBuilder<\n TRequired,\n TNullable,\n TResult & { readonly [K in BRAND]: TBrand },\n THasDefault,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return super.brand(_name);\n }\n\n /**\n * Marks the inferred type as `Readonly<Function>`. Sets the\n * `isReadonly` introspection flag for tooling consistency.\n *\n * @see {@link SchemaBuilder.readonly}\n */\n public readonly(): FunctionSchemaBuilder<\n TRequired,\n TNullable,\n Readonly<TResult>,\n THasDefault,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * @hidden\n */\n public nullable(): FunctionSchemaBuilder<\n TRequired,\n true,\n TExplicitType,\n THasDefault,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return super.nullable() as any;\n }\n\n /**\n * Appends a positional parameter schema to the function schema.\n *\n * Each call extends the inferred function signature by one parameter.\n * The full list of parameter schemas is available at runtime via\n * `introspect().parameters`.\n *\n * Parameter order matches the call order — the first `addParameter()` call\n * defines the type of the first argument, the second call defines the second\n * argument, and so on.\n *\n * @param schema - The schema describing the parameter. Pass an optional schema\n * (e.g. `string().optional()`) to make the corresponding argument optional.\n *\n * @example\n * ```ts\n * const fn = func()\n * .addParameter(string()) // (a: string, ...) => any\n * .addParameter(number().optional()) // (..., b?: number) => any\n * .addParameter(boolean()); // (..., c: boolean) => any\n *\n * type Fn = InferType<typeof fn>;\n * // → (a: string, b: number | undefined, c: boolean) => any\n * ```\n */\n public addParameter<TSchema extends SchemaBuilder<any, any, any, any, any>>(\n schema: TSchema\n ): FunctionSchemaBuilder<\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n [...TParameters, TSchema],\n TReturnTypeSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect(),\n parameters: [...this.#parameters, schema]\n } as any) as any;\n }\n\n /**\n * Sets the return type schema for the function schema.\n *\n * Replaces any previously set return type. The inferred function signature\n * gains a concrete return type instead of `any`. The schema is accessible at\n * runtime via `introspect().returnType`.\n *\n * @param schema - The schema describing the return type of the function.\n *\n * @example\n * ```ts\n * const fn = func()\n * .addParameter(string())\n * .hasReturnType(number());\n *\n * type Fn = InferType<typeof fn>;\n * // → (param0: string) => number\n *\n * fn.introspect().returnType; // NumberSchemaBuilder\n * ```\n */\n public hasReturnType<\n TSchema extends SchemaBuilder<any, any, any, any, any>\n >(\n schema: TSchema\n ): FunctionSchemaBuilder<\n TRequired,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions,\n TParameters,\n TSchema\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect(),\n returnType: schema\n } as any) as any;\n }\n\n /**\n * @hidden\n */\n public notNullable(): FunctionSchemaBuilder<\n TRequired,\n false,\n TExplicitType,\n THasDefault,\n TExtensions,\n TParameters,\n TReturnTypeSchema\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n}\n\n/**\n * Creates a `function` schema that validates the value is a JavaScript function.\n *\n * The returned builder is immutable and fully chainable. Use\n * {@link FunctionSchemaBuilder.addParameter} to annotate the expected parameter\n * types and {@link FunctionSchemaBuilder.hasReturnType} to annotate the return\n * type — the inferred TypeScript function signature is updated automatically.\n *\n * @returns A new {@link FunctionSchemaBuilder} with `isRequired` set to `true`.\n *\n * @example\n * ```ts\n * import { func, string, number, InferType } from '@cleverbrush/schema';\n *\n * const schema = func()\n * .addParameter(string())\n * .addParameter(number().optional())\n * .hasReturnType(string());\n *\n * type Fn = InferType<typeof schema>;\n * // → (param0: string, param1?: number) => string\n *\n * schema.validate(() => 'hello'); // { valid: true }\n * schema.validate('not a fn'); // { valid: false }\n * ```\n *\n * @see {@link FunctionSchemaBuilder}\n */\nexport const func = () =>\n FunctionSchemaBuilder.create({\n isRequired: true\n }) as FunctionSchemaBuilder<true>;\n"],"mappings":"wCA+DO,IAAMA,EAAN,MAAMC,UAmBHC,CAMR,CACEC,GAAwD,CAAC,EACzDC,GAKA,OAAc,OAAOC,EAA8C,CAC/D,OAAO,IAAIJ,EAAsB,CAC7B,KAAM,WACN,GAAGI,CACP,CAAC,CACL,CAEU,YAAYA,EAAoD,CACtE,MAAMA,CAAY,EAEd,MAAM,QAAQA,EAAM,UAAU,IAC9B,KAAKF,GAAcE,EAAM,WAAW,OAChCC,GAAKA,aAAaJ,CACtB,GAGAG,EAAM,sBAAsBH,IAC5B,KAAKE,GAAcC,EAAM,WAEjC,CAKO,QACHE,EAUY,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,CACvB,CAAQ,CACZ,CAKO,cASS,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,CACvB,CAAQ,CACZ,CA0BO,YAAa,CAChB,MAAO,CACH,GAAG,MAAM,WAAW,EAEpB,WAAY,CAAC,GAAG,KAAKJ,EAAW,EAEhC,WAAY,KAAKC,EACrB,CACJ,CAEAI,GACIC,EACyB,CACzB,GAAM,CACF,MAAAC,EACA,YAAaC,EACb,OAAAC,CACJ,EAAIH,EAEJ,GAAI,CAACC,EACD,MAAO,CAAE,MAAAA,EAAO,OAAAE,CAAO,EAG3B,GAAM,CACF,OAAQ,CAAE,gBAAiBC,CAAc,CAC7C,EAAIF,EAEJ,OACK,OAAOE,EAAkB,KAAe,CAAC,KAAK,YAC9CA,IAAkB,OAAS,CAAC,KAAK,YAAc,KAAK,YAE9C,CACH,MAAO,GACP,OAAQA,CACZ,EAGA,OAAOA,GAAkB,WAClB,CACH,MAAO,GACP,OAAQ,CACJ,CACI,QAAS,mCAAmC,OAAOA,CAAa,EACpE,CACJ,CACJ,EAGG,CACH,MAAO,GACP,OAAQA,CACZ,CACJ,CAGO,SACHC,EACAC,EACyB,CACzB,OAAO,MAAM,SAASD,EAAQC,CAAO,CACzC,CAGA,MAAa,cACTD,EACAC,EACkC,CAClC,OAAO,MAAM,cAAcD,EAAQC,CAAO,CAG9C,CAOU,UACND,EACAC,EACyB,CACzB,OAAO,KAAKP,GAAa,KAAK,gBAAgBM,EAAQC,CAAO,CAAC,CAClE,CAOA,MAAgB,eACZD,EACAC,EACkC,CAClC,OAAO,KAAKP,GAAa,MAAM,MAAM,iBAAiBM,EAAQC,CAAO,CAAC,CAC1E,CAEU,gBACNV,EACI,CACJ,OAAOJ,EAAsB,OAAOI,CAAY,CACpD,CAKO,SACHW,EAUY,CACZ,OAAO,MAAM,SAASA,CAAY,CACtC,CAKO,UASS,CACZ,OAAO,MAAM,SAAS,CAC1B,CAKO,QACHC,EAUY,CACZ,OAAO,MAAM,QAAQA,CAAK,CAC9B,CAKO,cASS,CACZ,OAAO,MAAM,aAAa,CAC9B,CAKO,MACHC,EAUY,CACZ,OAAO,MAAM,MAAMA,CAAK,CAC5B,CAQO,UASS,CACZ,OAAO,MAAM,SAAS,CAC1B,CAKO,UASS,CACZ,OAAO,MAAM,SAAS,CAC1B,CA2BO,aACHC,EAUY,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,EACnB,WAAY,CAAC,GAAG,KAAKhB,GAAagB,CAAM,CAC5C,CAAQ,CACZ,CAuBO,cAGHA,EAUY,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,EACnB,WAAYA,CAChB,CAAQ,CACZ,CAKO,aASS,CACZ,OAAO,MAAM,YAAY,CAC7B,CACJ,EA8BaC,EAAO,IAChBpB,EAAsB,OAAO,CACzB,WAAY,EAChB,CAAC","names":["FunctionSchemaBuilder","_FunctionSchemaBuilder","SchemaBuilder","#parameters","#returnType","props","p","_notUsed","#buildResult","superResult","valid","preValidationTransaction","errors","objToValidate","object","context","errorMessage","value","_name","schema","func"]}
@@ -0,0 +1,2 @@
1
+ import{f as m}from"./chunk-3JMDGYDT.js";var p=class R extends m{#a;#e;static create(e){return new R({type:"record",...e})}constructor(e){super(e),e.keySchema instanceof m&&(this.#a=e.keySchema),e.valueSchema instanceof m&&(this.#e=e.valueSchema)}hasType(e){return this.createFromProps({...this.introspect()})}clearHasType(){return this.createFromProps({...this.introspect()})}createFromProps(e){return R.create(e)}required(e){return super.required(e)}optional(){return super.optional()}default(e){return super.default(e)}clearDefault(){return super.clearDefault()}brand(e){return super.brand(e)}introspect(){return{...super.introspect(),keySchema:this.#a,valueSchema:this.#e}}#s(e){let t={};for(let[n,o]of e)t[n]=o;return t}#r(e,t,n){let o=this.#e;return{errors:t,isValid:t.length===0,seenValue:n!==null&&typeof n=="object"?n[e]:void 0,descriptor:{key:e,getSchema:()=>o,getValue:r=>r!==null&&typeof r=="object"&&Object.hasOwn(r,e)?{success:!0,value:r[e]}:{success:!1},setValue:(r,d)=>r!==null&&typeof r=="object"?(r[e]=d,!0):!1}}}#n(e,t){let{valid:n,errors:o}=t,r=[],d=new Map,y=()=>this.#s(d),u=l=>{if(typeof l>"u")return{errors:r,isValid:r.length===0,seenValue:e};let i=d.get(l),s=i&&!i.valid?(i.errors??[]).map(T=>T.message):[];return this.#r(l,s,e)};if(!n){for(let l of o??[])r.push(l.message);return{earlyReturn:!0,result:{valid:n,errors:o,getNestedErrors:y,getErrorsFor:u}}}let a=t.transaction.object.validatedObject;return typeof a>"u"&&!this.isRequired||a===null&&(!this.isRequired||this.isNullable)?{earlyReturn:!0,result:{valid:!0,object:a,getNestedErrors:y,getErrorsFor:u}}:typeof a!="object"||Array.isArray(a)||a===null?(r.push("object expected"),{earlyReturn:!0,result:{valid:!1,errors:[{message:"object expected"}],getNestedErrors:y,getErrorsFor:u}}):{earlyReturn:!1,objToValidate:a,nestedKeyResults:d,getNestedErrors:y,getErrorsFor:u}}#l(e,t,n,o,r,d){return e?{valid:!0,object:n,getNestedErrors:r,getErrorsFor:d}:{valid:!1,errors:o?t:[t[0]],getNestedErrors:r,getErrorsFor:d}}validate(e,t){return super.validate(e,t)}async validateAsync(e,t){return super.validateAsync(e,t)}_validate(e,t){if(this.canSkipPreValidation&&!t?.doNotStopOnFirstError){if(typeof e>"u"||e===null)if(typeof e>"u"&&this.hasDefault)e=this.resolveDefaultValue();else if(!this.isRequired||e===null&&this.isNullable){let a=e;return{valid:!0,object:e,getNestedErrors(){return{}},getErrorsFor:l=>typeof l>"u"?{errors:[],isValid:!0,seenValue:a}:this.#r(l,[],a)}}else return this.#t(e,t);if(typeof e!="object"||Array.isArray(e)||e===null)return this.#t(e,t);let n=new Map,o={},r=null;for(let a of Object.keys(e)){let l=this.#a.validate(a);if(!l.valid){let s=l.errors&&l.errors.length>0?l.errors:[{message:`key "${a}" is invalid`}];n.set(a,{valid:!1,errors:s}),r=s[0];break}let i=this.#e.validate(e[a]);if(n.set(a,i),i.valid)o[a]=i.object;else{let s=i.errors&&i.errors.length>0?i.errors:[{message:`value for key "${a}" is invalid`}];n.set(a,{valid:!1,errors:s}),r=s[0];break}}let d=e,y=()=>this.#s(n),u=a=>{if(typeof a>"u")return{errors:[],isValid:!0,seenValue:d};let l=n.get(a),i=l&&!l.valid?(l.errors??[]).map(s=>s.message):[];return this.#r(a,i,d)};return r!==null?{valid:!1,errors:[r],getNestedErrors:y,getErrorsFor:u}:{valid:!0,object:o,getNestedErrors:y,getErrorsFor:u}}return this.#t(e,t)}#t(e,t){let n=this.#n(e,this.preValidateSync(e,t));if(n.earlyReturn)return n.result;let{objToValidate:o,nestedKeyResults:r,getNestedErrors:d,getErrorsFor:y}=n,u=t?.doNotStopOnFirstError??!1,a=!0,l={},i=[];for(let s of Object.keys(o)){let T=this.#a.validate(s);if(!T.valid){a=!1;let h=T.errors&&T.errors.length>0?T.errors:[{message:`key "${s}" is invalid`}];if(r.set(s,{valid:!1,errors:h}),i.push(...h),!u)break;continue}let c=this.#e.validate(o[s],u?{doNotStopOnFirstError:!0}:void 0);if(r.set(s,c),c.valid)l[s]=c.object;else{a=!1;let h=c.errors&&c.errors.length>0?c.errors:[{message:`value for key "${s}" is invalid`}];if(i.push(...h),!u)break}}return this.#l(a,i,l,u,d,y)}async _validateAsync(e,t){let n=this.#n(e,await this.preValidateAsync(e,t));if(n.earlyReturn)return n.result;let{objToValidate:o,nestedKeyResults:r,getNestedErrors:d,getErrorsFor:y}=n,u=t?.doNotStopOnFirstError??!1,a=!0,l={},i=[];for(let s of Object.keys(o)){let T=await this.#a.validateAsync(s);if(!T.valid){a=!1;let h=T.errors&&T.errors.length>0?T.errors:[{message:`key "${s}" is invalid`}];if(r.set(s,{valid:!1,errors:h}),i.push(...h),!u)break;continue}let c=await this.#e.validateAsync(o[s],u?{doNotStopOnFirstError:!0}:void 0);if(r.set(s,c),c.valid)l[s]=c.object;else{a=!1;let h=c.errors&&c.errors.length>0?c.errors:[{message:`value for key "${s}" is invalid`}];if(i.push(...h),!u)break}}return this.#l(a,i,l,u,d,y)}nullable(){return super.nullable()}notNullable(){return super.notNullable()}};function f(R,e){return p.create({type:"record",keySchema:R,valueSchema:e})}export{p as a,f as b};
2
+ //# sourceMappingURL=chunk-ZFI27R3L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/builders/RecordSchemaBuilder.ts"],"sourcesContent":["/**\n * Schema builder for objects with dynamic string keys, where every value\n * must satisfy the same value schema.\n *\n * Equivalent to TypeScript's `Record<string, V>` (or a more constrained key\n * set when using a string-literal key schema) and Zod's `z.record()`.\n *\n * Unlike `ObjectSchemaBuilder` — which validates objects with a **known,\n * fixed set of property names** — `RecordSchemaBuilder` validates objects\n * whose keys are not known at schema-definition time (look-up tables, i18n\n * bundles, caches, etc.).\n *\n * @module\n */\nimport {\n type BRAND,\n type InferType,\n type PreValidationResult,\n SchemaBuilder,\n type ValidationContext,\n type ValidationError,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\nimport type { StringSchemaBuilder } from './StringSchemaBuilder.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * Descriptor for a single key-value entry within a validated record.\n * Provides `getValue`, `setValue`, and `getSchema` operations for the entry.\n *\n * Returned as part of {@link RecordKeyValidationResult}.\n */\nexport type RecordKeyDescriptor<\n TRecord,\n TValueSchema extends SchemaBuilder<any, any, any, any, any>\n> = {\n /** The key within the record this descriptor refers to. */\n readonly key: string;\n /** Returns the value schema every record entry must satisfy. */\n getSchema(): TValueSchema;\n /**\n * Retrieves the value at `key` from the given record object.\n * Returns `{ success: false }` when the key is not present.\n */\n getValue(obj: TRecord): {\n value?: InferType<TValueSchema>;\n success: boolean;\n };\n /**\n * Sets the value at `key` on the given record object.\n * Returns `false` when `obj` is not a non-null object.\n */\n setValue(obj: TRecord, value: InferType<TValueSchema>): boolean;\n};\n\n/**\n * Validation result for a single key-value entry in a record.\n * Returned by {@link RecordSchemaValidationResult.getErrorsFor | getErrorsFor(key)}.\n */\nexport type RecordKeyValidationResult<\n TRecord,\n TValueSchema extends SchemaBuilder<any, any, any, any, any>\n> = {\n /** Validation error messages for this entry; empty array when valid. */\n readonly errors: ReadonlyArray<string>;\n /** `true` when there are no validation errors for this entry. */\n readonly isValid: boolean;\n /** The value that was seen at this key during validation. */\n readonly seenValue: InferType<TValueSchema> | undefined;\n /** Descriptor for reading/writing the value at this key. */\n readonly descriptor: RecordKeyDescriptor<TRecord, TValueSchema>;\n};\n\n/**\n * Root-level validation result for the record object itself.\n * Returned by {@link RecordSchemaValidationResult.getErrorsFor | getErrorsFor()} (no argument).\n */\nexport type RecordRootValidationResult<TResult> = {\n /** Root-level error messages (e.g. `\"object expected\"`); empty when valid. */\n readonly errors: ReadonlyArray<string>;\n /** `true` when there are no root-level errors. */\n readonly isValid: boolean;\n /** The value that was being validated. */\n readonly seenValue: TResult | undefined;\n};\n\n/**\n * Validation result type returned by `RecordSchemaBuilder.validate()`.\n *\n * Extends `ValidationResult` with:\n * - `getNestedErrors()` — a per-key map of `ValidationResult` objects.\n * - `getErrorsFor()` — root-level errors for the record container itself.\n * - `getErrorsFor(key)` — errors, seen value, and descriptor for a specific key.\n */\nexport type RecordSchemaValidationResult<\n TResult,\n TValueSchema extends SchemaBuilder<any, any, any, any, any>\n> = ValidationResult<TResult> & {\n /**\n * Returns per-key validation results as a plain object.\n *\n * Each key in the returned object corresponds to a key in the input that\n * **failed** validation (in `doNotStopOnFirstError` mode) or the single\n * first failing key (in the default stop-on-first-error mode). Keys that\n * passed are not included.\n *\n * @deprecated Prefer {@link getErrorsFor} for a richer per-entry result\n * that also includes a descriptor and `seenValue`.\n *\n * @example\n * ```ts\n * const schema = record(string(), number().positive());\n * const result = schema.validate(\n * { a: 1, b: -2, c: 'oops' },\n * { doNotStopOnFirstError: true }\n * );\n *\n * if (!result.valid) {\n * const nested = result.getNestedErrors();\n * console.log(nested['b']); // ValidationResult for key 'b'\n * console.log(nested['c']); // ValidationResult for key 'c'\n * }\n * ```\n */\n getNestedErrors(): Record<\n string,\n ValidationResult<InferType<TValueSchema>>\n >;\n /**\n * Returns root-level errors for the record container itself\n * (e.g. `\"object expected\"` when a non-object value is passed,\n * or errors from custom validators added to the record schema).\n *\n * @example\n * ```ts\n * const schema = record(string(), number());\n * const root = schema.validate(42 as any).getErrorsFor();\n * // root.errors[0] === 'object expected'\n * // root.isValid === false\n * ```\n */\n getErrorsFor(): RecordRootValidationResult<TResult>;\n /**\n * Returns the validation result for the entry with the given key,\n * including error messages, the seen value, and a descriptor for\n * accessing and modifying the value at that key.\n *\n * If the key was not reached during validation (e.g. an earlier key\n * already failed in stop-on-first-error mode), an empty result with\n * `isValid: true` and no errors is returned.\n *\n * @param key - the key whose validation result to retrieve\n *\n * @example\n * ```ts\n * const schema = record(string(), number().min(0));\n * const result = schema.validate(\n * { a: 5, b: -2 },\n * { doNotStopOnFirstError: true }\n * );\n *\n * const bErrors = result.getErrorsFor('b');\n * // bErrors.isValid === false\n * // bErrors.errors[0] === 'the value must be >= 0'\n * // bErrors.seenValue === -2\n * // bErrors.descriptor.key === 'b'\n * // bErrors.descriptor.getSchema() === valueSchema\n * ```\n */\n getErrorsFor(key: string): RecordKeyValidationResult<TResult, TValueSchema>;\n};\n\ntype RecordSchemaBuilderCreateProps<\n TKeySchema extends StringSchemaBuilder<any, any, any, any>,\n TValueSchema extends SchemaBuilder<any, any, any, any, any>,\n R extends boolean = true\n> = Partial<\n ReturnType<RecordSchemaBuilder<TKeySchema, TValueSchema, R>['introspect']>\n>;\n\n// ---------------------------------------------------------------------------\n// Builder class\n// ---------------------------------------------------------------------------\n\n/**\n * Schema builder for objects with dynamic string keys.\n *\n * Every key in the validated object must be accepted by `keySchema` (a\n * `StringSchemaBuilder`) and every value must satisfy `valueSchema`.\n *\n * The inferred TypeScript type mirrors `Record<K, V>` where `K` is the\n * string type produced by `keySchema` and `V` is the type produced by\n * `valueSchema`.\n *\n * **NOTE** — this class is exported to allow extension by inheritance. Use\n * the {@link record | record()} factory function instead of instantiating it\n * directly.\n *\n * @example\n * ```ts\n * import { record, string, number } from '@cleverbrush/schema';\n *\n * // Basic: string keys, number values\n * const scores = record(string(), number().min(0));\n * // InferType<typeof scores> → Record<string, number>\n *\n * scores.validate({ alice: 95, bob: 87 }); // valid\n * scores.validate({ alice: 95, bob: -1 }); // invalid (negative)\n * ```\n *\n * @example\n * ```ts\n * // Restrict keys to a specific set of literals with .equals()\n * const locales = record(\n * string().matches(/^[a-z]{2}(-[A-Z]{2})?$/),\n * string().nonempty()\n * );\n * // accepts: { en: 'Hello', fr: 'Bonjour' }\n * // rejects: { 123: 'oops' } ← key doesn't match pattern\n * ```\n *\n * @see {@link record}\n */\nexport class RecordSchemaBuilder<\n TKeySchema extends StringSchemaBuilder<any, any, any, any>,\n TValueSchema extends SchemaBuilder<any, any, any, any, any>,\n TRequired extends boolean = true,\n TNullable extends boolean = false,\n TExplicitType = undefined,\n THasDefault extends boolean = false,\n TExtensions = {},\n TResult = TExplicitType extends undefined\n ? Record<InferType<TKeySchema>, InferType<TValueSchema>>\n : TExplicitType\n> extends SchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n #keySchema!: TKeySchema;\n #valueSchema!: TValueSchema;\n\n /**\n * @hidden\n */\n public static create(props: RecordSchemaBuilderCreateProps<any, any, any>) {\n return new RecordSchemaBuilder({\n type: 'record',\n ...props\n } as any);\n }\n\n protected constructor(\n props: RecordSchemaBuilderCreateProps<\n TKeySchema,\n TValueSchema,\n TRequired\n >\n ) {\n super(props as any);\n\n if (props.keySchema instanceof SchemaBuilder) {\n this.#keySchema = props.keySchema as TKeySchema;\n }\n if (props.valueSchema instanceof SchemaBuilder) {\n this.#valueSchema = props.valueSchema as TValueSchema;\n }\n }\n\n /**\n * @inheritdoc\n */\n public hasType<T>(\n _notUsed?: T\n ): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n true,\n TNullable,\n T,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * @inheritdoc\n */\n public clearHasType(): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n TRequired,\n TNullable,\n undefined,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * @hidden\n */\n protected createFromProps<TReq extends boolean>(\n props: RecordSchemaBuilderCreateProps<TKeySchema, TValueSchema, TReq>\n ): this {\n return RecordSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n true,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.required(errorMessage);\n }\n\n /**\n * @hidden\n */\n public optional(): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n false,\n TNullable,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.optional();\n }\n\n /**\n * @hidden\n */\n public default(\n value: TResult | (() => TResult)\n ): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n true,\n TNullable,\n TExplicitType,\n true,\n TExtensions\n > &\n TExtensions {\n return super.default(value) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n TRequired,\n TNullable,\n TExplicitType,\n false,\n TExtensions\n > &\n TExtensions {\n return super.clearDefault() as any;\n }\n\n /**\n * @hidden\n */\n public brand<TBrand extends string | symbol>(\n _name?: TBrand\n ): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n TRequired,\n TNullable,\n TResult & { readonly [K in BRAND]: TBrand },\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.brand(_name);\n }\n\n /**\n * Returns an introspection object describing the record schema.\n */\n public introspect() {\n return {\n ...super.introspect(),\n /**\n * The schema every key must satisfy (a `StringSchemaBuilder`).\n */\n keySchema: this.#keySchema,\n /**\n * The schema every value must satisfy.\n */\n valueSchema: this.#valueSchema\n };\n }\n\n // -----------------------------------------------------------------------\n // Validation helpers\n // -----------------------------------------------------------------------\n\n #buildNestedErrors(\n keyResults: Map<string, ValidationResult<any>>\n ): Record<string, ValidationResult<InferType<TValueSchema>>> {\n const out: Record<string, ValidationResult<any>> = {};\n for (const [k, v] of keyResults) {\n out[k] = v;\n }\n return out;\n }\n\n /**\n * Creates a {@link RecordKeyValidationResult} for `key` with the given\n * error message strings. Captures `rootObject` so the returned descriptor\n * can lazily read/write the value at that key.\n */\n #makeKeyResult(\n key: string,\n errors: string[],\n rootObject: TResult\n ): RecordKeyValidationResult<TResult, TValueSchema> {\n const valueSchema = this.#valueSchema;\n return {\n errors: errors as ReadonlyArray<string>,\n isValid: errors.length === 0,\n seenValue:\n rootObject !== null && typeof rootObject === 'object'\n ? (rootObject as any)[key]\n : undefined,\n descriptor: {\n key,\n getSchema: () => valueSchema,\n getValue: (obj: TResult) => {\n if (\n obj !== null &&\n typeof obj === 'object' &&\n Object.hasOwn(obj as any, key)\n ) {\n return { success: true, value: (obj as any)[key] };\n }\n return { success: false };\n },\n setValue: (obj: TResult, val: InferType<TValueSchema>) => {\n if (obj !== null && typeof obj === 'object') {\n (obj as any)[key] = val;\n return true;\n }\n return false;\n }\n }\n };\n }\n\n /**\n * Shared setup for {@link #validateFull} and {@link _validateAsync}.\n * Runs pre-validation guards (null / undefined / type checks) and\n * builds the `getNestedErrors` / `getErrorsFor` closures.\n *\n * Returns either an early result (when validation can short-circuit)\n * or the data needed for the per-entry loop.\n */\n #createValidationSetup(\n object: TResult,\n superResult: PreValidationResult<any, { validatedObject: any }>\n ):\n | {\n earlyReturn: true;\n result: RecordSchemaValidationResult<TResult, TValueSchema>;\n }\n | {\n earlyReturn: false;\n objToValidate: any;\n nestedKeyResults: Map<\n string,\n ValidationResult<InferType<TValueSchema>>\n >;\n getNestedErrors: () => Record<\n string,\n ValidationResult<InferType<TValueSchema>>\n >;\n getErrorsFor: (key?: string) => any;\n } {\n const { valid, errors } = superResult;\n\n const rootErrorMsgs: string[] = [];\n const nestedKeyResults = new Map<\n string,\n ValidationResult<InferType<TValueSchema>>\n >();\n const getNestedErrors = () => this.#buildNestedErrors(nestedKeyResults);\n const getErrorsFor = (key?: string): any => {\n if (typeof key === 'undefined') {\n return {\n errors: rootErrorMsgs as ReadonlyArray<string>,\n isValid: rootErrorMsgs.length === 0,\n seenValue: object\n };\n }\n const nestedResult = nestedKeyResults.get(key);\n const errMsgs =\n nestedResult && !nestedResult.valid\n ? (nestedResult.errors ?? []).map(\n (e: ValidationError) => e.message\n )\n : [];\n return this.#makeKeyResult(key, errMsgs, object);\n };\n\n if (!valid) {\n for (const e of errors ?? []) rootErrorMsgs.push(e.message);\n return {\n earlyReturn: true,\n result: {\n valid,\n errors,\n getNestedErrors,\n getErrorsFor\n } as any\n };\n }\n\n const objToValidate = superResult.transaction!.object\n .validatedObject as any;\n\n if (\n (typeof objToValidate === 'undefined' && !this.isRequired) ||\n (objToValidate === null && (!this.isRequired || this.isNullable))\n ) {\n return {\n earlyReturn: true,\n result: {\n valid: true,\n object: objToValidate,\n getNestedErrors,\n getErrorsFor\n } as any\n };\n }\n\n if (\n typeof objToValidate !== 'object' ||\n Array.isArray(objToValidate) ||\n objToValidate === null\n ) {\n rootErrorMsgs.push('object expected');\n return {\n earlyReturn: true,\n result: {\n valid: false,\n errors: [{ message: 'object expected' }],\n getNestedErrors,\n getErrorsFor\n } as any\n };\n }\n\n return {\n earlyReturn: false,\n objToValidate,\n nestedKeyResults,\n getNestedErrors,\n getErrorsFor\n };\n }\n\n /**\n * Builds the final validation result from the per-entry loop outcome.\n */\n #buildEntryResult(\n allValid: boolean,\n allErrors: ValidationError[],\n result: Record<string, any>,\n doNotStop: boolean,\n getNestedErrors: () => Record<\n string,\n ValidationResult<InferType<TValueSchema>>\n >,\n getErrorsFor: (key?: string) => any\n ): RecordSchemaValidationResult<TResult, TValueSchema> {\n if (!allValid) {\n return {\n valid: false,\n errors: doNotStop ? allErrors : [allErrors[0]],\n getNestedErrors,\n getErrorsFor\n } as any;\n }\n\n return {\n valid: true,\n object: result as TResult,\n getNestedErrors,\n getErrorsFor\n } as any;\n }\n\n /**\n * Core sync validation. {@inheritDoc SchemaBuilder.validate}\n */\n public validate(\n object: TResult,\n context?: ValidationContext\n ): RecordSchemaValidationResult<TResult, TValueSchema> {\n return super.validate(object, context) as RecordSchemaValidationResult<\n TResult,\n TValueSchema\n >;\n }\n\n /**\n * Core async validation. {@inheritDoc SchemaBuilder.validateAsync}\n */\n public async validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<RecordSchemaValidationResult<TResult, TValueSchema>> {\n return super.validateAsync(object, context) as Promise<\n RecordSchemaValidationResult<TResult, TValueSchema>\n >;\n }\n\n /**\n * Core sync validation. Returns `{ valid, object, errors, getNestedErrors, getErrorsFor }`.\n */\n protected _validate(\n object: TResult,\n context?: ValidationContext\n ): RecordSchemaValidationResult<TResult, TValueSchema> {\n // Fast path: skip pre-validation when no preprocessors/validators.\n if (this.canSkipPreValidation && !context?.doNotStopOnFirstError) {\n if (typeof object === 'undefined' || object === null) {\n if (typeof object === 'undefined' && this.hasDefault) {\n object = this.resolveDefaultValue();\n } else if (\n !this.isRequired ||\n (object === null && this.isNullable)\n ) {\n const capturedObj = object;\n return {\n valid: true,\n object,\n getNestedErrors() {\n return {};\n },\n getErrorsFor: (key?: string): any => {\n if (typeof key === 'undefined') {\n return {\n errors: [] as ReadonlyArray<string>,\n isValid: true,\n seenValue: capturedObj\n };\n }\n return this.#makeKeyResult(\n key,\n [],\n capturedObj as TResult\n );\n }\n } as any;\n } else {\n return this.#validateFull(object, context);\n }\n }\n\n if (\n typeof object !== 'object' ||\n Array.isArray(object) ||\n object === null\n ) {\n return this.#validateFull(object, context);\n }\n\n // Validate every entry inline, collecting per-key results as we go.\n const nestedKeyResults = new Map<string, ValidationResult<any>>();\n const result: Record<string, any> = {};\n let firstError: ValidationError | null = null;\n\n for (const key of Object.keys(object as any)) {\n const keyResult = this.#keySchema.validate(key);\n if (!keyResult.valid) {\n const keyErrors =\n keyResult.errors && keyResult.errors.length > 0\n ? keyResult.errors\n : [{ message: `key \"${key}\" is invalid` }];\n nestedKeyResults.set(key, {\n valid: false,\n errors: keyErrors\n });\n firstError = keyErrors[0];\n break;\n }\n\n const valueResult = this.#valueSchema.validate(\n (object as any)[key]\n );\n nestedKeyResults.set(key, valueResult as any);\n\n if (!valueResult.valid) {\n const valErrors =\n valueResult.errors && valueResult.errors.length > 0\n ? valueResult.errors\n : [\n {\n message: `value for key \"${key}\" is invalid`\n }\n ];\n nestedKeyResults.set(key, {\n valid: false,\n errors: valErrors\n });\n firstError = valErrors[0];\n break;\n } else {\n result[key] = valueResult.object;\n }\n }\n\n const capturedInput = object;\n const getNestedErrors = () =>\n this.#buildNestedErrors(nestedKeyResults);\n const getErrorsFor = (key?: string): any => {\n if (typeof key === 'undefined') {\n return {\n errors: [] as ReadonlyArray<string>,\n isValid: true,\n seenValue: capturedInput\n };\n }\n const nestedResult = nestedKeyResults.get(key);\n const errMsgs =\n nestedResult && !nestedResult.valid\n ? (nestedResult.errors ?? []).map(\n (e: ValidationError) => e.message\n )\n : [];\n return this.#makeKeyResult(key, errMsgs, capturedInput);\n };\n\n if (firstError !== null) {\n return {\n valid: false,\n errors: [firstError],\n getNestedErrors,\n getErrorsFor\n } as any;\n }\n\n return {\n valid: true,\n object: result as TResult,\n getNestedErrors,\n getErrorsFor\n } as any;\n }\n\n return this.#validateFull(object, context);\n }\n\n /**\n * Full validation path — processes preprocessors, validators, and collects\n * all per-entry results.\n */\n #validateFull(\n object: TResult,\n context?: ValidationContext\n ): RecordSchemaValidationResult<TResult, TValueSchema> {\n const setup = this.#createValidationSetup(\n object,\n this.preValidateSync(object, context)\n );\n if (setup.earlyReturn) return setup.result;\n\n const {\n objToValidate,\n nestedKeyResults,\n getNestedErrors,\n getErrorsFor\n } = setup;\n const doNotStop = context?.doNotStopOnFirstError ?? false;\n let allValid = true;\n const result: Record<string, any> = {};\n const allErrors: ValidationError[] = [];\n\n for (const key of Object.keys(objToValidate)) {\n const keyResult = this.#keySchema.validate(key);\n if (!keyResult.valid) {\n allValid = false;\n const keyErrors =\n keyResult.errors && keyResult.errors.length > 0\n ? keyResult.errors\n : [{ message: `key \"${key}\" is invalid` }];\n nestedKeyResults.set(key, {\n valid: false,\n errors: keyErrors\n });\n allErrors.push(...keyErrors);\n if (!doNotStop) break;\n continue;\n }\n\n const valueResult = this.#valueSchema.validate(\n objToValidate[key],\n doNotStop ? { doNotStopOnFirstError: true } : undefined\n );\n nestedKeyResults.set(key, valueResult as any);\n\n if (!valueResult.valid) {\n allValid = false;\n const valueErrors =\n valueResult.errors && valueResult.errors.length > 0\n ? valueResult.errors\n : [{ message: `value for key \"${key}\" is invalid` }];\n allErrors.push(...valueErrors);\n if (!doNotStop) break;\n } else {\n result[key] = valueResult.object;\n }\n }\n\n return this.#buildEntryResult(\n allValid,\n allErrors,\n result,\n doNotStop,\n getNestedErrors,\n getErrorsFor\n );\n }\n\n /**\n * Performs async validation of the record schema.\n *\n * Supports async preprocessors, validators, and error message providers.\n *\n * @param object - the value to validate\n * @param context - optional `ValidationContext` settings\n */\n protected async _validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<RecordSchemaValidationResult<TResult, TValueSchema>> {\n const setup = this.#createValidationSetup(\n object,\n await this.preValidateAsync(object, context)\n );\n if (setup.earlyReturn) return setup.result;\n\n const {\n objToValidate,\n nestedKeyResults,\n getNestedErrors,\n getErrorsFor\n } = setup;\n const doNotStop = context?.doNotStopOnFirstError ?? false;\n let allValid = true;\n const result: Record<string, any> = {};\n const allErrors: ValidationError[] = [];\n\n for (const key of Object.keys(objToValidate)) {\n const keyResult = await this.#keySchema.validateAsync(key);\n if (!keyResult.valid) {\n allValid = false;\n const keyErrors =\n keyResult.errors && keyResult.errors.length > 0\n ? keyResult.errors\n : [{ message: `key \"${key}\" is invalid` }];\n nestedKeyResults.set(key, {\n valid: false,\n errors: keyErrors\n });\n allErrors.push(...keyErrors);\n if (!doNotStop) break;\n continue;\n }\n\n const valueResult = await this.#valueSchema.validateAsync(\n objToValidate[key],\n doNotStop ? { doNotStopOnFirstError: true } : undefined\n );\n nestedKeyResults.set(key, valueResult as any);\n\n if (!valueResult.valid) {\n allValid = false;\n const valueErrors =\n valueResult.errors && valueResult.errors.length > 0\n ? valueResult.errors\n : [{ message: `value for key \"${key}\" is invalid` }];\n allErrors.push(...valueErrors);\n if (!doNotStop) break;\n } else {\n result[key] = valueResult.object;\n }\n }\n\n return this.#buildEntryResult(\n allValid,\n allErrors,\n result,\n doNotStop,\n getNestedErrors,\n getErrorsFor\n );\n }\n\n /**\n * @hidden\n */\n public nullable(): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n TRequired,\n true,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.nullable() as any;\n }\n\n /**\n * @hidden\n */\n public notNullable(): RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n TRequired,\n false,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory function\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a schema for objects with dynamic string keys, where every key\n * must satisfy `keySchema` and every value must satisfy `valueSchema`.\n *\n * The inferred TypeScript type is `Record<K, V>` where `K` is derived from\n * `keySchema` and `V` from `valueSchema`.\n *\n * @param keySchema - a `StringSchemaBuilder` that each key must satisfy\n * @param valueSchema - a `SchemaBuilder` that each value must satisfy\n *\n * @example\n * ```ts\n * import { record, string, number } from '@cleverbrush/schema';\n *\n * // Look-up table: string keys → number scores\n * const scores = record(string(), number().min(0).max(100));\n * // InferType<typeof scores> → Record<string, number>\n *\n * scores.validate({ alice: 95, bob: 87 }); // { valid: true }\n * scores.validate({ alice: 95, bob: -1 }); // { valid: false }\n * ```\n *\n * @example\n * ```ts\n * // i18n bundle: locale code keys → non-empty strings\n * const bundle = record(\n * string().matches(/^[a-z]{2}(-[A-Z]{2})?$/),\n * string().nonempty()\n * );\n *\n * bundle.validate({ en: 'Hello', 'fr-FR': 'Bonjour' }); // valid\n * bundle.validate({ en: '' }); // invalid (empty value)\n * bundle.validate({ '123': 'hi' }); // invalid (bad key)\n * ```\n *\n * @example\n * ```ts\n * // Optional record with a factory default\n * const cache = record(string(), number())\n * .optional()\n * .default(() => ({}));\n * ```\n *\n * @example\n * ```ts\n * // Nested record — values are objects\n * import { record, string, object, number } from '@cleverbrush/schema';\n *\n * const userMap = record(\n * string(),\n * object({ name: string(), age: number() })\n * );\n * ```\n */\nexport function record<\n TKeySchema extends StringSchemaBuilder<any, any, any, any>,\n TValueSchema extends SchemaBuilder<any, any, any, any, any>\n>(\n keySchema: TKeySchema,\n valueSchema: TValueSchema\n): RecordSchemaBuilder<TKeySchema, TValueSchema> {\n return RecordSchemaBuilder.create({\n type: 'record',\n keySchema,\n valueSchema\n } as any) as any;\n}\n"],"mappings":"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","names":["RecordSchemaBuilder","_RecordSchemaBuilder","SchemaBuilder","#keySchema","#valueSchema","props","_notUsed","errorMessage","value","_name","#buildNestedErrors","keyResults","out","k","v","#makeKeyResult","key","errors","rootObject","valueSchema","obj","val","#createValidationSetup","object","superResult","valid","rootErrorMsgs","nestedKeyResults","getNestedErrors","getErrorsFor","nestedResult","errMsgs","e","objToValidate","#buildEntryResult","allValid","allErrors","result","doNotStop","context","capturedObj","#validateFull","firstError","keyResult","keyErrors","valueResult","valErrors","capturedInput","setup","valueErrors","record","keySchema"]}
package/dist/core.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ export type { StandardSchemaV1, StandardTypedV1 } from '@standard-schema/spec';
2
+ export { AnySchemaBuilder, any } from './builders/AnySchemaBuilder.js';
3
+ export type { ArraySchemaValidationResult, ElementValidationResult } from './builders/ArraySchemaBuilder.js';
4
+ export { ArraySchemaBuilder, array } from './builders/ArraySchemaBuilder.js';
5
+ export { BooleanSchemaBuilder, boolean } from './builders/BooleanSchemaBuilder.js';
6
+ export { DateSchemaBuilder, date } from './builders/DateSchemaBuilder.js';
7
+ export { ExternSchemaBuilder, extern } from './builders/ExternSchemaBuilder.js';
8
+ export { FunctionSchemaBuilder, func } from './builders/FunctionSchemaBuilder.js';
9
+ export { GenericSchemaBuilder, generic } from './builders/GenericSchemaBuilder.js';
10
+ export { LazySchemaBuilder, lazy } from './builders/LazySchemaBuilder.js';
11
+ export { NullSchemaBuilder, nul } from './builders/NullSchemaBuilder.js';
12
+ export { NumberSchemaBuilder, number } from './builders/NumberSchemaBuilder.js';
13
+ export type { ObjectSchemaValidationResult } from './builders/ObjectSchemaBuilder.js';
14
+ export { ObjectSchemaBuilder, object, SchemaPropertySelector } from './builders/ObjectSchemaBuilder.js';
15
+ export type { ParseStringTemplateTag } from './builders/ParseStringSchemaBuilder.js';
16
+ export { ParseStringSchemaBuilder, parseString } from './builders/ParseStringSchemaBuilder.js';
17
+ export { PromiseSchemaBuilder, promise } from './builders/PromiseSchemaBuilder.js';
18
+ export type { RecordSchemaValidationResult } from './builders/RecordSchemaBuilder.js';
19
+ export { RecordSchemaBuilder, record } from './builders/RecordSchemaBuilder.js';
20
+ export type { NestedValidationResult, PropertyDescriptor, PropertyDescriptorInner, PropertyDescriptorTree, PropertySetterOptions, ValidationErrorMessageProvider } from './builders/SchemaBuilder.js';
21
+ export { BRAND, Brand, InferType, MakeOptional, SchemaBuilder, SchemaTypeBrand, SchemaValidationError, SYMBOL_HAS_PROPERTIES, SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR, ValidationError, ValidationResult } from './builders/SchemaBuilder.js';
22
+ export { StringSchemaBuilder, string } from './builders/StringSchemaBuilder.js';
23
+ export type { TupleElementValidationResults, TupleSchemaValidationResult } from './builders/TupleSchemaBuilder.js';
24
+ export { TupleSchemaBuilder, tuple } from './builders/TupleSchemaBuilder.js';
25
+ export type { OptionValidationResults, UnionSchemaValidationResult } from './builders/UnionSchemaBuilder.js';
26
+ export { UnionSchemaBuilder, union } from './builders/UnionSchemaBuilder.js';
27
+ export type { CleanExtended, ExtensionConfig, ExtensionDescriptor, FixedMethods, HiddenExtensionMethods } from './extension.js';
28
+ export { defineExtension, withExtensions } from './extension.js';