@vercube/cli 0.0.1-alpha.15

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.
@@ -0,0 +1,2 @@
1
+ import { type CommandDef } from "citty";
2
+ export declare const buildCommand: CommandDef;
@@ -0,0 +1,2 @@
1
+ import { type CommandDef } from "citty";
2
+ export declare const devCommand: CommandDef;
@@ -0,0 +1,4 @@
1
+ import { type CommandDef } from "citty";
2
+ import { type ConsolaInstance } from "consola";
3
+ export declare const logger: ConsolaInstance;
4
+ export declare const initCommand: CommandDef;
package/dist/index.cjs ADDED
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+ //#region rolldown:runtime
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+
24
+ //#endregion
25
+ const citty = __toESM(require("citty"));
26
+ const __vercube_devkit = __toESM(require("@vercube/devkit"));
27
+ const consola = __toESM(require("consola"));
28
+ const node_tty = __toESM(require("node:tty"));
29
+ const std_env = __toESM(require("std-env"));
30
+ const pathe = __toESM(require("pathe"));
31
+ const node_fs = __toESM(require("node:fs"));
32
+ const giget = __toESM(require("giget"));
33
+ const nypm = __toESM(require("nypm"));
34
+ const tinyexec = __toESM(require("tinyexec"));
35
+
36
+ //#region packages/cli/package.json
37
+ var version = "0.0.1-alpha.14";
38
+
39
+ //#endregion
40
+ //#region packages/cli/src/commands/build.ts
41
+ const buildCommand = (0, citty.defineCommand)({
42
+ meta: {
43
+ name: "build",
44
+ description: "Build the project"
45
+ },
46
+ run: async () => {
47
+ const app = await (0, __vercube_devkit.createVercube)();
48
+ await (0, __vercube_devkit.build)(app);
49
+ }
50
+ });
51
+
52
+ //#endregion
53
+ //#region packages/cli/src/commands/dev.ts
54
+ const devCommand = (0, citty.defineCommand)({
55
+ meta: {
56
+ name: "dev",
57
+ description: "Start development server"
58
+ },
59
+ async run() {
60
+ const app = await (0, __vercube_devkit.createVercube)();
61
+ (0, __vercube_devkit.createDevServer)(app);
62
+ await (0, __vercube_devkit.watch)(app);
63
+ }
64
+ });
65
+
66
+ //#endregion
67
+ //#region node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs
68
+ const { env = {}, argv = [], platform = "" } = typeof process === "undefined" ? {} : process;
69
+ const isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
70
+ const isForced = "FORCE_COLOR" in env || argv.includes("--color");
71
+ const isWindows = platform === "win32";
72
+ const isDumbTerminal = env.TERM === "dumb";
73
+ const isCompatibleTerminal = node_tty && node_tty.isatty && node_tty.isatty(1) && env.TERM && !isDumbTerminal;
74
+ const isCI = "CI" in env && ("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);
75
+ const isColorSupported = !isDisabled && (isForced || isWindows && !isDumbTerminal || isCompatibleTerminal || isCI);
76
+ function replaceClose(index, string, close, replace, head = string.slice(0, Math.max(0, index)) + replace, tail = string.slice(Math.max(0, index + close.length)), next = tail.indexOf(close)) {
77
+ return head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
78
+ }
79
+ function clearBleed(index, string, open, close, replace) {
80
+ return index < 0 ? open + string + close : open + replaceClose(index, string, close, replace) + close;
81
+ }
82
+ function filterEmpty(open, close, replace = open, at = open.length + 1) {
83
+ return (string) => string || !(string === "" || string === void 0) ? clearBleed(("" + string).indexOf(close, at), string, open, close, replace) : "";
84
+ }
85
+ function init(open, close, replace) {
86
+ return filterEmpty(`\x1B[${open}m`, `\x1B[${close}m`, replace);
87
+ }
88
+ const colorDefs = {
89
+ reset: init(0, 0),
90
+ bold: init(1, 22, "\x1B[22m\x1B[1m"),
91
+ dim: init(2, 22, "\x1B[22m\x1B[2m"),
92
+ italic: init(3, 23),
93
+ underline: init(4, 24),
94
+ inverse: init(7, 27),
95
+ hidden: init(8, 28),
96
+ strikethrough: init(9, 29),
97
+ black: init(30, 39),
98
+ red: init(31, 39),
99
+ green: init(32, 39),
100
+ yellow: init(33, 39),
101
+ blue: init(34, 39),
102
+ magenta: init(35, 39),
103
+ cyan: init(36, 39),
104
+ white: init(37, 39),
105
+ gray: init(90, 39),
106
+ bgBlack: init(40, 49),
107
+ bgRed: init(41, 49),
108
+ bgGreen: init(42, 49),
109
+ bgYellow: init(43, 49),
110
+ bgBlue: init(44, 49),
111
+ bgMagenta: init(45, 49),
112
+ bgCyan: init(46, 49),
113
+ bgWhite: init(47, 49),
114
+ blackBright: init(90, 39),
115
+ redBright: init(91, 39),
116
+ greenBright: init(92, 39),
117
+ yellowBright: init(93, 39),
118
+ blueBright: init(94, 39),
119
+ magentaBright: init(95, 39),
120
+ cyanBright: init(96, 39),
121
+ whiteBright: init(97, 39),
122
+ bgBlackBright: init(100, 49),
123
+ bgRedBright: init(101, 49),
124
+ bgGreenBright: init(102, 49),
125
+ bgYellowBright: init(103, 49),
126
+ bgBlueBright: init(104, 49),
127
+ bgMagentaBright: init(105, 49),
128
+ bgCyanBright: init(106, 49),
129
+ bgWhiteBright: init(107, 49)
130
+ };
131
+ function createColors(useColor = isColorSupported) {
132
+ return useColor ? colorDefs : Object.fromEntries(Object.keys(colorDefs).map((key) => [key, String]));
133
+ }
134
+ const colors = createColors();
135
+ const ansiRegex = [String.raw`[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?\u0007)`, String.raw`(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))`].join("|");
136
+
137
+ //#endregion
138
+ //#region packages/cli/src/utils/logo.ts
139
+ const startColor = {
140
+ r: 149,
141
+ g: 100,
142
+ b: 245
143
+ };
144
+ const endColor = {
145
+ r: 111,
146
+ g: 114,
147
+ b: 245
148
+ };
149
+ const icon = [
150
+ " _ ",
151
+ " | | ",
152
+ " __ _____ _ __ ___ _ _| |__ ___ ",
153
+ " \\ \\ / / _ \\ '__/ __| | | | '_ \\ / _ \\",
154
+ String.raw` \ V / __/ | | (__| |_| | |_) | __/`,
155
+ String.raw` \_/ \___|_| \___|\__,_|_.__/ \___|`,
156
+ " ",
157
+ " "
158
+ ];
159
+ function interpolateColor(startColor$1, endColor$1, factor) {
160
+ const r = Math.round(startColor$1.r + factor * (endColor$1.r - startColor$1.r));
161
+ const g = Math.round(startColor$1.g + factor * (endColor$1.g - startColor$1.g));
162
+ const b = Math.round(startColor$1.b + factor * (endColor$1.b - startColor$1.b));
163
+ return `\u001B[38;2;${r};${g};${b}m`;
164
+ }
165
+ function applyGradient(icon$1, startColor$1, endColor$1) {
166
+ const totalLines = icon$1.length;
167
+ return icon$1.map((line, index) => {
168
+ const factor = index / (totalLines - 1);
169
+ const color = interpolateColor(startColor$1, endColor$1, factor);
170
+ return color + line;
171
+ }).join("\n");
172
+ }
173
+ const vercubeIcon = applyGradient(icon, startColor, endColor);
174
+
175
+ //#endregion
176
+ //#region packages/cli/src/commands/init.ts
177
+ const logger = consola.consola.withTag(colors.whiteBright(colors.bold(colors.bgGreenBright(" vercube "))));
178
+ const DEFAULT_REGISTRY = "https://raw.githubusercontent.com/vercube/starter/main/templates";
179
+ const DEFAULT_TEMPLATE_NAME = "vercube";
180
+ const pms = {
181
+ npm: void 0,
182
+ pnpm: void 0,
183
+ yarn: void 0,
184
+ bun: void 0,
185
+ deno: void 0
186
+ };
187
+ const packageManagerOptions = Object.keys(pms);
188
+ const initCommand = (0, citty.defineCommand)({
189
+ meta: {
190
+ name: "init",
191
+ description: "Initialize a new Vercube app"
192
+ },
193
+ args: {
194
+ dir: {
195
+ type: "positional",
196
+ description: "Project directory",
197
+ default: ""
198
+ },
199
+ force: {
200
+ type: "boolean",
201
+ alias: "f",
202
+ description: "Override existing directory"
203
+ },
204
+ install: {
205
+ type: "boolean",
206
+ default: true,
207
+ description: "Skip installing dependencies"
208
+ },
209
+ gitInit: {
210
+ type: "boolean",
211
+ description: "Initialize git repository",
212
+ default: true
213
+ },
214
+ packageManager: {
215
+ type: "string",
216
+ description: "Package manager choice (npm, pnpm, yarn, bun)",
217
+ default: "pnpm"
218
+ }
219
+ },
220
+ async run(ctx) {
221
+ if (std_env.hasTTY) process.stdout.write(`\n${vercubeIcon}\n\n`);
222
+ consola.consola.info(`Welcome to ${colors.bold("Vercube")}!`);
223
+ if (ctx.args.dir === "") ctx.args.dir = await logger.prompt("Where would you like to create your project?", {
224
+ placeholder: "./vercube-app",
225
+ type: "text",
226
+ default: "vercube-app",
227
+ cancel: "reject"
228
+ }).catch(() => process.exit(1));
229
+ const cwd = (0, pathe.resolve)(process.cwd());
230
+ let templateDownloadPath = (0, pathe.resolve)(cwd, ctx.args.dir);
231
+ logger.info(`Creating a new project in ${colors.cyan((0, pathe.relative)(cwd, templateDownloadPath) || templateDownloadPath)}.`);
232
+ let shouldForce = Boolean(ctx.args.force);
233
+ const shouldVerify = !shouldForce && (0, node_fs.existsSync)(templateDownloadPath);
234
+ if (shouldVerify) {
235
+ const selectedAction = await logger.prompt(`The directory ${colors.cyan(templateDownloadPath)} already exists. What would you like to do?`, {
236
+ type: "select",
237
+ options: [
238
+ "Override its contents",
239
+ "Select different directory",
240
+ "Abort"
241
+ ]
242
+ });
243
+ switch (selectedAction) {
244
+ case "Override its contents": {
245
+ shouldForce = true;
246
+ break;
247
+ }
248
+ case "Select different directory": {
249
+ templateDownloadPath = (0, pathe.resolve)(cwd, await logger.prompt("Please specify a different directory:", {
250
+ type: "text",
251
+ cancel: "reject"
252
+ }).catch(() => process.exit(1)));
253
+ break;
254
+ }
255
+ default: process.exit(1);
256
+ }
257
+ }
258
+ let template;
259
+ try {
260
+ template = await (0, giget.downloadTemplate)(DEFAULT_TEMPLATE_NAME, {
261
+ dir: templateDownloadPath,
262
+ force: shouldForce,
263
+ offline: Boolean(ctx.args.offline),
264
+ preferOffline: Boolean(ctx.args.preferOffline),
265
+ registry: DEFAULT_REGISTRY
266
+ });
267
+ } catch (error_) {
268
+ if (process.env.DEBUG) throw error_;
269
+ logger.error(error_.toString());
270
+ process.exit(1);
271
+ }
272
+ const packageManagerArg = ctx.args.packageManager;
273
+ const selectedPackageManager = packageManagerOptions.includes(packageManagerArg) ? packageManagerArg : await logger.prompt("Which package manager would you like to use?", {
274
+ type: "select",
275
+ options: packageManagerOptions,
276
+ cancel: "reject"
277
+ }).catch(() => process.exit(1));
278
+ if (ctx.args.install === false) logger.info("Skipping install dependencies step.");
279
+ else {
280
+ logger.start("Installing dependencies...");
281
+ try {
282
+ await (0, nypm.installDependencies)({
283
+ cwd: template.dir,
284
+ packageManager: {
285
+ name: selectedPackageManager,
286
+ command: selectedPackageManager
287
+ }
288
+ });
289
+ } catch (error_) {
290
+ if (process.env.DEBUG) throw error_;
291
+ logger.error(error_.toString());
292
+ process.exit(1);
293
+ }
294
+ logger.success("Installation completed.");
295
+ }
296
+ if (ctx.args.gitInit === void 0) ctx.args.gitInit = await logger.prompt("Initialize git repository?", {
297
+ type: "confirm",
298
+ cancel: "reject"
299
+ }).catch(() => process.exit(1));
300
+ if (ctx.args.gitInit) {
301
+ logger.info("Initializing git repository...\n");
302
+ try {
303
+ await (0, tinyexec.x)("git", ["init", template.dir], {
304
+ throwOnError: true,
305
+ nodeOptions: { stdio: "inherit" }
306
+ });
307
+ } catch (error_) {
308
+ logger.warn(`Failed to initialize git repository: ${error_}`);
309
+ }
310
+ }
311
+ logger.log("\n✨ Vercube project has been created! Next steps:");
312
+ const relativeTemplateDir = (0, pathe.relative)(process.cwd(), template.dir) || ".";
313
+ const runCmd = selectedPackageManager === "deno" ? "task" : "run";
314
+ const nextSteps = [!ctx.args.shell && relativeTemplateDir.length > 1 && `\`cd ${relativeTemplateDir}\``, `Start development server with \`${selectedPackageManager} ${runCmd} dev\``].filter(Boolean);
315
+ for (const step of nextSteps) logger.log(` › ${step}`);
316
+ if (ctx.args.shell) (0, giget.startShell)(template.dir);
317
+ }
318
+ });
319
+
320
+ //#endregion
321
+ //#region packages/cli/src/index.ts
322
+ const main = (0, citty.defineCommand)({
323
+ meta: {
324
+ name: "Vercube",
325
+ version,
326
+ description: "Vercube CLI"
327
+ },
328
+ subCommands: {
329
+ build: buildCommand,
330
+ dev: devCommand,
331
+ init: initCommand
332
+ }
333
+ });
334
+ (0, citty.runMain)(main);
335
+
336
+ //#endregion
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.mjs ADDED
@@ -0,0 +1,312 @@
1
+ import { defineCommand, runMain } from "citty";
2
+ import { build, createDevServer, createVercube, watch } from "@vercube/devkit";
3
+ import { consola } from "consola";
4
+ import * as tty from "node:tty";
5
+ import { hasTTY } from "std-env";
6
+ import { relative, resolve } from "pathe";
7
+ import { existsSync } from "node:fs";
8
+ import { downloadTemplate, startShell } from "giget";
9
+ import { installDependencies } from "nypm";
10
+ import { x } from "tinyexec";
11
+
12
+ //#region packages/cli/package.json
13
+ var version = "0.0.1-alpha.14";
14
+
15
+ //#endregion
16
+ //#region packages/cli/src/commands/build.ts
17
+ const buildCommand = defineCommand({
18
+ meta: {
19
+ name: "build",
20
+ description: "Build the project"
21
+ },
22
+ run: async () => {
23
+ const app = await createVercube();
24
+ await build(app);
25
+ }
26
+ });
27
+
28
+ //#endregion
29
+ //#region packages/cli/src/commands/dev.ts
30
+ const devCommand = defineCommand({
31
+ meta: {
32
+ name: "dev",
33
+ description: "Start development server"
34
+ },
35
+ async run() {
36
+ const app = await createVercube();
37
+ createDevServer(app);
38
+ await watch(app);
39
+ }
40
+ });
41
+
42
+ //#endregion
43
+ //#region node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs
44
+ const { env = {}, argv = [], platform = "" } = typeof process === "undefined" ? {} : process;
45
+ const isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
46
+ const isForced = "FORCE_COLOR" in env || argv.includes("--color");
47
+ const isWindows = platform === "win32";
48
+ const isDumbTerminal = env.TERM === "dumb";
49
+ const isCompatibleTerminal = tty && tty.isatty && tty.isatty(1) && env.TERM && !isDumbTerminal;
50
+ const isCI = "CI" in env && ("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);
51
+ const isColorSupported = !isDisabled && (isForced || isWindows && !isDumbTerminal || isCompatibleTerminal || isCI);
52
+ function replaceClose(index, string, close, replace, head = string.slice(0, Math.max(0, index)) + replace, tail = string.slice(Math.max(0, index + close.length)), next = tail.indexOf(close)) {
53
+ return head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
54
+ }
55
+ function clearBleed(index, string, open, close, replace) {
56
+ return index < 0 ? open + string + close : open + replaceClose(index, string, close, replace) + close;
57
+ }
58
+ function filterEmpty(open, close, replace = open, at = open.length + 1) {
59
+ return (string) => string || !(string === "" || string === void 0) ? clearBleed(("" + string).indexOf(close, at), string, open, close, replace) : "";
60
+ }
61
+ function init(open, close, replace) {
62
+ return filterEmpty(`\x1B[${open}m`, `\x1B[${close}m`, replace);
63
+ }
64
+ const colorDefs = {
65
+ reset: init(0, 0),
66
+ bold: init(1, 22, "\x1B[22m\x1B[1m"),
67
+ dim: init(2, 22, "\x1B[22m\x1B[2m"),
68
+ italic: init(3, 23),
69
+ underline: init(4, 24),
70
+ inverse: init(7, 27),
71
+ hidden: init(8, 28),
72
+ strikethrough: init(9, 29),
73
+ black: init(30, 39),
74
+ red: init(31, 39),
75
+ green: init(32, 39),
76
+ yellow: init(33, 39),
77
+ blue: init(34, 39),
78
+ magenta: init(35, 39),
79
+ cyan: init(36, 39),
80
+ white: init(37, 39),
81
+ gray: init(90, 39),
82
+ bgBlack: init(40, 49),
83
+ bgRed: init(41, 49),
84
+ bgGreen: init(42, 49),
85
+ bgYellow: init(43, 49),
86
+ bgBlue: init(44, 49),
87
+ bgMagenta: init(45, 49),
88
+ bgCyan: init(46, 49),
89
+ bgWhite: init(47, 49),
90
+ blackBright: init(90, 39),
91
+ redBright: init(91, 39),
92
+ greenBright: init(92, 39),
93
+ yellowBright: init(93, 39),
94
+ blueBright: init(94, 39),
95
+ magentaBright: init(95, 39),
96
+ cyanBright: init(96, 39),
97
+ whiteBright: init(97, 39),
98
+ bgBlackBright: init(100, 49),
99
+ bgRedBright: init(101, 49),
100
+ bgGreenBright: init(102, 49),
101
+ bgYellowBright: init(103, 49),
102
+ bgBlueBright: init(104, 49),
103
+ bgMagentaBright: init(105, 49),
104
+ bgCyanBright: init(106, 49),
105
+ bgWhiteBright: init(107, 49)
106
+ };
107
+ function createColors(useColor = isColorSupported) {
108
+ return useColor ? colorDefs : Object.fromEntries(Object.keys(colorDefs).map((key) => [key, String]));
109
+ }
110
+ const colors = createColors();
111
+ const ansiRegex = [String.raw`[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?\u0007)`, String.raw`(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))`].join("|");
112
+
113
+ //#endregion
114
+ //#region packages/cli/src/utils/logo.ts
115
+ const startColor = {
116
+ r: 149,
117
+ g: 100,
118
+ b: 245
119
+ };
120
+ const endColor = {
121
+ r: 111,
122
+ g: 114,
123
+ b: 245
124
+ };
125
+ const icon = [
126
+ " _ ",
127
+ " | | ",
128
+ " __ _____ _ __ ___ _ _| |__ ___ ",
129
+ " \\ \\ / / _ \\ '__/ __| | | | '_ \\ / _ \\",
130
+ String.raw` \ V / __/ | | (__| |_| | |_) | __/`,
131
+ String.raw` \_/ \___|_| \___|\__,_|_.__/ \___|`,
132
+ " ",
133
+ " "
134
+ ];
135
+ function interpolateColor(startColor$1, endColor$1, factor) {
136
+ const r = Math.round(startColor$1.r + factor * (endColor$1.r - startColor$1.r));
137
+ const g = Math.round(startColor$1.g + factor * (endColor$1.g - startColor$1.g));
138
+ const b = Math.round(startColor$1.b + factor * (endColor$1.b - startColor$1.b));
139
+ return `\u001B[38;2;${r};${g};${b}m`;
140
+ }
141
+ function applyGradient(icon$1, startColor$1, endColor$1) {
142
+ const totalLines = icon$1.length;
143
+ return icon$1.map((line, index) => {
144
+ const factor = index / (totalLines - 1);
145
+ const color = interpolateColor(startColor$1, endColor$1, factor);
146
+ return color + line;
147
+ }).join("\n");
148
+ }
149
+ const vercubeIcon = applyGradient(icon, startColor, endColor);
150
+
151
+ //#endregion
152
+ //#region packages/cli/src/commands/init.ts
153
+ const logger = consola.withTag(colors.whiteBright(colors.bold(colors.bgGreenBright(" vercube "))));
154
+ const DEFAULT_REGISTRY = "https://raw.githubusercontent.com/vercube/starter/main/templates";
155
+ const DEFAULT_TEMPLATE_NAME = "vercube";
156
+ const pms = {
157
+ npm: void 0,
158
+ pnpm: void 0,
159
+ yarn: void 0,
160
+ bun: void 0,
161
+ deno: void 0
162
+ };
163
+ const packageManagerOptions = Object.keys(pms);
164
+ const initCommand = defineCommand({
165
+ meta: {
166
+ name: "init",
167
+ description: "Initialize a new Vercube app"
168
+ },
169
+ args: {
170
+ dir: {
171
+ type: "positional",
172
+ description: "Project directory",
173
+ default: ""
174
+ },
175
+ force: {
176
+ type: "boolean",
177
+ alias: "f",
178
+ description: "Override existing directory"
179
+ },
180
+ install: {
181
+ type: "boolean",
182
+ default: true,
183
+ description: "Skip installing dependencies"
184
+ },
185
+ gitInit: {
186
+ type: "boolean",
187
+ description: "Initialize git repository",
188
+ default: true
189
+ },
190
+ packageManager: {
191
+ type: "string",
192
+ description: "Package manager choice (npm, pnpm, yarn, bun)",
193
+ default: "pnpm"
194
+ }
195
+ },
196
+ async run(ctx) {
197
+ if (hasTTY) process.stdout.write(`\n${vercubeIcon}\n\n`);
198
+ consola.info(`Welcome to ${colors.bold("Vercube")}!`);
199
+ if (ctx.args.dir === "") ctx.args.dir = await logger.prompt("Where would you like to create your project?", {
200
+ placeholder: "./vercube-app",
201
+ type: "text",
202
+ default: "vercube-app",
203
+ cancel: "reject"
204
+ }).catch(() => process.exit(1));
205
+ const cwd = resolve(process.cwd());
206
+ let templateDownloadPath = resolve(cwd, ctx.args.dir);
207
+ logger.info(`Creating a new project in ${colors.cyan(relative(cwd, templateDownloadPath) || templateDownloadPath)}.`);
208
+ let shouldForce = Boolean(ctx.args.force);
209
+ const shouldVerify = !shouldForce && existsSync(templateDownloadPath);
210
+ if (shouldVerify) {
211
+ const selectedAction = await logger.prompt(`The directory ${colors.cyan(templateDownloadPath)} already exists. What would you like to do?`, {
212
+ type: "select",
213
+ options: [
214
+ "Override its contents",
215
+ "Select different directory",
216
+ "Abort"
217
+ ]
218
+ });
219
+ switch (selectedAction) {
220
+ case "Override its contents": {
221
+ shouldForce = true;
222
+ break;
223
+ }
224
+ case "Select different directory": {
225
+ templateDownloadPath = resolve(cwd, await logger.prompt("Please specify a different directory:", {
226
+ type: "text",
227
+ cancel: "reject"
228
+ }).catch(() => process.exit(1)));
229
+ break;
230
+ }
231
+ default: process.exit(1);
232
+ }
233
+ }
234
+ let template;
235
+ try {
236
+ template = await downloadTemplate(DEFAULT_TEMPLATE_NAME, {
237
+ dir: templateDownloadPath,
238
+ force: shouldForce,
239
+ offline: Boolean(ctx.args.offline),
240
+ preferOffline: Boolean(ctx.args.preferOffline),
241
+ registry: DEFAULT_REGISTRY
242
+ });
243
+ } catch (error_) {
244
+ if (process.env.DEBUG) throw error_;
245
+ logger.error(error_.toString());
246
+ process.exit(1);
247
+ }
248
+ const packageManagerArg = ctx.args.packageManager;
249
+ const selectedPackageManager = packageManagerOptions.includes(packageManagerArg) ? packageManagerArg : await logger.prompt("Which package manager would you like to use?", {
250
+ type: "select",
251
+ options: packageManagerOptions,
252
+ cancel: "reject"
253
+ }).catch(() => process.exit(1));
254
+ if (ctx.args.install === false) logger.info("Skipping install dependencies step.");
255
+ else {
256
+ logger.start("Installing dependencies...");
257
+ try {
258
+ await installDependencies({
259
+ cwd: template.dir,
260
+ packageManager: {
261
+ name: selectedPackageManager,
262
+ command: selectedPackageManager
263
+ }
264
+ });
265
+ } catch (error_) {
266
+ if (process.env.DEBUG) throw error_;
267
+ logger.error(error_.toString());
268
+ process.exit(1);
269
+ }
270
+ logger.success("Installation completed.");
271
+ }
272
+ if (ctx.args.gitInit === void 0) ctx.args.gitInit = await logger.prompt("Initialize git repository?", {
273
+ type: "confirm",
274
+ cancel: "reject"
275
+ }).catch(() => process.exit(1));
276
+ if (ctx.args.gitInit) {
277
+ logger.info("Initializing git repository...\n");
278
+ try {
279
+ await x("git", ["init", template.dir], {
280
+ throwOnError: true,
281
+ nodeOptions: { stdio: "inherit" }
282
+ });
283
+ } catch (error_) {
284
+ logger.warn(`Failed to initialize git repository: ${error_}`);
285
+ }
286
+ }
287
+ logger.log("\n✨ Vercube project has been created! Next steps:");
288
+ const relativeTemplateDir = relative(process.cwd(), template.dir) || ".";
289
+ const runCmd = selectedPackageManager === "deno" ? "task" : "run";
290
+ const nextSteps = [!ctx.args.shell && relativeTemplateDir.length > 1 && `\`cd ${relativeTemplateDir}\``, `Start development server with \`${selectedPackageManager} ${runCmd} dev\``].filter(Boolean);
291
+ for (const step of nextSteps) logger.log(` › ${step}`);
292
+ if (ctx.args.shell) startShell(template.dir);
293
+ }
294
+ });
295
+
296
+ //#endregion
297
+ //#region packages/cli/src/index.ts
298
+ const main = defineCommand({
299
+ meta: {
300
+ name: "Vercube",
301
+ version,
302
+ description: "Vercube CLI"
303
+ },
304
+ subCommands: {
305
+ build: buildCommand,
306
+ dev: devCommand,
307
+ init: initCommand
308
+ }
309
+ });
310
+ runMain(main);
311
+
312
+ //#endregion
@@ -0,0 +1 @@
1
+ export declare const vercubeIcon: string;
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@vercube/cli",
3
+ "version": "0.0.1-alpha.15",
4
+ "description": "CLI module for Vercube framework",
5
+ "repository": "@vercube/cli",
6
+ "license": "MIT",
7
+ "sideEffects": false,
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "main": "./dist/index.cjs",
17
+ "module": "./dist/index.mjs",
18
+ "types": "./dist/index.d.ts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "bin": {
23
+ "vercube": "./dist/index.cjs"
24
+ },
25
+ "dependencies": {
26
+ "citty": "0.1.6",
27
+ "consola": "3.4.2",
28
+ "giget": "2.0.0",
29
+ "nypm": "0.6.0",
30
+ "pathe": "2.0.3",
31
+ "std-env": "3.8.1",
32
+ "tinyexec": "1.0.1",
33
+ "@vercube/devkit": "0.0.1-alpha.15"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ }
38
+ }