@vc-shell/create-vc-app 2.4.0-pr302.e9fab59 → 2.4.0-pr303.f20ea90
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/commands/add-module.d.ts.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/index.js +153 -176
- package/dist/templates/dynamic-module/tsconfig.json +5 -1
- package/dist/templates/module/pages/list.vue.ejs +4 -24
- package/dist/templates/sample-module/composables/useList/index.ts +1 -1
- package/dist/templates/sample-module/pages/index.ts +1 -1
- package/dist/templates/sample-module/pages/list.vue +1 -9
- package/dist/templates/sample-module/sample-data/index.ts +2 -2
- package/dist/templates/standalone/_github/COMMIT_CONVENTION.md +12 -12
- package/dist/templates/standalone/_github/PULL_REQUEST_TEMPLATE.md +0 -3
- package/dist/templates/standalone/_vscode/extensions.json +3 -1
- package/dist/templates/standalone/_vscode/settings.json +8 -3
- package/dist/templates/standalone/eslint.config.mjs +0 -20
- package/dist/templates/standalone/src/api_client/README.md +37 -38
- package/dist/templates/standalone/src/components/dashboard-widgets/Welcome.vue +2 -1
- package/dist/templates/standalone/src/pages/Dashboard.vue.ejs +1 -1
- package/dist/templates/standalone/src/router/routes.ts.ejs +15 -12
- package/dist/templates/standalone/tsconfig.json +9 -2
- package/package.json +2 -3
- package/dist/engine/format.d.ts +0 -13
- package/dist/engine/format.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-module.d.ts","sourceRoot":"","sources":["../../src/commands/add-module.ts"],"names":[],"mappings":"
|
|
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 +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;
|
|
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"}
|
package/dist/index.js
CHANGED
|
@@ -1,54 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import z from "mri";
|
|
3
|
+
import n from "picocolors";
|
|
4
4
|
import c from "node:path";
|
|
5
|
-
import { exit as
|
|
6
|
-
import { fileURLToPath as
|
|
7
|
-
import
|
|
5
|
+
import { exit as L, argv as B } from "node:process";
|
|
6
|
+
import { fileURLToPath as F } from "node:url";
|
|
7
|
+
import A from "prompts";
|
|
8
8
|
import r from "node:fs";
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
version: Z
|
|
9
|
+
import E from "ejs";
|
|
10
|
+
const O = "2.4.0-pr303.f20ea90", V = {
|
|
11
|
+
version: O
|
|
13
12
|
};
|
|
14
13
|
function h(e) {
|
|
15
14
|
return e.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
16
15
|
}
|
|
17
16
|
function x(e) {
|
|
18
|
-
return e.replace(/[-_\s]+(.)?/g, (
|
|
17
|
+
return e.replace(/[-_\s]+(.)?/g, (a, t) => t ? t.toUpperCase() : "").replace(/^(.)/, (a, t) => t.toUpperCase());
|
|
19
18
|
}
|
|
20
|
-
function
|
|
21
|
-
const
|
|
22
|
-
return
|
|
19
|
+
function Z(e) {
|
|
20
|
+
const a = x(e);
|
|
21
|
+
return a.charAt(0).toLowerCase() + a.slice(1);
|
|
23
22
|
}
|
|
24
|
-
function
|
|
23
|
+
function D(e) {
|
|
25
24
|
return e.replace(/[-\s]+/g, "_").replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase();
|
|
26
25
|
}
|
|
27
|
-
function
|
|
28
|
-
return e.replace(/[-_]+/g, " ").replace(/\b\w/g, (
|
|
26
|
+
function S(e) {
|
|
27
|
+
return e.replace(/[-_]+/g, " ").replace(/\b\w/g, (a) => a.toUpperCase());
|
|
29
28
|
}
|
|
30
29
|
function k(e) {
|
|
31
30
|
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(e);
|
|
32
31
|
}
|
|
33
|
-
function
|
|
32
|
+
function C(e) {
|
|
34
33
|
return e.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9-~]+/g, "-");
|
|
35
34
|
}
|
|
36
|
-
function
|
|
35
|
+
function _(e) {
|
|
37
36
|
return e.trim().toLowerCase().replace(/\/+/g, "/").replace(/[^a-z0-9/-]+/g, "/").replace(/\/?$/, "/");
|
|
38
37
|
}
|
|
39
|
-
function
|
|
40
|
-
const
|
|
38
|
+
function R(e) {
|
|
39
|
+
const a = e.moduleName || "", t = a ? h(a) : "", s = {
|
|
41
40
|
hasModule: !!e.moduleName,
|
|
42
41
|
ModuleName: t,
|
|
43
|
-
ModuleNamePascalCase:
|
|
44
|
-
ModuleNameCamelCase:
|
|
42
|
+
ModuleNamePascalCase: a ? x(a) : "",
|
|
43
|
+
ModuleNameCamelCase: a ? Z(a) : "",
|
|
45
44
|
ModuleNameUppercase: t.toUpperCase(),
|
|
46
|
-
ModuleNameScreamingSnake:
|
|
47
|
-
ModuleNameSentenceCase:
|
|
45
|
+
ModuleNameScreamingSnake: a ? D(a) : "",
|
|
46
|
+
ModuleNameSentenceCase: a ? S(a) : ""
|
|
48
47
|
};
|
|
49
|
-
return e.projectName && (s.AppName = h(e.projectName), s.AppNameSentenceCase =
|
|
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;
|
|
50
49
|
}
|
|
51
|
-
const
|
|
50
|
+
const J = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".pdf", ".zip"]), K = {
|
|
52
51
|
_gitignore: ".gitignore",
|
|
53
52
|
"_yarnrc.yml": ".yarnrc.yml",
|
|
54
53
|
_browserslistrc: ".browserslistrc",
|
|
@@ -63,126 +62,104 @@ const q = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ic
|
|
|
63
62
|
_yarn: ".yarn",
|
|
64
63
|
"_package.json": "package.json"
|
|
65
64
|
};
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
const s = c.dirname(
|
|
65
|
+
function Y(e, a, t) {
|
|
66
|
+
a.endsWith(".ejs") && (a = a.slice(0, -4));
|
|
67
|
+
const s = c.dirname(a);
|
|
69
68
|
r.existsSync(s) || r.mkdirSync(s, { recursive: !0 });
|
|
70
69
|
const o = c.extname(e.replace(/\.ejs$/, "")).toLowerCase();
|
|
71
|
-
if (
|
|
72
|
-
r.copyFileSync(e,
|
|
70
|
+
if (J.has(o))
|
|
71
|
+
r.copyFileSync(e, a);
|
|
73
72
|
else {
|
|
74
|
-
const d = r.readFileSync(e, "utf-8"), p =
|
|
75
|
-
r.writeFileSync(
|
|
73
|
+
const d = r.readFileSync(e, "utf-8"), p = E.render(d, t, { filename: e });
|
|
74
|
+
r.writeFileSync(a, p);
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
|
-
function
|
|
77
|
+
function j(e, a, t) {
|
|
79
78
|
if (!r.existsSync(e)) return;
|
|
80
79
|
const s = r.readdirSync(e);
|
|
81
80
|
for (const o of s) {
|
|
82
81
|
const d = c.join(e, o), p = o.endsWith(".ejs") ? o.slice(0, -4) : o;
|
|
83
|
-
let m =
|
|
82
|
+
let m = K[p] ?? p;
|
|
84
83
|
try {
|
|
85
|
-
m =
|
|
84
|
+
m = E.render(m, t);
|
|
86
85
|
} catch {
|
|
87
86
|
}
|
|
88
|
-
const
|
|
89
|
-
r.statSync(d).isDirectory() ? (r.existsSync(
|
|
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);
|
|
90
89
|
}
|
|
91
90
|
}
|
|
92
|
-
function
|
|
91
|
+
function q(e) {
|
|
93
92
|
if (r.existsSync(e))
|
|
94
|
-
for (const
|
|
95
|
-
if (
|
|
96
|
-
const t = c.join(e,
|
|
93
|
+
for (const a of r.readdirSync(e)) {
|
|
94
|
+
if (a === ".git") continue;
|
|
95
|
+
const t = c.join(e, a);
|
|
97
96
|
r.statSync(t).isDirectory() ? r.rmSync(t, { recursive: !0, force: !0 }) : r.unlinkSync(t);
|
|
98
97
|
}
|
|
99
98
|
}
|
|
100
|
-
function
|
|
99
|
+
function I(e) {
|
|
101
100
|
if (!r.existsSync(e)) return !0;
|
|
102
|
-
const
|
|
103
|
-
return
|
|
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;
|
|
101
|
+
const a = r.readdirSync(e);
|
|
102
|
+
return a.length === 0 || a.length === 1 && a[0] === ".git";
|
|
113
103
|
}
|
|
114
|
-
|
|
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 = {
|
|
104
|
+
const W = {
|
|
128
105
|
standalone: "Standalone App",
|
|
129
106
|
"dynamic-module": "Dynamic Module"
|
|
130
107
|
};
|
|
131
|
-
function
|
|
132
|
-
const
|
|
108
|
+
function H(e) {
|
|
109
|
+
const a = W[e.projectType] ?? e.projectType, t = !!e.moduleName;
|
|
133
110
|
console.log(`
|
|
134
|
-
${
|
|
135
|
-
${
|
|
136
|
-
${
|
|
137
|
-
${
|
|
138
|
-
${
|
|
139
|
-
${
|
|
140
|
-
${t && e.moduleName ? ` ${
|
|
141
|
-
` : ""} ${
|
|
142
|
-
${
|
|
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("╰─────────────────────────────────────────╯")}
|
|
143
120
|
|
|
144
|
-
${
|
|
121
|
+
${n.bold("Next steps:")}
|
|
145
122
|
|
|
146
123
|
1. cd ${e.projectName}
|
|
147
124
|
2. yarn install
|
|
148
125
|
3. yarn serve
|
|
149
126
|
${t && e.moduleName ? `
|
|
150
127
|
Module is ready at:
|
|
151
|
-
src/modules/${
|
|
128
|
+
src/modules/${X(e.moduleName)}/
|
|
152
129
|
` : ""}
|
|
153
|
-
${
|
|
130
|
+
${n.dim("Docs: https://docs.virtocommerce.org/platform/developer-guide/latest/custom-apps-development/vc-shell/vc-shell-overview/")}
|
|
154
131
|
`);
|
|
155
132
|
}
|
|
156
|
-
function
|
|
133
|
+
function X(e) {
|
|
157
134
|
return e.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
158
135
|
}
|
|
159
|
-
const
|
|
136
|
+
const P = [
|
|
160
137
|
{ title: "Standalone App — full application with bundled modules", value: "standalone" },
|
|
161
138
|
{ title: "Dynamic Module — remote module loaded by host via Module Federation", value: "dynamic-module" }
|
|
162
139
|
];
|
|
163
|
-
function
|
|
164
|
-
return typeof e == "string" &&
|
|
140
|
+
function G(e) {
|
|
141
|
+
return typeof e == "string" && P.some((a) => a.value === e);
|
|
165
142
|
}
|
|
166
|
-
async function
|
|
143
|
+
async function Q(e, a) {
|
|
167
144
|
const t = process.cwd();
|
|
168
145
|
let o = e._?.[0] || e.name || e["app-name"];
|
|
169
146
|
const d = o || "vc-app", p = () => o === "." ? c.basename(c.resolve()) : o, m = !!(o && e.type);
|
|
170
|
-
let
|
|
147
|
+
let l;
|
|
171
148
|
if (m) {
|
|
172
149
|
o = o || d;
|
|
173
150
|
const f = c.resolve(t, o);
|
|
174
|
-
if (!
|
|
175
|
-
const
|
|
176
|
-
console.error(
|
|
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);
|
|
177
154
|
}
|
|
178
|
-
r.existsSync(f) && !
|
|
179
|
-
const u = p(), y = e.type, g = e["module-name"],
|
|
180
|
-
|
|
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 = {
|
|
181
158
|
projectName: h(u),
|
|
182
|
-
packageName: e["package-name"] || (k(u) ? u :
|
|
159
|
+
packageName: e["package-name"] || (k(u) ? u : C(u)),
|
|
183
160
|
projectType: y,
|
|
184
|
-
moduleName:
|
|
185
|
-
basePath: e["base-path"] ||
|
|
161
|
+
moduleName: N,
|
|
162
|
+
basePath: e["base-path"] || _(`/apps/${h(u)}/`),
|
|
186
163
|
tenantRoutes: e["tenant-routes"] || !1,
|
|
187
164
|
aiAgent: e["ai-agent"] || !1,
|
|
188
165
|
dashboard: e.dashboard || !1,
|
|
@@ -190,15 +167,15 @@ async function ae(e, n) {
|
|
|
190
167
|
};
|
|
191
168
|
} else {
|
|
192
169
|
const f = () => {
|
|
193
|
-
throw new Error(
|
|
170
|
+
throw new Error(n.red("✖") + " Creation cancelled");
|
|
194
171
|
};
|
|
195
172
|
try {
|
|
196
|
-
const u = await
|
|
173
|
+
const u = await A(
|
|
197
174
|
[
|
|
198
175
|
{
|
|
199
176
|
name: "projectName",
|
|
200
177
|
type: o ? null : "text",
|
|
201
|
-
message:
|
|
178
|
+
message: n.reset("Project name:"),
|
|
202
179
|
initial: d,
|
|
203
180
|
onState: (w) => {
|
|
204
181
|
o = h(String(w.value).trim()) || d;
|
|
@@ -206,14 +183,14 @@ async function ae(e, n) {
|
|
|
206
183
|
format: (w) => h(String(w).trim())
|
|
207
184
|
},
|
|
208
185
|
{
|
|
209
|
-
type: () => !r.existsSync(c.resolve(t, o)) ||
|
|
186
|
+
type: () => !r.existsSync(c.resolve(t, o)) || I(c.resolve(t, o)) ? null : "confirm",
|
|
210
187
|
name: "overwrite",
|
|
211
188
|
message: () => (o === "." ? "Current directory" : `Target directory "${o}"`) + " is not empty. Remove existing files and continue?"
|
|
212
189
|
},
|
|
213
190
|
{
|
|
214
191
|
type: (w, { overwrite: M }) => {
|
|
215
192
|
if (M === !1)
|
|
216
|
-
throw new Error(
|
|
193
|
+
throw new Error(n.red("✖") + " Operation cancelled");
|
|
217
194
|
return null;
|
|
218
195
|
},
|
|
219
196
|
name: "overwriteChecker"
|
|
@@ -221,19 +198,19 @@ async function ae(e, n) {
|
|
|
221
198
|
{
|
|
222
199
|
name: "packageName",
|
|
223
200
|
type: () => k(p()) ? null : "text",
|
|
224
|
-
message:
|
|
225
|
-
initial: () =>
|
|
201
|
+
message: n.reset("Package name:"),
|
|
202
|
+
initial: () => C(p()),
|
|
226
203
|
validate: (w) => k(w) || "Invalid package.json name"
|
|
227
204
|
},
|
|
228
205
|
{
|
|
229
206
|
type: "select",
|
|
230
207
|
name: "projectType",
|
|
231
|
-
message:
|
|
232
|
-
choices:
|
|
208
|
+
message: n.reset("Project type:"),
|
|
209
|
+
choices: P
|
|
233
210
|
}
|
|
234
211
|
],
|
|
235
212
|
{ onCancel: f }
|
|
236
|
-
), y = o ? h(o) : u.projectName, g = u.projectType || "standalone",
|
|
213
|
+
), y = o ? h(o) : u.projectName, g = u.projectType || "standalone", N = S(y), b = "/apps/" + h(y) + "/", $ = await A(
|
|
237
214
|
[
|
|
238
215
|
{
|
|
239
216
|
name: "includeModule",
|
|
@@ -244,16 +221,16 @@ async function ae(e, n) {
|
|
|
244
221
|
{
|
|
245
222
|
name: "moduleName",
|
|
246
223
|
type: (w, M) => g === "standalone" && !M.includeModule ? null : "text",
|
|
247
|
-
message:
|
|
248
|
-
initial:
|
|
224
|
+
message: n.reset("Module name:"),
|
|
225
|
+
initial: N,
|
|
249
226
|
format: (w) => String(w).trim()
|
|
250
227
|
},
|
|
251
228
|
{
|
|
252
229
|
name: "basePath",
|
|
253
230
|
type: g === "dynamic-module" ? null : "text",
|
|
254
|
-
message:
|
|
255
|
-
initial:
|
|
256
|
-
format: (w) =>
|
|
231
|
+
message: n.reset("Base path:"),
|
|
232
|
+
initial: b,
|
|
233
|
+
format: (w) => _(String(w).trim())
|
|
257
234
|
},
|
|
258
235
|
{
|
|
259
236
|
type: g === "dynamic-module" ? null : "confirm",
|
|
@@ -282,33 +259,33 @@ async function ae(e, n) {
|
|
|
282
259
|
],
|
|
283
260
|
{ onCancel: f }
|
|
284
261
|
);
|
|
285
|
-
|
|
262
|
+
l = {
|
|
286
263
|
projectName: y,
|
|
287
|
-
packageName: u.packageName || (k(y) ? y :
|
|
264
|
+
packageName: u.packageName || (k(y) ? y : C(y)),
|
|
288
265
|
projectType: g,
|
|
289
|
-
moduleName:
|
|
290
|
-
basePath:
|
|
291
|
-
tenantRoutes:
|
|
292
|
-
aiAgent:
|
|
293
|
-
dashboard:
|
|
294
|
-
mocks:
|
|
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
|
|
295
272
|
};
|
|
296
273
|
} catch (u) {
|
|
297
274
|
console.log(u.message), process.exit(1);
|
|
298
275
|
}
|
|
299
276
|
}
|
|
300
|
-
const
|
|
301
|
-
r.existsSync(
|
|
302
|
-
Scaffolding ${
|
|
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)}...
|
|
303
280
|
`);
|
|
304
|
-
const v =
|
|
305
|
-
if (
|
|
306
|
-
const f = h(
|
|
307
|
-
|
|
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);
|
|
308
285
|
}
|
|
309
|
-
|
|
286
|
+
l.mocks && j(c.join(a, "sample-module"), c.join(i, "src/modules/sample"), v), H(l);
|
|
310
287
|
}
|
|
311
|
-
function
|
|
288
|
+
function U(e, a) {
|
|
312
289
|
const t = /^import\s.+$/gm;
|
|
313
290
|
let s = null, o;
|
|
314
291
|
for (; (o = t.exec(e)) !== null; )
|
|
@@ -316,42 +293,42 @@ function L(e, n) {
|
|
|
316
293
|
if (s) {
|
|
317
294
|
const d = s.index + s[0].length;
|
|
318
295
|
return e.slice(0, d) + `
|
|
319
|
-
` +
|
|
296
|
+
` + a + e.slice(d);
|
|
320
297
|
}
|
|
321
|
-
return
|
|
298
|
+
return a + `
|
|
322
299
|
` + e;
|
|
323
300
|
}
|
|
324
|
-
function
|
|
301
|
+
function ee(e, a) {
|
|
325
302
|
let t = r.readFileSync(e, "utf-8");
|
|
326
|
-
const s = x(
|
|
327
|
-
t =
|
|
303
|
+
const s = x(a), o = h(a);
|
|
304
|
+
t = U(t, `import ${s} from "./modules/${o}";`);
|
|
328
305
|
const d = /\.use\([A-Z]\w+,\s*\{\s*router\s*\}\)/g;
|
|
329
306
|
let p = null, m;
|
|
330
307
|
for (; (m = d.exec(t)) !== null; )
|
|
331
308
|
p = m;
|
|
332
309
|
if (p) {
|
|
333
|
-
const
|
|
310
|
+
const l = p.index + p[0].length, i = `
|
|
334
311
|
.use(${s}, { router })`;
|
|
335
|
-
t = t.slice(0,
|
|
312
|
+
t = t.slice(0, l) + i + t.slice(l);
|
|
336
313
|
}
|
|
337
314
|
r.writeFileSync(e, t);
|
|
338
315
|
}
|
|
339
|
-
function
|
|
316
|
+
function te(e, a) {
|
|
340
317
|
let t = r.readFileSync(e, "utf-8");
|
|
341
|
-
const s = h(
|
|
318
|
+
const s = h(a), o = D(a);
|
|
342
319
|
if (!t.includes("addMenuItem")) {
|
|
343
320
|
const v = /import\s*\{([^}]+)\}\s*from\s*["']@vc-shell\/framework["']/.exec(t);
|
|
344
321
|
if (v) {
|
|
345
322
|
const f = v[1].trim() + ", addMenuItem";
|
|
346
323
|
t = t.replace(v[0], `import { ${f} } from "@vc-shell/framework"`);
|
|
347
324
|
} else
|
|
348
|
-
t =
|
|
325
|
+
t = U(t, 'import { addMenuItem } from "@vc-shell/framework";');
|
|
349
326
|
}
|
|
350
327
|
const d = /addMenuItem\(\{[\s\S]*?\}\);/g;
|
|
351
328
|
let p = null, m;
|
|
352
329
|
for (; (m = d.exec(t)) !== null; )
|
|
353
330
|
p = m;
|
|
354
|
-
const
|
|
331
|
+
const l = `
|
|
355
332
|
addMenuItem({
|
|
356
333
|
title: "${o}.MENU.TITLE",
|
|
357
334
|
icon: "lucide-box",
|
|
@@ -359,60 +336,60 @@ function re(e, n) {
|
|
|
359
336
|
url: "/${s}",
|
|
360
337
|
});`;
|
|
361
338
|
if (p) {
|
|
362
|
-
const
|
|
363
|
-
t = t.slice(0,
|
|
364
|
-
` +
|
|
339
|
+
const i = p.index + p[0].length;
|
|
340
|
+
t = t.slice(0, i) + `
|
|
341
|
+
` + l + t.slice(i);
|
|
365
342
|
} else {
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
` + t.slice(
|
|
343
|
+
const i = t.lastIndexOf("}");
|
|
344
|
+
i !== -1 && (t = t.slice(0, i) + l + `
|
|
345
|
+
` + t.slice(i));
|
|
369
346
|
}
|
|
370
347
|
r.writeFileSync(e, t);
|
|
371
348
|
}
|
|
372
|
-
async function
|
|
349
|
+
async function ae(e, a) {
|
|
373
350
|
const t = process.cwd(), s = e._?.[1], o = c.join(t, "package.json");
|
|
374
|
-
r.existsSync(o) || (console.error(
|
|
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));
|
|
375
352
|
const d = JSON.parse(r.readFileSync(o, "utf-8"));
|
|
376
|
-
({ ...d.dependencies, ...d.devDependencies })["@vc-shell/framework"] || (console.error(
|
|
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));
|
|
377
354
|
let m = s;
|
|
378
|
-
m || (m = (await
|
|
355
|
+
m || (m = (await A({
|
|
379
356
|
type: "text",
|
|
380
357
|
name: "moduleName",
|
|
381
358
|
message: "Module name:",
|
|
382
|
-
validate: (
|
|
383
|
-
})).moduleName), m || (console.error(
|
|
384
|
-
const
|
|
385
|
-
r.existsSync(v) || r.mkdirSync(v, { recursive: !0 }), r.existsSync(f) && (console.error(
|
|
386
|
-
const u =
|
|
387
|
-
|
|
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)}/`));
|
|
388
365
|
const y = c.join(t, "src/main.ts");
|
|
389
366
|
if (r.existsSync(y))
|
|
390
367
|
try {
|
|
391
|
-
|
|
368
|
+
ee(y, m), console.log(n.green(` ✔ Updated src/main.ts — added import & app.use(${i})`));
|
|
392
369
|
} catch {
|
|
393
|
-
console.warn(
|
|
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 });`));
|
|
394
371
|
}
|
|
395
372
|
const g = c.join(t, "src/bootstrap.ts");
|
|
396
373
|
if (r.existsSync(g))
|
|
397
374
|
try {
|
|
398
|
-
|
|
375
|
+
te(g, m), console.log(n.green(` ✔ Updated src/bootstrap.ts — added menu item "${S(m)}"`));
|
|
399
376
|
} catch {
|
|
400
|
-
console.warn(
|
|
377
|
+
console.warn(n.yellow(" ⚠ Could not auto-update src/bootstrap.ts. Add addMenuItem() manually."));
|
|
401
378
|
}
|
|
402
|
-
|
|
403
|
-
Module "${
|
|
379
|
+
console.log(`
|
|
380
|
+
Module "${l}" is ready! Run ${n.bold(n.green("yarn serve"))} to see it.
|
|
404
381
|
`);
|
|
405
382
|
}
|
|
406
|
-
const
|
|
407
|
-
function
|
|
383
|
+
const T = c.resolve(F(import.meta.url), "..", "templates");
|
|
384
|
+
function ne() {
|
|
408
385
|
console.log(`
|
|
409
|
-
${
|
|
386
|
+
${n.bold(n.green("create-vc-app"))} — Create VC Shell applications and modules
|
|
410
387
|
|
|
411
|
-
${
|
|
388
|
+
${n.bold("Usage:")}
|
|
412
389
|
create-vc-app [project-name] [options] Create a new project
|
|
413
390
|
create-vc-app add-module <module-name> Add a module to existing project
|
|
414
391
|
|
|
415
|
-
${
|
|
392
|
+
${n.bold("Options (create):")}
|
|
416
393
|
--type <type> Project type: standalone | dynamic-module
|
|
417
394
|
--name, --app-name <name> Application name
|
|
418
395
|
--package-name <name> npm package name
|
|
@@ -426,31 +403,31 @@ ${a.bold("Options (create):")}
|
|
|
426
403
|
--help, -h Show this help
|
|
427
404
|
--version, -v Show version
|
|
428
405
|
|
|
429
|
-
${
|
|
406
|
+
${n.bold("Examples:")}
|
|
430
407
|
create-vc-app my-app
|
|
431
408
|
create-vc-app my-app --type standalone --dashboard --mocks
|
|
432
409
|
create-vc-app my-module --type dynamic-module --module-name "Reviews"
|
|
433
410
|
create-vc-app add-module orders
|
|
434
411
|
|
|
435
|
-
${
|
|
412
|
+
${n.bold("Docs:")} https://docs.virtocommerce.org/platform/developer-guide/latest/custom-apps-development/vc-shell/vc-shell-overview/
|
|
436
413
|
`);
|
|
437
414
|
}
|
|
438
|
-
async function
|
|
439
|
-
const e = B
|
|
415
|
+
async function oe() {
|
|
416
|
+
const e = z(B.slice(2), {
|
|
440
417
|
alias: { h: "help", v: "version" },
|
|
441
418
|
boolean: ["help", "version", "mocks", "overwrite", "tenant-routes", "ai-agent", "dashboard"],
|
|
442
419
|
string: ["type", "name", "app-name", "package-name", "module-name", "base-path"]
|
|
443
420
|
});
|
|
444
421
|
if (e.help) {
|
|
445
|
-
|
|
422
|
+
ne();
|
|
446
423
|
return;
|
|
447
424
|
}
|
|
448
425
|
if (e.version) {
|
|
449
|
-
console.log(`create-vc-app v${
|
|
426
|
+
console.log(`create-vc-app v${V.version}`);
|
|
450
427
|
return;
|
|
451
428
|
}
|
|
452
|
-
e._[0] === "add-module" ? await
|
|
429
|
+
e._[0] === "add-module" ? await ae(e, T) : await Q(e, T);
|
|
453
430
|
}
|
|
454
|
-
|
|
455
|
-
console.error(
|
|
431
|
+
oe().catch((e) => {
|
|
432
|
+
console.error(n.red(e.message || String(e))), L(1);
|
|
456
433
|
});
|
|
@@ -18,30 +18,14 @@
|
|
|
18
18
|
@pagination-click="pagination.goToPage"
|
|
19
19
|
>
|
|
20
20
|
<!-- Add your columns here -->
|
|
21
|
-
<VcColumn
|
|
22
|
-
|
|
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
|
-
/>
|
|
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 />
|
|
32
23
|
</VcDataTable>
|
|
33
24
|
</VcBlade>
|
|
34
25
|
</template>
|
|
35
26
|
|
|
36
27
|
<script setup lang="ts">
|
|
37
|
-
import {
|
|
38
|
-
useBlade,
|
|
39
|
-
useDataTableSort,
|
|
40
|
-
useTableSearch,
|
|
41
|
-
useDataTablePagination,
|
|
42
|
-
useFunctions,
|
|
43
|
-
type IBladeToolbar,
|
|
44
|
-
} from "@vc-shell/framework";
|
|
28
|
+
import { useBlade, useDataTableSort, useTableSearch, useDataTablePagination, useFunctions, type IBladeToolbar } from "@vc-shell/framework";
|
|
45
29
|
import { VcBlade, VcDataTable, VcColumn } from "@vc-shell/framework/ui";
|
|
46
30
|
import { ref, watch } from "vue";
|
|
47
31
|
import use<%- ModuleNamePascalCase %>List from "../composables/useList";
|
|
@@ -73,11 +57,7 @@ const { sortField, sortOrder, sortExpression } = useDataTableSort({
|
|
|
73
57
|
const { data, loading, totalCount, getItems } = use<%- ModuleNamePascalCase %>List();
|
|
74
58
|
|
|
75
59
|
const { searchValue } = useTableSearch({ stateKey: "<%- ModuleNameScreamingSnake %>" });
|
|
76
|
-
const pagination = useDataTablePagination({
|
|
77
|
-
stateKey: "<%- ModuleNameScreamingSnake %>",
|
|
78
|
-
pageSize: PAGE_SIZE,
|
|
79
|
-
totalCount,
|
|
80
|
-
});
|
|
60
|
+
const pagination = useDataTablePagination({ stateKey: "<%- ModuleNameScreamingSnake %>", pageSize: PAGE_SIZE, totalCount });
|
|
81
61
|
|
|
82
62
|
function load() {
|
|
83
63
|
return getItems({
|
|
@@ -25,7 +25,7 @@ interface SearchResult {
|
|
|
25
25
|
|
|
26
26
|
export type { MockedItem };
|
|
27
27
|
|
|
28
|
-
export default (options?: { pageSize?: number
|
|
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 {
|
|
2
|
+
export {default as Details } from './details.vue'
|
|
@@ -75,15 +75,7 @@
|
|
|
75
75
|
|
|
76
76
|
<script lang="ts" setup>
|
|
77
77
|
import { ref, watch, computed } from "vue";
|
|
78
|
-
import {
|
|
79
|
-
IBladeToolbar,
|
|
80
|
-
useBlade,
|
|
81
|
-
usePopup,
|
|
82
|
-
useDataTableSort,
|
|
83
|
-
useTableSearch,
|
|
84
|
-
useDataTablePagination,
|
|
85
|
-
useFunctions,
|
|
86
|
-
} from "@vc-shell/framework";
|
|
78
|
+
import { IBladeToolbar, useBlade, usePopup, useDataTableSort, useTableSearch, useDataTablePagination, useFunctions } from "@vc-shell/framework";
|
|
87
79
|
import type { TableAction } from "@vc-shell/framework";
|
|
88
80
|
import { VcColumn, VcDataTable, VcBlade } from "@vc-shell/framework/ui";
|
|
89
81
|
import { useI18n } from "vue-i18n";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
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**.
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
"source.fixAll.eslint": true
|
|
4
4
|
},
|
|
5
5
|
"files.eol": "\r\n",
|
|
6
|
-
"eslint.validate": [
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
"eslint.validate": [
|
|
7
|
+
"vue",
|
|
8
|
+
"javascript"
|
|
9
|
+
],
|
|
10
|
+
"i18n-ally.localesPaths": [
|
|
11
|
+
"src/locales",
|
|
12
|
+
],
|
|
13
|
+
"typescript.preferences.importModuleSpecifier": "relative",
|
|
9
14
|
}
|
|
@@ -1,17 +1,12 @@
|
|
|
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";
|
|
5
4
|
|
|
6
5
|
export default [
|
|
7
6
|
{
|
|
8
7
|
ignores: ["**/node_modules/**", "**/dist/**", "api-client.ts"],
|
|
9
8
|
},
|
|
10
9
|
|
|
11
|
-
importPlugin.flatConfigs.recommended,
|
|
12
|
-
|
|
13
|
-
importPlugin.flatConfigs.typescript,
|
|
14
|
-
|
|
15
10
|
...pluginVue.configs["flat/recommended"],
|
|
16
11
|
|
|
17
12
|
...vueTsEslintConfig(),
|
|
@@ -19,14 +14,6 @@ export default [
|
|
|
19
14
|
vuePrettierConfig,
|
|
20
15
|
|
|
21
16
|
{
|
|
22
|
-
settings: {
|
|
23
|
-
"import/resolver": {
|
|
24
|
-
typescript: {
|
|
25
|
-
alwaysTryTypes: true,
|
|
26
|
-
project: "./tsconfig.json",
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
17
|
rules: {
|
|
31
18
|
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
|
32
19
|
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
|
@@ -39,13 +26,6 @@ export default [
|
|
|
39
26
|
"vue/require-default-prop": "off",
|
|
40
27
|
"vue/no-v-html": "off",
|
|
41
28
|
"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",
|
|
49
29
|
},
|
|
50
30
|
},
|
|
51
31
|
];
|
|
@@ -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
|
-
|
|
12
|
+
* .NET Core 6.0, particularly if you are using MacOS or Linux.
|
|
13
13
|
|
|
14
14
|
## Generate TypeScript API clients
|
|
15
15
|
|
|
@@ -22,7 +22,6 @@ Using command
|
|
|
22
22
|
```bash
|
|
23
23
|
yarn add @vc-shell/api-client-generator cross-env
|
|
24
24
|
```
|
|
25
|
-
|
|
26
25
|
<br>
|
|
27
26
|
|
|
28
27
|
`cross-env` runs scripts that set and use environment variables across platforms.
|
|
@@ -45,44 +44,44 @@ Add the dependencies to your project's **package.json**:
|
|
|
45
44
|
|
|
46
45
|
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:
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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` |
|
|
71
70
|
|
|
72
71
|
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:
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
```title="vc-app-extend/.env"
|
|
74
|
+
APP_PLATFORM_URL=https://vcmp-dev.govirto.com/
|
|
75
|
+
```
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
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.
|
|
80
79
|
|
|
81
80
|
4. Generate the API clients using the following command:
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
```
|
|
83
|
+
yarn generate-api-client
|
|
84
|
+
```
|
|
86
85
|
|
|
87
86
|
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.
|
|
88
87
|
|
|
@@ -113,7 +112,7 @@ API client now includes metadata to track the generation:
|
|
|
113
112
|
|
|
114
113
|
The generator handles multiple API clients effectively:
|
|
115
114
|
|
|
116
|
-
- Creates standardized exports with both short names (`./{moduleName}`) and full names (`./virtocommerce.{moduleName}`)
|
|
115
|
+
- Creates standardized exports with both short names (`./{moduleName}`) and full names (`./virtocommerce.{moduleName}`)
|
|
117
116
|
- Prevents duplicate module exports by intelligently merging with existing ones
|
|
118
117
|
- Automatically removes `module` and `types` fields that conflict with multiple exports
|
|
119
118
|
- Works properly with incremental generation (can add new APIs without breaking existing ones)
|
|
@@ -130,11 +129,11 @@ This enables both simple usage for single-API packages and proper subpath export
|
|
|
130
129
|
|
|
131
130
|
```js
|
|
132
131
|
// Single API package (using root export)
|
|
133
|
-
import { MyClient } from
|
|
132
|
+
import { MyClient } from '@myapp/api';
|
|
134
133
|
|
|
135
134
|
// Multi-API package (using subpath exports)
|
|
136
|
-
import { ClientA } from
|
|
137
|
-
import { ClientB } from
|
|
135
|
+
import { ClientA } from '@myapp/api/moduleA';
|
|
136
|
+
import { ClientB } from '@myapp/api/moduleB';
|
|
138
137
|
```
|
|
139
138
|
|
|
140
139
|
### Directory Creation
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
</template>
|
|
15
15
|
|
|
16
16
|
<script setup lang="ts">
|
|
17
|
+
// eslint-disable-next-line import/no-unresolved
|
|
17
18
|
import Welcome from "/assets/welcome.png";
|
|
18
19
|
</script>
|
|
19
20
|
|
|
@@ -39,7 +40,7 @@ import Welcome from "/assets/welcome.png";
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
&__welcome-description {
|
|
42
|
-
@apply tw-whitespace-break-spaces tw-text-
|
|
43
|
+
@apply tw-whitespace-break-spaces tw-text-s tw-max-w-[90%] tw-mx-auto tw-leading-5 tw-font-semibold;
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
</style>
|
|
@@ -1,40 +1,43 @@
|
|
|
1
1
|
import { RouteRecordRaw } from "vue-router";
|
|
2
2
|
import App from "../pages/App.vue";
|
|
3
|
-
<%
|
|
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
|
|
7
8
|
import whiteLogoImage from "/assets/logo-white.svg";
|
|
8
|
-
|
|
9
|
+
// eslint-disable-next-line import/no-unresolved
|
|
10
|
+
import bgImage from "/assets/background.jpg";
|
|
9
11
|
|
|
12
|
+
<% if (tenantRoutes) { %>
|
|
10
13
|
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}";
|
|
11
|
-
<%
|
|
14
|
+
<% } %>
|
|
12
15
|
|
|
13
16
|
export const routes: RouteRecordRaw[] = [
|
|
14
17
|
{
|
|
15
|
-
<%
|
|
18
|
+
<% if (tenantRoutes) { %>
|
|
16
19
|
path: `/:tenantId(${tenantIdRegex})?`,
|
|
17
|
-
<%
|
|
20
|
+
<% } else { %>
|
|
18
21
|
path: "/",
|
|
19
|
-
<%
|
|
22
|
+
<% } %>
|
|
20
23
|
component: App,
|
|
21
24
|
name: "App",
|
|
22
25
|
meta: {
|
|
23
26
|
root: true,
|
|
24
27
|
},
|
|
25
28
|
children: [
|
|
26
|
-
<%
|
|
29
|
+
<% if (dashboard) { %>
|
|
27
30
|
{
|
|
28
31
|
name: "Dashboard",
|
|
29
32
|
path: "",
|
|
30
|
-
<%
|
|
33
|
+
<% if (tenantRoutes) { %>
|
|
31
34
|
alias: `/:tenantId(${tenantIdRegex})?`,
|
|
32
|
-
<%
|
|
35
|
+
<% } else { %>
|
|
33
36
|
alias: "/",
|
|
34
|
-
<%
|
|
37
|
+
<% } %>
|
|
35
38
|
component: Dashboard,
|
|
36
39
|
},
|
|
37
|
-
<%
|
|
40
|
+
<% } %>
|
|
38
41
|
],
|
|
39
42
|
},
|
|
40
43
|
{
|
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
"baseUrl": ".",
|
|
5
5
|
"outDir": "dist",
|
|
6
6
|
"rootDir": "src",
|
|
7
|
-
"types": [
|
|
7
|
+
"types": [
|
|
8
|
+
"vite/client",
|
|
9
|
+
"@vc-shell/framework/globals"
|
|
10
|
+
]
|
|
8
11
|
},
|
|
9
|
-
"include": [
|
|
12
|
+
"include": [
|
|
13
|
+
"./src/**/*.ts",
|
|
14
|
+
"./src/**/*.vue",
|
|
15
|
+
"./src/**/*.json"
|
|
16
|
+
]
|
|
10
17
|
}
|
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-
|
|
4
|
+
"version": "2.4.0-pr303.f20ea90",
|
|
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-
|
|
19
|
+
"@vc-shell/ts-config": "2.4.0-pr303.f20ea90",
|
|
20
20
|
"copyfiles": "^2.4.1",
|
|
21
21
|
"cross-env": "^7.0.3",
|
|
22
22
|
"shx": "^0.3.4",
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"magicast": "^0.3.5",
|
|
28
28
|
"mri": "^1.2.0",
|
|
29
29
|
"picocolors": "^1.1.1",
|
|
30
|
-
"prettier": "^3.6.2",
|
|
31
30
|
"prompts": "^2.4.2",
|
|
32
31
|
"tslib": "^2.5.3",
|
|
33
32
|
"vite": "^6.3.3",
|
package/dist/engine/format.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|