@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.
- package/CHANGELOG.md +422 -0
- package/LICENSE +202 -0
- package/README.md +656 -0
- package/dist/src/builders/array.d.ts +12 -0
- package/dist/src/builders/array.d.ts.map +1 -0
- package/dist/src/builders/array.js +29 -0
- package/dist/src/builders/array.js.map +1 -0
- package/dist/src/builders/object.d.ts +62 -0
- package/dist/src/builders/object.d.ts.map +1 -0
- package/dist/src/builders/object.js +263 -0
- package/dist/src/builders/object.js.map +1 -0
- package/dist/src/builders/primitives.d.ts +37 -0
- package/dist/src/builders/primitives.d.ts.map +1 -0
- package/dist/src/builders/primitives.js +125 -0
- package/dist/src/builders/primitives.js.map +1 -0
- package/dist/src/builders/s.d.ts +27 -0
- package/dist/src/builders/s.d.ts.map +1 -0
- package/dist/src/builders/s.js +39 -0
- package/dist/src/builders/s.js.map +1 -0
- package/dist/src/builders/schema.d.ts +70 -0
- package/dist/src/builders/schema.d.ts.map +1 -0
- package/dist/src/builders/schema.js +98 -0
- package/dist/src/builders/schema.js.map +1 -0
- package/dist/src/cli-integration.d.ts +43 -0
- package/dist/src/cli-integration.d.ts.map +1 -0
- package/dist/src/cli-integration.js +48 -0
- package/dist/src/cli-integration.js.map +1 -0
- package/dist/src/errors/issue.d.ts +34 -0
- package/dist/src/errors/issue.d.ts.map +1 -0
- package/dist/src/errors/issue.js +89 -0
- package/dist/src/errors/issue.js.map +1 -0
- package/dist/src/generators/errors.d.ts +31 -0
- package/dist/src/generators/errors.d.ts.map +1 -0
- package/dist/src/generators/errors.js +34 -0
- package/dist/src/generators/errors.js.map +1 -0
- package/dist/src/generators/header.d.ts +42 -0
- package/dist/src/generators/header.d.ts.map +1 -0
- package/dist/src/generators/header.js +43 -0
- package/dist/src/generators/header.js.map +1 -0
- package/dist/src/generators/json-schema-meta.d.ts +36 -0
- package/dist/src/generators/json-schema-meta.d.ts.map +1 -0
- package/dist/src/generators/json-schema-meta.js +35 -0
- package/dist/src/generators/json-schema-meta.js.map +1 -0
- package/dist/src/generators/json-schema.d.ts +26 -0
- package/dist/src/generators/json-schema.d.ts.map +1 -0
- package/dist/src/generators/json-schema.js +88 -0
- package/dist/src/generators/json-schema.js.map +1 -0
- package/dist/src/generators/openapi.d.ts +33 -0
- package/dist/src/generators/openapi.d.ts.map +1 -0
- package/dist/src/generators/openapi.js +61 -0
- package/dist/src/generators/openapi.js.map +1 -0
- package/dist/src/generators/schema-fragment.d.ts +55 -0
- package/dist/src/generators/schema-fragment.d.ts.map +1 -0
- package/dist/src/generators/schema-fragment.js +253 -0
- package/dist/src/generators/schema-fragment.js.map +1 -0
- package/dist/src/generators/ts.d.ts +19 -0
- package/dist/src/generators/ts.d.ts.map +1 -0
- package/dist/src/generators/ts.js +252 -0
- package/dist/src/generators/ts.js.map +1 -0
- package/dist/src/generators/types.d.ts +96 -0
- package/dist/src/generators/types.d.ts.map +1 -0
- package/dist/src/generators/types.js +10 -0
- package/dist/src/generators/types.js.map +1 -0
- package/dist/src/generators/version.d.ts +11 -0
- package/dist/src/generators/version.d.ts.map +1 -0
- package/dist/src/generators/version.js +11 -0
- package/dist/src/generators/version.js.map +1 -0
- package/dist/src/generators/zod-mapping.d.ts +90 -0
- package/dist/src/generators/zod-mapping.d.ts.map +1 -0
- package/dist/src/generators/zod-mapping.js +174 -0
- package/dist/src/generators/zod-mapping.js.map +1 -0
- package/dist/src/generators/zod.d.ts +17 -0
- package/dist/src/generators/zod.d.ts.map +1 -0
- package/dist/src/generators/zod.js +118 -0
- package/dist/src/generators/zod.js.map +1 -0
- package/dist/src/index.d.ts +21 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +43 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/ir/hash.d.ts +19 -0
- package/dist/src/ir/hash.d.ts.map +1 -0
- package/dist/src/ir/hash.js +22 -0
- package/dist/src/ir/hash.js.map +1 -0
- package/dist/src/ir/nodes.d.ts +121 -0
- package/dist/src/ir/nodes.d.ts.map +1 -0
- package/dist/src/ir/nodes.js +14 -0
- package/dist/src/ir/nodes.js.map +1 -0
- package/dist/src/ir/serialize.d.ts +8 -0
- package/dist/src/ir/serialize.d.ts.map +1 -0
- package/dist/src/ir/serialize.js +23 -0
- package/dist/src/ir/serialize.js.map +1 -0
- package/dist/src/migrations/build-migration-registry.d.ts +46 -0
- package/dist/src/migrations/build-migration-registry.d.ts.map +1 -0
- package/dist/src/migrations/build-migration-registry.js +134 -0
- package/dist/src/migrations/build-migration-registry.js.map +1 -0
- package/dist/src/migrations/handlers/list.d.ts +35 -0
- package/dist/src/migrations/handlers/list.d.ts.map +1 -0
- package/dist/src/migrations/handlers/list.js +55 -0
- package/dist/src/migrations/handlers/list.js.map +1 -0
- package/dist/src/migrations/handlers/plan.d.ts +26 -0
- package/dist/src/migrations/handlers/plan.d.ts.map +1 -0
- package/dist/src/migrations/handlers/plan.js +28 -0
- package/dist/src/migrations/handlers/plan.js.map +1 -0
- package/dist/src/migrations/handlers/stub.d.ts +22 -0
- package/dist/src/migrations/handlers/stub.d.ts.map +1 -0
- package/dist/src/migrations/handlers/stub.js +24 -0
- package/dist/src/migrations/handlers/stub.js.map +1 -0
- package/dist/src/migrations/handlers/verify.d.ts +25 -0
- package/dist/src/migrations/handlers/verify.d.ts.map +1 -0
- package/dist/src/migrations/handlers/verify.js +27 -0
- package/dist/src/migrations/handlers/verify.js.map +1 -0
- package/dist/src/migrations/parse-provenance.d.ts +78 -0
- package/dist/src/migrations/parse-provenance.d.ts.map +1 -0
- package/dist/src/migrations/parse-provenance.js +157 -0
- package/dist/src/migrations/parse-provenance.js.map +1 -0
- package/dist/src/migrations/plan-migration.d.ts +50 -0
- package/dist/src/migrations/plan-migration.d.ts.map +1 -0
- package/dist/src/migrations/plan-migration.js +256 -0
- package/dist/src/migrations/plan-migration.js.map +1 -0
- package/dist/src/migrations/stub.d.ts +55 -0
- package/dist/src/migrations/stub.d.ts.map +1 -0
- package/dist/src/migrations/stub.js +201 -0
- package/dist/src/migrations/stub.js.map +1 -0
- package/dist/src/migrations/types.d.ts +297 -0
- package/dist/src/migrations/types.d.ts.map +1 -0
- package/dist/src/migrations/types.js +28 -0
- package/dist/src/migrations/types.js.map +1 -0
- package/dist/src/migrations/verify-provenance.d.ts +46 -0
- package/dist/src/migrations/verify-provenance.d.ts.map +1 -0
- package/dist/src/migrations/verify-provenance.js +158 -0
- package/dist/src/migrations/verify-provenance.js.map +1 -0
- package/dist/src/registry/build-registry.d.ts +65 -0
- package/dist/src/registry/build-registry.d.ts.map +1 -0
- package/dist/src/registry/build-registry.js +172 -0
- package/dist/src/registry/build-registry.js.map +1 -0
- package/dist/src/registry/diff.d.ts +25 -0
- package/dist/src/registry/diff.d.ts.map +1 -0
- package/dist/src/registry/diff.js +497 -0
- package/dist/src/registry/diff.js.map +1 -0
- package/dist/src/registry/handlers/check.d.ts +57 -0
- package/dist/src/registry/handlers/check.d.ts.map +1 -0
- package/dist/src/registry/handlers/check.js +181 -0
- package/dist/src/registry/handlers/check.js.map +1 -0
- package/dist/src/registry/handlers/diff.d.ts +33 -0
- package/dist/src/registry/handlers/diff.d.ts.map +1 -0
- package/dist/src/registry/handlers/diff.js +61 -0
- package/dist/src/registry/handlers/diff.js.map +1 -0
- package/dist/src/registry/handlers/generate.d.ts +87 -0
- package/dist/src/registry/handlers/generate.d.ts.map +1 -0
- package/dist/src/registry/handlers/generate.js +223 -0
- package/dist/src/registry/handlers/generate.js.map +1 -0
- package/dist/src/registry/handlers/list.d.ts +36 -0
- package/dist/src/registry/handlers/list.d.ts.map +1 -0
- package/dist/src/registry/handlers/list.js +84 -0
- package/dist/src/registry/handlers/list.js.map +1 -0
- package/dist/src/registry/parse-provenance.d.ts +63 -0
- package/dist/src/registry/parse-provenance.d.ts.map +1 -0
- package/dist/src/registry/parse-provenance.js +182 -0
- package/dist/src/registry/parse-provenance.js.map +1 -0
- package/dist/src/registry/source-hash.d.ts +28 -0
- package/dist/src/registry/source-hash.d.ts.map +1 -0
- package/dist/src/registry/source-hash.js +32 -0
- package/dist/src/registry/source-hash.js.map +1 -0
- package/dist/src/registry/types.d.ts +185 -0
- package/dist/src/registry/types.d.ts.map +1 -0
- package/dist/src/registry/types.js +22 -0
- package/dist/src/registry/types.js.map +1 -0
- package/dist/src/runtime/compile.d.ts +38 -0
- package/dist/src/runtime/compile.d.ts.map +1 -0
- package/dist/src/runtime/compile.js +45 -0
- package/dist/src/runtime/compile.js.map +1 -0
- package/dist/src/runtime/errors.d.ts +25 -0
- package/dist/src/runtime/errors.d.ts.map +1 -0
- package/dist/src/runtime/errors.js +43 -0
- package/dist/src/runtime/errors.js.map +1 -0
- package/dist/src/runtime/normalize-issues.d.ts +65 -0
- package/dist/src/runtime/normalize-issues.d.ts.map +1 -0
- package/dist/src/runtime/normalize-issues.js +208 -0
- package/dist/src/runtime/normalize-issues.js.map +1 -0
- package/dist/src/runtime/parse.d.ts +62 -0
- package/dist/src/runtime/parse.d.ts.map +1 -0
- package/dist/src/runtime/parse.js +107 -0
- package/dist/src/runtime/parse.js.map +1 -0
- package/dist/src/runtime/strip-defaults.d.ts +51 -0
- package/dist/src/runtime/strip-defaults.d.ts.map +1 -0
- package/dist/src/runtime/strip-defaults.js +81 -0
- package/dist/src/runtime/strip-defaults.js.map +1 -0
- package/dist/src/runtime/zod-compile.d.ts +27 -0
- package/dist/src/runtime/zod-compile.d.ts.map +1 -0
- package/dist/src/runtime/zod-compile.js +92 -0
- package/dist/src/runtime/zod-compile.js.map +1 -0
- package/dist/src/types.d.ts +116 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/docs/ABSENCE_SEMANTICS.md +37 -0
- package/docs/BENCHMARKS.md +64 -0
- package/docs/COMPOSITION.md +206 -0
- package/docs/DIFF_CLASSIFICATION.md +137 -0
- package/docs/EXAMPLES.md +221 -0
- package/docs/HEADER_FORMAT.md +66 -0
- package/docs/INVARIANTS.md +58 -0
- package/docs/IR_CONTRACT.md +67 -0
- package/docs/ISSUE_CODES.md +99 -0
- package/docs/JSON_SCHEMA_MAPPING.md +149 -0
- package/docs/MIGRATIONS.md +406 -0
- package/docs/MIGRATION_GUIDE.md +150 -0
- package/docs/OPENAPI_MAPPING.md +66 -0
- package/docs/REGISTRY.md +336 -0
- package/docs/RUNTIME.md +279 -0
- package/docs/SCOPE.md +119 -0
- package/docs/USAGE.md +376 -0
- package/docs/ZOD_MODIFIER_ORDERING.md +77 -0
- package/package.json +45 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Zod semantic mapping (Decision #6 of v0.6 plan).
|
|
3
|
+
*
|
|
4
|
+
* One module owns:
|
|
5
|
+
* - the IR traversal order
|
|
6
|
+
* - the fixed Zod modifier-application order (v0.2 contract — see
|
|
7
|
+
* `docs/ZOD_MODIFIER_ORDERING.md`):
|
|
8
|
+
*
|
|
9
|
+
* 1. base schema
|
|
10
|
+
* 2. portable refinements (IR insertion order)
|
|
11
|
+
* 3. describe
|
|
12
|
+
* 4. nullable / optional / nullish (mutually exclusive)
|
|
13
|
+
* 5. default (LAST)
|
|
14
|
+
*
|
|
15
|
+
* - the rules for empty / single / all-string / mixed enums
|
|
16
|
+
* - the rules for the `unknownKeys` object policy
|
|
17
|
+
*
|
|
18
|
+
* Two consumers realize this mapping into different concrete outputs:
|
|
19
|
+
*
|
|
20
|
+
* - `src/generators/zod.ts` (a `ZodEmitter<string>`) produces the
|
|
21
|
+
* deterministic TypeScript source text. v0.2 snapshot bytes must
|
|
22
|
+
* remain identical after this extraction.
|
|
23
|
+
*
|
|
24
|
+
* - `src/runtime/zod-compile.ts` (a `ZodEmitter<ZodTypeAny>`) produces
|
|
25
|
+
* a live Zod schema value for runtime `parse` / `safeParse` /
|
|
26
|
+
* `validate`.
|
|
27
|
+
*
|
|
28
|
+
* The shared mapping is the contract; neither consumer stringifies the
|
|
29
|
+
* other's output (no `eval`, no source-to-value parsing, no
|
|
30
|
+
* value-to-source serialization).
|
|
31
|
+
*/
|
|
32
|
+
import { UnsupportedNodeKindError } from "./errors.js";
|
|
33
|
+
/**
|
|
34
|
+
* Entry point: walk a `SchemaNode` and produce the consumer's `T`.
|
|
35
|
+
*
|
|
36
|
+
* `depth` is threaded for the string consumer's indentation. Callers
|
|
37
|
+
* outside this module should start at depth 0.
|
|
38
|
+
*/
|
|
39
|
+
export function emit(node, depth, emitter) {
|
|
40
|
+
let expr = emitBase(node, depth, emitter);
|
|
41
|
+
expr = applyPortableRefinements(expr, node.refinements ?? [], emitter);
|
|
42
|
+
expr = applyDescribeStep(expr, node, emitter);
|
|
43
|
+
expr = applyAbsenceModifiers(expr, node, emitter);
|
|
44
|
+
expr = applyDefaultStep(expr, node, emitter);
|
|
45
|
+
return expr;
|
|
46
|
+
}
|
|
47
|
+
function emitBase(node, depth, emitter) {
|
|
48
|
+
switch (node.kind) {
|
|
49
|
+
case "string":
|
|
50
|
+
return emitter.stringBase();
|
|
51
|
+
case "number":
|
|
52
|
+
return emitter.numberBase();
|
|
53
|
+
case "boolean":
|
|
54
|
+
return emitter.booleanBase();
|
|
55
|
+
case "literal":
|
|
56
|
+
return emitter.literalBase(node.value);
|
|
57
|
+
case "enum":
|
|
58
|
+
return emitEnum(node, emitter);
|
|
59
|
+
case "array":
|
|
60
|
+
return emitter.arrayBase(emit(node.element, depth + 1, emitter));
|
|
61
|
+
case "object":
|
|
62
|
+
return emitObject(node, depth, emitter);
|
|
63
|
+
default:
|
|
64
|
+
throw new UnsupportedNodeKindError({
|
|
65
|
+
kind: node.kind,
|
|
66
|
+
generator: "zod",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function emitEnum(node, emitter) {
|
|
71
|
+
// Empty enums should be rejected at the builder (`s.enum`); fail
|
|
72
|
+
// loudly if one ever reaches here so we never emit invalid Zod.
|
|
73
|
+
if (node.values.length === 0) {
|
|
74
|
+
throw new Error("Cannot emit Zod for an empty enum");
|
|
75
|
+
}
|
|
76
|
+
const allStrings = node.values.every((v) => typeof v === "string");
|
|
77
|
+
if (allStrings) {
|
|
78
|
+
return emitter.enumStringsBase(node.values);
|
|
79
|
+
}
|
|
80
|
+
// z.union requires >= 2 options; a single-value mixed/numeric enum
|
|
81
|
+
// collapses to z.literal.
|
|
82
|
+
if (node.values.length === 1) {
|
|
83
|
+
return emitter.enumSingleLiteralBase(node.values[0]);
|
|
84
|
+
}
|
|
85
|
+
return emitter.enumUnionBase(node.values);
|
|
86
|
+
}
|
|
87
|
+
function emitObject(node, depth, emitter) {
|
|
88
|
+
const entries = Object.entries(node.fields).map(([key, field]) => [key, emit(field, depth + 1, emitter)]);
|
|
89
|
+
return emitter.applyUnknownKeys(emitter.objectBase(entries, depth), node.unknownKeys);
|
|
90
|
+
}
|
|
91
|
+
function applyPortableRefinements(expr, refinements, emitter) {
|
|
92
|
+
let out = expr;
|
|
93
|
+
for (const r of refinements) {
|
|
94
|
+
if (r.kind === "runtime") {
|
|
95
|
+
// Invariant 7: fail loudly. Silently dropping a runtime refinement
|
|
96
|
+
// would emit a chain that accepts inputs the IR intends to reject.
|
|
97
|
+
throw new UnsupportedNodeKindError({
|
|
98
|
+
kind: "runtimeRefinement",
|
|
99
|
+
generator: "zod",
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (r.kind !== "portable")
|
|
103
|
+
continue;
|
|
104
|
+
out = applyPortableRefinement(out, r, emitter);
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
function applyPortableRefinement(expr, r, emitter) {
|
|
109
|
+
const params = r.params ?? {};
|
|
110
|
+
switch (r.name) {
|
|
111
|
+
case "minLength":
|
|
112
|
+
return emitter.applyMinLength(expr, numParam(params.value));
|
|
113
|
+
case "maxLength":
|
|
114
|
+
return emitter.applyMaxLength(expr, numParam(params.value));
|
|
115
|
+
case "length":
|
|
116
|
+
return emitter.applyLength(expr, numParam(params.value));
|
|
117
|
+
case "regex":
|
|
118
|
+
return emitter.applyRegex(expr, String(params.source ?? ""), String(params.flags ?? ""));
|
|
119
|
+
case "email":
|
|
120
|
+
return emitter.applyEmail(expr);
|
|
121
|
+
case "uuid":
|
|
122
|
+
return emitter.applyUuid(expr);
|
|
123
|
+
case "url":
|
|
124
|
+
return emitter.applyUrl(expr);
|
|
125
|
+
case "int":
|
|
126
|
+
return emitter.applyInt(expr);
|
|
127
|
+
case "min":
|
|
128
|
+
return emitter.applyMin(expr, numParam(params.value));
|
|
129
|
+
case "max":
|
|
130
|
+
return emitter.applyMax(expr, numParam(params.value));
|
|
131
|
+
case "gt":
|
|
132
|
+
return emitter.applyGt(expr, numParam(params.value));
|
|
133
|
+
case "lt":
|
|
134
|
+
return emitter.applyLt(expr, numParam(params.value));
|
|
135
|
+
case "multipleOf":
|
|
136
|
+
return emitter.applyMultipleOf(expr, numParam(params.value));
|
|
137
|
+
case "minItems":
|
|
138
|
+
return emitter.applyMinItems(expr, numParam(params.value));
|
|
139
|
+
case "maxItems":
|
|
140
|
+
return emitter.applyMaxItems(expr, numParam(params.value));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function applyDescribeStep(expr, node, emitter) {
|
|
144
|
+
const desc = node.metadata?.description;
|
|
145
|
+
if (!desc)
|
|
146
|
+
return expr;
|
|
147
|
+
return emitter.applyDescribe(expr, desc);
|
|
148
|
+
}
|
|
149
|
+
function applyAbsenceModifiers(expr, node, emitter) {
|
|
150
|
+
const mods = node.modifiers ?? {};
|
|
151
|
+
// Mutually exclusive — `.optional().nullable()` would produce a
|
|
152
|
+
// different Zod type than `.nullish()` despite the surface
|
|
153
|
+
// similarity.
|
|
154
|
+
if (mods.optional && mods.nullable)
|
|
155
|
+
return emitter.applyNullish(expr);
|
|
156
|
+
if (mods.nullable)
|
|
157
|
+
return emitter.applyNullable(expr);
|
|
158
|
+
if (mods.optional)
|
|
159
|
+
return emitter.applyOptional(expr);
|
|
160
|
+
return expr;
|
|
161
|
+
}
|
|
162
|
+
function applyDefaultStep(expr, node, emitter) {
|
|
163
|
+
const def = node.modifiers?.default;
|
|
164
|
+
if (!def)
|
|
165
|
+
return expr;
|
|
166
|
+
return emitter.applyDefault(expr, def.value);
|
|
167
|
+
}
|
|
168
|
+
function numParam(value) {
|
|
169
|
+
if (typeof value !== "number") {
|
|
170
|
+
throw new Error(`Expected numeric refinement param, got ${typeof value}`);
|
|
171
|
+
}
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=zod-mapping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-mapping.js","sourceRoot":"","sources":["../../../src/generators/zod-mapping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SchemaNode } from "../ir/nodes.js";
|
|
2
|
+
import type { ZodGeneratorOptions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generate Zod 3.x schema code from a SchemaNode.
|
|
5
|
+
*
|
|
6
|
+
* Output is a complete TS module: header + `import { z } from "zod"` +
|
|
7
|
+
* `export const <name> = <chain>;`.
|
|
8
|
+
*
|
|
9
|
+
* The per-node semantic mapping and modifier-application order live in
|
|
10
|
+
* [`zod-mapping.ts`](./zod-mapping.ts) — see that file's header for the
|
|
11
|
+
* v0.2 modifier-ordering contract. This file is the **string consumer**:
|
|
12
|
+
* it realizes each op as TypeScript source text. The runtime compiler
|
|
13
|
+
* in `src/runtime/zod-compile.ts` is the value consumer. They share
|
|
14
|
+
* the mapping; neither converts the other's output.
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateZod(node: SchemaNode, options?: ZodGeneratorOptions): string;
|
|
17
|
+
//# sourceMappingURL=zod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../../src/generators/zod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,UAAU,EAEX,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGtD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAkBR"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { buildHeader } from "./header.js";
|
|
2
|
+
import { emit } from "./zod-mapping.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generate Zod 3.x schema code from a SchemaNode.
|
|
5
|
+
*
|
|
6
|
+
* Output is a complete TS module: header + `import { z } from "zod"` +
|
|
7
|
+
* `export const <name> = <chain>;`.
|
|
8
|
+
*
|
|
9
|
+
* The per-node semantic mapping and modifier-application order live in
|
|
10
|
+
* [`zod-mapping.ts`](./zod-mapping.ts) — see that file's header for the
|
|
11
|
+
* v0.2 modifier-ordering contract. This file is the **string consumer**:
|
|
12
|
+
* it realizes each op as TypeScript source text. The runtime compiler
|
|
13
|
+
* in `src/runtime/zod-compile.ts` is the value consumer. They share
|
|
14
|
+
* the mapping; neither converts the other's output.
|
|
15
|
+
*/
|
|
16
|
+
export function generateZod(node, options = {}) {
|
|
17
|
+
const constName = options.constName ?? "schema";
|
|
18
|
+
const header = buildHeader(node, {
|
|
19
|
+
generator: "zod",
|
|
20
|
+
...(options.sourceHash !== undefined
|
|
21
|
+
? { sourceHash: options.sourceHash }
|
|
22
|
+
: {}),
|
|
23
|
+
});
|
|
24
|
+
const chain = emit(node, /*depth*/ 0, stringEmitter);
|
|
25
|
+
const doc = emitTopLevelDocComment(node);
|
|
26
|
+
return [
|
|
27
|
+
header,
|
|
28
|
+
"",
|
|
29
|
+
`import { z } from "zod";`,
|
|
30
|
+
"",
|
|
31
|
+
`${doc}export const ${constName} = ${chain};`,
|
|
32
|
+
"",
|
|
33
|
+
].join("\n");
|
|
34
|
+
}
|
|
35
|
+
// ---------- string consumer ----------
|
|
36
|
+
const stringEmitter = {
|
|
37
|
+
stringBase: () => "z.string()",
|
|
38
|
+
numberBase: () => "z.number()",
|
|
39
|
+
booleanBase: () => "z.boolean()",
|
|
40
|
+
literalBase: (value) => `z.literal(${formatJson(value)})`,
|
|
41
|
+
enumStringsBase: (values) => {
|
|
42
|
+
const list = values.map((v) => JSON.stringify(v)).join(", ");
|
|
43
|
+
return `z.enum([${list}] as const)`;
|
|
44
|
+
},
|
|
45
|
+
enumSingleLiteralBase: (value) => `z.literal(${formatJson(value)})`,
|
|
46
|
+
enumUnionBase: (values) => {
|
|
47
|
+
const parts = values.map((v) => `z.literal(${formatJson(v)})`);
|
|
48
|
+
return `z.union([${parts.join(", ")}])`;
|
|
49
|
+
},
|
|
50
|
+
arrayBase: (element) => `z.array(${element})`,
|
|
51
|
+
objectBase: (fields, depth) => {
|
|
52
|
+
if (fields.length === 0)
|
|
53
|
+
return "z.object({})";
|
|
54
|
+
const indent = " ".repeat(depth + 1);
|
|
55
|
+
const closeIndent = " ".repeat(depth);
|
|
56
|
+
const lines = fields.map(([key, value]) => {
|
|
57
|
+
const safeKey = isSafeIdentifier(key) ? key : JSON.stringify(key);
|
|
58
|
+
return `${indent}${safeKey}: ${value},`;
|
|
59
|
+
});
|
|
60
|
+
return `z.object({\n${lines.join("\n")}\n${closeIndent}})`;
|
|
61
|
+
},
|
|
62
|
+
applyUnknownKeys: (prev, policy) => {
|
|
63
|
+
// Zod's default is "strip"; emit the explicit modifier so the
|
|
64
|
+
// generated code is unambiguous about which policy applies.
|
|
65
|
+
switch (policy) {
|
|
66
|
+
case "strict":
|
|
67
|
+
return `${prev}.strict()`;
|
|
68
|
+
case "stripUnknown":
|
|
69
|
+
return `${prev}.strip()`;
|
|
70
|
+
case "passthrough":
|
|
71
|
+
return `${prev}.passthrough()`;
|
|
72
|
+
default:
|
|
73
|
+
return assertUnreachable(policy);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
applyMinLength: (prev, value) => `${prev}.min(${value})`,
|
|
77
|
+
applyMaxLength: (prev, value) => `${prev}.max(${value})`,
|
|
78
|
+
applyLength: (prev, value) => `${prev}.length(${value})`,
|
|
79
|
+
applyRegex: (prev, source, flags) => `${prev}.regex(new RegExp(${JSON.stringify(source)}, ${JSON.stringify(flags)}))`,
|
|
80
|
+
applyEmail: (prev) => `${prev}.email()`,
|
|
81
|
+
applyUuid: (prev) => `${prev}.uuid()`,
|
|
82
|
+
applyUrl: (prev) => `${prev}.url()`,
|
|
83
|
+
applyInt: (prev) => `${prev}.int()`,
|
|
84
|
+
applyMin: (prev, value) => `${prev}.min(${value})`,
|
|
85
|
+
applyMax: (prev, value) => `${prev}.max(${value})`,
|
|
86
|
+
applyGt: (prev, value) => `${prev}.gt(${value})`,
|
|
87
|
+
applyLt: (prev, value) => `${prev}.lt(${value})`,
|
|
88
|
+
applyMultipleOf: (prev, value) => `${prev}.multipleOf(${value})`,
|
|
89
|
+
applyMinItems: (prev, value) => `${prev}.min(${value})`,
|
|
90
|
+
applyMaxItems: (prev, value) => `${prev}.max(${value})`,
|
|
91
|
+
applyDescribe: (prev, text) => `${prev}.describe(${JSON.stringify(text)})`,
|
|
92
|
+
applyNullable: (prev) => `${prev}.nullable()`,
|
|
93
|
+
applyOptional: (prev) => `${prev}.optional()`,
|
|
94
|
+
applyNullish: (prev) => `${prev}.nullish()`,
|
|
95
|
+
applyDefault: (prev, value) => `${prev}.default(${formatJson(value)})`,
|
|
96
|
+
};
|
|
97
|
+
// ---------- string-only helpers ----------
|
|
98
|
+
function emitTopLevelDocComment(node) {
|
|
99
|
+
// `metadata.deprecated` is a source-level JSDoc concern; Zod has no
|
|
100
|
+
// runtime "deprecated" marker, so the runtime value consumer ignores
|
|
101
|
+
// it entirely.
|
|
102
|
+
const lines = [];
|
|
103
|
+
if (node.metadata?.deprecated)
|
|
104
|
+
lines.push("@deprecated");
|
|
105
|
+
if (lines.length === 0)
|
|
106
|
+
return "";
|
|
107
|
+
return `/**\n${lines.map((l) => ` * ${l}`).join("\n")}\n */\n`;
|
|
108
|
+
}
|
|
109
|
+
function formatJson(value) {
|
|
110
|
+
return JSON.stringify(value);
|
|
111
|
+
}
|
|
112
|
+
function isSafeIdentifier(s) {
|
|
113
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(s);
|
|
114
|
+
}
|
|
115
|
+
function assertUnreachable(value) {
|
|
116
|
+
throw new Error(`Unreachable: unknown unknownKeys policy ${String(value)}`);
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=zod.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.js","sourceRoot":"","sources":["../../../src/generators/zod.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { s } from "./builders/s.js";
|
|
2
|
+
export { Schema, type AnySchema } from "./builders/schema.js";
|
|
3
|
+
export type { ArraySchema } from "./builders/array.js";
|
|
4
|
+
export type { ObjectSchema } from "./builders/object.js";
|
|
5
|
+
export type { BooleanSchema, EnumSchema, LiteralSchema, NumberSchema, StringSchema, } from "./builders/primitives.js";
|
|
6
|
+
export type { ArrayNode, BooleanNode, EnumNode, JsonValue, LiteralNode, NumberNode, ObjectNode, SchemaNode, StringNode, } from "./ir/nodes.js";
|
|
7
|
+
export { serializeIR } from "./ir/serialize.js";
|
|
8
|
+
export { irHash } from "./ir/hash.js";
|
|
9
|
+
export { generateTypeScript } from "./generators/ts.js";
|
|
10
|
+
export { generateZod } from "./generators/zod.js";
|
|
11
|
+
export { generateJsonSchema } from "./generators/json-schema.js";
|
|
12
|
+
export { generateOpenApiSchemaComponent } from "./generators/openapi.js";
|
|
13
|
+
export type { GeneratorOptions, JsonSchemaGeneratorOptions, OpenApiGeneratorOptions, TypeScriptGeneratorOptions, ZodGeneratorOptions, } from "./generators/types.js";
|
|
14
|
+
export { GENERATOR_VERSION } from "./generators/version.js";
|
|
15
|
+
export { UnsupportedNodeKindError } from "./generators/errors.js";
|
|
16
|
+
export { ISSUE_CODES, type Issue, type IssueCode, type IssuePath, type Result, } from "./errors/issue.js";
|
|
17
|
+
export type { Infer, Input, Output } from "./types.js";
|
|
18
|
+
export type { Mask, OverrideMask, MergeOptions } from "./types.js";
|
|
19
|
+
export { parse, safeParse, validate } from "./runtime/parse.js";
|
|
20
|
+
export { ParseError } from "./runtime/errors.js";
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAK9D,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EACV,aAAa,EACb,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,GACb,MAAM,0BAA0B,CAAC;AAOlC,YAAY,EACV,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACT,WAAW,EACX,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,GACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAatC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,YAAY,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAGlE,OAAO,EACL,WAAW,EACX,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,MAAM,GACZ,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAQvD,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAWnE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Public API — @nekostack/schema v0.5
|
|
3
|
+
//
|
|
4
|
+
// Surface is intentionally narrow. Anything not re-exported here is package-
|
|
5
|
+
// internal and may change without a major version bump. See docs/SCOPE.md.
|
|
6
|
+
// =============================================================================
|
|
7
|
+
// ---- DSL entry point ----
|
|
8
|
+
export { s } from "./builders/s.js";
|
|
9
|
+
// ---- Base schema (for generic constraints) ----
|
|
10
|
+
export { Schema } from "./builders/schema.js";
|
|
11
|
+
export { serializeIR } from "./ir/serialize.js";
|
|
12
|
+
export { irHash } from "./ir/hash.js";
|
|
13
|
+
// ---- Generators ----
|
|
14
|
+
// Each generator consumes the canonical SchemaNode IR and returns a complete
|
|
15
|
+
// emit-ready artifact as a string. File-writing is intentionally a downstream
|
|
16
|
+
// concern.
|
|
17
|
+
// - generateTypeScript / generateZod emit TS-source artifacts (header
|
|
18
|
+
// comment + body code).
|
|
19
|
+
// - generateJsonSchema / generateOpenApiSchemaComponent emit JSON artifacts
|
|
20
|
+
// (provenance is embedded via the `x-nekostack` extension object — JSON
|
|
21
|
+
// has no comment syntax).
|
|
22
|
+
// See docs/USAGE.md for per-generator details and docs/{HEADER_FORMAT,
|
|
23
|
+
// JSON_SCHEMA_MAPPING, OPENAPI_MAPPING}.md for the per-format contracts.
|
|
24
|
+
export { generateTypeScript } from "./generators/ts.js";
|
|
25
|
+
export { generateZod } from "./generators/zod.js";
|
|
26
|
+
export { generateJsonSchema } from "./generators/json-schema.js";
|
|
27
|
+
export { generateOpenApiSchemaComponent } from "./generators/openapi.js";
|
|
28
|
+
export { GENERATOR_VERSION } from "./generators/version.js";
|
|
29
|
+
export { UnsupportedNodeKindError } from "./generators/errors.js";
|
|
30
|
+
// ---- Errors ----
|
|
31
|
+
export { ISSUE_CODES, } from "./errors/issue.js";
|
|
32
|
+
// ---- Runtime validation (v0.6) ----
|
|
33
|
+
// Three free-function entry points + one error class. See `docs/RUNTIME.md`
|
|
34
|
+
// for the full contract — default semantics, unknown-key policies, issue
|
|
35
|
+
// normalization, the validate-only IR variant, and the engine-swap-safe
|
|
36
|
+
// invariant that keeps Zod internal. The compile cache, the
|
|
37
|
+
// validate-variant cache, the Zod source-vs-runtime semantic mapping, and
|
|
38
|
+
// the `ZodError → Issue[]` normalizer are intentionally NOT re-exported:
|
|
39
|
+
// they are implementation surface that v0.7+ may rework without a major
|
|
40
|
+
// version bump.
|
|
41
|
+
export { parse, safeParse, validate } from "./runtime/parse.js";
|
|
42
|
+
export { ParseError } from "./runtime/errors.js";
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,sCAAsC;AACtC,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,gFAAgF;AAEhF,4BAA4B;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAEpC,kDAAkD;AAClD,OAAO,EAAE,MAAM,EAAkB,MAAM,sBAAsB,CAAC;AAgC9D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,uBAAuB;AACvB,6EAA6E;AAC7E,8EAA8E;AAC9E,WAAW;AACX,wEAAwE;AACxE,4BAA4B;AAC5B,8EAA8E;AAC9E,4EAA4E;AAC5E,8BAA8B;AAC9B,uEAAuE;AACvE,yEAAyE;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAQzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,mBAAmB;AACnB,OAAO,EACL,WAAW,GAKZ,MAAM,mBAAmB,CAAC;AAa3B,sCAAsC;AACtC,4EAA4E;AAC5E,yEAAyE;AACzE,wEAAwE;AACxE,4DAA4D;AAC5D,0EAA0E;AAC1E,yEAAyE;AACzE,wEAAwE;AACxE,gBAAgB;AAChB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SchemaNode } from "./nodes.js";
|
|
2
|
+
/**
|
|
3
|
+
* Stable, content-addressed hash of a SchemaNode's canonical IR. Two
|
|
4
|
+
* structurally identical IRs always produce the same hash; any semantic
|
|
5
|
+
* change to the IR produces a different one.
|
|
6
|
+
*
|
|
7
|
+
* Algorithm: `sha256(serializeIR(node))` over UTF-8 bytes, hex-encoded.
|
|
8
|
+
*
|
|
9
|
+
* Consumed by:
|
|
10
|
+
* - Generated-file headers (v0.2+) — proves a generated artifact was
|
|
11
|
+
* produced from a specific IR.
|
|
12
|
+
* - The v0.7 CLI freshness check — `neko schema check` re-derives the
|
|
13
|
+
* hash from current source and compares against the committed header.
|
|
14
|
+
*
|
|
15
|
+
* This helper deliberately does NOT compute `sourceHash`. That requires
|
|
16
|
+
* knowing the source file (path + bytes), which is a CLI concern.
|
|
17
|
+
*/
|
|
18
|
+
export declare function irHash(node: SchemaNode): string;
|
|
19
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/ir/hash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAE/C"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { serializeIR } from "./serialize.js";
|
|
3
|
+
/**
|
|
4
|
+
* Stable, content-addressed hash of a SchemaNode's canonical IR. Two
|
|
5
|
+
* structurally identical IRs always produce the same hash; any semantic
|
|
6
|
+
* change to the IR produces a different one.
|
|
7
|
+
*
|
|
8
|
+
* Algorithm: `sha256(serializeIR(node))` over UTF-8 bytes, hex-encoded.
|
|
9
|
+
*
|
|
10
|
+
* Consumed by:
|
|
11
|
+
* - Generated-file headers (v0.2+) — proves a generated artifact was
|
|
12
|
+
* produced from a specific IR.
|
|
13
|
+
* - The v0.7 CLI freshness check — `neko schema check` re-derives the
|
|
14
|
+
* hash from current source and compares against the committed header.
|
|
15
|
+
*
|
|
16
|
+
* This helper deliberately does NOT compute `sourceHash`. That requires
|
|
17
|
+
* knowing the source file (path + bytes), which is a CLI concern.
|
|
18
|
+
*/
|
|
19
|
+
export function irHash(node) {
|
|
20
|
+
return createHash("sha256").update(serializeIR(node), "utf8").digest("hex");
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../../src/ir/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,MAAM,CAAC,IAAgB;IACrC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Intermediate Representation for NekoStack schemas.
|
|
3
|
+
*
|
|
4
|
+
* Every builder produces a `SchemaNode`. Generators consume only IR — never
|
|
5
|
+
* builder internals. This is the single contract that prevents drift between
|
|
6
|
+
* the TS, Zod, JSON Schema, and OpenAPI outputs.
|
|
7
|
+
*
|
|
8
|
+
* The IR is JSON-serializable (no functions, no symbols, no class instances).
|
|
9
|
+
* Runtime-only constructs (transforms, custom refinement predicates) are
|
|
10
|
+
* stored as opaque metadata; the registry that owns the predicate is the
|
|
11
|
+
* runtime, not the IR.
|
|
12
|
+
*/
|
|
13
|
+
export type SchemaNode = StringNode | NumberNode | BooleanNode | DateNode | LiteralNode | EnumNode | ArrayNode | ObjectNode | UnionNode | RecursiveRefNode | TransformNode;
|
|
14
|
+
export interface NodeMetadata {
|
|
15
|
+
id?: string;
|
|
16
|
+
version?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
deprecated?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface NodeModifiers {
|
|
21
|
+
optional?: boolean;
|
|
22
|
+
nullable?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Stored as a serializable literal so the IR remains JSON-roundtrip-safe.
|
|
25
|
+
* Functions-as-defaults are explicitly disallowed in v0.1.
|
|
26
|
+
*/
|
|
27
|
+
default?: {
|
|
28
|
+
value: JsonValue;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export type Refinement = PortableRefinement | RuntimeRefinement;
|
|
32
|
+
/**
|
|
33
|
+
* A refinement representable in every output format (TS comments, Zod chain,
|
|
34
|
+
* JSON Schema keyword, OpenAPI schema).
|
|
35
|
+
*/
|
|
36
|
+
export interface PortableRefinement {
|
|
37
|
+
kind: "portable";
|
|
38
|
+
name: PortableRefinementName;
|
|
39
|
+
params?: Record<string, JsonValue>;
|
|
40
|
+
}
|
|
41
|
+
export type PortableRefinementName = "minLength" | "maxLength" | "length" | "regex" | "email" | "uuid" | "url" | "int" | "min" | "max" | "gt" | "lt" | "multipleOf" | "minItems" | "maxItems";
|
|
42
|
+
/**
|
|
43
|
+
* A custom predicate only the runtime can evaluate. Non-runtime outputs
|
|
44
|
+
* (JSON Schema, OpenAPI) MUST emit semantic-loss metadata when present.
|
|
45
|
+
*/
|
|
46
|
+
export interface RuntimeRefinement {
|
|
47
|
+
kind: "runtime";
|
|
48
|
+
/** Stable, machine-readable issue code emitted on failure. */
|
|
49
|
+
code: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
}
|
|
52
|
+
interface NodeBase {
|
|
53
|
+
metadata?: NodeMetadata;
|
|
54
|
+
modifiers?: NodeModifiers;
|
|
55
|
+
refinements?: readonly Refinement[];
|
|
56
|
+
}
|
|
57
|
+
export interface StringNode extends NodeBase {
|
|
58
|
+
kind: "string";
|
|
59
|
+
}
|
|
60
|
+
export interface NumberNode extends NodeBase {
|
|
61
|
+
kind: "number";
|
|
62
|
+
}
|
|
63
|
+
export interface BooleanNode extends NodeBase {
|
|
64
|
+
kind: "boolean";
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Date variants are explicit per the absence-of-ambiguity rule (no `s.date()`).
|
|
68
|
+
* - isoDateTime: ISO 8601 string (default for APIs / config)
|
|
69
|
+
* - isoDate: YYYY-MM-DD string
|
|
70
|
+
* - epochMs: integer milliseconds since epoch
|
|
71
|
+
* - dateObject: runtime-only Date (never serialized)
|
|
72
|
+
*
|
|
73
|
+
* v0.1 declares the IR shape; builders ship in a later phase.
|
|
74
|
+
*/
|
|
75
|
+
export interface DateNode extends NodeBase {
|
|
76
|
+
kind: "date";
|
|
77
|
+
variant: "isoDateTime" | "isoDate" | "epochMs" | "dateObject";
|
|
78
|
+
}
|
|
79
|
+
export interface LiteralNode<T extends JsonValue = JsonValue> extends NodeBase {
|
|
80
|
+
kind: "literal";
|
|
81
|
+
value: T;
|
|
82
|
+
}
|
|
83
|
+
export interface EnumNode<T extends string | number = string | number> extends NodeBase {
|
|
84
|
+
kind: "enum";
|
|
85
|
+
values: readonly T[];
|
|
86
|
+
}
|
|
87
|
+
export interface ArrayNode extends NodeBase {
|
|
88
|
+
kind: "array";
|
|
89
|
+
element: SchemaNode;
|
|
90
|
+
}
|
|
91
|
+
export type UnknownKeysPolicy = "strict" | "stripUnknown" | "passthrough";
|
|
92
|
+
export interface ObjectNode extends NodeBase {
|
|
93
|
+
kind: "object";
|
|
94
|
+
fields: Readonly<Record<string, SchemaNode>>;
|
|
95
|
+
unknownKeys: UnknownKeysPolicy;
|
|
96
|
+
}
|
|
97
|
+
export interface UnionNode extends NodeBase {
|
|
98
|
+
kind: "union";
|
|
99
|
+
options: readonly SchemaNode[];
|
|
100
|
+
/** When set, the union is discriminated by this field. */
|
|
101
|
+
discriminator?: string;
|
|
102
|
+
}
|
|
103
|
+
export interface RecursiveRefNode extends NodeBase {
|
|
104
|
+
kind: "recursiveRef";
|
|
105
|
+
/** Reverse-DNS schema id, e.g. "com.nekostack.auth.User". */
|
|
106
|
+
targetId: string;
|
|
107
|
+
/** Optional version pin; defaults to the latest registered. */
|
|
108
|
+
targetVersion?: string;
|
|
109
|
+
}
|
|
110
|
+
export interface TransformNode extends NodeBase {
|
|
111
|
+
kind: "transform";
|
|
112
|
+
source: SchemaNode;
|
|
113
|
+
/** Stable id of the transform; the runtime maps id → function. */
|
|
114
|
+
transformId: string;
|
|
115
|
+
}
|
|
116
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
117
|
+
export type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
118
|
+
[key: string]: JsonValue;
|
|
119
|
+
};
|
|
120
|
+
export {};
|
|
121
|
+
//# sourceMappingURL=nodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../../src/ir/nodes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Intermediate Representation for NekoStack schemas.
|
|
3
|
+
*
|
|
4
|
+
* Every builder produces a `SchemaNode`. Generators consume only IR — never
|
|
5
|
+
* builder internals. This is the single contract that prevents drift between
|
|
6
|
+
* the TS, Zod, JSON Schema, and OpenAPI outputs.
|
|
7
|
+
*
|
|
8
|
+
* The IR is JSON-serializable (no functions, no symbols, no class instances).
|
|
9
|
+
* Runtime-only constructs (transforms, custom refinement predicates) are
|
|
10
|
+
* stored as opaque metadata; the registry that owns the predicate is the
|
|
11
|
+
* runtime, not the IR.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=nodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodes.js","sourceRoot":"","sources":["../../../src/ir/nodes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SchemaNode } from "./nodes.js";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical JSON serialization of a SchemaNode: keys are sorted alphabetically
|
|
4
|
+
* at every level so two structurally identical IRs always produce byte-identical
|
|
5
|
+
* output. This is the input to `irHash` (computed in a later phase).
|
|
6
|
+
*/
|
|
7
|
+
export declare function serializeIR(node: SchemaNode): string;
|
|
8
|
+
//# sourceMappingURL=serialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../../src/ir/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEpD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical JSON serialization of a SchemaNode: keys are sorted alphabetically
|
|
3
|
+
* at every level so two structurally identical IRs always produce byte-identical
|
|
4
|
+
* output. This is the input to `irHash` (computed in a later phase).
|
|
5
|
+
*/
|
|
6
|
+
export function serializeIR(node) {
|
|
7
|
+
return JSON.stringify(canonicalize(node));
|
|
8
|
+
}
|
|
9
|
+
function canonicalize(value) {
|
|
10
|
+
if (value === null || typeof value !== "object")
|
|
11
|
+
return value;
|
|
12
|
+
if (Array.isArray(value))
|
|
13
|
+
return value.map(canonicalize);
|
|
14
|
+
const out = {};
|
|
15
|
+
for (const key of Object.keys(value).sort()) {
|
|
16
|
+
const v = value[key];
|
|
17
|
+
if (v === undefined)
|
|
18
|
+
continue;
|
|
19
|
+
out[key] = canonicalize(v);
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=serialize.js.map
|