@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,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codified `x-nekostack-*` extension keys used by the JSON Schema generator.
|
|
3
|
+
*
|
|
4
|
+
* These are the contract; any new extension key the generator emits must
|
|
5
|
+
* land here first. Stringly-typed extensions in the generator body would
|
|
6
|
+
* make typos and drift easy — the constants make both the spelling and the
|
|
7
|
+
* meaning grep-able.
|
|
8
|
+
*
|
|
9
|
+
* See [`docs/JSON_SCHEMA_MAPPING.md`](../../docs/JSON_SCHEMA_MAPPING.md) for
|
|
10
|
+
* the per-key contract: when each is emitted, what it means, and what
|
|
11
|
+
* NekoStack-aware consumers should do with it.
|
|
12
|
+
*/
|
|
13
|
+
export const JSON_SCHEMA_EXTENSIONS = {
|
|
14
|
+
/**
|
|
15
|
+
* Top-level provenance object: `{ generator, generatorVersion, irHash,
|
|
16
|
+
* schemaId, schemaVersion }`. Replaces the v0.2-style JSDoc header since
|
|
17
|
+
* JSON has no comment syntax.
|
|
18
|
+
*/
|
|
19
|
+
provenance: "x-nekostack",
|
|
20
|
+
/**
|
|
21
|
+
* Tag on a node carrying `default()`: signals that JSON Schema validators
|
|
22
|
+
* will NOT apply the default (it's annotation only); the NekoStack runtime
|
|
23
|
+
* (or the generated Zod) is responsible. Value is the literal string
|
|
24
|
+
* `"runtime"`.
|
|
25
|
+
*/
|
|
26
|
+
defaultAppliedBy: "x-nekostack-default-applied-by",
|
|
27
|
+
/**
|
|
28
|
+
* Tag on an object whose unknown-key policy is `stripUnknown`: signals
|
|
29
|
+
* that the schema accepts unknown keys (`additionalProperties: true`)
|
|
30
|
+
* and that NekoStack-aware runtime/CLI consumers should strip them.
|
|
31
|
+
* JSON Schema cannot express mutation; this is the bridge.
|
|
32
|
+
*/
|
|
33
|
+
strip: "x-nekostack-strip",
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=json-schema-meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-meta.js","sourceRoot":"","sources":["../../../src/generators/json-schema-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC;;;;OAIG;IACH,UAAU,EAAE,aAAa;IAEzB;;;;;OAKG;IACH,gBAAgB,EAAE,gCAAgC;IAElD;;;;;OAKG;IACH,KAAK,EAAE,mBAAmB;CAClB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SchemaNode } from "../ir/nodes.js";
|
|
2
|
+
import type { JsonSchemaGeneratorOptions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generate a JSON Schema **draft 2020-12** document from a `SchemaNode`.
|
|
5
|
+
*
|
|
6
|
+
* v0.4: refactored to a thin root wrapper that delegates the IR-to-fragment
|
|
7
|
+
* translation to {@link emitSchemaFragment}. The wrapper owns:
|
|
8
|
+
* - `$schema` (draft 2020-12 URL)
|
|
9
|
+
* - `$id` strategy (URN by default; URL via `options.idBase`)
|
|
10
|
+
* - `x-nekostack` provenance with `generator: "jsonSchema"`
|
|
11
|
+
* - Canonical serialization + trailing newline
|
|
12
|
+
*
|
|
13
|
+
* The wrapper does NOT own: absence semantics, object policy, portable
|
|
14
|
+
* refinements, runtime-refinement / regex-with-flags throws, canonical
|
|
15
|
+
* key sort. Those live in [`schema-fragment.ts`](./schema-fragment.ts) and
|
|
16
|
+
* are shared with the OpenAPI generator (v0.4+). See
|
|
17
|
+
* [`docs/JSON_SCHEMA_MAPPING.md`](../../docs/JSON_SCHEMA_MAPPING.md) for
|
|
18
|
+
* the contract.
|
|
19
|
+
*
|
|
20
|
+
* Throws `UnsupportedNodeKindError({ ..., generator: "jsonSchema" })`
|
|
21
|
+
* (Invariant 7) for: IR kinds without v0.3 mapping (`date` / `union` /
|
|
22
|
+
* `recursiveRef` / `transform`), runtime refinements, and regex with
|
|
23
|
+
* non-empty flags.
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateJsonSchema(node: SchemaNode, options?: JsonSchemaGeneratorOptions): string;
|
|
26
|
+
//# sourceMappingURL=json-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../../../src/generators/json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAQ5D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,0BAA+B,GACvC,MAAM,CAWR"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { irHash } from "../ir/hash.js";
|
|
2
|
+
import { GENERATOR_VERSION } from "./version.js";
|
|
3
|
+
import { JSON_SCHEMA_EXTENSIONS } from "./json-schema-meta.js";
|
|
4
|
+
import { canonicalize, emitSchemaFragment, } from "./schema-fragment.js";
|
|
5
|
+
/**
|
|
6
|
+
* Generate a JSON Schema **draft 2020-12** document from a `SchemaNode`.
|
|
7
|
+
*
|
|
8
|
+
* v0.4: refactored to a thin root wrapper that delegates the IR-to-fragment
|
|
9
|
+
* translation to {@link emitSchemaFragment}. The wrapper owns:
|
|
10
|
+
* - `$schema` (draft 2020-12 URL)
|
|
11
|
+
* - `$id` strategy (URN by default; URL via `options.idBase`)
|
|
12
|
+
* - `x-nekostack` provenance with `generator: "jsonSchema"`
|
|
13
|
+
* - Canonical serialization + trailing newline
|
|
14
|
+
*
|
|
15
|
+
* The wrapper does NOT own: absence semantics, object policy, portable
|
|
16
|
+
* refinements, runtime-refinement / regex-with-flags throws, canonical
|
|
17
|
+
* key sort. Those live in [`schema-fragment.ts`](./schema-fragment.ts) and
|
|
18
|
+
* are shared with the OpenAPI generator (v0.4+). See
|
|
19
|
+
* [`docs/JSON_SCHEMA_MAPPING.md`](../../docs/JSON_SCHEMA_MAPPING.md) for
|
|
20
|
+
* the contract.
|
|
21
|
+
*
|
|
22
|
+
* Throws `UnsupportedNodeKindError({ ..., generator: "jsonSchema" })`
|
|
23
|
+
* (Invariant 7) for: IR kinds without v0.3 mapping (`date` / `union` /
|
|
24
|
+
* `recursiveRef` / `transform`), runtime refinements, and regex with
|
|
25
|
+
* non-empty flags.
|
|
26
|
+
*/
|
|
27
|
+
export function generateJsonSchema(node, options = {}) {
|
|
28
|
+
const body = emitSchemaFragment(node, { generator: "jsonSchema" });
|
|
29
|
+
const idBlock = emitRootIdBlock(node, options);
|
|
30
|
+
const provenance = emitProvenance(node, options.sourceHash);
|
|
31
|
+
const root = {
|
|
32
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
33
|
+
...idBlock,
|
|
34
|
+
...body,
|
|
35
|
+
...provenance,
|
|
36
|
+
};
|
|
37
|
+
return JSON.stringify(canonicalize(root), null, 2) + "\n";
|
|
38
|
+
}
|
|
39
|
+
// ---------- root-level provenance + identity ----------
|
|
40
|
+
/**
|
|
41
|
+
* v0.3 placed provenance under a single `x-nekostack` extension object so
|
|
42
|
+
* it doesn't pollute the top-level JSON Schema namespace and is easy for
|
|
43
|
+
* downstream tooling to read or strip. Mirrors the v0.2 JSDoc header
|
|
44
|
+
* concept, adapted for a comment-less format.
|
|
45
|
+
*
|
|
46
|
+
* v0.7 adds `sourceHash` as an optional field. When the caller passes
|
|
47
|
+
* `options.sourceHash`, the field appears in the `x-nekostack` block;
|
|
48
|
+
* when omitted, the field is absent entirely (Master plan Decision #8 —
|
|
49
|
+
* NOT emitted as `null`). `canonicalize` drops `undefined` values, so
|
|
50
|
+
* setting the field to `undefined` here is equivalent to omitting it
|
|
51
|
+
* from the output JSON.
|
|
52
|
+
*/
|
|
53
|
+
function emitProvenance(node, sourceHash) {
|
|
54
|
+
return {
|
|
55
|
+
[JSON_SCHEMA_EXTENSIONS.provenance]: {
|
|
56
|
+
generator: "jsonSchema",
|
|
57
|
+
generatorVersion: GENERATOR_VERSION,
|
|
58
|
+
irHash: `sha256:${irHash(node)}`,
|
|
59
|
+
...(sourceHash !== undefined ? { sourceHash } : {}),
|
|
60
|
+
schemaId: node.metadata?.id ?? null,
|
|
61
|
+
schemaVersion: node.metadata?.version ?? null,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function emitRootIdBlock(node, options) {
|
|
66
|
+
const id = node.metadata?.id;
|
|
67
|
+
if (!id)
|
|
68
|
+
return {}; // anonymous → no $id (Decision #3)
|
|
69
|
+
const version = node.metadata?.version;
|
|
70
|
+
return { $id: formatId(id, version, options) };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Decision #2: URN by default (`urn:nekostack:schema:<id>:<version>`).
|
|
74
|
+
* URL-shaped IDs are opt-in via `options.idBase`. If `version` is absent,
|
|
75
|
+
* emit the URN/URL without the trailing version segment.
|
|
76
|
+
*/
|
|
77
|
+
function formatId(id, version, options) {
|
|
78
|
+
if (options.idBase !== undefined) {
|
|
79
|
+
const base = options.idBase.replace(/\/+$/, "");
|
|
80
|
+
return version === undefined
|
|
81
|
+
? `${base}/${id}`
|
|
82
|
+
: `${base}/${id}/${version}`;
|
|
83
|
+
}
|
|
84
|
+
return version === undefined
|
|
85
|
+
? `urn:nekostack:schema:${id}`
|
|
86
|
+
: `urn:nekostack:schema:${id}:${version}`;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=json-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../../src/generators/json-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EACL,YAAY,EACZ,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAG9B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAgB,EAChB,UAAsC,EAAE;IAExC,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG;QACX,OAAO,EAAE,8CAA8C;QACvD,GAAG,OAAO;QACV,GAAG,IAAI;QACP,GAAG,UAAU;KACd,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAC5D,CAAC;AAED,yDAAyD;AAEzD;;;;;;;;;;;;GAYG;AACH,SAAS,cAAc,CACrB,IAAgB,EAChB,UAA0C;IAE1C,OAAO;QACL,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE;YACnC,SAAS,EAAE,YAAY;YACvB,gBAAgB,EAAE,iBAAiB;YACnC,MAAM,EAAE,UAAU,MAAM,CAAC,IAAI,CAAC,EAAE;YAChC,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;YACnC,aAAa,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,IAAI,IAAI;SAC9C;KACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,IAAgB,EAChB,OAAmC;IAEnC,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC7B,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC,CAAC,mCAAmC;IACvD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC;IACvC,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CACf,EAAU,EACV,OAA2B,EAC3B,OAAmC;IAEnC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChD,OAAO,OAAO,KAAK,SAAS;YAC1B,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE;YACjB,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;IACjC,CAAC;IACD,OAAO,OAAO,KAAK,SAAS;QAC1B,CAAC,CAAC,wBAAwB,EAAE,EAAE;QAC9B,CAAC,CAAC,wBAAwB,EAAE,IAAI,OAAO,EAAE,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SchemaNode } from "../ir/nodes.js";
|
|
2
|
+
import type { OpenApiGeneratorOptions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generate an **OpenAPI 3.1 Schema Component** from a `SchemaNode`.
|
|
5
|
+
*
|
|
6
|
+
* The output is the value that would live under `components.schemas.<Name>`
|
|
7
|
+
* in a full OpenAPI document — NOT the document itself. Composing it into
|
|
8
|
+
* paths / operations / responses / requestBodies / etc. is the consumer's
|
|
9
|
+
* job (or `@nekostack/api`'s when that package exists).
|
|
10
|
+
*
|
|
11
|
+
* Differences from {@link generateJsonSchema}:
|
|
12
|
+
* - No `$schema` keyword — OpenAPI 3.1 documents declare the schema dialect
|
|
13
|
+
* once at the document root via `jsonSchemaDialect`; component schemas
|
|
14
|
+
* inherit it.
|
|
15
|
+
* - No `$id` — component identity is the position in the document
|
|
16
|
+
* (`#/components/schemas/<Name>`), per Decision #5.
|
|
17
|
+
* - Provenance `generator: "openApi"`.
|
|
18
|
+
*
|
|
19
|
+
* The IR-to-fragment translation (absence semantics, object policy,
|
|
20
|
+
* portable refinements, `stripUnknown` extension, throw paths,
|
|
21
|
+
* canonicalization) is shared with the JSON Schema generator via
|
|
22
|
+
* [`schema-fragment.ts`](./schema-fragment.ts). See
|
|
23
|
+
* [`docs/JSON_SCHEMA_MAPPING.md`](../../docs/JSON_SCHEMA_MAPPING.md) for
|
|
24
|
+
* the shared contract and the (small) OpenAPI deltas in
|
|
25
|
+
* [`docs/OPENAPI_MAPPING.md`](../../docs/OPENAPI_MAPPING.md).
|
|
26
|
+
*
|
|
27
|
+
* Throws `UnsupportedNodeKindError({ ..., generator: "openApi" })` per
|
|
28
|
+
* Invariant 7 for: IR kinds without v0.3-style mapping (`date`, `union`,
|
|
29
|
+
* `recursiveRef`, `transform`), runtime refinements, and regex with
|
|
30
|
+
* non-empty flags.
|
|
31
|
+
*/
|
|
32
|
+
export declare function generateOpenApiSchemaComponent(node: SchemaNode, options?: OpenApiGeneratorOptions): string;
|
|
33
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../src/generators/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAQ5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,uBAA4B,GACpC,MAAM,CAQR"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { irHash } from "../ir/hash.js";
|
|
2
|
+
import { GENERATOR_VERSION } from "./version.js";
|
|
3
|
+
import { JSON_SCHEMA_EXTENSIONS } from "./json-schema-meta.js";
|
|
4
|
+
import { canonicalize, emitSchemaFragment, } from "./schema-fragment.js";
|
|
5
|
+
/**
|
|
6
|
+
* Generate an **OpenAPI 3.1 Schema Component** from a `SchemaNode`.
|
|
7
|
+
*
|
|
8
|
+
* The output is the value that would live under `components.schemas.<Name>`
|
|
9
|
+
* in a full OpenAPI document — NOT the document itself. Composing it into
|
|
10
|
+
* paths / operations / responses / requestBodies / etc. is the consumer's
|
|
11
|
+
* job (or `@nekostack/api`'s when that package exists).
|
|
12
|
+
*
|
|
13
|
+
* Differences from {@link generateJsonSchema}:
|
|
14
|
+
* - No `$schema` keyword — OpenAPI 3.1 documents declare the schema dialect
|
|
15
|
+
* once at the document root via `jsonSchemaDialect`; component schemas
|
|
16
|
+
* inherit it.
|
|
17
|
+
* - No `$id` — component identity is the position in the document
|
|
18
|
+
* (`#/components/schemas/<Name>`), per Decision #5.
|
|
19
|
+
* - Provenance `generator: "openApi"`.
|
|
20
|
+
*
|
|
21
|
+
* The IR-to-fragment translation (absence semantics, object policy,
|
|
22
|
+
* portable refinements, `stripUnknown` extension, throw paths,
|
|
23
|
+
* canonicalization) is shared with the JSON Schema generator via
|
|
24
|
+
* [`schema-fragment.ts`](./schema-fragment.ts). See
|
|
25
|
+
* [`docs/JSON_SCHEMA_MAPPING.md`](../../docs/JSON_SCHEMA_MAPPING.md) for
|
|
26
|
+
* the shared contract and the (small) OpenAPI deltas in
|
|
27
|
+
* [`docs/OPENAPI_MAPPING.md`](../../docs/OPENAPI_MAPPING.md).
|
|
28
|
+
*
|
|
29
|
+
* Throws `UnsupportedNodeKindError({ ..., generator: "openApi" })` per
|
|
30
|
+
* Invariant 7 for: IR kinds without v0.3-style mapping (`date`, `union`,
|
|
31
|
+
* `recursiveRef`, `transform`), runtime refinements, and regex with
|
|
32
|
+
* non-empty flags.
|
|
33
|
+
*/
|
|
34
|
+
export function generateOpenApiSchemaComponent(node, options = {}) {
|
|
35
|
+
const body = emitSchemaFragment(node, { generator: "openApi" });
|
|
36
|
+
const provenance = emitProvenance(node, options.sourceHash);
|
|
37
|
+
const root = {
|
|
38
|
+
...body,
|
|
39
|
+
...provenance,
|
|
40
|
+
};
|
|
41
|
+
return JSON.stringify(canonicalize(root), null, 2) + "\n";
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Same shape as the JSON Schema provenance block, but with
|
|
45
|
+
* `generator: "openApi"`. v0.7 adds the optional `sourceHash` field
|
|
46
|
+
* (Master plan Decision #8); when omitted, the field is absent
|
|
47
|
+
* entirely from the emitted JSON (`canonicalize` drops `undefined`).
|
|
48
|
+
*/
|
|
49
|
+
function emitProvenance(node, sourceHash) {
|
|
50
|
+
return {
|
|
51
|
+
[JSON_SCHEMA_EXTENSIONS.provenance]: {
|
|
52
|
+
generator: "openApi",
|
|
53
|
+
generatorVersion: GENERATOR_VERSION,
|
|
54
|
+
irHash: `sha256:${irHash(node)}`,
|
|
55
|
+
...(sourceHash !== undefined ? { sourceHash } : {}),
|
|
56
|
+
schemaId: node.metadata?.id ?? null,
|
|
57
|
+
schemaVersion: node.metadata?.version ?? null,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../../src/generators/openapi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EACL,YAAY,EACZ,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAG9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,8BAA8B,CAC5C,IAAgB,EAChB,UAAmC,EAAE;IAErC,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG;QACX,GAAG,IAAI;QACP,GAAG,UAAU;KACd,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CACrB,IAAgB,EAChB,UAA0C;IAE1C,OAAO;QACL,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE;YACnC,SAAS,EAAE,SAAS;YACpB,gBAAgB,EAAE,iBAAiB;YACnC,MAAM,EAAE,UAAU,MAAM,CAAC,IAAI,CAAC,EAAE;YAChC,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;YACnC,aAAa,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,IAAI,IAAI;SAC9C;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { JsonValue, SchemaNode } from "../ir/nodes.js";
|
|
2
|
+
/**
|
|
3
|
+
* Shared IR → JSON-Schema-shaped fragment emitter consumed by both
|
|
4
|
+
* `json-schema.ts` and `openapi.ts`.
|
|
5
|
+
*
|
|
6
|
+
* **Why this module exists** (Decision #3, v0.4 plan): OpenAPI 3.1 Schema
|
|
7
|
+
* Objects are explicitly aligned with JSON Schema draft 2020-12 — the spec
|
|
8
|
+
* calls them a superset. Each wrapper has its own root structure (`$schema`,
|
|
9
|
+
* `$id`, provenance generator name), but the IR → fragment translation
|
|
10
|
+
* itself is identical and must not be duplicated. Duplication would create
|
|
11
|
+
* a real drift vector: bug fixes would have to land twice, behavior could
|
|
12
|
+
* silently diverge.
|
|
13
|
+
*
|
|
14
|
+
* The wrappers own:
|
|
15
|
+
* - Root document structure
|
|
16
|
+
* - `$schema` / `$id` decisions
|
|
17
|
+
* - Provenance `generator` field value
|
|
18
|
+
*
|
|
19
|
+
* This module owns:
|
|
20
|
+
* - Primitive type mapping
|
|
21
|
+
* - Array + object body mapping (including `required` array per absence semantics)
|
|
22
|
+
* - Object unknown-key policy (including `x-nekostack-strip`)
|
|
23
|
+
* - Portable refinement → keyword mapping
|
|
24
|
+
* - Runtime-refinement and regex-with-flags throws (Invariant 7)
|
|
25
|
+
* - Canonical key sort (`canonicalize`)
|
|
26
|
+
*
|
|
27
|
+
* Throw guards use the wrapper's generator name via `options.generator` so
|
|
28
|
+
* `UnsupportedNodeKindError` reports the right caller (`"jsonSchema"` vs
|
|
29
|
+
* `"openApi"`) — tests assert on this field per the v0.2 stable-error
|
|
30
|
+
* contract.
|
|
31
|
+
*/
|
|
32
|
+
export interface SchemaFragmentOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Which wrapper is calling. Used only to populate the `generator` field
|
|
35
|
+
* of any `UnsupportedNodeKindError` thrown during translation. The
|
|
36
|
+
* emitted fragment itself is identical regardless — OpenAPI 3.1 Schema
|
|
37
|
+
* Objects are draft-2020-12-compatible.
|
|
38
|
+
*/
|
|
39
|
+
generator: "jsonSchema" | "openApi";
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Emit the JSON-Schema-shaped fragment for a node. Returns a plain object;
|
|
43
|
+
* wrappers add `$schema` / `$id` / provenance and JSON-stringify.
|
|
44
|
+
*
|
|
45
|
+
* Throws `UnsupportedNodeKindError` with `options.generator` for runtime
|
|
46
|
+
* refinements (Decision #11) before walking the node — cheaper to fail
|
|
47
|
+
* fast than to emit a partial fragment.
|
|
48
|
+
*/
|
|
49
|
+
export declare function emitSchemaFragment(node: SchemaNode, options: SchemaFragmentOptions): Record<string, JsonValue>;
|
|
50
|
+
/**
|
|
51
|
+
* Canonical key-sort, recursive. Wrappers apply this to the assembled root
|
|
52
|
+
* before stringifying so the output is byte-stable across runs.
|
|
53
|
+
*/
|
|
54
|
+
export declare function canonicalize(value: unknown): unknown;
|
|
55
|
+
//# sourceMappingURL=schema-fragment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-fragment.d.ts","sourceRoot":"","sources":["../../../src/generators/schema-fragment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,SAAS,EAIT,UAAU,EACX,MAAM,gBAAgB,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,SAAS,EAAE,YAAY,GAAG,SAAS,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,qBAAqB,GAC7B,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAgB3B;AA6OD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAUpD"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { UnsupportedNodeKindError } from "./errors.js";
|
|
2
|
+
import { JSON_SCHEMA_EXTENSIONS } from "./json-schema-meta.js";
|
|
3
|
+
/**
|
|
4
|
+
* Emit the JSON-Schema-shaped fragment for a node. Returns a plain object;
|
|
5
|
+
* wrappers add `$schema` / `$id` / provenance and JSON-stringify.
|
|
6
|
+
*
|
|
7
|
+
* Throws `UnsupportedNodeKindError` with `options.generator` for runtime
|
|
8
|
+
* refinements (Decision #11) before walking the node — cheaper to fail
|
|
9
|
+
* fast than to emit a partial fragment.
|
|
10
|
+
*/
|
|
11
|
+
export function emitSchemaFragment(node, options) {
|
|
12
|
+
for (const r of node.refinements ?? []) {
|
|
13
|
+
if (r.kind === "runtime") {
|
|
14
|
+
throw new UnsupportedNodeKindError({
|
|
15
|
+
kind: "runtimeRefinement",
|
|
16
|
+
generator: options.generator,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const base = emitBareType(node, options);
|
|
21
|
+
applyPortableRefinements(base, node.refinements ?? [], options);
|
|
22
|
+
applyDescription(base, node);
|
|
23
|
+
applyNullability(base, node);
|
|
24
|
+
applyDefault(base, node);
|
|
25
|
+
return base;
|
|
26
|
+
}
|
|
27
|
+
function emitBareType(node, options) {
|
|
28
|
+
switch (node.kind) {
|
|
29
|
+
case "string":
|
|
30
|
+
return { type: "string" };
|
|
31
|
+
case "number":
|
|
32
|
+
return { type: "number" };
|
|
33
|
+
case "boolean":
|
|
34
|
+
return { type: "boolean" };
|
|
35
|
+
case "literal":
|
|
36
|
+
return emitLiteral(node);
|
|
37
|
+
case "enum":
|
|
38
|
+
return emitEnum(node);
|
|
39
|
+
case "array":
|
|
40
|
+
return emitArray(node, options);
|
|
41
|
+
case "object":
|
|
42
|
+
return emitObject(node, options);
|
|
43
|
+
default:
|
|
44
|
+
throw new UnsupportedNodeKindError({
|
|
45
|
+
kind: node.kind,
|
|
46
|
+
generator: options.generator,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function emitLiteral(node) {
|
|
51
|
+
return { const: node.value };
|
|
52
|
+
}
|
|
53
|
+
function emitEnum(node) {
|
|
54
|
+
if (node.values.length === 0) {
|
|
55
|
+
throw new Error("Cannot emit JSON Schema for an empty enum");
|
|
56
|
+
}
|
|
57
|
+
return { enum: [...node.values] };
|
|
58
|
+
}
|
|
59
|
+
function emitArray(node, options) {
|
|
60
|
+
return {
|
|
61
|
+
type: "array",
|
|
62
|
+
items: emitSchemaFragment(node.element, options),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function emitObject(node, options) {
|
|
66
|
+
const entries = Object.entries(node.fields);
|
|
67
|
+
const properties = {};
|
|
68
|
+
const required = [];
|
|
69
|
+
for (const [key, field] of entries) {
|
|
70
|
+
properties[key] = emitSchemaFragment(field, options);
|
|
71
|
+
if (isObjectRequired(field))
|
|
72
|
+
required.push(key);
|
|
73
|
+
}
|
|
74
|
+
const out = {
|
|
75
|
+
type: "object",
|
|
76
|
+
properties,
|
|
77
|
+
};
|
|
78
|
+
if (required.length > 0)
|
|
79
|
+
out.required = required;
|
|
80
|
+
// Decision #12 (corrected in v0.3): `stripUnknown` accepts unknown keys
|
|
81
|
+
// (`additionalProperties: true`) and tags `x-nekostack-strip: true` so
|
|
82
|
+
// NekoStack-aware consumers know to strip them. JSON Schema (and OpenAPI
|
|
83
|
+
// Schema Objects) cannot express mutation; stripping happens in the
|
|
84
|
+
// runtime.
|
|
85
|
+
switch (node.unknownKeys) {
|
|
86
|
+
case "strict":
|
|
87
|
+
out.additionalProperties = false;
|
|
88
|
+
break;
|
|
89
|
+
case "passthrough":
|
|
90
|
+
out.additionalProperties = true;
|
|
91
|
+
break;
|
|
92
|
+
case "stripUnknown":
|
|
93
|
+
out.additionalProperties = true;
|
|
94
|
+
out[JSON_SCHEMA_EXTENSIONS.strip] = true;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Object-field requiredness per Decisions #6-#9:
|
|
101
|
+
* - `optional()` → not in `required` array
|
|
102
|
+
* - `nullable()` → IS in `required` (null is a value)
|
|
103
|
+
* - `nullish()` → not in `required`
|
|
104
|
+
* - `default(v)` → not in `required` (input-optional honored;
|
|
105
|
+
* default applied by runtime, not the schema)
|
|
106
|
+
*/
|
|
107
|
+
function isObjectRequired(node) {
|
|
108
|
+
const mods = node.modifiers ?? {};
|
|
109
|
+
if (mods.optional)
|
|
110
|
+
return false;
|
|
111
|
+
if (mods.default !== undefined)
|
|
112
|
+
return false;
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
// ---------- refinements ----------
|
|
116
|
+
function applyPortableRefinements(out, refinements, options) {
|
|
117
|
+
for (const r of refinements) {
|
|
118
|
+
if (r.kind !== "portable")
|
|
119
|
+
continue; // runtime already threw
|
|
120
|
+
applyPortableRefinement(out, r, options);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function applyPortableRefinement(out, r, options) {
|
|
124
|
+
const params = r.params ?? {};
|
|
125
|
+
switch (r.name) {
|
|
126
|
+
case "minLength":
|
|
127
|
+
out.minLength = numParam(params.value);
|
|
128
|
+
return;
|
|
129
|
+
case "maxLength":
|
|
130
|
+
out.maxLength = numParam(params.value);
|
|
131
|
+
return;
|
|
132
|
+
case "length": {
|
|
133
|
+
const v = numParam(params.value);
|
|
134
|
+
out.minLength = v;
|
|
135
|
+
out.maxLength = v;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
case "regex": {
|
|
139
|
+
// Decision #11a: regex with non-empty flags throws — emitting
|
|
140
|
+
// source-only `pattern` would change validation behavior (drop
|
|
141
|
+
// case-insensitivity etc.), and Invariant 7 forbids silent drops.
|
|
142
|
+
const source = String(params.source ?? "");
|
|
143
|
+
const flags = String(params.flags ?? "");
|
|
144
|
+
if (flags.length > 0) {
|
|
145
|
+
throw new UnsupportedNodeKindError({
|
|
146
|
+
kind: "regexFlags",
|
|
147
|
+
generator: options.generator,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
out.pattern = source;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
case "email":
|
|
154
|
+
out.format = "email";
|
|
155
|
+
return;
|
|
156
|
+
case "uuid":
|
|
157
|
+
out.format = "uuid";
|
|
158
|
+
return;
|
|
159
|
+
case "url":
|
|
160
|
+
out.format = "uri";
|
|
161
|
+
return;
|
|
162
|
+
case "int":
|
|
163
|
+
out.type = "integer";
|
|
164
|
+
return;
|
|
165
|
+
case "min":
|
|
166
|
+
out.minimum = numParam(params.value);
|
|
167
|
+
return;
|
|
168
|
+
case "max":
|
|
169
|
+
out.maximum = numParam(params.value);
|
|
170
|
+
return;
|
|
171
|
+
case "gt":
|
|
172
|
+
out.exclusiveMinimum = numParam(params.value);
|
|
173
|
+
return;
|
|
174
|
+
case "lt":
|
|
175
|
+
out.exclusiveMaximum = numParam(params.value);
|
|
176
|
+
return;
|
|
177
|
+
case "multipleOf":
|
|
178
|
+
out.multipleOf = numParam(params.value);
|
|
179
|
+
return;
|
|
180
|
+
case "minItems":
|
|
181
|
+
out.minItems = numParam(params.value);
|
|
182
|
+
return;
|
|
183
|
+
case "maxItems":
|
|
184
|
+
out.maxItems = numParam(params.value);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// ---------- modifiers + description ----------
|
|
189
|
+
function applyDescription(out, node) {
|
|
190
|
+
if (node.metadata?.description)
|
|
191
|
+
out.description = node.metadata.description;
|
|
192
|
+
if (node.metadata?.deprecated)
|
|
193
|
+
out.deprecated = true;
|
|
194
|
+
}
|
|
195
|
+
function applyNullability(out, node) {
|
|
196
|
+
if (!node.modifiers?.nullable)
|
|
197
|
+
return;
|
|
198
|
+
if ("type" in out && out.type !== undefined) {
|
|
199
|
+
const current = out.type;
|
|
200
|
+
if (Array.isArray(current)) {
|
|
201
|
+
if (!current.includes("null"))
|
|
202
|
+
out.type = [...current, "null"];
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
out.type = [current, "null"];
|
|
206
|
+
}
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if ("enum" in out && Array.isArray(out.enum)) {
|
|
210
|
+
if (!out.enum.includes(null))
|
|
211
|
+
out.enum = [...out.enum, null];
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if ("const" in out) {
|
|
215
|
+
const value = out.const;
|
|
216
|
+
delete out.const;
|
|
217
|
+
out.anyOf = [{ const: value }, { type: "null" }];
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function applyDefault(out, node) {
|
|
222
|
+
const def = node.modifiers?.default;
|
|
223
|
+
if (def === undefined)
|
|
224
|
+
return;
|
|
225
|
+
out.default = def.value;
|
|
226
|
+
out[JSON_SCHEMA_EXTENSIONS.defaultAppliedBy] = "runtime";
|
|
227
|
+
}
|
|
228
|
+
// ---------- helpers ----------
|
|
229
|
+
function numParam(value) {
|
|
230
|
+
if (typeof value !== "number") {
|
|
231
|
+
throw new Error(`Expected numeric refinement param, got ${typeof value}`);
|
|
232
|
+
}
|
|
233
|
+
return value;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Canonical key-sort, recursive. Wrappers apply this to the assembled root
|
|
237
|
+
* before stringifying so the output is byte-stable across runs.
|
|
238
|
+
*/
|
|
239
|
+
export function canonicalize(value) {
|
|
240
|
+
if (value === null || typeof value !== "object")
|
|
241
|
+
return value;
|
|
242
|
+
if (Array.isArray(value))
|
|
243
|
+
return value.map(canonicalize);
|
|
244
|
+
const out = {};
|
|
245
|
+
for (const key of Object.keys(value).sort()) {
|
|
246
|
+
const v = value[key];
|
|
247
|
+
if (v === undefined)
|
|
248
|
+
continue;
|
|
249
|
+
out[key] = canonicalize(v);
|
|
250
|
+
}
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=schema-fragment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-fragment.js","sourceRoot":"","sources":["../../../src/generators/schema-fragment.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AA2C/D;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAgB,EAChB,OAA8B;IAE9B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,wBAAwB,CAAC;gBACjC,IAAI,EAAE,mBAAmB;gBACzB,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzC,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IAChE,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7B,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7B,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CACnB,IAAgB,EAChB,OAA8B;IAE9B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC5B,KAAK,SAAS;YACZ,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,KAAK,SAAS;YACZ,OAAO,WAAW,CAAC,IAAmB,CAAC,CAAC;QAC1C,KAAK,MAAM;YACT,OAAO,QAAQ,CAAC,IAAgB,CAAC,CAAC;QACpC,KAAK,OAAO;YACV,OAAO,SAAS,CAAC,IAAiB,EAAE,OAAO,CAAC,CAAC;QAC/C,KAAK,QAAQ;YACX,OAAO,UAAU,CAAC,IAAkB,EAAE,OAAO,CAAC,CAAC;QACjD;YACE,MAAM,IAAI,wBAAwB,CAAC;gBACjC,IAAI,EAAG,IAAyB,CAAC,IAAI;gBACrC,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC,CAAC;IACP,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAAiB;IACpC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,QAAQ,CAAC,IAAc;IAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAgB,EAAE,CAAC;AACnD,CAAC;AAED,SAAS,SAAS,CAChB,IAAe,EACf,OAA8B;IAE9B,OAAO;QACL,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;KACjD,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CACjB,IAAgB,EAChB,OAA8B;IAE9B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,UAAU,GAA8B,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,UAAU,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrD,IAAI,gBAAgB,CAAC,KAAK,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,GAAG,GAA8B;QACrC,IAAI,EAAE,QAAQ;QACd,UAAU;KACX,CAAC;IACF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAEjD,wEAAwE;IACxE,uEAAuE;IACvE,yEAAyE;IACzE,oEAAoE;IACpE,WAAW;IACX,QAAQ,IAAI,CAAC,WAAW,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,GAAG,CAAC,oBAAoB,GAAG,KAAK,CAAC;YACjC,MAAM;QACR,KAAK,aAAa;YAChB,GAAG,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAChC,MAAM;QACR,KAAK,cAAc;YACjB,GAAG,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAChC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YACzC,MAAM;IACV,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,gBAAgB,CAAC,IAAgB;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;IAClC,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oCAAoC;AAEpC,SAAS,wBAAwB,CAC/B,GAA8B,EAC9B,WAAwC,EACxC,OAA8B;IAE9B,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS,CAAC,wBAAwB;QAC7D,uBAAuB,CAAC,GAAG,EAAE,CAAuB,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAC9B,GAA8B,EAC9B,CAAqB,EACrB,OAA8B;IAE9B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IAC9B,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,WAAW;YACd,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvC,OAAO;QACT,KAAK,WAAW;YACd,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvC,OAAO;QACT,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACjC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC;YAClB,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC;YAClB,OAAO;QACT,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,8DAA8D;YAC9D,+DAA+D;YAC/D,kEAAkE;YAClE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACzC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,wBAAwB,CAAC;oBACjC,IAAI,EAAE,YAAY;oBAClB,SAAS,EAAE,OAAO,CAAC,SAAS;iBAC7B,CAAC,CAAC;YACL,CAAC;YACD,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;YACrB,OAAO;QACT,CAAC;QACD,KAAK,OAAO;YACV,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC;YACrB,OAAO;QACT,KAAK,MAAM;YACT,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACpB,OAAO;QACT,KAAK,KAAK;YACR,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC;YACnB,OAAO;QACT,KAAK,KAAK;YACR,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;YACrB,OAAO;QACT,KAAK,KAAK;YACR,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACrC,OAAO;QACT,KAAK,KAAK;YACR,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACrC,OAAO;QACT,KAAK,IAAI;YACP,GAAG,CAAC,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO;QACT,KAAK,IAAI;YACP,GAAG,CAAC,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO;QACT,KAAK,YAAY;YACf,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxC,OAAO;QACT,KAAK,UAAU;YACb,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtC,OAAO;QACT,KAAK,UAAU;YACb,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtC,OAAO;IACX,CAAC;AACH,CAAC;AAED,gDAAgD;AAEhD,SAAS,gBAAgB,CAAC,GAA8B,EAAE,IAAgB;IACxE,IAAI,IAAI,CAAC,QAAQ,EAAE,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC5E,IAAI,IAAI,CAAC,QAAQ,EAAE,UAAU;QAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC;AACvD,CAAC;AAED,SAAS,gBAAgB,CAAC,GAA8B,EAAE,IAAgB;IACxE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ;QAAE,OAAO;IAEtC,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;QACzB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,GAAG,CAAC,OAAiB,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,IAAI,OAAO,IAAI,GAAG,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QACxB,OAAO,GAAG,CAAC,KAAK,CAAC;QACjB,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAA8B,EAAE,IAAgB;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;IACpC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO;IAC9B,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC;IACxB,GAAG,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC;AAC3D,CAAC;AAED,gCAAgC;AAEhC,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,0CAA0C,OAAO,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACzD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACtD,MAAM,CAAC,GAAI,KAAiC,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,SAAS;YAAE,SAAS;QAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SchemaNode } from "../ir/nodes.js";
|
|
2
|
+
import type { TypeScriptGeneratorOptions } from "./types.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 declare function generateTypeScript(node: SchemaNode, options?: TypeScriptGeneratorOptions): string;
|
|
19
|
+
//# sourceMappingURL=ts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ts.d.ts","sourceRoot":"","sources":["../../../src/generators/ts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKV,UAAU,EACX,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAI7D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,0BAA+B,GACvC,MAAM,CAuBR"}
|