@ahoo-wang/fetcher-generator 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +190 -58
- package/README.zh-CN.md +406 -0
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.ts +10 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +59 -33
- package/dist/cli.js.map +1 -1
- package/dist/client/clientGenerator.d.ts.map +1 -1
- package/dist/client/commandClientGenerator.d.ts.map +1 -1
- package/dist/client/queryClientGenerator.d.ts.map +1 -1
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +736 -499
- package/dist/index.js.map +1 -1
- package/dist/model/modelGenerator.d.ts.map +1 -1
- package/dist/types.d.ts +3 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +4 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/sourceFiles.d.ts.map +1 -1
- package/package.json +9 -8
package/dist/index.js
CHANGED
|
@@ -1,70 +1,73 @@
|
|
|
1
|
-
import { VariableDeclarationKind as
|
|
1
|
+
import { VariableDeclarationKind as O, Scope as L } from "ts-morph";
|
|
2
2
|
import { parse as Q } from "yaml";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import * as v from "fs";
|
|
4
|
+
import { readFile as k } from "fs";
|
|
5
|
+
import { ContentTypeValues as I, combineURLs as q } from "@ahoo-wang/fetcher";
|
|
6
|
+
import * as K from "path";
|
|
7
|
+
import { join as U, relative as J } from "path";
|
|
8
|
+
import { ResourceAttributionPathSpec as R } from "@ahoo-wang/fetcher-wow";
|
|
9
|
+
function f(n) {
|
|
10
|
+
return n.$ref.split("/").pop();
|
|
8
11
|
}
|
|
9
|
-
function
|
|
10
|
-
const
|
|
11
|
-
return e.schemas?.[
|
|
12
|
+
function S(n, e) {
|
|
13
|
+
const t = f(n);
|
|
14
|
+
return e.schemas?.[t];
|
|
12
15
|
}
|
|
13
|
-
function
|
|
14
|
-
const
|
|
15
|
-
return e.requestBodies?.[
|
|
16
|
+
function V(n, e) {
|
|
17
|
+
const t = f(n);
|
|
18
|
+
return e.requestBodies?.[t];
|
|
16
19
|
}
|
|
17
|
-
function
|
|
18
|
-
const
|
|
19
|
-
return e.parameters?.[
|
|
20
|
+
function H(n, e) {
|
|
21
|
+
const t = f(n);
|
|
22
|
+
return e.parameters?.[t];
|
|
20
23
|
}
|
|
21
|
-
function
|
|
24
|
+
function C(n, e) {
|
|
22
25
|
return {
|
|
23
|
-
key:
|
|
24
|
-
schema:
|
|
26
|
+
key: f(n),
|
|
27
|
+
schema: S(n, e)
|
|
25
28
|
};
|
|
26
29
|
}
|
|
27
|
-
const
|
|
28
|
-
function
|
|
29
|
-
if (
|
|
30
|
+
const b = /[-_\s.]+|(?=[A-Z])/;
|
|
31
|
+
function w(n) {
|
|
32
|
+
if (n === "" || n.length === 0)
|
|
30
33
|
return "";
|
|
31
34
|
let e;
|
|
32
|
-
return Array.isArray(
|
|
33
|
-
if (
|
|
34
|
-
const
|
|
35
|
-
return (/[a-zA-Z]/.test(
|
|
35
|
+
return Array.isArray(n) ? e = n.flatMap((t) => t.split(b)) : e = n.split(b), e.filter((t) => t.length > 0).map((t) => {
|
|
36
|
+
if (t.length === 0) return "";
|
|
37
|
+
const o = t.charAt(0), r = t.slice(1);
|
|
38
|
+
return (/[a-zA-Z]/.test(o) ? o.toUpperCase() : o) + r.toLowerCase();
|
|
36
39
|
}).join("");
|
|
37
40
|
}
|
|
38
|
-
function
|
|
39
|
-
const e =
|
|
41
|
+
function h(n) {
|
|
42
|
+
const e = w(n);
|
|
40
43
|
return e.charAt(0).toLowerCase() + e.slice(1);
|
|
41
44
|
}
|
|
42
|
-
function
|
|
43
|
-
return
|
|
45
|
+
function Y(n) {
|
|
46
|
+
return n.startsWith("http://") || n.startsWith("https://") ? X(n) : Z(n);
|
|
44
47
|
}
|
|
45
|
-
async function
|
|
46
|
-
return await (await fetch(
|
|
48
|
+
async function X(n) {
|
|
49
|
+
return await (await fetch(n)).text();
|
|
47
50
|
}
|
|
48
|
-
function
|
|
49
|
-
return new Promise((e,
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
function Z(n) {
|
|
52
|
+
return new Promise((e, t) => {
|
|
53
|
+
k(n, "utf-8", (o, r) => {
|
|
54
|
+
o ? t(o) : e(r);
|
|
52
55
|
});
|
|
53
56
|
});
|
|
54
57
|
}
|
|
55
|
-
async function
|
|
56
|
-
const e = await
|
|
57
|
-
switch (
|
|
58
|
+
async function ee(n) {
|
|
59
|
+
const e = await Y(n);
|
|
60
|
+
switch (te(e)) {
|
|
58
61
|
case "json":
|
|
59
62
|
return JSON.parse(e);
|
|
60
63
|
case "yaml":
|
|
61
64
|
return Q(e);
|
|
62
65
|
default:
|
|
63
|
-
throw new Error(`Unsupported file format: ${
|
|
66
|
+
throw new Error(`Unsupported file format: ${n}`);
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
|
-
function
|
|
67
|
-
const e =
|
|
69
|
+
function te(n) {
|
|
70
|
+
const e = n.trimStart();
|
|
68
71
|
if (e.startsWith("{") || e.startsWith("["))
|
|
69
72
|
return "json";
|
|
70
73
|
if (e.startsWith("-") || e.startsWith("%YAML"))
|
|
@@ -77,69 +80,69 @@ function Z(t) {
|
|
|
77
80
|
}
|
|
78
81
|
throw new Error("Unable to infer file format");
|
|
79
82
|
}
|
|
80
|
-
function
|
|
81
|
-
return !!(
|
|
83
|
+
function g(n) {
|
|
84
|
+
return !!(n && typeof n == "object" && "$ref" in n);
|
|
82
85
|
}
|
|
83
|
-
function
|
|
84
|
-
return !
|
|
86
|
+
function oe(n) {
|
|
87
|
+
return !n || g(n) || !n.content ? void 0 : n.content[I.APPLICATION_JSON]?.schema;
|
|
85
88
|
}
|
|
86
|
-
function
|
|
89
|
+
function ne(n) {
|
|
87
90
|
return [
|
|
88
|
-
{ method: "get", operation:
|
|
89
|
-
{ method: "put", operation:
|
|
90
|
-
{ method: "post", operation:
|
|
91
|
-
{ method: "delete", operation:
|
|
92
|
-
{ method: "options", operation:
|
|
93
|
-
{ method: "head", operation:
|
|
94
|
-
{ method: "patch", operation:
|
|
95
|
-
{ method: "trace", operation:
|
|
91
|
+
{ method: "get", operation: n.get },
|
|
92
|
+
{ method: "put", operation: n.put },
|
|
93
|
+
{ method: "post", operation: n.post },
|
|
94
|
+
{ method: "delete", operation: n.delete },
|
|
95
|
+
{ method: "options", operation: n.options },
|
|
96
|
+
{ method: "head", operation: n.head },
|
|
97
|
+
{ method: "patch", operation: n.patch },
|
|
98
|
+
{ method: "trace", operation: n.trace }
|
|
96
99
|
].filter(({ operation: e }) => e !== void 0);
|
|
97
100
|
}
|
|
98
|
-
function
|
|
99
|
-
return
|
|
101
|
+
function G(n) {
|
|
102
|
+
return n.responses[200];
|
|
100
103
|
}
|
|
101
|
-
function M(
|
|
102
|
-
const e =
|
|
103
|
-
return
|
|
104
|
+
function M(n) {
|
|
105
|
+
const e = G(n);
|
|
106
|
+
return oe(e);
|
|
104
107
|
}
|
|
105
|
-
const
|
|
108
|
+
const re = [
|
|
106
109
|
"string",
|
|
107
110
|
"number",
|
|
108
111
|
"integer",
|
|
109
112
|
"boolean",
|
|
110
113
|
"null"
|
|
111
114
|
];
|
|
112
|
-
function
|
|
113
|
-
return Array.isArray(
|
|
115
|
+
function se(n) {
|
|
116
|
+
return Array.isArray(n) ? !0 : re.includes(n);
|
|
114
117
|
}
|
|
115
|
-
function
|
|
116
|
-
return
|
|
118
|
+
function ie(n) {
|
|
119
|
+
return n.type === "array";
|
|
117
120
|
}
|
|
118
|
-
function
|
|
119
|
-
return Array.isArray(
|
|
121
|
+
function ae(n) {
|
|
122
|
+
return Array.isArray(n.enum) && n.enum.length > 0;
|
|
120
123
|
}
|
|
121
|
-
function
|
|
122
|
-
return Array.isArray(
|
|
124
|
+
function F(n) {
|
|
125
|
+
return Array.isArray(n.anyOf) && n.anyOf.length > 0;
|
|
123
126
|
}
|
|
124
|
-
function
|
|
125
|
-
return Array.isArray(
|
|
127
|
+
function _(n) {
|
|
128
|
+
return Array.isArray(n.oneOf) && n.oneOf.length > 0;
|
|
126
129
|
}
|
|
127
|
-
function
|
|
128
|
-
return
|
|
130
|
+
function ce(n) {
|
|
131
|
+
return F(n) || _(n);
|
|
129
132
|
}
|
|
130
|
-
function
|
|
131
|
-
return Array.isArray(
|
|
133
|
+
function ge(n) {
|
|
134
|
+
return Array.isArray(n.allOf) && n.allOf.length > 0;
|
|
132
135
|
}
|
|
133
|
-
function j(
|
|
134
|
-
return
|
|
136
|
+
function j(n) {
|
|
137
|
+
return F(n) || _(n) || ge(n);
|
|
135
138
|
}
|
|
136
|
-
function
|
|
137
|
-
return
|
|
139
|
+
function le(n) {
|
|
140
|
+
return n.includes("|") || n.includes("&") ? `(${n})[]` : `${n}[]`;
|
|
138
141
|
}
|
|
139
|
-
function
|
|
140
|
-
if (Array.isArray(
|
|
141
|
-
return
|
|
142
|
-
switch (
|
|
142
|
+
function N(n) {
|
|
143
|
+
if (Array.isArray(n))
|
|
144
|
+
return n.map((e) => N(e)).join(" | ");
|
|
145
|
+
switch (n) {
|
|
143
146
|
case "string":
|
|
144
147
|
return "string";
|
|
145
148
|
case "number":
|
|
@@ -153,291 +156,92 @@ function x(t) {
|
|
|
153
156
|
return "any";
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
"wow.api.BindingError": "BindingError",
|
|
160
|
-
"wow.api.DefaultErrorInfo": "ErrorInfo",
|
|
161
|
-
"wow.api.RecoverableType": "RecoverableType",
|
|
162
|
-
"wow.api.command.DefaultDeleteAggregate": "DeleteAggregate",
|
|
163
|
-
"wow.api.command.DefaultRecoverAggregate": "RecoverAggregate",
|
|
164
|
-
"wow.api.messaging.FunctionInfoData": "FunctionInfo",
|
|
165
|
-
"wow.api.messaging.FunctionKind": "FunctionKind",
|
|
166
|
-
"wow.api.modeling.AggregateId": "AggregateId",
|
|
167
|
-
"wow.api.query.Condition": "Condition",
|
|
168
|
-
"wow.api.query.ConditionOptions": "ConditionOptions",
|
|
169
|
-
"wow.api.query.ListQuery": "ListQuery",
|
|
170
|
-
"wow.api.query.Operator": "Operator",
|
|
171
|
-
"wow.api.query.PagedQuery": "PagedQuery",
|
|
172
|
-
"wow.api.query.Pagination": "Pagination",
|
|
173
|
-
"wow.api.query.Projection": "Projection",
|
|
174
|
-
"wow.api.query.Sort": "FieldSort",
|
|
175
|
-
"wow.api.query.Sort.Direction": "SortDirection",
|
|
176
|
-
"wow.command.CommandStage": "CommandStage",
|
|
177
|
-
"wow.command.SimpleWaitSignal": "WaitSignal",
|
|
178
|
-
"wow.configuration.Aggregate": "Aggregate",
|
|
179
|
-
"wow.configuration.BoundedContext": "BoundedContext",
|
|
180
|
-
"wow.configuration.WowMetadata": "WowMetadata",
|
|
181
|
-
"wow.modeling.DomainEvent": "DomainEvent",
|
|
182
|
-
"wow.openapi.BatchResult": "BatchResult",
|
|
183
|
-
"wow.messaging.CompensationTarget": "CompensationTarget"
|
|
184
|
-
};
|
|
185
|
-
function l(t) {
|
|
186
|
-
if (!t)
|
|
187
|
-
return { name: "", path: "/" };
|
|
188
|
-
const e = ce[t];
|
|
189
|
-
if (e)
|
|
190
|
-
return { name: e, path: E };
|
|
191
|
-
const n = t.split(".");
|
|
192
|
-
let r = -1;
|
|
193
|
-
for (let i = 0; i < n.length; i++)
|
|
194
|
-
if (n[i] && /^[A-Z]/.test(n[i])) {
|
|
195
|
-
r = i;
|
|
196
|
-
break;
|
|
197
|
-
}
|
|
198
|
-
if (r === -1)
|
|
199
|
-
return { name: t, path: "/" };
|
|
200
|
-
const o = n.slice(0, r), a = o.length > 0 ? `/${o.join("/")}` : "/", s = n.slice(r);
|
|
201
|
-
return { name: P(s), path: a };
|
|
159
|
+
const W = "types.ts", pe = "@";
|
|
160
|
+
function me(n) {
|
|
161
|
+
return q(n.path, W);
|
|
202
162
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
/** The OpenAPI specification object */
|
|
207
|
-
openAPI;
|
|
208
|
-
/** The output directory path for generated files */
|
|
209
|
-
outputDir;
|
|
210
|
-
/** Map of bounded context aggregates for domain modeling */
|
|
211
|
-
contextAggregates;
|
|
212
|
-
/** Optional logger for generation progress and errors */
|
|
213
|
-
logger;
|
|
214
|
-
/**
|
|
215
|
-
* Creates a new ClientGenerator instance.
|
|
216
|
-
* @param context - The generation context containing OpenAPI spec and project details
|
|
217
|
-
*/
|
|
218
|
-
constructor(e) {
|
|
219
|
-
this.project = e.project, this.openAPI = e.openAPI, this.outputDir = e.outputDir, this.contextAggregates = e.contextAggregates, this.logger = e.logger;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
class ue extends O {
|
|
223
|
-
constructor(e) {
|
|
224
|
-
super(e);
|
|
225
|
-
}
|
|
226
|
-
getOrCreateSourceFile(e) {
|
|
227
|
-
const n = B(e);
|
|
228
|
-
return v(this.project, this.outputDir, n);
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Generates models for all schemas in the OpenAPI specification.
|
|
232
|
-
* Skips schemas with keys starting with 'wow.'.
|
|
233
|
-
*
|
|
234
|
-
* @remarks
|
|
235
|
-
* This method iterates through all schemas in the OpenAPI specification
|
|
236
|
-
* and generates corresponding TypeScript models for each one.
|
|
237
|
-
*/
|
|
238
|
-
generate() {
|
|
239
|
-
const e = this.openAPI.components?.schemas;
|
|
240
|
-
if (!e) {
|
|
241
|
-
this.logger.info("No schemas found in OpenAPI specification");
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
this.logger.progress(
|
|
245
|
-
`Generating models for ${Object.keys(e).length} schemas`
|
|
246
|
-
), Object.entries(e).forEach(([n, r]) => {
|
|
247
|
-
if (n.startsWith("wow."))
|
|
248
|
-
return;
|
|
249
|
-
this.logger.progress(`Processing schema: ${n}`);
|
|
250
|
-
const o = {
|
|
251
|
-
key: n,
|
|
252
|
-
schema: r
|
|
253
|
-
};
|
|
254
|
-
this.generateKeyedSchema(o);
|
|
255
|
-
}), this.logger.success("Model generation completed");
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Generates a model for a specific schema key.
|
|
259
|
-
* Processes enums, objects, unions, and type aliases in order.
|
|
260
|
-
*
|
|
261
|
-
* @param schemaKey - The key of the schema to generate
|
|
262
|
-
* @param schema - The schema definition
|
|
263
|
-
*
|
|
264
|
-
* @remarks
|
|
265
|
-
* The generation process follows this order:
|
|
266
|
-
* 1. Enum processing
|
|
267
|
-
* 2. Object processing
|
|
268
|
-
* 3. Union processing
|
|
269
|
-
* 4. Type alias processing
|
|
270
|
-
*/
|
|
271
|
-
generateKeyedSchema({ key: e, schema: n }) {
|
|
272
|
-
const r = l(e), o = this.getOrCreateSourceFile(r), a = this.process(r, o, n);
|
|
273
|
-
a && A(a, n.title, n.description);
|
|
274
|
-
}
|
|
275
|
-
process(e, n, r) {
|
|
276
|
-
if (oe(r))
|
|
277
|
-
return n.addEnum({
|
|
278
|
-
name: e.name,
|
|
279
|
-
isExported: !0,
|
|
280
|
-
members: r.enum.filter((a) => typeof a == "string" && a.length > 0).map((a) => ({
|
|
281
|
-
name: a,
|
|
282
|
-
initializer: `'${a}'`
|
|
283
|
-
}))
|
|
284
|
-
});
|
|
285
|
-
const o = n.addInterface({
|
|
286
|
-
name: e.name,
|
|
287
|
-
isExported: !0
|
|
288
|
-
});
|
|
289
|
-
return r.type === "object" && r.properties ? this.processInterface(n, e, r, o) : (j(r) && (r.anyOf || r.oneOf || r.allOf).forEach((s) => {
|
|
290
|
-
if (u(s)) {
|
|
291
|
-
const c = l(d(s));
|
|
292
|
-
N(e, n, this.outputDir, c), o.addExtends(c.name);
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
this.processInterface(n, e, s, o);
|
|
296
|
-
}), o);
|
|
297
|
-
}
|
|
298
|
-
processObject(e, n, r) {
|
|
299
|
-
const o = e.addInterface({
|
|
300
|
-
name: n.name,
|
|
301
|
-
isExported: !0
|
|
302
|
-
});
|
|
303
|
-
return this.processInterface(e, n, r, o);
|
|
304
|
-
}
|
|
305
|
-
processInterface(e, n, r, o) {
|
|
306
|
-
for (const [a, s] of Object.entries(r.properties)) {
|
|
307
|
-
const c = this.resolvePropertyType(n, e, a, s);
|
|
308
|
-
let i = o.getProperty(a);
|
|
309
|
-
i ? i.setType(c) : i = o.addProperty({
|
|
310
|
-
name: a,
|
|
311
|
-
type: c
|
|
312
|
-
}), u(s) || A(i, s.title, s.description);
|
|
313
|
-
}
|
|
314
|
-
return o;
|
|
315
|
-
}
|
|
316
|
-
resolvePropertyType(e, n, r, o) {
|
|
317
|
-
if (u(o)) {
|
|
318
|
-
const a = l(d(o));
|
|
319
|
-
return N(e, n, this.outputDir, a), a.name;
|
|
320
|
-
}
|
|
321
|
-
if (o.const)
|
|
322
|
-
return `'${o.const}'`;
|
|
323
|
-
if (re(o)) {
|
|
324
|
-
const a = this.resolvePropertyType(e, n, r, o.items);
|
|
325
|
-
return ie(a);
|
|
326
|
-
}
|
|
327
|
-
if (o.type && ne(o.type))
|
|
328
|
-
return x(o.type);
|
|
329
|
-
if (j(o))
|
|
330
|
-
return this.resolvePropertyCompositionType(e, n, o);
|
|
331
|
-
if (o.type === "object" && o.properties) {
|
|
332
|
-
const a = {
|
|
333
|
-
path: e.path,
|
|
334
|
-
name: `${e.name}${P(r)}`
|
|
335
|
-
}, s = this.processObject(n, a, o);
|
|
336
|
-
return A(s, o.title, o.description), a.name;
|
|
337
|
-
}
|
|
338
|
-
return "any";
|
|
339
|
-
}
|
|
340
|
-
resolvePropertyCompositionType(e, n, r) {
|
|
341
|
-
const o = r.anyOf || r.oneOf || r.allOf, a = /* @__PURE__ */ new Set();
|
|
342
|
-
o.forEach((c) => {
|
|
343
|
-
if (u(c)) {
|
|
344
|
-
const i = l(d(c));
|
|
345
|
-
N(e, n, this.outputDir, i), a.add(i.name);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
a.add(x(c.type ?? "string"));
|
|
349
|
-
});
|
|
350
|
-
const s = ae(r) ? "|" : "&";
|
|
351
|
-
return Array.from(a).join(s);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
const pe = "types.ts", I = "@";
|
|
355
|
-
function B(t) {
|
|
356
|
-
return C(t.path, pe);
|
|
357
|
-
}
|
|
358
|
-
function v(t, e, n) {
|
|
359
|
-
const r = C(e, n), o = t.getSourceFile(r);
|
|
360
|
-
return o || t.createSourceFile(r, "", {
|
|
163
|
+
function D(n, e, t) {
|
|
164
|
+
const o = q(e, t), r = n.getSourceFile(o);
|
|
165
|
+
return r || n.createSourceFile(o, "", {
|
|
361
166
|
overwrite: !0
|
|
362
167
|
});
|
|
363
168
|
}
|
|
364
|
-
function
|
|
365
|
-
let
|
|
366
|
-
(
|
|
169
|
+
function $(n, e, t) {
|
|
170
|
+
let o = n.getImportDeclaration(
|
|
171
|
+
(r) => r.getModuleSpecifierValue() === e
|
|
367
172
|
);
|
|
368
|
-
|
|
173
|
+
o || (o = n.addImportDeclaration({
|
|
369
174
|
moduleSpecifier: e
|
|
370
|
-
})),
|
|
371
|
-
|
|
372
|
-
(
|
|
373
|
-
) ||
|
|
175
|
+
})), t.forEach((r) => {
|
|
176
|
+
o.getNamedImports().some(
|
|
177
|
+
(i) => i.getName() === r
|
|
178
|
+
) || o.addNamedImport(r);
|
|
374
179
|
});
|
|
375
180
|
}
|
|
376
|
-
function
|
|
377
|
-
if (
|
|
378
|
-
|
|
181
|
+
function y(n, e, t) {
|
|
182
|
+
if (t.path.startsWith(pe)) {
|
|
183
|
+
$(n, t.path, [t.name]);
|
|
379
184
|
return;
|
|
380
185
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
r.startsWith(I) || (o = C(I, r)), w(t, o, [n.name]);
|
|
186
|
+
const o = n.getDirectoryPath(), r = U(e, t.path, W);
|
|
187
|
+
let s = J(o, r);
|
|
188
|
+
s = s.replace(/\.ts$/, ""), s.startsWith(".") || (s = "./" + s), $(n, s, [t.name]);
|
|
385
189
|
}
|
|
386
|
-
function
|
|
387
|
-
|
|
190
|
+
function E(n, e, t, o) {
|
|
191
|
+
n.path !== o.path && y(e, t, o);
|
|
388
192
|
}
|
|
389
|
-
function
|
|
390
|
-
const
|
|
391
|
-
(
|
|
193
|
+
function de(n, e) {
|
|
194
|
+
const t = [n, e].filter(
|
|
195
|
+
(o) => o !== void 0 && o.length > 0
|
|
392
196
|
);
|
|
393
|
-
return
|
|
197
|
+
return t.length > 0 ? t.join(`
|
|
394
198
|
`) : void 0;
|
|
395
199
|
}
|
|
396
|
-
function
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
description:
|
|
200
|
+
function P(n, e, t) {
|
|
201
|
+
const o = de(e, t);
|
|
202
|
+
o && n.addJsDoc({
|
|
203
|
+
description: o
|
|
400
204
|
});
|
|
401
205
|
}
|
|
402
|
-
function
|
|
403
|
-
const e =
|
|
206
|
+
function ue(n) {
|
|
207
|
+
const e = n.split(".");
|
|
404
208
|
return e.length != 2 || e[0].length === 0 || e[1].length === 0 ? null : e;
|
|
405
209
|
}
|
|
406
|
-
function
|
|
407
|
-
const e =
|
|
210
|
+
function fe(n) {
|
|
211
|
+
const e = ue(n.name);
|
|
408
212
|
return e ? {
|
|
409
|
-
tag:
|
|
213
|
+
tag: n,
|
|
410
214
|
contextAlias: e[0],
|
|
411
215
|
aggregateName: e[1]
|
|
412
216
|
} : null;
|
|
413
217
|
}
|
|
414
|
-
function
|
|
415
|
-
const e =
|
|
218
|
+
function he(n) {
|
|
219
|
+
const e = n?.map((o) => fe(o)).filter((o) => o !== null);
|
|
416
220
|
if (!e)
|
|
417
221
|
return /* @__PURE__ */ new Map();
|
|
418
|
-
const
|
|
419
|
-
return e.forEach((
|
|
420
|
-
|
|
421
|
-
aggregate:
|
|
222
|
+
const t = /* @__PURE__ */ new Map();
|
|
223
|
+
return e.forEach((o) => {
|
|
224
|
+
t.set(o.tag.name, {
|
|
225
|
+
aggregate: o,
|
|
422
226
|
commands: /* @__PURE__ */ new Map(),
|
|
423
227
|
events: /* @__PURE__ */ new Map()
|
|
424
228
|
});
|
|
425
|
-
}),
|
|
229
|
+
}), t;
|
|
426
230
|
}
|
|
427
|
-
function
|
|
428
|
-
if (!
|
|
231
|
+
function ye(n) {
|
|
232
|
+
if (!n)
|
|
429
233
|
return null;
|
|
430
|
-
const e =
|
|
234
|
+
const e = n.split(".");
|
|
431
235
|
return e.length != 3 ? null : e[2];
|
|
432
236
|
}
|
|
433
|
-
const
|
|
434
|
-
class
|
|
237
|
+
const Ae = "#/components/responses/wow.CommandOk", Ce = "#/components/parameters/wow.id";
|
|
238
|
+
class Pe {
|
|
435
239
|
/**
|
|
436
240
|
* Creates a new AggregateResolver instance.
|
|
437
241
|
* @param openAPI - The OpenAPI specification to resolve aggregates from
|
|
438
242
|
*/
|
|
439
243
|
constructor(e) {
|
|
440
|
-
this.openAPI = e, this.aggregates =
|
|
244
|
+
this.openAPI = e, this.aggregates = he(e.tags), this.build();
|
|
441
245
|
}
|
|
442
246
|
aggregates;
|
|
443
247
|
/**
|
|
@@ -445,10 +249,10 @@ class Ae {
|
|
|
445
249
|
* @private
|
|
446
250
|
*/
|
|
447
251
|
build() {
|
|
448
|
-
for (const [e,
|
|
449
|
-
const
|
|
450
|
-
for (const
|
|
451
|
-
this.commands(e,
|
|
252
|
+
for (const [e, t] of Object.entries(this.openAPI.paths)) {
|
|
253
|
+
const o = ne(t);
|
|
254
|
+
for (const r of o)
|
|
255
|
+
this.commands(e, r), this.state(r.operation), this.events(r.operation), this.fields(r.operation);
|
|
452
256
|
}
|
|
453
257
|
}
|
|
454
258
|
/**
|
|
@@ -457,12 +261,12 @@ class Ae {
|
|
|
457
261
|
*/
|
|
458
262
|
resolve() {
|
|
459
263
|
const e = /* @__PURE__ */ new Map();
|
|
460
|
-
for (const
|
|
461
|
-
if (!
|
|
264
|
+
for (const t of this.aggregates.values()) {
|
|
265
|
+
if (!t.state || !t.fields)
|
|
462
266
|
continue;
|
|
463
|
-
const
|
|
464
|
-
let
|
|
465
|
-
|
|
267
|
+
const o = t.aggregate.contextAlias;
|
|
268
|
+
let r = e.get(o);
|
|
269
|
+
r || (r = /* @__PURE__ */ new Set(), e.set(o, r)), r.add(t);
|
|
466
270
|
}
|
|
467
271
|
return e;
|
|
468
272
|
}
|
|
@@ -471,44 +275,44 @@ class Ae {
|
|
|
471
275
|
* @param path - The API path
|
|
472
276
|
* @param methodOperation - The HTTP method and operation details
|
|
473
277
|
*/
|
|
474
|
-
commands(e,
|
|
475
|
-
const
|
|
476
|
-
if (
|
|
278
|
+
commands(e, t) {
|
|
279
|
+
const o = t.operation;
|
|
280
|
+
if (o.operationId === "wow.command.send")
|
|
477
281
|
return;
|
|
478
|
-
const
|
|
479
|
-
if (!
|
|
282
|
+
const r = ye(o.operationId);
|
|
283
|
+
if (!r)
|
|
480
284
|
return;
|
|
481
|
-
const
|
|
482
|
-
if (!
|
|
285
|
+
const s = G(o);
|
|
286
|
+
if (!s || !g(s) || s.$ref !== Ae || !o.requestBody)
|
|
483
287
|
return;
|
|
484
|
-
const
|
|
485
|
-
(
|
|
288
|
+
const i = o.parameters ?? [], c = i.filter((d) => g(d) && d.$ref === Ce).at(0), a = i.filter(
|
|
289
|
+
(d) => !g(d) && d.in === "path"
|
|
486
290
|
);
|
|
487
291
|
if (c) {
|
|
488
|
-
const
|
|
292
|
+
const d = H(
|
|
489
293
|
c,
|
|
490
294
|
this.openAPI.components
|
|
491
295
|
);
|
|
492
|
-
|
|
296
|
+
a.push(d);
|
|
493
297
|
}
|
|
494
|
-
const
|
|
495
|
-
|
|
298
|
+
const m = o.requestBody.content[I.APPLICATION_JSON].schema, l = C(
|
|
299
|
+
m,
|
|
496
300
|
this.openAPI.components
|
|
497
301
|
);
|
|
498
|
-
|
|
499
|
-
const
|
|
500
|
-
name:
|
|
501
|
-
method:
|
|
302
|
+
l.schema.title = l.schema.title || o.summary, l.schema.description = l.schema.description || o.description;
|
|
303
|
+
const z = {
|
|
304
|
+
name: r,
|
|
305
|
+
method: t.method,
|
|
502
306
|
path: e,
|
|
503
|
-
pathParameters:
|
|
504
|
-
summary:
|
|
505
|
-
description:
|
|
506
|
-
schema:
|
|
507
|
-
operation:
|
|
307
|
+
pathParameters: a,
|
|
308
|
+
summary: o.summary,
|
|
309
|
+
description: o.description,
|
|
310
|
+
schema: l,
|
|
311
|
+
operation: o
|
|
508
312
|
};
|
|
509
|
-
|
|
510
|
-
const
|
|
511
|
-
|
|
313
|
+
o.tags?.forEach((d) => {
|
|
314
|
+
const T = this.aggregates.get(d);
|
|
315
|
+
T && T.commands.set(r, z);
|
|
512
316
|
});
|
|
513
317
|
}
|
|
514
318
|
/**
|
|
@@ -518,16 +322,16 @@ class Ae {
|
|
|
518
322
|
state(e) {
|
|
519
323
|
if (!e.operationId?.endsWith(".snapshot_state.single"))
|
|
520
324
|
return;
|
|
521
|
-
const
|
|
522
|
-
if (!
|
|
325
|
+
const t = M(e);
|
|
326
|
+
if (!g(t))
|
|
523
327
|
return;
|
|
524
|
-
const
|
|
525
|
-
|
|
328
|
+
const o = C(
|
|
329
|
+
t,
|
|
526
330
|
this.openAPI.components
|
|
527
331
|
);
|
|
528
|
-
e.tags?.forEach((
|
|
529
|
-
const
|
|
530
|
-
|
|
332
|
+
e.tags?.forEach((r) => {
|
|
333
|
+
const s = this.aggregates.get(r);
|
|
334
|
+
s && (s.state = o);
|
|
531
335
|
});
|
|
532
336
|
}
|
|
533
337
|
/**
|
|
@@ -537,30 +341,30 @@ class Ae {
|
|
|
537
341
|
events(e) {
|
|
538
342
|
if (!this.openAPI.components || !e.operationId?.endsWith(".event.list_query"))
|
|
539
343
|
return;
|
|
540
|
-
const
|
|
541
|
-
if (
|
|
344
|
+
const t = M(e);
|
|
345
|
+
if (g(t))
|
|
542
346
|
return;
|
|
543
|
-
const
|
|
544
|
-
if (!
|
|
347
|
+
const o = t?.items;
|
|
348
|
+
if (!g(o))
|
|
545
349
|
return;
|
|
546
|
-
const
|
|
547
|
-
|
|
350
|
+
const s = S(
|
|
351
|
+
o,
|
|
548
352
|
this.openAPI.components
|
|
549
|
-
).properties.body.items.anyOf.map((
|
|
550
|
-
const c =
|
|
551
|
-
|
|
353
|
+
).properties.body.items.anyOf.map((i) => {
|
|
354
|
+
const c = i.title, a = i.properties.name.const, p = i.properties.body, m = C(
|
|
355
|
+
p,
|
|
552
356
|
this.openAPI.components
|
|
553
357
|
);
|
|
554
|
-
return
|
|
358
|
+
return m.schema.title = m.schema.title || i.title, {
|
|
555
359
|
title: c,
|
|
556
|
-
name:
|
|
557
|
-
schema:
|
|
360
|
+
name: a,
|
|
361
|
+
schema: m
|
|
558
362
|
};
|
|
559
363
|
});
|
|
560
|
-
e.tags?.forEach((
|
|
561
|
-
const c = this.aggregates.get(
|
|
562
|
-
c &&
|
|
563
|
-
c.events.set(
|
|
364
|
+
e.tags?.forEach((i) => {
|
|
365
|
+
const c = this.aggregates.get(i);
|
|
366
|
+
c && s.forEach((a) => {
|
|
367
|
+
c.events.set(a.name, a);
|
|
564
368
|
});
|
|
565
369
|
});
|
|
566
370
|
}
|
|
@@ -571,33 +375,289 @@ class Ae {
|
|
|
571
375
|
fields(e) {
|
|
572
376
|
if (!this.openAPI.components || !e.operationId?.endsWith(".snapshot.count"))
|
|
573
377
|
return;
|
|
574
|
-
const
|
|
378
|
+
const o = V(
|
|
575
379
|
e.requestBody,
|
|
576
380
|
this.openAPI.components
|
|
577
|
-
).content[
|
|
578
|
-
|
|
381
|
+
).content[I.APPLICATION_JSON].schema, s = S(
|
|
382
|
+
o,
|
|
579
383
|
this.openAPI.components
|
|
580
|
-
).properties?.field,
|
|
384
|
+
).properties?.field, i = C(s, this.openAPI.components);
|
|
581
385
|
e.tags?.forEach((c) => {
|
|
582
|
-
const
|
|
583
|
-
|
|
386
|
+
const a = this.aggregates.get(c);
|
|
387
|
+
a && (a.fields = i);
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
const A = "@ahoo-wang/fetcher-wow", $e = {
|
|
392
|
+
"wow.command.CommandResult": "CommandResult",
|
|
393
|
+
"wow.MessageHeaderSqlType": "MessageHeaderSqlType",
|
|
394
|
+
"wow.api.BindingError": "BindingError",
|
|
395
|
+
"wow.api.DefaultErrorInfo": "ErrorInfo",
|
|
396
|
+
"wow.api.RecoverableType": "RecoverableType",
|
|
397
|
+
"wow.api.command.DefaultDeleteAggregate": "DeleteAggregate",
|
|
398
|
+
"wow.api.command.DefaultRecoverAggregate": "RecoverAggregate",
|
|
399
|
+
"wow.api.messaging.FunctionInfoData": "FunctionInfo",
|
|
400
|
+
"wow.api.messaging.FunctionKind": "FunctionKind",
|
|
401
|
+
"wow.api.modeling.AggregateId": "AggregateId",
|
|
402
|
+
"wow.api.query.Condition": "Condition",
|
|
403
|
+
"wow.api.query.ConditionOptions": "ConditionOptions",
|
|
404
|
+
"wow.api.query.ListQuery": "ListQuery",
|
|
405
|
+
"wow.api.query.Operator": "Operator",
|
|
406
|
+
"wow.api.query.PagedQuery": "PagedQuery",
|
|
407
|
+
"wow.api.query.Pagination": "Pagination",
|
|
408
|
+
"wow.api.query.Projection": "Projection",
|
|
409
|
+
"wow.api.query.Sort": "FieldSort",
|
|
410
|
+
"wow.api.query.Sort.Direction": "SortDirection",
|
|
411
|
+
"wow.command.CommandStage": "CommandStage",
|
|
412
|
+
"wow.command.SimpleWaitSignal": "WaitSignal",
|
|
413
|
+
"wow.configuration.Aggregate": "Aggregate",
|
|
414
|
+
"wow.configuration.BoundedContext": "BoundedContext",
|
|
415
|
+
"wow.configuration.WowMetadata": "WowMetadata",
|
|
416
|
+
"wow.modeling.DomainEvent": "DomainEvent",
|
|
417
|
+
"wow.openapi.BatchResult": "BatchResult",
|
|
418
|
+
"wow.messaging.CompensationTarget": "CompensationTarget"
|
|
419
|
+
};
|
|
420
|
+
function u(n) {
|
|
421
|
+
if (!n)
|
|
422
|
+
return { name: "", path: "/" };
|
|
423
|
+
const e = $e[n];
|
|
424
|
+
if (e)
|
|
425
|
+
return { name: e, path: A };
|
|
426
|
+
const t = n.split(".");
|
|
427
|
+
let o = -1;
|
|
428
|
+
for (let a = 0; a < t.length; a++)
|
|
429
|
+
if (t[a] && /^[A-Z]/.test(t[a])) {
|
|
430
|
+
o = a;
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
if (o === -1)
|
|
434
|
+
return { name: n, path: "/" };
|
|
435
|
+
const r = t.slice(0, o), s = r.length > 0 ? `/${r.join("/")}` : "/", i = t.slice(o);
|
|
436
|
+
return { name: w(i), path: s };
|
|
437
|
+
}
|
|
438
|
+
class x {
|
|
439
|
+
/** The ts-morph project instance used for code generation */
|
|
440
|
+
project;
|
|
441
|
+
/** The OpenAPI specification object */
|
|
442
|
+
openAPI;
|
|
443
|
+
/** The output directory path for generated files */
|
|
444
|
+
outputDir;
|
|
445
|
+
/** Map of bounded context aggregates for domain modeling */
|
|
446
|
+
contextAggregates;
|
|
447
|
+
/** Optional logger for generation progress and errors */
|
|
448
|
+
logger;
|
|
449
|
+
/**
|
|
450
|
+
* Creates a new ClientGenerator instance.
|
|
451
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
452
|
+
*/
|
|
453
|
+
constructor(e) {
|
|
454
|
+
this.project = e.project, this.openAPI = e.openAPI, this.outputDir = e.outputDir, this.contextAggregates = e.contextAggregates, this.logger = e.logger;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
class we extends x {
|
|
458
|
+
constructor(e) {
|
|
459
|
+
super(e);
|
|
460
|
+
}
|
|
461
|
+
getOrCreateSourceFile(e) {
|
|
462
|
+
const t = me(e);
|
|
463
|
+
return D(this.project, this.outputDir, t);
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Generates models for all schemas in the OpenAPI specification.
|
|
467
|
+
* Skips schemas with keys starting with 'wow.'.
|
|
468
|
+
*
|
|
469
|
+
* @remarks
|
|
470
|
+
* This method iterates through all schemas in the OpenAPI specification
|
|
471
|
+
* and generates corresponding TypeScript models for each one.
|
|
472
|
+
*/
|
|
473
|
+
generate() {
|
|
474
|
+
const e = this.openAPI.components?.schemas;
|
|
475
|
+
if (!e) {
|
|
476
|
+
this.logger.info("No schemas found in OpenAPI specification");
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const t = Object.entries(e).filter(
|
|
480
|
+
([o]) => !o.startsWith("wow.")
|
|
481
|
+
);
|
|
482
|
+
this.logger.progress(
|
|
483
|
+
`Generating models for ${t.length} schemas`
|
|
484
|
+
), t.forEach(([o, r], s) => {
|
|
485
|
+
this.logger.progressWithCount(
|
|
486
|
+
s + 1,
|
|
487
|
+
t.length,
|
|
488
|
+
`Processing schema: ${o}`,
|
|
489
|
+
2
|
|
490
|
+
);
|
|
491
|
+
const i = {
|
|
492
|
+
key: o,
|
|
493
|
+
schema: r
|
|
494
|
+
};
|
|
495
|
+
this.generateKeyedSchema(i);
|
|
496
|
+
}), this.logger.success("Model generation completed");
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Generates a model for a specific schema key.
|
|
500
|
+
* Processes enums, objects, unions, and type aliases in order.
|
|
501
|
+
*
|
|
502
|
+
* @param schemaKey - The key of the schema to generate
|
|
503
|
+
* @param schema - The schema definition
|
|
504
|
+
*
|
|
505
|
+
* @remarks
|
|
506
|
+
* The generation process follows this order:
|
|
507
|
+
* 1. Enum processing
|
|
508
|
+
* 2. Object processing
|
|
509
|
+
* 3. Union processing
|
|
510
|
+
* 4. Type alias processing
|
|
511
|
+
*/
|
|
512
|
+
generateKeyedSchema({ key: e, schema: t }) {
|
|
513
|
+
const o = u(e), r = this.getOrCreateSourceFile(o), s = this.process(o, r, t);
|
|
514
|
+
s && P(s, t.title, t.description);
|
|
515
|
+
}
|
|
516
|
+
process(e, t, o) {
|
|
517
|
+
if (ae(o))
|
|
518
|
+
return t.addEnum({
|
|
519
|
+
name: e.name,
|
|
520
|
+
isExported: !0,
|
|
521
|
+
members: o.enum.filter((s) => typeof s == "string" && s.length > 0).map((s) => ({
|
|
522
|
+
name: s,
|
|
523
|
+
initializer: `'${s}'`
|
|
524
|
+
}))
|
|
525
|
+
});
|
|
526
|
+
const r = t.addInterface({
|
|
527
|
+
name: e.name,
|
|
528
|
+
isExported: !0
|
|
529
|
+
});
|
|
530
|
+
return o.type === "object" && o.properties ? this.processInterface(
|
|
531
|
+
t,
|
|
532
|
+
e,
|
|
533
|
+
o,
|
|
534
|
+
r
|
|
535
|
+
) : (j(o) && (o.anyOf || o.oneOf || o.allOf).forEach((i) => {
|
|
536
|
+
if (g(i)) {
|
|
537
|
+
const c = u(
|
|
538
|
+
f(i)
|
|
539
|
+
);
|
|
540
|
+
E(
|
|
541
|
+
e,
|
|
542
|
+
t,
|
|
543
|
+
this.outputDir,
|
|
544
|
+
c
|
|
545
|
+
), r.addExtends(c.name);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
this.processInterface(
|
|
549
|
+
t,
|
|
550
|
+
e,
|
|
551
|
+
i,
|
|
552
|
+
r
|
|
553
|
+
);
|
|
554
|
+
}), r);
|
|
555
|
+
}
|
|
556
|
+
processObject(e, t, o) {
|
|
557
|
+
const r = e.addInterface({
|
|
558
|
+
name: t.name,
|
|
559
|
+
isExported: !0
|
|
560
|
+
});
|
|
561
|
+
return this.processInterface(
|
|
562
|
+
e,
|
|
563
|
+
t,
|
|
564
|
+
o,
|
|
565
|
+
r
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
processInterface(e, t, o, r) {
|
|
569
|
+
for (const [s, i] of Object.entries(o.properties)) {
|
|
570
|
+
const c = this.resolvePropertyType(
|
|
571
|
+
t,
|
|
572
|
+
e,
|
|
573
|
+
s,
|
|
574
|
+
i
|
|
575
|
+
);
|
|
576
|
+
let a = r.getProperty(s);
|
|
577
|
+
a ? a.setType(c) : a = r.addProperty({
|
|
578
|
+
name: s,
|
|
579
|
+
type: c
|
|
580
|
+
}), g(i) || P(a, i.title, i.description);
|
|
581
|
+
}
|
|
582
|
+
return r;
|
|
583
|
+
}
|
|
584
|
+
resolvePropertyType(e, t, o, r) {
|
|
585
|
+
if (g(r)) {
|
|
586
|
+
const s = u(f(r));
|
|
587
|
+
return E(
|
|
588
|
+
e,
|
|
589
|
+
t,
|
|
590
|
+
this.outputDir,
|
|
591
|
+
s
|
|
592
|
+
), s.name;
|
|
593
|
+
}
|
|
594
|
+
if (r.const)
|
|
595
|
+
return `'${r.const}'`;
|
|
596
|
+
if (ie(r)) {
|
|
597
|
+
const s = this.resolvePropertyType(
|
|
598
|
+
e,
|
|
599
|
+
t,
|
|
600
|
+
o,
|
|
601
|
+
r.items
|
|
602
|
+
);
|
|
603
|
+
return le(s);
|
|
604
|
+
}
|
|
605
|
+
if (r.type && se(r.type))
|
|
606
|
+
return N(r.type);
|
|
607
|
+
if (j(r))
|
|
608
|
+
return this.resolvePropertyCompositionType(
|
|
609
|
+
e,
|
|
610
|
+
t,
|
|
611
|
+
r
|
|
612
|
+
);
|
|
613
|
+
if (r.type === "object" && r.properties) {
|
|
614
|
+
const s = {
|
|
615
|
+
path: e.path,
|
|
616
|
+
name: `${e.name}${w(o)}`
|
|
617
|
+
}, i = this.processObject(
|
|
618
|
+
t,
|
|
619
|
+
s,
|
|
620
|
+
r
|
|
621
|
+
);
|
|
622
|
+
return P(i, r.title, r.description), s.name;
|
|
623
|
+
}
|
|
624
|
+
return "any";
|
|
625
|
+
}
|
|
626
|
+
resolvePropertyCompositionType(e, t, o) {
|
|
627
|
+
const r = o.anyOf || o.oneOf || o.allOf, s = /* @__PURE__ */ new Set();
|
|
628
|
+
r.forEach((c) => {
|
|
629
|
+
if (g(c)) {
|
|
630
|
+
const a = u(
|
|
631
|
+
f(c)
|
|
632
|
+
);
|
|
633
|
+
E(
|
|
634
|
+
e,
|
|
635
|
+
t,
|
|
636
|
+
this.outputDir,
|
|
637
|
+
a
|
|
638
|
+
), s.add(a.name);
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
s.add(N(c.type ?? "string"));
|
|
584
642
|
});
|
|
643
|
+
const i = ce(o) ? "|" : "&";
|
|
644
|
+
return Array.from(s).join(i);
|
|
585
645
|
}
|
|
586
646
|
}
|
|
587
|
-
function
|
|
588
|
-
let e = 0,
|
|
589
|
-
return
|
|
590
|
-
|
|
591
|
-
}), e === 0 &&
|
|
647
|
+
function xe(n) {
|
|
648
|
+
let e = 0, t = 0;
|
|
649
|
+
return n.commands.forEach((o) => {
|
|
650
|
+
o.path.startsWith(R.TENANT) && (e += 1), o.path.startsWith(R.OWNER) && (t += 1);
|
|
651
|
+
}), e === 0 && t === 0 ? "ResourceAttributionPathSpec.NONE" : e > t ? "ResourceAttributionPathSpec.TENANT" : "ResourceAttributionPathSpec.OWNER";
|
|
592
652
|
}
|
|
593
|
-
function
|
|
594
|
-
const
|
|
595
|
-
return
|
|
653
|
+
function B(n, e, t, o) {
|
|
654
|
+
const r = `${t.contextAlias}/${t.aggregateName}/${o}.ts`;
|
|
655
|
+
return D(n, e, r);
|
|
596
656
|
}
|
|
597
|
-
function
|
|
598
|
-
return `${
|
|
657
|
+
function Ee(n, e) {
|
|
658
|
+
return `${w(n.aggregateName)}${e}`;
|
|
599
659
|
}
|
|
600
|
-
class
|
|
660
|
+
class Oe extends x {
|
|
601
661
|
/**
|
|
602
662
|
* Creates a new QueryClientGenerator instance.
|
|
603
663
|
* @param context - The generation context containing OpenAPI spec and project details
|
|
@@ -609,13 +669,19 @@ class Pe extends O {
|
|
|
609
669
|
* Generates query client classes for all aggregates.
|
|
610
670
|
*/
|
|
611
671
|
generate() {
|
|
612
|
-
const e = Array.from(this.contextAggregates.values()).
|
|
613
|
-
|
|
672
|
+
const e = Array.from(this.contextAggregates.values()).reduce(
|
|
673
|
+
(o, r) => o + r.size,
|
|
674
|
+
0
|
|
675
|
+
);
|
|
676
|
+
this.logger.info("--- Generating Query Clients ---"), this.logger.progress(
|
|
614
677
|
`Generating query clients for ${e} aggregates`
|
|
615
678
|
);
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
679
|
+
let t = 0;
|
|
680
|
+
for (const [, o] of this.contextAggregates)
|
|
681
|
+
o.forEach((r) => {
|
|
682
|
+
t++, this.logger.progressWithCount(
|
|
683
|
+
t,
|
|
684
|
+
e,
|
|
619
685
|
`Processing query client for aggregate: ${r.aggregate.aggregateName}`
|
|
620
686
|
), this.processQueryClient(r);
|
|
621
687
|
});
|
|
@@ -627,12 +693,12 @@ class Pe extends O {
|
|
|
627
693
|
* @param fileName - The name of the client file
|
|
628
694
|
* @returns The source file for the client
|
|
629
695
|
*/
|
|
630
|
-
createClientFilePath(e,
|
|
631
|
-
return
|
|
696
|
+
createClientFilePath(e, t) {
|
|
697
|
+
return B(
|
|
632
698
|
this.project,
|
|
633
699
|
this.outputDir,
|
|
634
700
|
e,
|
|
635
|
-
|
|
701
|
+
t
|
|
636
702
|
);
|
|
637
703
|
}
|
|
638
704
|
/**
|
|
@@ -640,58 +706,77 @@ class Pe extends O {
|
|
|
640
706
|
* @param aggregate - The aggregate definition
|
|
641
707
|
*/
|
|
642
708
|
processQueryClient(e) {
|
|
643
|
-
const
|
|
709
|
+
const t = this.createClientFilePath(
|
|
644
710
|
e.aggregate,
|
|
645
711
|
"queryClient"
|
|
646
712
|
);
|
|
647
|
-
|
|
648
|
-
|
|
713
|
+
this.logger.info(
|
|
714
|
+
`Processing query client for aggregate: ${e.aggregate.aggregateName} in context: ${e.aggregate.contextAlias}`
|
|
715
|
+
), this.logger.info(
|
|
716
|
+
`Adding imports from ${A}: QueryClientFactory, QueryClientOptions, ResourceAttributionPathSpec`
|
|
717
|
+
), t.addImportDeclaration({
|
|
718
|
+
moduleSpecifier: A,
|
|
649
719
|
namedImports: [
|
|
650
720
|
"QueryClientFactory",
|
|
651
721
|
"QueryClientOptions",
|
|
652
722
|
"ResourceAttributionPathSpec"
|
|
653
723
|
]
|
|
654
724
|
});
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
725
|
+
const o = "DEFAULT_QUERY_CLIENT_OPTIONS";
|
|
726
|
+
this.logger.info(
|
|
727
|
+
`Creating default query client options: ${o}`
|
|
728
|
+
), t.addVariableStatement({
|
|
729
|
+
declarationKind: O.Const,
|
|
658
730
|
declarations: [
|
|
659
731
|
{
|
|
660
|
-
name:
|
|
732
|
+
name: o,
|
|
661
733
|
type: "QueryClientOptions",
|
|
662
734
|
initializer: `{
|
|
663
735
|
contextAlias: '${e.aggregate.contextAlias}',
|
|
664
736
|
aggregateName: '${e.aggregate.aggregateName}',
|
|
665
|
-
resourceAttribution: ${
|
|
737
|
+
resourceAttribution: ${xe(e)},
|
|
666
738
|
}`
|
|
667
739
|
}
|
|
668
740
|
],
|
|
669
741
|
isExported: !1
|
|
670
742
|
});
|
|
671
|
-
const
|
|
743
|
+
const r = [];
|
|
744
|
+
this.logger.info(
|
|
745
|
+
`Processing ${e.events.size} domain events for aggregate: ${e.aggregate.aggregateName}`
|
|
746
|
+
);
|
|
672
747
|
for (const m of e.events.values()) {
|
|
673
|
-
const
|
|
674
|
-
|
|
748
|
+
const l = u(m.schema.key);
|
|
749
|
+
this.logger.info(
|
|
750
|
+
`Adding import for event model: ${l.name} from path: ${l.path}`
|
|
751
|
+
), y(t, this.outputDir, l), r.push(l);
|
|
675
752
|
}
|
|
676
|
-
const
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
753
|
+
const s = "DOMAIN_EVENT_TYPES", i = r.map((m) => m.name).join(" | ");
|
|
754
|
+
this.logger.info(
|
|
755
|
+
`Creating domain event types union: ${s} = ${i}`
|
|
756
|
+
), t.addTypeAlias({
|
|
757
|
+
name: s,
|
|
758
|
+
type: i
|
|
680
759
|
});
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
760
|
+
const c = `${h(e.aggregate.aggregateName)}QueryClientFactory`, a = u(e.state.key), p = u(e.fields.key);
|
|
761
|
+
this.logger.info(
|
|
762
|
+
`Adding import for state model: ${a.name} from path: ${a.path}`
|
|
763
|
+
), y(t, this.outputDir, a), this.logger.info(
|
|
764
|
+
`Adding import for fields model: ${p.name} from path: ${p.path}`
|
|
765
|
+
), y(t, this.outputDir, p), this.logger.info(`Creating query client factory: ${c}`), t.addVariableStatement({
|
|
766
|
+
declarationKind: O.Const,
|
|
684
767
|
declarations: [
|
|
685
768
|
{
|
|
686
|
-
name:
|
|
687
|
-
initializer: `new QueryClientFactory<${
|
|
769
|
+
name: c,
|
|
770
|
+
initializer: `new QueryClientFactory<${a.name}, ${p.name} | string, ${s}>(${o})`
|
|
688
771
|
}
|
|
689
772
|
],
|
|
690
773
|
isExported: !0
|
|
691
|
-
})
|
|
774
|
+
}), this.logger.success(
|
|
775
|
+
`Query client generation completed for aggregate: ${e.aggregate.aggregateName}`
|
|
776
|
+
);
|
|
692
777
|
}
|
|
693
778
|
}
|
|
694
|
-
class
|
|
779
|
+
class Ie extends x {
|
|
695
780
|
commandEndpointPathsName = "COMMAND_ENDPOINT_PATHS";
|
|
696
781
|
defaultCommandClientOptionsName = "DEFAULT_COMMAND_CLIENT_OPTIONS";
|
|
697
782
|
/**
|
|
@@ -705,13 +790,19 @@ class Ee extends O {
|
|
|
705
790
|
* Generates command client classes for all aggregates.
|
|
706
791
|
*/
|
|
707
792
|
generate() {
|
|
708
|
-
const e = Array.from(this.contextAggregates.values()).
|
|
709
|
-
|
|
793
|
+
const e = Array.from(this.contextAggregates.values()).reduce(
|
|
794
|
+
(o, r) => o + r.size,
|
|
795
|
+
0
|
|
796
|
+
);
|
|
797
|
+
this.logger.info("--- Generating Command Clients ---"), this.logger.progress(
|
|
710
798
|
`Generating command clients for ${e} aggregates`
|
|
711
799
|
);
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
800
|
+
let t = 0;
|
|
801
|
+
for (const [, o] of this.contextAggregates)
|
|
802
|
+
o.forEach((r) => {
|
|
803
|
+
t++, this.logger.progressWithCount(
|
|
804
|
+
t,
|
|
805
|
+
e,
|
|
715
806
|
`Processing command client for aggregate: ${r.aggregate.aggregateName}`
|
|
716
807
|
), this.processAggregate(r);
|
|
717
808
|
});
|
|
@@ -722,14 +813,21 @@ class Ee extends O {
|
|
|
722
813
|
* @param aggregate - The aggregate definition
|
|
723
814
|
*/
|
|
724
815
|
processAggregate(e) {
|
|
725
|
-
|
|
816
|
+
this.logger.info(
|
|
817
|
+
`Processing command client for aggregate: ${e.aggregate.aggregateName} in context: ${e.aggregate.contextAlias}`
|
|
818
|
+
);
|
|
819
|
+
const t = B(
|
|
726
820
|
this.project,
|
|
727
821
|
this.outputDir,
|
|
728
822
|
e.aggregate,
|
|
729
823
|
"commandClient"
|
|
730
824
|
);
|
|
731
|
-
this.
|
|
732
|
-
|
|
825
|
+
this.logger.info(
|
|
826
|
+
`Processing command endpoint paths for ${e.commands.size} commands`
|
|
827
|
+
), this.processCommandEndpointPaths(t, e), this.logger.info(
|
|
828
|
+
`Creating default command client options: ${this.defaultCommandClientOptionsName}`
|
|
829
|
+
), t.addVariableStatement({
|
|
830
|
+
declarationKind: O.Const,
|
|
733
831
|
declarations: [
|
|
734
832
|
{
|
|
735
833
|
name: this.defaultCommandClientOptionsName,
|
|
@@ -740,8 +838,10 @@ class Ee extends O {
|
|
|
740
838
|
}
|
|
741
839
|
],
|
|
742
840
|
isExported: !1
|
|
743
|
-
}),
|
|
744
|
-
|
|
841
|
+
}), this.logger.info(
|
|
842
|
+
`Adding imports from ${A}: CommandRequest, CommandResult, CommandResultEventStream, DeleteAggregate, RecoverAggregate`
|
|
843
|
+
), t.addImportDeclaration({
|
|
844
|
+
moduleSpecifier: A,
|
|
745
845
|
namedImports: [
|
|
746
846
|
"CommandRequest",
|
|
747
847
|
"CommandResult",
|
|
@@ -750,10 +850,16 @@ class Ee extends O {
|
|
|
750
850
|
"RecoverAggregate"
|
|
751
851
|
],
|
|
752
852
|
isTypeOnly: !0
|
|
753
|
-
}),
|
|
853
|
+
}), this.logger.info(
|
|
854
|
+
"Adding import from @ahoo-wang/fetcher-eventstream: JsonEventStreamResultExtractor"
|
|
855
|
+
), t.addImportDeclaration({
|
|
754
856
|
moduleSpecifier: "@ahoo-wang/fetcher-eventstream",
|
|
755
857
|
namedImports: ["JsonEventStreamResultExtractor"]
|
|
756
|
-
}),
|
|
858
|
+
}), this.logger.info(
|
|
859
|
+
"Adding import from @ahoo-wang/fetcher: ContentTypeValues"
|
|
860
|
+
), $(t, "@ahoo-wang/fetcher", ["ContentTypeValues"]), this.logger.info(
|
|
861
|
+
"Adding imports from @ahoo-wang/fetcher-decorator: ApiMetadata types and decorators"
|
|
862
|
+
), $(t, "@ahoo-wang/fetcher-decorator", [
|
|
757
863
|
"type ApiMetadata",
|
|
758
864
|
"type ApiMetadataCapable",
|
|
759
865
|
"api",
|
|
@@ -765,28 +871,37 @@ class Ee extends O {
|
|
|
765
871
|
"attribute",
|
|
766
872
|
"path",
|
|
767
873
|
"autoGeneratedError"
|
|
768
|
-
]), this.processCommandClient(
|
|
874
|
+
]), this.logger.info("Generating standard command client class"), this.processCommandClient(t, e), this.logger.info("Generating stream command client class"), this.processCommandClient(t, e, !0), this.logger.success(
|
|
875
|
+
`Command client generation completed for aggregate: ${e.aggregate.aggregateName}`
|
|
876
|
+
);
|
|
769
877
|
}
|
|
770
|
-
processCommandEndpointPaths(e,
|
|
771
|
-
|
|
878
|
+
processCommandEndpointPaths(e, t) {
|
|
879
|
+
this.logger.info(
|
|
880
|
+
`Creating command endpoint paths enum: ${this.commandEndpointPathsName}`
|
|
881
|
+
);
|
|
882
|
+
const o = e.addEnum({
|
|
772
883
|
name: this.commandEndpointPathsName
|
|
773
884
|
});
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
885
|
+
t.commands.forEach((r) => {
|
|
886
|
+
this.logger.info(
|
|
887
|
+
`Adding command endpoint: ${r.name.toUpperCase()} = '${r.path}'`
|
|
888
|
+
), o.addMember({
|
|
889
|
+
name: r.name.toUpperCase(),
|
|
890
|
+
initializer: `'${r.path}'`
|
|
778
891
|
});
|
|
779
|
-
})
|
|
892
|
+
}), this.logger.success(
|
|
893
|
+
`Command endpoint paths enum created with ${t.commands.size} entries`
|
|
894
|
+
);
|
|
780
895
|
}
|
|
781
896
|
getEndpointPath(e) {
|
|
782
897
|
return `${this.commandEndpointPathsName}.${e.name.toUpperCase()}`;
|
|
783
898
|
}
|
|
784
|
-
processCommandClient(e,
|
|
785
|
-
let
|
|
899
|
+
processCommandClient(e, t, o = !1) {
|
|
900
|
+
let r = "CommandClient", s = {
|
|
786
901
|
name: "api",
|
|
787
902
|
arguments: []
|
|
788
|
-
},
|
|
789
|
-
|
|
903
|
+
}, i = "Promise<CommandResult>";
|
|
904
|
+
o && (r = "Stream" + r, s = {
|
|
790
905
|
name: "api",
|
|
791
906
|
arguments: [
|
|
792
907
|
"''",
|
|
@@ -795,28 +910,28 @@ class Ee extends O {
|
|
|
795
910
|
resultExtractor: JsonEventStreamResultExtractor,
|
|
796
911
|
}`
|
|
797
912
|
]
|
|
798
|
-
},
|
|
799
|
-
const c =
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
),
|
|
913
|
+
}, i = "Promise<CommandResultEventStream>");
|
|
914
|
+
const c = Ee(
|
|
915
|
+
t.aggregate,
|
|
916
|
+
r
|
|
917
|
+
), a = e.addClass({
|
|
803
918
|
name: c,
|
|
804
919
|
isExported: !0,
|
|
805
|
-
decorators: [
|
|
920
|
+
decorators: [s],
|
|
806
921
|
implements: ["ApiMetadataCapable"]
|
|
807
922
|
});
|
|
808
|
-
|
|
923
|
+
a.addConstructor({
|
|
809
924
|
parameters: [
|
|
810
925
|
{
|
|
811
926
|
name: "apiMetadata",
|
|
812
927
|
type: "ApiMetadata",
|
|
813
|
-
scope:
|
|
928
|
+
scope: L.Public,
|
|
814
929
|
isReadonly: !0,
|
|
815
930
|
initializer: `${this.defaultCommandClientOptionsName}`
|
|
816
931
|
}
|
|
817
932
|
]
|
|
818
|
-
}),
|
|
819
|
-
this.processCommandMethod(e,
|
|
933
|
+
}), t.commands.forEach((p) => {
|
|
934
|
+
this.processCommandMethod(e, a, p, i);
|
|
820
935
|
});
|
|
821
936
|
}
|
|
822
937
|
methodToDecorator(e) {
|
|
@@ -828,29 +943,41 @@ class Ee extends O {
|
|
|
828
943
|
* @param client - The client class declaration
|
|
829
944
|
* @param definition - The command definition
|
|
830
945
|
*/
|
|
831
|
-
processCommandMethod(e,
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
946
|
+
processCommandMethod(e, t, o, r) {
|
|
947
|
+
const s = u(o.schema.key);
|
|
948
|
+
this.logger.info(
|
|
949
|
+
`Adding import for command model: ${s.name} from path: ${s.path}`
|
|
950
|
+
), y(e, this.outputDir, s), this.logger.info(
|
|
951
|
+
`Generating command method: ${h(o.name)} for command: ${o.name}`
|
|
952
|
+
), this.logger.info(
|
|
953
|
+
`Command method details: HTTP ${o.method}, path: ${o.path}, return type: ${r}`
|
|
954
|
+
);
|
|
955
|
+
const i = o.pathParameters.map((a) => (this.logger.info(
|
|
956
|
+
`Adding path parameter: ${a.name} (type: string)`
|
|
957
|
+
), {
|
|
958
|
+
name: a.name,
|
|
836
959
|
type: "string",
|
|
837
960
|
decorators: [
|
|
838
961
|
{
|
|
839
962
|
name: "path",
|
|
840
|
-
arguments: [`'${
|
|
963
|
+
arguments: [`'${a.name}'`]
|
|
841
964
|
}
|
|
842
965
|
]
|
|
843
966
|
}));
|
|
844
|
-
|
|
967
|
+
this.logger.info(
|
|
968
|
+
`Adding command request parameter: commandRequest (type: CommandRequest<${s.name}>)`
|
|
969
|
+
), i.push({
|
|
845
970
|
name: "commandRequest",
|
|
846
|
-
type: `CommandRequest<${
|
|
971
|
+
type: `CommandRequest<${s.name}>`,
|
|
847
972
|
decorators: [
|
|
848
973
|
{
|
|
849
974
|
name: "request",
|
|
850
975
|
arguments: []
|
|
851
976
|
}
|
|
852
977
|
]
|
|
853
|
-
}),
|
|
978
|
+
}), this.logger.info(
|
|
979
|
+
"Adding attributes parameter: attributes (type: Record<string, any>)"
|
|
980
|
+
), i.push({
|
|
854
981
|
name: "attributes",
|
|
855
982
|
type: "Record<string, any>",
|
|
856
983
|
decorators: [
|
|
@@ -860,24 +987,28 @@ class Ee extends O {
|
|
|
860
987
|
}
|
|
861
988
|
]
|
|
862
989
|
});
|
|
863
|
-
const c =
|
|
864
|
-
name:
|
|
990
|
+
const c = t.addMethod({
|
|
991
|
+
name: h(o.name),
|
|
865
992
|
decorators: [
|
|
866
993
|
{
|
|
867
|
-
name: this.methodToDecorator(
|
|
868
|
-
arguments: [`${this.getEndpointPath(
|
|
994
|
+
name: this.methodToDecorator(o.method),
|
|
995
|
+
arguments: [`${this.getEndpointPath(o)}`]
|
|
869
996
|
}
|
|
870
997
|
],
|
|
871
|
-
parameters:
|
|
872
|
-
returnType:
|
|
998
|
+
parameters: i,
|
|
999
|
+
returnType: r,
|
|
873
1000
|
statements: [
|
|
874
|
-
`throw autoGeneratedError(${
|
|
1001
|
+
`throw autoGeneratedError(${i.map((a) => a.name).join(",")});`
|
|
875
1002
|
]
|
|
876
1003
|
});
|
|
877
|
-
|
|
1004
|
+
(o.summary || o.description) && this.logger.info(
|
|
1005
|
+
`Adding JSDoc documentation for method: ${h(o.name)}`
|
|
1006
|
+
), P(c, o.summary, o.description), this.logger.success(
|
|
1007
|
+
`Command method generated: ${h(o.name)}`
|
|
1008
|
+
);
|
|
878
1009
|
}
|
|
879
1010
|
}
|
|
880
|
-
class
|
|
1011
|
+
class Se extends x {
|
|
881
1012
|
queryClientGenerator;
|
|
882
1013
|
commandClientGenerator;
|
|
883
1014
|
/**
|
|
@@ -885,17 +1016,23 @@ class Oe extends O {
|
|
|
885
1016
|
* @param context - The generation context containing OpenAPI spec and project details
|
|
886
1017
|
*/
|
|
887
1018
|
constructor(e) {
|
|
888
|
-
super(e), this.queryClientGenerator = new
|
|
1019
|
+
super(e), this.queryClientGenerator = new Oe(e), this.commandClientGenerator = new Ie(e);
|
|
889
1020
|
}
|
|
890
1021
|
/**
|
|
891
1022
|
* Generates client classes for all aggregates.
|
|
892
1023
|
*/
|
|
893
1024
|
generate() {
|
|
894
|
-
this.logger.progress(
|
|
1025
|
+
this.logger.info("--- Generating Clients ---"), this.logger.progress(
|
|
895
1026
|
`Generating clients for ${this.contextAggregates.size} bounded contexts`
|
|
896
1027
|
);
|
|
897
|
-
|
|
898
|
-
|
|
1028
|
+
let e = 0;
|
|
1029
|
+
for (const [t] of this.contextAggregates)
|
|
1030
|
+
e++, this.logger.progressWithCount(
|
|
1031
|
+
e,
|
|
1032
|
+
this.contextAggregates.size,
|
|
1033
|
+
`Processing bounded context: ${t}`,
|
|
1034
|
+
1
|
|
1035
|
+
), this.processBoundedContext(t);
|
|
899
1036
|
this.queryClientGenerator.generate(), this.commandClientGenerator.generate(), this.logger.success("Client generation completed");
|
|
900
1037
|
}
|
|
901
1038
|
/**
|
|
@@ -903,19 +1040,25 @@ class Oe extends O {
|
|
|
903
1040
|
* @param contextAlias - The alias of the bounded context to process
|
|
904
1041
|
*/
|
|
905
1042
|
processBoundedContext(e) {
|
|
906
|
-
const
|
|
907
|
-
|
|
1043
|
+
const t = `${e}/boundedContext.ts`;
|
|
1044
|
+
this.logger.info(`Creating bounded context file: ${t}`);
|
|
1045
|
+
const o = D(this.project, this.outputDir, t);
|
|
1046
|
+
this.logger.info(
|
|
1047
|
+
`Adding bounded context alias constant: BOUNDED_CONTEXT_ALIAS = '${e}'`
|
|
1048
|
+
), o.addStatements(
|
|
908
1049
|
`export const BOUNDED_CONTEXT_ALIAS = '${e}';`
|
|
1050
|
+
), this.logger.success(
|
|
1051
|
+
`Bounded context file created successfully: ${t}`
|
|
909
1052
|
);
|
|
910
1053
|
}
|
|
911
1054
|
}
|
|
912
|
-
class
|
|
1055
|
+
class Me {
|
|
913
1056
|
/**
|
|
914
1057
|
* Creates a new CodeGenerator instance.
|
|
915
1058
|
* @param options - Configuration options for code generation
|
|
916
1059
|
*/
|
|
917
1060
|
constructor(e) {
|
|
918
|
-
this.options = e, this.project = e.project;
|
|
1061
|
+
this.options = e, this.project = e.project, this.options.logger.info("CodeGenerator instance created");
|
|
919
1062
|
}
|
|
920
1063
|
project;
|
|
921
1064
|
/**
|
|
@@ -924,19 +1067,113 @@ class xe {
|
|
|
924
1067
|
* and formats the output files.
|
|
925
1068
|
*/
|
|
926
1069
|
async generate() {
|
|
927
|
-
|
|
1070
|
+
this.options.logger.info(
|
|
1071
|
+
"Starting code generation from OpenAPI specification"
|
|
1072
|
+
), this.options.logger.info(`Input path: ${this.options.inputPath}`), this.options.logger.info(`Output directory: ${this.options.outputDir}`), this.options.logger.info("Parsing OpenAPI specification");
|
|
1073
|
+
const e = await ee(this.options.inputPath);
|
|
1074
|
+
this.options.logger.info("OpenAPI specification parsed successfully"), this.options.logger.info("Resolving bounded context aggregates");
|
|
1075
|
+
const o = new Pe(e).resolve();
|
|
1076
|
+
this.options.logger.info(
|
|
1077
|
+
`Resolved ${o.size} bounded context aggregates`
|
|
1078
|
+
);
|
|
1079
|
+
const r = {
|
|
928
1080
|
openAPI: e,
|
|
929
1081
|
project: this.project,
|
|
930
1082
|
outputDir: this.options.outputDir,
|
|
931
|
-
contextAggregates:
|
|
1083
|
+
contextAggregates: o,
|
|
932
1084
|
logger: this.options.logger
|
|
933
1085
|
};
|
|
934
|
-
new
|
|
935
|
-
|
|
936
|
-
|
|
1086
|
+
this.options.logger.info("Generating models"), new we(r).generate(), this.options.logger.info("Models generated successfully"), this.options.logger.info("Generating clients"), new Se(r).generate(), this.options.logger.info("Clients generated successfully"), this.options.logger.info("Generating index files"), this.generateIndex(), this.options.logger.info("Index files generated successfully"), this.options.logger.info("Optimizing source files"), this.optimizeSourceFiles(), this.options.logger.info("Source files optimized successfully"), this.options.logger.info("Saving project to disk"), await this.project.save(), this.options.logger.info("Code generation completed successfully");
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Generates index.ts files for all subdirectories in the output directory.
|
|
1090
|
+
* Scans all directories, gets all .ts files in each directory,
|
|
1091
|
+
* and creates index.ts files with export * from './xxx' statements.
|
|
1092
|
+
*/
|
|
1093
|
+
generateIndex() {
|
|
1094
|
+
this.options.logger.info(
|
|
1095
|
+
`Generating index files for output directory: ${this.options.outputDir}`
|
|
1096
|
+
);
|
|
1097
|
+
const e = this.project.getDirectory(this.options.outputDir);
|
|
1098
|
+
if (!e) {
|
|
1099
|
+
this.options.logger.info(
|
|
1100
|
+
"Output directory not found, skipping index generation"
|
|
1101
|
+
);
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
this.processDirectory(e), this.options.logger.info("Index file generation completed");
|
|
1105
|
+
}
|
|
1106
|
+
processDirectory(e) {
|
|
1107
|
+
const t = e.getDirectories();
|
|
1108
|
+
this.options.logger.info(`Processing ${t.length} subdirectories`);
|
|
1109
|
+
for (const o of t)
|
|
1110
|
+
this.options.logger.info(`Processing subdirectory: ${o.getPath()}`), this.generateIndexForDirectory(o), this.processDirectory(o);
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Generates an index.ts file for a specific directory.
|
|
1114
|
+
* @param dir - The directory to generate index.ts for
|
|
1115
|
+
*/
|
|
1116
|
+
generateIndexForDirectory(e) {
|
|
1117
|
+
const t = e.getPath();
|
|
1118
|
+
this.options.logger.info(`Generating index for directory: ${t}`);
|
|
1119
|
+
const o = e.getSourceFiles().filter(
|
|
1120
|
+
(c) => c.getBaseName().endsWith(".ts") && c.getBaseName() !== "index.ts"
|
|
1121
|
+
);
|
|
1122
|
+
let r = [];
|
|
1123
|
+
try {
|
|
1124
|
+
r = v.readdirSync(t).filter((c) => {
|
|
1125
|
+
const a = K.join(t, c);
|
|
1126
|
+
return v.statSync(a).isDirectory();
|
|
1127
|
+
});
|
|
1128
|
+
} catch (c) {
|
|
1129
|
+
this.options.logger.error(
|
|
1130
|
+
`Failed to read subdirectories for ${t}: ${c}`
|
|
1131
|
+
);
|
|
1132
|
+
}
|
|
1133
|
+
if (this.options.logger.info(
|
|
1134
|
+
`Found ${o.length} TypeScript files and ${r.length} subdirectories in ${t}`
|
|
1135
|
+
), o.length === 0 && r.length === 0) {
|
|
1136
|
+
this.options.logger.info(
|
|
1137
|
+
`No files or subdirectories to export in ${t}, skipping index generation`
|
|
1138
|
+
);
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
const s = `${t}/index.ts`;
|
|
1142
|
+
this.options.logger.info(`Creating/updating index file: ${s}`);
|
|
1143
|
+
const i = this.project.getSourceFile(s) || this.project.createSourceFile(s, "", { overwrite: !0 });
|
|
1144
|
+
i.removeText();
|
|
1145
|
+
for (const c of o) {
|
|
1146
|
+
const a = `./${c.getBaseNameWithoutExtension()}`;
|
|
1147
|
+
this.options.logger.info(`Adding export for file: ${a}`), i.addExportDeclaration({
|
|
1148
|
+
moduleSpecifier: a,
|
|
1149
|
+
isTypeOnly: !1,
|
|
1150
|
+
namedExports: []
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
for (const c of r) {
|
|
1154
|
+
const a = `./${c}`;
|
|
1155
|
+
this.options.logger.info(
|
|
1156
|
+
`Adding export for subdirectory: ${a}`
|
|
1157
|
+
), i.addExportDeclaration({
|
|
1158
|
+
moduleSpecifier: a,
|
|
1159
|
+
isTypeOnly: !1,
|
|
1160
|
+
namedExports: []
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
this.options.logger.info(
|
|
1164
|
+
`Index file generated for ${t} with ${o.length + r.length} exports`
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
optimizeSourceFiles() {
|
|
1168
|
+
const e = this.project.getSourceFiles();
|
|
1169
|
+
this.options.logger.info(`Optimizing ${e.length} source files`), e.forEach((t, o) => {
|
|
1170
|
+
this.options.logger.info(
|
|
1171
|
+
`Optimizing file ${o + 1}/${e.length}`
|
|
1172
|
+
), t.formatText(), t.organizeImports(), t.fixMissingImports();
|
|
1173
|
+
}), this.options.logger.info("All source files optimized");
|
|
937
1174
|
}
|
|
938
1175
|
}
|
|
939
1176
|
export {
|
|
940
|
-
|
|
1177
|
+
Me as CodeGenerator
|
|
941
1178
|
};
|
|
942
1179
|
//# sourceMappingURL=index.js.map
|