@vc-shell/create-vc-app 1.1.98-rc.5 → 1.1.99-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +552 -26
- package/dist/cli/argv.d.ts +4 -0
- package/dist/cli/argv.d.ts.map +1 -0
- package/dist/cli/constants.d.ts +4 -0
- package/dist/cli/constants.d.ts.map +1 -0
- package/dist/cli/errors.d.ts +12 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/runtime.d.ts +7 -0
- package/dist/cli/runtime.d.ts.map +1 -0
- package/dist/cli/types.d.ts +30 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/utils.d.ts +4 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/validation.d.ts +5 -0
- package/dist/cli/validation.d.ts.map +1 -0
- package/dist/commands/generate-blade.d.ts +16 -0
- package/dist/commands/generate-blade.d.ts.map +1 -0
- package/dist/index.js +1900 -530
- package/dist/templates/base/_package.json +5 -5
- package/dist/templates/base/ai-guides/.cursorrules-vc-shell +529 -0
- package/dist/templates/base/ai-guides/README.md +360 -0
- package/dist/templates/base/ai-guides/guides/AI_GUIDE.md +195 -0
- package/dist/templates/base/ai-guides/guides/blade-patterns.md +384 -0
- package/dist/templates/base/ai-guides/guides/complete-workflow.md +781 -0
- package/dist/templates/base/ai-guides/guides/composables-reference.md +338 -0
- package/dist/templates/base/ai-guides/guides/troubleshooting.md +529 -0
- package/dist/templates/base/ai-guides/guides/ui-components-reference.md +903 -0
- package/dist/templates/base/ai-guides/prompts/adapt-existing-module.md +1026 -0
- package/dist/templates/base/ai-guides/prompts/advanced-scenarios.md +852 -0
- package/dist/templates/base/ai-guides/prompts/api-client-generation.md +877 -0
- package/dist/templates/base/ai-guides/prompts/cli-usage.md +640 -0
- package/dist/templates/base/ai-guides/prompts/quick-start-scenarios.md +773 -0
- package/dist/templates/base/ai-guides/prompts/simple-modifications.md +987 -0
- package/dist/templates/base/src/main.ts +0 -4
- package/dist/templates/blades/details/blade.vue +175 -0
- package/dist/templates/blades/grid/blade.vue +340 -0
- package/dist/templates/composables/details-composable.ts +101 -0
- package/dist/templates/composables/grid-composable.ts +244 -0
- package/dist/templates/module/components/index.ts +2 -0
- package/dist/templates/module/components/widgets/index.ts +2 -0
- package/dist/templates/module/composables/index.ts +3 -0
- package/dist/templates/module/index.ts +13 -0
- package/dist/templates/module/locales/en.json +65 -0
- package/dist/templates/module/locales/index.ts +4 -0
- package/dist/templates/module/pages/index.ts +3 -0
- package/dist/templates/widgets/widget.vue +113 -0
- package/dist/utils/form-builder.d.ts +69 -0
- package/dist/utils/form-builder.d.ts.map +1 -0
- package/dist/utils/format.d.ts +24 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/naming.d.ts +44 -0
- package/dist/utils/naming.d.ts.map +1 -0
- package/dist/utils/register-module.d.ts +21 -0
- package/dist/utils/register-module.d.ts.map +1 -0
- package/dist/workflows/create-app.d.ts +14 -0
- package/dist/workflows/create-app.d.ts.map +1 -0
- package/package.json +12 -7
- package/dist/templates/mocks/sample-data/constants.ts +0 -89
- package/dist/templates/mocks/sample-data/index.ts +0 -2
- package/dist/templates/mocks/sample-data/methods.ts +0 -65
- package/dist/templates/modules/classic-module/composables/index.ts +0 -2
- package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}Details/index.ts +0 -24
- package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}List/index.ts +0 -47
- package/dist/templates/modules/classic-module/index.ts +0 -8
- package/dist/templates/modules/classic-module/locales/en.json +0 -37
- package/dist/templates/modules/classic-module/locales/index.ts +0 -2
- package/dist/templates/modules/classic-module/pages/details.vue +0 -87
- package/dist/templates/modules/classic-module/pages/index.ts +0 -2
- package/dist/templates/modules/classic-module/pages/list.vue +0 -257
- package/dist/templates/sample/classic-module/composables/index.ts +0 -2
- package/dist/templates/sample/classic-module/composables/useDetails/index.ts +0 -54
- package/dist/templates/sample/classic-module/composables/useList/index.ts +0 -62
- package/dist/templates/sample/classic-module/index.ts +0 -8
- package/dist/templates/sample/classic-module/locales/en.json +0 -67
- package/dist/templates/sample/classic-module/locales/index.ts +0 -2
- package/dist/templates/sample/classic-module/pages/details.vue +0 -238
- package/dist/templates/sample/classic-module/pages/index.ts +0 -2
- package/dist/templates/sample/classic-module/pages/list.vue +0 -300
- package/dist/templates/sample/overrides/main.ts +0 -52
package/dist/index.js
CHANGED
|
@@ -1,340 +1,122 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
function Je(e) {
|
|
32
|
-
return e != null && typeof e == "object";
|
|
33
|
-
}
|
|
34
|
-
var Ge = "[object Symbol]";
|
|
35
|
-
function Ye(e) {
|
|
36
|
-
return typeof e == "symbol" || Je(e) && Be(e) == Ge;
|
|
37
|
-
}
|
|
38
|
-
function qe(e, r) {
|
|
39
|
-
for (var a = -1, o = e == null ? 0 : e.length, i = Array(o); ++a < o; )
|
|
40
|
-
i[a] = r(e[a], a, e);
|
|
41
|
-
return i;
|
|
42
|
-
}
|
|
43
|
-
var Ke = Array.isArray, F = b ? b.prototype : void 0, V = F ? F.toString : void 0;
|
|
44
|
-
function Q(e) {
|
|
45
|
-
if (typeof e == "string")
|
|
46
|
-
return e;
|
|
47
|
-
if (Ke(e))
|
|
48
|
-
return qe(e, Q) + "";
|
|
49
|
-
if (Ye(e))
|
|
50
|
-
return V ? V.call(e) : "";
|
|
51
|
-
var r = e + "";
|
|
52
|
-
return r == "0" && 1 / e == -1 / 0 ? "-0" : r;
|
|
53
|
-
}
|
|
54
|
-
function R(e) {
|
|
55
|
-
return e == null ? "" : Q(e);
|
|
56
|
-
}
|
|
57
|
-
function Qe(e, r, a) {
|
|
58
|
-
var o = -1, i = e.length;
|
|
59
|
-
r < 0 && (r = -r > i ? 0 : i + r), a = a > i ? i : a, a < 0 && (a += i), i = r > a ? 0 : a - r >>> 0, r >>>= 0;
|
|
60
|
-
for (var u = Array(i); ++o < i; )
|
|
61
|
-
u[o] = e[o + r];
|
|
62
|
-
return u;
|
|
63
|
-
}
|
|
64
|
-
function Xe(e, r, a) {
|
|
65
|
-
var o = e.length;
|
|
66
|
-
return a = a === void 0 ? o : a, !r && a >= o ? e : Qe(e, r, a);
|
|
67
|
-
}
|
|
68
|
-
var er = "\\ud800-\\udfff", rr = "\\u0300-\\u036f", ar = "\\ufe20-\\ufe2f", nr = "\\u20d0-\\u20ff", or = rr + ar + nr, tr = "\\ufe0e\\ufe0f", ir = "\\u200d", sr = RegExp("[" + ir + er + or + tr + "]");
|
|
69
|
-
function X(e) {
|
|
70
|
-
return sr.test(e);
|
|
71
|
-
}
|
|
72
|
-
function ur(e) {
|
|
73
|
-
return e.split("");
|
|
74
|
-
}
|
|
75
|
-
var ee = "\\ud800-\\udfff", cr = "\\u0300-\\u036f", lr = "\\ufe20-\\ufe2f", fr = "\\u20d0-\\u20ff", pr = cr + lr + fr, mr = "\\ufe0e\\ufe0f", dr = "[" + ee + "]", U = "[" + pr + "]", P = "\\ud83c[\\udffb-\\udfff]", gr = "(?:" + U + "|" + P + ")", re = "[^" + ee + "]", ae = "(?:\\ud83c[\\udde6-\\uddff]){2}", ne = "[\\ud800-\\udbff][\\udc00-\\udfff]", xr = "\\u200d", oe = gr + "?", te = "[" + mr + "]?", br = "(?:" + xr + "(?:" + [re, ae, ne].join("|") + ")" + te + oe + ")*", vr = te + oe + br, yr = "(?:" + [re + U + "?", U, ae, ne, dr].join("|") + ")", hr = RegExp(P + "(?=" + P + ")|" + yr + vr, "g");
|
|
76
|
-
function $r(e) {
|
|
77
|
-
return e.match(hr) || [];
|
|
78
|
-
}
|
|
79
|
-
function Sr(e) {
|
|
80
|
-
return X(e) ? $r(e) : ur(e);
|
|
81
|
-
}
|
|
82
|
-
function ie(e) {
|
|
83
|
-
return function(r) {
|
|
84
|
-
r = R(r);
|
|
85
|
-
var a = X(r) ? Sr(r) : void 0, o = a ? a[0] : r.charAt(0), i = a ? Xe(a, 1).join("") : r.slice(1);
|
|
86
|
-
return o[e]() + i;
|
|
87
|
-
};
|
|
2
|
+
import o from "chalk";
|
|
3
|
+
import m from "node:path";
|
|
4
|
+
import { argv as me, cwd as _ } from "node:process";
|
|
5
|
+
import ue from "mri";
|
|
6
|
+
import x from "prompts";
|
|
7
|
+
import r from "node:fs";
|
|
8
|
+
import { fileURLToPath as X } from "node:url";
|
|
9
|
+
import Y from "prettier";
|
|
10
|
+
import { camelCase as F, snakeCase as v, upperFirst as T, kebabCase as N } from "lodash-es";
|
|
11
|
+
import pe from "pluralize";
|
|
12
|
+
function ge(t = me.slice(2)) {
|
|
13
|
+
return ue(t, {
|
|
14
|
+
alias: {
|
|
15
|
+
h: "help",
|
|
16
|
+
v: "version"
|
|
17
|
+
},
|
|
18
|
+
boolean: [
|
|
19
|
+
"help",
|
|
20
|
+
"version",
|
|
21
|
+
"overwrite",
|
|
22
|
+
"composable",
|
|
23
|
+
"locales",
|
|
24
|
+
"widget",
|
|
25
|
+
"is-workspace",
|
|
26
|
+
"skip-form-editor",
|
|
27
|
+
"skip-module-gen"
|
|
28
|
+
],
|
|
29
|
+
string: ["name", "app-name", "package-name", "module-name", "base-path", "type", "module", "path", "form-fields"]
|
|
30
|
+
});
|
|
88
31
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return L(R(e).toLowerCase());
|
|
32
|
+
function L(t) {
|
|
33
|
+
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(t);
|
|
92
34
|
}
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
a = r(a, e[i], i, e);
|
|
96
|
-
return a;
|
|
35
|
+
function A(t) {
|
|
36
|
+
return t.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9-~]+/g, "-");
|
|
97
37
|
}
|
|
98
|
-
function
|
|
99
|
-
return
|
|
100
|
-
return e?.[r];
|
|
101
|
-
};
|
|
38
|
+
function ee(t) {
|
|
39
|
+
return t.trim().toLowerCase().replace(/\/+/g, "/").replace(/[^a-z0-9/-]+/g, "/").replace(/\/?$/, "/");
|
|
102
40
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
À: "A",
|
|
106
|
-
Á: "A",
|
|
107
|
-
Â: "A",
|
|
108
|
-
Ã: "A",
|
|
109
|
-
Ä: "A",
|
|
110
|
-
Å: "A",
|
|
111
|
-
à: "a",
|
|
112
|
-
á: "a",
|
|
113
|
-
â: "a",
|
|
114
|
-
ã: "a",
|
|
115
|
-
ä: "a",
|
|
116
|
-
å: "a",
|
|
117
|
-
Ç: "C",
|
|
118
|
-
ç: "c",
|
|
119
|
-
Ð: "D",
|
|
120
|
-
ð: "d",
|
|
121
|
-
È: "E",
|
|
122
|
-
É: "E",
|
|
123
|
-
Ê: "E",
|
|
124
|
-
Ë: "E",
|
|
125
|
-
è: "e",
|
|
126
|
-
é: "e",
|
|
127
|
-
ê: "e",
|
|
128
|
-
ë: "e",
|
|
129
|
-
Ì: "I",
|
|
130
|
-
Í: "I",
|
|
131
|
-
Î: "I",
|
|
132
|
-
Ï: "I",
|
|
133
|
-
ì: "i",
|
|
134
|
-
í: "i",
|
|
135
|
-
î: "i",
|
|
136
|
-
ï: "i",
|
|
137
|
-
Ñ: "N",
|
|
138
|
-
ñ: "n",
|
|
139
|
-
Ò: "O",
|
|
140
|
-
Ó: "O",
|
|
141
|
-
Ô: "O",
|
|
142
|
-
Õ: "O",
|
|
143
|
-
Ö: "O",
|
|
144
|
-
Ø: "O",
|
|
145
|
-
ò: "o",
|
|
146
|
-
ó: "o",
|
|
147
|
-
ô: "o",
|
|
148
|
-
õ: "o",
|
|
149
|
-
ö: "o",
|
|
150
|
-
ø: "o",
|
|
151
|
-
Ù: "U",
|
|
152
|
-
Ú: "U",
|
|
153
|
-
Û: "U",
|
|
154
|
-
Ü: "U",
|
|
155
|
-
ù: "u",
|
|
156
|
-
ú: "u",
|
|
157
|
-
û: "u",
|
|
158
|
-
ü: "u",
|
|
159
|
-
Ý: "Y",
|
|
160
|
-
ý: "y",
|
|
161
|
-
ÿ: "y",
|
|
162
|
-
Æ: "Ae",
|
|
163
|
-
æ: "ae",
|
|
164
|
-
Þ: "Th",
|
|
165
|
-
þ: "th",
|
|
166
|
-
ß: "ss",
|
|
167
|
-
// Latin Extended-A block.
|
|
168
|
-
Ā: "A",
|
|
169
|
-
Ă: "A",
|
|
170
|
-
Ą: "A",
|
|
171
|
-
ā: "a",
|
|
172
|
-
ă: "a",
|
|
173
|
-
ą: "a",
|
|
174
|
-
Ć: "C",
|
|
175
|
-
Ĉ: "C",
|
|
176
|
-
Ċ: "C",
|
|
177
|
-
Č: "C",
|
|
178
|
-
ć: "c",
|
|
179
|
-
ĉ: "c",
|
|
180
|
-
ċ: "c",
|
|
181
|
-
č: "c",
|
|
182
|
-
Ď: "D",
|
|
183
|
-
Đ: "D",
|
|
184
|
-
ď: "d",
|
|
185
|
-
đ: "d",
|
|
186
|
-
Ē: "E",
|
|
187
|
-
Ĕ: "E",
|
|
188
|
-
Ė: "E",
|
|
189
|
-
Ę: "E",
|
|
190
|
-
Ě: "E",
|
|
191
|
-
ē: "e",
|
|
192
|
-
ĕ: "e",
|
|
193
|
-
ė: "e",
|
|
194
|
-
ę: "e",
|
|
195
|
-
ě: "e",
|
|
196
|
-
Ĝ: "G",
|
|
197
|
-
Ğ: "G",
|
|
198
|
-
Ġ: "G",
|
|
199
|
-
Ģ: "G",
|
|
200
|
-
ĝ: "g",
|
|
201
|
-
ğ: "g",
|
|
202
|
-
ġ: "g",
|
|
203
|
-
ģ: "g",
|
|
204
|
-
Ĥ: "H",
|
|
205
|
-
Ħ: "H",
|
|
206
|
-
ĥ: "h",
|
|
207
|
-
ħ: "h",
|
|
208
|
-
Ĩ: "I",
|
|
209
|
-
Ī: "I",
|
|
210
|
-
Ĭ: "I",
|
|
211
|
-
Į: "I",
|
|
212
|
-
İ: "I",
|
|
213
|
-
ĩ: "i",
|
|
214
|
-
ī: "i",
|
|
215
|
-
ĭ: "i",
|
|
216
|
-
į: "i",
|
|
217
|
-
ı: "i",
|
|
218
|
-
Ĵ: "J",
|
|
219
|
-
ĵ: "j",
|
|
220
|
-
Ķ: "K",
|
|
221
|
-
ķ: "k",
|
|
222
|
-
ĸ: "k",
|
|
223
|
-
Ĺ: "L",
|
|
224
|
-
Ļ: "L",
|
|
225
|
-
Ľ: "L",
|
|
226
|
-
Ŀ: "L",
|
|
227
|
-
Ł: "L",
|
|
228
|
-
ĺ: "l",
|
|
229
|
-
ļ: "l",
|
|
230
|
-
ľ: "l",
|
|
231
|
-
ŀ: "l",
|
|
232
|
-
ł: "l",
|
|
233
|
-
Ń: "N",
|
|
234
|
-
Ņ: "N",
|
|
235
|
-
Ň: "N",
|
|
236
|
-
Ŋ: "N",
|
|
237
|
-
ń: "n",
|
|
238
|
-
ņ: "n",
|
|
239
|
-
ň: "n",
|
|
240
|
-
ŋ: "n",
|
|
241
|
-
Ō: "O",
|
|
242
|
-
Ŏ: "O",
|
|
243
|
-
Ő: "O",
|
|
244
|
-
ō: "o",
|
|
245
|
-
ŏ: "o",
|
|
246
|
-
ő: "o",
|
|
247
|
-
Ŕ: "R",
|
|
248
|
-
Ŗ: "R",
|
|
249
|
-
Ř: "R",
|
|
250
|
-
ŕ: "r",
|
|
251
|
-
ŗ: "r",
|
|
252
|
-
ř: "r",
|
|
253
|
-
Ś: "S",
|
|
254
|
-
Ŝ: "S",
|
|
255
|
-
Ş: "S",
|
|
256
|
-
Š: "S",
|
|
257
|
-
ś: "s",
|
|
258
|
-
ŝ: "s",
|
|
259
|
-
ş: "s",
|
|
260
|
-
š: "s",
|
|
261
|
-
Ţ: "T",
|
|
262
|
-
Ť: "T",
|
|
263
|
-
Ŧ: "T",
|
|
264
|
-
ţ: "t",
|
|
265
|
-
ť: "t",
|
|
266
|
-
ŧ: "t",
|
|
267
|
-
Ũ: "U",
|
|
268
|
-
Ū: "U",
|
|
269
|
-
Ŭ: "U",
|
|
270
|
-
Ů: "U",
|
|
271
|
-
Ű: "U",
|
|
272
|
-
Ų: "U",
|
|
273
|
-
ũ: "u",
|
|
274
|
-
ū: "u",
|
|
275
|
-
ŭ: "u",
|
|
276
|
-
ů: "u",
|
|
277
|
-
ű: "u",
|
|
278
|
-
ų: "u",
|
|
279
|
-
Ŵ: "W",
|
|
280
|
-
ŵ: "w",
|
|
281
|
-
Ŷ: "Y",
|
|
282
|
-
ŷ: "y",
|
|
283
|
-
Ÿ: "Y",
|
|
284
|
-
Ź: "Z",
|
|
285
|
-
Ż: "Z",
|
|
286
|
-
Ž: "Z",
|
|
287
|
-
ź: "z",
|
|
288
|
-
ż: "z",
|
|
289
|
-
ž: "z",
|
|
290
|
-
IJ: "IJ",
|
|
291
|
-
ij: "ij",
|
|
292
|
-
Œ: "Oe",
|
|
293
|
-
œ: "oe",
|
|
294
|
-
ʼn: "'n",
|
|
295
|
-
ſ: "s"
|
|
296
|
-
}, Rr = wr(jr), Ar = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g, Nr = "\\u0300-\\u036f", Or = "\\ufe20-\\ufe2f", Mr = "\\u20d0-\\u20ff", Er = Nr + Or + Mr, Tr = "[" + Er + "]", Ur = RegExp(Tr, "g");
|
|
297
|
-
function Pr(e) {
|
|
298
|
-
return e = R(e), e && e.replace(Ar, Rr).replace(Ur, "");
|
|
299
|
-
}
|
|
300
|
-
var Lr = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
301
|
-
function _r(e) {
|
|
302
|
-
return e.match(Lr) || [];
|
|
303
|
-
}
|
|
304
|
-
var zr = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
|
|
305
|
-
function Dr(e) {
|
|
306
|
-
return zr.test(e);
|
|
307
|
-
}
|
|
308
|
-
var se = "\\ud800-\\udfff", Ir = "\\u0300-\\u036f", Zr = "\\ufe20-\\ufe2f", Fr = "\\u20d0-\\u20ff", Vr = Ir + Zr + Fr, ue = "\\u2700-\\u27bf", ce = "a-z\\xdf-\\xf6\\xf8-\\xff", Hr = "\\xac\\xb1\\xd7\\xf7", Wr = "\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf", Br = "\\u2000-\\u206f", Jr = " \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000", le = "A-Z\\xc0-\\xd6\\xd8-\\xde", Gr = "\\ufe0e\\ufe0f", fe = Hr + Wr + Br + Jr, pe = "['’]", H = "[" + fe + "]", Yr = "[" + Vr + "]", me = "\\d+", qr = "[" + ue + "]", de = "[" + ce + "]", ge = "[^" + se + fe + me + ue + ce + le + "]", Kr = "\\ud83c[\\udffb-\\udfff]", Qr = "(?:" + Yr + "|" + Kr + ")", Xr = "[^" + se + "]", xe = "(?:\\ud83c[\\udde6-\\uddff]){2}", be = "[\\ud800-\\udbff][\\udc00-\\udfff]", x = "[" + le + "]", ea = "\\u200d", W = "(?:" + de + "|" + ge + ")", ra = "(?:" + x + "|" + ge + ")", B = "(?:" + pe + "(?:d|ll|m|re|s|t|ve))?", J = "(?:" + pe + "(?:D|LL|M|RE|S|T|VE))?", ve = Qr + "?", ye = "[" + Gr + "]?", aa = "(?:" + ea + "(?:" + [Xr, xe, be].join("|") + ")" + ye + ve + ")*", na = "\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])", oa = "\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])", ta = ye + ve + aa, ia = "(?:" + [qr, xe, be].join("|") + ")" + ta, sa = RegExp([
|
|
309
|
-
x + "?" + de + "+" + B + "(?=" + [H, x, "$"].join("|") + ")",
|
|
310
|
-
ra + "+" + J + "(?=" + [H, x + W, "$"].join("|") + ")",
|
|
311
|
-
x + "?" + W + "+" + B,
|
|
312
|
-
x + "+" + J,
|
|
313
|
-
oa,
|
|
314
|
-
na,
|
|
315
|
-
me,
|
|
316
|
-
ia
|
|
317
|
-
].join("|"), "g");
|
|
318
|
-
function ua(e) {
|
|
319
|
-
return e.match(sa) || [];
|
|
320
|
-
}
|
|
321
|
-
function ca(e, r, a) {
|
|
322
|
-
return e = R(e), r = r, r === void 0 ? Dr(e) ? ua(e) : _r(e) : e.match(r) || [];
|
|
323
|
-
}
|
|
324
|
-
var la = "['’]", fa = RegExp(la, "g");
|
|
325
|
-
function _(e) {
|
|
326
|
-
return function(r) {
|
|
327
|
-
return Cr(ca(Pr(r).replace(fa, "")), e, "");
|
|
328
|
-
};
|
|
41
|
+
function fe(t) {
|
|
42
|
+
return t.startsWith("/") && t.endsWith("/");
|
|
329
43
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}),
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
|
|
44
|
+
function ye(t) {
|
|
45
|
+
const e = [];
|
|
46
|
+
return t["package-name"] && !L(t["package-name"]) && e.push(`Invalid package name: ${t["package-name"]}`), t["base-path"] && !fe(t["base-path"]) && e.push(`Invalid base path: ${t["base-path"]}. Must start and end with "/"`), e;
|
|
47
|
+
}
|
|
48
|
+
const he = "1.1.99-alpha.0", U = {
|
|
49
|
+
version: he
|
|
50
|
+
};
|
|
51
|
+
function we() {
|
|
52
|
+
console.log(`
|
|
53
|
+
${o.bold(o.green("create-vc-app"))} - Create a new VC Shell application or generate modules/blades
|
|
54
|
+
|
|
55
|
+
${o.bold("Usage:")}
|
|
56
|
+
create-vc-app [project-name] [options] Create a new application
|
|
57
|
+
create-vc-app blade|generate Interactive generator (modules, blades, widgets)
|
|
58
|
+
|
|
59
|
+
${o.bold("Create App Options:")}
|
|
60
|
+
--name, --app-name <name> Name of the application
|
|
61
|
+
--package-name <name> Package name (defaults to app name)
|
|
62
|
+
--base-path <path> Base path for the application [default: /apps/<app-name>/]
|
|
63
|
+
--skip-module-gen Skip module generation (create only base app)
|
|
64
|
+
--skip-form-editor Skip interactive form builder
|
|
65
|
+
--form-fields <json> JSON string with form field definitions
|
|
66
|
+
--overwrite Overwrite existing files without confirmation
|
|
67
|
+
--help, -h Show this help message
|
|
68
|
+
--version, -v Show version
|
|
69
|
+
|
|
70
|
+
${o.bold("Blade Generator Options:")}
|
|
71
|
+
--module <name> Target module name
|
|
72
|
+
--type <grid|details> Blade type
|
|
73
|
+
--name <name> Blade name
|
|
74
|
+
--is-workspace Mark blade as workspace (main module blade)
|
|
75
|
+
--widget Generate widget instead of blade
|
|
76
|
+
--composable Generate composable
|
|
77
|
+
--locales Generate locales
|
|
78
|
+
--path <path> Target path
|
|
79
|
+
|
|
80
|
+
${o.bold("Interactive Generator:")}
|
|
81
|
+
The blade/generate command provides an interactive menu to:
|
|
82
|
+
- Create new modules with Grid and/or Details blades
|
|
83
|
+
- Add blades to existing modules
|
|
84
|
+
- Generate widgets for existing blades
|
|
85
|
+
- Customize form fields interactively with rich components
|
|
86
|
+
- Automatically format generated code with Prettier
|
|
87
|
+
|
|
88
|
+
Features:
|
|
89
|
+
- Smart naming (no more "offerss" bugs)
|
|
90
|
+
- Filter support in Grid blades (staged/applied architecture)
|
|
91
|
+
- Proper useModificationTracker usage in Details blades
|
|
92
|
+
- All Vc components: VcInput, VcSelect, VcEditor, VcSwitch, VcGallery, etc.
|
|
93
|
+
- TODO comments for API client integration
|
|
94
|
+
- Automatic module registration in main.ts
|
|
95
|
+
|
|
96
|
+
${o.bold("Examples:")}
|
|
97
|
+
${o.gray("# Create new application interactively")}
|
|
98
|
+
${o.gray("# Will prompt for: app name, package name, base path")}
|
|
99
|
+
${o.gray("# Then use blade generator to create initial module")}
|
|
100
|
+
create-vc-app my-app
|
|
101
|
+
|
|
102
|
+
${o.gray("# Create app without module (base only)")}
|
|
103
|
+
create-vc-app my-app --skip-module-gen
|
|
104
|
+
|
|
105
|
+
${o.gray("# Interactive blade/module generator")}
|
|
106
|
+
create-vc-app blade
|
|
107
|
+
|
|
108
|
+
${o.gray("# Create blade with custom form fields (non-interactive)")}
|
|
109
|
+
create-vc-app blade --module products --type details --name product-details \\
|
|
110
|
+
--form-fields '[{"name":"price","type":"currency","required":true},{"name":"description","type":"editor","required":false}]'
|
|
111
|
+
|
|
112
|
+
${o.gray("# Generate widget interactively")}
|
|
113
|
+
create-vc-app blade --widget
|
|
114
|
+
`);
|
|
115
|
+
}
|
|
116
|
+
function be() {
|
|
117
|
+
console.log(`create-vc-app version ${U.version}`);
|
|
118
|
+
}
|
|
119
|
+
const Se = {
|
|
338
120
|
_gitignore: ".gitignore",
|
|
339
121
|
"_yarnrc.yml": ".yarnrc.yml",
|
|
340
122
|
_browserslistrc: ".browserslistrc",
|
|
@@ -351,246 +133,1834 @@ const da = {
|
|
|
351
133
|
_vscode: ".vscode",
|
|
352
134
|
_yarn: ".yarn",
|
|
353
135
|
"_package.json": "package.json"
|
|
354
|
-
},
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
136
|
+
}, $e = [".ts", ".vue", ".js", ".json", ".md"], Z = "18.0.0";
|
|
137
|
+
function Ee() {
|
|
138
|
+
const t = process.version.slice(1), [e] = t.split(".").map(Number), [n] = Z.split(".").map(Number);
|
|
139
|
+
return {
|
|
140
|
+
compatible: e >= n,
|
|
141
|
+
currentVersion: t,
|
|
142
|
+
minVersion: Z
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
async function P(t) {
|
|
146
|
+
try {
|
|
147
|
+
const e = r.readFileSync(t, "utf-8"), n = m.extname(t);
|
|
148
|
+
let a = "typescript";
|
|
149
|
+
n === ".vue" ? a = "vue" : n === ".json" ? a = "json" : n === ".md" ? a = "markdown" : n === ".css" || n === ".scss" ? a = "css" : n === ".html" ? a = "html" : n === ".js" || n === ".mjs" || n === ".cjs" ? a = "babel" : (n === ".ts" || n === ".mts" || n === ".cts") && (a = "typescript");
|
|
150
|
+
let s = null;
|
|
151
|
+
try {
|
|
152
|
+
s = await Y.resolveConfig(t, {
|
|
153
|
+
editorconfig: !0
|
|
154
|
+
});
|
|
155
|
+
} catch {
|
|
156
|
+
}
|
|
157
|
+
const l = {
|
|
158
|
+
...{
|
|
159
|
+
endOfLine: "auto",
|
|
160
|
+
// Changed from "lf" to "auto"
|
|
161
|
+
singleAttributePerLine: !0
|
|
162
|
+
// Added for Vue files
|
|
163
|
+
},
|
|
164
|
+
...s,
|
|
165
|
+
parser: a
|
|
166
|
+
// Always use detected parser
|
|
167
|
+
}, d = await Y.format(e, l);
|
|
168
|
+
r.writeFileSync(t, d, "utf-8");
|
|
169
|
+
} catch (e) {
|
|
170
|
+
console.warn(o.yellow(`⚠️ Warning: Could not format ${t}`)), console.warn(o.yellow(` ${e.message}`));
|
|
362
171
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
172
|
+
}
|
|
173
|
+
async function te(t, e = [".ts", ".vue", ".js", ".json"]) {
|
|
174
|
+
const n = r.readdirSync(t);
|
|
175
|
+
for (const a of n) {
|
|
176
|
+
const s = m.join(t, a);
|
|
177
|
+
r.statSync(s).isDirectory() ? await te(s, e) : e.some((l) => a.endsWith(l)) && await P(s);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function W(t, e) {
|
|
181
|
+
const n = F(t), a = pe(t), s = F(a);
|
|
182
|
+
return {
|
|
183
|
+
entitySingular: t,
|
|
184
|
+
entityPlural: a,
|
|
185
|
+
moduleName: e,
|
|
186
|
+
entitySingularPascal: T(n),
|
|
187
|
+
entitySingularCamel: n,
|
|
188
|
+
entitySingularKebab: N(t),
|
|
189
|
+
entityPluralPascal: T(s),
|
|
190
|
+
entityPluralCamel: s,
|
|
191
|
+
entityPluralKebab: N(a),
|
|
192
|
+
moduleNamePascal: T(F(e)),
|
|
193
|
+
moduleNameUpperSnake: v(e).toUpperCase()
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function z(t) {
|
|
197
|
+
return {
|
|
198
|
+
"{{EntityName}}": t.entitySingularPascal,
|
|
199
|
+
"{{EntityNamePlural}}": t.entityPluralPascal,
|
|
200
|
+
"{{entityName}}": t.entitySingularCamel,
|
|
201
|
+
"{{entityNamePlural}}": t.entityPluralCamel,
|
|
202
|
+
"{{entity-name}}": t.entitySingularKebab,
|
|
203
|
+
"{{entity-name-plural}}": t.entityPluralKebab,
|
|
204
|
+
"{{entity_name}}": v(t.entitySingular),
|
|
205
|
+
"{{entity_name_plural}}": v(t.entityPlural),
|
|
206
|
+
"{{ModuleName}}": t.moduleNamePascal,
|
|
207
|
+
"{{moduleName}}": F(t.moduleName),
|
|
208
|
+
"{{module-name}}": N(t.moduleName),
|
|
209
|
+
"{{MODULE_NAME}}": t.moduleNameUpperSnake,
|
|
210
|
+
"{{MODULE_NAME_UPPERCASE}}": t.moduleNameUpperSnake
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function H(t, e) {
|
|
214
|
+
let n = t;
|
|
215
|
+
for (const [a, s] of Object.entries(e))
|
|
216
|
+
n = n.replace(new RegExp(a, "g"), s);
|
|
217
|
+
return n;
|
|
218
|
+
}
|
|
219
|
+
function ae(t) {
|
|
220
|
+
return t.replace(/'/g, "\\'").replace(/"/g, '\\"');
|
|
221
|
+
}
|
|
222
|
+
async function ne() {
|
|
223
|
+
const t = [];
|
|
224
|
+
let e = !0;
|
|
225
|
+
for (console.log(`
|
|
226
|
+
📝 Configure form fields (press Ctrl+C to skip):
|
|
227
|
+
`); e; )
|
|
228
|
+
try {
|
|
229
|
+
const n = await x(
|
|
230
|
+
[
|
|
231
|
+
{
|
|
232
|
+
type: "text",
|
|
233
|
+
name: "name",
|
|
234
|
+
message: "Field name (e.g., price, description):",
|
|
235
|
+
validate: (a) => a ? /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(a) ? !0 : "Field name must be a valid identifier (letters, numbers, underscore)" : "Field name is required"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
type: "select",
|
|
239
|
+
name: "type",
|
|
240
|
+
message: "Field type:",
|
|
241
|
+
choices: [
|
|
242
|
+
{
|
|
243
|
+
title: "Text Input",
|
|
244
|
+
value: "text"
|
|
245
|
+
/* Text */
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
title: "Textarea",
|
|
249
|
+
value: "textarea"
|
|
250
|
+
/* Textarea */
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
title: "Number",
|
|
254
|
+
value: "number"
|
|
255
|
+
/* Number */
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
title: "Date",
|
|
259
|
+
value: "date"
|
|
260
|
+
/* Date */
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
title: "Select Dropdown",
|
|
264
|
+
value: "select"
|
|
265
|
+
/* Select */
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
title: "Checkbox",
|
|
269
|
+
value: "checkbox"
|
|
270
|
+
/* Checkbox */
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
title: "Radio Button",
|
|
274
|
+
value: "radio"
|
|
275
|
+
/* RadioButton */
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
title: "Switch",
|
|
279
|
+
value: "switch"
|
|
280
|
+
/* Switch */
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
title: "Currency Input",
|
|
284
|
+
value: "currency"
|
|
285
|
+
/* Currency */
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
title: "Rich Text Editor",
|
|
289
|
+
value: "editor"
|
|
290
|
+
/* Editor */
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
title: "Image Upload",
|
|
294
|
+
value: "image"
|
|
295
|
+
/* Image */
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
title: "Multivalue Input",
|
|
299
|
+
value: "multivalue"
|
|
300
|
+
/* Multivalue */
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
title: "Gallery",
|
|
304
|
+
value: "gallery"
|
|
305
|
+
/* Gallery */
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
title: "Data Field",
|
|
309
|
+
value: "data-field"
|
|
310
|
+
/* DataField */
|
|
311
|
+
}
|
|
312
|
+
]
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
type: (a) => a === "select" || a === "radio" ? "list" : null,
|
|
316
|
+
name: "options",
|
|
317
|
+
message: "Options (comma-separated):",
|
|
318
|
+
separator: ","
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
type: "text",
|
|
322
|
+
name: "label",
|
|
323
|
+
message: "Field label (optional, press Enter to skip):",
|
|
324
|
+
initial: ""
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
type: "confirm",
|
|
328
|
+
name: "required",
|
|
329
|
+
message: "Is this field required?",
|
|
330
|
+
initial: !1
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
type: "confirm",
|
|
334
|
+
name: "addAnother",
|
|
335
|
+
message: "Add another field?",
|
|
336
|
+
initial: !0
|
|
337
|
+
}
|
|
338
|
+
],
|
|
339
|
+
{
|
|
340
|
+
onCancel: () => {
|
|
341
|
+
throw e = !1, new Error("cancelled");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
if (!n.name) {
|
|
346
|
+
e = !1;
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
t.push({
|
|
350
|
+
name: n.name,
|
|
351
|
+
type: n.type,
|
|
352
|
+
label: n.label || T(n.name),
|
|
353
|
+
required: n.required,
|
|
354
|
+
options: n.options
|
|
355
|
+
}), e = n.addAnother;
|
|
356
|
+
} catch (n) {
|
|
357
|
+
if (n.message === "cancelled")
|
|
358
|
+
break;
|
|
359
|
+
throw n;
|
|
360
|
+
}
|
|
361
|
+
return t;
|
|
362
|
+
}
|
|
363
|
+
function q(t, e) {
|
|
364
|
+
const n = v(t.name).toUpperCase(), a = t.required ? 'rules="required"' : "";
|
|
365
|
+
let s = "";
|
|
366
|
+
return t.type === "number" ? s = 'type="number"' : t.type === "date" && (s = 'type="date"'), ` <Field
|
|
367
|
+
v-slot="{ field, errorMessage, handleChange, errors }"
|
|
368
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
369
|
+
:model-value="item.${t.name}"
|
|
370
|
+
name="${t.name}"
|
|
371
|
+
${a}
|
|
372
|
+
>
|
|
373
|
+
<VcInput
|
|
374
|
+
v-bind="field"
|
|
375
|
+
v-model="item.${t.name}"
|
|
376
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
377
|
+
:placeholder="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}_PLACEHOLDER')"
|
|
378
|
+
${s}
|
|
379
|
+
${t.required ? "required" : ""}
|
|
380
|
+
clearable
|
|
381
|
+
:error="!!errors.length"
|
|
382
|
+
:error-message="errorMessage"
|
|
383
|
+
@update:model-value="handleChange"
|
|
384
|
+
/>
|
|
385
|
+
</Field>`;
|
|
386
|
+
}
|
|
387
|
+
function ve(t, e) {
|
|
388
|
+
const n = v(t.name).toUpperCase();
|
|
389
|
+
return ` <VcTextarea
|
|
390
|
+
v-model="item.${t.name}"
|
|
391
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
392
|
+
:placeholder="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}_PLACEHOLDER')"
|
|
393
|
+
${t.required ? "required" : ""}
|
|
394
|
+
clearable
|
|
395
|
+
/>`;
|
|
396
|
+
}
|
|
397
|
+
function Ie(t, e) {
|
|
398
|
+
const n = v(t.name).toUpperCase(), a = t.required ? 'rules="required"' : "", s = t.options?.map((c) => {
|
|
399
|
+
const l = ae(c);
|
|
400
|
+
return `{ value: '${l}', label: '${l}' }`;
|
|
401
|
+
}).join(", ") || "";
|
|
402
|
+
return ` <Field
|
|
403
|
+
v-slot="{ errorMessage, handleChange, errors }"
|
|
404
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
405
|
+
:model-value="item.${t.name}"
|
|
406
|
+
name="${t.name}"
|
|
407
|
+
${a}
|
|
408
|
+
>
|
|
409
|
+
<VcSelect
|
|
410
|
+
v-model="item.${t.name}"
|
|
411
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
412
|
+
:placeholder="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}_PLACEHOLDER')"
|
|
413
|
+
:options="[${s}]"
|
|
414
|
+
option-value="value"
|
|
415
|
+
option-label="label"
|
|
416
|
+
searchable
|
|
417
|
+
${t.required ? "required" : ""}
|
|
418
|
+
:clearable="false"
|
|
419
|
+
:error="!!errors.length"
|
|
420
|
+
:error-message="errorMessage"
|
|
421
|
+
@update:model-value="handleChange"
|
|
422
|
+
/>
|
|
423
|
+
</Field>`;
|
|
424
|
+
}
|
|
425
|
+
function Ce(t, e) {
|
|
426
|
+
const n = v(t.name).toUpperCase(), a = t.required ? 'rules="required"' : "";
|
|
427
|
+
return ` <Field
|
|
428
|
+
v-slot="{ errorMessage, handleChange, errors }"
|
|
429
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
430
|
+
:model-value="item.${t.name}"
|
|
431
|
+
name="${t.name}"
|
|
432
|
+
${a}
|
|
433
|
+
>
|
|
434
|
+
<VcEditor
|
|
435
|
+
v-model="item.${t.name}"
|
|
436
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
437
|
+
:placeholder="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}_PLACEHOLDER')"
|
|
438
|
+
${t.required ? "required" : ""}
|
|
439
|
+
:error="!!errors.length"
|
|
440
|
+
:error-message="errorMessage"
|
|
441
|
+
@update:model-value="handleChange"
|
|
442
|
+
/>
|
|
443
|
+
</Field>`;
|
|
444
|
+
}
|
|
445
|
+
function xe(t, e) {
|
|
446
|
+
const n = v(t.name).toUpperCase();
|
|
447
|
+
return ` <VcSwitch
|
|
448
|
+
v-model="item.${t.name}"
|
|
449
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
450
|
+
:tooltip="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}_TOOLTIP')"
|
|
451
|
+
:true-value="true"
|
|
452
|
+
:false-value="false"
|
|
453
|
+
/>`;
|
|
454
|
+
}
|
|
455
|
+
function Ae(t, e) {
|
|
456
|
+
const n = v(t.name).toUpperCase();
|
|
457
|
+
return ` <VcCard :header="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')">
|
|
458
|
+
<VcGallery
|
|
459
|
+
:images="item.${t.name}"
|
|
460
|
+
multiple
|
|
461
|
+
@upload="assetsHandler.upload"
|
|
462
|
+
@sort="assetsHandler.edit"
|
|
463
|
+
@remove="assetsHandler.remove"
|
|
464
|
+
@edit="onGalleryItemEdit"
|
|
465
|
+
/>
|
|
466
|
+
</VcCard>`;
|
|
467
|
+
}
|
|
468
|
+
function Ne(t) {
|
|
469
|
+
return `
|
|
470
|
+
// VcGallery Assets Handler Setup
|
|
471
|
+
// TODO: Import Image type from your API client (e.g., import { Image, IImage } from "@your-app/api/client")
|
|
472
|
+
const { upload, remove, edit, loading: assetsLoading } = useAssets();
|
|
384
473
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
474
|
+
/**
|
|
475
|
+
* Handles asset operations for VcGallery
|
|
476
|
+
* TODO: Update the path '${t}s/\${item.value?.id}' to match your entity structure
|
|
477
|
+
*/
|
|
478
|
+
const assetsHandler = {
|
|
479
|
+
loading: assetsLoading,
|
|
480
|
+
async upload(files: FileList, startingSortOrder?: number) {
|
|
481
|
+
// TODO: Update path to match your entity (e.g., 'products/\${item.value?.id}')
|
|
482
|
+
const uploaded = await upload(files, \`${t}s/\${item.value?.id}\`, startingSortOrder);
|
|
483
|
+
// TODO: If using typed Image class, map: uploaded.map((x) => new Image(x))
|
|
484
|
+
item.value.images = [...(item.value?.images ?? []), ...uploaded];
|
|
485
|
+
},
|
|
486
|
+
async remove(file: ICommonAsset) {
|
|
487
|
+
if (await showConfirmation(t("COMMON.ALERTS.IMAGE_DELETE_CONFIRMATION"))) {
|
|
488
|
+
const remainingImages = remove([file], item.value?.images ?? []);
|
|
489
|
+
// TODO: If using typed Image class, map: remainingImages.map((x) => new Image(x))
|
|
490
|
+
item.value.images = remainingImages;
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
edit(files: ICommonAsset[]) {
|
|
494
|
+
const edited = edit(files, item.value?.images ?? []);
|
|
495
|
+
// TODO: If using typed Image class, map: edited.map((x) => new Image(x))
|
|
496
|
+
item.value.images = edited;
|
|
497
|
+
},
|
|
498
|
+
};
|
|
390
499
|
|
|
391
|
-
|
|
392
|
-
|
|
500
|
+
/**
|
|
501
|
+
* Opens asset details blade for editing
|
|
502
|
+
* TODO: Create AssetsDetails blade or remove this handler
|
|
503
|
+
*/
|
|
504
|
+
const onGalleryItemEdit = (asset: ICommonAsset) => {
|
|
505
|
+
// openBlade({
|
|
506
|
+
// blade: { name: "AssetsDetails" },
|
|
507
|
+
// options: {
|
|
508
|
+
// asset: asset,
|
|
509
|
+
// assetEditHandler: (file: ICommonAsset) => assetsHandler.edit?.([file]),
|
|
510
|
+
// assetRemoveHandler: (file: ICommonAsset) => assetsHandler.remove?.(file),
|
|
511
|
+
// },
|
|
512
|
+
// });
|
|
513
|
+
console.log("Gallery item clicked:", asset);
|
|
514
|
+
};
|
|
515
|
+
`;
|
|
516
|
+
}
|
|
517
|
+
function Pe(t, e) {
|
|
518
|
+
const n = v(t.name).toUpperCase();
|
|
519
|
+
return ` <VcField
|
|
520
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
521
|
+
:model-value="item.${t.name}"
|
|
522
|
+
orientation="horizontal"
|
|
523
|
+
:aspect-ratio="[1, 2]"
|
|
524
|
+
type="text"
|
|
525
|
+
/>`;
|
|
526
|
+
}
|
|
527
|
+
function Oe(t, e) {
|
|
528
|
+
const n = v(t.name).toUpperCase(), a = t.required ? 'rules="required"' : "";
|
|
529
|
+
return ` <Field
|
|
530
|
+
v-slot="{ field, errorMessage, handleChange, errors }"
|
|
531
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
532
|
+
:model-value="item.${t.name}"
|
|
533
|
+
name="${t.name}"
|
|
534
|
+
${a}
|
|
535
|
+
>
|
|
536
|
+
<VcInputCurrency
|
|
537
|
+
v-bind="field"
|
|
538
|
+
v-model="item.${t.name}"
|
|
539
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
540
|
+
${t.required ? "required" : ""}
|
|
541
|
+
clearable
|
|
542
|
+
:error="!!errors.length"
|
|
543
|
+
:error-message="errorMessage"
|
|
544
|
+
@update:model-value="handleChange"
|
|
545
|
+
/>
|
|
546
|
+
</Field>`;
|
|
547
|
+
}
|
|
548
|
+
function Te(t, e) {
|
|
549
|
+
const n = v(t.name).toUpperCase(), a = t.required ? 'rules="required"' : "", s = t.options?.map((c) => {
|
|
550
|
+
const l = ae(c);
|
|
551
|
+
return ` <VcRadioButton
|
|
552
|
+
:model-value="item.${t.name}"
|
|
553
|
+
value="${l}"
|
|
554
|
+
:label="'${l}'"
|
|
555
|
+
@update:model-value="handleChange"
|
|
556
|
+
/>`;
|
|
557
|
+
}).join(`
|
|
558
|
+
`) || "";
|
|
559
|
+
return ` <Field
|
|
560
|
+
v-slot="{ field, errorMessage, handleChange, errors }"
|
|
561
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
562
|
+
:model-value="item.${t.name}"
|
|
563
|
+
name="${t.name}"
|
|
564
|
+
${a}
|
|
565
|
+
>
|
|
566
|
+
<div class="tw-space-y-2">
|
|
567
|
+
${s}
|
|
568
|
+
</div>
|
|
569
|
+
<div v-if="errors.length" class="tw-text-red-500 tw-text-sm">{{ errorMessage }}</div>
|
|
570
|
+
</Field>`;
|
|
571
|
+
}
|
|
572
|
+
function Fe(t, e) {
|
|
573
|
+
const n = v(t.name).toUpperCase();
|
|
574
|
+
return ` <VcCheckbox
|
|
575
|
+
v-model="item.${t.name}"
|
|
576
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
577
|
+
/>`;
|
|
578
|
+
}
|
|
579
|
+
function De(t, e) {
|
|
580
|
+
const n = v(t.name).toUpperCase(), a = t.required ? 'rules="required"' : "";
|
|
581
|
+
return ` <!-- TODO: Configure VcMultivalue dictionary and placeholder -->
|
|
582
|
+
<Field
|
|
583
|
+
v-slot="{ errorMessage, handleChange, errors }"
|
|
584
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
585
|
+
:model-value="item.${t.name}"
|
|
586
|
+
name="${t.name}"
|
|
587
|
+
${a}
|
|
588
|
+
>
|
|
589
|
+
<VcMultivalue
|
|
590
|
+
v-model="item.${t.name}"
|
|
591
|
+
:label="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}')"
|
|
592
|
+
:placeholder="$t('${e}.PAGES.DETAILS.FORM.INFO.${n}_PLACEHOLDER')"
|
|
593
|
+
${t.required ? "required" : ""}
|
|
594
|
+
:error="!!errors.length"
|
|
595
|
+
:error-message="errorMessage"
|
|
596
|
+
@update:model-value="handleChange"
|
|
597
|
+
/>
|
|
598
|
+
</Field>`;
|
|
599
|
+
}
|
|
600
|
+
function Me(t) {
|
|
601
|
+
return t.some(
|
|
602
|
+
(e) => e.type === "gallery"
|
|
603
|
+
/* Gallery */
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
function R(t, e) {
|
|
607
|
+
return t.length === 0 ? oe(e) : t.map((n) => {
|
|
608
|
+
switch (n.type) {
|
|
609
|
+
case "text":
|
|
610
|
+
case "number":
|
|
611
|
+
case "date":
|
|
612
|
+
return q(n, e);
|
|
613
|
+
case "textarea":
|
|
614
|
+
return ve(n, e);
|
|
615
|
+
case "select":
|
|
616
|
+
return Ie(n, e);
|
|
617
|
+
case "editor":
|
|
618
|
+
return Ce(n, e);
|
|
619
|
+
case "switch":
|
|
620
|
+
return xe(n, e);
|
|
621
|
+
case "gallery":
|
|
622
|
+
return Ae(n, e);
|
|
623
|
+
case "data-field":
|
|
624
|
+
return Pe(n, e);
|
|
625
|
+
case "currency":
|
|
626
|
+
return Oe(n, e);
|
|
627
|
+
case "radio":
|
|
628
|
+
return Te(n, e);
|
|
629
|
+
case "checkbox":
|
|
630
|
+
return Fe(n, e);
|
|
631
|
+
case "multivalue":
|
|
632
|
+
return De(n, e);
|
|
633
|
+
case "image":
|
|
634
|
+
return q({
|
|
635
|
+
...n,
|
|
636
|
+
type: "text"
|
|
637
|
+
/* Text */
|
|
638
|
+
}, e);
|
|
639
|
+
default:
|
|
640
|
+
return q(n, e);
|
|
641
|
+
}
|
|
642
|
+
}).join(`
|
|
393
643
|
|
|
394
|
-
${t.bold("Available variants:")}
|
|
395
|
-
${j.map((e) => ` ${e.name.padEnd(10)} - ${e.display}`).join(`
|
|
396
|
-
`)}
|
|
397
644
|
`);
|
|
398
645
|
}
|
|
399
|
-
function
|
|
400
|
-
|
|
646
|
+
function k(t) {
|
|
647
|
+
const e = {};
|
|
648
|
+
for (const n of t) {
|
|
649
|
+
const a = v(n.name).toUpperCase();
|
|
650
|
+
e[a] = n.label || T(n.name);
|
|
651
|
+
}
|
|
652
|
+
return e;
|
|
401
653
|
}
|
|
402
|
-
function
|
|
403
|
-
return
|
|
654
|
+
function oe(t) {
|
|
655
|
+
return ` <Field
|
|
656
|
+
v-slot="{ field, errorMessage, handleChange, errors }"
|
|
657
|
+
:label="$t('${t}.PAGES.DETAILS.FORM.INFO.NAME')"
|
|
658
|
+
:model-value="item.name"
|
|
659
|
+
name="name"
|
|
660
|
+
rules="required"
|
|
661
|
+
>
|
|
662
|
+
<VcInput
|
|
663
|
+
v-bind="field"
|
|
664
|
+
v-model="item.name"
|
|
665
|
+
:label="$t('${t}.PAGES.DETAILS.FORM.INFO.NAME')"
|
|
666
|
+
:placeholder="$t('${t}.PAGES.DETAILS.FORM.INFO.NAME_PLACEHOLDER')"
|
|
667
|
+
required
|
|
668
|
+
clearable
|
|
669
|
+
:error="!!errors.length"
|
|
670
|
+
:error-message="errorMessage"
|
|
671
|
+
@update:model-value="handleChange"
|
|
672
|
+
/>
|
|
673
|
+
</Field>
|
|
674
|
+
|
|
675
|
+
<VcField
|
|
676
|
+
:label="$t('${t}.PAGES.DETAILS.FORM.INFO.CREATED_DATE')"
|
|
677
|
+
:model-value="createdDate"
|
|
678
|
+
orientation="horizontal"
|
|
679
|
+
:aspect-ratio="[1, 2]"
|
|
680
|
+
type="text"
|
|
681
|
+
/>`;
|
|
404
682
|
}
|
|
405
|
-
function
|
|
406
|
-
|
|
683
|
+
async function Le(t, e, n) {
|
|
684
|
+
const a = m.join(t, "src", "main.ts");
|
|
685
|
+
if (!r.existsSync(a))
|
|
686
|
+
return console.log(o.yellow(`⚠️ main.ts not found at ${a}`)), console.log(o.yellow(" Please register the module manually.")), !1;
|
|
687
|
+
try {
|
|
688
|
+
let s = r.readFileSync(a, "utf-8");
|
|
689
|
+
const c = `import ${n}Module from "./modules/${e}";`, l = `.use(${n}Module, { router })`;
|
|
690
|
+
if (s.includes(c) || s.includes(`from "./modules/${e}"`))
|
|
691
|
+
return console.log(o.yellow(` Module ${e} is already registered in main.ts`)), !0;
|
|
692
|
+
const d = /^import\s+.+\s+from\s+['"]\.\/.+['"];?\s*$/gm, w = s.match(d);
|
|
693
|
+
if (w && w.length > 0) {
|
|
694
|
+
const p = w[w.length - 1], i = s.lastIndexOf(p);
|
|
695
|
+
s = s.slice(0, i + p.length) + `
|
|
696
|
+
${c}` + s.slice(i + p.length);
|
|
697
|
+
} else {
|
|
698
|
+
const p = s.search(/^import/m);
|
|
699
|
+
p !== -1 && (s = s.slice(0, p) + `${c}
|
|
700
|
+
` + s.slice(p));
|
|
701
|
+
}
|
|
702
|
+
const u = /(app\.use|\.use)\(router\)/, g = s.match(u);
|
|
703
|
+
if (g) {
|
|
704
|
+
const p = s.indexOf(g[0]);
|
|
705
|
+
let i = p;
|
|
706
|
+
for (; i > 0 && s[i - 1] !== `
|
|
707
|
+
`; )
|
|
708
|
+
i--;
|
|
709
|
+
const f = s.slice(i, p).match(/^\s*/)?.[0] || " ";
|
|
710
|
+
s = s.slice(0, i) + `${f}${l}
|
|
711
|
+
` + s.slice(i);
|
|
712
|
+
} else {
|
|
713
|
+
const p = /(app\.use|\.use)\([^)]+\)/g, i = [...s.matchAll(p)];
|
|
714
|
+
if (i.length > 0) {
|
|
715
|
+
const f = i[i.length - 1], y = f.index + f[0].length;
|
|
716
|
+
s = s.slice(0, y) + `
|
|
717
|
+
${l}` + s.slice(y);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
return r.writeFileSync(a, s, "utf-8"), console.log(o.green("✓ Registered module in main.ts")), !0;
|
|
721
|
+
} catch (s) {
|
|
722
|
+
return console.log(o.yellow(`⚠️ Failed to auto-register module: ${s.message}`)), console.log(o.yellow(" Please register manually.")), !1;
|
|
723
|
+
}
|
|
407
724
|
}
|
|
408
|
-
function
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
725
|
+
async function K(t, e) {
|
|
726
|
+
const n = m.join(t, "pages"), a = m.join(n, "index.ts");
|
|
727
|
+
try {
|
|
728
|
+
let s = "";
|
|
729
|
+
r.existsSync(a) && (s = r.readFileSync(a, "utf-8"));
|
|
730
|
+
for (const c of e) {
|
|
731
|
+
const l = `export { default as ${c.exportName} } from "./${c.fileName}.vue";`;
|
|
732
|
+
!s.includes(l) && !s.includes(`from "./${c.fileName}.vue"`) && (s += l + `
|
|
733
|
+
`);
|
|
734
|
+
}
|
|
735
|
+
return r.writeFileSync(a, s, "utf-8"), await P(a), console.log(o.green("✓ Updated pages/index.ts")), !0;
|
|
736
|
+
} catch (s) {
|
|
737
|
+
return console.log(o.yellow(`⚠️ Failed to update pages/index.ts: ${s.message}`)), !1;
|
|
738
|
+
}
|
|
416
739
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
740
|
+
class O extends Error {
|
|
741
|
+
exitCode;
|
|
742
|
+
constructor(e, n = 1) {
|
|
743
|
+
super(e), this.name = "CLIError", this.exitCode = n;
|
|
744
|
+
}
|
|
420
745
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
746
|
+
class B extends O {
|
|
747
|
+
issues;
|
|
748
|
+
constructor(e) {
|
|
749
|
+
super("Validation failed", 1), this.name = "ValidationError", this.issues = e;
|
|
750
|
+
}
|
|
424
751
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
v: "version"
|
|
430
|
-
},
|
|
431
|
-
boolean: ["help", "version", "mocks", "overwrite"],
|
|
432
|
-
string: ["name", "app-name", "package-name", "variant", "module-name", "base-path"]
|
|
433
|
-
});
|
|
752
|
+
class E extends O {
|
|
753
|
+
constructor() {
|
|
754
|
+
super("Operation cancelled by user", 0), this.name = "UserCancelledError";
|
|
755
|
+
}
|
|
434
756
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
if (e.help) {
|
|
438
|
-
ga();
|
|
757
|
+
function se(t) {
|
|
758
|
+
if (!r.existsSync(t))
|
|
439
759
|
return;
|
|
760
|
+
const e = m.relative(_(), t) || t;
|
|
761
|
+
throw new O(`File already exists: ${e}. Remove it or rename before regenerating.`);
|
|
762
|
+
}
|
|
763
|
+
async function le(t = {}) {
|
|
764
|
+
console.log(`
|
|
765
|
+
${o.bold(o.green("@vc-shell/create-vc-app Generator"))}
|
|
766
|
+
`);
|
|
767
|
+
const e = t.path || _(), n = m.join(e, "package.json");
|
|
768
|
+
if (!r.existsSync(n))
|
|
769
|
+
throw new O("❌ No package.json found. Are you in a project directory?");
|
|
770
|
+
try {
|
|
771
|
+
if (t.module && t.type && t.name) {
|
|
772
|
+
console.log(o.cyan(`📝 Running in non-interactive mode
|
|
773
|
+
`)), await Re(e, {
|
|
774
|
+
moduleName: N(t.module),
|
|
775
|
+
// Normalize to kebab-case
|
|
776
|
+
bladeType: t.type,
|
|
777
|
+
entityName: t.name,
|
|
778
|
+
isWorkspace: t.isWorkspace ?? !1,
|
|
779
|
+
includeComposable: t.composable ?? !0,
|
|
780
|
+
includeLocales: t.locales ?? !0,
|
|
781
|
+
formFields: t.formFields,
|
|
782
|
+
skipFormEditor: t.skipFormEditor
|
|
783
|
+
});
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
if (t.widget) {
|
|
787
|
+
await Q(e);
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
let a;
|
|
791
|
+
t._skipActionPrompt ? a = "module" : a = (await x(
|
|
792
|
+
{
|
|
793
|
+
type: "select",
|
|
794
|
+
name: "action",
|
|
795
|
+
message: "What would you like to generate?",
|
|
796
|
+
choices: [
|
|
797
|
+
{ title: "Module (with blades)", value: "module" },
|
|
798
|
+
{ title: "Blade (in existing module)", value: "blade" },
|
|
799
|
+
{ title: "Widget (for existing blade)", value: "widget" }
|
|
800
|
+
]
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
onCancel: () => {
|
|
804
|
+
throw new E();
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
)).action, a === "module" ? await ke(e) : a === "blade" ? await je(e) : a === "widget" && await Q(e);
|
|
808
|
+
} catch (a) {
|
|
809
|
+
if (a instanceof E)
|
|
810
|
+
throw new E();
|
|
811
|
+
if (a instanceof O)
|
|
812
|
+
throw a;
|
|
813
|
+
const s = a instanceof Error ? a.message : String(a), c = a instanceof Error && a.stack ? `
|
|
814
|
+
${a.stack}` : "";
|
|
815
|
+
throw new O(`
|
|
816
|
+
❌ Generation failed: ${s}${c ? `
|
|
817
|
+
${c}` : ""}`);
|
|
440
818
|
}
|
|
441
|
-
|
|
442
|
-
|
|
819
|
+
}
|
|
820
|
+
async function Re(t, e) {
|
|
821
|
+
const n = m.join(t, "src", "modules"), a = m.join(n, e.moduleName);
|
|
822
|
+
if (!r.existsSync(a)) {
|
|
823
|
+
console.log(o.cyan(`📦 Module "${e.moduleName}" not found. Creating new module...
|
|
824
|
+
`));
|
|
825
|
+
const y = {
|
|
826
|
+
moduleName: e.moduleName,
|
|
827
|
+
entitySingular: e.moduleName,
|
|
828
|
+
createBothBlades: !1,
|
|
829
|
+
createGridBlade: e.bladeType === "grid",
|
|
830
|
+
createDetailsBlade: e.bladeType === "details",
|
|
831
|
+
gridIsWorkspace: e.isWorkspace && e.bladeType === "grid",
|
|
832
|
+
detailsIsWorkspace: e.isWorkspace && e.bladeType === "details",
|
|
833
|
+
includeComposables: e.includeComposable,
|
|
834
|
+
includeLocales: e.includeLocales,
|
|
835
|
+
customizeForm: !1
|
|
836
|
+
};
|
|
837
|
+
await re(t, y, e.formFields, e.skipFormEditor), console.log(o.green(`✅ Module "${e.moduleName}" with ${e.bladeType} blade created successfully
|
|
838
|
+
`));
|
|
443
839
|
return;
|
|
444
840
|
}
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
841
|
+
const s = W(e.entityName, e.moduleName), c = z(s), l = V(), d = [];
|
|
842
|
+
let w = "", u = {}, g = [];
|
|
843
|
+
if (e.bladeType === "details" && e.formFields)
|
|
844
|
+
try {
|
|
845
|
+
g = JSON.parse(e.formFields), g.length > 0 && (w = R(g, s.moduleNameUpperSnake), u = k(g));
|
|
846
|
+
} catch (y) {
|
|
847
|
+
throw console.error(o.red("❌ Invalid form-fields JSON")), y;
|
|
848
|
+
}
|
|
849
|
+
const p = await j(
|
|
850
|
+
l,
|
|
851
|
+
a,
|
|
852
|
+
e.bladeType,
|
|
853
|
+
c,
|
|
854
|
+
e.isWorkspace,
|
|
855
|
+
w,
|
|
856
|
+
g
|
|
857
|
+
);
|
|
858
|
+
if (d.push(p), e.includeComposable) {
|
|
859
|
+
const y = await G(
|
|
860
|
+
l,
|
|
861
|
+
a,
|
|
862
|
+
e.bladeType,
|
|
863
|
+
s,
|
|
864
|
+
c
|
|
865
|
+
);
|
|
866
|
+
d.push(y);
|
|
867
|
+
const b = m.join(a, "composables", "index.ts"), h = `export * from "./${e.bladeType === "grid" ? `use${s.entitySingularPascal}List` : `use${s.entitySingularPascal}Details`}";
|
|
868
|
+
`;
|
|
869
|
+
r.existsSync(b) ? r.readFileSync(b, "utf-8").includes(h) || r.appendFileSync(b, h) : r.writeFileSync(b, h);
|
|
870
|
+
}
|
|
871
|
+
const i = e.bladeType === "grid" ? `${s.entitySingularPascal}List` : `${s.entitySingularPascal}Details`, f = e.bladeType === "grid" ? c["{{entity-name-plural}}"] : `${c["{{entity-name}}"]}-details`;
|
|
872
|
+
if (await K(a, [{ exportName: i, fileName: f }]), e.includeLocales && Object.keys(u).length > 0) {
|
|
873
|
+
const y = m.join(a, "locales", "en.json");
|
|
874
|
+
if (r.existsSync(y)) {
|
|
875
|
+
const b = JSON.parse(r.readFileSync(y, "utf-8"));
|
|
876
|
+
b.PAGES || (b.PAGES = {}), b.PAGES.DETAILS || (b.PAGES.DETAILS = {}), b.PAGES.DETAILS.FORM || (b.PAGES.DETAILS.FORM = {}), b.PAGES.DETAILS.FORM.INFO || (b.PAGES.DETAILS.FORM.INFO = {}), Object.assign(b.PAGES.DETAILS.FORM.INFO, u), r.writeFileSync(y, JSON.stringify(b, null, 2), "utf-8"), d.push(y);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
console.log(o.cyan(`
|
|
880
|
+
✨ Formatting files with Prettier...
|
|
881
|
+
`));
|
|
882
|
+
for (const y of d)
|
|
883
|
+
await P(y);
|
|
884
|
+
console.log(o.green(`
|
|
885
|
+
✅ Blade generated successfully!
|
|
886
|
+
`));
|
|
887
|
+
}
|
|
888
|
+
async function ke(t, e, n, a) {
|
|
889
|
+
console.log(o.cyan(`
|
|
890
|
+
📦 Creating new module
|
|
891
|
+
`));
|
|
892
|
+
let s;
|
|
893
|
+
{
|
|
894
|
+
let l = {
|
|
895
|
+
...await x(
|
|
469
896
|
[
|
|
470
897
|
{
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
message:
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
},
|
|
478
|
-
{
|
|
479
|
-
type: () => !s.existsSync(o) || q(o) ? null : "confirm",
|
|
480
|
-
name: "overwrite",
|
|
481
|
-
message: () => (o === "." ? "Current directory" : `Target directory "${o}"`) + " is not empty. Remove existing files and continue?"
|
|
482
|
-
},
|
|
483
|
-
{
|
|
484
|
-
type: (n, { overwrite: g }) => {
|
|
485
|
-
if (g === !1)
|
|
486
|
-
throw new Error(t.red("✖") + " Operation cancelled");
|
|
487
|
-
return null;
|
|
488
|
-
},
|
|
489
|
-
name: "overwriteChecker"
|
|
490
|
-
},
|
|
491
|
-
{
|
|
492
|
-
name: "packageName",
|
|
493
|
-
type: () => w(u()) ? null : "text",
|
|
494
|
-
message: t.reset("Package name:"),
|
|
495
|
-
initial: () => p(u()),
|
|
496
|
-
validate: (n) => w(n) || "Invalid package.json name"
|
|
898
|
+
type: "text",
|
|
899
|
+
name: "moduleName",
|
|
900
|
+
message: "Module name (e.g., products, orders):",
|
|
901
|
+
validate: (d) => d.length > 0 ? !0 : "Module name is required",
|
|
902
|
+
format: (d) => N(d)
|
|
903
|
+
// Normalize to kebab-case
|
|
497
904
|
},
|
|
498
905
|
{
|
|
499
|
-
name: "basePath",
|
|
500
906
|
type: "text",
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
907
|
+
name: "entitySingular",
|
|
908
|
+
message: "Entity name (e.g., Product, Order):",
|
|
909
|
+
validate: (d) => d.length > 0 ? !0 : "Entity name is required"
|
|
504
910
|
},
|
|
505
911
|
{
|
|
506
|
-
type: "
|
|
507
|
-
name: "
|
|
508
|
-
message:
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
912
|
+
type: "confirm",
|
|
913
|
+
name: "createBothBlades",
|
|
914
|
+
message: "Create both Grid and Details blades?",
|
|
915
|
+
initial: !0
|
|
916
|
+
}
|
|
917
|
+
],
|
|
918
|
+
{
|
|
919
|
+
onCancel: () => {
|
|
920
|
+
throw new E();
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
),
|
|
924
|
+
createGridBlade: !1,
|
|
925
|
+
createDetailsBlade: !1,
|
|
926
|
+
gridIsWorkspace: !1,
|
|
927
|
+
detailsIsWorkspace: !1,
|
|
928
|
+
includeComposables: !0,
|
|
929
|
+
includeLocales: !0,
|
|
930
|
+
customizeForm: !1
|
|
931
|
+
};
|
|
932
|
+
if (l.createBothBlades) {
|
|
933
|
+
const d = await x(
|
|
934
|
+
{
|
|
935
|
+
type: "select",
|
|
936
|
+
name: "workspace",
|
|
937
|
+
message: "Which blade should be the workspace blade (main module blade)?",
|
|
938
|
+
choices: [
|
|
939
|
+
{ title: "Grid blade", value: "grid" },
|
|
940
|
+
{ title: "Details blade", value: "details" },
|
|
941
|
+
{ title: "None", value: "none" }
|
|
942
|
+
]
|
|
943
|
+
},
|
|
944
|
+
{
|
|
945
|
+
onCancel: () => {
|
|
946
|
+
throw new E();
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
);
|
|
950
|
+
l.createGridBlade = !0, l.createDetailsBlade = !0, l.gridIsWorkspace = d.workspace === "grid", l.detailsIsWorkspace = d.workspace === "details";
|
|
951
|
+
} else {
|
|
952
|
+
const d = await x(
|
|
953
|
+
[
|
|
514
954
|
{
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
message:
|
|
518
|
-
|
|
519
|
-
|
|
955
|
+
type: "select",
|
|
956
|
+
name: "bladeType",
|
|
957
|
+
message: "Which blade type?",
|
|
958
|
+
choices: [
|
|
959
|
+
{ title: "Grid (List with table, search, pagination)", value: "grid" },
|
|
960
|
+
{ title: "Details (Form with validation and toolbar)", value: "details" }
|
|
961
|
+
]
|
|
520
962
|
},
|
|
521
963
|
{
|
|
522
|
-
name: "mocks",
|
|
523
964
|
type: "confirm",
|
|
524
|
-
|
|
525
|
-
|
|
965
|
+
name: "isWorkspace",
|
|
966
|
+
message: "Make this a workspace blade (main module blade)?",
|
|
967
|
+
initial: !0
|
|
526
968
|
}
|
|
527
969
|
],
|
|
528
970
|
{
|
|
529
971
|
onCancel: () => {
|
|
530
|
-
throw new
|
|
972
|
+
throw new E();
|
|
531
973
|
}
|
|
532
974
|
}
|
|
533
975
|
);
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
976
|
+
l.createGridBlade = d.bladeType === "grid", l.createDetailsBlade = d.bladeType === "details", l.gridIsWorkspace = l.createGridBlade && d.isWorkspace, l.detailsIsWorkspace = l.createDetailsBlade && d.isWorkspace;
|
|
977
|
+
}
|
|
978
|
+
if (l.createDetailsBlade) {
|
|
979
|
+
const d = await x(
|
|
980
|
+
{
|
|
981
|
+
type: "confirm",
|
|
982
|
+
name: "customizeForm",
|
|
983
|
+
message: "Customize form fields interactively?",
|
|
984
|
+
initial: !1
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
onCancel: () => {
|
|
988
|
+
throw new E();
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
);
|
|
992
|
+
l.customizeForm = d.customizeForm;
|
|
993
|
+
}
|
|
994
|
+
s = l;
|
|
995
|
+
}
|
|
996
|
+
await re(t, s, n, a);
|
|
997
|
+
}
|
|
998
|
+
async function re(t, e, n, a) {
|
|
999
|
+
try {
|
|
1000
|
+
const s = W(e.entitySingular, e.moduleName), c = z(s), l = m.join(t, "src", "modules", e.moduleName);
|
|
1001
|
+
if (r.existsSync(l) && !We(l))
|
|
1002
|
+
throw new O(
|
|
1003
|
+
`Module "${e.moduleName}" already exists and is not empty. Use the blade generator to extend it instead of recreating.`
|
|
1004
|
+
);
|
|
1005
|
+
console.log(o.cyan(`
|
|
1006
|
+
📁 Creating module structure...
|
|
1007
|
+
`));
|
|
1008
|
+
const d = [
|
|
1009
|
+
l,
|
|
1010
|
+
m.join(l, "pages"),
|
|
1011
|
+
m.join(l, "composables"),
|
|
1012
|
+
m.join(l, "locales"),
|
|
1013
|
+
m.join(l, "components"),
|
|
1014
|
+
m.join(l, "components", "widgets")
|
|
1015
|
+
];
|
|
1016
|
+
for (const h of d)
|
|
1017
|
+
if (!r.existsSync(h))
|
|
1018
|
+
try {
|
|
1019
|
+
r.mkdirSync(h, { recursive: !0 }), console.log(o.green(`✓ Created directory: ${m.relative(t, h)}`));
|
|
1020
|
+
} catch ($) {
|
|
1021
|
+
throw new Error(`Failed to create directory ${h}: ${$.message}`);
|
|
1022
|
+
}
|
|
1023
|
+
const w = V(), u = [];
|
|
1024
|
+
let g = "", p = {};
|
|
1025
|
+
if (e.createGridBlade) {
|
|
1026
|
+
const h = await j(w, l, "grid", c, e.gridIsWorkspace);
|
|
1027
|
+
u.push(h);
|
|
1028
|
+
}
|
|
1029
|
+
let i = [];
|
|
1030
|
+
if (e.createDetailsBlade) {
|
|
1031
|
+
if (n)
|
|
1032
|
+
try {
|
|
1033
|
+
i = JSON.parse(n), i.length > 0 && (g = R(i, s.moduleNameUpperSnake), p = k(i));
|
|
1034
|
+
} catch ($) {
|
|
1035
|
+
throw console.error(o.red("❌ Invalid form-fields JSON")), $;
|
|
1036
|
+
}
|
|
1037
|
+
else e.customizeForm && !a && (i = await ne(), i.length > 0 && (g = R(i, s.moduleNameUpperSnake), p = k(i)));
|
|
1038
|
+
const h = await j(
|
|
1039
|
+
w,
|
|
1040
|
+
l,
|
|
1041
|
+
"details",
|
|
1042
|
+
c,
|
|
1043
|
+
e.detailsIsWorkspace,
|
|
1044
|
+
g,
|
|
1045
|
+
i
|
|
1046
|
+
);
|
|
1047
|
+
u.push(h);
|
|
1048
|
+
}
|
|
1049
|
+
if (e.includeComposables) {
|
|
1050
|
+
if (e.createGridBlade) {
|
|
1051
|
+
const $ = await G(w, l, "grid", s, c);
|
|
1052
|
+
u.push($);
|
|
1053
|
+
}
|
|
1054
|
+
if (e.createDetailsBlade) {
|
|
1055
|
+
const $ = await G(
|
|
1056
|
+
w,
|
|
1057
|
+
l,
|
|
1058
|
+
"details",
|
|
1059
|
+
s,
|
|
1060
|
+
c
|
|
1061
|
+
);
|
|
1062
|
+
u.push($);
|
|
560
1063
|
}
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
)
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
1064
|
+
const h = await Be(l, e, s);
|
|
1065
|
+
u.push(h);
|
|
1066
|
+
}
|
|
1067
|
+
if (e.includeLocales) {
|
|
1068
|
+
const h = await Ve(l, s, c, p);
|
|
1069
|
+
u.push(h);
|
|
1070
|
+
const $ = m.join(l, "locales", "index.ts");
|
|
1071
|
+
r.writeFileSync($, `import en from "./en.json";
|
|
1072
|
+
export { en };
|
|
1073
|
+
`), u.push($);
|
|
1074
|
+
}
|
|
1075
|
+
const f = m.join(l, "index.ts");
|
|
1076
|
+
r.writeFileSync(f, `import * as pages from "./pages";
|
|
1077
|
+
import * as locales from "./locales";
|
|
1078
|
+
import { createAppModule } from "@vc-shell/framework";
|
|
1079
|
+
|
|
1080
|
+
export default createAppModule(pages, locales);
|
|
1081
|
+
|
|
1082
|
+
export * from "./composables";
|
|
1083
|
+
`), u.push(f);
|
|
1084
|
+
const b = [];
|
|
1085
|
+
e.createGridBlade && b.push({
|
|
1086
|
+
exportName: `${s.entitySingularPascal}List`,
|
|
1087
|
+
fileName: s.entityPluralKebab
|
|
1088
|
+
}), e.createDetailsBlade && b.push({
|
|
1089
|
+
exportName: `${s.entitySingularPascal}Details`,
|
|
1090
|
+
fileName: `${s.entitySingularKebab}-details`
|
|
1091
|
+
}), b.length > 0 && await K(l, b), console.log(o.cyan(`
|
|
1092
|
+
✨ Formatting files with Prettier...
|
|
1093
|
+
`));
|
|
1094
|
+
for (const h of u)
|
|
1095
|
+
await P(h);
|
|
1096
|
+
console.log(o.green(`
|
|
1097
|
+
✅ Module generated successfully!`)), console.log(o.cyan(`
|
|
1098
|
+
📦 Registering module in main.ts...
|
|
1099
|
+
`));
|
|
1100
|
+
const S = await Le(t, e.moduleName, s.moduleNamePascal);
|
|
1101
|
+
console.log(o.cyan(`
|
|
1102
|
+
📝 Next steps:`)), S ? (console.log(o.cyan(" 1. Update API client imports in the generated composables")), console.log(o.cyan(` 2. Customize the table columns and form fields as needed
|
|
1103
|
+
`))) : (console.log(o.cyan(" 1. Import the module in your main.ts:")), console.log(o.gray(` import ${s.moduleNamePascal}Module from "./modules/${e.moduleName}";`)), console.log(o.gray(` app.use(${s.moduleNamePascal}Module, { router });`)), console.log(o.cyan(" 2. Update API client imports in the generated composables")), console.log(o.cyan(` 3. Customize the table columns and form fields as needed
|
|
1104
|
+
`)));
|
|
1105
|
+
} catch (s) {
|
|
1106
|
+
throw console.error(o.red(`
|
|
1107
|
+
❌ Module generation failed:`), s.message), s;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
async function je(t) {
|
|
1111
|
+
try {
|
|
1112
|
+
console.log(o.cyan(`
|
|
1113
|
+
📄 Adding blade to existing module
|
|
1114
|
+
`));
|
|
1115
|
+
const e = m.join(t, "src", "modules");
|
|
1116
|
+
if (!r.existsSync(e))
|
|
1117
|
+
throw console.error(o.red("❌ No modules directory found at src/modules")), new Error("Modules directory not found");
|
|
1118
|
+
const n = r.readdirSync(e).filter((S) => r.statSync(m.join(e, S)).isDirectory());
|
|
1119
|
+
if (n.length === 0)
|
|
1120
|
+
throw console.error(o.red("❌ No existing modules found")), new Error("No existing modules found");
|
|
1121
|
+
const a = await x(
|
|
1122
|
+
[
|
|
1123
|
+
{
|
|
1124
|
+
type: "autocomplete",
|
|
1125
|
+
name: "moduleName",
|
|
1126
|
+
message: "Select existing module:",
|
|
1127
|
+
choices: n.map((S) => ({ title: S, value: S }))
|
|
1128
|
+
},
|
|
1129
|
+
{
|
|
1130
|
+
type: "text",
|
|
1131
|
+
name: "entitySingular",
|
|
1132
|
+
message: "Entity name (e.g., Product, Order):",
|
|
1133
|
+
validate: (S) => S.length > 0 ? !0 : "Entity name is required"
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
type: "select",
|
|
1137
|
+
name: "bladeType",
|
|
1138
|
+
message: "Blade type:",
|
|
1139
|
+
choices: [
|
|
1140
|
+
{ title: "Grid (List with table, search, pagination)", value: "grid" },
|
|
1141
|
+
{ title: "Details (Form with validation and toolbar)", value: "details" }
|
|
1142
|
+
]
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
type: "confirm",
|
|
1146
|
+
name: "isWorkspace",
|
|
1147
|
+
message: "Is this a workspace blade?",
|
|
1148
|
+
initial: !1
|
|
1149
|
+
},
|
|
1150
|
+
{
|
|
1151
|
+
type: "confirm",
|
|
1152
|
+
name: "includeComposable",
|
|
1153
|
+
message: "Include composable?",
|
|
1154
|
+
initial: !0
|
|
1155
|
+
}
|
|
1156
|
+
],
|
|
1157
|
+
{
|
|
1158
|
+
onCancel: () => {
|
|
1159
|
+
throw new E();
|
|
573
1160
|
}
|
|
574
|
-
s.writeFileSync(M, h);
|
|
575
1161
|
}
|
|
1162
|
+
);
|
|
1163
|
+
let s = !1;
|
|
1164
|
+
a.bladeType === "details" && (s = (await x(
|
|
1165
|
+
{
|
|
1166
|
+
type: "confirm",
|
|
1167
|
+
name: "customizeForm",
|
|
1168
|
+
message: "Customize form fields interactively?",
|
|
1169
|
+
initial: !1
|
|
1170
|
+
},
|
|
1171
|
+
{
|
|
1172
|
+
onCancel: () => {
|
|
1173
|
+
throw new E();
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
)).customizeForm);
|
|
1177
|
+
const c = W(a.entitySingular, a.moduleName), l = z(c), d = m.join(e, a.moduleName), w = V(), u = [];
|
|
1178
|
+
let g = "", p = {}, i = [];
|
|
1179
|
+
s && a.bladeType === "details" && (i = await ne(), i.length > 0 && (g = R(i, c.moduleNameUpperSnake), p = k(i)));
|
|
1180
|
+
const f = await j(
|
|
1181
|
+
w,
|
|
1182
|
+
d,
|
|
1183
|
+
a.bladeType,
|
|
1184
|
+
l,
|
|
1185
|
+
a.isWorkspace,
|
|
1186
|
+
g,
|
|
1187
|
+
i
|
|
1188
|
+
);
|
|
1189
|
+
if (u.push(f), a.includeComposable) {
|
|
1190
|
+
const S = await G(
|
|
1191
|
+
w,
|
|
1192
|
+
d,
|
|
1193
|
+
a.bladeType,
|
|
1194
|
+
c,
|
|
1195
|
+
l
|
|
1196
|
+
);
|
|
1197
|
+
u.push(S);
|
|
1198
|
+
const h = m.join(d, "composables", "index.ts"), I = `export * from "./${a.bladeType === "grid" ? `use${c.entitySingularPascal}List` : `use${c.entitySingularPascal}Details`}";
|
|
1199
|
+
`;
|
|
1200
|
+
r.existsSync(h) ? r.readFileSync(h, "utf-8").includes(I) || r.appendFileSync(h, I) : r.writeFileSync(h, I);
|
|
576
1201
|
}
|
|
1202
|
+
if (Object.keys(p).length > 0) {
|
|
1203
|
+
const S = m.join(d, "locales", "en.json");
|
|
1204
|
+
if (r.existsSync(S)) {
|
|
1205
|
+
const h = JSON.parse(r.readFileSync(S, "utf-8")), $ = Object.keys(h)[0];
|
|
1206
|
+
$ && h[$]?.PAGES?.DETAILS?.FORM?.INFO && (h[$].PAGES.DETAILS.FORM.INFO = {
|
|
1207
|
+
...h[$].PAGES.DETAILS.FORM.INFO,
|
|
1208
|
+
...p
|
|
1209
|
+
}, r.writeFileSync(S, JSON.stringify(h, null, 2)), console.log(o.green("✓ Updated locales with custom fields")));
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
const y = a.bladeType === "grid" ? `${c.entitySingularPascal}List` : `${c.entitySingularPascal}Details`, b = a.bladeType === "grid" ? l["{{entity-name-plural}}"] : `${l["{{entity-name}}"]}-details`;
|
|
1213
|
+
await K(d, [{ exportName: y, fileName: b }]), console.log(o.cyan(`
|
|
1214
|
+
✨ Formatting files with Prettier...
|
|
1215
|
+
`));
|
|
1216
|
+
for (const S of u)
|
|
1217
|
+
await P(S);
|
|
1218
|
+
console.log(o.green(`
|
|
1219
|
+
✅ Blade generated successfully!
|
|
1220
|
+
`));
|
|
1221
|
+
} catch (e) {
|
|
1222
|
+
throw console.error(o.red(`
|
|
1223
|
+
❌ Blade generation failed:`), e.message), e;
|
|
577
1224
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
const n =
|
|
588
|
-
|
|
589
|
-
|
|
1225
|
+
}
|
|
1226
|
+
async function Q(t) {
|
|
1227
|
+
try {
|
|
1228
|
+
console.log(o.cyan(`
|
|
1229
|
+
🧩 Creating widget
|
|
1230
|
+
`));
|
|
1231
|
+
const e = m.join(t, "src", "modules");
|
|
1232
|
+
if (!r.existsSync(e))
|
|
1233
|
+
throw console.error(o.red("❌ No modules directory found")), new Error("Modules directory not found");
|
|
1234
|
+
const n = r.readdirSync(e).filter((u) => r.statSync(m.join(e, u)).isDirectory());
|
|
1235
|
+
if (n.length === 0)
|
|
1236
|
+
throw console.error(o.red("❌ No existing modules found")), new Error("No existing modules found");
|
|
1237
|
+
const a = await x(
|
|
1238
|
+
{
|
|
1239
|
+
type: "autocomplete",
|
|
1240
|
+
name: "moduleName",
|
|
1241
|
+
message: "Select module:",
|
|
1242
|
+
choices: n.map((u) => ({ title: u, value: u }))
|
|
1243
|
+
},
|
|
1244
|
+
{
|
|
1245
|
+
onCancel: () => {
|
|
1246
|
+
throw new E();
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
), s = m.join(e, a.moduleName), c = m.join(s, "pages");
|
|
1250
|
+
if (!r.existsSync(c))
|
|
1251
|
+
throw console.error(o.red("❌ No pages directory found in this module")), new Error("Pages directory not found");
|
|
1252
|
+
const l = r.readdirSync(c).filter((u) => u.endsWith(".vue"));
|
|
1253
|
+
if (l.length === 0)
|
|
1254
|
+
throw console.error(o.red("❌ No blades found in this module")), new Error("No blades found in module");
|
|
1255
|
+
const d = await x(
|
|
1256
|
+
[
|
|
1257
|
+
{
|
|
1258
|
+
type: "autocomplete",
|
|
1259
|
+
name: "bladeName",
|
|
1260
|
+
message: "Select blade to register widget in:",
|
|
1261
|
+
choices: l.map((u) => ({ title: u, value: u.replace(".vue", "") }))
|
|
1262
|
+
},
|
|
1263
|
+
{
|
|
1264
|
+
type: "text",
|
|
1265
|
+
name: "widgetName",
|
|
1266
|
+
message: "Widget name (e.g., Stats, Chart, Items):",
|
|
1267
|
+
validate: (u) => u.length > 0 ? !0 : "Widget name is required"
|
|
1268
|
+
},
|
|
1269
|
+
{
|
|
1270
|
+
type: "text",
|
|
1271
|
+
name: "entityName",
|
|
1272
|
+
message: "Related entity name (e.g., Offer, Item, Review):",
|
|
1273
|
+
validate: (u) => u.length > 0 ? !0 : "Entity name is required"
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
type: "select",
|
|
1277
|
+
name: "icon",
|
|
1278
|
+
message: "Widget icon:",
|
|
1279
|
+
choices: [
|
|
1280
|
+
{ title: "List (material-list)", value: "material-list" },
|
|
1281
|
+
{ title: "Sell/Price (material-sell)", value: "material-sell" },
|
|
1282
|
+
{ title: "Shopping Cart (material-shopping_cart)", value: "material-shopping_cart" },
|
|
1283
|
+
{ title: "Star/Rating (material-star)", value: "material-star" },
|
|
1284
|
+
{ title: "Image (material-image)", value: "material-image" },
|
|
1285
|
+
{ title: "Description (material-description)", value: "material-description" },
|
|
1286
|
+
{ title: "Custom (enter manually)", value: "custom" }
|
|
1287
|
+
]
|
|
1288
|
+
}
|
|
1289
|
+
],
|
|
1290
|
+
{
|
|
1291
|
+
onCancel: () => {
|
|
1292
|
+
throw new E();
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
590
1295
|
);
|
|
1296
|
+
let w = d.icon;
|
|
1297
|
+
w === "custom" && (w = (await x(
|
|
1298
|
+
{
|
|
1299
|
+
type: "text",
|
|
1300
|
+
name: "customIcon",
|
|
1301
|
+
message: "Enter custom icon name (e.g., material-dashboard):",
|
|
1302
|
+
validate: (g) => g.length > 0 ? !0 : "Icon is required"
|
|
1303
|
+
},
|
|
1304
|
+
{
|
|
1305
|
+
onCancel: () => {
|
|
1306
|
+
throw new E();
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
)).customIcon), await Ge(s, d, w, a.moduleName);
|
|
1310
|
+
} catch (e) {
|
|
1311
|
+
throw console.error(o.red(`
|
|
1312
|
+
❌ Widget generation failed:`), e.message), e;
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
async function Ge(t, e, n, a) {
|
|
1316
|
+
try {
|
|
1317
|
+
const s = W(e.entityName, a), c = V(), l = m.join(c, "widgets", "widget.vue");
|
|
1318
|
+
if (!r.existsSync(l))
|
|
1319
|
+
throw new Error(`Widget template not found at ${l}`);
|
|
1320
|
+
const d = e.bladeName.match(/^(.+?)(-list|-details)?$/), w = d ? d[1] : e.bladeName, u = m.join(t, "components", "widgets"), g = m.join(u, N(e.widgetName)), p = m.join(g, `${N(e.widgetName)}-widget.vue`), i = m.join(g, "index.ts");
|
|
1321
|
+
if (!r.existsSync(g))
|
|
1322
|
+
try {
|
|
1323
|
+
r.mkdirSync(g, { recursive: !0 });
|
|
1324
|
+
} catch (C) {
|
|
1325
|
+
throw new Error(`Failed to create widget directory: ${C.message}`);
|
|
1326
|
+
}
|
|
1327
|
+
let f = r.readFileSync(l, "utf-8");
|
|
1328
|
+
const y = {
|
|
1329
|
+
"{{MODULE_NAME_UPPERCASE}}": v(a).toUpperCase(),
|
|
1330
|
+
"{{WIDGET_NAME_UPPERCASE}}": v(e.widgetName).toUpperCase(),
|
|
1331
|
+
"{{WIDGET_ICON}}": n,
|
|
1332
|
+
"{{EntityName}}": s.entitySingularPascal,
|
|
1333
|
+
"{{entityName}}": s.entitySingularCamel,
|
|
1334
|
+
"{{ParentEntity}}": T(F(w)),
|
|
1335
|
+
"{{parentEntityCamel}}": F(w),
|
|
1336
|
+
"{{BladeName}}": `${s.entitySingularPascal}List`
|
|
1337
|
+
};
|
|
1338
|
+
f = H(f, y), r.writeFileSync(p, f), console.log(o.green(`✓ Created widget: ${m.relative(process.cwd(), p)}`));
|
|
1339
|
+
const b = `${T(F(e.widgetName))}Widget`, S = `export { default as ${b} } from "./${N(e.widgetName)}-widget.vue";
|
|
1340
|
+
`;
|
|
1341
|
+
r.writeFileSync(i, S);
|
|
1342
|
+
const h = m.join(u, "index.ts"), $ = `export * from "./${N(e.widgetName)}";
|
|
1343
|
+
`;
|
|
1344
|
+
r.existsSync(h) ? r.readFileSync(h, "utf-8").includes($) || r.appendFileSync(h, $) : r.writeFileSync(h, $);
|
|
1345
|
+
const I = m.join(t, "locales", "en.json");
|
|
1346
|
+
if (r.existsSync(I))
|
|
1347
|
+
try {
|
|
1348
|
+
const C = JSON.parse(r.readFileSync(I, "utf-8")), M = Object.keys(C)[0];
|
|
1349
|
+
if (M) {
|
|
1350
|
+
C[M].WIDGETS || (C[M].WIDGETS = {});
|
|
1351
|
+
const J = v(e.widgetName).toUpperCase();
|
|
1352
|
+
C[M].WIDGETS[J] || (C[M].WIDGETS[J] = {
|
|
1353
|
+
TITLE: T(e.widgetName)
|
|
1354
|
+
}), r.writeFileSync(I, JSON.stringify(C, null, 2)), await P(I), console.log(o.green("✓ Updated locales with widget translations"));
|
|
1355
|
+
}
|
|
1356
|
+
} catch (C) {
|
|
1357
|
+
console.warn(o.yellow(`⚠️ Could not update locales: ${C.message}`));
|
|
1358
|
+
}
|
|
1359
|
+
const D = m.join(t, "pages", `${e.bladeName}.vue`);
|
|
1360
|
+
if (r.existsSync(D))
|
|
1361
|
+
try {
|
|
1362
|
+
await _e(D, b, s.entitySingularCamel), console.log(o.green(`✓ Registered widget in ${e.bladeName}.vue`));
|
|
1363
|
+
} catch (C) {
|
|
1364
|
+
console.warn(o.yellow(`⚠️ Could not auto-register widget in blade: ${C.message}`)), console.warn(o.yellow(" Please add the widget registration manually."));
|
|
1365
|
+
}
|
|
1366
|
+
await P(p), await P(i), r.existsSync(D) && await P(D), console.log(o.green(`
|
|
1367
|
+
✅ Widget generated successfully!`)), console.log(o.cyan(`
|
|
1368
|
+
📝 Widget is automatically registered in the blade!`)), console.log(o.cyan(` See TODO comments in widget file for API integration.
|
|
1369
|
+
`));
|
|
1370
|
+
} catch (s) {
|
|
1371
|
+
throw console.error(o.red(`
|
|
1372
|
+
❌ Widget file creation failed:`), s.message), s;
|
|
591
1373
|
}
|
|
592
|
-
console.log(` ${t.bold(t.green("yarn"))}`), console.log(` ${t.bold(t.green("yarn serve"))}`);
|
|
593
1374
|
}
|
|
594
|
-
|
|
595
|
-
|
|
1375
|
+
async function _e(t, e, n) {
|
|
1376
|
+
let a = r.readFileSync(t, "utf-8");
|
|
1377
|
+
if (!new RegExp(
|
|
1378
|
+
`import\\s*\\{[^}]*\\b${e}\\b[^}]*\\}\\s*from\\s*["']\\.\\./components/widgets["']`
|
|
1379
|
+
).test(a)) {
|
|
1380
|
+
const p = a.match(/import\s*\{([^}]+)\}\s*from\s*["']\.\.\/components\/widgets["']/);
|
|
1381
|
+
if (p) {
|
|
1382
|
+
const f = p[1].split(",").map((y) => y.trim()).filter(Boolean);
|
|
1383
|
+
if (!f.includes(e)) {
|
|
1384
|
+
f.push(e);
|
|
1385
|
+
const y = f.join(", ");
|
|
1386
|
+
a = a.replace(p[0], `import { ${y} } from "../components/widgets"`);
|
|
1387
|
+
}
|
|
1388
|
+
} else {
|
|
1389
|
+
const i = a.match(/<script\s+(?:setup\s+lang="ts"|lang="ts"\s+setup|setup)>/);
|
|
1390
|
+
if (i) {
|
|
1391
|
+
const f = a.indexOf(i[0]) + i[0].length, y = [...a.slice(f).matchAll(/import\s+[\s\S]+?;/g)];
|
|
1392
|
+
if (y.length > 0) {
|
|
1393
|
+
const b = y[y.length - 1], S = f + b.index + b[0].length;
|
|
1394
|
+
a = a.slice(0, S) + `
|
|
1395
|
+
import { ${e} } from "../components/widgets";` + a.slice(S);
|
|
1396
|
+
} else
|
|
1397
|
+
a = a.slice(0, f) + `
|
|
1398
|
+
import { ${e} } from "../components/widgets";
|
|
1399
|
+
` + a.slice(f);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
const c = `${e}`, l = ` registerWidget(
|
|
1404
|
+
{
|
|
1405
|
+
id: "${c}",
|
|
1406
|
+
component: ${e},
|
|
1407
|
+
props: { item },
|
|
1408
|
+
updateFunctionName: "updateActiveWidgetCount",
|
|
1409
|
+
// isVisible: computed(() => !!props.param), // Uncomment to show widget only when blade has param
|
|
1410
|
+
},
|
|
1411
|
+
blade?.value.id ?? "",
|
|
1412
|
+
);`, d = a.match(/function\s+registerWidgets\s*\(\s*\)\s*\{/);
|
|
1413
|
+
if (d) {
|
|
1414
|
+
const p = a.indexOf(d[0]) + d[0].length;
|
|
1415
|
+
let i = 1, f = p;
|
|
1416
|
+
for (let y = p; y < a.length && i > 0; y++)
|
|
1417
|
+
a[y] === "{" && i++, a[y] === "}" && i--, i === 1 && (f = y);
|
|
1418
|
+
a = a.slice(0, f) + `
|
|
1419
|
+
` + l + `
|
|
1420
|
+
` + a.slice(f);
|
|
1421
|
+
} else {
|
|
1422
|
+
const p = a.match(/defineExpose\s*\(/);
|
|
1423
|
+
if (p) {
|
|
1424
|
+
const i = a.indexOf(p[0]), f = `
|
|
1425
|
+
function registerWidgets() {
|
|
1426
|
+
${l}
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
registerWidgets();
|
|
1430
|
+
|
|
1431
|
+
`;
|
|
1432
|
+
a = a.slice(0, i) + f + a.slice(i);
|
|
1433
|
+
} else {
|
|
1434
|
+
const i = a.match(/<\/script>/);
|
|
1435
|
+
if (i) {
|
|
1436
|
+
const f = a.indexOf(i[0]), y = `
|
|
1437
|
+
function registerWidgets() {
|
|
1438
|
+
${l}
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
registerWidgets();
|
|
1442
|
+
|
|
1443
|
+
`;
|
|
1444
|
+
a = a.slice(0, f) + y + a.slice(f);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
const w = ` unregisterWidget("${c}", blade?.value.id);`, u = a.match(/onBeforeUnmount\s*\(\s*\(\s*\)\s*=>\s*\{/);
|
|
1449
|
+
if (u) {
|
|
1450
|
+
const p = a.indexOf(u[0]) + u[0].length;
|
|
1451
|
+
a = a.slice(0, p) + `
|
|
1452
|
+
` + w + `
|
|
1453
|
+
` + a.slice(p);
|
|
1454
|
+
} else {
|
|
1455
|
+
const p = a.match(/defineExpose\s*\(/);
|
|
1456
|
+
if (p) {
|
|
1457
|
+
const i = a.indexOf(p[0]), f = `
|
|
1458
|
+
onBeforeUnmount(() => {
|
|
1459
|
+
${w}
|
|
596
1460
|
});
|
|
1461
|
+
|
|
1462
|
+
`;
|
|
1463
|
+
a = a.slice(0, i) + f + a.slice(i);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
const g = [
|
|
1467
|
+
// registerWidget and unregisterWidget come from useWidgets(), not direct imports
|
|
1468
|
+
{ name: "useWidgets", from: "@vc-shell/framework" },
|
|
1469
|
+
{ name: "useBlade", from: "@vc-shell/framework" },
|
|
1470
|
+
{ name: "onBeforeUnmount", from: "vue" }
|
|
1471
|
+
// { name: "computed", from: "vue" }, // Not needed if isVisible is commented
|
|
1472
|
+
];
|
|
1473
|
+
for (const { name: p, from: i } of g) {
|
|
1474
|
+
const f = i.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), y = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']${f}["']`, "g"), b = [...a.matchAll(y)];
|
|
1475
|
+
if (b.length > 0) {
|
|
1476
|
+
const S = b[0], $ = S[1].split(",").map((I) => I.trim()).filter(Boolean);
|
|
1477
|
+
if (!$.includes(p)) {
|
|
1478
|
+
$.push(p);
|
|
1479
|
+
const I = $.join(", ");
|
|
1480
|
+
a = a.replace(S[0], `import { ${I} } from "${i}"`);
|
|
1481
|
+
}
|
|
1482
|
+
} else {
|
|
1483
|
+
const S = a.match(/<script\s+(?:setup\s+lang="ts"|lang="ts"\s+setup|setup)>/);
|
|
1484
|
+
if (S) {
|
|
1485
|
+
const h = a.indexOf(S[0]) + S[0].length, $ = a.slice(h).match(/^[\s\n]*import/m);
|
|
1486
|
+
if ($) {
|
|
1487
|
+
const I = h + a.slice(h).indexOf($[0]);
|
|
1488
|
+
a = a.slice(0, I) + `import { ${p} } from "${i}";
|
|
1489
|
+
` + a.slice(I);
|
|
1490
|
+
} else
|
|
1491
|
+
a = a.slice(0, h) + `
|
|
1492
|
+
import { ${p} } from "${i}";
|
|
1493
|
+
` + a.slice(h);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
if (!a.includes("const blade = useBlade()")) {
|
|
1498
|
+
const p = `
|
|
1499
|
+
const blade = useBlade();
|
|
1500
|
+
`, i = a.match(/const\s+\w+\s*=\s*[^;]+;(?=[^;]*const)/g);
|
|
1501
|
+
if (i && i.length > 0) {
|
|
1502
|
+
const f = i[i.length - 1], y = a.lastIndexOf(f) + f.length;
|
|
1503
|
+
a = a.slice(0, y) + p + a.slice(y);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
if (!a.includes("const { registerWidget, unregisterWidget } = useWidgets()")) {
|
|
1507
|
+
const p = `
|
|
1508
|
+
const { registerWidget, unregisterWidget } = useWidgets();
|
|
1509
|
+
`, i = a.match(/const blade = useBlade\(\);/);
|
|
1510
|
+
if (i) {
|
|
1511
|
+
const f = a.indexOf(i[0]) + i[0].length;
|
|
1512
|
+
a = a.slice(0, f) + p + a.slice(f);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
r.writeFileSync(t, a);
|
|
1516
|
+
}
|
|
1517
|
+
function V() {
|
|
1518
|
+
return m.resolve(X(import.meta.url), "..", "..", "templates");
|
|
1519
|
+
}
|
|
1520
|
+
async function j(t, e, n, a, s, c, l) {
|
|
1521
|
+
const d = m.join(t, "blades", n, "blade.vue"), w = n === "grid" ? `${a["{{entity-name-plural}}"]}.vue` : `${a["{{entity-name}}"]}-details.vue`, u = m.join(e, "pages", w);
|
|
1522
|
+
se(u);
|
|
1523
|
+
let g = r.readFileSync(d, "utf-8");
|
|
1524
|
+
if (s ? (g = g.replace(/{{isWorkspace}}/g, "true"), g = g.replace(
|
|
1525
|
+
/{{menuItem}}/g,
|
|
1526
|
+
`{
|
|
1527
|
+
id: "${a["{{entityName}}"]}",
|
|
1528
|
+
title: "${a["{{MODULE_NAME_UPPERCASE}}"]}.MENU.TITLE",
|
|
1529
|
+
icon: "material-list",
|
|
1530
|
+
priority: 1,
|
|
1531
|
+
}`
|
|
1532
|
+
)) : (g = g.replace(/{{isWorkspace}}/g, "false"), g = g.replace(/{{menuItem}}/g, "undefined")), n === "details") {
|
|
1533
|
+
if (c)
|
|
1534
|
+
g = g.replace(/\{\{FORM_FIELDS\}\}/g, c);
|
|
1535
|
+
else {
|
|
1536
|
+
const i = oe(a["{{MODULE_NAME_UPPERCASE}}"]);
|
|
1537
|
+
g = g.replace(/\{\{FORM_FIELDS\}\}/g, i);
|
|
1538
|
+
}
|
|
1539
|
+
if (l && Me(l)) {
|
|
1540
|
+
g = g.replace(/\{\{GALLERY_IMPORTS\}\}/g, `
|
|
1541
|
+
useAssets,
|
|
1542
|
+
ICommonAsset,`);
|
|
1543
|
+
const i = Ne(a["{{entityName}}"]);
|
|
1544
|
+
g = g.replace(/\{\{GALLERY_SCRIPT_ADDITIONS\}\}/g, i);
|
|
1545
|
+
} else
|
|
1546
|
+
g = g.replace(/\{\{GALLERY_IMPORTS\}\}/g, ""), g = g.replace(/\{\{GALLERY_SCRIPT_ADDITIONS\}\}/g, "");
|
|
1547
|
+
}
|
|
1548
|
+
return g = H(g, a), r.writeFileSync(u, g), console.log(o.green(`✓ Created ${n} blade: ${m.relative(process.cwd(), u)}`)), u;
|
|
1549
|
+
}
|
|
1550
|
+
async function G(t, e, n, a, s) {
|
|
1551
|
+
const c = n === "grid" ? "grid-composable.ts" : "details-composable.ts", l = m.join(t, "composables", c), d = n === "grid" ? `use${a.entitySingularPascal}List.ts` : `use${a.entitySingularPascal}Details.ts`, w = m.join(e, "composables", d);
|
|
1552
|
+
se(w);
|
|
1553
|
+
let u = r.readFileSync(l, "utf-8");
|
|
1554
|
+
return u = H(u, s), r.writeFileSync(w, u), console.log(o.green(`✓ Created composable: ${m.relative(process.cwd(), w)}`)), w;
|
|
1555
|
+
}
|
|
1556
|
+
function We(t) {
|
|
1557
|
+
const e = r.readdirSync(t);
|
|
1558
|
+
return e.length === 0 || e.length === 1 && e[0] === ".git";
|
|
1559
|
+
}
|
|
1560
|
+
async function Be(t, e, n) {
|
|
1561
|
+
const a = m.join(t, "composables", "index.ts");
|
|
1562
|
+
let s = "";
|
|
1563
|
+
return e.createGridBlade && (s += `export * from "./use${n.entitySingularPascal}List";
|
|
1564
|
+
`), e.createDetailsBlade && (s += `export * from "./use${n.entitySingularPascal}Details";
|
|
1565
|
+
`), r.writeFileSync(a, s), console.log(o.green("✓ Created composables index")), a;
|
|
1566
|
+
}
|
|
1567
|
+
async function Ve(t, e, n, a) {
|
|
1568
|
+
const s = m.join(t, "locales", "en.json"), c = {
|
|
1569
|
+
TITLE: "Information",
|
|
1570
|
+
NAME: "Name",
|
|
1571
|
+
NAME_PLACEHOLDER: `Enter ${e.entitySingularCamel} name`,
|
|
1572
|
+
CREATED_DATE: "Created Date"
|
|
1573
|
+
}, l = a && Object.keys(a).length > 0 ? { TITLE: "Information", ...a } : c, d = {
|
|
1574
|
+
[e.moduleNameUpperSnake]: {
|
|
1575
|
+
MENU: {
|
|
1576
|
+
TITLE: e.entityPluralPascal
|
|
1577
|
+
},
|
|
1578
|
+
PAGES: {
|
|
1579
|
+
LIST: {
|
|
1580
|
+
TITLE: e.entityPluralPascal,
|
|
1581
|
+
SEARCH: {
|
|
1582
|
+
PLACEHOLDER: `Search ${e.entityPluralCamel}...`
|
|
1583
|
+
},
|
|
1584
|
+
TOOLBAR: {
|
|
1585
|
+
REFRESH: "Refresh",
|
|
1586
|
+
ADD: `Add ${e.entitySingularPascal}`,
|
|
1587
|
+
DELETE: "Delete selected"
|
|
1588
|
+
},
|
|
1589
|
+
TABLE: {
|
|
1590
|
+
HEADER: {
|
|
1591
|
+
NAME: "Name",
|
|
1592
|
+
CREATED_DATE: "Created"
|
|
1593
|
+
},
|
|
1594
|
+
TOTALS: `{count} ${e.entityPluralCamel}`,
|
|
1595
|
+
FILTER: {
|
|
1596
|
+
STATUS: {
|
|
1597
|
+
TITLE: "Status",
|
|
1598
|
+
Active: "Active",
|
|
1599
|
+
Inactive: "Inactive",
|
|
1600
|
+
Pending: "Pending"
|
|
1601
|
+
},
|
|
1602
|
+
DATE: {
|
|
1603
|
+
TITLE: "Date Range",
|
|
1604
|
+
START_DATE: "Start Date",
|
|
1605
|
+
END_DATE: "End Date"
|
|
1606
|
+
},
|
|
1607
|
+
APPLY: "Apply",
|
|
1608
|
+
RESET: "Reset"
|
|
1609
|
+
}
|
|
1610
|
+
},
|
|
1611
|
+
EMPTY: {
|
|
1612
|
+
NO_ITEMS: `No ${e.entityPluralCamel} yet`,
|
|
1613
|
+
ADD: `Add ${e.entitySingularPascal}`
|
|
1614
|
+
},
|
|
1615
|
+
NOT_FOUND: {
|
|
1616
|
+
EMPTY: `No ${e.entityPluralCamel} found`,
|
|
1617
|
+
RESET: "Reset search"
|
|
1618
|
+
}
|
|
1619
|
+
},
|
|
1620
|
+
DETAILS: {
|
|
1621
|
+
TITLE: `New ${e.entitySingularPascal}`,
|
|
1622
|
+
TOOLBAR: {
|
|
1623
|
+
SAVE: "Save",
|
|
1624
|
+
DELETE: "Delete"
|
|
1625
|
+
},
|
|
1626
|
+
FORM: {
|
|
1627
|
+
INFO: l
|
|
1628
|
+
}
|
|
1629
|
+
},
|
|
1630
|
+
ALERTS: {
|
|
1631
|
+
DELETE: `Are you sure you want to delete this ${e.entitySingularCamel}?`,
|
|
1632
|
+
DELETE_SELECTED_CONFIRMATION: {
|
|
1633
|
+
MESSAGE: `Are you sure you want to delete {count} ${e.entityPluralCamel}?`,
|
|
1634
|
+
ALL: "all {totalCount}"
|
|
1635
|
+
},
|
|
1636
|
+
CLOSE_CONFIRMATION: "You have unsaved changes. Are you sure you want to close?",
|
|
1637
|
+
NOT_VALID: "Please fill all required fields correctly."
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
return r.writeFileSync(s, JSON.stringify(d, null, 2)), console.log(o.green("✓ Created locales file")), s;
|
|
1643
|
+
}
|
|
1644
|
+
async function qe(t) {
|
|
1645
|
+
const { args: e, cwd: n } = t, a = e._[0] || e.name || e["app-name"], l = await Ue({
|
|
1646
|
+
args: e,
|
|
1647
|
+
defaultAppName: a || "vc-app",
|
|
1648
|
+
hasAllArgs: !!a
|
|
1649
|
+
});
|
|
1650
|
+
console.log(o.cyan(`
|
|
1651
|
+
📋 Creating app with the following configuration:`)), console.log(o.cyan(` App name: ${l.appName}`)), console.log(o.cyan(` Package name: ${l.packageName}`)), console.log(o.cyan(` Base path: ${l.basePath}`)), console.log();
|
|
1652
|
+
const d = a === "." ? n : m.join(n, l.appName);
|
|
1653
|
+
He(d, {
|
|
1654
|
+
overwrite: !!e.overwrite
|
|
1655
|
+
}), console.log(o.cyan(`
|
|
1656
|
+
📦 Scaffolding app in ${o.bold(d)}...`));
|
|
1657
|
+
const w = Ke(l), u = Je({
|
|
1658
|
+
templateName: "base",
|
|
1659
|
+
targetDirectory: d,
|
|
1660
|
+
replacements: w
|
|
1661
|
+
});
|
|
1662
|
+
return console.log(o.green(`✅ Created ${u} files`)), console.log(o.cyan(`
|
|
1663
|
+
🎨 Formatting files with Prettier...`)), await Xe(d), e["skip-module-gen"] || await et(d, e), {
|
|
1664
|
+
root: d,
|
|
1665
|
+
filesCreated: u,
|
|
1666
|
+
config: l
|
|
1667
|
+
};
|
|
1668
|
+
}
|
|
1669
|
+
async function Ue(t) {
|
|
1670
|
+
const { args: e, defaultAppName: n, hasAllArgs: a } = t;
|
|
1671
|
+
if (a) {
|
|
1672
|
+
const s = A(e._[0] || e.name || e["app-name"] || n), c = e._[0] || e.name || e["app-name"] || s, l = e["package-name"] || (L(c) ? c : A(c)), d = ee(e["base-path"] || `/apps/${A(c)}/`);
|
|
1673
|
+
return {
|
|
1674
|
+
appName: s,
|
|
1675
|
+
packageName: l,
|
|
1676
|
+
moduleName: "",
|
|
1677
|
+
basePath: d
|
|
1678
|
+
};
|
|
1679
|
+
}
|
|
1680
|
+
return ze(n);
|
|
1681
|
+
}
|
|
1682
|
+
async function ze(t) {
|
|
1683
|
+
let e = t;
|
|
1684
|
+
try {
|
|
1685
|
+
const n = await x(
|
|
1686
|
+
[
|
|
1687
|
+
{
|
|
1688
|
+
name: "appName",
|
|
1689
|
+
type: "text",
|
|
1690
|
+
message: o.reset("Project name:"),
|
|
1691
|
+
initial: t,
|
|
1692
|
+
onState: (l) => {
|
|
1693
|
+
e = A(String(l.value).trim()) || t;
|
|
1694
|
+
},
|
|
1695
|
+
format: (l) => A(String(l).trim())
|
|
1696
|
+
},
|
|
1697
|
+
{
|
|
1698
|
+
type: () => !r.existsSync(e) || de(e) ? null : "confirm",
|
|
1699
|
+
name: "overwrite",
|
|
1700
|
+
message: () => (e === "." ? "Current directory" : `Target directory "${e}"`) + " is not empty. Remove existing files and continue?"
|
|
1701
|
+
},
|
|
1702
|
+
{
|
|
1703
|
+
type: (l, { overwrite: d }) => {
|
|
1704
|
+
if (d === !1)
|
|
1705
|
+
throw new E();
|
|
1706
|
+
return null;
|
|
1707
|
+
},
|
|
1708
|
+
name: "overwriteChecker"
|
|
1709
|
+
},
|
|
1710
|
+
{
|
|
1711
|
+
name: "packageName",
|
|
1712
|
+
type: () => L(e) ? null : "text",
|
|
1713
|
+
message: o.reset("Package name:"),
|
|
1714
|
+
initial: () => A(e),
|
|
1715
|
+
validate: (l) => L(l) || "Invalid package.json name"
|
|
1716
|
+
},
|
|
1717
|
+
{
|
|
1718
|
+
name: "basePath",
|
|
1719
|
+
type: "text",
|
|
1720
|
+
message: o.reset("Base path:"),
|
|
1721
|
+
initial: () => `/apps/${A(e)}/`,
|
|
1722
|
+
format: (l) => ee(String(l).trim())
|
|
1723
|
+
}
|
|
1724
|
+
],
|
|
1725
|
+
{
|
|
1726
|
+
onCancel: () => {
|
|
1727
|
+
throw new E();
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
), a = n.appName || A(t), s = n.packageName || A(a), c = n.basePath || `/apps/${a}/`;
|
|
1731
|
+
return {
|
|
1732
|
+
appName: a,
|
|
1733
|
+
packageName: s,
|
|
1734
|
+
moduleName: "",
|
|
1735
|
+
basePath: c
|
|
1736
|
+
};
|
|
1737
|
+
} catch (n) {
|
|
1738
|
+
if (n instanceof E)
|
|
1739
|
+
throw n;
|
|
1740
|
+
const a = n;
|
|
1741
|
+
throw new B([a.message]);
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
function He(t, e) {
|
|
1745
|
+
if (r.existsSync(t)) {
|
|
1746
|
+
if (!de(t) && !e.overwrite)
|
|
1747
|
+
throw new B([
|
|
1748
|
+
`Target directory "${t}" is not empty. Use --overwrite to overwrite existing files.`
|
|
1749
|
+
]);
|
|
1750
|
+
ce(t);
|
|
1751
|
+
} else
|
|
1752
|
+
r.mkdirSync(t, { recursive: !0 });
|
|
1753
|
+
}
|
|
1754
|
+
function Ke(t) {
|
|
1755
|
+
return /* @__PURE__ */ new Map([
|
|
1756
|
+
["{{AppName}}", t.appName],
|
|
1757
|
+
["{{AppNameSentenceCase}}", tt(t.appName)],
|
|
1758
|
+
["{{BasePath}}", t.basePath],
|
|
1759
|
+
["{{PackageName}}", t.packageName]
|
|
1760
|
+
]);
|
|
1761
|
+
}
|
|
1762
|
+
function Je(t) {
|
|
1763
|
+
const e = m.resolve(X(import.meta.url), "..", "..", "templates"), n = m.join(e, t.templateName);
|
|
1764
|
+
let a = 0;
|
|
1765
|
+
return ie(n, (s, c) => {
|
|
1766
|
+
const l = m.join(t.targetDirectory, c), d = Ye(l, t.replacements);
|
|
1767
|
+
if (r.statSync(s).isDirectory()) {
|
|
1768
|
+
r.mkdirSync(d, { recursive: !0 });
|
|
1769
|
+
return;
|
|
1770
|
+
}
|
|
1771
|
+
const u = m.dirname(d);
|
|
1772
|
+
if (r.existsSync(u) || r.mkdirSync(u, { recursive: !0 }), Qe(s))
|
|
1773
|
+
r.copyFileSync(s, d);
|
|
1774
|
+
else {
|
|
1775
|
+
const g = r.readFileSync(s, "utf-8"), p = Ze(g, t.replacements);
|
|
1776
|
+
r.writeFileSync(d, p);
|
|
1777
|
+
}
|
|
1778
|
+
a += 1;
|
|
1779
|
+
}), a;
|
|
1780
|
+
}
|
|
1781
|
+
function ie(t, e, n = "") {
|
|
1782
|
+
const a = r.readdirSync(t);
|
|
1783
|
+
for (const s of a) {
|
|
1784
|
+
const c = m.join(t, s), l = m.join(n, Se[s] ?? s);
|
|
1785
|
+
r.statSync(c).isDirectory() ? ie(c, e, l) : e(c, l);
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
function Ye(t, e) {
|
|
1789
|
+
let n = t;
|
|
1790
|
+
for (const [a, s] of e) {
|
|
1791
|
+
const c = new RegExp(a, "g");
|
|
1792
|
+
n = n.replace(c, s);
|
|
1793
|
+
}
|
|
1794
|
+
return n;
|
|
1795
|
+
}
|
|
1796
|
+
function Ze(t, e) {
|
|
1797
|
+
let n = t;
|
|
1798
|
+
for (const [a, s] of e) {
|
|
1799
|
+
const c = new RegExp(a, "g");
|
|
1800
|
+
n = n.replace(c, s);
|
|
1801
|
+
}
|
|
1802
|
+
return n;
|
|
1803
|
+
}
|
|
1804
|
+
function Qe(t) {
|
|
1805
|
+
const e = m.extname(t).toLowerCase();
|
|
1806
|
+
return [".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".pdf", ".zip"].includes(e);
|
|
1807
|
+
}
|
|
1808
|
+
function ce(t) {
|
|
1809
|
+
if (r.existsSync(t))
|
|
1810
|
+
for (const e of r.readdirSync(t)) {
|
|
1811
|
+
const n = m.join(t, e);
|
|
1812
|
+
r.lstatSync(n).isDirectory() ? ce(n) : r.unlinkSync(n);
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
function de(t) {
|
|
1816
|
+
const e = r.readdirSync(t);
|
|
1817
|
+
return e.length === 0 || e.length === 1 && e[0] === ".git";
|
|
1818
|
+
}
|
|
1819
|
+
async function Xe(t) {
|
|
1820
|
+
try {
|
|
1821
|
+
await te(t, $e), console.log(o.green("✅ All files formatted"));
|
|
1822
|
+
} catch (e) {
|
|
1823
|
+
console.log(o.yellow(`⚠️ Some files could not be formatted: ${e.message}`));
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
async function et(t, e) {
|
|
1827
|
+
console.log(o.cyan(`
|
|
1828
|
+
🏗️ Creating module with blade generator...
|
|
1829
|
+
`));
|
|
1830
|
+
try {
|
|
1831
|
+
await le({
|
|
1832
|
+
name: void 0,
|
|
1833
|
+
type: void 0,
|
|
1834
|
+
module: void 0,
|
|
1835
|
+
composable: !0,
|
|
1836
|
+
locales: !0,
|
|
1837
|
+
widget: !1,
|
|
1838
|
+
isWorkspace: !0,
|
|
1839
|
+
path: t,
|
|
1840
|
+
formFields: e["form-fields"],
|
|
1841
|
+
skipFormEditor: e["skip-form-editor"],
|
|
1842
|
+
_skipActionPrompt: !0
|
|
1843
|
+
});
|
|
1844
|
+
} catch (n) {
|
|
1845
|
+
if (n instanceof E) {
|
|
1846
|
+
console.log(o.yellow(`
|
|
1847
|
+
⚠️ Module generation cancelled`)), console.log(o.yellow(" You can add modules later using: create-vc-app blade"));
|
|
1848
|
+
return;
|
|
1849
|
+
}
|
|
1850
|
+
console.log(o.yellow(`
|
|
1851
|
+
⚠️ Module generation failed: ${n.message}`)), console.log(o.yellow(" You can add modules later using: create-vc-app blade"));
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
function tt(t) {
|
|
1855
|
+
return t.split("-").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
|
|
1856
|
+
}
|
|
1857
|
+
async function at(t) {
|
|
1858
|
+
const e = ge(t);
|
|
1859
|
+
if (e.help)
|
|
1860
|
+
return we(), 0;
|
|
1861
|
+
if (e.version)
|
|
1862
|
+
return be(), 0;
|
|
1863
|
+
nt();
|
|
1864
|
+
const n = e._[0];
|
|
1865
|
+
if (n === "blade" || n === "generate")
|
|
1866
|
+
return await ot(e), 0;
|
|
1867
|
+
const a = ye(e);
|
|
1868
|
+
if (a.length > 0)
|
|
1869
|
+
throw new B(a);
|
|
1870
|
+
return lt(), await st(e), 0;
|
|
1871
|
+
}
|
|
1872
|
+
function nt() {
|
|
1873
|
+
const t = Ee();
|
|
1874
|
+
if (!t.compatible)
|
|
1875
|
+
throw new O(
|
|
1876
|
+
[
|
|
1877
|
+
o.red(`❌ Node.js ${t.minVersion} or higher is required.`),
|
|
1878
|
+
o.red(` Current version: ${t.currentVersion}`),
|
|
1879
|
+
o.yellow(`
|
|
1880
|
+
Please upgrade Node.js to continue.`)
|
|
1881
|
+
].join(`
|
|
1882
|
+
`)
|
|
1883
|
+
);
|
|
1884
|
+
}
|
|
1885
|
+
async function ot(t) {
|
|
1886
|
+
const [, e] = t._;
|
|
1887
|
+
await le({
|
|
1888
|
+
name: e || t.name,
|
|
1889
|
+
type: t.type,
|
|
1890
|
+
module: t.module,
|
|
1891
|
+
composable: t.composable,
|
|
1892
|
+
locales: t.locales,
|
|
1893
|
+
widget: t.widget,
|
|
1894
|
+
isWorkspace: t["is-workspace"],
|
|
1895
|
+
path: t.path,
|
|
1896
|
+
formFields: t["form-fields"],
|
|
1897
|
+
skipFormEditor: t["skip-form-editor"]
|
|
1898
|
+
});
|
|
1899
|
+
}
|
|
1900
|
+
async function st(t) {
|
|
1901
|
+
try {
|
|
1902
|
+
const e = await qe({ args: t, cwd: _() });
|
|
1903
|
+
rt(e.root, e.config.packageName, e.config.basePath, e.filesCreated), it(e.root);
|
|
1904
|
+
} catch (e) {
|
|
1905
|
+
if (e instanceof E) {
|
|
1906
|
+
console.log(o.yellow(`
|
|
1907
|
+
⚠️ Operation cancelled by user`)), console.log(o.gray(` No changes were made.
|
|
1908
|
+
`));
|
|
1909
|
+
return;
|
|
1910
|
+
}
|
|
1911
|
+
throw e;
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
function lt() {
|
|
1915
|
+
const t = "═".repeat(50);
|
|
1916
|
+
console.log(o.bold(o.green(`
|
|
1917
|
+
╔${t}╗`))), console.log(o.bold(o.green(`║ create-vc-app v${U.version}${" ".repeat(33 - String(U.version).length)}║`))), console.log(o.bold(o.green(`╚${t}╝
|
|
1918
|
+
`)));
|
|
1919
|
+
}
|
|
1920
|
+
function rt(t, e, n, a) {
|
|
1921
|
+
console.log(o.green(`
|
|
1922
|
+
${"=".repeat(50)}`)), console.log(o.green(o.bold("✨ Application created successfully!"))), console.log(o.green(`${"=".repeat(50)}
|
|
1923
|
+
`)), console.log(o.cyan("📊 Summary:")), console.log(o.cyan(` Location: ${o.bold(t)}`)), console.log(o.cyan(` Package: ${o.bold(e)}`)), console.log(o.cyan(` Base path: ${o.bold(n)}`)), console.log(o.cyan(` Files created: ${o.bold(a.toString())}`));
|
|
1924
|
+
}
|
|
1925
|
+
function it(t) {
|
|
1926
|
+
console.log(o.cyan(`
|
|
1927
|
+
🚀 Next steps:
|
|
1928
|
+
`));
|
|
1929
|
+
const e = _();
|
|
1930
|
+
if (t !== e) {
|
|
1931
|
+
const n = m.relative(e, t) || t, a = n.includes(" ") ? `"${n}"` : n;
|
|
1932
|
+
console.log(o.white(` 1. ${o.bold(o.cyan(`cd ${a}`))}`)), console.log(o.white(` 2. ${o.bold(o.cyan("yarn"))}`)), console.log(o.white(` 3. ${o.bold(o.cyan("yarn serve"))}`));
|
|
1933
|
+
} else
|
|
1934
|
+
console.log(o.white(` 1. ${o.bold(o.cyan("yarn"))}`)), console.log(o.white(` 2. ${o.bold(o.cyan("yarn serve"))}`));
|
|
1935
|
+
console.log(o.gray(`
|
|
1936
|
+
You can also run:`)), console.log(o.gray(" yarn build - Build for production")), console.log(o.gray(" yarn lint - Run linter")), console.log(o.gray(" create-vc-app blade - Generate modules/blades/widgets")), console.log();
|
|
1937
|
+
}
|
|
1938
|
+
async function ct() {
|
|
1939
|
+
try {
|
|
1940
|
+
await at(process.argv.slice(2));
|
|
1941
|
+
} catch (t) {
|
|
1942
|
+
dt(t);
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
function dt(t) {
|
|
1946
|
+
if (t instanceof E && (console.log(o.yellow(`
|
|
1947
|
+
⚠️ Operation cancelled by user
|
|
1948
|
+
`)), process.exit(0)), t instanceof B) {
|
|
1949
|
+
if (t.issues?.length) {
|
|
1950
|
+
console.error(o.red(`
|
|
1951
|
+
❌ Validation errors:
|
|
1952
|
+
`));
|
|
1953
|
+
for (const n of t.issues)
|
|
1954
|
+
console.error(o.red(` • ${n}`));
|
|
1955
|
+
console.log(o.gray(`
|
|
1956
|
+
Run ${o.cyan("create-vc-app --help")} for usage information.
|
|
1957
|
+
`));
|
|
1958
|
+
}
|
|
1959
|
+
process.exit(t.exitCode);
|
|
1960
|
+
}
|
|
1961
|
+
t instanceof O && (console.error(t.message), process.exit(t.exitCode));
|
|
1962
|
+
const e = t instanceof Error ? t.message : String(t);
|
|
1963
|
+
console.error(o.red(`
|
|
1964
|
+
❌ Unexpected error: ${e}`)), t instanceof Error && t.stack && console.error(o.gray(t.stack)), process.exit(1);
|
|
1965
|
+
}
|
|
1966
|
+
ct();
|