@ahoo-wang/fetcher-generator 2.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/LICENSE +201 -0
- package/README.md +289 -0
- package/dist/aggregate/aggregate.d.ts +73 -0
- package/dist/aggregate/aggregate.d.ts.map +1 -0
- package/dist/aggregate/aggregateResolver.d.ts +48 -0
- package/dist/aggregate/aggregateResolver.d.ts.map +1 -0
- package/dist/aggregate/index.d.ts +5 -0
- package/dist/aggregate/index.d.ts.map +1 -0
- package/dist/aggregate/types.d.ts +33 -0
- package/dist/aggregate/types.d.ts.map +1 -0
- package/dist/aggregate/utils.d.ts +45 -0
- package/dist/aggregate/utils.d.ts.map +1 -0
- package/dist/baseCodeGenerator.d.ts +22 -0
- package/dist/baseCodeGenerator.d.ts.map +1 -0
- package/dist/cli.cjs +2 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +56 -0
- package/dist/client/clientGenerator.d.ts +25 -0
- package/dist/client/clientGenerator.d.ts.map +1 -0
- package/dist/client/commandClientGenerator.d.ts +38 -0
- package/dist/client/commandClientGenerator.d.ts.map +1 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/queryClientGenerator.d.ts +32 -0
- package/dist/client/queryClientGenerator.d.ts.map +1 -0
- package/dist/client/utils.d.ts +12 -0
- package/dist/client/utils.d.ts.map +1 -0
- package/dist/index.cjs +11 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +968 -0
- package/dist/model/index.d.ts +4 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/modelGenerator.d.ts +130 -0
- package/dist/model/modelGenerator.d.ts.map +1 -0
- package/dist/model/modelInfo.d.ts +27 -0
- package/dist/model/modelInfo.d.ts.map +1 -0
- package/dist/model/wowTypeMapping.d.ts +33 -0
- package/dist/model/wowTypeMapping.d.ts.map +1 -0
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/clis.d.ts +18 -0
- package/dist/utils/clis.d.ts.map +1 -0
- package/dist/utils/components.d.ts +64 -0
- package/dist/utils/components.d.ts.map +1 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/naming.d.ts +21 -0
- package/dist/utils/naming.d.ts.map +1 -0
- package/dist/utils/openAPIParser.d.ts +14 -0
- package/dist/utils/openAPIParser.d.ts.map +1 -0
- package/dist/utils/operations.d.ts +29 -0
- package/dist/utils/operations.d.ts.map +1 -0
- package/dist/utils/references.d.ts +3 -0
- package/dist/utils/references.d.ts.map +1 -0
- package/dist/utils/resources.d.ts +4 -0
- package/dist/utils/resources.d.ts.map +1 -0
- package/dist/utils/responses.d.ts +8 -0
- package/dist/utils/responses.d.ts.map +1 -0
- package/dist/utils/schemas.d.ts +22 -0
- package/dist/utils/schemas.d.ts.map +1 -0
- package/dist/utils/sourceFiles.d.ts +54 -0
- package/dist/utils/sourceFiles.d.ts.map +1 -0
- package/package.json +82 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,968 @@
|
|
|
1
|
+
import { VariableDeclarationKind as S, Scope as F } from "ts-morph";
|
|
2
|
+
import { parse as L } from "yaml";
|
|
3
|
+
import { readFile as K } from "fs";
|
|
4
|
+
import { ContentTypeValues as P, combineURLs as A } from "@ahoo-wang/fetcher";
|
|
5
|
+
import { ResourceAttributionPathSpec as R } from "@ahoo-wang/fetcher-wow";
|
|
6
|
+
function h(r) {
|
|
7
|
+
return r.$ref.split("/").pop();
|
|
8
|
+
}
|
|
9
|
+
function E(r, e) {
|
|
10
|
+
const n = h(r);
|
|
11
|
+
return e.schemas?.[n];
|
|
12
|
+
}
|
|
13
|
+
function Q(r, e) {
|
|
14
|
+
const n = h(r);
|
|
15
|
+
return e.requestBodies?.[n];
|
|
16
|
+
}
|
|
17
|
+
function k(r, e) {
|
|
18
|
+
const n = h(r);
|
|
19
|
+
return e.parameters?.[n];
|
|
20
|
+
}
|
|
21
|
+
function y(r, e) {
|
|
22
|
+
return {
|
|
23
|
+
key: h(r),
|
|
24
|
+
schema: E(r, e)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const x = /[-_\s.]+|(?=[A-Z])/;
|
|
28
|
+
function O(r) {
|
|
29
|
+
if (r === "" || r.length === 0)
|
|
30
|
+
return "";
|
|
31
|
+
let e;
|
|
32
|
+
return Array.isArray(r) ? e = r.flatMap((n) => n.split(x)) : e = r.split(x), e.filter((n) => n.length > 0).map((n) => {
|
|
33
|
+
if (n.length === 0) return "";
|
|
34
|
+
const t = n.charAt(0), o = n.slice(1);
|
|
35
|
+
return (/[a-zA-Z]/.test(t) ? t.toUpperCase() : t) + o.toLowerCase();
|
|
36
|
+
}).join("");
|
|
37
|
+
}
|
|
38
|
+
function M(r) {
|
|
39
|
+
const e = O(r);
|
|
40
|
+
return e.charAt(0).toLowerCase() + e.slice(1);
|
|
41
|
+
}
|
|
42
|
+
function U(r) {
|
|
43
|
+
return r.startsWith("http://") || r.startsWith("https://") ? J(r) : V(r);
|
|
44
|
+
}
|
|
45
|
+
async function J(r) {
|
|
46
|
+
return await (await fetch(r)).text();
|
|
47
|
+
}
|
|
48
|
+
function V(r) {
|
|
49
|
+
return new Promise((e, n) => {
|
|
50
|
+
K(r, "utf-8", (t, o) => {
|
|
51
|
+
t ? n(t) : e(o);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function z(r) {
|
|
56
|
+
const e = await U(r);
|
|
57
|
+
switch (H(e)) {
|
|
58
|
+
case "json":
|
|
59
|
+
return JSON.parse(e);
|
|
60
|
+
case "yaml":
|
|
61
|
+
return L(e);
|
|
62
|
+
default:
|
|
63
|
+
throw new Error(`Unsupported file format: ${r}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function H(r) {
|
|
67
|
+
const e = r.trimStart();
|
|
68
|
+
if (e.startsWith("{") || e.startsWith("["))
|
|
69
|
+
return "json";
|
|
70
|
+
if (e.startsWith("-") || e.startsWith("%YAML"))
|
|
71
|
+
return "yaml";
|
|
72
|
+
try {
|
|
73
|
+
return JSON.parse(e), "json";
|
|
74
|
+
} catch {
|
|
75
|
+
if (e.length > 0)
|
|
76
|
+
return "yaml";
|
|
77
|
+
}
|
|
78
|
+
throw new Error("Unable to infer file format");
|
|
79
|
+
}
|
|
80
|
+
function l(r) {
|
|
81
|
+
return !!(r && typeof r == "object" && "$ref" in r);
|
|
82
|
+
}
|
|
83
|
+
function Y(r) {
|
|
84
|
+
return !r || l(r) || !r.content ? void 0 : r.content[P.APPLICATION_JSON]?.schema;
|
|
85
|
+
}
|
|
86
|
+
function Z(r) {
|
|
87
|
+
return [
|
|
88
|
+
{ method: "get", operation: r.get },
|
|
89
|
+
{ method: "put", operation: r.put },
|
|
90
|
+
{ method: "post", operation: r.post },
|
|
91
|
+
{ method: "delete", operation: r.delete },
|
|
92
|
+
{ method: "options", operation: r.options },
|
|
93
|
+
{ method: "head", operation: r.head },
|
|
94
|
+
{ method: "patch", operation: r.patch },
|
|
95
|
+
{ method: "trace", operation: r.trace }
|
|
96
|
+
].filter(({ operation: e }) => e !== void 0);
|
|
97
|
+
}
|
|
98
|
+
function j(r) {
|
|
99
|
+
return r.responses[200];
|
|
100
|
+
}
|
|
101
|
+
function b(r) {
|
|
102
|
+
const e = j(r);
|
|
103
|
+
return Y(e);
|
|
104
|
+
}
|
|
105
|
+
function X(r) {
|
|
106
|
+
return Array.isArray(r.enum) && r.enum.length > 0;
|
|
107
|
+
}
|
|
108
|
+
function $(r) {
|
|
109
|
+
if (Array.isArray(r))
|
|
110
|
+
return r.map((e) => $(e)).join(" | ");
|
|
111
|
+
switch (r) {
|
|
112
|
+
case "string":
|
|
113
|
+
return "string";
|
|
114
|
+
case "number":
|
|
115
|
+
case "integer":
|
|
116
|
+
return "number";
|
|
117
|
+
case "boolean":
|
|
118
|
+
return "boolean";
|
|
119
|
+
case "null":
|
|
120
|
+
return "null";
|
|
121
|
+
default:
|
|
122
|
+
return "any";
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const ee = "types.ts", w = "@";
|
|
126
|
+
function q(r) {
|
|
127
|
+
return A(r.path, ee);
|
|
128
|
+
}
|
|
129
|
+
function T(r, e, n) {
|
|
130
|
+
const t = A(e, n), o = r.getSourceFile(t);
|
|
131
|
+
return o || r.createSourceFile(t, "", {
|
|
132
|
+
overwrite: !0
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function N(r, e, n) {
|
|
136
|
+
let t = r.getImportDeclaration(
|
|
137
|
+
(o) => o.getModuleSpecifierValue() === e
|
|
138
|
+
);
|
|
139
|
+
t || (t = r.addImportDeclaration({
|
|
140
|
+
moduleSpecifier: e
|
|
141
|
+
})), n.forEach((o) => {
|
|
142
|
+
t.getNamedImports().some(
|
|
143
|
+
(s) => s.getName() === o
|
|
144
|
+
) || t.addNamedImport(o);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function f(r, e, n) {
|
|
148
|
+
let t = q(n);
|
|
149
|
+
n.path.startsWith(w) || (t = A(e, t));
|
|
150
|
+
let o = t;
|
|
151
|
+
t.startsWith(w) || (o = A(w, t)), N(r, o, [n.name]);
|
|
152
|
+
}
|
|
153
|
+
function te(r, e, n, t) {
|
|
154
|
+
r.path !== t.path && f(e, n, t);
|
|
155
|
+
}
|
|
156
|
+
function _(r, e) {
|
|
157
|
+
const n = [r, e].filter(
|
|
158
|
+
(t) => t !== void 0 && t.length > 0
|
|
159
|
+
);
|
|
160
|
+
return n.length > 0 ? n.join(`
|
|
161
|
+
`) : void 0;
|
|
162
|
+
}
|
|
163
|
+
function D(r, e) {
|
|
164
|
+
const n = _(r, e);
|
|
165
|
+
return n ? [n] : [];
|
|
166
|
+
}
|
|
167
|
+
function G(r, e, n) {
|
|
168
|
+
const t = _(e, n);
|
|
169
|
+
t && r.addJsDoc({
|
|
170
|
+
description: t
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function ne(r) {
|
|
174
|
+
const e = r.split(".");
|
|
175
|
+
return e.length != 2 || e[0].length === 0 || e[1].length === 0 ? null : e;
|
|
176
|
+
}
|
|
177
|
+
function re(r) {
|
|
178
|
+
const e = ne(r.name);
|
|
179
|
+
return e ? {
|
|
180
|
+
tag: r,
|
|
181
|
+
contextAlias: e[0],
|
|
182
|
+
aggregateName: e[1]
|
|
183
|
+
} : null;
|
|
184
|
+
}
|
|
185
|
+
function oe(r) {
|
|
186
|
+
const e = r?.map((t) => re(t)).filter((t) => t !== null);
|
|
187
|
+
if (!e)
|
|
188
|
+
return /* @__PURE__ */ new Map();
|
|
189
|
+
const n = /* @__PURE__ */ new Map();
|
|
190
|
+
return e.forEach((t) => {
|
|
191
|
+
n.set(t.tag.name, {
|
|
192
|
+
aggregate: t,
|
|
193
|
+
commands: /* @__PURE__ */ new Map(),
|
|
194
|
+
events: /* @__PURE__ */ new Map()
|
|
195
|
+
});
|
|
196
|
+
}), n;
|
|
197
|
+
}
|
|
198
|
+
function ae(r) {
|
|
199
|
+
if (!r)
|
|
200
|
+
return null;
|
|
201
|
+
const e = r.split(".");
|
|
202
|
+
return e.length != 3 ? null : e[2];
|
|
203
|
+
}
|
|
204
|
+
const se = "#/components/responses/wow.CommandOk", ie = "#/components/parameters/wow.id";
|
|
205
|
+
class ce {
|
|
206
|
+
/**
|
|
207
|
+
* Creates a new AggregateResolver instance.
|
|
208
|
+
* @param openAPI - The OpenAPI specification to resolve aggregates from
|
|
209
|
+
*/
|
|
210
|
+
constructor(e) {
|
|
211
|
+
this.openAPI = e, this.aggregates = oe(e.tags), this.build();
|
|
212
|
+
}
|
|
213
|
+
aggregates;
|
|
214
|
+
/**
|
|
215
|
+
* Builds the aggregate definitions by processing all operations in the OpenAPI spec.
|
|
216
|
+
* @private
|
|
217
|
+
*/
|
|
218
|
+
build() {
|
|
219
|
+
for (const [e, n] of Object.entries(this.openAPI.paths)) {
|
|
220
|
+
const t = Z(n);
|
|
221
|
+
for (const o of t)
|
|
222
|
+
this.commands(e, o), this.state(o.operation), this.events(o.operation), this.fields(o.operation);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Returns the resolved aggregate definitions.
|
|
227
|
+
* @returns Map of aggregate definitions keyed by context alias
|
|
228
|
+
*/
|
|
229
|
+
resolve() {
|
|
230
|
+
const e = /* @__PURE__ */ new Map();
|
|
231
|
+
for (const n of this.aggregates.values()) {
|
|
232
|
+
if (!n.state || !n.fields)
|
|
233
|
+
continue;
|
|
234
|
+
const t = n.aggregate.contextAlias;
|
|
235
|
+
let o = e.get(t);
|
|
236
|
+
o || (o = /* @__PURE__ */ new Set(), e.set(t, o)), o.add(n);
|
|
237
|
+
}
|
|
238
|
+
return e;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Processes command operations and adds them to the appropriate aggregates.
|
|
242
|
+
* @param path - The API path
|
|
243
|
+
* @param methodOperation - The HTTP method and operation details
|
|
244
|
+
*/
|
|
245
|
+
commands(e, n) {
|
|
246
|
+
const t = n.operation;
|
|
247
|
+
if (t.operationId === "wow.command.send")
|
|
248
|
+
return;
|
|
249
|
+
const o = ae(t.operationId);
|
|
250
|
+
if (!o)
|
|
251
|
+
return;
|
|
252
|
+
const a = j(t);
|
|
253
|
+
if (!a || !l(a) || a.$ref !== se || !t.requestBody)
|
|
254
|
+
return;
|
|
255
|
+
const s = t.parameters ?? [], c = s.filter((m) => l(m) && m.$ref === ie).at(0), i = s.filter(
|
|
256
|
+
(m) => !l(m) && m.in === "path"
|
|
257
|
+
);
|
|
258
|
+
if (c) {
|
|
259
|
+
const m = k(
|
|
260
|
+
c,
|
|
261
|
+
this.openAPI.components
|
|
262
|
+
);
|
|
263
|
+
i.push(m);
|
|
264
|
+
}
|
|
265
|
+
const u = t.requestBody.content[P.APPLICATION_JSON].schema, d = y(
|
|
266
|
+
u,
|
|
267
|
+
this.openAPI.components
|
|
268
|
+
);
|
|
269
|
+
d.schema.title = d.schema.title || t.summary, d.schema.description = d.schema.description || t.description;
|
|
270
|
+
const B = {
|
|
271
|
+
name: o,
|
|
272
|
+
method: n.method,
|
|
273
|
+
path: e,
|
|
274
|
+
pathParameters: i,
|
|
275
|
+
summary: t.summary,
|
|
276
|
+
description: t.description,
|
|
277
|
+
schema: d,
|
|
278
|
+
operation: t
|
|
279
|
+
};
|
|
280
|
+
t.tags?.forEach((m) => {
|
|
281
|
+
const I = this.aggregates.get(m);
|
|
282
|
+
I && I.commands.set(o, B);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Processes state snapshot operations and associates them with aggregates.
|
|
287
|
+
* @param operation - The OpenAPI operation
|
|
288
|
+
*/
|
|
289
|
+
state(e) {
|
|
290
|
+
if (!e.operationId?.endsWith(".snapshot_state.single"))
|
|
291
|
+
return;
|
|
292
|
+
const n = b(e);
|
|
293
|
+
if (!l(n))
|
|
294
|
+
return;
|
|
295
|
+
const t = y(
|
|
296
|
+
n,
|
|
297
|
+
this.openAPI.components
|
|
298
|
+
);
|
|
299
|
+
e.tags?.forEach((o) => {
|
|
300
|
+
const a = this.aggregates.get(o);
|
|
301
|
+
a && (a.state = t);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Processes event stream operations and extracts domain events for aggregates.
|
|
306
|
+
* @param operation - The OpenAPI operation
|
|
307
|
+
*/
|
|
308
|
+
events(e) {
|
|
309
|
+
if (!this.openAPI.components || !e.operationId?.endsWith(".event.list_query"))
|
|
310
|
+
return;
|
|
311
|
+
const n = b(e);
|
|
312
|
+
if (l(n))
|
|
313
|
+
return;
|
|
314
|
+
const t = n?.items;
|
|
315
|
+
if (!l(t))
|
|
316
|
+
return;
|
|
317
|
+
const a = E(
|
|
318
|
+
t,
|
|
319
|
+
this.openAPI.components
|
|
320
|
+
).properties.body.items.anyOf.map((s) => {
|
|
321
|
+
const c = s.title, i = s.properties.name.const, p = s.properties.body, u = y(
|
|
322
|
+
p,
|
|
323
|
+
this.openAPI.components
|
|
324
|
+
);
|
|
325
|
+
return u.schema.title = u.schema.title || s.title, {
|
|
326
|
+
title: c,
|
|
327
|
+
name: i,
|
|
328
|
+
schema: u
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
e.tags?.forEach((s) => {
|
|
332
|
+
const c = this.aggregates.get(s);
|
|
333
|
+
c && a.forEach((i) => {
|
|
334
|
+
c.events.set(i.name, i);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Processes field query operations and associates field schemas with aggregates.
|
|
340
|
+
* @param operation - The OpenAPI operation
|
|
341
|
+
*/
|
|
342
|
+
fields(e) {
|
|
343
|
+
if (!this.openAPI.components || !e.operationId?.endsWith(".snapshot.count"))
|
|
344
|
+
return;
|
|
345
|
+
const t = Q(
|
|
346
|
+
e.requestBody,
|
|
347
|
+
this.openAPI.components
|
|
348
|
+
).content[P.APPLICATION_JSON].schema, a = E(
|
|
349
|
+
t,
|
|
350
|
+
this.openAPI.components
|
|
351
|
+
).properties?.field, s = y(a, this.openAPI.components);
|
|
352
|
+
e.tags?.forEach((c) => {
|
|
353
|
+
const i = this.aggregates.get(c);
|
|
354
|
+
i && (i.fields = s);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const v = "@ahoo-wang/fetcher-wow", pe = {
|
|
359
|
+
"wow.command.CommandResult": "CommandResult",
|
|
360
|
+
"wow.MessageHeaderSqlType": "MessageHeaderSqlType",
|
|
361
|
+
"wow.api.BindingError": "BindingError",
|
|
362
|
+
"wow.api.DefaultErrorInfo": "ErrorInfo",
|
|
363
|
+
"wow.api.RecoverableType": "RecoverableType",
|
|
364
|
+
"wow.api.command.DefaultDeleteAggregate": "DeleteAggregate",
|
|
365
|
+
"wow.api.command.DefaultRecoverAggregate": "RecoverAggregate",
|
|
366
|
+
"wow.api.messaging.FunctionInfoData": "FunctionInfo",
|
|
367
|
+
"wow.api.messaging.FunctionKind": "FunctionKind",
|
|
368
|
+
"wow.api.modeling.AggregateId": "AggregateId",
|
|
369
|
+
"wow.api.query.Condition": "Condition",
|
|
370
|
+
"wow.api.query.ConditionOptions": "ConditionOptions",
|
|
371
|
+
"wow.api.query.ListQuery": "ListQuery",
|
|
372
|
+
"wow.api.query.Operator": "Operator",
|
|
373
|
+
"wow.api.query.PagedQuery": "PagedQuery",
|
|
374
|
+
"wow.api.query.Pagination": "Pagination",
|
|
375
|
+
"wow.api.query.Projection": "Projection",
|
|
376
|
+
"wow.api.query.Sort": "FieldSort",
|
|
377
|
+
"wow.api.query.Sort.Direction": "SortDirection",
|
|
378
|
+
"wow.command.CommandStage": "CommandStage",
|
|
379
|
+
"wow.command.SimpleWaitSignal": "WaitSignal",
|
|
380
|
+
"wow.configuration.Aggregate": "Aggregate",
|
|
381
|
+
"wow.configuration.BoundedContext": "BoundedContext",
|
|
382
|
+
"wow.configuration.WowMetadata": "WowMetadata",
|
|
383
|
+
"wow.modeling.DomainEvent": "DomainEvent",
|
|
384
|
+
"wow.openapi.BatchResult": "BatchResult",
|
|
385
|
+
"wow.messaging.CompensationTarget": "CompensationTarget"
|
|
386
|
+
};
|
|
387
|
+
function g(r) {
|
|
388
|
+
if (!r)
|
|
389
|
+
return { name: "", path: "/" };
|
|
390
|
+
const e = pe[r];
|
|
391
|
+
if (e)
|
|
392
|
+
return { name: e, path: v };
|
|
393
|
+
const n = r.split(".");
|
|
394
|
+
let t = -1;
|
|
395
|
+
for (let i = 0; i < n.length; i++)
|
|
396
|
+
if (n[i] && /^[A-Z]/.test(n[i])) {
|
|
397
|
+
t = i;
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
if (t === -1)
|
|
401
|
+
return { name: r, path: "/" };
|
|
402
|
+
const o = n.slice(0, t), a = o.length > 0 ? `/${o.join("/")}` : "/", s = n.slice(t);
|
|
403
|
+
return { name: O(s), path: a };
|
|
404
|
+
}
|
|
405
|
+
class C {
|
|
406
|
+
project;
|
|
407
|
+
openAPI;
|
|
408
|
+
outputDir;
|
|
409
|
+
contextAggregates;
|
|
410
|
+
logger;
|
|
411
|
+
/**
|
|
412
|
+
* Creates a new ClientGenerator instance.
|
|
413
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
414
|
+
*/
|
|
415
|
+
constructor(e) {
|
|
416
|
+
this.project = e.project, this.openAPI = e.openAPI, this.outputDir = e.outputDir, this.contextAggregates = e.contextAggregates, this.logger = e.logger;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
class me extends C {
|
|
420
|
+
constructor(e) {
|
|
421
|
+
super(e);
|
|
422
|
+
}
|
|
423
|
+
getOrCreateSourceFile(e) {
|
|
424
|
+
const n = q(e);
|
|
425
|
+
return T(this.project, this.outputDir, n);
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Generates models for all schemas in the OpenAPI specification.
|
|
429
|
+
* Skips schemas with keys starting with 'wow.'.
|
|
430
|
+
*
|
|
431
|
+
* @remarks
|
|
432
|
+
* This method iterates through all schemas in the OpenAPI specification
|
|
433
|
+
* and generates corresponding TypeScript models for each one.
|
|
434
|
+
*/
|
|
435
|
+
generate() {
|
|
436
|
+
const e = this.openAPI.components?.schemas;
|
|
437
|
+
if (!e) {
|
|
438
|
+
this.logger?.info("No schemas found in OpenAPI specification");
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
this.logger?.progress(
|
|
442
|
+
`Generating models for ${Object.keys(e).length} schemas`
|
|
443
|
+
), Object.entries(e).forEach(([n, t]) => {
|
|
444
|
+
n.startsWith("wow.") || (this.logger?.progress(`Processing schema: ${n}`), this.generateKeyedSchema(n, t));
|
|
445
|
+
}), this.logger?.success("Model generation completed");
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Generates a model for a specific schema key.
|
|
449
|
+
* Processes enums, objects, unions, and type aliases in order.
|
|
450
|
+
*
|
|
451
|
+
* @param schemaKey - The key of the schema to generate
|
|
452
|
+
* @param schema - The schema definition
|
|
453
|
+
*
|
|
454
|
+
* @remarks
|
|
455
|
+
* The generation process follows this order:
|
|
456
|
+
* 1. Enum processing
|
|
457
|
+
* 2. Object processing
|
|
458
|
+
* 3. Union processing
|
|
459
|
+
* 4. Type alias processing
|
|
460
|
+
*/
|
|
461
|
+
generateKeyedSchema(e, n) {
|
|
462
|
+
const t = g(e), o = this.getOrCreateSourceFile(t), a = this.process(t, o, n);
|
|
463
|
+
return G(a, n.title, n.description), o;
|
|
464
|
+
}
|
|
465
|
+
process(e, n, t) {
|
|
466
|
+
let o = this.processEnum(
|
|
467
|
+
e,
|
|
468
|
+
n,
|
|
469
|
+
t
|
|
470
|
+
);
|
|
471
|
+
return o || (o = this.processObject(e, n, t), o) || (o = this.processUnion(e, n, t), o) ? o : this.processTypeAlias(e, n, t);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Processes enum schemas and generates TypeScript enums.
|
|
475
|
+
*
|
|
476
|
+
* @param modelInfo - The model information
|
|
477
|
+
* @param sourceFile - The source file to add the enum to
|
|
478
|
+
* @param schema - The enum schema
|
|
479
|
+
* @returns true if the schema was processed as an enum, false otherwise
|
|
480
|
+
*
|
|
481
|
+
* @remarks
|
|
482
|
+
* This method filters out non-string enum values and generates
|
|
483
|
+
* a TypeScript enum with string literal initializers.
|
|
484
|
+
*/
|
|
485
|
+
processEnum(e, n, t) {
|
|
486
|
+
if (X(t))
|
|
487
|
+
return n.addEnum({
|
|
488
|
+
name: e.name,
|
|
489
|
+
isExported: !0,
|
|
490
|
+
members: t.enum.filter((o) => typeof o == "string" && o.length > 0).map((o) => ({
|
|
491
|
+
name: o,
|
|
492
|
+
initializer: `'${o}'`
|
|
493
|
+
}))
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Processes object schemas and generates TypeScript interfaces.
|
|
498
|
+
*
|
|
499
|
+
* @param modelInfo - The model information
|
|
500
|
+
* @param sourceFile - The source file to add the interface to
|
|
501
|
+
* @param schema - The object schema
|
|
502
|
+
* @returns true if the schema was processed as an object, false otherwise
|
|
503
|
+
*
|
|
504
|
+
* @remarks
|
|
505
|
+
* This method handles optional properties by checking the required array
|
|
506
|
+
* and adds undefined union types for optional properties.
|
|
507
|
+
*/
|
|
508
|
+
processObject(e, n, t) {
|
|
509
|
+
if (t.type !== "object" || !t.properties)
|
|
510
|
+
return;
|
|
511
|
+
const o = {}, a = t.required || [];
|
|
512
|
+
for (const [s, c] of Object.entries(t.properties)) {
|
|
513
|
+
const i = this.resolveType(e, n, c), p = !a.includes(s);
|
|
514
|
+
o[s] = p ? `${i} | undefined` : i;
|
|
515
|
+
}
|
|
516
|
+
return n.addInterface({
|
|
517
|
+
name: e.name,
|
|
518
|
+
isExported: !0,
|
|
519
|
+
properties: Object.entries(o).map(([s, c]) => ({
|
|
520
|
+
name: s,
|
|
521
|
+
type: c
|
|
522
|
+
}))
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Processes union schemas (allOf, anyOf, oneOf) and generates TypeScript type aliases.
|
|
527
|
+
*
|
|
528
|
+
* @param modelInfo - The model information
|
|
529
|
+
* @param sourceFile - The source file to add the type alias to
|
|
530
|
+
* @param schema - The union schema
|
|
531
|
+
* @returns true if the schema was processed as a union, false otherwise
|
|
532
|
+
*
|
|
533
|
+
* @remarks
|
|
534
|
+
* This method handles three types of unions:
|
|
535
|
+
* - allOf: Generates intersection types (&)
|
|
536
|
+
* - anyOf: Generates union types (|)
|
|
537
|
+
* - oneOf: Generates union types (|)
|
|
538
|
+
*/
|
|
539
|
+
processUnion(e, n, t) {
|
|
540
|
+
let o = null;
|
|
541
|
+
if (t.allOf ? o = t.allOf.map((a) => this.resolveType(e, n, a)).join(" & ") : t.anyOf ? o = t.anyOf.map((a) => this.resolveType(e, n, a)).join(" | ") : t.oneOf && (o = t.oneOf.map((a) => this.resolveType(e, n, a)).join(" | ")), !!o)
|
|
542
|
+
return n.addTypeAlias({
|
|
543
|
+
name: e.name,
|
|
544
|
+
type: o,
|
|
545
|
+
isExported: !0,
|
|
546
|
+
docs: D(t.title, t.description)
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Processes type alias schemas and generates TypeScript type aliases.
|
|
551
|
+
*
|
|
552
|
+
* @param modelInfo - The model information
|
|
553
|
+
* @param sourceFile - The source file to add the type alias to
|
|
554
|
+
* @param schema - The schema to process
|
|
555
|
+
*
|
|
556
|
+
* @remarks
|
|
557
|
+
* This method is used as a fallback for schemas that don't match
|
|
558
|
+
* enum, object, or union patterns. It resolves the type and creates
|
|
559
|
+
* a simple type alias.
|
|
560
|
+
*/
|
|
561
|
+
processTypeAlias(e, n, t) {
|
|
562
|
+
const o = this.resolveType(e, n, t);
|
|
563
|
+
return n.addTypeAlias({
|
|
564
|
+
name: e.name,
|
|
565
|
+
type: o,
|
|
566
|
+
isExported: !0,
|
|
567
|
+
docs: D(t.title, t.description)
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Resolves the TypeScript type for a given schema or reference.
|
|
572
|
+
* Handles arrays, objects, primitives, and references.
|
|
573
|
+
*
|
|
574
|
+
* @param modelInfo - The model information
|
|
575
|
+
* @param sourceFile - The source file for import management
|
|
576
|
+
* @param schema - The schema or reference to resolve
|
|
577
|
+
* @returns The resolved TypeScript type as a string
|
|
578
|
+
*
|
|
579
|
+
* @remarks
|
|
580
|
+
* This method handles various schema types:
|
|
581
|
+
* - References: Resolves to imported types
|
|
582
|
+
* - Arrays: Resolves item types and adds array notation
|
|
583
|
+
* - Objects: Resolves to Record<string, any> for generic objects
|
|
584
|
+
* - Primitives: Maps to TypeScript primitives
|
|
585
|
+
* - Nullable: Adds null union type
|
|
586
|
+
*/
|
|
587
|
+
resolveType(e, n, t) {
|
|
588
|
+
if (l(t))
|
|
589
|
+
return this.resolveReference(e, n, t);
|
|
590
|
+
if (t.type === "array")
|
|
591
|
+
return `${t.items ? this.resolveType(e, n, t.items) : "any"}[]`;
|
|
592
|
+
if (t.type === "object" && !t.properties)
|
|
593
|
+
return "Record<string, any>";
|
|
594
|
+
let o;
|
|
595
|
+
return t.type ? o = $(t.type) : o = "any", t.nullable && (o = `${o} | null`), o;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Resolves a reference to another schema.
|
|
599
|
+
* Handles mapped types and imports.
|
|
600
|
+
*
|
|
601
|
+
* @param modelInfo - The current model information
|
|
602
|
+
* @param sourceFile - The source file for import management
|
|
603
|
+
* @param ref - The reference to resolve
|
|
604
|
+
* @returns The resolved type name
|
|
605
|
+
*
|
|
606
|
+
* @remarks
|
|
607
|
+
* This method checks for mapped types first (WOW_TYPE_MAPPING).
|
|
608
|
+
* If not found, it adds an import for the referenced model.
|
|
609
|
+
*/
|
|
610
|
+
resolveReference(e, n, t) {
|
|
611
|
+
const o = h(t), a = g(o);
|
|
612
|
+
return te(e, n, this.outputDir, a), a.name;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
function ue(r) {
|
|
616
|
+
let e = 0, n = 0;
|
|
617
|
+
return r.commands.forEach((t) => {
|
|
618
|
+
t.path.startsWith(R.TENANT) && (e += 1), t.path.startsWith(R.OWNER) && (n += 1);
|
|
619
|
+
}), e === 0 && n === 0 ? "ResourceAttributionPathSpec.NONE" : e > n ? "ResourceAttributionPathSpec.TENANT" : "ResourceAttributionPathSpec.OWNER";
|
|
620
|
+
}
|
|
621
|
+
function W(r, e, n, t) {
|
|
622
|
+
const o = `${n.contextAlias}/${n.aggregateName}/${t}.ts`;
|
|
623
|
+
return T(r, e, o);
|
|
624
|
+
}
|
|
625
|
+
function le(r, e) {
|
|
626
|
+
return `${O(r.aggregateName)}${e}`;
|
|
627
|
+
}
|
|
628
|
+
class ge extends C {
|
|
629
|
+
/**
|
|
630
|
+
* Creates a new QueryClientGenerator instance.
|
|
631
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
632
|
+
*/
|
|
633
|
+
constructor(e) {
|
|
634
|
+
super(e);
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Generates query client classes for all aggregates.
|
|
638
|
+
*/
|
|
639
|
+
generate() {
|
|
640
|
+
const e = Array.from(this.contextAggregates.values()).flat().length;
|
|
641
|
+
this.logger?.progress(
|
|
642
|
+
`Generating query clients for ${e} aggregates`
|
|
643
|
+
);
|
|
644
|
+
for (const [, n] of this.contextAggregates)
|
|
645
|
+
n.forEach((t) => {
|
|
646
|
+
this.logger?.progress(
|
|
647
|
+
`Processing query client for aggregate: ${t.aggregate.aggregateName}`
|
|
648
|
+
), this.processQueryClient(t);
|
|
649
|
+
});
|
|
650
|
+
this.logger?.success("Query client generation completed");
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Creates or retrieves a source file for client generation.
|
|
654
|
+
* @param aggregate - The aggregate metadata
|
|
655
|
+
* @param fileName - The name of the client file
|
|
656
|
+
* @returns The source file for the client
|
|
657
|
+
*/
|
|
658
|
+
createClientFilePath(e, n) {
|
|
659
|
+
return W(
|
|
660
|
+
this.project,
|
|
661
|
+
this.outputDir,
|
|
662
|
+
e,
|
|
663
|
+
n
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Processes and generates query client classes for an aggregate.
|
|
668
|
+
* @param aggregate - The aggregate definition
|
|
669
|
+
*/
|
|
670
|
+
processQueryClient(e) {
|
|
671
|
+
const n = this.createClientFilePath(
|
|
672
|
+
e.aggregate,
|
|
673
|
+
"queryClient"
|
|
674
|
+
);
|
|
675
|
+
n.addImportDeclaration({
|
|
676
|
+
moduleSpecifier: v,
|
|
677
|
+
namedImports: [
|
|
678
|
+
"QueryClientFactory",
|
|
679
|
+
"QueryClientOptions",
|
|
680
|
+
"ResourceAttributionPathSpec"
|
|
681
|
+
]
|
|
682
|
+
});
|
|
683
|
+
const t = "DEFAULT_QUERY_CLIENT_OPTIONS";
|
|
684
|
+
n.addVariableStatement({
|
|
685
|
+
declarationKind: S.Const,
|
|
686
|
+
declarations: [
|
|
687
|
+
{
|
|
688
|
+
name: t,
|
|
689
|
+
type: "QueryClientOptions",
|
|
690
|
+
initializer: `{
|
|
691
|
+
contextAlias: '${e.aggregate.contextAlias}',
|
|
692
|
+
aggregateName: '${e.aggregate.aggregateName}',
|
|
693
|
+
resourceAttribution: ${ue(e)},
|
|
694
|
+
}`
|
|
695
|
+
}
|
|
696
|
+
],
|
|
697
|
+
isExported: !1
|
|
698
|
+
});
|
|
699
|
+
const o = [];
|
|
700
|
+
for (const p of e.events.values()) {
|
|
701
|
+
const u = g(p.schema.key);
|
|
702
|
+
f(n, this.outputDir, u), o.push(u);
|
|
703
|
+
}
|
|
704
|
+
const a = "DOMAIN_EVENT_TYPES";
|
|
705
|
+
n.addTypeAlias({
|
|
706
|
+
name: a,
|
|
707
|
+
type: o.map((p) => p.name).join(" | ")
|
|
708
|
+
});
|
|
709
|
+
const s = `${M(e.aggregate.aggregateName)}QueryClientFactory`, c = g(e.state.key), i = g(e.fields.key);
|
|
710
|
+
f(n, this.outputDir, c), f(n, this.outputDir, i), n.addVariableStatement({
|
|
711
|
+
declarationKind: S.Const,
|
|
712
|
+
declarations: [
|
|
713
|
+
{
|
|
714
|
+
name: s,
|
|
715
|
+
initializer: `new QueryClientFactory<${c.name}, ${i.name} | string, ${a}>(${t})`
|
|
716
|
+
}
|
|
717
|
+
],
|
|
718
|
+
isExported: !0
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
class de extends C {
|
|
723
|
+
commandEndpointPathsName = "COMMAND_ENDPOINT_PATHS";
|
|
724
|
+
defaultCommandClientOptionsName = "DEFAULT_COMMAND_CLIENT_OPTIONS";
|
|
725
|
+
/**
|
|
726
|
+
* Creates a new CommandClientGenerator instance.
|
|
727
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
728
|
+
*/
|
|
729
|
+
constructor(e) {
|
|
730
|
+
super(e);
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Generates command client classes for all aggregates.
|
|
734
|
+
*/
|
|
735
|
+
generate() {
|
|
736
|
+
const e = Array.from(this.contextAggregates.values()).flat().length;
|
|
737
|
+
this.logger?.progress(
|
|
738
|
+
`Generating command clients for ${e} aggregates`
|
|
739
|
+
);
|
|
740
|
+
for (const [, n] of this.contextAggregates)
|
|
741
|
+
n.forEach((t) => {
|
|
742
|
+
this.logger?.progress(
|
|
743
|
+
`Processing command client for aggregate: ${t.aggregate.aggregateName}`
|
|
744
|
+
), this.processAggregate(t);
|
|
745
|
+
});
|
|
746
|
+
this.logger?.success("Command client generation completed");
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Processes and generates command client for an aggregate.
|
|
750
|
+
* @param aggregate - The aggregate definition
|
|
751
|
+
*/
|
|
752
|
+
processAggregate(e) {
|
|
753
|
+
const n = W(
|
|
754
|
+
this.project,
|
|
755
|
+
this.outputDir,
|
|
756
|
+
e.aggregate,
|
|
757
|
+
"commandClient"
|
|
758
|
+
);
|
|
759
|
+
this.processCommandEndpointPaths(n, e), n.addVariableStatement({
|
|
760
|
+
declarationKind: S.Const,
|
|
761
|
+
declarations: [
|
|
762
|
+
{
|
|
763
|
+
name: this.defaultCommandClientOptionsName,
|
|
764
|
+
type: "ApiMetadata",
|
|
765
|
+
initializer: `{
|
|
766
|
+
basePath: '${e.aggregate.contextAlias}'
|
|
767
|
+
}`
|
|
768
|
+
}
|
|
769
|
+
],
|
|
770
|
+
isExported: !1
|
|
771
|
+
}), n.addImportDeclaration({
|
|
772
|
+
moduleSpecifier: v,
|
|
773
|
+
namedImports: [
|
|
774
|
+
"CommandRequest",
|
|
775
|
+
"CommandResult",
|
|
776
|
+
"CommandResultEventStream",
|
|
777
|
+
"DeleteAggregate",
|
|
778
|
+
"RecoverAggregate"
|
|
779
|
+
],
|
|
780
|
+
isTypeOnly: !0
|
|
781
|
+
}), n.addImportDeclaration({
|
|
782
|
+
moduleSpecifier: "@ahoo-wang/fetcher-eventstream",
|
|
783
|
+
namedImports: ["JsonEventStreamResultExtractor"]
|
|
784
|
+
}), N(n, "@ahoo-wang/fetcher", ["ContentTypeValues"]), N(n, "@ahoo-wang/fetcher-decorator", [
|
|
785
|
+
"type ApiMetadata",
|
|
786
|
+
"type ApiMetadataCapable",
|
|
787
|
+
"api",
|
|
788
|
+
"post",
|
|
789
|
+
"put",
|
|
790
|
+
"del",
|
|
791
|
+
"request",
|
|
792
|
+
"attribute",
|
|
793
|
+
"path",
|
|
794
|
+
"autoGeneratedError"
|
|
795
|
+
]), this.processCommandClient(n, e), this.processCommandClient(n, e, !0);
|
|
796
|
+
}
|
|
797
|
+
processCommandEndpointPaths(e, n) {
|
|
798
|
+
const t = e.addEnum({
|
|
799
|
+
name: this.commandEndpointPathsName
|
|
800
|
+
});
|
|
801
|
+
n.commands.forEach((o) => {
|
|
802
|
+
t.addMember({
|
|
803
|
+
name: o.name.toUpperCase(),
|
|
804
|
+
initializer: `'${o.path}'`
|
|
805
|
+
});
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
getEndpointPath(e) {
|
|
809
|
+
return `${this.commandEndpointPathsName}.${e.name.toUpperCase()}`;
|
|
810
|
+
}
|
|
811
|
+
processCommandClient(e, n, t = !1) {
|
|
812
|
+
let o = "CommandClient", a = {
|
|
813
|
+
name: "api",
|
|
814
|
+
arguments: []
|
|
815
|
+
}, s = "Promise<CommandResult>";
|
|
816
|
+
t && (o = "Stream" + o, a = {
|
|
817
|
+
name: "api",
|
|
818
|
+
arguments: [
|
|
819
|
+
"''",
|
|
820
|
+
`{
|
|
821
|
+
headers: { Accept: ContentTypeValues.TEXT_EVENT_STREAM },
|
|
822
|
+
resultExtractor: JsonEventStreamResultExtractor,
|
|
823
|
+
}`
|
|
824
|
+
]
|
|
825
|
+
}, s = "Promise<CommandResultEventStream>");
|
|
826
|
+
const c = le(
|
|
827
|
+
n.aggregate,
|
|
828
|
+
o
|
|
829
|
+
), i = e.addClass({
|
|
830
|
+
name: c,
|
|
831
|
+
isExported: !0,
|
|
832
|
+
decorators: [a],
|
|
833
|
+
implements: ["ApiMetadataCapable"]
|
|
834
|
+
});
|
|
835
|
+
i.addConstructor({
|
|
836
|
+
parameters: [
|
|
837
|
+
{
|
|
838
|
+
name: "apiMetadata",
|
|
839
|
+
type: "ApiMetadata",
|
|
840
|
+
scope: F.Public,
|
|
841
|
+
isReadonly: !0,
|
|
842
|
+
initializer: `${this.defaultCommandClientOptionsName}`
|
|
843
|
+
}
|
|
844
|
+
]
|
|
845
|
+
}), n.commands.forEach((p) => {
|
|
846
|
+
this.processCommandMethod(e, i, p, s);
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
methodToDecorator(e) {
|
|
850
|
+
return e === "delete" ? "del" : e;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Processes and generates a command method for the command client.
|
|
854
|
+
* @param sourceFile - The source file containing the client
|
|
855
|
+
* @param client - The client class declaration
|
|
856
|
+
* @param definition - The command definition
|
|
857
|
+
*/
|
|
858
|
+
processCommandMethod(e, n, t, o) {
|
|
859
|
+
const a = g(t.schema.key);
|
|
860
|
+
f(e, this.outputDir, a);
|
|
861
|
+
const s = t.pathParameters.map((i) => ({
|
|
862
|
+
name: i.name,
|
|
863
|
+
type: "string",
|
|
864
|
+
decorators: [
|
|
865
|
+
{
|
|
866
|
+
name: "path",
|
|
867
|
+
arguments: [`'${i.name}'`]
|
|
868
|
+
}
|
|
869
|
+
]
|
|
870
|
+
}));
|
|
871
|
+
s.push({
|
|
872
|
+
name: "commandRequest",
|
|
873
|
+
type: `CommandRequest<${a.name}>`,
|
|
874
|
+
decorators: [
|
|
875
|
+
{
|
|
876
|
+
name: "request",
|
|
877
|
+
arguments: []
|
|
878
|
+
}
|
|
879
|
+
]
|
|
880
|
+
}), s.push({
|
|
881
|
+
name: "attributes",
|
|
882
|
+
type: "Record<string, any>",
|
|
883
|
+
decorators: [
|
|
884
|
+
{
|
|
885
|
+
name: "attribute",
|
|
886
|
+
arguments: []
|
|
887
|
+
}
|
|
888
|
+
]
|
|
889
|
+
});
|
|
890
|
+
const c = n.addMethod({
|
|
891
|
+
name: M(t.name),
|
|
892
|
+
decorators: [
|
|
893
|
+
{
|
|
894
|
+
name: this.methodToDecorator(t.method),
|
|
895
|
+
arguments: [`${this.getEndpointPath(t)}`]
|
|
896
|
+
}
|
|
897
|
+
],
|
|
898
|
+
parameters: s,
|
|
899
|
+
returnType: o,
|
|
900
|
+
statements: [
|
|
901
|
+
`throw autoGeneratedError(${s.map((i) => i.name).join(",")});`
|
|
902
|
+
]
|
|
903
|
+
});
|
|
904
|
+
G(c, t.summary, t.description);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
class fe extends C {
|
|
908
|
+
queryClientGenerator;
|
|
909
|
+
commandClientGenerator;
|
|
910
|
+
/**
|
|
911
|
+
* Creates a new ClientGenerator instance.
|
|
912
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
913
|
+
*/
|
|
914
|
+
constructor(e) {
|
|
915
|
+
super(e), this.queryClientGenerator = new ge(e), this.commandClientGenerator = new de(e);
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Generates client classes for all aggregates.
|
|
919
|
+
*/
|
|
920
|
+
generate() {
|
|
921
|
+
this.logger?.progress(
|
|
922
|
+
`Generating clients for ${this.contextAggregates.size} bounded contexts`
|
|
923
|
+
);
|
|
924
|
+
for (const [e] of this.contextAggregates)
|
|
925
|
+
this.logger?.progress(`Processing bounded context: ${e}`), this.processBoundedContext(e);
|
|
926
|
+
this.queryClientGenerator.generate(), this.commandClientGenerator.generate(), this.logger?.success("Client generation completed");
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Processes a bounded context by creating a file with the context alias constant.
|
|
930
|
+
* @param contextAlias - The alias of the bounded context to process
|
|
931
|
+
*/
|
|
932
|
+
processBoundedContext(e) {
|
|
933
|
+
const n = `${e}/boundedContext.ts`;
|
|
934
|
+
T(this.project, this.outputDir, n).addStatements(
|
|
935
|
+
`export const BOUNDED_CONTEXT_ALIAS = '${e}';`
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
class Se {
|
|
940
|
+
/**
|
|
941
|
+
* Creates a new CodeGenerator instance.
|
|
942
|
+
* @param options - Configuration options for code generation
|
|
943
|
+
*/
|
|
944
|
+
constructor(e) {
|
|
945
|
+
this.options = e, this.project = e.project;
|
|
946
|
+
}
|
|
947
|
+
project;
|
|
948
|
+
/**
|
|
949
|
+
* Generates TypeScript code from the OpenAPI specification.
|
|
950
|
+
* Parses the OpenAPI spec, resolves aggregates, generates models and clients,
|
|
951
|
+
* and formats the output files.
|
|
952
|
+
*/
|
|
953
|
+
async generate() {
|
|
954
|
+
const e = await z(this.options.inputPath), t = new ce(e).resolve(), o = {
|
|
955
|
+
openAPI: e,
|
|
956
|
+
project: this.project,
|
|
957
|
+
outputDir: this.options.outputDir,
|
|
958
|
+
contextAggregates: t,
|
|
959
|
+
logger: this.options.logger
|
|
960
|
+
};
|
|
961
|
+
new me(o).generate(), new fe(o).generate(), this.project.getSourceFiles().forEach((c) => {
|
|
962
|
+
c.formatText(), c.organizeImports(), c.fixMissingImports();
|
|
963
|
+
}), await this.project.save();
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
export {
|
|
967
|
+
Se as CodeGenerator
|
|
968
|
+
};
|