@wix/web50-cli 0.1.0 → 0.1.2
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/bin/web5.js +1 -2
- package/dist/cjs/auth/deviceFlow.js +175 -16
- package/dist/cjs/auth/deviceFlow.js.map +1 -1
- package/dist/cjs/auth/index.js +93 -10
- package/dist/cjs/auth/index.js.map +1 -1
- package/dist/cjs/auth/secretStore.js.map +1 -1
- package/dist/cjs/cli.js +29 -1
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands/bundle.js +103 -0
- package/dist/cjs/commands/bundle.js.map +1 -0
- package/dist/cjs/commands/conversation.js +50 -0
- package/dist/cjs/commands/conversation.js.map +1 -0
- package/dist/cjs/commands/conversationWizard.js +528 -0
- package/dist/cjs/commands/conversationWizard.js.map +1 -0
- package/dist/cjs/commands/deploy.js +237 -0
- package/dist/cjs/commands/deploy.js.map +1 -0
- package/dist/cjs/commands/ecom.js +239 -0
- package/dist/cjs/commands/ecom.js.map +1 -0
- package/dist/cjs/commands/embed.js +118 -0
- package/dist/cjs/commands/embed.js.map +1 -0
- package/dist/cjs/commands/init.js +65 -29
- package/dist/cjs/commands/init.js.map +1 -1
- package/dist/cjs/commands/instructions.js +456 -0
- package/dist/cjs/commands/instructions.js.map +1 -0
- package/dist/cjs/commands/login.js +63 -4
- package/dist/cjs/commands/login.js.map +1 -1
- package/dist/cjs/commands/logout.js +16 -0
- package/dist/cjs/commands/logout.js.map +1 -0
- package/dist/cjs/commands/serve.js +122 -0
- package/dist/cjs/commands/serve.js.map +1 -0
- package/dist/cjs/commands/storybook.js +102 -0
- package/dist/cjs/commands/storybook.js.map +1 -0
- package/dist/cjs/commands/validate.js +617 -17
- package/dist/cjs/commands/validate.js.map +1 -1
- package/dist/cjs/commands/whoami.js +48 -0
- package/dist/cjs/commands/whoami.js.map +1 -0
- package/dist/cjs/templates/aiInstructionsSchema.js +5 -1
- package/dist/cjs/templates/aiInstructionsSchema.js.map +1 -1
- package/dist/cjs/templates/cmsMappingSchema.js +132 -0
- package/dist/cjs/templates/cmsMappingSchema.js.map +1 -0
- package/dist/cjs/utils/print.js +12 -0
- package/dist/cjs/utils/print.js.map +1 -1
- package/dist/cjs/utils/project.js +24 -0
- package/dist/cjs/utils/project.js.map +1 -1
- package/dist/cjs/utils/wixApi.js +57 -0
- package/dist/cjs/utils/wixApi.js.map +1 -0
- package/dist/esm/auth/deviceFlow.js +182 -17
- package/dist/esm/auth/deviceFlow.js.map +1 -1
- package/dist/esm/auth/index.js +98 -11
- package/dist/esm/auth/index.js.map +1 -1
- package/dist/esm/auth/secretStore.js.map +1 -1
- package/dist/esm/cli.js +29 -1
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/bundle.js +100 -0
- package/dist/esm/commands/bundle.js.map +1 -0
- package/dist/esm/commands/conversation.js +44 -0
- package/dist/esm/commands/conversation.js.map +1 -0
- package/dist/esm/commands/conversationWizard.js +529 -0
- package/dist/esm/commands/conversationWizard.js.map +1 -0
- package/dist/esm/commands/deploy.js +239 -0
- package/dist/esm/commands/deploy.js.map +1 -0
- package/dist/esm/commands/ecom.js +234 -0
- package/dist/esm/commands/ecom.js.map +1 -0
- package/dist/esm/commands/embed.js +112 -0
- package/dist/esm/commands/embed.js.map +1 -0
- package/dist/esm/commands/init.js +66 -30
- package/dist/esm/commands/init.js.map +1 -1
- package/dist/esm/commands/instructions.js +459 -0
- package/dist/esm/commands/instructions.js.map +1 -0
- package/dist/esm/commands/login.js +66 -6
- package/dist/esm/commands/login.js.map +1 -1
- package/dist/esm/commands/logout.js +12 -0
- package/dist/esm/commands/logout.js.map +1 -0
- package/dist/esm/commands/serve.js +117 -0
- package/dist/esm/commands/serve.js.map +1 -0
- package/dist/esm/commands/storybook.js +97 -0
- package/dist/esm/commands/storybook.js.map +1 -0
- package/dist/esm/commands/validate.js +623 -19
- package/dist/esm/commands/validate.js.map +1 -1
- package/dist/esm/commands/whoami.js +44 -0
- package/dist/esm/commands/whoami.js.map +1 -0
- package/dist/esm/templates/aiInstructionsSchema.js +5 -1
- package/dist/esm/templates/aiInstructionsSchema.js.map +1 -1
- package/dist/esm/templates/cmsMappingSchema.js +128 -0
- package/dist/esm/templates/cmsMappingSchema.js.map +1 -0
- package/dist/esm/utils/print.js +10 -0
- package/dist/esm/utils/print.js.map +1 -1
- package/dist/esm/utils/project.js +23 -0
- package/dist/esm/utils/project.js.map +1 -1
- package/dist/esm/utils/wixApi.js +53 -0
- package/dist/esm/utils/wixApi.js.map +1 -0
- package/dist/types/auth/deviceFlow.d.ts +3 -1
- package/dist/types/auth/deviceFlow.d.ts.map +1 -1
- package/dist/types/auth/index.d.ts +6 -1
- package/dist/types/auth/index.d.ts.map +1 -1
- package/dist/types/auth/secretStore.d.ts +2 -0
- package/dist/types/auth/secretStore.d.ts.map +1 -1
- package/dist/types/commands/bundle.d.ts +10 -0
- package/dist/types/commands/bundle.d.ts.map +1 -0
- package/dist/types/commands/conversation.d.ts +3 -0
- package/dist/types/commands/conversation.d.ts.map +1 -0
- package/dist/types/commands/conversationWizard.d.ts +3 -0
- package/dist/types/commands/conversationWizard.d.ts.map +1 -0
- package/dist/types/commands/deploy.d.ts +3 -0
- package/dist/types/commands/deploy.d.ts.map +1 -0
- package/dist/types/commands/ecom.d.ts +3 -0
- package/dist/types/commands/ecom.d.ts.map +1 -0
- package/dist/types/commands/embed.d.ts +3 -0
- package/dist/types/commands/embed.d.ts.map +1 -0
- package/dist/types/commands/init.d.ts.map +1 -1
- package/dist/types/commands/instructions.d.ts +3 -0
- package/dist/types/commands/instructions.d.ts.map +1 -0
- package/dist/types/commands/login.d.ts.map +1 -1
- package/dist/types/commands/logout.d.ts +3 -0
- package/dist/types/commands/logout.d.ts.map +1 -0
- package/dist/types/commands/serve.d.ts +3 -0
- package/dist/types/commands/serve.d.ts.map +1 -0
- package/dist/types/commands/storybook.d.ts +3 -0
- package/dist/types/commands/storybook.d.ts.map +1 -0
- package/dist/types/commands/validate.d.ts +7 -0
- package/dist/types/commands/validate.d.ts.map +1 -1
- package/dist/types/commands/whoami.d.ts +3 -0
- package/dist/types/commands/whoami.d.ts.map +1 -0
- package/dist/types/templates/aiInstructionsSchema.d.ts.map +1 -1
- package/dist/types/templates/cmsMappingSchema.d.ts +2 -0
- package/dist/types/templates/cmsMappingSchema.d.ts.map +1 -0
- package/dist/types/utils/print.d.ts +3 -0
- package/dist/types/utils/print.d.ts.map +1 -1
- package/dist/types/utils/project.d.ts +12 -0
- package/dist/types/utils/project.d.ts.map +1 -1
- package/dist/types/utils/wixApi.d.ts +9 -0
- package/dist/types/utils/wixApi.d.ts.map +1 -0
- package/package.json +5 -5
- package/defaults/package.json +0 -42
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { logout } from '../auth';
|
|
3
|
+
import { error } from '../utils/print';
|
|
4
|
+
export const logoutCommand = new Command('logout').description('Sign out and remove stored credentials').action(async () => {
|
|
5
|
+
try {
|
|
6
|
+
await logout();
|
|
7
|
+
} catch (err_) {
|
|
8
|
+
error(err_ instanceof Error ? err_.message : String(err_));
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Command","logout","error","logoutCommand","description","action","err_","Error","message","String","process","exit"],"sources":["../../../src/commands/logout.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { logout } from '../auth';\nimport { error } from '../utils/print';\n\nexport const logoutCommand = new Command('logout')\n .description('Sign out and remove stored credentials')\n .action(async () => {\n try {\n await logout();\n } catch (err_) {\n error(err_ instanceof Error ? err_.message : String(err_));\n process.exit(1);\n }\n });\n"],"mappings":"AAAA,SAASA,OAAO,QAAQ,WAAW;AACnC,SAASC,MAAM,QAAQ,SAAS;AAChC,SAASC,KAAK,QAAQ,gBAAgB;AAEtC,OAAO,MAAMC,aAAa,GAAG,IAAIH,OAAO,CAAC,QAAQ,CAAC,CAC/CI,WAAW,CAAC,wCAAwC,CAAC,CACrDC,MAAM,CAAC,YAAY;EAClB,IAAI;IACF,MAAMJ,MAAM,CAAC,CAAC;EAChB,CAAC,CAAC,OAAOK,IAAI,EAAE;IACbJ,KAAK,CAACI,IAAI,YAAYC,KAAK,GAAGD,IAAI,CAACE,OAAO,GAAGC,MAAM,CAACH,IAAI,CAAC,CAAC;IAC1DI,OAAO,CAACC,IAAI,CAAC,CAAC,CAAC;EACjB;AACF,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as http from 'http';
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
import { success, error, info, isJsonMode } from '../utils/print';
|
|
7
|
+
import { findProjectRoot } from '../utils/project';
|
|
8
|
+
import { runBundle } from './bundle';
|
|
9
|
+
const DEFAULT_PORT = 4001;
|
|
10
|
+
const MIME_TYPES = {
|
|
11
|
+
'.js': 'application/javascript',
|
|
12
|
+
'.css': 'text/css',
|
|
13
|
+
'.json': 'application/json',
|
|
14
|
+
'.map': 'application/json'
|
|
15
|
+
};
|
|
16
|
+
function startServer(distDir, corsOrigin) {
|
|
17
|
+
const server = http.createServer((req, res) => {
|
|
18
|
+
res.setHeader('Access-Control-Allow-Origin', corsOrigin);
|
|
19
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
|
20
|
+
res.setHeader('Access-Control-Allow-Headers', '*');
|
|
21
|
+
if (req.method === 'OPTIONS') {
|
|
22
|
+
res.writeHead(204);
|
|
23
|
+
res.end();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const urlPath = req.url === '/' ? '' : req.url ?? '';
|
|
27
|
+
const filePath = path.join(distDir, urlPath);
|
|
28
|
+
|
|
29
|
+
// Prevent path traversal outside distDir
|
|
30
|
+
if (!filePath.startsWith(distDir)) {
|
|
31
|
+
res.writeHead(403);
|
|
32
|
+
res.end('Forbidden');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (!fs.existsSync(filePath) || fs.statSync(filePath).isDirectory()) {
|
|
36
|
+
res.writeHead(404);
|
|
37
|
+
res.end('Not found');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const ext = path.extname(filePath);
|
|
41
|
+
const contentType = MIME_TYPES[ext] ?? 'application/octet-stream';
|
|
42
|
+
res.setHeader('Content-Type', contentType);
|
|
43
|
+
res.writeHead(200);
|
|
44
|
+
fs.createReadStream(filePath).pipe(res);
|
|
45
|
+
});
|
|
46
|
+
return server;
|
|
47
|
+
}
|
|
48
|
+
export const serveCommand = new Command('serve').description('Bundle components and serve them on http://localhost:<port> with CORS enabled').option('--port <n>', 'Port to listen on', String(DEFAULT_PORT)).option('--no-bundle', 'Serve existing dist/cdn/ without rebuilding').option('--watch', 'Re-bundle on source changes (starts vite --watch alongside server)').option('--open', 'Open the served URL in your browser after start').option('--cors-origin <origin>', 'Restrict CORS Allow-Origin header', '*').action(async opts => {
|
|
49
|
+
try {
|
|
50
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
51
|
+
if (!projectRoot) {
|
|
52
|
+
error('No web5.config.json found. Run this command from within a Web5 project.');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
const port = parseInt(opts.port, 10);
|
|
56
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
57
|
+
error(`Invalid port: ${opts.port}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const distDir = path.join(projectRoot, 'dist', 'cdn');
|
|
61
|
+
|
|
62
|
+
// ── Bundle (unless --no-bundle) ─────────────────────────────────────────
|
|
63
|
+
if (opts.bundle !== false) {
|
|
64
|
+
await runBundle(projectRoot);
|
|
65
|
+
}
|
|
66
|
+
if (!fs.existsSync(distDir)) {
|
|
67
|
+
error(`Bundle output not found at ${distDir}. Run \`web5 bundle\` first or remove --no-bundle.`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ── Watch mode: spawn vite --watch in background ────────────────────────
|
|
72
|
+
if (opts.watch) {
|
|
73
|
+
const viteBin = path.join(projectRoot, 'node_modules', '.bin', 'vite');
|
|
74
|
+
if (!fs.existsSync(viteBin)) {
|
|
75
|
+
error('vite not found. Run `npm install` in your project first.');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const watcher = spawn(`"${viteBin}"`, ['build', '--config', 'src/vite.cdn.config.ts', '--watch'], {
|
|
79
|
+
cwd: projectRoot,
|
|
80
|
+
shell: true,
|
|
81
|
+
stdio: 'inherit'
|
|
82
|
+
});
|
|
83
|
+
watcher.on('error', err_ => error(`Watch process error: ${err_.message}`));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ── Start HTTP server ───────────────────────────────────────────────────
|
|
87
|
+
const server = startServer(distDir, opts.corsOrigin);
|
|
88
|
+
const url = `http://localhost:${port}`;
|
|
89
|
+
server.listen(port, async () => {
|
|
90
|
+
const files = fs.readdirSync(distDir);
|
|
91
|
+
if (isJsonMode()) {
|
|
92
|
+
console.log(JSON.stringify({
|
|
93
|
+
url,
|
|
94
|
+
port,
|
|
95
|
+
files: files.map(f => `${url}/${f}`)
|
|
96
|
+
}));
|
|
97
|
+
} else {
|
|
98
|
+
success(`Serving on ${url}`);
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
info(` ${url}/${file}`);
|
|
101
|
+
}
|
|
102
|
+
if (opts.watch) {
|
|
103
|
+
info('Watch mode active — rebuilds automatically on file changes.');
|
|
104
|
+
}
|
|
105
|
+
info('Press Ctrl+C to stop.');
|
|
106
|
+
}
|
|
107
|
+
if (opts.open) {
|
|
108
|
+
const openPkg = (await import('open')).default;
|
|
109
|
+
await openPkg(url);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
} catch (err_) {
|
|
113
|
+
error(err_ instanceof Error ? err_.message : String(err_));
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Command","path","fs","http","spawn","success","error","info","isJsonMode","findProjectRoot","runBundle","DEFAULT_PORT","MIME_TYPES","startServer","distDir","corsOrigin","server","createServer","req","res","setHeader","method","writeHead","end","urlPath","url","filePath","join","startsWith","existsSync","statSync","isDirectory","ext","extname","contentType","createReadStream","pipe","serveCommand","description","option","String","action","opts","projectRoot","process","cwd","exit","port","parseInt","isNaN","bundle","watch","viteBin","watcher","shell","stdio","on","err_","message","listen","files","readdirSync","console","log","JSON","stringify","map","f","file","open","openPkg","default","Error"],"sources":["../../../src/commands/serve.ts"],"sourcesContent":["import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as http from 'http';\nimport { spawn } from 'child_process';\nimport { success, error, info, isJsonMode } from '../utils/print';\nimport { findProjectRoot } from '../utils/project';\nimport { runBundle } from './bundle';\n\nconst DEFAULT_PORT = 4001;\n\nconst MIME_TYPES: Record<string, string> = {\n '.js': 'application/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.map': 'application/json',\n};\n\nfunction startServer(distDir: string, corsOrigin: string): http.Server {\n const server = http.createServer((req, res) => {\n res.setHeader('Access-Control-Allow-Origin', corsOrigin);\n res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', '*');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n const urlPath = req.url === '/' ? '' : req.url ?? '';\n const filePath = path.join(distDir, urlPath);\n\n // Prevent path traversal outside distDir\n if (!filePath.startsWith(distDir)) {\n res.writeHead(403);\n res.end('Forbidden');\n return;\n }\n\n if (!fs.existsSync(filePath) || fs.statSync(filePath).isDirectory()) {\n res.writeHead(404);\n res.end('Not found');\n return;\n }\n\n const ext = path.extname(filePath);\n const contentType = MIME_TYPES[ext] ?? 'application/octet-stream';\n res.setHeader('Content-Type', contentType);\n res.writeHead(200);\n fs.createReadStream(filePath).pipe(res);\n });\n\n return server;\n}\n\nexport const serveCommand = new Command('serve')\n .description(\n 'Bundle components and serve them on http://localhost:<port> with CORS enabled',\n )\n .option('--port <n>', 'Port to listen on', String(DEFAULT_PORT))\n .option('--no-bundle', 'Serve existing dist/cdn/ without rebuilding')\n .option(\n '--watch',\n 'Re-bundle on source changes (starts vite --watch alongside server)',\n )\n .option('--open', 'Open the served URL in your browser after start')\n .option('--cors-origin <origin>', 'Restrict CORS Allow-Origin header', '*')\n .action(\n async (opts: {\n port: string;\n bundle: boolean;\n watch?: boolean;\n open?: boolean;\n corsOrigin: string;\n }) => {\n try {\n const projectRoot = findProjectRoot(process.cwd());\n if (!projectRoot) {\n error(\n 'No web5.config.json found. Run this command from within a Web5 project.',\n );\n process.exit(1);\n }\n\n const port = parseInt(opts.port, 10);\n if (isNaN(port) || port < 1 || port > 65535) {\n error(`Invalid port: ${opts.port}`);\n process.exit(1);\n }\n\n const distDir = path.join(projectRoot, 'dist', 'cdn');\n\n // ── Bundle (unless --no-bundle) ─────────────────────────────────────────\n if (opts.bundle !== false) {\n await runBundle(projectRoot);\n }\n\n if (!fs.existsSync(distDir)) {\n error(\n `Bundle output not found at ${distDir}. Run \\`web5 bundle\\` first or remove --no-bundle.`,\n );\n process.exit(1);\n }\n\n // ── Watch mode: spawn vite --watch in background ────────────────────────\n if (opts.watch) {\n const viteBin = path.join(\n projectRoot,\n 'node_modules',\n '.bin',\n 'vite',\n );\n if (!fs.existsSync(viteBin)) {\n error('vite not found. Run `npm install` in your project first.');\n process.exit(1);\n }\n const watcher = spawn(\n `\"${viteBin}\"`,\n ['build', '--config', 'src/vite.cdn.config.ts', '--watch'],\n { cwd: projectRoot, shell: true, stdio: 'inherit' },\n );\n watcher.on('error', (err_) =>\n error(`Watch process error: ${err_.message}`),\n );\n }\n\n // ── Start HTTP server ───────────────────────────────────────────────────\n const server = startServer(distDir, opts.corsOrigin);\n const url = `http://localhost:${port}`;\n\n server.listen(port, async () => {\n const files = fs.readdirSync(distDir);\n\n if (isJsonMode()) {\n console.log(\n JSON.stringify({\n url,\n port,\n files: files.map((f) => `${url}/${f}`),\n }),\n );\n } else {\n success(`Serving on ${url}`);\n for (const file of files) {\n info(` ${url}/${file}`);\n }\n if (opts.watch) {\n info(\n 'Watch mode active — rebuilds automatically on file changes.',\n );\n }\n info('Press Ctrl+C to stop.');\n }\n\n if (opts.open) {\n const openPkg = (await import('open')).default;\n await openPkg(url);\n }\n });\n } catch (err_) {\n error(err_ instanceof Error ? err_.message : String(err_));\n process.exit(1);\n }\n },\n );\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import { cp, readFile, writeFile } from 'fs/promises';
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
import { success, error, info, warn } from '../utils/print';
|
|
7
|
+
import { findProjectRoot } from '../utils/project';
|
|
8
|
+
const DEFAULTS_DIR = path.join(__dirname, '../../../defaults');
|
|
9
|
+
const STORYBOOK_DEPS = {
|
|
10
|
+
storybook: '^8.0.0',
|
|
11
|
+
'@storybook/react-vite': '^8.0.0',
|
|
12
|
+
'@storybook/addon-essentials': '^8.0.0'
|
|
13
|
+
};
|
|
14
|
+
const STORYBOOK_SCRIPTS = {
|
|
15
|
+
storybook: 'storybook dev -p 6006',
|
|
16
|
+
'build-storybook': 'storybook build'
|
|
17
|
+
};
|
|
18
|
+
export const storybookCommand = new Command('storybook').description('Add Storybook configuration and stories to a Web5 project').action(async () => {
|
|
19
|
+
try {
|
|
20
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
21
|
+
if (!projectRoot) {
|
|
22
|
+
error('No web5.config.json found. Run this command from within a Web5 project.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
info(`Adding Storybook to ${projectRoot}`);
|
|
26
|
+
|
|
27
|
+
// ── Copy .storybook/ config (overwrites on re-run — intentional) ──────
|
|
28
|
+
const storybookConfigSrc = path.join(DEFAULTS_DIR, '.storybook');
|
|
29
|
+
const storybookConfigDest = path.join(projectRoot, '.storybook');
|
|
30
|
+
await cp(storybookConfigSrc, storybookConfigDest, {
|
|
31
|
+
recursive: true
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// ── Copy stories folder (overwrites on re-run — intentional) ──────────
|
|
35
|
+
const storiesSrc = path.join(DEFAULTS_DIR, 'src', 'components', 'storybook');
|
|
36
|
+
const storiesDest = path.join(projectRoot, 'src', 'components', 'storybook');
|
|
37
|
+
await cp(storiesSrc, storiesDest, {
|
|
38
|
+
recursive: true
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// ── Update package.json (idempotent) ───────────────────────────────────
|
|
42
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
43
|
+
if (!fs.existsSync(pkgPath)) {
|
|
44
|
+
error('No package.json found in project root.');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf8'));
|
|
48
|
+
let pkgChanged = false;
|
|
49
|
+
|
|
50
|
+
// Scripts
|
|
51
|
+
pkg.scripts ??= {};
|
|
52
|
+
for (const [name, cmd] of Object.entries(STORYBOOK_SCRIPTS)) {
|
|
53
|
+
if (!pkg.scripts[name]) {
|
|
54
|
+
pkg.scripts[name] = cmd;
|
|
55
|
+
pkgChanged = true;
|
|
56
|
+
} else {
|
|
57
|
+
warn(`Script "${name}" already exists — skipping`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// devDependencies
|
|
62
|
+
pkg.devDependencies ??= {};
|
|
63
|
+
const missingDeps = [];
|
|
64
|
+
for (const [dep, version] of Object.entries(STORYBOOK_DEPS)) {
|
|
65
|
+
if (!pkg.devDependencies[dep]) {
|
|
66
|
+
pkg.devDependencies[dep] = version;
|
|
67
|
+
missingDeps.push(dep);
|
|
68
|
+
pkgChanged = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (pkgChanged) {
|
|
72
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
73
|
+
info('Updated package.json');
|
|
74
|
+
} else {
|
|
75
|
+
info('package.json already up to date');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ── Install dependencies ───────────────────────────────────────────────
|
|
79
|
+
if (missingDeps.length > 0) {
|
|
80
|
+
info(`Installing: ${missingDeps.join(', ')}`);
|
|
81
|
+
} else {
|
|
82
|
+
info('Running npm install to ensure dependencies are installed...');
|
|
83
|
+
}
|
|
84
|
+
execSync('npm install', {
|
|
85
|
+
cwd: projectRoot,
|
|
86
|
+
stdio: 'inherit'
|
|
87
|
+
});
|
|
88
|
+
success('Storybook is ready.');
|
|
89
|
+
console.log('');
|
|
90
|
+
info('Run it with:');
|
|
91
|
+
info(' npm run storybook');
|
|
92
|
+
} catch (err_) {
|
|
93
|
+
error(err_ instanceof Error ? err_.message : String(err_));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=storybook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Command","path","fs","cp","readFile","writeFile","execSync","success","error","info","warn","findProjectRoot","DEFAULTS_DIR","join","__dirname","STORYBOOK_DEPS","storybook","STORYBOOK_SCRIPTS","storybookCommand","description","action","projectRoot","process","cwd","exit","storybookConfigSrc","storybookConfigDest","recursive","storiesSrc","storiesDest","pkgPath","existsSync","pkg","JSON","parse","pkgChanged","scripts","name","cmd","Object","entries","devDependencies","missingDeps","dep","version","push","stringify","length","stdio","console","log","err_","Error","message","String"],"sources":["../../../src/commands/storybook.ts"],"sourcesContent":["import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { cp, readFile, writeFile } from 'fs/promises';\nimport { execSync } from 'child_process';\nimport { success, error, info, warn } from '../utils/print';\nimport { findProjectRoot } from '../utils/project';\n\nconst DEFAULTS_DIR = path.join(__dirname, '../../../defaults');\n\nconst STORYBOOK_DEPS = {\n storybook: '^8.0.0',\n '@storybook/react-vite': '^8.0.0',\n '@storybook/addon-essentials': '^8.0.0',\n};\n\nconst STORYBOOK_SCRIPTS = {\n storybook: 'storybook dev -p 6006',\n 'build-storybook': 'storybook build',\n};\n\nexport const storybookCommand = new Command('storybook')\n .description('Add Storybook configuration and stories to a Web5 project')\n .action(async () => {\n try {\n const projectRoot = findProjectRoot(process.cwd());\n if (!projectRoot) {\n error(\n 'No web5.config.json found. Run this command from within a Web5 project.',\n );\n process.exit(1);\n }\n\n info(`Adding Storybook to ${projectRoot}`);\n\n // ── Copy .storybook/ config (overwrites on re-run — intentional) ──────\n const storybookConfigSrc = path.join(DEFAULTS_DIR, '.storybook');\n const storybookConfigDest = path.join(projectRoot, '.storybook');\n await cp(storybookConfigSrc, storybookConfigDest, { recursive: true });\n\n // ── Copy stories folder (overwrites on re-run — intentional) ──────────\n const storiesSrc = path.join(\n DEFAULTS_DIR,\n 'src',\n 'components',\n 'storybook',\n );\n const storiesDest = path.join(\n projectRoot,\n 'src',\n 'components',\n 'storybook',\n );\n await cp(storiesSrc, storiesDest, { recursive: true });\n\n // ── Update package.json (idempotent) ───────────────────────────────────\n const pkgPath = path.join(projectRoot, 'package.json');\n if (!fs.existsSync(pkgPath)) {\n error('No package.json found in project root.');\n process.exit(1);\n }\n\n const pkg = JSON.parse(await readFile(pkgPath, 'utf8')) as {\n scripts?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n let pkgChanged = false;\n\n // Scripts\n pkg.scripts ??= {};\n for (const [name, cmd] of Object.entries(STORYBOOK_SCRIPTS)) {\n if (!pkg.scripts[name]) {\n pkg.scripts[name] = cmd;\n pkgChanged = true;\n } else {\n warn(`Script \"${name}\" already exists — skipping`);\n }\n }\n\n // devDependencies\n pkg.devDependencies ??= {};\n const missingDeps: string[] = [];\n for (const [dep, version] of Object.entries(STORYBOOK_DEPS)) {\n if (!pkg.devDependencies[dep]) {\n pkg.devDependencies[dep] = version;\n missingDeps.push(dep);\n pkgChanged = true;\n }\n }\n\n if (pkgChanged) {\n await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\\n', 'utf8');\n info('Updated package.json');\n } else {\n info('package.json already up to date');\n }\n\n // ── Install dependencies ───────────────────────────────────────────────\n if (missingDeps.length > 0) {\n info(`Installing: ${missingDeps.join(', ')}`);\n } else {\n info('Running npm install to ensure dependencies are installed...');\n }\n\n execSync('npm install', { cwd: projectRoot, stdio: 'inherit' });\n\n success('Storybook is ready.');\n console.log('');\n info('Run it with:');\n info(' npm run storybook');\n } catch (err_) {\n error(err_ instanceof Error ? err_.message : String(err_));\n process.exit(1);\n }\n });\n"],"mappings":"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","ignoreList":[]}
|