@vc-shell/api-client-generator 2.0.7 → 2.0.8

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 CHANGED
@@ -56,13 +56,13 @@ Add the dependencies to your project's **package.json**:
56
56
 
57
57
  The options are listed in the table below:
58
58
 
59
- | Options | Description | Example |
60
- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
61
- | `--APP_PLATFORM_MODULES` | Platform modules to generate API client.<br>{==string[]==} <br> Supports spaces in module lists: `[Module1, Module2]` or `[Module1,Module2]`<br>Customize the `--APP_PLATFORM_MODULES` list<br>to match your project's requirements. | `--APP_PLATFORM_MODULES='[VirtoCommerce.Catalog, VirtoCommerce.Orders]'` |
62
- | `--APP_API_CLIENT_DIRECTORY` | Output directory for generated API clients. <br>{==string==} | `--APP_API_CLIENT_DIRECTORY=./src/api_client/` |
63
- | `--APP_PLATFORM_URL` | Platform URL to obtain client API configs. <br>{==string==} | `--APP_PLATFORM_URL=https://vcmp-dev.govirto.com/` |
64
- | `--APP_TYPE_STYLE` | Sets the type style for generated DTOs. Can be 'Class' or 'Interface'.<br>{==string==} | `--APP_TYPE_STYLE=Interface` |
65
- | `--VERBOSE` | Enable verbose logging. <br>{==boolean==} | `--VERBOSE=true` |
59
+ | Options | Description | Example |
60
+ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
61
+ | `--APP_PLATFORM_MODULES` | Platform modules to generate API client.<br>{==string[]==} <br> **Always quote the value** so the shell does not split it: `'[Module1, Module2]'`. Spaces inside quotes are fine. The generator validates the value and fails fast with a quoting hint if it looks truncated. | `--APP_PLATFORM_MODULES='[VirtoCommerce.Catalog, VirtoCommerce.Orders]'` |
62
+ | `--APP_API_CLIENT_DIRECTORY` | Output directory for generated API clients. <br>{==string==} | `--APP_API_CLIENT_DIRECTORY=./src/api_client/` |
63
+ | `--APP_PLATFORM_URL` | Platform URL to obtain client API configs. <br>{==string==} | `--APP_PLATFORM_URL=https://vcmp-dev.govirto.com/` |
64
+ | `--APP_TYPE_STYLE` | Sets the type style for generated DTOs. Can be 'Class' or 'Interface'.<br>{==string==} | `--APP_TYPE_STYLE=Interface` |
65
+ | `--VERBOSE` | Enable verbose logging. <br>{==boolean==} | `--VERBOSE=true` |
66
66
 
67
67
  !!! note
68
68
  For the `--APP_TYPE_STYLE` parameter, use **exactly** `"Class"` or `"Interface"` (case-sensitive). Any other value will cause an error.
@@ -70,6 +70,9 @@ Add the dependencies to your project's **package.json**:
70
70
  !!! tip
71
71
  Use `--APP_TYPE_STYLE=Interface` for better TypeScript integration and smaller bundle sizes. Use `--APP_TYPE_STYLE=Class` when you need runtime type checking or class-specific features.
72
72
 
73
+ !!! warning
74
+ When passing `--APP_PLATFORM_MODULES` on the command line, wrap the value in quotes. Without quotes, the shell splits `[A, B]` on the space and only the first module is seen — the generator now detects this and exits with an error instead of silently generating a partial client.
75
+
73
76
  3. Configure Platform URL and other settings in your project's **.env** file:
74
77
 
75
78
  ```title="vc-app-extend/.env"
@@ -1,74 +1,74 @@
1
1
  import e from "chalk";
2
- import { sync as v } from "cross-spawn";
3
- import { resolveConfig as j } from "vite";
4
- import { existsSync as w, mkdirSync as I, writeFileSync as T, readdirSync as O, readFileSync as x } from "node:fs";
5
- import m, { dirname as N, resolve as B, join as b, relative as S } from "node:path";
6
- import { fileURLToPath as L } from "node:url";
7
- import { cwd as M } from "node:process";
8
- import U from "mri";
9
- const $ = L(import.meta.url), F = N($);
10
- class V {
2
+ import { sync as M } from "cross-spawn";
3
+ import { resolveConfig as N } from "vite";
4
+ import { existsSync as w, mkdirSync as R, writeFileSync as O, readdirSync as U, readFileSync as k } from "node:fs";
5
+ import h, { dirname as F, resolve as I, join as E, relative as x } from "node:path";
6
+ import { fileURLToPath as $ } from "node:url";
7
+ import { cwd as V } from "node:process";
8
+ import G from "mri";
9
+ const K = $(import.meta.url), Y = F(K);
10
+ class W {
11
11
  workingDirectory;
12
12
  generatorDirectory;
13
13
  assetsDirectory;
14
14
  apiClientDirectory;
15
15
  nswagPaths;
16
16
  constructor(r) {
17
- this.workingDirectory = M(), this.generatorDirectory = B(F, ".."), this.assetsDirectory = b(this.generatorDirectory, "public", "assets"), this.apiClientDirectory = B(this.workingDirectory, r), this.nswagPaths = {
18
- configuration: b(S(this.workingDirectory, this.assetsDirectory), "config.nswag"),
17
+ this.workingDirectory = V(), this.generatorDirectory = I(Y, ".."), this.assetsDirectory = E(this.generatorDirectory, "public", "assets"), this.apiClientDirectory = I(this.workingDirectory, r), this.nswagPaths = {
18
+ configuration: E(x(this.workingDirectory, this.assetsDirectory), "config.nswag"),
19
19
  authApiBase: "authApiBase.ts",
20
20
  templates: "templates"
21
21
  };
22
22
  }
23
23
  resolveApiClientPaths(r) {
24
- const n = `${r.toLowerCase()}.ts`;
24
+ const i = `${r.toLowerCase()}.ts`;
25
25
  return {
26
- fileName: n,
27
- nswag: b(S(this.assetsDirectory, this.apiClientDirectory), n),
28
- console: b(S(this.workingDirectory, this.apiClientDirectory), n)
26
+ fileName: i,
27
+ nswag: E(x(this.assetsDirectory, this.apiClientDirectory), i),
28
+ console: E(x(this.workingDirectory, this.apiClientDirectory), i)
29
29
  };
30
30
  }
31
31
  }
32
- function D(o, r, n = []) {
32
+ function L(o, r, i = []) {
33
33
  const t = { ...o };
34
- for (const i of n)
35
- i in r && (t[i] = r[i]);
36
- for (const [i, s] of Object.entries(r)) {
37
- const a = i;
38
- i in t && typeof t[a] == "object" && !Array.isArray(t[a]) && typeof s == "object" && !Array.isArray(s) && s !== null ? t[a] = { ...t[a], ...s } : n.includes(i) || (t[a] = s);
34
+ for (const n of i)
35
+ n in r && (t[n] = r[n]);
36
+ for (const [n, s] of Object.entries(r)) {
37
+ const a = n;
38
+ n in t && typeof t[a] == "object" && !Array.isArray(t[a]) && typeof s == "object" && !Array.isArray(s) && s !== null ? t[a] = { ...t[a], ...s } : i.includes(n) || (t[a] = s);
39
39
  }
40
40
  return t;
41
41
  }
42
- function G(o, r, n, t) {
43
- const i = {
42
+ function q(o, r, i, t) {
43
+ const n = {
44
44
  extends: "@vc-shell/ts-config/tsconfig.json",
45
45
  compilerOptions: {
46
46
  baseUrl: ".",
47
- declarationDir: m.join(n, "types"),
47
+ declarationDir: h.join(i, "types"),
48
48
  outDir: t,
49
49
  rootDir: "./"
50
50
  },
51
51
  files: [],
52
52
  include: ["*.ts"]
53
53
  };
54
- let s = { ...i };
54
+ let s = { ...n };
55
55
  if (w(o))
56
56
  try {
57
- const a = x(o, "utf-8");
57
+ const a = k(o, "utf-8");
58
58
  try {
59
59
  const l = JSON.parse(a);
60
- s = D(i, l), l.compilerOptions && typeof l.compilerOptions == "object" && (s.compilerOptions = {
61
- ...i.compilerOptions,
60
+ s = L(n, l), l.compilerOptions && typeof l.compilerOptions == "object" && (s.compilerOptions = {
61
+ ...n.compilerOptions,
62
62
  ...l.compilerOptions
63
- }, s.compilerOptions.outDir = t, s.compilerOptions.declarationDir = m.join(t, "types"));
64
- const p = Array.isArray(l.files) ? l.files : [];
65
- s.files = Array.from(/* @__PURE__ */ new Set([...r, ...p])), console.log("api-client-generator %s Updated existing tsconfig.json", e.greenBright("success"));
63
+ }, s.compilerOptions.outDir = t, s.compilerOptions.declarationDir = h.join(t, "types"));
64
+ const c = Array.isArray(l.files) ? l.files : [];
65
+ s.files = Array.from(/* @__PURE__ */ new Set([...r, ...c])), console.log("api-client-generator %s Updated existing tsconfig.json", e.greenBright("success"));
66
66
  } catch (l) {
67
67
  console.error(
68
68
  "api-client-generator %s Failed to parse existing tsconfig.json, creating new one",
69
69
  e.yellow("warning"),
70
70
  l
71
- ), s = { ...i }, s.files = r;
71
+ ), s = { ...n }, s.files = r;
72
72
  }
73
73
  } catch (a) {
74
74
  console.error("api-client-generator %s Failed to read existing tsconfig.json", e.red("error"), a);
@@ -77,158 +77,158 @@ function G(o, r, n, t) {
77
77
  s.files = r, console.log("api-client-generator %s Created new tsconfig.json", e.greenBright("success"));
78
78
  return s;
79
79
  }
80
- function E(o) {
80
+ function b(o) {
81
81
  let r = o;
82
- const n = [".d.ts", ".ts", ".js"];
82
+ const i = [".d.ts", ".ts", ".js"];
83
83
  let t;
84
84
  do {
85
85
  t = !1;
86
- for (const i of n)
87
- if (r.toLowerCase().endsWith(i.toLowerCase())) {
88
- r = r.substring(0, r.length - i.length), t = !0;
86
+ for (const n of i)
87
+ if (r.toLowerCase().endsWith(n.toLowerCase())) {
88
+ r = r.substring(0, r.length - n.length), t = !0;
89
89
  break;
90
90
  }
91
91
  } while (t);
92
- return r = r.replace(/\/\.\//g, "/"), r = r.replace(/\/+/g, "/"), r = r.replace(/\.\.\//g, ""), r !== "." && !r.startsWith("./") && !r.startsWith("/") && !m.isAbsolute(r) && (r = "./" + r), r.startsWith("//") && (r = "./" + r.substring(2)), r !== "." && r.startsWith("/") && !r.startsWith("./") && !m.isAbsolute(r) && (r = "." + r), r !== "." && r.startsWith("././") && (r = "./" + r.substring(3)), r;
92
+ return r = r.replace(/\/\.\//g, "/"), r = r.replace(/\/+/g, "/"), r = r.replace(/\.\.\//g, ""), r !== "." && !r.startsWith("./") && !r.startsWith("/") && !h.isAbsolute(r) && (r = "./" + r), r.startsWith("//") && (r = "./" + r.substring(2)), r !== "." && r.startsWith("/") && !r.startsWith("./") && !h.isAbsolute(r) && (r = "." + r), r !== "." && r.startsWith("././") && (r = "./" + r.substring(3)), r;
93
93
  }
94
- function _(o) {
95
- let r = E(o);
96
- r = m.basename(r);
97
- const n = r.toLowerCase(), t = n.indexOf(".");
94
+ function S(o) {
95
+ let r = b(o);
96
+ r = h.basename(r);
97
+ const i = r.toLowerCase(), t = i.indexOf(".");
98
98
  if (t > 0) {
99
- const i = n.substring(0, t), s = n.substring(t + 1);
99
+ const n = i.substring(0, t), s = i.substring(t + 1);
100
100
  return {
101
- prefix: i,
101
+ prefix: n,
102
102
  coreName: s,
103
- fullName: n
103
+ fullName: i
104
104
  };
105
105
  }
106
106
  return {
107
107
  prefix: void 0,
108
- coreName: n,
109
- fullName: n
108
+ coreName: i,
109
+ fullName: i
110
110
  };
111
111
  }
112
- function R(o) {
113
- return _(o).coreName;
112
+ function j(o) {
113
+ return S(o).coreName;
114
114
  }
115
- function K(o, r) {
115
+ function J(o, r) {
116
116
  if (!o)
117
117
  return [];
118
- const n = [`./${o}`];
119
- return r && n.push(`./${r}.${o}`), n;
118
+ const i = [`./${o}`];
119
+ return r && i.push(`./${r}.${o}`), i;
120
120
  }
121
121
  function P(o) {
122
122
  return o.replace(/\\/g, "/");
123
123
  }
124
- function Y(o, r, n, t) {
125
- const i = {}, s = /* @__PURE__ */ new Set();
126
- for (const d of o) {
127
- const g = _(d);
128
- if (!g.coreName) continue;
129
- const y = g.fullName, c = P(`./${m.join(r, `${y}.js`)}`), h = P(`./${m.join(r, "types", `${y}.d.ts`)}`), u = { import: c, types: h }, f = K(g.coreName, g.prefix);
130
- for (const A of f)
131
- i[A] = u, t && console.log(
124
+ function z(o, r, i, t) {
125
+ const n = {}, s = /* @__PURE__ */ new Set();
126
+ for (const u of o) {
127
+ const d = S(u);
128
+ if (!d.coreName) continue;
129
+ const m = d.fullName, f = P(`./${h.join(r, `${m}.js`)}`), y = P(`./${h.join(r, "types", `${m}.d.ts`)}`), g = { import: f, types: y }, p = J(d.coreName, d.prefix);
130
+ for (const A of p)
131
+ n[A] = g, t && console.log(
132
132
  "api-client-generator %s Generated standard export: %s -> { import: %s, types: %s }",
133
133
  e.blue("debug"),
134
134
  e.whiteBright(A),
135
- e.whiteBright(c),
136
- e.whiteBright(h)
135
+ e.whiteBright(f),
136
+ e.whiteBright(y)
137
137
  );
138
- s.add(g.coreName);
138
+ s.add(d.coreName);
139
139
  }
140
- const a = { ...i };
141
- if (n)
142
- for (const [d, g] of Object.entries(n)) {
143
- if (d === ".")
140
+ const a = { ...n };
141
+ if (i)
142
+ for (const [u, d] of Object.entries(i)) {
143
+ if (u === ".")
144
144
  continue;
145
- if (typeof g != "object" || g === null) {
145
+ if (typeof d != "object" || d === null) {
146
146
  t && console.log(
147
147
  "api-client-generator %s Skipping malformed existing export value for key: %s",
148
148
  e.yellow("warning"),
149
- d
149
+ u
150
150
  );
151
151
  continue;
152
152
  }
153
- const y = g;
154
- if (!y.import || !y.types) {
153
+ const m = d;
154
+ if (!m.import || !m.types) {
155
155
  t && console.log(
156
156
  "api-client-generator %s Skipping existing export with missing import/types for key: %s",
157
157
  e.yellow("warning"),
158
- d
158
+ u
159
159
  );
160
160
  continue;
161
161
  }
162
- const c = E(d);
163
- if (!(!c || c === "."))
164
- if (R(c), c in i)
162
+ const f = b(u);
163
+ if (!(!f || f === "."))
164
+ if (j(f), f in n)
165
165
  t && console.log(
166
166
  "api-client-generator %s Existing export key '%s' was handled by new generation.",
167
167
  e.blue("debug"),
168
- e.whiteBright(c)
168
+ e.whiteBright(f)
169
169
  );
170
170
  else {
171
- const h = E(y.import), u = E(y.types);
172
- a[c] = {
173
- import: P(`${h}.js`),
174
- types: P(`${u}.d.ts`)
171
+ const y = b(m.import), g = b(m.types);
172
+ a[f] = {
173
+ import: P(`${y}.js`),
174
+ types: P(`${g}.d.ts`)
175
175
  }, t && console.log(
176
176
  "api-client-generator %s Preserved existing export: %s -> { import: %s, types: %s }",
177
177
  e.blue("debug"),
178
- e.whiteBright(c),
179
- e.whiteBright(`${h}.js`),
180
- e.whiteBright(`${u}.d.ts`)
178
+ e.whiteBright(f),
179
+ e.whiteBright(`${y}.js`),
180
+ e.whiteBright(`${g}.d.ts`)
181
181
  );
182
182
  }
183
183
  }
184
184
  const l = /* @__PURE__ */ new Map();
185
- for (const d in a) {
186
- if (d === ".") continue;
187
- const g = _(d);
188
- g.coreName && l.set(g.coreName, g.fullName);
185
+ for (const u in a) {
186
+ if (u === ".") continue;
187
+ const d = S(u);
188
+ d.coreName && l.set(d.coreName, d.fullName);
189
189
  }
190
- const p = Array.from(l.keys());
191
- if (p.length === 1) {
192
- const d = p[0], g = l.get(d), y = P(`./${m.join(r, `${g}.js`)}`), c = P(`./${m.join(r, "types", `${g}.d.ts`)}`);
190
+ const c = Array.from(l.keys());
191
+ if (c.length === 1) {
192
+ const u = c[0], d = l.get(u), m = P(`./${h.join(r, `${d}.js`)}`), f = P(`./${h.join(r, "types", `${d}.d.ts`)}`);
193
193
  a["."] = {
194
- import: y,
195
- types: c
194
+ import: m,
195
+ types: f
196
196
  }, t && console.log(
197
197
  "api-client-generator %s Set root export for single module '%s': { import: %s, types: %s }",
198
198
  e.blue("debug"),
199
- e.whiteBright(g),
200
- e.whiteBright(y),
201
- e.whiteBright(c)
199
+ e.whiteBright(d),
200
+ e.whiteBright(m),
201
+ e.whiteBright(f)
202
202
  );
203
- } else if (n && "." in n) {
204
- const d = n["."];
205
- if (typeof d == "object" && d !== null) {
206
- const g = d;
207
- if (g.import && g.types) {
208
- const c = _(g.import).coreName;
209
- if (c && p.includes(c)) {
210
- const h = l.get(c), u = P(`./${m.join(r, `${h}.js`)}`), f = P(`./${m.join(r, "types", `${h}.d.ts`)}`);
211
- a["."] = { import: u, types: f }, t && console.log(
203
+ } else if (i && "." in i) {
204
+ const u = i["."];
205
+ if (typeof u == "object" && u !== null) {
206
+ const d = u;
207
+ if (d.import && d.types) {
208
+ const f = S(d.import).coreName;
209
+ if (f && c.includes(f)) {
210
+ const y = l.get(f), g = P(`./${h.join(r, `${y}.js`)}`), p = P(`./${h.join(r, "types", `${y}.d.ts`)}`);
211
+ a["."] = { import: g, types: p }, t && console.log(
212
212
  "api-client-generator %s Preserved and standardized existing root export pointing to module '%s'",
213
213
  e.blue("debug"),
214
- e.whiteBright(h)
214
+ e.whiteBright(y)
215
215
  );
216
216
  } else t && console.log(
217
217
  "api-client-generator %s Removed existing root export as it pointed to an unknown or unhandled module '%s'",
218
218
  e.yellow("warning"),
219
- c || "unknown"
219
+ f || "unknown"
220
220
  );
221
221
  } else t && console.log("api-client-generator %s Removed malformed existing root export.", e.yellow("warning"));
222
222
  }
223
223
  }
224
224
  return a;
225
225
  }
226
- function J(o, r, n) {
227
- const t = n.VERBOSE ?? !1, i = n.APP_BUILD_DIR ?? "dist", s = [];
228
- i && s.push(i), s.push("package.json");
226
+ function H(o, r, i) {
227
+ const t = i.VERBOSE ?? !1, n = i.APP_BUILD_DIR ?? "dist", s = [];
228
+ n && s.push(n), s.push("package.json");
229
229
  const a = {
230
- name: n.APP_PACKAGE_NAME || "api-client",
231
- version: n.APP_PACKAGE_VERSION || "1.0.0",
230
+ name: i.APP_PACKAGE_NAME || "api-client",
231
+ version: i.APP_PACKAGE_VERSION || "1.0.0",
232
232
  files: s,
233
233
  exports: {},
234
234
  // Add metadata to track generated content
@@ -237,13 +237,13 @@ function J(o, r, n) {
237
237
  generatedAt: (/* @__PURE__ */ new Date()).toISOString()
238
238
  }
239
239
  };
240
- let l = { ...a }, p, d, g;
240
+ let l = { ...a }, c, u, d;
241
241
  if (w(o))
242
242
  try {
243
- const u = x(o, "utf-8");
243
+ const g = k(o, "utf-8");
244
244
  try {
245
- const f = JSON.parse(u);
246
- typeof f.module == "string" && (d = f.module), typeof f.types == "string" && (g = f.types), l = D(a, f, [
245
+ const p = JSON.parse(g);
246
+ typeof p.module == "string" && (u = p.module), typeof p.types == "string" && (d = p.types), l = L(a, p, [
247
247
  "name",
248
248
  "version",
249
249
  "description",
@@ -254,56 +254,56 @@ function J(o, r, n) {
254
254
  "scripts",
255
255
  "devDependencies",
256
256
  "dependencies"
257
- ]), l.apiClientGenerator = a.apiClientGenerator, f.files && Array.isArray(f.files) && (l.files = Array.from(/* @__PURE__ */ new Set([...s, ...f.files]))), p = f.exports, console.log("api-client-generator %s Updated existing package.json", e.greenBright("success"));
258
- } catch (f) {
257
+ ]), l.apiClientGenerator = a.apiClientGenerator, p.files && Array.isArray(p.files) && (l.files = Array.from(/* @__PURE__ */ new Set([...s, ...p.files]))), c = p.exports, console.log("api-client-generator %s Updated existing package.json", e.greenBright("success"));
258
+ } catch (p) {
259
259
  console.error(
260
260
  "api-client-generator %s Failed to parse existing package.json, creating new one",
261
261
  e.yellow("warning"),
262
- f
262
+ p
263
263
  );
264
264
  }
265
- } catch (u) {
266
- console.error("api-client-generator %s Failed to read existing package.json", e.red("error"), u);
265
+ } catch (g) {
266
+ console.error("api-client-generator %s Failed to read existing package.json", e.red("error"), g);
267
267
  }
268
268
  else
269
269
  console.log("api-client-generator %s Creating new package.json", e.greenBright("success"));
270
- l.exports = Y(r, i, p, t);
271
- const y = Object.keys(l.exports), c = /* @__PURE__ */ new Set();
272
- for (const u of y) {
273
- if (u === ".") continue;
274
- const f = R(u);
275
- f && c.add(f);
270
+ l.exports = z(r, n, c, t);
271
+ const m = Object.keys(l.exports), f = /* @__PURE__ */ new Set();
272
+ for (const g of m) {
273
+ if (g === ".") continue;
274
+ const p = j(g);
275
+ p && f.add(p);
276
276
  }
277
- if (Array.from(c).length, l.exports && "." in l.exports) {
278
- const u = l.exports["."];
279
- u && u.import && (l.module = u.import, t && console.log(
277
+ if (Array.from(f).length, l.exports && "." in l.exports) {
278
+ const g = l.exports["."];
279
+ g && g.import && (l.module = g.import, t && console.log(
280
280
  "api-client-generator %s Set 'module' field from root export: %s",
281
281
  e.blue("debug"),
282
- e.whiteBright(u.import)
283
- )), u && u.types && (l.types = u.types, t && console.log(
282
+ e.whiteBright(g.import)
283
+ )), g && g.types && (l.types = g.types, t && console.log(
284
284
  "api-client-generator %s Set 'types' field from root export: %s",
285
285
  e.blue("debug"),
286
- e.whiteBright(u.types)
286
+ e.whiteBright(g.types)
287
287
  ));
288
288
  } else
289
289
  "module" in l && (delete l.module, t && console.log("api-client-generator %s Removed 'module' field (no clear root export).", e.blue("debug"))), "types" in l && (delete l.types, t && console.log("api-client-generator %s Removed 'types' field (no clear root export).", e.blue("debug")));
290
290
  return l;
291
291
  }
292
- function W(o) {
293
- const r = m.resolve(process.cwd(), o);
292
+ function Q(o) {
293
+ const r = h.resolve(process.cwd(), o);
294
294
  if (!w(r))
295
295
  return;
296
- let n;
296
+ let i;
297
297
  try {
298
- n = O(r).filter((t) => t.endsWith(".ts") && t !== "index.ts");
298
+ i = U(r).filter((t) => t.endsWith(".ts") && t !== "index.ts");
299
299
  } catch {
300
300
  return;
301
301
  }
302
- if (n.length !== 0) {
303
- for (const t of n.slice(0, 5)) {
304
- const i = m.join(r, t);
302
+ if (i.length !== 0) {
303
+ for (const t of i.slice(0, 5)) {
304
+ const n = h.join(r, t);
305
305
  try {
306
- const s = x(i, "utf-8");
306
+ const s = k(n, "utf-8");
307
307
  if (/export class \w+ implements I\w+/.test(s))
308
308
  return "Class";
309
309
  } catch {
@@ -313,94 +313,132 @@ function W(o) {
313
313
  return "Interface";
314
314
  }
315
315
  }
316
- function q() {
317
- const o = U(process.argv.slice(2)), r = process.env.APP_PLATFORM_URL ?? o.APP_PLATFORM_URL, n = r?.endsWith("/") ? r : r && `${r}/`, t = process.env.APP_PLATFORM_MODULES ?? o.APP_PLATFORM_MODULES, i = process.env.APP_API_CLIENT_DIRECTORY ?? o.APP_API_CLIENT_DIRECTORY, s = process.env.APP_PACKAGE_NAME ?? o.APP_PACKAGE_NAME, a = process.env.APP_PACKAGE_VERSION ?? o.APP_PACKAGE_VERSION, l = process.env.APP_OUT_DIR ?? o.APP_OUT_DIR ?? "./", p = process.env.APP_BUILD_DIR ?? o.APP_BUILD_DIR ?? "dist", d = process.env.RUNTIME ?? o.RUNTIME ?? "Net80", g = process.env.SKIP_BUILD === "true" || o.SKIP_BUILD === !0, y = process.env.VERBOSE === "true" || o.VERBOSE === !0, c = process.env.APP_TYPE_STYLE ?? o.APP_TYPE_STYLE;
318
- let h;
319
- c ? h = c : i ? h = W(i) ?? "Interface" : h = "Interface", c || console.log(
316
+ function X(o, r, i) {
317
+ const t = Array.isArray(o) ? o.join(",") : o ?? "", n = (t.match(/\[/g) ?? []).length, s = (t.match(/\]/g) ?? []).length, a = n !== s, l = a || t.trim().endsWith(",");
318
+ if (!i && r.length > 0 && l) {
319
+ const u = [t, ...r].join(" ");
320
+ return {
321
+ ok: !1,
322
+ message: `APP_PLATFORM_MODULES looks truncated — unexpected extra arguments were received: ${r.join(
323
+ ", "
324
+ )}`,
325
+ hint: `This usually means the value was not quoted and the shell split it on spaces.
326
+ Wrap the whole value in quotes, e.g.
327
+ --APP_PLATFORM_MODULES='${u}'`
328
+ };
329
+ }
330
+ if (a)
331
+ return {
332
+ ok: !1,
333
+ message: `APP_PLATFORM_MODULES has unbalanced brackets: ${t}`,
334
+ hint: `The value appears truncated. Wrap it in quotes, e.g.
335
+ --APP_PLATFORM_MODULES='[VirtoCommerce.Catalog, VirtoCommerce.Orders]'`
336
+ };
337
+ const c = t.replace(/[[\]]/g, "").split(",").map((u) => u.trim()).filter((u) => u.length > 0);
338
+ return c.length === 0 ? {
339
+ ok: !1,
340
+ message: `APP_PLATFORM_MODULES did not contain any module names: ${t}`,
341
+ hint: `Provide at least one module, e.g.
342
+ --APP_PLATFORM_MODULES='[VirtoCommerce.Catalog]'`
343
+ } : { ok: !0, modules: c };
344
+ }
345
+ function Z() {
346
+ const o = G(process.argv.slice(2)), r = process.env.APP_PLATFORM_URL ?? o.APP_PLATFORM_URL, i = r?.endsWith("/") ? r : r && `${r}/`, t = process.env.APP_PLATFORM_MODULES !== void 0, n = t ? process.env.APP_PLATFORM_MODULES : o.APP_PLATFORM_MODULES, s = (o._ ?? []).map(String), a = process.env.APP_API_CLIENT_DIRECTORY ?? o.APP_API_CLIENT_DIRECTORY, l = process.env.APP_PACKAGE_NAME ?? o.APP_PACKAGE_NAME, c = process.env.APP_PACKAGE_VERSION ?? o.APP_PACKAGE_VERSION, u = process.env.APP_OUT_DIR ?? o.APP_OUT_DIR ?? "./", d = process.env.APP_BUILD_DIR ?? o.APP_BUILD_DIR ?? "dist", m = process.env.RUNTIME ?? o.RUNTIME ?? "Net80", f = process.env.SKIP_BUILD === "true" || o.SKIP_BUILD === !0, y = process.env.VERBOSE === "true" || o.VERBOSE === !0, g = process.env.APP_TYPE_STYLE ?? o.APP_TYPE_STYLE;
347
+ let p;
348
+ g ? p = g : a ? p = Q(a) ?? "Interface" : p = "Interface", g || console.log(
320
349
  "api-client-generator %s APP_TYPE_STYLE not specified, using %s (set APP_TYPE_STYLE=Class to generate class-based DTOs)",
321
350
  e.blue("info"),
322
- e.whiteBright(h)
351
+ e.whiteBright(p)
323
352
  );
324
- const u = process.env.APP_PACKAGE_MODE === "true" || o.PACKAGE === !0, f = ["Net80", "Net90", "Net100"];
325
- if (f.includes(d) || console.warn(
353
+ const A = process.env.APP_PACKAGE_MODE === "true" || o.PACKAGE === !0, T = ["Net80", "Net90", "Net100"];
354
+ if (T.includes(m) || console.warn(
326
355
  "api-client-generator %s Unknown RUNTIME value: %s. Known values: %s. Proceeding anyway — NSwag will report an error if the runtime is unsupported.",
327
356
  e.yellow("warning"),
328
- e.whiteBright(d),
329
- e.whiteBright(f.join(", "))
330
- ), h !== "Class" && h !== "Interface" && (console.error(
357
+ e.whiteBright(m),
358
+ e.whiteBright(T.join(", "))
359
+ ), p !== "Class" && p !== "Interface" && (console.error(
331
360
  "api-client-generator %s Invalid APP_TYPE_STYLE value: %s. Must be either 'Class' or 'Interface'",
332
361
  e.red("error"),
333
- e.whiteBright(h)
362
+ e.whiteBright(p)
334
363
  ), process.exit(1)), y) {
335
- const k = c ? "explicit" : i ? "auto-detected" : "default";
364
+ const D = g ? "explicit" : a ? "auto-detected" : "default";
336
365
  console.log(
337
366
  "api-client-generator %s Using APP_TYPE_STYLE: %s (%s)",
338
367
  e.blue("debug"),
339
- e.whiteBright(h),
340
- e.gray(k)
368
+ e.whiteBright(p),
369
+ e.gray(D)
341
370
  );
342
371
  }
343
- n || (console.error(
372
+ i || (console.error(
344
373
  "api-client-generator %s APP_PLATFORM_URL is required in .env config or as api-client-generator argument",
345
374
  e.red("error")
346
- ), process.exit(1)), t || (console.error(
375
+ ), process.exit(1)), (n === void 0 || n === "") && (console.error(
347
376
  "api-client-generator %s APP_PLATFORM_MODULES is required in .env config or as api-client-generator argument",
348
377
  e.red("error")
349
- ), process.exit(1)), i || (console.error(
378
+ ), process.exit(1));
379
+ const _ = X(n, s, t);
380
+ _.ok || (console.error("api-client-generator %s %s", e.red("error"), _.message), _.hint && console.error(e.blue(_.hint)), process.exit(1));
381
+ const C = _.modules;
382
+ console.log(
383
+ "api-client-generator %s Parsed %d module(s): %s",
384
+ e.blue("info"),
385
+ C.length,
386
+ e.whiteBright(C.join(", "))
387
+ ), a || (console.error(
350
388
  "api-client-generator %s APP_API_CLIENT_DIRECTORY is required in .env config or as api-client-generator argument",
351
389
  e.red("error")
352
390
  ), process.exit(1));
353
- const A = m.join(m.resolve(process.cwd(), i), "package.json"), C = u || w(A);
391
+ const v = h.join(h.resolve(process.cwd(), a), "package.json"), B = A || w(v);
354
392
  return y && console.log(
355
393
  "api-client-generator %s Package mode: %s (explicit flag: %s, existing package.json: %s)",
356
394
  e.blue("debug"),
357
- e.whiteBright(String(C)),
358
- e.whiteBright(String(u)),
359
- e.whiteBright(String(w(A)))
395
+ e.whiteBright(String(B)),
396
+ e.whiteBright(String(A)),
397
+ e.whiteBright(String(w(v)))
360
398
  ), {
361
- platformUrl: n,
362
- platformModules: t,
363
- apiClientDirectory: i,
364
- packageName: s,
365
- packageVersion: a,
366
- outDir: l,
367
- buildDir: p,
368
- runtime: d,
369
- skipBuild: g,
399
+ platformUrl: i,
400
+ platformModulesList: C,
401
+ apiClientDirectory: a,
402
+ packageName: l,
403
+ packageVersion: c,
404
+ outDir: u,
405
+ buildDir: d,
406
+ runtime: m,
407
+ skipBuild: f,
370
408
  verbose: y,
371
- typeStyle: h,
372
- packageMode: C,
409
+ typeStyle: p,
410
+ packageMode: B,
373
411
  parsedArgs: o
374
412
  };
375
413
  }
376
- function z(o) {
377
- const r = new V(o.apiClientDirectory);
414
+ function ee(o) {
415
+ const r = new W(o.apiClientDirectory);
378
416
  if (!w(o.apiClientDirectory))
379
417
  try {
380
- I(o.apiClientDirectory, { recursive: !0 }), console.log(
418
+ R(o.apiClientDirectory, { recursive: !0 }), console.log(
381
419
  "api-client-generator %s Created directory %s",
382
420
  e.greenBright("success"),
383
421
  e.whiteBright(o.apiClientDirectory)
384
422
  );
385
- } catch (i) {
423
+ } catch (n) {
386
424
  console.error(
387
425
  "api-client-generator %s Failed to create directory %s",
388
426
  e.red("error"),
389
427
  e.whiteBright(o.apiClientDirectory)
390
- ), console.error(e.red("Error details:"), i), console.error("api-client-generator %s Directory creation troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if you have write permissions in the parent directory")), console.error(e.blue(" - Ensure the path is valid and not too long")), console.error(e.blue(" - Try running with elevated permissions if needed")), process.exit(1);
428
+ ), console.error(e.red("Error details:"), n), console.error("api-client-generator %s Directory creation troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if you have write permissions in the parent directory")), console.error(e.blue(" - Ensure the path is valid and not too long")), console.error(e.blue(" - Try running with elevated permissions if needed")), process.exit(1);
391
429
  }
392
- const n = o.platformModules.replace(/[[\]]/g, "").split(",").map((i) => i.trim()).filter((i) => i.length > 0), t = [];
393
- for (const i of n) {
394
- const s = r.resolveApiClientPaths(i);
430
+ const i = o.platformModulesList, t = [];
431
+ for (const n of i) {
432
+ const s = r.resolveApiClientPaths(n);
395
433
  console.log(
396
434
  "api-client-generator %s Generating API client for %s module on %s environment",
397
435
  e.green("info"),
398
- e.whiteBright(i),
436
+ e.whiteBright(n),
399
437
  e.whiteBright(o.platformUrl)
400
438
  );
401
439
  const a = [
402
440
  `APP_PLATFORM_URL=${o.platformUrl}`,
403
- `APP_PLATFORM_MODULE=${i}`,
441
+ `APP_PLATFORM_MODULE=${n}`,
404
442
  `APP_AUTH_API_BASE_PATH=${r.nswagPaths.authApiBase}`,
405
443
  `APP_TEMPLATE_DIRECTORY=${r.nswagPaths.templates}`,
406
444
  `APP_API_CLIENT_PATH=${s.nswag}`,
@@ -408,55 +446,55 @@ function z(o) {
408
446
  `RUNTIME=${o.runtime}`
409
447
  ].join(","), l = ["run", r.nswagPaths.configuration, `/variables:${a}`];
410
448
  o.verbose && (console.log("api-client-generator %s Running command: npx nswag %s", e.blue("debug"), l.join(" ")), console.log("api-client-generator %s Variables: %s", e.blue("debug"), a));
411
- const p = v("npx nswag", l, {
449
+ const c = M("npx nswag", l, {
412
450
  stdio: ["ignore", o.verbose ? "inherit" : "pipe", "inherit"],
413
451
  shell: !0
414
452
  });
415
- p.status === 0 ? (console.log(
453
+ c.status === 0 ? (console.log(
416
454
  "api-client-generator %s Successfully generated %s",
417
455
  e.greenBright("success"),
418
456
  e.whiteBright(s.console)
419
- ), t.push(`${i.toLowerCase()}.ts`)) : (console.error(
457
+ ), t.push(`${n.toLowerCase()}.ts`)) : (console.error(
420
458
  "api-client-generator %s Failed to generate %s",
421
459
  e.red("error"),
422
460
  e.whiteBright(s.console)
423
461
  ), console.error(
424
462
  "api-client-generator %s NSwag command failed with exit code: %s",
425
463
  e.red("error"),
426
- p.status
427
- ), p.stderr && p.stderr.toString().trim() && (console.error("api-client-generator %s NSwag error output:", e.red("error")), console.error(e.red(p.stderr.toString()))), p.stdout && p.stdout.toString().trim() && (console.error("api-client-generator %s NSwag output:", e.yellow("warning")), console.error(e.yellow(p.stdout.toString()))), console.error("api-client-generator %s Troubleshooting tips:", e.blue("info")), console.error(e.blue(" - Check if the platform URL is accessible: %s"), o.platformUrl), console.error(e.blue(" - Verify the module name '%s' exists on the platform"), i), console.error(e.blue(` - Ensure .NET Core ${o.runtime} is installed`)), console.error(e.blue(" - Try running with --VERBOSE=true for more details")), process.exit(1));
464
+ c.status
465
+ ), c.stderr && c.stderr.toString().trim() && (console.error("api-client-generator %s NSwag error output:", e.red("error")), console.error(e.red(c.stderr.toString()))), c.stdout && c.stdout.toString().trim() && (console.error("api-client-generator %s NSwag output:", e.yellow("warning")), console.error(e.yellow(c.stdout.toString()))), console.error("api-client-generator %s Troubleshooting tips:", e.blue("info")), console.error(e.blue(" - Check if the platform URL is accessible: %s"), o.platformUrl), console.error(e.blue(" - Verify the module name '%s' exists on the platform"), n), console.error(e.blue(` - Ensure .NET Core ${o.runtime} is installed`)), console.error(e.blue(" - Try running with --VERBOSE=true for more details")), process.exit(1));
428
466
  }
429
467
  return t;
430
468
  }
431
- function H(o, r) {
432
- const n = m.join(o.apiClientDirectory, o.buildDir);
433
- if (!w(n))
469
+ function re(o, r) {
470
+ const i = h.join(o.apiClientDirectory, o.buildDir);
471
+ if (!w(i))
434
472
  try {
435
- I(n, { recursive: !0 }), console.log(
473
+ R(i, { recursive: !0 }), console.log(
436
474
  "api-client-generator %s Created build directory %s",
437
475
  e.greenBright("success"),
438
- e.whiteBright(n)
476
+ e.whiteBright(i)
439
477
  );
440
- } catch (p) {
478
+ } catch (c) {
441
479
  console.error(
442
480
  "api-client-generator %s Failed to create build directory %s",
443
481
  e.red("error"),
444
- e.whiteBright(n)
445
- ), console.error(e.red("Error details:"), p), console.error("api-client-generator %s Build directory creation troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if you have write permissions in the API client directory")), console.error(e.blue(" - Ensure the build directory path is valid")), console.error(e.blue(" - The TypeScript compiler will attempt to create the directory during compilation"));
482
+ e.whiteBright(i)
483
+ ), console.error(e.red("Error details:"), c), console.error("api-client-generator %s Build directory creation troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if you have write permissions in the API client directory")), console.error(e.blue(" - Ensure the build directory path is valid")), console.error(e.blue(" - The TypeScript compiler will attempt to create the directory during compilation"));
446
484
  }
447
- const t = m.join(o.apiClientDirectory, "tsconfig.json"), i = G(t, r, o.outDir, o.buildDir);
485
+ const t = h.join(o.apiClientDirectory, "tsconfig.json"), n = q(t, r, o.outDir, o.buildDir);
448
486
  try {
449
- T(t, JSON.stringify(i, null, 2)), o.verbose && console.log("api-client-generator %s Updated tsconfig.json", e.greenBright("success"));
450
- } catch (p) {
451
- console.error("api-client-generator %s Failed to write tsconfig.json", e.red("error")), console.error(e.red("Error details:"), p), console.error("api-client-generator %s File writing troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if you have write permissions in the API client directory")), console.error(e.blue(" - Ensure the file path is valid and not locked by another process")), console.error(e.blue(" - Try running with elevated permissions if needed")), process.exit(1);
487
+ O(t, JSON.stringify(n, null, 2)), o.verbose && console.log("api-client-generator %s Updated tsconfig.json", e.greenBright("success"));
488
+ } catch (c) {
489
+ console.error("api-client-generator %s Failed to write tsconfig.json", e.red("error")), console.error(e.red("Error details:"), c), console.error("api-client-generator %s File writing troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if you have write permissions in the API client directory")), console.error(e.blue(" - Ensure the file path is valid and not locked by another process")), console.error(e.blue(" - Try running with elevated permissions if needed")), process.exit(1);
452
490
  }
453
491
  console.log("api-client-generator %s Compiling TypeScript files to JavaScript", e.green("info"));
454
- const s = v("npx tsc", ["--project", t], {
492
+ const s = M("npx tsc", ["--project", t], {
455
493
  stdio: ["ignore", "pipe", "pipe"],
456
494
  shell: !0
457
495
  });
458
496
  s.status === 0 ? console.log("api-client-generator %s Successfully compiled TypeScript files", e.greenBright("success")) : (console.error("api-client-generator %s Failed to compile TypeScript files", e.red("error")), s.stderr && s.stderr.toString().trim() && (console.error("api-client-generator %s TypeScript compilation errors:", e.red("error")), console.error(e.red(s.stderr.toString()))), s.stdout && s.stdout.toString().trim() && (console.error("api-client-generator %s TypeScript output:", e.yellow("warning")), console.error(e.yellow(s.stdout.toString()))), console.error("api-client-generator %s TypeScript compilation troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if all required dependencies are installed")), console.error(e.blue(" - Verify TypeScript configuration in tsconfig.json")), console.error(e.blue(" - Ensure generated API files are valid TypeScript")), console.error(e.blue(" - Try running with --VERBOSE=true for more details")), process.exit(1));
459
- const a = m.join(o.apiClientDirectory, "package.json"), l = J(a, r, {
497
+ const a = h.join(o.apiClientDirectory, "package.json"), l = H(a, r, {
460
498
  ...o.parsedArgs,
461
499
  APP_PACKAGE_NAME: o.packageName,
462
500
  APP_PACKAGE_VERSION: o.packageVersion,
@@ -464,16 +502,16 @@ function H(o, r) {
464
502
  VERBOSE: o.verbose
465
503
  });
466
504
  try {
467
- T(a, JSON.stringify(l, null, 2)), console.log("api-client-generator %s Generated package.json", e.greenBright("success"));
468
- } catch (p) {
469
- console.error("api-client-generator %s Failed to write package.json", e.red("error")), console.error(e.red("Error details:"), p), console.error("api-client-generator %s Package.json writing troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if you have write permissions in the API client directory")), console.error(e.blue(" - Ensure the file path is valid and not locked by another process")), console.error(e.blue(" - Try running with elevated permissions if needed")), process.exit(1);
505
+ O(a, JSON.stringify(l, null, 2)), console.log("api-client-generator %s Generated package.json", e.greenBright("success"));
506
+ } catch (c) {
507
+ console.error("api-client-generator %s Failed to write package.json", e.red("error")), console.error(e.red("Error details:"), c), console.error("api-client-generator %s Package.json writing troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if you have write permissions in the API client directory")), console.error(e.blue(" - Ensure the file path is valid and not locked by another process")), console.error(e.blue(" - Try running with elevated permissions if needed")), process.exit(1);
470
508
  }
471
509
  }
472
- async function Q() {
510
+ async function oe() {
473
511
  try {
474
- await j({}, "build");
475
- const o = q(), r = z(o);
476
- o.packageMode && !o.skipBuild && r.length > 0 ? H(o, r) : o.packageMode || console.log(
512
+ await N({}, "build");
513
+ const o = Z(), r = ee(o);
514
+ o.packageMode && !o.skipBuild && r.length > 0 ? re(o, r) : o.packageMode || console.log(
477
515
  "api-client-generator %s Generated %d API client file(s) in simple mode (no package build)",
478
516
  e.greenBright("success"),
479
517
  r.length
@@ -482,4 +520,4 @@ async function Q() {
482
520
  console.error("api-client-generator %s Unexpected error occurred during API client generation", e.red("error")), console.error(e.red("Error details:"), o), console.error("api-client-generator %s General troubleshooting:", e.blue("info")), console.error(e.blue(" - Check if all required dependencies are installed")), console.error(e.blue(" - Ensure you have proper permissions")), console.error(e.blue(" - Try running with --VERBOSE=true for more details")), console.error(e.blue(" - Check the platform URL and module names")), process.exit(1);
483
521
  }
484
522
  }
485
- Q();
523
+ oe();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vc-shell/api-client-generator",
3
3
  "description": "Tool for API clients generation",
4
- "version": "2.0.7",
4
+ "version": "2.0.8",
5
5
  "type": "module",
6
6
  "bin": "./dist/api-client-generator.js",
7
7
  "files": [
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "devDependencies": {
15
15
  "@types/cross-spawn": "^6.0.6",
16
- "@vc-shell/ts-config": "2.0.7",
16
+ "@vc-shell/ts-config": "2.0.8",
17
17
  "typescript": "^5.8.3"
18
18
  },
19
19
  "dependencies": {