@vc-shell/create-vc-app 1.1.99-alpha.2 → 1.2.1

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.
Files changed (86) hide show
  1. package/README.md +26 -552
  2. package/dist/index.js +530 -1901
  3. package/dist/templates/base/_package.json +6 -7
  4. package/dist/templates/base/src/main.ts +4 -0
  5. package/dist/templates/mocks/sample-data/constants.ts +89 -0
  6. package/dist/templates/mocks/sample-data/index.ts +2 -0
  7. package/dist/templates/mocks/sample-data/methods.ts +65 -0
  8. package/dist/templates/modules/classic-module/composables/index.ts +2 -0
  9. package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}Details/index.ts +24 -0
  10. package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}List/index.ts +47 -0
  11. package/dist/templates/modules/classic-module/index.ts +8 -0
  12. package/dist/templates/modules/classic-module/locales/en.json +37 -0
  13. package/dist/templates/modules/classic-module/locales/index.ts +2 -0
  14. package/dist/templates/modules/classic-module/pages/details.vue +87 -0
  15. package/dist/templates/modules/classic-module/pages/index.ts +2 -0
  16. package/dist/templates/modules/classic-module/pages/list.vue +257 -0
  17. package/dist/templates/sample/classic-module/composables/index.ts +2 -0
  18. package/dist/templates/sample/classic-module/composables/useDetails/index.ts +54 -0
  19. package/dist/templates/sample/classic-module/composables/useList/index.ts +62 -0
  20. package/dist/templates/sample/classic-module/index.ts +8 -0
  21. package/dist/templates/sample/classic-module/locales/en.json +67 -0
  22. package/dist/templates/sample/classic-module/locales/index.ts +2 -0
  23. package/dist/templates/sample/classic-module/pages/details.vue +238 -0
  24. package/dist/templates/sample/classic-module/pages/index.ts +2 -0
  25. package/dist/templates/sample/classic-module/pages/list.vue +300 -0
  26. package/dist/templates/sample/overrides/main.ts +52 -0
  27. package/package.json +7 -12
  28. package/dist/cli/argv.d.ts +0 -4
  29. package/dist/cli/argv.d.ts.map +0 -1
  30. package/dist/cli/constants.d.ts +0 -4
  31. package/dist/cli/constants.d.ts.map +0 -1
  32. package/dist/cli/errors.d.ts +0 -12
  33. package/dist/cli/errors.d.ts.map +0 -1
  34. package/dist/cli/help.d.ts +0 -3
  35. package/dist/cli/help.d.ts.map +0 -1
  36. package/dist/cli/run.d.ts +0 -2
  37. package/dist/cli/run.d.ts.map +0 -1
  38. package/dist/cli/runtime.d.ts +0 -7
  39. package/dist/cli/runtime.d.ts.map +0 -1
  40. package/dist/cli/types.d.ts +0 -30
  41. package/dist/cli/types.d.ts.map +0 -1
  42. package/dist/cli/utils.d.ts +0 -4
  43. package/dist/cli/utils.d.ts.map +0 -1
  44. package/dist/cli/validation.d.ts +0 -5
  45. package/dist/cli/validation.d.ts.map +0 -1
  46. package/dist/commands/generate-blade.d.ts +0 -16
  47. package/dist/commands/generate-blade.d.ts.map +0 -1
  48. package/dist/templates/base/_husky/commit-msg +0 -4
  49. package/dist/templates/base/_husky/pre-commit +0 -4
  50. package/dist/templates/base/ai-guides/.cursorrules-vc-shell +0 -529
  51. package/dist/templates/base/ai-guides/README.md +0 -360
  52. package/dist/templates/base/ai-guides/guides/AI_GUIDE.md +0 -195
  53. package/dist/templates/base/ai-guides/guides/blade-patterns.md +0 -384
  54. package/dist/templates/base/ai-guides/guides/complete-workflow.md +0 -781
  55. package/dist/templates/base/ai-guides/guides/composables-reference.md +0 -338
  56. package/dist/templates/base/ai-guides/guides/troubleshooting.md +0 -529
  57. package/dist/templates/base/ai-guides/guides/ui-components-reference.md +0 -903
  58. package/dist/templates/base/ai-guides/prompts/adapt-existing-module.md +0 -1026
  59. package/dist/templates/base/ai-guides/prompts/advanced-scenarios.md +0 -852
  60. package/dist/templates/base/ai-guides/prompts/api-client-generation.md +0 -877
  61. package/dist/templates/base/ai-guides/prompts/cli-usage.md +0 -640
  62. package/dist/templates/base/ai-guides/prompts/quick-start-scenarios.md +0 -773
  63. package/dist/templates/base/ai-guides/prompts/simple-modifications.md +0 -987
  64. package/dist/templates/base/scripts/release.ts +0 -5
  65. package/dist/templates/blades/details/blade.vue +0 -175
  66. package/dist/templates/blades/grid/blade.vue +0 -340
  67. package/dist/templates/composables/details-composable.ts +0 -101
  68. package/dist/templates/composables/grid-composable.ts +0 -244
  69. package/dist/templates/module/components/index.ts +0 -2
  70. package/dist/templates/module/components/widgets/index.ts +0 -2
  71. package/dist/templates/module/composables/index.ts +0 -3
  72. package/dist/templates/module/index.ts +0 -13
  73. package/dist/templates/module/locales/en.json +0 -65
  74. package/dist/templates/module/locales/index.ts +0 -4
  75. package/dist/templates/module/pages/index.ts +0 -3
  76. package/dist/templates/widgets/widget.vue +0 -113
  77. package/dist/utils/form-builder.d.ts +0 -69
  78. package/dist/utils/form-builder.d.ts.map +0 -1
  79. package/dist/utils/format.d.ts +0 -24
  80. package/dist/utils/format.d.ts.map +0 -1
  81. package/dist/utils/naming.d.ts +0 -44
  82. package/dist/utils/naming.d.ts.map +0 -1
  83. package/dist/utils/register-module.d.ts +0 -21
  84. package/dist/utils/register-module.d.ts.map +0 -1
  85. package/dist/workflows/create-app.d.ts +0 -14
  86. package/dist/workflows/create-app.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,122 +1,340 @@
1
1
  #!/usr/bin/env node
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
- });
31
- }
32
- function L(t) {
33
- return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(t);
34
- }
35
- function A(t) {
36
- return t.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9-~]+/g, "-");
37
- }
38
- function ee(t) {
39
- return t.trim().toLowerCase().replace(/\/+/g, "/").replace(/[^a-z0-9/-]+/g, "/").replace(/\/?$/, "/");
2
+ import Ae from "prompts";
3
+ import Ne from "mri";
4
+ import t from "chalk";
5
+ import c from "node:path";
6
+ import s from "node:fs";
7
+ import { fileURLToPath as Oe } from "node:url";
8
+ import { cwd as Me, exit as Ee, argv as Te } from "node:process";
9
+ const Ue = "1.2.1", I = {
10
+ version: Ue
11
+ };
12
+ var Pe = typeof global == "object" && global && global.Object === Object && global, Le = typeof self == "object" && self && self.Object === Object && self, _e = Pe || Le || Function("return this")(), b = _e.Symbol, K = Object.prototype, ze = K.hasOwnProperty, De = K.toString, $ = b ? b.toStringTag : void 0;
13
+ function Ie(e) {
14
+ var r = ze.call(e, $), a = e[$];
15
+ try {
16
+ e[$] = void 0;
17
+ var o = !0;
18
+ } catch {
19
+ }
20
+ var i = De.call(e);
21
+ return o && (r ? e[$] = a : delete e[$]), i;
22
+ }
23
+ var Ze = Object.prototype, Fe = Ze.toString;
24
+ function Ve(e) {
25
+ return Fe.call(e);
26
+ }
27
+ var He = "[object Null]", We = "[object Undefined]", Z = b ? b.toStringTag : void 0;
28
+ function Be(e) {
29
+ return e == null ? e === void 0 ? We : He : Z && Z in Object(e) ? Ie(e) : Ve(e);
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
+ };
40
88
  }
41
- function fe(t) {
42
- return t.startsWith("/") && t.endsWith("/");
89
+ var L = ie("toUpperCase");
90
+ function Cr(e) {
91
+ return L(R(e).toLowerCase());
43
92
  }
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;
93
+ function kr(e, r, a, o) {
94
+ for (var i = -1, u = e == null ? 0 : e.length; ++i < u; )
95
+ a = r(a, e[i], i, e);
96
+ return a;
47
97
  }
48
- const he = "1.1.99-alpha.2", 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
- `);
98
+ function wr(e) {
99
+ return function(r) {
100
+ return e?.[r];
101
+ };
115
102
  }
116
- function be() {
117
- console.log(`create-vc-app version ${U.version}`);
103
+ var jr = {
104
+ // Latin-1 Supplement block.
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 kr(ca(Pr(r).replace(fa, "")), e, "");
328
+ };
118
329
  }
119
- const Se = {
330
+ var G = _(function(e, r, a) {
331
+ return r = r.toLowerCase(), e + (a ? Cr(r) : r);
332
+ }), pa = ie("toLowerCase"), ma = _(function(e, r, a) {
333
+ return e + (a ? "_" : "") + r.toLowerCase();
334
+ }), k = _(function(e, r, a) {
335
+ return e + (a ? " " : "") + L(r);
336
+ });
337
+ const da = {
120
338
  _gitignore: ".gitignore",
121
339
  "_yarnrc.yml": ".yarnrc.yml",
122
340
  _browserslistrc: ".browserslistrc",
@@ -129,1838 +347,249 @@ const Se = {
129
347
  _prettierrc: ".prettierrc",
130
348
  "_eslintrc.js": ".eslintrc.js",
131
349
  _github: ".github",
132
- _husky: ".husky",
133
350
  _vscode: ".vscode",
134
351
  _yarn: ".yarn",
135
352
  "_package.json": "package.json"
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}`));
171
- }
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);
353
+ }, j = [
354
+ // {
355
+ // name: "dynamic",
356
+ // display: "Dynamic view modules boilerplate",
357
+ // },
358
+ {
359
+ name: "classic",
360
+ display: "Classic view modules boilerplate"
178
361
  }
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();
473
-
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
- },
362
+ ], T = {
363
+ classic: ["classic-module"],
364
+ dynamic: ["dynamic-module"]
498
365
  };
366
+ function ga() {
367
+ console.log(`
368
+ ${t.bold(t.green("create-vc-app"))} - Create a new VC Shell application
499
369
 
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(`
370
+ ${t.bold("Usage:")}
371
+ create-vc-app [project-name] [options]
372
+
373
+ ${t.bold("Options:")}
374
+ --name, --app-name <name> Name of the application
375
+ --package-name <name> Package name (defaults to app name)
376
+ --variant <variant> Module variant (classic|dynamic) [default: classic]
377
+ --module-name <name> Module name (defaults to app name in title case)
378
+ --base-path <path> Base path for the application [default: /apps/<app-name>/]
379
+ --mocks Include additional module with sample data
380
+ --overwrite Overwrite existing files without confirmation
381
+ --help, -h Show this help message
382
+ --version, -v Show version
383
+
384
+ ${t.bold("Examples:")}
385
+ create-vc-app my-app
386
+ create-vc-app my-app --variant classic --mocks
387
+ create-vc-app my-app --module-name "My Module" --base-path "/custom/path/"
388
+ create-vc-app . --name existing-project --overwrite
643
389
 
390
+ ${t.bold("Non-interactive mode:")}
391
+ create-vc-app my-app --variant classic --module-name "My Module" --mocks --overwrite
392
+
393
+ ${t.bold("Available variants:")}
394
+ ${j.map((e) => ` ${e.name.padEnd(10)} - ${e.display}`).join(`
395
+ `)}
644
396
  `);
645
397
  }
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;
398
+ function w(e) {
399
+ return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(e);
653
400
  }
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
- />`;
401
+ function p(e) {
402
+ return e.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9-~]+/g, "-");
682
403
  }
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
- }
404
+ function Y(e) {
405
+ return e.trim().toLowerCase().replace(/\/+/g, "/").replace(/[^a-z0-9/-]+/g, "/").replace(/\/?$/, "/");
724
406
  }
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
- }
407
+ function he(e) {
408
+ if (s.existsSync(e))
409
+ s.readdirSync(e).forEach((r) => {
410
+ const a = c.join(e, r);
411
+ s.lstatSync(a).isDirectory() ? he(a) : s.unlinkSync(a);
412
+ });
413
+ else
414
+ return;
739
415
  }
740
- class O extends Error {
741
- exitCode;
742
- constructor(e, n = 1) {
743
- super(e), this.name = "CLIError", this.exitCode = n;
744
- }
416
+ function q(e) {
417
+ const r = s.readdirSync(e);
418
+ return r.length === 0 || r.length === 1 && r[0] === ".git";
745
419
  }
746
- class B extends O {
747
- issues;
748
- constructor(e) {
749
- super("Validation failed", 1), this.name = "ValidationError", this.issues = e;
750
- }
420
+ function xa(e) {
421
+ const r = [];
422
+ return e.variant && !j.some((a) => a.name === e.variant) && r.push(`Invalid variant: ${e.variant}. Available variants: ${j.map((a) => a.name).join(", ")}`), e["package-name"] && !w(e["package-name"]) && r.push(`Invalid package name: ${e["package-name"]}`), { valid: r.length === 0, errors: r };
751
423
  }
752
- class E extends O {
753
- constructor() {
754
- super("Operation cancelled by user", 0), this.name = "UserCancelledError";
755
- }
424
+ function ba() {
425
+ return Ne(Te.slice(2), {
426
+ alias: {
427
+ h: "help",
428
+ v: "version"
429
+ },
430
+ boolean: ["help", "version", "mocks", "overwrite"],
431
+ string: ["name", "app-name", "package-name", "variant", "module-name", "base-path"]
432
+ });
756
433
  }
757
- function se(t) {
758
- if (!r.existsSync(t))
434
+ async function va() {
435
+ const e = ba();
436
+ if (e.help) {
437
+ ga();
759
438
  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}` : ""}`);
818
439
  }
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
- `));
440
+ if (e.version) {
441
+ console.log(`create-vc-app version ${I.version}`);
839
442
  return;
840
443
  }
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(
444
+ const r = xa(e);
445
+ r.valid || (console.error(t.red("Error:")), r.errors.forEach((n) => console.error(t.red(` ${n}`))), process.exit(1)), console.log(` ${t.bold(t.green(`
446
+ create-vc-app version: ${I.version}
447
+ `))}`);
448
+ const a = Me();
449
+ let o = e._[0] || e.name || e["app-name"];
450
+ const i = o || "vc-app", u = () => o === "." ? c.basename(c.resolve()) : o, $e = !!(o || e.name || e["app-name"]);
451
+ let l;
452
+ try {
453
+ if ($e && e.variant) {
454
+ o = o || e.name || e["app-name"] || i, o || (console.error(t.red("Project name is required")), process.exit(1)), s.existsSync(o) && !q(o) && !e.overwrite && (console.error(
455
+ t.red(`Target directory "${o}" is not empty. Use --overwrite to overwrite existing files.`)
456
+ ), process.exit(1));
457
+ const n = u(), g = e["package-name"] || (w(n) ? n : p(n)), S = e["module-name"] || k(n), N = e["base-path"] || Y(`/apps/${p(n)}/`);
458
+ l = {
459
+ appName: p(o),
460
+ packageName: g,
461
+ variant: e.variant,
462
+ moduleName: S,
463
+ basePath: N,
464
+ mocks: e.mocks || !1
465
+ }, console.log(t.cyan("Creating app with the following configuration:")), console.log(t.cyan(` App name: ${l.appName}`)), console.log(t.cyan(` Package name: ${l.packageName}`)), console.log(t.cyan(` Variant: ${l.variant}`)), console.log(t.cyan(` Module name: ${l.moduleName}`)), console.log(t.cyan(` Base path: ${l.basePath}`)), console.log(t.cyan(` Mocks: ${l.mocks ? "Yes" : "No"}`)), console.log();
466
+ } else
467
+ l = await Ae(
896
468
  [
897
469
  {
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
470
+ name: "appName",
471
+ type: o ? null : "text",
472
+ message: t.reset("Project name:"),
473
+ initial: i,
474
+ onState: (n) => o = p(String(n.value).trim()) || i,
475
+ format: (n) => p(String(n).trim())
904
476
  },
905
477
  {
906
- type: "text",
907
- name: "entitySingular",
908
- message: "Entity name (e.g., Product, Order):",
909
- validate: (d) => d.length > 0 ? !0 : "Entity name is required"
478
+ type: () => !s.existsSync(o) || q(o) ? null : "confirm",
479
+ name: "overwrite",
480
+ message: () => (o === "." ? "Current directory" : `Target directory "${o}"`) + " is not empty. Remove existing files and continue?"
910
481
  },
911
482
  {
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
- [
483
+ type: (n, { overwrite: g }) => {
484
+ if (g === !1)
485
+ throw new Error(t.red("✖") + " Operation cancelled");
486
+ return null;
487
+ },
488
+ name: "overwriteChecker"
489
+ },
490
+ {
491
+ name: "packageName",
492
+ type: () => w(u()) ? null : "text",
493
+ message: t.reset("Package name:"),
494
+ initial: () => p(u()),
495
+ validate: (n) => w(n) || "Invalid package.json name"
496
+ },
497
+ {
498
+ name: "basePath",
499
+ type: "text",
500
+ message: t.reset("Base path:"),
501
+ initial: () => "/apps/" + p(u()) + "/",
502
+ format: (n) => Y(String(n).trim())
503
+ },
954
504
  {
955
505
  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
- ]
506
+ name: "variant",
507
+ message: t.reset("Select module variant:"),
508
+ choices: j.map((n) => ({
509
+ title: n.display,
510
+ value: n.name
511
+ }))
512
+ },
513
+ {
514
+ name: "moduleName",
515
+ type: "text",
516
+ message: t.reset("Module name:"),
517
+ initial: () => k(u()),
518
+ format: (n) => String(n).trim()
962
519
  },
963
520
  {
521
+ name: "mocks",
964
522
  type: "confirm",
965
- name: "isWorkspace",
966
- message: "Make this a workspace blade (main module blade)?",
967
- initial: !0
523
+ message: "Do you want to include additional module with sample data?",
524
+ initial: !1
968
525
  }
969
526
  ],
970
527
  {
971
528
  onCancel: () => {
972
- throw new E();
529
+ throw new Error(t.red("✖") + " Creation cancelled");
973
530
  }
974
531
  }
975
532
  );
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($);
1063
- }
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();
1160
- }
533
+ } catch (n) {
534
+ console.log(n.message), Ee(1);
535
+ }
536
+ const { packageName: Se, variant: v, moduleName: d, appName: z, basePath: Ce, mocks: ke } = l, A = /* @__PURE__ */ new Map([
537
+ ["{{ModuleName}}", p(d)],
538
+ ["{{ModuleNamePascalCase}}", L(G(d))],
539
+ ["{{ModuleNameUppercase}}", d.toUpperCase()],
540
+ ["{{ModuleNameUppercaseSnakeCase}}", ma(d).toUpperCase()],
541
+ ["{{ModuleNameExports}}", pa(G(d))],
542
+ ["{{ModuleNameSentenceCase}}", k(d)],
543
+ ["{{AppName}}", z],
544
+ ["{{AppNameSentenceCase}}", k(z)],
545
+ ["{{BasePath}}", Ce],
546
+ ["{{PackageName}}", Se || u()]
547
+ ]), f = c.join(a, o);
548
+ s.existsSync(f) ? he(f) : s.existsSync(f) || s.mkdirSync(f), console.log(`
549
+ Scaffolding app in ${f}...`);
550
+ const we = c.resolve(Oe(import.meta.url), "..", "templates");
551
+ function m(n, g = "") {
552
+ const S = c.resolve(we, n), N = s.readdirSync(S);
553
+ for (const y of N) {
554
+ const O = c.join(S, y);
555
+ let C = da[y] ?? y;
556
+ for (const [D, h] of A.entries()) {
557
+ const E = new RegExp(D, "g");
558
+ C = C.replace(E, h);
1161
559
  }
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();
560
+ const M = c.join(f, g, C);
561
+ if (s.statSync(O).isDirectory())
562
+ s.mkdirSync(M, { recursive: !0 }), m(c.join(n, y), c.join(g, C));
563
+ else if ([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".pdf", ".zip"].includes(
564
+ c.extname(y).toLowerCase()
565
+ ))
566
+ s.copyFileSync(O, M);
567
+ else {
568
+ let h = s.readFileSync(O, "utf-8");
569
+ for (const [E, je] of A.entries()) {
570
+ const Re = new RegExp(E, "g");
571
+ h = h.replace(Re, je);
1174
572
  }
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);
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")));
573
+ s.writeFileSync(M, h);
1210
574
  }
1211
575
  }
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;
1224
576
  }
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
- }
577
+ if (m("base"), T[v].forEach((n) => {
578
+ m(`modules/${n}`, "src/modules/" + A.get("{{ModuleName}}"));
579
+ }), ke && (v === "dynamic" && T[v].forEach((n) => {
580
+ m(`sample/${n}`, "src/modules/sample");
581
+ }), v === "classic" && T[v].forEach((n) => {
582
+ m(`sample/${n}`, "src/modules/sample");
583
+ }), m("mocks", "src/modules/sample"), m("sample/overrides", "src")), console.log(`
584
+ Done. You can now run application:
585
+ `), f !== a) {
586
+ const n = c.relative(a, f);
587
+ console.log(
588
+ ` ${t.bold(t.green(`cd ${n.includes(" ") ? `"${n}"` : n}`))}`
1295
589
  );
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;
1373
590
  }
591
+ console.log(` ${t.bold(t.green("yarn"))}`), console.log(` ${t.bold(t.green("yarn serve"))}`);
1374
592
  }
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}
593
+ va().catch((e) => {
594
+ console.error(e);
1460
595
  });
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();