@wavemaker-ai/react-codegen 1.0.0-rc.647684 → 12.0.0-rc.335
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/command.js +52 -7
- package/command.js.map +1 -1
- package/dist/transpiler/index.d.mts +42 -1
- package/dist/transpiler/index.mjs +682 -90
- package/dist/transpiler/index.mjs.map +1 -1
- package/dist/transpiler/wm-styles.css +10 -20
- package/index.js +7 -0
- package/index.js.map +1 -1
- package/package-lock.json +102 -102
- package/package.json +1 -1
- package/src/app.generator.js +223 -35
- package/src/app.generator.js.map +1 -1
- package/src/handlebar-helpers.js +32 -0
- package/src/handlebar-helpers.js.map +1 -1
- package/src/increment-builder.js +32 -2
- package/src/increment-builder.js.map +1 -1
- package/src/profiles/profile.js +2 -0
- package/src/profiles/profile.js.map +1 -1
- package/src/profiles/web-preview.profile.js +4 -0
- package/src/profiles/web-preview.profile.js.map +1 -1
- package/src/services/designtime-collector.js +235 -0
- package/src/services/designtime-collector.js.map +1 -0
- package/src/services/doc-normalizer.js +185 -0
- package/src/services/doc-normalizer.js.map +1 -0
- package/src/services/method-emitter.js +367 -0
- package/src/services/method-emitter.js.map +1 -0
- package/src/services/model-emitter.js +281 -0
- package/src/services/model-emitter.js.map +1 -0
- package/src/services/schema-to-ts.js +50 -0
- package/src/services/schema-to-ts.js.map +1 -0
- package/src/services/service.generator.js +223 -0
- package/src/services/service.generator.js.map +1 -0
- package/src/transpile/bind.ex.transformer.js +4 -1
- package/src/transpile/bind.ex.transformer.js.map +1 -1
- package/src/transpile/components/container/accordion.transformer.js +4 -4
- package/src/transpile/components/container/accordion.transformer.js.map +1 -1
- package/src/transpile/components/container/tabs.transformer.js +4 -2
- package/src/transpile/components/container/tabs.transformer.js.map +1 -1
- package/src/transpile/components/data/list/list-transformer.js +7 -2
- package/src/transpile/components/data/list/list-transformer.js.map +1 -1
- package/src/transpile/components/data/table/table.transformer.js +14 -20
- package/src/transpile/components/data/table/table.transformer.js.map +1 -1
- package/src/transpile/components/data/table/utils.js +90 -0
- package/src/transpile/components/data/table/utils.js.map +1 -1
- package/src/transpile/components/dialogs/dialog-actions.transformer.js +4 -6
- package/src/transpile/components/dialogs/dialog-actions.transformer.js.map +1 -1
- package/src/transpile/components/dialogs/dialog.transformer.js +14 -3
- package/src/transpile/components/dialogs/dialog.transformer.js.map +1 -1
- package/src/transpile/components/layout/layout-region-factory.js +8 -2
- package/src/transpile/components/layout/layout-region-factory.js.map +1 -1
- package/src/transpile/components/nav/nav.transformer.js +3 -5
- package/src/transpile/components/nav/nav.transformer.js.map +1 -1
- package/src/transpile/components/utils.js +11 -5
- package/src/transpile/components/utils.js.map +1 -1
- package/src/transpile/transpile.js +62 -21
- package/src/transpile/transpile.js.map +1 -1
- package/src/transpile/variables-template-source.js +2 -2
- package/src/transpile/variables-template-source.js.map +1 -1
- package/src/utils.browser.js +51 -6
- package/src/utils.browser.js.map +1 -1
- package/src/variables/variable.transformer.js +623 -12
- package/src/variables/variable.transformer.js.map +1 -1
- package/templates/project/app/client.layout.tsx +7 -7
- package/templates/project/app/components.css +10 -0
- package/templates/project/app/widgetInlineStylesOverride.css +0 -20
- package/templates/project/package.json +6 -5
- package/templates/project/services/base.service.ts +361 -0
- package/templates/service/service-class.hbs +19 -0
- package/templates/variables.template +67 -1
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Emits one method per operation: every declared parameter becomes a positional argument, in the
|
|
4
|
+
* doc's order, named from `x-WM-ORIGINAL-NAME`. Types come from the service's shared models
|
|
5
|
+
* (model-emitter.ts) — this file emits none of its own.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.toModelTypeName = void 0;
|
|
9
|
+
exports.emitMethod = emitMethod;
|
|
10
|
+
const model_emitter_1 = require("./model-emitter");
|
|
11
|
+
Object.defineProperty(exports, "toModelTypeName", { enumerable: true, get: function () { return model_emitter_1.toModelTypeName; } });
|
|
12
|
+
/** Marks the query params Spring binds into a single `Pageable` controller argument. */
|
|
13
|
+
const PAGEABLE_RESOLVER = "org.springframework.data.domain.Pageable";
|
|
14
|
+
const PAGEABLE_PARAM_NAMES = new Set(["page", "size", "sort"]);
|
|
15
|
+
const RESERVED_IDENTIFIERS = new Set([
|
|
16
|
+
"break",
|
|
17
|
+
"case",
|
|
18
|
+
"catch",
|
|
19
|
+
"class",
|
|
20
|
+
"const",
|
|
21
|
+
"continue",
|
|
22
|
+
"debugger",
|
|
23
|
+
"default",
|
|
24
|
+
"delete",
|
|
25
|
+
"do",
|
|
26
|
+
"else",
|
|
27
|
+
"export",
|
|
28
|
+
"extends",
|
|
29
|
+
"false",
|
|
30
|
+
"finally",
|
|
31
|
+
"for",
|
|
32
|
+
"function",
|
|
33
|
+
"if",
|
|
34
|
+
"import",
|
|
35
|
+
"in",
|
|
36
|
+
"instanceof",
|
|
37
|
+
"new",
|
|
38
|
+
"null",
|
|
39
|
+
"return",
|
|
40
|
+
"super",
|
|
41
|
+
"switch",
|
|
42
|
+
"this",
|
|
43
|
+
"throw",
|
|
44
|
+
"true",
|
|
45
|
+
"try",
|
|
46
|
+
"typeof",
|
|
47
|
+
"var",
|
|
48
|
+
"void",
|
|
49
|
+
"while",
|
|
50
|
+
"with",
|
|
51
|
+
"yield",
|
|
52
|
+
"let",
|
|
53
|
+
"static",
|
|
54
|
+
"enum",
|
|
55
|
+
"await",
|
|
56
|
+
"implements",
|
|
57
|
+
"package",
|
|
58
|
+
"protected",
|
|
59
|
+
"interface",
|
|
60
|
+
"private",
|
|
61
|
+
"public",
|
|
62
|
+
]);
|
|
63
|
+
function toSafeIdentifier(name) {
|
|
64
|
+
const base = String(name || "param")
|
|
65
|
+
.replace(/[^A-Za-z0-9_$]/g, "_")
|
|
66
|
+
.replace(/^(\d)/, "_$1");
|
|
67
|
+
const identifier = base || "param";
|
|
68
|
+
return RESERVED_IDENTIFIERS.has(identifier) ? `${identifier}Param` : identifier;
|
|
69
|
+
}
|
|
70
|
+
/** The declared argument name: `x-WM-ORIGINAL-NAME` when WM recorded one, else the camelCased wire name. */
|
|
71
|
+
function declaredArgName(param) {
|
|
72
|
+
const original = param["x-WM-ORIGINAL-NAME"];
|
|
73
|
+
if (typeof original === "string" && original) {
|
|
74
|
+
return toSafeIdentifier(original);
|
|
75
|
+
}
|
|
76
|
+
const wire = String(param.name || "arg");
|
|
77
|
+
const words = wire.split(/[^a-zA-Z0-9]+/).filter(Boolean);
|
|
78
|
+
const camel = words
|
|
79
|
+
.map((w, i) => i === 0 ? w.charAt(0).toLowerCase() + w.slice(1) : w.charAt(0).toUpperCase() + w.slice(1))
|
|
80
|
+
.join("");
|
|
81
|
+
return toSafeIdentifier(camel || "arg");
|
|
82
|
+
}
|
|
83
|
+
function paramSchema(param) {
|
|
84
|
+
if (param.schema)
|
|
85
|
+
return param.schema;
|
|
86
|
+
return {
|
|
87
|
+
type: param.type || "string",
|
|
88
|
+
format: param.format,
|
|
89
|
+
enum: param.enum,
|
|
90
|
+
items: param.items,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Resolves a schema to a TS type expression, referencing shared models via $ref. */
|
|
94
|
+
function schemaTsType(schema, ctx, imports) {
|
|
95
|
+
return (0, model_emitter_1.typeExpr)(schema, {
|
|
96
|
+
definitions: ctx.definitions,
|
|
97
|
+
registry: ctx.models.tsNameByDefinition,
|
|
98
|
+
arity: new Map(Array.from(ctx.models.typeParamsByDefinition, ([name, params]) => [name, params.length])),
|
|
99
|
+
imports,
|
|
100
|
+
// No self-reference to exclude here: a controller file is never a model file, so every
|
|
101
|
+
// referenced model is a genuine import.
|
|
102
|
+
selfName: "",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function isPageableParam(param) {
|
|
106
|
+
return (param["x-WM-RESOLVER"] === PAGEABLE_RESOLVER ||
|
|
107
|
+
(param.in === "query" &&
|
|
108
|
+
param["x-WM-EDITABLE"] === false &&
|
|
109
|
+
PAGEABLE_PARAM_NAMES.has(param.name)));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Splits declared parameters into positional arguments. The `x-WM-RESOLVER`-marked page/size/sort
|
|
113
|
+
* trio collapses back into one `pageable`, since that is the single object the backend binds them
|
|
114
|
+
* into.
|
|
115
|
+
*/
|
|
116
|
+
function buildArgs(operation, pathTemplate, ctx, imports) {
|
|
117
|
+
const params = operation.parameters || [];
|
|
118
|
+
const args = [];
|
|
119
|
+
const pageableNames = [];
|
|
120
|
+
let pageableIndex = -1;
|
|
121
|
+
const usedNames = new Set();
|
|
122
|
+
const claimName = (preferred) => {
|
|
123
|
+
let name = preferred;
|
|
124
|
+
let suffix = 2;
|
|
125
|
+
while (usedNames.has(name)) {
|
|
126
|
+
name = `${preferred}${suffix++}`;
|
|
127
|
+
}
|
|
128
|
+
usedNames.add(name);
|
|
129
|
+
return name;
|
|
130
|
+
};
|
|
131
|
+
params.forEach(param => {
|
|
132
|
+
if (isPageableParam(param)) {
|
|
133
|
+
if (pageableIndex < 0) {
|
|
134
|
+
pageableIndex = args.length;
|
|
135
|
+
args.push({
|
|
136
|
+
name: "pageable",
|
|
137
|
+
tsType: "",
|
|
138
|
+
optional: true,
|
|
139
|
+
source: { kind: "pageable", paramNames: pageableNames },
|
|
140
|
+
});
|
|
141
|
+
usedNames.add("pageable");
|
|
142
|
+
}
|
|
143
|
+
pageableNames.push(param.name);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const kind = param.in === "path"
|
|
147
|
+
? "path"
|
|
148
|
+
: param.in === "body"
|
|
149
|
+
? "body"
|
|
150
|
+
: param.in === "formData"
|
|
151
|
+
? "formData"
|
|
152
|
+
: param.in === "header"
|
|
153
|
+
? "header"
|
|
154
|
+
: "query";
|
|
155
|
+
args.push({
|
|
156
|
+
name: claimName(declaredArgName(param)),
|
|
157
|
+
tsType: schemaTsType(paramSchema(param), ctx, imports),
|
|
158
|
+
optional: !param.required,
|
|
159
|
+
source: { kind, paramName: param.name },
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
// Path arguments must follow the URL TEMPLATE's order, not the order `parameters[]` happens to
|
|
163
|
+
// declare them in — the two genuinely disagree in real docs (e.g.
|
|
164
|
+
// `/{categoryID}/characteristic/{key}` declaring [key, categoryID]). Since the invokeHttp glue
|
|
165
|
+
// passes these positionally, trusting the declared order silently swaps the two values.
|
|
166
|
+
// Any `{token}` with no declared parameter still has to be interpolated, so it is added here.
|
|
167
|
+
const pathTokens = Array.from(pathTemplate.matchAll(/\{([^}]+)\}/g)).map(m => m[1]);
|
|
168
|
+
const pathArgsByToken = new Map(args
|
|
169
|
+
.filter(a => a.source.kind === "path")
|
|
170
|
+
.map(a => [a.source.paramName, a]));
|
|
171
|
+
const orderedPathArgs = pathTokens.map(token => {
|
|
172
|
+
var _a;
|
|
173
|
+
return (_a = pathArgsByToken.get(token)) !== null && _a !== void 0 ? _a : {
|
|
174
|
+
name: claimName(toSafeIdentifier(token)),
|
|
175
|
+
tsType: "string",
|
|
176
|
+
optional: false,
|
|
177
|
+
source: { kind: "path", paramName: token },
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
// Path args lead, in template order; everything else keeps its declared order after them.
|
|
181
|
+
const nonPathArgs = args.filter(a => a.source.kind !== "path");
|
|
182
|
+
args.length = 0;
|
|
183
|
+
args.push(...orderedPathArgs, ...nonPathArgs);
|
|
184
|
+
if (pageableIndex >= 0) {
|
|
185
|
+
pageableIndex = args.findIndex(a => a.source.kind === "pageable");
|
|
186
|
+
}
|
|
187
|
+
if (pageableIndex >= 0) {
|
|
188
|
+
const pageableModel = ctx.models.tsNameByDefinition.get("Pageable");
|
|
189
|
+
if (pageableModel) {
|
|
190
|
+
imports.add(pageableModel);
|
|
191
|
+
args[pageableIndex].tsType = pageableModel;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// Service has no Pageable definition — inline the shape it actually sends on the wire.
|
|
195
|
+
args[pageableIndex].tsType = "{ page?: number; size?: number; sort?: string }";
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// TS forbids a required parameter after an optional one. The source docs have no such rule, so
|
|
199
|
+
// one can declare (optional query, required body) — keep the declared ORDER but relax earlier optional
|
|
200
|
+
// args to required-with-undefined-allowed, so the emitted signature is valid TS.
|
|
201
|
+
const lastRequired = args.reduce((acc, a, i) => (a.optional ? acc : i), -1);
|
|
202
|
+
args.forEach((a, i) => {
|
|
203
|
+
if (i < lastRequired && a.optional) {
|
|
204
|
+
a.optional = false;
|
|
205
|
+
a.tsType = `${a.tsType} | undefined`;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
return args;
|
|
209
|
+
}
|
|
210
|
+
/** Response type: the success schema, resolved against shared models. */
|
|
211
|
+
function responseTsType(operation, ctx, imports) {
|
|
212
|
+
var _a;
|
|
213
|
+
const responses = operation.responses || {};
|
|
214
|
+
const code = ["200", "201", "204", "default"].find(c => responses[c]);
|
|
215
|
+
const schema = code ? (_a = responses[code]) === null || _a === void 0 ? void 0 : _a.schema : undefined;
|
|
216
|
+
if (!schema) {
|
|
217
|
+
return "any";
|
|
218
|
+
}
|
|
219
|
+
return schemaTsType(schema, ctx, imports);
|
|
220
|
+
}
|
|
221
|
+
/** The path relative to the controller base path passed to super(), with params interpolated. */
|
|
222
|
+
function relativePathExpr(pathTemplate, ctx, args) {
|
|
223
|
+
let relative = pathTemplate;
|
|
224
|
+
if (ctx.controllerBasePath && pathTemplate.startsWith(ctx.controllerBasePath)) {
|
|
225
|
+
relative = pathTemplate.slice(ctx.controllerBasePath.length);
|
|
226
|
+
}
|
|
227
|
+
const nameByToken = new Map(args
|
|
228
|
+
.filter(a => a.source.kind === "path")
|
|
229
|
+
.map(a => [a.source.paramName, a.name]));
|
|
230
|
+
const interpolated = relative.replace(/\{([^}]+)\}/g, (_, token) => "${" + (nameByToken.get(token) || toSafeIdentifier(token)) + "}");
|
|
231
|
+
return "`" + interpolated + "`";
|
|
232
|
+
}
|
|
233
|
+
/** A body-local name that cannot collide with any of the method's own argument names. */
|
|
234
|
+
function claimLocalName(preferred, args) {
|
|
235
|
+
const taken = new Set(args.map(a => a.name));
|
|
236
|
+
let name = preferred;
|
|
237
|
+
let suffix = 2;
|
|
238
|
+
while (taken.has(name)) {
|
|
239
|
+
name = `${preferred}${suffix++}`;
|
|
240
|
+
}
|
|
241
|
+
return name;
|
|
242
|
+
}
|
|
243
|
+
function emitMethod(pathTemplate, httpMethod, operation, ctx) {
|
|
244
|
+
const methodName = operation.operationId;
|
|
245
|
+
if (!methodName) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
const modelImports = new Set();
|
|
249
|
+
const args = buildArgs(operation, pathTemplate, ctx, modelImports);
|
|
250
|
+
const responseType = responseTsType(operation, ctx, modelImports);
|
|
251
|
+
const signature = [
|
|
252
|
+
...args.map(a => `${a.name}${a.optional ? "?" : ""}: ${a.tsType}`),
|
|
253
|
+
"ctx?: ServiceFnCtx",
|
|
254
|
+
].join(", ");
|
|
255
|
+
// --- request wiring ---
|
|
256
|
+
const queryArgs = args.filter(a => a.source.kind === "query");
|
|
257
|
+
const pageableArg = args.find(a => a.source.kind === "pageable");
|
|
258
|
+
const headerArgs = args.filter(a => a.source.kind === "header");
|
|
259
|
+
const bodyArg = args.find(a => a.source.kind === "body");
|
|
260
|
+
const formDataArgs = args.filter(a => a.source.kind === "formData");
|
|
261
|
+
// An operation declaring `application/x-www-form-urlencoded` reads its non-pageable params from
|
|
262
|
+
// the FORM BODY, not the query string — Spring binds a @RequestParam from either, and for these
|
|
263
|
+
// operations WM's own runtime sends it in the body. This is the whole reason such an operation
|
|
264
|
+
// exists: WM generates a POST /filter twin of GET /<entity> specifically for when the query is
|
|
265
|
+
// "too big to fit in GET request with request param" (the doc's own description), so putting it
|
|
266
|
+
// back in the URL would defeat the operation's purpose and re-introduce the length limit.
|
|
267
|
+
// Pagination stays in the query string either way — the URL template the runtime uses for these
|
|
268
|
+
// operations is `/filter?page=:page&size=:size&:sort` with only the query in the body.
|
|
269
|
+
//
|
|
270
|
+
// GET/HEAD is WS_CONSTANTS.NON_BODY_HTTP_METHODS: they cannot carry a body, so their params stay
|
|
271
|
+
// in the URL. DELETE is not in that list and keeps the redirection.
|
|
272
|
+
const canCarryBody = !["get", "head"].includes(httpMethod.toLowerCase());
|
|
273
|
+
const isFormUrlEncoded = (operation.consumes || []).includes("application/x-www-form-urlencoded") && canCarryBody;
|
|
274
|
+
const formBodyArgs = isFormUrlEncoded ? queryArgs : [];
|
|
275
|
+
const urlQueryArgs = isFormUrlEncoded ? [] : queryArgs;
|
|
276
|
+
const lines = [];
|
|
277
|
+
const queryEntries = urlQueryArgs.map(a => `${JSON.stringify(a.source.paramName)}: ${a.name}`);
|
|
278
|
+
if (pageableArg) {
|
|
279
|
+
// Flattened back to the wire params Spring's Pageable resolver reads.
|
|
280
|
+
pageableArg.source.paramNames.forEach(wireName => {
|
|
281
|
+
const prop = wireName === "sort" ? "sort" : wireName === "size" ? "pageSize" : "pageNumber";
|
|
282
|
+
queryEntries.push(`${JSON.stringify(wireName)}: ${pageableArg.name}?.${prop}`);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
// `ctx` reaches buildTargetUrl so a direct (non-proxied) connector can resolve its real target
|
|
286
|
+
// from ctx.serviceInfo.directPath at runtime — that URL only exists in the app's
|
|
287
|
+
// servicedefs.json, never in the designtime doc (see BaseService.url()).
|
|
288
|
+
const relativePath = relativePathExpr(pathTemplate, ctx, args);
|
|
289
|
+
// Every local the method body declares must dodge the argument names in scope (see claimLocalName).
|
|
290
|
+
const urlVar = claimLocalName("url", args);
|
|
291
|
+
// Only array params whose doc declares a non-default collectionFormat/style need describing;
|
|
292
|
+
// everything else serializes identically, so the generated call omits the argument entirely.
|
|
293
|
+
const arrayFormats = urlQueryArgs
|
|
294
|
+
.map(a => {
|
|
295
|
+
const param = (operation.parameters || []).find((p) => p.name === a.source.paramName);
|
|
296
|
+
const format = (param === null || param === void 0 ? void 0 : param.collectionFormat) || (param === null || param === void 0 ? void 0 : param.style);
|
|
297
|
+
return format && (param === null || param === void 0 ? void 0 : param.type) === "array"
|
|
298
|
+
? `${JSON.stringify(param.name)}: ${JSON.stringify(format)}`
|
|
299
|
+
: "";
|
|
300
|
+
})
|
|
301
|
+
.filter(Boolean);
|
|
302
|
+
if (queryEntries.length) {
|
|
303
|
+
// Deliberately NOT named `query`: a real operation commonly has a parameter called exactly
|
|
304
|
+
// that (WM names the DataService filter param `query` via x-WM-ORIGINAL-NAME), and a local
|
|
305
|
+
// `const query` would shadow it.
|
|
306
|
+
const localName = claimLocalName("queryParams", args);
|
|
307
|
+
lines.push(`const ${localName} = { ${queryEntries.join(", ")} };`);
|
|
308
|
+
const formatsArg = arrayFormats.length ? `, { ${arrayFormats.join(", ")} }` : "";
|
|
309
|
+
lines.push(`const ${urlVar} = this.buildTargetUrl(${relativePath}, ${localName}, ctx${formatsArg});`);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
lines.push(`const ${urlVar} = this.buildTargetUrl(${relativePath}, {}, ctx);`);
|
|
313
|
+
}
|
|
314
|
+
const ctxExtra = [];
|
|
315
|
+
if (bodyArg && formBodyArgs.length) {
|
|
316
|
+
// Both claim the body; ServiceVariableUtils appends rather than letting one win.
|
|
317
|
+
const entries = formBodyArgs
|
|
318
|
+
.map(a => `${JSON.stringify(a.source.paramName)}: ${a.name}`)
|
|
319
|
+
.join(", ");
|
|
320
|
+
ctxExtra.push(`data: [${bodyArg.name}, toFormUrlEncoded({ ${entries} })].filter(Boolean).join("&")`);
|
|
321
|
+
}
|
|
322
|
+
else if (bodyArg) {
|
|
323
|
+
ctxExtra.push(`data: ${bodyArg.name}`);
|
|
324
|
+
}
|
|
325
|
+
else if (formBodyArgs.length) {
|
|
326
|
+
// Serialized to a string rather than handed to axios as an object: axios would emit a blank
|
|
327
|
+
// `q=` for an unsupplied param, and a blank filter is not the same as no filter. A string body
|
|
328
|
+
// also makes axios set the form-urlencoded Content-Type itself, so none is emitted here.
|
|
329
|
+
const entries = formBodyArgs
|
|
330
|
+
.map(a => `${JSON.stringify(a.source.paramName)}: ${a.name}`)
|
|
331
|
+
.join(", ");
|
|
332
|
+
ctxExtra.push(`data: toFormUrlEncoded({ ${entries} })`);
|
|
333
|
+
}
|
|
334
|
+
else if (formDataArgs.length) {
|
|
335
|
+
const entries = formDataArgs.map(a => `${JSON.stringify(a.source.paramName)}: ${a.name}`);
|
|
336
|
+
ctxExtra.push(`data: { ${entries.join(", ")} }`);
|
|
337
|
+
}
|
|
338
|
+
const headerEntries = headerArgs.map(
|
|
339
|
+
// A header param is not always a string in the doc (real APIs declare boolean flags like
|
|
340
|
+
// `X-SortArrays`), and `boolean as string` is not a legal TS assertion — so stringify the
|
|
341
|
+
// value instead of asserting its type. `undefined` is preserved rather than becoming the
|
|
342
|
+
// literal "undefined": the request interceptor drops absent headers.
|
|
343
|
+
a => `${JSON.stringify(a.source.paramName)}: ${a.name} === undefined ? undefined : String(${a.name})`);
|
|
344
|
+
if (headerEntries.length) {
|
|
345
|
+
// Spread ctx.headers first: it carries what the runtime already set for this call
|
|
346
|
+
// (X-Requested-With, plus any header the caller supplied). Replacing the object outright
|
|
347
|
+
// would silently drop those, so the operation's own header params merge OVER them.
|
|
348
|
+
ctxExtra.push(`headers: { ...ctx?.headers, ${headerEntries.join(", ")} }`);
|
|
349
|
+
}
|
|
350
|
+
// Pass ctx straight through when the operation contributes nothing of its own — no wrapper
|
|
351
|
+
// object, and the caller's ctx (serviceInfo, responseType, ...) still reaches request().
|
|
352
|
+
const requestCtxArg = ctxExtra.length ? `{ ...ctx, ${ctxExtra.join(", ")} }` : "ctx";
|
|
353
|
+
lines.push(`return this.request<${responseType}>(${urlVar}, ${JSON.stringify(httpMethod)}, ${requestCtxArg});`);
|
|
354
|
+
const description = operation.description ? ` /** ${operation.description} */\n` : "";
|
|
355
|
+
const returnType = `Promise<ServiceResponse<${responseType}>>`;
|
|
356
|
+
// Operations with many parameters are genuinely hard to call positionally — real connectors
|
|
357
|
+
// reach 15 args, and once several consecutive ones share a type (a run of optional booleans or
|
|
358
|
+
// strings) a transposed pair is silently valid TypeScript. For those, also accept a single named
|
|
359
|
+
// object: the positional form stays the primary signature (the generated invokeHttp glue and
|
|
360
|
+
// Java-style calls are unchanged), with the object form as an overload that is far easier to
|
|
361
|
+
// read and impossible to mis-order.
|
|
362
|
+
const methodCode = `${description} ${methodName}(${signature}): ${returnType} {
|
|
363
|
+
${lines.map(l => ` ${l}`).join("\n")}
|
|
364
|
+
}`;
|
|
365
|
+
return { methodName, methodCode, modelImports, args };
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=method-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-emitter.js","sourceRoot":"","sources":["../../../src/services/method-emitter.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAqTH,gCAsJC;AAzcD,mDAA2E;AA2clE,gGA3ce,+BAAe,OA2cf;AAxcxB,wFAAwF;AACxF,MAAM,iBAAiB,GAAG,0CAA0C,CAAC;AAErE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAwC/D,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,UAAU;IACV,UAAU;IACV,SAAS;IACT,QAAQ;IACR,IAAI;IACJ,MAAM;IACN,QAAQ;IACR,SAAS;IACT,OAAO;IACP,SAAS;IACT,KAAK;IACL,UAAU;IACV,IAAI;IACJ,QAAQ;IACR,IAAI;IACJ,YAAY;IACZ,KAAK;IACL,MAAM;IACN,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,MAAM;IACN,OAAO;IACP,MAAM;IACN,KAAK;IACL,QAAQ;IACR,KAAK;IACL,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,YAAY;IACZ,SAAS;IACT,WAAW;IACX,WAAW;IACX,SAAS;IACT,QAAQ;CACT,CAAC,CAAC;AAEH,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC;SACjC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;SAC/B,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,IAAI,OAAO,CAAC;IACnC,OAAO,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;AAClF,CAAC;AAED,4GAA4G;AAC5G,SAAS,eAAe,CAAC,KAAU;IACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC7C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAC7C,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,KAAK;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACZ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC1F;SACA,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,gBAAgB,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,WAAW,CAAC,KAAU;IAC7B,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IACtC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,QAAQ;QAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,SAAS,YAAY,CAAC,MAAW,EAAE,GAAmB,EAAE,OAAoB;IAC1E,OAAO,IAAA,wBAAQ,EAAC,MAAM,EAAE;QACtB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,kBAAkB;QACvC,KAAK,EAAE,IAAI,GAAG,CACZ,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CACzF;QACD,OAAO;QACP,uFAAuF;QACvF,wCAAwC;QACxC,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,KAAU;IACjC,OAAO,CACL,KAAK,CAAC,eAAe,CAAC,KAAK,iBAAiB;QAC5C,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO;YACnB,KAAK,CAAC,eAAe,CAAC,KAAK,KAAK;YAChC,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CACxC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAChB,SAAc,EACd,YAAoB,EACpB,GAAmB,EACnB,OAAoB;IAEpB,MAAM,MAAM,GAAU,SAAS,CAAC,UAAU,IAAI,EAAE,CAAC;IACjD,MAAM,IAAI,GAAgB,EAAE,CAAC;IAC7B,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,MAAM,SAAS,GAAG,CAAC,SAAiB,EAAU,EAAE;QAC9C,IAAI,IAAI,GAAG,SAAS,CAAC;QACrB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,IAAI,GAAG,GAAG,SAAS,GAAG,MAAM,EAAE,EAAE,CAAC;QACnC,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACrB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;gBACtB,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC5B,IAAI,CAAC,IAAI,CAAC;oBACR,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,EAAE;oBACV,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE;iBACxD,CAAC,CAAC;gBACH,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC5B,CAAC;YACD,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GACR,KAAK,CAAC,EAAE,KAAK,MAAM;YACjB,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,MAAM;gBACnB,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,UAAU;oBACvB,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,QAAQ;wBACrB,CAAC,CAAC,QAAQ;wBACV,CAAC,CAAC,OAAO,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACvC,MAAM,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC;YACtD,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ;YACzB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAyB;SAC/D,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,+FAA+F;IAC/F,kEAAkE;IAClE,+FAA+F;IAC/F,wFAAwF;IACxF,8FAA8F;IAC9F,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,IAAI;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC;SACrC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAE,CAAC,CAAC,MAAgC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAChE,CAAC;IACF,MAAM,eAAe,GAAG,UAAU,CAAC,GAAG,CACpC,KAAK,CAAC,EAAE;;QACN,OAAA,MAAA,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAI;YAC5B,IAAI,EAAE,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACxC,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,SAAS,EAAE,KAAK,EAAE;SACpD,CAAA;KAAA,CACJ,CAAC;IACF,0FAA0F;IAC1F,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAC/D,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAChB,IAAI,CAAC,IAAI,CAAC,GAAG,eAAe,EAAE,GAAG,WAAW,CAAC,CAAC;IAC9C,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QACvB,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpE,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC3B,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,aAAa,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,uFAAuF;YACvF,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,iDAAiD,CAAC;QACjF,CAAC;IACH,CAAC;IAED,+FAA+F;IAC/F,uGAAuG;IACvG,iFAAiF;IACjF,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpB,IAAI,CAAC,GAAG,YAAY,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACnC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC;YACnB,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,cAAc,CAAC;QACvC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yEAAyE;AACzE,SAAS,cAAc,CAAC,SAAc,EAAE,GAAmB,EAAE,OAAoB;;IAC/E,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAA,SAAS,CAAC,IAAI,CAAC,0CAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,iGAAiG;AACjG,SAAS,gBAAgB,CAAC,YAAoB,EAAE,GAAmB,EAAE,IAAiB;IACpF,IAAI,QAAQ,GAAG,YAAY,CAAC;IAC5B,IAAI,GAAG,CAAC,kBAAkB,IAAI,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9E,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,IAAI;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC;SACrC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAE,CAAC,CAAC,MAAgC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CACrE,CAAC;IACF,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CACnC,cAAc,EACd,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAC/E,CAAC;IACF,OAAO,GAAG,GAAG,YAAY,GAAG,GAAG,CAAC;AAClC,CAAC;AAED,yFAAyF;AACzF,SAAS,cAAc,CAAC,SAAiB,EAAE,IAAiB;IAC1D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,IAAI,IAAI,GAAG,SAAS,CAAC;IACrB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,SAAS,GAAG,MAAM,EAAE,EAAE,CAAC;IACnC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,UAAU,CACxB,YAAoB,EACpB,UAAkB,EAClB,SAAc,EACd,GAAmB;IAEnB,MAAM,UAAU,GAAuB,SAAS,CAAC,WAAW,CAAC;IAC7D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,cAAc,CAAC,SAAS,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;IAElE,MAAM,SAAS,GAAG;QAChB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAClE,oBAAoB;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,yBAAyB;IACzB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAEpE,gGAAgG;IAChG,gGAAgG;IAChG,+FAA+F;IAC/F,+FAA+F;IAC/F,gGAAgG;IAChG,0FAA0F;IAC1F,gGAAgG;IAChG,uFAAuF;IACvF,EAAE;IACF,iGAAiG;IACjG,oEAAoE;IACpE,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;IACzE,MAAM,gBAAgB,GACpB,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC,IAAI,YAAY,CAAC;IAC3F,MAAM,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,MAAM,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,YAAY,GAAa,YAAY,CAAC,GAAG,CAC7C,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAE,CAAC,CAAC,MAAgC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CACnF,CAAC;IACF,IAAI,WAAW,EAAE,CAAC;QAChB,sEAAsE;QACrE,WAAW,CAAC,MAAmC,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YAC7E,MAAM,IAAI,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;YAC5F,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,WAAW,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;QACjF,CAAC,CAAC,CAAC;IACL,CAAC;IAED,+FAA+F;IAC/F,iFAAiF;IACjF,yEAAyE;IACzE,MAAM,YAAY,GAAG,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/D,oGAAoG;IACpG,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAE3C,6FAA6F;IAC7F,6FAA6F;IAC7F,MAAM,YAAY,GAAG,YAAY;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE;QACP,MAAM,KAAK,GAAG,CAAC,SAAS,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAC7C,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAM,CAAC,CAAC,MAAgC,CAAC,SAAS,CACrE,CAAC;QACF,MAAM,MAAM,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,gBAAgB,MAAI,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,CAAA,CAAC;QACvD,OAAO,MAAM,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,MAAK,OAAO;YACtC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;YAC5D,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC;SACD,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,2FAA2F;QAC3F,2FAA2F;QAC3F,iCAAiC;QACjC,MAAM,SAAS,GAAG,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,SAAS,SAAS,QAAQ,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnE,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACjF,KAAK,CAAC,IAAI,CACR,SAAS,MAAM,0BAA0B,YAAY,KAAK,SAAS,QAAQ,UAAU,IAAI,CAC1F,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,SAAS,MAAM,0BAA0B,YAAY,aAAa,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACnC,iFAAiF;QACjF,MAAM,OAAO,GAAG,YAAY;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAE,CAAC,CAAC,MAAgC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;aACvF,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,QAAQ,CAAC,IAAI,CACX,UAAU,OAAO,CAAC,IAAI,wBAAwB,OAAO,gCAAgC,CACtF,CAAC;IACJ,CAAC;SAAM,IAAI,OAAO,EAAE,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;SAAM,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QAC/B,4FAA4F;QAC5F,+FAA+F;QAC/F,yFAAyF;QACzF,MAAM,OAAO,GAAG,YAAY;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAE,CAAC,CAAC,MAAgC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;aACvF,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,QAAQ,CAAC,IAAI,CAAC,4BAA4B,OAAO,KAAK,CAAC,CAAC;IAC1D,CAAC;SAAM,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAC9B,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAE,CAAC,CAAC,MAAgC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CACnF,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;IACD,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG;IAClC,yFAAyF;IACzF,0FAA0F;IAC1F,yFAAyF;IACzF,qEAAqE;IACrE,CAAC,CAAC,EAAE,CACF,GAAG,IAAI,CAAC,SAAS,CAAE,CAAC,CAAC,MAAgC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,uCAAuC,CAAC,CAAC,IAAI,GAAG,CAC9H,CAAC;IACF,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;QACzB,kFAAkF;QAClF,yFAAyF;QACzF,mFAAmF;QACnF,QAAQ,CAAC,IAAI,CAAC,+BAA+B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7E,CAAC;IACD,2FAA2F;IAC3F,yFAAyF;IACzF,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACrF,KAAK,CAAC,IAAI,CACR,uBAAuB,YAAY,KAAK,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,aAAa,IAAI,CACpG,CAAC;IAEF,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,SAAS,CAAC,WAAW,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,MAAM,UAAU,GAAG,2BAA2B,YAAY,IAAI,CAAC;IAE/D,4FAA4F;IAC5F,+FAA+F;IAC/F,iGAAiG;IACjG,6FAA6F;IAC7F,6FAA6F;IAC7F,oCAAoC;IACpC,MAAM,UAAU,GAAG,GAAG,WAAW,KAAK,UAAU,IAAI,SAAS,MAAM,UAAU;EAC7E,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IACnC,CAAC;IAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Emits a service's `definitions` block as models — one interface per definition, one file each.
|
|
4
|
+
* These are service-wide, so they are emitted ONCE rather than re-derived per operation (which
|
|
5
|
+
* produced 79 duplicated type declarations for 14 methods in one real file).
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.toModelTypeName = toModelTypeName;
|
|
9
|
+
exports.typeExpr = typeExpr;
|
|
10
|
+
exports.buildModels = buildModels;
|
|
11
|
+
/**
|
|
12
|
+
* `Object` (and friends) are real definition names in WM docs, but emitting `export interface
|
|
13
|
+
* Object` and importing it would shadow the TS global inside every file that references it.
|
|
14
|
+
* Renamed on emission; every `$ref` to them resolves through tsNameByDefinition, so nothing
|
|
15
|
+
* else in the generator needs to know.
|
|
16
|
+
*/
|
|
17
|
+
const SHADOWING_NAMES = new Set(["Object", "Function", "Array", "String", "Number", "Boolean"]);
|
|
18
|
+
/** Definition name -> valid, non-shadowing TS identifier. "Sort$Order" -> "SortOrder". */
|
|
19
|
+
function toModelTypeName(definitionName) {
|
|
20
|
+
let name = String(definitionName || "")
|
|
21
|
+
.split(/[^a-zA-Z0-9]+/)
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.map(w => w.charAt(0).toUpperCase() + w.slice(1))
|
|
24
|
+
.join("");
|
|
25
|
+
if (!name) {
|
|
26
|
+
name = "Model";
|
|
27
|
+
}
|
|
28
|
+
if (/^[0-9]/.test(name)) {
|
|
29
|
+
name = "_" + name;
|
|
30
|
+
}
|
|
31
|
+
if (SHADOWING_NAMES.has(name)) {
|
|
32
|
+
name = `Wm${name}`;
|
|
33
|
+
}
|
|
34
|
+
return name;
|
|
35
|
+
}
|
|
36
|
+
function refDefinitionName(ref) {
|
|
37
|
+
return ref.split("/").pop() || ref;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Java generics, from `x-WM-TYPE_ARGUMENTS`. A definition is generic if any reference to it
|
|
41
|
+
* supplies type arguments — `Page` is referenced as `Page<Department>`, so it is emitted as
|
|
42
|
+
* `Page<T>`. Scans the whole doc, since such a reference can appear anywhere.
|
|
43
|
+
*/
|
|
44
|
+
function collectGenericArity(doc) {
|
|
45
|
+
const arity = new Map();
|
|
46
|
+
const walk = (node) => {
|
|
47
|
+
if (Array.isArray(node)) {
|
|
48
|
+
node.forEach(walk);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (!node || typeof node !== "object") {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const typeArgs = node["x-WM-TYPE_ARGUMENTS"];
|
|
55
|
+
if (typeof node.$ref === "string" && Array.isArray(typeArgs) && typeArgs.length) {
|
|
56
|
+
const name = refDefinitionName(node.$ref);
|
|
57
|
+
arity.set(name, Math.max(arity.get(name) || 0, typeArgs.length));
|
|
58
|
+
}
|
|
59
|
+
Object.values(node).forEach(walk);
|
|
60
|
+
};
|
|
61
|
+
walk(doc);
|
|
62
|
+
return arity;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Which property carries the type parameter. WM does not mark this: `Page.content` is declared
|
|
66
|
+
* `Array<$ref Object>` with the real element type supplied only at the reference site, so the
|
|
67
|
+
* erased `Object` slots ARE the type-parameter positions.
|
|
68
|
+
*/
|
|
69
|
+
function isErasedTypeSlot(schema, definitions) {
|
|
70
|
+
if (!schema || typeof schema !== "object" || typeof schema.$ref !== "string") {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const target = definitions[refDefinitionName(schema.$ref)];
|
|
74
|
+
if (!target) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return !target.properties && !target.allOf && !target.type;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Well-known JVM types a doc can `$ref` without ever declaring them in `definitions`
|
|
81
|
+
* (e.g. `"$ref": "#/definitions/java.lang.String"` in a real REST connector's doc), mapped to
|
|
82
|
+
* their TS equivalents.
|
|
83
|
+
*/
|
|
84
|
+
const UNDECLARED_REF_TYPES = {
|
|
85
|
+
"java.lang.String": "string",
|
|
86
|
+
"java.lang.Integer": "number",
|
|
87
|
+
"java.lang.Long": "number",
|
|
88
|
+
"java.lang.Short": "number",
|
|
89
|
+
"java.lang.Double": "number",
|
|
90
|
+
"java.lang.Float": "number",
|
|
91
|
+
"java.lang.Boolean": "boolean",
|
|
92
|
+
"java.lang.Object": "any",
|
|
93
|
+
"java.util.Date": "string",
|
|
94
|
+
};
|
|
95
|
+
function refTypeExpr(schema, ctx) {
|
|
96
|
+
var _a;
|
|
97
|
+
const defName = refDefinitionName(schema.$ref);
|
|
98
|
+
// A $ref can point at a definition the doc never declares. Resolving it to a model NAME anyway
|
|
99
|
+
// would emit an import for a file that was never generated ("Module './types' has no exported
|
|
100
|
+
// member ..."), so map the well-known JVM types and fall back to `any` for anything else —
|
|
101
|
+
// never a dangling reference.
|
|
102
|
+
if (!ctx.definitions[defName]) {
|
|
103
|
+
return (_a = UNDECLARED_REF_TYPES[defName]) !== null && _a !== void 0 ? _a : "any";
|
|
104
|
+
}
|
|
105
|
+
const tsName = ctx.registry.get(defName) || toModelTypeName(defName);
|
|
106
|
+
if (tsName !== ctx.selfName) {
|
|
107
|
+
ctx.imports.add(tsName);
|
|
108
|
+
}
|
|
109
|
+
const declaredArity = ctx.arity.get(defName) || 0;
|
|
110
|
+
if (!declaredArity) {
|
|
111
|
+
return tsName;
|
|
112
|
+
}
|
|
113
|
+
const suppliedArgs = schema["x-WM-TYPE_ARGUMENTS"] || [];
|
|
114
|
+
const args = [];
|
|
115
|
+
for (let i = 0; i < declaredArity; i++) {
|
|
116
|
+
args.push(suppliedArgs[i] ? typeExpr(suppliedArgs[i], ctx) : "any");
|
|
117
|
+
}
|
|
118
|
+
return `${tsName}<${args.join(", ")}>`;
|
|
119
|
+
}
|
|
120
|
+
function typeExpr(schema, ctx) {
|
|
121
|
+
if (!schema || typeof schema !== "object") {
|
|
122
|
+
return "any";
|
|
123
|
+
}
|
|
124
|
+
if (schema.$ref) {
|
|
125
|
+
// Inside a generic definition, an erased Object slot IS the type-parameter position.
|
|
126
|
+
if (ctx.typeParam && isErasedTypeSlot(schema, ctx.definitions)) {
|
|
127
|
+
return ctx.typeParam;
|
|
128
|
+
}
|
|
129
|
+
return refTypeExpr(schema, ctx);
|
|
130
|
+
}
|
|
131
|
+
if (Array.isArray(schema.enum) && schema.enum.length) {
|
|
132
|
+
return schema.enum.map((v) => JSON.stringify(v)).join(" | ");
|
|
133
|
+
}
|
|
134
|
+
switch (schema.type) {
|
|
135
|
+
case "array":
|
|
136
|
+
return `Array<${typeExpr(schema.items, ctx)}>`;
|
|
137
|
+
case "object":
|
|
138
|
+
if (schema.additionalProperties) {
|
|
139
|
+
return `Record<string, ${typeExpr(schema.additionalProperties, ctx)}>`;
|
|
140
|
+
}
|
|
141
|
+
if (schema.properties) {
|
|
142
|
+
return inlineObjectExpr(schema, ctx, " ");
|
|
143
|
+
}
|
|
144
|
+
return "Record<string, any>";
|
|
145
|
+
case "integer":
|
|
146
|
+
case "number":
|
|
147
|
+
return "number";
|
|
148
|
+
case "boolean":
|
|
149
|
+
return "boolean";
|
|
150
|
+
case "file":
|
|
151
|
+
return "any";
|
|
152
|
+
case "string":
|
|
153
|
+
return "string";
|
|
154
|
+
default:
|
|
155
|
+
return schema.properties ? inlineObjectExpr(schema, ctx, " ") : "any";
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function propertyLines(schema, ctx, indent) {
|
|
159
|
+
const required = schema.required || [];
|
|
160
|
+
return Object.entries(schema.properties || {}).map(([key, propSchema]) => {
|
|
161
|
+
const optional = required.includes(key) ? "" : "?";
|
|
162
|
+
const safeKey = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
|
|
163
|
+
const format = (propSchema === null || propSchema === void 0 ? void 0 : propSchema.format) ? `${indent}/** @format ${propSchema.format} */\n` : "";
|
|
164
|
+
return `${format}${indent}${safeKey}${optional}: ${typeExpr(propSchema, ctx)};`;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function inlineObjectExpr(schema, ctx, indent) {
|
|
168
|
+
const lines = propertyLines(schema, ctx, `${indent} `);
|
|
169
|
+
if (!lines.length) {
|
|
170
|
+
return "Record<string, any>";
|
|
171
|
+
}
|
|
172
|
+
return `{\n${lines.join("\n")}\n${indent}}`;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Swagger `allOf` composition maps onto TS interface inheritance — e.g. `DataExportOptions`
|
|
176
|
+
* is `allOf: [ExportOptions, { properties: { query } }]`, which is exactly
|
|
177
|
+
* `interface DataExportOptions extends ExportOptions { query?: string }` in TS, and mirrors the
|
|
178
|
+
* Java `class DataExportOptions extends ExportOptions`.
|
|
179
|
+
*/
|
|
180
|
+
function splitAllOf(schema) {
|
|
181
|
+
const parentRefs = [];
|
|
182
|
+
const ownSchemas = [];
|
|
183
|
+
(schema.allOf || []).forEach((part) => {
|
|
184
|
+
if (part && part.$ref) {
|
|
185
|
+
parentRefs.push(part);
|
|
186
|
+
}
|
|
187
|
+
else if (part && (part.properties || part.required)) {
|
|
188
|
+
ownSchemas.push(part);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
return { parentRefs, ownSchemas };
|
|
192
|
+
}
|
|
193
|
+
function renderImports(imports) {
|
|
194
|
+
return Array.from(imports)
|
|
195
|
+
.sort()
|
|
196
|
+
.map(name => `import { ${name} } from './${name}';`)
|
|
197
|
+
.join("\n");
|
|
198
|
+
}
|
|
199
|
+
const FILE_HEADER = "/* eslint-disable */\n// Auto-generated model. Do not edit manually — regenerated on every build.\n";
|
|
200
|
+
function emitModelFile(definitionName, schema, registry, arity, definitions) {
|
|
201
|
+
const tsName = registry.get(definitionName) || toModelTypeName(definitionName);
|
|
202
|
+
const typeParamCount = arity.get(definitionName) || 0;
|
|
203
|
+
const typeParams = Array.from({ length: typeParamCount }, (_, i) => typeParamCount === 1 ? "T" : `T${i + 1}`);
|
|
204
|
+
const ctx = {
|
|
205
|
+
definitions,
|
|
206
|
+
registry,
|
|
207
|
+
arity,
|
|
208
|
+
imports: new Set(),
|
|
209
|
+
selfName: tsName,
|
|
210
|
+
typeParam: typeParams[0],
|
|
211
|
+
};
|
|
212
|
+
const generics = typeParams.length ? `<${typeParams.join(", ")}>` : "";
|
|
213
|
+
const { parentRefs, ownSchemas } = splitAllOf(schema || {});
|
|
214
|
+
const parents = parentRefs.map(ref => refTypeExpr(ref, ctx));
|
|
215
|
+
const extendsClause = parents.length ? ` extends ${parents.join(", ")}` : "";
|
|
216
|
+
// Own properties: the definition's direct `properties`, plus any inline allOf part's.
|
|
217
|
+
const ownLines = [
|
|
218
|
+
...propertyLines(schema || {}, ctx, " "),
|
|
219
|
+
...ownSchemas.flatMap(part => propertyLines(part, ctx, " ")),
|
|
220
|
+
];
|
|
221
|
+
let body;
|
|
222
|
+
if (ownLines.length || parents.length) {
|
|
223
|
+
body = `export interface ${tsName}${generics}${extendsClause} {\n${ownLines.join("\n")}\n}`;
|
|
224
|
+
if (!ownLines.length) {
|
|
225
|
+
body = `export interface ${tsName}${generics}${extendsClause} {}`;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// Property-less definitions (Object, InputStream, Stream) are Java types with no exposed
|
|
230
|
+
// shape — the honest TS equivalent is `any`, not an empty interface (which would wrongly
|
|
231
|
+
// accept nothing and reject everything useful).
|
|
232
|
+
body = `export type ${tsName}${generics} = any;`;
|
|
233
|
+
}
|
|
234
|
+
const importBlock = renderImports(ctx.imports);
|
|
235
|
+
const content = `${FILE_HEADER}${importBlock ? `\n${importBlock}\n` : ""}\n${body}\n`;
|
|
236
|
+
return { name: tsName, content };
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Builds every model file for one service's `definitions` block, plus the name/arity registry
|
|
240
|
+
* the operation emitter uses to reference these models by `$ref`.
|
|
241
|
+
*/
|
|
242
|
+
function buildModels(doc) {
|
|
243
|
+
const definitions = (doc === null || doc === void 0 ? void 0 : doc.definitions) || {};
|
|
244
|
+
const arity = collectGenericArity(doc);
|
|
245
|
+
const tsNameByDefinition = new Map();
|
|
246
|
+
const usedNames = new Set();
|
|
247
|
+
Object.keys(definitions).forEach(defName => {
|
|
248
|
+
let tsName = toModelTypeName(defName);
|
|
249
|
+
// Two distinct definitions can sanitize to the same identifier (e.g. "Sort$Order" and
|
|
250
|
+
// "SortOrder", were both present) — keep them distinct rather than silently overwriting one
|
|
251
|
+
// model file with the other.
|
|
252
|
+
let suffix = 2;
|
|
253
|
+
while (usedNames.has(tsName)) {
|
|
254
|
+
tsName = `${toModelTypeName(defName)}${suffix++}`;
|
|
255
|
+
}
|
|
256
|
+
usedNames.add(tsName);
|
|
257
|
+
tsNameByDefinition.set(defName, tsName);
|
|
258
|
+
});
|
|
259
|
+
const typeParamsByDefinition = new Map();
|
|
260
|
+
arity.forEach((count, defName) => {
|
|
261
|
+
if (!definitions[defName])
|
|
262
|
+
return;
|
|
263
|
+
typeParamsByDefinition.set(defName, Array.from({ length: count }, (_, i) => (count === 1 ? "T" : `T${i + 1}`)));
|
|
264
|
+
});
|
|
265
|
+
const files = Object.entries(definitions).map(([defName, schema]) => emitModelFile(defName, schema, tsNameByDefinition, arity, definitions));
|
|
266
|
+
// Barrel, so a controller file can `import { Department, Page } from './types'`.
|
|
267
|
+
// A service can legitimately have NO definitions at all (e.g. a connector whose operations only
|
|
268
|
+
// take and return primitives) — a comment-only file is not a module, and TypeScript rejects
|
|
269
|
+
// `export * from './types'` against it ("File ... is not a module"), so emit an explicit empty
|
|
270
|
+
// export to keep it a valid module.
|
|
271
|
+
const barrel = files.length
|
|
272
|
+
? files
|
|
273
|
+
.map(f => f.name)
|
|
274
|
+
.sort()
|
|
275
|
+
.map(name => `export * from './${name}';`)
|
|
276
|
+
.join("\n")
|
|
277
|
+
: "export {};";
|
|
278
|
+
files.push({ name: "index", content: `${FILE_HEADER}\n${barrel}\n` });
|
|
279
|
+
return { tsNameByDefinition, typeParamsByDefinition, files };
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=model-emitter.js.map
|