@vc-shell/create-vc-app 2.4.0-pr302.99e48e1 → 2.4.0-pr302.b052b38
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/engine/codegen.d.ts +5 -2
- package/dist/engine/codegen.d.ts.map +1 -1
- package/dist/engine/codegen.test.d.ts +2 -0
- package/dist/engine/codegen.test.d.ts.map +1 -0
- package/dist/index.js +327 -253
- package/dist/templates/module/composables/useDetails.ts.ejs +1 -0
- package/dist/templates/module/composables/useList.ts.ejs +2 -1
- package/dist/templates/standalone/src/bootstrap.ts.ejs +1 -2
- package/dist/templates/standalone/src/pages/App.vue.ejs +1 -0
- package/package.json +2 -3
package/dist/engine/codegen.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Add a module import and app.use()
|
|
2
|
+
* Add a module import and its `app.use()` registration to main.ts.
|
|
3
|
+
*
|
|
4
|
+
* Throws when either anchor is missing, so the caller can tell the user what to
|
|
5
|
+
* add by hand rather than reporting a change it did not make.
|
|
3
6
|
*/
|
|
4
7
|
export declare function addModuleToMain(mainTsPath: string, moduleName: string): void;
|
|
5
8
|
/**
|
|
6
|
-
* Add a menu item registration to bootstrap.ts
|
|
9
|
+
* Add a menu item registration to bootstrap.ts, after the last existing one.
|
|
7
10
|
*/
|
|
8
11
|
export declare function addMenuItemToBootstrap(bootstrapPath: string, moduleName: string): void;
|
|
9
12
|
//# sourceMappingURL=codegen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/engine/codegen.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/engine/codegen.ts"],"names":[],"mappings":"AA6IA;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CA2B5E;AAiCD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAsCtF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.test.d.ts","sourceRoot":"","sources":["../../src/engine/codegen.test.ts"],"names":[],"mappings":""}
|
package/dist/index.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { exit as
|
|
6
|
-
import { fileURLToPath as
|
|
2
|
+
import K from "mri";
|
|
3
|
+
import r from "picocolors";
|
|
4
|
+
import m from "node:path";
|
|
5
|
+
import { exit as J, argv as Y } from "node:process";
|
|
6
|
+
import { fileURLToPath as Z } from "node:url";
|
|
7
7
|
import P from "prompts";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
const
|
|
12
|
-
version:
|
|
8
|
+
import i from "node:fs";
|
|
9
|
+
import F from "ejs";
|
|
10
|
+
import I from "prettier";
|
|
11
|
+
const q = "2.4.0-pr302.b052b38", W = {
|
|
12
|
+
version: q
|
|
13
13
|
};
|
|
14
|
-
function
|
|
14
|
+
function v(e) {
|
|
15
15
|
return e.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
16
16
|
}
|
|
17
|
-
function
|
|
18
|
-
return e.replace(/[-_\s]+(.)?/g, (
|
|
17
|
+
function M(e) {
|
|
18
|
+
return e.replace(/[-_\s]+(.)?/g, (t, n) => n ? n.toUpperCase() : "").replace(/^(.)/, (t, n) => n.toUpperCase());
|
|
19
19
|
}
|
|
20
|
-
function
|
|
21
|
-
const
|
|
22
|
-
return
|
|
20
|
+
function G(e) {
|
|
21
|
+
const t = M(e);
|
|
22
|
+
return t.charAt(0).toLowerCase() + t.slice(1);
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function O(e) {
|
|
25
25
|
return e.replace(/[-\s]+/g, "_").replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase();
|
|
26
26
|
}
|
|
27
|
-
function
|
|
28
|
-
return e.replace(/[-_]+/g, " ").replace(/\b\w/g, (
|
|
27
|
+
function x(e) {
|
|
28
|
+
return e.replace(/[-_]+/g, " ").replace(/\b\w/g, (t) => t.toUpperCase());
|
|
29
29
|
}
|
|
30
|
-
function
|
|
30
|
+
function N(e) {
|
|
31
31
|
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(e);
|
|
32
32
|
}
|
|
33
|
-
function
|
|
33
|
+
function A(e) {
|
|
34
34
|
return e.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9-~]+/g, "-");
|
|
35
35
|
}
|
|
36
|
-
function
|
|
36
|
+
function E(e) {
|
|
37
37
|
return e.trim().toLowerCase().replace(/\/+/g, "/").replace(/[^a-z0-9/-]+/g, "/").replace(/\/?$/, "/");
|
|
38
38
|
}
|
|
39
|
-
function
|
|
40
|
-
const
|
|
39
|
+
function U(e) {
|
|
40
|
+
const t = e.moduleName || "", n = t ? v(t) : "", o = {
|
|
41
41
|
hasModule: !!e.moduleName,
|
|
42
|
-
ModuleName:
|
|
43
|
-
ModuleNamePascalCase:
|
|
44
|
-
ModuleNameCamelCase:
|
|
45
|
-
ModuleNameUppercase:
|
|
46
|
-
ModuleNameScreamingSnake:
|
|
47
|
-
ModuleNameSentenceCase:
|
|
42
|
+
ModuleName: n,
|
|
43
|
+
ModuleNamePascalCase: t ? M(t) : "",
|
|
44
|
+
ModuleNameCamelCase: t ? G(t) : "",
|
|
45
|
+
ModuleNameUppercase: n.toUpperCase(),
|
|
46
|
+
ModuleNameScreamingSnake: t ? O(t) : "",
|
|
47
|
+
ModuleNameSentenceCase: t ? x(t) : ""
|
|
48
48
|
};
|
|
49
|
-
return e.projectName && (
|
|
49
|
+
return e.projectName && (o.AppName = v(e.projectName), o.AppNameSentenceCase = x(e.projectName)), e.packageName !== void 0 && (o.PackageName = e.packageName || "", o.BasePath = e.basePath || "", o.tenantRoutes = e.tenantRoutes || !1, o.aiAgent = e.aiAgent || !1, o.dashboard = e.dashboard || !1, o.mocks = e.mocks || !1), o;
|
|
50
50
|
}
|
|
51
|
-
const
|
|
51
|
+
const H = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".pdf", ".zip"]), X = {
|
|
52
52
|
_gitignore: ".gitignore",
|
|
53
53
|
"_yarnrc.yml": ".yarnrc.yml",
|
|
54
54
|
_browserslistrc: ".browserslistrc",
|
|
@@ -63,177 +63,177 @@ const q = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ic
|
|
|
63
63
|
_yarn: ".yarn",
|
|
64
64
|
"_package.json": "package.json"
|
|
65
65
|
};
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
72
|
-
|
|
66
|
+
function Q(e, t, n) {
|
|
67
|
+
t.endsWith(".ejs") && (t = t.slice(0, -4));
|
|
68
|
+
const o = m.dirname(t);
|
|
69
|
+
i.existsSync(o) || i.mkdirSync(o, { recursive: !0 });
|
|
70
|
+
const a = m.extname(e.replace(/\.ejs$/, "")).toLowerCase();
|
|
71
|
+
if (H.has(a))
|
|
72
|
+
i.copyFileSync(e, t);
|
|
73
73
|
else {
|
|
74
|
-
const
|
|
75
|
-
|
|
74
|
+
const l = i.readFileSync(e, "utf-8"), s = F.render(l, n, { filename: e });
|
|
75
|
+
i.writeFileSync(t, s);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
function
|
|
79
|
-
if (!
|
|
80
|
-
const
|
|
81
|
-
for (const
|
|
82
|
-
const
|
|
83
|
-
let
|
|
78
|
+
function j(e, t, n) {
|
|
79
|
+
if (!i.existsSync(e)) return;
|
|
80
|
+
const o = i.readdirSync(e);
|
|
81
|
+
for (const a of o) {
|
|
82
|
+
const l = m.join(e, a), s = a.endsWith(".ejs") ? a.slice(0, -4) : a;
|
|
83
|
+
let c = X[s] ?? s;
|
|
84
84
|
try {
|
|
85
|
-
|
|
85
|
+
c = F.render(c, n);
|
|
86
86
|
} catch {
|
|
87
87
|
}
|
|
88
|
-
const
|
|
89
|
-
|
|
88
|
+
const d = m.join(t, c);
|
|
89
|
+
i.statSync(l).isDirectory() ? (i.existsSync(d) || i.mkdirSync(d, { recursive: !0 }), j(l, d, n)) : Q(l, d, n);
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
function
|
|
93
|
-
if (
|
|
94
|
-
for (const
|
|
95
|
-
if (
|
|
96
|
-
const
|
|
97
|
-
|
|
92
|
+
function ee(e) {
|
|
93
|
+
if (i.existsSync(e))
|
|
94
|
+
for (const t of i.readdirSync(e)) {
|
|
95
|
+
if (t === ".git") continue;
|
|
96
|
+
const n = m.join(e, t);
|
|
97
|
+
i.statSync(n).isDirectory() ? i.rmSync(n, { recursive: !0, force: !0 }) : i.unlinkSync(n);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
function
|
|
101
|
-
if (!
|
|
102
|
-
const
|
|
103
|
-
return
|
|
100
|
+
function T(e) {
|
|
101
|
+
if (!i.existsSync(e)) return !0;
|
|
102
|
+
const t = i.readdirSync(e);
|
|
103
|
+
return t.length === 0 || t.length === 1 && t[0] === ".git";
|
|
104
104
|
}
|
|
105
|
-
const
|
|
106
|
-
function
|
|
107
|
-
if (!
|
|
108
|
-
if (!
|
|
109
|
-
return
|
|
110
|
-
for (const
|
|
111
|
-
|
|
112
|
-
return
|
|
105
|
+
const te = /* @__PURE__ */ new Set(["node_modules", ".git", ".yarn", "dist"]);
|
|
106
|
+
function L(e, t = []) {
|
|
107
|
+
if (!i.existsSync(e)) return t;
|
|
108
|
+
if (!i.statSync(e).isDirectory())
|
|
109
|
+
return t.push(e), t;
|
|
110
|
+
for (const n of i.readdirSync(e))
|
|
111
|
+
te.has(n) || L(m.join(e, n), t);
|
|
112
|
+
return t;
|
|
113
113
|
}
|
|
114
114
|
async function z(e) {
|
|
115
|
-
const
|
|
116
|
-
let
|
|
117
|
-
for (const
|
|
115
|
+
const t = e.flatMap((o) => L(o));
|
|
116
|
+
let n = 0;
|
|
117
|
+
for (const o of t)
|
|
118
118
|
try {
|
|
119
|
-
const
|
|
120
|
-
if (!
|
|
121
|
-
const
|
|
122
|
-
|
|
119
|
+
const a = await I.getFileInfo(o, { resolveConfig: !0 });
|
|
120
|
+
if (!a.inferredParser || a.ignored) continue;
|
|
121
|
+
const l = i.readFileSync(o, "utf-8"), s = await I.resolveConfig(o, { editorconfig: !0 }), c = await I.format(l, { ...s, filepath: o });
|
|
122
|
+
c !== l && (i.writeFileSync(o, c), n++);
|
|
123
123
|
} catch {
|
|
124
124
|
}
|
|
125
|
-
return
|
|
125
|
+
return n;
|
|
126
126
|
}
|
|
127
|
-
const
|
|
127
|
+
const ne = {
|
|
128
128
|
standalone: "Standalone App",
|
|
129
129
|
"dynamic-module": "Dynamic Module"
|
|
130
130
|
};
|
|
131
|
-
function
|
|
132
|
-
const
|
|
131
|
+
function oe(e) {
|
|
132
|
+
const t = ne[e.projectType] ?? e.projectType, n = !!e.moduleName;
|
|
133
133
|
console.log(`
|
|
134
|
-
${
|
|
135
|
-
${
|
|
136
|
-
${
|
|
137
|
-
${
|
|
138
|
-
${
|
|
139
|
-
${
|
|
140
|
-
${
|
|
141
|
-
` : ""} ${
|
|
142
|
-
${
|
|
134
|
+
${r.green("╭─────────────────────────────────────────╮")}
|
|
135
|
+
${r.green("│")} ${r.green("│")}
|
|
136
|
+
${r.green("│")} ${r.bold("VC Shell App created successfully!")} ${r.green("│")}
|
|
137
|
+
${r.green("│")} ${r.green("│")}
|
|
138
|
+
${r.green("│")} Project: ${r.cyan(e.projectName.padEnd(28))}${r.green("│")}
|
|
139
|
+
${r.green("│")} Type: ${r.cyan(t.padEnd(28))}${r.green("│")}
|
|
140
|
+
${n && e.moduleName ? ` ${r.green("│")} Module: ${r.cyan(e.moduleName.padEnd(28))}${r.green("│")}
|
|
141
|
+
` : ""} ${r.green("│")} ${r.green("│")}
|
|
142
|
+
${r.green("╰─────────────────────────────────────────╯")}
|
|
143
143
|
|
|
144
|
-
${
|
|
144
|
+
${r.bold("Next steps:")}
|
|
145
145
|
|
|
146
146
|
1. cd ${e.projectName}
|
|
147
147
|
2. yarn install
|
|
148
148
|
3. yarn serve
|
|
149
|
-
${
|
|
149
|
+
${n && e.moduleName ? `
|
|
150
150
|
Module is ready at:
|
|
151
|
-
src/modules/${
|
|
151
|
+
src/modules/${ae(e.moduleName)}/
|
|
152
152
|
` : ""}
|
|
153
|
-
${
|
|
153
|
+
${r.dim("Docs: https://docs.virtocommerce.org/platform/developer-guide/latest/custom-apps-development/vc-shell/vc-shell-overview/")}
|
|
154
154
|
`);
|
|
155
155
|
}
|
|
156
|
-
function
|
|
156
|
+
function ae(e) {
|
|
157
157
|
return e.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
158
158
|
}
|
|
159
|
-
const
|
|
159
|
+
const D = [
|
|
160
160
|
{ title: "Standalone App — full application with bundled modules", value: "standalone" },
|
|
161
161
|
{ title: "Dynamic Module — remote module loaded by host via Module Federation", value: "dynamic-module" }
|
|
162
162
|
];
|
|
163
|
-
function
|
|
164
|
-
return typeof e == "string" &&
|
|
163
|
+
function re(e) {
|
|
164
|
+
return typeof e == "string" && D.some((t) => t.value === e);
|
|
165
165
|
}
|
|
166
|
-
async function
|
|
167
|
-
const
|
|
168
|
-
let
|
|
169
|
-
const
|
|
170
|
-
let
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
if (!
|
|
175
|
-
const
|
|
176
|
-
console.error(
|
|
166
|
+
async function se(e, t) {
|
|
167
|
+
const n = process.cwd();
|
|
168
|
+
let a = e._?.[0] || e.name || e["app-name"];
|
|
169
|
+
const l = a || "vc-app", s = () => a === "." ? m.basename(m.resolve()) : a, c = !!(a && e.type);
|
|
170
|
+
let d;
|
|
171
|
+
if (c) {
|
|
172
|
+
a = a || l;
|
|
173
|
+
const y = m.resolve(n, a);
|
|
174
|
+
if (!re(e.type)) {
|
|
175
|
+
const S = D.map(($) => $.value).join(", ");
|
|
176
|
+
console.error(r.red(`Unknown project type: "${e.type}". Valid types: ${S}`)), process.exit(1);
|
|
177
177
|
}
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
projectName:
|
|
182
|
-
packageName: e["package-name"] || (
|
|
183
|
-
projectType:
|
|
184
|
-
moduleName:
|
|
185
|
-
basePath: e["base-path"] ||
|
|
178
|
+
i.existsSync(y) && !T(y) && !e.overwrite && (console.error(r.red(`Target directory "${a}" is not empty. Use --overwrite to overwrite.`)), process.exit(1));
|
|
179
|
+
const f = s(), h = e.type, g = e["module-name"], b = h === "dynamic-module" ? g || x(f) : g || void 0;
|
|
180
|
+
d = {
|
|
181
|
+
projectName: v(f),
|
|
182
|
+
packageName: e["package-name"] || (N(f) ? f : A(f)),
|
|
183
|
+
projectType: h,
|
|
184
|
+
moduleName: b,
|
|
185
|
+
basePath: e["base-path"] || E(`/apps/${v(f)}/`),
|
|
186
186
|
tenantRoutes: e["tenant-routes"] || !1,
|
|
187
187
|
aiAgent: e["ai-agent"] || !1,
|
|
188
188
|
dashboard: e.dashboard || !1,
|
|
189
189
|
mocks: e.mocks || !1
|
|
190
190
|
};
|
|
191
191
|
} else {
|
|
192
|
-
const
|
|
193
|
-
throw new Error(
|
|
192
|
+
const y = () => {
|
|
193
|
+
throw new Error(r.red("✖") + " Creation cancelled");
|
|
194
194
|
};
|
|
195
195
|
try {
|
|
196
|
-
const
|
|
196
|
+
const f = await P(
|
|
197
197
|
[
|
|
198
198
|
{
|
|
199
199
|
name: "projectName",
|
|
200
|
-
type:
|
|
201
|
-
message:
|
|
202
|
-
initial:
|
|
200
|
+
type: a ? null : "text",
|
|
201
|
+
message: r.reset("Project name:"),
|
|
202
|
+
initial: l,
|
|
203
203
|
onState: (w) => {
|
|
204
|
-
|
|
204
|
+
a = v(String(w.value).trim()) || l;
|
|
205
205
|
},
|
|
206
|
-
format: (w) =>
|
|
206
|
+
format: (w) => v(String(w).trim())
|
|
207
207
|
},
|
|
208
208
|
{
|
|
209
|
-
type: () => !
|
|
209
|
+
type: () => !i.existsSync(m.resolve(n, a)) || T(m.resolve(n, a)) ? null : "confirm",
|
|
210
210
|
name: "overwrite",
|
|
211
|
-
message: () => (
|
|
211
|
+
message: () => (a === "." ? "Current directory" : `Target directory "${a}"`) + " is not empty. Remove existing files and continue?"
|
|
212
212
|
},
|
|
213
213
|
{
|
|
214
|
-
type: (w, { overwrite:
|
|
215
|
-
if (
|
|
216
|
-
throw new Error(
|
|
214
|
+
type: (w, { overwrite: _ }) => {
|
|
215
|
+
if (_ === !1)
|
|
216
|
+
throw new Error(r.red("✖") + " Operation cancelled");
|
|
217
217
|
return null;
|
|
218
218
|
},
|
|
219
219
|
name: "overwriteChecker"
|
|
220
220
|
},
|
|
221
221
|
{
|
|
222
222
|
name: "packageName",
|
|
223
|
-
type: () =>
|
|
224
|
-
message:
|
|
225
|
-
initial: () =>
|
|
226
|
-
validate: (w) =>
|
|
223
|
+
type: () => N(s()) ? null : "text",
|
|
224
|
+
message: r.reset("Package name:"),
|
|
225
|
+
initial: () => A(s()),
|
|
226
|
+
validate: (w) => N(w) || "Invalid package.json name"
|
|
227
227
|
},
|
|
228
228
|
{
|
|
229
229
|
type: "select",
|
|
230
230
|
name: "projectType",
|
|
231
|
-
message:
|
|
232
|
-
choices:
|
|
231
|
+
message: r.reset("Project type:"),
|
|
232
|
+
choices: D
|
|
233
233
|
}
|
|
234
234
|
],
|
|
235
|
-
{ onCancel:
|
|
236
|
-
),
|
|
235
|
+
{ onCancel: y }
|
|
236
|
+
), h = a ? v(a) : f.projectName, g = f.projectType || "standalone", b = x(h), S = "/apps/" + v(h) + "/", $ = await P(
|
|
237
237
|
[
|
|
238
238
|
{
|
|
239
239
|
name: "includeModule",
|
|
@@ -243,17 +243,17 @@ async function ae(e, n) {
|
|
|
243
243
|
},
|
|
244
244
|
{
|
|
245
245
|
name: "moduleName",
|
|
246
|
-
type: (w,
|
|
247
|
-
message:
|
|
248
|
-
initial:
|
|
246
|
+
type: (w, _) => g === "standalone" && !_.includeModule ? null : "text",
|
|
247
|
+
message: r.reset("Module name:"),
|
|
248
|
+
initial: b,
|
|
249
249
|
format: (w) => String(w).trim()
|
|
250
250
|
},
|
|
251
251
|
{
|
|
252
252
|
name: "basePath",
|
|
253
253
|
type: g === "dynamic-module" ? null : "text",
|
|
254
|
-
message:
|
|
255
|
-
initial:
|
|
256
|
-
format: (w) =>
|
|
254
|
+
message: r.reset("Base path:"),
|
|
255
|
+
initial: S,
|
|
256
|
+
format: (w) => E(String(w).trim())
|
|
257
257
|
},
|
|
258
258
|
{
|
|
259
259
|
type: g === "dynamic-module" ? null : "confirm",
|
|
@@ -280,139 +280,213 @@ async function ae(e, n) {
|
|
|
280
280
|
initial: !1
|
|
281
281
|
}
|
|
282
282
|
],
|
|
283
|
-
{ onCancel:
|
|
283
|
+
{ onCancel: y }
|
|
284
284
|
);
|
|
285
|
-
|
|
286
|
-
projectName:
|
|
287
|
-
packageName:
|
|
285
|
+
d = {
|
|
286
|
+
projectName: h,
|
|
287
|
+
packageName: f.packageName || (N(h) ? h : A(h)),
|
|
288
288
|
projectType: g,
|
|
289
|
-
moduleName:
|
|
290
|
-
basePath:
|
|
291
|
-
tenantRoutes:
|
|
292
|
-
aiAgent:
|
|
293
|
-
dashboard:
|
|
294
|
-
mocks:
|
|
289
|
+
moduleName: $.moduleName || ($.includeModule !== !1 ? b : void 0),
|
|
290
|
+
basePath: $.basePath || E(S),
|
|
291
|
+
tenantRoutes: $.tenantRoutes || !1,
|
|
292
|
+
aiAgent: $.aiAgent || !1,
|
|
293
|
+
dashboard: $.dashboard ?? !0,
|
|
294
|
+
mocks: $.mocks || !1
|
|
295
295
|
};
|
|
296
|
-
} catch (
|
|
297
|
-
console.log(
|
|
296
|
+
} catch (f) {
|
|
297
|
+
console.log(f.message), process.exit(1);
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
Scaffolding ${
|
|
300
|
+
const p = m.resolve(n, a);
|
|
301
|
+
i.existsSync(p) && !T(p) ? ee(p) : i.existsSync(p) || i.mkdirSync(p, { recursive: !0 }), console.log(`
|
|
302
|
+
Scaffolding ${r.cyan(d.projectType)} in ${r.green(p)}...
|
|
303
303
|
`);
|
|
304
|
-
const
|
|
305
|
-
if (
|
|
306
|
-
const
|
|
307
|
-
|
|
304
|
+
const u = U(d);
|
|
305
|
+
if (j(m.join(t, d.projectType), p, u), d.moduleName) {
|
|
306
|
+
const y = v(d.moduleName), f = d.projectType === "dynamic-module" ? m.join(p, "src/modules") : m.join(p, "src/modules", y);
|
|
307
|
+
j(m.join(t, "module"), f, u);
|
|
308
|
+
}
|
|
309
|
+
d.mocks && j(m.join(t, "sample-module"), m.join(p, "src/modules/sample"), u), await z([p]), oe(d);
|
|
310
|
+
}
|
|
311
|
+
function k(e, { strings: t = !0 } = {}) {
|
|
312
|
+
const n = e.split("");
|
|
313
|
+
let o = 0;
|
|
314
|
+
const a = (l, s) => {
|
|
315
|
+
for (let c = l; c < s && c < e.length; c++)
|
|
316
|
+
n[c] !== `
|
|
317
|
+
` && (n[c] = " ");
|
|
318
|
+
};
|
|
319
|
+
for (; o < e.length; ) {
|
|
320
|
+
const l = e[o];
|
|
321
|
+
if (l === "/" && e[o + 1] === "/") {
|
|
322
|
+
const s = e.indexOf(`
|
|
323
|
+
`, o), c = s === -1 ? e.length : s;
|
|
324
|
+
a(o, c), o = c;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (l === "/" && e[o + 1] === "*") {
|
|
328
|
+
const s = e.indexOf("*/", o + 2), c = s === -1 ? e.length : s + 2;
|
|
329
|
+
a(o, c), o = c;
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
if (l === '"' || l === "'" || l === "`") {
|
|
333
|
+
let s = o + 1;
|
|
334
|
+
for (; s < e.length; ) {
|
|
335
|
+
if (e[s] === "\\") {
|
|
336
|
+
s += 2;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (e[s] === l) break;
|
|
340
|
+
s++;
|
|
341
|
+
}
|
|
342
|
+
t && a(o + 1, s), o = s + 1;
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
o++;
|
|
308
346
|
}
|
|
309
|
-
|
|
347
|
+
return n.join("");
|
|
310
348
|
}
|
|
311
|
-
function
|
|
312
|
-
|
|
313
|
-
let
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
` + n + e.slice(d);
|
|
349
|
+
function ie(e, t) {
|
|
350
|
+
let n = 0;
|
|
351
|
+
for (let o = t; o < e.length; o++) {
|
|
352
|
+
const a = e[o];
|
|
353
|
+
if (a === "(" || a === "[" || a === "{")
|
|
354
|
+
n++;
|
|
355
|
+
else if ((a === ")" || a === "]" || a === "}") && (n--, n === 0))
|
|
356
|
+
return e[o + 1] === ";" ? o + 2 : o + 1;
|
|
320
357
|
}
|
|
321
|
-
return
|
|
322
|
-
` + e;
|
|
358
|
+
return -1;
|
|
323
359
|
}
|
|
324
|
-
function
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const i = p.index + p[0].length, l = `
|
|
334
|
-
.use(${s}, { router })`;
|
|
335
|
-
t = t.slice(0, i) + l + t.slice(i);
|
|
360
|
+
function ce(e, t) {
|
|
361
|
+
const n = new RegExp(`\\b${t}\\s*\\(`, "g"), o = [];
|
|
362
|
+
let a;
|
|
363
|
+
for (; (a = n.exec(e)) !== null; ) {
|
|
364
|
+
const l = o[o.length - 1];
|
|
365
|
+
if (l && a.index < l.end) continue;
|
|
366
|
+
const s = ie(e, a.index + a[0].length - 1);
|
|
367
|
+
if (s === -1) break;
|
|
368
|
+
o.push({ start: a.index, end: s });
|
|
336
369
|
}
|
|
337
|
-
|
|
370
|
+
return o;
|
|
338
371
|
}
|
|
339
|
-
function
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
if (
|
|
345
|
-
|
|
346
|
-
t = t.replace(v[0], `import { ${f} } from "@vc-shell/framework"`);
|
|
347
|
-
} else
|
|
348
|
-
t = L(t, 'import { addMenuItem } from "@vc-shell/framework";');
|
|
372
|
+
function B(e) {
|
|
373
|
+
const t = /^[ \t]*import(?=[\s{"'])/gm;
|
|
374
|
+
let n = -1, o;
|
|
375
|
+
for (; (o = t.exec(e)) !== null; ) {
|
|
376
|
+
const a = e.indexOf(";", o.index);
|
|
377
|
+
if (a === -1) break;
|
|
378
|
+
n = a + 1, t.lastIndex = n;
|
|
349
379
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
380
|
+
return n;
|
|
381
|
+
}
|
|
382
|
+
function V(e, t) {
|
|
383
|
+
const n = e.lastIndexOf(`
|
|
384
|
+
`, t - 1) + 1;
|
|
385
|
+
return /^[ \t]*/.exec(e.slice(n, t))?.[0] ?? "";
|
|
386
|
+
}
|
|
387
|
+
function C(e, t) {
|
|
388
|
+
return [...t].sort((n, o) => o.at - n.at).reduce((n, { at: o, text: a }) => n.slice(0, o) + a + n.slice(o), e);
|
|
389
|
+
}
|
|
390
|
+
function le(e, t) {
|
|
391
|
+
const n = i.readFileSync(e, "utf-8"), o = k(n), a = M(t), l = v(t), s = /^[ \t]*app\.use\(\s*router\s*\)\s*;/m.exec(o);
|
|
392
|
+
if (!s)
|
|
393
|
+
throw new Error("Could not find `app.use(router)` in main.ts");
|
|
394
|
+
const c = B(o);
|
|
395
|
+
if (c === -1)
|
|
396
|
+
throw new Error("Could not find an import statement in main.ts");
|
|
397
|
+
const d = V(n, s.index + s[0].length);
|
|
398
|
+
i.writeFileSync(
|
|
399
|
+
e,
|
|
400
|
+
C(n, [
|
|
401
|
+
{ at: c, text: `
|
|
402
|
+
import ${a} from "./modules/${l}";` },
|
|
403
|
+
{ at: s.index, text: `${d}app.use(${a});
|
|
404
|
+
` }
|
|
405
|
+
])
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
function me(e) {
|
|
409
|
+
const t = k(e);
|
|
410
|
+
if (/\baddMenuItem\b/.test(t)) return e;
|
|
411
|
+
const n = /import\s*\{([^}]*)\}\s*from\s*["']@vc-shell\/framework["']/.exec(
|
|
412
|
+
k(e, { strings: !1 })
|
|
413
|
+
);
|
|
414
|
+
if (n) {
|
|
415
|
+
const l = n[1].trim().replace(/,$/, ""), s = n.index + n[0].length;
|
|
416
|
+
return e.slice(0, n.index) + `import { ${l}, addMenuItem } from "@vc-shell/framework"` + e.slice(s);
|
|
417
|
+
}
|
|
418
|
+
const o = 'import { addMenuItem } from "@vc-shell/framework";', a = B(t);
|
|
419
|
+
return a === -1 ? `${o}
|
|
420
|
+
${e}` : C(e, [{ at: a, text: `
|
|
421
|
+
${o}` }]);
|
|
422
|
+
}
|
|
423
|
+
function de(e, t) {
|
|
424
|
+
const n = v(t), o = O(t), a = me(i.readFileSync(e, "utf-8")), l = k(a), s = (u) => [
|
|
425
|
+
`${u}addMenuItem({`,
|
|
426
|
+
`${u} title: "${o}.MENU.TITLE",`,
|
|
427
|
+
`${u} icon: "lucide-box",`,
|
|
428
|
+
`${u} priority: 10,`,
|
|
429
|
+
`${u} url: "/${n}",`,
|
|
430
|
+
`${u}});`
|
|
431
|
+
].join(`
|
|
432
|
+
`), c = ce(l, "addMenuItem"), d = c[c.length - 1];
|
|
433
|
+
if (d) {
|
|
434
|
+
const u = V(a, d.start);
|
|
435
|
+
i.writeFileSync(e, C(a, [{ at: d.end, text: `
|
|
436
|
+
|
|
437
|
+
${s(u)}` }]));
|
|
438
|
+
return;
|
|
369
439
|
}
|
|
370
|
-
|
|
440
|
+
const p = l.lastIndexOf("}");
|
|
441
|
+
if (p === -1)
|
|
442
|
+
throw new Error("Could not find the bootstrap function body in bootstrap.ts");
|
|
443
|
+
i.writeFileSync(e, C(a, [{ at: p, text: `${s(" ")}
|
|
444
|
+
` }]));
|
|
371
445
|
}
|
|
372
|
-
async function
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
const
|
|
376
|
-
({ ...
|
|
377
|
-
let
|
|
378
|
-
|
|
446
|
+
async function pe(e, t) {
|
|
447
|
+
const n = process.cwd(), o = e._?.[1], a = m.join(n, "package.json");
|
|
448
|
+
i.existsSync(a) || (console.error(r.red("Error: No package.json found. Run this command from a vc-shell project root.")), process.exit(1));
|
|
449
|
+
const l = JSON.parse(i.readFileSync(a, "utf-8"));
|
|
450
|
+
({ ...l.dependencies, ...l.devDependencies })["@vc-shell/framework"] || (console.error(r.red("Error: Not a vc-shell project (@vc-shell/framework not found in dependencies).")), process.exit(1));
|
|
451
|
+
let c = o;
|
|
452
|
+
c || (c = (await P({
|
|
379
453
|
type: "text",
|
|
380
454
|
name: "moduleName",
|
|
381
455
|
message: "Module name:",
|
|
382
|
-
validate: (
|
|
383
|
-
})).moduleName),
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
const
|
|
389
|
-
if (
|
|
456
|
+
validate: (S) => S.trim().length > 0 || "Module name is required"
|
|
457
|
+
})).moduleName), c || (console.error(r.red("Module name is required.")), process.exit(1));
|
|
458
|
+
const d = v(c), p = M(c), u = m.join(n, "src/modules"), y = m.join(u, d);
|
|
459
|
+
i.existsSync(u) || i.mkdirSync(u, { recursive: !0 }), i.existsSync(y) && (console.error(r.red(`Error: Module "${d}" already exists at ${m.relative(n, y)}`)), process.exit(1));
|
|
460
|
+
const f = U({ moduleName: c, projectName: m.basename(n) });
|
|
461
|
+
j(m.join(t, "module"), y, f), console.log(r.green(` ✔ Created ${m.relative(n, y)}/`));
|
|
462
|
+
const h = m.join(n, "src/main.ts");
|
|
463
|
+
if (i.existsSync(h))
|
|
390
464
|
try {
|
|
391
|
-
|
|
465
|
+
le(h, c), console.log(r.green(` ✔ Updated src/main.ts — added import & app.use(${p})`));
|
|
392
466
|
} catch {
|
|
393
|
-
console.warn(
|
|
467
|
+
console.warn(r.yellow(" ⚠ Could not auto-update src/main.ts. Add manually:")), console.warn(r.yellow(` import ${p} from "./modules/${d}";`)), console.warn(r.yellow(` app.use(${p}, { router });`));
|
|
394
468
|
}
|
|
395
|
-
const g =
|
|
396
|
-
if (
|
|
469
|
+
const g = m.join(n, "src/bootstrap.ts");
|
|
470
|
+
if (i.existsSync(g))
|
|
397
471
|
try {
|
|
398
|
-
|
|
472
|
+
de(g, c), console.log(r.green(` ✔ Updated src/bootstrap.ts — added menu item "${x(c)}"`));
|
|
399
473
|
} catch {
|
|
400
|
-
console.warn(
|
|
474
|
+
console.warn(r.yellow(" ⚠ Could not auto-update src/bootstrap.ts. Add addMenuItem() manually."));
|
|
401
475
|
}
|
|
402
|
-
await z([
|
|
403
|
-
Module "${
|
|
476
|
+
await z([y, h, g]), console.log(`
|
|
477
|
+
Module "${d}" is ready! Run ${r.bold(r.green("yarn serve"))} to see it.
|
|
404
478
|
`);
|
|
405
479
|
}
|
|
406
|
-
const
|
|
407
|
-
function
|
|
480
|
+
const R = m.resolve(Z(import.meta.url), "..", "templates");
|
|
481
|
+
function ue() {
|
|
408
482
|
console.log(`
|
|
409
|
-
${
|
|
483
|
+
${r.bold(r.green("create-vc-app"))} — Create VC Shell applications and modules
|
|
410
484
|
|
|
411
|
-
${
|
|
485
|
+
${r.bold("Usage:")}
|
|
412
486
|
create-vc-app [project-name] [options] Create a new project
|
|
413
487
|
create-vc-app add-module <module-name> Add a module to existing project
|
|
414
488
|
|
|
415
|
-
${
|
|
489
|
+
${r.bold("Options (create):")}
|
|
416
490
|
--type <type> Project type: standalone | dynamic-module
|
|
417
491
|
--name, --app-name <name> Application name
|
|
418
492
|
--package-name <name> npm package name
|
|
@@ -426,31 +500,31 @@ ${a.bold("Options (create):")}
|
|
|
426
500
|
--help, -h Show this help
|
|
427
501
|
--version, -v Show version
|
|
428
502
|
|
|
429
|
-
${
|
|
503
|
+
${r.bold("Examples:")}
|
|
430
504
|
create-vc-app my-app
|
|
431
505
|
create-vc-app my-app --type standalone --dashboard --mocks
|
|
432
506
|
create-vc-app my-module --type dynamic-module --module-name "Reviews"
|
|
433
507
|
create-vc-app add-module orders
|
|
434
508
|
|
|
435
|
-
${
|
|
509
|
+
${r.bold("Docs:")} https://docs.virtocommerce.org/platform/developer-guide/latest/custom-apps-development/vc-shell/vc-shell-overview/
|
|
436
510
|
`);
|
|
437
511
|
}
|
|
438
|
-
async function
|
|
439
|
-
const e =
|
|
512
|
+
async function fe() {
|
|
513
|
+
const e = K(Y.slice(2), {
|
|
440
514
|
alias: { h: "help", v: "version" },
|
|
441
515
|
boolean: ["help", "version", "mocks", "overwrite", "tenant-routes", "ai-agent", "dashboard"],
|
|
442
516
|
string: ["type", "name", "app-name", "package-name", "module-name", "base-path"]
|
|
443
517
|
});
|
|
444
518
|
if (e.help) {
|
|
445
|
-
|
|
519
|
+
ue();
|
|
446
520
|
return;
|
|
447
521
|
}
|
|
448
522
|
if (e.version) {
|
|
449
|
-
console.log(`create-vc-app v${
|
|
523
|
+
console.log(`create-vc-app v${W.version}`);
|
|
450
524
|
return;
|
|
451
525
|
}
|
|
452
|
-
e._[0] === "add-module" ? await
|
|
526
|
+
e._[0] === "add-module" ? await pe(e, R) : await se(e, R);
|
|
453
527
|
}
|
|
454
|
-
|
|
455
|
-
console.error(
|
|
528
|
+
fe().catch((e) => {
|
|
529
|
+
console.error(r.red(e.message || String(e))), J(1);
|
|
456
530
|
});
|
|
@@ -4,6 +4,7 @@ import { useAsync, useLoading } from "@vc-shell/framework";
|
|
|
4
4
|
export default function use<%- ModuleNamePascalCase %>Details() {
|
|
5
5
|
const item = ref<Record<string, any>>({});
|
|
6
6
|
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- used by the TODO API call below
|
|
7
8
|
const { loading: itemLoading, action: fetchItem } = useAsync(async (id?: string) => {
|
|
8
9
|
// TODO: Replace with real API call
|
|
9
10
|
// const result = await apiClient.getById(id);
|
|
@@ -8,11 +8,11 @@ export interface <%- ModuleNamePascalCase %>ListQuery {
|
|
|
8
8
|
take?: number;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
11
|
export default function use<%- ModuleNamePascalCase %>List() {
|
|
13
12
|
const data: Ref<Record<string, any>[]> = ref([]);
|
|
14
13
|
const totalCount = ref(0);
|
|
15
14
|
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- used by the TODO API call below
|
|
16
16
|
const { loading: itemsLoading, action: getItems } = useAsync<<%- ModuleNamePascalCase %>ListQuery>(async (query) => {
|
|
17
17
|
// TODO: Replace with real API call
|
|
18
18
|
// const result = await apiClient.search({
|
|
@@ -25,6 +25,7 @@ export default function use<%- ModuleNamePascalCase %>List() {
|
|
|
25
25
|
// totalCount.value = result.totalCount ?? 0;
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- used by the TODO API call below
|
|
28
29
|
const { loading: deleteLoading, action: removeItems } = useAsync(async (ids?: string[]) => {
|
|
29
30
|
// TODO: Replace with real API call
|
|
30
31
|
// await Promise.all((ids ?? []).map((id) => apiClient.delete(id)));
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { App } from "vue";
|
|
1
|
+
import { App<% if (dashboard) { %>, markRaw<% } %> } from "vue";
|
|
2
2
|
<% if (dashboard) { -%>
|
|
3
3
|
import { addMenuItem, registerDashboardWidget } from "@vc-shell/framework";
|
|
4
|
-
import { markRaw } from "vue";
|
|
5
4
|
import Welcome from "./components/dashboard-widgets/Welcome.vue";
|
|
6
5
|
<% } -%>
|
|
7
6
|
|
|
@@ -18,6 +18,7 @@ const isReady = ref(false);
|
|
|
18
18
|
const version = import.meta.env.PACKAGE_VERSION;
|
|
19
19
|
|
|
20
20
|
const { isAuthenticated } = useUser();
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- used by the TODO example below
|
|
21
22
|
const { setBroadcastFilter } = useBroadcastFilter();
|
|
22
23
|
|
|
23
24
|
onMounted(async () => {
|
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-pr302.
|
|
4
|
+
"version": "2.4.0-pr302.b052b38",
|
|
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-pr302.
|
|
19
|
+
"@vc-shell/ts-config": "2.4.0-pr302.b052b38",
|
|
20
20
|
"copyfiles": "^2.4.1",
|
|
21
21
|
"cross-env": "^7.0.3",
|
|
22
22
|
"shx": "^0.3.4",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"ejs": "^3.1.10",
|
|
27
|
-
"magicast": "^0.3.5",
|
|
28
27
|
"mri": "^1.2.0",
|
|
29
28
|
"picocolors": "^1.1.1",
|
|
30
29
|
"prettier": "^3.6.2",
|