ajsc 5.2.4 → 7.1.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 +103 -0
- package/README.md +303 -144
- package/dist/converter/BaseConverter.d.ts +315 -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 +24 -0
- package/dist/converter/index.js +24 -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 +137 -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 +142 -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 +13 -0
- package/dist/kotlin/index.js +14 -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 +113 -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 +13 -0
- package/dist/swift/index.js +14 -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 +254 -0
- package/dist/typescript/TypescriptConverter.js.map +1 -0
- package/dist/typescript/index.d.ts +12 -0
- package/dist/typescript/index.js +13 -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 +39 -6
- 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 -1070
- 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 -606
- 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,315 @@
|
|
|
1
|
+
import { ILanguageConverter, IRNode, SignatureOccurrenceValue } from "../types.js";
|
|
2
|
+
export { walkIR } from "./walk.js";
|
|
3
|
+
export type RefTypeName = string;
|
|
4
|
+
export interface RefTypeEntry {
|
|
5
|
+
signature: SignatureOccurrenceValue["signature"];
|
|
6
|
+
name: RefTypeName;
|
|
7
|
+
code: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
doc?: string;
|
|
11
|
+
}
|
|
12
|
+
export type RefTypes = RefTypeEntry[];
|
|
13
|
+
/**
|
|
14
|
+
* Per-language configuration bundle. Each language subclass declares one
|
|
15
|
+
* `languageProfile` field; the base class reads from it instead of calling
|
|
16
|
+
* a method-per-knob. Optional fields fall through to the base default.
|
|
17
|
+
*/
|
|
18
|
+
export interface LanguageProfile {
|
|
19
|
+
/** Language identifier emitted as `language` on the converter. */
|
|
20
|
+
language: string;
|
|
21
|
+
/**
|
|
22
|
+
* When true, `getReferencedType` short-circuits IR nodes whose `name` matches
|
|
23
|
+
* the root name back to a direct self-reference (so e.g. a `Tree` schema with
|
|
24
|
+
* `children: Array<{$ref: "#"}>` emits as `children: Array<Tree>` rather than
|
|
25
|
+
* extracting a duplicate `Child` type). Default: true. All current languages
|
|
26
|
+
* use the default; this hook exists for hypothetical future targets that want
|
|
27
|
+
* a different recursion shape.
|
|
28
|
+
*/
|
|
29
|
+
detectSelfReferenceToRoot?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* When true, `enhanceDiscriminatedUnions` ALSO walks `oneOf` unions (in addition
|
|
32
|
+
* to `anyOf`). Default: false. Languages that emit a tagged-union form for `oneOf`
|
|
33
|
+
* (Kotlin sealed interface, Swift enum w/ associated values) override to true.
|
|
34
|
+
*/
|
|
35
|
+
processOneOfAsDiscriminatedUnion?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* When true, `applyDiscriminatedUnionEnhancements` populates `discriminatorInfo`
|
|
38
|
+
* for downstream consolidated enum emission. Default: false. TS overrides based
|
|
39
|
+
* on `enumStyle === "enum" && !inlineTypes`.
|
|
40
|
+
*/
|
|
41
|
+
shouldPopulateDiscriminatorInfo?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* When true, `stripDiscriminatorField` removes the discriminator key from variant
|
|
44
|
+
* payload bodies (because the language hoists it into a tag annotation or codable
|
|
45
|
+
* plumbing). Default: false. Kotlin = `isKotlinx`. Swift = `isCodable`.
|
|
46
|
+
*/
|
|
47
|
+
shouldEraseDiscriminator?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Custom ref-type naming configuration. Merged shallow over the BaseConverter default
|
|
50
|
+
* (postfix list, depluralize, etc.). Useful for adding language-specific postfixes
|
|
51
|
+
* (e.g. "Enum" in TS).
|
|
52
|
+
*/
|
|
53
|
+
refTypeNamingConfig?: Partial<RefTypeNamingConfig>;
|
|
54
|
+
/**
|
|
55
|
+
* Parent-name component used by `applyDiscriminatedUnionEnhancements` when deriving
|
|
56
|
+
* variant names. Default: last non-numeric segment of `ir.path`. Kotlin extends this
|
|
57
|
+
* with a fallback to `ir.name || ir.title`; Swift always returns "" (variants are
|
|
58
|
+
* nested in the enum, no parent suffix needed).
|
|
59
|
+
*/
|
|
60
|
+
getDiscriminatedVariantParentName?: (ir: IRNode) => string;
|
|
61
|
+
/**
|
|
62
|
+
* Override ref-type name resolution. `defaultResolver()` invokes the path-based
|
|
63
|
+
* default. TS uses this to apply enum-style overrides.
|
|
64
|
+
*/
|
|
65
|
+
resolveRefTypeName?: (ir: IRNode, signature: string, defaultResolver: () => string) => string;
|
|
66
|
+
/**
|
|
67
|
+
* Language-specific signature dedup decision. Default: false. TS = `dedupSignatures.has(sig)`.
|
|
68
|
+
*/
|
|
69
|
+
shouldReuseExistingSignature?: (signature: string) => boolean;
|
|
70
|
+
}
|
|
71
|
+
export interface RefTypeNamingConfig {
|
|
72
|
+
/** Base postfixes to try for name collision resolution */
|
|
73
|
+
postfixes: string[];
|
|
74
|
+
/** If true, singularize array item path segments (e.g. "entries" → "entry", "people" → "person") */
|
|
75
|
+
depluralize?: boolean;
|
|
76
|
+
/** If true, handle "*" path endings with AnyKey/AnyProperty postfixes */
|
|
77
|
+
handleAnySymbol?: boolean;
|
|
78
|
+
/** If true, strip leading "*" from proposed names */
|
|
79
|
+
stripLeadingAnySymbol?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Controls the postfix added to array item type names.
|
|
82
|
+
* - `false` (default) → no postfix, uses property name directly
|
|
83
|
+
* - `string` → custom postfix (e.g. "Item" → ContactsItem, "Element" → ContactsElement)
|
|
84
|
+
*/
|
|
85
|
+
arrayItemNaming?: string | false;
|
|
86
|
+
/**
|
|
87
|
+
* Additional words that should not be singularized when `depluralize` is true.
|
|
88
|
+
* Built-in uncountables: "data", "metadata".
|
|
89
|
+
* @example ["criteria", "alumni", "corpus"]
|
|
90
|
+
*/
|
|
91
|
+
uncountableWords?: string[];
|
|
92
|
+
}
|
|
93
|
+
export type GenerateTypeUtils = {
|
|
94
|
+
getReferencedType(ir: IRNode): string | undefined;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* The state-and-method surface that helper modules in `src/converter/`
|
|
98
|
+
* need to operate on a BaseConverter instance. BaseConverter implements
|
|
99
|
+
* this; helpers take it as their first argument.
|
|
100
|
+
*
|
|
101
|
+
* Using this interface (rather than the BaseConverter class itself) keeps
|
|
102
|
+
* helper modules from depending on the abstract class shape — they only
|
|
103
|
+
* see the concrete contract they need.
|
|
104
|
+
*
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
export interface BaseConverterContext {
|
|
108
|
+
readonly refTypes: RefTypeEntry[];
|
|
109
|
+
readonly usedDeclarationNames: Set<string>;
|
|
110
|
+
rootName?: string;
|
|
111
|
+
rootDoc?: string;
|
|
112
|
+
baseOpts?: BaseConverterOpts;
|
|
113
|
+
readonly variantNames: Map<IRNode, string>;
|
|
114
|
+
readonly discriminatorInfo: Map<IRNode, {
|
|
115
|
+
allValues: string[];
|
|
116
|
+
thisValue: string;
|
|
117
|
+
}>;
|
|
118
|
+
readonly dedupSignatures: Set<string>;
|
|
119
|
+
mergeCounter: number;
|
|
120
|
+
/** Used internally by `getUniqueRefTypeName`; exposed for the helper to mutate. */
|
|
121
|
+
fallbackCounter: number;
|
|
122
|
+
readonly languageProfile: LanguageProfile;
|
|
123
|
+
/** Subclass-implemented; called by `getReferencedType` after registering an entry. */
|
|
124
|
+
generateObjectType(ir: IRNode, utils: GenerateTypeUtils): string;
|
|
125
|
+
/** Returns a name not already in `usedDeclarationNames`, suffixing as needed. */
|
|
126
|
+
findAvailableName(base: string): string;
|
|
127
|
+
/** Locates a const-string discriminator property across union options. */
|
|
128
|
+
findDiscriminatorProperty(options: IRNode[], sharedPropNames: string[]): string | null;
|
|
129
|
+
/** Computes shared and combined property names across union options. */
|
|
130
|
+
collectUnionPropertyNames(options: IRNode[]): {
|
|
131
|
+
allPropNames: string[];
|
|
132
|
+
sharedPropNames: string[];
|
|
133
|
+
};
|
|
134
|
+
/** Returns a clone of `opt` with the discriminator property removed. */
|
|
135
|
+
stripDiscriminatorField(opt: IRNode, discriminator: string): IRNode;
|
|
136
|
+
/** Returns the const string value of an enum/literal IR, if any. */
|
|
137
|
+
getConstStringValue(ir: IRNode | undefined): string | undefined;
|
|
138
|
+
}
|
|
139
|
+
export interface BaseConverterOpts {
|
|
140
|
+
/** Overrides the IR root name (which defaults to schema.title or "Root"). */
|
|
141
|
+
rootTypeName?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Controls the postfix added to array item type names.
|
|
144
|
+
* - `false` (default) → no postfix, uses property name directly
|
|
145
|
+
* - `string` → custom postfix (e.g. "Item" → ContactsItem, "Element" → ContactsElement)
|
|
146
|
+
*/
|
|
147
|
+
arrayItemNaming?: string | false;
|
|
148
|
+
/**
|
|
149
|
+
* If true (default), singularize array item path segments when generating type names.
|
|
150
|
+
*/
|
|
151
|
+
depluralize?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Additional words that should not be singularized when `depluralize` is true.
|
|
154
|
+
*/
|
|
155
|
+
uncountableWords?: string[];
|
|
156
|
+
/**
|
|
157
|
+
* How to handle unions that survive merging with no discriminator.
|
|
158
|
+
* - `"throw"` (default) — throw with a path-bearing message
|
|
159
|
+
* - `"fallback"` — emit a language-specific fallback type (added in later tasks)
|
|
160
|
+
*/
|
|
161
|
+
unsupportedUnions?: "throw" | "fallback";
|
|
162
|
+
/**
|
|
163
|
+
* Shared registry of declaration names already emitted. When provided,
|
|
164
|
+
* the converter uses this Set as its `usedDeclarationNames` and mutates
|
|
165
|
+
* it as new types are emitted. Pass the same Set across multiple emit
|
|
166
|
+
* calls to avoid duplicate-name compile errors when the resulting code
|
|
167
|
+
* blocks are concatenated into one Kotlin/Swift namespace.
|
|
168
|
+
*
|
|
169
|
+
* Names that collide across calls fall through the standard collision-
|
|
170
|
+
* resolution path (parent path escalation, postfix list, then a numeric
|
|
171
|
+
* suffix). Pair with {@link namePrefix} for cleaner per-slot names.
|
|
172
|
+
*
|
|
173
|
+
* Most useful for Kotlin and Swift, which require named declarations for
|
|
174
|
+
* all non-primitive types. Harmless for TypeScript, which can use
|
|
175
|
+
* `inlineTypes: true` to flatten nested types instead.
|
|
176
|
+
*/
|
|
177
|
+
nameRegistry?: Set<string>;
|
|
178
|
+
/**
|
|
179
|
+
* Optional synthetic component prepended to every extracted (nested)
|
|
180
|
+
* type name during ref-type naming. With `namePrefix: "Body"`, a nested
|
|
181
|
+
* `address` field extracts as `BodyAddress` instead of `Address`.
|
|
182
|
+
*
|
|
183
|
+
* Useful when emitting multiple sibling schemas that share an output
|
|
184
|
+
* namespace — pair with {@link nameRegistry} and a per-slot
|
|
185
|
+
* {@link rootTypeName} to avoid all cross-call collisions.
|
|
186
|
+
*
|
|
187
|
+
* Does not affect the root type name (use `rootTypeName` for that).
|
|
188
|
+
* The prefix is sanitized via PascalCase, so non-identifier characters
|
|
189
|
+
* are stripped.
|
|
190
|
+
*/
|
|
191
|
+
namePrefix?: string;
|
|
192
|
+
}
|
|
193
|
+
export declare abstract class BaseConverter implements Partial<ILanguageConverter>, BaseConverterContext {
|
|
194
|
+
abstract readonly code: string;
|
|
195
|
+
/** @internal Public for `BaseConverterContext`; treat as protected for subclasses. */
|
|
196
|
+
abstract readonly languageProfile: LanguageProfile;
|
|
197
|
+
abstract readonly rootTypeName: string;
|
|
198
|
+
abstract readonly extractedTypeNames: string[];
|
|
199
|
+
abstract readonly imports: string[];
|
|
200
|
+
get language(): string;
|
|
201
|
+
/** @internal Public for `BaseConverterContext`; treat as protected for subclasses. */
|
|
202
|
+
refTypes: RefTypes;
|
|
203
|
+
/**
|
|
204
|
+
* Shared registry of all top-level declaration names (types + enums) for cross-namespace collision detection.
|
|
205
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
206
|
+
*/
|
|
207
|
+
usedDeclarationNames: Set<string>;
|
|
208
|
+
/**
|
|
209
|
+
* Root schema name, used as fallback context for root-level array item naming.
|
|
210
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
211
|
+
*/
|
|
212
|
+
rootName?: string;
|
|
213
|
+
/**
|
|
214
|
+
* Optional doc note attached to the root type declaration. Populated by
|
|
215
|
+
* subclasses (e.g. for additionalProperties annotations) since the root
|
|
216
|
+
* type is not held in the refTypes registry.
|
|
217
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
218
|
+
*/
|
|
219
|
+
rootDoc?: string;
|
|
220
|
+
/**
|
|
221
|
+
* Shared options available to all language converters.
|
|
222
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
223
|
+
*/
|
|
224
|
+
baseOpts?: BaseConverterOpts;
|
|
225
|
+
/** @internal Public for `BaseConverterContext`; treat as private. */
|
|
226
|
+
fallbackCounter: number;
|
|
227
|
+
/** @internal Public for `BaseConverterContext`; treat as protected for subclasses. */
|
|
228
|
+
mergeCounter: number;
|
|
229
|
+
/**
|
|
230
|
+
* Maps discriminator literal IR nodes to their consolidated enum info.
|
|
231
|
+
* Used by generateLiteralType and preRegisterEnumNames to emit a single
|
|
232
|
+
* consolidated enum and member references instead of single-value enums.
|
|
233
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
234
|
+
*/
|
|
235
|
+
discriminatorInfo: Map<IRNode, {
|
|
236
|
+
allValues: string[];
|
|
237
|
+
thisValue: string;
|
|
238
|
+
}>;
|
|
239
|
+
/**
|
|
240
|
+
* Maps variant IR nodes to their enhancement-assigned names.
|
|
241
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
242
|
+
*/
|
|
243
|
+
variantNames: Map<IRNode, string>;
|
|
244
|
+
/**
|
|
245
|
+
* Signatures eligible for cross-variant deduplication.
|
|
246
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
247
|
+
*/
|
|
248
|
+
dedupSignatures: Set<string>;
|
|
249
|
+
/**
|
|
250
|
+
* Returns names of all extracted ref types in declaration order.
|
|
251
|
+
* Subclasses may filter further (e.g. to exclude the root type).
|
|
252
|
+
*/
|
|
253
|
+
protected computeExtractedTypeNames(): string[];
|
|
254
|
+
/** Path-derived, collision-free ref type name. Delegates to `naming.ts`. */
|
|
255
|
+
protected getUniqueRefTypeName(signature: string, nodePath: string): RefTypeName;
|
|
256
|
+
/**
|
|
257
|
+
* Each language subclass must implement object-literal emission.
|
|
258
|
+
* `getReferencedType` calls this when registering a new ref type.
|
|
259
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
260
|
+
*/
|
|
261
|
+
abstract generateObjectType(ir: IRNode, utils: GenerateTypeUtils): string;
|
|
262
|
+
/** Resolves an IR node to its registered ref-type name. Delegates to `registry.ts`. */
|
|
263
|
+
protected getReferencedType(ir: IRNode): string | undefined;
|
|
264
|
+
/**
|
|
265
|
+
* Recursively walks the IR tree (bottom-up) and merges anyOf unions
|
|
266
|
+
* whose options are all objects with compatible property types.
|
|
267
|
+
* Delegates to `mergeUnions.ts`.
|
|
268
|
+
*/
|
|
269
|
+
protected mergeCompatibleUnions(ir: IRNode): IRNode;
|
|
270
|
+
/** Delegates to `mergeUnions.ts`. */
|
|
271
|
+
protected tryMergeObjectUnion(ir: IRNode): IRNode | null;
|
|
272
|
+
/** Delegates to `mergeUnions.ts`. */
|
|
273
|
+
protected tryMergeProperty(instances: IRNode[]): IRNode | null;
|
|
274
|
+
/** Delegates to `mergeUnions.ts`. */
|
|
275
|
+
protected isDiscriminatedUnion(options: IRNode[], sharedPropNames: string[], allPropNames: string[]): boolean;
|
|
276
|
+
/**
|
|
277
|
+
* Walks the IR tree and applies discriminated union enhancements
|
|
278
|
+
* to anyOf unions that survived merging. Delegates to `discriminatedUnions.ts`.
|
|
279
|
+
*/
|
|
280
|
+
protected enhanceDiscriminatedUnions(ir: IRNode): void;
|
|
281
|
+
/**
|
|
282
|
+
* Delegates to `discriminatedUnions.ts`.
|
|
283
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
284
|
+
*/
|
|
285
|
+
stripDiscriminatorField(opt: IRNode, discriminator: string): IRNode;
|
|
286
|
+
/**
|
|
287
|
+
* Returns `base` if it is not already taken in `usedDeclarationNames`,
|
|
288
|
+
* otherwise appends an incrementing suffix (`base2`, `base3`, …) until a
|
|
289
|
+
* free name is found. Subclasses use this for collision-free declaration
|
|
290
|
+
* names where path-derived disambiguation is not appropriate (e.g. enum
|
|
291
|
+
* names derived from a property name).
|
|
292
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
293
|
+
*/
|
|
294
|
+
findAvailableName(base: string): string;
|
|
295
|
+
/** Delegates to `discriminatedUnions.ts`. */
|
|
296
|
+
protected applyDiscriminatedUnionEnhancements(ir: IRNode): void;
|
|
297
|
+
/**
|
|
298
|
+
* Delegates to `discriminatedUnions.ts`.
|
|
299
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
300
|
+
*/
|
|
301
|
+
collectUnionPropertyNames(options: IRNode[]): {
|
|
302
|
+
allPropNames: string[];
|
|
303
|
+
sharedPropNames: string[];
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Delegates to `discriminatedUnions.ts`.
|
|
307
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
308
|
+
*/
|
|
309
|
+
findDiscriminatorProperty(options: IRNode[], sharedPropNames: string[]): string | null;
|
|
310
|
+
/**
|
|
311
|
+
* Delegates to `discriminatedUnions.ts`.
|
|
312
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
313
|
+
*/
|
|
314
|
+
getConstStringValue(ir: IRNode | undefined): string | undefined;
|
|
315
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { computeExtractedTypeNames, getUniqueRefTypeName, } from "./naming.js";
|
|
2
|
+
import { getReferencedType } from "./registry.js";
|
|
3
|
+
import { isDiscriminatedUnion, mergeCompatibleUnions, tryMergeObjectUnion, tryMergeProperty, } from "./mergeUnions.js";
|
|
4
|
+
import { applyDiscriminatedUnionEnhancements, collectUnionPropertyNames, enhanceDiscriminatedUnions, findDiscriminatorProperty, getConstStringValue, stripDiscriminatorField, } from "./discriminatedUnions.js";
|
|
5
|
+
export { walkIR } from "./walk.js";
|
|
6
|
+
export class BaseConverter {
|
|
7
|
+
constructor() {
|
|
8
|
+
/** @internal Public for `BaseConverterContext`; treat as protected for subclasses. */
|
|
9
|
+
this.refTypes = [];
|
|
10
|
+
/**
|
|
11
|
+
* Shared registry of all top-level declaration names (types + enums) for cross-namespace collision detection.
|
|
12
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
13
|
+
*/
|
|
14
|
+
this.usedDeclarationNames = new Set();
|
|
15
|
+
/** @internal Public for `BaseConverterContext`; treat as private. */
|
|
16
|
+
this.fallbackCounter = 0;
|
|
17
|
+
/** @internal Public for `BaseConverterContext`; treat as protected for subclasses. */
|
|
18
|
+
this.mergeCounter = 0;
|
|
19
|
+
/**
|
|
20
|
+
* Maps discriminator literal IR nodes to their consolidated enum info.
|
|
21
|
+
* Used by generateLiteralType and preRegisterEnumNames to emit a single
|
|
22
|
+
* consolidated enum and member references instead of single-value enums.
|
|
23
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
24
|
+
*/
|
|
25
|
+
this.discriminatorInfo = new Map();
|
|
26
|
+
/**
|
|
27
|
+
* Maps variant IR nodes to their enhancement-assigned names.
|
|
28
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
29
|
+
*/
|
|
30
|
+
this.variantNames = new Map();
|
|
31
|
+
/**
|
|
32
|
+
* Signatures eligible for cross-variant deduplication.
|
|
33
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
34
|
+
*/
|
|
35
|
+
this.dedupSignatures = new Set();
|
|
36
|
+
}
|
|
37
|
+
get language() {
|
|
38
|
+
return this.languageProfile.language;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns names of all extracted ref types in declaration order.
|
|
42
|
+
* Subclasses may filter further (e.g. to exclude the root type).
|
|
43
|
+
*/
|
|
44
|
+
computeExtractedTypeNames() {
|
|
45
|
+
return computeExtractedTypeNames(this);
|
|
46
|
+
}
|
|
47
|
+
/** Path-derived, collision-free ref type name. Delegates to `naming.ts`. */
|
|
48
|
+
getUniqueRefTypeName(signature, nodePath) {
|
|
49
|
+
return getUniqueRefTypeName(this, signature, nodePath);
|
|
50
|
+
}
|
|
51
|
+
/** Resolves an IR node to its registered ref-type name. Delegates to `registry.ts`. */
|
|
52
|
+
getReferencedType(ir) {
|
|
53
|
+
return getReferencedType(this, ir);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Recursively walks the IR tree (bottom-up) and merges anyOf unions
|
|
57
|
+
* whose options are all objects with compatible property types.
|
|
58
|
+
* Delegates to `mergeUnions.ts`.
|
|
59
|
+
*/
|
|
60
|
+
mergeCompatibleUnions(ir) {
|
|
61
|
+
return mergeCompatibleUnions(this, ir);
|
|
62
|
+
}
|
|
63
|
+
/** Delegates to `mergeUnions.ts`. */
|
|
64
|
+
tryMergeObjectUnion(ir) {
|
|
65
|
+
return tryMergeObjectUnion(this, ir);
|
|
66
|
+
}
|
|
67
|
+
/** Delegates to `mergeUnions.ts`. */
|
|
68
|
+
tryMergeProperty(instances) {
|
|
69
|
+
return tryMergeProperty(instances);
|
|
70
|
+
}
|
|
71
|
+
/** Delegates to `mergeUnions.ts`. */
|
|
72
|
+
isDiscriminatedUnion(options, sharedPropNames, allPropNames) {
|
|
73
|
+
return isDiscriminatedUnion(options, sharedPropNames, allPropNames);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Walks the IR tree and applies discriminated union enhancements
|
|
77
|
+
* to anyOf unions that survived merging. Delegates to `discriminatedUnions.ts`.
|
|
78
|
+
*/
|
|
79
|
+
enhanceDiscriminatedUnions(ir) {
|
|
80
|
+
enhanceDiscriminatedUnions(this, ir);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Delegates to `discriminatedUnions.ts`.
|
|
84
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
85
|
+
*/
|
|
86
|
+
stripDiscriminatorField(opt, discriminator) {
|
|
87
|
+
return stripDiscriminatorField(this, opt, discriminator);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Returns `base` if it is not already taken in `usedDeclarationNames`,
|
|
91
|
+
* otherwise appends an incrementing suffix (`base2`, `base3`, …) until a
|
|
92
|
+
* free name is found. Subclasses use this for collision-free declaration
|
|
93
|
+
* names where path-derived disambiguation is not appropriate (e.g. enum
|
|
94
|
+
* names derived from a property name).
|
|
95
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
96
|
+
*/
|
|
97
|
+
findAvailableName(base) {
|
|
98
|
+
if (!this.usedDeclarationNames.has(base))
|
|
99
|
+
return base;
|
|
100
|
+
let i = 2;
|
|
101
|
+
while (this.usedDeclarationNames.has(base + i))
|
|
102
|
+
i++;
|
|
103
|
+
return base + i;
|
|
104
|
+
}
|
|
105
|
+
/** Delegates to `discriminatedUnions.ts`. */
|
|
106
|
+
applyDiscriminatedUnionEnhancements(ir) {
|
|
107
|
+
applyDiscriminatedUnionEnhancements(this, ir);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Delegates to `discriminatedUnions.ts`.
|
|
111
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
112
|
+
*/
|
|
113
|
+
collectUnionPropertyNames(options) {
|
|
114
|
+
return collectUnionPropertyNames(options);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Delegates to `discriminatedUnions.ts`.
|
|
118
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
119
|
+
*/
|
|
120
|
+
findDiscriminatorProperty(options, sharedPropNames) {
|
|
121
|
+
return findDiscriminatorProperty(options, sharedPropNames);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Delegates to `discriminatedUnions.ts`.
|
|
125
|
+
* @internal Public for `BaseConverterContext`; treat as protected for subclasses.
|
|
126
|
+
*/
|
|
127
|
+
getConstStringValue(ir) {
|
|
128
|
+
return getConstStringValue(ir);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=BaseConverter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseConverter.js","sourceRoot":"","sources":["../../src/converter/BaseConverter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface EmitterOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Indentation unit (string repeated per nesting level). Defaults to two spaces.
|
|
4
|
+
* Common values: `" "` (2 spaces, Kotlin convention), `" "` (4 spaces, Swift).
|
|
5
|
+
*/
|
|
6
|
+
indentUnit?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Indent-aware string builder for code emission. Tracks nesting depth via
|
|
10
|
+
* `block()` and emits a single line at the current depth via `line()`.
|
|
11
|
+
*
|
|
12
|
+
* Designed so that all current Kotlin/Swift output can be reproduced without
|
|
13
|
+
* any hardcoded pad strings inside the emit logic.
|
|
14
|
+
*/
|
|
15
|
+
export declare class Emitter {
|
|
16
|
+
private readonly indentUnit;
|
|
17
|
+
private currentIndent;
|
|
18
|
+
private readonly lines;
|
|
19
|
+
constructor(opts?: EmitterOptions);
|
|
20
|
+
/** Emit a line at the current indent. Empty string emits a blank line with no indent. */
|
|
21
|
+
line(s?: string): this;
|
|
22
|
+
/** Emit a blank line (no indent). */
|
|
23
|
+
blank(): this;
|
|
24
|
+
/**
|
|
25
|
+
* Emit `header + " {"`, then run `body` at one deeper indent, then emit `footer`.
|
|
26
|
+
* Footer defaults to `"}"`.
|
|
27
|
+
*/
|
|
28
|
+
block(header: string, body: () => void, footer?: string): this;
|
|
29
|
+
/**
|
|
30
|
+
* Emit pre-formatted multi-line content at current indent. Each non-empty
|
|
31
|
+
* source line is prefixed with the current indent; empty source lines stay empty.
|
|
32
|
+
*/
|
|
33
|
+
raw(s: string): this;
|
|
34
|
+
toString(): string;
|
|
35
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Indent-aware string builder for code emission. Tracks nesting depth via
|
|
3
|
+
* `block()` and emits a single line at the current depth via `line()`.
|
|
4
|
+
*
|
|
5
|
+
* Designed so that all current Kotlin/Swift output can be reproduced without
|
|
6
|
+
* any hardcoded pad strings inside the emit logic.
|
|
7
|
+
*/
|
|
8
|
+
export class Emitter {
|
|
9
|
+
constructor(opts = {}) {
|
|
10
|
+
this.currentIndent = "";
|
|
11
|
+
this.lines = [];
|
|
12
|
+
this.indentUnit = opts.indentUnit ?? " ";
|
|
13
|
+
}
|
|
14
|
+
/** Emit a line at the current indent. Empty string emits a blank line with no indent. */
|
|
15
|
+
line(s = "") {
|
|
16
|
+
this.lines.push(s.length ? this.currentIndent + s : "");
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
/** Emit a blank line (no indent). */
|
|
20
|
+
blank() {
|
|
21
|
+
this.lines.push("");
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Emit `header + " {"`, then run `body` at one deeper indent, then emit `footer`.
|
|
26
|
+
* Footer defaults to `"}"`.
|
|
27
|
+
*/
|
|
28
|
+
block(header, body, footer = "}") {
|
|
29
|
+
this.line(header + " {");
|
|
30
|
+
this.currentIndent += this.indentUnit;
|
|
31
|
+
body();
|
|
32
|
+
this.currentIndent = this.currentIndent.slice(0, -this.indentUnit.length);
|
|
33
|
+
this.line(footer);
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Emit pre-formatted multi-line content at current indent. Each non-empty
|
|
38
|
+
* source line is prefixed with the current indent; empty source lines stay empty.
|
|
39
|
+
*/
|
|
40
|
+
raw(s) {
|
|
41
|
+
for (const ln of s.split("\n")) {
|
|
42
|
+
this.lines.push(ln.length ? this.currentIndent + ln : "");
|
|
43
|
+
}
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
toString() {
|
|
47
|
+
return this.lines.join("\n");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=Emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Emitter.js","sourceRoot":"","sources":["../../src/converter/Emitter.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,MAAM,OAAO,OAAO;IAKlB,YAAY,OAAuB,EAAE;QAH7B,kBAAa,GAAG,EAAE,CAAC;QACV,UAAK,GAAa,EAAE,CAAC;QAGpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;IAC5C,CAAC;IAED,yFAAyF;IACzF,IAAI,CAAC,CAAC,GAAG,EAAE;QACT,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IACrC,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAc,EAAE,IAAgB,EAAE,MAAM,GAAG,GAAG;QAClD,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,UAAU,CAAC;QACtC,IAAI,EAAE,CAAC;QACP,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC1E,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,GAAG,CAAC,CAAS;QACX,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { IRNode } from "../types.js";
|
|
2
|
+
import type { BaseConverterContext } from "./BaseConverter.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 declare function collectUnionPropertyNames(options: IRNode[]): {
|
|
10
|
+
allPropNames: string[];
|
|
11
|
+
sharedPropNames: string[];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Extracts a single const string value from an IR node (literal with string
|
|
15
|
+
* value or single-value string enum).
|
|
16
|
+
*
|
|
17
|
+
* Pure helper — does not depend on any converter context.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getConstStringValue(ir: IRNode | undefined): string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Finds the discriminator property among shared properties: a property where
|
|
22
|
+
* each option has a distinct const or single-value-enum string value.
|
|
23
|
+
*/
|
|
24
|
+
export declare function findDiscriminatorProperty(options: IRNode[], sharedPropNames: string[]): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Walks the IR tree and applies discriminated union enhancements
|
|
27
|
+
* to anyOf unions that survived merging. Subclasses may opt in to also
|
|
28
|
+
* process `oneOf` unions via the `processOneOfAsDiscriminatedUnion`
|
|
29
|
+
* field on `languageProfile`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function enhanceDiscriminatedUnions(c: BaseConverterContext, ir: IRNode): void;
|
|
32
|
+
/**
|
|
33
|
+
* Enhances an unmerged anyOf union that has a discriminator property.
|
|
34
|
+
* Sets `ir.name` on each variant to a discriminator-derived name and
|
|
35
|
+
* populates `discriminatorInfo` for consolidated enum emission.
|
|
36
|
+
*/
|
|
37
|
+
export declare function applyDiscriminatedUnionEnhancements(c: BaseConverterContext, ir: IRNode): void;
|
|
38
|
+
/**
|
|
39
|
+
* Returns a copy of the variant IR node with the discriminator property removed
|
|
40
|
+
* when `languageProfile.shouldEraseDiscriminator` is true. Otherwise returns the original.
|
|
41
|
+
*
|
|
42
|
+
* Used by language emitters that hoist the discriminator into a sealed-interface
|
|
43
|
+
* annotation (Kotlin `@JsonClassDiscriminator`) or a Codable plumbing block (Swift
|
|
44
|
+
* generated `init(from:)`/`encode(to:)`), where carrying the field on the variant
|
|
45
|
+
* struct would cause a duplicate-key error during decode.
|
|
46
|
+
*/
|
|
47
|
+
export declare function stripDiscriminatorField(c: BaseConverterContext, opt: IRNode, discriminator: string): IRNode;
|