ajsc 5.2.3 → 7.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/README.md +253 -145
- package/dist/converter/BaseConverter.d.ts +283 -0
- package/dist/converter/BaseConverter.js +131 -0
- package/dist/converter/BaseConverter.js.map +1 -0
- package/dist/converter/Emitter.d.ts +35 -0
- package/dist/converter/Emitter.js +50 -0
- package/dist/converter/Emitter.js.map +1 -0
- package/dist/converter/discriminatedUnions.d.ts +47 -0
- package/dist/converter/discriminatedUnions.js +168 -0
- package/dist/converter/discriminatedUnions.js.map +1 -0
- package/dist/converter/formatDefault.d.ts +20 -0
- package/dist/converter/formatDefault.js +31 -0
- package/dist/converter/formatDefault.js.map +1 -0
- package/dist/converter/index.d.ts +2 -0
- package/dist/converter/index.js +2 -0
- package/dist/converter/index.js.map +1 -0
- package/dist/converter/mergeUnions.d.ts +36 -0
- package/dist/converter/mergeUnions.js +189 -0
- package/dist/converter/mergeUnions.js.map +1 -0
- package/dist/converter/naming.d.ts +29 -0
- package/dist/converter/naming.js +130 -0
- package/dist/converter/naming.js.map +1 -0
- package/dist/converter/registry.d.ts +18 -0
- package/dist/converter/registry.js +50 -0
- package/dist/converter/registry.js.map +1 -0
- package/dist/converter/walk.d.ts +9 -0
- package/dist/converter/walk.js +40 -0
- package/dist/converter/walk.js.map +1 -0
- package/dist/index.d.ts +71 -3
- package/dist/index.js +63 -3
- package/dist/index.js.map +1 -1
- package/dist/{JSONSchemaConverter.d.ts → ir/JSONSchemaConverter.d.ts} +1 -1
- package/dist/{JSONSchemaConverter.js → ir/JSONSchemaConverter.js} +9 -3
- package/dist/ir/JSONSchemaConverter.js.map +1 -0
- package/dist/ir/index.d.ts +1 -0
- package/dist/ir/index.js +2 -0
- package/dist/ir/index.js.map +1 -0
- package/dist/kotlin/KotlinBaseConverter.d.ts +18 -0
- package/dist/kotlin/KotlinBaseConverter.js +36 -0
- package/dist/kotlin/KotlinBaseConverter.js.map +1 -0
- package/dist/kotlin/KotlinConverter.d.ts +67 -0
- package/dist/kotlin/KotlinConverter.js +140 -0
- package/dist/kotlin/KotlinConverter.js.map +1 -0
- package/dist/kotlin/annotations.d.ts +26 -0
- package/dist/kotlin/annotations.js +35 -0
- package/dist/kotlin/annotations.js.map +1 -0
- package/dist/kotlin/enums.d.ts +15 -0
- package/dist/kotlin/enums.js +58 -0
- package/dist/kotlin/enums.js.map +1 -0
- package/dist/kotlin/index.d.ts +2 -0
- package/dist/kotlin/index.js +3 -0
- package/dist/kotlin/index.js.map +1 -0
- package/dist/kotlin/objectEmitter.d.ts +12 -0
- package/dist/kotlin/objectEmitter.js +74 -0
- package/dist/kotlin/objectEmitter.js.map +1 -0
- package/dist/kotlin/sealedUnion.d.ts +17 -0
- package/dist/kotlin/sealedUnion.js +74 -0
- package/dist/kotlin/sealedUnion.js.map +1 -0
- package/dist/kotlin/typeMapper.d.ts +17 -0
- package/dist/kotlin/typeMapper.js +107 -0
- package/dist/kotlin/typeMapper.js.map +1 -0
- package/dist/kotlin/unsupported.d.ts +13 -0
- package/dist/kotlin/unsupported.js +53 -0
- package/dist/kotlin/unsupported.js.map +1 -0
- package/dist/swift/SwiftBaseConverter.d.ts +18 -0
- package/dist/swift/SwiftBaseConverter.js +38 -0
- package/dist/swift/SwiftBaseConverter.js.map +1 -0
- package/dist/swift/SwiftConverter.d.ts +60 -0
- package/dist/swift/SwiftConverter.js +111 -0
- package/dist/swift/SwiftConverter.js.map +1 -0
- package/dist/swift/discriminatedEnum.d.ts +18 -0
- package/dist/swift/discriminatedEnum.js +99 -0
- package/dist/swift/discriminatedEnum.js.map +1 -0
- package/dist/swift/enums.d.ts +15 -0
- package/dist/swift/enums.js +62 -0
- package/dist/swift/enums.js.map +1 -0
- package/dist/swift/index.d.ts +2 -0
- package/dist/swift/index.js +3 -0
- package/dist/swift/index.js.map +1 -0
- package/dist/swift/structEmitter.d.ts +12 -0
- package/dist/swift/structEmitter.js +70 -0
- package/dist/swift/structEmitter.js.map +1 -0
- package/dist/swift/typeMapper.d.ts +18 -0
- package/dist/swift/typeMapper.js +106 -0
- package/dist/swift/typeMapper.js.map +1 -0
- package/dist/swift/unsupported.d.ts +19 -0
- package/dist/swift/unsupported.js +88 -0
- package/dist/swift/unsupported.js.map +1 -0
- package/dist/typescript/TypescriptBaseConverter.d.ts +25 -0
- package/dist/typescript/TypescriptBaseConverter.js +178 -0
- package/dist/typescript/TypescriptBaseConverter.js.map +1 -0
- package/dist/typescript/TypescriptConverter.d.ts +74 -0
- package/dist/typescript/TypescriptConverter.js +252 -0
- package/dist/typescript/TypescriptConverter.js.map +1 -0
- package/dist/typescript/index.d.ts +2 -0
- package/dist/typescript/index.js +3 -0
- package/dist/typescript/index.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +37 -5
- package/dist/JSONSchemaConverter.js.map +0 -1
- package/dist/JSONSchemaConverter.test.d.ts +0 -1
- package/dist/JSONSchemaConverter.test.js +0 -585
- package/dist/JSONSchemaConverter.test.js.map +0 -1
- package/dist/Typebox.test.d.ts +0 -1
- package/dist/Typebox.test.js +0 -88
- package/dist/Typebox.test.js.map +0 -1
- package/dist/TypescriptBaseConverter.d.ts +0 -75
- package/dist/TypescriptBaseConverter.js +0 -321
- package/dist/TypescriptBaseConverter.js.map +0 -1
- package/dist/TypescriptConverter.additionalProperties.test.d.ts +0 -1
- package/dist/TypescriptConverter.additionalProperties.test.js +0 -110
- package/dist/TypescriptConverter.additionalProperties.test.js.map +0 -1
- package/dist/TypescriptConverter.arrays.test.d.ts +0 -1
- package/dist/TypescriptConverter.arrays.test.js +0 -130
- package/dist/TypescriptConverter.arrays.test.js.map +0 -1
- package/dist/TypescriptConverter.composites.advanced.test.d.ts +0 -1
- package/dist/TypescriptConverter.composites.advanced.test.js +0 -924
- package/dist/TypescriptConverter.composites.advanced.test.js.map +0 -1
- package/dist/TypescriptConverter.composites.test.d.ts +0 -1
- package/dist/TypescriptConverter.composites.test.js +0 -335
- package/dist/TypescriptConverter.composites.test.js.map +0 -1
- package/dist/TypescriptConverter.d.ts +0 -163
- package/dist/TypescriptConverter.js +0 -595
- package/dist/TypescriptConverter.js.map +0 -1
- package/dist/TypescriptConverter.jsdoc.test.d.ts +0 -1
- package/dist/TypescriptConverter.jsdoc.test.js +0 -194
- package/dist/TypescriptConverter.jsdoc.test.js.map +0 -1
- package/dist/TypescriptConverter.objects.test.d.ts +0 -1
- package/dist/TypescriptConverter.objects.test.js +0 -258
- package/dist/TypescriptConverter.objects.test.js.map +0 -1
- package/dist/TypescriptConverter.options.test.d.ts +0 -1
- package/dist/TypescriptConverter.options.test.js +0 -501
- package/dist/TypescriptConverter.options.test.js.map +0 -1
- package/dist/TypescriptConverter.primitives.test.d.ts +0 -1
- package/dist/TypescriptConverter.primitives.test.js +0 -26
- package/dist/TypescriptConverter.primitives.test.js.map +0 -1
- package/dist/utils/path-utils.test.d.ts +0 -1
- package/dist/utils/path-utils.test.js +0 -92
- package/dist/utils/path-utils.test.js.map +0 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { toPascalCase } from "../utils/to-pascal-case.js";
|
|
2
|
+
import { walkIR } from "./walk.js";
|
|
3
|
+
/**
|
|
4
|
+
* Collects all property names (in first-seen order) and shared property names
|
|
5
|
+
* across union options.
|
|
6
|
+
*
|
|
7
|
+
* Pure helper — does not depend on any converter context.
|
|
8
|
+
*/
|
|
9
|
+
export function collectUnionPropertyNames(options) {
|
|
10
|
+
const allPropNames = [];
|
|
11
|
+
const seenProps = new Set();
|
|
12
|
+
for (const opt of options) {
|
|
13
|
+
if (opt.properties) {
|
|
14
|
+
for (const key of Object.keys(opt.properties)) {
|
|
15
|
+
if (!seenProps.has(key)) {
|
|
16
|
+
seenProps.add(key);
|
|
17
|
+
allPropNames.push(key);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const sharedPropNames = allPropNames.filter((propName) => options.every((opt) => opt.properties?.[propName] !== undefined));
|
|
23
|
+
return { allPropNames, sharedPropNames };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extracts a single const string value from an IR node (literal with string
|
|
27
|
+
* value or single-value string enum).
|
|
28
|
+
*
|
|
29
|
+
* Pure helper — does not depend on any converter context.
|
|
30
|
+
*/
|
|
31
|
+
export function getConstStringValue(ir) {
|
|
32
|
+
if (!ir)
|
|
33
|
+
return undefined;
|
|
34
|
+
if (ir.type === "literal" && typeof ir.constraints?.value === "string") {
|
|
35
|
+
return ir.constraints.value;
|
|
36
|
+
}
|
|
37
|
+
if (ir.type === "enum" &&
|
|
38
|
+
ir.values?.length === 1 &&
|
|
39
|
+
typeof ir.values[0] === "string") {
|
|
40
|
+
return ir.values[0];
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Finds the discriminator property among shared properties: a property where
|
|
46
|
+
* each option has a distinct const or single-value-enum string value.
|
|
47
|
+
*/
|
|
48
|
+
export function findDiscriminatorProperty(options, sharedPropNames) {
|
|
49
|
+
for (const propName of sharedPropNames) {
|
|
50
|
+
const values = options.map((opt) => getConstStringValue(opt.properties?.[propName]));
|
|
51
|
+
if (values.every((v) => v !== undefined)) {
|
|
52
|
+
const uniqueValues = new Set(values);
|
|
53
|
+
if (uniqueValues.size === options.length) {
|
|
54
|
+
return propName;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns the parent-context name used when generating discriminated-union
|
|
62
|
+
* variant names (e.g. for a `Shape` union, returning `"shape"` yields variant
|
|
63
|
+
* names like `CircleShape`/`SquareShape`).
|
|
64
|
+
*
|
|
65
|
+
* Default: the last non-numeric segment of the union's path. Languages may
|
|
66
|
+
* override via `languageProfile.getDiscriminatedVariantParentName` to apply
|
|
67
|
+
* a fallback (e.g. Kotlin falls back to `ir.name || ir.title` for root-level
|
|
68
|
+
* unions) or to disable the parent suffix entirely (e.g. Swift emits variants
|
|
69
|
+
* nested in the enum, so `Circle` is unambiguous and bare).
|
|
70
|
+
*/
|
|
71
|
+
function defaultVariantParentName(ir) {
|
|
72
|
+
const pathSegments = ir.path.split(".").filter((x) => !/^\d+$/.test(x));
|
|
73
|
+
return pathSegments[pathSegments.length - 1] || "";
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Walks the IR tree and applies discriminated union enhancements
|
|
77
|
+
* to anyOf unions that survived merging. Subclasses may opt in to also
|
|
78
|
+
* process `oneOf` unions via the `processOneOfAsDiscriminatedUnion`
|
|
79
|
+
* field on `languageProfile`.
|
|
80
|
+
*/
|
|
81
|
+
export function enhanceDiscriminatedUnions(c, ir) {
|
|
82
|
+
walkIR(ir, (node) => {
|
|
83
|
+
if (node.type === "union" &&
|
|
84
|
+
node.options &&
|
|
85
|
+
node.options.length > 1) {
|
|
86
|
+
const isAnyOf = node.constraints?.combinator === "anyOf";
|
|
87
|
+
const isOneOf = node.constraints?.combinator === "oneOf";
|
|
88
|
+
if (isAnyOf || (isOneOf && (c.languageProfile.processOneOfAsDiscriminatedUnion ?? false))) {
|
|
89
|
+
applyDiscriminatedUnionEnhancements(c, node);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Enhances an unmerged anyOf union that has a discriminator property.
|
|
96
|
+
* Sets `ir.name` on each variant to a discriminator-derived name and
|
|
97
|
+
* populates `discriminatorInfo` for consolidated enum emission.
|
|
98
|
+
*/
|
|
99
|
+
export function applyDiscriminatedUnionEnhancements(c, ir) {
|
|
100
|
+
const options = ir.options;
|
|
101
|
+
if (!options || !options.every((opt) => opt.type === "object"))
|
|
102
|
+
return;
|
|
103
|
+
// Compute shared property names
|
|
104
|
+
const { sharedPropNames } = collectUnionPropertyNames(options);
|
|
105
|
+
const discriminator = findDiscriminatorProperty(options, sharedPropNames);
|
|
106
|
+
if (!discriminator)
|
|
107
|
+
return;
|
|
108
|
+
const parentName = c.languageProfile.getDiscriminatedVariantParentName?.(ir)
|
|
109
|
+
?? defaultVariantParentName(ir);
|
|
110
|
+
// Collect all discriminator values in order
|
|
111
|
+
const allValues = [];
|
|
112
|
+
for (const opt of options) {
|
|
113
|
+
const val = getConstStringValue(opt.properties[discriminator]);
|
|
114
|
+
if (val)
|
|
115
|
+
allValues.push(val);
|
|
116
|
+
}
|
|
117
|
+
// Collect signatures of object/array properties across all variants
|
|
118
|
+
// for cross-variant deduplication. If the same signature appears at
|
|
119
|
+
// different property names across variants, it should be deduplicated.
|
|
120
|
+
const signatureCounts = new Map();
|
|
121
|
+
for (const opt of options) {
|
|
122
|
+
if (!opt.properties)
|
|
123
|
+
continue;
|
|
124
|
+
for (const prop of Object.values(opt.properties)) {
|
|
125
|
+
if (prop.signature) {
|
|
126
|
+
signatureCounts.set(prop.signature, (signatureCounts.get(prop.signature) ?? 0) + 1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
for (const [sig, count] of signatureCounts) {
|
|
131
|
+
if (count > 1)
|
|
132
|
+
c.dedupSignatures.add(sig);
|
|
133
|
+
}
|
|
134
|
+
for (const opt of options) {
|
|
135
|
+
const val = getConstStringValue(opt.properties[discriminator]);
|
|
136
|
+
if (!val)
|
|
137
|
+
continue;
|
|
138
|
+
// Compute discriminator-derived variant name and stash it for downstream emitters.
|
|
139
|
+
const variantName = toPascalCase(val) + toPascalCase(parentName);
|
|
140
|
+
c.variantNames.set(opt, variantName);
|
|
141
|
+
// Populate discriminator info — subclasses opt in via the profile
|
|
142
|
+
if (c.languageProfile.shouldPopulateDiscriminatorInfo ?? false) {
|
|
143
|
+
const discProp = opt.properties[discriminator];
|
|
144
|
+
c.discriminatorInfo.set(discProp, { allValues, thisValue: val });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Returns a copy of the variant IR node with the discriminator property removed
|
|
150
|
+
* when `languageProfile.shouldEraseDiscriminator` is true. Otherwise returns the original.
|
|
151
|
+
*
|
|
152
|
+
* Used by language emitters that hoist the discriminator into a sealed-interface
|
|
153
|
+
* annotation (Kotlin `@JsonClassDiscriminator`) or a Codable plumbing block (Swift
|
|
154
|
+
* generated `init(from:)`/`encode(to:)`), where carrying the field on the variant
|
|
155
|
+
* struct would cause a duplicate-key error during decode.
|
|
156
|
+
*/
|
|
157
|
+
export function stripDiscriminatorField(c, opt, discriminator) {
|
|
158
|
+
if (!(c.languageProfile.shouldEraseDiscriminator ?? false))
|
|
159
|
+
return opt;
|
|
160
|
+
const propsToEmit = {};
|
|
161
|
+
for (const [k, v] of Object.entries(opt.properties ?? {})) {
|
|
162
|
+
if (k === discriminator)
|
|
163
|
+
continue;
|
|
164
|
+
propsToEmit[k] = v;
|
|
165
|
+
}
|
|
166
|
+
return { ...opt, properties: propsToEmit };
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=discriminatedUnions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminatedUnions.js","sourceRoot":"","sources":["../../src/converter/discriminatedUnions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a JSON Schema `default` value as a literal usable in target-language
|
|
3
|
+
* inline property initialization (Kotlin `val`, Swift `let`).
|
|
4
|
+
*
|
|
5
|
+
* Returns `undefined` when the value cannot be safely emitted as an inline
|
|
6
|
+
* literal — caller should treat that as "no default."
|
|
7
|
+
*
|
|
8
|
+
* Supported:
|
|
9
|
+
* - strings (escaped via JSON.stringify, which produces double-quoted form
|
|
10
|
+
* valid in both Kotlin and Swift for printable ASCII; verify if your
|
|
11
|
+
* fixtures contain unusual characters)
|
|
12
|
+
* - finite numbers
|
|
13
|
+
* - booleans
|
|
14
|
+
*
|
|
15
|
+
* Not supported (returns undefined):
|
|
16
|
+
* - null / undefined
|
|
17
|
+
* - arrays, objects (require language-specific literal syntax)
|
|
18
|
+
* - non-finite numbers
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatPrimitiveDefault(value: unknown): string | undefined;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a JSON Schema `default` value as a literal usable in target-language
|
|
3
|
+
* inline property initialization (Kotlin `val`, Swift `let`).
|
|
4
|
+
*
|
|
5
|
+
* Returns `undefined` when the value cannot be safely emitted as an inline
|
|
6
|
+
* literal — caller should treat that as "no default."
|
|
7
|
+
*
|
|
8
|
+
* Supported:
|
|
9
|
+
* - strings (escaped via JSON.stringify, which produces double-quoted form
|
|
10
|
+
* valid in both Kotlin and Swift for printable ASCII; verify if your
|
|
11
|
+
* fixtures contain unusual characters)
|
|
12
|
+
* - finite numbers
|
|
13
|
+
* - booleans
|
|
14
|
+
*
|
|
15
|
+
* Not supported (returns undefined):
|
|
16
|
+
* - null / undefined
|
|
17
|
+
* - arrays, objects (require language-specific literal syntax)
|
|
18
|
+
* - non-finite numbers
|
|
19
|
+
*/
|
|
20
|
+
export function formatPrimitiveDefault(value) {
|
|
21
|
+
if (value === null || value === undefined)
|
|
22
|
+
return undefined;
|
|
23
|
+
if (typeof value === "string")
|
|
24
|
+
return JSON.stringify(value);
|
|
25
|
+
if (typeof value === "boolean")
|
|
26
|
+
return String(value);
|
|
27
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
28
|
+
return String(value);
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=formatDefault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatDefault.js","sourceRoot":"","sources":["../../src/converter/formatDefault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9E,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/converter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { IRNode } from "../types.js";
|
|
2
|
+
import type { BaseConverterContext } from "./BaseConverter.js";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively walks the IR tree (bottom-up) and merges anyOf unions
|
|
5
|
+
* whose options are all objects with compatible property types.
|
|
6
|
+
* Merged enums collect values from all options; properties missing
|
|
7
|
+
* from some options become optional in the merged type.
|
|
8
|
+
*/
|
|
9
|
+
export declare function mergeCompatibleUnions(c: BaseConverterContext, ir: IRNode): IRNode;
|
|
10
|
+
/**
|
|
11
|
+
* Attempts to merge all options of an anyOf union into a single object type.
|
|
12
|
+
* Returns the merged IRNode, or null if the options are not compatible.
|
|
13
|
+
*/
|
|
14
|
+
export declare function tryMergeObjectUnion(c: BaseConverterContext, ir: IRNode): IRNode | null;
|
|
15
|
+
/**
|
|
16
|
+
* Tries to merge multiple instances of the same property across union options.
|
|
17
|
+
* Returns the merged IRNode, or null if incompatible.
|
|
18
|
+
*
|
|
19
|
+
* Pure helper — does not depend on any converter context.
|
|
20
|
+
*/
|
|
21
|
+
export declare function tryMergeProperty(instances: IRNode[]): IRNode | null;
|
|
22
|
+
/**
|
|
23
|
+
* Detects discriminated union patterns where merging would lose
|
|
24
|
+
* semantic precision. A discriminated union requires:
|
|
25
|
+
* 1. A shared property with distinct const/single-value-enum per option
|
|
26
|
+
* (the "discriminator")
|
|
27
|
+
* 2. Every option has at least one property exclusive to only that option
|
|
28
|
+
* (variant-specific fields tied to the discriminator value)
|
|
29
|
+
*
|
|
30
|
+
* This distinguishes true tagged unions (circle+radius vs square+side)
|
|
31
|
+
* from schemas where single-value enums represent different values of
|
|
32
|
+
* the same field that should be merged (past/current/future → Timeframe).
|
|
33
|
+
*
|
|
34
|
+
* Pure helper — does not depend on any converter context.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isDiscriminatedUnion(options: IRNode[], sharedPropNames: string[], allPropNames: string[]): boolean;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { collectUnionPropertyNames, findDiscriminatorProperty, } from "./discriminatedUnions.js";
|
|
2
|
+
import { walkIR } from "./walk.js";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively walks the IR tree (bottom-up) and merges anyOf unions
|
|
5
|
+
* whose options are all objects with compatible property types.
|
|
6
|
+
* Merged enums collect values from all options; properties missing
|
|
7
|
+
* from some options become optional in the merged type.
|
|
8
|
+
*/
|
|
9
|
+
export function mergeCompatibleUnions(c, ir) {
|
|
10
|
+
return walkIR(ir, (node) => {
|
|
11
|
+
if (node.type === "union" &&
|
|
12
|
+
node.constraints?.combinator === "anyOf" &&
|
|
13
|
+
node.options &&
|
|
14
|
+
node.options.length > 1) {
|
|
15
|
+
return tryMergeObjectUnion(c, node);
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Attempts to merge all options of an anyOf union into a single object type.
|
|
22
|
+
* Returns the merged IRNode, or null if the options are not compatible.
|
|
23
|
+
*/
|
|
24
|
+
export function tryMergeObjectUnion(c, ir) {
|
|
25
|
+
const options = ir.options;
|
|
26
|
+
// All options must be objects
|
|
27
|
+
if (!options.every((opt) => opt.type === "object")) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
// Bail if any option has patternProperties
|
|
31
|
+
if (options.some((opt) => opt.patternProperties)) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
// Bail if options have conflicting additionalProperties values.
|
|
35
|
+
// Identical values (all false, all true, all same schema) are fine.
|
|
36
|
+
const apValues = options.map((opt) => opt.additionalProperties);
|
|
37
|
+
const hasAp = apValues.some((v) => v !== undefined);
|
|
38
|
+
if (hasAp) {
|
|
39
|
+
const serialized = apValues.map((v) => JSON.stringify(v ?? null));
|
|
40
|
+
if (!serialized.every((s) => s === serialized[0])) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Collect all property names in first-seen order across options
|
|
45
|
+
const { allPropNames, sharedPropNames } = collectUnionPropertyNames(options);
|
|
46
|
+
if (allPropNames.length === 0) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
// Only merge when options share at least one property name —
|
|
50
|
+
// disjoint objects should remain as a union to preserve semantics.
|
|
51
|
+
if (sharedPropNames.length === 0) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
// Detect discriminated unions: if a shared property has different
|
|
55
|
+
// const/single-value-enum values across options AND there are
|
|
56
|
+
// option-specific (non-shared) properties, this is a tagged union
|
|
57
|
+
// where merging would lose the correlation between discriminator
|
|
58
|
+
// and variant-specific fields.
|
|
59
|
+
if (isDiscriminatedUnion(options, sharedPropNames, allPropNames)) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
// Try to merge each property across all options
|
|
63
|
+
const mergedProperties = {};
|
|
64
|
+
for (const propName of allPropNames) {
|
|
65
|
+
const instances = [];
|
|
66
|
+
for (const opt of options) {
|
|
67
|
+
if (opt.properties?.[propName]) {
|
|
68
|
+
instances.push(opt.properties[propName]);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const merged = tryMergeProperty(instances);
|
|
72
|
+
if (!merged) {
|
|
73
|
+
return null; // Incompatible — bail out, keep as union
|
|
74
|
+
}
|
|
75
|
+
// Required only if property exists in ALL options AND required in all
|
|
76
|
+
const existsInAll = options.every((opt) => opt.properties?.[propName] !== undefined);
|
|
77
|
+
const requiredInAll = instances.every((inst) => inst.required === true);
|
|
78
|
+
merged.required = existsInAll && requiredInAll;
|
|
79
|
+
mergedProperties[propName] = merged;
|
|
80
|
+
}
|
|
81
|
+
// Derive a name from the union's path
|
|
82
|
+
const pathSegments = ir.path.split(".").filter((x) => !/^\d+$/.test(x));
|
|
83
|
+
const name = pathSegments[pathSegments.length - 1] || ir.title || "Merged";
|
|
84
|
+
const merged = {
|
|
85
|
+
...ir,
|
|
86
|
+
type: "object",
|
|
87
|
+
properties: mergedProperties,
|
|
88
|
+
signature: `merged:${++c.mergeCounter}`,
|
|
89
|
+
// explicitly nullify fields that don't apply to a merged object
|
|
90
|
+
options: undefined,
|
|
91
|
+
constraints: undefined,
|
|
92
|
+
};
|
|
93
|
+
if (name)
|
|
94
|
+
merged.name = name;
|
|
95
|
+
// Propagate additionalProperties when all options agree on the same value
|
|
96
|
+
if (hasAp) {
|
|
97
|
+
merged.additionalProperties = options[0].additionalProperties;
|
|
98
|
+
}
|
|
99
|
+
return merged;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Tries to merge multiple instances of the same property across union options.
|
|
103
|
+
* Returns the merged IRNode, or null if incompatible.
|
|
104
|
+
*
|
|
105
|
+
* Pure helper — does not depend on any converter context.
|
|
106
|
+
*/
|
|
107
|
+
export function tryMergeProperty(instances) {
|
|
108
|
+
if (instances.length === 0)
|
|
109
|
+
return null;
|
|
110
|
+
if (instances.length === 1)
|
|
111
|
+
return { ...instances[0] };
|
|
112
|
+
const isStringEnum = (ir) => ir.type === "enum" &&
|
|
113
|
+
ir.values?.every((v) => typeof v === "string");
|
|
114
|
+
const isStringLiteral = (ir) => ir.type === "literal" && typeof ir.constraints?.value === "string";
|
|
115
|
+
// Merge string enums and/or string literals into a single enum
|
|
116
|
+
if (instances.every((inst) => isStringEnum(inst) || isStringLiteral(inst))) {
|
|
117
|
+
const seen = new Set();
|
|
118
|
+
const mergedValues = [];
|
|
119
|
+
for (const inst of instances) {
|
|
120
|
+
const values = isStringEnum(inst)
|
|
121
|
+
? inst.values
|
|
122
|
+
: [inst.constraints.value];
|
|
123
|
+
for (const v of values) {
|
|
124
|
+
if (!seen.has(v)) {
|
|
125
|
+
seen.add(v);
|
|
126
|
+
mergedValues.push(v);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
type: "enum",
|
|
132
|
+
values: mergedValues,
|
|
133
|
+
path: instances[0].path,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// Same primitive type across all instances
|
|
137
|
+
const firstType = instances[0].type;
|
|
138
|
+
if (instances.every((inst) => inst.type === firstType) &&
|
|
139
|
+
["string", "number", "integer", "boolean", "null"].includes(firstType)) {
|
|
140
|
+
return { ...instances[0] };
|
|
141
|
+
}
|
|
142
|
+
// Same object signature across all instances
|
|
143
|
+
if (instances.every((inst) => inst.type === "object" && inst.signature) &&
|
|
144
|
+
instances.every((inst) => inst.signature === instances[0].signature)) {
|
|
145
|
+
return { ...instances[0] };
|
|
146
|
+
}
|
|
147
|
+
// Incompatible types
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Detects discriminated union patterns where merging would lose
|
|
152
|
+
* semantic precision. A discriminated union requires:
|
|
153
|
+
* 1. A shared property with distinct const/single-value-enum per option
|
|
154
|
+
* (the "discriminator")
|
|
155
|
+
* 2. Every option has at least one property exclusive to only that option
|
|
156
|
+
* (variant-specific fields tied to the discriminator value)
|
|
157
|
+
*
|
|
158
|
+
* This distinguishes true tagged unions (circle+radius vs square+side)
|
|
159
|
+
* from schemas where single-value enums represent different values of
|
|
160
|
+
* the same field that should be merged (past/current/future → Timeframe).
|
|
161
|
+
*
|
|
162
|
+
* Pure helper — does not depend on any converter context.
|
|
163
|
+
*/
|
|
164
|
+
export function isDiscriminatedUnion(options, sharedPropNames, allPropNames) {
|
|
165
|
+
const hasOptionSpecificProps = allPropNames.length > sharedPropNames.length;
|
|
166
|
+
if (!hasOptionSpecificProps) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
// Reuse findDiscriminatorProperty instead of inline loop
|
|
170
|
+
const discriminator = findDiscriminatorProperty(options, sharedPropNames);
|
|
171
|
+
if (!discriminator) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
// For a true discriminated union, every option must have at least one
|
|
175
|
+
// property that is exclusive to ONLY that option (no other option has it).
|
|
176
|
+
// This distinguishes { kind:"circle", radius } | { kind:"square", side }
|
|
177
|
+
// from { timeframe:"past", title } | { timeframe:"current", title } | { timeframe:"future" }
|
|
178
|
+
const sharedSet = new Set(sharedPropNames);
|
|
179
|
+
return options.every((opt) => {
|
|
180
|
+
const optProps = Object.keys(opt.properties ?? {});
|
|
181
|
+
return optProps.some((propName) => {
|
|
182
|
+
if (sharedSet.has(propName))
|
|
183
|
+
return false;
|
|
184
|
+
// Check if this prop appears in any other option
|
|
185
|
+
return !options.some((other) => other !== opt && other.properties?.[propName] !== undefined);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=mergeUnions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeUnions.js","sourceRoot":"","sources":["../../src/converter/mergeUnions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IRNode } from "../types.js";
|
|
2
|
+
import type { BaseConverterContext, RefTypeName, RefTypeNamingConfig } from "./BaseConverter.js";
|
|
3
|
+
/** Pure helper: singularize a word, respecting uncountable allow-lists. */
|
|
4
|
+
export declare function singularize(word: string, extraUncountable?: string[]): string;
|
|
5
|
+
/** Default ref-type naming configuration shared by all language converters. */
|
|
6
|
+
export declare function defaultRefTypeNamingConfig(): RefTypeNamingConfig;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the effective ref-type naming config for the given context: the
|
|
9
|
+
* default merged shallow with the language profile's `refTypeNamingConfig` overrides.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getRefTypeNamingConfig(c: BaseConverterContext): RefTypeNamingConfig;
|
|
12
|
+
/**
|
|
13
|
+
* Computes a path-derived, collision-free ref type name for a (signature, nodePath) pair.
|
|
14
|
+
*
|
|
15
|
+
* Algorithm:
|
|
16
|
+
* 1. Parse the path into segments and pick the array-item / `*` / regular postfix list.
|
|
17
|
+
* 2. Try increasingly more parent segments combined with each postfix.
|
|
18
|
+
* 3. If a refType already exists for (signature, proposedName), reuse it.
|
|
19
|
+
* 4. If no name is free after exhausting postfixes, fall back to `<base><N>` with a
|
|
20
|
+
* deterministic instance-scoped counter on `c.fallbackCounter`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getUniqueRefTypeName(c: BaseConverterContext, signature: string, nodePath: string): RefTypeName;
|
|
23
|
+
/** Default resolver for a ref-type name from an IR node and signature. */
|
|
24
|
+
export declare function defaultResolveRefTypeName(c: BaseConverterContext, ir: IRNode, signature: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Returns names of all extracted ref types in declaration order.
|
|
27
|
+
* Subclasses may filter further (e.g. to exclude the root type).
|
|
28
|
+
*/
|
|
29
|
+
export declare function computeExtractedTypeNames(c: BaseConverterContext): string[];
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import pluralize from "pluralize";
|
|
2
|
+
import { PathUtils } from "../utils/path-utils.js";
|
|
3
|
+
import { toPascalCase } from "../utils/to-pascal-case.js";
|
|
4
|
+
/** Default words that should not be singularized (common programming/API terms). */
|
|
5
|
+
const DEFAULT_UNCOUNTABLE_WORDS = ["data", "metadata"];
|
|
6
|
+
/** Pure helper: singularize a word, respecting uncountable allow-lists. */
|
|
7
|
+
export function singularize(word, extraUncountable) {
|
|
8
|
+
const uncountable = [...DEFAULT_UNCOUNTABLE_WORDS, ...(extraUncountable ?? [])];
|
|
9
|
+
if (uncountable.some((u) => word.toLowerCase().endsWith(u.toLowerCase()))) {
|
|
10
|
+
return word;
|
|
11
|
+
}
|
|
12
|
+
return pluralize.singular(word);
|
|
13
|
+
}
|
|
14
|
+
/** Default ref-type naming configuration shared by all language converters. */
|
|
15
|
+
export function defaultRefTypeNamingConfig() {
|
|
16
|
+
return {
|
|
17
|
+
postfixes: [
|
|
18
|
+
"Type", "Element", "Schema", "Object", "Shape", "Definition",
|
|
19
|
+
"Item", "Entry", "One", "Two", "Three", "Four", "Five",
|
|
20
|
+
"Six", "Seven", "Eight", "Nine", "Ten",
|
|
21
|
+
],
|
|
22
|
+
handleAnySymbol: true,
|
|
23
|
+
stripLeadingAnySymbol: true,
|
|
24
|
+
depluralize: true,
|
|
25
|
+
arrayItemNaming: false,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns the effective ref-type naming config for the given context: the
|
|
30
|
+
* default merged shallow with the language profile's `refTypeNamingConfig` overrides.
|
|
31
|
+
*/
|
|
32
|
+
export function getRefTypeNamingConfig(c) {
|
|
33
|
+
return { ...defaultRefTypeNamingConfig(), ...c.languageProfile.refTypeNamingConfig };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Computes a path-derived, collision-free ref type name for a (signature, nodePath) pair.
|
|
37
|
+
*
|
|
38
|
+
* Algorithm:
|
|
39
|
+
* 1. Parse the path into segments and pick the array-item / `*` / regular postfix list.
|
|
40
|
+
* 2. Try increasingly more parent segments combined with each postfix.
|
|
41
|
+
* 3. If a refType already exists for (signature, proposedName), reuse it.
|
|
42
|
+
* 4. If no name is free after exhausting postfixes, fall back to `<base><N>` with a
|
|
43
|
+
* deterministic instance-scoped counter on `c.fallbackCounter`.
|
|
44
|
+
*/
|
|
45
|
+
export function getUniqueRefTypeName(c, signature, nodePath) {
|
|
46
|
+
const config = getRefTypeNamingConfig(c);
|
|
47
|
+
const path = PathUtils.parsePath(nodePath);
|
|
48
|
+
const lastPathItem = nodePath.split(".").slice(-1)[0];
|
|
49
|
+
const isArrayItem = lastPathItem === "0";
|
|
50
|
+
const isAnySymbol = lastPathItem === "*";
|
|
51
|
+
const postFixes = [...config.postfixes];
|
|
52
|
+
if (isArrayItem) {
|
|
53
|
+
if (config.arrayItemNaming !== false) {
|
|
54
|
+
postFixes.unshift(config.arrayItemNaming ?? "Item");
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
postFixes.unshift("");
|
|
58
|
+
}
|
|
59
|
+
// When path is empty (root-level array), use the root schema name as context
|
|
60
|
+
if (path.length === 0 && c.rootName) {
|
|
61
|
+
path.push(c.rootName);
|
|
62
|
+
}
|
|
63
|
+
if (config.depluralize && path.length > 0 && path[path.length - 1]) {
|
|
64
|
+
path[path.length - 1] = singularize(path[path.length - 1], config.uncountableWords);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (config.handleAnySymbol && isAnySymbol) {
|
|
68
|
+
postFixes.unshift("AnyKey", "AnyProperty", "AnyField", "AnyIdentifier");
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
postFixes.unshift("");
|
|
72
|
+
}
|
|
73
|
+
let pathsSegmentsToInclude = 1;
|
|
74
|
+
let name = "";
|
|
75
|
+
let postFixIndexToTry = 0;
|
|
76
|
+
while (!name) {
|
|
77
|
+
let proposedName = path.slice(-pathsSegmentsToInclude).map(toPascalCase).join("") +
|
|
78
|
+
postFixes[postFixIndexToTry];
|
|
79
|
+
if (config.stripLeadingAnySymbol && proposedName[0] === "*") {
|
|
80
|
+
proposedName = proposedName.slice(1);
|
|
81
|
+
}
|
|
82
|
+
const foundSignatureMatch = c.refTypes.find((entry) => entry.signature === signature && entry.name === proposedName);
|
|
83
|
+
if (foundSignatureMatch) {
|
|
84
|
+
return foundSignatureMatch.name;
|
|
85
|
+
}
|
|
86
|
+
// Skip empty proposed names (e.g. empty path with no postfix)
|
|
87
|
+
if (!proposedName) {
|
|
88
|
+
postFixIndexToTry++;
|
|
89
|
+
if (postFixIndexToTry >= postFixes.length) {
|
|
90
|
+
do {
|
|
91
|
+
c.fallbackCounter++;
|
|
92
|
+
name = "Type" + c.fallbackCounter;
|
|
93
|
+
} while (c.usedDeclarationNames.has(name));
|
|
94
|
+
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const nameAlreadyUsed = c.usedDeclarationNames.has(proposedName);
|
|
98
|
+
if (nameAlreadyUsed) {
|
|
99
|
+
pathsSegmentsToInclude++;
|
|
100
|
+
if (pathsSegmentsToInclude >= path.length) {
|
|
101
|
+
postFixIndexToTry++;
|
|
102
|
+
pathsSegmentsToInclude = 1;
|
|
103
|
+
if (postFixIndexToTry === postFixes.length) {
|
|
104
|
+
// Deterministic instance-scoped fallback
|
|
105
|
+
do {
|
|
106
|
+
c.fallbackCounter++;
|
|
107
|
+
name = proposedName + c.fallbackCounter;
|
|
108
|
+
} while (c.usedDeclarationNames.has(name));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
name = proposedName;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
c.usedDeclarationNames.add(name);
|
|
117
|
+
return name;
|
|
118
|
+
}
|
|
119
|
+
/** Default resolver for a ref-type name from an IR node and signature. */
|
|
120
|
+
export function defaultResolveRefTypeName(c, ir, signature) {
|
|
121
|
+
return getUniqueRefTypeName(c, signature, ir.path);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Returns names of all extracted ref types in declaration order.
|
|
125
|
+
* Subclasses may filter further (e.g. to exclude the root type).
|
|
126
|
+
*/
|
|
127
|
+
export function computeExtractedTypeNames(c) {
|
|
128
|
+
return c.refTypes.map((entry) => entry.name);
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/converter/naming.ts"],"names":[],"mappings":"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"}
|