@ahoo-wang/fetcher-generator 2.1.0 → 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/dist/index.js CHANGED
@@ -1,70 +1,73 @@
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";
1
+ import { VariableDeclarationKind as O, Scope as L } from "ts-morph";
2
+ import { parse as Q } from "yaml";
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";
5
8
  import { ResourceAttributionPathSpec as R } from "@ahoo-wang/fetcher-wow";
6
- function h(r) {
7
- return r.$ref.split("/").pop();
9
+ function f(n) {
10
+ return n.$ref.split("/").pop();
8
11
  }
9
- function E(r, e) {
10
- const n = h(r);
11
- return e.schemas?.[n];
12
+ function S(n, e) {
13
+ const t = f(n);
14
+ return e.schemas?.[t];
12
15
  }
13
- function Q(r, e) {
14
- const n = h(r);
15
- return e.requestBodies?.[n];
16
+ function V(n, e) {
17
+ const t = f(n);
18
+ return e.requestBodies?.[t];
16
19
  }
17
- function k(r, e) {
18
- const n = h(r);
19
- return e.parameters?.[n];
20
+ function H(n, e) {
21
+ const t = f(n);
22
+ return e.parameters?.[t];
20
23
  }
21
- function y(r, e) {
24
+ function C(n, e) {
22
25
  return {
23
- key: h(r),
24
- schema: E(r, e)
26
+ key: f(n),
27
+ schema: S(n, e)
25
28
  };
26
29
  }
27
- const x = /[-_\s.]+|(?=[A-Z])/;
28
- function O(r) {
29
- if (r === "" || r.length === 0)
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(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();
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 M(r) {
39
- const e = O(r);
41
+ function h(n) {
42
+ const e = w(n);
40
43
  return e.charAt(0).toLowerCase() + e.slice(1);
41
44
  }
42
- function U(r) {
43
- return r.startsWith("http://") || r.startsWith("https://") ? J(r) : V(r);
45
+ function Y(n) {
46
+ return n.startsWith("http://") || n.startsWith("https://") ? X(n) : Z(n);
44
47
  }
45
- async function J(r) {
46
- return await (await fetch(r)).text();
48
+ async function X(n) {
49
+ return await (await fetch(n)).text();
47
50
  }
48
- function V(r) {
49
- return new Promise((e, n) => {
50
- K(r, "utf-8", (t, o) => {
51
- t ? n(t) : e(o);
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 z(r) {
56
- const e = await U(r);
57
- switch (H(e)) {
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
- return L(e);
64
+ return Q(e);
62
65
  default:
63
- throw new Error(`Unsupported file format: ${r}`);
66
+ throw new Error(`Unsupported file format: ${n}`);
64
67
  }
65
68
  }
66
- function H(r) {
67
- const e = r.trimStart();
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,38 +80,69 @@ function H(r) {
77
80
  }
78
81
  throw new Error("Unable to infer file format");
79
82
  }
80
- function l(r) {
81
- return !!(r && typeof r == "object" && "$ref" in r);
83
+ function g(n) {
84
+ return !!(n && typeof n == "object" && "$ref" in n);
82
85
  }
83
- function Y(r) {
84
- return !r || l(r) || !r.content ? void 0 : r.content[P.APPLICATION_JSON]?.schema;
86
+ function oe(n) {
87
+ return !n || g(n) || !n.content ? void 0 : n.content[I.APPLICATION_JSON]?.schema;
85
88
  }
86
- function Z(r) {
89
+ function ne(n) {
87
90
  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 }
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 j(r) {
99
- return r.responses[200];
101
+ function G(n) {
102
+ return n.responses[200];
100
103
  }
101
- function b(r) {
102
- const e = j(r);
103
- return Y(e);
104
+ function M(n) {
105
+ const e = G(n);
106
+ return oe(e);
104
107
  }
105
- function X(r) {
106
- return Array.isArray(r.enum) && r.enum.length > 0;
108
+ const re = [
109
+ "string",
110
+ "number",
111
+ "integer",
112
+ "boolean",
113
+ "null"
114
+ ];
115
+ function se(n) {
116
+ return Array.isArray(n) ? !0 : re.includes(n);
107
117
  }
108
- function $(r) {
109
- if (Array.isArray(r))
110
- return r.map((e) => $(e)).join(" | ");
111
- switch (r) {
118
+ function ie(n) {
119
+ return n.type === "array";
120
+ }
121
+ function ae(n) {
122
+ return Array.isArray(n.enum) && n.enum.length > 0;
123
+ }
124
+ function F(n) {
125
+ return Array.isArray(n.anyOf) && n.anyOf.length > 0;
126
+ }
127
+ function _(n) {
128
+ return Array.isArray(n.oneOf) && n.oneOf.length > 0;
129
+ }
130
+ function ce(n) {
131
+ return F(n) || _(n);
132
+ }
133
+ function ge(n) {
134
+ return Array.isArray(n.allOf) && n.allOf.length > 0;
135
+ }
136
+ function j(n) {
137
+ return F(n) || _(n) || ge(n);
138
+ }
139
+ function le(n) {
140
+ return n.includes("|") || n.includes("&") ? `(${n})[]` : `${n}[]`;
141
+ }
142
+ function N(n) {
143
+ if (Array.isArray(n))
144
+ return n.map((e) => N(e)).join(" | ");
145
+ switch (n) {
112
146
  case "string":
113
147
  return "string";
114
148
  case "number":
@@ -122,93 +156,92 @@ function $(r) {
122
156
  return "any";
123
157
  }
124
158
  }
125
- const ee = "types.ts", w = "@";
126
- function q(r) {
127
- return A(r.path, ee);
159
+ const W = "types.ts", pe = "@";
160
+ function me(n) {
161
+ return q(n.path, W);
128
162
  }
129
- function T(r, e, n) {
130
- const t = A(e, n), o = r.getSourceFile(t);
131
- return o || r.createSourceFile(t, "", {
163
+ function D(n, e, t) {
164
+ const o = q(e, t), r = n.getSourceFile(o);
165
+ return r || n.createSourceFile(o, "", {
132
166
  overwrite: !0
133
167
  });
134
168
  }
135
- function N(r, e, n) {
136
- let t = r.getImportDeclaration(
137
- (o) => o.getModuleSpecifierValue() === e
169
+ function $(n, e, t) {
170
+ let o = n.getImportDeclaration(
171
+ (r) => r.getModuleSpecifierValue() === e
138
172
  );
139
- t || (t = r.addImportDeclaration({
173
+ o || (o = n.addImportDeclaration({
140
174
  moduleSpecifier: e
141
- })), n.forEach((o) => {
142
- t.getNamedImports().some(
143
- (s) => s.getName() === o
144
- ) || t.addNamedImport(o);
175
+ })), t.forEach((r) => {
176
+ o.getNamedImports().some(
177
+ (i) => i.getName() === r
178
+ ) || o.addNamedImport(r);
145
179
  });
146
180
  }
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]);
181
+ function y(n, e, t) {
182
+ if (t.path.startsWith(pe)) {
183
+ $(n, t.path, [t.name]);
184
+ return;
185
+ }
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]);
152
189
  }
153
- function te(r, e, n, t) {
154
- r.path !== t.path && f(e, n, t);
190
+ function E(n, e, t, o) {
191
+ n.path !== o.path && y(e, t, o);
155
192
  }
156
- function _(r, e) {
157
- const n = [r, e].filter(
158
- (t) => t !== void 0 && t.length > 0
193
+ function de(n, e) {
194
+ const t = [n, e].filter(
195
+ (o) => o !== void 0 && o.length > 0
159
196
  );
160
- return n.length > 0 ? n.join(`
197
+ return t.length > 0 ? t.join(`
161
198
  `) : void 0;
162
199
  }
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
200
+ function P(n, e, t) {
201
+ const o = de(e, t);
202
+ o && n.addJsDoc({
203
+ description: o
171
204
  });
172
205
  }
173
- function ne(r) {
174
- const e = r.split(".");
206
+ function ue(n) {
207
+ const e = n.split(".");
175
208
  return e.length != 2 || e[0].length === 0 || e[1].length === 0 ? null : e;
176
209
  }
177
- function re(r) {
178
- const e = ne(r.name);
210
+ function fe(n) {
211
+ const e = ue(n.name);
179
212
  return e ? {
180
- tag: r,
213
+ tag: n,
181
214
  contextAlias: e[0],
182
215
  aggregateName: e[1]
183
216
  } : null;
184
217
  }
185
- function oe(r) {
186
- const e = r?.map((t) => re(t)).filter((t) => t !== null);
218
+ function he(n) {
219
+ const e = n?.map((o) => fe(o)).filter((o) => o !== null);
187
220
  if (!e)
188
221
  return /* @__PURE__ */ new Map();
189
- const n = /* @__PURE__ */ new Map();
190
- return e.forEach((t) => {
191
- n.set(t.tag.name, {
192
- aggregate: t,
222
+ const t = /* @__PURE__ */ new Map();
223
+ return e.forEach((o) => {
224
+ t.set(o.tag.name, {
225
+ aggregate: o,
193
226
  commands: /* @__PURE__ */ new Map(),
194
227
  events: /* @__PURE__ */ new Map()
195
228
  });
196
- }), n;
229
+ }), t;
197
230
  }
198
- function ae(r) {
199
- if (!r)
231
+ function ye(n) {
232
+ if (!n)
200
233
  return null;
201
- const e = r.split(".");
234
+ const e = n.split(".");
202
235
  return e.length != 3 ? null : e[2];
203
236
  }
204
- const se = "#/components/responses/wow.CommandOk", ie = "#/components/parameters/wow.id";
205
- class ce {
237
+ const Ae = "#/components/responses/wow.CommandOk", Ce = "#/components/parameters/wow.id";
238
+ class Pe {
206
239
  /**
207
240
  * Creates a new AggregateResolver instance.
208
241
  * @param openAPI - The OpenAPI specification to resolve aggregates from
209
242
  */
210
243
  constructor(e) {
211
- this.openAPI = e, this.aggregates = oe(e.tags), this.build();
244
+ this.openAPI = e, this.aggregates = he(e.tags), this.build();
212
245
  }
213
246
  aggregates;
214
247
  /**
@@ -216,10 +249,10 @@ class ce {
216
249
  * @private
217
250
  */
218
251
  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);
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);
223
256
  }
224
257
  }
225
258
  /**
@@ -228,12 +261,12 @@ class ce {
228
261
  */
229
262
  resolve() {
230
263
  const e = /* @__PURE__ */ new Map();
231
- for (const n of this.aggregates.values()) {
232
- if (!n.state || !n.fields)
264
+ for (const t of this.aggregates.values()) {
265
+ if (!t.state || !t.fields)
233
266
  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);
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);
237
270
  }
238
271
  return e;
239
272
  }
@@ -242,44 +275,44 @@ class ce {
242
275
  * @param path - The API path
243
276
  * @param methodOperation - The HTTP method and operation details
244
277
  */
245
- commands(e, n) {
246
- const t = n.operation;
247
- if (t.operationId === "wow.command.send")
278
+ commands(e, t) {
279
+ const o = t.operation;
280
+ if (o.operationId === "wow.command.send")
248
281
  return;
249
- const o = ae(t.operationId);
250
- if (!o)
282
+ const r = ye(o.operationId);
283
+ if (!r)
251
284
  return;
252
- const a = j(t);
253
- if (!a || !l(a) || a.$ref !== se || !t.requestBody)
285
+ const s = G(o);
286
+ if (!s || !g(s) || s.$ref !== Ae || !o.requestBody)
254
287
  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"
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"
257
290
  );
258
291
  if (c) {
259
- const m = k(
292
+ const d = H(
260
293
  c,
261
294
  this.openAPI.components
262
295
  );
263
- i.push(m);
296
+ a.push(d);
264
297
  }
265
- const u = t.requestBody.content[P.APPLICATION_JSON].schema, d = y(
266
- u,
298
+ const m = o.requestBody.content[I.APPLICATION_JSON].schema, l = C(
299
+ m,
267
300
  this.openAPI.components
268
301
  );
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,
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,
273
306
  path: e,
274
- pathParameters: i,
275
- summary: t.summary,
276
- description: t.description,
277
- schema: d,
278
- operation: t
307
+ pathParameters: a,
308
+ summary: o.summary,
309
+ description: o.description,
310
+ schema: l,
311
+ operation: o
279
312
  };
280
- t.tags?.forEach((m) => {
281
- const I = this.aggregates.get(m);
282
- I && I.commands.set(o, B);
313
+ o.tags?.forEach((d) => {
314
+ const T = this.aggregates.get(d);
315
+ T && T.commands.set(r, z);
283
316
  });
284
317
  }
285
318
  /**
@@ -289,16 +322,16 @@ class ce {
289
322
  state(e) {
290
323
  if (!e.operationId?.endsWith(".snapshot_state.single"))
291
324
  return;
292
- const n = b(e);
293
- if (!l(n))
325
+ const t = M(e);
326
+ if (!g(t))
294
327
  return;
295
- const t = y(
296
- n,
328
+ const o = C(
329
+ t,
297
330
  this.openAPI.components
298
331
  );
299
- e.tags?.forEach((o) => {
300
- const a = this.aggregates.get(o);
301
- a && (a.state = t);
332
+ e.tags?.forEach((r) => {
333
+ const s = this.aggregates.get(r);
334
+ s && (s.state = o);
302
335
  });
303
336
  }
304
337
  /**
@@ -308,30 +341,30 @@ class ce {
308
341
  events(e) {
309
342
  if (!this.openAPI.components || !e.operationId?.endsWith(".event.list_query"))
310
343
  return;
311
- const n = b(e);
312
- if (l(n))
344
+ const t = M(e);
345
+ if (g(t))
313
346
  return;
314
- const t = n?.items;
315
- if (!l(t))
347
+ const o = t?.items;
348
+ if (!g(o))
316
349
  return;
317
- const a = E(
318
- t,
350
+ const s = S(
351
+ o,
319
352
  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(
353
+ ).properties.body.items.anyOf.map((i) => {
354
+ const c = i.title, a = i.properties.name.const, p = i.properties.body, m = C(
322
355
  p,
323
356
  this.openAPI.components
324
357
  );
325
- return u.schema.title = u.schema.title || s.title, {
358
+ return m.schema.title = m.schema.title || i.title, {
326
359
  title: c,
327
- name: i,
328
- schema: u
360
+ name: a,
361
+ schema: m
329
362
  };
330
363
  });
331
- e.tags?.forEach((s) => {
332
- const c = this.aggregates.get(s);
333
- c && a.forEach((i) => {
334
- c.events.set(i.name, i);
364
+ e.tags?.forEach((i) => {
365
+ const c = this.aggregates.get(i);
366
+ c && s.forEach((a) => {
367
+ c.events.set(a.name, a);
335
368
  });
336
369
  });
337
370
  }
@@ -342,20 +375,20 @@ class ce {
342
375
  fields(e) {
343
376
  if (!this.openAPI.components || !e.operationId?.endsWith(".snapshot.count"))
344
377
  return;
345
- const t = Q(
378
+ const o = V(
346
379
  e.requestBody,
347
380
  this.openAPI.components
348
- ).content[P.APPLICATION_JSON].schema, a = E(
349
- t,
381
+ ).content[I.APPLICATION_JSON].schema, s = S(
382
+ o,
350
383
  this.openAPI.components
351
- ).properties?.field, s = y(a, this.openAPI.components);
384
+ ).properties?.field, i = C(s, this.openAPI.components);
352
385
  e.tags?.forEach((c) => {
353
- const i = this.aggregates.get(c);
354
- i && (i.fields = s);
386
+ const a = this.aggregates.get(c);
387
+ a && (a.fields = i);
355
388
  });
356
389
  }
357
390
  }
358
- const v = "@ahoo-wang/fetcher-wow", pe = {
391
+ const A = "@ahoo-wang/fetcher-wow", $e = {
359
392
  "wow.command.CommandResult": "CommandResult",
360
393
  "wow.MessageHeaderSqlType": "MessageHeaderSqlType",
361
394
  "wow.api.BindingError": "BindingError",
@@ -384,29 +417,34 @@ const v = "@ahoo-wang/fetcher-wow", pe = {
384
417
  "wow.openapi.BatchResult": "BatchResult",
385
418
  "wow.messaging.CompensationTarget": "CompensationTarget"
386
419
  };
387
- function g(r) {
388
- if (!r)
420
+ function u(n) {
421
+ if (!n)
389
422
  return { name: "", path: "/" };
390
- const e = pe[r];
423
+ const e = $e[n];
391
424
  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;
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;
398
431
  break;
399
432
  }
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 };
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 };
404
437
  }
405
- class C {
438
+ class x {
439
+ /** The ts-morph project instance used for code generation */
406
440
  project;
441
+ /** The OpenAPI specification object */
407
442
  openAPI;
443
+ /** The output directory path for generated files */
408
444
  outputDir;
445
+ /** Map of bounded context aggregates for domain modeling */
409
446
  contextAggregates;
447
+ /** Optional logger for generation progress and errors */
410
448
  logger;
411
449
  /**
412
450
  * Creates a new ClientGenerator instance.
@@ -416,13 +454,13 @@ class C {
416
454
  this.project = e.project, this.openAPI = e.openAPI, this.outputDir = e.outputDir, this.contextAggregates = e.contextAggregates, this.logger = e.logger;
417
455
  }
418
456
  }
419
- class me extends C {
457
+ class we extends x {
420
458
  constructor(e) {
421
459
  super(e);
422
460
  }
423
461
  getOrCreateSourceFile(e) {
424
- const n = q(e);
425
- return T(this.project, this.outputDir, n);
462
+ const t = me(e);
463
+ return D(this.project, this.outputDir, t);
426
464
  }
427
465
  /**
428
466
  * Generates models for all schemas in the OpenAPI specification.
@@ -435,14 +473,27 @@ class me extends C {
435
473
  generate() {
436
474
  const e = this.openAPI.components?.schemas;
437
475
  if (!e) {
438
- this.logger?.info("No schemas found in OpenAPI specification");
476
+ this.logger.info("No schemas found in OpenAPI specification");
439
477
  return;
440
478
  }
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");
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");
446
497
  }
447
498
  /**
448
499
  * Generates a model for a specific schema key.
@@ -458,174 +509,155 @@ class me extends C {
458
509
  * 3. Union processing
459
510
  * 4. Type alias processing
460
511
  */
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;
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);
464
515
  }
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({
516
+ process(e, t, o) {
517
+ if (ae(o))
518
+ return t.addEnum({
488
519
  name: e.name,
489
520
  isExported: !0,
490
- members: t.enum.filter((o) => typeof o == "string" && o.length > 0).map((o) => ({
491
- name: o,
492
- initializer: `'${o}'`
521
+ members: o.enum.filter((s) => typeof s == "string" && s.length > 0).map((s) => ({
522
+ name: s,
523
+ initializer: `'${s}'`
493
524
  }))
494
525
  });
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({
526
+ const r = t.addInterface({
517
527
  name: e.name,
518
- isExported: !0,
519
- properties: Object.entries(o).map(([s, c]) => ({
520
- name: s,
521
- type: c
522
- }))
528
+ isExported: !0
523
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);
524
555
  }
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)
556
+ processObject(e, t, o) {
557
+ const r = e.addInterface({
558
+ name: t.name,
559
+ isExported: !0
568
560
  });
561
+ return this.processInterface(
562
+ e,
563
+ t,
564
+ o,
565
+ r
566
+ );
569
567
  }
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;
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;
596
583
  }
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;
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"));
642
+ });
643
+ const i = ce(o) ? "|" : "&";
644
+ return Array.from(s).join(i);
613
645
  }
614
646
  }
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";
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";
620
652
  }
621
- function W(r, e, n, t) {
622
- const o = `${n.contextAlias}/${n.aggregateName}/${t}.ts`;
623
- return T(r, e, o);
653
+ function B(n, e, t, o) {
654
+ const r = `${t.contextAlias}/${t.aggregateName}/${o}.ts`;
655
+ return D(n, e, r);
624
656
  }
625
- function le(r, e) {
626
- return `${O(r.aggregateName)}${e}`;
657
+ function Ee(n, e) {
658
+ return `${w(n.aggregateName)}${e}`;
627
659
  }
628
- class ge extends C {
660
+ class Oe extends x {
629
661
  /**
630
662
  * Creates a new QueryClientGenerator instance.
631
663
  * @param context - The generation context containing OpenAPI spec and project details
@@ -637,17 +669,23 @@ class ge extends C {
637
669
  * Generates query client classes for all aggregates.
638
670
  */
639
671
  generate() {
640
- const e = Array.from(this.contextAggregates.values()).flat().length;
641
- this.logger?.progress(
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(
642
677
  `Generating query clients for ${e} aggregates`
643
678
  );
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);
679
+ let t = 0;
680
+ for (const [, o] of this.contextAggregates)
681
+ o.forEach((r) => {
682
+ t++, this.logger.progressWithCount(
683
+ t,
684
+ e,
685
+ `Processing query client for aggregate: ${r.aggregate.aggregateName}`
686
+ ), this.processQueryClient(r);
649
687
  });
650
- this.logger?.success("Query client generation completed");
688
+ this.logger.success("Query client generation completed");
651
689
  }
652
690
  /**
653
691
  * Creates or retrieves a source file for client generation.
@@ -655,12 +693,12 @@ class ge extends C {
655
693
  * @param fileName - The name of the client file
656
694
  * @returns The source file for the client
657
695
  */
658
- createClientFilePath(e, n) {
659
- return W(
696
+ createClientFilePath(e, t) {
697
+ return B(
660
698
  this.project,
661
699
  this.outputDir,
662
700
  e,
663
- n
701
+ t
664
702
  );
665
703
  }
666
704
  /**
@@ -668,58 +706,77 @@ class ge extends C {
668
706
  * @param aggregate - The aggregate definition
669
707
  */
670
708
  processQueryClient(e) {
671
- const n = this.createClientFilePath(
709
+ const t = this.createClientFilePath(
672
710
  e.aggregate,
673
711
  "queryClient"
674
712
  );
675
- n.addImportDeclaration({
676
- moduleSpecifier: v,
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,
677
719
  namedImports: [
678
720
  "QueryClientFactory",
679
721
  "QueryClientOptions",
680
722
  "ResourceAttributionPathSpec"
681
723
  ]
682
724
  });
683
- const t = "DEFAULT_QUERY_CLIENT_OPTIONS";
684
- n.addVariableStatement({
685
- declarationKind: S.Const,
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,
686
730
  declarations: [
687
731
  {
688
- name: t,
732
+ name: o,
689
733
  type: "QueryClientOptions",
690
734
  initializer: `{
691
735
  contextAlias: '${e.aggregate.contextAlias}',
692
736
  aggregateName: '${e.aggregate.aggregateName}',
693
- resourceAttribution: ${ue(e)},
737
+ resourceAttribution: ${xe(e)},
694
738
  }`
695
739
  }
696
740
  ],
697
741
  isExported: !1
698
742
  });
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);
743
+ const r = [];
744
+ this.logger.info(
745
+ `Processing ${e.events.size} domain events for aggregate: ${e.aggregate.aggregateName}`
746
+ );
747
+ for (const m of e.events.values()) {
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);
703
752
  }
704
- const a = "DOMAIN_EVENT_TYPES";
705
- n.addTypeAlias({
706
- name: a,
707
- type: o.map((p) => p.name).join(" | ")
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
708
759
  });
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,
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,
712
767
  declarations: [
713
768
  {
714
- name: s,
715
- initializer: `new QueryClientFactory<${c.name}, ${i.name} | string, ${a}>(${t})`
769
+ name: c,
770
+ initializer: `new QueryClientFactory<${a.name}, ${p.name} | string, ${s}>(${o})`
716
771
  }
717
772
  ],
718
773
  isExported: !0
719
- });
774
+ }), this.logger.success(
775
+ `Query client generation completed for aggregate: ${e.aggregate.aggregateName}`
776
+ );
720
777
  }
721
778
  }
722
- class de extends C {
779
+ class Ie extends x {
723
780
  commandEndpointPathsName = "COMMAND_ENDPOINT_PATHS";
724
781
  defaultCommandClientOptionsName = "DEFAULT_COMMAND_CLIENT_OPTIONS";
725
782
  /**
@@ -733,31 +790,44 @@ class de extends C {
733
790
  * Generates command client classes for all aggregates.
734
791
  */
735
792
  generate() {
736
- const e = Array.from(this.contextAggregates.values()).flat().length;
737
- this.logger?.progress(
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(
738
798
  `Generating command clients for ${e} aggregates`
739
799
  );
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);
800
+ let t = 0;
801
+ for (const [, o] of this.contextAggregates)
802
+ o.forEach((r) => {
803
+ t++, this.logger.progressWithCount(
804
+ t,
805
+ e,
806
+ `Processing command client for aggregate: ${r.aggregate.aggregateName}`
807
+ ), this.processAggregate(r);
745
808
  });
746
- this.logger?.success("Command client generation completed");
809
+ this.logger.success("Command client generation completed");
747
810
  }
748
811
  /**
749
812
  * Processes and generates command client for an aggregate.
750
813
  * @param aggregate - The aggregate definition
751
814
  */
752
815
  processAggregate(e) {
753
- const n = W(
816
+ this.logger.info(
817
+ `Processing command client for aggregate: ${e.aggregate.aggregateName} in context: ${e.aggregate.contextAlias}`
818
+ );
819
+ const t = B(
754
820
  this.project,
755
821
  this.outputDir,
756
822
  e.aggregate,
757
823
  "commandClient"
758
824
  );
759
- this.processCommandEndpointPaths(n, e), n.addVariableStatement({
760
- declarationKind: S.Const,
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,
761
831
  declarations: [
762
832
  {
763
833
  name: this.defaultCommandClientOptionsName,
@@ -768,8 +838,10 @@ class de extends C {
768
838
  }
769
839
  ],
770
840
  isExported: !1
771
- }), n.addImportDeclaration({
772
- moduleSpecifier: v,
841
+ }), this.logger.info(
842
+ `Adding imports from ${A}: CommandRequest, CommandResult, CommandResultEventStream, DeleteAggregate, RecoverAggregate`
843
+ ), t.addImportDeclaration({
844
+ moduleSpecifier: A,
773
845
  namedImports: [
774
846
  "CommandRequest",
775
847
  "CommandResult",
@@ -778,42 +850,58 @@ class de extends C {
778
850
  "RecoverAggregate"
779
851
  ],
780
852
  isTypeOnly: !0
781
- }), n.addImportDeclaration({
853
+ }), this.logger.info(
854
+ "Adding import from @ahoo-wang/fetcher-eventstream: JsonEventStreamResultExtractor"
855
+ ), t.addImportDeclaration({
782
856
  moduleSpecifier: "@ahoo-wang/fetcher-eventstream",
783
857
  namedImports: ["JsonEventStreamResultExtractor"]
784
- }), N(n, "@ahoo-wang/fetcher", ["ContentTypeValues"]), N(n, "@ahoo-wang/fetcher-decorator", [
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", [
785
863
  "type ApiMetadata",
786
864
  "type ApiMetadataCapable",
787
865
  "api",
788
866
  "post",
789
867
  "put",
868
+ "patch",
790
869
  "del",
791
870
  "request",
792
871
  "attribute",
793
872
  "path",
794
873
  "autoGeneratedError"
795
- ]), this.processCommandClient(n, e), this.processCommandClient(n, e, !0);
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
+ );
796
877
  }
797
- processCommandEndpointPaths(e, n) {
798
- const t = e.addEnum({
878
+ processCommandEndpointPaths(e, t) {
879
+ this.logger.info(
880
+ `Creating command endpoint paths enum: ${this.commandEndpointPathsName}`
881
+ );
882
+ const o = e.addEnum({
799
883
  name: this.commandEndpointPathsName
800
884
  });
801
- n.commands.forEach((o) => {
802
- t.addMember({
803
- name: o.name.toUpperCase(),
804
- initializer: `'${o.path}'`
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}'`
805
891
  });
806
- });
892
+ }), this.logger.success(
893
+ `Command endpoint paths enum created with ${t.commands.size} entries`
894
+ );
807
895
  }
808
896
  getEndpointPath(e) {
809
897
  return `${this.commandEndpointPathsName}.${e.name.toUpperCase()}`;
810
898
  }
811
- processCommandClient(e, n, t = !1) {
812
- let o = "CommandClient", a = {
899
+ processCommandClient(e, t, o = !1) {
900
+ let r = "CommandClient", s = {
813
901
  name: "api",
814
902
  arguments: []
815
- }, s = "Promise<CommandResult>";
816
- t && (o = "Stream" + o, a = {
903
+ }, i = "Promise<CommandResult>";
904
+ o && (r = "Stream" + r, s = {
817
905
  name: "api",
818
906
  arguments: [
819
907
  "''",
@@ -822,28 +910,28 @@ class de extends C {
822
910
  resultExtractor: JsonEventStreamResultExtractor,
823
911
  }`
824
912
  ]
825
- }, s = "Promise<CommandResultEventStream>");
826
- const c = le(
827
- n.aggregate,
828
- o
829
- ), i = e.addClass({
913
+ }, i = "Promise<CommandResultEventStream>");
914
+ const c = Ee(
915
+ t.aggregate,
916
+ r
917
+ ), a = e.addClass({
830
918
  name: c,
831
919
  isExported: !0,
832
- decorators: [a],
920
+ decorators: [s],
833
921
  implements: ["ApiMetadataCapable"]
834
922
  });
835
- i.addConstructor({
923
+ a.addConstructor({
836
924
  parameters: [
837
925
  {
838
926
  name: "apiMetadata",
839
927
  type: "ApiMetadata",
840
- scope: F.Public,
928
+ scope: L.Public,
841
929
  isReadonly: !0,
842
930
  initializer: `${this.defaultCommandClientOptionsName}`
843
931
  }
844
932
  ]
845
- }), n.commands.forEach((p) => {
846
- this.processCommandMethod(e, i, p, s);
933
+ }), t.commands.forEach((p) => {
934
+ this.processCommandMethod(e, a, p, i);
847
935
  });
848
936
  }
849
937
  methodToDecorator(e) {
@@ -855,29 +943,41 @@ class de extends C {
855
943
  * @param client - The client class declaration
856
944
  * @param definition - The command definition
857
945
  */
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,
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,
863
959
  type: "string",
864
960
  decorators: [
865
961
  {
866
962
  name: "path",
867
- arguments: [`'${i.name}'`]
963
+ arguments: [`'${a.name}'`]
868
964
  }
869
965
  ]
870
966
  }));
871
- s.push({
967
+ this.logger.info(
968
+ `Adding command request parameter: commandRequest (type: CommandRequest<${s.name}>)`
969
+ ), i.push({
872
970
  name: "commandRequest",
873
- type: `CommandRequest<${a.name}>`,
971
+ type: `CommandRequest<${s.name}>`,
874
972
  decorators: [
875
973
  {
876
974
  name: "request",
877
975
  arguments: []
878
976
  }
879
977
  ]
880
- }), s.push({
978
+ }), this.logger.info(
979
+ "Adding attributes parameter: attributes (type: Record<string, any>)"
980
+ ), i.push({
881
981
  name: "attributes",
882
982
  type: "Record<string, any>",
883
983
  decorators: [
@@ -887,24 +987,28 @@ class de extends C {
887
987
  }
888
988
  ]
889
989
  });
890
- const c = n.addMethod({
891
- name: M(t.name),
990
+ const c = t.addMethod({
991
+ name: h(o.name),
892
992
  decorators: [
893
993
  {
894
- name: this.methodToDecorator(t.method),
895
- arguments: [`${this.getEndpointPath(t)}`]
994
+ name: this.methodToDecorator(o.method),
995
+ arguments: [`${this.getEndpointPath(o)}`]
896
996
  }
897
997
  ],
898
- parameters: s,
899
- returnType: o,
998
+ parameters: i,
999
+ returnType: r,
900
1000
  statements: [
901
- `throw autoGeneratedError(${s.map((i) => i.name).join(",")});`
1001
+ `throw autoGeneratedError(${i.map((a) => a.name).join(",")});`
902
1002
  ]
903
1003
  });
904
- G(c, t.summary, t.description);
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
+ );
905
1009
  }
906
1010
  }
907
- class fe extends C {
1011
+ class Se extends x {
908
1012
  queryClientGenerator;
909
1013
  commandClientGenerator;
910
1014
  /**
@@ -912,37 +1016,49 @@ class fe extends C {
912
1016
  * @param context - The generation context containing OpenAPI spec and project details
913
1017
  */
914
1018
  constructor(e) {
915
- super(e), this.queryClientGenerator = new ge(e), this.commandClientGenerator = new de(e);
1019
+ super(e), this.queryClientGenerator = new Oe(e), this.commandClientGenerator = new Ie(e);
916
1020
  }
917
1021
  /**
918
1022
  * Generates client classes for all aggregates.
919
1023
  */
920
1024
  generate() {
921
- this.logger?.progress(
1025
+ this.logger.info("--- Generating Clients ---"), this.logger.progress(
922
1026
  `Generating clients for ${this.contextAggregates.size} bounded contexts`
923
1027
  );
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");
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);
1036
+ this.queryClientGenerator.generate(), this.commandClientGenerator.generate(), this.logger.success("Client generation completed");
927
1037
  }
928
1038
  /**
929
1039
  * Processes a bounded context by creating a file with the context alias constant.
930
1040
  * @param contextAlias - The alias of the bounded context to process
931
1041
  */
932
1042
  processBoundedContext(e) {
933
- const n = `${e}/boundedContext.ts`;
934
- T(this.project, this.outputDir, n).addStatements(
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(
935
1049
  `export const BOUNDED_CONTEXT_ALIAS = '${e}';`
1050
+ ), this.logger.success(
1051
+ `Bounded context file created successfully: ${t}`
936
1052
  );
937
1053
  }
938
1054
  }
939
- class Se {
1055
+ class Me {
940
1056
  /**
941
1057
  * Creates a new CodeGenerator instance.
942
1058
  * @param options - Configuration options for code generation
943
1059
  */
944
1060
  constructor(e) {
945
- this.options = e, this.project = e.project;
1061
+ this.options = e, this.project = e.project, this.options.logger.info("CodeGenerator instance created");
946
1062
  }
947
1063
  project;
948
1064
  /**
@@ -951,18 +1067,113 @@ class Se {
951
1067
  * and formats the output files.
952
1068
  */
953
1069
  async generate() {
954
- const e = await z(this.options.inputPath), t = new ce(e).resolve(), o = {
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 = {
955
1080
  openAPI: e,
956
1081
  project: this.project,
957
1082
  outputDir: this.options.outputDir,
958
- contextAggregates: t,
1083
+ contextAggregates: o,
959
1084
  logger: this.options.logger
960
1085
  };
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();
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");
964
1174
  }
965
1175
  }
966
1176
  export {
967
- Se as CodeGenerator
1177
+ Me as CodeGenerator
968
1178
  };
1179
+ //# sourceMappingURL=index.js.map