@nekostack/schema 1.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 (214) hide show
  1. package/CHANGELOG.md +422 -0
  2. package/LICENSE +202 -0
  3. package/README.md +656 -0
  4. package/dist/src/builders/array.d.ts +12 -0
  5. package/dist/src/builders/array.d.ts.map +1 -0
  6. package/dist/src/builders/array.js +29 -0
  7. package/dist/src/builders/array.js.map +1 -0
  8. package/dist/src/builders/object.d.ts +62 -0
  9. package/dist/src/builders/object.d.ts.map +1 -0
  10. package/dist/src/builders/object.js +263 -0
  11. package/dist/src/builders/object.js.map +1 -0
  12. package/dist/src/builders/primitives.d.ts +37 -0
  13. package/dist/src/builders/primitives.d.ts.map +1 -0
  14. package/dist/src/builders/primitives.js +125 -0
  15. package/dist/src/builders/primitives.js.map +1 -0
  16. package/dist/src/builders/s.d.ts +27 -0
  17. package/dist/src/builders/s.d.ts.map +1 -0
  18. package/dist/src/builders/s.js +39 -0
  19. package/dist/src/builders/s.js.map +1 -0
  20. package/dist/src/builders/schema.d.ts +70 -0
  21. package/dist/src/builders/schema.d.ts.map +1 -0
  22. package/dist/src/builders/schema.js +98 -0
  23. package/dist/src/builders/schema.js.map +1 -0
  24. package/dist/src/cli-integration.d.ts +43 -0
  25. package/dist/src/cli-integration.d.ts.map +1 -0
  26. package/dist/src/cli-integration.js +48 -0
  27. package/dist/src/cli-integration.js.map +1 -0
  28. package/dist/src/errors/issue.d.ts +34 -0
  29. package/dist/src/errors/issue.d.ts.map +1 -0
  30. package/dist/src/errors/issue.js +89 -0
  31. package/dist/src/errors/issue.js.map +1 -0
  32. package/dist/src/generators/errors.d.ts +31 -0
  33. package/dist/src/generators/errors.d.ts.map +1 -0
  34. package/dist/src/generators/errors.js +34 -0
  35. package/dist/src/generators/errors.js.map +1 -0
  36. package/dist/src/generators/header.d.ts +42 -0
  37. package/dist/src/generators/header.d.ts.map +1 -0
  38. package/dist/src/generators/header.js +43 -0
  39. package/dist/src/generators/header.js.map +1 -0
  40. package/dist/src/generators/json-schema-meta.d.ts +36 -0
  41. package/dist/src/generators/json-schema-meta.d.ts.map +1 -0
  42. package/dist/src/generators/json-schema-meta.js +35 -0
  43. package/dist/src/generators/json-schema-meta.js.map +1 -0
  44. package/dist/src/generators/json-schema.d.ts +26 -0
  45. package/dist/src/generators/json-schema.d.ts.map +1 -0
  46. package/dist/src/generators/json-schema.js +88 -0
  47. package/dist/src/generators/json-schema.js.map +1 -0
  48. package/dist/src/generators/openapi.d.ts +33 -0
  49. package/dist/src/generators/openapi.d.ts.map +1 -0
  50. package/dist/src/generators/openapi.js +61 -0
  51. package/dist/src/generators/openapi.js.map +1 -0
  52. package/dist/src/generators/schema-fragment.d.ts +55 -0
  53. package/dist/src/generators/schema-fragment.d.ts.map +1 -0
  54. package/dist/src/generators/schema-fragment.js +253 -0
  55. package/dist/src/generators/schema-fragment.js.map +1 -0
  56. package/dist/src/generators/ts.d.ts +19 -0
  57. package/dist/src/generators/ts.d.ts.map +1 -0
  58. package/dist/src/generators/ts.js +252 -0
  59. package/dist/src/generators/ts.js.map +1 -0
  60. package/dist/src/generators/types.d.ts +96 -0
  61. package/dist/src/generators/types.d.ts.map +1 -0
  62. package/dist/src/generators/types.js +10 -0
  63. package/dist/src/generators/types.js.map +1 -0
  64. package/dist/src/generators/version.d.ts +11 -0
  65. package/dist/src/generators/version.d.ts.map +1 -0
  66. package/dist/src/generators/version.js +11 -0
  67. package/dist/src/generators/version.js.map +1 -0
  68. package/dist/src/generators/zod-mapping.d.ts +90 -0
  69. package/dist/src/generators/zod-mapping.d.ts.map +1 -0
  70. package/dist/src/generators/zod-mapping.js +174 -0
  71. package/dist/src/generators/zod-mapping.js.map +1 -0
  72. package/dist/src/generators/zod.d.ts +17 -0
  73. package/dist/src/generators/zod.d.ts.map +1 -0
  74. package/dist/src/generators/zod.js +118 -0
  75. package/dist/src/generators/zod.js.map +1 -0
  76. package/dist/src/index.d.ts +21 -0
  77. package/dist/src/index.d.ts.map +1 -0
  78. package/dist/src/index.js +43 -0
  79. package/dist/src/index.js.map +1 -0
  80. package/dist/src/ir/hash.d.ts +19 -0
  81. package/dist/src/ir/hash.d.ts.map +1 -0
  82. package/dist/src/ir/hash.js +22 -0
  83. package/dist/src/ir/hash.js.map +1 -0
  84. package/dist/src/ir/nodes.d.ts +121 -0
  85. package/dist/src/ir/nodes.d.ts.map +1 -0
  86. package/dist/src/ir/nodes.js +14 -0
  87. package/dist/src/ir/nodes.js.map +1 -0
  88. package/dist/src/ir/serialize.d.ts +8 -0
  89. package/dist/src/ir/serialize.d.ts.map +1 -0
  90. package/dist/src/ir/serialize.js +23 -0
  91. package/dist/src/ir/serialize.js.map +1 -0
  92. package/dist/src/migrations/build-migration-registry.d.ts +46 -0
  93. package/dist/src/migrations/build-migration-registry.d.ts.map +1 -0
  94. package/dist/src/migrations/build-migration-registry.js +134 -0
  95. package/dist/src/migrations/build-migration-registry.js.map +1 -0
  96. package/dist/src/migrations/handlers/list.d.ts +35 -0
  97. package/dist/src/migrations/handlers/list.d.ts.map +1 -0
  98. package/dist/src/migrations/handlers/list.js +55 -0
  99. package/dist/src/migrations/handlers/list.js.map +1 -0
  100. package/dist/src/migrations/handlers/plan.d.ts +26 -0
  101. package/dist/src/migrations/handlers/plan.d.ts.map +1 -0
  102. package/dist/src/migrations/handlers/plan.js +28 -0
  103. package/dist/src/migrations/handlers/plan.js.map +1 -0
  104. package/dist/src/migrations/handlers/stub.d.ts +22 -0
  105. package/dist/src/migrations/handlers/stub.d.ts.map +1 -0
  106. package/dist/src/migrations/handlers/stub.js +24 -0
  107. package/dist/src/migrations/handlers/stub.js.map +1 -0
  108. package/dist/src/migrations/handlers/verify.d.ts +25 -0
  109. package/dist/src/migrations/handlers/verify.d.ts.map +1 -0
  110. package/dist/src/migrations/handlers/verify.js +27 -0
  111. package/dist/src/migrations/handlers/verify.js.map +1 -0
  112. package/dist/src/migrations/parse-provenance.d.ts +78 -0
  113. package/dist/src/migrations/parse-provenance.d.ts.map +1 -0
  114. package/dist/src/migrations/parse-provenance.js +157 -0
  115. package/dist/src/migrations/parse-provenance.js.map +1 -0
  116. package/dist/src/migrations/plan-migration.d.ts +50 -0
  117. package/dist/src/migrations/plan-migration.d.ts.map +1 -0
  118. package/dist/src/migrations/plan-migration.js +256 -0
  119. package/dist/src/migrations/plan-migration.js.map +1 -0
  120. package/dist/src/migrations/stub.d.ts +55 -0
  121. package/dist/src/migrations/stub.d.ts.map +1 -0
  122. package/dist/src/migrations/stub.js +201 -0
  123. package/dist/src/migrations/stub.js.map +1 -0
  124. package/dist/src/migrations/types.d.ts +297 -0
  125. package/dist/src/migrations/types.d.ts.map +1 -0
  126. package/dist/src/migrations/types.js +28 -0
  127. package/dist/src/migrations/types.js.map +1 -0
  128. package/dist/src/migrations/verify-provenance.d.ts +46 -0
  129. package/dist/src/migrations/verify-provenance.d.ts.map +1 -0
  130. package/dist/src/migrations/verify-provenance.js +158 -0
  131. package/dist/src/migrations/verify-provenance.js.map +1 -0
  132. package/dist/src/registry/build-registry.d.ts +65 -0
  133. package/dist/src/registry/build-registry.d.ts.map +1 -0
  134. package/dist/src/registry/build-registry.js +172 -0
  135. package/dist/src/registry/build-registry.js.map +1 -0
  136. package/dist/src/registry/diff.d.ts +25 -0
  137. package/dist/src/registry/diff.d.ts.map +1 -0
  138. package/dist/src/registry/diff.js +497 -0
  139. package/dist/src/registry/diff.js.map +1 -0
  140. package/dist/src/registry/handlers/check.d.ts +57 -0
  141. package/dist/src/registry/handlers/check.d.ts.map +1 -0
  142. package/dist/src/registry/handlers/check.js +181 -0
  143. package/dist/src/registry/handlers/check.js.map +1 -0
  144. package/dist/src/registry/handlers/diff.d.ts +33 -0
  145. package/dist/src/registry/handlers/diff.d.ts.map +1 -0
  146. package/dist/src/registry/handlers/diff.js +61 -0
  147. package/dist/src/registry/handlers/diff.js.map +1 -0
  148. package/dist/src/registry/handlers/generate.d.ts +87 -0
  149. package/dist/src/registry/handlers/generate.d.ts.map +1 -0
  150. package/dist/src/registry/handlers/generate.js +223 -0
  151. package/dist/src/registry/handlers/generate.js.map +1 -0
  152. package/dist/src/registry/handlers/list.d.ts +36 -0
  153. package/dist/src/registry/handlers/list.d.ts.map +1 -0
  154. package/dist/src/registry/handlers/list.js +84 -0
  155. package/dist/src/registry/handlers/list.js.map +1 -0
  156. package/dist/src/registry/parse-provenance.d.ts +63 -0
  157. package/dist/src/registry/parse-provenance.d.ts.map +1 -0
  158. package/dist/src/registry/parse-provenance.js +182 -0
  159. package/dist/src/registry/parse-provenance.js.map +1 -0
  160. package/dist/src/registry/source-hash.d.ts +28 -0
  161. package/dist/src/registry/source-hash.d.ts.map +1 -0
  162. package/dist/src/registry/source-hash.js +32 -0
  163. package/dist/src/registry/source-hash.js.map +1 -0
  164. package/dist/src/registry/types.d.ts +185 -0
  165. package/dist/src/registry/types.d.ts.map +1 -0
  166. package/dist/src/registry/types.js +22 -0
  167. package/dist/src/registry/types.js.map +1 -0
  168. package/dist/src/runtime/compile.d.ts +38 -0
  169. package/dist/src/runtime/compile.d.ts.map +1 -0
  170. package/dist/src/runtime/compile.js +45 -0
  171. package/dist/src/runtime/compile.js.map +1 -0
  172. package/dist/src/runtime/errors.d.ts +25 -0
  173. package/dist/src/runtime/errors.d.ts.map +1 -0
  174. package/dist/src/runtime/errors.js +43 -0
  175. package/dist/src/runtime/errors.js.map +1 -0
  176. package/dist/src/runtime/normalize-issues.d.ts +65 -0
  177. package/dist/src/runtime/normalize-issues.d.ts.map +1 -0
  178. package/dist/src/runtime/normalize-issues.js +208 -0
  179. package/dist/src/runtime/normalize-issues.js.map +1 -0
  180. package/dist/src/runtime/parse.d.ts +62 -0
  181. package/dist/src/runtime/parse.d.ts.map +1 -0
  182. package/dist/src/runtime/parse.js +107 -0
  183. package/dist/src/runtime/parse.js.map +1 -0
  184. package/dist/src/runtime/strip-defaults.d.ts +51 -0
  185. package/dist/src/runtime/strip-defaults.d.ts.map +1 -0
  186. package/dist/src/runtime/strip-defaults.js +81 -0
  187. package/dist/src/runtime/strip-defaults.js.map +1 -0
  188. package/dist/src/runtime/zod-compile.d.ts +27 -0
  189. package/dist/src/runtime/zod-compile.d.ts.map +1 -0
  190. package/dist/src/runtime/zod-compile.js +92 -0
  191. package/dist/src/runtime/zod-compile.js.map +1 -0
  192. package/dist/src/types.d.ts +116 -0
  193. package/dist/src/types.d.ts.map +1 -0
  194. package/dist/src/types.js +2 -0
  195. package/dist/src/types.js.map +1 -0
  196. package/docs/ABSENCE_SEMANTICS.md +37 -0
  197. package/docs/BENCHMARKS.md +64 -0
  198. package/docs/COMPOSITION.md +206 -0
  199. package/docs/DIFF_CLASSIFICATION.md +137 -0
  200. package/docs/EXAMPLES.md +221 -0
  201. package/docs/HEADER_FORMAT.md +66 -0
  202. package/docs/INVARIANTS.md +58 -0
  203. package/docs/IR_CONTRACT.md +67 -0
  204. package/docs/ISSUE_CODES.md +99 -0
  205. package/docs/JSON_SCHEMA_MAPPING.md +149 -0
  206. package/docs/MIGRATIONS.md +406 -0
  207. package/docs/MIGRATION_GUIDE.md +150 -0
  208. package/docs/OPENAPI_MAPPING.md +66 -0
  209. package/docs/REGISTRY.md +336 -0
  210. package/docs/RUNTIME.md +279 -0
  211. package/docs/SCOPE.md +119 -0
  212. package/docs/USAGE.md +376 -0
  213. package/docs/ZOD_MODIFIER_ORDERING.md +77 -0
  214. package/package.json +45 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Validate-only IR variant (Decision #8 of v0.6 plan).
3
+ *
4
+ * `stripDefaultsForValidate(node)` produces a new `SchemaNode` tree
5
+ * with every default-bearing modifier removed and `optional: true`
6
+ * set at that same level. The original IR is not mutated (the builder
7
+ * deep-freezes the IR; this transform is non-destructive by
8
+ * construction).
9
+ *
10
+ * **Why both at once.** Per v0.1 (Invariant 4 + the absence-semantics
11
+ * table), `default(v)` means *input-optional + output-required* — a
12
+ * missing default-bearing field is a valid input. So `validate` (which
13
+ * returns `Result<s.input<S>>`, no fill) must (a) accept the absence,
14
+ * which means flipping `optional: true`, and (b) NOT fill the default
15
+ * value, which means dropping the `default` modifier. The combined
16
+ * "strip default + flip to optional" is the only rule consistent with
17
+ * both halves of the v0.1 absence-semantics contract for the validate
18
+ * path.
19
+ *
20
+ * **What stays.** `nullable` / `nullish` modifiers, refinements,
21
+ * metadata (`id`, `version`, `description`, `deprecated`), and every
22
+ * field's `unknownKeys` policy are preserved verbatim. This is a
23
+ * runtime compilation variant of the same schema, not a composition
24
+ * operation — schema-level identity (id / version / description) may
25
+ * matter for issue normalization downstream.
26
+ *
27
+ * **Recursion.** Object fields and array elements are walked
28
+ * recursively. Other composite kinds (`union`, `transform`,
29
+ * `recursiveRef`, `date`) are passed through unchanged here; the
30
+ * compile layer (`runtime/compile.ts` → `runtime/zod-compile.ts`)
31
+ * throws `UnsupportedNodeKindError` for those, so the strip transform
32
+ * does not need to gate them itself.
33
+ *
34
+ * The returned tree has different object identity from the original
35
+ * for every level that was touched. The compile cache keys on
36
+ * `SchemaNode` identity (Decision #7), so the validate variant is
37
+ * cached on its own slot automatically — no second `WeakMap` is
38
+ * needed at this layer.
39
+ */
40
+ import type { SchemaNode } from "../ir/nodes.js";
41
+ /**
42
+ * Return a new `SchemaNode` tree suitable for `validate`. For every
43
+ * default-bearing modifier in the tree:
44
+ * - drops `modifiers.default`
45
+ * - sets `modifiers.optional = true` at that same level
46
+ *
47
+ * Leaves `nullable` / `nullish`, refinements, metadata, and
48
+ * unrelated fields untouched. Does not mutate the input.
49
+ */
50
+ export declare function stripDefaultsForValidate(node: SchemaNode): SchemaNode;
51
+ //# sourceMappingURL=strip-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strip-defaults.d.ts","sourceRoot":"","sources":["../../../src/runtime/strip-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAGV,UAAU,EACX,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAGrE"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Validate-only IR variant (Decision #8 of v0.6 plan).
3
+ *
4
+ * `stripDefaultsForValidate(node)` produces a new `SchemaNode` tree
5
+ * with every default-bearing modifier removed and `optional: true`
6
+ * set at that same level. The original IR is not mutated (the builder
7
+ * deep-freezes the IR; this transform is non-destructive by
8
+ * construction).
9
+ *
10
+ * **Why both at once.** Per v0.1 (Invariant 4 + the absence-semantics
11
+ * table), `default(v)` means *input-optional + output-required* — a
12
+ * missing default-bearing field is a valid input. So `validate` (which
13
+ * returns `Result<s.input<S>>`, no fill) must (a) accept the absence,
14
+ * which means flipping `optional: true`, and (b) NOT fill the default
15
+ * value, which means dropping the `default` modifier. The combined
16
+ * "strip default + flip to optional" is the only rule consistent with
17
+ * both halves of the v0.1 absence-semantics contract for the validate
18
+ * path.
19
+ *
20
+ * **What stays.** `nullable` / `nullish` modifiers, refinements,
21
+ * metadata (`id`, `version`, `description`, `deprecated`), and every
22
+ * field's `unknownKeys` policy are preserved verbatim. This is a
23
+ * runtime compilation variant of the same schema, not a composition
24
+ * operation — schema-level identity (id / version / description) may
25
+ * matter for issue normalization downstream.
26
+ *
27
+ * **Recursion.** Object fields and array elements are walked
28
+ * recursively. Other composite kinds (`union`, `transform`,
29
+ * `recursiveRef`, `date`) are passed through unchanged here; the
30
+ * compile layer (`runtime/compile.ts` → `runtime/zod-compile.ts`)
31
+ * throws `UnsupportedNodeKindError` for those, so the strip transform
32
+ * does not need to gate them itself.
33
+ *
34
+ * The returned tree has different object identity from the original
35
+ * for every level that was touched. The compile cache keys on
36
+ * `SchemaNode` identity (Decision #7), so the validate variant is
37
+ * cached on its own slot automatically — no second `WeakMap` is
38
+ * needed at this layer.
39
+ */
40
+ /**
41
+ * Return a new `SchemaNode` tree suitable for `validate`. For every
42
+ * default-bearing modifier in the tree:
43
+ * - drops `modifiers.default`
44
+ * - sets `modifiers.optional = true` at that same level
45
+ *
46
+ * Leaves `nullable` / `nullish`, refinements, metadata, and
47
+ * unrelated fields untouched. Does not mutate the input.
48
+ */
49
+ export function stripDefaultsForValidate(node) {
50
+ const recursed = recurseChildren(node);
51
+ return stripOwnDefault(recursed);
52
+ }
53
+ function recurseChildren(node) {
54
+ if (node.kind === "array") {
55
+ const arr = node;
56
+ const stripped = stripDefaultsForValidate(arr.element);
57
+ return { ...arr, element: stripped };
58
+ }
59
+ if (node.kind === "object") {
60
+ const obj = node;
61
+ const nextFields = {};
62
+ for (const [key, child] of Object.entries(obj.fields)) {
63
+ nextFields[key] = stripDefaultsForValidate(child);
64
+ }
65
+ return { ...obj, fields: nextFields };
66
+ }
67
+ return node;
68
+ }
69
+ function stripOwnDefault(node) {
70
+ const mods = node.modifiers;
71
+ if (!mods?.default)
72
+ return node;
73
+ // Drop `default`, force `optional: true`. Preserve `nullable` (and
74
+ // therefore `nullish`, which is `optional + nullable`).
75
+ const { default: _dropped, ...rest } = mods;
76
+ return {
77
+ ...node,
78
+ modifiers: { ...rest, optional: true },
79
+ };
80
+ }
81
+ //# sourceMappingURL=strip-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strip-defaults.js","sourceRoot":"","sources":["../../../src/runtime/strip-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAQH;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAgB;IACvD,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,eAAe,CAAC,IAAgB;IACvC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAiB,CAAC;QAC9B,MAAM,QAAQ,GAAG,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvD,OAAO,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IACvC,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAkB,CAAC;QAC/B,MAAM,UAAU,GAA+B,EAAE,CAAC;QAClD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACtD,UAAU,CAAC,GAAG,CAAC,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,IAAgB;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;IAC5B,IAAI,CAAC,IAAI,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC;IAChC,mEAAmE;IACnE,wDAAwD;IACxD,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAC5C,OAAO;QACL,GAAG,IAAI;QACP,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KACzB,CAAC;AAClB,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Runtime Zod compiler — value consumer of the shared semantic mapping
3
+ * in `src/generators/zod-mapping.ts`.
4
+ *
5
+ * Produces a live `ZodTypeAny` from a `SchemaNode`. Used by
6
+ * `parse` / `safeParse` / `validate` (lands in subsequent commits).
7
+ *
8
+ * **No source involvement.** This consumer never parses generated
9
+ * source text; the source generator (`src/generators/zod.ts`) never
10
+ * stringifies a compiled value. Their only shared surface is the
11
+ * `ZodEmitter` interface and the traversal order in `zod-mapping.ts`.
12
+ *
13
+ * No caching at this layer — the per-`SchemaNode` `WeakMap` lives in
14
+ * `runtime/compile.ts` (next commit). Repeated calls here re-build.
15
+ */
16
+ import { type ZodTypeAny } from "zod";
17
+ import type { SchemaNode } from "../ir/nodes.js";
18
+ /**
19
+ * Compile an IR `SchemaNode` into a live Zod schema.
20
+ *
21
+ * Same semantic mapping and modifier ordering as `generateZod`; differs
22
+ * only in producing a `ZodTypeAny` value instead of TypeScript source.
23
+ */
24
+ export declare function compileZodSchema(node: SchemaNode): ZodTypeAny;
25
+ /** Alias matching the v0.6 plan's naming. */
26
+ export declare const irToZodSchema: typeof compileZodSchema;
27
+ //# sourceMappingURL=zod-compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-compile.d.ts","sourceRoot":"","sources":["../../../src/runtime/zod-compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAK,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AACzC,OAAO,KAAK,EAAa,UAAU,EAAqB,MAAM,gBAAgB,CAAC;AAG/E;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAE7D;AAED,6CAA6C;AAC7C,eAAO,MAAM,aAAa,yBAAmB,CAAC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Runtime Zod compiler — value consumer of the shared semantic mapping
3
+ * in `src/generators/zod-mapping.ts`.
4
+ *
5
+ * Produces a live `ZodTypeAny` from a `SchemaNode`. Used by
6
+ * `parse` / `safeParse` / `validate` (lands in subsequent commits).
7
+ *
8
+ * **No source involvement.** This consumer never parses generated
9
+ * source text; the source generator (`src/generators/zod.ts`) never
10
+ * stringifies a compiled value. Their only shared surface is the
11
+ * `ZodEmitter` interface and the traversal order in `zod-mapping.ts`.
12
+ *
13
+ * No caching at this layer — the per-`SchemaNode` `WeakMap` lives in
14
+ * `runtime/compile.ts` (next commit). Repeated calls here re-build.
15
+ */
16
+ import { z } from "zod";
17
+ import { emit } from "../generators/zod-mapping.js";
18
+ /**
19
+ * Compile an IR `SchemaNode` into a live Zod schema.
20
+ *
21
+ * Same semantic mapping and modifier ordering as `generateZod`; differs
22
+ * only in producing a `ZodTypeAny` value instead of TypeScript source.
23
+ */
24
+ export function compileZodSchema(node) {
25
+ return emit(node, /*depth*/ 0, valueEmitter);
26
+ }
27
+ /** Alias matching the v0.6 plan's naming. */
28
+ export const irToZodSchema = compileZodSchema;
29
+ const valueEmitter = {
30
+ stringBase: () => z.string(),
31
+ numberBase: () => z.number(),
32
+ booleanBase: () => z.boolean(),
33
+ literalBase: (value) => z.literal(value),
34
+ enumStringsBase: (values) => {
35
+ // z.enum requires a non-empty tuple; the shared traversal guarantees
36
+ // length >= 1 by the time it reaches here.
37
+ return z.enum(values);
38
+ },
39
+ enumSingleLiteralBase: (value) => z.literal(value),
40
+ enumUnionBase: (values) => {
41
+ const options = values.map((v) => z.literal(v));
42
+ // z.union requires at least 2 options — the shared traversal already
43
+ // collapses length === 1 to z.literal via enumSingleLiteralBase.
44
+ return z.union(options);
45
+ },
46
+ arrayBase: (element) => z.array(element),
47
+ objectBase: (fields, _depth) => {
48
+ const shape = {};
49
+ for (const [key, value] of fields)
50
+ shape[key] = value;
51
+ return z.object(shape);
52
+ },
53
+ applyUnknownKeys: (prev, policy) => {
54
+ // Mirror the source generator's explicit-policy emission: every
55
+ // object gets an explicit modifier, no implicit "strip" fallback.
56
+ const obj = prev;
57
+ switch (policy) {
58
+ case "strict":
59
+ return obj.strict();
60
+ case "stripUnknown":
61
+ return obj.strip();
62
+ case "passthrough":
63
+ return obj.passthrough();
64
+ default:
65
+ return assertUnreachable(policy);
66
+ }
67
+ },
68
+ applyMinLength: (prev, value) => prev.min(value),
69
+ applyMaxLength: (prev, value) => prev.max(value),
70
+ applyLength: (prev, value) => prev.length(value),
71
+ applyRegex: (prev, source, flags) => prev.regex(new RegExp(source, flags)),
72
+ applyEmail: (prev) => prev.email(),
73
+ applyUuid: (prev) => prev.uuid(),
74
+ applyUrl: (prev) => prev.url(),
75
+ applyInt: (prev) => prev.int(),
76
+ applyMin: (prev, value) => prev.min(value),
77
+ applyMax: (prev, value) => prev.max(value),
78
+ applyGt: (prev, value) => prev.gt(value),
79
+ applyLt: (prev, value) => prev.lt(value),
80
+ applyMultipleOf: (prev, value) => prev.multipleOf(value),
81
+ applyMinItems: (prev, value) => prev.min(value),
82
+ applyMaxItems: (prev, value) => prev.max(value),
83
+ applyDescribe: (prev, text) => prev.describe(text),
84
+ applyNullable: (prev) => prev.nullable(),
85
+ applyOptional: (prev) => prev.optional(),
86
+ applyNullish: (prev) => prev.nullish(),
87
+ applyDefault: (prev, value) => prev.default(value),
88
+ };
89
+ function assertUnreachable(value) {
90
+ throw new Error(`Unreachable: unknown unknownKeys policy ${String(value)}`);
91
+ }
92
+ //# sourceMappingURL=zod-compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-compile.js","sourceRoot":"","sources":["../../../src/runtime/zod-compile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import type { Schema, AnySchema } from "./builders/schema.js";
2
+ /**
3
+ * Marks how a schema participates in object composition.
4
+ * - "required": object field is `key: T`
5
+ * - "optional": object field is `key?: T`
6
+ *
7
+ * Input and output keys are tracked separately because `.default()` accepts a
8
+ * missing input but produces a required output. See the absence-semantics
9
+ * table in the package README.
10
+ */
11
+ export type ObjectKey = "required" | "optional";
12
+ /** Standard "prettify intersection" trick to make hover types readable. */
13
+ export type Identity<T> = {
14
+ [K in keyof T]: T[K];
15
+ } & {};
16
+ export type Input<S> = S extends Schema<infer I, unknown, ObjectKey, ObjectKey> ? I : never;
17
+ export type Output<S> = S extends Schema<unknown, infer O, ObjectKey, ObjectKey> ? O : never;
18
+ /** `s.infer<T>` resolves to the *output* type — same default as Zod. */
19
+ export type Infer<S> = Output<S>;
20
+ export type RawShape = Record<string, AnySchema>;
21
+ type OptionalInputKeys<S extends RawShape> = {
22
+ [K in keyof S]: S[K] extends Schema<unknown, unknown, "optional", ObjectKey> ? K : never;
23
+ }[keyof S];
24
+ type RequiredInputKeys<S extends RawShape> = Exclude<keyof S, OptionalInputKeys<S>>;
25
+ type OptionalOutputKeys<S extends RawShape> = {
26
+ [K in keyof S]: S[K] extends Schema<unknown, unknown, ObjectKey, "optional"> ? K : never;
27
+ }[keyof S];
28
+ type RequiredOutputKeys<S extends RawShape> = Exclude<keyof S, OptionalOutputKeys<S>>;
29
+ export type InferObjectInput<S extends RawShape> = Identity<{
30
+ [K in RequiredInputKeys<S>]: Input<S[K]>;
31
+ } & {
32
+ [K in OptionalInputKeys<S>]?: Input<S[K]>;
33
+ }>;
34
+ export type InferObjectOutput<S extends RawShape> = Identity<{
35
+ [K in RequiredOutputKeys<S>]: Output<S[K]>;
36
+ } & {
37
+ [K in OptionalOutputKeys<S>]?: Output<S[K]>;
38
+ }>;
39
+ /** `{ key: true }` subset mask over an existing shape. Used by pick/omit/partial/required. */
40
+ export type Mask<S extends RawShape> = {
41
+ [K in keyof S]?: true;
42
+ };
43
+ /**
44
+ * Constraint for `override`. Keys must be a subset of `keyof S`, but VALUES
45
+ * may be any `AnySchema` — `override` exists to replace a field's schema
46
+ * with a different one (e.g., `override({ id: s.number() })` on a previously-
47
+ * string `id`). A `Partial<S>` constraint would force values to keep the old
48
+ * field types and defeat the purpose.
49
+ */
50
+ export type OverrideMask<S extends RawShape> = {
51
+ [K in keyof S]?: AnySchema;
52
+ };
53
+ /** Merge resolution knobs — both default to `"throw"`. See `merge` overloads. */
54
+ export type MergeOptions = {
55
+ conflict?: "throw" | "left" | "right";
56
+ unknownKeys?: "throw" | "left" | "right";
57
+ };
58
+ export type ExtendShape<S extends RawShape, E extends RawShape> = Identity<S & E>;
59
+ export type PickShape<S extends RawShape, M extends Mask<S>> = Identity<{
60
+ [K in keyof S as M[K] extends true ? K : never]: S[K];
61
+ }>;
62
+ export type OmitShape<S extends RawShape, M extends Mask<S>> = Identity<{
63
+ [K in keyof S as M[K] extends true ? never : K]: S[K];
64
+ }>;
65
+ /**
66
+ * Decision #6 + #15: `partial()` sets the field's TInputKey AND TOutputKey
67
+ * to "optional" and widens TInput/TOutput to include `undefined`. Mirrors
68
+ * what `.optional()` does on Schema at the type level. Default-stripping
69
+ * happens at the IR layer; it's not visible in the type because v0.1
70
+ * `default()` already sets `_outputKey: "required"` while v0.5 `partial`
71
+ * forces it to `"optional"`.
72
+ */
73
+ type PartialField<F> = F extends Schema<infer I, infer O, ObjectKey, ObjectKey> ? Schema<I | undefined, O | undefined, "optional", "optional"> : never;
74
+ export type PartialShape<S extends RawShape> = {
75
+ [K in keyof S]: PartialField<S[K]>;
76
+ };
77
+ export type PartialByShape<S extends RawShape, M extends Mask<S>> = Identity<{
78
+ [K in keyof S]: M[K] extends true ? PartialField<S[K]> : S[K];
79
+ }>;
80
+ /**
81
+ * Decision #8 + #15: `required()` sets both keys to "required" and excludes
82
+ * `undefined` from TInput/TOutput. Default-stripping happens at the IR layer.
83
+ */
84
+ type RequiredField<F> = F extends Schema<infer I, infer O, ObjectKey, ObjectKey> ? Schema<Exclude<I, undefined>, Exclude<O, undefined>, "required", "required"> : never;
85
+ export type RequiredShape<S extends RawShape> = {
86
+ [K in keyof S]: RequiredField<S[K]>;
87
+ };
88
+ export type RequiredByShape<S extends RawShape, M extends Mask<S>> = Identity<{
89
+ [K in keyof S]: M[K] extends true ? RequiredField<S[K]> : S[K];
90
+ }>;
91
+ /**
92
+ * Throw-shape: TS-level intersection of both shapes (`Identity<S & Other>`).
93
+ * Preserves disjoint merges; lets TypeScript surface some conflicts through
94
+ * normal intersection behavior where possible. **Runtime conflict detection
95
+ * is the load-bearing guarantee** — consumers MUST NOT rely on
96
+ * `MergeThrowShape` as the sole conflict detector. Use explicit
97
+ * `conflict: "left" | "right"` on `merge` when intentionally resolving
98
+ * overlaps; let the runtime throw catch the unintended ones.
99
+ *
100
+ * (Original design used a per-key conditional that mapped all overlapping
101
+ * keys to `never`. That broke variance for `ObjectSchema<{...}>` vs.
102
+ * `ObjectSchema<RawShape>` because `RawShape` overlaps with every key. The
103
+ * intersection form preserves variance.)
104
+ */
105
+ export type MergeThrowShape<S extends RawShape, Other extends RawShape> = Identity<S & Other>;
106
+ export type MergeLeftShape<S extends RawShape, Other extends RawShape> = Identity<{
107
+ [K in keyof S | keyof Other]: K extends keyof S ? S[K] : K extends keyof Other ? Other[K] : never;
108
+ }>;
109
+ export type MergeRightShape<S extends RawShape, Other extends RawShape> = Identity<{
110
+ [K in keyof S | keyof Other]: K extends keyof Other ? Other[K] : K extends keyof S ? S[K] : never;
111
+ }>;
112
+ export type OverrideShape<S extends RawShape, O extends OverrideMask<S>> = Identity<{
113
+ [K in keyof S]: K extends keyof O ? O[K] extends AnySchema ? O[K] : S[K] : S[K];
114
+ }>;
115
+ export {};
116
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ # Absence Semantics
2
+
3
+ The single most under-specified part of any schema system. This package pins it.
4
+
5
+ `null` is a value. Missing is the absence of a value. They are different. Conflating them is the most common source of API drift.
6
+
7
+ ## The table
8
+
9
+ | DSL | TypeScript (output) | Runtime accepts | JSON Schema `required`? | OpenAPI `nullable`? |
10
+ |---|---|---|---|---|
11
+ | `s.string()` | `field: string` | string only | yes | no |
12
+ | `s.string().optional()` | `field?: string` | missing or undefined | no | no |
13
+ | `s.string().nullable()` | `field: string \| null` | string or null; missing rejected | yes | yes |
14
+ | `s.string().nullish()` | `field?: string \| null` | missing, undefined, or null | no | yes |
15
+ | `s.string().default("x")` | input `field?: string`; output `field: string` | missing accepted; replaced | no (default emitted) | no |
16
+
17
+ ## Input vs output
18
+
19
+ Critical distinction. The schema's *input* is what `parse`/`validate` accepts; the *output* is what `parse` returns (post-defaults, post-transforms).
20
+
21
+ - `optional()`: input is `T | undefined`, output is `T | undefined`. Object key is optional in *both*.
22
+ - `nullable()`: input is `T | null`, output is `T | null`. Object key is required in *both*.
23
+ - `nullish()`: input is `T | null | undefined`, output is `T | null | undefined`. Object key is optional in *both*.
24
+ - `default(v)`: input is `T | undefined` (object-optional), output is `T` (object-**required** — the default has been applied).
25
+
26
+ ## Why default's asymmetry matters
27
+
28
+ A `default()`-bearing field accepts a missing input, but downstream code receives a fully-populated value. If the output type were also optional, every consumer of `parse(Schema, ...)` would have to defensively check for `undefined` despite the default making that impossible.
29
+
30
+ This is enforced by tracking `TInputKey` and `TOutputKey` as separate type parameters on `Schema` — see [`IR_CONTRACT.md`](./IR_CONTRACT.md).
31
+
32
+ ## Tests that prove this
33
+
34
+ - [`tests/inference.test-d.ts`](../tests/inference.test-d.ts) — `describe("audit User example — proves the absence-semantics contract verbatim")` mirrors this table at the type level.
35
+ - [`tests/builders.test.ts`](../tests/builders.test.ts) — `describe("absence modifiers")` proves the IR modifiers (`optional`, `nullable`, `default`) are encoded correctly.
36
+
37
+ If you change `Schema`'s modifier methods, those tests are the gate. They are deliberately written against the spec table, not against implementation details.
@@ -0,0 +1,64 @@
1
+ # Performance Benchmarks
2
+
3
+ > "High Integrity shouldn't mean High Latency."
4
+
5
+ This document outlines the performance characteristics of `@nekostack/schema` (v0.6+). Because NekoStack introduces an Intermediate Representation (IR) and normalizes all errors into a strict `Issue` vocabulary, a common concern is the overhead this adds on top of the underlying execution engine (Zod).
6
+
7
+ We track these metrics using Vitest's benchmarking suite. The results below are run against a standard "User" schema containing UUIDs, nested objects, and arrays.
8
+
9
+ To run the benchmarks yourself:
10
+ ```bash
11
+ cd packages/schema
12
+ npm run build
13
+ npx vitest bench tests/performance.bench.ts --run
14
+ ```
15
+
16
+ ---
17
+
18
+ ## 1. Runtime Validation Overhead
19
+
20
+ The primary concern for any schema engine is the "Hot Path"—validating incoming API requests or database reads.
21
+
22
+ **NekoStack achieves Near-Native Parity with Zod.**
23
+
24
+ | Operation | Ops/sec (Hz) | Overhead vs Zod | Note |
25
+ |---|---|---|---|
26
+ | `z.safeParse()` (Raw Zod) | ~865,000 | Baseline | The fastest possible path. |
27
+ | `z.parse()` (Raw Zod) | ~833,000 | 1.04x slower | Throws exceptions. |
28
+ | **NekoStack `parse()`** | **~819,000** | **1.06x slower** | Includes WeakMap compile-cache lookup + Issue normalization. |
29
+ | **NekoStack `validate()`** | **~764,000** | **1.13x slower** | Runs the stripped-defaults variant of the schema. |
30
+
31
+ ### The Verdict: S-Tier Performance
32
+ NekoStack adds a mere **~6% overhead** to the hot path (`parse()`) compared to raw Zod `safeParse`.
33
+
34
+ For that 6%, you get:
35
+ 1. Guarantee of structural purity (no Silent Lies).
36
+ 2. Predictable, normalized `IssueCode` arrays instead of Zod's internal error tree.
37
+ 3. The ability to generate TS, OpenAPI, and JSON Schema from the exact same definition.
38
+
39
+ At 800,000+ operations per second, the validation step will **never** be the bottleneck in your web application.
40
+
41
+ ---
42
+
43
+ ## 2. Generator Throughput
44
+
45
+ NekoStack doesn't just parse data; it generates code. Generator speed matters for CI pipelines (`neko schema check`) and local Developer Experience.
46
+
47
+ | Generator | Ops/sec (Hz) | Time per 10k Schemas |
48
+ |---|---|---|
49
+ | `generateZod` | ~92,000 | ~108ms |
50
+ | `generateTypeScript` | ~91,000 | ~110ms |
51
+ | `generateJsonSchema` | ~83,000 | ~120ms |
52
+ | `generateOpenApiSchemaComponent` | ~81,000 | ~122ms |
53
+
54
+ ### The Verdict: Instantaneous Generation
55
+ All four generators operate at >80,000 ops/sec. Generating the entire artifact suite (TS, Zod, OpenAPI, JSON Schema) for a massive 1,000-schema monorepo takes less than **50 milliseconds**.
56
+
57
+ This proves that `neko schema generate` and `neko schema check` will feel completely instantaneous to the developer, and add zero noticeable overhead to CI/CD pipelines.
58
+
59
+ ---
60
+
61
+ ## Conclusion
62
+ `@nekostack/schema` is mathematically proven to be structurally safe (via property-based fuzzing) and empirically proven to be production-fast.
63
+
64
+ You do not have to choose between architecture and latency.