@cleverbrush/schema 3.0.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +14 -2
  2. package/dist/builders/AnySchemaBuilder.js +1 -1
  3. package/dist/builders/ArraySchemaBuilder.js +1 -1
  4. package/dist/builders/BooleanSchemaBuilder.js +1 -1
  5. package/dist/builders/DateSchemaBuilder.js +1 -1
  6. package/dist/builders/ExternSchemaBuilder.js +1 -1
  7. package/dist/builders/FunctionSchemaBuilder.js +1 -1
  8. package/dist/builders/NumberSchemaBuilder.js +1 -1
  9. package/dist/builders/ObjectSchemaBuilder.js +1 -1
  10. package/dist/builders/ParseStringSchemaBuilder.d.ts +9 -0
  11. package/dist/builders/ParseStringSchemaBuilder.js +1 -1
  12. package/dist/builders/PromiseSchemaBuilder.js +1 -1
  13. package/dist/builders/RecordSchemaBuilder.js +1 -1
  14. package/dist/builders/SchemaBuilder.d.ts +13 -7
  15. package/dist/builders/StringSchemaBuilder.js +1 -1
  16. package/dist/builders/TupleSchemaBuilder.js +1 -1
  17. package/dist/builders/UnionSchemaBuilder.js +1 -1
  18. package/dist/{chunk-NUW3VXZV.js → chunk-3K7MOEPS.js} +2 -2
  19. package/dist/{chunk-K6Z47OQY.js → chunk-4RMOR7SV.js} +2 -2
  20. package/dist/{chunk-ZFI27R3L.js → chunk-57AZDIBB.js} +2 -2
  21. package/dist/chunk-C4LSLV6T.js +2 -0
  22. package/dist/chunk-C4LSLV6T.js.map +1 -0
  23. package/dist/{chunk-WQDYWDOE.js → chunk-EBGC6ZBF.js} +2 -2
  24. package/dist/{chunk-CFIJQ4GP.js → chunk-ETJPB3TR.js} +2 -2
  25. package/dist/{chunk-WDMJBGBD.js → chunk-FTA66XZT.js} +2 -2
  26. package/dist/{chunk-3JMDGYDT.js → chunk-G6HTNXRO.js} +1 -1
  27. package/dist/chunk-G6HTNXRO.js.map +1 -0
  28. package/dist/{chunk-ZC6YBKCP.js → chunk-OJJHAZZ4.js} +2 -2
  29. package/dist/{chunk-BUEVZ3KA.js → chunk-PUWIYD4T.js} +2 -2
  30. package/dist/{chunk-YQZHDMRF.js → chunk-QG254RGI.js} +2 -2
  31. package/dist/{chunk-PHE4LIAN.js → chunk-QWYVMYJ2.js} +2 -2
  32. package/dist/chunk-SY5EYKF2.js +2 -0
  33. package/dist/chunk-SY5EYKF2.js.map +1 -0
  34. package/dist/{chunk-QARCEYGO.js → chunk-VRRKXJ2H.js} +2 -2
  35. package/dist/{chunk-EIVZX4ZO.js → chunk-YYE5HQCL.js} +2 -2
  36. package/dist/chunk-ZC2HTRZF.js +2 -0
  37. package/dist/chunk-ZC2HTRZF.js.map +1 -0
  38. package/dist/{chunk-HN774HD7.js → chunk-ZHBJ46HB.js} +2 -2
  39. package/dist/core.d.ts +2 -2
  40. package/dist/core.js +1 -1
  41. package/dist/extension.d.ts +76 -4
  42. package/dist/extension.js +2 -0
  43. package/dist/extension.js.map +1 -0
  44. package/dist/index.js +1 -1
  45. package/dist/index.js.map +1 -1
  46. package/package.json +6 -2
  47. package/dist/chunk-3JMDGYDT.js.map +0 -1
  48. package/dist/chunk-DY7J6RNN.js +0 -2
  49. package/dist/chunk-DY7J6RNN.js.map +0 -1
  50. package/dist/chunk-GXPV6UQK.js +0 -2
  51. package/dist/chunk-GXPV6UQK.js.map +0 -1
  52. /package/dist/{chunk-NUW3VXZV.js.map → chunk-3K7MOEPS.js.map} +0 -0
  53. /package/dist/{chunk-K6Z47OQY.js.map → chunk-4RMOR7SV.js.map} +0 -0
  54. /package/dist/{chunk-ZFI27R3L.js.map → chunk-57AZDIBB.js.map} +0 -0
  55. /package/dist/{chunk-WQDYWDOE.js.map → chunk-EBGC6ZBF.js.map} +0 -0
  56. /package/dist/{chunk-CFIJQ4GP.js.map → chunk-ETJPB3TR.js.map} +0 -0
  57. /package/dist/{chunk-WDMJBGBD.js.map → chunk-FTA66XZT.js.map} +0 -0
  58. /package/dist/{chunk-ZC6YBKCP.js.map → chunk-OJJHAZZ4.js.map} +0 -0
  59. /package/dist/{chunk-BUEVZ3KA.js.map → chunk-PUWIYD4T.js.map} +0 -0
  60. /package/dist/{chunk-YQZHDMRF.js.map → chunk-QG254RGI.js.map} +0 -0
  61. /package/dist/{chunk-PHE4LIAN.js.map → chunk-QWYVMYJ2.js.map} +0 -0
  62. /package/dist/{chunk-QARCEYGO.js.map → chunk-VRRKXJ2H.js.map} +0 -0
  63. /package/dist/{chunk-EIVZX4ZO.js.map → chunk-YYE5HQCL.js.map} +0 -0
  64. /package/dist/{chunk-HN774HD7.js.map → chunk-ZHBJ46HB.js.map} +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/extensions/util.ts","../src/extensions/array.ts","../src/extensions/number.ts","../src/extensions/string.ts","../src/extensions/index.ts"],"sourcesContent":["import type { ValidationErrorMessageProvider } from '../builders/SchemaBuilder.js';\n\n/** Validation result returned by validators on failure. */\ninterface ValidationFailure {\n valid: false;\n errors: { message: string }[];\n}\n\n/**\n * Builds a synchronous validation-failure result, resolving the user-supplied\n * error-message provider (or falling back to `defaultMsg`).\n *\n * @param provider - custom error message provider (string, sync function, or `undefined`)\n * @param defaultMsg - fallback message used when `provider` is `undefined`\n * @param value - the value that failed validation\n * @param schema - the schema builder instance\n * @returns a `{ valid: false, errors: [{ message }] }` object\n */\nexport function validationFail(\n provider: ValidationErrorMessageProvider<any> | undefined,\n defaultMsg: string,\n value: unknown,\n schema: unknown\n): ValidationFailure {\n const msg = resolveErrorMessage(provider, defaultMsg, value, schema);\n return { valid: false, errors: [{ message: msg }] };\n}\n\n/**\n * Synchronously resolves a {@link ValidationErrorMessageProvider} to a concrete error message string.\n * Returns the default message when no custom provider is supplied.\n * Throws if the provider function returns a Promise.\n *\n * @param provider - custom error message provider (string, sync function, or `undefined`)\n * @param defaultMsg - fallback message used when `provider` is `undefined`\n * @param value - the value that failed validation (passed to function providers)\n * @param schema - the schema builder instance (passed to function providers)\n * @returns the resolved error message string\n * @throws Error if the provider returns a Promise\n */\nexport function resolveErrorMessage(\n provider: ValidationErrorMessageProvider<any> | undefined,\n defaultMsg: string,\n value: unknown,\n schema: unknown\n): string {\n if (provider === undefined) return defaultMsg;\n if (typeof provider === 'string') return provider;\n const result = provider(value, schema);\n if (result instanceof Promise) {\n throw new Error(\n 'Async error message providers require validateAsync(). Use a string or sync function instead.'\n );\n }\n return result;\n}\n\n/**\n * Asynchronously resolves a {@link ValidationErrorMessageProvider} to a concrete error message string.\n * Returns the default message when no custom provider is supplied.\n * Supports async provider functions.\n *\n * @param provider - custom error message provider (string, function, or `undefined`)\n * @param defaultMsg - fallback message used when `provider` is `undefined`\n * @param value - the value that failed validation (passed to function providers)\n * @param schema - the schema builder instance (passed to function providers)\n * @returns the resolved error message string\n */\nexport async function resolveErrorMessageAsync(\n provider: ValidationErrorMessageProvider<any> | undefined,\n defaultMsg: string,\n value: unknown,\n schema: unknown\n): Promise<string> {\n if (provider === undefined) return defaultMsg;\n if (typeof provider === 'string') return provider;\n return provider(value, schema);\n}\n","/**\n * Built-in array extensions for `@cleverbrush/schema`.\n *\n * Provides common array validators: {@link arrayExtensions | nonempty}\n * and {@link arrayExtensions | unique}.\n *\n * These are pre-applied in the default `@cleverbrush/schema` import.\n * Import from `@cleverbrush/schema/core` to get bare builders without these extensions.\n *\n * @module\n */\nimport type { ArraySchemaBuilder } from '../builders/ArraySchemaBuilder.js';\nimport type {\n SchemaBuilder,\n ValidationErrorMessageProvider\n} from '../builders/SchemaBuilder.js';\nimport type { HiddenExtensionMethods } from '../extension.js';\nimport { defineExtension } from '../extension.js';\nimport { validationFail } from './util.js';\n\n// ---------------------------------------------------------------------------\n// Public interface — carries JSDoc into .d.ts for consumers\n// ---------------------------------------------------------------------------\n\n/** Return type shared by every method on {@link ArrayBuiltinExtensions}. */\ntype ArrayExtReturn<\n TElementSchema extends SchemaBuilder<\n any,\n any,\n any,\n any,\n any\n > = SchemaBuilder<any, any, any>\n> = ArraySchemaBuilder<\n TElementSchema,\n true,\n false,\n undefined,\n false,\n ArrayBuiltinExtensions<TElementSchema>\n> &\n ArrayBuiltinExtensions<TElementSchema> &\n HiddenExtensionMethods;\n\n/**\n * Methods added to `ArraySchemaBuilder` by the built-in array extension pack.\n *\n * **WORKAROUND:** This interface duplicates the method signatures from\n * `arrayExtensions` so that JSDoc survives into the published `.d.ts`\n * files. TypeScript strips JSDoc when method signatures are reconstructed\n * through the `FixedMethods` mapped type (conditional `infer` loses\n * comments). Remove this interface once TypeScript preserves JSDoc\n * through mapped types / conditional type inference.\n *\n * @see https://github.com/microsoft/TypeScript/issues/50715\n */\nexport interface ArrayBuiltinExtensions<\n TElementSchema extends SchemaBuilder<\n any,\n any,\n any,\n any,\n any\n > = SchemaBuilder<any, any, any>\n> {\n /**\n * Validates that the array contains at least one element.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the nonempty validator applied\n *\n * @example\n * ```ts\n * array().nonempty();\n * array().nonempty('At least one item required');\n * ```\n */\n nonempty(\n errorMessage?: ValidationErrorMessageProvider<ArraySchemaBuilder<any>>\n ): ArrayExtReturn<TElementSchema>;\n\n /**\n * Validates that all elements in the array are unique.\n *\n * For primitive elements, uses strict equality. For objects, pass a `keyFn`\n * that extracts a comparison key from each element.\n *\n * @param keyFn - optional function to extract a comparison key from each element\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the unique validator applied\n *\n * @example\n * ```ts\n * array().unique();\n * array().unique((item) => item.id);\n * array().unique(undefined, 'No duplicates allowed');\n * ```\n */\n unique(\n keyFn?: (item: any) => unknown,\n errorMessage?: ValidationErrorMessageProvider<ArraySchemaBuilder<any>>\n ): ArrayExtReturn<TElementSchema>;\n}\n\n/**\n * Extension descriptor that adds common array validators\n * to `ArraySchemaBuilder`.\n *\n * Included methods: `nonempty`, `unique`.\n *\n * @example\n * ```ts\n * import { withExtensions } from '@cleverbrush/schema/core';\n * import { arrayExtensions } from '@cleverbrush/schema';\n *\n * const s = withExtensions(arrayExtensions);\n * const schema = s.array().nonempty().unique();\n * ```\n */\nexport const arrayExtensions = defineExtension({\n array: {\n /**\n * Validates that the array contains at least one element.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the nonempty validator applied\n *\n * @example\n * ```ts\n * array().nonempty();\n * array().nonempty('At least one item required');\n * ```\n */\n nonempty(\n this: ArraySchemaBuilder<any>,\n errorMessage?: ValidationErrorMessageProvider<\n ArraySchemaBuilder<any>\n >\n ) {\n return this.withExtension('nonempty', true).addValidator(\n (val: unknown[]) => {\n if (!Array.isArray(val))\n return validationFail(\n errorMessage,\n 'must not be empty',\n val,\n this\n );\n const valid = val.length > 0;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must not be empty',\n val,\n this\n );\n }\n );\n },\n\n /**\n * Validates that all elements in the array are unique.\n *\n * For primitive elements, uses strict equality. For objects, pass a `keyFn`\n * that extracts a comparison key from each element.\n *\n * @param keyFn - optional function to extract a comparison key from each element\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the unique validator applied\n *\n * @example\n * ```ts\n * array().unique();\n * array().unique((item) => item.id);\n * array().unique(undefined, 'No duplicates allowed');\n * ```\n */\n unique(\n this: ArraySchemaBuilder<any>,\n keyFn?: (item: any) => unknown,\n errorMessage?: ValidationErrorMessageProvider<\n ArraySchemaBuilder<any>\n >\n ) {\n const meta = keyFn ?? true;\n\n return this.withExtension('unique', meta).addValidator(\n (val: unknown[]) => {\n if (!Array.isArray(val))\n return validationFail(\n errorMessage,\n 'must contain unique elements',\n val,\n this\n );\n const seen = new Set();\n for (const item of val) {\n const key = keyFn ? keyFn(item) : item;\n if (seen.has(key)) {\n return validationFail(\n errorMessage,\n 'must contain unique elements',\n val,\n this\n );\n }\n seen.add(key);\n }\n return { valid: true, errors: [] };\n }\n );\n }\n }\n});\n","/**\n * Built-in number extensions for `@cleverbrush/schema`.\n *\n * Provides common number validators: {@link numberExtensions | positive},\n * {@link numberExtensions | negative}, {@link numberExtensions | finite},\n * {@link numberExtensions | multipleOf}, and {@link numberExtensions | oneOf}.\n *\n * These are pre-applied in the default `@cleverbrush/schema` import.\n * Import from `@cleverbrush/schema/core` to get bare builders without these extensions.\n *\n * @module\n */\nimport type { NumberSchemaBuilder } from '../builders/NumberSchemaBuilder.js';\nimport type { ValidationErrorMessageProvider } from '../builders/SchemaBuilder.js';\nimport type { HiddenExtensionMethods } from '../extension.js';\nimport { defineExtension } from '../extension.js';\nimport { validationFail } from './util.js';\n\n// ---------------------------------------------------------------------------\n// Public interface — carries JSDoc into .d.ts for consumers\n// ---------------------------------------------------------------------------\n\n/** Return type shared by every method on {@link NumberBuiltinExtensions}. */\ntype NumberExtReturn<T extends number = number> = NumberSchemaBuilder<\n T,\n true,\n false,\n false,\n NumberBuiltinExtensions<T>\n> &\n NumberBuiltinExtensions<T> &\n HiddenExtensionMethods;\n\n/**\n * Methods added to `NumberSchemaBuilder` by the built-in number extension pack.\n *\n * **WORKAROUND:** This interface duplicates the method signatures from\n * `numberExtensions` so that JSDoc survives into the published `.d.ts`\n * files. TypeScript strips JSDoc when method signatures are reconstructed\n * through the `FixedMethods` mapped type (conditional `infer` loses\n * comments). Remove this interface once TypeScript preserves JSDoc\n * through mapped types / conditional type inference.\n *\n * @see https://github.com/microsoft/TypeScript/issues/50715\n */\nexport interface NumberBuiltinExtensions<T extends number = number> {\n /**\n * Validates that the number is strictly greater than zero.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the positive validator applied\n *\n * @example\n * ```ts\n * number().positive();\n * number().positive('Must be greater than zero');\n * ```\n */\n positive(\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<T>;\n\n /**\n * Validates that the number is strictly less than zero.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the negative validator applied\n *\n * @example\n * ```ts\n * number().negative();\n * number().negative('Must be below zero');\n * ```\n */\n negative(\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<T>;\n\n /**\n * Validates that the number is finite (rejects `Infinity` and `-Infinity`).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the finite validator applied\n *\n * @example\n * ```ts\n * number().finite();\n * number().finite('No infinities allowed');\n * ```\n */\n finite(\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<T>;\n\n /**\n * Validates that the number is an exact multiple of `n`.\n *\n * Uses a relative tolerance of `1e-10` for float-safe comparison.\n *\n * @param n - the divisor to check against\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the multipleOf validator applied\n *\n * @example\n * ```ts\n * number().multipleOf(5);\n * number().multipleOf(0.1, 'Must be a multiple of 0.1');\n * ```\n */\n multipleOf(\n n: number,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<T>;\n\n /**\n * Constrains the number to one of the specified literal values.\n *\n * Narrows the inferred type from `number` to the union of the\n * provided literals.\n *\n * @param values - the allowed number literals\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * import { number, InferType } from '@cleverbrush/schema';\n *\n * const priority = number().oneOf(1, 2, 3);\n * type Priority = InferType<typeof priority>; // 1 | 2 | 3\n *\n * priority.validate(1); // valid\n * priority.validate(4); // invalid — \"must be one of: 1, 2, 3\"\n * ```\n */\n oneOf<V extends number>(...values: [V, ...V[]]): NumberExtReturn<V>;\n\n /**\n * Constrains the number to one of the specified literal values,\n * with a custom error message or factory as the last argument.\n *\n * @example\n * ```ts\n * const priority = number().oneOf(1, 2, 3, 'Priority must be 1, 2, or 3');\n * const priority2 = number().oneOf(1, 2, 3, (val) => `${val} is not a valid priority`);\n * ```\n */\n oneOf<V extends number>(\n ...args: [\n ...[V, ...V[]],\n ValidationErrorMessageProvider<NumberSchemaBuilder>\n ]\n ): NumberExtReturn<V>;\n\n /**\n * Constrains the number to one of the specified literal values,\n * with an optional custom error message or factory.\n *\n * @param values - the allowed number literals as an array\n * @param errorMessage - optional custom error message or factory function\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * const priority = number().oneOf([1, 2, 3], 'Must be 1, 2, or 3');\n * ```\n */\n oneOf<V extends number>(\n values: readonly [V, ...V[]],\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<V>;\n}\n\n/**\n * Subset of {@link NumberBuiltinExtensions} containing only the `.oneOf()` overloads.\n * Exported for backward compatibility.\n */\nexport type NumberOneOfExtension = Pick<NumberBuiltinExtensions, 'oneOf'>;\n\n/**\n * Extension descriptor that adds common number validators\n * to `NumberSchemaBuilder`.\n *\n * Included methods: `positive`, `negative`, `finite`, `multipleOf`, `oneOf`.\n *\n * @example\n * ```ts\n * import { withExtensions } from '@cleverbrush/schema/core';\n * import { numberExtensions } from '@cleverbrush/schema';\n *\n * const s = withExtensions(numberExtensions);\n * const schema = s.number().positive().multipleOf(5);\n * ```\n */\nexport const numberExtensions = defineExtension({\n number: {\n /**\n * Validates that the number is strictly greater than zero.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the positive validator applied\n *\n * @example\n * ```ts\n * number().positive();\n * number().positive('Must be greater than zero');\n * ```\n */\n positive(\n this: NumberSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ) {\n return this.withExtension('positive', true).addValidator(val => {\n if (typeof val !== 'number')\n return validationFail(\n errorMessage,\n 'must be a positive number',\n val,\n this\n );\n const valid = val > 0;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a positive number',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the number is strictly less than zero.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the negative validator applied\n *\n * @example\n * ```ts\n * number().negative();\n * number().negative('Must be below zero');\n * ```\n */\n negative(\n this: NumberSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ) {\n return this.withExtension('negative', true).addValidator(val => {\n if (typeof val !== 'number')\n return validationFail(\n errorMessage,\n 'must be a negative number',\n val,\n this\n );\n const valid = val < 0;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a negative number',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the number is finite (rejects `Infinity` and `-Infinity`).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the finite validator applied\n *\n * @example\n * ```ts\n * number().finite();\n * number().finite('No infinities allowed');\n * ```\n */\n finite(\n this: NumberSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ) {\n return this.withExtension('finite', true).addValidator(val => {\n if (typeof val !== 'number')\n return validationFail(\n errorMessage,\n 'must be a finite number',\n val,\n this\n );\n const valid = Number.isFinite(val);\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a finite number',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the number is an exact multiple of `n`.\n *\n * Uses a relative tolerance of `1e-10` for float-safe comparison.\n *\n * @param n - the divisor to check against\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the multipleOf validator applied\n *\n * @example\n * ```ts\n * number().multipleOf(5);\n * number().multipleOf(0.1, 'Must be a multiple of 0.1');\n * ```\n */\n multipleOf(\n this: NumberSchemaBuilder,\n n: number,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ) {\n if (n === 0 || !Number.isFinite(n)) {\n throw new Error(\n 'multipleOf: n must be a finite, non-zero number'\n );\n }\n return this.withExtension('multipleOf', n).addValidator(val => {\n if (typeof val !== 'number')\n return validationFail(\n errorMessage,\n `must be a multiple of ${n}`,\n val,\n this\n );\n const remainder = Math.abs(val % n);\n const tolerance = Math.abs(n) * 1e-10;\n const valid =\n remainder < tolerance ||\n Math.abs(remainder - Math.abs(n)) < tolerance;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n `must be a multiple of ${n}`,\n val,\n this\n );\n });\n },\n\n /**\n * Constrains the number to one of the specified literal values.\n *\n * @param args - the allowed number literals, optionally followed by an error message\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * number().oneOf(1, 2, 3);\n * number().oneOf([1, 2, 3], 'Must be 1, 2, or 3');\n * ```\n */\n oneOf(this: NumberSchemaBuilder, ...args: any[]) {\n let values: number[];\n let errorMessage:\n | ValidationErrorMessageProvider<NumberSchemaBuilder>\n | undefined;\n\n if (args.length === 0) {\n throw new Error('oneOf requires at least one value');\n }\n\n if (Array.isArray(args[0])) {\n // Array form: oneOf([1, 2, 3], errorMessage?)\n values = args[0] as number[];\n errorMessage = args[1] as\n | ValidationErrorMessageProvider<NumberSchemaBuilder>\n | undefined;\n } else {\n // Rest params form: oneOf(1, 2, 3) or oneOf(1, 2, 3, 'error') or oneOf(1, 2, 3, errorFn)\n // Last arg is a string or function → error message (unambiguous since values are numbers)\n const lastArg = args[args.length - 1];\n if (\n typeof lastArg === 'string' ||\n typeof lastArg === 'function'\n ) {\n values = args.slice(0, -1) as number[];\n errorMessage =\n lastArg as ValidationErrorMessageProvider<NumberSchemaBuilder>;\n } else {\n values = args as number[];\n errorMessage = undefined;\n }\n }\n\n if (values.length === 0) {\n throw new Error('oneOf requires at least one value');\n }\n\n const allowed = new Set(values);\n return this.withExtension('oneOf', values).addValidator(val => {\n if (typeof val === 'number' && allowed.has(val)) {\n return { valid: true, errors: [] };\n }\n return validationFail(\n errorMessage,\n `must be one of: ${values.join(', ')}`,\n val,\n this\n );\n });\n }\n }\n});\n","/**\n * Built-in string extensions for `@cleverbrush/schema`.\n *\n * Provides common string validators and preprocessors: {@link stringExtensions | email},\n * {@link stringExtensions | url}, {@link stringExtensions | uuid},\n * {@link stringExtensions | ip}, {@link stringExtensions | trim},\n * {@link stringExtensions | toLowerCase}, {@link stringExtensions | nonempty},\n * and {@link stringExtensions | oneOf}.\n *\n * These are pre-applied in the default `@cleverbrush/schema` import.\n * Import from `@cleverbrush/schema/core` to get bare builders without these extensions.\n *\n * @module\n */\nimport type { ValidationErrorMessageProvider } from '../builders/SchemaBuilder.js';\nimport type { StringSchemaBuilder } from '../builders/StringSchemaBuilder.js';\nimport type { HiddenExtensionMethods } from '../extension.js';\nimport { defineExtension } from '../extension.js';\nimport { validationFail } from './util.js';\n\n// ---------------------------------------------------------------------------\n// Public interface — carries JSDoc into .d.ts for consumers\n// ---------------------------------------------------------------------------\n\n/** Return type shared by every method on {@link StringBuiltinExtensions}. */\ntype StringExtReturn<T extends string = string> = StringSchemaBuilder<\n T,\n true,\n false,\n false,\n StringBuiltinExtensions<T>\n> &\n StringBuiltinExtensions<T> &\n HiddenExtensionMethods;\n\n/**\n * Methods added to `StringSchemaBuilder` by the built-in string extension pack.\n *\n * **WORKAROUND:** This interface duplicates the method signatures from\n * `stringExtensions` so that JSDoc survives into the published `.d.ts`\n * files. TypeScript strips JSDoc when method signatures are reconstructed\n * through the `FixedMethods` mapped type (conditional `infer` loses\n * comments). Remove this interface once TypeScript preserves JSDoc\n * through mapped types / conditional type inference.\n *\n * @see https://github.com/microsoft/TypeScript/issues/50715\n */\nexport interface StringBuiltinExtensions<T extends string = string> {\n /**\n * Validates that the string is a well-formed email address.\n *\n * Uses the pattern `^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$` for validation.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the email validator applied\n *\n * @example\n * ```ts\n * string().email();\n * string().email('Please enter a valid email');\n * string().email((val) => `\"${val}\" is not a valid email`);\n * ```\n */\n email(\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Validates that the string is a well-formed URL.\n *\n * By default only `http` and `https` protocols are accepted.\n * Pass `opts.protocols` to restrict or expand the allowed set.\n *\n * @param opts - optional configuration\n * @param opts.protocols - allowed URL protocols (default: `['http', 'https']`)\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the URL validator applied\n *\n * @example\n * ```ts\n * string().url();\n * string().url({ protocols: ['https'] });\n * string().url('Must be a valid URL');\n * string().url({ protocols: ['https'] }, 'Must be a valid URL');\n * ```\n */\n url(\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n url(\n opts?: { protocols?: string[] },\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Validates that the string is a valid UUID (versions 1–5).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the UUID validator applied\n *\n * @example\n * ```ts\n * string().uuid();\n * string().uuid('Invalid identifier');\n * ```\n */\n uuid(\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Validates that the string is a valid IP address (IPv4 or IPv6).\n *\n * Pass `opts.version` to restrict validation to a specific IP version.\n *\n * @param opts - optional configuration\n * @param opts.version - restrict to `'v4'` or `'v6'` (default: accept both)\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the IP validator applied\n *\n * @example\n * ```ts\n * string().ip();\n * string().ip({ version: 'v4' });\n * string().ip(undefined, 'Bad IP address');\n * ```\n */\n ip(\n opts?: { version?: 'v4' | 'v6' },\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Preprocessor that trims leading and trailing whitespace before validation.\n *\n * @returns a new schema builder with the trim preprocessor applied\n *\n * @example\n * ```ts\n * string().trim().minLength(1); // ' hi ' → 'hi'\n * ```\n */\n trim(): StringExtReturn<T>;\n\n /**\n * Preprocessor that converts the string to lowercase before validation.\n *\n * @returns a new schema builder with the toLowerCase preprocessor applied\n *\n * @example\n * ```ts\n * string().toLowerCase(); // 'HELLO' → 'hello'\n * ```\n */\n toLowerCase(): StringExtReturn<T>;\n\n /**\n * Validates that the string is not empty (length > 0).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the nonempty validator applied\n *\n * @example\n * ```ts\n * string().nonempty();\n * string().nonempty('Name is required');\n * ```\n */\n nonempty(\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Constrains the string to one of the specified literal values.\n *\n * Narrows the inferred type from `string` to the union of the\n * provided literals.\n *\n * @param values - the allowed string literals\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * import { string, InferType } from '@cleverbrush/schema';\n *\n * const role = string().oneOf('admin', 'user', 'guest');\n * type Role = InferType<typeof role>; // 'admin' | 'user' | 'guest'\n *\n * role.validate('admin'); // valid\n * role.validate('other'); // invalid — \"must be one of: admin, user, guest\"\n * ```\n */\n oneOf<V extends string>(...values: [V, ...V[]]): StringExtReturn<V>;\n\n /**\n * Constrains the string to one of the specified literal values,\n * with a custom error message or factory as the last argument.\n *\n * @example\n * ```ts\n * const role = string().oneOf('admin', 'user', (val) => `\"${val}\" is not allowed`);\n * ```\n */\n oneOf<V extends string>(\n ...args: [\n ...[V, ...V[]],\n ValidationErrorMessageProvider<StringSchemaBuilder>\n ]\n ): StringExtReturn<V>;\n\n /**\n * Constrains the string to one of the specified literal values,\n * with an optional custom error message or factory.\n *\n * @param values - the allowed string literals as an array\n * @param errorMessage - optional custom error message or factory function\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * const role = string().oneOf(['admin', 'user', 'guest'], 'Invalid role');\n * ```\n */\n oneOf<V extends string>(\n values: readonly [V, ...V[]],\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<V>;\n}\n\n/**\n * Subset of {@link StringBuiltinExtensions} containing only the `.oneOf()` overloads.\n * Exported for backward compatibility.\n */\nexport type StringOneOfExtension = Pick<StringBuiltinExtensions, 'oneOf'>;\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nconst IPV4_RE =\n /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/;\n\nconst IPV6_RE =\n /^(?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$|^::(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4}$|^(?:[0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}$|^(?:[0-9a-f]{1,4}:){1,5}(?::[0-9a-f]{1,4}){1,2}$|^(?:[0-9a-f]{1,4}:){1,4}(?::[0-9a-f]{1,4}){1,3}$|^(?:[0-9a-f]{1,4}:){1,3}(?::[0-9a-f]{1,4}){1,4}$|^(?:[0-9a-f]{1,4}:){1,2}(?::[0-9a-f]{1,4}){1,5}$|^[0-9a-f]{1,4}:(?::[0-9a-f]{1,4}){1,6}$|^::$/i;\n\n/**\n * Extension descriptor that adds common string validators and preprocessors\n * to `StringSchemaBuilder`.\n *\n * Included methods: `email`, `url`, `uuid`, `ip`, `trim`, `toLowerCase`, `nonempty`, `oneOf`.\n *\n * @example\n * ```ts\n * import { withExtensions } from '@cleverbrush/schema/core';\n * import { stringExtensions } from '@cleverbrush/schema';\n *\n * const s = withExtensions(stringExtensions);\n * const schema = s.string().email().trim();\n * ```\n */\nexport const stringExtensions = defineExtension({\n string: {\n /**\n * Validates that the string is a well-formed email address.\n *\n * Uses the pattern `^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$` for validation.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the email validator applied\n *\n * @example\n * ```ts\n * string().email();\n * string().email('Please enter a valid email');\n * string().email((val) => `\"${val}\" is not a valid email`);\n * ```\n */\n email(\n this: StringSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n return this.withExtension('email', true).addValidator(val => {\n if (typeof val !== 'string')\n return validationFail(\n errorMessage,\n 'must be a valid email',\n val,\n this\n );\n const valid = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(val);\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a valid email',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the string is a well-formed URL.\n *\n * By default only `http` and `https` protocols are accepted.\n * Pass `opts.protocols` to restrict or expand the allowed set.\n *\n * @param opts - optional configuration\n * @param opts.protocols - allowed URL protocols (default: `['http', 'https']`)\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the URL validator applied\n *\n * @example\n * ```ts\n * string().url();\n * string().url({ protocols: ['https'] });\n * string().url('Must be a valid URL');\n * string().url({ protocols: ['https'] }, 'Must be a valid URL');\n * ```\n */\n url(\n this: StringSchemaBuilder,\n optsOrError?:\n | { protocols?: string[] }\n | ValidationErrorMessageProvider<StringSchemaBuilder>,\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n let opts: { protocols?: string[] } | undefined;\n if (\n typeof optsOrError === 'string' ||\n typeof optsOrError === 'function'\n ) {\n errorMessage = optsOrError;\n opts = undefined;\n } else {\n opts = optsOrError;\n }\n if (\n opts?.protocols !== undefined &&\n (opts.protocols.length === 0 ||\n opts.protocols.some(p => !p || p.trim() === ''))\n ) {\n throw new Error(\n 'url: opts.protocols must be a non-empty array of non-empty strings'\n );\n }\n const protocols = opts?.protocols ?? ['http', 'https'];\n const meta = opts?.protocols ? { protocols: opts.protocols } : true;\n\n return this.withExtension('url', meta).addValidator(val => {\n if (typeof val !== 'string')\n return validationFail(\n errorMessage,\n 'must be a valid URL',\n val,\n this\n );\n let valid = false;\n let defaultMsg = 'must be a valid URL';\n try {\n const parsed = new URL(val);\n const proto = parsed.protocol.replace(':', '');\n valid = protocols.includes(proto);\n if (!valid)\n defaultMsg = `protocol must be one of: ${protocols.join(', ')}`;\n } catch {\n /* invalid URL */\n }\n if (valid) return { valid: true, errors: [] };\n return validationFail(errorMessage, defaultMsg, val, this);\n });\n },\n\n /**\n * Validates that the string is a valid UUID (versions 1–5).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the UUID validator applied\n *\n * @example\n * ```ts\n * string().uuid();\n * string().uuid('Invalid identifier');\n * ```\n */\n uuid(\n this: StringSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n return this.withExtension('uuid', true).addValidator(val => {\n if (typeof val !== 'string')\n return validationFail(\n errorMessage,\n 'must be a valid UUID',\n val,\n this\n );\n const valid = UUID_RE.test(val);\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a valid UUID',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the string is a valid IP address (IPv4 or IPv6).\n *\n * Pass `opts.version` to restrict validation to a specific IP version.\n *\n * @param opts - optional configuration\n * @param opts.version - restrict to `'v4'` or `'v6'` (default: accept both)\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the IP validator applied\n *\n * @example\n * ```ts\n * string().ip();\n * string().ip({ version: 'v4' });\n * string().ip(undefined, 'Bad IP address');\n * ```\n */\n ip(\n this: StringSchemaBuilder,\n opts?: { version?: 'v4' | 'v6' },\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n const version = opts?.version;\n const meta = version ? { version } : true;\n\n return this.withExtension('ip', meta).addValidator(val => {\n const defaultMsg = version\n ? `must be a valid ${version} IP address`\n : 'must be a valid IP address';\n if (typeof val !== 'string')\n return validationFail(errorMessage, defaultMsg, val, this);\n let valid: boolean;\n if (version === 'v4') {\n valid = IPV4_RE.test(val);\n } else if (version === 'v6') {\n valid = IPV6_RE.test(val);\n } else {\n valid = IPV4_RE.test(val) || IPV6_RE.test(val);\n }\n if (valid) return { valid: true, errors: [] };\n return validationFail(errorMessage, defaultMsg, val, this);\n });\n },\n\n /**\n * Preprocessor that trims leading and trailing whitespace before validation.\n *\n * @returns a new schema builder with the trim preprocessor applied\n *\n * @example\n * ```ts\n * string().trim().minLength(1); // ' hi ' → 'hi'\n * ```\n */\n trim(this: StringSchemaBuilder) {\n return this.addPreprocessor(val =>\n typeof val === 'string' ? val.trim() : val\n );\n },\n\n /**\n * Preprocessor that converts the string to lowercase before validation.\n *\n * @returns a new schema builder with the toLowerCase preprocessor applied\n *\n * @example\n * ```ts\n * string().toLowerCase(); // 'HELLO' → 'hello'\n * ```\n */\n toLowerCase(this: StringSchemaBuilder) {\n return this.addPreprocessor(val =>\n typeof val === 'string' ? val.toLowerCase() : val\n );\n },\n\n /**\n * Validates that the string is not empty (length > 0).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the nonempty validator applied\n *\n * @example\n * ```ts\n * string().nonempty();\n * string().nonempty('Name is required');\n * ```\n */\n nonempty(\n this: StringSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n return this.withExtension('nonempty', true).addValidator(val => {\n if (typeof val !== 'string')\n return validationFail(\n errorMessage,\n 'must not be empty',\n val,\n this\n );\n const valid = val.length > 0;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must not be empty',\n val,\n this\n );\n });\n },\n\n /**\n * Constrains the string to one of the specified literal values.\n *\n * @param args - the allowed string literals, optionally followed by an error message\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * string().oneOf('admin', 'user', 'guest');\n * string().oneOf(['admin', 'user'], 'Invalid role');\n * ```\n */\n oneOf(this: StringSchemaBuilder, ...args: any[]) {\n let values: string[];\n let errorMessage:\n | ValidationErrorMessageProvider<StringSchemaBuilder>\n | undefined;\n\n if (args.length === 0) {\n throw new Error('oneOf requires at least one value');\n }\n\n if (Array.isArray(args[0])) {\n // Array form: oneOf(['a', 'b', 'c'], errorMessage?)\n values = args[0] as string[];\n errorMessage = args[1] as\n | ValidationErrorMessageProvider<StringSchemaBuilder>\n | undefined;\n } else {\n // Rest params form: oneOf('a', 'b', 'c') or oneOf('a', 'b', errorFn)\n // Last arg is a function → error message factory (unambiguous)\n const lastArg = args[args.length - 1];\n if (typeof lastArg === 'function') {\n values = args.slice(0, -1) as string[];\n errorMessage =\n lastArg as ValidationErrorMessageProvider<StringSchemaBuilder>;\n } else {\n values = args as string[];\n errorMessage = undefined;\n }\n }\n\n if (values.length === 0) {\n throw new Error('oneOf requires at least one value');\n }\n\n const allowed = new Set(values);\n return this.withExtension('oneOf', values).addValidator(val => {\n if (typeof val === 'string' && allowed.has(val)) {\n return { valid: true, errors: [] };\n }\n return validationFail(\n errorMessage,\n `must be one of: ${values.join(', ')}`,\n val,\n this\n );\n });\n }\n }\n});\n","/**\n * Pre‑wired extension pack for `@cleverbrush/schema`.\n *\n * Combines {@link stringExtensions}, {@link numberExtensions},\n * and {@link arrayExtensions} via\n * `withExtensions()` and re‑exports the augmented factory functions.\n *\n * The default `@cleverbrush/schema` entry point re‑exports these\n * augmented factories so that `email()`, `positive()`, `nonempty()`,\n * `.nullable()`, etc. are available without any setup.\n *\n * @module\n */\nimport type { AnySchemaBuilder } from '../builders/AnySchemaBuilder.js';\nimport type { ArraySchemaBuilder } from '../builders/ArraySchemaBuilder.js';\nimport type { BooleanSchemaBuilder } from '../builders/BooleanSchemaBuilder.js';\nimport type { DateSchemaBuilder } from '../builders/DateSchemaBuilder.js';\nimport type { FunctionSchemaBuilder } from '../builders/FunctionSchemaBuilder.js';\nimport type { NumberSchemaBuilder } from '../builders/NumberSchemaBuilder.js';\nimport type { ObjectSchemaBuilder } from '../builders/ObjectSchemaBuilder.js';\nimport type { PromiseSchemaBuilder } from '../builders/PromiseSchemaBuilder.js';\nimport type { RecordSchemaBuilder } from '../builders/RecordSchemaBuilder.js';\nimport type {\n SchemaBuilder,\n ValidationErrorMessageProvider\n} from '../builders/SchemaBuilder.js';\nimport type { StringSchemaBuilder } from '../builders/StringSchemaBuilder.js';\nimport type { TupleSchemaBuilder } from '../builders/TupleSchemaBuilder.js';\nimport type { UnionSchemaBuilder } from '../builders/UnionSchemaBuilder.js';\nimport type { HiddenExtensionMethods } from '../extension.js';\nimport { withExtensions } from '../extension.js';\nimport type { ArrayBuiltinExtensions } from './array.js';\nimport { arrayExtensions } from './array.js';\nimport type { NumberBuiltinExtensions } from './number.js';\nimport { numberExtensions } from './number.js';\nimport type { StringBuiltinExtensions } from './string.js';\nimport { stringExtensions } from './string.js';\n\nexport { type ArrayBuiltinExtensions, arrayExtensions } from './array.js';\nexport {\n type NumberBuiltinExtensions,\n type NumberOneOfExtension,\n numberExtensions\n} from './number.js';\nexport {\n type StringBuiltinExtensions,\n type StringOneOfExtension,\n stringExtensions\n} from './string.js';\n\n// ---------------------------------------------------------------------------\n// Explicitly-typed factories — preserves JSDoc in .d.ts output.\n// WORKAROUND: TypeScript strips JSDoc when signatures pass through the\n// FixedMethods mapped type (conditional `infer` loses comments). These\n// explicit type aliases + factory annotations bypass FixedMethods so that\n// JSDoc from the *BuiltinExtensions interfaces reaches consumers.\n// Remove once TypeScript preserves JSDoc through mapped types.\n// See: https://github.com/microsoft/TypeScript/issues/50715\n// ---------------------------------------------------------------------------\n\n/** A `StringSchemaBuilder` with built-in extension methods. */\nexport type ExtendedString<T extends string = string> = StringSchemaBuilder<\n T,\n true,\n false,\n false,\n StringBuiltinExtensions<T>\n> &\n StringBuiltinExtensions<T> &\n HiddenExtensionMethods;\n\n/** A `NumberSchemaBuilder` with built-in extension methods. */\nexport type ExtendedNumber<T extends number = number> = NumberSchemaBuilder<\n T,\n true,\n false,\n false,\n NumberBuiltinExtensions<T>\n> &\n NumberBuiltinExtensions<T> &\n HiddenExtensionMethods;\n\n/** An `ArraySchemaBuilder` with built-in extension methods. */\nexport type ExtendedArray<\n TElementSchema extends SchemaBuilder<\n any,\n any,\n any,\n any,\n any\n > = SchemaBuilder<any, any, any>\n> = ArraySchemaBuilder<\n TElementSchema,\n true,\n false,\n undefined,\n false,\n ArrayBuiltinExtensions<TElementSchema>\n> &\n ArrayBuiltinExtensions<TElementSchema> &\n HiddenExtensionMethods;\n\n/** A `BooleanSchemaBuilder` with built-in extension methods. */\nexport type ExtendedBoolean = BooleanSchemaBuilder<\n boolean,\n true,\n false,\n undefined,\n false,\n {}\n> &\n HiddenExtensionMethods;\n\n/** A `DateSchemaBuilder` with built-in extension methods. */\nexport type ExtendedDate = DateSchemaBuilder<Date, true, false, false, {}> &\n HiddenExtensionMethods;\n\n/** An `ObjectSchemaBuilder` with built-in extension methods. */\nexport type ExtendedObject<\n TProps extends Record<string, SchemaBuilder<any, any, any, any, any>> = {}\n> = ObjectSchemaBuilder<TProps, true, false, undefined, false, {}, []> &\n HiddenExtensionMethods;\n\n/** A `UnionSchemaBuilder` with built-in extension methods. */\nexport type ExtendedUnion<\n TOptions extends readonly SchemaBuilder<any, any, any, any, any>[]\n> = UnionSchemaBuilder<TOptions, true, false, undefined, false, {}> &\n HiddenExtensionMethods;\n\n/** A `FunctionSchemaBuilder` with built-in extension methods. */\nexport type ExtendedFunc = FunctionSchemaBuilder<\n true,\n false,\n undefined,\n false,\n {}\n> &\n HiddenExtensionMethods;\n\n/** A `PromiseSchemaBuilder` with built-in extension methods. */\nexport type ExtendedPromise<\n TResolvedTypeSchema extends\n | SchemaBuilder<any, any, any, any, any>\n | undefined = undefined\n> = PromiseSchemaBuilder<\n true,\n false,\n undefined,\n false,\n {},\n TResolvedTypeSchema\n> &\n HiddenExtensionMethods;\n\n/** An `AnySchemaBuilder` with built-in extension methods. */\nexport type ExtendedAny = AnySchemaBuilder<true, false, undefined, false, {}> &\n HiddenExtensionMethods;\n\n/** A `TupleSchemaBuilder` with built-in extension methods. */\nexport type ExtendedTuple<\n TElements extends readonly SchemaBuilder<\n any,\n any,\n any\n >[] = readonly SchemaBuilder<any, any, any, any, any>[]\n> = TupleSchemaBuilder<TElements, true, false, undefined, false, {}> &\n HiddenExtensionMethods;\n\n/** A `RecordSchemaBuilder` with built-in extension methods. */\nexport type ExtendedRecord<\n TKeySchema extends StringSchemaBuilder<\n any,\n any,\n any,\n any\n > = StringSchemaBuilder<any, any, any, any>,\n TValueSchema extends SchemaBuilder<any, any, any, any, any> = SchemaBuilder<\n any,\n any,\n any\n >\n> = RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n true,\n false,\n undefined,\n false,\n {}\n> &\n HiddenExtensionMethods;\n\n// -- Runtime factories with explicit type annotations -------------------------\n\nconst s = withExtensions(stringExtensions, numberExtensions, arrayExtensions);\n\nexport const string: {\n (): ExtendedString;\n <T extends string>(equals: T): ExtendedString<T>;\n} = s.string as any;\n\nexport const number: {\n (): ExtendedNumber;\n <T extends number>(equals: T): ExtendedNumber<T>;\n} = s.number as any;\n\nexport const array: <\n TElementSchema extends SchemaBuilder<any, any, any, any, any>\n>(\n elementSchema?: TElementSchema\n) => ExtendedArray<TElementSchema> = s.array as any;\n\nexport const boolean: () => ExtendedBoolean = s.boolean as any;\nexport const date: () => ExtendedDate = s.date as any;\nexport const object: {\n (): ExtendedObject<{}>;\n <TProps extends Record<string, SchemaBuilder<any, any, any, any, any>>>(\n props: TProps\n ): ExtendedObject<TProps>;\n <TProps extends Record<string, SchemaBuilder<any, any, any, any, any>>>(\n props?: TProps\n ): ExtendedObject<TProps>;\n} = s.object as any;\nexport const union: <TOptions extends SchemaBuilder<any, any, any, any, any>>(\n schema: TOptions\n) => ExtendedUnion<[TOptions]> = s.union as any;\nexport const func: () => ExtendedFunc = s.func as any;\nexport const any: () => ExtendedAny = s.any as any;\nexport const tuple: <\n const TElements extends readonly SchemaBuilder<any, any, any, any, any>[]\n>(\n elements: [...TElements]\n) => ExtendedTuple<TElements> = s.tuple as any;\n\nexport const 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) => ExtendedRecord<TKeySchema, TValueSchema> = s.record as any;\n\nexport const promise: <TWrapped extends SchemaBuilder<any, any, any, any, any>>(\n wrapped: TWrapped\n) => ExtendedPromise<TWrapped> = s.promise as any;\n\n/**\n * Creates a string schema constrained to the given literal values.\n *\n * Convenience factory equivalent to `string().oneOf(...values)`.\n * Mirrors Zod's `z.enum(['admin', 'user', 'guest'])` API.\n *\n * **Rest-params form** (no custom error message):\n * ```ts\n * const Role = enumOf('admin', 'user', 'guest');\n * ```\n *\n * **Array form** (with optional custom error message):\n * ```ts\n * const Role = enumOf(['admin', 'user', 'guest'], 'Invalid role');\n * const Role2 = enumOf(['admin', 'user'], (val) => `\"${val}\" is not a valid role`);\n * ```\n *\n * @param values - the allowed string literals (at least one required)\n * @returns a typed `StringSchemaBuilder` that only accepts the given values\n *\n * @example\n * ```ts\n * import { enumOf, InferType } from '@cleverbrush/schema';\n *\n * const Role = enumOf('admin', 'user', 'guest');\n * type Role = InferType<typeof Role>; // 'admin' | 'user' | 'guest'\n *\n * Role.validate('admin'); // valid\n * Role.validate('other'); // invalid\n * ```\n */\nexport function enumOf<const T extends string>(\n ...values: [T, ...T[]]\n): ExtendedString<T>;\nexport function enumOf<const T extends string>(\n values: readonly [T, ...T[]],\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n): ExtendedString<T>;\nexport function enumOf<const T extends string>(\n ...args:\n | [T, ...T[]]\n | [\n readonly [T, ...T[]],\n ValidationErrorMessageProvider<StringSchemaBuilder>?\n ]\n): ExtendedString<T> {\n if (Array.isArray(args[0])) {\n return string().oneOf(\n args[0] as readonly [T, ...T[]],\n args[1] as\n | ValidationErrorMessageProvider<StringSchemaBuilder>\n | undefined\n ) as unknown as ExtendedString<T>;\n }\n return string().oneOf(\n ...(args as [T, ...T[]])\n ) as unknown as ExtendedString<T>;\n}\n"],"mappings":"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","names":["validationFail","provider","defaultMsg","value","schema","resolveErrorMessage","result","arrayExtensions","defineExtension","errorMessage","val","validationFail","keyFn","meta","seen","item","key","numberExtensions","defineExtension","errorMessage","val","validationFail","n","remainder","tolerance","args","values","lastArg","allowed","UUID_RE","IPV4_RE","IPV6_RE","stringExtensions","defineExtension","errorMessage","val","validationFail","optsOrError","opts","p","protocols","meta","valid","defaultMsg","proto","version","args","values","lastArg","allowed","s","withExtensions","stringExtensions","numberExtensions","arrayExtensions","string","number","array","boolean","date","object","union","func","any","tuple","record","promise","enumOf","args"]}
1
+ {"version":3,"sources":["../src/extensions/util.ts","../src/extensions/array.ts","../src/extensions/number.ts","../src/extensions/string.ts","../src/extensions/index.ts"],"sourcesContent":["import type { ValidationErrorMessageProvider } from '../builders/SchemaBuilder.js';\n\n/** Validation result returned by validators on failure. */\ninterface ValidationFailure {\n valid: false;\n errors: { message: string }[];\n}\n\n/**\n * Builds a synchronous validation-failure result, resolving the user-supplied\n * error-message provider (or falling back to `defaultMsg`).\n *\n * @param provider - custom error message provider (string, sync function, or `undefined`)\n * @param defaultMsg - fallback message used when `provider` is `undefined`\n * @param value - the value that failed validation\n * @param schema - the schema builder instance\n * @returns a `{ valid: false, errors: [{ message }] }` object\n */\nexport function validationFail(\n provider: ValidationErrorMessageProvider<any> | undefined,\n defaultMsg: string,\n value: unknown,\n schema: unknown\n): ValidationFailure {\n const msg = resolveErrorMessage(provider, defaultMsg, value, schema);\n return { valid: false, errors: [{ message: msg }] };\n}\n\n/**\n * Synchronously resolves a {@link ValidationErrorMessageProvider} to a concrete error message string.\n * Returns the default message when no custom provider is supplied.\n * Throws if the provider function returns a Promise.\n *\n * @param provider - custom error message provider (string, sync function, or `undefined`)\n * @param defaultMsg - fallback message used when `provider` is `undefined`\n * @param value - the value that failed validation (passed to function providers)\n * @param schema - the schema builder instance (passed to function providers)\n * @returns the resolved error message string\n * @throws Error if the provider returns a Promise\n */\nexport function resolveErrorMessage(\n provider: ValidationErrorMessageProvider<any> | undefined,\n defaultMsg: string,\n value: unknown,\n schema: unknown\n): string {\n if (provider === undefined) return defaultMsg;\n if (typeof provider === 'string') return provider;\n const result = provider(value, schema);\n if (result instanceof Promise) {\n throw new Error(\n 'Async error message providers require validateAsync(). Use a string or sync function instead.'\n );\n }\n return result;\n}\n\n/**\n * Asynchronously resolves a {@link ValidationErrorMessageProvider} to a concrete error message string.\n * Returns the default message when no custom provider is supplied.\n * Supports async provider functions.\n *\n * @param provider - custom error message provider (string, function, or `undefined`)\n * @param defaultMsg - fallback message used when `provider` is `undefined`\n * @param value - the value that failed validation (passed to function providers)\n * @param schema - the schema builder instance (passed to function providers)\n * @returns the resolved error message string\n */\nexport async function resolveErrorMessageAsync(\n provider: ValidationErrorMessageProvider<any> | undefined,\n defaultMsg: string,\n value: unknown,\n schema: unknown\n): Promise<string> {\n if (provider === undefined) return defaultMsg;\n if (typeof provider === 'string') return provider;\n return provider(value, schema);\n}\n","/**\n * Built-in array extensions for `@cleverbrush/schema`.\n *\n * Provides common array validators: {@link arrayExtensions | nonempty}\n * and {@link arrayExtensions | unique}.\n *\n * These are pre-applied in the default `@cleverbrush/schema` import.\n * Import from `@cleverbrush/schema/core` to get bare builders without these extensions.\n *\n * @module\n */\nimport type { ArraySchemaBuilder } from '../builders/ArraySchemaBuilder.js';\nimport type {\n SchemaBuilder,\n ValidationErrorMessageProvider\n} from '../builders/SchemaBuilder.js';\nimport type { HiddenExtensionMethods } from '../extension.js';\nimport { defineExtension } from '../extension.js';\nimport { validationFail } from './util.js';\n\n// ---------------------------------------------------------------------------\n// Public interface — carries JSDoc into .d.ts for consumers\n// ---------------------------------------------------------------------------\n\n/** Return type shared by every method on {@link ArrayBuiltinExtensions}. */\ntype ArrayExtReturn<\n TElementSchema extends SchemaBuilder<\n any,\n any,\n any,\n any,\n any\n > = SchemaBuilder<any, any, any>\n> = ArraySchemaBuilder<\n TElementSchema,\n true,\n false,\n undefined,\n false,\n ArrayBuiltinExtensions<TElementSchema>\n> &\n ArrayBuiltinExtensions<TElementSchema> &\n HiddenExtensionMethods;\n\n/**\n * Methods added to `ArraySchemaBuilder` by the built-in array extension pack.\n *\n * **WORKAROUND:** This interface duplicates the method signatures from\n * `arrayExtensions` so that JSDoc survives into the published `.d.ts`\n * files. TypeScript strips JSDoc when method signatures are reconstructed\n * through the `FixedMethods` mapped type (conditional `infer` loses\n * comments). Remove this interface once TypeScript preserves JSDoc\n * through mapped types / conditional type inference.\n *\n * @see https://github.com/microsoft/TypeScript/issues/50715\n */\nexport interface ArrayBuiltinExtensions<\n TElementSchema extends SchemaBuilder<\n any,\n any,\n any,\n any,\n any\n > = SchemaBuilder<any, any, any>\n> {\n /**\n * Validates that the array contains at least one element.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the nonempty validator applied\n *\n * @example\n * ```ts\n * array().nonempty();\n * array().nonempty('At least one item required');\n * ```\n */\n nonempty(\n errorMessage?: ValidationErrorMessageProvider<ArraySchemaBuilder<any>>\n ): ArrayExtReturn<TElementSchema>;\n\n /**\n * Validates that all elements in the array are unique.\n *\n * For primitive elements, uses strict equality. For objects, pass a `keyFn`\n * that extracts a comparison key from each element.\n *\n * @param keyFn - optional function to extract a comparison key from each element\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the unique validator applied\n *\n * @example\n * ```ts\n * array().unique();\n * array().unique((item) => item.id);\n * array().unique(undefined, 'No duplicates allowed');\n * ```\n */\n unique(\n keyFn?: (item: any) => unknown,\n errorMessage?: ValidationErrorMessageProvider<ArraySchemaBuilder<any>>\n ): ArrayExtReturn<TElementSchema>;\n}\n\n/**\n * Extension descriptor that adds common array validators\n * to `ArraySchemaBuilder`.\n *\n * Included methods: `nonempty`, `unique`.\n *\n * @example\n * ```ts\n * import { withExtensions } from '@cleverbrush/schema/core';\n * import { arrayExtensions } from '@cleverbrush/schema';\n *\n * const s = withExtensions(arrayExtensions);\n * const schema = s.array().nonempty().unique();\n * ```\n */\nexport const arrayExtensions = defineExtension({\n array: {\n /**\n * Validates that the array contains at least one element.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the nonempty validator applied\n *\n * @example\n * ```ts\n * array().nonempty();\n * array().nonempty('At least one item required');\n * ```\n */\n nonempty(\n this: ArraySchemaBuilder<any>,\n errorMessage?: ValidationErrorMessageProvider<\n ArraySchemaBuilder<any>\n >\n ) {\n return this.withExtension('nonempty', true).addValidator(\n (val: unknown[]) => {\n if (!Array.isArray(val))\n return validationFail(\n errorMessage,\n 'must not be empty',\n val,\n this\n );\n const valid = val.length > 0;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must not be empty',\n val,\n this\n );\n }\n );\n },\n\n /**\n * Validates that all elements in the array are unique.\n *\n * For primitive elements, uses strict equality. For objects, pass a `keyFn`\n * that extracts a comparison key from each element.\n *\n * @param keyFn - optional function to extract a comparison key from each element\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the unique validator applied\n *\n * @example\n * ```ts\n * array().unique();\n * array().unique((item) => item.id);\n * array().unique(undefined, 'No duplicates allowed');\n * ```\n */\n unique(\n this: ArraySchemaBuilder<any>,\n keyFn?: (item: any) => unknown,\n errorMessage?: ValidationErrorMessageProvider<\n ArraySchemaBuilder<any>\n >\n ) {\n const meta = keyFn ?? true;\n\n return this.withExtension('unique', meta).addValidator(\n (val: unknown[]) => {\n if (!Array.isArray(val))\n return validationFail(\n errorMessage,\n 'must contain unique elements',\n val,\n this\n );\n const seen = new Set();\n for (const item of val) {\n const key = keyFn ? keyFn(item) : item;\n if (seen.has(key)) {\n return validationFail(\n errorMessage,\n 'must contain unique elements',\n val,\n this\n );\n }\n seen.add(key);\n }\n return { valid: true, errors: [] };\n }\n );\n }\n }\n});\n","/**\n * Built-in number extensions for `@cleverbrush/schema`.\n *\n * Provides common number validators: {@link numberExtensions | positive},\n * {@link numberExtensions | negative}, {@link numberExtensions | finite},\n * {@link numberExtensions | multipleOf}, and {@link numberExtensions | oneOf}.\n *\n * These are pre-applied in the default `@cleverbrush/schema` import.\n * Import from `@cleverbrush/schema/core` to get bare builders without these extensions.\n *\n * @module\n */\nimport type { NumberSchemaBuilder } from '../builders/NumberSchemaBuilder.js';\nimport type { ValidationErrorMessageProvider } from '../builders/SchemaBuilder.js';\nimport type { HiddenExtensionMethods } from '../extension.js';\nimport { defineExtension } from '../extension.js';\nimport { validationFail } from './util.js';\n\n// ---------------------------------------------------------------------------\n// Public interface — carries JSDoc into .d.ts for consumers\n// ---------------------------------------------------------------------------\n\n/** Return type shared by every method on {@link NumberBuiltinExtensions}. */\ntype NumberExtReturn<T extends number = number> = NumberSchemaBuilder<\n T,\n true,\n false,\n false,\n NumberBuiltinExtensions<T>\n> &\n NumberBuiltinExtensions<T> &\n HiddenExtensionMethods;\n\n/**\n * Methods added to `NumberSchemaBuilder` by the built-in number extension pack.\n *\n * **WORKAROUND:** This interface duplicates the method signatures from\n * `numberExtensions` so that JSDoc survives into the published `.d.ts`\n * files. TypeScript strips JSDoc when method signatures are reconstructed\n * through the `FixedMethods` mapped type (conditional `infer` loses\n * comments). Remove this interface once TypeScript preserves JSDoc\n * through mapped types / conditional type inference.\n *\n * @see https://github.com/microsoft/TypeScript/issues/50715\n */\nexport interface NumberBuiltinExtensions<T extends number = number> {\n /**\n * Validates that the number is strictly greater than zero.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the positive validator applied\n *\n * @example\n * ```ts\n * number().positive();\n * number().positive('Must be greater than zero');\n * ```\n */\n positive(\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<T>;\n\n /**\n * Validates that the number is strictly less than zero.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the negative validator applied\n *\n * @example\n * ```ts\n * number().negative();\n * number().negative('Must be below zero');\n * ```\n */\n negative(\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<T>;\n\n /**\n * Validates that the number is finite (rejects `Infinity` and `-Infinity`).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the finite validator applied\n *\n * @example\n * ```ts\n * number().finite();\n * number().finite('No infinities allowed');\n * ```\n */\n finite(\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<T>;\n\n /**\n * Validates that the number is an exact multiple of `n`.\n *\n * Uses a relative tolerance of `1e-10` for float-safe comparison.\n *\n * @param n - the divisor to check against\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the multipleOf validator applied\n *\n * @example\n * ```ts\n * number().multipleOf(5);\n * number().multipleOf(0.1, 'Must be a multiple of 0.1');\n * ```\n */\n multipleOf(\n n: number,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<T>;\n\n /**\n * Constrains the number to one of the specified literal values.\n *\n * Narrows the inferred type from `number` to the union of the\n * provided literals.\n *\n * @param values - the allowed number literals\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * import { number, InferType } from '@cleverbrush/schema';\n *\n * const priority = number().oneOf(1, 2, 3);\n * type Priority = InferType<typeof priority>; // 1 | 2 | 3\n *\n * priority.validate(1); // valid\n * priority.validate(4); // invalid — \"must be one of: 1, 2, 3\"\n * ```\n */\n oneOf<V extends number>(...values: [V, ...V[]]): NumberExtReturn<V>;\n\n /**\n * Constrains the number to one of the specified literal values,\n * with a custom error message or factory as the last argument.\n *\n * @example\n * ```ts\n * const priority = number().oneOf(1, 2, 3, 'Priority must be 1, 2, or 3');\n * const priority2 = number().oneOf(1, 2, 3, (val) => `${val} is not a valid priority`);\n * ```\n */\n oneOf<V extends number>(\n ...args: [\n ...[V, ...V[]],\n ValidationErrorMessageProvider<NumberSchemaBuilder>\n ]\n ): NumberExtReturn<V>;\n\n /**\n * Constrains the number to one of the specified literal values,\n * with an optional custom error message or factory.\n *\n * @param values - the allowed number literals as an array\n * @param errorMessage - optional custom error message or factory function\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * const priority = number().oneOf([1, 2, 3], 'Must be 1, 2, or 3');\n * ```\n */\n oneOf<V extends number>(\n values: readonly [V, ...V[]],\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ): NumberExtReturn<V>;\n}\n\n/**\n * Subset of {@link NumberBuiltinExtensions} containing only the `.oneOf()` overloads.\n * Exported for backward compatibility.\n */\nexport type NumberOneOfExtension = Pick<NumberBuiltinExtensions, 'oneOf'>;\n\n/**\n * Extension descriptor that adds common number validators\n * to `NumberSchemaBuilder`.\n *\n * Included methods: `positive`, `negative`, `finite`, `multipleOf`, `oneOf`.\n *\n * @example\n * ```ts\n * import { withExtensions } from '@cleverbrush/schema/core';\n * import { numberExtensions } from '@cleverbrush/schema';\n *\n * const s = withExtensions(numberExtensions);\n * const schema = s.number().positive().multipleOf(5);\n * ```\n */\nexport const numberExtensions = defineExtension({\n number: {\n /**\n * Validates that the number is strictly greater than zero.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the positive validator applied\n *\n * @example\n * ```ts\n * number().positive();\n * number().positive('Must be greater than zero');\n * ```\n */\n positive(\n this: NumberSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ) {\n return this.withExtension('positive', true).addValidator(val => {\n if (typeof val !== 'number')\n return validationFail(\n errorMessage,\n 'must be a positive number',\n val,\n this\n );\n const valid = val > 0;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a positive number',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the number is strictly less than zero.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the negative validator applied\n *\n * @example\n * ```ts\n * number().negative();\n * number().negative('Must be below zero');\n * ```\n */\n negative(\n this: NumberSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ) {\n return this.withExtension('negative', true).addValidator(val => {\n if (typeof val !== 'number')\n return validationFail(\n errorMessage,\n 'must be a negative number',\n val,\n this\n );\n const valid = val < 0;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a negative number',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the number is finite (rejects `Infinity` and `-Infinity`).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the finite validator applied\n *\n * @example\n * ```ts\n * number().finite();\n * number().finite('No infinities allowed');\n * ```\n */\n finite(\n this: NumberSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ) {\n return this.withExtension('finite', true).addValidator(val => {\n if (typeof val !== 'number')\n return validationFail(\n errorMessage,\n 'must be a finite number',\n val,\n this\n );\n const valid = Number.isFinite(val);\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a finite number',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the number is an exact multiple of `n`.\n *\n * Uses a relative tolerance of `1e-10` for float-safe comparison.\n *\n * @param n - the divisor to check against\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the multipleOf validator applied\n *\n * @example\n * ```ts\n * number().multipleOf(5);\n * number().multipleOf(0.1, 'Must be a multiple of 0.1');\n * ```\n */\n multipleOf(\n this: NumberSchemaBuilder,\n n: number,\n errorMessage?: ValidationErrorMessageProvider<NumberSchemaBuilder>\n ) {\n if (n === 0 || !Number.isFinite(n)) {\n throw new Error(\n 'multipleOf: n must be a finite, non-zero number'\n );\n }\n return this.withExtension('multipleOf', n).addValidator(val => {\n if (typeof val !== 'number')\n return validationFail(\n errorMessage,\n `must be a multiple of ${n}`,\n val,\n this\n );\n const remainder = Math.abs(val % n);\n const tolerance = Math.abs(n) * 1e-10;\n const valid =\n remainder < tolerance ||\n Math.abs(remainder - Math.abs(n)) < tolerance;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n `must be a multiple of ${n}`,\n val,\n this\n );\n });\n },\n\n /**\n * Constrains the number to one of the specified literal values.\n *\n * @param args - the allowed number literals, optionally followed by an error message\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * number().oneOf(1, 2, 3);\n * number().oneOf([1, 2, 3], 'Must be 1, 2, or 3');\n * ```\n */\n oneOf(this: NumberSchemaBuilder, ...args: any[]) {\n let values: number[];\n let errorMessage:\n | ValidationErrorMessageProvider<NumberSchemaBuilder>\n | undefined;\n\n if (args.length === 0) {\n throw new Error('oneOf requires at least one value');\n }\n\n if (Array.isArray(args[0])) {\n // Array form: oneOf([1, 2, 3], errorMessage?)\n values = args[0] as number[];\n errorMessage = args[1] as\n | ValidationErrorMessageProvider<NumberSchemaBuilder>\n | undefined;\n } else {\n // Rest params form: oneOf(1, 2, 3) or oneOf(1, 2, 3, 'error') or oneOf(1, 2, 3, errorFn)\n // Last arg is a string or function → error message (unambiguous since values are numbers)\n const lastArg = args[args.length - 1];\n if (\n typeof lastArg === 'string' ||\n typeof lastArg === 'function'\n ) {\n values = args.slice(0, -1) as number[];\n errorMessage =\n lastArg as ValidationErrorMessageProvider<NumberSchemaBuilder>;\n } else {\n values = args as number[];\n errorMessage = undefined;\n }\n }\n\n if (values.length === 0) {\n throw new Error('oneOf requires at least one value');\n }\n\n const allowed = new Set(values);\n return this.withExtension('oneOf', values).addValidator(val => {\n if (typeof val === 'number' && allowed.has(val)) {\n return { valid: true, errors: [] };\n }\n return validationFail(\n errorMessage,\n `must be one of: ${values.join(', ')}`,\n val,\n this\n );\n });\n }\n }\n});\n","/**\n * Built-in string extensions for `@cleverbrush/schema`.\n *\n * Provides common string validators and preprocessors: {@link stringExtensions | email},\n * {@link stringExtensions | url}, {@link stringExtensions | uuid},\n * {@link stringExtensions | ip}, {@link stringExtensions | trim},\n * {@link stringExtensions | toLowerCase}, {@link stringExtensions | nonempty},\n * and {@link stringExtensions | oneOf}.\n *\n * These are pre-applied in the default `@cleverbrush/schema` import.\n * Import from `@cleverbrush/schema/core` to get bare builders without these extensions.\n *\n * @module\n */\nimport type { ValidationErrorMessageProvider } from '../builders/SchemaBuilder.js';\nimport type { StringSchemaBuilder } from '../builders/StringSchemaBuilder.js';\nimport type { HiddenExtensionMethods } from '../extension.js';\nimport { defineExtension } from '../extension.js';\nimport { validationFail } from './util.js';\n\n// ---------------------------------------------------------------------------\n// Public interface — carries JSDoc into .d.ts for consumers\n// ---------------------------------------------------------------------------\n\n/** Return type shared by every method on {@link StringBuiltinExtensions}. */\ntype StringExtReturn<T extends string = string> = StringSchemaBuilder<\n T,\n true,\n false,\n false,\n StringBuiltinExtensions<T>\n> &\n StringBuiltinExtensions<T> &\n HiddenExtensionMethods;\n\n/**\n * Methods added to `StringSchemaBuilder` by the built-in string extension pack.\n *\n * **WORKAROUND:** This interface duplicates the method signatures from\n * `stringExtensions` so that JSDoc survives into the published `.d.ts`\n * files. TypeScript strips JSDoc when method signatures are reconstructed\n * through the `FixedMethods` mapped type (conditional `infer` loses\n * comments). Remove this interface once TypeScript preserves JSDoc\n * through mapped types / conditional type inference.\n *\n * @see https://github.com/microsoft/TypeScript/issues/50715\n */\nexport interface StringBuiltinExtensions<T extends string = string> {\n /**\n * Validates that the string is a well-formed email address.\n *\n * Uses the pattern `^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$` for validation.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the email validator applied\n *\n * @example\n * ```ts\n * string().email();\n * string().email('Please enter a valid email');\n * string().email((val) => `\"${val}\" is not a valid email`);\n * ```\n */\n email(\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Validates that the string is a well-formed URL.\n *\n * By default only `http` and `https` protocols are accepted.\n * Pass `opts.protocols` to restrict or expand the allowed set.\n *\n * @param opts - optional configuration\n * @param opts.protocols - allowed URL protocols (default: `['http', 'https']`)\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the URL validator applied\n *\n * @example\n * ```ts\n * string().url();\n * string().url({ protocols: ['https'] });\n * string().url('Must be a valid URL');\n * string().url({ protocols: ['https'] }, 'Must be a valid URL');\n * ```\n */\n url(\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n url(\n opts?: { protocols?: string[] },\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Validates that the string is a valid UUID (versions 1–5).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the UUID validator applied\n *\n * @example\n * ```ts\n * string().uuid();\n * string().uuid('Invalid identifier');\n * ```\n */\n uuid(\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Validates that the string is a valid IP address (IPv4 or IPv6).\n *\n * Pass `opts.version` to restrict validation to a specific IP version.\n *\n * @param opts - optional configuration\n * @param opts.version - restrict to `'v4'` or `'v6'` (default: accept both)\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the IP validator applied\n *\n * @example\n * ```ts\n * string().ip();\n * string().ip({ version: 'v4' });\n * string().ip(undefined, 'Bad IP address');\n * ```\n */\n ip(\n opts?: { version?: 'v4' | 'v6' },\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Preprocessor that trims leading and trailing whitespace before validation.\n *\n * @returns a new schema builder with the trim preprocessor applied\n *\n * @example\n * ```ts\n * string().trim().minLength(1); // ' hi ' → 'hi'\n * ```\n */\n trim(): StringExtReturn<T>;\n\n /**\n * Preprocessor that converts the string to lowercase before validation.\n *\n * @returns a new schema builder with the toLowerCase preprocessor applied\n *\n * @example\n * ```ts\n * string().toLowerCase(); // 'HELLO' → 'hello'\n * ```\n */\n toLowerCase(): StringExtReturn<T>;\n\n /**\n * Validates that the string is not empty (length > 0).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the nonempty validator applied\n *\n * @example\n * ```ts\n * string().nonempty();\n * string().nonempty('Name is required');\n * ```\n */\n nonempty(\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<T>;\n\n /**\n * Constrains the string to one of the specified literal values.\n *\n * Narrows the inferred type from `string` to the union of the\n * provided literals.\n *\n * @param values - the allowed string literals\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * import { string, InferType } from '@cleverbrush/schema';\n *\n * const role = string().oneOf('admin', 'user', 'guest');\n * type Role = InferType<typeof role>; // 'admin' | 'user' | 'guest'\n *\n * role.validate('admin'); // valid\n * role.validate('other'); // invalid — \"must be one of: admin, user, guest\"\n * ```\n */\n oneOf<V extends string>(...values: [V, ...V[]]): StringExtReturn<V>;\n\n /**\n * Constrains the string to one of the specified literal values,\n * with a custom error message or factory as the last argument.\n *\n * @example\n * ```ts\n * const role = string().oneOf('admin', 'user', (val) => `\"${val}\" is not allowed`);\n * ```\n */\n oneOf<V extends string>(\n ...args: [\n ...[V, ...V[]],\n ValidationErrorMessageProvider<StringSchemaBuilder>\n ]\n ): StringExtReturn<V>;\n\n /**\n * Constrains the string to one of the specified literal values,\n * with an optional custom error message or factory.\n *\n * @param values - the allowed string literals as an array\n * @param errorMessage - optional custom error message or factory function\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * const role = string().oneOf(['admin', 'user', 'guest'], 'Invalid role');\n * ```\n */\n oneOf<V extends string>(\n values: readonly [V, ...V[]],\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ): StringExtReturn<V>;\n}\n\n/**\n * Subset of {@link StringBuiltinExtensions} containing only the `.oneOf()` overloads.\n * Exported for backward compatibility.\n */\nexport type StringOneOfExtension = Pick<StringBuiltinExtensions, 'oneOf'>;\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nconst IPV4_RE =\n /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/;\n\nconst IPV6_RE =\n /^(?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$|^::(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4}$|^(?:[0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}$|^(?:[0-9a-f]{1,4}:){1,5}(?::[0-9a-f]{1,4}){1,2}$|^(?:[0-9a-f]{1,4}:){1,4}(?::[0-9a-f]{1,4}){1,3}$|^(?:[0-9a-f]{1,4}:){1,3}(?::[0-9a-f]{1,4}){1,4}$|^(?:[0-9a-f]{1,4}:){1,2}(?::[0-9a-f]{1,4}){1,5}$|^[0-9a-f]{1,4}:(?::[0-9a-f]{1,4}){1,6}$|^::$/i;\n\n/**\n * Extension descriptor that adds common string validators and preprocessors\n * to `StringSchemaBuilder`.\n *\n * Included methods: `email`, `url`, `uuid`, `ip`, `trim`, `toLowerCase`, `nonempty`, `oneOf`.\n *\n * @example\n * ```ts\n * import { withExtensions } from '@cleverbrush/schema/core';\n * import { stringExtensions } from '@cleverbrush/schema';\n *\n * const s = withExtensions(stringExtensions);\n * const schema = s.string().email().trim();\n * ```\n */\nexport const stringExtensions = defineExtension({\n string: {\n /**\n * Validates that the string is a well-formed email address.\n *\n * Uses the pattern `^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$` for validation.\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the email validator applied\n *\n * @example\n * ```ts\n * string().email();\n * string().email('Please enter a valid email');\n * string().email((val) => `\"${val}\" is not a valid email`);\n * ```\n */\n email(\n this: StringSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n return this.withExtension('email', true).addValidator(val => {\n if (typeof val !== 'string')\n return validationFail(\n errorMessage,\n 'must be a valid email',\n val,\n this\n );\n const valid = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(val);\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a valid email',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the string is a well-formed URL.\n *\n * By default only `http` and `https` protocols are accepted.\n * Pass `opts.protocols` to restrict or expand the allowed set.\n *\n * @param opts - optional configuration\n * @param opts.protocols - allowed URL protocols (default: `['http', 'https']`)\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the URL validator applied\n *\n * @example\n * ```ts\n * string().url();\n * string().url({ protocols: ['https'] });\n * string().url('Must be a valid URL');\n * string().url({ protocols: ['https'] }, 'Must be a valid URL');\n * ```\n */\n url(\n this: StringSchemaBuilder,\n optsOrError?:\n | { protocols?: string[] }\n | ValidationErrorMessageProvider<StringSchemaBuilder>,\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n let opts: { protocols?: string[] } | undefined;\n if (\n typeof optsOrError === 'string' ||\n typeof optsOrError === 'function'\n ) {\n errorMessage = optsOrError;\n opts = undefined;\n } else {\n opts = optsOrError;\n }\n if (\n opts?.protocols !== undefined &&\n (opts.protocols.length === 0 ||\n opts.protocols.some(p => !p || p.trim() === ''))\n ) {\n throw new Error(\n 'url: opts.protocols must be a non-empty array of non-empty strings'\n );\n }\n const protocols = opts?.protocols ?? ['http', 'https'];\n const meta = opts?.protocols ? { protocols: opts.protocols } : true;\n\n return this.withExtension('url', meta).addValidator(val => {\n if (typeof val !== 'string')\n return validationFail(\n errorMessage,\n 'must be a valid URL',\n val,\n this\n );\n let valid = false;\n let defaultMsg = 'must be a valid URL';\n try {\n const parsed = new URL(val);\n const proto = parsed.protocol.replace(':', '');\n valid = protocols.includes(proto);\n if (!valid)\n defaultMsg = `protocol must be one of: ${protocols.join(', ')}`;\n } catch {\n /* invalid URL */\n }\n if (valid) return { valid: true, errors: [] };\n return validationFail(errorMessage, defaultMsg, val, this);\n });\n },\n\n /**\n * Validates that the string is a valid UUID (versions 1–5).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the UUID validator applied\n *\n * @example\n * ```ts\n * string().uuid();\n * string().uuid('Invalid identifier');\n * ```\n */\n uuid(\n this: StringSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n return this.withExtension('uuid', true).addValidator(val => {\n if (typeof val !== 'string')\n return validationFail(\n errorMessage,\n 'must be a valid UUID',\n val,\n this\n );\n const valid = UUID_RE.test(val);\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must be a valid UUID',\n val,\n this\n );\n });\n },\n\n /**\n * Validates that the string is a valid IP address (IPv4 or IPv6).\n *\n * Pass `opts.version` to restrict validation to a specific IP version.\n *\n * @param opts - optional configuration\n * @param opts.version - restrict to `'v4'` or `'v6'` (default: accept both)\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the IP validator applied\n *\n * @example\n * ```ts\n * string().ip();\n * string().ip({ version: 'v4' });\n * string().ip(undefined, 'Bad IP address');\n * ```\n */\n ip(\n this: StringSchemaBuilder,\n opts?: { version?: 'v4' | 'v6' },\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n const version = opts?.version;\n const meta = version ? { version } : true;\n\n return this.withExtension('ip', meta).addValidator(val => {\n const defaultMsg = version\n ? `must be a valid ${version} IP address`\n : 'must be a valid IP address';\n if (typeof val !== 'string')\n return validationFail(errorMessage, defaultMsg, val, this);\n let valid: boolean;\n if (version === 'v4') {\n valid = IPV4_RE.test(val);\n } else if (version === 'v6') {\n valid = IPV6_RE.test(val);\n } else {\n valid = IPV4_RE.test(val) || IPV6_RE.test(val);\n }\n if (valid) return { valid: true, errors: [] };\n return validationFail(errorMessage, defaultMsg, val, this);\n });\n },\n\n /**\n * Preprocessor that trims leading and trailing whitespace before validation.\n *\n * @returns a new schema builder with the trim preprocessor applied\n *\n * @example\n * ```ts\n * string().trim().minLength(1); // ' hi ' → 'hi'\n * ```\n */\n trim(this: StringSchemaBuilder) {\n return this.addPreprocessor(val =>\n typeof val === 'string' ? val.trim() : val\n );\n },\n\n /**\n * Preprocessor that converts the string to lowercase before validation.\n *\n * @returns a new schema builder with the toLowerCase preprocessor applied\n *\n * @example\n * ```ts\n * string().toLowerCase(); // 'HELLO' → 'hello'\n * ```\n */\n toLowerCase(this: StringSchemaBuilder) {\n return this.addPreprocessor(val =>\n typeof val === 'string' ? val.toLowerCase() : val\n );\n },\n\n /**\n * Validates that the string is not empty (length > 0).\n *\n * @param errorMessage - custom error message or function to generate one\n * @returns a new schema builder with the nonempty validator applied\n *\n * @example\n * ```ts\n * string().nonempty();\n * string().nonempty('Name is required');\n * ```\n */\n nonempty(\n this: StringSchemaBuilder,\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n ) {\n return this.withExtension('nonempty', true).addValidator(val => {\n if (typeof val !== 'string')\n return validationFail(\n errorMessage,\n 'must not be empty',\n val,\n this\n );\n const valid = val.length > 0;\n if (valid) return { valid: true, errors: [] };\n return validationFail(\n errorMessage,\n 'must not be empty',\n val,\n this\n );\n });\n },\n\n /**\n * Constrains the string to one of the specified literal values.\n *\n * @param args - the allowed string literals, optionally followed by an error message\n * @returns a new schema builder restricted to the given values\n *\n * @example\n * ```ts\n * string().oneOf('admin', 'user', 'guest');\n * string().oneOf(['admin', 'user'], 'Invalid role');\n * ```\n */\n oneOf(this: StringSchemaBuilder, ...args: any[]) {\n let values: string[];\n let errorMessage:\n | ValidationErrorMessageProvider<StringSchemaBuilder>\n | undefined;\n\n if (args.length === 0) {\n throw new Error('oneOf requires at least one value');\n }\n\n if (Array.isArray(args[0])) {\n // Array form: oneOf(['a', 'b', 'c'], errorMessage?)\n values = args[0] as string[];\n errorMessage = args[1] as\n | ValidationErrorMessageProvider<StringSchemaBuilder>\n | undefined;\n } else {\n // Rest params form: oneOf('a', 'b', 'c') or oneOf('a', 'b', errorFn)\n // Last arg is a function → error message factory (unambiguous)\n const lastArg = args[args.length - 1];\n if (typeof lastArg === 'function') {\n values = args.slice(0, -1) as string[];\n errorMessage =\n lastArg as ValidationErrorMessageProvider<StringSchemaBuilder>;\n } else {\n values = args as string[];\n errorMessage = undefined;\n }\n }\n\n if (values.length === 0) {\n throw new Error('oneOf requires at least one value');\n }\n\n const allowed = new Set(values);\n return this.withExtension('oneOf', values).addValidator(val => {\n if (typeof val === 'string' && allowed.has(val)) {\n return { valid: true, errors: [] };\n }\n return validationFail(\n errorMessage,\n `must be one of: ${values.join(', ')}`,\n val,\n this\n );\n });\n }\n }\n});\n","/**\n * Pre‑wired extension pack for `@cleverbrush/schema`.\n *\n * Combines {@link stringExtensions}, {@link numberExtensions},\n * and {@link arrayExtensions} via\n * `withExtensions()` and re‑exports the augmented factory functions.\n *\n * The default `@cleverbrush/schema` entry point re‑exports these\n * augmented factories so that `email()`, `positive()`, `nonempty()`,\n * `.nullable()`, etc. are available without any setup.\n *\n * @module\n */\nimport type { AnySchemaBuilder } from '../builders/AnySchemaBuilder.js';\nimport type { ArraySchemaBuilder } from '../builders/ArraySchemaBuilder.js';\nimport type { BooleanSchemaBuilder } from '../builders/BooleanSchemaBuilder.js';\nimport type { DateSchemaBuilder } from '../builders/DateSchemaBuilder.js';\nimport type { FunctionSchemaBuilder } from '../builders/FunctionSchemaBuilder.js';\nimport type { NumberSchemaBuilder } from '../builders/NumberSchemaBuilder.js';\nimport type { ObjectSchemaBuilder } from '../builders/ObjectSchemaBuilder.js';\nimport type { PromiseSchemaBuilder } from '../builders/PromiseSchemaBuilder.js';\nimport type { RecordSchemaBuilder } from '../builders/RecordSchemaBuilder.js';\nimport type {\n SchemaBuilder,\n ValidationErrorMessageProvider\n} from '../builders/SchemaBuilder.js';\nimport type { StringSchemaBuilder } from '../builders/StringSchemaBuilder.js';\nimport type { TupleSchemaBuilder } from '../builders/TupleSchemaBuilder.js';\nimport type { UnionSchemaBuilder } from '../builders/UnionSchemaBuilder.js';\nimport type { HiddenExtensionMethods } from '../extension.js';\nimport { withExtensions } from '../extension.js';\nimport type { ArrayBuiltinExtensions } from './array.js';\nimport { arrayExtensions } from './array.js';\nimport type { NumberBuiltinExtensions } from './number.js';\nimport { numberExtensions } from './number.js';\nimport type { StringBuiltinExtensions } from './string.js';\nimport { stringExtensions } from './string.js';\n\nexport { type ArrayBuiltinExtensions, arrayExtensions } from './array.js';\nexport {\n type NumberBuiltinExtensions,\n type NumberOneOfExtension,\n numberExtensions\n} from './number.js';\nexport {\n type StringBuiltinExtensions,\n type StringOneOfExtension,\n stringExtensions\n} from './string.js';\n\n// ---------------------------------------------------------------------------\n// Explicitly-typed factories — preserves JSDoc in .d.ts output.\n// WORKAROUND: TypeScript strips JSDoc when signatures pass through the\n// FixedMethods mapped type (conditional `infer` loses comments). These\n// explicit type aliases + factory annotations bypass FixedMethods so that\n// JSDoc from the *BuiltinExtensions interfaces reaches consumers.\n// Remove once TypeScript preserves JSDoc through mapped types.\n// See: https://github.com/microsoft/TypeScript/issues/50715\n// ---------------------------------------------------------------------------\n\n/** A `StringSchemaBuilder` with built-in extension methods. */\nexport type ExtendedString<T extends string = string> = StringSchemaBuilder<\n T,\n true,\n false,\n false,\n StringBuiltinExtensions<T>\n> &\n StringBuiltinExtensions<T> &\n HiddenExtensionMethods;\n\n/** A `NumberSchemaBuilder` with built-in extension methods. */\nexport type ExtendedNumber<T extends number = number> = NumberSchemaBuilder<\n T,\n true,\n false,\n false,\n NumberBuiltinExtensions<T>\n> &\n NumberBuiltinExtensions<T> &\n HiddenExtensionMethods;\n\n/** An `ArraySchemaBuilder` with built-in extension methods. */\nexport type ExtendedArray<\n TElementSchema extends SchemaBuilder<\n any,\n any,\n any,\n any,\n any\n > = SchemaBuilder<any, any, any>\n> = ArraySchemaBuilder<\n TElementSchema,\n true,\n false,\n undefined,\n false,\n ArrayBuiltinExtensions<TElementSchema>\n> &\n ArrayBuiltinExtensions<TElementSchema> &\n HiddenExtensionMethods;\n\n/** A `BooleanSchemaBuilder` with built-in extension methods. */\nexport type ExtendedBoolean = BooleanSchemaBuilder<\n boolean,\n true,\n false,\n undefined,\n false,\n {}\n> &\n HiddenExtensionMethods;\n\n/** A `DateSchemaBuilder` with built-in extension methods. */\nexport type ExtendedDate = DateSchemaBuilder<Date, true, false, false, {}> &\n HiddenExtensionMethods;\n\n/** An `ObjectSchemaBuilder` with built-in extension methods. */\nexport type ExtendedObject<\n TProps extends Record<string, SchemaBuilder<any, any, any, any, any>> = {}\n> = ObjectSchemaBuilder<TProps, true, false, undefined, false, {}, []> &\n HiddenExtensionMethods;\n\n/** A `UnionSchemaBuilder` with built-in extension methods. */\nexport type ExtendedUnion<\n TOptions extends readonly SchemaBuilder<any, any, any, any, any>[]\n> = UnionSchemaBuilder<TOptions, true, false, undefined, false, {}> &\n HiddenExtensionMethods;\n\n/** A `FunctionSchemaBuilder` with built-in extension methods. */\nexport type ExtendedFunc = FunctionSchemaBuilder<\n true,\n false,\n undefined,\n false,\n {}\n> &\n HiddenExtensionMethods;\n\n/** A `PromiseSchemaBuilder` with built-in extension methods. */\nexport type ExtendedPromise<\n TResolvedTypeSchema extends\n | SchemaBuilder<any, any, any, any, any>\n | undefined = undefined\n> = PromiseSchemaBuilder<\n true,\n false,\n undefined,\n false,\n {},\n TResolvedTypeSchema\n> &\n HiddenExtensionMethods;\n\n/** An `AnySchemaBuilder` with built-in extension methods. */\nexport type ExtendedAny = AnySchemaBuilder<true, false, undefined, false, {}> &\n HiddenExtensionMethods;\n\n/** A `TupleSchemaBuilder` with built-in extension methods. */\nexport type ExtendedTuple<\n TElements extends readonly SchemaBuilder<\n any,\n any,\n any\n >[] = readonly SchemaBuilder<any, any, any, any, any>[]\n> = TupleSchemaBuilder<TElements, true, false, undefined, false, {}> &\n HiddenExtensionMethods;\n\n/** A `RecordSchemaBuilder` with built-in extension methods. */\nexport type ExtendedRecord<\n TKeySchema extends StringSchemaBuilder<\n any,\n any,\n any,\n any\n > = StringSchemaBuilder<any, any, any, any>,\n TValueSchema extends SchemaBuilder<any, any, any, any, any> = SchemaBuilder<\n any,\n any,\n any\n >\n> = RecordSchemaBuilder<\n TKeySchema,\n TValueSchema,\n true,\n false,\n undefined,\n false,\n {}\n> &\n HiddenExtensionMethods;\n\n// -- Runtime factories with explicit type annotations -------------------------\n\nconst s = withExtensions(stringExtensions, numberExtensions, arrayExtensions);\n\nexport const string: {\n (): ExtendedString;\n <T extends string>(equals: T): ExtendedString<T>;\n} = s.string as any;\n\nexport const number: {\n (): ExtendedNumber;\n <T extends number>(equals: T): ExtendedNumber<T>;\n} = s.number as any;\n\nexport const array: <\n TElementSchema extends SchemaBuilder<any, any, any, any, any>\n>(\n elementSchema?: TElementSchema\n) => ExtendedArray<TElementSchema> = s.array as any;\n\nexport const boolean: () => ExtendedBoolean = s.boolean as any;\nexport const date: () => ExtendedDate = s.date as any;\nexport const object: {\n (): ExtendedObject<{}>;\n <TProps extends Record<string, SchemaBuilder<any, any, any, any, any>>>(\n props: TProps\n ): ExtendedObject<TProps>;\n <TProps extends Record<string, SchemaBuilder<any, any, any, any, any>>>(\n props?: TProps\n ): ExtendedObject<TProps>;\n} = s.object as any;\nexport const union: <TOptions extends SchemaBuilder<any, any, any, any, any>>(\n schema: TOptions\n) => ExtendedUnion<[TOptions]> = s.union as any;\nexport const func: () => ExtendedFunc = s.func as any;\nexport const any: () => ExtendedAny = s.any as any;\nexport const tuple: <\n const TElements extends readonly SchemaBuilder<any, any, any, any, any>[]\n>(\n elements: [...TElements]\n) => ExtendedTuple<TElements> = s.tuple as any;\n\nexport const 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) => ExtendedRecord<TKeySchema, TValueSchema> = s.record as any;\n\nexport const promise: <TWrapped extends SchemaBuilder<any, any, any, any, any>>(\n wrapped: TWrapped\n) => ExtendedPromise<TWrapped> = s.promise as any;\n\n/**\n * Creates a string schema constrained to the given literal values.\n *\n * Convenience factory equivalent to `string().oneOf(...values)`.\n * Mirrors Zod's `z.enum(['admin', 'user', 'guest'])` API.\n *\n * **Rest-params form** (no custom error message):\n * ```ts\n * const Role = enumOf('admin', 'user', 'guest');\n * ```\n *\n * **Array form** (with optional custom error message):\n * ```ts\n * const Role = enumOf(['admin', 'user', 'guest'], 'Invalid role');\n * const Role2 = enumOf(['admin', 'user'], (val) => `\"${val}\" is not a valid role`);\n * ```\n *\n * @param values - the allowed string literals (at least one required)\n * @returns a typed `StringSchemaBuilder` that only accepts the given values\n *\n * @example\n * ```ts\n * import { enumOf, InferType } from '@cleverbrush/schema';\n *\n * const Role = enumOf('admin', 'user', 'guest');\n * type Role = InferType<typeof Role>; // 'admin' | 'user' | 'guest'\n *\n * Role.validate('admin'); // valid\n * Role.validate('other'); // invalid\n * ```\n */\nexport function enumOf<const T extends string>(\n ...values: [T, ...T[]]\n): ExtendedString<T>;\nexport function enumOf<const T extends string>(\n values: readonly [T, ...T[]],\n errorMessage?: ValidationErrorMessageProvider<StringSchemaBuilder>\n): ExtendedString<T>;\nexport function enumOf<const T extends string>(\n ...args:\n | [T, ...T[]]\n | [\n readonly [T, ...T[]],\n ValidationErrorMessageProvider<StringSchemaBuilder>?\n ]\n): ExtendedString<T> {\n if (Array.isArray(args[0])) {\n return string().oneOf(\n args[0] as readonly [T, ...T[]],\n args[1] as\n | ValidationErrorMessageProvider<StringSchemaBuilder>\n | undefined\n ) as unknown as ExtendedString<T>;\n }\n return string().oneOf(\n ...(args as [T, ...T[]])\n ) as unknown as ExtendedString<T>;\n}\n"],"mappings":"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","names":["validationFail","provider","defaultMsg","value","schema","resolveErrorMessage","result","arrayExtensions","defineExtension","errorMessage","val","validationFail","keyFn","meta","seen","item","key","numberExtensions","defineExtension","errorMessage","val","validationFail","n","remainder","tolerance","args","values","lastArg","allowed","UUID_RE","IPV4_RE","IPV6_RE","stringExtensions","defineExtension","errorMessage","val","validationFail","optsOrError","opts","p","protocols","meta","valid","defaultMsg","proto","version","args","values","lastArg","allowed","s","withExtensions","stringExtensions","numberExtensions","arrayExtensions","string","number","array","boolean","date","object","union","func","any","tuple","record","promise","enumOf","args"]}
package/package.json CHANGED
@@ -31,6 +31,10 @@
31
31
  "types": "./dist/core.d.ts",
32
32
  "import": "./dist/core.js"
33
33
  },
34
+ "./extension": {
35
+ "types": "./dist/extension.d.ts",
36
+ "import": "./dist/extension.js"
37
+ },
34
38
  "./string": {
35
39
  "types": "./dist/builders/StringSchemaBuilder.d.ts",
36
40
  "import": "./dist/builders/StringSchemaBuilder.js"
@@ -102,9 +106,9 @@
102
106
  },
103
107
  "type": "module",
104
108
  "types": "./dist/index.d.ts",
105
- "version": "3.0.1",
109
+ "version": "4.0.0",
106
110
  "devDependencies": {
107
- "@cleverbrush/deep": "^3.0.1"
111
+ "@cleverbrush/deep": "^4.0.0"
108
112
  },
109
113
  "peerDependencies": {
110
114
  "@standard-schema/spec": "^1.1.0"