@zipbul/baker 5.0.0 → 5.2.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 (207) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +11 -14
  3. package/dist/index.d.ts +11 -12
  4. package/dist/index.js +1 -1
  5. package/dist/src/baker.d.ts +19 -9
  6. package/dist/src/baker.js +1 -1
  7. package/dist/src/common/enums.d.ts +10 -0
  8. package/dist/src/common/enums.js +1 -0
  9. package/dist/src/common/index.d.ts +6 -0
  10. package/dist/src/common/index.js +1 -0
  11. package/dist/src/common/interfaces.d.ts +4 -0
  12. package/dist/src/common/types.d.ts +2 -0
  13. package/dist/src/config/config-normalizer.d.ts +7 -0
  14. package/dist/src/config/config-normalizer.js +1 -0
  15. package/dist/src/config/constants.d.ts +6 -0
  16. package/dist/src/config/constants.js +1 -0
  17. package/dist/src/config/index.d.ts +3 -0
  18. package/dist/src/config/index.js +1 -0
  19. package/dist/src/{configure.d.ts → config/interfaces.d.ts} +1 -8
  20. package/dist/src/config/interfaces.js +0 -0
  21. package/dist/src/decorators/constants.d.ts +2 -0
  22. package/dist/src/decorators/constants.js +1 -0
  23. package/dist/src/decorators/enums.d.ts +5 -0
  24. package/dist/src/decorators/enums.js +1 -0
  25. package/dist/src/decorators/field.d.ts +3 -54
  26. package/dist/src/decorators/field.js +1 -1
  27. package/dist/src/decorators/index.d.ts +2 -2
  28. package/dist/src/decorators/index.js +1 -1
  29. package/dist/src/decorators/interfaces.d.ts +50 -0
  30. package/dist/src/decorators/interfaces.js +0 -0
  31. package/dist/src/decorators/public.d.ts +2 -0
  32. package/dist/src/decorators/public.js +1 -0
  33. package/dist/src/decorators/types.d.ts +6 -0
  34. package/dist/src/decorators/types.js +0 -0
  35. package/dist/src/metadata/enums.d.ts +5 -0
  36. package/dist/src/metadata/enums.js +1 -0
  37. package/dist/src/metadata/index.d.ts +3 -0
  38. package/dist/src/metadata/index.js +1 -0
  39. package/dist/src/metadata/interfaces.d.ts +90 -0
  40. package/dist/src/metadata/interfaces.js +0 -0
  41. package/dist/src/metadata/meta-store.d.ts +49 -0
  42. package/dist/src/metadata/meta-store.js +1 -0
  43. package/dist/src/metadata/types.d.ts +10 -0
  44. package/dist/src/metadata/types.js +0 -0
  45. package/dist/src/rules/array.d.ts +2 -2
  46. package/dist/src/rules/array.js +1 -1
  47. package/dist/src/rules/binary.d.ts +2 -2
  48. package/dist/src/rules/binary.js +1 -1
  49. package/dist/src/rules/combinators.d.ts +1 -1
  50. package/dist/src/rules/combinators.js +1 -1
  51. package/dist/src/rules/common.d.ts +3 -3
  52. package/dist/src/rules/common.js +1 -1
  53. package/dist/src/rules/constants.d.ts +10 -0
  54. package/dist/src/rules/constants.js +1 -0
  55. package/dist/src/{create-rule.d.ts → rules/create-rule.d.ts} +1 -1
  56. package/dist/src/rules/create-rule.js +1 -0
  57. package/dist/src/rules/date.d.ts +1 -1
  58. package/dist/src/rules/date.js +1 -1
  59. package/dist/src/{enums.d.ts → rules/enums.d.ts} +0 -20
  60. package/dist/src/rules/enums.js +1 -0
  61. package/dist/src/rules/index.d.ts +5 -13
  62. package/dist/src/rules/index.js +1 -1
  63. package/dist/src/rules/interfaces.d.ts +43 -0
  64. package/dist/src/rules/interfaces.js +0 -0
  65. package/dist/src/rules/locales.d.ts +1 -1
  66. package/dist/src/rules/locales.js +1 -1
  67. package/dist/src/rules/number.d.ts +3 -3
  68. package/dist/src/rules/number.js +1 -1
  69. package/dist/src/rules/object.d.ts +1 -1
  70. package/dist/src/rules/object.js +1 -1
  71. package/dist/src/rules/public.d.ts +14 -0
  72. package/dist/src/rules/public.js +1 -0
  73. package/dist/src/{rule-metadata.d.ts → rules/rule-metadata.d.ts} +1 -1
  74. package/dist/src/{rule-metadata.js → rules/rule-metadata.js} +1 -1
  75. package/dist/src/{rule-plan.d.ts → rules/rule-plan.d.ts} +4 -7
  76. package/dist/src/rules/rule-plan.js +1 -0
  77. package/dist/src/rules/string-basic.d.ts +23 -0
  78. package/dist/src/rules/string-basic.js +1 -0
  79. package/dist/src/rules/string-crypto.d.ts +5 -0
  80. package/dist/src/rules/string-crypto.js +1 -0
  81. package/dist/src/rules/string-datetime.d.ts +3 -0
  82. package/dist/src/rules/string-datetime.js +1 -0
  83. package/dist/src/rules/string-encoding.d.ts +14 -0
  84. package/dist/src/rules/string-encoding.js +1 -0
  85. package/dist/src/rules/string-finance.d.ts +18 -0
  86. package/dist/src/rules/string-finance.js +10 -0
  87. package/dist/src/rules/string-format.d.ts +38 -0
  88. package/dist/src/rules/string-format.js +1 -0
  89. package/dist/src/rules/string-geo.d.ts +5 -0
  90. package/dist/src/rules/string-geo.js +1 -0
  91. package/dist/src/rules/string-identifier.d.ts +16 -0
  92. package/dist/src/rules/string-identifier.js +3 -0
  93. package/dist/src/rules/string-shared.d.ts +3 -0
  94. package/dist/src/rules/string-shared.js +1 -0
  95. package/dist/src/rules/string-width.d.ts +6 -0
  96. package/dist/src/rules/string-width.js +1 -0
  97. package/dist/src/rules/string.d.ts +14 -110
  98. package/dist/src/rules/string.js +1 -12
  99. package/dist/src/rules/typechecker.d.ts +10 -10
  100. package/dist/src/rules/typechecker.js +5 -5
  101. package/dist/src/rules/types.d.ts +26 -0
  102. package/dist/src/rules/types.js +0 -0
  103. package/dist/src/{functions → runtime}/check-call-options.d.ts +1 -1
  104. package/dist/src/runtime/check-call-options.js +1 -0
  105. package/dist/src/runtime/constants.d.ts +3 -0
  106. package/dist/src/runtime/constants.js +1 -0
  107. package/dist/src/runtime/deserialize.d.ts +6 -0
  108. package/dist/src/runtime/deserialize.js +1 -0
  109. package/dist/src/runtime/index.d.ts +3 -0
  110. package/dist/src/runtime/index.js +1 -0
  111. package/dist/src/runtime/serialize.d.ts +11 -0
  112. package/dist/src/runtime/serialize.js +1 -0
  113. package/dist/src/runtime/validate.d.ts +6 -0
  114. package/dist/src/runtime/validate.js +1 -0
  115. package/dist/src/seal/async-analyzer.d.ts +20 -0
  116. package/dist/src/seal/async-analyzer.js +1 -0
  117. package/dist/src/seal/circular-analyzer.d.ts +9 -6
  118. package/dist/src/seal/circular-analyzer.js +1 -1
  119. package/dist/src/seal/circular-placeholder.d.ts +20 -0
  120. package/dist/src/seal/circular-placeholder.js +1 -0
  121. package/dist/src/seal/codegen-utils.d.ts +15 -0
  122. package/dist/src/seal/codegen-utils.js +1 -1
  123. package/dist/src/seal/compile-cache.d.ts +38 -0
  124. package/dist/src/seal/compile-cache.js +1 -0
  125. package/dist/src/seal/constants.d.ts +62 -0
  126. package/dist/src/seal/constants.js +1 -0
  127. package/dist/src/seal/deserialize-builder.d.ts +6 -9
  128. package/dist/src/seal/deserialize-builder.js +199 -262
  129. package/dist/src/seal/deserialize-codegen.d.ts +58 -0
  130. package/dist/src/seal/deserialize-codegen.js +64 -0
  131. package/dist/src/seal/enums.d.ts +1 -2
  132. package/dist/src/seal/enums.js +1 -1
  133. package/dist/src/seal/expose-validator.d.ts +2 -2
  134. package/dist/src/seal/expose-validator.js +1 -1
  135. package/dist/src/seal/index.d.ts +3 -0
  136. package/dist/src/seal/index.js +1 -0
  137. package/dist/src/seal/inheritance-merger.d.ts +18 -0
  138. package/dist/src/seal/inheritance-merger.js +1 -0
  139. package/dist/src/seal/interfaces.d.ts +89 -0
  140. package/dist/src/seal/interfaces.js +0 -0
  141. package/dist/src/seal/meta-validator.d.ts +16 -0
  142. package/dist/src/seal/meta-validator.js +1 -0
  143. package/dist/src/seal/seal.d.ts +5 -30
  144. package/dist/src/seal/seal.js +1 -1
  145. package/dist/src/seal/serialize-builder.d.ts +6 -4
  146. package/dist/src/seal/serialize-builder.js +63 -63
  147. package/dist/src/seal/type-normalizer.d.ts +9 -0
  148. package/dist/src/seal/type-normalizer.js +1 -0
  149. package/dist/src/seal/type-resolver.d.ts +2 -0
  150. package/dist/src/seal/type-resolver.js +1 -0
  151. package/dist/src/seal/types.d.ts +6 -0
  152. package/dist/src/seal/types.js +0 -0
  153. package/dist/src/symbols.d.ts +2 -4
  154. package/dist/src/symbols.js +1 -1
  155. package/dist/src/transformers/{collection.transformer.d.ts → collection.d.ts} +1 -1
  156. package/dist/src/transformers/constants.d.ts +2 -0
  157. package/dist/src/transformers/constants.js +1 -0
  158. package/dist/src/transformers/{date.transformer.d.ts → date.d.ts} +1 -1
  159. package/dist/src/transformers/date.js +1 -0
  160. package/dist/src/transformers/index.d.ts +3 -8
  161. package/dist/src/transformers/index.js +1 -1
  162. package/dist/src/transformers/interfaces.d.ts +26 -0
  163. package/dist/src/transformers/interfaces.js +0 -0
  164. package/dist/src/transformers/luxon.d.ts +3 -0
  165. package/dist/src/transformers/luxon.js +1 -0
  166. package/dist/src/transformers/moment.d.ts +3 -0
  167. package/dist/src/transformers/moment.js +1 -0
  168. package/dist/src/transformers/{number.transformer.d.ts → number.d.ts} +1 -1
  169. package/dist/src/transformers/public.d.ts +7 -0
  170. package/dist/src/transformers/public.js +1 -0
  171. package/dist/src/transformers/{string.transformer.d.ts → string.d.ts} +1 -1
  172. package/dist/src/transformers/types.d.ts +3 -0
  173. package/dist/src/transformers/types.js +0 -0
  174. package/package.json +7 -7
  175. package/dist/src/collect.d.ts +0 -15
  176. package/dist/src/collect.js +0 -1
  177. package/dist/src/configure.js +0 -1
  178. package/dist/src/create-rule.js +0 -1
  179. package/dist/src/enums.js +0 -1
  180. package/dist/src/functions/check-call-options.js +0 -1
  181. package/dist/src/functions/deserialize.d.ts +0 -19
  182. package/dist/src/functions/deserialize.js +0 -1
  183. package/dist/src/functions/serialize.d.ts +0 -16
  184. package/dist/src/functions/serialize.js +0 -1
  185. package/dist/src/functions/validate.d.ts +0 -18
  186. package/dist/src/functions/validate.js +0 -1
  187. package/dist/src/interfaces.d.ts +0 -32
  188. package/dist/src/meta-access.d.ts +0 -19
  189. package/dist/src/meta-access.js +0 -1
  190. package/dist/src/rule-plan.js +0 -1
  191. package/dist/src/seal/validate-meta.d.ts +0 -13
  192. package/dist/src/seal/validate-meta.js +0 -1
  193. package/dist/src/transformers/date.transformer.js +0 -1
  194. package/dist/src/transformers/luxon.transformer.d.ts +0 -8
  195. package/dist/src/transformers/luxon.transformer.js +0 -1
  196. package/dist/src/transformers/moment.transformer.d.ts +0 -7
  197. package/dist/src/transformers/moment.transformer.js +0 -1
  198. package/dist/src/types.d.ts +0 -177
  199. /package/dist/src/{errors.d.ts → common/errors.d.ts} +0 -0
  200. /package/dist/src/{errors.js → common/errors.js} +0 -0
  201. /package/dist/src/{interfaces.js → common/interfaces.js} +0 -0
  202. /package/dist/src/{types.js → common/types.js} +0 -0
  203. /package/dist/src/{utils.d.ts → common/utils.d.ts} +0 -0
  204. /package/dist/src/{utils.js → common/utils.js} +0 -0
  205. /package/dist/src/transformers/{collection.transformer.js → collection.js} +0 -0
  206. /package/dist/src/transformers/{number.transformer.js → number.js} +0 -0
  207. /package/dist/src/transformers/{string.transformer.js → string.js} +0 -0
@@ -1,8 +1,6 @@
1
1
  /**
2
- * 2 Symbols — zero external storage, zero global pollution
3
- * Uses Symbol.for: allows AOT code and runtime code to share the same Symbol via the global registry
2
+ * RAW symbol — zero external storage, zero global pollution.
3
+ * Uses Symbol.for: allows AOT code and runtime code to share the same Symbol via the global registry.
4
4
  */
5
5
  /** Tier 1 collection metadata (stored on Class[Symbol.metadata] by decorators) */
6
6
  export declare const RAW: unique symbol;
7
- /** Tier 2 seal result (dual executor stored on Class at seal time) */
8
- export declare const SEALED: unique symbol;
@@ -1 +1 @@
1
- Symbol.metadata??=Symbol.for("Symbol.metadata");export const RAW=Symbol.for("baker:raw");export const SEALED=Symbol.for("baker:sealed");
1
+ Symbol.metadata??=Symbol.for("Symbol.metadata");export const RAW=Symbol.for("baker:raw");
@@ -1,3 +1,3 @@
1
- import type { Transformer } from '../types';
1
+ import type { Transformer } from './interfaces';
2
2
  export declare function csvTransformer(separator?: string): Transformer;
3
3
  export declare const jsonTransformer: Transformer;
@@ -0,0 +1,2 @@
1
+ export declare const LUXON_MISSING = "luxonTransformer requires the optional peer dependency 'luxon'. Install it with: bun add luxon";
2
+ export declare const MOMENT_MISSING = "momentTransformer requires the optional peer dependency 'moment'. Install it with: bun add moment";
@@ -0,0 +1 @@
1
+ export const LUXON_MISSING="luxonTransformer requires the optional peer dependency 'luxon'. Install it with: bun add luxon";export const MOMENT_MISSING="momentTransformer requires the optional peer dependency 'moment'. Install it with: bun add moment";
@@ -1,4 +1,4 @@
1
- import type { Transformer } from '../types';
1
+ import type { Transformer } from './interfaces';
2
2
  export declare const unixSecondsTransformer: Transformer;
3
3
  export declare const unixMillisTransformer: Transformer;
4
4
  export declare const isoStringTransformer: Transformer;
@@ -0,0 +1 @@
1
+ export const unixSecondsTransformer={deserialize:({value:b})=>{if(typeof b!=="number")return b;const j=new Date(b*1000);return Number.isNaN(j.getTime())?b:j},serialize:({value:b})=>b instanceof Date?Math.floor(b.getTime()/1000):b};export const unixMillisTransformer={deserialize:({value:b})=>{if(typeof b!=="number")return b;const j=new Date(b);return Number.isNaN(j.getTime())?b:j},serialize:({value:b})=>b instanceof Date?b.getTime():b};export const isoStringTransformer={deserialize:({value:b})=>{if(typeof b!=="string")return b;const j=new Date(b);return Number.isNaN(j.getTime())?b:j},serialize:({value:b})=>b instanceof Date?b.toISOString():b};
@@ -1,8 +1,3 @@
1
- export { trimTransformer, toLowerCaseTransformer, toUpperCaseTransformer } from './string.transformer';
2
- export { roundTransformer } from './number.transformer';
3
- export { unixSecondsTransformer, unixMillisTransformer, isoStringTransformer } from './date.transformer';
4
- export { csvTransformer, jsonTransformer } from './collection.transformer';
5
- export { luxonTransformer } from './luxon.transformer';
6
- export type { LuxonTransformerOptions } from './luxon.transformer';
7
- export { momentTransformer } from './moment.transformer';
8
- export type { MomentTransformerOptions } from './moment.transformer';
1
+ export * from './public';
2
+ export type { Transformer, TransformParams } from './interfaces';
3
+ export type { TransformFunction } from './types';
@@ -1 +1 @@
1
- export{trimTransformer,toLowerCaseTransformer,toUpperCaseTransformer}from"./string.transformer.js";export{roundTransformer}from"./number.transformer.js";export{unixSecondsTransformer,unixMillisTransformer,isoStringTransformer}from"./date.transformer.js";export{csvTransformer,jsonTransformer}from"./collection.transformer.js";export{luxonTransformer}from"./luxon.transformer.js";export{momentTransformer}from"./moment.transformer.js";
1
+ export*from"./public.js";
@@ -0,0 +1,26 @@
1
+ export interface TransformParams {
2
+ value: unknown;
3
+ key: string;
4
+ obj: Record<string, unknown>;
5
+ }
6
+ export interface Transformer {
7
+ deserialize(params: TransformParams): unknown;
8
+ serialize(params: TransformParams): unknown;
9
+ }
10
+ export interface LuxonTransformerOptions {
11
+ format?: string;
12
+ zone?: string;
13
+ }
14
+ /** Structural shape of a Luxon DateTime — both methods required so an unrelated object isn't mangled. */
15
+ export interface LuxonLike {
16
+ toISO(): string;
17
+ toFormat(f: string): string;
18
+ }
19
+ export interface MomentTransformerOptions {
20
+ format?: string;
21
+ }
22
+ /** Structural shape of a Moment — both methods required so an unrelated object isn't mangled. */
23
+ export interface MomentLike {
24
+ toISOString(): string;
25
+ format(f: string): string;
26
+ }
File without changes
@@ -0,0 +1,3 @@
1
+ import type { LuxonTransformerOptions, Transformer } from './interfaces';
2
+ declare function luxonTransformer(opts?: LuxonTransformerOptions): Promise<Transformer>;
3
+ export { luxonTransformer };
@@ -0,0 +1 @@
1
+ import{BakerError as F}from"../common/index.js";import{LUXON_MISSING as H}from"./constants.js";async function luxonTransformer(q){let w;try{w=await import("luxon")}catch(b){throw b.code==="ERR_MODULE_NOT_FOUND"?new F(H,{cause:b}):b}const{DateTime:y}=w,A=q?.zone??"utc",C=q?.format;return{deserialize:({value:b})=>{if(typeof b==="string"){const j=y.fromISO(b,{zone:A});return j.isValid?j:b}if(b instanceof Date){const j=y.fromJSDate(b,{zone:A});return j.isValid?j:b}return b},serialize:({value:b})=>{if(b&&typeof b==="object"&&typeof b.toISO==="function"&&typeof b.toFormat==="function"){const j=b;return C?j.toFormat(C):j.toISO()}return b}}}export{luxonTransformer};
@@ -0,0 +1,3 @@
1
+ import type { MomentTransformerOptions, Transformer } from './interfaces';
2
+ declare function momentTransformer(opts?: MomentTransformerOptions): Promise<Transformer>;
3
+ export { momentTransformer };
@@ -0,0 +1 @@
1
+ import{BakerError as y}from"../common/index.js";import{MOMENT_MISSING as z}from"./constants.js";async function momentTransformer(x){let q;try{q=(await import("moment")).default}catch(b){throw b.code==="ERR_MODULE_NOT_FOUND"?new y(z,{cause:b}):b}const w=x?.format;return{deserialize:({value:b})=>{if(typeof b==="string"||b instanceof Date){const j=q.utc(b);return j.isValid()?j:b}return b},serialize:({value:b})=>{if(b&&typeof b==="object"&&typeof b.toISOString==="function"&&typeof b.format==="function"){const j=b;return w?j.format(w):j.toISOString()}return b}}}export{momentTransformer};
@@ -1,2 +1,2 @@
1
- import type { Transformer } from '../types';
1
+ import type { Transformer } from './interfaces';
2
2
  export declare function roundTransformer(precision?: number): Transformer;
@@ -0,0 +1,7 @@
1
+ export { trimTransformer, toLowerCaseTransformer, toUpperCaseTransformer } from './string';
2
+ export { roundTransformer } from './number';
3
+ export { unixSecondsTransformer, unixMillisTransformer, isoStringTransformer } from './date';
4
+ export { csvTransformer, jsonTransformer } from './collection';
5
+ export { luxonTransformer } from './luxon';
6
+ export { momentTransformer } from './moment';
7
+ export type { LuxonTransformerOptions, MomentTransformerOptions } from './interfaces';
@@ -0,0 +1 @@
1
+ export{trimTransformer,toLowerCaseTransformer,toUpperCaseTransformer}from"./string.js";export{roundTransformer}from"./number.js";export{unixSecondsTransformer,unixMillisTransformer,isoStringTransformer}from"./date.js";export{csvTransformer,jsonTransformer}from"./collection.js";export{luxonTransformer}from"./luxon.js";export{momentTransformer}from"./moment.js";
@@ -1,4 +1,4 @@
1
- import type { Transformer } from '../types';
1
+ import type { Transformer } from './interfaces';
2
2
  export declare const trimTransformer: Transformer;
3
3
  export declare const toLowerCaseTransformer: Transformer;
4
4
  export declare const toUpperCaseTransformer: Transformer;
@@ -0,0 +1,3 @@
1
+ import type { TransformParams } from './interfaces';
2
+ /** Internal — direction-specific transform function stored after @Field processing */
3
+ export type TransformFunction = (params: TransformParams) => unknown;
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zipbul/baker",
3
- "version": "5.0.0",
3
+ "version": "5.2.0",
4
4
  "description": "Bun-only AOT decorator-based DTO validation & serialization. class-validator DX, sealed code generation, zero reflect-metadata.",
5
5
  "keywords": [
6
6
  "aot",
@@ -50,20 +50,20 @@
50
50
  "import": "./dist/index.js"
51
51
  },
52
52
  "./decorators": {
53
- "types": "./dist/src/decorators/index.d.ts",
54
- "import": "./dist/src/decorators/index.js"
53
+ "types": "./dist/src/decorators/public.d.ts",
54
+ "import": "./dist/src/decorators/public.js"
55
55
  },
56
56
  "./rules": {
57
- "types": "./dist/src/rules/index.d.ts",
58
- "import": "./dist/src/rules/index.js"
57
+ "types": "./dist/src/rules/public.d.ts",
58
+ "import": "./dist/src/rules/public.js"
59
59
  },
60
60
  "./symbols": {
61
61
  "types": "./dist/src/symbols.d.ts",
62
62
  "import": "./dist/src/symbols.js"
63
63
  },
64
64
  "./transformers": {
65
- "types": "./dist/src/transformers/index.d.ts",
66
- "import": "./dist/src/transformers/index.js"
65
+ "types": "./dist/src/transformers/public.d.ts",
66
+ "import": "./dist/src/transformers/public.js"
67
67
  }
68
68
  },
69
69
  "publishConfig": {
@@ -1,15 +0,0 @@
1
- import type { RawClassMeta, RawPropertyMeta } from './types';
2
- import { RAW } from './symbols';
3
- type MetaObject = Record<PropertyKey, unknown> & {
4
- [RAW]?: RawClassMeta;
5
- };
6
- /**
7
- * Returns the RawPropertyMeta for the given propertyKey on the class's decorator metadata.
8
- * Creates the RAW slot and the per-key default meta if absent.
9
- *
10
- * The own-RAW check is required: a subclass's metadata inherits the parent's RAW via the
11
- * metadata prototype chain, so a bare assignment would pollute the parent. Creating a fresh
12
- * own RAW (null prototype) keeps child fields isolated.
13
- */
14
- export declare function ensureMeta(metadata: MetaObject, key: string): RawPropertyMeta;
15
- export {};
@@ -1 +0,0 @@
1
- import{RAW as x}from"./symbols.js";export function ensureMeta(j,z){if(!Object.hasOwn(j,x))j[x]=Object.create(null);const B=j[x];return B[z]??={validation:[],transform:[],expose:[],exclude:null,type:null,flags:{}}}
@@ -1 +0,0 @@
1
- import{BakerError as u}from"./errors.js";const v=new Set(["autoConvert","allowClassDefaults","stopAtFirstError","forbidUnknown","debug"]);function normalizeConfig(j){if(j===null||typeof j!=="object"||Array.isArray(j))throw new u(`[baker] config requires a plain object. Received: ${j===null?"null":Array.isArray(j)?"array":typeof j}.`);for(const q of Object.keys(j))if(!v.has(q))throw new u(`[baker] unknown key '${q}'. Valid keys: ${[...v].join(", ")}.`);return Object.freeze({enableImplicitConversion:j.autoConvert??!1,exposeDefaultValues:j.allowClassDefaults??!1,stopAtFirstError:j.stopAtFirstError??!1,whitelist:j.forbidUnknown??!1,debug:j.debug??!1})}export{normalizeConfig};
@@ -1 +0,0 @@
1
- import{BakerError as K}from"./errors.js";import{defineRuleMetadata as U}from"./rule-metadata.js";import{isAsyncFunction as V,isPromiseLike as W}from"./utils.js";export function createRule(b,Q){const z=typeof b==="string"?b:b.name,C=typeof b==="string"?Q:b.validate;if(typeof C!=="function")throw new K(`createRule(${z}): a validate function is required.`);const I=typeof b==="object"?b.constraints:void 0,J=typeof b==="object"?b.requiresType:void 0,D=V(C),j=function(H){const w=C(H);if(!D&&W(w))throw new K(`createRule(${z}): sync rule returned Promise. Declare the validator with async if it is asynchronous.`);return w};j.emit=function(H,w){const S=w.addRef(j);return`if(!(${D?"await ":""}refs[${S}](${H}))) ${w.fail(z)};`};const G={emit:j.emit,ruleName:z,isAsync:D};if(I!==void 0)G.constraints=I;if(J!==void 0)G.requiresType=J;U(j,G);return j}
package/dist/src/enums.js DELETED
@@ -1 +0,0 @@
1
- export var RequiredType;((b)=>{b.String="string";b.Number="number";b.Boolean="boolean";b.Date="date";b.Array="array";b.Object="object"})(RequiredType||={});export var Direction;((g)=>{g.Deserialize="deserialize";g.Serialize="serialize"})(Direction||={});export var CollectionType;((g)=>{g.Map="Map";g.Set="Set"})(CollectionType||={});export var CacheKey;((g)=>{g.Length="length";g.Time="time"})(CacheKey||={});export var RulePlanExprKind;((j)=>{j.Value="value";j.Member="member";j.Call0="call0";j.Literal="literal"})(RulePlanExprKind||={});export var RulePlanCheckKind;((m)=>{m.Compare="compare";m.And="and";m.Or="or"})(RulePlanCheckKind||={});export var RuleOp;((b)=>{b.Lt="<";b.Lte="<=";b.Gt=">";b.Gte=">=";b.Eq="===";b.Neq="!=="})(RuleOp||={});export var ExcludeMode;((g)=>{g.DeserializeOnly="deserializeOnly";g.SerializeOnly="serializeOnly"})(ExcludeMode||={});
@@ -1 +0,0 @@
1
- import{BakerError as v}from"../errors.js";const x=new Set(["groups"]);const F=new Set(["autoConvert","allowClassDefaults","stopAtFirstError","forbidUnknown","debug","enableImplicitConversion","exposeDefaultValues","whitelist"]);export function checkCallOptions(d){if(d===void 0||d===null)return;if(typeof d!=="object"||Array.isArray(d))throw new v(`Call options must be a plain object. Received: ${Array.isArray(d)?"array":typeof d}.`);const D=Object.getPrototypeOf(d);if(D!==null&&D!==Object.prototype){const q=d.constructor?.name??"unknown";throw new v(`Call options must be a plain object literal. Received instance of ${q}.`)}for(const q of Object.keys(d)){if(x.has(q))continue;if(F.has(q))throw new v(`Option '${q}' is a seal-time setting and cannot be passed per-call. Move it to new Baker({ ${q}: ... }) at app startup. Per-call options: ${[...x].join(", ")}.`);throw new v(`Unknown per-call option '${q}'. Valid per-call options: ${[...x].join(", ")}. Seal-time options go to new Baker({...}).`)}return d}
@@ -1,19 +0,0 @@
1
- import type { RuntimeOptions } from '../interfaces';
2
- import { type BakerIssueSet } from '../errors';
3
- /**
4
- * Converts input to a Class instance + validates.
5
- * - Requires the class's baker to be sealed (`new Baker().seal()`) beforehand; throws `BakerError` if not sealed
6
- * - Sync DTOs return directly; async DTOs return Promise
7
- * - Success: T
8
- * - Validation failure: BakerIssueSet (use isBakerIssueSet() to narrow)
9
- */
10
- export declare function deserialize<T>(Class: new (...args: never[]) => T, input: unknown, options?: RuntimeOptions): T | BakerIssueSet | Promise<T | BakerIssueSet>;
11
- /**
12
- * Sync-asserted deserialize. Throws `BakerError` if Class has any async rule/transform
13
- * on the deserialize side.
14
- */
15
- export declare function deserializeSync<T>(Class: new (...args: never[]) => T, input: unknown, options?: RuntimeOptions): T | BakerIssueSet;
16
- /**
17
- * Async-asserted deserialize. Always returns Promise (sync DTOs are wrapped via Promise.resolve).
18
- */
19
- export declare function deserializeAsync<T>(Class: new (...args: never[]) => T, input: unknown, options?: RuntimeOptions): Promise<T | BakerIssueSet>;
@@ -1 +0,0 @@
1
- import{isErr as H}from"@zipbul/result";import{toBakerIssueSet as J,BakerError as M}from"../errors.js";import{ensureSealed as K}from"../seal/seal.js";import{checkCallOptions as L}from"./check-call-options.js";export function deserialize(F,j,G){const q=L(G),g=K(F);if(g.isAsync)return g.deserialize(j,q).then((x)=>{if(H(x))return J(x.data);return x});const f=g.deserialize(j,q);if(H(f))return J(f.data);return f}export function deserializeSync(F,j,G){const q=L(G),g=K(F);if(g.isAsync)throw new M(`deserializeSync(${F.name}): DTO has async rules/transforms. Use deserializeAsync() instead.`);const f=g.deserialize(j,q);if(H(f))return J(f.data);return f}export function deserializeAsync(F,j,G){const q=L(G),g=K(F);if(g.isAsync)return g.deserialize(j,q).then((x)=>{if(H(x))return J(x.data);return x});const f=g.deserialize(j,q);if(H(f))return Promise.resolve(J(f.data));return Promise.resolve(f)}
@@ -1,16 +0,0 @@
1
- import type { RuntimeOptions } from '../interfaces';
2
- /**
3
- * Converts a Class instance to a plain object.
4
- * - Requires the class's baker to be sealed (`new Baker().seal()`) beforehand; throws `BakerError` if not sealed
5
- * - Sync DTOs return directly; async DTOs return Promise
6
- * - No validation — always returns Record<string, unknown>
7
- */
8
- export declare function serialize<T>(instance: T, options?: RuntimeOptions): Record<string, unknown> | Promise<Record<string, unknown>>;
9
- /**
10
- * Sync-asserted serialize. Throws `BakerError` if Class has any async transform on the serialize side.
11
- */
12
- export declare function serializeSync<T>(instance: T, options?: RuntimeOptions): Record<string, unknown>;
13
- /**
14
- * Async-asserted serialize. Always returns Promise (sync DTOs are wrapped via Promise.resolve).
15
- */
16
- export declare function serializeAsync<T>(instance: T, options?: RuntimeOptions): Promise<Record<string, unknown>>;
@@ -1 +0,0 @@
1
- import{BakerError as x}from"../errors.js";import{ensureSealed as I}from"../seal/seal.js";import{checkCallOptions as F}from"./check-call-options.js";function G(b,q){if(b==null||typeof b!=="object")throw new x(`${q}: expected a class instance, got ${b===null?"null":typeof b}`);const g=b.constructor;if(typeof g!=="function")throw new x(`${q}: instance has no constructor`);if(g===Object||!(b instanceof g))throw new x(`${q}: received a plain object. Pass an instance of a DTO class decorated with @Field.`);return I(g)}export function serialize(b,q){const g=F(q),j=G(b,"serialize");return j.isSerializeAsync?j.serialize(b,g):j.serialize(b,g)}export function serializeSync(b,q){const g=F(q),j=G(b,"serializeSync");if(j.isSerializeAsync){const H=b.constructor.name;throw new x(`serializeSync(${H}): DTO has async serialize transforms. Use serializeAsync() instead.`)}return j.serialize(b,g)}export function serializeAsync(b,q){const g=F(q),j=G(b,"serializeAsync");return j.isSerializeAsync?j.serialize(b,g):Promise.resolve(j.serialize(b,g))}
@@ -1,18 +0,0 @@
1
- import type { BakerIssueSet } from '../errors';
2
- import type { RuntimeOptions } from '../interfaces';
3
- /**
4
- * DTO-level validation — validates `input` against a decorated class's schema.
5
- * Sync DTOs return directly; async DTOs return Promise. To validate a single primitive without a
6
- * DTO, call the rule directly (e.g. `isEmail()(value)`).
7
- */
8
- declare function validate<T>(Class: new (...args: never[]) => T, input: unknown, options?: RuntimeOptions): true | BakerIssueSet | Promise<true | BakerIssueSet>;
9
- /**
10
- * Sync-asserted validate. Throws `BakerError` if Class has any async rule/transform
11
- * on the deserialize/validate side. Use when caller code assumes sync return.
12
- */
13
- declare function validateSync<T>(Class: new (...args: never[]) => T, input: unknown, options?: RuntimeOptions): true | BakerIssueSet;
14
- /**
15
- * Async-asserted validate. Always returns Promise (sync DTOs are wrapped via Promise.resolve).
16
- */
17
- declare function validateAsync<T>(Class: new (...args: never[]) => T, input: unknown, options?: RuntimeOptions): Promise<true | BakerIssueSet>;
18
- export { validate, validateSync, validateAsync };
@@ -1 +0,0 @@
1
- import{toBakerIssueSet as F,BakerError as J}from"../errors.js";import{ensureSealed as G}from"../seal/seal.js";import{checkCallOptions as H}from"./check-call-options.js";function validate(q,g,x){const j=H(x),b=G(q);if(b.isAsync)return b.validate(g,j).then((z)=>z===null?!0:F(z));const f=b.validate(g,j);return f===null?!0:F(f)}function validateSync(q,g,x){const j=H(x),b=G(q);if(b.isAsync)throw new J(`validateSync(${q.name}): DTO has async rules/transforms. Use validateAsync() instead.`);const f=b.validate(g,j);return f===null?!0:F(f)}function validateAsync(q,g,x){const j=H(x),b=G(q);if(b.isAsync)return b.validate(g,j).then((z)=>z===null?!0:F(z));const f=b.validate(g,j);return Promise.resolve(f===null?!0:F(f))}export{validate,validateSync,validateAsync};
@@ -1,32 +0,0 @@
1
- export interface SealOptions {
2
- /**
3
- * Automatic conversion using validation decorators as type hints.
4
- * @default false
5
- */
6
- enableImplicitConversion?: boolean;
7
- /**
8
- * Use class default values when the key is missing from input.
9
- * @default false
10
- */
11
- exposeDefaultValues?: boolean;
12
- /**
13
- * true: return immediately on first error. false (default): collect all errors.
14
- * @default false
15
- */
16
- stopAtFirstError?: boolean;
17
- /**
18
- * true: reject undeclared fields. Uses the key set from mergeInheritance(Class) as the allowlist.
19
- * `@Exclude` fields are also included in the whitelist — their presence is allowed but they are excluded from the result.
20
- * @default false
21
- */
22
- whitelist?: boolean;
23
- /**
24
- * true: include field exclusion reasons as comments in generated code.
25
- * @default false
26
- */
27
- debug?: boolean;
28
- }
29
- export interface RuntimeOptions {
30
- /** Per-request groups — passed at runtime since they may vary per request */
31
- groups?: string[];
32
- }
@@ -1,19 +0,0 @@
1
- import type { RawClassMeta, SealedExecutors } from './types';
2
- export declare function getSealed(cls: Function): SealedExecutors<unknown> | undefined;
3
- /** Same as getSealed but throws if the class is not sealed — for callers that establish the invariant elsewhere. */
4
- export declare function requireSealed(cls: Function): SealedExecutors<unknown>;
5
- export declare function setSealed(cls: Function, exec: SealedExecutors<unknown>): void;
6
- export declare function hasSealedOwn(cls: Function): boolean;
7
- export declare function deleteSealed(cls: Function): void;
8
- export declare function deleteRaw(cls: Function): void;
9
- export declare function getRaw(cls: Function): RawClassMeta | undefined;
10
- /** Same as getRaw but throws if the class has no @Field decorators — for callers that establish the invariant elsewhere. */
11
- export declare function requireRaw(cls: Function): RawClassMeta;
12
- export declare function setRaw(cls: Function, raw: RawClassMeta): void;
13
- /**
14
- * True only when cls has its OWN RAW slot. A subclass without its own @Field decorators
15
- * resolves Class[Symbol.metadata] to the parent's metadata via the class prototype chain;
16
- * the dual own-check keeps mergeInheritance from double-counting inherited fields.
17
- */
18
- export declare function hasRawOwn(cls: Function): boolean;
19
- export declare function freezeRaw(cls: Function): void;
@@ -1 +0,0 @@
1
- import{RAW as B,SEALED as q}from"./symbols.js";function C(j){return j[Symbol.metadata]??void 0}function F(j){if(!Object.hasOwn(j,Symbol.metadata))Object.defineProperty(j,Symbol.metadata,{value:{},writable:!0,configurable:!0,enumerable:!1});return j[Symbol.metadata]}export function getSealed(j){return j[q]}export function requireSealed(j){const k=j[q];if(k===void 0)throw Error(`${j.name||"<anonymous>"}: class is not sealed`);return k}export function setSealed(j,k){j[q]=k}export function hasSealedOwn(j){return Object.hasOwn(j,q)}export function deleteSealed(j){delete j[q]}export function deleteRaw(j){if(Object.hasOwn(j,Symbol.metadata))delete j[Symbol.metadata][B]}export function getRaw(j){return C(j)?.[B]}export function requireRaw(j){const k=getRaw(j);if(k===void 0)throw Error(`${j.name||"<anonymous>"}: class has no @Field decorators`);return k}export function setRaw(j,k){F(j)[B]=k}export function hasRawOwn(j){if(!Object.hasOwn(j,Symbol.metadata))return!1;const k=j[Symbol.metadata];return k!=null&&Object.hasOwn(k,B)}export function freezeRaw(j){if(!hasRawOwn(j))return;Object.freeze(getRaw(j))}
@@ -1 +0,0 @@
1
- import{RuleOp as Y,RulePlanCheckKind as H,RulePlanExprKind as D}from"./enums.js";import{defineRuleMetadata as Z}from"./rule-metadata.js";const planValue=()=>({kind:D.Value});const planLength=(z=planValue())=>({kind:D.Member,object:z,property:"length"});const planTime=(z=planValue())=>({kind:D.Call0,object:z,method:"getTime"});const planLiteral=(z)=>({kind:D.Literal,value:z});const planCompare=(z,A,B)=>({kind:H.Compare,left:z,op:A,right:typeof B==="number"?planLiteral(B):B});const planOr=(...z)=>({kind:H.Or,checks:z});function makePlannedRule(z){const A={name:z.name,requiresType:z.requiresType,plan:z.plan,validate:z.validate,emit:(B,F)=>emitRulePlan(B,F,z.name,z.plan,void 0,F.insideTypeGate)};if(z.constraints!==void 0)A.constraints=z.constraints;return makeRule(A)}function makeRule(z){const A=(F)=>z.validate(F),B={emit:z.emit,ruleName:z.name,constraints:z.constraints??{}};if(z.requiresType!==void 0)B.requiresType=z.requiresType;if(z.isAsync!==void 0)B.isAsync=z.isAsync;if(z.plan!==void 0)B.plan=z.plan;Z(A,B);return A}function emitRulePlan(z,A,B,F,J,W){const X=W?_(F.failure):F.failure;return`if (${U(X,z,J)}) ${A.fail(B)};`}function _(z){if(z.kind===H.Compare)return z;const A=z.checks.filter((B)=>!$(B));if(A.length===0)return z;if(A.length===1)return A[0];return{kind:z.kind,checks:A}}function $(z){if(z.kind!==H.Compare||z.op!==Y.Neq)return!1;return Q(z.left,z.right)}function Q(z,A){if(z.kind!==A.kind)return!1;switch(z.kind){case D.Value:return!0;case D.Literal:return z.value===A.value;case D.Member:return Q(z.object,A.object);case D.Call0:return z.method===A.method&&Q(z.object,A.object);default:return z}}function U(z,A,B){if(z.kind===H.Compare)return`${I(z.left,A,B)} ${z.op} ${I(z.right,A,B)}`;const F=z.kind===H.And?" && ":" || ";return`(${z.checks.map((J)=>U(J,A,B)).join(F)})`}function I(z,A,B){switch(z.kind){case D.Value:return A;case D.Literal:return String(z.value);case D.Member:return B?.length??`${I(z.object,A,B)}.length`;case D.Call0:return B?.time??`${I(z.object,A,B)}.getTime()`;default:return z}}export{planValue,planLength,planTime,planLiteral,planCompare,planOr,makePlannedRule,makeRule,emitRulePlan};
@@ -1,13 +0,0 @@
1
- import type { RawClassMeta } from '../types';
2
- /**
3
- * @internal — seal-time invariant checks invoked from sealOne after merge + type normalization,
4
- * before codegen. Throws BakerError on the first violation.
5
- *
6
- * Covers W2 (D7 + D9):
7
- * - Discriminator shape: empty subTypes / invalid subType entry / name collision / missing property
8
- * - Set/Map pairing: Set without setValue, Map without mapValue, setValue/mapValue target missing @Field metadata
9
- * - async-in-sync: a DTO that mixes async rules/transforms with sync rules/transforms in such a way
10
- * that the caller cannot easily tell — this throws BakerError so the user makes the intent explicit.
11
- * (Per W2 decision: throw, not warn.)
12
- */
13
- export declare function validateMeta(Class: Function, merged: RawClassMeta): void;
@@ -1 +0,0 @@
1
- import{CollectionType as K}from"../enums.js";import{BakerError as z}from"../errors.js";import{hasRawOwn as H}from"../meta-access.js";export function validateMeta(I,J){const q=I.name;for(const[x,D]of Object.entries(J)){if(D.type?.discriminator){const f=D.type.discriminator;if(typeof f.property!=="string"||f.property.length===0)throw new z(`${q}.${x}: discriminator.property must be a non-empty string.`);if(!Array.isArray(f.subTypes)||f.subTypes.length===0)throw new z(`${q}.${x}: discriminator.subTypes must be a non-empty array of { value, name } entries.`);const F=new Set;for(let A=0;A<f.subTypes.length;A++){const j=f.subTypes[A];if(typeof j.name!=="string"||j.name.length===0)throw new z(`${q}.${x}: discriminator.subTypes[${A}].name must be a non-empty string.`);if(typeof j.value!=="function")throw new z(`${q}.${x}: discriminator.subTypes[${A}].value must be a class constructor (got ${typeof j.value}).`);if(F.has(j.name))throw new z(`${q}.${x}: discriminator.subTypes has duplicate name '${j.name}'. Each subType must have a unique name.`);F.add(j.name);if(!H(j.value))throw new z(`${q}.${x}: discriminator.subTypes[${A}].value (${j.value.name}) has no @Field decorators.`)}}const G=D.type?.collection;if(G!==void 0&&D.type?.resolvedCollectionValue){const f=D.type.resolvedCollectionValue;if(!H(f)){const F=G===K.Set?"setValue":"mapValue";throw new z(`${q}.${x}: ${F} target (${f.name}) has no @Field decorators.`)}}}}
@@ -1 +0,0 @@
1
- export const unixSecondsTransformer={deserialize:({value:r})=>typeof r==="number"?new Date(r*1000):r,serialize:({value:r})=>r instanceof Date?Math.floor(r.getTime()/1000):r};export const unixMillisTransformer={deserialize:({value:r})=>typeof r==="number"?new Date(r):r,serialize:({value:r})=>r instanceof Date?r.getTime():r};export const isoStringTransformer={deserialize:({value:r})=>{if(typeof r!=="string")return r;const e=new Date(r);return Number.isNaN(e.getTime())?r:e},serialize:({value:r})=>r instanceof Date?r.toISOString():r};
@@ -1,8 +0,0 @@
1
- import type { Transformer } from '../types';
2
- interface LuxonTransformerOptions {
3
- format?: string;
4
- zone?: string;
5
- }
6
- declare function luxonTransformer(opts?: LuxonTransformerOptions): Promise<Transformer>;
7
- export type { LuxonTransformerOptions };
8
- export { luxonTransformer };
@@ -1 +0,0 @@
1
- import{BakerError as C}from"../errors.js";const F="luxonTransformer requires the optional peer dependency 'luxon'. Install it with: bun add luxon";async function luxonTransformer(g){let j;try{j=await import("luxon")}catch(b){throw new C(F,{cause:b})}const{DateTime:q}=j,w=g?.zone??"utc",y=g?.format;return{deserialize:({value:b})=>{if(typeof b==="string")return q.fromISO(b,{zone:w});if(b instanceof Date)return q.fromJSDate(b,{zone:w});return b},serialize:({value:b})=>{if(b&&typeof b==="object"&&typeof b.toISO==="function"){const A=b;return y?A.toFormat(y):A.toISO()}return b}}}export{luxonTransformer};
@@ -1,7 +0,0 @@
1
- import type { Transformer } from '../types';
2
- interface MomentTransformerOptions {
3
- format?: string;
4
- }
5
- declare function momentTransformer(opts?: MomentTransformerOptions): Promise<Transformer>;
6
- export type { MomentTransformerOptions };
7
- export { momentTransformer };
@@ -1 +0,0 @@
1
- import{BakerError as x}from"../errors.js";const y="momentTransformer requires the optional peer dependency 'moment'. Install it with: bun add moment";async function momentTransformer(w){let g;try{g=(await import("moment")).default}catch(b){throw new x(y,{cause:b})}const j=w?.format;return{deserialize:({value:b})=>{if(typeof b==="string"||b instanceof Date)return g(b);return b},serialize:({value:b})=>{if(b&&typeof b==="object"&&typeof b.toISOString==="function"&&typeof b.format==="function"){const q=b;return j?q.format(j):q.toISOString()}return b}}}export{momentTransformer};
@@ -1,177 +0,0 @@
1
- import type { Result, ResultAsync } from '@zipbul/result';
2
- import type { CacheKey, CollectionType, RequiredType, RuleOp, RulePlanCheckKind, RulePlanExprKind } from './enums';
3
- import type { BakerIssue } from './errors';
4
- import type { RuntimeOptions } from './interfaces';
5
- export interface EmitContext {
6
- /** Register a RegExp in the reference array, return its index */
7
- addRegex(re: RegExp): number;
8
- /** Register in the reference array, return its index — functions, arrays, Sets, primitives, etc. */
9
- addRef(value: unknown): number;
10
- /** Register a SealedExecutors object in the reference array — for nested @Type DTOs */
11
- addExecutor(executor: SealedExecutors<unknown>): number;
12
- /** Generate a failure code string from an error code — path is bound by the builder */
13
- fail(code: string): string;
14
- /** Whether error collection mode is enabled (= !stopAtFirstError) */
15
- collectErrors: boolean;
16
- /** Whether this emit runs inside a type gate (typeof/instanceof already verified) */
17
- insideTypeGate?: boolean;
18
- /** @internal Path expression for inline nested — used by makeRuleEmitCtx */
19
- pathExpr?: string;
20
- }
21
- export interface EmittableRule {
22
- (value: unknown): boolean | Promise<boolean>;
23
- emit(varName: string, ctx: EmitContext): string;
24
- readonly ruleName: string;
25
- /**
26
- * Meta for the builder to determine whether to insert a typeof guard.
27
- * Only set for rules that assume a specific type (e.g., isEmail → 'string').
28
- * `@IsString` itself is undefined (it includes its own typeof check).
29
- */
30
- readonly requiresType?: RequiredType;
31
- /** Expose rule parameters for external reading */
32
- readonly constraints?: Record<string, unknown>;
33
- /** true when the rule is explicitly async and must be awaited */
34
- readonly isAsync?: boolean;
35
- }
36
- /** @internal internal rule shape used by builders for optimization metadata */
37
- export interface InternalRule extends EmittableRule {
38
- readonly plan?: RulePlan;
39
- }
40
- export type RulePlanExpr = {
41
- kind: RulePlanExprKind.Value;
42
- } | {
43
- kind: RulePlanExprKind.Member;
44
- object: RulePlanExpr;
45
- property: 'length';
46
- } | {
47
- kind: RulePlanExprKind.Call0;
48
- object: RulePlanExpr;
49
- method: 'getTime';
50
- } | {
51
- kind: RulePlanExprKind.Literal;
52
- value: number;
53
- };
54
- export type RulePlanCheck = {
55
- kind: RulePlanCheckKind.Compare;
56
- left: RulePlanExpr;
57
- op: RuleOp;
58
- right: RulePlanExpr;
59
- } | {
60
- kind: RulePlanCheckKind.And | RulePlanCheckKind.Or;
61
- checks: RulePlanCheck[];
62
- };
63
- export interface RulePlan {
64
- cacheKey?: CacheKey;
65
- failure: RulePlanCheck;
66
- }
67
- /** Arguments for user-defined message callback */
68
- export interface MessageArgs {
69
- property: string;
70
- value: unknown;
71
- constraints: Record<string, unknown>;
72
- }
73
- export interface RuleDef {
74
- rule: InternalRule;
75
- each?: boolean;
76
- groups?: string[];
77
- /** Value to include in BakerIssue.message on validation failure */
78
- message?: string | ((args: MessageArgs) => string);
79
- /** Arbitrary value to include in BakerIssue.context on validation failure */
80
- context?: unknown;
81
- }
82
- export interface TransformParams {
83
- value: unknown;
84
- key: string;
85
- obj: Record<string, unknown>;
86
- }
87
- export interface Transformer {
88
- deserialize(params: TransformParams): unknown | Promise<unknown>;
89
- serialize(params: TransformParams): unknown | Promise<unknown>;
90
- }
91
- /** Internal — direction-specific transform function stored after @Field processing */
92
- export type TransformFunction = (params: TransformParams) => unknown | Promise<unknown>;
93
- export interface TransformDef {
94
- fn: TransformFunction;
95
- isAsync?: boolean;
96
- options?: {
97
- groups?: string[];
98
- deserializeOnly?: boolean;
99
- serializeOnly?: boolean;
100
- };
101
- }
102
- export interface ExposeDef {
103
- name?: string;
104
- groups?: string[];
105
- deserializeOnly?: boolean;
106
- serializeOnly?: boolean;
107
- }
108
- export interface ExcludeDef {
109
- deserializeOnly?: boolean;
110
- serializeOnly?: boolean;
111
- }
112
- /** Generic class constructor — contravariant `never[]` args accept any user constructor */
113
- export type ClassCtor<T = object> = new (...args: never[]) => T;
114
- export interface TypeDef {
115
- fn: () => ClassCtor | ClassCtor[] | MapConstructor | SetConstructor;
116
- discriminator?: {
117
- property: string;
118
- subTypes: {
119
- value: Function;
120
- name: string;
121
- }[];
122
- };
123
- keepDiscriminatorProperty?: boolean;
124
- /** seal-time normalization result — true if fn() returns an array */
125
- isArray?: boolean;
126
- /** seal-time normalization result — cached class after resolving fn() (DTOs only, excluding primitives) */
127
- resolvedClass?: ClassCtor;
128
- /** seal-time normalization result — Map or Set collection type */
129
- collection?: CollectionType;
130
- /** Nested DTO class thunk for Map value / Set element */
131
- collectionValue?: () => ClassCtor;
132
- /** seal-time normalization result — cached class after resolving collectionValue */
133
- resolvedCollectionValue?: ClassCtor;
134
- }
135
- export interface PropertyFlags {
136
- /** `@IsOptional`() — skip all validation when undefined/null */
137
- isOptional?: boolean;
138
- /** `@IsDefined`() — disallow undefined (overrides @IsOptional). Current code rejects only undefined; null is delegated to subsequent validation */
139
- isDefined?: boolean;
140
- /** `@IsNullable`() — allow and assign null, reject undefined */
141
- isNullable?: boolean;
142
- /** `@ValidateIf`(cond) — skip all field validation when false */
143
- validateIf?: (obj: Record<string, unknown>) => boolean;
144
- /** `@ValidateNested`() — trigger recursive validation for nested DTOs. Used with @Type */
145
- validateNested?: boolean;
146
- /** `@ValidateNested`({ each: true }) — validate nested DTOs per array element */
147
- validateNestedEach?: boolean;
148
- }
149
- export interface RawPropertyMeta {
150
- validation: RuleDef[];
151
- transform: TransformDef[];
152
- expose: ExposeDef[];
153
- exclude: ExcludeDef | null;
154
- type: TypeDef | null;
155
- flags: PropertyFlags;
156
- /** Field-level message applied to ALL failures of this field (gate/structural/required/conversion/rule) */
157
- message?: string | ((args: MessageArgs) => string);
158
- /** Field-level context attached to ALL failures of this field */
159
- context?: unknown;
160
- }
161
- export interface RawClassMeta {
162
- [propertyKey: string]: RawPropertyMeta;
163
- }
164
- export interface SealedExecutors<T> {
165
- /** Internal executor — Result pattern. deserialize() wraps and converts to throw */
166
- deserialize(input: unknown, options?: RuntimeOptions): Result<T, BakerIssue[]> | ResultAsync<T, BakerIssue[]>;
167
- /** Internal executor — always succeeds. serialize assumes no validation */
168
- serialize(instance: T, options?: RuntimeOptions): Record<string, unknown> | Promise<Record<string, unknown>>;
169
- /** Internal executor — validate-only (no object creation). Returns null on success, BakerIssue[] on failure */
170
- validate(input: unknown, options?: RuntimeOptions): BakerIssue[] | null | Promise<BakerIssue[] | null>;
171
- /** true if the deserialize direction has async rules/transforms/nested */
172
- isAsync: boolean;
173
- /** true if the serialize direction has async transforms/nested */
174
- isSerializeAsync: boolean;
175
- /** Merged metadata cache — used internally by unseal helper */
176
- merged?: RawClassMeta;
177
- }
File without changes
File without changes
File without changes
File without changes
File without changes