@cleverbrush/schema 4.5.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.md +176 -19
- package/dist/builders/AnySchemaBuilder.d.ts +11 -2
- package/dist/builders/AnySchemaBuilder.js +1 -1
- package/dist/builders/ArraySchemaBuilder.d.ts +15 -4
- package/dist/builders/ArraySchemaBuilder.js +1 -1
- package/dist/builders/BooleanSchemaBuilder.d.ts +21 -6
- package/dist/builders/BooleanSchemaBuilder.js +1 -1
- package/dist/builders/DateSchemaBuilder.d.ts +24 -10
- package/dist/builders/DateSchemaBuilder.js +1 -1
- package/dist/builders/ExternSchemaBuilder.d.ts +3 -2
- package/dist/builders/ExternSchemaBuilder.js +1 -1
- package/dist/builders/FunctionSchemaBuilder.d.ts +14 -2
- package/dist/builders/FunctionSchemaBuilder.js +1 -1
- package/dist/builders/GenericSchemaBuilder.d.ts +14 -3
- package/dist/builders/IntersectionSchemaBuilder.d.ts +1 -0
- package/dist/builders/LazySchemaBuilder.d.ts +1 -0
- package/dist/builders/NullSchemaBuilder.d.ts +2 -4
- package/dist/builders/NumberSchemaBuilder.d.ts +21 -7
- package/dist/builders/NumberSchemaBuilder.js +1 -1
- package/dist/builders/ObjectSchemaBuilder.d.ts +15 -4
- package/dist/builders/ObjectSchemaBuilder.js +1 -1
- package/dist/builders/ParseStringSchemaBuilder.d.ts +1 -0
- package/dist/builders/ParseStringSchemaBuilder.js +1 -1
- package/dist/builders/PromiseSchemaBuilder.d.ts +13 -2
- package/dist/builders/PromiseSchemaBuilder.js +1 -1
- package/dist/builders/RecordSchemaBuilder.d.ts +12 -0
- package/dist/builders/RecordSchemaBuilder.js +1 -1
- package/dist/builders/SchemaBuilder.d.ts +59 -10
- package/dist/builders/StringSchemaBuilder.d.ts +23 -8
- package/dist/builders/StringSchemaBuilder.js +1 -1
- package/dist/builders/TupleSchemaBuilder.d.ts +16 -4
- package/dist/builders/TupleSchemaBuilder.js +1 -1
- package/dist/builders/UnionSchemaBuilder.d.ts +12 -2
- package/dist/builders/UnionSchemaBuilder.js +1 -1
- package/dist/chunk-25KL2NBJ.js +2 -0
- package/dist/chunk-25KL2NBJ.js.map +1 -0
- package/dist/chunk-2BKBVVZ3.js +2 -0
- package/dist/chunk-2BKBVVZ3.js.map +1 -0
- package/dist/chunk-3E5M6GRR.js +2 -0
- package/dist/chunk-3E5M6GRR.js.map +1 -0
- package/dist/chunk-66U6MMJ2.js +2 -0
- package/dist/chunk-66U6MMJ2.js.map +1 -0
- package/dist/chunk-BMA2X7LI.js +2 -0
- package/dist/chunk-BMA2X7LI.js.map +1 -0
- package/dist/chunk-BTR3ZGES.js +2 -0
- package/dist/chunk-BTR3ZGES.js.map +1 -0
- package/dist/chunk-D7RXO2FA.js +2 -0
- package/dist/chunk-D7RXO2FA.js.map +1 -0
- package/dist/chunk-JH7VLA6C.js +2 -0
- package/dist/chunk-JH7VLA6C.js.map +1 -0
- package/dist/chunk-K7TDPKGQ.js +2 -0
- package/dist/chunk-K7TDPKGQ.js.map +1 -0
- package/dist/chunk-NDESVCWI.js +2 -0
- package/dist/chunk-NDESVCWI.js.map +1 -0
- package/dist/chunk-VBPZRO7L.js +2 -0
- package/dist/chunk-VBPZRO7L.js.map +1 -0
- package/dist/chunk-W5D22D4P.js +2 -0
- package/dist/chunk-W5D22D4P.js.map +1 -0
- package/dist/{chunk-XHSBY2QK.js → chunk-W5LLKFM7.js} +2 -2
- package/dist/{chunk-XHSBY2QK.js.map → chunk-W5LLKFM7.js.map} +1 -1
- package/dist/chunk-WNAU5MPQ.js +2 -0
- package/dist/chunk-WNAU5MPQ.js.map +1 -0
- package/dist/chunk-XASMTNON.js +2 -0
- package/dist/chunk-XASMTNON.js.map +1 -0
- package/dist/chunk-Z4SFUZSP.js +2 -0
- package/dist/chunk-Z4SFUZSP.js.map +1 -0
- package/dist/chunk-ZYWDTLNL.js +2 -0
- package/dist/chunk-ZYWDTLNL.js.map +1 -0
- package/dist/core.d.ts +3 -3
- package/dist/core.js +1 -1
- package/dist/extension.d.ts +4 -1
- package/dist/extension.js +1 -1
- package/dist/extensions/string.d.ts +2 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata-extension.d.ts +196 -0
- package/package.json +6 -3
- package/dist/chunk-54RHS4F4.js +0 -2
- package/dist/chunk-54RHS4F4.js.map +0 -1
- package/dist/chunk-6LSN7NXQ.js +0 -2
- package/dist/chunk-6LSN7NXQ.js.map +0 -1
- package/dist/chunk-C6YQOKWB.js +0 -2
- package/dist/chunk-C6YQOKWB.js.map +0 -1
- package/dist/chunk-ELPPAHNO.js +0 -2
- package/dist/chunk-ELPPAHNO.js.map +0 -1
- package/dist/chunk-G424M7GI.js +0 -2
- package/dist/chunk-G424M7GI.js.map +0 -1
- package/dist/chunk-JUFZ7PLO.js +0 -2
- package/dist/chunk-JUFZ7PLO.js.map +0 -1
- package/dist/chunk-K4ZLXLE2.js +0 -2
- package/dist/chunk-K4ZLXLE2.js.map +0 -1
- package/dist/chunk-KC45JEFL.js +0 -2
- package/dist/chunk-KC45JEFL.js.map +0 -1
- package/dist/chunk-NF4CRFMN.js +0 -2
- package/dist/chunk-NF4CRFMN.js.map +0 -1
- package/dist/chunk-ORV2G6ZL.js +0 -2
- package/dist/chunk-ORV2G6ZL.js.map +0 -1
- package/dist/chunk-PQINUGZW.js +0 -2
- package/dist/chunk-PQINUGZW.js.map +0 -1
- package/dist/chunk-REYZ7G7J.js +0 -2
- package/dist/chunk-REYZ7G7J.js.map +0 -1
- package/dist/chunk-VSU5GILY.js +0 -2
- package/dist/chunk-VSU5GILY.js.map +0 -1
- package/dist/chunk-XL723XFL.js +0 -2
- package/dist/chunk-XL723XFL.js.map +0 -1
- package/dist/chunk-XPLTW5DI.js +0 -2
- package/dist/chunk-XPLTW5DI.js.map +0 -1
- package/dist/chunk-YAOZEA2R.js +0 -2
- package/dist/chunk-YAOZEA2R.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/builders/IntersectionSchemaBuilder.ts","../src/builders/LazySchemaBuilder.ts","../src/builders/NullSchemaBuilder.ts"],"sourcesContent":["import {\n type BRAND,\n type InferType,\n SchemaBuilder,\n type ValidationContext,\n type ValidationResult\n} from './SchemaBuilder.js';\n\ntype IntersectionSchemaBuilderCreateProps<\n TLeft extends SchemaBuilder<any, any, any, any, any>,\n TRight extends SchemaBuilder<any, any, any, any, any>,\n R extends boolean = true\n> = Partial<\n ReturnType<IntersectionSchemaBuilder<TLeft, TRight, R>['introspect']>\n>;\n\ntype SchemaIntersection<\n TLeft extends SchemaBuilder<any, any, any, any, any>,\n TRight extends SchemaBuilder<any, any, any, any, any>\n> = InferType<TLeft> & InferType<TRight>;\n\nexport type IntersectionSchemaValidationResult<T> = ValidationResult<T>;\n\nexport class IntersectionSchemaBuilder<\n TLeft extends SchemaBuilder<any, any, any, any, any>,\n TRight 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> extends SchemaBuilder<\n TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n #left!: TLeft;\n #right!: TRight;\n\n /**\n * @hidden\n */\n public static create(\n props: IntersectionSchemaBuilderCreateProps<any, any>\n ) {\n return new IntersectionSchemaBuilder({\n type: 'intersection',\n ...props\n });\n }\n\n protected constructor(\n props: IntersectionSchemaBuilderCreateProps<TLeft, TRight, TRequired>\n ) {\n super(props as any);\n\n if (props.left instanceof SchemaBuilder) {\n this.#left = props.left;\n }\n if (props.right instanceof SchemaBuilder) {\n this.#right = props.right;\n }\n }\n\n public introspect() {\n return {\n ...super.introspect(),\n left: this.#left,\n right: this.#right\n };\n }\n\n /**\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 ): IntersectionSchemaBuilder<\n TLeft,\n TRight,\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(): IntersectionSchemaBuilder<\n TLeft,\n TRight,\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 * @inheritdoc\n */\n public validate(\n object: TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType,\n context?: ValidationContext\n ): IntersectionSchemaValidationResult<\n TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType\n > {\n return super.validate(object, context) as any;\n }\n\n /**\n * @inheritdoc\n */\n public async validateAsync(\n object: TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType,\n context?: ValidationContext\n ): Promise<\n IntersectionSchemaValidationResult<\n TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType\n >\n > {\n return super.validateAsync(object, context) as any;\n }\n\n #mergeObjects(leftObj: any, rightObj: any): any {\n if (\n typeof leftObj === 'object' &&\n leftObj !== null &&\n typeof rightObj === 'object' &&\n rightObj !== null &&\n !Array.isArray(leftObj) &&\n !Array.isArray(rightObj)\n ) {\n return { ...leftObj, ...rightObj };\n }\n return rightObj;\n }\n\n #createValidationSetup(\n superResult: ReturnType<\n IntersectionSchemaBuilder<any, any>['preValidateSync']\n >\n ) {\n const {\n valid,\n transaction: preValidationTransaction,\n context: prevalidationContext,\n errors\n } = superResult;\n\n if (!valid) {\n return {\n needsValidation: false as const,\n result: { valid, errors } 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 needsValidation: false as const,\n result: {\n valid: true,\n object: objToValidate\n } as any\n };\n }\n\n return {\n needsValidation: true as const,\n objToValidate,\n prevalidationContext\n };\n }\n\n /**\n * Performs synchronous validation.\n * Validates left schema first, then right schema.\n * Both must pass for the intersection to be valid.\n */\n protected _validate(\n object: TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType,\n context?: ValidationContext\n ): IntersectionSchemaValidationResult<\n TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType\n > {\n if (\n this.canSkipPreValidation &&\n !context?.doNotStopOnFirstError &&\n !context?.rootPropertyDescriptor\n ) {\n if (typeof object === 'undefined') {\n if (this.hasDefault) {\n object = this.resolveDefaultValue();\n } else if (!this.isRequired) {\n return { valid: true, object } as any;\n } else {\n return {\n valid: false,\n errors: [\n {\n message: this.getValidationErrorMessageSync(\n this.requiredErrorMessage,\n object as any\n )\n }\n ]\n } as any;\n }\n } else if (\n object === null &&\n (!this.isRequired || this.isNullable)\n ) {\n return { valid: true, object } as any;\n }\n\n const leftResult = this.#left.validate(object as any);\n if (!leftResult.valid) {\n return {\n valid: false,\n errors: leftResult.errors\n } as any;\n }\n\n const rightResult = this.#right.validate(object as any);\n if (!rightResult.valid) {\n return {\n valid: false,\n errors: rightResult.errors\n } as any;\n }\n\n const mergedObject = this.#mergeObjects(\n leftResult.object,\n rightResult.object\n );\n return { valid: true, object: mergedObject } as any;\n }\n\n return this.#validateFull(object, context);\n }\n\n #validateFull(\n object: any,\n context?: ValidationContext\n ): IntersectionSchemaValidationResult<any> {\n const setup = this.#createValidationSetup(\n this.preValidateSync(object, context)\n );\n\n if (!setup.needsValidation) return setup.result;\n\n const { objToValidate, prevalidationContext } = setup;\n\n const leftResult = this.#left.validate(objToValidate, {\n ...prevalidationContext,\n currentPropertyDescriptor: undefined,\n rootPropertyDescriptor: undefined\n } as any);\n\n if (!leftResult.valid) {\n return {\n valid: false,\n errors: leftResult.errors\n };\n }\n\n const rightResult = this.#right.validate(objToValidate, {\n ...prevalidationContext,\n currentPropertyDescriptor: undefined,\n rootPropertyDescriptor: undefined\n } as any);\n\n if (!rightResult.valid) {\n return {\n valid: false,\n errors: rightResult.errors\n };\n }\n\n const mergedObject = this.#mergeObjects(\n leftResult.object,\n rightResult.object\n );\n\n return {\n valid: true,\n object: mergedObject\n };\n }\n\n /**\n * Performs async validation.\n */\n protected async _validateAsync(\n object: TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType,\n context?: ValidationContext\n ): Promise<\n IntersectionSchemaValidationResult<\n TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType\n >\n > {\n const setup = this.#createValidationSetup(\n await super.preValidateAsync(object, context)\n );\n\n if (!setup.needsValidation) return setup.result;\n\n const { objToValidate, prevalidationContext } = setup;\n\n const leftResult = await this.#left.validateAsync(objToValidate, {\n ...prevalidationContext,\n currentPropertyDescriptor: undefined,\n rootPropertyDescriptor: undefined\n } as any);\n\n if (!leftResult.valid) {\n return {\n valid: false,\n errors: leftResult.errors\n };\n }\n\n const rightResult = await this.#right.validateAsync(objToValidate, {\n ...prevalidationContext,\n currentPropertyDescriptor: undefined,\n rootPropertyDescriptor: undefined\n } as any);\n\n if (!rightResult.valid) {\n return {\n valid: false,\n errors: rightResult.errors\n };\n }\n\n const mergedObject = this.#mergeObjects(\n leftResult.object,\n rightResult.object\n );\n\n return {\n valid: true,\n object: mergedObject\n };\n }\n\n protected createFromProps<\n TL extends SchemaBuilder<any, any, any, any, any>,\n TR extends SchemaBuilder<any, any, any, any, any>,\n TReq extends boolean\n >(props: IntersectionSchemaBuilderCreateProps<TL, TR, TReq>): this {\n return IntersectionSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: any\n ): IntersectionSchemaBuilder<\n TLeft,\n TRight,\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(): IntersectionSchemaBuilder<\n TLeft,\n TRight,\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 ? SchemaIntersection<TLeft, TRight>\n : TExplicitType)\n | (() => TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType)\n ): IntersectionSchemaBuilder<\n TLeft,\n TRight,\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(): IntersectionSchemaBuilder<\n TLeft,\n TRight,\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 ): IntersectionSchemaBuilder<\n TLeft,\n TRight,\n TRequired,\n TNullable,\n (TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\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(): IntersectionSchemaBuilder<\n TLeft,\n TRight,\n TRequired,\n TNullable,\n Readonly<\n TExplicitType extends undefined\n ? SchemaIntersection<TLeft, TRight>\n : TExplicitType\n >,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * @hidden\n */\n public nullable(): IntersectionSchemaBuilder<\n TLeft,\n TRight,\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(): IntersectionSchemaBuilder<\n TLeft,\n TRight,\n TRequired,\n false,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n\n /**\n * Gets the left side of this intersection.\n */\n public get leftSchema(): TLeft {\n return this.#left;\n }\n\n /**\n * Gets the right side of this intersection.\n */\n public get rightSchema(): TRight {\n return this.#right;\n }\n}\n\n/**\n * Creates an intersection schema.\n * The resulting schema validates that the input satisfies both `left` and `right` schemas.\n *\n * @example\n * ```ts\n * const schema = intersection(\n * object({ name: string() }),\n * object({ age: number() })\n * );\n * // InferType<typeof schema> === { name: string } & { age: number }\n * ```\n *\n * @param left - first schema\n * @param right - second schema\n */\nexport const intersection = <\n TLeft extends SchemaBuilder<any, any, any, any, any>,\n TRight extends SchemaBuilder<any, any, any, any, any>\n>(\n left: TLeft,\n right: TRight\n) =>\n IntersectionSchemaBuilder.create({\n isRequired: true,\n left,\n right\n }) as IntersectionSchemaBuilder<TLeft, TRight>;\n","import {\n type BRAND,\n SchemaBuilder,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\n\ntype LazySchemaBuilderCreateProps<R extends boolean = true> = Partial<\n ReturnType<LazySchemaBuilder<any, R>['introspect']>\n>;\n\n/**\n * Lazy schema builder class. Allows defining recursive/self-referential schemas\n * by wrapping a getter function that returns the target schema. The getter is\n * called once on first validation and the result is cached.\n *\n * This is the primary mechanism for building recursive data structures such as\n * tree nodes, nested menus, and threaded comments.\n *\n * **NOTE** TypeScript cannot infer recursive types automatically, so you must\n * provide an explicit type annotation on the variable holding the schema:\n *\n * @example\n * ```ts\n * type TreeNode = { value: number; children: TreeNode[] };\n *\n * const treeNode: SchemaBuilder<TreeNode, true> = object({\n * value: number(),\n * children: array(lazy(() => treeNode))\n * });\n *\n * treeNode.validate({ value: 1, children: [{ value: 2, children: [] }] });\n * // { valid: true, object: { value: 1, children: [{ value: 2, children: [] }] } }\n * ```\n *\n * @example\n * ```ts\n * type Comment = { text: string; replies: Comment[] };\n *\n * const commentSchema: SchemaBuilder<Comment, true> = object({\n * text: string(),\n * replies: array(lazy(() => commentSchema))\n * });\n * ```\n */\nexport class LazySchemaBuilder<\n TResult = any,\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 #getter: () => SchemaBuilder<TResult, any, any>;\n #resolvedSchema: SchemaBuilder<TResult, any, any> | null = null;\n\n /**\n * @hidden\n */\n public static create(props: LazySchemaBuilderCreateProps<any>) {\n return new LazySchemaBuilder({\n type: 'lazy',\n ...props\n });\n }\n\n protected constructor(props: LazySchemaBuilderCreateProps<TRequired>) {\n super(props as any);\n if (typeof (props as any).getter !== 'function') {\n throw new Error('LazySchemaBuilder: getter must be a function');\n }\n this.#getter = (props as any).getter;\n }\n\n /**\n * Resolves the lazy schema by calling the getter (once; result is cached).\n * After the first call subsequent calls return the cached schema instance.\n */\n public resolve(): SchemaBuilder<TResult, any, any> {\n if (this.#resolvedSchema === null) {\n this.#resolvedSchema = this.#getter();\n }\n return this.#resolvedSchema;\n }\n\n /**\n * @inheritdoc\n */\n public introspect() {\n return {\n ...super.introspect(),\n /**\n * The getter function that returns the lazily-resolved schema.\n * Call {@link LazySchemaBuilder.resolve} to obtain the schema instance.\n */\n getter: this.#getter\n };\n }\n\n #buildResult(\n superResult: ReturnType<LazySchemaBuilder['preValidateSync']>,\n context?: ValidationContext\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 // Value is null/undefined and the schema is optional — skip delegation.\n if (objToValidate == null) {\n return { valid: true, object: objToValidate };\n }\n\n return this.resolve().validate(\n objToValidate,\n context\n ) as ValidationResult<TResult>;\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(\n this.preValidateSync(object, context),\n context\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<ValidationResult<TResult>> {\n const superResult = await super.preValidateAsync(object, context);\n\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 (objToValidate == null) {\n return { valid: true, object: objToValidate };\n }\n\n return this.resolve().validateAsync(objToValidate, context) as Promise<\n ValidationResult<TResult>\n >;\n }\n\n protected createFromProps<TReq extends boolean>(\n props: LazySchemaBuilderCreateProps<TReq>\n ): this {\n return LazySchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @inheritdoc\n */\n public hasType<T>(\n _notUsed?: T\n ): LazySchemaBuilder<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(): LazySchemaBuilder<\n TResult,\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 /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): LazySchemaBuilder<TResult, true, TNullable, THasDefault, TExtensions> &\n TExtensions {\n return super.required(errorMessage);\n }\n\n /**\n * @hidden\n */\n public optional(): LazySchemaBuilder<\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 ): LazySchemaBuilder<TResult, true, TNullable, true, TExtensions> &\n TExtensions {\n return super.default(value) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): LazySchemaBuilder<\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 ): LazySchemaBuilder<\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 * @hidden\n */\n public readonly(): LazySchemaBuilder<\n Readonly<TResult>,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * @hidden\n */\n public nullable(): LazySchemaBuilder<\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(): LazySchemaBuilder<\n TResult,\n TRequired,\n false,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n}\n\n/**\n * Creates a lazy schema that defers the schema definition until first validation.\n * Use this to define recursive/self-referential schemas.\n *\n * The getter function is called **once** on first use and the result is cached.\n * You **must** provide an explicit TypeScript type annotation on the variable\n * holding the outer schema — TypeScript cannot infer recursive types automatically.\n *\n * @param getter - A function that returns the schema to use for validation.\n *\n * @example\n * ```ts\n * // Tree structure\n * type TreeNode = { value: number; children: TreeNode[] };\n *\n * const treeNode: SchemaBuilder<TreeNode, true> = object({\n * value: number(),\n * children: array(lazy(() => treeNode))\n * });\n * ```\n *\n * @example\n * ```ts\n * // Optional recursive field (submenu)\n * type MenuItem = { label: string; submenu?: MenuItem[] };\n *\n * const menuItem: SchemaBuilder<MenuItem, true> = object({\n * label: string(),\n * submenu: array(lazy(() => menuItem)).optional()\n * });\n * ```\n */\nexport function lazy<TResult>(\n getter: () => SchemaBuilder<TResult, any, any>\n): LazySchemaBuilder<TResult, true, false, false, {}> {\n return LazySchemaBuilder.create({\n type: 'lazy',\n isRequired: true,\n preprocessors: [],\n validators: [],\n getter\n } as any);\n}\n","import {\n type BRAND,\n SchemaBuilder,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\n\ntype NullSchemaBuilderCreateProps<R extends boolean = true> = Partial<\n ReturnType<NullSchemaBuilder<R>['introspect']>\n>;\n\n/**\n * Schema builder for `null` values. Validates that the input is exactly `null`.\n *\n * When required (the default), only `null` is accepted. When optional (via\n * `.optional()`), both `null` and `undefined` are accepted; any other value\n * is rejected.\n *\n * This builder is useful when you need to represent an explicitly-null field\n * in a typed schema, for example in discriminated-union branches or when\n * modelling a JSON payload that may carry a JSON `null` value.\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 nul | nul()} function instead.\n *\n * @example\n * ```ts\n * import { nul } from '@cleverbrush/schema';\n *\n * const schema = nul();\n *\n * schema.validate(null); // { valid: true, object: null }\n * schema.validate(undefined); // { valid: false }\n * schema.validate(0); // { valid: false }\n * schema.validate(''); // { valid: false }\n * ```\n *\n * @example\n * ```ts\n * // Optional — accepts null or undefined\n * const schema = nul().optional();\n *\n * schema.validate(null); // { valid: true, object: null }\n * schema.validate(undefined); // { valid: true, object: undefined }\n * schema.validate(false); // { valid: false }\n * ```\n *\n * @example\n * ```ts\n * // Use inside a union to model a nullable string field\n * import { union, string, nul, InferType } from '@cleverbrush/schema';\n *\n * const NullableString = union(string()).or(nul());\n * type NullableString = InferType<typeof NullableString>;\n * // string | null\n *\n * NullableString.validate('hello'); // valid\n * NullableString.validate(null); // valid\n * NullableString.validate(42); // invalid\n * ```\n *\n * @see {@link nul}\n */\nexport class NullSchemaBuilder<\n TRequired extends boolean = true,\n TNullable extends boolean = false,\n TExplicitType = undefined,\n THasDefault extends boolean = false,\n TExtensions = {}\n> extends SchemaBuilder<null, TRequired, TNullable, THasDefault, TExtensions> {\n /**\n * @hidden\n */\n public static create(props: NullSchemaBuilderCreateProps<any>) {\n return new NullSchemaBuilder({\n type: 'null',\n ...props\n });\n }\n\n protected constructor(props: NullSchemaBuilderCreateProps<TRequired>) {\n super(props as any);\n }\n\n /**\n * @hidden\n */\n public hasType<T>(\n _notUsed?: T\n ): NullSchemaBuilder<true, TNullable, T, THasDefault, TExtensions> &\n TExtensions {\n return this.createFromProps({\n ...this.introspect()\n } as any) as any;\n }\n\n /**\n * @hidden\n */\n public clearHasType(): NullSchemaBuilder<\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 // The SchemaBuilder base-class preValidateSync/preValidateAsync treats\n // null as an invalid value for required schemas, which would prevent null\n // from ever passing validation here. We therefore bypass preValidateSync\n // entirely and implement the full (and simple) validation inline.\n #buildResult(object: any): ValidationResult<null> {\n if (object === null) return { valid: true, object: null };\n\n if (object === undefined && this.hasDefault) {\n const defaultVal = this.resolveDefaultValue();\n if (defaultVal === null) return { valid: true, object: null };\n return { valid: false, errors: [{ message: 'must be null' }] };\n }\n\n if (object === undefined && !this.isRequired) {\n return { valid: true, object: undefined as any };\n }\n\n return {\n valid: false,\n errors: [{ message: 'must be null' }]\n };\n }\n\n /** {@inheritDoc SchemaBuilder.validate} */\n public validate(\n object: null,\n context?: ValidationContext\n ): ValidationResult<null> {\n return super.validate(object, context) as ValidationResult<null>;\n }\n\n /** {@inheritDoc SchemaBuilder.validateAsync} */\n public async validateAsync(\n object: null,\n context?: ValidationContext\n ): Promise<ValidationResult<null>> {\n return super.validateAsync(object, context) as Promise<\n ValidationResult<null>\n >;\n }\n\n /**\n * Performs synchronous validation of the schema over `object`.\n * @param context Optional `ValidationContext` settings.\n */\n protected _validate(\n object: null,\n _context?: ValidationContext\n ): ValidationResult<null> {\n return this.#buildResult(object);\n }\n\n /**\n * Performs async validation of the schema over `object`.\n * @param context Optional `ValidationContext` settings.\n */\n protected async _validateAsync(\n object: null,\n _context?: ValidationContext\n ): Promise<ValidationResult<null>> {\n return this.#buildResult(object);\n }\n\n protected createFromProps<TReq extends boolean>(\n props: NullSchemaBuilderCreateProps<TReq>\n ): this {\n return NullSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): NullSchemaBuilder<\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(): NullSchemaBuilder<\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: null | (() => null)\n ): NullSchemaBuilder<true, TNullable, TExplicitType, true, TExtensions> &\n TExtensions {\n return super.default(value) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): NullSchemaBuilder<\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 ): NullSchemaBuilder<\n TRequired,\n TNullable,\n null & { readonly [K in BRAND]: TBrand },\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.brand(_name);\n }\n\n /**\n * Marks the inferred type as `Readonly<null>`. Since `null` is already\n * immutable this is an identity operation, but it sets the `isReadonly`\n * introspection flag for tooling consistency.\n *\n * @see {@link SchemaBuilder.readonly}\n */\n public readonly(): NullSchemaBuilder<\n TRequired,\n TNullable,\n Readonly<null>,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * @hidden\n */\n public nullable(): NullSchemaBuilder<\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(): NullSchemaBuilder<\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 schema that validates the value is exactly `null`.\n *\n * By default the schema is **required** — only `null` is accepted.\n * Call `.optional()` to also allow `undefined`.\n *\n * @example\n * ```ts\n * import { nul } from '@cleverbrush/schema';\n *\n * nul().validate(null); // { valid: true, object: null }\n * nul().validate(undefined); // { valid: false }\n * nul().validate(0); // { valid: false }\n * ```\n *\n * @example\n * ```ts\n * nul().optional().validate(null); // { valid: true, object: null }\n * nul().optional().validate(undefined); // { valid: true, object: undefined }\n * nul().optional().validate(false); // { valid: false }\n * ```\n *\n * @example\n * ```ts\n * // Nullable field in an object schema\n * import { object, string, nul, union, InferType } from '@cleverbrush/schema';\n *\n * const Schema = object({\n * name: string(),\n * deleted: union(nul()).or(string()), // null | string\n * });\n *\n * type T = InferType<typeof Schema>;\n * // { name: string; deleted: null | string }\n * ```\n */\nexport const nul = () =>\n NullSchemaBuilder.create({\n isRequired: true\n }) as NullSchemaBuilder<true>;\n"],"mappings":"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","names":["IntersectionSchemaBuilder","_IntersectionSchemaBuilder","SchemaBuilder","#left","#right","props","_notUsed","object","context","#mergeObjects","leftObj","rightObj","#createValidationSetup","superResult","valid","preValidationTransaction","prevalidationContext","errors","objToValidate","leftResult","rightResult","#validateFull","setup","errorMessage","value","_name","intersection","left","right","LazySchemaBuilder","_LazySchemaBuilder","SchemaBuilder","#getter","#resolvedSchema","props","#buildResult","superResult","context","valid","preValidationTransaction","errors","objToValidate","object","_notUsed","errorMessage","value","_name","lazy","getter","NullSchemaBuilder","_NullSchemaBuilder","SchemaBuilder","props","_notUsed","#buildResult","object","context","_context","errorMessage","value","_name","nul"]}
|
package/dist/chunk-XL723XFL.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{f as m}from"./chunk-REYZ7G7J.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-XL723XFL.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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/chunk-XPLTW5DI.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{f as n}from"./chunk-REYZ7G7J.js";var a=class l extends n{static create(e){return new l({type:"any",...e})}constructor(e){super(e)}hasType(e){return this.createFromProps({...this.introspect()})}clearHasType(){return this.createFromProps({...this.introspect()})}#e(e){let{valid:t,transaction:s,errors:i}=e;if(!t)return{valid:t,errors:i};let{object:{validatedObject:r}}=s;return{valid:!0,object:r}}validate(e,t){return super.validate(e,t)}async validateAsync(e,t){return super.validateAsync(e,t)}_validate(e,t){return this.#e(this.preValidateSync(e,t))}async _validateAsync(e,t){return this.#e(await super.preValidateAsync(e,t))}createFromProps(e){return l.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()}},o=()=>a.create({isRequired:!0});export{a,o as b};
|
|
2
|
-
//# sourceMappingURL=chunk-XPLTW5DI.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/builders/AnySchemaBuilder.ts"],"sourcesContent":["import {\n type BRAND,\n SchemaBuilder,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\n\ntype AnySchemaBuilderCreateProps<R extends boolean = true> = Partial<\n ReturnType<AnySchemaBuilder<R>['introspect']>\n>;\n\n/**\n * Any schema builder class. Similar to the `any` type\n * in TypeScript. Allows to define a schema for `any` value.\n * Use it when you don't know the type of the value.\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 `any()` function instead.\n *\n * @example\n * ```ts\n * const schema = any();\n * const result = schema.validate(123);\n * // result.valid === true\n * // result.object === 123\n * ```\n */\nexport class AnySchemaBuilder<\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 ? any : TExplicitType\n> extends SchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n /**\n * @hidden\n */\n public static create(props: AnySchemaBuilderCreateProps<any>) {\n return new AnySchemaBuilder({\n type: 'any',\n ...props\n });\n }\n\n protected constructor(props: AnySchemaBuilderCreateProps<TRequired>) {\n super(props as any);\n }\n\n /**\n * @inheritdoc\n */\n public hasType<T>(\n _notUsed?: T\n ): AnySchemaBuilder<true, TNullable, T, 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(): AnySchemaBuilder<\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 #buildResult(\n superResult: ReturnType<AnySchemaBuilder['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 return { valid: true, object: objToValidate };\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: AnySchemaBuilderCreateProps<TReq>\n ): this {\n return AnySchemaBuilder.create(props as any) as any;\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): AnySchemaBuilder<\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(): AnySchemaBuilder<\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 ): AnySchemaBuilder<true, TNullable, TExplicitType, true, TExtensions> &\n TExtensions {\n return super.default(value) as any;\n }\n\n /**\n * @hidden\n */\n public clearDefault(): AnySchemaBuilder<\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 ): AnySchemaBuilder<\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 * Marks the inferred type as `Readonly<T>`. Sets the `isReadonly`\n * introspection flag for tooling consistency.\n *\n * @see {@link SchemaBuilder.readonly}\n */\n public readonly(): AnySchemaBuilder<\n TRequired,\n TNullable,\n Readonly<TResult>,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * @hidden\n */\n public nullable(): AnySchemaBuilder<\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(): AnySchemaBuilder<\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 `any` schema.\n * @example\n * ```\n * const anyObject = any();\n *\n * // null - invalid\n * // undefined - invalid\n * // string - valid\n * // {} - valid\n * // Date -valid\n * // { someProp: 123 } - valid\n * // etc\n * ```\n * @example\n * ```\n * const anyObject = any().optional();\n * // null - valid\n * // undefined - valid\n * // string - valid\n * // {} - valid\n * // Date -valid\n * // { someProp: 123 } - valid\n * ```\n */\nexport const any = () =>\n AnySchemaBuilder.create({\n isRequired: true\n }) as AnySchemaBuilder<true>;\n"],"mappings":"wCA6BO,IAAMA,EAAN,MAAMC,UAOHC,CAMR,CAIE,OAAc,OAAOC,EAAyC,CAC1D,OAAO,IAAIF,EAAiB,CACxB,KAAM,MACN,GAAGE,CACP,CAAC,CACL,CAEU,YAAYA,EAA+C,CACjE,MAAMA,CAAY,CACtB,CAKO,QACHC,EAEY,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,CACvB,CAAQ,CACZ,CAKO,cAOS,CACZ,OAAO,KAAK,gBAAgB,CACxB,GAAG,KAAK,WAAW,CACvB,CAAQ,CACZ,CAEAC,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,MAAO,CAAE,MAAO,GAAM,OAAQE,CAAc,CAChD,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,OAAOF,EAAiB,OAAOE,CAAY,CAC/C,CAKO,SACHU,EAQY,CACZ,OAAO,MAAM,SAASA,CAAY,CACtC,CAKO,UAOS,CACZ,OAAO,MAAM,SAAS,CAC1B,CAKO,QACHC,EAEY,CACZ,OAAO,MAAM,QAAQA,CAAK,CAC9B,CAKO,cAOS,CACZ,OAAO,MAAM,aAAa,CAC9B,CAKO,MACHC,EAQY,CACZ,OAAO,MAAM,MAAMA,CAAK,CAC5B,CAQO,UAOS,CACZ,OAAO,MAAM,SAAS,CAC1B,CAKO,UAOS,CACZ,OAAO,MAAM,SAAS,CAC1B,CAKO,aAOS,CACZ,OAAO,MAAM,YAAY,CAC7B,CACJ,EA2BaC,EAAM,IACfhB,EAAiB,OAAO,CACpB,WAAY,EAChB,CAAC","names":["AnySchemaBuilder","_AnySchemaBuilder","SchemaBuilder","props","_notUsed","#buildResult","superResult","valid","preValidationTransaction","errors","objToValidate","object","context","errorMessage","value","_name","any"]}
|
package/dist/chunk-YAOZEA2R.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{d as p,f as h}from"./chunk-REYZ7G7J.js";function S(s){return typeof s=="object"&&s!==null&&"key"in s?String(s.key):String(s)}function m(s){return s.map(S).join(".")}var T=class s extends h{#e;[p]=!0;static create(e){return new s({type:"extern",...e})}constructor(e){super(e),this.#e=e.standardSchema}get standardSchema(){return this.#e}hasType(e){return this.createFromProps({...this.introspect()})}clearHasType(){return this.createFromProps({...this.introspect()})}#a(e){return e.map(t=>({message:t.path&&t.path.length>0?`${m(t.path)}: ${t.message}`:t.message}))}#t(e,t){let i=new Map,o=[];for(let r of e)if(r.path&&r.path.length>0){let a=S(r.path[0]),d=r.path.slice(1),c=d.length>0?`${m(d)}: ${r.message}`:r.message;i.has(a)||(i.set(a,[]),o.push(a)),i.get(a).push(c)}let l=new WeakMap,n=t?.currentPropertyDescriptor;if(n)for(let r of o){let a=n[r];a&&typeof a=="object"&&l.set(a,r)}return{fn:r=>{let a;if(typeof r=="function"?a=r(n):a=n,!a||typeof a!="object")return{isValid:!0,errors:[]};let d=l.get(a),c=d?i.get(d)||[]:[];return{isValid:c.length===0,errors:c}},errorPropertyNames:o}}validate(e,t){return super.validate(e,t)}async validateAsync(e,t){return super.validateAsync(e,t)}_validate(e,t){let i=this.preValidateSync(e,t);if(!i.valid)return{valid:!1,errors:i.errors};let{transaction:o}=i,l=o.object.validatedObject;if(l==null)return{valid:!0,object:l};let n=this.#e["~standard"].validate(l);if(n instanceof Promise)throw new Error("The external Standard Schema returned a Promise from validate(). Use validateAsync() for schemas with async validation.");if("value"in n){let{fn:a}=this.#t([],t);return{valid:!0,object:n.value,getErrorsFor:a}}let{fn:u,errorPropertyNames:r}=this.#t(n.issues,t);return{valid:!1,errors:this.#a(n.issues),getErrorsFor:u,__externErrorPropertyNames:r}}async _validateAsync(e,t){let i=await this.preValidateAsync(e,t);if(!i.valid)return{valid:!1,errors:i.errors};let{transaction:o}=i,l=o.object.validatedObject;if(l==null)return{valid:!0,object:l};let n=await this.#e["~standard"].validate(l);if("value"in n){let{fn:a}=this.#t([],t);return{valid:!0,object:n.value,getErrorsFor:a}}let{fn:u,errorPropertyNames:r}=this.#t(n.issues,t);return{valid:!1,errors:this.#a(n.issues),getErrorsFor:u,__externErrorPropertyNames:r}}createFromProps(e){return s.create(e)}introspect(){return{...super.introspect(),standardSchema:this.#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()}},f=s=>T.create({isRequired:!0,standardSchema:s});export{T as a,f as b};
|
|
2
|
-
//# sourceMappingURL=chunk-YAOZEA2R.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/builders/ExternSchemaBuilder.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n type BRAND,\n SchemaBuilder,\n SYMBOL_HAS_PROPERTIES,\n type ValidationContext,\n type ValidationErrorMessageProvider,\n type ValidationResult\n} from './SchemaBuilder.js';\n\ntype ExternSchemaBuilderCreateProps<R extends boolean = true> = Partial<\n ReturnType<ExternSchemaBuilder<any, R>['introspect']>\n> & {\n standardSchema: StandardSchemaV1;\n};\n\n/**\n * Extracts the first path segment from a Standard Schema issue path entry\n * as a string.\n */\nfunction firstPathSegmentStr(\n segment: PropertyKey | StandardSchemaV1.PathSegment\n): string {\n return typeof segment === 'object' && segment !== null && 'key' in segment\n ? String(segment.key)\n : String(segment);\n}\n\n/**\n * Formats a Standard Schema issue path into a dotted string.\n *\n * Standard Schema paths may contain bare `PropertyKey` values (string, number,\n * symbol) or `PathSegment` objects with a `.key` property.\n *\n * @example\n * ```\n * formatIssuePath(['address', 'city']) // → 'address.city'\n * formatIssuePath([{ key: 'items' }, 0]) // → 'items.0'\n * ```\n */\nfunction formatIssuePath(\n path: ReadonlyArray<PropertyKey | StandardSchemaV1.PathSegment>\n): string {\n return path.map(firstPathSegmentStr).join('.');\n}\n\n/**\n * Schema builder that wraps an external\n * [Standard Schema v1](https://standardschema.dev/) compatible schema\n * (e.g. Zod, Valibot, ArkType) into a `@cleverbrush/schema` builder.\n *\n * This enables cross-library schema composition — you can use a Zod schema\n * as a property inside a `@cleverbrush/schema` object schema, and the\n * inferred TypeScript type will be correct.\n *\n * Validation is delegated entirely to the external schema's\n * `['~standard'].validate()` method. Standard Schema issues are mapped to\n * `@cleverbrush/schema` `ValidationError` objects, with any issue paths\n * formatted as dotted prefixes (e.g. `\"address.city: must be a string\"`).\n *\n * When used inside an `object()` schema, the property descriptor tree is\n * built dynamically (via Proxy) from the external schema's output type,\n * so `getErrorsFor(t => t.order.id)` works without any additional\n * configuration.\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 the {@link extern | extern()} factory function instead.\n *\n * @example\n * ```ts\n * import { z } from 'zod';\n * import { object, date, extern, InferType } from '@cleverbrush/schema';\n *\n * const zodUser = z.object({ first: z.string(), last: z.string() });\n *\n * const order = object({\n * user: extern(zodUser),\n * date: date(),\n * });\n *\n * type Order = InferType<typeof order>;\n * // { user: { first: string; last: string }; date: Date }\n * ```\n *\n * @see {@link extern}\n */\nexport class ExternSchemaBuilder<\n TStandardSchema extends StandardSchemaV1 = StandardSchemaV1,\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 ? StandardSchemaV1.InferOutput<TStandardSchema>\n : TExplicitType\n> extends SchemaBuilder<\n TResult,\n TRequired,\n TNullable,\n THasDefault,\n TExtensions\n> {\n #standardSchema: TStandardSchema;\n\n /**\n * Always `true` for extern schemas — enables Proxy-based property\n * descriptor trees and nested error propagation in\n * `ObjectSchemaBuilder`.\n */\n readonly [SYMBOL_HAS_PROPERTIES] = true;\n\n /**\n * @hidden\n */\n public static create(props: ExternSchemaBuilderCreateProps<any>) {\n return new ExternSchemaBuilder({\n type: 'extern',\n ...props\n });\n }\n\n protected constructor(props: ExternSchemaBuilderCreateProps<TRequired>) {\n super(props as any);\n this.#standardSchema = props.standardSchema as TStandardSchema;\n }\n\n /**\n * Returns the wrapped Standard Schema instance.\n */\n public get standardSchema(): TStandardSchema {\n return this.#standardSchema;\n }\n\n /**\n * @inheritdoc\n */\n public hasType<T>(\n _notUsed?: T\n ): ExternSchemaBuilder<\n TStandardSchema,\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(): ExternSchemaBuilder<\n TStandardSchema,\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 * Maps a Standard Schema failure result into the library's\n * `ValidationError[]` format.\n */\n #mapIssues(\n issues: ReadonlyArray<StandardSchemaV1.Issue>\n ): { message: string }[] {\n return issues.map(issue => ({\n message:\n issue.path && issue.path.length > 0\n ? `${formatIssuePath(issue.path)}: ${issue.message}`\n : issue.message\n }));\n }\n\n /**\n * Builds a `getErrorsFor` function that maps Standard Schema issue\n * paths to per-property error lists via the Proxy-based property\n * descriptor tree.\n *\n * The function groups issues by their first path segment, then builds\n * a WeakMap from each Proxy-created child descriptor to its property\n * name so that `getErrorsFor(() => descriptor)` can look up errors.\n */\n #buildGetErrorsFor(\n issues: ReadonlyArray<StandardSchemaV1.Issue>,\n context?: ValidationContext\n ): {\n fn: (selector?: Function) => { isValid: boolean; errors: string[] };\n errorPropertyNames: string[];\n } {\n const errorsByProperty = new Map<string, string[]>();\n const errorPropertyNames: string[] = [];\n\n for (const issue of issues) {\n if (issue.path && issue.path.length > 0) {\n const firstName = firstPathSegmentStr(issue.path[0]);\n\n const restPath = issue.path.slice(1);\n const message =\n restPath.length > 0\n ? `${formatIssuePath(restPath)}: ${issue.message}`\n : issue.message;\n\n if (!errorsByProperty.has(firstName)) {\n errorsByProperty.set(firstName, []);\n errorPropertyNames.push(firstName);\n }\n errorsByProperty.get(firstName)!.push(message);\n }\n }\n\n // Build reverse map: access each error property on the Proxy\n // descriptor to create (and cache) the child, then map it back\n // to the property name.\n const descriptorToName = new WeakMap<object, string>();\n const currentPropertyDescriptor = context?.currentPropertyDescriptor;\n if (currentPropertyDescriptor) {\n for (const name of errorPropertyNames) {\n const desc = (currentPropertyDescriptor as any)[name];\n if (desc && typeof desc === 'object') {\n descriptorToName.set(desc, name);\n }\n }\n }\n\n const fn = (selector?: Function) => {\n let descriptor: any;\n if (typeof selector === 'function') {\n descriptor = selector(currentPropertyDescriptor);\n } else {\n descriptor = currentPropertyDescriptor;\n }\n\n if (!descriptor || typeof descriptor !== 'object') {\n return { isValid: true, errors: [] };\n }\n\n const propName = descriptorToName.get(descriptor);\n const errors = propName ? errorsByProperty.get(propName) || [] : [];\n\n return {\n isValid: errors.length === 0,\n errors\n };\n };\n\n return { fn, errorPropertyNames };\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 by delegating to the external\n * Standard Schema's `validate()` method.\n *\n * If the external schema returns a `Promise` (async validation),\n * this method throws — use {@link validateAsync} instead.\n */\n protected _validate(\n object: TResult,\n context?: ValidationContext\n ): ValidationResult<TResult> {\n const superResult = this.preValidateSync(object, context);\n\n if (!superResult.valid) {\n return { valid: false, errors: superResult.errors };\n }\n\n const { transaction: preValidationTransaction } = superResult;\n\n const objToValidate = preValidationTransaction!.object.validatedObject;\n\n // When the value is null/undefined and preValidation accepted it\n // (optional or nullable), return early without calling the external\n // schema — it would likely reject these sentinel values.\n if (objToValidate === undefined || objToValidate === null) {\n return { valid: true, object: objToValidate };\n }\n\n const result =\n this.#standardSchema['~standard'].validate(objToValidate);\n\n if (result instanceof Promise) {\n throw new Error(\n 'The external Standard Schema returned a Promise from validate(). ' +\n 'Use validateAsync() for schemas with async validation.'\n );\n }\n\n if ('value' in result) {\n const { fn } = this.#buildGetErrorsFor([], context);\n return {\n valid: true,\n object: result.value as TResult,\n getErrorsFor: fn\n } as any;\n }\n\n const { fn, errorPropertyNames } = this.#buildGetErrorsFor(\n result.issues,\n context\n );\n return {\n valid: false,\n errors: this.#mapIssues(result.issues),\n getErrorsFor: fn,\n __externErrorPropertyNames: errorPropertyNames\n } as any;\n }\n\n /**\n * Performs async validation by delegating to the external\n * Standard Schema's `validate()` method. Supports external schemas\n * that return a `Promise` from their `validate()`.\n */\n protected async _validateAsync(\n object: TResult,\n context?: ValidationContext\n ): Promise<ValidationResult<TResult>> {\n const superResult = await this.preValidateAsync(object, context);\n\n if (!superResult.valid) {\n return { valid: false, errors: superResult.errors };\n }\n\n const { transaction: preValidationTransaction } = superResult;\n\n const objToValidate = preValidationTransaction!.object.validatedObject;\n\n if (objToValidate === undefined || objToValidate === null) {\n return { valid: true, object: objToValidate };\n }\n\n const result =\n await this.#standardSchema['~standard'].validate(objToValidate);\n\n if ('value' in result) {\n const { fn } = this.#buildGetErrorsFor([], context);\n return {\n valid: true,\n object: result.value as TResult,\n getErrorsFor: fn\n } as any;\n }\n\n const { fn, errorPropertyNames } = this.#buildGetErrorsFor(\n result.issues,\n context\n );\n return {\n valid: false,\n errors: this.#mapIssues(result.issues),\n getErrorsFor: fn,\n __externErrorPropertyNames: errorPropertyNames\n } as any;\n }\n\n protected createFromProps<TReq extends boolean>(\n props: ExternSchemaBuilderCreateProps<TReq>\n ): this {\n return ExternSchemaBuilder.create(props as any) as any;\n }\n\n /**\n * Returns a snapshot of the builder's internal state.\n * Includes the wrapped `standardSchema` reference.\n */\n public introspect() {\n return {\n ...super.introspect(),\n standardSchema: this.#standardSchema\n };\n }\n\n /**\n * @hidden\n */\n public required(\n errorMessage?: ValidationErrorMessageProvider\n ): ExternSchemaBuilder<\n TStandardSchema,\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(): ExternSchemaBuilder<\n TStandardSchema,\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 ): ExternSchemaBuilder<\n TStandardSchema,\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(): ExternSchemaBuilder<\n TStandardSchema,\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 ): ExternSchemaBuilder<\n TStandardSchema,\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 * Marks the inferred type as `Readonly<T>`. Sets the `isReadonly`\n * introspection flag for tooling consistency.\n *\n * @see {@link SchemaBuilder.readonly}\n */\n public readonly(): ExternSchemaBuilder<\n TStandardSchema,\n TRequired,\n TNullable,\n Readonly<TResult>,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.readonly();\n }\n\n /**\n * @hidden\n */\n public nullable(): ExternSchemaBuilder<\n TStandardSchema,\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(): ExternSchemaBuilder<\n TStandardSchema,\n TRequired,\n false,\n TExplicitType,\n THasDefault,\n TExtensions\n > &\n TExtensions {\n return super.notNullable() as any;\n }\n}\n\n/**\n * Wraps an external [Standard Schema v1](https://standardschema.dev/)\n * compatible schema into a `@cleverbrush/schema` builder.\n *\n * This enables cross-library schema composition — use schemas from Zod,\n * Valibot, ArkType, or any Standard Schema v1 compliant library as\n * properties inside `@cleverbrush/schema` object schemas with full type\n * inference.\n *\n * @param standardSchema - A Standard Schema v1 compliant schema instance\n * (any object that exposes a `['~standard']` property with `version: 1`\n * and a `validate` function).\n *\n * @example\n * ```ts\n * import { z } from 'zod';\n * import { object, date, extern, InferType } from '@cleverbrush/schema';\n *\n * const zodUser = z.object({ first: z.string(), last: z.string() });\n *\n * const order = object({\n * user: extern(zodUser),\n * date: date(),\n * });\n *\n * type Order = InferType<typeof order>;\n * // { user: { first: string; last: string }; date: Date }\n *\n * order.validate({\n * user: { first: 'Alice', last: 'Smith' },\n * date: new Date(),\n * }); // { valid: true, object: { user: …, date: … } }\n * ```\n *\n * @example\n * ```ts\n * // Optional external schema\n * const schema = extern(zodUser).optional();\n * schema.validate(undefined); // valid\n * ```\n *\n * @example\n * ```ts\n * // Inside an array\n * import { array, extern } from '@cleverbrush/schema';\n * const users = array(extern(zodUser));\n * ```\n */\nexport const extern = <T extends StandardSchemaV1>(standardSchema: T) =>\n ExternSchemaBuilder.create({\n isRequired: true,\n standardSchema\n }) as ExternSchemaBuilder<T, true>;\n"],"mappings":"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","names":["firstPathSegmentStr","segment","formatIssuePath","path","ExternSchemaBuilder","_ExternSchemaBuilder","SchemaBuilder","#standardSchema","SYMBOL_HAS_PROPERTIES","props","_notUsed","#mapIssues","issues","issue","#buildGetErrorsFor","context","errorsByProperty","errorPropertyNames","firstName","restPath","message","descriptorToName","currentPropertyDescriptor","name","desc","selector","descriptor","propName","errors","object","superResult","preValidationTransaction","objToValidate","result","fn","errorMessage","value","_name","extern","standardSchema"]}
|