@vc-shell/create-vc-app 2.4.0-pr300.83479a4 → 2.4.0-pr302.99e48e1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"add-module.d.ts","sourceRoot":"","sources":["../../src/commands/add-module.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFzF"}
1
+ {"version":3,"file":"add-module.d.ts","sourceRoot":"","sources":["../../src/commands/add-module.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoFzF"}
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAA+B,MAAM,aAAa,CAAC;AAqBxE,wBAAsB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuNpF"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAA+B,MAAM,aAAa,CAAC;AAsBxE,wBAAsB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4NpF"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Format generated sources in place.
3
+ *
4
+ * Templates are `.ejs`, so neither Prettier nor ESLint can check them directly —
5
+ * EJS control tags and the regex splicing in `codegen.ts` both emit code whose
6
+ * shape depends on runtime data. Running Prettier over the *output* is the only
7
+ * point where the result can be normalised.
8
+ *
9
+ * Formatting is best-effort: a file Prettier cannot parse is left untouched
10
+ * rather than failing the scaffold.
11
+ */
12
+ export declare function formatGenerated(targets: string[]): Promise<number>;
13
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/engine/format.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BxE"}
package/dist/index.js CHANGED
@@ -1,53 +1,54 @@
1
1
  #!/usr/bin/env node
2
- import z from "mri";
3
- import n from "picocolors";
2
+ import B from "mri";
3
+ import a from "picocolors";
4
4
  import c from "node:path";
5
- import { exit as L, argv as B } from "node:process";
6
- import { fileURLToPath as F } from "node:url";
7
- import A from "prompts";
5
+ import { exit as O, argv as V } from "node:process";
6
+ import { fileURLToPath as K } from "node:url";
7
+ import P from "prompts";
8
8
  import r from "node:fs";
9
- import E from "ejs";
10
- const O = "2.4.0-pr300.83479a4", V = {
11
- version: O
9
+ import D from "ejs";
10
+ import C from "prettier";
11
+ const Z = "2.4.0-pr302.99e48e1", J = {
12
+ version: Z
12
13
  };
13
14
  function h(e) {
14
15
  return e.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase().replace(/[^a-z0-9-]/g, "");
15
16
  }
16
17
  function x(e) {
17
- return e.replace(/[-_\s]+(.)?/g, (a, t) => t ? t.toUpperCase() : "").replace(/^(.)/, (a, t) => t.toUpperCase());
18
+ return e.replace(/[-_\s]+(.)?/g, (n, t) => t ? t.toUpperCase() : "").replace(/^(.)/, (n, t) => t.toUpperCase());
18
19
  }
19
- function Z(e) {
20
- const a = x(e);
21
- return a.charAt(0).toLowerCase() + a.slice(1);
20
+ function Y(e) {
21
+ const n = x(e);
22
+ return n.charAt(0).toLowerCase() + n.slice(1);
22
23
  }
23
- function D(e) {
24
+ function R(e) {
24
25
  return e.replace(/[-\s]+/g, "_").replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase();
25
26
  }
26
- function S(e) {
27
- return e.replace(/[-_]+/g, " ").replace(/\b\w/g, (a) => a.toUpperCase());
27
+ function j(e) {
28
+ return e.replace(/[-_]+/g, " ").replace(/\b\w/g, (n) => n.toUpperCase());
28
29
  }
29
30
  function k(e) {
30
31
  return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(e);
31
32
  }
32
- function C(e) {
33
+ function _(e) {
33
34
  return e.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9-~]+/g, "-");
34
35
  }
35
- function _(e) {
36
+ function I(e) {
36
37
  return e.trim().toLowerCase().replace(/\/+/g, "/").replace(/[^a-z0-9/-]+/g, "/").replace(/\/?$/, "/");
37
38
  }
38
- function R(e) {
39
- const a = e.moduleName || "", t = a ? h(a) : "", s = {
39
+ function F(e) {
40
+ const n = e.moduleName || "", t = n ? h(n) : "", s = {
40
41
  hasModule: !!e.moduleName,
41
42
  ModuleName: t,
42
- ModuleNamePascalCase: a ? x(a) : "",
43
- ModuleNameCamelCase: a ? Z(a) : "",
43
+ ModuleNamePascalCase: n ? x(n) : "",
44
+ ModuleNameCamelCase: n ? Y(n) : "",
44
45
  ModuleNameUppercase: t.toUpperCase(),
45
- ModuleNameScreamingSnake: a ? D(a) : "",
46
- ModuleNameSentenceCase: a ? S(a) : ""
46
+ ModuleNameScreamingSnake: n ? R(n) : "",
47
+ ModuleNameSentenceCase: n ? j(n) : ""
47
48
  };
48
- return e.projectName && (s.AppName = h(e.projectName), s.AppNameSentenceCase = S(e.projectName)), e.packageName !== void 0 && (s.PackageName = e.packageName || "", s.BasePath = e.basePath || "", s.tenantRoutes = e.tenantRoutes || !1, s.aiAgent = e.aiAgent || !1, s.dashboard = e.dashboard || !1, s.mocks = e.mocks || !1), s;
49
+ return e.projectName && (s.AppName = h(e.projectName), s.AppNameSentenceCase = j(e.projectName)), e.packageName !== void 0 && (s.PackageName = e.packageName || "", s.BasePath = e.basePath || "", s.tenantRoutes = e.tenantRoutes || !1, s.aiAgent = e.aiAgent || !1, s.dashboard = e.dashboard || !1, s.mocks = e.mocks || !1), s;
49
50
  }
50
- const J = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".pdf", ".zip"]), K = {
51
+ const q = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".pdf", ".zip"]), W = {
51
52
  _gitignore: ".gitignore",
52
53
  "_yarnrc.yml": ".yarnrc.yml",
53
54
  _browserslistrc: ".browserslistrc",
@@ -62,104 +63,126 @@ const J = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ic
62
63
  _yarn: ".yarn",
63
64
  "_package.json": "package.json"
64
65
  };
65
- function Y(e, a, t) {
66
- a.endsWith(".ejs") && (a = a.slice(0, -4));
67
- const s = c.dirname(a);
66
+ function G(e, n, t) {
67
+ n.endsWith(".ejs") && (n = n.slice(0, -4));
68
+ const s = c.dirname(n);
68
69
  r.existsSync(s) || r.mkdirSync(s, { recursive: !0 });
69
70
  const o = c.extname(e.replace(/\.ejs$/, "")).toLowerCase();
70
- if (J.has(o))
71
- r.copyFileSync(e, a);
71
+ if (q.has(o))
72
+ r.copyFileSync(e, n);
72
73
  else {
73
- const d = r.readFileSync(e, "utf-8"), p = E.render(d, t, { filename: e });
74
- r.writeFileSync(a, p);
74
+ const d = r.readFileSync(e, "utf-8"), p = D.render(d, t, { filename: e });
75
+ r.writeFileSync(n, p);
75
76
  }
76
77
  }
77
- function j(e, a, t) {
78
+ function b(e, n, t) {
78
79
  if (!r.existsSync(e)) return;
79
80
  const s = r.readdirSync(e);
80
81
  for (const o of s) {
81
82
  const d = c.join(e, o), p = o.endsWith(".ejs") ? o.slice(0, -4) : o;
82
- let m = K[p] ?? p;
83
+ let m = W[p] ?? p;
83
84
  try {
84
- m = E.render(m, t);
85
+ m = D.render(m, t);
85
86
  } catch {
86
87
  }
87
- const l = c.join(a, m);
88
- r.statSync(d).isDirectory() ? (r.existsSync(l) || r.mkdirSync(l, { recursive: !0 }), j(d, l, t)) : Y(d, l, t);
88
+ const i = c.join(n, m);
89
+ r.statSync(d).isDirectory() ? (r.existsSync(i) || r.mkdirSync(i, { recursive: !0 }), b(d, i, t)) : G(d, i, t);
89
90
  }
90
91
  }
91
- function q(e) {
92
+ function H(e) {
92
93
  if (r.existsSync(e))
93
- for (const a of r.readdirSync(e)) {
94
- if (a === ".git") continue;
95
- const t = c.join(e, a);
94
+ for (const n of r.readdirSync(e)) {
95
+ if (n === ".git") continue;
96
+ const t = c.join(e, n);
96
97
  r.statSync(t).isDirectory() ? r.rmSync(t, { recursive: !0, force: !0 }) : r.unlinkSync(t);
97
98
  }
98
99
  }
99
- function I(e) {
100
+ function A(e) {
100
101
  if (!r.existsSync(e)) return !0;
101
- const a = r.readdirSync(e);
102
- return a.length === 0 || a.length === 1 && a[0] === ".git";
102
+ const n = r.readdirSync(e);
103
+ return n.length === 0 || n.length === 1 && n[0] === ".git";
104
+ }
105
+ const X = /* @__PURE__ */ new Set(["node_modules", ".git", ".yarn", "dist"]);
106
+ function U(e, n = []) {
107
+ if (!r.existsSync(e)) return n;
108
+ if (!r.statSync(e).isDirectory())
109
+ return n.push(e), n;
110
+ for (const t of r.readdirSync(e))
111
+ X.has(t) || U(c.join(e, t), n);
112
+ return n;
103
113
  }
104
- const W = {
114
+ async function z(e) {
115
+ const n = e.flatMap((s) => U(s));
116
+ let t = 0;
117
+ for (const s of n)
118
+ try {
119
+ const o = await C.getFileInfo(s, { resolveConfig: !0 });
120
+ if (!o.inferredParser || o.ignored) continue;
121
+ const d = r.readFileSync(s, "utf-8"), p = await C.resolveConfig(s, { editorconfig: !0 }), m = await C.format(d, { ...p, filepath: s });
122
+ m !== d && (r.writeFileSync(s, m), t++);
123
+ } catch {
124
+ }
125
+ return t;
126
+ }
127
+ const Q = {
105
128
  standalone: "Standalone App",
106
129
  "dynamic-module": "Dynamic Module"
107
130
  };
108
- function H(e) {
109
- const a = W[e.projectType] ?? e.projectType, t = !!e.moduleName;
131
+ function ee(e) {
132
+ const n = Q[e.projectType] ?? e.projectType, t = !!e.moduleName;
110
133
  console.log(`
111
- ${n.green("╭─────────────────────────────────────────╮")}
112
- ${n.green("│")} ${n.green("│")}
113
- ${n.green("│")} ${n.bold("VC Shell App created successfully!")} ${n.green("│")}
114
- ${n.green("│")} ${n.green("│")}
115
- ${n.green("│")} Project: ${n.cyan(e.projectName.padEnd(28))}${n.green("│")}
116
- ${n.green("│")} Type: ${n.cyan(a.padEnd(28))}${n.green("│")}
117
- ${t && e.moduleName ? ` ${n.green("│")} Module: ${n.cyan(e.moduleName.padEnd(28))}${n.green("│")}
118
- ` : ""} ${n.green("│")} ${n.green("│")}
119
- ${n.green("╰─────────────────────────────────────────╯")}
134
+ ${a.green("╭─────────────────────────────────────────╮")}
135
+ ${a.green("│")} ${a.green("│")}
136
+ ${a.green("│")} ${a.bold("VC Shell App created successfully!")} ${a.green("│")}
137
+ ${a.green("│")} ${a.green("│")}
138
+ ${a.green("│")} Project: ${a.cyan(e.projectName.padEnd(28))}${a.green("│")}
139
+ ${a.green("│")} Type: ${a.cyan(n.padEnd(28))}${a.green("│")}
140
+ ${t && e.moduleName ? ` ${a.green("│")} Module: ${a.cyan(e.moduleName.padEnd(28))}${a.green("│")}
141
+ ` : ""} ${a.green("│")} ${a.green("│")}
142
+ ${a.green("╰─────────────────────────────────────────╯")}
120
143
 
121
- ${n.bold("Next steps:")}
144
+ ${a.bold("Next steps:")}
122
145
 
123
146
  1. cd ${e.projectName}
124
147
  2. yarn install
125
148
  3. yarn serve
126
149
  ${t && e.moduleName ? `
127
150
  Module is ready at:
128
- src/modules/${X(e.moduleName)}/
151
+ src/modules/${te(e.moduleName)}/
129
152
  ` : ""}
130
- ${n.dim("Docs: https://docs.virtocommerce.org/platform/developer-guide/latest/custom-apps-development/vc-shell/vc-shell-overview/")}
153
+ ${a.dim("Docs: https://docs.virtocommerce.org/platform/developer-guide/latest/custom-apps-development/vc-shell/vc-shell-overview/")}
131
154
  `);
132
155
  }
133
- function X(e) {
156
+ function te(e) {
134
157
  return e.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase().replace(/[^a-z0-9-]/g, "");
135
158
  }
136
- const P = [
159
+ const T = [
137
160
  { title: "Standalone App — full application with bundled modules", value: "standalone" },
138
161
  { title: "Dynamic Module — remote module loaded by host via Module Federation", value: "dynamic-module" }
139
162
  ];
140
- function G(e) {
141
- return typeof e == "string" && P.some((a) => a.value === e);
163
+ function ne(e) {
164
+ return typeof e == "string" && T.some((n) => n.value === e);
142
165
  }
143
- async function Q(e, a) {
166
+ async function ae(e, n) {
144
167
  const t = process.cwd();
145
168
  let o = e._?.[0] || e.name || e["app-name"];
146
169
  const d = o || "vc-app", p = () => o === "." ? c.basename(c.resolve()) : o, m = !!(o && e.type);
147
- let l;
170
+ let i;
148
171
  if (m) {
149
172
  o = o || d;
150
173
  const f = c.resolve(t, o);
151
- if (!G(e.type)) {
152
- const b = P.map(($) => $.value).join(", ");
153
- console.error(n.red(`Unknown project type: "${e.type}". Valid types: ${b}`)), process.exit(1);
174
+ if (!ne(e.type)) {
175
+ const N = T.map((S) => S.value).join(", ");
176
+ console.error(a.red(`Unknown project type: "${e.type}". Valid types: ${N}`)), process.exit(1);
154
177
  }
155
- r.existsSync(f) && !I(f) && !e.overwrite && (console.error(n.red(`Target directory "${o}" is not empty. Use --overwrite to overwrite.`)), process.exit(1));
156
- const u = p(), y = e.type, g = e["module-name"], N = y === "dynamic-module" ? g || S(u) : g || void 0;
157
- l = {
178
+ r.existsSync(f) && !A(f) && !e.overwrite && (console.error(a.red(`Target directory "${o}" is not empty. Use --overwrite to overwrite.`)), process.exit(1));
179
+ const u = p(), y = e.type, g = e["module-name"], $ = y === "dynamic-module" ? g || j(u) : g || void 0;
180
+ i = {
158
181
  projectName: h(u),
159
- packageName: e["package-name"] || (k(u) ? u : C(u)),
182
+ packageName: e["package-name"] || (k(u) ? u : _(u)),
160
183
  projectType: y,
161
- moduleName: N,
162
- basePath: e["base-path"] || _(`/apps/${h(u)}/`),
184
+ moduleName: $,
185
+ basePath: e["base-path"] || I(`/apps/${h(u)}/`),
163
186
  tenantRoutes: e["tenant-routes"] || !1,
164
187
  aiAgent: e["ai-agent"] || !1,
165
188
  dashboard: e.dashboard || !1,
@@ -167,15 +190,15 @@ async function Q(e, a) {
167
190
  };
168
191
  } else {
169
192
  const f = () => {
170
- throw new Error(n.red("✖") + " Creation cancelled");
193
+ throw new Error(a.red("✖") + " Creation cancelled");
171
194
  };
172
195
  try {
173
- const u = await A(
196
+ const u = await P(
174
197
  [
175
198
  {
176
199
  name: "projectName",
177
200
  type: o ? null : "text",
178
- message: n.reset("Project name:"),
201
+ message: a.reset("Project name:"),
179
202
  initial: d,
180
203
  onState: (w) => {
181
204
  o = h(String(w.value).trim()) || d;
@@ -183,14 +206,14 @@ async function Q(e, a) {
183
206
  format: (w) => h(String(w).trim())
184
207
  },
185
208
  {
186
- type: () => !r.existsSync(c.resolve(t, o)) || I(c.resolve(t, o)) ? null : "confirm",
209
+ type: () => !r.existsSync(c.resolve(t, o)) || A(c.resolve(t, o)) ? null : "confirm",
187
210
  name: "overwrite",
188
211
  message: () => (o === "." ? "Current directory" : `Target directory "${o}"`) + " is not empty. Remove existing files and continue?"
189
212
  },
190
213
  {
191
214
  type: (w, { overwrite: M }) => {
192
215
  if (M === !1)
193
- throw new Error(n.red("✖") + " Operation cancelled");
216
+ throw new Error(a.red("✖") + " Operation cancelled");
194
217
  return null;
195
218
  },
196
219
  name: "overwriteChecker"
@@ -198,19 +221,19 @@ async function Q(e, a) {
198
221
  {
199
222
  name: "packageName",
200
223
  type: () => k(p()) ? null : "text",
201
- message: n.reset("Package name:"),
202
- initial: () => C(p()),
224
+ message: a.reset("Package name:"),
225
+ initial: () => _(p()),
203
226
  validate: (w) => k(w) || "Invalid package.json name"
204
227
  },
205
228
  {
206
229
  type: "select",
207
230
  name: "projectType",
208
- message: n.reset("Project type:"),
209
- choices: P
231
+ message: a.reset("Project type:"),
232
+ choices: T
210
233
  }
211
234
  ],
212
235
  { onCancel: f }
213
- ), y = o ? h(o) : u.projectName, g = u.projectType || "standalone", N = S(y), b = "/apps/" + h(y) + "/", $ = await A(
236
+ ), y = o ? h(o) : u.projectName, g = u.projectType || "standalone", $ = j(y), N = "/apps/" + h(y) + "/", S = await P(
214
237
  [
215
238
  {
216
239
  name: "includeModule",
@@ -221,16 +244,16 @@ async function Q(e, a) {
221
244
  {
222
245
  name: "moduleName",
223
246
  type: (w, M) => g === "standalone" && !M.includeModule ? null : "text",
224
- message: n.reset("Module name:"),
225
- initial: N,
247
+ message: a.reset("Module name:"),
248
+ initial: $,
226
249
  format: (w) => String(w).trim()
227
250
  },
228
251
  {
229
252
  name: "basePath",
230
253
  type: g === "dynamic-module" ? null : "text",
231
- message: n.reset("Base path:"),
232
- initial: b,
233
- format: (w) => _(String(w).trim())
254
+ message: a.reset("Base path:"),
255
+ initial: N,
256
+ format: (w) => I(String(w).trim())
234
257
  },
235
258
  {
236
259
  type: g === "dynamic-module" ? null : "confirm",
@@ -259,33 +282,33 @@ async function Q(e, a) {
259
282
  ],
260
283
  { onCancel: f }
261
284
  );
262
- l = {
285
+ i = {
263
286
  projectName: y,
264
- packageName: u.packageName || (k(y) ? y : C(y)),
287
+ packageName: u.packageName || (k(y) ? y : _(y)),
265
288
  projectType: g,
266
- moduleName: $.moduleName || ($.includeModule !== !1 ? N : void 0),
267
- basePath: $.basePath || _(b),
268
- tenantRoutes: $.tenantRoutes || !1,
269
- aiAgent: $.aiAgent || !1,
270
- dashboard: $.dashboard ?? !0,
271
- mocks: $.mocks || !1
289
+ moduleName: S.moduleName || (S.includeModule !== !1 ? $ : void 0),
290
+ basePath: S.basePath || I(N),
291
+ tenantRoutes: S.tenantRoutes || !1,
292
+ aiAgent: S.aiAgent || !1,
293
+ dashboard: S.dashboard ?? !0,
294
+ mocks: S.mocks || !1
272
295
  };
273
296
  } catch (u) {
274
297
  console.log(u.message), process.exit(1);
275
298
  }
276
299
  }
277
- const i = c.resolve(t, o);
278
- r.existsSync(i) && !I(i) ? q(i) : r.existsSync(i) || r.mkdirSync(i, { recursive: !0 }), console.log(`
279
- Scaffolding ${n.cyan(l.projectType)} in ${n.green(i)}...
300
+ const l = c.resolve(t, o);
301
+ r.existsSync(l) && !A(l) ? H(l) : r.existsSync(l) || r.mkdirSync(l, { recursive: !0 }), console.log(`
302
+ Scaffolding ${a.cyan(i.projectType)} in ${a.green(l)}...
280
303
  `);
281
- const v = R(l);
282
- if (j(c.join(a, l.projectType), i, v), l.moduleName) {
283
- const f = h(l.moduleName), u = l.projectType === "dynamic-module" ? c.join(i, "src/modules") : c.join(i, "src/modules", f);
284
- j(c.join(a, "module"), u, v);
304
+ const v = F(i);
305
+ if (b(c.join(n, i.projectType), l, v), i.moduleName) {
306
+ const f = h(i.moduleName), u = i.projectType === "dynamic-module" ? c.join(l, "src/modules") : c.join(l, "src/modules", f);
307
+ b(c.join(n, "module"), u, v);
285
308
  }
286
- l.mocks && j(c.join(a, "sample-module"), c.join(i, "src/modules/sample"), v), H(l);
309
+ i.mocks && b(c.join(n, "sample-module"), c.join(l, "src/modules/sample"), v), await z([l]), ee(i);
287
310
  }
288
- function U(e, a) {
311
+ function L(e, n) {
289
312
  const t = /^import\s.+$/gm;
290
313
  let s = null, o;
291
314
  for (; (o = t.exec(e)) !== null; )
@@ -293,42 +316,42 @@ function U(e, a) {
293
316
  if (s) {
294
317
  const d = s.index + s[0].length;
295
318
  return e.slice(0, d) + `
296
- ` + a + e.slice(d);
319
+ ` + n + e.slice(d);
297
320
  }
298
- return a + `
321
+ return n + `
299
322
  ` + e;
300
323
  }
301
- function ee(e, a) {
324
+ function oe(e, n) {
302
325
  let t = r.readFileSync(e, "utf-8");
303
- const s = x(a), o = h(a);
304
- t = U(t, `import ${s} from "./modules/${o}";`);
326
+ const s = x(n), o = h(n);
327
+ t = L(t, `import ${s} from "./modules/${o}";`);
305
328
  const d = /\.use\([A-Z]\w+,\s*\{\s*router\s*\}\)/g;
306
329
  let p = null, m;
307
330
  for (; (m = d.exec(t)) !== null; )
308
331
  p = m;
309
332
  if (p) {
310
- const l = p.index + p[0].length, i = `
333
+ const i = p.index + p[0].length, l = `
311
334
  .use(${s}, { router })`;
312
- t = t.slice(0, l) + i + t.slice(l);
335
+ t = t.slice(0, i) + l + t.slice(i);
313
336
  }
314
337
  r.writeFileSync(e, t);
315
338
  }
316
- function te(e, a) {
339
+ function re(e, n) {
317
340
  let t = r.readFileSync(e, "utf-8");
318
- const s = h(a), o = D(a);
341
+ const s = h(n), o = R(n);
319
342
  if (!t.includes("addMenuItem")) {
320
343
  const v = /import\s*\{([^}]+)\}\s*from\s*["']@vc-shell\/framework["']/.exec(t);
321
344
  if (v) {
322
345
  const f = v[1].trim() + ", addMenuItem";
323
346
  t = t.replace(v[0], `import { ${f} } from "@vc-shell/framework"`);
324
347
  } else
325
- t = U(t, 'import { addMenuItem } from "@vc-shell/framework";');
348
+ t = L(t, 'import { addMenuItem } from "@vc-shell/framework";');
326
349
  }
327
350
  const d = /addMenuItem\(\{[\s\S]*?\}\);/g;
328
351
  let p = null, m;
329
352
  for (; (m = d.exec(t)) !== null; )
330
353
  p = m;
331
- const l = `
354
+ const i = `
332
355
  addMenuItem({
333
356
  title: "${o}.MENU.TITLE",
334
357
  icon: "lucide-box",
@@ -336,60 +359,60 @@ function te(e, a) {
336
359
  url: "/${s}",
337
360
  });`;
338
361
  if (p) {
339
- const i = p.index + p[0].length;
340
- t = t.slice(0, i) + `
341
- ` + l + t.slice(i);
362
+ const l = p.index + p[0].length;
363
+ t = t.slice(0, l) + `
364
+ ` + i + t.slice(l);
342
365
  } else {
343
- const i = t.lastIndexOf("}");
344
- i !== -1 && (t = t.slice(0, i) + l + `
345
- ` + t.slice(i));
366
+ const l = t.lastIndexOf("}");
367
+ l !== -1 && (t = t.slice(0, l) + i + `
368
+ ` + t.slice(l));
346
369
  }
347
370
  r.writeFileSync(e, t);
348
371
  }
349
- async function ae(e, a) {
372
+ async function se(e, n) {
350
373
  const t = process.cwd(), s = e._?.[1], o = c.join(t, "package.json");
351
- r.existsSync(o) || (console.error(n.red("Error: No package.json found. Run this command from a vc-shell project root.")), process.exit(1));
374
+ r.existsSync(o) || (console.error(a.red("Error: No package.json found. Run this command from a vc-shell project root.")), process.exit(1));
352
375
  const d = JSON.parse(r.readFileSync(o, "utf-8"));
353
- ({ ...d.dependencies, ...d.devDependencies })["@vc-shell/framework"] || (console.error(n.red("Error: Not a vc-shell project (@vc-shell/framework not found in dependencies).")), process.exit(1));
376
+ ({ ...d.dependencies, ...d.devDependencies })["@vc-shell/framework"] || (console.error(a.red("Error: Not a vc-shell project (@vc-shell/framework not found in dependencies).")), process.exit(1));
354
377
  let m = s;
355
- m || (m = (await A({
378
+ m || (m = (await P({
356
379
  type: "text",
357
380
  name: "moduleName",
358
381
  message: "Module name:",
359
- validate: (b) => b.trim().length > 0 || "Module name is required"
360
- })).moduleName), m || (console.error(n.red("Module name is required.")), process.exit(1));
361
- const l = h(m), i = x(m), v = c.join(t, "src/modules"), f = c.join(v, l);
362
- r.existsSync(v) || r.mkdirSync(v, { recursive: !0 }), r.existsSync(f) && (console.error(n.red(`Error: Module "${l}" already exists at ${c.relative(t, f)}`)), process.exit(1));
363
- const u = R({ moduleName: m, projectName: c.basename(t) });
364
- j(c.join(a, "module"), f, u), console.log(n.green(` ✔ Created ${c.relative(t, f)}/`));
382
+ validate: (N) => N.trim().length > 0 || "Module name is required"
383
+ })).moduleName), m || (console.error(a.red("Module name is required.")), process.exit(1));
384
+ const i = h(m), l = x(m), v = c.join(t, "src/modules"), f = c.join(v, i);
385
+ r.existsSync(v) || r.mkdirSync(v, { recursive: !0 }), r.existsSync(f) && (console.error(a.red(`Error: Module "${i}" already exists at ${c.relative(t, f)}`)), process.exit(1));
386
+ const u = F({ moduleName: m, projectName: c.basename(t) });
387
+ b(c.join(n, "module"), f, u), console.log(a.green(` ✔ Created ${c.relative(t, f)}/`));
365
388
  const y = c.join(t, "src/main.ts");
366
389
  if (r.existsSync(y))
367
390
  try {
368
- ee(y, m), console.log(n.green(` ✔ Updated src/main.ts — added import & app.use(${i})`));
391
+ oe(y, m), console.log(a.green(` ✔ Updated src/main.ts — added import & app.use(${l})`));
369
392
  } catch {
370
- console.warn(n.yellow(" ⚠ Could not auto-update src/main.ts. Add manually:")), console.warn(n.yellow(` import ${i} from "./modules/${l}";`)), console.warn(n.yellow(` app.use(${i}, { router });`));
393
+ console.warn(a.yellow(" ⚠ Could not auto-update src/main.ts. Add manually:")), console.warn(a.yellow(` import ${l} from "./modules/${i}";`)), console.warn(a.yellow(` app.use(${l}, { router });`));
371
394
  }
372
395
  const g = c.join(t, "src/bootstrap.ts");
373
396
  if (r.existsSync(g))
374
397
  try {
375
- te(g, m), console.log(n.green(` ✔ Updated src/bootstrap.ts — added menu item "${S(m)}"`));
398
+ re(g, m), console.log(a.green(` ✔ Updated src/bootstrap.ts — added menu item "${j(m)}"`));
376
399
  } catch {
377
- console.warn(n.yellow(" ⚠ Could not auto-update src/bootstrap.ts. Add addMenuItem() manually."));
400
+ console.warn(a.yellow(" ⚠ Could not auto-update src/bootstrap.ts. Add addMenuItem() manually."));
378
401
  }
379
- console.log(`
380
- Module "${l}" is ready! Run ${n.bold(n.green("yarn serve"))} to see it.
402
+ await z([f, y, g]), console.log(`
403
+ Module "${i}" is ready! Run ${a.bold(a.green("yarn serve"))} to see it.
381
404
  `);
382
405
  }
383
- const T = c.resolve(F(import.meta.url), "..", "templates");
384
- function ne() {
406
+ const E = c.resolve(K(import.meta.url), "..", "templates");
407
+ function ce() {
385
408
  console.log(`
386
- ${n.bold(n.green("create-vc-app"))} — Create VC Shell applications and modules
409
+ ${a.bold(a.green("create-vc-app"))} — Create VC Shell applications and modules
387
410
 
388
- ${n.bold("Usage:")}
411
+ ${a.bold("Usage:")}
389
412
  create-vc-app [project-name] [options] Create a new project
390
413
  create-vc-app add-module <module-name> Add a module to existing project
391
414
 
392
- ${n.bold("Options (create):")}
415
+ ${a.bold("Options (create):")}
393
416
  --type <type> Project type: standalone | dynamic-module
394
417
  --name, --app-name <name> Application name
395
418
  --package-name <name> npm package name
@@ -403,31 +426,31 @@ ${n.bold("Options (create):")}
403
426
  --help, -h Show this help
404
427
  --version, -v Show version
405
428
 
406
- ${n.bold("Examples:")}
429
+ ${a.bold("Examples:")}
407
430
  create-vc-app my-app
408
431
  create-vc-app my-app --type standalone --dashboard --mocks
409
432
  create-vc-app my-module --type dynamic-module --module-name "Reviews"
410
433
  create-vc-app add-module orders
411
434
 
412
- ${n.bold("Docs:")} https://docs.virtocommerce.org/platform/developer-guide/latest/custom-apps-development/vc-shell/vc-shell-overview/
435
+ ${a.bold("Docs:")} https://docs.virtocommerce.org/platform/developer-guide/latest/custom-apps-development/vc-shell/vc-shell-overview/
413
436
  `);
414
437
  }
415
- async function oe() {
416
- const e = z(B.slice(2), {
438
+ async function ie() {
439
+ const e = B(V.slice(2), {
417
440
  alias: { h: "help", v: "version" },
418
441
  boolean: ["help", "version", "mocks", "overwrite", "tenant-routes", "ai-agent", "dashboard"],
419
442
  string: ["type", "name", "app-name", "package-name", "module-name", "base-path"]
420
443
  });
421
444
  if (e.help) {
422
- ne();
445
+ ce();
423
446
  return;
424
447
  }
425
448
  if (e.version) {
426
- console.log(`create-vc-app v${V.version}`);
449
+ console.log(`create-vc-app v${J.version}`);
427
450
  return;
428
451
  }
429
- e._[0] === "add-module" ? await ae(e, T) : await Q(e, T);
452
+ e._[0] === "add-module" ? await se(e, E) : await ae(e, E);
430
453
  }
431
- oe().catch((e) => {
432
- console.error(n.red(e.message || String(e))), L(1);
454
+ ie().catch((e) => {
455
+ console.error(a.red(e.message || String(e))), O(1);
433
456
  });
@@ -6,9 +6,5 @@
6
6
  "rootDir": "src",
7
7
  "types": ["vite/client", "@vc-shell/framework/globals"]
8
8
  },
9
- "include": [
10
- "./src/**/*.ts",
11
- "./src/**/*.vue",
12
- "./src/**/*.json"
13
- ]
9
+ "include": ["./src/**/*.ts", "./src/**/*.vue", "./src/**/*.json"]
14
10
  }
@@ -18,14 +18,30 @@
18
18
  @pagination-click="pagination.goToPage"
19
19
  >
20
20
  <!-- Add your columns here -->
21
- <VcColumn id="name" :title="$t('<%- ModuleNameScreamingSnake %>.PAGES.LIST.COLUMNS.NAME')" sortable />
22
- <VcColumn id="createdDate" :title="$t('<%- ModuleNameScreamingSnake %>.PAGES.LIST.COLUMNS.CREATED_DATE')" type="datetime" sortable />
21
+ <VcColumn
22
+ id="name"
23
+ :title="$t('<%- ModuleNameScreamingSnake %>.PAGES.LIST.COLUMNS.NAME')"
24
+ sortable
25
+ />
26
+ <VcColumn
27
+ id="createdDate"
28
+ :title="$t('<%- ModuleNameScreamingSnake %>.PAGES.LIST.COLUMNS.CREATED_DATE')"
29
+ type="datetime"
30
+ sortable
31
+ />
23
32
  </VcDataTable>
24
33
  </VcBlade>
25
34
  </template>
26
35
 
27
36
  <script setup lang="ts">
28
- import { useBlade, useDataTableSort, useTableSearch, useDataTablePagination, useFunctions, type IBladeToolbar } from "@vc-shell/framework";
37
+ import {
38
+ useBlade,
39
+ useDataTableSort,
40
+ useTableSearch,
41
+ useDataTablePagination,
42
+ useFunctions,
43
+ type IBladeToolbar,
44
+ } from "@vc-shell/framework";
29
45
  import { VcBlade, VcDataTable, VcColumn } from "@vc-shell/framework/ui";
30
46
  import { ref, watch } from "vue";
31
47
  import use<%- ModuleNamePascalCase %>List from "../composables/useList";
@@ -57,7 +73,11 @@ const { sortField, sortOrder, sortExpression } = useDataTableSort({
57
73
  const { data, loading, totalCount, getItems } = use<%- ModuleNamePascalCase %>List();
58
74
 
59
75
  const { searchValue } = useTableSearch({ stateKey: "<%- ModuleNameScreamingSnake %>" });
60
- const pagination = useDataTablePagination({ stateKey: "<%- ModuleNameScreamingSnake %>", pageSize: PAGE_SIZE, totalCount });
76
+ const pagination = useDataTablePagination({
77
+ stateKey: "<%- ModuleNameScreamingSnake %>",
78
+ pageSize: PAGE_SIZE,
79
+ totalCount,
80
+ });
61
81
 
62
82
  function load() {
63
83
  return getItems({
@@ -25,7 +25,7 @@ interface SearchResult {
25
25
 
26
26
  export type { MockedItem };
27
27
 
28
- export default (options?: { pageSize?: number, sort?: string }): useClassicAppList => {
28
+ export default (options?: { pageSize?: number; sort?: string }): useClassicAppList => {
29
29
  const pageSize = options?.pageSize || 20;
30
30
  const searchResult = ref<SearchResult>();
31
31
  const searchQuery = ref<SearchQuery>({
@@ -1,2 +1,2 @@
1
1
  export { default as List } from "./list.vue";
2
- export {default as Details } from './details.vue'
2
+ export { default as Details } from "./details.vue";
@@ -75,7 +75,15 @@
75
75
 
76
76
  <script lang="ts" setup>
77
77
  import { ref, watch, computed } from "vue";
78
- import { IBladeToolbar, useBlade, usePopup, useDataTableSort, useTableSearch, useDataTablePagination, useFunctions } from "@vc-shell/framework";
78
+ import {
79
+ IBladeToolbar,
80
+ useBlade,
81
+ usePopup,
82
+ useDataTableSort,
83
+ useTableSearch,
84
+ useDataTablePagination,
85
+ useFunctions,
86
+ } from "@vc-shell/framework";
79
87
  import type { TableAction } from "@vc-shell/framework";
80
88
  import { VcColumn, VcDataTable, VcBlade } from "@vc-shell/framework/ui";
81
89
  import { useI18n } from "vue-i18n";
@@ -1,2 +1,2 @@
1
- export * from './constants'
2
- export * from './methods'
1
+ export * from "./constants";
2
+ export * from "./methods";
@@ -4,21 +4,21 @@
4
4
 
5
5
  Messages must be matched by the following regex:
6
6
 
7
- ``` js
8
- /^(revert: )?(feat|fix|docs|style|refactor|perf|test|workflow|ci|chore|types)(\(.+\))?: .{1,50}/
7
+ ```js
8
+ /^(revert: )?(feat|fix|docs|style|refactor|perf|test|workflow|ci|chore|types)(\(.+\))?: .{1,50}/;
9
9
  ```
10
10
 
11
11
  ## Examples
12
12
 
13
13
  Appears under "Features" header, `ui-kit` subheader:
14
14
 
15
- ``` text
15
+ ```text
16
16
  feat(ui-kit): add 'comments' option
17
17
  ```
18
18
 
19
19
  Appears under "Bug Fixes" header, `shell` subheader, with a link to issue #28:
20
20
 
21
- ``` text
21
+ ```text
22
22
  fix(shell): handle events on blur
23
23
 
24
24
  close #28
@@ -26,7 +26,7 @@ close #28
26
26
 
27
27
  Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:
28
28
 
29
- ``` text
29
+ ```text
30
30
  perf(api-client): improve vdom diffing by removing 'foo' option
31
31
 
32
32
  BREAKING CHANGE: The 'foo' option has been removed.
@@ -34,7 +34,7 @@ BREAKING CHANGE: The 'foo' option has been removed.
34
34
 
35
35
  The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.
36
36
 
37
- ``` text
37
+ ```text
38
38
  revert: feat(ui-kit): add 'comments' option
39
39
 
40
40
  This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
@@ -42,9 +42,9 @@ This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
42
42
 
43
43
  ## Full Message Format
44
44
 
45
- A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
45
+ A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
46
46
 
47
- ``` text
47
+ ```text
48
48
  <type>(<scope>): <subject>
49
49
  <BLANK LINE>
50
50
  <body>
@@ -68,15 +68,15 @@ Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`
68
68
 
69
69
  ### Scope
70
70
 
71
- The scope could be any valid workspace package name. For example `shell`, `ui-kit`, `api-client`, etc...
71
+ The scope could be any valid workspace package name. For example `shell`, `ui-kit`, `api-client`, etc...
72
72
 
73
73
  ### Subject
74
74
 
75
75
  The subject contains succinct description of the change:
76
76
 
77
- * use the imperative, present tense: "change" not "changed" nor "changes"
78
- * don't capitalize first letter
79
- * no dot (.) at the end
77
+ - use the imperative, present tense: "change" not "changed" nor "changes"
78
+ - don't capitalize first letter
79
+ - no dot (.) at the end
80
80
 
81
81
  ### Body
82
82
 
@@ -1,8 +1,11 @@
1
1
  # Project Task
2
+
2
3
  <!-- paste a link to related issue -->
4
+
3
5
  Closes #
4
6
 
5
7
  ## Scope of work
8
+
6
9
  <!-- describe what you did -->
7
10
 
8
11
  ## Checklist
@@ -8,7 +8,5 @@
8
8
  "vue.volar",
9
9
  "lokalise.i18n-ally"
10
10
  ],
11
- "unwantedRecommendations": [
12
- "octref.vetur"
13
- ]
11
+ "unwantedRecommendations": ["octref.vetur"]
14
12
  }
@@ -3,12 +3,7 @@
3
3
  "source.fixAll.eslint": true
4
4
  },
5
5
  "files.eol": "\r\n",
6
- "eslint.validate": [
7
- "vue",
8
- "javascript"
9
- ],
10
- "i18n-ally.localesPaths": [
11
- "src/locales",
12
- ],
13
- "typescript.preferences.importModuleSpecifier": "relative",
6
+ "eslint.validate": ["vue", "javascript"],
7
+ "i18n-ally.localesPaths": ["src/locales"],
8
+ "typescript.preferences.importModuleSpecifier": "relative"
14
9
  }
@@ -1,12 +1,17 @@
1
1
  import pluginVue from "eslint-plugin-vue";
2
2
  import vueTsEslintConfig from "@vue/eslint-config-typescript";
3
3
  import vuePrettierConfig from "@vue/eslint-config-prettier";
4
+ import importPlugin from "eslint-plugin-import";
4
5
 
5
6
  export default [
6
7
  {
7
8
  ignores: ["**/node_modules/**", "**/dist/**", "api-client.ts"],
8
9
  },
9
10
 
11
+ importPlugin.flatConfigs.recommended,
12
+
13
+ importPlugin.flatConfigs.typescript,
14
+
10
15
  ...pluginVue.configs["flat/recommended"],
11
16
 
12
17
  ...vueTsEslintConfig(),
@@ -14,6 +19,14 @@ export default [
14
19
  vuePrettierConfig,
15
20
 
16
21
  {
22
+ settings: {
23
+ "import/resolver": {
24
+ typescript: {
25
+ alwaysTryTypes: true,
26
+ project: "./tsconfig.json",
27
+ },
28
+ },
29
+ },
17
30
  rules: {
18
31
  "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
19
32
  "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
@@ -26,6 +39,13 @@ export default [
26
39
  "vue/require-default-prop": "off",
27
40
  "vue/no-v-html": "off",
28
41
  "vue/no-template-shadow": "off",
42
+ // Vite serves `public/` at the site root, so these are not module paths.
43
+ "import/no-unresolved": ["error", { ignore: ["^/assets/"] }],
44
+ // TypeScript already covers these, and the rules parse dependency
45
+ // sources with espree, which chokes on modern syntax in `dist` output.
46
+ "import/namespace": "off",
47
+ "import/default": "off",
48
+ "import/no-named-as-default-member": "off",
29
49
  },
30
50
  },
31
51
  ];
@@ -5,11 +5,11 @@
5
5
  This guide describes the process of generating an API client to access the VC Platform API from your custom application.
6
6
 
7
7
  !!! note
8
- Platform Manager REST Client offers generated REST API methods that make it easy to interact with the existing VirtoCommerce Platform API.
8
+ Platform Manager REST Client offers generated REST API methods that make it easy to interact with the existing VirtoCommerce Platform API.
9
9
 
10
10
  ## Prerequisites
11
11
 
12
- * .NET Core 6.0, particularly if you are using MacOS or Linux.
12
+ - .NET Core 6.0, particularly if you are using MacOS or Linux.
13
13
 
14
14
  ## Generate TypeScript API clients
15
15
 
@@ -22,6 +22,7 @@ Using command
22
22
  ```bash
23
23
  yarn add @vc-shell/api-client-generator cross-env
24
24
  ```
25
+
25
26
  <br>
26
27
 
27
28
  `cross-env` runs scripts that set and use environment variables across platforms.
@@ -44,44 +45,44 @@ Add the dependencies to your project's **package.json**:
44
45
 
45
46
  2. Configure client generation in your project. Inside your project's **package.json** file, add a `"generate-api-client"` command to the list of scripts:
46
47
 
47
- ```title="vc-app-extend/package.json" linenums="1"
48
- {
49
- "scripts": {
50
- ...
51
- "generate-api-client": cross-env api-client-generator --APP_PLATFORM_MODULES='[MarketplaceVendor,Catalog,Orders]' --APP_API_CLIENT_DIRECTORY=./src/api_client/
52
- }
53
- }
54
- ```
55
-
56
- The options are listed in the table below:
57
-
58
- | Options | Description | Example |
59
- |----------------------------- |---------------------------------------------------------------- |------------------------------------------------------------ |
60
- | `--APP_PLATFORM_MODULES` | Platform modules to generate API client.<br>{==string[]==} <br> Customize the `--APP_PLATFORM_MODULES` list<br>to match your project's requirements. | `--APP_PLATFORM_MODULES='[MarketplaceVendor,Orders,Catalog]'` |
61
- | `--APP_API_CLIENT_DIRECTORY` | Output directory for generated API clients. <br>{==string==} | `--APP_API_CLIENT_DIRECTORY=./src/api_client/` |
62
- | `--APP_PLATFORM_URL` | Platform URL to obtain client API configs. <br>{==string==} | `--APP_PLATFORM_URL=https://vcmp-dev.govirto.com/` |
63
- | `--APP_PACKAGE_NAME` | Package name for generated API clients. <br>{==string==} | `--APP_PACKAGE_NAME=vc-app-extend` |
64
- | `--APP_PACKAGE_VERSION` | Package version for generated API clients. <br>{==string==} | `--APP_PACKAGE_VERSION=1.0.0` |
65
- | `--APP_TYPE_STYLE` | Sets the type style for generated DTOs. Can be 'Class' or 'Interface'.<br>{==string==} | `--APP_TYPE_STYLE=Interface` |
66
- | `--APP_OUT_DIR` | Output directory for generated API clients. <br>{==string==} | `--APP_OUT_DIR=./src/api_client/` |
67
- | `--APP_BUILD_DIR` | Directory where TypeScript files will be compiled. <br>{==string==} | `--APP_BUILD_DIR=lib` (default is "dist") |
68
- | `--SKIP_BUILD` | Skip build step. <br>{==boolean==} | `--SKIP_BUILD=true` |
69
- | `--VERBOSE` | Enable verbose logging. <br>{==boolean==} | `--VERBOSE=true` |
48
+ ```title="vc-app-extend/package.json" linenums="1"
49
+ {
50
+ "scripts": {
51
+ ...
52
+ "generate-api-client": cross-env api-client-generator --APP_PLATFORM_MODULES='[MarketplaceVendor,Catalog,Orders]' --APP_API_CLIENT_DIRECTORY=./src/api_client/
53
+ }
54
+ }
55
+ ```
56
+
57
+ The options are listed in the table below:
58
+
59
+ | Options | Description | Example |
60
+ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
61
+ | `--APP_PLATFORM_MODULES` | Platform modules to generate API client.<br>{==string[]==} <br> Customize the `--APP_PLATFORM_MODULES` list<br>to match your project's requirements. | `--APP_PLATFORM_MODULES='[MarketplaceVendor,Orders,Catalog]'` |
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_PACKAGE_NAME` | Package name for generated API clients. <br>{==string==} | `--APP_PACKAGE_NAME=vc-app-extend` |
65
+ | `--APP_PACKAGE_VERSION` | Package version for generated API clients. <br>{==string==} | `--APP_PACKAGE_VERSION=1.0.0` |
66
+ | `--APP_TYPE_STYLE` | Sets the type style for generated DTOs. Can be 'Class' or 'Interface'.<br>{==string==} | `--APP_TYPE_STYLE=Interface` |
67
+ | `--APP_OUT_DIR` | Output directory for generated API clients. <br>{==string==} | `--APP_OUT_DIR=./src/api_client/` |
68
+ | `--APP_BUILD_DIR` | Directory where TypeScript files will be compiled. <br>{==string==} | `--APP_BUILD_DIR=lib` (default is "dist") |
69
+ | `--SKIP_BUILD` | Skip build step. <br>{==boolean==} | `--SKIP_BUILD=true` |
70
+ | `--VERBOSE` | Enable verbose logging. <br>{==boolean==} | `--VERBOSE=true` |
70
71
 
71
72
  3. Configure Platform URL to ensure your project can access the platform's API configurations. Add the platform URL to your project's **.env** file:
72
73
 
73
- ```title="vc-app-extend/.env"
74
- APP_PLATFORM_URL=https://vcmp-dev.govirto.com/
75
- ```
74
+ ```title="vc-app-extend/.env"
75
+ APP_PLATFORM_URL=https://vcmp-dev.govirto.com/
76
+ ```
76
77
 
77
- !!! note
78
- Alternatively, you can specify the Platform URL as a command option in the previous step when running the `"generate-api-client"` command.
78
+ !!! note
79
+ Alternatively, you can specify the Platform URL as a command option in the previous step when running the `"generate-api-client"` command.
79
80
 
80
81
  4. Generate the API clients using the following command:
81
82
 
82
- ```
83
- yarn generate-api-client
84
- ```
83
+ ```
84
+ yarn generate-api-client
85
+ ```
85
86
 
86
87
  This command generates the required API clients for your custom application. Now you can effortlessly access the VC Platform API from your custom application using the generated API client.
87
88
 
@@ -112,7 +113,7 @@ API client now includes metadata to track the generation:
112
113
 
113
114
  The generator handles multiple API clients effectively:
114
115
 
115
- - Creates standardized exports with both short names (`./{moduleName}`) and full names (`./virtocommerce.{moduleName}`)
116
+ - Creates standardized exports with both short names (`./{moduleName}`) and full names (`./virtocommerce.{moduleName}`)
116
117
  - Prevents duplicate module exports by intelligently merging with existing ones
117
118
  - Automatically removes `module` and `types` fields that conflict with multiple exports
118
119
  - Works properly with incremental generation (can add new APIs without breaking existing ones)
@@ -129,11 +130,11 @@ This enables both simple usage for single-API packages and proper subpath export
129
130
 
130
131
  ```js
131
132
  // Single API package (using root export)
132
- import { MyClient } from '@myapp/api';
133
+ import { MyClient } from "@myapp/api";
133
134
 
134
135
  // Multi-API package (using subpath exports)
135
- import { ClientA } from '@myapp/api/moduleA';
136
- import { ClientB } from '@myapp/api/moduleB';
136
+ import { ClientA } from "@myapp/api/moduleA";
137
+ import { ClientB } from "@myapp/api/moduleB";
137
138
  ```
138
139
 
139
140
  ### Directory Creation
@@ -14,7 +14,6 @@
14
14
  </template>
15
15
 
16
16
  <script setup lang="ts">
17
- // eslint-disable-next-line import/no-unresolved
18
17
  import Welcome from "/assets/welcome.png";
19
18
  </script>
20
19
 
@@ -40,7 +39,7 @@ import Welcome from "/assets/welcome.png";
40
39
  }
41
40
 
42
41
  &__welcome-description {
43
- @apply tw-whitespace-break-spaces tw-text-s tw-max-w-[90%] tw-mx-auto tw-leading-5 tw-font-semibold;
42
+ @apply tw-whitespace-break-spaces tw-text-sm tw-max-w-[90%] tw-mx-auto tw-leading-5 tw-font-semibold;
44
43
  }
45
44
  }
46
45
  </style>
@@ -4,4 +4,4 @@
4
4
 
5
5
  <script lang="ts" setup>
6
6
  import { DraggableDashboard } from "@vc-shell/framework";
7
- </script>
7
+ </script>
@@ -1,43 +1,40 @@
1
1
  import { RouteRecordRaw } from "vue-router";
2
2
  import App from "../pages/App.vue";
3
- <% if (dashboard) { %>
3
+ <%_ if (dashboard) { -%>
4
4
  import Dashboard from "../pages/Dashboard.vue";
5
- <% } %>
5
+ <%_ } -%>
6
6
  import { Invite, Login, ResetPassword, ForgotPassword, ChangePasswordPage } from "@vc-shell/framework";
7
- // eslint-disable-next-line import/no-unresolved
8
7
  import whiteLogoImage from "/assets/logo-white.svg";
9
- // eslint-disable-next-line import/no-unresolved
10
- import bgImage from "/assets/background.jpg";
8
+ <%_ if (tenantRoutes) { -%>
11
9
 
12
- <% if (tenantRoutes) { %>
13
10
  const tenantIdRegex = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
14
- <% } %>
11
+ <%_ } -%>
15
12
 
16
13
  export const routes: RouteRecordRaw[] = [
17
14
  {
18
- <% if (tenantRoutes) { %>
15
+ <%_ if (tenantRoutes) { -%>
19
16
  path: `/:tenantId(${tenantIdRegex})?`,
20
- <% } else { %>
17
+ <%_ } else { -%>
21
18
  path: "/",
22
- <% } %>
19
+ <%_ } -%>
23
20
  component: App,
24
21
  name: "App",
25
22
  meta: {
26
23
  root: true,
27
24
  },
28
25
  children: [
29
- <% if (dashboard) { %>
26
+ <%_ if (dashboard) { -%>
30
27
  {
31
28
  name: "Dashboard",
32
29
  path: "",
33
- <% if (tenantRoutes) { %>
30
+ <%_ if (tenantRoutes) { -%>
34
31
  alias: `/:tenantId(${tenantIdRegex})?`,
35
- <% } else { %>
32
+ <%_ } else { -%>
36
33
  alias: "/",
37
- <% } %>
34
+ <%_ } -%>
38
35
  component: Dashboard,
39
36
  },
40
- <% } %>
37
+ <%_ } -%>
41
38
  ],
42
39
  },
43
40
  {
@@ -4,14 +4,7 @@
4
4
  "baseUrl": ".",
5
5
  "outDir": "dist",
6
6
  "rootDir": "src",
7
- "types": [
8
- "vite/client",
9
- "@vc-shell/framework/globals"
10
- ]
7
+ "types": ["vite/client", "@vc-shell/framework/globals"]
11
8
  },
12
- "include": [
13
- "./src/**/*.ts",
14
- "./src/**/*.vue",
15
- "./src/**/*.json"
16
- ]
9
+ "include": ["./src/**/*.ts", "./src/**/*.vue", "./src/**/*.json"]
17
10
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vc-shell/create-vc-app",
3
3
  "description": "Application scaffolding",
4
- "version": "2.4.0-pr300.83479a4",
4
+ "version": "2.4.0-pr302.99e48e1",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",
7
7
  "files": [
@@ -16,7 +16,7 @@
16
16
  "devDependencies": {
17
17
  "@types/ejs": "^3.1.5",
18
18
  "@types/prompts": "^2.4.4",
19
- "@vc-shell/ts-config": "2.4.0-pr300.83479a4",
19
+ "@vc-shell/ts-config": "2.4.0-pr302.99e48e1",
20
20
  "copyfiles": "^2.4.1",
21
21
  "cross-env": "^7.0.3",
22
22
  "shx": "^0.3.4",
@@ -27,6 +27,7 @@
27
27
  "magicast": "^0.3.5",
28
28
  "mri": "^1.2.0",
29
29
  "picocolors": "^1.1.1",
30
+ "prettier": "^3.6.2",
30
31
  "prompts": "^2.4.2",
31
32
  "tslib": "^2.5.3",
32
33
  "vite": "^6.3.3",