@zipbul/baker 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +256 -0
  2. package/MIGRATION-3.0.md +104 -0
  3. package/README.md +121 -75
  4. package/dist/index.d.ts +8 -7
  5. package/dist/index.js +10 -229
  6. package/dist/src/collect.d.ts +13 -10
  7. package/dist/src/collect.js +26 -0
  8. package/dist/src/configure.d.ts +8 -11
  9. package/dist/src/configure.js +43 -0
  10. package/dist/src/create-rule.d.ts +1 -1
  11. package/dist/src/create-rule.js +41 -0
  12. package/dist/src/decorators/field.d.ts +22 -18
  13. package/dist/src/decorators/field.js +268 -0
  14. package/dist/src/decorators/index.d.ts +1 -0
  15. package/dist/src/decorators/index.js +2 -2
  16. package/dist/src/decorators/recipe.d.ts +17 -0
  17. package/dist/src/decorators/recipe.js +23 -0
  18. package/dist/src/errors.d.ts +28 -17
  19. package/dist/src/errors.js +52 -0
  20. package/dist/src/functions/check-call-options.d.ts +8 -0
  21. package/dist/src/functions/check-call-options.js +51 -0
  22. package/dist/src/functions/deserialize.d.ts +14 -6
  23. package/dist/src/functions/deserialize.js +57 -0
  24. package/dist/src/functions/serialize.d.ts +10 -3
  25. package/dist/src/functions/serialize.js +52 -0
  26. package/dist/src/functions/validate.d.ts +13 -8
  27. package/dist/src/functions/validate.js +49 -0
  28. package/dist/src/interfaces.d.ts +1 -1
  29. package/dist/src/interfaces.js +4 -0
  30. package/dist/src/meta-access.d.ts +19 -0
  31. package/dist/src/meta-access.js +75 -0
  32. package/dist/src/registry.js +8 -0
  33. package/dist/src/rule-metadata.d.ts +11 -0
  34. package/dist/src/rule-metadata.js +17 -0
  35. package/dist/src/rule-plan.d.ts +29 -0
  36. package/dist/src/rule-plan.js +117 -0
  37. package/dist/src/rules/array.d.ts +7 -6
  38. package/dist/src/rules/array.js +96 -0
  39. package/dist/src/rules/common.d.ts +2 -2
  40. package/dist/src/rules/common.js +77 -0
  41. package/dist/src/rules/date.js +35 -0
  42. package/dist/src/rules/index.d.ts +2 -4
  43. package/dist/src/rules/index.js +8 -11
  44. package/dist/src/rules/locales.d.ts +5 -4
  45. package/dist/src/rules/locales.js +249 -0
  46. package/dist/src/rules/number.d.ts +2 -2
  47. package/dist/src/rules/number.js +79 -0
  48. package/dist/src/rules/object.d.ts +1 -1
  49. package/dist/src/rules/object.js +49 -0
  50. package/dist/src/rules/string.d.ts +83 -80
  51. package/dist/src/rules/string.js +1998 -0
  52. package/dist/src/rules/typechecker.d.ts +6 -6
  53. package/dist/src/rules/typechecker.js +143 -0
  54. package/dist/src/seal/circular-analyzer.js +63 -0
  55. package/dist/src/seal/codegen-utils.d.ts +7 -0
  56. package/dist/src/seal/codegen-utils.js +18 -0
  57. package/dist/src/seal/deserialize-builder.d.ts +8 -3
  58. package/dist/src/seal/deserialize-builder.js +1546 -0
  59. package/dist/src/seal/expose-validator.d.ts +3 -2
  60. package/dist/src/seal/expose-validator.js +65 -0
  61. package/dist/src/seal/seal-state.d.ts +10 -0
  62. package/dist/src/seal/seal-state.js +18 -0
  63. package/dist/src/seal/seal.d.ts +22 -21
  64. package/dist/src/seal/seal.js +431 -0
  65. package/dist/src/seal/serialize-builder.d.ts +3 -2
  66. package/dist/src/seal/serialize-builder.js +374 -0
  67. package/dist/src/seal/validate-meta.d.ts +13 -0
  68. package/dist/src/seal/validate-meta.js +61 -0
  69. package/dist/src/symbols.d.ts +1 -1
  70. package/dist/src/symbols.js +13 -2
  71. package/dist/src/transformers/collection.transformer.js +25 -0
  72. package/dist/src/transformers/date.transformer.js +18 -0
  73. package/dist/src/transformers/index.js +6 -2
  74. package/dist/src/transformers/luxon.transformer.d.ts +4 -2
  75. package/dist/src/transformers/luxon.transformer.js +34 -0
  76. package/dist/src/transformers/moment.transformer.d.ts +4 -2
  77. package/dist/src/transformers/moment.transformer.js +32 -0
  78. package/dist/src/transformers/number.transformer.js +8 -0
  79. package/dist/src/transformers/string.transformer.js +12 -0
  80. package/dist/src/types.d.ts +68 -28
  81. package/dist/src/types.js +1 -0
  82. package/dist/src/utils.d.ts +4 -2
  83. package/dist/src/utils.js +10 -0
  84. package/package.json +80 -67
  85. package/dist/index-fnv35wrf.js +0 -3
  86. package/dist/index-k3d659ad.js +0 -3
  87. package/dist/index-s0n74vx1.js +0 -3
  88. package/dist/index-xdn55cz3.js +0 -1
  89. package/dist/src/functions/_run-sealed.d.ts +0 -7
  90. package/dist/src/functions/index.d.ts +0 -3
  91. package/dist/src/seal/index.d.ts +0 -5
package/README.md CHANGED
@@ -1,17 +1,17 @@
1
1
  # @zipbul/baker
2
2
 
3
- The fastest decorator-based DTO validation library for TypeScript. Generates optimized validation code at class definition time (AOT), delivering **42ns per validation** up to 163x faster than class-validator, 16x faster than Zod.
3
+ The fastest decorator-based DTO validation library for TypeScript. Generates optimized validation and serialization code on first seal, then reuses the sealed executors on every call.
4
4
 
5
5
  ```bash
6
6
  bun add @zipbul/baker
7
7
  ```
8
8
 
9
- Zero `reflect-metadata`. Zero runtime overhead. 1,890 tests. 99%+ line coverage.
9
+ Zero `reflect-metadata`. Sealed codegen. 99%+ line coverage.
10
10
 
11
11
  ## Quick Start
12
12
 
13
13
  ```typescript
14
- import { deserialize, isBakerError, Field } from '@zipbul/baker';
14
+ import { deserialize, isBakerIssueSet, Field, seal } from '@zipbul/baker';
15
15
  import { isString, isNumber, isEmail, min, minLength } from '@zipbul/baker/rules';
16
16
 
17
17
  class UserDto {
@@ -20,108 +20,138 @@ class UserDto {
20
20
  @Field(isString, isEmail()) email!: string;
21
21
  }
22
22
 
23
+ // Call once at app startup, after all DTOs are loaded.
24
+ seal();
25
+
23
26
  const result = await deserialize(UserDto, {
24
- name: 'Alice', age: 30, email: 'alice@test.com',
27
+ name: 'Alice',
28
+ age: 30,
29
+ email: 'alice@test.com',
25
30
  });
26
31
 
27
- if (isBakerError(result)) {
32
+ if (isBakerIssueSet(result)) {
28
33
  console.log(result.errors); // [{ path: 'email', code: 'isEmail' }]
29
34
  } else {
30
- console.log(result.name); // 'Alice' — typed as UserDto
35
+ console.log(result.name); // 'Alice' — typed as UserDto
31
36
  }
32
37
  ```
33
38
 
34
39
  ## Why Baker?
35
40
 
36
- Baker generates optimized JavaScript validation functions **once** at class definition time, then executes them on every call — no interpretation, no schema traversal, no runtime compilation cost after the first seal.
41
+ Baker generates optimized JavaScript functions once on first seal, then executes them on every call.
37
42
 
38
- | Feature | baker | class-validator | Zod |
39
- |---|---|---|---|
40
- | Valid path (5 fields) | **42ns** | 6,852ns | 675ns |
41
- | Invalid path (5 fields) | **93ns** | 10,109ns | 7,948ns |
42
- | Approach | AOT code generation | Runtime interpretation | Schema method chain |
43
- | Decorators | `@Field` (unified) | 30+ individual | N/A |
44
- | `reflect-metadata` | Not needed | Required | N/A |
45
- | Sync DTO return | Direct value | Promise | Direct value |
43
+ | Feature | baker | class-validator | Zod |
44
+ | ----------------------- | -------------------- | ---------------------- | ------------------- |
45
+ | Valid path (5 fields) | **fast sealed path** | slower | slower |
46
+ | Invalid path (5 fields) | **fast sealed path** | slower | slower |
47
+ | Approach | AOT code generation | Runtime interpretation | Schema method chain |
48
+ | Decorators | `@Field` (unified) | 30+ individual | N/A |
49
+ | `reflect-metadata` | Not needed | Required | N/A |
50
+ | Sync DTO return | Direct value | Promise | Direct value |
46
51
 
47
52
  ## Performance
48
53
 
49
- Benchmarked against 6 libraries on a simple 5-field DTO (valid + invalid input):
54
+ Benchmarked against multiple libraries on simple, nested, array, and error-collection scenarios. Exact numbers vary by machine and runtime.
50
55
 
51
- | Library | Valid | Invalid | vs baker (valid) | vs baker (invalid) |
52
- |---|---|---|---|---|
53
- | **baker** | **42ns** | **93ns** | — | — |
54
- | TypeBox | 123ns | 112ns | 2.9x slower | 1.2x slower |
55
- | AJV | 142ns | 201ns | 3.4x slower | 2.2x slower |
56
- | ArkType | 145ns | 8,591ns | 3.4x slower | 92x slower |
57
- | Valibot | 281ns | 1,070ns | 6.7x slower | 12x slower |
58
- | Zod | 675ns | 7,948ns | 16x slower | 85x slower |
59
- | class-validator | 6,852ns | 10,109ns | 163x slower | 109x slower |
56
+ See [`bench/`](./bench) for the current benchmark suite and exact scenarios.
60
57
 
61
58
  ## API
62
59
 
60
+ ### `seal(...classes?)`
61
+
62
+ **Required.** Call once at app startup, after every DTO module has been imported. With no arguments, seals every class registered via `@Field` so far. With class arguments, seals only those (and any nested DTOs they reach). Idempotent.
63
+
64
+ `deserialize` / `serialize` / `validate` throw `BakerError` if the DTO is not sealed. Tests that need to mutate decorator metadata should call `seal()` after each `configure(...)` reconfiguration.
65
+
63
66
  ### `deserialize<T>(Class, input, options?)`
64
67
 
65
- Returns `T | BakerErrors | Promise<T | BakerErrors>`. Sync DTOs return directly — no Promise wrapping. Never throws on validation failure.
68
+ Returns `T | BakerIssueSet` for sync DTOs, `Promise<T | BakerIssueSet>` for async DTOs. Never throws on validation failure.
69
+
70
+ If the DTO has any async rule or transformer, `deserialize` returns a `Promise`. Otherwise it returns the value directly. For full type safety pick a strict variant (see below).
71
+
72
+ ### `deserializeSync<T>` / `deserializeAsync<T>`
73
+
74
+ Strict variants. `deserializeSync` throws `BakerError` if the DTO is async on the deserialize side. `deserializeAsync` always returns `Promise` (sync DTOs are wrapped via `Promise.resolve`).
66
75
 
67
76
  ### `serialize<T>(instance, options?)`
68
77
 
69
- Returns `Record<string, unknown> | Promise<Record<string, unknown>>`. No validation. Sync DTOs return directly.
78
+ Returns `Record<string, unknown>` for sync DTOs, `Promise<Record<string, unknown>>` for async DTOs. No validation. Async asymmetry: `_isSerializeAsync` is independent of `_isAsync` — a DTO can be async on deserialize but sync on serialize, and vice versa.
79
+
80
+ ### `serializeSync<T>` / `serializeAsync<T>`
81
+
82
+ Strict variants. `serializeSync` throws `BakerError` if the DTO is async on the serialize side.
83
+
84
+ ### `validate(Class, input, options?)`
70
85
 
71
- ### `validate(Class, input, options?)` / `validate(input, ...rules)`
86
+ Validates `input` against a decorated class's schema. Returns `true | BakerIssueSet` for sync paths, `Promise<true | BakerIssueSet>` for async paths. To validate a single primitive without a DTO, call the rule directly (e.g. `isEmail()(value)`).
72
87
 
73
- DTO-level or ad-hoc single-value validation. Returns `true | BakerErrors`.
88
+ ### `validateSync` / `validateAsync`
74
89
 
75
- ### `isBakerError(value)`
90
+ Strict variants. `validateSync` throws `BakerError` if the DTO is async; `validateAsync` always returns `Promise`.
76
91
 
77
- Type guard. Narrows result to `BakerErrors` containing `{ path, code, message?, context? }[]`.
92
+ ### `isBakerIssueSet(value)`
93
+
94
+ Type guard. Narrows result to `BakerIssueSet` containing `{ path, code, message?, context? }[]`.
78
95
 
79
96
  ### `configure(config)`
80
97
 
81
- Global configuration. Call before first deserialize/serialize/validate.
98
+ Global configuration. Must be called **before** `seal()`. After seal, `configure(...)` throws `BakerError`; reconfiguring requires `unseal()` (test-only helper) + `configure(...)` + `seal()` again.
82
99
 
83
100
  ```typescript
84
101
  configure({
85
- autoConvert: true, // coerce "123" → 123
102
+ autoConvert: true, // coerce "123" → 123
86
103
  allowClassDefaults: true, // use class field initializers for missing keys
87
- stopAtFirstError: true, // return on first validation failure
88
- forbidUnknown: true, // reject undeclared fields
104
+ stopAtFirstError: true, // return on first validation failure
105
+ forbidUnknown: true, // reject undeclared fields
89
106
  });
90
107
  ```
91
108
 
92
109
  ### `createRule(name, validate)`
93
110
 
94
- Custom validation rule with optional AOT `emit()` for maximum performance.
111
+ Custom validation rule.
112
+
113
+ ```typescript
114
+ const isEven = createRule({
115
+ name: 'isEven',
116
+ validate: v => typeof v === 'number' && v % 2 === 0,
117
+ requiresType: 'number',
118
+ });
119
+ ```
95
120
 
96
121
  ## @Field Decorator
97
122
 
98
123
  One decorator for everything — replaces 30+ individual decorators from class-validator.
99
124
 
125
+ Only fields decorated with `@Field` participate in validation, deserialization, and serialization. Undecorated fields are silently absent from results — they are not part of the DTO contract.
126
+
100
127
  ```typescript
101
128
  @Field(...rules)
102
129
  @Field(...rules, options)
103
130
  @Field(options)
131
+ @Field() // marker-only (no rules)
104
132
  ```
105
133
 
134
+ Each rule must be an emittable rule object created via `createRule()` or one of the built-in rule factories. Passing a raw function (e.g. `@Field(isNumber)` instead of `@Field(isNumber())`) throws `BakerError` at decorator-evaluation time.
135
+
106
136
  ### Options
107
137
 
108
- | Option | Type | Description |
109
- |---|---|---|
110
- | `type` | `() => Dto \| [Dto]` | Nested DTO. `[Dto]` for arrays |
111
- | `discriminator` | `{ property, subTypes }` | Polymorphic dispatch |
112
- | `optional` | `boolean` | Allow undefined |
113
- | `nullable` | `boolean` | Allow null |
114
- | `name` | `string` | Bidirectional key mapping |
115
- | `deserializeName` | `string` | Input key mapping |
116
- | `serializeName` | `string` | Output key mapping |
117
- | `exclude` | `boolean \| 'deserializeOnly' \| 'serializeOnly'` | Field exclusion |
118
- | `groups` | `string[]` | Conditional visibility |
119
- | `when` | `(obj) => boolean` | Conditional validation |
120
- | `transform` | `Transformer \| Transformer[]` | Value transformer |
121
- | `message` | `string \| (args) => string` | Error message override |
122
- | `context` | `unknown` | Error context |
123
- | `mapValue` | `() => Dto` | Map value DTO |
124
- | `setValue` | `() => Dto` | Set element DTO |
138
+ | Option | Type | Description |
139
+ | ----------------- | ------------------------------------------------- | ------------------------------ |
140
+ | `type` | `() => Dto \| [Dto]` | Nested DTO. `[Dto]` for arrays |
141
+ | `discriminator` | `{ property, subTypes }` | Polymorphic dispatch |
142
+ | `optional` | `boolean` | Allow undefined |
143
+ | `nullable` | `boolean` | Allow null |
144
+ | `name` | `string` | Bidirectional key mapping |
145
+ | `deserializeName` | `string` | Input key mapping |
146
+ | `serializeName` | `string` | Output key mapping |
147
+ | `exclude` | `boolean \| 'deserializeOnly' \| 'serializeOnly'` | Field exclusion |
148
+ | `groups` | `string[]` | Conditional visibility |
149
+ | `when` | `(obj) => boolean` | Conditional validation |
150
+ | `transform` | `Transformer \| Transformer[]` | Value transformer |
151
+ | `message` | `string \| (args) => string` | Error message override |
152
+ | `context` | `unknown` | Error context |
153
+ | `mapValue` | `() => Dto` | Map value DTO |
154
+ | `setValue` | `() => Dto` | Set element DTO |
125
155
 
126
156
  ## Transformers
127
157
 
@@ -131,8 +161,8 @@ Bidirectional value transformers with separate `deserialize` and `serialize` met
131
161
  import type { Transformer } from '@zipbul/baker';
132
162
 
133
163
  const centsTransformer: Transformer = {
134
- deserialize: ({ value }) => typeof value === 'number' ? value * 100 : value,
135
- serialize: ({ value }) => typeof value === 'number' ? value / 100 : value,
164
+ deserialize: ({ value }) => (typeof value === 'number' ? value * 100 : value),
165
+ serialize: ({ value }) => (typeof value === 'number' ? value / 100 : value),
136
166
  };
137
167
  ```
138
168
 
@@ -140,27 +170,34 @@ const centsTransformer: Transformer = {
140
170
 
141
171
  ```typescript
142
172
  import {
143
- trimTransformer, toLowerCaseTransformer, toUpperCaseTransformer,
144
- roundTransformer, unixSecondsTransformer, unixMillisTransformer,
145
- isoStringTransformer, csvTransformer, jsonTransformer,
173
+ trimTransformer,
174
+ toLowerCaseTransformer,
175
+ toUpperCaseTransformer,
176
+ roundTransformer,
177
+ unixSecondsTransformer,
178
+ unixMillisTransformer,
179
+ isoStringTransformer,
180
+ csvTransformer,
181
+ jsonTransformer,
146
182
  } from '@zipbul/baker/transformers';
147
183
  ```
148
184
 
149
- | Transformer | deserialize | serialize |
150
- |---|---|---|
151
- | `trimTransformer` | trim string | trim string |
152
- | `toLowerCaseTransformer` | lowercase | lowercase |
153
- | `toUpperCaseTransformer` | uppercase | uppercase |
154
- | `roundTransformer(n?)` | round to n decimals | round to n decimals |
155
- | `unixSecondsTransformer` | unix seconds &rarr; Date | Date &rarr; unix seconds |
156
- | `unixMillisTransformer` | unix ms &rarr; Date | Date &rarr; unix ms |
157
- | `isoStringTransformer` | ISO string &rarr; Date | Date &rarr; ISO string |
158
- | `csvTransformer(sep?)` | `"a,b"` &rarr; `["a","b"]` | `["a","b"]` &rarr; `"a,b"` |
159
- | `jsonTransformer` | JSON string &rarr; object | object &rarr; JSON string |
185
+ | Transformer | deserialize | serialize |
186
+ | ------------------------ | -------------------------- | -------------------------- |
187
+ | `trimTransformer` | trim string | trim string |
188
+ | `toLowerCaseTransformer` | lowercase | lowercase |
189
+ | `toUpperCaseTransformer` | uppercase | uppercase |
190
+ | `roundTransformer(n?)` | round to n decimals | round to n decimals |
191
+ | `unixSecondsTransformer` | unix seconds &rarr; Date | Date &rarr; unix seconds |
192
+ | `unixMillisTransformer` | unix ms &rarr; Date | Date &rarr; unix ms |
193
+ | `isoStringTransformer` | ISO string &rarr; Date | Date &rarr; ISO string |
194
+ | `csvTransformer(sep?)` | `"a,b"` &rarr; `["a","b"]` | `["a","b"]` &rarr; `"a,b"` |
195
+ | `jsonTransformer` | JSON string &rarr; object | object &rarr; JSON string |
160
196
 
161
197
  ### Transform Array Order
162
198
 
163
199
  Multiple transformers apply as a codec stack:
200
+
164
201
  - **Deserialize**: left to right — `[A, B, C]` applies A, then B, then C
165
202
  - **Serialize**: right to left — `[A, B, C]` applies C, then B, then A
166
203
 
@@ -189,9 +226,11 @@ import { momentTransformer } from '@zipbul/baker/transformers';
189
226
  const mt = await momentTransformer({ format: 'YYYY-MM-DD' });
190
227
  ```
191
228
 
229
+ > **Note on `format`**: The `format` option in `luxonTransformer` / `momentTransformer` controls the **serialize-side output only**. On deserialize, both transformers parse the input with the library's default parser (ISO-first for Luxon, lenient parser for Moment). Using a lossy format like `'YYYY-MM-DD'` makes the transformer one-way — `serialize → deserialize` will not recover the original time of day. If you need a lossless roundtrip, omit `format` (defaults to ISO 8601).
230
+
192
231
  ## Rules
193
232
 
194
- 104 built-in validation rules.
233
+ 105 built-in validation rules.
195
234
 
196
235
  ### Type Checkers
197
236
 
@@ -209,7 +248,7 @@ const mt = await momentTransformer({ format: 'YYYY-MM-DD' });
209
248
 
210
249
  ### Formats
211
250
 
212
- `isEmail()`, `isURL()`, `isUUID(version?)`, `isIP(version?)`, `isISO8601()`, `isJSON`, `isJWT`, `isCreditCard`, `isIBAN()`, `isFQDN()`, `isMACAddress()`, `isBase64()`, `isHexColor`, `isSemVer`, `isMongoId`, `isPhoneNumber()`, `isStrongPassword()`, `isULID()`, `isCUID2()`
251
+ `isEmail()`, `isURL()`, `isUUID(version?)`, `isIP(version?)`, `isISO8601()`, `isJSON`, `isJWT`, `isCreditCard`, `isIBAN()`, `isFQDN()`, `isMACAddress()`, `isBase64()`, `isHexColor`, `isSemVer`, `isMongoId`, `isPhoneNumber()`, `isStrongPassword()`, `isULID()`, `isCUID2()`, `isHttpToken`
213
252
 
214
253
  ### Arrays
215
254
 
@@ -262,7 +301,8 @@ class PetOwner {
262
301
  { value: DogDto, name: 'dog' },
263
302
  ],
264
303
  },
265
- }) pet!: CatDto | DogDto;
304
+ })
305
+ pet!: CatDto | DogDto;
266
306
  }
267
307
  ```
268
308
 
@@ -299,13 +339,19 @@ Yes. baker's `@Field` decorator works alongside NestJS pipes. Use `deserialize()
299
339
 
300
340
  ### How does the AOT code generation work?
301
341
 
302
- On the first call to `deserialize`/`serialize`/`validate`, baker seals all registered DTOs: it analyzes field metadata, generates optimized JavaScript validation functions via `new Function()`, and caches them. Subsequent calls execute the pre-compiled functions directly.
342
+ Calling `seal()` once at app startup walks every registered DTO, analyzes field metadata, generates optimized JavaScript validation functions via `new Function()`, and caches them. Subsequent `deserialize`/`serialize`/`validate` calls execute the pre-compiled functions directly. There is no auto-seal — forgetting to call `seal()` raises `BakerError` on first use.
303
343
 
304
344
  ## Exports
305
345
 
306
346
  ```typescript
307
- import { deserialize, validate, serialize, configure, createRule, Field, arrayOf, isBakerError, SealError } from '@zipbul/baker';
308
- import type { Transformer, TransformParams, BakerError, BakerErrors, FieldOptions, EmittableRule, RuntimeOptions } from '@zipbul/baker';
347
+ import {
348
+ seal,
349
+ deserialize, deserializeSync, deserializeAsync,
350
+ validate, validateSync, validateAsync,
351
+ serialize, serializeSync, serializeAsync,
352
+ configure, createRule, Field, arrayOf, isBakerIssueSet, BakerError,
353
+ } from '@zipbul/baker';
354
+ import type { Transformer, TransformParams, BakerError, BakerIssueSet, FieldOptions, EmittableRule, RuntimeOptions } from '@zipbul/baker';
309
355
  import { isString, isEmail, isULID, isCUID2, ... } from '@zipbul/baker/rules';
310
356
  import { trimTransformer, jsonTransformer, ... } from '@zipbul/baker/transformers';
311
357
  ```
package/dist/index.d.ts CHANGED
@@ -1,12 +1,13 @@
1
- export { deserialize } from './src/functions/deserialize';
2
- export { validate } from './src/functions/validate';
3
- export { serialize } from './src/functions/serialize';
1
+ export { deserialize, deserializeSync, deserializeAsync } from './src/functions/deserialize';
2
+ export { validate, validateSync, validateAsync } from './src/functions/validate';
3
+ export { serialize, serializeSync, serializeAsync } from './src/functions/serialize';
4
4
  export { configure } from './src/configure';
5
5
  export { createRule } from './src/create-rule';
6
- export { Field, arrayOf } from './src/decorators/index';
6
+ export { seal } from './src/seal/seal';
7
+ export { Field, arrayOf, Recipe } from './src/decorators/index';
7
8
  export type { FieldOptions, ArrayOfMarker } from './src/decorators/index';
8
- export type { BakerError, BakerErrors } from './src/errors';
9
- export { isBakerError, SealError } from './src/errors';
9
+ export type { BakerIssue, BakerIssueSet } from './src/errors';
10
+ export { isBakerIssueSet, BakerError } from './src/errors';
10
11
  export type { EmittableRule, Transformer, TransformParams } from './src/types';
11
- export type { BakerConfig, ConfigureResult } from './src/configure';
12
+ export type { BakerConfig } from './src/configure';
12
13
  export type { RuntimeOptions } from './src/interfaces';
package/dist/index.js CHANGED
@@ -1,229 +1,10 @@
1
- // @bun
2
- import"./index-xdn55cz3.js";import{a as G,b as dJ,c as sJ}from"./index-k3d659ad.js";import{d as k,e as R}from"./index-fnv35wrf.js";import"./index-s0n74vx1.js";import{isErr as HJ}from"@zipbul/result";var l=Symbol.for("baker:error");function WJ(Q){return Q!=null&&typeof Q==="object"&&l in Q}function K(Q){return{[l]:!0,errors:Q}}class O extends Error{constructor(Q){super(Q);this.name="SealError"}}var d={};function LJ(Q){let J=[];if(s())J.push("[baker] configure() called after auto-seal. Already-sealed classes are not affected. Call configure() before the first deserialize/serialize."),console.warn("[baker] configure() called after auto-seal. Already-sealed classes are not affected. Call configure() before the first deserialize/serialize.");return d={enableImplicitConversion:Q.autoConvert??!1,exposeDefaultValues:Q.allowClassDefaults??!1,stopAtFirstError:Q.stopAtFirstError??!1,whitelist:Q.forbidUnknown??!1,debug:Q.debug??!1},{warnings:J}}function c(){return d}import{err as zJ,isErr as wJ}from"@zipbul/result";function b(Q){return Q[Symbol.toStringTag]==="AsyncFunction"}var U={field:"__bk$f_",index:"__bk$i_",setIdx:"__bk$si_",setVal:"__bk$sv_",mapIdx:"__bk$mi_",mapVal:"__bk$mv_",mark:"__bk$mark_",skip:"__bk$skip_",result:"__bk$r_",errors:"__bk$re_",arr:"__bk$arr_",disc:"__bk$dt_",nestedIdx:"__bk$j_",out:"__bk$out",errList:"__bk$errors",groups:"__bk$groups",groupsSet:"__bk$groupsSet",key:"__bk$k"};function A(Q){return Q.replace(/[^a-zA-Z0-9_]/g,(J)=>`$${J.charCodeAt(0)}$`)}function u(Q,J,$,X){return`var ${X}={path:${J},code:${$}.code};
3
- if(${$}.message!==undefined)${X}.message=${$}.message;
4
- if(${$}.context!==undefined)${X}.context=${$}.context;
5
- ${Q}.push(${X});
6
- `}function f(Q,J,$){return`var ${$}={path:${Q},code:${J}.code};
7
- if(${J}.message!==undefined)${$}.message=${J}.message;
8
- if(${J}.context!==undefined)${$}.context=${J}.context;
9
- return _err([${$}]);
10
- `}function _J(Q){return U.field+A(Q)}function e(Q,J){let $=J.find((Y)=>Y.deserializeOnly&&Y.name);if($)return $.name;let X=J.find((Y)=>!Y.deserializeOnly&&!Y.serializeOnly&&Y.name);if(X)return X.name;return Q}function JJ(Q){let J=Q.filter((X)=>!X.serializeOnly);if(J.length===0)return;if(J.some((X)=>!X.groups||X.groups.length===0))return;let $=new Set;for(let X of J)for(let Y of X.groups)$.add(Y);return[...$]}function QJ(Q,J,$,X,Y){let B=$?.stopAtFirstError??!1,q=!B,Z=$?.exposeDefaultValues??!1,M=[],F=[],H=[],j=`'use strict';
11
- `;if(j+=Z?`var ${U.out} = new _Cls();
12
- `:`var ${U.out} = Object.create(_Cls.prototype);
13
- `,q)j+=`var ${U.errList} = [];
14
- `;j+=`if (input == null || typeof input !== 'object' || Array.isArray(input)) return _err([{path:'',code:'invalidInput'}]);
15
- `;let z=-1;if(X)F.push(new WeakSet),z=F.length-1,j+=`if (_refs[${z}].has(input)) return _err([{path:'',code:'circular'}]);
16
- `,j+=`_refs[${z}].add(input);
17
- `,j+=`try {
18
- `;if($?.whitelist){let W=new Set;for(let[w,h]of Object.entries(J)){let T=e(w,h.expose);W.add(T)}let D=F.length;if(F.push(W),q)j+=`for (var ${U.key} of Object.keys(input)) { if (!_refs[${D}].has(${U.key})) ${U.errList}.push({path:${U.key},code:'whitelistViolation'}); }
19
- `;else j+=`for (var ${U.key} of Object.keys(input)) { if (!_refs[${D}].has(${U.key})) return _err([{path:${U.key},code:'whitelistViolation'}]); }
20
- `}if(Object.values(J).some((W)=>{let D=JJ(W.expose);if(D&&D.length>0)return!0;if(W.validation.some((w)=>w.groups&&w.groups.length>0))return!0;return!1}))j+=`var ${U.groups} = _opts && _opts.groups;
21
- `,j+=`var ${U.groupsSet} = ${U.groups} ? new Set(${U.groups}) : null;
22
- `;for(let[W,D]of Object.entries(J)){let w=OJ(W,D,{stopAtFirstError:B,collectErrors:q,exposeDefaultValues:Z,isAsync:Y,regexes:M,refs:F,execs:H,options:$});j+=w}if(q)j+=`if (${U.errList}.length) return _err(${U.errList});
23
- `;if(j+=`return ${U.out};
24
- `,X)j+=`} finally { _refs[${z}].delete(input); }
25
- `;return j+=`//# sourceURL=baker://${Q.name}/deserialize
26
- `,Function("_Cls","_re","_refs","_execs","_err","_isErr",`return ${Y?"async function":"function"}(input, _opts) { `+j+" }")(Q,M,F,H,zJ,wJ)}function DJ(Q,J,$){if(Q&&J)return"nullable+optional";if(Q)return"nullable";if($)return"defined";if(J)return"optional";return"default"}var hJ={"nullable+optional"({varName:Q,assignNull:J,validationCode:$}){let X=`if (${Q} === null) { ${J}}
27
- `;return X+=`else if (${Q} !== undefined) {
28
- `,X+=$,X+=`}
29
- `,X},nullable({varName:Q,emitCtx:J,assignNull:$,validationCode:X}){let Y=`if (${Q} === undefined) ${J.fail("isDefined")};
30
- `;return Y+=`else if (${Q} !== null) {
31
- `,Y+=X,Y+=`} else { ${$}}
32
- `,Y},defined({varName:Q,emitCtx:J,validationCode:$}){let X=`if (${Q} === undefined) ${J.fail("isDefined")};
33
- `;return X+=$,X},optional({varName:Q,validationCode:J}){let $=`if (${Q} !== undefined && ${Q} !== null) {
34
- `;return $+=J,$+=`}
35
- `,$},default({varName:Q,emitCtx:J,validationCode:$}){let X=`if (${Q} === undefined || ${Q} === null) ${J.fail("isDefined")};
36
- `;return X+=`else {
37
- `,X+=$,X+=`}
38
- `,X}};function OJ(Q,J,$){let{collectErrors:X,exposeDefaultValues:Y}=$;if(J.exclude){if(!J.exclude.serializeOnly){if($.options?.debug){let T=J.exclude.deserializeOnly?"deserializeOnly":"bidirectional";return`// [baker] field "${Q}" excluded (${T} @Exclude)
39
- `}return""}}if(J.expose.length>0&&J.expose.every((T)=>T.serializeOnly)){if($.options?.debug)return`// [baker] field "${Q}" excluded (all @Expose entries are serializeOnly)
40
- `;return""}let B=_J(Q),q=e(Q,J.expose),Z=JJ(J.expose),M=CJ(Q,$),F="",H=null;if(J.flags.validateIf)H=$.refs.length,$.refs.push(J.flags.validateIf);let j;if(Y&&!J.flags.isOptional)j=`var ${B} = (${JSON.stringify(q)} in input) ? input[${JSON.stringify(q)}] : ${U.out}[${JSON.stringify(Q)}];
41
- `;else j=`var ${B} = input[${JSON.stringify(q)}];
42
- `;let z="",L="";if(Z&&Z.length>0){let T=JSON.stringify(Z);z=`if (${U.groupsSet} && ${T}.some(function(g){return ${U.groupsSet}.has(g);})) {
43
- `,L=`}
44
- `}let P=j,_=!!(J.flags.isOptional&&!J.flags.isDefined),W=J.flags.isNullable===!0,D=TJ(Q,B,J,$,M),w=`${U.out}[${JSON.stringify(Q)}] = null;
45
- `,h=DJ(W,_,J.flags.isDefined??!1);if(P+=hJ[h]({varName:B,emitCtx:M,assignNull:w,validationCode:D}),H!==null)F+=z+`if (_refs[${H}](input)) {
46
- `+P+`}
47
- `+L;else F+=z+P+L;return F}function TJ(Q,J,$,X,Y){let{collectErrors:B,execs:q}=X,Z="",M=$.transform.filter((F)=>!F.options?.serializeOnly);if(M.length>0)for(let F of M){let H=X.refs.length;X.refs.push(F.fn);let j=X.isAsync&&b(F.fn),z=`_refs[${H}]({value:${J},key:${JSON.stringify(Q)},obj:input})`;Z+=`${J} = ${j?"await ":""}${z};
48
- `}if($.type?.collection)return Z+=GJ(Q,J,$,X,Y),Z;if($.flags.validateNested&&$.type?.fn)return Z+=KJ(Q,J,$,X,Y),Z;if($.validation.length===0)return Z+=`${U.out}[${JSON.stringify(Q)}] = ${J};
49
- `,Z;return Z+=gJ(Q,J,$.validation,B,Y,X,$),Z}function XJ(Q,J,$,X){let Y="";if(typeof Q.message==="string")Y+=`,message:${JSON.stringify(Q.message)}`;else if(typeof Q.message==="function"){let B=X.refs.length;X.refs.push(Q.message);let q=X.refs.length;X.refs.push(Q.rule.constraints??{}),Y+=`,message:_refs[${B}]({property:${JSON.stringify(J)},value:${$},constraints:_refs[${q}]})`}if(Q.context!==void 0){let B=X.refs.length;X.refs.push(Q.context),Y+=`,context:_refs[${B}]`}return Y}function g(Q,J,$,X,Y){let B=XJ(X,J,$,Y);if(!B)return Q;return{...Q,fail(q){if(Q.collectErrors)return`${U.errList}.push({path:${JSON.stringify(J)},code:${JSON.stringify(q)}${B}})`;else return`return _err([{path:${JSON.stringify(J)},code:${JSON.stringify(q)}${B}}])`}}}function C(Q,J){if(!Q.groups||Q.groups.length===0)return J;let $=JSON.stringify(Q.groups);return`if (!${U.groupsSet} || ${$}.some(function(g){return ${U.groupsSet}.has(g);})) {
50
- ${J}
51
- }
52
- `}function t(Q,J,$,X,Y,B){let q=Y?`${U.errList}.push({path:${JSON.stringify($)},code:'conversionFailed'}); ${X} = true;`:B.fail("conversionFailed")+";";switch(Q){case"string":return` ${J} = String(${J});
53
- `;case"number":return` ${J} = Number(${J});
54
- if (isNaN(${J})) { ${q} }
55
- `;case"boolean":return` if (${J} === 'true' || ${J} === '1' || ${J} === 1) ${J} = true;
56
- else if (${J} === 'false' || ${J} === '0' || ${J} === 0) ${J} = false;
57
- else { ${q} }
58
- `;case"date":return` ${J} = new Date(${J});
59
- if (isNaN(${J}.getTime())) { ${q} }
60
- `;default:throw new O(`Unknown implicit conversion type: "${Q}" for field "${$}"`)}}var RJ={Number:"number",Boolean:"boolean",String:"string",Date:"date"},r={isString:"string",isNumber:"number",isBoolean:"boolean",isDate:"date",isInt:"number"},SJ=new Set(["isString","isBoolean"]);function VJ(Q,J){let $=J.filter((H)=>H.each),X=J.filter((H)=>!H.each),Y=X.filter((H)=>H.rule.requiresType==="string"),B=X.filter((H)=>H.rule.requiresType==="number"),q=X.filter((H)=>H.rule.requiresType==="boolean"),Z=X.filter((H)=>H.rule.requiresType==="date"),M=X.filter((H)=>!H.rule.requiresType),F=[{type:"string",deps:Y},{type:"number",deps:B},{type:"boolean",deps:q},{type:"date",deps:Z}].filter((H)=>H.deps.length>0);if(F.length>1)throw new O(`Field "${Q}" has conflicting requiresType: ${F.map((H)=>H.type).join(", ")}`);return{each:$,generalRules:M,typedDeps:F.length>0?F[0]:void 0}}function IJ(Q,J,$,X){let{generalRules:Y,typedDeps:B}=J,q=!!B,Z=B?.type??null,M=B?.deps??[],F=-1;if(Z)F=Y.findIndex((P)=>r[P.rule.ruleName]===Z);let H=!!X.options?.enableImplicitConversion&&!$?.transform.some((P)=>!P.options?.serializeOnly),j=null;if(!q&&H&&F<0)for(let P=0;P<Y.length;P++){let _=r[Y[P].rule.ruleName];if(_){F=P,j=_;break}}let z=F>=0?Y[F]:void 0,L=null;if(!q&&!j&&H&&$?.type?.fn)try{let P=$.type.fn(),_=Array.isArray(P)?P[0]:P;L=_?RJ[_.name]??null:null}catch(P){throw new O(`field "${Q}": @Field type function threw: ${P.message}`)}return{effectiveGateType:Z??j??L,gateDeps:M,typeAsserterIdx:F,typeAsserter:z,enableConversion:H,asserterInferredGate:j,typeHintGate:L}}function bJ(Q,J,$,X,Y,B){let q="",{effectiveGateType:Z,gateCondition:M,gateErrorCode:F,gateEmitCtx:H,otherGeneral:j,gateDeps:z,typeAsserter:L,enableConversion:P}=B,_=(W)=>{let D="";if(L&&!SJ.has(L.rule.ruleName)){let w=C(L,L.rule.emit(J,g(X,Q,J,L,Y)));D+=W+w.replace(/\n/g,`
61
- `+W)+`
62
- `}for(let w of j){let h=C(w,w.rule.emit(J,g(X,Q,J,w,Y)));D+=W+h.replace(/\n/g,`
63
- `+W)+`
64
- `}for(let w of z){let h=C(w,w.rule.emit(J,g(X,Q,J,w,Y)));D+=W+h.replace(/\n/g,`
65
- `+W)+`
66
- `}return D};if($)if(P){let W=`${U.skip}${A(Q)}`;q+=`var ${W} = false;
67
- `,q+=`if (${M}) {
68
- `,q+=t(Z,J,Q,W,!0,X),q+=`}
69
- `,q+=`if (!${W}) {
70
- `;let D=`${U.mark}${A(Q)}`;q+=` var ${D} = ${U.errList}.length;
71
- `,q+=_(" "),q+=` if (${U.errList}.length === ${D}) ${U.out}[${JSON.stringify(Q)}] = ${J};
72
- `,q+=`}
73
- `}else{q+=`if (${M}) ${H.fail(F)};
74
- `,q+=`else {
75
- `;let W=`${U.mark}${A(Q)}`;q+=` var ${W} = ${U.errList}.length;
76
- `,q+=_(" "),q+=` if (${U.errList}.length === ${W}) ${U.out}[${JSON.stringify(Q)}] = ${J};
77
- `,q+=`}
78
- `}else if(P)q+=`if (${M}) {
79
- `,q+=t(Z,J,Q,null,!1,X),q+=`}
80
- `,q+=_(""),q+=`${U.out}[${JSON.stringify(Q)}] = ${J};
81
- `;else q+=`if (${M}) ${H.fail(F)};
82
- `,q+=_(""),q+=`${U.out}[${JSON.stringify(Q)}] = ${J};
83
- `;return q}function AJ(Q,J,$,X,Y,B){let q="";if(X)if($.length===0)q+=`${U.out}[${JSON.stringify(Q)}] = ${J};
84
- `;else{let Z=`${U.mark}${A(Q)}`;q+=`var ${Z} = ${U.errList}.length;
85
- `;for(let M of $)q+=C(M,M.rule.emit(J,g(Y,Q,J,M,B)))+`
86
- `;q+=`if (${U.errList}.length === ${Z}) ${U.out}[${JSON.stringify(Q)}] = ${J};
87
- `}else{for(let Z of $)q+=C(Z,Z.rule.emit(J,g(Y,Q,J,Z,B)))+`
88
- `;q+=`${U.out}[${JSON.stringify(Q)}] = ${J};
89
- `}return q}function kJ(Q,J,$,X,Y,B){let q="";for(let Z of $){let M=JSON.stringify(Q),F=A(Q),H=`${U.index}${F}`,j=`${U.setIdx}${F}`,z=`${U.setVal}${F}`,L=`${U.mapIdx}${F}`,P=`${U.mapVal}${F}`,_=XJ(Z,Q,J,B),W=Z.groups&&Z.groups.length>0?`if (!${U.groupsSet} || ${JSON.stringify(Z.groups)}.some(function(g){return ${U.groupsSet}.has(g);})) {
90
- `:"",D=Z.groups&&Z.groups.length>0?`}
91
- `:"",w=[{guard:`Array.isArray(${J})`,idxVar:H,elemExpr:`${J}[${H}]`,loopHeader:`for (var ${H}=0; ${H}<${J}.length; ${H}++)`,counterDecl:"",counterInc:""},{guard:`${J} instanceof Set`,idxVar:j,elemExpr:z,loopHeader:`for (var ${z} of ${J})`,counterDecl:`var ${j} = 0;
92
- `,counterInc:`${j}++;
93
- `},{guard:`${J} instanceof Map`,idxVar:L,elemExpr:P,loopHeader:`for (var ${P} of ${J}.values())`,counterDecl:`var ${L} = 0;
94
- `,counterInc:`${L}++;
95
- `}],h=(T)=>{let V={...Y,fail:(I)=>X?`${U.errList}.push({path:${M}+'['+${T.idxVar}+']',code:${JSON.stringify(I)}${_}})`:`return _err([{path:${M}+'['+${T.idxVar}+']',code:${JSON.stringify(I)}${_}}])`},S="";if(S+=` ${T.counterDecl}`,S+=` ${T.loopHeader} {
96
- `,S+=" "+Z.rule.emit(T.elemExpr,V)+`
97
- `,T.counterInc)S+=` ${T.counterInc}`;return S+=` }
98
- `,S};if(q+=W,X)q+=`if (${w[0].guard}) {
99
- `,q+=h(w[0]),q+=`} else if (${w[1].guard}) {
100
- `,q+=h(w[1]),q+=`} else if (${w[2].guard}) {
101
- `,q+=h(w[2]),q+=`} else { ${U.errList}.push({path:${M},code:'isArray'}); }
102
- `;else q+=`if (!${w[0].guard} && !(${J} instanceof Set) && !(${J} instanceof Map)) ${Y.fail("isArray")};
103
- `,q+=`if (${w[0].guard}) {
104
- `,q+=h(w[0]),q+=`} else if (${w[1].guard}) {
105
- `,q+=h(w[1]),q+=`} else if (${w[2].guard}) {
106
- `,q+=h(w[2]),q+=`}
107
- `;q+=D}return q}function gJ(Q,J,$,X,Y,B,q){let Z=VJ(Q,$),M=IJ(Q,Z,q,B),F="";if(!!Z.typedDeps||M.asserterInferredGate||M.typeHintGate){let j=M.typeAsserter?Z.generalRules.filter((_,W)=>W!==M.typeAsserterIdx):Z.generalRules,z,L;if(M.typeAsserter)L=M.typeAsserter.rule.ruleName;else if(M.gateDeps.length>0)L=M.gateDeps[0].rule.ruleName;else L="conversionFailed";if(M.effectiveGateType==="date")z=`!(${J} instanceof Date)`;else z=`typeof ${J} !== '${M.effectiveGateType}'`;let P=M.typeAsserter?g(Y,Q,J,M.typeAsserter,B):Y;F+=bJ(Q,J,X,Y,B,{effectiveGateType:M.effectiveGateType,gateCondition:z,gateErrorCode:L,gateEmitCtx:P,otherGeneral:j,gateDeps:M.gateDeps,typeAsserter:M.typeAsserter,enableConversion:M.enableConversion})}else F+=AJ(Q,J,Z.generalRules,X,Y,B);return F+=kJ(Q,J,Z.each,X,Y,B),F}function GJ(Q,J,$,X,Y){let{collectErrors:B,execs:q}=X,Z=A(Q),M=$.type.collection,F=X.isAsync?"await ":"",H=-1;if($.type.resolvedCollectionValue){let z=$.type.resolvedCollectionValue[R];H=q.length,q.push(z)}let j="";if(M==="Set"){j+=`if (Array.isArray(${J})) {
108
- `;let z=$.validation.filter((P)=>!P.each);for(let P of z){let _=g(Y,Q,J,P,X);j+=` ${P.rule.emit(J,_)}
109
- `}if(H>=0){let P=`${U.index}${Z}`;if(j+=` var ${U.arr}${Z} = new Set();
110
- `,j+=` for (var ${P}=0; ${P}<${J}.length; ${P}++) {
111
- `,j+=` var ${U.result}${Z} = ${F}_execs[${H}]._deserialize(${J}[${P}], _opts);
112
- `,j+=` if (_isErr(${U.result}${Z})) {
113
- `,B)j+=` var ${U.errors}${Z} = ${U.result}${Z}.data;
114
- `,j+=` for (var ${U.nestedIdx}${Z}=0; ${U.nestedIdx}${Z}<${U.errors}${Z}.length; ${U.nestedIdx}${Z}++) {
115
- `,j+=" "+u(U.errList,`${JSON.stringify(Q)}+'['+${P}+'].'+${U.errors}${Z}[${U.nestedIdx}${Z}].path`,`${U.errors}${Z}[${U.nestedIdx}${Z}]`,`__ne${Z}`),j+=` }
116
- `;else j+=` var ${U.errors}${Z} = ${U.result}${Z}.data;
117
- `,j+=" "+f(`${JSON.stringify(Q)}+'['+${P}+'].'+${U.errors}${Z}[0].path`,`${U.errors}${Z}[0]`,`__ne${Z}`);j+=` } else { ${U.arr}${Z}.add(${U.result}${Z}); }
118
- `,j+=` }
119
- `,j+=` ${U.out}[${JSON.stringify(Q)}] = ${U.arr}${Z};
120
- `}else j+=` ${U.out}[${JSON.stringify(Q)}] = new Set(${J});
121
- `;let L=$.validation.filter((P)=>P.each);if(L.length>0){let P=`${U.setIdx}${Z}`,_=`${U.setVal}${Z}`;j+=` var ${P} = 0;
122
- `,j+=` for (var ${_} of ${U.out}[${JSON.stringify(Q)}]) {
123
- `;for(let W of L){let w={...Y,fail:(h)=>B?`${U.errList}.push({path:${JSON.stringify(Q)}+'['+${P}+']',code:${JSON.stringify(h)}})`:`return _err([{path:${JSON.stringify(Q)}+'['+${P}+']',code:${JSON.stringify(h)}}])`};j+=` ${W.rule.emit(_,w)}
124
- `}j+=` ${P}++;
125
- `,j+=` }
126
- `}j+=`} else { ${Y.fail("isArray")}; }
127
- `}else{if(j+=`if (${J} != null && typeof ${J} === 'object' && !Array.isArray(${J})) {
128
- `,H>=0){let z=`${U.key}${Z}`;if(j+=` var ${U.arr}${Z} = new Map();
129
- `,j+=` for (var ${z} in ${J}) {
130
- `,j+=` if (!Object.prototype.hasOwnProperty.call(${J}, ${z})) continue;
131
- `,j+=` var ${U.result}${Z} = ${F}_execs[${H}]._deserialize(${J}[${z}], _opts);
132
- `,j+=` if (_isErr(${U.result}${Z})) {
133
- `,B)j+=` var ${U.errors}${Z} = ${U.result}${Z}.data;
134
- `,j+=` for (var ${U.nestedIdx}${Z}=0; ${U.nestedIdx}${Z}<${U.errors}${Z}.length; ${U.nestedIdx}${Z}++) {
135
- `,j+=" "+u(U.errList,`${JSON.stringify(Q)}+'['+${z}+'].'+${U.errors}${Z}[${U.nestedIdx}${Z}].path`,`${U.errors}${Z}[${U.nestedIdx}${Z}]`,`__ne${Z}`),j+=` }
136
- `;else j+=` var ${U.errors}${Z} = ${U.result}${Z}.data;
137
- `,j+=" "+f(`${JSON.stringify(Q)}+'['+${z}+'].'+${U.errors}${Z}[0].path`,`${U.errors}${Z}[0]`,`__ne${Z}`);j+=` } else { ${U.arr}${Z}.set(${z}, ${U.result}${Z}); }
138
- `,j+=` }
139
- `,j+=` ${U.out}[${JSON.stringify(Q)}] = ${U.arr}${Z};
140
- `}else j+=` var ${U.arr}${Z} = new Map();
141
- `,j+=` for (var ${U.key}${Z} in ${J}) {
142
- `,j+=` if (Object.prototype.hasOwnProperty.call(${J}, ${U.key}${Z})) ${U.arr}${Z}.set(${U.key}${Z}, ${J}[${U.key}${Z}]);
143
- `,j+=` }
144
- `,j+=` ${U.out}[${JSON.stringify(Q)}] = ${U.arr}${Z};
145
- `;j+=`} else { ${Y.fail("isObject")}; }
146
- `}return j}function KJ(Q,J,$,X,Y){let{collectErrors:B,execs:q}=X;if(!$.type)return`${U.out}[${JSON.stringify(Q)}] = ${J};
147
- `;let Z="",M=A(Q);if($.type.discriminator){let F=JSON.stringify($.type.discriminator.property);Z+=`var ${U.disc}${M} = ${J} && ${J}[${F}];
148
- `,Z+=`switch (${U.disc}${M}) {
149
- `;for(let H of $.type.discriminator.subTypes){let j=H.value[R],z=q.length;q.push(j);let L=X.isAsync?"await ":"";Z+=` case ${JSON.stringify(H.name)}:
150
- `,Z+=` var ${U.result}${M} = ${L}_execs[${z}]._deserialize(${J}, _opts);
151
- `,Z+=a(Q,`${U.result}${M}`,B),Z+=` break;
152
- `}if(Z+=` default: ${Y.fail("invalidDiscriminator")};
153
- `,Z+=`}
154
- `,$.type.keepDiscriminatorProperty)Z+=`if (${U.out}[${JSON.stringify(Q)}] != null) ${U.out}[${JSON.stringify(Q)}][${F}] = ${U.disc}${M};
155
- `}else{let H=($.type.resolvedClass??$.type.fn())[R],j=q.length;if(q.push(H),$.type?.isArray||$.flags.validateNestedEach||$.validation.some((L)=>L.each)){let L=`${U.index}${M}`,P=X.isAsync?"await ":"";Z+=`if (Array.isArray(${J})) {
156
- `;let _=$.validation.filter((W)=>!W.each);for(let W of _){let D=g(Y,Q,J,W,X),w=W.rule.emit(J,D);Z+=` ${w}
157
- `}if(Z+=` var ${U.arr}${M} = [];
158
- `,Z+=` for (var ${L}=0; ${L}<${J}.length; ${L}++) {
159
- `,Z+=` var ${U.result}${M} = ${P}_execs[${j}]._deserialize(${J}[${L}], _opts);
160
- `,Z+=` if (_isErr(${U.result}${M})) {
161
- `,B)Z+=` var ${U.errors}${M} = ${U.result}${M}.data;
162
- `,Z+=` for (var ${U.nestedIdx}${M}=0; ${U.nestedIdx}${M}<${U.errors}${M}.length; ${U.nestedIdx}${M}++) {
163
- `,Z+=" "+u(U.errList,`${JSON.stringify(Q)}+'['+${L}+'].'+${U.errors}${M}[${U.nestedIdx}${M}].path`,`${U.errors}${M}[${U.nestedIdx}${M}]`,`__ne${M}`),Z+=` }
164
- `;else Z+=` var ${U.errors}${M} = ${U.result}${M}.data;
165
- `,Z+=" "+f(`${JSON.stringify(Q)}+'['+${L}+'].'+${U.errors}${M}[0].path`,`${U.errors}${M}[0]`,`__ne${M}`);Z+=` } else { ${U.arr}${M}.push(${U.result}${M}); }
166
- `,Z+=` }
167
- `,Z+=` ${U.out}[${JSON.stringify(Q)}] = ${U.arr}${M};
168
- `,Z+=`} else { ${Y.fail("isArray")}; }
169
- `}else{let L=X.isAsync?"await ":"";Z+=`if (${J} != null && typeof ${J} === 'object') {
170
- `,Z+=` var ${U.result}${M} = ${L}_execs[${j}]._deserialize(${J}, _opts);
171
- `,Z+=a(Q,`${U.result}${M}`,B),Z+=`} else { ${Y.fail("isObject")}; }
172
- `}}return Z}function a(Q,J,$){let X=A(Q);if($){let Y=`${U.errors}${X}[${U.nestedIdx}${X}]`;return` if (_isErr(${J})) {
173
- var ${U.errors}${X} = ${J}.data;
174
- for (var ${U.nestedIdx}${X}=0; ${U.nestedIdx}${X}<${U.errors}${X}.length; ${U.nestedIdx}${X}++) {
175
- `+u(U.errList,`${JSON.stringify(Q+".")}+${Y}.path`,Y,`__ne${X}`)+` }
176
- } else { ${U.out}[${JSON.stringify(Q)}] = ${J}; }
177
- `}else{let Y=`${U.errors}${X}[0]`;return` if (_isErr(${J})) {
178
- var ${U.errors}${X} = ${J}.data;
179
- `+f(`${JSON.stringify(Q+".")}+${Y}.path`,Y,`__ne${X}`)+` } else { ${U.out}[${JSON.stringify(Q)}] = ${J}; }
180
- `}}function CJ(Q,J){let{collectErrors:$,regexes:X,refs:Y,execs:B}=J;return{addRegex(q){return X.push(q),X.length-1},addRef(q){return Y.push(q),Y.length-1},addExecutor(q){return B.push(q),B.length-1},fail(q){if($)return`${U.errList}.push({path:${JSON.stringify(Q)},code:${JSON.stringify(q)}})`;else return`return _err([{path:${JSON.stringify(Q)},code:${JSON.stringify(q)}}])`},collectErrors:$}}function vJ(Q,J){let $=J.find((Y)=>Y.serializeOnly&&Y.name);if($)return $.name;let X=J.find((Y)=>!Y.deserializeOnly&&!Y.serializeOnly&&Y.name);if(X)return X.name;return Q}function $J(Q){let J=Q.filter((X)=>!X.deserializeOnly);if(J.length===0)return;if(J.some((X)=>!X.groups||X.groups.length===0))return;let $=new Set;for(let X of J)for(let Y of X.groups)$.add(Y);return[...$]}function ZJ(Q,J,$,X,Y){if($.length===0)return"";let B=[...$].reverse(),q=Q;for(let Z of B){let M=X.length;X.push(Z.fn);let F=`_refs[${M}]({value:${q},key:${JSON.stringify(J)},obj:instance})`;q=Y&&b(Z.fn)?`(await ${F})`:F}return`
181
- ${Q} = ${q};`}function UJ(Q,J,$,X){let Y=[],B=[],q=`'use strict';
182
- `;if(q+=`var __bk$out = {};
183
- `,Object.values(J).some((H)=>{let j=$J(H.expose);return j&&j.length>0}))q+=`var __bk$groups = _opts && _opts.groups;
184
- `,q+=`var __bk$groupsSet = __bk$groups ? new Set(__bk$groups) : null;
185
- `;for(let[H,j]of Object.entries(J))q+=xJ(H,j,Y,B,X,$);return q+=`return __bk$out;
186
- `,q+=`//# sourceURL=baker://${Q.name}/serialize
187
- `,Function("_refs","_execs",`return ${X?"async function":"function"}(instance, _opts) { `+q+" }")(Y,B)}function xJ(Q,J,$,X,Y,B){if(J.exclude){if(!J.exclude.deserializeOnly){if(B?.debug){let P=J.exclude.serializeOnly?"serializeOnly":"bidirectional";return`// [baker] field "${Q}" excluded (${P} @Exclude)
188
- `}return""}}if(J.expose.length>0&&J.expose.every((P)=>P.deserializeOnly)){if(B?.debug)return`// [baker] field "${Q}" excluded (all @Expose entries are deserializeOnly)
189
- `;return""}let q=vJ(Q,J.expose),Z=$J(J.expose),M="",F="",H="";if(Z&&Z.length>0)F=`if (__bk$groupsSet && ${JSON.stringify(Z)}.some(function(g){return __bk$groupsSet.has(g);})) {
190
- `,H=`}
191
- `;let j="",z=J.flags.isOptional,L=J.transform.filter((P)=>!P.options?.deserializeOnly);if(J.type?.collection){let P=`__bk$out[${JSON.stringify(q)}]`,_=J.type.collection,W;if(_==="Set")if(J.type.resolvedCollectionValue){let D=J.type.resolvedCollectionValue[R],w=X.length;if(X.push(D),Y)W=`${P} = await Promise.all(Array.from(instance[${JSON.stringify(Q)}]).map(async function(__ser_item) { return __ser_item == null ? __ser_item : await _execs[${w}]._serialize(__ser_item, _opts); }));`;else W=`${P} = Array.from(instance[${JSON.stringify(Q)}]).map(function(__ser_item) { return __ser_item == null ? __ser_item : _execs[${w}]._serialize(__ser_item, _opts); });`}else W=`${P} = Array.from(instance[${JSON.stringify(Q)}]);`;else if(J.type.resolvedCollectionValue){let D=J.type.resolvedCollectionValue[R],w=X.length;X.push(D);let h=Y?"await ":"";W=`var __bk$m = {};
192
- `,W+=` for (var __bk$me of instance[${JSON.stringify(Q)}]) {
193
- `,W+=` __bk$m[__bk$me[0]] = __bk$me[1] == null ? __bk$me[1] : ${h}_execs[${w}]._serialize(__bk$me[1], _opts);
194
- `,W+=` }
195
- `,W+=` ${P} = __bk$m;`}else W=`${P} = Object.fromEntries(instance[${JSON.stringify(Q)}]);`;if(W+=ZJ(P,Q,L,$,Y),z)j=`if (instance[${JSON.stringify(Q)}] !== undefined && instance[${JSON.stringify(Q)}] !== null) {
196
- ${W}
197
- } else if (instance[${JSON.stringify(Q)}] === null) {
198
- ${P} = null;
199
- }
200
- `;else j=`if (instance[${JSON.stringify(Q)}] != null) {
201
- ${W}
202
- } else {
203
- ${P} = instance[${JSON.stringify(Q)}];
204
- }
205
- `;return M+=F+j+H,M}if(J.type?.resolvedClass||J.type?.discriminator||J.type?.fn&&J.flags.validateNested){let P=J.type?.isArray||J.flags.validateNestedEach||J.validation.some((D)=>D.each),_=`__bk$out[${JSON.stringify(q)}]`,W;if(J.type.discriminator){let{property:D,subTypes:w}=J.type.discriminator,h=J.type.keepDiscriminatorProperty!==!1,T=[...w].sort((V,S)=>{if(V.value.prototype instanceof S.value)return-1;if(S.value.prototype instanceof V.value)return 1;return 0}),n=(V,S)=>{let I="";for(let x=0;x<T.length;x++){let m=T[x],FJ=m.value[R],BJ=X.length;X.push(FJ);let PJ=$.length;if($.push(m.value),I+=`${x===0?"if":"} else if"} (${V} instanceof _refs[${PJ}]) {
206
- `,I+=` var __bk$sr = ${S}_execs[${BJ}]._serialize(${V}, _opts);
207
- `,h)I+=` __bk$sr[${JSON.stringify(D)}] = ${JSON.stringify(m.name)};
208
- `;I+=` __bk$out_item = __bk$sr;
209
- `}return I+="} else { __bk$out_item = "+V+`; }
210
- `,I};if(P){let V=Y?"await ":"";if(Y)W=`${_} = await Promise.all(instance[${JSON.stringify(Q)}].map(async function(__ser_item) {
211
- `;else W=`${_} = instance[${JSON.stringify(Q)}].map(function(__ser_item) {
212
- `;W+=` var __bk$out_item;
213
- `,W+=n("__ser_item",V),W+=` return __bk$out_item;
214
- `,W+=Y?"}));":"});"}else{let V=Y?"await ":"",S=JSON.stringify(Q);W=`var __bk$out_item;
215
- `,W+=n(`instance[${S}]`,V),W+=`${_} = __bk$out_item;`}}else{let w=(J.type.resolvedClass??J.type.fn())[R],h=X.length;if(X.push(w),P)if(Y)W=`${_} = await Promise.all(instance[${JSON.stringify(Q)}].map(async function(__ser_item) { return __ser_item == null ? __ser_item : await _execs[${h}]._serialize(__ser_item, _opts); }));`;else W=`${_} = instance[${JSON.stringify(Q)}].map(function(__ser_item) { return __ser_item == null ? __ser_item : _execs[${h}]._serialize(__ser_item, _opts); });`;else W=`${_} = ${Y?"await ":""}_execs[${h}]._serialize(instance[${JSON.stringify(Q)}], _opts);`}if(W+=ZJ(_,Q,L,$,Y),z)j=`if (instance[${JSON.stringify(Q)}] !== undefined && instance[${JSON.stringify(Q)}] !== null) {
216
- ${W}
217
- } else if (instance[${JSON.stringify(Q)}] === null) {
218
- ${_} = null;
219
- }
220
- `;else j=`if (instance[${JSON.stringify(Q)}] != null) {
221
- ${W}
222
- } else {
223
- ${_} = instance[${JSON.stringify(Q)}];
224
- }
225
- `}else{let P=uJ(Q,q,J,$,Y);if(z)j+=`if (instance[${JSON.stringify(Q)}] !== undefined) {
226
- `,j+=" "+P+`
227
- `,j+=`}
228
- `;else j+=P+`
229
- `}return M+=F+j+H,M}function uJ(Q,J,$,X,Y){let B=`__bk$out[${JSON.stringify(J)}]`,q=$.transform.filter((Z)=>!Z.options?.deserializeOnly);if(q.length>0){let Z=[...q].reverse(),M=`instance[${JSON.stringify(Q)}]`;for(let F of Z){let H=X.length;X.push(F.fn);let j=`_refs[${H}]({value:${M},key:${JSON.stringify(Q)},obj:instance})`;M=Y&&b(F.fn)?`(await ${j})`:j}return`${B} = ${M};`}return`${B} = instance[${JSON.stringify(Q)}];`}function qJ(Q){let J=new Set;function $(X){if(J.has(X))return!0;J.add(X);let Y=X[k];if(Y)for(let B of Object.values(Y)){if(B.type?.fn){let q;try{q=B.type.fn()}catch(M){throw new O(`${X.name}: type function threw: ${M.message}`)}let Z=Array.isArray(q)?q[0]:q;if($(Z))return!0}if(B.type?.discriminator){for(let q of B.type.discriminator.subTypes)if($(q.value))return!0}}return J.delete(X),!1}return $(Q)}function jJ(Q,J){let $=J?`${J}.`:"";for(let[X,Y]of Object.entries(Q)){for(let Z of Y.expose)if(Z.deserializeOnly&&Z.serializeOnly)throw new O(`Invalid @Expose on field '${$}${X}': cannot have both deserializeOnly:true and serializeOnly:true on the same @Expose entry. Use separate @Expose decorators for each direction.`);let B=Y.expose.filter((Z)=>!Z.serializeOnly),q=Y.expose.filter((Z)=>!Z.deserializeOnly);YJ($+X,B,"deserialize"),YJ($+X,q,"serialize")}}function YJ(Q,J,$){for(let X=0;X<J.length;X++)for(let Y=X+1;Y<J.length;Y++){let B=J[X].groups??[],q=J[Y].groups??[];if(fJ(B,q)){let Z=new Set(q),M=B.length===0?[]:B.filter((F)=>Z.has(F));throw new O(`@Expose conflict on '${Q}': 2 @Expose stacks with '${$}' direction and overlapping groups [${M.join(", ")}]. Each direction must have at most one @Expose per group set.`)}}}function fJ(Q,J){if(Q.length===0&&J.length===0)return!0;if(Q.length===0||J.length===0)return!1;return Q.some(($)=>J.includes($))}var pJ=new Set(["__proto__","constructor","prototype"]),MJ=new Set([Number,String,Boolean,Date]);function EJ(Q){let J=`Circular dependency during seal: ${Q} is still being sealed`;return{_deserialize(){throw new O(J)},_serialize(){throw new O(J)},_isAsync:!1,_isSerializeAsync:!1}}function E(Q,J,$){let X=$??new Set;for(let Y of Object.values(Q)){if(J==="deserialize"&&Y.validation.some((q)=>q.rule.isAsync))return!0;if((J==="deserialize"?Y.transform.filter((q)=>!q.options?.serializeOnly):Y.transform.filter((q)=>!q.options?.deserializeOnly)).some((q)=>b(q.fn)))return!0;if(Y.type?.resolvedClass){let q=Y.type.resolvedClass;if(!X.has(q)){X.add(q);let Z=i(q);if(E(Z,J,X))return!0}}if(Y.type?.discriminator){for(let q of Y.type.discriminator.subTypes)if(!X.has(q.value)){X.add(q.value);let Z=i(q.value);if(E(Z,J,X))return!0}}}return!1}var o=!1;function s(){return o}var p=new Set;function NJ(){if(o)return;let Q=c();try{for(let J of G)v(J,Q)}catch(J){for(let $ of G)if(Object.hasOwn($,R))delete $[R];throw J}for(let J of G)p.add(J),Object.freeze(J[k]);G.clear(),o=!0}function yJ(Q){if(Object.hasOwn(Q,R))return;if(!Object.hasOwn(Q,k))return;let J=new Set(p),$=c();v(Q,$),p.add(Q),Object.freeze(Q[k]),G.delete(Q);let X=[...G].filter((Y)=>Object.hasOwn(Y,R)&&!J.has(Y));for(let Y of X)p.add(Y),Object.freeze(Y[k]),G.delete(Y)}function N(Q){let J=Q[R];if(!J)NJ(),J=Q[R];if(!J)yJ(Q),J=Q[R];if(!J)throw new O(`${Q.name} has no @Field decorators`);return J}function v(Q,J){if(Object.hasOwn(Q,R))return;let $=EJ(Q.name);Q[R]=$;let X=i(Q);for(let F of Object.keys(X))if(pJ.has(F))throw new O(`${Q.name}: field name '${F}' is not allowed (reserved property name)`);for(let[F,H]of Object.entries(X)){if(!H.type?.fn)continue;let j=H.type.fn();if(j===Map||j===Set){let _=j===Map?"Map":"Set",W={...H.type,collection:_,isArray:!1};if(H.type.collectionValue){let D=H.type.collectionValue();if(D!=null&&typeof D==="function"&&!MJ.has(D))W.resolvedCollectionValue=D}X[F]={...H,type:W};continue}let z=Array.isArray(j),L=z?j[0]:j;if(L==null||typeof L!=="function")throw new O(`${Q.name}: @Type/@Field type must return a constructor or [constructor], got ${String(L)}`);let P={...H.type,isArray:z};if(!MJ.has(L)){if(P.resolvedClass=L,!H.flags.validateNested||!H.flags.validateNestedEach){if(H.flags={...H.flags},!H.flags.validateNested)H.flags.validateNested=!0;if(z&&!H.flags.validateNestedEach)H.flags.validateNestedEach=!0}}X[F]={...H,type:P}}jJ(X,Q.name);let Y=qJ(Q);for(let F of Object.values(X)){if(F.type?.resolvedClass)v(F.type.resolvedClass,J);if(F.type?.resolvedCollectionValue)v(F.type.resolvedCollectionValue,J);if(F.type?.discriminator)for(let H of F.type.discriminator.subTypes)v(H.value,J)}let B=E(X,"deserialize"),q=E(X,"serialize"),Z=QJ(Q,X,J,Y,B),M=UJ(Q,X,J,q);Object.assign($,{_deserialize:Z,_serialize:M,_isAsync:B,_isSerializeAsync:q,_merged:X})}function i(Q){let J=[],$=Q;while($&&$!==Object){if(Object.hasOwn($,k))J.push($);let Y=Object.getPrototypeOf($);$=Y===$?null:Y}let X=Object.create(null);for(let Y of J){let B=Y[k];for(let[q,Z]of Object.entries(B))if(!X[q])X[q]={validation:[...Z.validation],transform:[...Z.transform],expose:[...Z.expose],exclude:Z.exclude,type:Z.type,flags:{...Z.flags}};else{let M=X[q],F=Z;for(let z of F.validation)if(!M.validation.some((L)=>L.rule===z.rule))M.validation.push(z);if(M.transform.length===0&&F.transform.length>0)M.transform=[...F.transform];if(M.expose.length===0&&F.expose.length>0)M.expose=[...F.expose];if(M.exclude===null&&F.exclude!==null)M.exclude=F.exclude;if(M.type===null&&F.type!==null)M.type=F.type;let H=M.flags,j=F.flags;if(j.isOptional!==void 0&&H.isOptional===void 0)H.isOptional=j.isOptional;if(j.isDefined!==void 0&&H.isDefined===void 0)H.isDefined=j.isDefined;if(j.validateIf!==void 0&&H.validateIf===void 0)H.validateIf=j.validateIf;if(j.isNullable!==void 0&&H.isNullable===void 0)H.isNullable=j.isNullable;if(j.validateNested!==void 0&&H.validateNested===void 0)H.validateNested=j.validateNested;if(j.validateNestedEach!==void 0&&H.validateNestedEach===void 0)H.validateNestedEach=j.validateNestedEach}}return X}function y(Q,J,$,X){let Y=N(Q);if(Y._isAsync)return Y._deserialize(J,$).then((q)=>{if(HJ(q))return K(q.data);return X(q)});let B=Y._deserialize(J,$);if(HJ(B))return K(B.data);return X(B)}function nJ(Q,J,$){return y(Q,J,$,(X)=>X)}function mJ(Q,...J){if(typeof Q==="function"&&J.length>=1){let $=J[0];if(!($!=null&&typeof $==="function"&&("emit"in $)&&("ruleName"in $)))return y(Q,$,J[1],()=>!0)}return cJ(Q,J)}function cJ(Q,J){if(J.some((Y)=>Y.isAsync))return oJ(Q,J);let X=[];for(let Y of J)if(!Y(Q))X.push({path:"",code:Y.ruleName});return X.length?K(X):!0}async function oJ(Q,J){let $=[];for(let X of J)if(!await X(Q))$.push({path:"",code:X.ruleName});return $.length?K($):!0}function iJ(Q,J){if(Q==null||typeof Q!=="object")throw new O("serialize: expected a class instance, got "+(Q===null?"null":typeof Q));let $=Q.constructor;if(typeof $!=="function")throw new O("serialize: instance has no constructor");let X=N($);if(X._isSerializeAsync)return X._serialize(Q,J);return X._serialize(Q,J)}function lJ(Q,J){let $=typeof Q==="string"?Q:Q.name,X=typeof Q==="string"?J:Q.validate,Y=typeof Q==="object"?Q.constraints:void 0,B=typeof Q==="object"?Q.requiresType:void 0,q=b(X),Z=function(M){return X(M)};if(Z.emit=function(M,F){let H=F.addRef(X);if(q)return`if(!(await _refs[${H}](${M}))) ${F.fail($)};`;return`if(!_refs[${H}](${M})) ${F.fail($)};`},Z.ruleName=$,Z.isAsync=q,Y)Z.constraints=Y;if(B)Z.requiresType=B;return Z}export{mJ as validate,iJ as serialize,WJ as isBakerError,nJ as deserialize,lJ as createRule,LJ as configure,dJ as arrayOf,O as SealError,sJ as Field};
1
+ // Public API — Core
2
+ export { deserialize, deserializeSync, deserializeAsync } from './src/functions/deserialize.js';
3
+ export { validate, validateSync, validateAsync } from './src/functions/validate.js';
4
+ export { serialize, serializeSync, serializeAsync } from './src/functions/serialize.js';
5
+ export { configure } from './src/configure.js';
6
+ export { createRule } from './src/create-rule.js';
7
+ export { seal } from './src/seal/seal.js';
8
+ // Decorators
9
+ export { Field, arrayOf, Recipe } from './src/decorators/index.js';
10
+ export { isBakerIssueSet, BakerError } from './src/errors.js';