@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,252 @@
|
|
|
1
|
+
import { UnsupportedNodeKindError } from "./errors.js";
|
|
2
|
+
import { buildHeader } from "./header.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generate a TypeScript type alias from a SchemaNode.
|
|
5
|
+
*
|
|
6
|
+
* Modes (Decision #9):
|
|
7
|
+
* - "output" (default): post-default shape, matches `s.infer<T>` / `s.output<T>`.
|
|
8
|
+
* - "input": pre-default shape, matches `s.input<T>`.
|
|
9
|
+
* - "both": emits both `<Name>Input` and `<Name>Output`.
|
|
10
|
+
*
|
|
11
|
+
* Naming: derived from `metadata.id`'s last dotted segment, or
|
|
12
|
+
* `options.typeName`, or `"Schema"` for anonymous schemas. In `"both"` mode,
|
|
13
|
+
* the suffixes are always appended — no bare `<Name>`.
|
|
14
|
+
*
|
|
15
|
+
* Headers: deterministic JSDoc preamble per `buildHeader`. Same IR + same
|
|
16
|
+
* generator version → byte-identical output.
|
|
17
|
+
*/
|
|
18
|
+
export function generateTypeScript(node, options = {}) {
|
|
19
|
+
const mode = options.mode ?? "output";
|
|
20
|
+
const baseName = options.typeName ?? deriveName(node);
|
|
21
|
+
const header = buildHeader(node, {
|
|
22
|
+
generator: "typescript",
|
|
23
|
+
...(options.sourceHash !== undefined
|
|
24
|
+
? { sourceHash: options.sourceHash }
|
|
25
|
+
: {}),
|
|
26
|
+
});
|
|
27
|
+
if (mode === "both") {
|
|
28
|
+
return [
|
|
29
|
+
header,
|
|
30
|
+
"",
|
|
31
|
+
emitTypeAlias(node, "input", `${baseName}Input`),
|
|
32
|
+
"",
|
|
33
|
+
emitTypeAlias(node, "output", `${baseName}Output`),
|
|
34
|
+
"",
|
|
35
|
+
].join("\n");
|
|
36
|
+
}
|
|
37
|
+
const name = mode === "input" ? `${baseName}Input` : baseName;
|
|
38
|
+
return [header, "", emitTypeAlias(node, mode, name), ""].join("\n");
|
|
39
|
+
}
|
|
40
|
+
// ---------- top-level emit ----------
|
|
41
|
+
function emitTypeAlias(node, mode, name) {
|
|
42
|
+
const doc = emitTopLevelDocComment(node);
|
|
43
|
+
const expr = emitTypeExpression(node, mode, /*depth*/ 0);
|
|
44
|
+
return `${doc}export type ${name} = ${expr};`;
|
|
45
|
+
}
|
|
46
|
+
function emitTopLevelDocComment(node) {
|
|
47
|
+
const lines = [];
|
|
48
|
+
if (node.metadata?.description)
|
|
49
|
+
lines.push(node.metadata.description);
|
|
50
|
+
if (node.metadata?.deprecated)
|
|
51
|
+
lines.push("@deprecated");
|
|
52
|
+
if (lines.length === 0)
|
|
53
|
+
return "";
|
|
54
|
+
return `/**\n${lines.map((l) => ` * ${l}`).join("\n")}\n */\n`;
|
|
55
|
+
}
|
|
56
|
+
// ---------- type expressions (non-field positions) ----------
|
|
57
|
+
/**
|
|
58
|
+
* Emit a complete type expression honoring nullable/optional/default for the
|
|
59
|
+
* current mode. Used at top level and inside array elements — anywhere that
|
|
60
|
+
* is NOT directly an object field. Object fields use {@link emitObjectField}
|
|
61
|
+
* because they handle optionality via the `?` key marker.
|
|
62
|
+
*
|
|
63
|
+
* `depth` is the indentation depth of the *containing* construct (0 at top
|
|
64
|
+
* level, +1 inside each enclosing object). Object types use it to indent
|
|
65
|
+
* their own bodies one level deeper.
|
|
66
|
+
*/
|
|
67
|
+
function emitTypeExpression(node, mode, depth) {
|
|
68
|
+
let inner = emitBareType(node, mode, depth);
|
|
69
|
+
const mods = node.modifiers ?? {};
|
|
70
|
+
if (mods.nullable)
|
|
71
|
+
inner = `${inner} | null`;
|
|
72
|
+
if (mods.optional) {
|
|
73
|
+
const defaultApplied = mods.default !== undefined && mode === "output";
|
|
74
|
+
if (!defaultApplied)
|
|
75
|
+
inner = `${inner} | undefined`;
|
|
76
|
+
}
|
|
77
|
+
return inner;
|
|
78
|
+
}
|
|
79
|
+
// ---------- bare types ----------
|
|
80
|
+
function emitBareType(node, mode, depth) {
|
|
81
|
+
// Runtime refinements are unsupported in v0.2 generators (Invariant 7).
|
|
82
|
+
// The TS generator doesn't *use* refinement values, but a node carrying a
|
|
83
|
+
// runtime refinement still represents validation the IR intends to enforce;
|
|
84
|
+
// silently emitting the type without it would imply runtime semantics this
|
|
85
|
+
// package can't (yet) guarantee. Fail loudly to match the Zod generator.
|
|
86
|
+
for (const r of node.refinements ?? []) {
|
|
87
|
+
if (r.kind === "runtime") {
|
|
88
|
+
throw new UnsupportedNodeKindError({
|
|
89
|
+
kind: "runtimeRefinement",
|
|
90
|
+
generator: "typescript",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
switch (node.kind) {
|
|
95
|
+
case "string":
|
|
96
|
+
return "string";
|
|
97
|
+
case "number":
|
|
98
|
+
return "number";
|
|
99
|
+
case "boolean":
|
|
100
|
+
return "boolean";
|
|
101
|
+
case "literal":
|
|
102
|
+
return formatLiteral(node.value);
|
|
103
|
+
case "enum":
|
|
104
|
+
return node.values.map((v) => formatLiteral(v)).join(" | ");
|
|
105
|
+
case "array":
|
|
106
|
+
return emitArrayType(node, mode, depth);
|
|
107
|
+
case "object":
|
|
108
|
+
return emitObjectType(node, mode, depth);
|
|
109
|
+
default:
|
|
110
|
+
throw new UnsupportedNodeKindError({
|
|
111
|
+
kind: node.kind,
|
|
112
|
+
generator: "typescript",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function emitArrayType(node, mode, depth) {
|
|
117
|
+
const elementExpr = emitTypeExpression(node.element, mode, depth);
|
|
118
|
+
// Parenthesize when the element type contains a *top-level* union so `[]`
|
|
119
|
+
// binds correctly. A naive `startsWith("{")` shortcut is wrong: an
|
|
120
|
+
// object-then-union element like `{...} | undefined` (produced by
|
|
121
|
+
// `s.array(s.object({...}).optional())`) starts with `{` but still needs
|
|
122
|
+
// parens, otherwise we emit `{...} | undefined[]` which parses as
|
|
123
|
+
// "object or array of undefined" — not what the IR means.
|
|
124
|
+
return hasTopLevelUnion(elementExpr)
|
|
125
|
+
? `(${elementExpr})[]`
|
|
126
|
+
: `${elementExpr}[]`;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* True if `expr` contains a `|` outside of all braces, parens, brackets,
|
|
130
|
+
* and string literals. This is the structural check that distinguishes
|
|
131
|
+
* `string | undefined` (top-level union → needs parens for `[]`) from
|
|
132
|
+
* `{ foo: "a | b" }` (no top-level union → bare `[]` is fine).
|
|
133
|
+
*/
|
|
134
|
+
function hasTopLevelUnion(expr) {
|
|
135
|
+
let depth = 0;
|
|
136
|
+
let inString = false;
|
|
137
|
+
let escape = false;
|
|
138
|
+
for (let i = 0; i < expr.length; i++) {
|
|
139
|
+
const ch = expr[i];
|
|
140
|
+
if (escape) {
|
|
141
|
+
escape = false;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (inString) {
|
|
145
|
+
if (ch === "\\")
|
|
146
|
+
escape = true;
|
|
147
|
+
else if (ch === '"')
|
|
148
|
+
inString = false;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (ch === '"')
|
|
152
|
+
inString = true;
|
|
153
|
+
else if (ch === "{" || ch === "(" || ch === "[")
|
|
154
|
+
depth++;
|
|
155
|
+
else if (ch === "}" || ch === ")" || ch === "]")
|
|
156
|
+
depth = Math.max(0, depth - 1);
|
|
157
|
+
else if (ch === "|" && depth === 0)
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Emit a TS object body. `depth` is the indentation depth of THIS object:
|
|
164
|
+
* - depth 0 ⇒ top-level type alias body: inner fields at 2 spaces, `}` at column 0.
|
|
165
|
+
* - depth 1 ⇒ first-level nested object: inner fields at 4 spaces, `}` at 2 spaces.
|
|
166
|
+
* - depth N ⇒ inner fields at 2*(N+1) spaces, `}` at 2*N spaces.
|
|
167
|
+
*
|
|
168
|
+
* Each enclosing object passes `depth + 1` to its field's emit, so nesting
|
|
169
|
+
* grows the indent consistently. Mirrors what the Zod generator already does.
|
|
170
|
+
*/
|
|
171
|
+
function emitObjectType(node, mode, depth) {
|
|
172
|
+
const entries = Object.entries(node.fields);
|
|
173
|
+
if (entries.length === 0)
|
|
174
|
+
return "{}";
|
|
175
|
+
const fieldIndent = " ".repeat(depth + 1);
|
|
176
|
+
const closeIndent = " ".repeat(depth);
|
|
177
|
+
const lines = entries.map(([key, field]) => {
|
|
178
|
+
const { keyMark, typeExpr } = emitObjectField(field, mode, depth + 1);
|
|
179
|
+
const fieldDoc = emitFieldDocComment(field, fieldIndent);
|
|
180
|
+
const safeKey = formatPropertyKey(key);
|
|
181
|
+
return `${fieldDoc}${fieldIndent}${safeKey}${keyMark}: ${typeExpr};`;
|
|
182
|
+
});
|
|
183
|
+
return `{\n${lines.join("\n")}\n${closeIndent}}`;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Emit an object property key. Identifier-safe keys go bare; anything else
|
|
187
|
+
* (hyphens, spaces, leading digits, reserved characters) is quoted via
|
|
188
|
+
* JSON.stringify so the generated type alias is valid TS for any IR-valid key.
|
|
189
|
+
*/
|
|
190
|
+
function formatPropertyKey(key) {
|
|
191
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
|
|
192
|
+
}
|
|
193
|
+
function emitObjectField(field, mode, depth) {
|
|
194
|
+
const mods = field.modifiers ?? {};
|
|
195
|
+
let typeExpr = emitBareType(field, mode, depth);
|
|
196
|
+
if (mods.nullable)
|
|
197
|
+
typeExpr = `${typeExpr} | null`;
|
|
198
|
+
// In object-field position, optionality uses the `?` key marker; we do
|
|
199
|
+
// NOT also append `| undefined` — that would produce noisier output that
|
|
200
|
+
// is structurally identical (TS treats `field?: T` ≡ `field?: T | undefined`).
|
|
201
|
+
let isOptional = false;
|
|
202
|
+
if (mods.optional) {
|
|
203
|
+
if (mods.default !== undefined) {
|
|
204
|
+
isOptional = mode === "input"; // default makes input optional, output required
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
isOptional = true; // .optional() or .nullish()
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return { keyMark: isOptional ? "?" : "", typeExpr };
|
|
211
|
+
}
|
|
212
|
+
function emitFieldDocComment(field, indent) {
|
|
213
|
+
const lines = [];
|
|
214
|
+
if (field.metadata?.description)
|
|
215
|
+
lines.push(field.metadata.description);
|
|
216
|
+
if (field.metadata?.deprecated)
|
|
217
|
+
lines.push("@deprecated");
|
|
218
|
+
if (lines.length === 0)
|
|
219
|
+
return "";
|
|
220
|
+
// Per-field JSDoc matches the field's indent so it lines up with the field.
|
|
221
|
+
return `${indent}/**\n${lines.map((l) => `${indent} * ${l}`).join("\n")}\n${indent} */\n`;
|
|
222
|
+
}
|
|
223
|
+
// ---------- helpers ----------
|
|
224
|
+
/**
|
|
225
|
+
* Format a JsonValue as a TS literal-type expression.
|
|
226
|
+
*
|
|
227
|
+
* In practice v0.2 schemas use string/number/boolean/null literals; the IR
|
|
228
|
+
* accepts the full `JsonValue` space (arrays / objects) for forward-compat,
|
|
229
|
+
* so we accept it here and emit via `JSON.stringify`. Arrays/objects emit as
|
|
230
|
+
* value-shaped JS literals — valid in expression position but not as TS
|
|
231
|
+
* *literal types*. That's acceptable: nobody constructs schemas with
|
|
232
|
+
* object-literal `s.literal(...)` today, and the alternative (throwing) is
|
|
233
|
+
* worse than emitting a JSON-shaped fallback.
|
|
234
|
+
*/
|
|
235
|
+
function formatLiteral(value) {
|
|
236
|
+
if (typeof value === "string")
|
|
237
|
+
return JSON.stringify(value);
|
|
238
|
+
if (value === null)
|
|
239
|
+
return "null";
|
|
240
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
241
|
+
return String(value);
|
|
242
|
+
}
|
|
243
|
+
return JSON.stringify(value);
|
|
244
|
+
}
|
|
245
|
+
function deriveName(node) {
|
|
246
|
+
const id = node.metadata?.id;
|
|
247
|
+
if (!id)
|
|
248
|
+
return "Schema";
|
|
249
|
+
const last = id.split(".").pop();
|
|
250
|
+
return last && last.length > 0 ? last : "Schema";
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=ts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ts.js","sourceRoot":"","sources":["../../../src/generators/ts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared option types for generators.
|
|
3
|
+
*
|
|
4
|
+
* Each generator may extend with its own options; this file declares only
|
|
5
|
+
* what is genuinely shared. v0.2 ships TS and Zod generators; v0.3 adds
|
|
6
|
+
* JSON Schema, v0.4 adds OpenAPI, v0.7 adds the cross-generator
|
|
7
|
+
* `ProvenanceOptions` slice (below).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Provenance options shared by every generator (v0.7+).
|
|
11
|
+
*
|
|
12
|
+
* `sourceHash` is the sha256 of the originating `*.schema.ts` source
|
|
13
|
+
* file's UTF-8 bytes, as produced by
|
|
14
|
+
* `registry/source-hash.ts → sourceHashFromText`. The CLI passes it
|
|
15
|
+
* through to each generator call when invoked via `neko schema *`;
|
|
16
|
+
* direct generator calls (vitest snapshots, ad-hoc scripts) may omit it.
|
|
17
|
+
*
|
|
18
|
+
* **Omission behavior (Master plan Decision #8, locked):**
|
|
19
|
+
* - When omitted, TS/Zod emit **no** `sourceHash:` JSDoc header line
|
|
20
|
+
* (not `null`, not `unknown` — the line is absent entirely).
|
|
21
|
+
* - When omitted, JSON Schema / OpenAPI emit **no** `x-nekostack.sourceHash`
|
|
22
|
+
* field (the field is absent entirely; not `null`).
|
|
23
|
+
* - Header / provenance parsers (`registry/parse-provenance.ts`, Step 5)
|
|
24
|
+
* treat absent `sourceHash` as "unknown" — v0.6-era artifacts without
|
|
25
|
+
* `sourceHash` are NOT integrity errors.
|
|
26
|
+
*
|
|
27
|
+
* Type discipline: the template-literal `` `sha256:${string}` `` is the
|
|
28
|
+
* canonical form everywhere `sourceHash` appears on the v0.7 surface
|
|
29
|
+
* (`RegistryEntry`, `GeneratedArtifact`, this option slice). A raw hex
|
|
30
|
+
* string without the `sha256:` prefix is a type error at the generator
|
|
31
|
+
* call site.
|
|
32
|
+
*/
|
|
33
|
+
export interface ProvenanceOptions {
|
|
34
|
+
readonly sourceHash?: `sha256:${string}`;
|
|
35
|
+
}
|
|
36
|
+
/** Options accepted by `generateTypeScript`. */
|
|
37
|
+
export interface TypeScriptGeneratorOptions extends ProvenanceOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Which side of the input/output split to emit. Default: "output".
|
|
40
|
+
*
|
|
41
|
+
* - "output": post-default, post-transform type (matches `s.infer<T>`).
|
|
42
|
+
* - "input": pre-default, pre-transform type (matches `s.input<T>`).
|
|
43
|
+
* - "both": emits both `<Name>Input` and `<Name>Output` aliases.
|
|
44
|
+
*
|
|
45
|
+
* The input/output split is a v0.1 contract; default/transform make the
|
|
46
|
+
* two sides differ. The TS generator honors it at generation time, not
|
|
47
|
+
* just at the `s.*` helper level.
|
|
48
|
+
*/
|
|
49
|
+
mode?: "input" | "output" | "both";
|
|
50
|
+
/**
|
|
51
|
+
* Type-alias name override. By default, the generator uses the schema's
|
|
52
|
+
* `metadata.id` (last dotted segment) or `"Schema"` for anonymous schemas.
|
|
53
|
+
* In `mode: "both"`, the suffixes `Input` / `Output` are appended.
|
|
54
|
+
*/
|
|
55
|
+
typeName?: string;
|
|
56
|
+
}
|
|
57
|
+
/** Options accepted by `generateZod`. */
|
|
58
|
+
export interface ZodGeneratorOptions extends ProvenanceOptions {
|
|
59
|
+
/**
|
|
60
|
+
* Const name for the emitted Zod schema. Defaults to `"schema"` (lowercase
|
|
61
|
+
* since it's a value, not a type).
|
|
62
|
+
*/
|
|
63
|
+
constName?: string;
|
|
64
|
+
}
|
|
65
|
+
/** Options accepted by `generateJsonSchema`. */
|
|
66
|
+
export interface JsonSchemaGeneratorOptions extends ProvenanceOptions {
|
|
67
|
+
/**
|
|
68
|
+
* Optional URL base for `$id`. When provided, emitted IDs take the form
|
|
69
|
+
* `${idBase}/${metadata.id}/${metadata.version}` instead of the default
|
|
70
|
+
* URN form (`urn:nekostack:schema:<id>:<version>`).
|
|
71
|
+
*
|
|
72
|
+
* Use only when you actually host the schemas at that URL — JSON Schema
|
|
73
|
+
* tooling treats URL-shaped `$id` as resolvable in some contexts.
|
|
74
|
+
*/
|
|
75
|
+
idBase?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Options accepted by `generateOpenApiSchemaComponent`.
|
|
79
|
+
*
|
|
80
|
+
* v0.4 declared this as `Record<string, never>` to enforce a no-options
|
|
81
|
+
* contract. v0.7 narrows the contract by exactly one field:
|
|
82
|
+
* `ProvenanceOptions.sourceHash` is now accepted (and only that). All
|
|
83
|
+
* other options — `idBase`, `discriminator`, anything not declared on
|
|
84
|
+
* `ProvenanceOptions` — continue to fail at compile time, because the
|
|
85
|
+
* interface declares no own members.
|
|
86
|
+
*
|
|
87
|
+
* Extension point preserved: adding the first OpenAPI-specific option
|
|
88
|
+
* later (likely `discriminator` when union builders ship) is
|
|
89
|
+
* non-breaking — `extends ProvenanceOptions` widens further without
|
|
90
|
+
* removing the export.
|
|
91
|
+
*/
|
|
92
|
+
export interface OpenApiGeneratorOptions extends ProvenanceOptions {
|
|
93
|
+
}
|
|
94
|
+
/** Union of all generator option types — exported for ergonomics. */
|
|
95
|
+
export type GeneratorOptions = TypeScriptGeneratorOptions | ZodGeneratorOptions | JsonSchemaGeneratorOptions | OpenApiGeneratorOptions;
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/generators/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,MAAM,EAAE,CAAC;CAC1C;AAED,gDAAgD;AAChD,MAAM,WAAW,0BAA2B,SAAQ,iBAAiB;IACnE;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yCAAyC;AACzC,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,gDAAgD;AAChD,MAAM,WAAW,0BAA2B,SAAQ,iBAAiB;IACnE;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;CAAG;AAErE,qEAAqE;AACrE,MAAM,MAAM,gBAAgB,GACxB,0BAA0B,GAC1B,mBAAmB,GACnB,0BAA0B,GAC1B,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared option types for generators.
|
|
3
|
+
*
|
|
4
|
+
* Each generator may extend with its own options; this file declares only
|
|
5
|
+
* what is genuinely shared. v0.2 ships TS and Zod generators; v0.3 adds
|
|
6
|
+
* JSON Schema, v0.4 adds OpenAPI, v0.7 adds the cross-generator
|
|
7
|
+
* `ProvenanceOptions` slice (below).
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/generators/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the generator-version string embedded in every
|
|
3
|
+
* generated-file header. Bumped with the package version.
|
|
4
|
+
*
|
|
5
|
+
* Decision #5 in PHASE_PLAN_v0.2: one string for all generators (TS and Zod
|
|
6
|
+
* share the same version), not per-generator. When this string changes,
|
|
7
|
+
* generated artifacts produced by an older version are stale and CI should
|
|
8
|
+
* re-emit them.
|
|
9
|
+
*/
|
|
10
|
+
export declare const GENERATOR_VERSION: "@nekostack/schema@0.8.0";
|
|
11
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/generators/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,EAAG,yBAAkC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the generator-version string embedded in every
|
|
3
|
+
* generated-file header. Bumped with the package version.
|
|
4
|
+
*
|
|
5
|
+
* Decision #5 in PHASE_PLAN_v0.2: one string for all generators (TS and Zod
|
|
6
|
+
* share the same version), not per-generator. When this string changes,
|
|
7
|
+
* generated artifacts produced by an older version are stale and CI should
|
|
8
|
+
* re-emit them.
|
|
9
|
+
*/
|
|
10
|
+
export const GENERATOR_VERSION = "@nekostack/schema@0.8.0";
|
|
11
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/generators/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,yBAAkC,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
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 type { JsonValue, SchemaNode, UnknownKeysPolicy } from "../ir/nodes.js";
|
|
33
|
+
/**
|
|
34
|
+
* The per-operation surface a Zod consumer implements. `T` is the
|
|
35
|
+
* consumer's output type (`string` for the source generator,
|
|
36
|
+
* `ZodTypeAny` for the runtime compiler).
|
|
37
|
+
*
|
|
38
|
+
* Every method maps to one concrete Zod construction or chain step;
|
|
39
|
+
* the shared traversal in `emit()` is responsible for *when* each
|
|
40
|
+
* method is called, the consumer is responsible for *how* it realizes
|
|
41
|
+
* the operation.
|
|
42
|
+
*/
|
|
43
|
+
export interface ZodEmitter<T> {
|
|
44
|
+
stringBase(): T;
|
|
45
|
+
numberBase(): T;
|
|
46
|
+
booleanBase(): T;
|
|
47
|
+
literalBase(value: JsonValue): T;
|
|
48
|
+
/** Length >= 1, all values are strings — use `z.enum([...])`. */
|
|
49
|
+
enumStringsBase(values: readonly string[]): T;
|
|
50
|
+
/** Length === 1, value is non-string — collapse to `z.literal(v)`. */
|
|
51
|
+
enumSingleLiteralBase(value: JsonValue): T;
|
|
52
|
+
/** Length >= 2, mixed/numeric — `z.union([z.literal(...), ...])`. */
|
|
53
|
+
enumUnionBase(values: readonly JsonValue[]): T;
|
|
54
|
+
arrayBase(element: T): T;
|
|
55
|
+
/**
|
|
56
|
+
* @param fields Pre-emitted per-key children, in iteration order.
|
|
57
|
+
* @param depth Nesting depth, supplied so a string consumer can
|
|
58
|
+
* compute indentation. The value consumer ignores it.
|
|
59
|
+
*/
|
|
60
|
+
objectBase(fields: ReadonlyArray<readonly [key: string, value: T]>, depth: number): T;
|
|
61
|
+
applyUnknownKeys(prev: T, policy: UnknownKeysPolicy): T;
|
|
62
|
+
applyMinLength(prev: T, value: number): T;
|
|
63
|
+
applyMaxLength(prev: T, value: number): T;
|
|
64
|
+
applyLength(prev: T, value: number): T;
|
|
65
|
+
applyRegex(prev: T, source: string, flags: string): T;
|
|
66
|
+
applyEmail(prev: T): T;
|
|
67
|
+
applyUuid(prev: T): T;
|
|
68
|
+
applyUrl(prev: T): T;
|
|
69
|
+
applyInt(prev: T): T;
|
|
70
|
+
applyMin(prev: T, value: number): T;
|
|
71
|
+
applyMax(prev: T, value: number): T;
|
|
72
|
+
applyGt(prev: T, value: number): T;
|
|
73
|
+
applyLt(prev: T, value: number): T;
|
|
74
|
+
applyMultipleOf(prev: T, value: number): T;
|
|
75
|
+
applyMinItems(prev: T, value: number): T;
|
|
76
|
+
applyMaxItems(prev: T, value: number): T;
|
|
77
|
+
applyDescribe(prev: T, text: string): T;
|
|
78
|
+
applyNullable(prev: T): T;
|
|
79
|
+
applyOptional(prev: T): T;
|
|
80
|
+
applyNullish(prev: T): T;
|
|
81
|
+
applyDefault(prev: T, value: JsonValue): T;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Entry point: walk a `SchemaNode` and produce the consumer's `T`.
|
|
85
|
+
*
|
|
86
|
+
* `depth` is threaded for the string consumer's indentation. Callers
|
|
87
|
+
* outside this module should start at depth 0.
|
|
88
|
+
*/
|
|
89
|
+
export declare function emit<T>(node: SchemaNode, depth: number, emitter: ZodEmitter<T>): T;
|
|
90
|
+
//# sourceMappingURL=zod-mapping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-mapping.d.ts","sourceRoot":"","sources":["../../../src/generators/zod-mapping.ts"],"names":[],"mappings":"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"}
|