@vobs/cli 0.3.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +116 -0
- package/bin/vobs.js +12 -0
- package/dist/banner.cjs +37 -0
- package/dist/banner.cjs.map +1 -0
- package/dist/banner.d.cts +18 -0
- package/dist/banner.d.ts +18 -0
- package/dist/banner.js +33 -0
- package/dist/banner.js.map +1 -0
- package/dist/cli.cjs +416 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +5 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +389 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.cjs +113 -0
- package/dist/commands/add.cjs.map +1 -0
- package/dist/commands/add.d.cts +5 -0
- package/dist/commands/add.d.ts +5 -0
- package/dist/commands/add.js +88 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/build.cjs +55 -0
- package/dist/commands/build.cjs.map +1 -0
- package/dist/commands/build.d.cts +5 -0
- package/dist/commands/build.d.ts +5 -0
- package/dist/commands/build.js +49 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/dev.cjs +57 -0
- package/dist/commands/dev.cjs.map +1 -0
- package/dist/commands/dev.d.cts +5 -0
- package/dist/commands/dev.d.ts +5 -0
- package/dist/commands/dev.js +51 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/generate.cjs +153 -0
- package/dist/commands/generate.cjs.map +1 -0
- package/dist/commands/generate.d.cts +5 -0
- package/dist/commands/generate.d.ts +5 -0
- package/dist/commands/generate.js +126 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/index.cjs +331 -0
- package/dist/commands/index.cjs.map +1 -0
- package/dist/commands/index.d.cts +6 -0
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.js +300 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.cjs +187 -0
- package/dist/commands/init.cjs.map +1 -0
- package/dist/commands/init.d.cts +5 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.js +160 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/index.cjs +561 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -18
- package/dist/index.js +489 -486
- package/dist/index.js.map +1 -0
- package/dist/repl.cjs +436 -0
- package/dist/repl.cjs.map +1 -0
- package/dist/repl.d.cts +8 -0
- package/dist/repl.d.ts +8 -0
- package/dist/repl.js +409 -0
- package/dist/repl.js.map +1 -0
- package/dist/start.cjs +543 -0
- package/dist/start.cjs.map +1 -0
- package/dist/start.d.cts +4 -0
- package/dist/start.d.ts +4 -0
- package/dist/start.js +516 -0
- package/dist/start.js.map +1 -0
- package/dist/templates/basic/.gitignore.hbs +4 -0
- package/dist/templates/basic/index.html.hbs +12 -0
- package/dist/templates/basic/package.json.hbs +25 -0
- package/dist/templates/basic/src/App.tsx.hbs +8 -0
- package/dist/templates/basic/src/app.css.hbs +32 -0
- package/dist/templates/basic/src/main.ts.hbs +20 -0
- package/dist/templates/basic/tsconfig.json.hbs +19 -0
- package/dist/templates/basic/vite.config.ts.hbs +10 -0
- package/dist/templates/component.hbs +7 -0
- package/dist/templates/page.hbs +7 -0
- package/dist/types.cjs +4 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +71 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file.cjs +79 -0
- package/dist/utils/file.cjs.map +1 -0
- package/dist/utils/file.d.cts +14 -0
- package/dist/utils/file.d.ts +14 -0
- package/dist/utils/file.js +67 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/logger.cjs +45 -0
- package/dist/utils/logger.cjs.map +1 -0
- package/dist/utils/logger.d.cts +14 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.js +34 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pm.cjs +38 -0
- package/dist/utils/pm.cjs.map +1 -0
- package/dist/utils/pm.d.cts +9 -0
- package/dist/utils/pm.d.ts +9 -0
- package/dist/utils/pm.js +34 -0
- package/dist/utils/pm.js.map +1 -0
- package/package.json +30 -40
- package/src/banner.ts +41 -0
- package/src/cli.ts +108 -0
- package/src/commands/add.ts +37 -0
- package/src/commands/build.ts +17 -0
- package/src/commands/dev.ts +19 -0
- package/src/commands/generate.ts +87 -0
- package/src/commands/index.ts +5 -0
- package/src/commands/init.ts +84 -0
- package/src/index.ts +13 -0
- package/src/repl.ts +140 -0
- package/src/start.ts +20 -0
- package/src/templates/basic/.gitignore.hbs +4 -0
- package/src/templates/basic/index.html.hbs +12 -0
- package/src/templates/basic/package.json.hbs +25 -0
- package/src/templates/basic/src/App.tsx.hbs +8 -0
- package/src/templates/basic/src/app.css.hbs +32 -0
- package/src/templates/basic/src/main.ts.hbs +20 -0
- package/src/templates/basic/tsconfig.json.hbs +19 -0
- package/src/templates/basic/vite.config.ts.hbs +10 -0
- package/src/templates/component.hbs +7 -0
- package/src/templates/page.hbs +7 -0
- package/src/types.ts +78 -0
- package/src/utils/file.ts +77 -0
- package/src/utils/logger.ts +27 -0
- package/src/utils/pm.ts +42 -0
- package/dist/ai-server.d.ts +0 -11
- package/dist/ai-server.js +0 -212
- package/dist/context.d.ts +0 -12
- package/dist/context.js +0 -301
- package/dist/diagnose.d.ts +0 -12
- package/dist/diagnose.js +0 -122
- package/dist/enterprise-template.d.ts +0 -83
- package/dist/enterprise-template.js +0 -638
- package/dist/inspect.d.ts +0 -11
- package/dist/inspect.js +0 -576
- package/dist/logo/cli-logo.d.ts +0 -5
- package/dist/logo/cli-logo.js +0 -16
- package/dist/scaffold.d.ts +0 -23
- package/dist/scaffold.js +0 -448
package/dist/index.js
CHANGED
|
@@ -1,513 +1,516 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* @
|
|
5
|
-
|
|
6
|
-
import { existsSync } from '
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import { createInterface } from '
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import { runVobsAiServer } from './ai-server.js';
|
|
18
|
-
export { runVobsAiServer } from './ai-server.js';
|
|
19
|
-
import { renderCliLogo } from './logo/cli-logo.js';
|
|
20
|
-
import { createScaffold, isScaffoldTemplate, scaffoldSuccessText, } from './scaffold.js';
|
|
21
|
-
export function runVobsCli(args, streams = {
|
|
22
|
-
stdin: process.stdin,
|
|
23
|
-
stdout: process.stdout,
|
|
24
|
-
stderr: process.stderr,
|
|
25
|
-
}) {
|
|
26
|
-
const { args: commandArgs, shouldShowLogo } = readLogoOption(args);
|
|
27
|
-
if (shouldShowLogo) {
|
|
28
|
-
streams.stdout.write(`${renderCliLogo()}\n\n`);
|
|
29
|
-
}
|
|
30
|
-
const parsed = parseArgs(commandArgs);
|
|
31
|
-
if (parsed.command === 'help') {
|
|
32
|
-
streams.stdout.write(helpText());
|
|
33
|
-
return Promise.resolve(0);
|
|
34
|
-
}
|
|
35
|
-
if (parsed.command === 'new') {
|
|
36
|
-
return runNewCommand(parsed, streams);
|
|
37
|
-
}
|
|
38
|
-
if (parsed.command === 'inspect') {
|
|
39
|
-
return runInspectCommand(parsed, streams);
|
|
40
|
-
}
|
|
41
|
-
if (parsed.command === 'ai-tools') {
|
|
42
|
-
streams.stdout.write(`${JSON.stringify(VOBS_AI_TOOL_CATALOG, null, 2)}\n`);
|
|
43
|
-
return Promise.resolve(0);
|
|
44
|
-
}
|
|
45
|
-
if (parsed.command === 'ai-serve') {
|
|
46
|
-
return runAiServeCommand(streams);
|
|
47
|
-
}
|
|
48
|
-
if (parsed.command === 'context') {
|
|
49
|
-
streams.stdout.write(`${JSON.stringify(createVobsProjectContext(parsed.options), null, 2)}\n`);
|
|
50
|
-
return Promise.resolve(0);
|
|
51
|
-
}
|
|
52
|
-
if (parsed.command === 'diagnose') {
|
|
53
|
-
streams.stdout.write(`${JSON.stringify(createVobsDiagnosticReport(parsed.options), null, 2)}\n`);
|
|
54
|
-
return Promise.resolve(0);
|
|
55
|
-
}
|
|
56
|
-
const result = checkViewProject({
|
|
57
|
-
tsconfigPath: parsed.tsconfigPath,
|
|
58
|
-
...(parsed.viewFiles === undefined ? {} : { viewFiles: parsed.viewFiles }),
|
|
59
|
-
});
|
|
60
|
-
const errors = result.diagnostics.filter((diagnostic) => diagnostic.severity === 'error');
|
|
61
|
-
const warnings = result.diagnostics.filter((diagnostic) => diagnostic.severity === 'warning');
|
|
62
|
-
if (errors.length === 0) {
|
|
63
|
-
if (warnings.length > 0) {
|
|
64
|
-
streams.stderr.write(`vobs check warnings\n${formatDiagnostics(warnings)}\n`);
|
|
65
|
-
}
|
|
66
|
-
streams.stdout.write(`vobs check passed (${result.units.length} view unit(s)).\n`);
|
|
67
|
-
return Promise.resolve(0);
|
|
68
|
-
}
|
|
69
|
-
streams.stderr.write(`vobs check failed\n${formatDiagnostics(errors)}${warnings.length === 0 ? '' : `\nvobs check warnings\n${formatDiagnostics(warnings)}`}\n`);
|
|
70
|
-
return Promise.resolve(1);
|
|
1
|
+
import { cac } from 'cac';
|
|
2
|
+
import { dirname, resolve } from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import * as p from '@clack/prompts';
|
|
5
|
+
import pc2 from 'picocolors';
|
|
6
|
+
import { readFileSync, mkdirSync, writeFileSync, existsSync } from 'fs';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import Handlebars from 'handlebars';
|
|
9
|
+
import { createServer, build } from 'vite';
|
|
10
|
+
import { createInterface } from 'readline/promises';
|
|
11
|
+
import { stdout, stdin } from 'process';
|
|
12
|
+
|
|
13
|
+
var __defProp = Object.defineProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
function timestamp() {
|
|
16
|
+
return pc2.dim(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}]`);
|
|
71
17
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
args: commandArgs,
|
|
77
|
-
shouldShowLogo: !args.includes('--no-logo') &&
|
|
78
|
-
!args.includes('--json') &&
|
|
79
|
-
!args.includes('inspect') &&
|
|
80
|
-
!isAiServer,
|
|
81
|
-
};
|
|
18
|
+
__name(timestamp, "timestamp");
|
|
19
|
+
function info(msg) {
|
|
20
|
+
console.log(`${timestamp()} ${pc2.cyan("\u2139")} ${msg}`);
|
|
82
21
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return { command: 'help' };
|
|
87
|
-
if (command === 'new' || command === 'create')
|
|
88
|
-
return parseNewArgs(rest, command === 'create');
|
|
89
|
-
if (command === 'inspect')
|
|
90
|
-
return parseInspectArgs(rest);
|
|
91
|
-
if (command === 'ai' && rest[0] === 'tools')
|
|
92
|
-
return parseAiToolsArgs(rest.slice(1));
|
|
93
|
-
if (command === 'ai' && rest[0] === 'serve')
|
|
94
|
-
return parseAiServeArgs(rest.slice(1));
|
|
95
|
-
if (command === 'ai' && rest[0] === 'context')
|
|
96
|
-
return parseContextArgs(rest.slice(1));
|
|
97
|
-
if (command === 'ai' && rest[0] === 'diagnose')
|
|
98
|
-
return parseDiagnoseArgs(rest.slice(1));
|
|
99
|
-
if (command === 'ai-tools')
|
|
100
|
-
return parseAiToolsArgs(rest);
|
|
101
|
-
if (command === 'ai-serve')
|
|
102
|
-
return parseAiServeArgs(rest);
|
|
103
|
-
if (command === 'context')
|
|
104
|
-
return parseContextArgs(rest);
|
|
105
|
-
if (command === 'diagnose')
|
|
106
|
-
return parseDiagnoseArgs(rest);
|
|
107
|
-
if (command !== 'check')
|
|
108
|
-
throw new Error(`Unknown command: ${command}`);
|
|
109
|
-
let tsconfigPath = path.join(process.cwd(), 'tsconfig.json');
|
|
110
|
-
const viewFiles = [];
|
|
111
|
-
for (let index = 0; index < rest.length; index += 1) {
|
|
112
|
-
const arg = rest[index];
|
|
113
|
-
if (arg === '--help' || arg === '-h')
|
|
114
|
-
return { command: 'help' };
|
|
115
|
-
if (arg === '--tsconfig' || arg === '-p') {
|
|
116
|
-
const value = rest[index + 1];
|
|
117
|
-
if (value === undefined)
|
|
118
|
-
throw new Error(`${arg} requires a path`);
|
|
119
|
-
tsconfigPath = path.resolve(value);
|
|
120
|
-
index += 1;
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if (arg === '--view') {
|
|
124
|
-
const value = rest[index + 1];
|
|
125
|
-
if (value === undefined)
|
|
126
|
-
throw new Error('--view requires a path');
|
|
127
|
-
viewFiles.push(path.resolve(value));
|
|
128
|
-
index += 1;
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
throw new Error(`Unknown option: ${arg ?? ''}`);
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
command: 'check',
|
|
135
|
-
tsconfigPath,
|
|
136
|
-
viewFiles: viewFiles.length === 0 ? undefined : viewFiles,
|
|
137
|
-
};
|
|
22
|
+
__name(info, "info");
|
|
23
|
+
function success(msg) {
|
|
24
|
+
console.log(`${timestamp()} ${pc2.green("\u2714")} ${msg}`);
|
|
138
25
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return { command: 'help' };
|
|
143
|
-
throw new Error(`Unknown option: ${arg}`);
|
|
144
|
-
}
|
|
145
|
-
return { command: 'ai-serve' };
|
|
26
|
+
__name(success, "success");
|
|
27
|
+
function warn(msg) {
|
|
28
|
+
console.log(`${timestamp()} ${pc2.yellow("\u26A0")} ${msg}`);
|
|
146
29
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
continue;
|
|
151
|
-
if (arg === '--help' || arg === '-h')
|
|
152
|
-
return { command: 'help' };
|
|
153
|
-
throw new Error(`Unknown option: ${arg}`);
|
|
154
|
-
}
|
|
155
|
-
return { command: 'ai-tools' };
|
|
30
|
+
__name(warn, "warn");
|
|
31
|
+
function error(msg) {
|
|
32
|
+
console.error(`${timestamp()} ${pc2.red("\u2716")} ${msg}`);
|
|
156
33
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
let depth;
|
|
162
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
163
|
-
const arg = args[index];
|
|
164
|
-
if (arg === '--json')
|
|
165
|
-
continue;
|
|
166
|
-
if (arg === '--help' || arg === '-h')
|
|
167
|
-
return { command: 'help' };
|
|
168
|
-
if (arg === '--tsconfig' || arg === '-p') {
|
|
169
|
-
const value = args[index + 1];
|
|
170
|
-
if (value === undefined)
|
|
171
|
-
throw new Error(`${arg} requires a path`);
|
|
172
|
-
tsconfigPath = path.resolve(value);
|
|
173
|
-
index += 1;
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
if (arg === '--route') {
|
|
177
|
-
const value = args[index + 1];
|
|
178
|
-
if (value === undefined)
|
|
179
|
-
throw new Error('--route requires a path');
|
|
180
|
-
route = value;
|
|
181
|
-
index += 1;
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
if (arg === '--file') {
|
|
185
|
-
const value = args[index + 1];
|
|
186
|
-
if (value === undefined)
|
|
187
|
-
throw new Error('--file requires a path');
|
|
188
|
-
file = value;
|
|
189
|
-
index += 1;
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
if (arg === '--depth') {
|
|
193
|
-
const value = args[index + 1];
|
|
194
|
-
if (value === undefined)
|
|
195
|
-
throw new Error('--depth requires a number');
|
|
196
|
-
depth = Number(value);
|
|
197
|
-
index += 1;
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
throw new Error(`Unknown option: ${arg ?? ''}`);
|
|
201
|
-
}
|
|
202
|
-
return {
|
|
203
|
-
command: 'context',
|
|
204
|
-
options: {
|
|
205
|
-
tsconfigPath,
|
|
206
|
-
...(route === undefined ? {} : { route }),
|
|
207
|
-
...(file === undefined ? {} : { file }),
|
|
208
|
-
...(depth === undefined ? {} : { depth }),
|
|
209
|
-
},
|
|
210
|
-
};
|
|
34
|
+
__name(error, "error");
|
|
35
|
+
function step(msg) {
|
|
36
|
+
console.log(`
|
|
37
|
+
${pc2.bold(pc2.cyan(msg))}`);
|
|
211
38
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const arg = args[index];
|
|
219
|
-
if (arg === '--json')
|
|
220
|
-
continue;
|
|
221
|
-
if (arg === '--help' || arg === '-h')
|
|
222
|
-
return { command: 'help' };
|
|
223
|
-
if (arg === '--tsconfig' || arg === '-p') {
|
|
224
|
-
const value = args[index + 1];
|
|
225
|
-
if (value === undefined)
|
|
226
|
-
throw new Error(`${arg} requires a path`);
|
|
227
|
-
tsconfigPath = path.resolve(value);
|
|
228
|
-
index += 1;
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
if (arg === '--route') {
|
|
232
|
-
const value = args[index + 1];
|
|
233
|
-
if (value === undefined)
|
|
234
|
-
throw new Error('--route requires a path');
|
|
235
|
-
route = value;
|
|
236
|
-
index += 1;
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
if (arg === '--file') {
|
|
240
|
-
const value = args[index + 1];
|
|
241
|
-
if (value === undefined)
|
|
242
|
-
throw new Error('--file requires a path');
|
|
243
|
-
file = value;
|
|
244
|
-
index += 1;
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
if (arg === '--depth') {
|
|
248
|
-
const value = args[index + 1];
|
|
249
|
-
if (value === undefined)
|
|
250
|
-
throw new Error('--depth requires a number');
|
|
251
|
-
depth = Number(value);
|
|
252
|
-
index += 1;
|
|
253
|
-
continue;
|
|
254
|
-
}
|
|
255
|
-
throw new Error(`Unknown option: ${arg ?? ''}`);
|
|
256
|
-
}
|
|
257
|
-
return {
|
|
258
|
-
command: 'diagnose',
|
|
259
|
-
options: {
|
|
260
|
-
tsconfigPath,
|
|
261
|
-
...(route === undefined ? {} : { route }),
|
|
262
|
-
...(file === undefined ? {} : { file }),
|
|
263
|
-
...(depth === undefined ? {} : { depth }),
|
|
264
|
-
},
|
|
265
|
-
};
|
|
39
|
+
__name(step, "step");
|
|
40
|
+
var logger = { info, success, warn, error, step };
|
|
41
|
+
var __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
42
|
+
var TEMPLATES_ROOT = resolve(__dirname$1, "..", "templates");
|
|
43
|
+
function getTemplatesDir() {
|
|
44
|
+
return TEMPLATES_ROOT;
|
|
266
45
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
if (arg === '--help' || arg === '-h')
|
|
273
|
-
return { command: 'help' };
|
|
274
|
-
if (arg === '--json')
|
|
275
|
-
continue;
|
|
276
|
-
if (arg === '--tsconfig' || arg === '-p') {
|
|
277
|
-
const value = args[index + 1];
|
|
278
|
-
if (value === undefined)
|
|
279
|
-
throw new Error(`${arg} requires a path`);
|
|
280
|
-
tsconfigPath = path.resolve(value);
|
|
281
|
-
index += 1;
|
|
282
|
-
continue;
|
|
283
|
-
}
|
|
284
|
-
if (arg === '--out' || arg === '-o') {
|
|
285
|
-
const value = args[index + 1];
|
|
286
|
-
if (value === undefined)
|
|
287
|
-
throw new Error(`${arg} requires a path`);
|
|
288
|
-
out = value;
|
|
289
|
-
index += 1;
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
throw new Error(`Unknown option: ${arg ?? ''}`);
|
|
293
|
-
}
|
|
294
|
-
return { command: 'inspect', options: { tsconfigPath, ...(out === undefined ? {} : { out }) } };
|
|
46
|
+
__name(getTemplatesDir, "getTemplatesDir");
|
|
47
|
+
function renderTemplate(templatePath, context) {
|
|
48
|
+
const source = readFileSync(templatePath, "utf-8");
|
|
49
|
+
const template = Handlebars.compile(source);
|
|
50
|
+
return template(context);
|
|
295
51
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
writeInspectOutput(manifest, command.options.out);
|
|
304
|
-
streams.stdout.write(`Wrote vobs inspect manifest to ${path.resolve(process.cwd(), command.options.out)}\n`);
|
|
305
|
-
}
|
|
306
|
-
return Promise.resolve(0);
|
|
52
|
+
__name(renderTemplate, "renderTemplate");
|
|
53
|
+
function writeFile(dir, filename, content) {
|
|
54
|
+
const filePath = resolve(dir, filename);
|
|
55
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
56
|
+
writeFileSync(filePath, content, "utf-8");
|
|
307
57
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
input,
|
|
314
|
-
stdout: streams.stdout,
|
|
315
|
-
...(streams.stderr === undefined ? {} : { stderr: streams.stderr }),
|
|
316
|
-
};
|
|
317
|
-
try {
|
|
318
|
-
await runVobsAiServer(serverStreams);
|
|
319
|
-
}
|
|
320
|
-
finally {
|
|
321
|
-
input.close();
|
|
322
|
-
}
|
|
323
|
-
return 0;
|
|
58
|
+
__name(writeFile, "writeFile");
|
|
59
|
+
function ensureDir(dir) {
|
|
60
|
+
if (!existsSync(dir)) {
|
|
61
|
+
mkdirSync(dir, { recursive: true });
|
|
62
|
+
}
|
|
324
63
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
index += 1;
|
|
345
|
-
continue;
|
|
346
|
-
}
|
|
347
|
-
if (arg === '--with-di') {
|
|
348
|
-
withDi = true;
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
if (arg === '--force') {
|
|
352
|
-
force = true;
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
if (arg.startsWith('-'))
|
|
356
|
-
throw new Error(`Unknown option: ${arg}`);
|
|
357
|
-
if (type === undefined) {
|
|
358
|
-
type = arg;
|
|
359
|
-
continue;
|
|
360
|
-
}
|
|
361
|
-
if (name === undefined) {
|
|
362
|
-
name = arg;
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
throw new Error(`Unexpected argument: ${arg ?? ''}`);
|
|
64
|
+
__name(ensureDir, "ensureDir");
|
|
65
|
+
async function copyDirRecursive(srcDir, destDir, context) {
|
|
66
|
+
const { readdirSync } = await import('fs');
|
|
67
|
+
const { join } = await import('path');
|
|
68
|
+
const entries = readdirSync(srcDir, { withFileTypes: true });
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
const srcPath = join(srcDir, entry.name);
|
|
71
|
+
const isHbs = entry.name.endsWith(".hbs");
|
|
72
|
+
const destName = isHbs ? entry.name.slice(0, -4) : entry.name;
|
|
73
|
+
const destPath = join(destDir, destName);
|
|
74
|
+
if (entry.isDirectory()) {
|
|
75
|
+
ensureDir(destPath);
|
|
76
|
+
await copyDirRecursive(srcPath, destPath, context);
|
|
77
|
+
} else if (isHbs) {
|
|
78
|
+
const content = renderTemplate(srcPath, context);
|
|
79
|
+
writeFile(destDir, destName, content);
|
|
80
|
+
} else {
|
|
81
|
+
const content = readFileSync(srcPath, "utf-8");
|
|
82
|
+
writeFile(destDir, destName, content);
|
|
366
83
|
}
|
|
367
|
-
|
|
368
|
-
const resolvedName = template === undefined ? name : (name ?? type);
|
|
369
|
-
return {
|
|
370
|
-
command: 'new',
|
|
371
|
-
type: resolvedType,
|
|
372
|
-
name: resolvedName,
|
|
373
|
-
options: {
|
|
374
|
-
...(template === undefined ? {} : { template }),
|
|
375
|
-
...(withDi === undefined ? {} : { withDi }),
|
|
376
|
-
...(force ? { force } : {}),
|
|
377
|
-
},
|
|
378
|
-
deprecatedAlias,
|
|
379
|
-
};
|
|
84
|
+
}
|
|
380
85
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
86
|
+
__name(copyDirRecursive, "copyDirRecursive");
|
|
87
|
+
async function scaffoldProject(targetDir, context) {
|
|
88
|
+
const templateDir = resolve(TEMPLATES_ROOT, "basic");
|
|
89
|
+
ensureDir(targetDir);
|
|
90
|
+
await copyDirRecursive(templateDir, targetDir, context);
|
|
91
|
+
}
|
|
92
|
+
__name(scaffoldProject, "scaffoldProject");
|
|
93
|
+
function detectPackageManager(targetDir) {
|
|
94
|
+
if (targetDir) {
|
|
95
|
+
if (existsSync(resolve(targetDir, "pnpm-lock.yaml"))) return "pnpm";
|
|
96
|
+
if (existsSync(resolve(targetDir, "yarn.lock"))) return "yarn";
|
|
97
|
+
if (existsSync(resolve(targetDir, "package-lock.json"))) return "npm";
|
|
98
|
+
}
|
|
99
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
100
|
+
if (userAgent.startsWith("pnpm")) return "pnpm";
|
|
101
|
+
if (userAgent.startsWith("yarn")) return "yarn";
|
|
102
|
+
if (userAgent.startsWith("npm")) return "npm";
|
|
103
|
+
return "pnpm";
|
|
104
|
+
}
|
|
105
|
+
__name(detectPackageManager, "detectPackageManager");
|
|
106
|
+
function installDependencies(targetDir, pm) {
|
|
107
|
+
const cmd = pm === "yarn" ? "yarn" : `${pm} install`;
|
|
108
|
+
execSync(cmd, { cwd: targetDir, stdio: "inherit" });
|
|
109
|
+
}
|
|
110
|
+
__name(installDependencies, "installDependencies");
|
|
111
|
+
function addPackage(targetDir, pm, pkg, dev) {
|
|
112
|
+
const installFlag = dev ? "-D" : "";
|
|
113
|
+
const cmd = pm === "npm" ? `npm install ${installFlag} ${pkg}` : pm === "yarn" ? `yarn add ${installFlag} ${pkg}` : `pnpm add ${installFlag} ${pkg}`;
|
|
114
|
+
execSync(cmd, { cwd: targetDir, stdio: "inherit" });
|
|
395
115
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
116
|
+
__name(addPackage, "addPackage");
|
|
117
|
+
|
|
118
|
+
// packages/cli/src/commands/init.ts
|
|
119
|
+
async function initCommand(options) {
|
|
120
|
+
const projectName = options.name || await p.text({
|
|
121
|
+
message: "Project name:",
|
|
122
|
+
placeholder: "my-vobs-app",
|
|
123
|
+
validate: /* @__PURE__ */ __name((v) => !v ? "Project name is required" : void 0, "validate")
|
|
124
|
+
});
|
|
125
|
+
if (p.isCancel(projectName)) {
|
|
126
|
+
p.cancel("Cancelled");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const targetDir = options.targetDir || resolve(process.cwd(), projectName);
|
|
130
|
+
const packageManager = options.packageManager || await p.select({
|
|
131
|
+
message: "Package manager:",
|
|
132
|
+
options: [
|
|
133
|
+
{ value: "pnpm", label: "pnpm" },
|
|
134
|
+
{ value: "npm", label: "npm" },
|
|
135
|
+
{ value: "yarn", label: "yarn" }
|
|
136
|
+
]
|
|
137
|
+
});
|
|
138
|
+
if (p.isCancel(packageManager)) {
|
|
139
|
+
p.cancel("Cancelled");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const useTypescript = options.typescript ?? await p.confirm({
|
|
143
|
+
message: "Use TypeScript?",
|
|
144
|
+
initialValue: true
|
|
145
|
+
});
|
|
146
|
+
if (p.isCancel(useTypescript)) {
|
|
147
|
+
p.cancel("Cancelled");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const initGit = options.git ?? await p.confirm({
|
|
151
|
+
message: "Initialize a git repository?",
|
|
152
|
+
initialValue: true
|
|
153
|
+
});
|
|
154
|
+
if (p.isCancel(initGit)) {
|
|
155
|
+
p.cancel("Cancelled");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
logger.step(`Creating project ${projectName}...`);
|
|
159
|
+
await scaffoldProject(targetDir, {
|
|
160
|
+
name: projectName,
|
|
161
|
+
packageName: projectName.toLowerCase().replace(/\s+/g, "-"),
|
|
162
|
+
typescript: useTypescript,
|
|
163
|
+
vobsVersion: "1.0.0"
|
|
164
|
+
});
|
|
165
|
+
logger.success("Project scaffolded");
|
|
166
|
+
logger.step("Installing dependencies...");
|
|
167
|
+
installDependencies(targetDir, packageManager);
|
|
168
|
+
logger.success("Dependencies installed");
|
|
169
|
+
if (initGit) {
|
|
170
|
+
logger.step("Initializing git repository...");
|
|
401
171
|
try {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
? await prompt.confirm('Include @vobs/di integration?', false)
|
|
407
|
-
: undefined);
|
|
408
|
-
const force = command.options.force === true
|
|
409
|
-
? true
|
|
410
|
-
: existsSync(path.resolve(process.cwd(), name))
|
|
411
|
-
? await prompt.confirm(`Directory "${name}" already exists. Overwrite?`, false)
|
|
412
|
-
: undefined;
|
|
413
|
-
return {
|
|
414
|
-
...command,
|
|
415
|
-
type,
|
|
416
|
-
name,
|
|
417
|
-
options: {
|
|
418
|
-
...command.options,
|
|
419
|
-
...(withDi === undefined ? {} : { withDi }),
|
|
420
|
-
...(force === undefined ? {} : { force }),
|
|
421
|
-
},
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
finally {
|
|
425
|
-
if (streams.prompt === undefined)
|
|
426
|
-
prompt.close?.();
|
|
172
|
+
execSync("git init", { cwd: targetDir, stdio: "ignore" });
|
|
173
|
+
logger.success("Git repository initialized");
|
|
174
|
+
} catch {
|
|
175
|
+
logger.warn("Git not found, skipping git init");
|
|
427
176
|
}
|
|
177
|
+
}
|
|
178
|
+
logger.step("Done!");
|
|
179
|
+
console.log(`
|
|
180
|
+
${packageManager === "pnpm" ? "pnpm" : packageManager === "yarn" ? "yarn" : "npm run"} dev
|
|
181
|
+
`);
|
|
428
182
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
183
|
+
__name(initCommand, "initCommand");
|
|
184
|
+
async function devCommand(options) {
|
|
185
|
+
logger.info("Starting dev server...");
|
|
186
|
+
const server = await createServer({
|
|
187
|
+
configFile: options.config,
|
|
188
|
+
server: {
|
|
189
|
+
port: options.port,
|
|
190
|
+
open: options.open
|
|
434
191
|
}
|
|
192
|
+
});
|
|
193
|
+
await server.listen();
|
|
194
|
+
server.printUrls();
|
|
195
|
+
logger.success("Dev server is running");
|
|
435
196
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
197
|
+
__name(devCommand, "devCommand");
|
|
198
|
+
async function buildCommand(options) {
|
|
199
|
+
logger.info("Building for production...");
|
|
200
|
+
await build({
|
|
201
|
+
configFile: options.config,
|
|
202
|
+
build: {
|
|
203
|
+
outDir: options.outDir
|
|
204
|
+
},
|
|
205
|
+
mode: options.mode || "production"
|
|
206
|
+
});
|
|
207
|
+
logger.success("Build complete");
|
|
442
208
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
209
|
+
__name(buildCommand, "buildCommand");
|
|
210
|
+
async function generateCommand(options) {
|
|
211
|
+
const type = options.type || await p.select({
|
|
212
|
+
message: "What to generate?",
|
|
213
|
+
options: [
|
|
214
|
+
{ value: "component", label: "Component" },
|
|
215
|
+
{ value: "page", label: "Page" }
|
|
216
|
+
]
|
|
217
|
+
});
|
|
218
|
+
if (p.isCancel(type)) {
|
|
219
|
+
p.cancel("Cancelled");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const name = options.name || await p.text({
|
|
223
|
+
message: "Name:",
|
|
224
|
+
placeholder: type === "component" ? "Button" : "AboutPage",
|
|
225
|
+
validate: /* @__PURE__ */ __name((v) => !v ? "Name is required" : void 0, "validate")
|
|
226
|
+
});
|
|
227
|
+
if (p.isCancel(name)) {
|
|
228
|
+
p.cancel("Cancelled");
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const templatesDir = getTemplatesDir();
|
|
232
|
+
if (type === "component") {
|
|
233
|
+
const targetDir = options.targetDir || resolve(process.cwd(), "src/components");
|
|
234
|
+
ensureDir(targetDir);
|
|
235
|
+
const context = {
|
|
236
|
+
name: toPascalCase(name),
|
|
237
|
+
kebabName: toKebabCase(name)
|
|
464
238
|
};
|
|
239
|
+
const content = renderTemplate(
|
|
240
|
+
resolve(templatesDir, "component.hbs"),
|
|
241
|
+
context
|
|
242
|
+
);
|
|
243
|
+
const filename = `${context.name}.tsx`;
|
|
244
|
+
writeFile(targetDir, filename, content);
|
|
245
|
+
logger.success(`Created ${type} at ${resolve(targetDir, filename)}`);
|
|
246
|
+
} else {
|
|
247
|
+
const targetDir = options.targetDir || resolve(process.cwd(), "src/pages");
|
|
248
|
+
ensureDir(targetDir);
|
|
249
|
+
const context = {
|
|
250
|
+
name: toPascalCase(name),
|
|
251
|
+
path: `/${toKebabCase(name)}`
|
|
252
|
+
};
|
|
253
|
+
const content = renderTemplate(
|
|
254
|
+
resolve(templatesDir, "page.hbs"),
|
|
255
|
+
context
|
|
256
|
+
);
|
|
257
|
+
const filename = `${context.name}.tsx`;
|
|
258
|
+
writeFile(targetDir, filename, content);
|
|
259
|
+
logger.success(`Created ${type} at ${resolve(targetDir, filename)}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
__name(generateCommand, "generateCommand");
|
|
263
|
+
function toPascalCase(str) {
|
|
264
|
+
return str.replace(/[^a-zA-Z0-9]/g, " ").split(/\s+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
|
|
265
|
+
}
|
|
266
|
+
__name(toPascalCase, "toPascalCase");
|
|
267
|
+
function toKebabCase(str) {
|
|
268
|
+
return str.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "").replace(/[^a-z0-9-]/g, "-").replace(/--+/g, "-").replace(/^-|-$/g, "");
|
|
465
269
|
}
|
|
466
|
-
|
|
467
|
-
|
|
270
|
+
__name(toKebabCase, "toKebabCase");
|
|
271
|
+
async function addCommand(options) {
|
|
272
|
+
const pkg = options.package || await p.text({
|
|
273
|
+
message: "Package to add:",
|
|
274
|
+
placeholder: "@vobs/ui",
|
|
275
|
+
validate: /* @__PURE__ */ __name((v) => !v ? "Package name is required" : void 0, "validate")
|
|
276
|
+
});
|
|
277
|
+
if (p.isCancel(pkg)) {
|
|
278
|
+
p.cancel("Cancelled");
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const isDev = options.dev ?? await p.confirm({
|
|
282
|
+
message: "Save as dev dependency?",
|
|
283
|
+
initialValue: false
|
|
284
|
+
});
|
|
285
|
+
if (p.isCancel(isDev)) {
|
|
286
|
+
p.cancel("Cancelled");
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const pm = detectPackageManager(process.cwd());
|
|
290
|
+
logger.step(`Installing ${pkg}...`);
|
|
291
|
+
addPackage(process.cwd(), pm, pkg, isDev);
|
|
292
|
+
logger.success(`Installed ${pkg}`);
|
|
293
|
+
console.log(`
|
|
294
|
+
Import it in your code:
|
|
295
|
+
`);
|
|
296
|
+
console.log(` import { ... } from '${pkg}'`);
|
|
297
|
+
console.log();
|
|
468
298
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
299
|
+
__name(addCommand, "addCommand");
|
|
300
|
+
|
|
301
|
+
// packages/cli/src/banner.ts
|
|
302
|
+
var BANNER_LINE1 = "\u{1D5E9}\u{1D5E2}\u{1D5D5}\u{1D5E6} \u{1D5D6}\u{1D5DF}\u{1D5DC} \u{1D603}\u{1D7ED}.\u{1D7EC}";
|
|
303
|
+
var BANNER_TAGLINE = "Signals First \xB7 Zero Re-renders \xB7 Ultra Lightweight";
|
|
304
|
+
var INDENT = " ";
|
|
305
|
+
var DIM = "\x1B[2m";
|
|
306
|
+
var RESET = "\x1B[0m";
|
|
307
|
+
function showLogo() {
|
|
308
|
+
console.log();
|
|
309
|
+
console.log();
|
|
310
|
+
console.log(`${INDENT}${BANNER_LINE1}`);
|
|
311
|
+
console.log();
|
|
312
|
+
console.log(`${INDENT}${DIM}${BANNER_TAGLINE}${RESET}`);
|
|
313
|
+
console.log();
|
|
314
|
+
console.log();
|
|
473
315
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
' vobs check [--tsconfig tsconfig.json] [--view view.html]',
|
|
478
|
-
' vobs new [app|app-di|enterprise|lib|lib-di] [name] [--with-di] [--force]',
|
|
479
|
-
' vobs inspect --json [--tsconfig tsconfig.json] [--out manifest.json]',
|
|
480
|
-
' vobs ai tools --json',
|
|
481
|
-
' vobs ai serve JSON-RPC stdio bridge for read-only AI tools',
|
|
482
|
-
' vobs context --json (--route path | --file source) [--depth 0..4]',
|
|
483
|
-
' vobs diagnose --json [--route path | --file source] [--depth 0..4]',
|
|
484
|
-
'',
|
|
485
|
-
'Check options:',
|
|
486
|
-
' -p, --tsconfig <path> TypeScript project file. Defaults to ./tsconfig.json.',
|
|
487
|
-
' --view <path> Require a specific HTML view to have exactly one owner.',
|
|
488
|
-
'',
|
|
489
|
-
'New options:',
|
|
490
|
-
' -t, --template <name> Template: app, app-di, enterprise, lib, lib-di.',
|
|
491
|
-
' --with-di Include DI integration for app/lib templates.',
|
|
492
|
-
' --force Overwrite an existing project directory.',
|
|
493
|
-
'',
|
|
494
|
-
'Global options:',
|
|
495
|
-
' --no-logo Hide the startup logo.',
|
|
496
|
-
' -h, --help Show this help.',
|
|
497
|
-
'',
|
|
498
|
-
'Example:',
|
|
499
|
-
' vobs new enterprise my-admin',
|
|
500
|
-
'',
|
|
501
|
-
].join('\n');
|
|
316
|
+
__name(showLogo, "showLogo");
|
|
317
|
+
function showBanner() {
|
|
318
|
+
console.log(`${INDENT}${BANNER_LINE1}`);
|
|
502
319
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
320
|
+
__name(showBanner, "showBanner");
|
|
321
|
+
function showDevBanner() {
|
|
322
|
+
console.log();
|
|
323
|
+
console.log(`${INDENT}${BANNER_LINE1}`);
|
|
324
|
+
console.log();
|
|
325
|
+
}
|
|
326
|
+
__name(showDevBanner, "showDevBanner");
|
|
327
|
+
|
|
328
|
+
// packages/cli/src/cli.ts
|
|
329
|
+
function createCLI() {
|
|
330
|
+
const cli = cac("vobs");
|
|
331
|
+
cli.command("init [name]", "Create a new vobs project").option("--dir <dir>", "Target directory").option("--pm <pm>", "Package manager (pnpm/npm/yarn)").option("--no-typescript", "Do not use TypeScript").option("--no-git", "Do not initialize git").action(async (name, options) => {
|
|
332
|
+
await initCommand({
|
|
333
|
+
name,
|
|
334
|
+
targetDir: options.dir,
|
|
335
|
+
packageManager: options.pm,
|
|
336
|
+
typescript: options.typescript !== false,
|
|
337
|
+
git: options.git !== false
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
cli.command("create [name]", "Alias for init").option("--dir <dir>", "Target directory").option("--pm <pm>", "Package manager (pnpm/npm/yarn)").option("--no-typescript", "Do not use TypeScript").option("--no-git", "Do not initialize git").action(async (name, options) => {
|
|
341
|
+
await initCommand({
|
|
342
|
+
name,
|
|
343
|
+
targetDir: options.dir,
|
|
344
|
+
packageManager: options.pm,
|
|
345
|
+
typescript: options.typescript !== false,
|
|
346
|
+
git: options.git !== false
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
cli.command("dev", "Start the dev server").option("--config <path>", "Vite config file").option("--port <port>", "Port to listen on").option("--open", "Open browser on start").action(async (options) => {
|
|
350
|
+
showDevBanner();
|
|
351
|
+
await devCommand({
|
|
352
|
+
config: options.config,
|
|
353
|
+
port: options.port,
|
|
354
|
+
open: options.open
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
cli.command("build", "Build for production").option("--config <path>", "Vite config file").option("--outDir <dir>", "Output directory").option("--mode <mode>", "Build mode").action(async (options) => {
|
|
358
|
+
await buildCommand({
|
|
359
|
+
config: options.config,
|
|
360
|
+
outDir: options.outDir,
|
|
361
|
+
mode: options.mode
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
cli.command("generate [name]", "Generate code (component/page)").alias("g").option("--type <type>", "Type: component or page").option("--dir <dir>", "Target directory").action(async (name, options) => {
|
|
365
|
+
await generateCommand({
|
|
366
|
+
name,
|
|
367
|
+
type: options.type || void 0,
|
|
368
|
+
targetDir: options.dir
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
cli.command("add [package]", "Add a package").option("-D, --dev", "Save as dev dependency").action(async (pkg, options) => {
|
|
372
|
+
await addCommand({
|
|
373
|
+
package: pkg,
|
|
374
|
+
dev: options.dev
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
cli.command("logo", "Show the vobs CLI logo and version info").action(() => {
|
|
378
|
+
showLogo();
|
|
379
|
+
});
|
|
380
|
+
cli.on("--help", () => {
|
|
381
|
+
showBanner();
|
|
382
|
+
});
|
|
383
|
+
cli.help();
|
|
384
|
+
cli.version("1.0.0");
|
|
385
|
+
return cli;
|
|
386
|
+
}
|
|
387
|
+
__name(createCLI, "createCLI");
|
|
388
|
+
async function startRepl() {
|
|
389
|
+
showLogo();
|
|
390
|
+
const rl = createInterface({
|
|
391
|
+
input: stdin,
|
|
392
|
+
output: stdout,
|
|
393
|
+
prompt: ` ${pc2.magenta("\u276F")} `,
|
|
394
|
+
terminal: true
|
|
395
|
+
});
|
|
396
|
+
rl.prompt();
|
|
397
|
+
for await (const rawLine of rl) {
|
|
398
|
+
const line = rawLine.trim();
|
|
399
|
+
if (!line) {
|
|
400
|
+
rl.prompt();
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
const args = splitArgs(line);
|
|
404
|
+
try {
|
|
405
|
+
await dispatch(args);
|
|
406
|
+
} catch (err) {
|
|
407
|
+
console.error(` ${pc2.red("\u2716")} ${err instanceof Error ? err.message : String(err)}`);
|
|
508
408
|
}
|
|
409
|
+
rl.prompt();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
__name(startRepl, "startRepl");
|
|
413
|
+
var TABLE = {
|
|
414
|
+
help: {
|
|
415
|
+
cmd: /* @__PURE__ */ __name(async () => {
|
|
416
|
+
console.log(` ${pc2.bold("Available commands:")}`);
|
|
417
|
+
console.log(` ${pc2.dim("exit|quit")} Leave the interactive CLI`);
|
|
418
|
+
console.log(` ${pc2.dim("clear")} Clear the screen`);
|
|
419
|
+
console.log(` ${pc2.dim("logo")} Re-print the banner`);
|
|
420
|
+
console.log(` ${pc2.dim("version")} Show version`);
|
|
421
|
+
console.log(` ${pc2.dim("init <name>")} Create a new vobs project`);
|
|
422
|
+
console.log(` ${pc2.dim("generate <name>")} Generate a component/page`);
|
|
423
|
+
console.log(` ${pc2.dim("add <package>")} Add a package`);
|
|
424
|
+
console.log(` ${pc2.dim("dev|build")} Use \`vobs dev\` / \`vobs build\` in a terminal`);
|
|
425
|
+
}, "cmd"),
|
|
426
|
+
help: ""
|
|
427
|
+
},
|
|
428
|
+
logo: { cmd: /* @__PURE__ */ __name(async () => showLogo(), "cmd"), help: "" },
|
|
429
|
+
version: { cmd: /* @__PURE__ */ __name(async () => showBanner(), "cmd"), help: "" },
|
|
430
|
+
clear: {
|
|
431
|
+
cmd: /* @__PURE__ */ __name(async () => {
|
|
432
|
+
process.stdout.write("\x1Bc");
|
|
433
|
+
}, "cmd"),
|
|
434
|
+
help: ""
|
|
435
|
+
},
|
|
436
|
+
exit: { cmd: /* @__PURE__ */ __name(async () => process.exit(0), "cmd"), help: "" },
|
|
437
|
+
quit: { cmd: /* @__PURE__ */ __name(async () => process.exit(0), "cmd"), help: "" },
|
|
438
|
+
init: {
|
|
439
|
+
cmd: /* @__PURE__ */ __name(async (args) => {
|
|
440
|
+
await initCommand({
|
|
441
|
+
name: args[0],
|
|
442
|
+
targetDir: void 0,
|
|
443
|
+
packageManager: void 0,
|
|
444
|
+
typescript: true,
|
|
445
|
+
git: true
|
|
446
|
+
});
|
|
447
|
+
}, "cmd"),
|
|
448
|
+
help: ""
|
|
449
|
+
},
|
|
450
|
+
generate: {
|
|
451
|
+
cmd: /* @__PURE__ */ __name(async (args) => {
|
|
452
|
+
await generateCommand({
|
|
453
|
+
name: args[0],
|
|
454
|
+
type: void 0,
|
|
455
|
+
targetDir: void 0
|
|
456
|
+
});
|
|
457
|
+
}, "cmd"),
|
|
458
|
+
help: ""
|
|
459
|
+
},
|
|
460
|
+
g: {
|
|
461
|
+
cmd: /* @__PURE__ */ __name(async (args) => {
|
|
462
|
+
await generateCommand({
|
|
463
|
+
name: args[0],
|
|
464
|
+
type: void 0,
|
|
465
|
+
targetDir: void 0
|
|
466
|
+
});
|
|
467
|
+
}, "cmd"),
|
|
468
|
+
help: ""
|
|
469
|
+
},
|
|
470
|
+
add: {
|
|
471
|
+
cmd: /* @__PURE__ */ __name(async (args) => {
|
|
472
|
+
await addCommand({ package: args[0], dev: args.includes("-D") || args.includes("--dev") });
|
|
473
|
+
}, "cmd"),
|
|
474
|
+
help: ""
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
async function dispatch(args) {
|
|
478
|
+
const name = args[0];
|
|
479
|
+
const rest = args.slice(1);
|
|
480
|
+
if (!name) return;
|
|
481
|
+
const entry = TABLE[name];
|
|
482
|
+
if (entry) {
|
|
483
|
+
await entry.cmd(rest);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
console.log(` ${pc2.yellow("\u26A0")} Unknown command: ${pc2.bold(String(name))}. Type ${pc2.cyan("help")} to see options.`);
|
|
487
|
+
}
|
|
488
|
+
__name(dispatch, "dispatch");
|
|
489
|
+
function splitArgs(line) {
|
|
490
|
+
const out = [];
|
|
491
|
+
const re = /[^\s"']+|"([^"]*)"|'([^']*)'/g;
|
|
492
|
+
let m;
|
|
493
|
+
while ((m = re.exec(line)) !== null) {
|
|
494
|
+
out.push(m[1] ?? m[2] ?? m[0]);
|
|
495
|
+
}
|
|
496
|
+
return out;
|
|
509
497
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
498
|
+
__name(splitArgs, "splitArgs");
|
|
499
|
+
|
|
500
|
+
// packages/cli/src/start.ts
|
|
501
|
+
async function start(args) {
|
|
502
|
+
if (args.length === 0 || args[0] === "cli") {
|
|
503
|
+
await startRepl();
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
if (args.includes("--version") || args.includes("-V")) {
|
|
507
|
+
showBanner();
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
createCLI().parse();
|
|
513
511
|
}
|
|
512
|
+
__name(start, "start");
|
|
513
|
+
|
|
514
|
+
export { addCommand, addPackage, buildCommand, createCLI, detectPackageManager, devCommand, ensureDir, generateCommand, initCommand, installDependencies, logger, renderTemplate, scaffoldProject, showBanner, showDevBanner, showLogo, start, startRepl, writeFile };
|
|
515
|
+
//# sourceMappingURL=index.js.map
|
|
516
|
+
//# sourceMappingURL=index.js.map
|