@warlock.js/seal 5.37.0 → 5.38.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 (49) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/cjs/index.cjs +36 -8
  3. package/cjs/index.cjs.map +1 -1
  4. package/cjs/{object-Um5Ds4ch.cjs → object-BK6x62QZ.cjs} +27 -4
  5. package/cjs/object-BK6x62QZ.cjs.map +1 -0
  6. package/cjs/object.cjs +2 -2
  7. package/cjs/{required-methods-Bh481cKm.cjs → required-methods-Bt9oNJ5V.cjs} +102 -17
  8. package/cjs/required-methods-Bt9oNJ5V.cjs.map +1 -0
  9. package/cjs/{string-BOKt6UtS.cjs → string-bc4YzeXc.cjs} +2 -2
  10. package/cjs/{string-BOKt6UtS.cjs.map → string-bc4YzeXc.cjs.map} +1 -1
  11. package/cjs/string.cjs +2 -2
  12. package/esm/helpers/humanize-attribute.d.mts +18 -0
  13. package/esm/helpers/humanize-attribute.d.mts.map +1 -0
  14. package/esm/helpers/humanize-attribute.mjs +24 -0
  15. package/esm/helpers/humanize-attribute.mjs.map +1 -0
  16. package/esm/helpers/index.d.mts +2 -1
  17. package/esm/helpers/index.mjs +2 -1
  18. package/esm/helpers/validation-helpers.d.mts.map +1 -1
  19. package/esm/helpers/validation-helpers.mjs +2 -1
  20. package/esm/helpers/validation-helpers.mjs.map +1 -1
  21. package/esm/index.d.mts +3 -2
  22. package/esm/index.mjs +2 -1
  23. package/esm/standard-schema/json-schema.d.mts +12 -3
  24. package/esm/standard-schema/json-schema.d.mts.map +1 -1
  25. package/esm/standard-schema/json-schema.mjs +65 -15
  26. package/esm/standard-schema/json-schema.mjs.map +1 -1
  27. package/esm/types/index.d.mts +2 -2
  28. package/esm/types/inference-types.d.mts +13 -0
  29. package/esm/types/inference-types.d.mts.map +1 -1
  30. package/esm/validators/base-validator.d.mts +30 -0
  31. package/esm/validators/base-validator.d.mts.map +1 -1
  32. package/esm/validators/base-validator.mjs +34 -0
  33. package/esm/validators/base-validator.mjs.map +1 -1
  34. package/esm/validators/object-validator.d.mts +23 -4
  35. package/esm/validators/object-validator.d.mts.map +1 -1
  36. package/esm/validators/object-validator.mjs +25 -2
  37. package/esm/validators/object-validator.mjs.map +1 -1
  38. package/esm/validators/scalar-validator.d.mts +1 -1
  39. package/esm/validators/scalar-validator.d.mts.map +1 -1
  40. package/esm/validators/scalar-validator.mjs +8 -5
  41. package/esm/validators/scalar-validator.mjs.map +1 -1
  42. package/esm/validators/union-validator.mjs +4 -2
  43. package/esm/validators/union-validator.mjs.map +1 -1
  44. package/llms-full.txt +2 -1
  45. package/package.json +1 -1
  46. package/skills/define-structural-shape/SKILL.md +1 -1
  47. package/skills/generate-json-schema/SKILL.md +1 -0
  48. package/cjs/object-Um5Ds4ch.cjs.map +0 -1
  49. package/cjs/required-methods-Bh481cKm.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema.mjs","names":[],"sources":["../../../../../../../../packages/seal/src/standard-schema/json-schema.ts"],"sourcesContent":["import type { StandardJSONSchemaV1 } from \"./types\";\n\n/**\n * Supported JSON Schema generation targets.\n */\nexport type JsonSchemaTarget = StandardJSONSchemaV1.Target;\n\n/**\n * The result shape for a generated JSON Schema.\n */\nexport type JsonSchemaResult = Record<string, unknown>;\n\n/**\n * Apply nullable to a JSON Schema object based on the target dialect.\n *\n * - draft-2020-12 : `type` becomes an array: `[\"string\", \"null\"]`\n * - openai-strict : same as draft-2020-12 (type array form)\n * - draft-07 : wraps in `oneOf: [{ ...schema }, { type: \"null\" }]`\n * - openapi-3.0 : adds `nullable: true` alongside the existing type\n *\n * Mutates the schema in-place.\n *\n * @example\n * ```ts\n * const schema = { type: \"string\" };\n * applyNullable(schema, \"draft-2020-12\");\n * // → { type: [\"string\", \"null\"] }\n * ```\n */\nexport function applyNullable(schema: JsonSchemaResult, target: JsonSchemaTarget): void {\n if (target === \"openapi-3.0\") {\n schema.nullable = true;\n return;\n }\n\n if (target === \"draft-2020-12\" || target === \"openai-strict\") {\n const baseType = schema.type as string | string[] | undefined;\n schema.type = Array.isArray(baseType) ? [...baseType, \"null\"] : [baseType as string, \"null\"];\n return;\n }\n\n // draft-07: oneOf wrapping\n const copy = { ...schema };\n for (const key of Object.keys(schema)) {\n delete schema[key];\n }\n schema.oneOf = [copy, { type: \"null\" }];\n}\n\n/**\n * Wrap a field schema as nullable for OpenAI strict mode.\n *\n * OpenAI strict requires optional fields to be expressed as a nullable type\n * rather than being omitted from the `required` array. This helper wraps a\n * given schema into its nullable equivalent using the type-array form.\n *\n * Unlike `applyNullable()` (which mutates in-place), this returns a new\n * schema object to avoid side effects when wrapping child schemas.\n *\n * @example\n * ```ts\n * wrapNullableStrict({ type: \"string\", minLength: 3 })\n * // → { type: [\"string\", \"null\"], minLength: 3 }\n *\n * wrapNullableStrict({ type: \"object\", properties: {...} })\n * // → { type: [\"object\", \"null\"], properties: {...} }\n *\n * wrapNullableStrict({ oneOf: [...] })\n * // → { oneOf: [..., { type: \"null\" }] }\n * ```\n */\nexport function wrapNullableStrict(schema: JsonSchemaResult): JsonSchemaResult {\n // If the schema uses oneOf/anyOf (e.g. union), append null to the list\n if (schema.oneOf) {\n return { ...schema, oneOf: [...(schema.oneOf as unknown[]), { type: \"null\" }] };\n }\n\n if (schema.anyOf) {\n return { ...schema, anyOf: [...(schema.anyOf as unknown[]), { type: \"null\" }] };\n }\n\n // If there's no type at all (permissive `{}`), stay permissive\n if (schema.type === undefined) {\n return schema;\n }\n\n // Standard case: wrap type into array with null\n const baseType = schema.type as string | string[];\n return {\n ...schema,\n type: Array.isArray(baseType) ? [...baseType, \"null\"] : [baseType, \"null\"],\n };\n}\n\n/**\n * Find the first rule matching the given name in a rules array,\n * and return its options bag.\n */\nexport function getRuleOptions(\n rules: Array<{ name: string; context: { options: Record<string, unknown> } }>,\n ruleName: string,\n): Record<string, unknown> | undefined {\n const rule = rules.find((r) => r.name === ruleName);\n return rule?.context?.options as Record<string, unknown> | undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA6BA,SAAgB,cAAc,QAA0B,QAAgC;CACtF,IAAI,WAAW,eAAe;EAC5B,OAAO,WAAW;EAClB;CACF;CAEA,IAAI,WAAW,mBAAmB,WAAW,iBAAiB;EAC5D,MAAM,WAAW,OAAO;EACxB,OAAO,OAAO,MAAM,QAAQ,QAAQ,IAAI,CAAC,GAAG,UAAU,MAAM,IAAI,CAAC,UAAoB,MAAM;EAC3F;CACF;CAGA,MAAM,OAAO,EAAE,GAAG,OAAO;CACzB,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,OAAO,OAAO;CAEhB,OAAO,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;AACxC;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,mBAAmB,QAA4C;CAE7E,IAAI,OAAO,OACT,OAAO;EAAE,GAAG;EAAQ,OAAO,CAAC,GAAI,OAAO,OAAqB,EAAE,MAAM,OAAO,CAAC;CAAE;CAGhF,IAAI,OAAO,OACT,OAAO;EAAE,GAAG;EAAQ,OAAO,CAAC,GAAI,OAAO,OAAqB,EAAE,MAAM,OAAO,CAAC;CAAE;CAIhF,IAAI,OAAO,SAAS,QAClB,OAAO;CAIT,MAAM,WAAW,OAAO;CACxB,OAAO;EACL,GAAG;EACH,MAAM,MAAM,QAAQ,QAAQ,IAAI,CAAC,GAAG,UAAU,MAAM,IAAI,CAAC,UAAU,MAAM;CAC3E;AACF;;;;;AAMA,SAAgB,eACd,OACA,UACqC;CAErC,OADa,MAAM,MAAM,MAAM,EAAE,SAAS,QAChC,CAAC,EAAE,SAAS;AACxB"}
1
+ {"version":3,"file":"json-schema.mjs","names":[],"sources":["../../../../../../../../packages/seal/src/standard-schema/json-schema.ts"],"sourcesContent":["import type { StandardJSONSchemaV1 } from \"./types\";\n\n/**\n * Supported JSON Schema generation targets.\n */\nexport type JsonSchemaTarget = StandardJSONSchemaV1.Target;\n\n/**\n * The result shape for a generated JSON Schema.\n */\nexport type JsonSchemaResult = Record<string, unknown>;\n\n/**\n * Apply nullable to a JSON Schema object based on the target dialect.\n *\n * - draft-2020-12 : `type` becomes an array: `[\"string\", \"null\"]`\n * - openai-strict : same as draft-2020-12 (type array form)\n * - draft-07 : wraps in `oneOf: [{ ...schema }, { type: \"null\" }]`\n * - openapi-3.0 : adds `nullable: true` alongside the existing type\n *\n * Mutates the schema in-place.\n *\n * @example\n * ```ts\n * const schema = { type: \"string\" };\n * applyNullable(schema, \"draft-2020-12\");\n * // → { type: [\"string\", \"null\"] }\n * ```\n */\nexport function applyNullable(schema: JsonSchemaResult, target: JsonSchemaTarget): void {\n if (target === \"openapi-3.0\") {\n schema.nullable = true;\n\n // `nullable: true` alone does not admit null when an enum is present\n if (Array.isArray(schema.enum) && !schema.enum.includes(null)) {\n schema.enum = [...schema.enum, null];\n }\n\n return;\n }\n\n if (target === \"draft-2020-12\" || target === \"openai-strict\") {\n const wrapped = wrapNullableStrict(schema);\n\n for (const key of Object.keys(schema)) {\n delete schema[key];\n }\n\n Object.assign(schema, wrapped);\n return;\n }\n\n // draft-07: oneOf wrapping\n const copy = { ...schema };\n for (const key of Object.keys(schema)) {\n delete schema[key];\n }\n schema.oneOf = [copy, { type: \"null\" }];\n}\n\nconst NULL_BRANCH = { type: \"null\" } as const;\n\nfunction hasNullBranch(branches: unknown[]): boolean {\n return branches.some(\n (branch) => typeof branch === \"object\" && branch !== null && (branch as any).type === \"null\",\n );\n}\n\n/**\n * Wrap a field schema as nullable for OpenAI strict mode.\n *\n * OpenAI strict requires optional fields to be expressed as a nullable type\n * rather than being omitted from the `required` array. This helper wraps a\n * given schema into its nullable equivalent, whatever its shape:\n *\n * - `type` : the type becomes an array with `\"null\"`\n * - `enum` : `null` is added to the enum (and to `type` when present)\n * - `const` : becomes `anyOf: [{ const }, { type: \"null\" }]`\n * - `anyOf` / `oneOf` : a `{ type: \"null\" }` branch is appended once\n * - `allOf` / `$ref` : wrapped in `anyOf` with a null branch\n *\n * Unlike `applyNullable()` (which mutates in-place), this returns a new\n * schema object to avoid side effects when wrapping child schemas.\n *\n * @example\n * ```ts\n * wrapNullableStrict({ type: \"string\", minLength: 3 })\n * // → { type: [\"string\", \"null\"], minLength: 3 }\n *\n * wrapNullableStrict({ enum: [\"left\", \"right\"] })\n * // → { enum: [\"left\", \"right\", null] }\n *\n * wrapNullableStrict({ const: \"items\" })\n * // → { anyOf: [{ const: \"items\" }, { type: \"null\" }] }\n *\n * wrapNullableStrict({ oneOf: [...] })\n * // → { oneOf: [..., { type: \"null\" }] }\n * ```\n */\nexport function wrapNullableStrict(schema: JsonSchemaResult): JsonSchemaResult {\n // Union shapes: append the null branch, once\n for (const key of [\"oneOf\", \"anyOf\"] as const) {\n const branches = schema[key];\n\n if (Array.isArray(branches)) {\n if (hasNullBranch(branches)) return schema;\n\n return { ...schema, [key]: [...branches, { ...NULL_BRANCH }] };\n }\n }\n\n // Permissive `{}` already accepts null\n if (Object.keys(schema).length === 0) {\n return schema;\n }\n\n if (Array.isArray(schema.enum)) {\n const output: JsonSchemaResult = {\n ...schema,\n enum: schema.enum.includes(null) ? schema.enum : [...schema.enum, null],\n };\n\n if (schema.type !== undefined) {\n const baseType = schema.type as string | string[];\n const types = Array.isArray(baseType) ? baseType : [baseType];\n output.type = types.includes(\"null\") ? types : [...types, \"null\"];\n }\n\n return output;\n }\n\n if (schema.const !== undefined) {\n if (schema.const === null) return schema;\n\n const { const: constant, type, ...rest } = schema;\n const branch: JsonSchemaResult =\n type === undefined ? { const: constant } : { const: constant, type };\n\n return { ...rest, anyOf: [branch, { ...NULL_BRANCH }] };\n }\n\n if (schema.type === undefined) {\n // `$ref`, `allOf`, `not` and any other typeless shape: wrap as a whole\n const { description, title, default: defaultValue, ...inner } = schema;\n const output: JsonSchemaResult = { anyOf: [inner, { ...NULL_BRANCH }] };\n\n if (description !== undefined) output.description = description;\n if (title !== undefined) output.title = title;\n if (defaultValue !== undefined) output.default = defaultValue;\n\n return output;\n }\n\n // Standard case: wrap type into array with null\n const baseType = schema.type as string | string[];\n const types = Array.isArray(baseType) ? baseType : [baseType];\n\n return {\n ...schema,\n type: types.includes(\"null\") ? types : [...types, \"null\"],\n };\n}\n\n/**\n * Find the first rule matching the given name in a rules array,\n * and return its options bag.\n */\nexport function getRuleOptions(\n rules: Array<{ name: string; context: { options: Record<string, unknown> } }>,\n ruleName: string,\n): Record<string, unknown> | undefined {\n const rule = rules.find((r) => r.name === ruleName);\n return rule?.context?.options as Record<string, unknown> | undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA6BA,SAAgB,cAAc,QAA0B,QAAgC;CACtF,IAAI,WAAW,eAAe;EAC5B,OAAO,WAAW;EAGlB,IAAI,MAAM,QAAQ,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,GAC1D,OAAO,OAAO,CAAC,GAAG,OAAO,MAAM,IAAI;EAGrC;CACF;CAEA,IAAI,WAAW,mBAAmB,WAAW,iBAAiB;EAC5D,MAAM,UAAU,mBAAmB,MAAM;EAEzC,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,OAAO,OAAO;EAGhB,OAAO,OAAO,QAAQ,OAAO;EAC7B;CACF;CAGA,MAAM,OAAO,EAAE,GAAG,OAAO;CACzB,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,OAAO,OAAO;CAEhB,OAAO,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;AACxC;AAEA,MAAM,cAAc,EAAE,MAAM,OAAO;AAEnC,SAAS,cAAc,UAA8B;CACnD,OAAO,SAAS,MACb,WAAW,OAAO,WAAW,YAAY,WAAW,QAAS,OAAe,SAAS,MACxF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,mBAAmB,QAA4C;CAE7E,KAAK,MAAM,OAAO,CAAC,SAAS,OAAO,GAAY;EAC7C,MAAM,WAAW,OAAO;EAExB,IAAI,MAAM,QAAQ,QAAQ,GAAG;GAC3B,IAAI,cAAc,QAAQ,GAAG,OAAO;GAEpC,OAAO;IAAE,GAAG;KAAS,MAAM,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC;GAAE;EAC/D;CACF;CAGA,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC,WAAW,GACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,IAAI,GAAG;EAC9B,MAAM,SAA2B;GAC/B,GAAG;GACH,MAAM,OAAO,KAAK,SAAS,IAAI,IAAI,OAAO,OAAO,CAAC,GAAG,OAAO,MAAM,IAAI;EACxE;EAEA,IAAI,OAAO,SAAS,QAAW;GAC7B,MAAM,WAAW,OAAO;GACxB,MAAM,QAAQ,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;GAC5D,OAAO,OAAO,MAAM,SAAS,MAAM,IAAI,QAAQ,CAAC,GAAG,OAAO,MAAM;EAClE;EAEA,OAAO;CACT;CAEA,IAAI,OAAO,UAAU,QAAW;EAC9B,IAAI,OAAO,UAAU,MAAM,OAAO;EAElC,MAAM,EAAE,OAAO,UAAU,MAAM,GAAG,SAAS;EAC3C,MAAM,SACJ,SAAS,SAAY,EAAE,OAAO,SAAS,IAAI;GAAE,OAAO;GAAU;EAAK;EAErE,OAAO;GAAE,GAAG;GAAM,OAAO,CAAC,QAAQ,EAAE,GAAG,YAAY,CAAC;EAAE;CACxD;CAEA,IAAI,OAAO,SAAS,QAAW;EAE7B,MAAM,EAAE,aAAa,OAAO,SAAS,cAAc,GAAG,UAAU;EAChE,MAAM,SAA2B,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,YAAY,CAAC,EAAE;EAEtE,IAAI,gBAAgB,QAAW,OAAO,cAAc;EACpD,IAAI,UAAU,QAAW,OAAO,QAAQ;EACxC,IAAI,iBAAiB,QAAW,OAAO,UAAU;EAEjD,OAAO;CACT;CAGA,MAAM,WAAW,OAAO;CACxB,MAAM,QAAQ,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;CAE5D,OAAO;EACL,GAAG;EACH,MAAM,MAAM,SAAS,MAAM,IAAI,QAAQ,CAAC,GAAG,OAAO,MAAM;CAC1D;AACF;;;;;AAMA,SAAgB,eACd,OACA,UACqC;CAErC,OADa,MAAM,MAAM,MAAM,EAAE,SAAS,QAChC,CAAC,EAAE,SAAS;AACxB"}
@@ -5,7 +5,7 @@ import { TypedValidationResult, ValidationResult } from "./result-types.mjs";
5
5
  import { ContextualizedMutator, Mutator, MutatorContext } from "./mutator-types.mjs";
6
6
  import { WhenRuleOptions } from "./conditional-types.mjs";
7
7
  import { ContextualizedTransformer, SimpleTransformerCallback, TransformerCallback } from "./data-transformer-types.mjs";
8
- import { Infer, InferInput, InferInputObjectShape, InferObjectShape, InferOutput, InferOutputObjectShape, IsInputOptionalKey, IsOptionalKey, IsOutputOptionalKey, ValidatedOutput } from "./inference-types.mjs";
8
+ import { Infer, InferInput, InferInputObjectShape, InferObjectShape, InferOutput, InferOutputObjectShape, InternalKeys, IsInputOptionalKey, IsOptionalKey, IsOutputOptionalKey, PartialSchema, ValidatedOutput } from "./inference-types.mjs";
9
9
  import { WEEK_DAYS, WeekDay } from "./date-types.mjs";
10
10
  import { FileSizeOption } from "./file.types.mjs";
11
- export { AttributeTranslation, ContextualSchemaRule, ContextualizedMutator, ContextualizedTransformer, FileSizeOption, Infer, InferInput, InferInputObjectShape, InferObjectShape, InferOutput, InferOutputObjectShape, IsInputOptionalKey, IsOptionalKey, IsOutputOptionalKey, Mutator, MutatorContext, RuleResult, RuleTranslation, Schema, SchemaContext, SchemaRule, SchemaRuleOptions, SimpleTransformerCallback, TransformerCallback, TypedValidationResult, ValidatedOutput, ValidationAttributesList, ValidationResult, WEEK_DAYS, WeekDay, WhenRuleOptions };
11
+ export { AttributeTranslation, ContextualSchemaRule, ContextualizedMutator, ContextualizedTransformer, FileSizeOption, Infer, InferInput, InferInputObjectShape, InferObjectShape, InferOutput, InferOutputObjectShape, InternalKeys, IsInputOptionalKey, IsOptionalKey, IsOutputOptionalKey, Mutator, MutatorContext, PartialSchema, RuleResult, RuleTranslation, Schema, SchemaContext, SchemaRule, SchemaRuleOptions, SimpleTransformerCallback, TransformerCallback, TypedValidationResult, ValidatedOutput, ValidationAttributesList, ValidationResult, WEEK_DAYS, WeekDay, WhenRuleOptions };
@@ -108,6 +108,19 @@ export type IsInputOptionalKey<V> = V extends {
108
108
  } | {
109
109
  hasCatch: true;
110
110
  } ? true : false;
111
+ /**
112
+ * The keys of a schema whose validator was marked with `.internal()`.
113
+ */
114
+ export type InternalKeys<S extends Schema> = { [K in keyof S]: S[K] extends {
115
+ isInternal: true;
116
+ } ? K : never; }[keyof S];
117
+ /**
118
+ * A schema where the given keys are optional. Mapped once over the keys, so
119
+ * the cost grows with the key count, not with the nesting depth.
120
+ */
121
+ export type PartialSchema<S extends Schema, K extends keyof S> = { [P in keyof S]: P extends K ? S[P] & {
122
+ isOptional: true;
123
+ } : S[P]; };
111
124
  /**
112
125
  * Merge the optional-key and required-key halves of an object shape into one
113
126
  * object type, so `Infer<>` reads (and compares) as a single literal instead
@@ -1 +1 @@
1
- {"version":3,"file":"inference-types.d.mts","names":[],"sources":["../../../../../../../../packages/seal/src/types/inference-types.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqFK,aAAa,KAAK;EAAY;WAE/B;EAAY;;;;;;;;YAUJ,oBAAoB,KAAK;EAAY;IAC7C,aAAa;;;;;;;YAWL,mBAAmB,KAAK;EAC9B;;EACA;;EACA;;;;;;;KASD,QAAQ,QAAQ,WAAW,IAAI,EAAE;;;;;;;;KASjC,aAAa,GAAG,KAAK;EAAY;IAAqB,WAAW;;;;;;;;;YAU1D,uBAAuB,UAAU,UAAU,WAElD,WAAW,KAAK,oBAAoB,EAAE,mBAAmB,aAAa,MAAM,OAAO,EAAE,YAErF,WAAW,KAAK,oBAAoB,EAAE,2BAA2B,IAAI,MAAM,OAAO,EAAE;;;;;;;YAU7E,sBAAsB,UAAU,UAAU,WAEjD,WAAW,KAAK,mBAAmB,EAAE,mBAAmB,aAAa,MAAM,MAAM,EAAE,YAEnF,WAAW,KAAK,mBAAmB,EAAE,2BAA2B,IAAI,MAAM,MAAM,EAAE;;;;;YAQ3E,MAAM,KAAK,MAAM,MAAM;yBAGlB;;;;;OAKH,MAAM,KAChB,UAAU,oBAAoB,KAC1B,MAAM,KACN,UAAU,uCAAuC,YAC/C,iBAAiB,oBAAoB,KACnC,UAAU,gBACR,aAAa,GAAG,MAAM,sBAG1B,UAAU,sBAAsB,KAC9B,aAAa,GAAG,sBAAsB,MACtC,UAAU,iBACR;IAAY,iBAAiB,UAAU;MACrC,aAAa,GAAG,MAAM,MAAM,eAE9B,UAAU,uBAAuB,KAC/B,aAAa,GAAG,aAChB,UAAU,0BAA0B,KAClC,aAAa,GAAG,KAChB,UAAU,wBAAwB,KAChC,IACA,UAAU,uBAAuB,KAC/B,IACA,UAAU,uBAAuB,UAC/B,aAAa,GAAG,KAChB,UAAU,kBACR,aAAa,aACb,UAAU,eACR,aAAa,aACb,UAAU,iBACR,aAAa,aACb,UAAU,mBACR,aAAa,cACb,UAAU,gBACR,aAAa,GAAG,QAChB,UAAU,kBACR,aAAa,gCACb,UAAU;;;;;;OAShC,OAAO,KACjB,UAAU,oBAAoB,KAC1B,OAAO,KACP,UAAU,uCAAuC,YAC/C,iBAAiB,oBAAoB,KACnC,UAAU,gBACR,aAAa,GAAG,OAAO,sBAG3B,UAAU,sBAAsB,KAC9B,aAAa,GAAG,uBAAuB,MACvC,UAAU,iBACR;IAAY,iBAAiB,UAAU;MACrC,aAAa,GAAG,MAAM,OAAO,eAE/B,UAAU,uBAAuB,KAC/B,aAAa,GAAG,aAChB,UAAU,0BAA0B,KAClC,aAAa,GAAG,KAChB,UAAU,wBAAwB,KAChC,IACA,UAAU,uBAAuB,KAC/B,IAMA,UAAU,mBACR,aAAa,GAAG,iBAAiB,YAAY,MAC7C,UAAU,kBACR,aAAa,aACb,UAAU,eACR,aAAa,aACb,UAAU,iBACR,aAAa,aACb,UAAU,mBACR,aAAa,cACb,UAAU,gBACR,aAAa,GAAG,QAChB,UAAU,kBACR,aAAa,gCACb,UAAU;;;;;;YASlC,WAAW,KAAK,MAAM,MAAM;;;;;YAM5B,YAAY,KAAK,MAAM,OAAO;;;;YAK9B,iBAAiB,UAAU,UAAU,uBAAuB;;;;YAK5D,cAAc,KAAK,oBAAoB;;;;;;;;;;;YAYvC,gBAAgB,MAAM,MAAM,OAAO,mBAAmB,qBAC9C,UAEd,wCACuB,oBACH,QAAQ,WAEtB,IACF,IACF"}
1
+ {"version":3,"file":"inference-types.d.mts","names":[],"sources":["../../../../../../../../packages/seal/src/types/inference-types.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqFK,aAAa,KAAK;EAAY;WAE/B;EAAY;;;;;;;;YAUJ,oBAAoB,KAAK;EAAY;IAC7C,aAAa;;;;;;;YAWL,mBAAmB,KAAK;EAC9B;;EACA;;EACA;;;;;YAOM,aAAa,UAAU,aAChC,WAAW,IAAI,EAAE;EAAa;IAAqB,mBAC9C;;;;;YAMI,cAAc,UAAU,QAAQ,gBAAgB,QACzD,WAAW,IAAI,UAAU,IAAI,EAAE;EAAO;IAAqB,EAAE;;;;;;KAQ3D,QAAQ,QAAQ,WAAW,IAAI,EAAE;;;;;;;;KASjC,aAAa,GAAG,KAAK;EAAY;IAAqB,WAAW;;;;;;;;;YAU1D,uBAAuB,UAAU,UAAU,WAElD,WAAW,KAAK,oBAAoB,EAAE,mBAAmB,aAAa,MAAM,OAAO,EAAE,YAErF,WAAW,KAAK,oBAAoB,EAAE,2BAA2B,IAAI,MAAM,OAAO,EAAE;;;;;;;YAU7E,sBAAsB,UAAU,UAAU,WAEjD,WAAW,KAAK,mBAAmB,EAAE,mBAAmB,aAAa,MAAM,MAAM,EAAE,YAEnF,WAAW,KAAK,mBAAmB,EAAE,2BAA2B,IAAI,MAAM,MAAM,EAAE;;;;;YAQ3E,MAAM,KAAK,MAAM,MAAM;yBAGlB;;;;;OAKH,MAAM,KAChB,UAAU,oBAAoB,KAC1B,MAAM,KACN,UAAU,uCAAuC,YAC/C,iBAAiB,oBAAoB,KACnC,UAAU,gBACR,aAAa,GAAG,MAAM,sBAG1B,UAAU,sBAAsB,KAC9B,aAAa,GAAG,sBAAsB,MACtC,UAAU,iBACR;IAAY,iBAAiB,UAAU;MACrC,aAAa,GAAG,MAAM,MAAM,eAE9B,UAAU,uBAAuB,KAC/B,aAAa,GAAG,aAChB,UAAU,0BAA0B,KAClC,aAAa,GAAG,KAChB,UAAU,wBAAwB,KAChC,IACA,UAAU,uBAAuB,KAC/B,IACA,UAAU,uBAAuB,UAC/B,aAAa,GAAG,KAChB,UAAU,kBACR,aAAa,aACb,UAAU,eACR,aAAa,aACb,UAAU,iBACR,aAAa,aACb,UAAU,mBACR,aAAa,cACb,UAAU,gBACR,aAAa,GAAG,QAChB,UAAU,kBACR,aAAa,gCACb,UAAU;;;;;;OAShC,OAAO,KACjB,UAAU,oBAAoB,KAC1B,OAAO,KACP,UAAU,uCAAuC,YAC/C,iBAAiB,oBAAoB,KACnC,UAAU,gBACR,aAAa,GAAG,OAAO,sBAG3B,UAAU,sBAAsB,KAC9B,aAAa,GAAG,uBAAuB,MACvC,UAAU,iBACR;IAAY,iBAAiB,UAAU;MACrC,aAAa,GAAG,MAAM,OAAO,eAE/B,UAAU,uBAAuB,KAC/B,aAAa,GAAG,aAChB,UAAU,0BAA0B,KAClC,aAAa,GAAG,KAChB,UAAU,wBAAwB,KAChC,IACA,UAAU,uBAAuB,KAC/B,IAMA,UAAU,mBACR,aAAa,GAAG,iBAAiB,YAAY,MAC7C,UAAU,kBACR,aAAa,aACb,UAAU,eACR,aAAa,aACb,UAAU,iBACR,aAAa,aACb,UAAU,mBACR,aAAa,cACb,UAAU,gBACR,aAAa,GAAG,QAChB,UAAU,kBACR,aAAa,gCACb,UAAU;;;;;;YASlC,WAAW,KAAK,MAAM,MAAM;;;;;YAM5B,YAAY,KAAK,MAAM,OAAO;;;;YAK9B,iBAAiB,UAAU,UAAU,uBAAuB;;;;YAK5D,cAAc,KAAK,oBAAoB;;;;;;;;;;;YAYvC,gBAAgB,MAAM,MAAM,OAAO,mBAAmB,qBAC9C,UAEd,wCACuB,oBACH,QAAQ,WAEtB,IACF,IACF"}
@@ -17,6 +17,8 @@ export declare class BaseValidator<TInput = unknown, TOutput = TInput> {
17
17
  protected defaultValue: any | (() => any);
18
18
  protected description?: string;
19
19
  protected shouldOmit: boolean;
20
+ /** Set by `.internal()`: the server fills this field, request schemas leave it out. */
21
+ protected serverSet: boolean;
20
22
  protected isNullable: boolean;
21
23
  protected isMutable: boolean;
22
24
  /** Treat empty or whitespace-only form strings as an absent value. */
@@ -286,6 +288,34 @@ export declare class BaseValidator<TInput = unknown, TOutput = TInput> {
286
288
  * @alias omit
287
289
  */
288
290
  exclude(): this;
291
+ /**
292
+ * Mark this field as set by the server, never by the client.
293
+ *
294
+ * The field stays a normal member of the schema: it validates, casts and
295
+ * infers exactly as before, so a Cascade model can write it. Request schemas
296
+ * derived with `ObjectValidator#withoutInternal()` (or `Model.requestSchema()`)
297
+ * leave it out, so the same declaration serves the model and the request.
298
+ *
299
+ * Brands the return type with `{ isInternal: true }` so the derived schema
300
+ * drops the key at the type level too.
301
+ *
302
+ * @example
303
+ * ```ts
304
+ * const postSchema = v.object({
305
+ * title: v.string().required(),
306
+ * authorId: v.int().required().internal(),
307
+ * });
308
+ *
309
+ * const requestSchema = postSchema.withoutInternal(); // { title }
310
+ * ```
311
+ */
312
+ internal(): this & {
313
+ isInternal: true;
314
+ };
315
+ /**
316
+ * Whether `.internal()` marked this field as server-set
317
+ */
318
+ isServerSet(): boolean;
289
319
  /**
290
320
  * Check if this field should be omitted from the output
291
321
  */
@@ -1 +1 @@
1
- {"version":3,"file":"base-validator.d.mts","names":[],"sources":["../../../../../../../../packages/seal/src/validators/base-validator.ts"],"mappings":";;;;;;;;;;;;qBAyBa,cAAc,kBAAkB,UAAU;EAC9C,OAAO;YACJ,aAAa;EAChB,UAAU;YACP;YACA;YACA;YACA;YACA;;YAEA;;;;;;;;YASA,oBAEJ,QAAQ,4BAA4B,6BAA6B;YAC7D;;;;;;;;EASH;;;;;;;;EASA,cAAc;;;;YAKX,kBAAkB;;;;;;YAOlB,gBAAgB;;;;YAKhB,sBAAsB;;;;MAKrB;;;;MAQA;;;;;;gBAUG;;;;;EAQP;;;;;;;EAUA;IAAqB;;;;;;;;EAYrB;IAAwB;;;;;;;;;;;;;;;;;;;;EAwBxB,eAAe,WAAW,qBAAqB;;;;;;;;;;;;;;;;;;;EAyB/C,sBAAsB,WAAW,qBAAqB;;;;;;;;;;;;;;;;;;EAwBtD,SAAS,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCnB,OAAO;;;;;EAUD,4BAA4B,WAAW,SAAS,gBAAa;;;;;;;;;;;;;;;;;;EA4BnE,WAAW,YAAY,wBAAwB;;;;EAY/C,gBAAgB,YAAY;;;;EAY5B,SAAS;;;;;;;;;;;;;;;;;;;;;;;EA4BT,YAAY;;;;;;;;;;;;;;;;;;;EAsBZ;;;;;;;EA+BA,iBAAiB;;;;;;;;;;;;;;;;;;EAsBjB;;;;EASA;;;;EAOA;;;;EAOA,QAAQ,UAAU,oBAAoB,mBAC3C,MAAM,WAAW,IACjB,uBACA,UAAS;;;;;;;;;;;;;;;;;;;EAyBJ,gBAAgB,UAAU,oBAAoB,mBACnD,MAAM,WAAW,IACjB,uBACA,UAAS;;;;EAWJ,eAAe,UAAU,oBAAoB,mBAClD,MAAM,WAAW,IACjB,uBACA,UAAS,IACR,qBAAqB;;;;YAWd,WAAW,UAAU,oBAAoB,mBACjD,MAAM,WAAW,IACjB,uBACA,UAAS,IACR,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;EA8CjB,QAAQ,UAAU,oBAAoB,mBAC3C,MAAM,WAAW,IACjB,UAAU;IAAM;;;;;;EAUX,OACL,WACE,OAAO,mDACP,SAAS,kBACN;;YAoBS,aACd,QAAQ,kBACR,SAAS,gBACR,QAAQ;;;;EAkBJ,WAAW,SAAS,SAAS;;;;EAS7B,kBAAkB,SAAS,SAAS;;;;;;;;EAiBpC,QAAQ;IAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoC9B,MACL,kBAEM,QAAQ,4BAA4B,6BAA6B;IAC7D;;;;;EAYC,OAAO,WAAW,SAAS,gBAAa;;;;EAc9C,MAAM;;;;EASA,SAAS,WAAW,SAAS,gBAAgB,QAAQ;;YAclD,cAAc,WAAW,SAAS,gBAAgB,QAAQ;;;;YA8HhE,sBAAsB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAoDjB,qBAAqB,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCjD,aAAa,UAAS,mBAAqC"}
1
+ {"version":3,"file":"base-validator.d.mts","names":[],"sources":["../../../../../../../../packages/seal/src/validators/base-validator.ts"],"mappings":";;;;;;;;;;;;qBAyBa,cAAc,kBAAkB,UAAU;EAC9C,OAAO;YACJ,aAAa;EAChB,UAAU;YACP;YACA;YACA;;YAEA;YACA;YACA;;YAEA;;;;;;;;YASA,oBAEJ,QAAQ,4BAA4B,6BAA6B;YAC7D;;;;;;;;EASH;;;;;;;;EASA,cAAc;;;;YAKX,kBAAkB;;;;;;YAOlB,gBAAgB;;;;YAKhB,sBAAsB;;;;MAKrB;;;;MAQA;;;;;;gBAUG;;;;;EAQP;;;;;;;EAUA;IAAqB;;;;;;;;EAYrB;IAAwB;;;;;;;;;;;;;;;;;;;;EAwBxB,eAAe,WAAW,qBAAqB;;;;;;;;;;;;;;;;;;;EAyB/C,sBAAsB,WAAW,qBAAqB;;;;;;;;;;;;;;;;;;EAwBtD,SAAS,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCnB,OAAO;;;;;EAUD,4BAA4B,WAAW,SAAS,gBAAa;;;;;;;;;;;;;;;;;;EA4BnE,WAAW,YAAY,wBAAwB;;;;EAY/C,gBAAgB,YAAY;;;;EAY5B,SAAS;;;;;;;;;;;;;;;;;;;;;;;EA4BT,YAAY;;;;;;;;;;;;;;;;;;;EAsBZ;;;;;;;EAgCA,iBAAiB;;;;;;;;;;;;;;;;;;EAsBjB;;;;EASA;;;;;;;;;;;;;;;;;;;;;;EAyBA;IAAqB;;;;;EASrB;;;;EAOA;;;;EAOA,QAAQ,UAAU,oBAAoB,mBAC3C,MAAM,WAAW,IACjB,uBACA,UAAS;;;;;;;;;;;;;;;;;;;EAyBJ,gBAAgB,UAAU,oBAAoB,mBACnD,MAAM,WAAW,IACjB,uBACA,UAAS;;;;EAWJ,eAAe,UAAU,oBAAoB,mBAClD,MAAM,WAAW,IACjB,uBACA,UAAS,IACR,qBAAqB;;;;YAWd,WAAW,UAAU,oBAAoB,mBACjD,MAAM,WAAW,IACjB,uBACA,UAAS,IACR,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;EA8CjB,QAAQ,UAAU,oBAAoB,mBAC3C,MAAM,WAAW,IACjB,UAAU;IAAM;;;;;;EAUX,OACL,WACE,OAAO,mDACP,SAAS,kBACN;;YAoBS,aACd,QAAQ,kBACR,SAAS,gBACR,QAAQ;;;;EAkBJ,WAAW,SAAS,SAAS;;;;EAS7B,kBAAkB,SAAS,SAAS;;;;;;;;EAiBpC,QAAQ;IAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoC9B,MACL,kBAEM,QAAQ,4BAA4B,6BAA6B;IAC7D;;;;;EAYC,OAAO,WAAW,SAAS,gBAAa;;;;EAc9C,MAAM;;;;EASA,SAAS,WAAW,SAAS,gBAAgB,QAAQ;;YAclD,cAAc,WAAW,SAAS,gBAAgB,QAAQ;;;;YA8HhE,sBAAsB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAoDjB,qBAAqB,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCjD,aAAa,UAAS,mBAAqC"}
@@ -15,6 +15,7 @@ var BaseValidator = class {
15
15
  this.refinements = [];
16
16
  this.mutators = [];
17
17
  this.shouldOmit = false;
18
+ this.serverSet = false;
18
19
  this.isNullable = false;
19
20
  this.isMutable = false;
20
21
  this.blankIsMissing = false;
@@ -277,6 +278,7 @@ var BaseValidator = class {
277
278
  cloned.dataTransformers = [...this.dataTransformers];
278
279
  cloned.defaultValue = this.defaultValue;
279
280
  cloned.shouldOmit = this.shouldOmit;
281
+ cloned.serverSet = this.serverSet;
280
282
  cloned.description = this.description;
281
283
  cloned.attributesText = { ...this.attributesText };
282
284
  cloned.translatedAttributes = { ...this.translatedAttributes };
@@ -326,6 +328,38 @@ var BaseValidator = class {
326
328
  return this.omit();
327
329
  }
328
330
  /**
331
+ * Mark this field as set by the server, never by the client.
332
+ *
333
+ * The field stays a normal member of the schema: it validates, casts and
334
+ * infers exactly as before, so a Cascade model can write it. Request schemas
335
+ * derived with `ObjectValidator#withoutInternal()` (or `Model.requestSchema()`)
336
+ * leave it out, so the same declaration serves the model and the request.
337
+ *
338
+ * Brands the return type with `{ isInternal: true }` so the derived schema
339
+ * drops the key at the type level too.
340
+ *
341
+ * @example
342
+ * ```ts
343
+ * const postSchema = v.object({
344
+ * title: v.string().required(),
345
+ * authorId: v.int().required().internal(),
346
+ * });
347
+ *
348
+ * const requestSchema = postSchema.withoutInternal(); // { title }
349
+ * ```
350
+ */
351
+ internal() {
352
+ const instance = this.instance;
353
+ instance.serverSet = true;
354
+ return instance;
355
+ }
356
+ /**
357
+ * Whether `.internal()` marked this field as server-set
358
+ */
359
+ isServerSet() {
360
+ return this.serverSet;
361
+ }
362
+ /**
329
363
  * Check if this field should be omitted from the output
330
364
  */
331
365
  isOmitted() {
@@ -1 +1 @@
1
- {"version":3,"file":"base-validator.mjs","names":["defaultRequiredRule"],"sources":["../../../../../../../../packages/seal/src/validators/base-validator.ts"],"sourcesContent":["import { clone } from \"@mongez/reinforcements\";\nimport { validate } from \"../factory/validate\";\nimport { VALID_RULE, invalidRule } from \"../helpers/validation-helpers\";\nimport { isEmptyValue } from \"../helpers/is-empty-value\";\nimport { requiredRule as defaultRequiredRule } from \"../rules/core/required\";\nimport type { JsonSchemaResult, JsonSchemaTarget } from \"../standard-schema/json-schema\";\nimport { mapToStandardResult } from \"../standard-schema/map-result\";\nimport type { StandardJSONSchemaV1, StandardSchemaV1 } from \"../standard-schema/types\";\nimport type {\n ContextualSchemaRule,\n ContextualizedMutator,\n ContextualizedTransformer,\n Mutator,\n SchemaContext,\n SchemaRule,\n SchemaRuleOptions,\n SimpleTransformerCallback,\n TransformerCallback,\n ValidationAttributesList,\n ValidationResult,\n} from \"../types\";\n\n/**\n * Base validator class - foundation for all validators\n */\nexport class BaseValidator<TInput = unknown, TOutput = TInput> {\n public rules: ContextualSchemaRule[] = [];\n protected refinements: ContextualSchemaRule[] = [];\n public mutators: ContextualizedMutator[] = [];\n protected defaultValue: any | (() => any);\n protected description?: string;\n protected shouldOmit = false;\n protected isNullable = false;\n protected isMutable = false;\n /** Treat empty or whitespace-only form strings as an absent value. */\n protected blankIsMissing = false;\n\n /**\n * Catch state — when `hasCatch` is true and validation fails, `catchValue`\n * (or its callback result) substitutes for the failed value, and the public\n * result reports `isValid: true` with no errors.\n *\n * See `.catch()` for semantics and the v1 scope (leaf-only).\n */\n protected catchValue:\n | any\n | ((errors: ValidationResult[\"errors\"], originalInput: any) => any | Promise<any>);\n protected hasCatch = false;\n\n /**\n * Whether the field is optional.\n * - false (default): field is required unless a requiredRule governs the condition.\n * - true: field can be absent or empty — set by calling .optional().\n *\n * Also used as a TypeScript literal brand via the optional() return type.\n */\n public isOptional = false;\n\n /**\n * The single required-condition rule for this field.\n * - null: field uses strict default (always required when not optional).\n * - set: the rule governs when the field is required (e.g., requiredIf).\n *\n * Stored separately from rules[] and prepended at validate() time.\n */\n public requiredRule: ContextualSchemaRule | null = this.createRule(defaultRequiredRule);\n\n /**\n * Pipeline to transform the mutated/original data before returning it\n */\n protected dataTransformers: ContextualizedTransformer[] = [];\n\n /**\n * Attributes text to be replaced on translations\n * If the value is an object, it will be used as the attributes list for the rule\n * If the value is a string, it will be used as the attributes list for the rule\n */\n protected attributesText: ValidationAttributesList = {};\n\n /**\n * Attributed that will be always using the attribute translator\n */\n protected translatedAttributes: Record<string, string> = {};\n\n /**\n * Mark the validator as mutable\n */\n public get mutable() {\n this.isMutable = true;\n return this;\n }\n\n /**\n * Mark the validator as immutable\n */\n public get immutable() {\n this.isMutable = false;\n return this;\n }\n\n /**\n * Get the instance to apply changes to.\n * By default (immutable), returns a clone so the original is unchanged.\n * When `.mutable` is set, returns `this` to mutate in place.\n */\n protected get instance(): this {\n return this.isMutable ? this : this.clone();\n }\n\n /**\n * Get the default value\n * Supports lazy evaluation via callbacks\n */\n public getDefaultValue(): any {\n return typeof this.defaultValue === \"function\" ? this.defaultValue() : this.defaultValue;\n }\n\n /**\n * Allow null as a valid value.\n *\n * Brands the return type with `{ isNullable: true }` so `Infer<>` widens\n * the inferred output to include `| null`.\n */\n public nullable(): this & { isNullable: true } {\n const instance = this.instance;\n instance.isNullable = true;\n return instance as this & { isNullable: true };\n }\n\n /**\n * Explicitly disallow null values after calling nullable.\n *\n * Brands the return type with `{ isNullable: false }` to cancel any prior\n * `.nullable()` at the type level.\n */\n public notNullable(): this & { isNullable: false } {\n const instance = this.instance;\n instance.isNullable = false;\n return instance as this & { isNullable: false };\n }\n\n /**\n * Add transformer with optional options\n *\n * @param transform - The transformer callback function\n * @param options - Optional options to pass to the transformer\n *\n * @example\n * ```ts\n * // Without options\n * v.date().addTransformer(data => data.toISOString())\n *\n * // With options\n * v.date().addTransformer(\n * (data, { options }) => dayjs(data).format(options.format),\n * { format: 'YYYY-MM-DD' }\n * )\n * ```\n */\n public addTransformer(transform: TransformerCallback, options: any = {}) {\n const instance = this.instance;\n instance.addMutableTransformer(transform, options);\n\n return instance;\n }\n\n /**\n * Add transformer with optional options\n *\n * @param transform - The transformer callback function\n * @param options - Optional options to pass to the transformer\n *\n * @example\n * ```ts\n * // Without options\n * v.date().addTransformer(data => data.toISOString())\n *\n * // With options\n * v.date().addTransformer(\n * (data, { options }) => dayjs(data).format(options.format),\n * { format: 'YYYY-MM-DD' }\n * )\n * ```\n */\n public addMutableTransformer(transform: TransformerCallback, options: any = {}) {\n this.dataTransformers.push({\n transform,\n options,\n });\n }\n\n /**\n * Transform the output value - simple one-time transformation\n *\n * @param callback - Simple callback receiving data and context\n *\n * @example\n * ```ts\n * // Simple transformation\n * v.string().outputAs(data => data.toUpperCase())\n *\n * // With context\n * v.string().outputAs((data, context) => {\n * console.log(`Transforming ${context.path}`);\n * return data.toLowerCase();\n * })\n * ```\n */\n public outputAs(callback: SimpleTransformerCallback) {\n return this.addTransformer((data, { context }) => callback(data, context));\n }\n\n /**\n * Transform output to JSON string\n *\n * Works with any validator type (string, number, date, object, array, etc.)\n *\n * @param indent - Optional indentation for pretty printing (default: 0 for compact)\n *\n * @example\n * ```ts\n * // Compact JSON\n * v.object({ name: v.string() }).toJSON()\n * // Output: '{\"name\":\"John\"}'\n *\n * // Pretty-printed JSON\n * v.array(v.object({...})).toJSON(2)\n * // Output:\n * // [\n * // {\n * // \"name\": \"John\"\n * // }\n * // ]\n *\n * // Works with any type\n * v.string().toJSON() // '\"hello\"'\n * v.number().toJSON() // '42'\n * v.date().toJSON() // '\"2024-10-26T00:00:00.000Z\"'\n * ```\n *\n * @category Transformer\n */\n public toJSON(indent?: number) {\n return this.addTransformer((data, { options }) => JSON.stringify(data, null, options.indent), {\n indent: indent ?? 0,\n });\n }\n\n /**\n * Start data transformation pipeline\n * Context is passed at runtime, not stored\n */\n public async startTransformationPipeline(data: any, context: SchemaContext) {\n for (const transformer of this.dataTransformers) {\n data = await transformer.transform(data, {\n options: transformer.options,\n context,\n });\n }\n\n return data;\n }\n\n /**\n * Set attributes text to be replaced on translations\n * If the value is an object, it will be used as the attributes list for the rule\n * If the value is a string, it will be used as the attributes list for the rule\n *\n * @example\n * v.string().attributes({\n * name: \"Name\",\n * email: \"Email\",\n * });\n * // Example 2: Add custom attributes for matches\n * v.string().matches(\"confirmPassword\").attributes({\n * matches: {\n * confirmPassword: \"Confirm Password\",\n * },\n * });\n */\n public attributes(attributes: Record<string, string | Record<string, string>>) {\n const instance = this.instance;\n for (const [key, value] of Object.entries(attributes)) {\n instance.attributesText[key] = value;\n }\n\n return instance;\n }\n\n /**\n * Define a lazy getter property for each attribute in the given object and use the config attribute translator\n */\n public transAttributes(attributes: Record<string, string>) {\n const instance = this.instance;\n for (const [key, value] of Object.entries(attributes)) {\n instance.translatedAttributes[key] = value;\n }\n\n return instance;\n }\n\n /**\n * Add description to the validator\n */\n public describe(description: string) {\n const instance = this.instance;\n instance.description = description;\n return instance;\n }\n\n /**\n * Check if this validator can handle the given value's type\n * Override this in specific validators to enable type-based routing in union validators\n *\n * Default: returns true (validator will attempt to validate any type)\n *\n * @param value - The value to check\n * @returns True if this validator can handle this type\n *\n * @example\n * ```ts\n * // StringValidator\n * public matchesType(value: any): boolean {\n * return typeof value === 'string';\n * }\n *\n * // Custom FileValidator\n * public matchesType(value: any): boolean {\n * return value instanceof UploadedFile;\n * }\n * ```\n */\n public matchesType(_value: any): boolean {\n return true; // Default: permissive, attempt to validate any type\n }\n\n /**\n * Create a copy of this validator with the same configuration\n * Copies all rules, mutators, transformers, default values, and settings\n *\n * @returns A new validator instance with copied configuration\n *\n * @example\n * ```ts\n * // Create reusable validator templates\n * const baseString = v.string().required().trim().min(3);\n * const emailField = baseString.clone().email();\n * const usernameField = baseString.clone().alphanumeric().max(20);\n *\n * // Works with all validators\n * const positiveInt = v.int().positive().required();\n * const ageField = positiveInt.clone().min(18).max(120);\n * ```\n */\n public clone(): this {\n // Create a new instance using Object.create to preserve the prototype chain\n const Constructor = this.constructor as new (...args: any[]) => this;\n const cloned = Object.create(Constructor.prototype);\n\n // Copy all BaseValidator properties\n cloned.rules = [...this.rules];\n cloned.refinements = [...this.refinements];\n cloned.mutators = [...this.mutators];\n cloned.dataTransformers = [...this.dataTransformers];\n cloned.defaultValue = this.defaultValue;\n cloned.shouldOmit = this.shouldOmit;\n cloned.description = this.description;\n cloned.attributesText = { ...this.attributesText };\n cloned.translatedAttributes = { ...this.translatedAttributes };\n cloned.isNullable = this.isNullable;\n cloned.isOptional = this.isOptional;\n cloned.blankIsMissing = this.blankIsMissing;\n cloned.requiredRule = this.requiredRule; // same reference is fine — rule is treated as immutable\n cloned.catchValue = this.catchValue;\n cloned.hasCatch = this.hasCatch;\n\n return cloned;\n }\n\n /**\n * @deprecated This method is no longer needed and does nothing.\n * Empty values are now automatically skipped for validation rules by default.\n * Only presence validators (required, present, etc.) will check empty values.\n * You can safely remove this call from your code.\n */\n public ignoreEmptyValue(_ignoreEmptyValue = true) {\n // No-op for backward compatibility\n return this;\n }\n\n /**\n * Omit this field from the validated data output\n *\n * Field will still be validated but not included in the final result.\n * Useful for confirmation fields, captcha, terms acceptance, etc.\n *\n * @example\n * ```ts\n * v.object({\n * password: v.string().required(),\n * confirmPassword: v.string().required().sameAs(\"password\").omit(),\n * acceptTerms: v.boolean().required().omit(),\n * });\n * // Output: { password: \"...\" }\n * // confirmPassword and acceptTerms validated but omitted\n * ```\n */\n public omit() {\n const instance = this.instance;\n instance.shouldOmit = true;\n return instance;\n }\n\n /**\n * @alias omit\n */\n public exclude() {\n return this.omit();\n }\n\n /**\n * Check if this field should be omitted from the output\n */\n public isOmitted(): boolean {\n return this.shouldOmit;\n }\n\n /**\n * Add rule to the validator\n */\n public addRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n errorMessage?: string,\n options: T = {} as T,\n ): this {\n const instance = this.instance;\n instance.addMutableRule(rule, errorMessage, options);\n return instance;\n }\n\n /**\n * Set the required-condition rule for this field.\n *\n * Unlike addRule(), this does NOT push to rules[]. The rule is stored in the\n * dedicated `requiredRule` slot and is prepended to the validation pipeline\n * at runtime. Only one required rule can be active per field — this replaces\n * any previously set required rule.\n *\n * Also marks the field as not optional (isOptional = false).\n *\n * @example\n * ```ts\n * // Used internally by required(), requiredIf(), requiredWith(), etc.\n * BaseValidator.prototype.required = function(msg) {\n * return this.setRequiredRule(requiredRule, msg);\n * };\n * ```\n */\n public setRequiredRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n errorMessage?: string,\n options: T = {} as T,\n ): this {\n const instance = this.instance;\n instance.isOptional = false;\n instance.requiredRule = instance.createRule(rule, errorMessage, options);\n return instance;\n }\n\n /**\n * Add mutable rule\n */\n public addMutableRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n errorMessage?: string,\n options: T = {} as T,\n ): ContextualSchemaRule<T> {\n const newRule: ContextualSchemaRule<T> = this.createRule(rule, errorMessage, options);\n\n this.rules.push(newRule);\n\n return newRule;\n }\n\n /**\n * Create new rule\n */\n protected createRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n errorMessage?: string,\n options: T = {} as T,\n ): ContextualSchemaRule<T> {\n const newRule: ContextualSchemaRule<T> = {\n ...(clone(rule) as ContextualSchemaRule<T>),\n context: {\n errorMessage,\n options,\n attributesList: this.attributesText,\n translatedAttributes: this.translatedAttributes,\n translationParams: {},\n translatableParams: {},\n },\n };\n\n if (errorMessage) {\n newRule.errorMessage = errorMessage;\n }\n\n if (rule.sortOrder === undefined) {\n newRule.sortOrder = this.rules.length + 1;\n }\n\n return newRule;\n }\n\n /**\n * Use a custom or pre-built validation rule\n *\n * @param rule - The validation rule to apply\n * @param options - Rule options including errorMessage and any rule-specific options\n *\n * @example\n * ```ts\n * import { hexColorRule } from \"@warlock.js/seal\";\n *\n * v.string().useRule(hexColorRule, { errorMessage: \"Invalid color\" });\n * ```\n *\n * @example\n * ```ts\n * // With rule options\n * v.string().useRule(myCustomRule, {\n * customOption: true,\n * errorMessage: \"Custom validation failed\"\n * });\n * ```\n */\n public useRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n options?: T & { errorMessage?: string },\n ) {\n const { errorMessage, ...ruleOptions } = options || ({} as any);\n return this.addRule(rule, errorMessage, ruleOptions);\n }\n\n /**\n * Validate the successful output after type rules, children and transformers.\n * Refinements are skipped for absent/null values and failed validation.\n */\n public refine(\n callback: (\n value: NonNullable<this[\"~standard\"][\"types\"]>[\"output\"],\n context: SchemaContext,\n ) => Promise<string | undefined> | string | undefined,\n ): this {\n const instance = this.instance;\n instance.refinements.push(\n instance.createRule({\n name: \"custom\",\n async validate(value, context) {\n const result = await callback(value, context);\n if (result) {\n this.context.errorMessage = result;\n return invalidRule(this, context);\n }\n return VALID_RULE;\n },\n }),\n );\n return instance;\n }\n\n /** Complete validation only after the entire output is available. */\n protected async refineResult(\n result: ValidationResult,\n context: SchemaContext,\n ): Promise<ValidationResult> {\n if (!result.isValid || result.data == null) return result;\n\n const errors: ValidationResult[\"errors\"] = [];\n for (const rule of this.refinements) {\n this.setRuleAttributesList(rule);\n const refined = await rule.validate(result.data, context);\n if (!refined.isValid) {\n errors.push({ type: rule.name, error: refined.error, input: refined.path ?? context.path });\n if (context.configurations?.firstErrorOnly ?? true) break;\n }\n }\n return errors.length ? { isValid: false, errors, data: undefined } : result;\n }\n\n /**\n * Add mutator to the validator\n */\n public addMutator(mutator: Mutator, options: any = {}) {\n const instance = this.instance;\n instance.addMutableMutator(mutator, options);\n return instance;\n }\n\n /**\n * Add mutable mutator\n */\n public addMutableMutator(mutator: Mutator, options: any = {}) {\n this.mutators.push({\n mutate: mutator,\n context: {\n options,\n ctx: {} as any,\n },\n });\n }\n\n /**\n * Set default value for the field. The default is used when the input is\n * absent (`undefined`); it then flows through the rule pipeline.\n *\n * Brands the return type with `{ hasDefault: true }` so `Infer<>` treats\n * the field as guaranteed-present even when chained with `.optional()`.\n */\n public default(value: any): this & { hasDefault: true } {\n const instance = this.instance;\n instance.defaultValue = value;\n return instance as this & { hasDefault: true };\n }\n\n /**\n * Fallback to a value when validation fails.\n *\n * Complementary to `.default()`: `.default(x)` fires when input is **absent**,\n * `.catch(y)` fires when input is **present but invalid**. Combine them when\n * you want both behaviours: `.optional().default(x).catch(y)`.\n *\n * The fallback can be a value or a callback `(errors, originalInput) => fallback`.\n * The callback variant is the only side-channel for the swallowed errors —\n * use it to log/alert before the fallback substitutes.\n *\n * Brands the return type with `{ hasCatch: true }` so `Infer<>` treats the\n * field as guaranteed-present (the catch ensures a value will always exist).\n *\n * **Scope (v1).** Catch is honoured for **leaf validators** (string, number,\n * boolean, date, …) and for fields inside containers. It is a **no-op on\n * container validators themselves** (`v.object`, `v.array`, `v.record`,\n * `v.tuple`, `v.discriminatedUnion`) — those use their own iteration logic\n * that bypasses the catch hook in `BaseValidator.validate()`.\n *\n * @example\n * ```ts\n * v.int().min(0).catch(3) // bad number → 3\n * v.string().in([\"us\", \"eu\"]).catch(\"us\") // unknown enum → \"us\"\n * v.string().catch((errors, input) => {\n * console.warn(`bad user value: ${JSON.stringify(input)}`, errors);\n * return \"anonymous\";\n * })\n * ```\n */\n public catch(\n fallback:\n | any\n | ((errors: ValidationResult[\"errors\"], originalInput: any) => any | Promise<any>),\n ): this & { hasCatch: true } {\n const instance = this.instance;\n\n instance.catchValue = fallback;\n instance.hasCatch = true;\n\n return instance as this & { hasCatch: true };\n }\n\n /**\n * Mutate the data\n */\n public async mutate(data: any, context: SchemaContext) {\n let mutatedData = data;\n\n for (const mutator of this.mutators) {\n mutator.context.ctx = context;\n mutatedData = await mutator.mutate(mutatedData, mutator.context);\n }\n\n return mutatedData;\n }\n\n /**\n * Set the label for the validator that will be matching the :input attribute\n */\n public label(label: string) {\n const instance = this.instance;\n instance.attributesText.input = label;\n return instance;\n }\n\n /**\n * Validate the data\n */\n public async validate(data: any, context: SchemaContext): Promise<ValidationResult> {\n const result = await this.refineResult(await this.validateRules(data, context), context);\n\n if (!result.isValid && this.hasCatch) {\n const fallback =\n typeof this.catchValue === \"function\"\n ? await this.catchValue(result.errors, data)\n : this.catchValue;\n return { isValid: true, errors: [], data: fallback };\n }\n return result;\n }\n\n /** Validate presence and value rules before containers descend into children. */\n protected async validateRules(data: any, context: SchemaContext): Promise<ValidationResult> {\n if (data === null && this.isNullable) {\n return { isValid: true, errors: [], data: null };\n }\n\n const isBlank = this.blankIsMissing && typeof data === \"string\" && data.trim() === \"\";\n\n if (isBlank && this.isNullable) {\n return { isValid: true, errors: [], data: null };\n }\n\n const input = isBlank ? undefined : data;\n let valueForRules = input ?? this.getDefaultValue();\n // A parent object pre-fills an absent key with this field's default and\n // flags it; consume the flag so nested item contexts don't inherit it.\n const parentFilledDefault = context?.valueIsDefault === true;\n\n if (parentFilledDefault) context.valueIsDefault = false;\n\n // A default only stands in for a value when it is one the field accepts:\n // a `null` default on a non-nullable field is still \"no value\".\n const isUsableDefault = (value: unknown) =>\n value !== undefined && (value !== null || this.isNullable);\n\n // A present blank string on a field whose default is itself blank is that\n // default (an HTML form posts `note=\"\"` for an untouched input).\n let blankMatchesDefault = false;\n\n if (typeof input === \"string\" && input.trim() === \"\" && this.defaultValue !== undefined) {\n const fallback = this.getDefaultValue();\n\n if (typeof fallback === \"string\" && fallback.trim() === \"\") {\n valueForRules = fallback;\n blankMatchesDefault = true;\n }\n }\n\n // The author's own default is a value, even an empty one: `.default(\"\")`\n // must not fail the required check it exists to satisfy.\n const usedDefault =\n blankMatchesDefault ||\n (input == null && isUsableDefault(valueForRules)) ||\n (parentFilledDefault && isUsableDefault(input));\n // Optional fields with no resolved value are absent, not values to\n // transform. Skipping here protects every mutator while still allowing\n // defaults and present values through the normal mutation pipeline.\n let mutatedData =\n this.isOptional && valueForRules === undefined\n ? undefined\n : await this.mutate(valueForRules, context);\n\n const errors: ValidationResult[\"errors\"] = [];\n let isValid = true;\n const isFirstErrorOnly = context.configurations?.firstErrorOnly ?? true;\n\n const isEmpty = isEmptyValue(valueForRules);\n\n // D8 fix (design/core-defects-found.md): for an optional field, only a\n // truly ABSENT value (`valueForRules === undefined` — the key was\n // missing, or was `null`/`undefined` and got coalesced above) may skip\n // the value rules. A PRESENT-but-empty value (e.g. `\"\"` from `?page=`)\n // must still run them, so `v.int().optional()` given `\"\"` fails instead\n // of silently handing back a string that `Infer.Output`'s\n // `number | undefined` forbids. Non-optional fields are unaffected —\n // their `requiredRule` (not nulled out by `.optional()`) already rejects\n // `\"\"` before these rules matter.\n // An empty default of the wrong type (`v.int().default(\"\")`) must still\n // meet the type rule; skipping it would hand back a value `Infer.Output`\n // forbids. An empty default of the right type (`v.string().default(\"\")`)\n // keeps skipping the value rules, so `.min(3).default(\"\")` still passes.\n const emptyDefaultOfWrongType =\n usedDefault && isEmpty && valueForRules !== null && !this.matchesType(valueForRules);\n\n const skipEmptyRules = emptyDefaultOfWrongType\n ? false\n : this.isOptional\n ? valueForRules === undefined\n : isEmpty;\n\n // Prepend the required-condition rule if set, so it always runs first.\n // requiredRule has requiresValue = false so it runs even on empty values.\n const rulesToRun =\n this.requiredRule && !usedDefault ? [this.requiredRule, ...this.rules] : this.rules;\n\n for (const rule of rulesToRun) {\n if ((rule.requiresValue ?? true) && skipEmptyRules) continue;\n\n this.setRuleAttributesList(rule);\n\n const result = await rule.validate(mutatedData, context);\n\n if (result.isValid && \"data\" in result) {\n mutatedData = result.data;\n }\n\n if (result.isValid === false) {\n isValid = false;\n const reported = result.errors?.length\n ? result.errors\n : [{ error: result.error, path: result.path }];\n\n for (const { error, path } of reported) {\n errors.push({ type: rule.name, error, input: path ?? context.path });\n }\n\n if (isFirstErrorOnly) {\n break;\n }\n }\n }\n\n const result: ValidationResult = {\n isValid,\n errors,\n data:\n mutatedData !== undefined\n ? await this.startTransformationPipeline(mutatedData, context)\n : undefined,\n };\n\n return result;\n }\n\n /**\n * Set rule attributes list\n */\n protected setRuleAttributesList(rule: ContextualSchemaRule) {\n rule.context.attributesList =\n typeof this.attributesText[rule.name] === \"object\"\n ? (this.attributesText[rule.name] as ValidationAttributesList)\n : this.attributesText;\n rule.context.translatedAttributes = this.translatedAttributes;\n }\n\n /**\n * Standard Schema V1 compliance.\n *\n * Allows this validator to be used with any Standard Schema-aware library\n * (OpenAI structured outputs, LangGraph, TanStack Form, Conform, Valibot adapters, etc.)\n * without extra adapters.\n *\n * Delegates to the `validate()` factory so all `configureSeal()` options\n * (translations, firstErrorOnly) are picked up automatically at call time.\n *\n * Includes Standard JSON Schema support via `jsonSchema.input()` / `jsonSchema.output()`.\n *\n * ## How Standard Schema libraries consume this\n *\n * You pass the **schema object itself** to the library — they internally read\n * `schema[\"~standard\"]`. Do NOT pass `schema[\"~standard\"]` directly.\n *\n * @example\n * ```ts\n * const schema = v.object({ name: v.string().required() });\n *\n * // TanStack Form — pass schema, library reads [\"~standard\"] internally\n * const form = useForm({ validators: { onChange: schema } });\n *\n * // Conform (Remix) — same pattern\n * const [form] = useForm({ onValidate({ formData }) {\n * return parseWithStandardSchema(formData, { schema });\n * }});\n *\n * // Direct validation (lower level — most apps don't need this)\n * const result = await schema[\"~standard\"].validate({ name: \"Hasan\" });\n * // → { value: { name: \"Hasan\" } } on success\n * // → { issues: [{ message: \"...\", path: [{ key: \"name\" }] }] } on failure\n *\n * // JSON Schema for OpenAI / LangChain tool calling\n * const parameters = schema[\"~standard\"].jsonSchema.input({ target: \"openai-strict\" });\n * // → { type: \"object\", properties: {...}, required: [...], additionalProperties: false }\n * ```\n *\n * @note Cross-field rules (sameAs, requiredIf, requiredWith) rely on sibling values\n * available in the full validation context. When called on a standalone scalar validator,\n * sibling data is absent and those rules will not evaluate correctly.\n * Always call on the parent ObjectValidator for full-payload validation.\n */\n get [\"~standard\"](): StandardJSONSchemaV1.Props<TInput, TOutput> {\n return {\n version: 1,\n vendor: \"seal\",\n types: undefined as unknown as StandardSchemaV1.Types<TInput, TOutput>,\n validate: async (value: unknown) => {\n const result = await validate(this, value);\n return mapToStandardResult(result) as StandardSchemaV1.Result<TOutput>;\n },\n jsonSchema: {\n input: (options) => this.toJsonSchema(options.target),\n output: (options) => this.toJsonSchema(options.target),\n },\n };\n }\n\n /**\n * Generate a JSON Schema representation of this validator.\n *\n * Supports targets: `\"draft-2020-12\"` (default), `\"draft-07\"`, `\"openapi-3.0\"`.\n *\n * Subclasses override this to describe their specific constraints.\n * The base implementation returns `{}` (permissive — accepts anything),\n * which is correct for validators with no representable JSON Schema constraints.\n *\n * @note Rules that cannot be expressed in JSON Schema are silently omitted:\n * - Cross-field rules: sameAs, requiredIf, requiredWith, requiredWithout\n * - Custom callbacks: refine()\n * - Framework-specific runtime rules (core/cascade plugins)\n * These rules still run normally at validation time — only absent from JSON Schema.\n *\n * @example\n * ```ts\n * v.string().min(3).max(50).toJsonSchema(\"draft-2020-12\")\n * // → { type: \"string\", minLength: 3, maxLength: 50 }\n *\n * v.object({ name: v.string().required(), age: v.int().optional() })\n * .toJsonSchema(\"draft-07\")\n * // → { type: \"object\", properties: { name: { type: \"string\" }, age: { type: \"integer\" } }, required: [\"name\"] }\n * ```\n */\n public toJsonSchema(_target: JsonSchemaTarget = \"draft-2020-12\"): JsonSchemaResult {\n return {};\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base-validator.mjs","names":["defaultRequiredRule"],"sources":["../../../../../../../../packages/seal/src/validators/base-validator.ts"],"sourcesContent":["import { clone } from \"@mongez/reinforcements\";\nimport { validate } from \"../factory/validate\";\nimport { VALID_RULE, invalidRule } from \"../helpers/validation-helpers\";\nimport { isEmptyValue } from \"../helpers/is-empty-value\";\nimport { requiredRule as defaultRequiredRule } from \"../rules/core/required\";\nimport type { JsonSchemaResult, JsonSchemaTarget } from \"../standard-schema/json-schema\";\nimport { mapToStandardResult } from \"../standard-schema/map-result\";\nimport type { StandardJSONSchemaV1, StandardSchemaV1 } from \"../standard-schema/types\";\nimport type {\n ContextualSchemaRule,\n ContextualizedMutator,\n ContextualizedTransformer,\n Mutator,\n SchemaContext,\n SchemaRule,\n SchemaRuleOptions,\n SimpleTransformerCallback,\n TransformerCallback,\n ValidationAttributesList,\n ValidationResult,\n} from \"../types\";\n\n/**\n * Base validator class - foundation for all validators\n */\nexport class BaseValidator<TInput = unknown, TOutput = TInput> {\n public rules: ContextualSchemaRule[] = [];\n protected refinements: ContextualSchemaRule[] = [];\n public mutators: ContextualizedMutator[] = [];\n protected defaultValue: any | (() => any);\n protected description?: string;\n protected shouldOmit = false;\n /** Set by `.internal()`: the server fills this field, request schemas leave it out. */\n protected serverSet = false;\n protected isNullable = false;\n protected isMutable = false;\n /** Treat empty or whitespace-only form strings as an absent value. */\n protected blankIsMissing = false;\n\n /**\n * Catch state — when `hasCatch` is true and validation fails, `catchValue`\n * (or its callback result) substitutes for the failed value, and the public\n * result reports `isValid: true` with no errors.\n *\n * See `.catch()` for semantics and the v1 scope (leaf-only).\n */\n protected catchValue:\n | any\n | ((errors: ValidationResult[\"errors\"], originalInput: any) => any | Promise<any>);\n protected hasCatch = false;\n\n /**\n * Whether the field is optional.\n * - false (default): field is required unless a requiredRule governs the condition.\n * - true: field can be absent or empty — set by calling .optional().\n *\n * Also used as a TypeScript literal brand via the optional() return type.\n */\n public isOptional = false;\n\n /**\n * The single required-condition rule for this field.\n * - null: field uses strict default (always required when not optional).\n * - set: the rule governs when the field is required (e.g., requiredIf).\n *\n * Stored separately from rules[] and prepended at validate() time.\n */\n public requiredRule: ContextualSchemaRule | null = this.createRule(defaultRequiredRule);\n\n /**\n * Pipeline to transform the mutated/original data before returning it\n */\n protected dataTransformers: ContextualizedTransformer[] = [];\n\n /**\n * Attributes text to be replaced on translations\n * If the value is an object, it will be used as the attributes list for the rule\n * If the value is a string, it will be used as the attributes list for the rule\n */\n protected attributesText: ValidationAttributesList = {};\n\n /**\n * Attributed that will be always using the attribute translator\n */\n protected translatedAttributes: Record<string, string> = {};\n\n /**\n * Mark the validator as mutable\n */\n public get mutable() {\n this.isMutable = true;\n return this;\n }\n\n /**\n * Mark the validator as immutable\n */\n public get immutable() {\n this.isMutable = false;\n return this;\n }\n\n /**\n * Get the instance to apply changes to.\n * By default (immutable), returns a clone so the original is unchanged.\n * When `.mutable` is set, returns `this` to mutate in place.\n */\n protected get instance(): this {\n return this.isMutable ? this : this.clone();\n }\n\n /**\n * Get the default value\n * Supports lazy evaluation via callbacks\n */\n public getDefaultValue(): any {\n return typeof this.defaultValue === \"function\" ? this.defaultValue() : this.defaultValue;\n }\n\n /**\n * Allow null as a valid value.\n *\n * Brands the return type with `{ isNullable: true }` so `Infer<>` widens\n * the inferred output to include `| null`.\n */\n public nullable(): this & { isNullable: true } {\n const instance = this.instance;\n instance.isNullable = true;\n return instance as this & { isNullable: true };\n }\n\n /**\n * Explicitly disallow null values after calling nullable.\n *\n * Brands the return type with `{ isNullable: false }` to cancel any prior\n * `.nullable()` at the type level.\n */\n public notNullable(): this & { isNullable: false } {\n const instance = this.instance;\n instance.isNullable = false;\n return instance as this & { isNullable: false };\n }\n\n /**\n * Add transformer with optional options\n *\n * @param transform - The transformer callback function\n * @param options - Optional options to pass to the transformer\n *\n * @example\n * ```ts\n * // Without options\n * v.date().addTransformer(data => data.toISOString())\n *\n * // With options\n * v.date().addTransformer(\n * (data, { options }) => dayjs(data).format(options.format),\n * { format: 'YYYY-MM-DD' }\n * )\n * ```\n */\n public addTransformer(transform: TransformerCallback, options: any = {}) {\n const instance = this.instance;\n instance.addMutableTransformer(transform, options);\n\n return instance;\n }\n\n /**\n * Add transformer with optional options\n *\n * @param transform - The transformer callback function\n * @param options - Optional options to pass to the transformer\n *\n * @example\n * ```ts\n * // Without options\n * v.date().addTransformer(data => data.toISOString())\n *\n * // With options\n * v.date().addTransformer(\n * (data, { options }) => dayjs(data).format(options.format),\n * { format: 'YYYY-MM-DD' }\n * )\n * ```\n */\n public addMutableTransformer(transform: TransformerCallback, options: any = {}) {\n this.dataTransformers.push({\n transform,\n options,\n });\n }\n\n /**\n * Transform the output value - simple one-time transformation\n *\n * @param callback - Simple callback receiving data and context\n *\n * @example\n * ```ts\n * // Simple transformation\n * v.string().outputAs(data => data.toUpperCase())\n *\n * // With context\n * v.string().outputAs((data, context) => {\n * console.log(`Transforming ${context.path}`);\n * return data.toLowerCase();\n * })\n * ```\n */\n public outputAs(callback: SimpleTransformerCallback) {\n return this.addTransformer((data, { context }) => callback(data, context));\n }\n\n /**\n * Transform output to JSON string\n *\n * Works with any validator type (string, number, date, object, array, etc.)\n *\n * @param indent - Optional indentation for pretty printing (default: 0 for compact)\n *\n * @example\n * ```ts\n * // Compact JSON\n * v.object({ name: v.string() }).toJSON()\n * // Output: '{\"name\":\"John\"}'\n *\n * // Pretty-printed JSON\n * v.array(v.object({...})).toJSON(2)\n * // Output:\n * // [\n * // {\n * // \"name\": \"John\"\n * // }\n * // ]\n *\n * // Works with any type\n * v.string().toJSON() // '\"hello\"'\n * v.number().toJSON() // '42'\n * v.date().toJSON() // '\"2024-10-26T00:00:00.000Z\"'\n * ```\n *\n * @category Transformer\n */\n public toJSON(indent?: number) {\n return this.addTransformer((data, { options }) => JSON.stringify(data, null, options.indent), {\n indent: indent ?? 0,\n });\n }\n\n /**\n * Start data transformation pipeline\n * Context is passed at runtime, not stored\n */\n public async startTransformationPipeline(data: any, context: SchemaContext) {\n for (const transformer of this.dataTransformers) {\n data = await transformer.transform(data, {\n options: transformer.options,\n context,\n });\n }\n\n return data;\n }\n\n /**\n * Set attributes text to be replaced on translations\n * If the value is an object, it will be used as the attributes list for the rule\n * If the value is a string, it will be used as the attributes list for the rule\n *\n * @example\n * v.string().attributes({\n * name: \"Name\",\n * email: \"Email\",\n * });\n * // Example 2: Add custom attributes for matches\n * v.string().matches(\"confirmPassword\").attributes({\n * matches: {\n * confirmPassword: \"Confirm Password\",\n * },\n * });\n */\n public attributes(attributes: Record<string, string | Record<string, string>>) {\n const instance = this.instance;\n for (const [key, value] of Object.entries(attributes)) {\n instance.attributesText[key] = value;\n }\n\n return instance;\n }\n\n /**\n * Define a lazy getter property for each attribute in the given object and use the config attribute translator\n */\n public transAttributes(attributes: Record<string, string>) {\n const instance = this.instance;\n for (const [key, value] of Object.entries(attributes)) {\n instance.translatedAttributes[key] = value;\n }\n\n return instance;\n }\n\n /**\n * Add description to the validator\n */\n public describe(description: string) {\n const instance = this.instance;\n instance.description = description;\n return instance;\n }\n\n /**\n * Check if this validator can handle the given value's type\n * Override this in specific validators to enable type-based routing in union validators\n *\n * Default: returns true (validator will attempt to validate any type)\n *\n * @param value - The value to check\n * @returns True if this validator can handle this type\n *\n * @example\n * ```ts\n * // StringValidator\n * public matchesType(value: any): boolean {\n * return typeof value === 'string';\n * }\n *\n * // Custom FileValidator\n * public matchesType(value: any): boolean {\n * return value instanceof UploadedFile;\n * }\n * ```\n */\n public matchesType(_value: any): boolean {\n return true; // Default: permissive, attempt to validate any type\n }\n\n /**\n * Create a copy of this validator with the same configuration\n * Copies all rules, mutators, transformers, default values, and settings\n *\n * @returns A new validator instance with copied configuration\n *\n * @example\n * ```ts\n * // Create reusable validator templates\n * const baseString = v.string().required().trim().min(3);\n * const emailField = baseString.clone().email();\n * const usernameField = baseString.clone().alphanumeric().max(20);\n *\n * // Works with all validators\n * const positiveInt = v.int().positive().required();\n * const ageField = positiveInt.clone().min(18).max(120);\n * ```\n */\n public clone(): this {\n // Create a new instance using Object.create to preserve the prototype chain\n const Constructor = this.constructor as new (...args: any[]) => this;\n const cloned = Object.create(Constructor.prototype);\n\n // Copy all BaseValidator properties\n cloned.rules = [...this.rules];\n cloned.refinements = [...this.refinements];\n cloned.mutators = [...this.mutators];\n cloned.dataTransformers = [...this.dataTransformers];\n cloned.defaultValue = this.defaultValue;\n cloned.shouldOmit = this.shouldOmit;\n cloned.serverSet = this.serverSet;\n cloned.description = this.description;\n cloned.attributesText = { ...this.attributesText };\n cloned.translatedAttributes = { ...this.translatedAttributes };\n cloned.isNullable = this.isNullable;\n cloned.isOptional = this.isOptional;\n cloned.blankIsMissing = this.blankIsMissing;\n cloned.requiredRule = this.requiredRule; // same reference is fine — rule is treated as immutable\n cloned.catchValue = this.catchValue;\n cloned.hasCatch = this.hasCatch;\n\n return cloned;\n }\n\n /**\n * @deprecated This method is no longer needed and does nothing.\n * Empty values are now automatically skipped for validation rules by default.\n * Only presence validators (required, present, etc.) will check empty values.\n * You can safely remove this call from your code.\n */\n public ignoreEmptyValue(_ignoreEmptyValue = true) {\n // No-op for backward compatibility\n return this;\n }\n\n /**\n * Omit this field from the validated data output\n *\n * Field will still be validated but not included in the final result.\n * Useful for confirmation fields, captcha, terms acceptance, etc.\n *\n * @example\n * ```ts\n * v.object({\n * password: v.string().required(),\n * confirmPassword: v.string().required().sameAs(\"password\").omit(),\n * acceptTerms: v.boolean().required().omit(),\n * });\n * // Output: { password: \"...\" }\n * // confirmPassword and acceptTerms validated but omitted\n * ```\n */\n public omit() {\n const instance = this.instance;\n instance.shouldOmit = true;\n return instance;\n }\n\n /**\n * @alias omit\n */\n public exclude() {\n return this.omit();\n }\n\n /**\n * Mark this field as set by the server, never by the client.\n *\n * The field stays a normal member of the schema: it validates, casts and\n * infers exactly as before, so a Cascade model can write it. Request schemas\n * derived with `ObjectValidator#withoutInternal()` (or `Model.requestSchema()`)\n * leave it out, so the same declaration serves the model and the request.\n *\n * Brands the return type with `{ isInternal: true }` so the derived schema\n * drops the key at the type level too.\n *\n * @example\n * ```ts\n * const postSchema = v.object({\n * title: v.string().required(),\n * authorId: v.int().required().internal(),\n * });\n *\n * const requestSchema = postSchema.withoutInternal(); // { title }\n * ```\n */\n public internal(): this & { isInternal: true } {\n const instance = this.instance;\n instance.serverSet = true;\n return instance as this & { isInternal: true };\n }\n\n /**\n * Whether `.internal()` marked this field as server-set\n */\n public isServerSet(): boolean {\n return this.serverSet;\n }\n\n /**\n * Check if this field should be omitted from the output\n */\n public isOmitted(): boolean {\n return this.shouldOmit;\n }\n\n /**\n * Add rule to the validator\n */\n public addRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n errorMessage?: string,\n options: T = {} as T,\n ): this {\n const instance = this.instance;\n instance.addMutableRule(rule, errorMessage, options);\n return instance;\n }\n\n /**\n * Set the required-condition rule for this field.\n *\n * Unlike addRule(), this does NOT push to rules[]. The rule is stored in the\n * dedicated `requiredRule` slot and is prepended to the validation pipeline\n * at runtime. Only one required rule can be active per field — this replaces\n * any previously set required rule.\n *\n * Also marks the field as not optional (isOptional = false).\n *\n * @example\n * ```ts\n * // Used internally by required(), requiredIf(), requiredWith(), etc.\n * BaseValidator.prototype.required = function(msg) {\n * return this.setRequiredRule(requiredRule, msg);\n * };\n * ```\n */\n public setRequiredRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n errorMessage?: string,\n options: T = {} as T,\n ): this {\n const instance = this.instance;\n instance.isOptional = false;\n instance.requiredRule = instance.createRule(rule, errorMessage, options);\n return instance;\n }\n\n /**\n * Add mutable rule\n */\n public addMutableRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n errorMessage?: string,\n options: T = {} as T,\n ): ContextualSchemaRule<T> {\n const newRule: ContextualSchemaRule<T> = this.createRule(rule, errorMessage, options);\n\n this.rules.push(newRule);\n\n return newRule;\n }\n\n /**\n * Create new rule\n */\n protected createRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n errorMessage?: string,\n options: T = {} as T,\n ): ContextualSchemaRule<T> {\n const newRule: ContextualSchemaRule<T> = {\n ...(clone(rule) as ContextualSchemaRule<T>),\n context: {\n errorMessage,\n options,\n attributesList: this.attributesText,\n translatedAttributes: this.translatedAttributes,\n translationParams: {},\n translatableParams: {},\n },\n };\n\n if (errorMessage) {\n newRule.errorMessage = errorMessage;\n }\n\n if (rule.sortOrder === undefined) {\n newRule.sortOrder = this.rules.length + 1;\n }\n\n return newRule;\n }\n\n /**\n * Use a custom or pre-built validation rule\n *\n * @param rule - The validation rule to apply\n * @param options - Rule options including errorMessage and any rule-specific options\n *\n * @example\n * ```ts\n * import { hexColorRule } from \"@warlock.js/seal\";\n *\n * v.string().useRule(hexColorRule, { errorMessage: \"Invalid color\" });\n * ```\n *\n * @example\n * ```ts\n * // With rule options\n * v.string().useRule(myCustomRule, {\n * customOption: true,\n * errorMessage: \"Custom validation failed\"\n * });\n * ```\n */\n public useRule<T extends SchemaRuleOptions = SchemaRuleOptions>(\n rule: SchemaRule<T>,\n options?: T & { errorMessage?: string },\n ) {\n const { errorMessage, ...ruleOptions } = options || ({} as any);\n return this.addRule(rule, errorMessage, ruleOptions);\n }\n\n /**\n * Validate the successful output after type rules, children and transformers.\n * Refinements are skipped for absent/null values and failed validation.\n */\n public refine(\n callback: (\n value: NonNullable<this[\"~standard\"][\"types\"]>[\"output\"],\n context: SchemaContext,\n ) => Promise<string | undefined> | string | undefined,\n ): this {\n const instance = this.instance;\n instance.refinements.push(\n instance.createRule({\n name: \"custom\",\n async validate(value, context) {\n const result = await callback(value, context);\n if (result) {\n this.context.errorMessage = result;\n return invalidRule(this, context);\n }\n return VALID_RULE;\n },\n }),\n );\n return instance;\n }\n\n /** Complete validation only after the entire output is available. */\n protected async refineResult(\n result: ValidationResult,\n context: SchemaContext,\n ): Promise<ValidationResult> {\n if (!result.isValid || result.data == null) return result;\n\n const errors: ValidationResult[\"errors\"] = [];\n for (const rule of this.refinements) {\n this.setRuleAttributesList(rule);\n const refined = await rule.validate(result.data, context);\n if (!refined.isValid) {\n errors.push({ type: rule.name, error: refined.error, input: refined.path ?? context.path });\n if (context.configurations?.firstErrorOnly ?? true) break;\n }\n }\n return errors.length ? { isValid: false, errors, data: undefined } : result;\n }\n\n /**\n * Add mutator to the validator\n */\n public addMutator(mutator: Mutator, options: any = {}) {\n const instance = this.instance;\n instance.addMutableMutator(mutator, options);\n return instance;\n }\n\n /**\n * Add mutable mutator\n */\n public addMutableMutator(mutator: Mutator, options: any = {}) {\n this.mutators.push({\n mutate: mutator,\n context: {\n options,\n ctx: {} as any,\n },\n });\n }\n\n /**\n * Set default value for the field. The default is used when the input is\n * absent (`undefined`); it then flows through the rule pipeline.\n *\n * Brands the return type with `{ hasDefault: true }` so `Infer<>` treats\n * the field as guaranteed-present even when chained with `.optional()`.\n */\n public default(value: any): this & { hasDefault: true } {\n const instance = this.instance;\n instance.defaultValue = value;\n return instance as this & { hasDefault: true };\n }\n\n /**\n * Fallback to a value when validation fails.\n *\n * Complementary to `.default()`: `.default(x)` fires when input is **absent**,\n * `.catch(y)` fires when input is **present but invalid**. Combine them when\n * you want both behaviours: `.optional().default(x).catch(y)`.\n *\n * The fallback can be a value or a callback `(errors, originalInput) => fallback`.\n * The callback variant is the only side-channel for the swallowed errors —\n * use it to log/alert before the fallback substitutes.\n *\n * Brands the return type with `{ hasCatch: true }` so `Infer<>` treats the\n * field as guaranteed-present (the catch ensures a value will always exist).\n *\n * **Scope (v1).** Catch is honoured for **leaf validators** (string, number,\n * boolean, date, …) and for fields inside containers. It is a **no-op on\n * container validators themselves** (`v.object`, `v.array`, `v.record`,\n * `v.tuple`, `v.discriminatedUnion`) — those use their own iteration logic\n * that bypasses the catch hook in `BaseValidator.validate()`.\n *\n * @example\n * ```ts\n * v.int().min(0).catch(3) // bad number → 3\n * v.string().in([\"us\", \"eu\"]).catch(\"us\") // unknown enum → \"us\"\n * v.string().catch((errors, input) => {\n * console.warn(`bad user value: ${JSON.stringify(input)}`, errors);\n * return \"anonymous\";\n * })\n * ```\n */\n public catch(\n fallback:\n | any\n | ((errors: ValidationResult[\"errors\"], originalInput: any) => any | Promise<any>),\n ): this & { hasCatch: true } {\n const instance = this.instance;\n\n instance.catchValue = fallback;\n instance.hasCatch = true;\n\n return instance as this & { hasCatch: true };\n }\n\n /**\n * Mutate the data\n */\n public async mutate(data: any, context: SchemaContext) {\n let mutatedData = data;\n\n for (const mutator of this.mutators) {\n mutator.context.ctx = context;\n mutatedData = await mutator.mutate(mutatedData, mutator.context);\n }\n\n return mutatedData;\n }\n\n /**\n * Set the label for the validator that will be matching the :input attribute\n */\n public label(label: string) {\n const instance = this.instance;\n instance.attributesText.input = label;\n return instance;\n }\n\n /**\n * Validate the data\n */\n public async validate(data: any, context: SchemaContext): Promise<ValidationResult> {\n const result = await this.refineResult(await this.validateRules(data, context), context);\n\n if (!result.isValid && this.hasCatch) {\n const fallback =\n typeof this.catchValue === \"function\"\n ? await this.catchValue(result.errors, data)\n : this.catchValue;\n return { isValid: true, errors: [], data: fallback };\n }\n return result;\n }\n\n /** Validate presence and value rules before containers descend into children. */\n protected async validateRules(data: any, context: SchemaContext): Promise<ValidationResult> {\n if (data === null && this.isNullable) {\n return { isValid: true, errors: [], data: null };\n }\n\n const isBlank = this.blankIsMissing && typeof data === \"string\" && data.trim() === \"\";\n\n if (isBlank && this.isNullable) {\n return { isValid: true, errors: [], data: null };\n }\n\n const input = isBlank ? undefined : data;\n let valueForRules = input ?? this.getDefaultValue();\n // A parent object pre-fills an absent key with this field's default and\n // flags it; consume the flag so nested item contexts don't inherit it.\n const parentFilledDefault = context?.valueIsDefault === true;\n\n if (parentFilledDefault) context.valueIsDefault = false;\n\n // A default only stands in for a value when it is one the field accepts:\n // a `null` default on a non-nullable field is still \"no value\".\n const isUsableDefault = (value: unknown) =>\n value !== undefined && (value !== null || this.isNullable);\n\n // A present blank string on a field whose default is itself blank is that\n // default (an HTML form posts `note=\"\"` for an untouched input).\n let blankMatchesDefault = false;\n\n if (typeof input === \"string\" && input.trim() === \"\" && this.defaultValue !== undefined) {\n const fallback = this.getDefaultValue();\n\n if (typeof fallback === \"string\" && fallback.trim() === \"\") {\n valueForRules = fallback;\n blankMatchesDefault = true;\n }\n }\n\n // The author's own default is a value, even an empty one: `.default(\"\")`\n // must not fail the required check it exists to satisfy.\n const usedDefault =\n blankMatchesDefault ||\n (input == null && isUsableDefault(valueForRules)) ||\n (parentFilledDefault && isUsableDefault(input));\n // Optional fields with no resolved value are absent, not values to\n // transform. Skipping here protects every mutator while still allowing\n // defaults and present values through the normal mutation pipeline.\n let mutatedData =\n this.isOptional && valueForRules === undefined\n ? undefined\n : await this.mutate(valueForRules, context);\n\n const errors: ValidationResult[\"errors\"] = [];\n let isValid = true;\n const isFirstErrorOnly = context.configurations?.firstErrorOnly ?? true;\n\n const isEmpty = isEmptyValue(valueForRules);\n\n // D8 fix (design/core-defects-found.md): for an optional field, only a\n // truly ABSENT value (`valueForRules === undefined` — the key was\n // missing, or was `null`/`undefined` and got coalesced above) may skip\n // the value rules. A PRESENT-but-empty value (e.g. `\"\"` from `?page=`)\n // must still run them, so `v.int().optional()` given `\"\"` fails instead\n // of silently handing back a string that `Infer.Output`'s\n // `number | undefined` forbids. Non-optional fields are unaffected —\n // their `requiredRule` (not nulled out by `.optional()`) already rejects\n // `\"\"` before these rules matter.\n // An empty default of the wrong type (`v.int().default(\"\")`) must still\n // meet the type rule; skipping it would hand back a value `Infer.Output`\n // forbids. An empty default of the right type (`v.string().default(\"\")`)\n // keeps skipping the value rules, so `.min(3).default(\"\")` still passes.\n const emptyDefaultOfWrongType =\n usedDefault && isEmpty && valueForRules !== null && !this.matchesType(valueForRules);\n\n const skipEmptyRules = emptyDefaultOfWrongType\n ? false\n : this.isOptional\n ? valueForRules === undefined\n : isEmpty;\n\n // Prepend the required-condition rule if set, so it always runs first.\n // requiredRule has requiresValue = false so it runs even on empty values.\n const rulesToRun =\n this.requiredRule && !usedDefault ? [this.requiredRule, ...this.rules] : this.rules;\n\n for (const rule of rulesToRun) {\n if ((rule.requiresValue ?? true) && skipEmptyRules) continue;\n\n this.setRuleAttributesList(rule);\n\n const result = await rule.validate(mutatedData, context);\n\n if (result.isValid && \"data\" in result) {\n mutatedData = result.data;\n }\n\n if (result.isValid === false) {\n isValid = false;\n const reported = result.errors?.length\n ? result.errors\n : [{ error: result.error, path: result.path }];\n\n for (const { error, path } of reported) {\n errors.push({ type: rule.name, error, input: path ?? context.path });\n }\n\n if (isFirstErrorOnly) {\n break;\n }\n }\n }\n\n const result: ValidationResult = {\n isValid,\n errors,\n data:\n mutatedData !== undefined\n ? await this.startTransformationPipeline(mutatedData, context)\n : undefined,\n };\n\n return result;\n }\n\n /**\n * Set rule attributes list\n */\n protected setRuleAttributesList(rule: ContextualSchemaRule) {\n rule.context.attributesList =\n typeof this.attributesText[rule.name] === \"object\"\n ? (this.attributesText[rule.name] as ValidationAttributesList)\n : this.attributesText;\n rule.context.translatedAttributes = this.translatedAttributes;\n }\n\n /**\n * Standard Schema V1 compliance.\n *\n * Allows this validator to be used with any Standard Schema-aware library\n * (OpenAI structured outputs, LangGraph, TanStack Form, Conform, Valibot adapters, etc.)\n * without extra adapters.\n *\n * Delegates to the `validate()` factory so all `configureSeal()` options\n * (translations, firstErrorOnly) are picked up automatically at call time.\n *\n * Includes Standard JSON Schema support via `jsonSchema.input()` / `jsonSchema.output()`.\n *\n * ## How Standard Schema libraries consume this\n *\n * You pass the **schema object itself** to the library — they internally read\n * `schema[\"~standard\"]`. Do NOT pass `schema[\"~standard\"]` directly.\n *\n * @example\n * ```ts\n * const schema = v.object({ name: v.string().required() });\n *\n * // TanStack Form — pass schema, library reads [\"~standard\"] internally\n * const form = useForm({ validators: { onChange: schema } });\n *\n * // Conform (Remix) — same pattern\n * const [form] = useForm({ onValidate({ formData }) {\n * return parseWithStandardSchema(formData, { schema });\n * }});\n *\n * // Direct validation (lower level — most apps don't need this)\n * const result = await schema[\"~standard\"].validate({ name: \"Hasan\" });\n * // → { value: { name: \"Hasan\" } } on success\n * // → { issues: [{ message: \"...\", path: [{ key: \"name\" }] }] } on failure\n *\n * // JSON Schema for OpenAI / LangChain tool calling\n * const parameters = schema[\"~standard\"].jsonSchema.input({ target: \"openai-strict\" });\n * // → { type: \"object\", properties: {...}, required: [...], additionalProperties: false }\n * ```\n *\n * @note Cross-field rules (sameAs, requiredIf, requiredWith) rely on sibling values\n * available in the full validation context. When called on a standalone scalar validator,\n * sibling data is absent and those rules will not evaluate correctly.\n * Always call on the parent ObjectValidator for full-payload validation.\n */\n get [\"~standard\"](): StandardJSONSchemaV1.Props<TInput, TOutput> {\n return {\n version: 1,\n vendor: \"seal\",\n types: undefined as unknown as StandardSchemaV1.Types<TInput, TOutput>,\n validate: async (value: unknown) => {\n const result = await validate(this, value);\n return mapToStandardResult(result) as StandardSchemaV1.Result<TOutput>;\n },\n jsonSchema: {\n input: (options) => this.toJsonSchema(options.target),\n output: (options) => this.toJsonSchema(options.target),\n },\n };\n }\n\n /**\n * Generate a JSON Schema representation of this validator.\n *\n * Supports targets: `\"draft-2020-12\"` (default), `\"draft-07\"`, `\"openapi-3.0\"`.\n *\n * Subclasses override this to describe their specific constraints.\n * The base implementation returns `{}` (permissive — accepts anything),\n * which is correct for validators with no representable JSON Schema constraints.\n *\n * @note Rules that cannot be expressed in JSON Schema are silently omitted:\n * - Cross-field rules: sameAs, requiredIf, requiredWith, requiredWithout\n * - Custom callbacks: refine()\n * - Framework-specific runtime rules (core/cascade plugins)\n * These rules still run normally at validation time — only absent from JSON Schema.\n *\n * @example\n * ```ts\n * v.string().min(3).max(50).toJsonSchema(\"draft-2020-12\")\n * // → { type: \"string\", minLength: 3, maxLength: 50 }\n *\n * v.object({ name: v.string().required(), age: v.int().optional() })\n * .toJsonSchema(\"draft-07\")\n * // → { type: \"object\", properties: { name: { type: \"string\" }, age: { type: \"integer\" } }, required: [\"name\"] }\n * ```\n */\n public toJsonSchema(_target: JsonSchemaTarget = \"draft-2020-12\"): JsonSchemaResult {\n return {};\n }\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { JsonSchemaResult, JsonSchemaTarget } from "../standard-schema/json-sche
2
2
  import { Schema } from "../types/schema-types.mjs";
3
3
  import { SchemaContext } from "../types/context-types.mjs";
4
4
  import { ValidationResult } from "../types/result-types.mjs";
5
- import { InferInputObjectShape, InferOutputObjectShape } from "../types/inference-types.mjs";
5
+ import { InferInputObjectShape, InferOutputObjectShape, InternalKeys, PartialSchema } from "../types/inference-types.mjs";
6
6
  import "../types/index.mjs";
7
7
  import { BaseValidator } from "./base-validator.mjs";
8
8
  //#region ../../packages/seal/src/validators/object-validator.d.ts
@@ -22,7 +22,7 @@ import { BaseValidator } from "./base-validator.mjs";
22
22
  * recursive class-base evaluation that would otherwise occur when the
23
23
  * brand-aware widening tries to inspect the class type.
24
24
  */
25
- export declare class ObjectValidator<TSchema extends Schema = Schema> extends BaseValidator<InferInputObjectShape<TSchema>, InferOutputObjectShape<TSchema>> {
25
+ export declare class ObjectValidator<out TSchema extends Schema = Schema> extends BaseValidator<InferInputObjectShape<TSchema>, InferOutputObjectShape<TSchema>> {
26
26
  schema: TSchema;
27
27
  protected shouldAllowUnknown: boolean;
28
28
  protected allowedKeys: string[];
@@ -158,9 +158,28 @@ export declare class ObjectValidator<TSchema extends Schema = Schema> extends Ba
158
158
  */
159
159
  pick<K extends keyof TSchema>(...keys: K[]): ObjectValidator<Pick<TSchema, K>>;
160
160
  /**
161
- * Mark all or the given schema fields as optional
161
+ * Mark all or the given schema fields as optional.
162
+ *
163
+ * The result keeps its types: each named field becomes optional in the
164
+ * inferred shape, the others are untouched.
165
+ */
166
+ partial<K extends keyof TSchema = keyof TSchema>(...keys: K[]): ObjectValidator<PartialSchema<TSchema, K>>;
167
+ /**
168
+ * The keys of the fields marked with `.internal()`
169
+ */
170
+ internalKeys(): InternalKeys<TSchema>[];
171
+ /**
172
+ * A copy of this schema without the fields marked with `.internal()`.
173
+ * Use it for request validation: the server sets those fields itself.
174
+ * Configuration (`allowUnknown`, `stripUnknown`, ...) is preserved.
175
+ *
176
+ * @example
177
+ * ```ts
178
+ * const requestSchema = postSchema.withoutInternal();
179
+ * const createSchema = postSchema.withoutInternal().pick("title");
180
+ * ```
162
181
  */
163
- partial<K extends keyof TSchema>(...keys: K[]): this;
182
+ withoutInternal(): ObjectValidator<Omit<TSchema, InternalKeys<TSchema>>>;
164
183
  /**
165
184
  * Make the all or the given fields as required
166
185
  */
@@ -1 +1 @@
1
- {"version":3,"file":"object-validator.d.mts","names":[],"sources":["../../../../../../../../packages/seal/src/validators/object-validator.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;qBA6Ba,gBAAgB,gBAAgB,SAAS,gBAAgB,cACpE,sBAAsB,UACtB,uBAAuB;EAOd,QAAQ;YALP;YACA;YACA;EAEV,YACS,QAAQ,SACf;;;;EASK,YAAY;;EAKZ;;EAUA,SAAS;;EAOT,KAAK;;;;EAQL,aAAa;;;;;;;;;;;;;;EAmBJ,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgEf,OAAO,mBAAmB,QAC/B,mBAAmB,aAAa,gBAAgB,cAC/C,gBAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CtB,MAAM,eAAe,QAC1B,WAAW,gBAAgB,UAC1B,gBAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6DtB,KAAK,gBAAgB,YAAY,MAAM,MAAM,gBAAgB,KAAK,SAAS;;;;EAoB3E,QAAQ,gBAAgB,YAAY,MAAM;;;;EAmB1C,eAAe,gBAAgB,YAAY,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDjD,QAAQ,gBAAgB,YAAY,MAAM,MAAM,gBAAgB,KAAK,SAAS;;EAkB9E,OAAO,WAAW,SAAS;;EAMrB,SACX,WACA,UAAS,gBACR,QAAQ;;;;;UAiKH;;;;UAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CQ,aAAa,SAAQ,mBAAqC"}
1
+ {"version":3,"file":"object-validator.d.mts","names":[],"sources":["../../../../../../../../packages/seal/src/validators/object-validator.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;qBAsCa,oBAAoB,gBAAgB,SAAS,gBAAgB,cACxE,sBAAsB,UACtB,uBAAuB;EAOd,QAAQ;YALP;YACA;YACA;EAEV,YACS,QAAQ,SACf;;;;EASK,YAAY;;EAKZ;;EAUA,SAAS;;EAOT,KAAK;;;;EAQL,aAAa;;;;;;;;;;;;;;EAmBJ,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgEf,OAAO,mBAAmB,QAC/B,mBAAmB,aAAa,gBAAgB,cAC/C,gBAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CtB,MAAM,eAAe,QAC1B,WAAW,gBAAgB,UAC1B,gBAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6DtB,KAAK,gBAAgB,YAAY,MAAM,MAAM,gBAAgB,KAAK,SAAS;;;;;;;EAuB3E,QAAQ,gBAAgB,gBAAgB,YAC1C,MAAM,MACR,gBAAgB,cAAc,SAAS;;;;EAmBnC,gBAAgB,aAAa;;;;;;;;;;;;EAiB7B,mBAAmB,gBAAgB,KAAK,SAAS,aAAa;;;;EAS9D,eAAe,gBAAgB,YAAY,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDjD,QAAQ,gBAAgB,YAAY,MAAM,MAAM,gBAAgB,KAAK,SAAS;;EAkB9E,OAAO,WAAW,SAAS;;EAMrB,SACX,WACA,UAAS,gBACR,QAAQ;;;;;UAiKH;;;;UAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CQ,aAAa,SAAQ,mBAAqC"}
@@ -224,15 +224,38 @@ var ObjectValidator = class ObjectValidator extends BaseValidator {
224
224
  return picked;
225
225
  }
226
226
  /**
227
- * Mark all or the given schema fields as optional
227
+ * Mark all or the given schema fields as optional.
228
+ *
229
+ * The result keeps its types: each named field becomes optional in the
230
+ * inferred shape, the others are untouched.
228
231
  */
229
232
  partial(...keys) {
230
233
  const validationSchema = this.clone();
231
234
  if (keys.length === 0) keys = Object.keys(validationSchema.schema);
232
- for (const [key, validator] of Object.entries(validationSchema.schema)) if (keys.length === 0 || keys.includes(key)) validationSchema.schema[key] = validator.optional();
235
+ for (const [key, validator] of Object.entries(validationSchema.schema)) if (keys.includes(key)) validationSchema.schema[key] = validator.optional();
233
236
  return validationSchema;
234
237
  }
235
238
  /**
239
+ * The keys of the fields marked with `.internal()`
240
+ */
241
+ internalKeys() {
242
+ return Object.entries(this.schema).filter(([, validator]) => validator.isServerSet()).map(([key]) => key);
243
+ }
244
+ /**
245
+ * A copy of this schema without the fields marked with `.internal()`.
246
+ * Use it for request validation: the server sets those fields itself.
247
+ * Configuration (`allowUnknown`, `stripUnknown`, ...) is preserved.
248
+ *
249
+ * @example
250
+ * ```ts
251
+ * const requestSchema = postSchema.withoutInternal();
252
+ * const createSchema = postSchema.withoutInternal().pick("title");
253
+ * ```
254
+ */
255
+ withoutInternal() {
256
+ return this.without(...this.internalKeys());
257
+ }
258
+ /**
236
259
  * Make the all or the given fields as required
237
260
  */
238
261
  requiredFields(...keys) {