@butterbase/cli 0.2.0 → 0.2.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/dist/bin/butterbase.js +254 -2
- package/dist/bin/butterbase.js.map +1 -1
- package/dist/src/commands/billing.d.ts +26 -0
- package/dist/src/commands/billing.d.ts.map +1 -0
- package/dist/src/commands/billing.js +183 -0
- package/dist/src/commands/billing.js.map +1 -0
- package/dist/src/commands/deploy-edge-ssr-from-source.d.ts +10 -0
- package/dist/src/commands/deploy-edge-ssr-from-source.d.ts.map +1 -0
- package/dist/src/commands/deploy-edge-ssr-from-source.js +141 -0
- package/dist/src/commands/deploy-edge-ssr-from-source.js.map +1 -0
- package/dist/src/commands/deploy-edge-ssr.d.ts +7 -0
- package/dist/src/commands/deploy-edge-ssr.d.ts.map +1 -0
- package/dist/src/commands/deploy-edge-ssr.js +141 -0
- package/dist/src/commands/deploy-edge-ssr.js.map +1 -0
- package/dist/src/commands/deploy-from-source.d.ts +9 -0
- package/dist/src/commands/deploy-from-source.d.ts.map +1 -0
- package/dist/src/commands/deploy-from-source.js +140 -0
- package/dist/src/commands/deploy-from-source.js.map +1 -0
- package/dist/src/commands/do.d.ts +33 -0
- package/dist/src/commands/do.d.ts.map +1 -0
- package/dist/src/commands/do.js +165 -0
- package/dist/src/commands/do.js.map +1 -0
- package/dist/src/commands/functions.d.ts +12 -0
- package/dist/src/commands/functions.d.ts.map +1 -1
- package/dist/src/commands/functions.js +108 -1
- package/dist/src/commands/functions.js.map +1 -1
- package/dist/src/commands/rag.d.ts +44 -0
- package/dist/src/commands/rag.d.ts.map +1 -0
- package/dist/src/commands/rag.js +271 -0
- package/dist/src/commands/rag.js.map +1 -0
- package/dist/src/commands/rls.d.ts +25 -0
- package/dist/src/commands/rls.d.ts.map +1 -0
- package/dist/src/commands/rls.js +127 -0
- package/dist/src/commands/rls.js.map +1 -0
- package/dist/src/lib/api-client.d.ts +81 -0
- package/dist/src/lib/api-client.d.ts.map +1 -1
- package/dist/src/lib/api-client.js +122 -0
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/lockfile-hash.d.ts +5 -0
- package/dist/src/lib/lockfile-hash.d.ts.map +1 -0
- package/dist/src/lib/lockfile-hash.js +23 -0
- package/dist/src/lib/lockfile-hash.js.map +1 -0
- package/dist/src/lib/sse.d.ts +7 -0
- package/dist/src/lib/sse.d.ts.map +1 -0
- package/dist/src/lib/sse.js +63 -0
- package/dist/src/lib/sse.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import AdmZip from 'adm-zip';
|
|
6
|
+
import { getMergedConfig } from '../lib/config.js';
|
|
7
|
+
import { getCurrentAppId } from '../lib/config.js';
|
|
8
|
+
import { detectPackageManagerAndLockfile } from '../lib/lockfile-hash.js';
|
|
9
|
+
import { streamSSE } from '../lib/sse.js';
|
|
10
|
+
async function requireAppId(appId) {
|
|
11
|
+
if (appId)
|
|
12
|
+
return appId;
|
|
13
|
+
const currentAppId = await getCurrentAppId();
|
|
14
|
+
if (!currentAppId) {
|
|
15
|
+
console.error(chalk.red('No app specified and no current app set'));
|
|
16
|
+
console.log(chalk.gray('Use: butterbase apps use <app-id>'));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
return currentAppId;
|
|
20
|
+
}
|
|
21
|
+
function zipDir(root, prefix, zip, exclude) {
|
|
22
|
+
const entries = fs.readdirSync(root, { withFileTypes: true });
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
if (exclude.includes(entry.name))
|
|
25
|
+
continue;
|
|
26
|
+
const abs = path.join(root, entry.name);
|
|
27
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
28
|
+
if (entry.isDirectory()) {
|
|
29
|
+
zipDir(abs, rel, zip, exclude);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
zip.addFile(rel, fs.readFileSync(abs));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export async function deployEdgeSsrFromSource(opts) {
|
|
37
|
+
const projectDir = path.resolve(opts.fromPath ?? process.cwd());
|
|
38
|
+
if (!fs.existsSync(projectDir) || !fs.statSync(projectDir).isDirectory()) {
|
|
39
|
+
console.error(chalk.red(`${projectDir} is not a directory`));
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const appId = await requireAppId(opts.app);
|
|
43
|
+
const config = await getMergedConfig();
|
|
44
|
+
const apiBase = config.endpoint;
|
|
45
|
+
const apiKey = config.apiKey;
|
|
46
|
+
if (!apiKey) {
|
|
47
|
+
console.error(chalk.red('Not authenticated. Run: butterbase login'));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const framework = opts.framework ?? 'nextjs-edge';
|
|
51
|
+
const spinner = ora('Zipping source...').start();
|
|
52
|
+
try {
|
|
53
|
+
// 1. Zip the project
|
|
54
|
+
const zip = new AdmZip();
|
|
55
|
+
zipDir(projectDir, '', zip, ['node_modules', '.next', '.vercel', '.git']);
|
|
56
|
+
const zipBuf = zip.toBuffer();
|
|
57
|
+
if (zipBuf.length > 50 * 1024 * 1024) {
|
|
58
|
+
spinner.fail('Source too large');
|
|
59
|
+
console.error(chalk.red('Zipped source exceeds 50 MB limit'));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
// 2. Create deployment
|
|
63
|
+
spinner.text = 'Creating deployment...';
|
|
64
|
+
const createRes = await fetch(`${apiBase}/v1/${appId}/edge-ssr/deployments/from-source`, {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: {
|
|
67
|
+
authorization: `Bearer ${apiKey}`,
|
|
68
|
+
'content-type': 'application/json',
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify({ framework }),
|
|
71
|
+
});
|
|
72
|
+
if (!createRes.ok) {
|
|
73
|
+
const text = await createRes.text();
|
|
74
|
+
throw new Error(`create failed: ${createRes.status} ${text}`);
|
|
75
|
+
}
|
|
76
|
+
const created = (await createRes.json());
|
|
77
|
+
// 3. Upload zip to presigned URL
|
|
78
|
+
spinner.text = `Uploading source (${(zipBuf.length / 1024 / 1024).toFixed(1)} MB)...`;
|
|
79
|
+
const putRes = await fetch(created.upload_url, {
|
|
80
|
+
method: 'PUT',
|
|
81
|
+
body: new Uint8Array(zipBuf),
|
|
82
|
+
headers: { 'content-type': 'application/zip' },
|
|
83
|
+
});
|
|
84
|
+
if (!putRes.ok) {
|
|
85
|
+
throw new Error(`upload failed: ${putRes.status}`);
|
|
86
|
+
}
|
|
87
|
+
// 4. Detect package manager + lockfile hash
|
|
88
|
+
const { packageManager, lockfileHash } = detectPackageManagerAndLockfile(projectDir);
|
|
89
|
+
// 5. Start build
|
|
90
|
+
spinner.text = 'Starting build...';
|
|
91
|
+
const startRes = await fetch(`${apiBase}/v1/${appId}/edge-ssr/deployments/from-source/${created.deployment_id}/start`, {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: {
|
|
94
|
+
authorization: `Bearer ${apiKey}`,
|
|
95
|
+
'content-type': 'application/json',
|
|
96
|
+
},
|
|
97
|
+
body: JSON.stringify({
|
|
98
|
+
buildCommand: opts.buildCommand ?? 'npx @cloudflare/next-on-pages',
|
|
99
|
+
outputDir: opts.outputDir ?? '.vercel/output/static',
|
|
100
|
+
packageManager,
|
|
101
|
+
lockfileHash,
|
|
102
|
+
userEnv: {},
|
|
103
|
+
}),
|
|
104
|
+
});
|
|
105
|
+
if (!startRes.ok) {
|
|
106
|
+
const text = await startRes.text();
|
|
107
|
+
throw new Error(`start failed: ${startRes.status} ${text}`);
|
|
108
|
+
}
|
|
109
|
+
spinner.succeed('Build started — streaming logs...');
|
|
110
|
+
console.log('');
|
|
111
|
+
// 6. Tail SSE logs
|
|
112
|
+
await streamSSE(`${apiBase}/v1/${appId}/edge-ssr/deployments/from-source/${created.deployment_id}/logs`, { authorization: `Bearer ${apiKey}` });
|
|
113
|
+
// 7. Poll deployment status until terminal (READY / ERROR)
|
|
114
|
+
const deadline = Date.now() + 30_000;
|
|
115
|
+
let final = null;
|
|
116
|
+
while (Date.now() < deadline) {
|
|
117
|
+
const r = await fetch(`${apiBase}/v1/${appId}/edge-ssr/deployments/${created.deployment_id}`, {
|
|
118
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
119
|
+
});
|
|
120
|
+
if (r.ok) {
|
|
121
|
+
final = (await r.json());
|
|
122
|
+
if (final && (final.status === 'READY' || final.status === 'ERROR' || final.status === 'FAILED'))
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
await new Promise((resolve) => setTimeout(resolve, 2_000));
|
|
126
|
+
}
|
|
127
|
+
console.log('');
|
|
128
|
+
if (!final || final.status !== 'READY') {
|
|
129
|
+
process.stderr.write(`\n✗ Deploy failed: ${final?.status ?? 'unknown'}${final?.error ? ` (${final.error})` : ''}\n`);
|
|
130
|
+
process.exitCode = 1;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
process.stdout.write(`\n✓ Deployed: ${final.url}\n`);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
spinner.fail('Deployment failed');
|
|
137
|
+
console.error(chalk.red(error.message));
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=deploy-edge-ssr-from-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-edge-ssr-from-source.js","sourceRoot":"","sources":["../../../src/commands/deploy-edge-ssr-from-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-edge-ssr.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy-edge-ssr.ts"],"names":[],"mappings":"AAkEA,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,iBAmG7E"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import AdmZip from 'adm-zip';
|
|
6
|
+
import { createEdgeSsrDeployment, uploadBinary, startEdgeSsrDeployment, getEdgeSsrDeployment } from '../lib/api-client.js';
|
|
7
|
+
import { getCurrentAppId } from '../lib/config.js';
|
|
8
|
+
const WORKER_JS = '_worker.js';
|
|
9
|
+
const WORKER_JS_INDEX = path.join('_worker.js', 'index.js');
|
|
10
|
+
const DEFAULT_VERCEL_OUTPUT = path.join('.vercel', 'output', 'static');
|
|
11
|
+
const MISSING_WORKER_MESSAGE = 'No _worker.js found. Run `npx @cloudflare/next-on-pages` to build, or use `--from <path>` to point at the directory containing _worker.js.';
|
|
12
|
+
async function requireAppId(appId) {
|
|
13
|
+
if (appId)
|
|
14
|
+
return appId;
|
|
15
|
+
const currentAppId = await getCurrentAppId();
|
|
16
|
+
if (!currentAppId) {
|
|
17
|
+
console.error(chalk.red('No app specified and no current app set'));
|
|
18
|
+
console.log(chalk.gray('Use: butterbase apps use <app-id>'));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
return currentAppId;
|
|
22
|
+
}
|
|
23
|
+
function hasWorkerJs(dir) {
|
|
24
|
+
return (fs.existsSync(path.join(dir, WORKER_JS)) ||
|
|
25
|
+
fs.existsSync(path.join(dir, WORKER_JS_INDEX)));
|
|
26
|
+
}
|
|
27
|
+
function detectEdgeSsrDirectory() {
|
|
28
|
+
// 1. Prefer .vercel/output/static/ if it contains _worker.js
|
|
29
|
+
if (fs.existsSync(DEFAULT_VERCEL_OUTPUT) && hasWorkerJs(DEFAULT_VERCEL_OUTPUT)) {
|
|
30
|
+
return DEFAULT_VERCEL_OUTPUT;
|
|
31
|
+
}
|
|
32
|
+
// 2. Fall back to cwd if it contains _worker.js
|
|
33
|
+
if (hasWorkerJs('.')) {
|
|
34
|
+
return '.';
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function zipDirectory(dir) {
|
|
39
|
+
const zip = new AdmZip();
|
|
40
|
+
const absDir = path.resolve(dir);
|
|
41
|
+
function addDir(currentDir, zipPath) {
|
|
42
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
45
|
+
const entryZipPath = zipPath ? `${zipPath}/${entry.name}` : entry.name;
|
|
46
|
+
if (entry.isDirectory()) {
|
|
47
|
+
addDir(fullPath, entryZipPath);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
zip.addFile(entryZipPath, fs.readFileSync(fullPath));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
addDir(absDir, '');
|
|
55
|
+
return zip.toBuffer();
|
|
56
|
+
}
|
|
57
|
+
export async function deployEdgeSsrCommand(directory, options) {
|
|
58
|
+
const appId = await requireAppId(options.app);
|
|
59
|
+
// Resolve the source directory: explicit positional > --from > auto-detect
|
|
60
|
+
const resolvedDir = directory ?? options.from ?? detectEdgeSsrDirectory();
|
|
61
|
+
if (!resolvedDir) {
|
|
62
|
+
console.error(chalk.red(MISSING_WORKER_MESSAGE));
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
// Pre-upload validation: directory must exist
|
|
66
|
+
if (!fs.existsSync(resolvedDir)) {
|
|
67
|
+
console.error(chalk.red(`Directory not found: ${resolvedDir}`));
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
// Pre-upload validation: must contain _worker.js (file or _worker.js/index.js)
|
|
71
|
+
if (!hasWorkerJs(resolvedDir)) {
|
|
72
|
+
console.error(chalk.red(MISSING_WORKER_MESSAGE));
|
|
73
|
+
console.error(chalk.gray(`Checked: ${path.resolve(resolvedDir)}`));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
const framework = options.framework ?? 'nextjs-edge';
|
|
77
|
+
const spinner = ora('Creating Edge SSR deployment...').start();
|
|
78
|
+
try {
|
|
79
|
+
// Step 1: Create deployment (get upload URL)
|
|
80
|
+
const deployment = await createEdgeSsrDeployment(appId, framework);
|
|
81
|
+
// Step 2: Zip the directory
|
|
82
|
+
spinner.text = 'Zipping build directory...';
|
|
83
|
+
const zipBuffer = zipDirectory(resolvedDir);
|
|
84
|
+
// Step 3: Upload zip to presigned URL
|
|
85
|
+
spinner.text = 'Uploading...';
|
|
86
|
+
await uploadBinary(deployment.uploadUrl, zipBuffer, 'application/zip');
|
|
87
|
+
// Step 4: Start the deployment pipeline
|
|
88
|
+
spinner.text = 'Deploying...';
|
|
89
|
+
await startEdgeSsrDeployment(appId, deployment.id);
|
|
90
|
+
// Step 5: Poll until terminal state (5 s × 60 = 5 min max)
|
|
91
|
+
let status = 'BUILDING';
|
|
92
|
+
let url = '';
|
|
93
|
+
let fileCount = 0;
|
|
94
|
+
let totalSize = 0;
|
|
95
|
+
let attempts = 0;
|
|
96
|
+
while (['BUILDING', 'UPLOADING', 'WAITING'].includes(status) && attempts < 60) {
|
|
97
|
+
await new Promise((r) => setTimeout(r, 5000));
|
|
98
|
+
spinner.text = `Deploying... (${attempts * 5}s)`;
|
|
99
|
+
const result = await getEdgeSsrDeployment(appId, deployment.id);
|
|
100
|
+
status = result.status;
|
|
101
|
+
url = result.url;
|
|
102
|
+
fileCount = result.fileCount;
|
|
103
|
+
totalSize = result.totalSizeBytes;
|
|
104
|
+
attempts++;
|
|
105
|
+
}
|
|
106
|
+
if (status === 'READY') {
|
|
107
|
+
spinner.succeed('Deployed!');
|
|
108
|
+
if (options.json) {
|
|
109
|
+
console.log(JSON.stringify({ url, deploymentId: deployment.id, status, framework, fileCount, totalSizeBytes: totalSize }, null, 2));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
console.log('');
|
|
113
|
+
console.log(` URL: ${chalk.green(url)}`);
|
|
114
|
+
console.log(` Framework: ${framework}`);
|
|
115
|
+
if (fileCount)
|
|
116
|
+
console.log(` Files: ${fileCount}`);
|
|
117
|
+
if (totalSize)
|
|
118
|
+
console.log(` Size: ${(totalSize / 1024 / 1024).toFixed(1)} MB`);
|
|
119
|
+
}
|
|
120
|
+
else if (status === 'ERROR') {
|
|
121
|
+
spinner.fail('Deployment failed');
|
|
122
|
+
const result = await getEdgeSsrDeployment(appId, deployment.id);
|
|
123
|
+
console.error(chalk.red(result.error ?? 'Unknown error'));
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
else if (status === 'CANCELED' || status === 'SUPERSEDED') {
|
|
127
|
+
spinner.warn(`Deployment ${status.toLowerCase()} (id: ${deployment.id})`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// Timeout — attempts exhausted while still in a transient state
|
|
131
|
+
spinner.warn(`Deployment timed out (status: ${status})`);
|
|
132
|
+
console.log(chalk.gray(`Check status: butterbase status --app ${appId}`));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
spinner.fail('Deployment failed');
|
|
137
|
+
console.error(chalk.red(error.message));
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=deploy-edge-ssr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-edge-ssr.js","sourceRoot":"","sources":["../../../src/commands/deploy-edge-ssr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-from-source.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy-from-source.ts"],"names":[],"mappings":"AAUA,UAAU,OAAO;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAoInE"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import AdmZip from 'adm-zip';
|
|
6
|
+
import { getMergedConfig } from '../lib/config.js';
|
|
7
|
+
import { getCurrentAppId } from '../lib/config.js';
|
|
8
|
+
import { detectPackageManagerAndLockfile } from '../lib/lockfile-hash.js';
|
|
9
|
+
import { streamSSE } from '../lib/sse.js';
|
|
10
|
+
async function requireAppId(appId) {
|
|
11
|
+
if (appId)
|
|
12
|
+
return appId;
|
|
13
|
+
const currentAppId = await getCurrentAppId();
|
|
14
|
+
if (!currentAppId) {
|
|
15
|
+
console.error(chalk.red('No app specified and no current app set'));
|
|
16
|
+
console.log(chalk.gray('Use: butterbase apps use <app-id>'));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
return currentAppId;
|
|
20
|
+
}
|
|
21
|
+
function zipDir(root, prefix, zip, exclude) {
|
|
22
|
+
const entries = fs.readdirSync(root, { withFileTypes: true });
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
if (exclude.includes(entry.name))
|
|
25
|
+
continue;
|
|
26
|
+
const abs = path.join(root, entry.name);
|
|
27
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
28
|
+
if (entry.isDirectory()) {
|
|
29
|
+
zipDir(abs, rel, zip, exclude);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
zip.addFile(rel, fs.readFileSync(abs));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export async function deployFromSource(opts) {
|
|
37
|
+
const projectDir = path.resolve(opts.fromPath ?? process.cwd());
|
|
38
|
+
if (!fs.existsSync(projectDir) || !fs.statSync(projectDir).isDirectory()) {
|
|
39
|
+
console.error(chalk.red(`${projectDir} is not a directory`));
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const appId = await requireAppId(opts.app);
|
|
43
|
+
const config = await getMergedConfig();
|
|
44
|
+
const apiBase = config.endpoint;
|
|
45
|
+
const apiKey = config.apiKey;
|
|
46
|
+
if (!apiKey) {
|
|
47
|
+
console.error(chalk.red('Not authenticated. Run: butterbase login'));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const spinner = ora('Zipping source...').start();
|
|
51
|
+
try {
|
|
52
|
+
// 1. Zip the project
|
|
53
|
+
const zip = new AdmZip();
|
|
54
|
+
zipDir(projectDir, '', zip, ['node_modules', '.next', '.vercel', '.git']);
|
|
55
|
+
const zipBuf = zip.toBuffer();
|
|
56
|
+
if (zipBuf.length > 50 * 1024 * 1024) {
|
|
57
|
+
spinner.fail('Source too large');
|
|
58
|
+
console.error(chalk.red('Zipped source exceeds 50 MB limit'));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
// 2. Create deployment (no body — frontend from-source create takes no body)
|
|
62
|
+
spinner.text = 'Creating deployment...';
|
|
63
|
+
const createRes = await fetch(`${apiBase}/v1/${appId}/frontend/deployments/from-source`, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: {
|
|
66
|
+
authorization: `Bearer ${apiKey}`,
|
|
67
|
+
'content-type': 'application/json',
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify({}),
|
|
70
|
+
});
|
|
71
|
+
if (!createRes.ok) {
|
|
72
|
+
const text = await createRes.text();
|
|
73
|
+
throw new Error(`create failed: ${createRes.status} ${text}`);
|
|
74
|
+
}
|
|
75
|
+
const created = (await createRes.json());
|
|
76
|
+
// 3. Upload zip to presigned URL
|
|
77
|
+
spinner.text = `Uploading source (${(zipBuf.length / 1024 / 1024).toFixed(1)} MB)...`;
|
|
78
|
+
const putRes = await fetch(created.upload_url, {
|
|
79
|
+
method: 'PUT',
|
|
80
|
+
body: new Uint8Array(zipBuf),
|
|
81
|
+
headers: { 'content-type': 'application/zip' },
|
|
82
|
+
});
|
|
83
|
+
if (!putRes.ok) {
|
|
84
|
+
throw new Error(`upload failed: ${putRes.status}`);
|
|
85
|
+
}
|
|
86
|
+
// 4. Detect package manager + lockfile hash
|
|
87
|
+
const { packageManager, lockfileHash } = detectPackageManagerAndLockfile(projectDir);
|
|
88
|
+
// 5. Start build
|
|
89
|
+
spinner.text = 'Starting build...';
|
|
90
|
+
const startRes = await fetch(`${apiBase}/v1/${appId}/frontend/deployments/from-source/${created.deployment_id}/start`, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
headers: {
|
|
93
|
+
authorization: `Bearer ${apiKey}`,
|
|
94
|
+
'content-type': 'application/json',
|
|
95
|
+
},
|
|
96
|
+
body: JSON.stringify({
|
|
97
|
+
buildCommand: opts.buildCommand ?? 'npm run build',
|
|
98
|
+
outputDir: opts.outputDir ?? 'dist',
|
|
99
|
+
packageManager,
|
|
100
|
+
lockfileHash,
|
|
101
|
+
userEnv: {},
|
|
102
|
+
}),
|
|
103
|
+
});
|
|
104
|
+
if (!startRes.ok) {
|
|
105
|
+
const text = await startRes.text();
|
|
106
|
+
throw new Error(`start failed: ${startRes.status} ${text}`);
|
|
107
|
+
}
|
|
108
|
+
spinner.succeed('Build started — streaming logs...');
|
|
109
|
+
console.log('');
|
|
110
|
+
// 6. Tail SSE logs
|
|
111
|
+
await streamSSE(`${apiBase}/v1/${appId}/frontend/deployments/from-source/${created.deployment_id}/logs`, { authorization: `Bearer ${apiKey}` });
|
|
112
|
+
// 7. Poll deployment status until terminal (READY / ERROR)
|
|
113
|
+
const deadline = Date.now() + 30_000;
|
|
114
|
+
let final = null;
|
|
115
|
+
while (Date.now() < deadline) {
|
|
116
|
+
const r = await fetch(`${apiBase}/v1/${appId}/frontend/deployments/${created.deployment_id}`, {
|
|
117
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
118
|
+
});
|
|
119
|
+
if (r.ok) {
|
|
120
|
+
final = (await r.json());
|
|
121
|
+
if (final && (final.status === 'READY' || final.status === 'ERROR' || final.status === 'FAILED'))
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
await new Promise((resolve) => setTimeout(resolve, 2_000));
|
|
125
|
+
}
|
|
126
|
+
console.log('');
|
|
127
|
+
if (!final || final.status !== 'READY') {
|
|
128
|
+
process.stderr.write(`\n✗ Deploy failed: ${final?.status ?? 'unknown'}${final?.error ? ` (${final.error})` : ''}\n`);
|
|
129
|
+
process.exitCode = 1;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
process.stdout.write(`\n✓ Deployed: ${final.url}\n`);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
spinner.fail('Deployment failed');
|
|
136
|
+
console.error(chalk.red(error.message));
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=deploy-from-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-from-source.js","sourceRoot":"","sources":["../../../src/commands/deploy-from-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare function doDeployCommand(file: string, options: {
|
|
2
|
+
app?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
accessMode?: string;
|
|
5
|
+
json?: boolean;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
export declare function doListCommand(options: {
|
|
8
|
+
app?: string;
|
|
9
|
+
json?: boolean;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
export declare function doGetCommand(name: string, options: {
|
|
12
|
+
app?: string;
|
|
13
|
+
json?: boolean;
|
|
14
|
+
code?: boolean;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
export declare function doDeleteCommand(name: string, options: {
|
|
17
|
+
app?: string;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
export declare function doEnvListCommand(options: {
|
|
20
|
+
app?: string;
|
|
21
|
+
json?: boolean;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
export declare function doEnvSetCommand(key: string, value: string, options: {
|
|
24
|
+
app?: string;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
export declare function doEnvUnsetCommand(key: string, options: {
|
|
27
|
+
app?: string;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
export declare function doUsageCommand(name: string, options: {
|
|
30
|
+
app?: string;
|
|
31
|
+
json?: boolean;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
//# sourceMappingURL=do.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"do.d.ts","sourceRoot":"","sources":["../../../src/commands/do.ts"],"names":[],"mappings":"AA2BA,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,iBA6BhI;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,iBAiB5E;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,iBAkBzG;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,iBAW5E;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,iBAe/E;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,iBAe1F;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,iBAe7E;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,iBAW3F"}
|