specra-cli 0.3.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.MD +33 -0
- package/README.md +246 -0
- package/dist/api-client-VHQARPDT.js +15 -0
- package/dist/api-client-VHQARPDT.js.map +1 -0
- package/dist/chunk-5765WX4D.js +192 -0
- package/dist/chunk-5765WX4D.js.map +1 -0
- package/dist/chunk-72RDEJR2.js +94 -0
- package/dist/chunk-72RDEJR2.js.map +1 -0
- package/dist/chunk-SQ2MMFUZ.js +102 -0
- package/dist/chunk-SQ2MMFUZ.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +242 -0
- package/dist/cli.js.map +1 -0
- package/dist/deploy-V4JO2D6B.js +179 -0
- package/dist/deploy-V4JO2D6B.js.map +1 -0
- package/dist/doctor-ICALAJ4N.js +309 -0
- package/dist/doctor-ICALAJ4N.js.map +1 -0
- package/dist/login-UG3WU7DY.js +92 -0
- package/dist/login-UG3WU7DY.js.map +1 -0
- package/dist/logout-WJKHJZT6.js +24 -0
- package/dist/logout-WJKHJZT6.js.map +1 -0
- package/dist/logs-BLUJPWNO.js +77 -0
- package/dist/logs-BLUJPWNO.js.map +1 -0
- package/dist/projects-LJ57GK3D.js +49 -0
- package/dist/projects-LJ57GK3D.js.map +1 -0
- package/package.json +50 -0
- package/templates/book-docs/.env.sample +1 -0
- package/templates/book-docs/docs/v1.0.0/concepts.mdx +89 -0
- package/templates/book-docs/docs/v1.0.0/content/_category_.json +7 -0
- package/templates/book-docs/docs/v1.0.0/content/formatting.mdx +128 -0
- package/templates/book-docs/docs/v1.0.0/content/reusable-content.mdx +116 -0
- package/templates/book-docs/docs/v1.0.0/content/structure.mdx +92 -0
- package/templates/book-docs/docs/v1.0.0/customization/_category_.json +7 -0
- package/templates/book-docs/docs/v1.0.0/customization/branding.mdx +115 -0
- package/templates/book-docs/docs/v1.0.0/customization/themes.mdx +81 -0
- package/templates/book-docs/docs/v1.0.0/introduction.mdx +38 -0
- package/templates/book-docs/docs/v1.0.0/quickstart.mdx +112 -0
- package/templates/book-docs/docs/v2.0.0/concepts.mdx +89 -0
- package/templates/book-docs/docs/v2.0.0/content/_category_.json +7 -0
- package/templates/book-docs/docs/v2.0.0/content/formatting.mdx +128 -0
- package/templates/book-docs/docs/v2.0.0/content/reusable-content.mdx +116 -0
- package/templates/book-docs/docs/v2.0.0/content/structure.mdx +92 -0
- package/templates/book-docs/docs/v2.0.0/customization/_category_.json +7 -0
- package/templates/book-docs/docs/v2.0.0/customization/branding.mdx +115 -0
- package/templates/book-docs/docs/v2.0.0/customization/themes.mdx +81 -0
- package/templates/book-docs/docs/v2.0.0/introduction.mdx +39 -0
- package/templates/book-docs/docs/v2.0.0/quickstart.mdx +112 -0
- package/templates/book-docs/gitignore +7 -0
- package/templates/book-docs/package.json +28 -0
- package/templates/book-docs/postcss.config.mjs +8 -0
- package/templates/book-docs/public/api-specs/openapi-example.json +259 -0
- package/templates/book-docs/public/api-specs/postman-example.json +205 -0
- package/templates/book-docs/public/api-specs/test-api.json +256 -0
- package/templates/book-docs/public/api-specs/users-api.json +264 -0
- package/templates/book-docs/specra.config.json +77 -0
- package/templates/book-docs/src/app.css +86 -0
- package/templates/book-docs/src/app.html +17 -0
- package/templates/book-docs/src/params/product.ts +7 -0
- package/templates/book-docs/src/routes/+layout.server.ts +14 -0
- package/templates/book-docs/src/routes/+layout.svelte +21 -0
- package/templates/book-docs/src/routes/+page.server.ts +9 -0
- package/templates/book-docs/src/routes/docs/[product=product]/[version]/+layout.server.ts +40 -0
- package/templates/book-docs/src/routes/docs/[product=product]/[version]/+page.server.ts +24 -0
- package/templates/book-docs/src/routes/docs/[product=product]/[version]/[...slug]/+page.server.ts +131 -0
- package/templates/book-docs/src/routes/docs/[product=product]/[version]/[...slug]/+page.svelte +180 -0
- package/templates/book-docs/src/routes/docs/[version]/+layout.server.ts +42 -0
- package/templates/book-docs/src/routes/docs/[version]/+page.server.ts +27 -0
- package/templates/book-docs/src/routes/docs/[version]/[...slug]/+page.server.ts +106 -0
- package/templates/book-docs/src/routes/docs/[version]/[...slug]/+page.svelte +172 -0
- package/templates/book-docs/static/favicon.svg +4 -0
- package/templates/book-docs/svelte.config.js +13 -0
- package/templates/book-docs/tsconfig.json +12 -0
- package/templates/book-docs/vite.config.ts +6 -0
- package/templates/jbrains-docs/.env.sample +1 -0
- package/templates/jbrains-docs/docs/v1.0.0/advanced/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v1.0.0/advanced/async.mdx +95 -0
- package/templates/jbrains-docs/docs/v1.0.0/advanced/generics.mdx +126 -0
- package/templates/jbrains-docs/docs/v1.0.0/basics/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v1.0.0/basics/control-flow.mdx +106 -0
- package/templates/jbrains-docs/docs/v1.0.0/basics/syntax.mdx +129 -0
- package/templates/jbrains-docs/docs/v1.0.0/basics/types.mdx +135 -0
- package/templates/jbrains-docs/docs/v1.0.0/getting-started.mdx +111 -0
- package/templates/jbrains-docs/docs/v1.0.0/home.mdx +37 -0
- package/templates/jbrains-docs/docs/v1.0.0/tools/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v1.0.0/tools/build-tools.mdx +165 -0
- package/templates/jbrains-docs/docs/v1.0.0/tools/testing.mdx +112 -0
- package/templates/jbrains-docs/docs/v2.0.0/advanced/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v2.0.0/advanced/async.mdx +95 -0
- package/templates/jbrains-docs/docs/v2.0.0/advanced/generics.mdx +126 -0
- package/templates/jbrains-docs/docs/v2.0.0/basics/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v2.0.0/basics/control-flow.mdx +106 -0
- package/templates/jbrains-docs/docs/v2.0.0/basics/syntax.mdx +129 -0
- package/templates/jbrains-docs/docs/v2.0.0/basics/types.mdx +135 -0
- package/templates/jbrains-docs/docs/v2.0.0/getting-started.mdx +111 -0
- package/templates/jbrains-docs/docs/v2.0.0/home.mdx +37 -0
- package/templates/jbrains-docs/docs/v2.0.0/tools/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v2.0.0/tools/build-tools.mdx +165 -0
- package/templates/jbrains-docs/docs/v2.0.0/tools/testing.mdx +112 -0
- package/templates/jbrains-docs/gitignore +7 -0
- package/templates/jbrains-docs/package.json +28 -0
- package/templates/jbrains-docs/postcss.config.mjs +8 -0
- package/templates/jbrains-docs/public/api-specs/openapi-example.json +259 -0
- package/templates/jbrains-docs/public/api-specs/postman-example.json +205 -0
- package/templates/jbrains-docs/public/api-specs/test-api.json +256 -0
- package/templates/jbrains-docs/public/api-specs/users-api.json +264 -0
- package/templates/jbrains-docs/specra.config.json +80 -0
- package/templates/jbrains-docs/src/app.css +86 -0
- package/templates/jbrains-docs/src/app.html +17 -0
- package/templates/jbrains-docs/src/params/product.ts +7 -0
- package/templates/jbrains-docs/src/routes/+layout.server.ts +14 -0
- package/templates/jbrains-docs/src/routes/+layout.svelte +21 -0
- package/templates/jbrains-docs/src/routes/+page.server.ts +9 -0
- package/templates/jbrains-docs/src/routes/docs/[product=product]/[version]/+layout.server.ts +40 -0
- package/templates/jbrains-docs/src/routes/docs/[product=product]/[version]/+page.server.ts +24 -0
- package/templates/jbrains-docs/src/routes/docs/[product=product]/[version]/[...slug]/+page.server.ts +131 -0
- package/templates/jbrains-docs/src/routes/docs/[product=product]/[version]/[...slug]/+page.svelte +180 -0
- package/templates/jbrains-docs/src/routes/docs/[version]/+layout.server.ts +42 -0
- package/templates/jbrains-docs/src/routes/docs/[version]/+page.server.ts +27 -0
- package/templates/jbrains-docs/src/routes/docs/[version]/[...slug]/+page.server.ts +106 -0
- package/templates/jbrains-docs/src/routes/docs/[version]/[...slug]/+page.svelte +172 -0
- package/templates/jbrains-docs/static/favicon.svg +4 -0
- package/templates/jbrains-docs/svelte.config.js +13 -0
- package/templates/jbrains-docs/tsconfig.json +12 -0
- package/templates/jbrains-docs/vite.config.ts +6 -0
- package/templates/minimal/.env.sample +1 -0
- package/templates/minimal/docs/v1.0.0/about.mdx +57 -0
- package/templates/minimal/docs/v1.0.0/components/_category_.json +8 -0
- package/templates/minimal/docs/v1.0.0/components/callout.mdx +83 -0
- package/templates/minimal/docs/v1.0.0/components/code-block.mdx +103 -0
- package/templates/minimal/docs/v1.0.0/components/index.mdx +8 -0
- package/templates/minimal/docs/v1.0.0/components/tabs.mdx +92 -0
- package/templates/minimal/docs/v1.0.0/configuration.mdx +322 -0
- package/templates/minimal/docs/v1.0.0/features.mdx +197 -0
- package/templates/minimal/docs/v1.0.0/getting-started.mdx +183 -0
- package/templates/minimal/docs/v2.0.0/about.mdx +57 -0
- package/templates/minimal/docs/v2.0.0/components/_category_.json +8 -0
- package/templates/minimal/docs/v2.0.0/components/callout.mdx +83 -0
- package/templates/minimal/docs/v2.0.0/components/code-block.mdx +103 -0
- package/templates/minimal/docs/v2.0.0/components/index.mdx +8 -0
- package/templates/minimal/docs/v2.0.0/components/tabs.mdx +92 -0
- package/templates/minimal/docs/v2.0.0/configuration.mdx +322 -0
- package/templates/minimal/docs/v2.0.0/features.mdx +197 -0
- package/templates/minimal/docs/v2.0.0/getting-started.mdx +183 -0
- package/templates/minimal/gitignore +7 -0
- package/templates/minimal/package.json +29 -0
- package/templates/minimal/postcss.config.mjs +8 -0
- package/templates/minimal/specra.config.json +91 -0
- package/templates/minimal/src/app.css +86 -0
- package/templates/minimal/src/app.html +17 -0
- package/templates/minimal/src/hooks.server.ts +8 -0
- package/templates/minimal/src/params/product.ts +7 -0
- package/templates/minimal/src/routes/+error.svelte +10 -0
- package/templates/minimal/src/routes/+layout.server.ts +14 -0
- package/templates/minimal/src/routes/+layout.svelte +21 -0
- package/templates/minimal/src/routes/+page.server.ts +9 -0
- package/templates/minimal/src/routes/+page.svelte +149 -0
- package/templates/minimal/src/routes/docs/[product=product]/[version]/+layout.server.ts +40 -0
- package/templates/minimal/src/routes/docs/[product=product]/[version]/+page.server.ts +24 -0
- package/templates/minimal/src/routes/docs/[product=product]/[version]/[...slug]/+page.server.ts +131 -0
- package/templates/minimal/src/routes/docs/[product=product]/[version]/[...slug]/+page.svelte +180 -0
- package/templates/minimal/src/routes/docs/[version]/+layout.server.ts +42 -0
- package/templates/minimal/src/routes/docs/[version]/+page.server.ts +27 -0
- package/templates/minimal/src/routes/docs/[version]/[...slug]/+page.server.ts +106 -0
- package/templates/minimal/src/routes/docs/[version]/[...slug]/+page.svelte +172 -0
- package/templates/minimal/static/api-specs/openapi-example.json +259 -0
- package/templates/minimal/static/api-specs/postman-example.json +205 -0
- package/templates/minimal/static/api-specs/test-api.json +256 -0
- package/templates/minimal/static/api-specs/users-api.json +264 -0
- package/templates/minimal/static/favicon.svg +4 -0
- package/templates/minimal/svelte.config.js +13 -0
- package/templates/minimal/tsconfig.json +12 -0
- package/templates/minimal/vite.config.ts +6 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/utils.ts
|
|
4
|
+
import validateNpmPackageName from "validate-npm-package-name";
|
|
5
|
+
import { execSync } from "child_process";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
function validateProjectName(name) {
|
|
9
|
+
const validation = validateNpmPackageName(name);
|
|
10
|
+
if (validation.validForNewPackages) {
|
|
11
|
+
return { valid: true };
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
valid: false,
|
|
15
|
+
problems: [
|
|
16
|
+
...validation.errors || [],
|
|
17
|
+
...validation.warnings || []
|
|
18
|
+
]
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function isWriteable(directory) {
|
|
22
|
+
try {
|
|
23
|
+
fs.accessSync(directory, fs.constants.W_OK);
|
|
24
|
+
return true;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function isFolderEmpty(path2) {
|
|
30
|
+
const files = fs.readdirSync(path2);
|
|
31
|
+
return files.length === 0 || files.length === 1 && files[0] === ".git";
|
|
32
|
+
}
|
|
33
|
+
function getPackageManagerCommand(packageManager) {
|
|
34
|
+
switch (packageManager) {
|
|
35
|
+
case "yarn":
|
|
36
|
+
return {
|
|
37
|
+
install: "yarn install",
|
|
38
|
+
run: (script) => `yarn ${script}`
|
|
39
|
+
};
|
|
40
|
+
case "pnpm":
|
|
41
|
+
return {
|
|
42
|
+
install: "pnpm install",
|
|
43
|
+
run: (script) => `pnpm ${script}`
|
|
44
|
+
};
|
|
45
|
+
case "npm":
|
|
46
|
+
default:
|
|
47
|
+
return {
|
|
48
|
+
install: "npm install",
|
|
49
|
+
run: (script) => `npm run ${script}`
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function detectPackageManager(dir) {
|
|
54
|
+
const configPath = path.join(dir, "specra.config.json");
|
|
55
|
+
try {
|
|
56
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
57
|
+
if (config.packageManager) return config.packageManager;
|
|
58
|
+
} catch {
|
|
59
|
+
}
|
|
60
|
+
if (fs.existsSync(path.join(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
61
|
+
if (fs.existsSync(path.join(dir, "yarn.lock"))) return "yarn";
|
|
62
|
+
return "npm";
|
|
63
|
+
}
|
|
64
|
+
function tryGitInit(root) {
|
|
65
|
+
try {
|
|
66
|
+
execSync("git --version", { stdio: "ignore" });
|
|
67
|
+
execSync("git init", { cwd: root, stdio: "ignore" });
|
|
68
|
+
execSync("git add -A", { cwd: root, stdio: "ignore" });
|
|
69
|
+
execSync('git commit -m "Initial commit from create-specra"', {
|
|
70
|
+
cwd: root,
|
|
71
|
+
stdio: "ignore"
|
|
72
|
+
});
|
|
73
|
+
return true;
|
|
74
|
+
} catch {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function copyRecursive(src, dest) {
|
|
79
|
+
const stat = fs.statSync(src);
|
|
80
|
+
if (stat.isDirectory()) {
|
|
81
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
82
|
+
const entries = fs.readdirSync(src);
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
const srcPath = path.join(src, entry);
|
|
85
|
+
const destPath = path.join(dest, entry);
|
|
86
|
+
copyRecursive(srcPath, destPath);
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
fs.copyFileSync(src, dest);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export {
|
|
94
|
+
validateProjectName,
|
|
95
|
+
isWriteable,
|
|
96
|
+
isFolderEmpty,
|
|
97
|
+
getPackageManagerCommand,
|
|
98
|
+
detectPackageManager,
|
|
99
|
+
tryGitInit,
|
|
100
|
+
copyRecursive
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=chunk-SQ2MMFUZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import validateNpmPackageName from 'validate-npm-package-name'\nimport { execSync } from 'child_process'\nimport fs from 'fs'\nimport path from 'path'\n\nexport function validateProjectName(name: string) {\n const validation = validateNpmPackageName(name)\n\n if (validation.validForNewPackages) {\n return { valid: true }\n }\n\n return {\n valid: false,\n problems: [\n ...(validation.errors || []),\n ...(validation.warnings || []),\n ],\n }\n}\n\nexport function isWriteable(directory: string): boolean {\n try {\n fs.accessSync(directory, fs.constants.W_OK)\n return true\n } catch {\n return false\n }\n}\n\nexport function isFolderEmpty(path: string): boolean {\n const files = fs.readdirSync(path)\n return files.length === 0 || (files.length === 1 && files[0] === '.git')\n}\n\nexport function getPackageManagerCommand(packageManager: string): {\n install: string\n run: (script: string) => string\n} {\n switch (packageManager) {\n case 'yarn':\n return {\n install: 'yarn install',\n run: (script) => `yarn ${script}`,\n }\n case 'pnpm':\n return {\n install: 'pnpm install',\n run: (script) => `pnpm ${script}`,\n }\n case 'npm':\n default:\n return {\n install: 'npm install',\n run: (script) => `npm run ${script}`,\n }\n }\n}\n\nexport function detectPackageManager(dir: string): string {\n // 1. Check specra.config.json for explicit setting\n const configPath = path.join(dir, 'specra.config.json')\n try {\n const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'))\n if (config.packageManager) return config.packageManager\n } catch {\n // ignore\n }\n\n // 2. Detect from lockfiles\n if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml'))) return 'pnpm'\n if (fs.existsSync(path.join(dir, 'yarn.lock'))) return 'yarn'\n return 'npm'\n}\n\nexport function tryGitInit(root: string): boolean {\n try {\n execSync('git --version', { stdio: 'ignore' })\n execSync('git init', { cwd: root, stdio: 'ignore' })\n execSync('git add -A', { cwd: root, stdio: 'ignore' })\n execSync('git commit -m \"Initial commit from create-specra\"', {\n cwd: root,\n stdio: 'ignore',\n })\n return true\n } catch {\n return false\n }\n}\n\nexport function copyRecursive(src: string, dest: string) {\n const stat = fs.statSync(src)\n\n if (stat.isDirectory()) {\n fs.mkdirSync(dest, { recursive: true })\n const entries = fs.readdirSync(src)\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry)\n const destPath = path.join(dest, entry)\n copyRecursive(srcPath, destPath)\n }\n } else {\n fs.copyFileSync(src, dest)\n }\n}\n"],"mappings":";;;AAAA,OAAO,4BAA4B;AACnC,SAAS,gBAAgB;AACzB,OAAO,QAAQ;AACf,OAAO,UAAU;AAEV,SAAS,oBAAoB,MAAc;AAChD,QAAM,aAAa,uBAAuB,IAAI;AAE9C,MAAI,WAAW,qBAAqB;AAClC,WAAO,EAAE,OAAO,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,MACR,GAAI,WAAW,UAAU,CAAC;AAAA,MAC1B,GAAI,WAAW,YAAY,CAAC;AAAA,IAC9B;AAAA,EACF;AACF;AAEO,SAAS,YAAY,WAA4B;AACtD,MAAI;AACF,OAAG,WAAW,WAAW,GAAG,UAAU,IAAI;AAC1C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAcA,OAAuB;AACnD,QAAM,QAAQ,GAAG,YAAYA,KAAI;AACjC,SAAO,MAAM,WAAW,KAAM,MAAM,WAAW,KAAK,MAAM,CAAC,MAAM;AACnE;AAEO,SAAS,yBAAyB,gBAGvC;AACA,UAAQ,gBAAgB;AAAA,IACtB,KAAK;AACH,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK,CAAC,WAAW,QAAQ,MAAM;AAAA,MACjC;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK,CAAC,WAAW,QAAQ,MAAM;AAAA,MACjC;AAAA,IACF,KAAK;AAAA,IACL;AACE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK,CAAC,WAAW,WAAW,MAAM;AAAA,MACpC;AAAA,EACJ;AACF;AAEO,SAAS,qBAAqB,KAAqB;AAExD,QAAM,aAAa,KAAK,KAAK,KAAK,oBAAoB;AACtD,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,GAAG,aAAa,YAAY,OAAO,CAAC;AAC9D,QAAI,OAAO,eAAgB,QAAO,OAAO;AAAA,EAC3C,QAAQ;AAAA,EAER;AAGA,MAAI,GAAG,WAAW,KAAK,KAAK,KAAK,gBAAgB,CAAC,EAAG,QAAO;AAC5D,MAAI,GAAG,WAAW,KAAK,KAAK,KAAK,WAAW,CAAC,EAAG,QAAO;AACvD,SAAO;AACT;AAEO,SAAS,WAAW,MAAuB;AAChD,MAAI;AACF,aAAS,iBAAiB,EAAE,OAAO,SAAS,CAAC;AAC7C,aAAS,YAAY,EAAE,KAAK,MAAM,OAAO,SAAS,CAAC;AACnD,aAAS,cAAc,EAAE,KAAK,MAAM,OAAO,SAAS,CAAC;AACrD,aAAS,qDAAqD;AAAA,MAC5D,KAAK;AAAA,MACL,OAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAc,KAAa,MAAc;AACvD,QAAM,OAAO,GAAG,SAAS,GAAG;AAE5B,MAAI,KAAK,YAAY,GAAG;AACtB,OAAG,UAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AACtC,UAAM,UAAU,GAAG,YAAY,GAAG;AAElC,eAAW,SAAS,SAAS;AAC3B,YAAM,UAAU,KAAK,KAAK,KAAK,KAAK;AACpC,YAAM,WAAW,KAAK,KAAK,MAAM,KAAK;AACtC,oBAAc,SAAS,QAAQ;AAAA,IACjC;AAAA,EACF,OAAO;AACL,OAAG,aAAa,KAAK,IAAI;AAAA,EAC3B;AACF;","names":["path"]}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
copyRecursive,
|
|
4
|
+
getPackageManagerCommand,
|
|
5
|
+
isFolderEmpty,
|
|
6
|
+
isWriteable,
|
|
7
|
+
tryGitInit,
|
|
8
|
+
validateProjectName
|
|
9
|
+
} from "./chunk-SQ2MMFUZ.js";
|
|
10
|
+
|
|
11
|
+
// src/cli.ts
|
|
12
|
+
import { Command } from "commander";
|
|
13
|
+
import prompts from "prompts";
|
|
14
|
+
import path2 from "path";
|
|
15
|
+
import pc2 from "picocolors";
|
|
16
|
+
|
|
17
|
+
// src/create-project.ts
|
|
18
|
+
import fs from "fs";
|
|
19
|
+
import path from "path";
|
|
20
|
+
import { fileURLToPath } from "url";
|
|
21
|
+
import { execSync } from "child_process";
|
|
22
|
+
import pc from "picocolors";
|
|
23
|
+
async function createProject({
|
|
24
|
+
projectName,
|
|
25
|
+
template,
|
|
26
|
+
packageManager,
|
|
27
|
+
skipInstall
|
|
28
|
+
}) {
|
|
29
|
+
const root = path.resolve(projectName);
|
|
30
|
+
const appName = path.basename(root);
|
|
31
|
+
if (fs.existsSync(root)) {
|
|
32
|
+
if (!isWriteable(root)) {
|
|
33
|
+
console.error(
|
|
34
|
+
pc.red(`The directory ${pc.cyan(projectName)} is not writable.`)
|
|
35
|
+
);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
if (!isFolderEmpty(root)) {
|
|
39
|
+
console.error(
|
|
40
|
+
pc.red(
|
|
41
|
+
`The directory ${pc.cyan(
|
|
42
|
+
projectName
|
|
43
|
+
)} contains files that could conflict. Please use a new directory.`
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
fs.mkdirSync(root, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
console.log(`Creating a new Specra documentation site (SvelteKit) in ${pc.cyan(root)}`);
|
|
52
|
+
console.log();
|
|
53
|
+
const __filename2 = fileURLToPath(import.meta.url);
|
|
54
|
+
const __dirname2 = path.dirname(__filename2);
|
|
55
|
+
const templateDir = path.join(__dirname2, "..", "templates", template);
|
|
56
|
+
if (!fs.existsSync(templateDir)) {
|
|
57
|
+
console.error(pc.red(`Template ${pc.cyan(template)} not found.`));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
console.log(`Using template: ${pc.cyan(template)}`);
|
|
61
|
+
console.log();
|
|
62
|
+
copyRecursive(templateDir, root);
|
|
63
|
+
const packageJsonPath = path.join(root, "package.json");
|
|
64
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
65
|
+
packageJson.name = appName;
|
|
66
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
|
|
67
|
+
const specraConfigPath = path.join(root, "specra.config.json");
|
|
68
|
+
if (fs.existsSync(specraConfigPath)) {
|
|
69
|
+
const specraConfig = JSON.parse(fs.readFileSync(specraConfigPath, "utf8"));
|
|
70
|
+
specraConfig.packageManager = packageManager;
|
|
71
|
+
fs.writeFileSync(specraConfigPath, JSON.stringify(specraConfig, null, 2) + "\n");
|
|
72
|
+
}
|
|
73
|
+
const gitignorePath = path.join(root, "gitignore");
|
|
74
|
+
if (fs.existsSync(gitignorePath)) {
|
|
75
|
+
fs.renameSync(gitignorePath, path.join(root, ".gitignore"));
|
|
76
|
+
}
|
|
77
|
+
if (!skipInstall) {
|
|
78
|
+
console.log("Installing dependencies...");
|
|
79
|
+
console.log();
|
|
80
|
+
const command2 = getPackageManagerCommand(packageManager);
|
|
81
|
+
try {
|
|
82
|
+
execSync(command2.install, { cwd: root, stdio: "inherit" });
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error(pc.red("Failed to install dependencies."));
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
console.log();
|
|
88
|
+
}
|
|
89
|
+
if (tryGitInit(root)) {
|
|
90
|
+
console.log("Initialized a git repository.");
|
|
91
|
+
console.log();
|
|
92
|
+
}
|
|
93
|
+
console.log(pc.green("Success!") + ` Created ${appName} at ${root}`);
|
|
94
|
+
console.log();
|
|
95
|
+
console.log("Inside that directory, you can run several commands:");
|
|
96
|
+
console.log();
|
|
97
|
+
const command = getPackageManagerCommand(packageManager);
|
|
98
|
+
console.log(pc.cyan(` ${command.run("dev")}`));
|
|
99
|
+
console.log(" Starts the development server.");
|
|
100
|
+
console.log();
|
|
101
|
+
console.log(pc.cyan(` ${command.run("build")}`));
|
|
102
|
+
console.log(" Builds the app for production.");
|
|
103
|
+
console.log();
|
|
104
|
+
console.log(pc.cyan(` ${command.run("preview")}`));
|
|
105
|
+
console.log(" Previews the built app locally.");
|
|
106
|
+
console.log();
|
|
107
|
+
console.log("We suggest that you begin by typing:");
|
|
108
|
+
console.log();
|
|
109
|
+
console.log(pc.cyan(" cd"), projectName);
|
|
110
|
+
console.log(` ${pc.cyan(command.run("dev"))}`);
|
|
111
|
+
console.log();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/cli.ts
|
|
115
|
+
import { createRequire } from "module";
|
|
116
|
+
var require2 = createRequire(import.meta.url);
|
|
117
|
+
var { version } = require2("../package.json");
|
|
118
|
+
var program = new Command();
|
|
119
|
+
program.name("specra").description("Specra CLI - Deploy and manage your documentation sites").version(version);
|
|
120
|
+
program.command("create [project-directory]").description("Create a new Specra documentation site").option("--template <template>", "Template to use (minimal, book-docs, jbrains-docs)").option("--use-npm", "Use npm as the package manager").option("--use-pnpm", "Use pnpm as the package manager").option("--use-yarn", "Use yarn as the package manager").option("--skip-install", "Skip package installation").action(async (projectDirectory, options) => {
|
|
121
|
+
console.log();
|
|
122
|
+
console.log(pc2.bold(pc2.cyan("Create Specra Documentation Site")));
|
|
123
|
+
console.log();
|
|
124
|
+
let projectName = projectDirectory;
|
|
125
|
+
if (!projectName) {
|
|
126
|
+
const response = await prompts({
|
|
127
|
+
type: "text",
|
|
128
|
+
name: "projectName",
|
|
129
|
+
message: "What is your project named?",
|
|
130
|
+
initial: "my-docs",
|
|
131
|
+
validate: (name) => {
|
|
132
|
+
const validation2 = validateProjectName(name);
|
|
133
|
+
if (validation2.valid) return true;
|
|
134
|
+
return validation2.problems[0];
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
if (!response.projectName) {
|
|
138
|
+
console.log();
|
|
139
|
+
console.log("Aborting.");
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
projectName = response.projectName;
|
|
143
|
+
}
|
|
144
|
+
const projectBaseName = path2.basename(path2.resolve(projectName));
|
|
145
|
+
const validation = validateProjectName(projectBaseName);
|
|
146
|
+
if (!validation.valid) {
|
|
147
|
+
console.error(
|
|
148
|
+
pc2.red(
|
|
149
|
+
`Cannot create a project named ${pc2.cyan(
|
|
150
|
+
`"${projectBaseName}"`
|
|
151
|
+
)} because of npm naming restrictions:
|
|
152
|
+
`
|
|
153
|
+
)
|
|
154
|
+
);
|
|
155
|
+
validation.problems.forEach(
|
|
156
|
+
(p) => console.error(` ${pc2.red("\u2022")} ${p}`)
|
|
157
|
+
);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
let template = options.template;
|
|
161
|
+
if (!template) {
|
|
162
|
+
const response = await prompts({
|
|
163
|
+
type: "select",
|
|
164
|
+
name: "template",
|
|
165
|
+
message: "Which template would you like to use?",
|
|
166
|
+
choices: [
|
|
167
|
+
{ title: "Minimal", value: "minimal", description: "Minimal setup to get started quickly" },
|
|
168
|
+
{ title: "Book Docs", value: "book-docs", description: "Knowledge base style with dark theme and categorized sidebar" },
|
|
169
|
+
{ title: "JBrains Docs", value: "jbrains-docs", description: "Reference docs style with light theme and tab groups" }
|
|
170
|
+
],
|
|
171
|
+
initial: 0
|
|
172
|
+
});
|
|
173
|
+
if (!response.template) {
|
|
174
|
+
console.log();
|
|
175
|
+
console.log("Aborting.");
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
template = response.template;
|
|
179
|
+
}
|
|
180
|
+
let packageManager = options.useNpm ? "npm" : options.usePnpm ? "pnpm" : options.useYarn ? "yarn" : void 0;
|
|
181
|
+
if (!packageManager && !options.skipInstall) {
|
|
182
|
+
const response = await prompts({
|
|
183
|
+
type: "select",
|
|
184
|
+
name: "packageManager",
|
|
185
|
+
message: "Which package manager do you want to use?",
|
|
186
|
+
choices: [
|
|
187
|
+
{ title: "npm", value: "npm" },
|
|
188
|
+
{ title: "yarn", value: "yarn" },
|
|
189
|
+
{ title: "pnpm", value: "pnpm" }
|
|
190
|
+
],
|
|
191
|
+
initial: 0
|
|
192
|
+
});
|
|
193
|
+
if (!response.packageManager) {
|
|
194
|
+
console.log();
|
|
195
|
+
console.log("Aborting.");
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
packageManager = response.packageManager;
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
await createProject({
|
|
202
|
+
projectName,
|
|
203
|
+
template: template || "minimal",
|
|
204
|
+
packageManager: packageManager || "npm",
|
|
205
|
+
skipInstall: options.skipInstall
|
|
206
|
+
});
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.error(pc2.red("\nError creating project:"));
|
|
209
|
+
console.error(error);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
program.command("login").description("Authenticate with your Specra account").option("-g, --global", "Store credentials in ~/.specra/ instead of local specra.config.json").action(async (options) => {
|
|
214
|
+
const { login } = await import("./login-UG3WU7DY.js");
|
|
215
|
+
await login(options);
|
|
216
|
+
});
|
|
217
|
+
program.command("logout").description("Clear stored credentials").option("-g, --global", "Clear credentials from ~/.specra/ instead of local specra.config.json").action(async (options) => {
|
|
218
|
+
const { logout } = await import("./logout-WJKHJZT6.js");
|
|
219
|
+
await logout(options);
|
|
220
|
+
});
|
|
221
|
+
program.command("deploy").description("Deploy your docs project").option("-p, --project <id>", "Project ID to deploy to").option("-d, --dir <directory>", "Docs directory to deploy", ".").option("-v, --verbose", "Show detailed build output and logs").action(async (options) => {
|
|
222
|
+
const { deploy } = await import("./deploy-V4JO2D6B.js");
|
|
223
|
+
await deploy(options);
|
|
224
|
+
});
|
|
225
|
+
program.command("projects").description("List your projects").action(async () => {
|
|
226
|
+
const { projects } = await import("./projects-LJ57GK3D.js");
|
|
227
|
+
await projects();
|
|
228
|
+
});
|
|
229
|
+
program.command("logs").description("View deployment logs").argument("<projectId>", "Project ID").option("--deployment <id>", "Specific deployment ID").action(async (projectId, options) => {
|
|
230
|
+
const { logs } = await import("./logs-BLUJPWNO.js");
|
|
231
|
+
await logs(projectId, options);
|
|
232
|
+
});
|
|
233
|
+
program.command("doctor").description("Check specra.config.json for issues").option("-d, --dir <directory>", "Project directory to check", ".").action(async (options) => {
|
|
234
|
+
const { doctor } = await import("./doctor-ICALAJ4N.js");
|
|
235
|
+
await doctor(options);
|
|
236
|
+
});
|
|
237
|
+
program.parse();
|
|
238
|
+
process.on("unhandledRejection", (err) => {
|
|
239
|
+
console.error(pc2.red("Error:"), err);
|
|
240
|
+
process.exit(1);
|
|
241
|
+
});
|
|
242
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/create-project.ts"],"sourcesContent":["import { Command } from 'commander'\nimport prompts from 'prompts'\nimport path from 'path'\nimport pc from 'picocolors'\nimport { createProject } from './create-project.js'\nimport { validateProjectName } from './utils.js'\nimport { createRequire } from 'module'\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json')\n\nconst program = new Command()\n\nprogram\n .name('specra')\n .description('Specra CLI - Deploy and manage your documentation sites')\n .version(version)\n\nprogram\n .command('create [project-directory]')\n .description('Create a new Specra documentation site')\n .option('--template <template>', 'Template to use (minimal, book-docs, jbrains-docs)')\n .option('--use-npm', 'Use npm as the package manager')\n .option('--use-pnpm', 'Use pnpm as the package manager')\n .option('--use-yarn', 'Use yarn as the package manager')\n .option('--skip-install', 'Skip package installation')\n .action(async (projectDirectory: string | undefined, options) => {\n console.log()\n console.log(pc.bold(pc.cyan('Create Specra Documentation Site')))\n console.log()\n\n let projectName = projectDirectory\n\n if (!projectName) {\n const response = await prompts({\n type: 'text',\n name: 'projectName',\n message: 'What is your project named?',\n initial: 'my-docs',\n validate: (name) => {\n const validation = validateProjectName(name)\n if (validation.valid) return true\n return validation.problems![0]\n },\n })\n\n if (!response.projectName) {\n console.log()\n console.log('Aborting.')\n process.exit(1)\n }\n\n projectName = response.projectName\n }\n\n const projectBaseName = path.basename(path.resolve(projectName!))\n const validation = validateProjectName(projectBaseName)\n if (!validation.valid) {\n console.error(\n pc.red(\n `Cannot create a project named ${pc.cyan(\n `\"${projectBaseName}\"`\n )} because of npm naming restrictions:\\n`\n )\n )\n validation.problems!.forEach((p) =>\n console.error(` ${pc.red('•')} ${p}`)\n )\n process.exit(1)\n }\n\n let template = options.template\n if (!template) {\n const response = await prompts({\n type: 'select',\n name: 'template',\n message: 'Which template would you like to use?',\n choices: [\n { title: 'Minimal', value: 'minimal', description: 'Minimal setup to get started quickly' },\n { title: 'Book Docs', value: 'book-docs', description: 'Knowledge base style with dark theme and categorized sidebar' },\n { title: 'JBrains Docs', value: 'jbrains-docs', description: 'Reference docs style with light theme and tab groups' },\n ],\n initial: 0,\n })\n\n if (!response.template) {\n console.log()\n console.log('Aborting.')\n process.exit(1)\n }\n\n template = response.template\n }\n\n let packageManager = options.useNpm\n ? 'npm'\n : options.usePnpm\n ? 'pnpm'\n : options.useYarn\n ? 'yarn'\n : undefined\n\n if (!packageManager && !options.skipInstall) {\n const response = await prompts({\n type: 'select',\n name: 'packageManager',\n message: 'Which package manager do you want to use?',\n choices: [\n { title: 'npm', value: 'npm' },\n { title: 'yarn', value: 'yarn' },\n { title: 'pnpm', value: 'pnpm' },\n ],\n initial: 0,\n })\n\n if (!response.packageManager) {\n console.log()\n console.log('Aborting.')\n process.exit(1)\n }\n\n packageManager = response.packageManager\n }\n\n try {\n await createProject({\n projectName: projectName!,\n template: template || 'minimal',\n packageManager: packageManager || 'npm',\n skipInstall: options.skipInstall,\n })\n } catch (error) {\n console.error(pc.red('\\nError creating project:'))\n console.error(error)\n process.exit(1)\n }\n })\n\nprogram\n .command('login')\n .description('Authenticate with your Specra account')\n .option('-g, --global', 'Store credentials in ~/.specra/ instead of local specra.config.json')\n .action(async (options) => {\n const { login } = await import('./commands/login.js')\n await login(options)\n })\n\nprogram\n .command('logout')\n .description('Clear stored credentials')\n .option('-g, --global', 'Clear credentials from ~/.specra/ instead of local specra.config.json')\n .action(async (options) => {\n const { logout } = await import('./commands/logout.js')\n await logout(options)\n })\n\nprogram\n .command('deploy')\n .description('Deploy your docs project')\n .option('-p, --project <id>', 'Project ID to deploy to')\n .option('-d, --dir <directory>', 'Docs directory to deploy', '.')\n .option('-v, --verbose', 'Show detailed build output and logs')\n .action(async (options) => {\n const { deploy } = await import('./commands/deploy.js')\n await deploy(options)\n })\n\nprogram\n .command('projects')\n .description('List your projects')\n .action(async () => {\n const { projects } = await import('./commands/projects.js')\n await projects()\n })\n\nprogram\n .command('logs')\n .description('View deployment logs')\n .argument('<projectId>', 'Project ID')\n .option('--deployment <id>', 'Specific deployment ID')\n .action(async (projectId: string, options) => {\n const { logs } = await import('./commands/logs.js')\n await logs(projectId, options)\n })\n\nprogram\n .command('doctor')\n .description('Check specra.config.json for issues')\n .option('-d, --dir <directory>', 'Project directory to check', '.')\n .action(async (options) => {\n const { doctor } = await import('./commands/doctor.js')\n await doctor(options)\n })\n\nprogram.parse()\n\n// Handle unhandled rejections\nprocess.on('unhandledRejection', (err) => {\n console.error(pc.red('Error:'), err)\n process.exit(1)\n})\n","import fs from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport { execSync } from 'child_process'\nimport pc from 'picocolors'\nimport {\n isWriteable,\n isFolderEmpty,\n getPackageManagerCommand,\n tryGitInit,\n copyRecursive,\n} from './utils.js'\n\ninterface CreateProjectOptions {\n projectName: string\n template: string\n packageManager: string\n skipInstall: boolean\n}\n\nexport async function createProject({\n projectName,\n template,\n packageManager,\n skipInstall,\n}: CreateProjectOptions) {\n const root = path.resolve(projectName)\n const appName = path.basename(root)\n\n // Check if directory exists\n if (fs.existsSync(root)) {\n if (!isWriteable(root)) {\n console.error(\n pc.red(`The directory ${pc.cyan(projectName)} is not writable.`)\n )\n process.exit(1)\n }\n\n if (!isFolderEmpty(root)) {\n console.error(\n pc.red(\n `The directory ${pc.cyan(\n projectName\n )} contains files that could conflict. Please use a new directory.`\n )\n )\n process.exit(1)\n }\n } else {\n fs.mkdirSync(root, { recursive: true })\n }\n\n console.log(`Creating a new Specra documentation site (SvelteKit) in ${pc.cyan(root)}`)\n console.log()\n\n // Create project structure based on template\n const __filename = fileURLToPath(import.meta.url)\n const __dirname = path.dirname(__filename)\n const templateDir = path.join(__dirname, '..', 'templates', template)\n\n if (!fs.existsSync(templateDir)) {\n console.error(pc.red(`Template ${pc.cyan(template)} not found.`))\n process.exit(1)\n }\n\n console.log(`Using template: ${pc.cyan(template)}`)\n console.log()\n\n // Copy template files\n copyRecursive(templateDir, root)\n\n // Update package.json with project name\n const packageJsonPath = path.join(root, 'package.json')\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))\n packageJson.name = appName\n fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\\n')\n\n // Save package manager choice to specra.config.json\n const specraConfigPath = path.join(root, 'specra.config.json')\n if (fs.existsSync(specraConfigPath)) {\n const specraConfig = JSON.parse(fs.readFileSync(specraConfigPath, 'utf8'))\n specraConfig.packageManager = packageManager\n fs.writeFileSync(specraConfigPath, JSON.stringify(specraConfig, null, 2) + '\\n')\n }\n\n // Rename gitignore\n const gitignorePath = path.join(root, 'gitignore')\n if (fs.existsSync(gitignorePath)) {\n fs.renameSync(gitignorePath, path.join(root, '.gitignore'))\n }\n\n // Install dependencies\n if (!skipInstall) {\n console.log('Installing dependencies...')\n console.log()\n\n const command = getPackageManagerCommand(packageManager)\n\n try {\n execSync(command.install, { cwd: root, stdio: 'inherit' })\n } catch (error) {\n console.error(pc.red('Failed to install dependencies.'))\n process.exit(1)\n }\n\n console.log()\n }\n\n // Initialize git\n if (tryGitInit(root)) {\n console.log('Initialized a git repository.')\n console.log()\n }\n\n // Success message\n console.log(pc.green('Success!') + ` Created ${appName} at ${root}`)\n console.log()\n console.log('Inside that directory, you can run several commands:')\n console.log()\n\n const command = getPackageManagerCommand(packageManager)\n\n console.log(pc.cyan(` ${command.run('dev')}`))\n console.log(' Starts the development server.')\n console.log()\n console.log(pc.cyan(` ${command.run('build')}`))\n console.log(' Builds the app for production.')\n console.log()\n console.log(pc.cyan(` ${command.run('preview')}`))\n console.log(' Previews the built app locally.')\n console.log()\n console.log('We suggest that you begin by typing:')\n console.log()\n console.log(pc.cyan(' cd'), projectName)\n console.log(` ${pc.cyan(command.run('dev'))}`)\n console.log()\n}\n"],"mappings":"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","names":["path","pc","__filename","__dirname","command","require","pc","validation","path"]}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
detectPackageManager,
|
|
4
|
+
getPackageManagerCommand
|
|
5
|
+
} from "./chunk-SQ2MMFUZ.js";
|
|
6
|
+
import {
|
|
7
|
+
apiRequest,
|
|
8
|
+
apiUpload,
|
|
9
|
+
formatError
|
|
10
|
+
} from "./chunk-72RDEJR2.js";
|
|
11
|
+
import {
|
|
12
|
+
getConfig,
|
|
13
|
+
isAuthenticated
|
|
14
|
+
} from "./chunk-5765WX4D.js";
|
|
15
|
+
|
|
16
|
+
// src/commands/deploy.ts
|
|
17
|
+
import pc from "picocolors";
|
|
18
|
+
import ora from "ora";
|
|
19
|
+
|
|
20
|
+
// src/archive.ts
|
|
21
|
+
import * as tar from "tar";
|
|
22
|
+
import { existsSync, statSync } from "fs";
|
|
23
|
+
import { resolve } from "path";
|
|
24
|
+
async function createArchive(dir) {
|
|
25
|
+
const absDir = resolve(dir);
|
|
26
|
+
if (!existsSync(absDir)) {
|
|
27
|
+
throw new Error(`Directory not found: ${absDir}`);
|
|
28
|
+
}
|
|
29
|
+
if (!statSync(absDir).isDirectory()) {
|
|
30
|
+
throw new Error(`Not a directory: ${absDir}`);
|
|
31
|
+
}
|
|
32
|
+
const chunks = [];
|
|
33
|
+
const stream = tar.create(
|
|
34
|
+
{
|
|
35
|
+
gzip: true,
|
|
36
|
+
cwd: absDir
|
|
37
|
+
},
|
|
38
|
+
["."]
|
|
39
|
+
);
|
|
40
|
+
for await (const chunk of stream) {
|
|
41
|
+
chunks.push(chunk);
|
|
42
|
+
}
|
|
43
|
+
const result = Buffer.concat(chunks);
|
|
44
|
+
if (result.length === 0) {
|
|
45
|
+
throw new Error("Archive is empty \u2014 no files found in the build output");
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/commands/deploy.ts
|
|
51
|
+
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
52
|
+
import { join, resolve as resolve2 } from "path";
|
|
53
|
+
async function deploy(options) {
|
|
54
|
+
if (!isAuthenticated()) {
|
|
55
|
+
console.error(pc.red("Not authenticated. Run `specra login` first."));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const dir = resolve2(options.dir);
|
|
59
|
+
let projectId = options.project;
|
|
60
|
+
if (!projectId) {
|
|
61
|
+
const configPath = join(dir, "specra.config.json");
|
|
62
|
+
if (existsSync2(configPath)) {
|
|
63
|
+
try {
|
|
64
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
65
|
+
projectId = config.projectId;
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!projectId) {
|
|
71
|
+
let projects;
|
|
72
|
+
try {
|
|
73
|
+
projects = await apiRequest(
|
|
74
|
+
"/api/projects"
|
|
75
|
+
);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.error(pc.red(formatError("Failed to fetch projects", err)));
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
if (projects.length === 0) {
|
|
81
|
+
console.error(
|
|
82
|
+
pc.red("No projects found. Create one at https://specra-docs.com/dashboard/projects/new")
|
|
83
|
+
);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
console.log(pc.bold("Select a project to deploy to:"));
|
|
87
|
+
projects.forEach((p, i) => {
|
|
88
|
+
console.log(` ${pc.dim(`${i + 1}.`)} ${p.name} ${pc.dim(`(${p.subdomain}.docs.specra.dev)`)}`);
|
|
89
|
+
});
|
|
90
|
+
const prompts = await import("prompts");
|
|
91
|
+
const response = await prompts.default({
|
|
92
|
+
type: "select",
|
|
93
|
+
name: "project",
|
|
94
|
+
message: "Project",
|
|
95
|
+
choices: projects.map((p) => ({
|
|
96
|
+
title: p.name,
|
|
97
|
+
value: p.id,
|
|
98
|
+
description: `${p.subdomain}.docs.specra.dev`
|
|
99
|
+
}))
|
|
100
|
+
});
|
|
101
|
+
if (!response.project) {
|
|
102
|
+
console.log("Aborted.");
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
projectId = response.project;
|
|
106
|
+
}
|
|
107
|
+
const verbose = options.verbose ?? false;
|
|
108
|
+
if (verbose) {
|
|
109
|
+
console.log(pc.dim(`Project ID: ${projectId}`));
|
|
110
|
+
console.log(pc.dim(`Directory: ${dir}`));
|
|
111
|
+
}
|
|
112
|
+
const spinner = ora("Building project...").start();
|
|
113
|
+
try {
|
|
114
|
+
const buildDir = join(dir, "build");
|
|
115
|
+
const { execSync } = await import("child_process");
|
|
116
|
+
const pm = detectPackageManager(dir);
|
|
117
|
+
const pmCmd = getPackageManagerCommand(pm);
|
|
118
|
+
if (verbose) {
|
|
119
|
+
spinner.stop();
|
|
120
|
+
console.log(pc.dim(`Package manager: ${pm}`));
|
|
121
|
+
console.log(pc.dim(`Running: ${pmCmd.run("build")}`));
|
|
122
|
+
console.log();
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
execSync(pmCmd.run("build"), { cwd: dir, stdio: verbose ? "inherit" : "pipe" });
|
|
126
|
+
} catch (err) {
|
|
127
|
+
if (!verbose) {
|
|
128
|
+
const stderr = err instanceof Error && "stderr" in err ? err.stderr?.toString() : "";
|
|
129
|
+
throw new Error(`Build failed:
|
|
130
|
+
${stderr}`);
|
|
131
|
+
}
|
|
132
|
+
throw new Error("Build failed. See output above.");
|
|
133
|
+
}
|
|
134
|
+
if (verbose) {
|
|
135
|
+
spinner.start();
|
|
136
|
+
}
|
|
137
|
+
if (!existsSync2(buildDir)) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
"Build output not found. Expected a `build/` directory.\nMake sure your project uses @sveltejs/adapter-static."
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
spinner.text = "Packaging build output...";
|
|
143
|
+
const archive = await createArchive(buildDir);
|
|
144
|
+
spinner.text = `Uploading (${(archive.length / 1024).toFixed(0)}KB)...`;
|
|
145
|
+
if (verbose) {
|
|
146
|
+
console.log(pc.dim(`Archive size: ${(archive.length / 1024).toFixed(1)}KB`));
|
|
147
|
+
}
|
|
148
|
+
let commitSha;
|
|
149
|
+
try {
|
|
150
|
+
commitSha = execSync("git rev-parse HEAD", { cwd: dir }).toString().trim();
|
|
151
|
+
} catch {
|
|
152
|
+
}
|
|
153
|
+
const result = await apiUpload(
|
|
154
|
+
`/api/projects/${projectId}/deploy`,
|
|
155
|
+
archive,
|
|
156
|
+
{
|
|
157
|
+
"X-Deploy-Trigger": "CLI",
|
|
158
|
+
"X-Pre-Built": "true",
|
|
159
|
+
...commitSha ? { "X-Commit-Sha": commitSha } : {}
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
spinner.succeed(pc.green("Deployed!"));
|
|
163
|
+
console.log();
|
|
164
|
+
console.log(` Deployment ID: ${pc.cyan(result.deploymentId)}`);
|
|
165
|
+
const config = getConfig();
|
|
166
|
+
console.log(
|
|
167
|
+
` View status: ${pc.dim(`${config.apiUrl}/dashboard/projects/${projectId}/deployments`)}`
|
|
168
|
+
);
|
|
169
|
+
console.log();
|
|
170
|
+
} catch (err) {
|
|
171
|
+
spinner.fail(pc.red("Deploy failed"));
|
|
172
|
+
console.error(pc.red(formatError("", err)));
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
export {
|
|
177
|
+
deploy
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=deploy-V4JO2D6B.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/deploy.ts","../src/archive.ts"],"sourcesContent":["import pc from 'picocolors'\nimport ora from 'ora'\nimport { createArchive } from '../archive.js'\nimport { apiUpload, apiRequest, formatError } from '../api-client.js'\nimport { isAuthenticated, getConfig } from '../config.js'\nimport { existsSync, readFileSync } from 'fs'\nimport { join, resolve } from 'path'\nimport { detectPackageManager, getPackageManagerCommand } from '../utils.js'\n\ninterface DeployOptions {\n project?: string\n dir: string\n verbose?: boolean\n}\n\nexport async function deploy(options: DeployOptions) {\n if (!isAuthenticated()) {\n console.error(pc.red('Not authenticated. Run `specra login` first.'))\n process.exit(1)\n }\n\n const dir = resolve(options.dir)\n let projectId = options.project\n\n // If no project specified, try to read from specra.config.json\n if (!projectId) {\n const configPath = join(dir, 'specra.config.json')\n if (existsSync(configPath)) {\n try {\n const config = JSON.parse(readFileSync(configPath, 'utf-8'))\n projectId = config.projectId\n } catch {\n // ignore\n }\n }\n }\n\n if (!projectId) {\n // List projects and ask user to pick\n let projects: Array<{ id: string; name: string; subdomain: string }>\n try {\n projects = await apiRequest<Array<{ id: string; name: string; subdomain: string }>>(\n '/api/projects'\n )\n } catch (err) {\n console.error(pc.red(formatError('Failed to fetch projects', err)))\n process.exit(1)\n }\n\n if (projects.length === 0) {\n console.error(\n pc.red('No projects found. Create one at https://specra-docs.com/dashboard/projects/new')\n )\n process.exit(1)\n }\n\n console.log(pc.bold('Select a project to deploy to:'))\n projects.forEach((p, i) => {\n console.log(` ${pc.dim(`${i + 1}.`)} ${p.name} ${pc.dim(`(${p.subdomain}.docs.specra.dev)`)}`)\n })\n\n const prompts = await import('prompts')\n const response = await prompts.default({\n type: 'select',\n name: 'project',\n message: 'Project',\n choices: projects.map((p) => ({\n title: p.name,\n value: p.id,\n description: `${p.subdomain}.docs.specra.dev`,\n })),\n })\n\n if (!response.project) {\n console.log('Aborted.')\n process.exit(1)\n }\n\n projectId = response.project\n }\n\n const verbose = options.verbose ?? false\n\n if (verbose) {\n console.log(pc.dim(`Project ID: ${projectId}`))\n console.log(pc.dim(`Directory: ${dir}`))\n }\n\n const spinner = ora('Building project...').start()\n\n try {\n // 1. Build the project locally\n const buildDir = join(dir, 'build')\n const { execSync } = await import('child_process')\n\n const pm = detectPackageManager(dir)\n const pmCmd = getPackageManagerCommand(pm)\n\n if (verbose) {\n spinner.stop()\n console.log(pc.dim(`Package manager: ${pm}`))\n console.log(pc.dim(`Running: ${pmCmd.run('build')}`))\n console.log()\n }\n\n try {\n execSync(pmCmd.run('build'), { cwd: dir, stdio: verbose ? 'inherit' : 'pipe' })\n } catch (err) {\n if (!verbose) {\n const stderr = err instanceof Error && 'stderr' in err\n ? (err as { stderr: Buffer }).stderr?.toString()\n : ''\n throw new Error(`Build failed:\\n${stderr}`)\n }\n throw new Error('Build failed. See output above.')\n }\n\n if (verbose) {\n spinner.start()\n }\n\n if (!existsSync(buildDir)) {\n throw new Error(\n 'Build output not found. Expected a `build/` directory.\\n' +\n 'Make sure your project uses @sveltejs/adapter-static.'\n )\n }\n\n // 2. Archive the build output\n spinner.text = 'Packaging build output...'\n const archive = await createArchive(buildDir)\n spinner.text = `Uploading (${(archive.length / 1024).toFixed(0)}KB)...`\n\n if (verbose) {\n console.log(pc.dim(`Archive size: ${(archive.length / 1024).toFixed(1)}KB`))\n }\n\n // 3. Get git commit SHA if available\n let commitSha: string | undefined\n try {\n commitSha = execSync('git rev-parse HEAD', { cwd: dir })\n .toString()\n .trim()\n } catch {\n // not a git repo\n }\n\n // 4. Upload as pre-built\n const result = await apiUpload(\n `/api/projects/${projectId}/deploy`,\n archive,\n {\n 'X-Deploy-Trigger': 'CLI',\n 'X-Pre-Built': 'true',\n ...(commitSha ? { 'X-Commit-Sha': commitSha } : {}),\n }\n ) as { deploymentId: string }\n\n spinner.succeed(pc.green('Deployed!'))\n console.log()\n console.log(` Deployment ID: ${pc.cyan(result.deploymentId)}`)\n\n const config = getConfig()\n console.log(\n ` View status: ${pc.dim(`${config.apiUrl}/dashboard/projects/${projectId}/deployments`)}`\n )\n console.log()\n } catch (err) {\n spinner.fail(pc.red('Deploy failed'))\n console.error(pc.red(formatError('', err)))\n process.exit(1)\n }\n}\n","import * as tar from 'tar'\nimport { existsSync, statSync } from 'fs'\nimport { resolve } from 'path'\n\nexport async function createArchive(dir: string): Promise<Buffer> {\n const absDir = resolve(dir)\n\n if (!existsSync(absDir)) {\n throw new Error(`Directory not found: ${absDir}`)\n }\n\n if (!statSync(absDir).isDirectory()) {\n throw new Error(`Not a directory: ${absDir}`)\n }\n\n const chunks: Buffer[] = []\n\n const stream = tar.create(\n {\n gzip: true,\n cwd: absDir,\n },\n ['.']\n )\n\n for await (const chunk of stream) {\n chunks.push(chunk as Buffer)\n }\n\n const result = Buffer.concat(chunks)\n if (result.length === 0) {\n throw new Error('Archive is empty — no files found in the build output')\n }\n\n return result\n}\n"],"mappings":"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","names":["existsSync","resolve","resolve","existsSync"]}
|