@insforge/cli 0.1.50 → 0.1.51
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/index.js +236 -50
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { readFileSync as readFileSync7 } from "fs";
|
|
5
|
-
import { join as
|
|
5
|
+
import { join as join10, dirname } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import * as clack11 from "@clack/prompts";
|
|
@@ -1123,7 +1123,7 @@ async function reportCliUsage(toolName, success, maxRetries = 1, explicitConfig)
|
|
|
1123
1123
|
|
|
1124
1124
|
// src/lib/analytics.ts
|
|
1125
1125
|
import { PostHog } from "posthog-node";
|
|
1126
|
-
var POSTHOG_API_KEY = "
|
|
1126
|
+
var POSTHOG_API_KEY = "";
|
|
1127
1127
|
var POSTHOG_HOST = process.env.POSTHOG_HOST || "https://us.i.posthog.com";
|
|
1128
1128
|
var client = null;
|
|
1129
1129
|
function getClient() {
|
|
@@ -1247,10 +1247,13 @@ async function readEnvFile(cwd) {
|
|
|
1247
1247
|
// src/commands/deployments/deploy.ts
|
|
1248
1248
|
import * as path2 from "path";
|
|
1249
1249
|
import * as fs2 from "fs/promises";
|
|
1250
|
+
import { createReadStream } from "fs";
|
|
1251
|
+
import { createHash as createHash2 } from "crypto";
|
|
1250
1252
|
import * as clack6 from "@clack/prompts";
|
|
1251
1253
|
import archiver from "archiver";
|
|
1252
1254
|
var POLL_INTERVAL_MS = 5e3;
|
|
1253
1255
|
var POLL_TIMEOUT_MS = 3e5;
|
|
1256
|
+
var DIRECT_UPLOAD_CONCURRENCY = 8;
|
|
1254
1257
|
var EXCLUDE_PATTERNS = [
|
|
1255
1258
|
"node_modules",
|
|
1256
1259
|
".git",
|
|
@@ -1278,6 +1281,12 @@ var EXCLUDE_PATTERNS = [
|
|
|
1278
1281
|
"skills",
|
|
1279
1282
|
"coverage"
|
|
1280
1283
|
];
|
|
1284
|
+
var DirectDeploymentUnsupportedError = class extends Error {
|
|
1285
|
+
constructor() {
|
|
1286
|
+
super("Direct deployment endpoints are not available on this backend");
|
|
1287
|
+
this.name = "DirectDeploymentUnsupportedError";
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1281
1290
|
function shouldExclude(name) {
|
|
1282
1291
|
const normalized = name.replace(/\\/g, "/");
|
|
1283
1292
|
for (const pattern of EXCLUDE_PATTERNS) {
|
|
@@ -1288,6 +1297,56 @@ function shouldExclude(name) {
|
|
|
1288
1297
|
if (normalized.endsWith(".log")) return true;
|
|
1289
1298
|
return false;
|
|
1290
1299
|
}
|
|
1300
|
+
function isInsforgeCloudOssHost(ossHost) {
|
|
1301
|
+
try {
|
|
1302
|
+
return new URL(ossHost).hostname.endsWith(".insforge.app");
|
|
1303
|
+
} catch {
|
|
1304
|
+
return false;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
function normalizeRelativePath(sourceDir, absolutePath) {
|
|
1308
|
+
return path2.relative(sourceDir, absolutePath).split(path2.sep).join("/").replace(/\\/g, "/");
|
|
1309
|
+
}
|
|
1310
|
+
async function hashFile(filePath) {
|
|
1311
|
+
const hash = createHash2("sha1");
|
|
1312
|
+
let size = 0;
|
|
1313
|
+
for await (const chunk of createReadStream(filePath)) {
|
|
1314
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
1315
|
+
size += buffer.length;
|
|
1316
|
+
hash.update(buffer);
|
|
1317
|
+
}
|
|
1318
|
+
return { sha: hash.digest("hex"), size };
|
|
1319
|
+
}
|
|
1320
|
+
async function collectDeploymentFiles(sourceDir) {
|
|
1321
|
+
const files = [];
|
|
1322
|
+
async function walk(currentDir) {
|
|
1323
|
+
const entries = await fs2.readdir(currentDir, { withFileTypes: true });
|
|
1324
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
1325
|
+
for (const entry of entries) {
|
|
1326
|
+
const absolutePath = path2.join(currentDir, entry.name);
|
|
1327
|
+
const normalizedPath = normalizeRelativePath(sourceDir, absolutePath);
|
|
1328
|
+
if (!normalizedPath || shouldExclude(normalizedPath)) {
|
|
1329
|
+
continue;
|
|
1330
|
+
}
|
|
1331
|
+
if (entry.isDirectory()) {
|
|
1332
|
+
await walk(absolutePath);
|
|
1333
|
+
continue;
|
|
1334
|
+
}
|
|
1335
|
+
if (!entry.isFile()) {
|
|
1336
|
+
continue;
|
|
1337
|
+
}
|
|
1338
|
+
const { sha, size } = await hashFile(absolutePath);
|
|
1339
|
+
files.push({
|
|
1340
|
+
absolutePath,
|
|
1341
|
+
path: normalizedPath,
|
|
1342
|
+
sha,
|
|
1343
|
+
size
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
await walk(sourceDir);
|
|
1348
|
+
return files;
|
|
1349
|
+
}
|
|
1291
1350
|
async function createZipBuffer(sourceDir) {
|
|
1292
1351
|
return new Promise((resolve4, reject) => {
|
|
1293
1352
|
const archive = archiver("zip", { zlib: { level: 9 } });
|
|
@@ -1302,40 +1361,84 @@ async function createZipBuffer(sourceDir) {
|
|
|
1302
1361
|
void archive.finalize();
|
|
1303
1362
|
});
|
|
1304
1363
|
}
|
|
1305
|
-
async function
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
const formData = new FormData();
|
|
1314
|
-
for (const [key, value] of Object.entries(uploadFields)) {
|
|
1315
|
-
formData.append(key, value);
|
|
1364
|
+
async function runWithConcurrency(items, concurrency, worker) {
|
|
1365
|
+
let nextIndex = 0;
|
|
1366
|
+
async function runWorker() {
|
|
1367
|
+
while (nextIndex < items.length) {
|
|
1368
|
+
const index = nextIndex;
|
|
1369
|
+
nextIndex += 1;
|
|
1370
|
+
await worker(items[index], index);
|
|
1371
|
+
}
|
|
1316
1372
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1373
|
+
const workerCount = Math.min(concurrency, items.length);
|
|
1374
|
+
await Promise.all(Array.from({ length: workerCount }, () => runWorker()));
|
|
1375
|
+
}
|
|
1376
|
+
async function createDirectDeploymentSession(config, files) {
|
|
1377
|
+
const url = `${config.oss_host}/api/deployments/direct`;
|
|
1378
|
+
let response;
|
|
1379
|
+
try {
|
|
1380
|
+
response = await fetch(url, {
|
|
1381
|
+
method: "POST",
|
|
1382
|
+
headers: {
|
|
1383
|
+
"Content-Type": "application/json",
|
|
1384
|
+
Authorization: `Bearer ${config.api_key}`
|
|
1385
|
+
},
|
|
1386
|
+
body: JSON.stringify({ files })
|
|
1387
|
+
});
|
|
1388
|
+
} catch (error) {
|
|
1389
|
+
throw new CLIError(formatFetchError(error, url));
|
|
1326
1390
|
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1391
|
+
if (response.status === 404) {
|
|
1392
|
+
throw new DirectDeploymentUnsupportedError();
|
|
1393
|
+
}
|
|
1394
|
+
if (!response.ok) {
|
|
1395
|
+
const err = await response.json().catch(() => ({}));
|
|
1396
|
+
let message = err.message ?? err.error ?? `OSS request failed: ${response.status}`;
|
|
1397
|
+
if (err.nextActions) {
|
|
1398
|
+
message += `
|
|
1399
|
+
${err.nextActions}`;
|
|
1400
|
+
}
|
|
1401
|
+
throw new CLIError(message);
|
|
1402
|
+
}
|
|
1403
|
+
const payload = await response.json();
|
|
1404
|
+
if (!payload.id || !Array.isArray(payload.files)) {
|
|
1405
|
+
throw new CLIError("Unexpected response from direct deployment create endpoint.");
|
|
1406
|
+
}
|
|
1407
|
+
return payload;
|
|
1408
|
+
}
|
|
1409
|
+
async function uploadDirectDeploymentFile(deploymentId, manifestFile, localFile) {
|
|
1410
|
+
const requestInit = {
|
|
1411
|
+
method: "PUT",
|
|
1412
|
+
headers: {
|
|
1413
|
+
"Content-Type": "application/octet-stream",
|
|
1414
|
+
"Content-Length": String(localFile.size)
|
|
1415
|
+
},
|
|
1416
|
+
body: createReadStream(localFile.absolutePath),
|
|
1417
|
+
duplex: "half"
|
|
1418
|
+
};
|
|
1419
|
+
await ossFetch(
|
|
1420
|
+
`/api/deployments/${encodeURIComponent(deploymentId)}/files/${encodeURIComponent(manifestFile.fileId)}/content`,
|
|
1421
|
+
requestInit
|
|
1422
|
+
);
|
|
1423
|
+
}
|
|
1424
|
+
async function startDirectDeployment(deploymentId, startBody) {
|
|
1425
|
+
const response = await ossFetch(`/api/deployments/${encodeURIComponent(deploymentId)}/start`, {
|
|
1329
1426
|
method: "POST",
|
|
1427
|
+
headers: { "Content-Type": "application/json" },
|
|
1330
1428
|
body: JSON.stringify(startBody)
|
|
1331
1429
|
});
|
|
1332
|
-
await
|
|
1333
|
-
|
|
1430
|
+
await response.json();
|
|
1431
|
+
}
|
|
1432
|
+
async function pollDeployment(deploymentId, spinner7, syncBeforeRead) {
|
|
1433
|
+
spinner7?.message("Building and deploying...");
|
|
1334
1434
|
const startTime = Date.now();
|
|
1335
1435
|
let deployment = null;
|
|
1336
1436
|
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
|
|
1337
|
-
await new Promise((
|
|
1437
|
+
await new Promise((resolve4) => setTimeout(resolve4, POLL_INTERVAL_MS));
|
|
1338
1438
|
try {
|
|
1439
|
+
if (syncBeforeRead) {
|
|
1440
|
+
await ossFetch(`/api/deployments/${deploymentId}/sync`, { method: "POST" });
|
|
1441
|
+
}
|
|
1339
1442
|
const statusRes = await ossFetch(`/api/deployments/${deploymentId}`);
|
|
1340
1443
|
deployment = await statusRes.json();
|
|
1341
1444
|
const status = deployment.status.toUpperCase();
|
|
@@ -1343,11 +1446,13 @@ async function deployProject(opts) {
|
|
|
1343
1446
|
break;
|
|
1344
1447
|
}
|
|
1345
1448
|
if (status === "ERROR" || status === "CANCELED") {
|
|
1346
|
-
|
|
1347
|
-
throw new CLIError(
|
|
1449
|
+
spinner7?.stop("Deployment failed");
|
|
1450
|
+
throw new CLIError(
|
|
1451
|
+
getDeploymentError(deployment.metadata) ?? `Deployment failed with status: ${deployment.status}`
|
|
1452
|
+
);
|
|
1348
1453
|
}
|
|
1349
1454
|
const elapsed = Math.round((Date.now() - startTime) / 1e3);
|
|
1350
|
-
|
|
1455
|
+
spinner7?.message(`Building and deploying... (${elapsed}s, status: ${deployment.status})`);
|
|
1351
1456
|
} catch (err) {
|
|
1352
1457
|
if (err instanceof CLIError) throw err;
|
|
1353
1458
|
}
|
|
@@ -1356,8 +1461,78 @@ async function deployProject(opts) {
|
|
|
1356
1461
|
const liveUrl = isReady ? deployment?.url ?? null : null;
|
|
1357
1462
|
return { deploymentId, deployment, isReady, liveUrl };
|
|
1358
1463
|
}
|
|
1464
|
+
async function deployProjectDirect(opts, config) {
|
|
1465
|
+
const { sourceDir, startBody = {}, spinner: spinner7 } = opts;
|
|
1466
|
+
spinner7?.start("Scanning source files...");
|
|
1467
|
+
const localFiles = await collectDeploymentFiles(sourceDir);
|
|
1468
|
+
if (localFiles.length === 0) {
|
|
1469
|
+
throw new CLIError("No deployable files found in the source directory.");
|
|
1470
|
+
}
|
|
1471
|
+
spinner7?.message("Creating deployment...");
|
|
1472
|
+
const createResult = await createDirectDeploymentSession(
|
|
1473
|
+
config,
|
|
1474
|
+
localFiles.map(({ path: relativePath, sha, size }) => ({ path: relativePath, sha, size }))
|
|
1475
|
+
);
|
|
1476
|
+
const localFileByPath = new Map(localFiles.map((file) => [file.path, file]));
|
|
1477
|
+
const pendingFiles = createResult.files.filter((file) => !file.uploadedAt);
|
|
1478
|
+
spinner7?.message(`Uploading ${pendingFiles.length} file${pendingFiles.length === 1 ? "" : "s"}...`);
|
|
1479
|
+
await runWithConcurrency(pendingFiles, DIRECT_UPLOAD_CONCURRENCY, async (manifestFile) => {
|
|
1480
|
+
const localFile = localFileByPath.get(manifestFile.path);
|
|
1481
|
+
if (!localFile) {
|
|
1482
|
+
throw new CLIError(`Backend returned an unknown file path: ${manifestFile.path}`);
|
|
1483
|
+
}
|
|
1484
|
+
if (localFile.sha !== manifestFile.sha || localFile.size !== manifestFile.size) {
|
|
1485
|
+
throw new CLIError(`Backend file metadata mismatch for: ${manifestFile.path}`);
|
|
1486
|
+
}
|
|
1487
|
+
await uploadDirectDeploymentFile(createResult.id, manifestFile, localFile);
|
|
1488
|
+
});
|
|
1489
|
+
spinner7?.message("Starting deployment...");
|
|
1490
|
+
await startDirectDeployment(createResult.id, startBody);
|
|
1491
|
+
return await pollDeployment(createResult.id, spinner7, !isInsforgeCloudOssHost(config.oss_host));
|
|
1492
|
+
}
|
|
1493
|
+
async function deployProjectLegacy(opts) {
|
|
1494
|
+
const { sourceDir, startBody = {}, spinner: spinner7 } = opts;
|
|
1495
|
+
spinner7?.message("Creating deployment...");
|
|
1496
|
+
const createRes = await ossFetch("/api/deployments", { method: "POST" });
|
|
1497
|
+
const { id: deploymentId, uploadUrl, uploadFields } = await createRes.json();
|
|
1498
|
+
spinner7?.message("Compressing source files...");
|
|
1499
|
+
const zipBuffer = await createZipBuffer(sourceDir);
|
|
1500
|
+
spinner7?.message("Uploading...");
|
|
1501
|
+
const formData = new FormData();
|
|
1502
|
+
for (const [key, value] of Object.entries(uploadFields)) {
|
|
1503
|
+
formData.append(key, value);
|
|
1504
|
+
}
|
|
1505
|
+
formData.append("file", new Blob([zipBuffer], { type: "application/zip" }), "deployment.zip");
|
|
1506
|
+
const uploadRes = await fetch(uploadUrl, { method: "POST", body: formData });
|
|
1507
|
+
if (!uploadRes.ok) {
|
|
1508
|
+
const uploadErr = await uploadRes.text();
|
|
1509
|
+
throw new CLIError(`Failed to upload: ${uploadErr}`);
|
|
1510
|
+
}
|
|
1511
|
+
spinner7?.message("Starting deployment...");
|
|
1512
|
+
const startRes = await ossFetch(`/api/deployments/${deploymentId}/start`, {
|
|
1513
|
+
method: "POST",
|
|
1514
|
+
body: JSON.stringify(startBody)
|
|
1515
|
+
});
|
|
1516
|
+
await startRes.json();
|
|
1517
|
+
return await pollDeployment(deploymentId, spinner7, false);
|
|
1518
|
+
}
|
|
1519
|
+
async function deployProject(opts) {
|
|
1520
|
+
const config = getProjectConfig();
|
|
1521
|
+
if (!config) {
|
|
1522
|
+
throw new ProjectNotLinkedError();
|
|
1523
|
+
}
|
|
1524
|
+
try {
|
|
1525
|
+
return await deployProjectDirect(opts, config);
|
|
1526
|
+
} catch (error) {
|
|
1527
|
+
if (!(error instanceof DirectDeploymentUnsupportedError)) {
|
|
1528
|
+
throw error;
|
|
1529
|
+
}
|
|
1530
|
+
opts.spinner?.message("Direct deployment is not available on this backend. Falling back to the legacy zip upload flow...");
|
|
1531
|
+
return await deployProjectLegacy(opts);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1359
1534
|
function registerDeploymentsDeployCommand(deploymentsCmd2) {
|
|
1360
|
-
deploymentsCmd2.command("deploy [directory]").description("Deploy a frontend project to Vercel").option("--env <vars>",
|
|
1535
|
+
deploymentsCmd2.command("deploy [directory]").description("Deploy a frontend project to Vercel").option("--env <vars>", 'Environment variables as JSON (e.g. {"KEY":"value"})').option("--meta <meta>", "Deployment metadata as JSON").action(async (directory, opts, cmd) => {
|
|
1361
1536
|
const { json } = getRootOpts(cmd);
|
|
1362
1537
|
try {
|
|
1363
1538
|
await requireAuth();
|
|
@@ -1370,17 +1545,24 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
|
|
|
1370
1545
|
}
|
|
1371
1546
|
const dirName = path2.basename(sourceDir);
|
|
1372
1547
|
if (EXCLUDE_PATTERNS.includes(dirName)) {
|
|
1373
|
-
throw new CLIError(
|
|
1548
|
+
throw new CLIError(
|
|
1549
|
+
`"${dirName}" is an excluded directory and cannot be used as a deploy source. Please specify your project root or output directory instead.`
|
|
1550
|
+
);
|
|
1374
1551
|
}
|
|
1375
|
-
const
|
|
1552
|
+
const spinner7 = !json ? clack6.spinner() : null;
|
|
1376
1553
|
const startBody = {};
|
|
1377
1554
|
if (opts.env) {
|
|
1378
1555
|
try {
|
|
1379
1556
|
const parsed = JSON.parse(opts.env);
|
|
1380
1557
|
if (Array.isArray(parsed)) {
|
|
1381
1558
|
startBody.envVars = parsed;
|
|
1559
|
+
} else if (parsed && typeof parsed === "object") {
|
|
1560
|
+
startBody.envVars = Object.entries(parsed).map(([key, value]) => ({
|
|
1561
|
+
key,
|
|
1562
|
+
value: String(value)
|
|
1563
|
+
}));
|
|
1382
1564
|
} else {
|
|
1383
|
-
|
|
1565
|
+
throw new CLIError("Invalid --env JSON. Expected an object or array.");
|
|
1384
1566
|
}
|
|
1385
1567
|
} catch {
|
|
1386
1568
|
throw new CLIError("Invalid --env JSON.");
|
|
@@ -1393,9 +1575,9 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
|
|
|
1393
1575
|
throw new CLIError("Invalid --meta JSON.");
|
|
1394
1576
|
}
|
|
1395
1577
|
}
|
|
1396
|
-
const result = await deployProject({ sourceDir, startBody, spinner:
|
|
1578
|
+
const result = await deployProject({ sourceDir, startBody, spinner: spinner7 });
|
|
1397
1579
|
if (result.isReady) {
|
|
1398
|
-
|
|
1580
|
+
spinner7?.stop("Deployment complete");
|
|
1399
1581
|
if (json) {
|
|
1400
1582
|
outputJson(result.deployment);
|
|
1401
1583
|
} else {
|
|
@@ -1405,9 +1587,13 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
|
|
|
1405
1587
|
clack6.log.info(`Deployment ID: ${result.deploymentId}`);
|
|
1406
1588
|
}
|
|
1407
1589
|
} else {
|
|
1408
|
-
|
|
1590
|
+
spinner7?.stop("Deployment is still building");
|
|
1409
1591
|
if (json) {
|
|
1410
|
-
outputJson({
|
|
1592
|
+
outputJson({
|
|
1593
|
+
id: result.deploymentId,
|
|
1594
|
+
status: result.deployment?.status ?? "building",
|
|
1595
|
+
timedOut: true
|
|
1596
|
+
});
|
|
1411
1597
|
} else {
|
|
1412
1598
|
clack6.log.info(`Deployment ID: ${result.deploymentId}`);
|
|
1413
1599
|
clack6.log.warn("Deployment did not finish within 5 minutes.");
|
|
@@ -2666,17 +2852,17 @@ function registerFunctionsCommands(functionsCmd2) {
|
|
|
2666
2852
|
|
|
2667
2853
|
// src/commands/functions/deploy.ts
|
|
2668
2854
|
import { readFileSync as readFileSync4, existsSync as existsSync3 } from "fs";
|
|
2669
|
-
import { join as
|
|
2855
|
+
import { join as join7 } from "path";
|
|
2670
2856
|
function registerFunctionsDeployCommand(functionsCmd2) {
|
|
2671
2857
|
functionsCmd2.command("deploy <slug>").description("Deploy an edge function (create or update)").option("--file <path>", "Path to the function source file").option("--name <name>", "Function display name").option("--description <desc>", "Function description").action(async (slug, opts, cmd) => {
|
|
2672
2858
|
const { json } = getRootOpts(cmd);
|
|
2673
2859
|
try {
|
|
2674
2860
|
await requireAuth();
|
|
2675
|
-
const filePath = opts.file ??
|
|
2861
|
+
const filePath = opts.file ?? join7(process.cwd(), "insforge", "functions", slug, "index.ts");
|
|
2676
2862
|
if (!existsSync3(filePath)) {
|
|
2677
2863
|
throw new CLIError(
|
|
2678
2864
|
`Source file not found: ${filePath}
|
|
2679
|
-
Specify --file <path> or create ${
|
|
2865
|
+
Specify --file <path> or create ${join7("insforge", "functions", slug, "index.ts")}`
|
|
2680
2866
|
);
|
|
2681
2867
|
}
|
|
2682
2868
|
const code = readFileSync4(filePath, "utf-8");
|
|
@@ -2910,7 +3096,7 @@ function registerStorageUploadCommand(storageCmd2) {
|
|
|
2910
3096
|
|
|
2911
3097
|
// src/commands/storage/download.ts
|
|
2912
3098
|
import { writeFileSync as writeFileSync3 } from "fs";
|
|
2913
|
-
import { join as
|
|
3099
|
+
import { join as join8, basename as basename6 } from "path";
|
|
2914
3100
|
function registerStorageDownloadCommand(storageCmd2) {
|
|
2915
3101
|
storageCmd2.command("download <objectKey>").description("Download a file from a storage bucket").requiredOption("--bucket <name>", "Source bucket name").option("--output <path>", "Output file path (defaults to current directory)").action(async (objectKey, opts, cmd) => {
|
|
2916
3102
|
const { json } = getRootOpts(cmd);
|
|
@@ -2930,7 +3116,7 @@ function registerStorageDownloadCommand(storageCmd2) {
|
|
|
2930
3116
|
throw new CLIError(err.error ?? `Download failed: ${res.status}`);
|
|
2931
3117
|
}
|
|
2932
3118
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
2933
|
-
const outputPath = opts.output ??
|
|
3119
|
+
const outputPath = opts.output ?? join8(process.cwd(), basename6(objectKey));
|
|
2934
3120
|
writeFileSync3(outputPath, buffer);
|
|
2935
3121
|
if (json) {
|
|
2936
3122
|
outputJson({ success: true, path: outputPath, size: buffer.length });
|
|
@@ -4038,10 +4224,10 @@ function registerComputeLogsCommand(computeCmd2) {
|
|
|
4038
4224
|
|
|
4039
4225
|
// src/commands/compute/deploy.ts
|
|
4040
4226
|
import { existsSync as existsSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, renameSync } from "fs";
|
|
4041
|
-
import { join as
|
|
4227
|
+
import { join as join9 } from "path";
|
|
4042
4228
|
import { execSync, spawn } from "child_process";
|
|
4043
4229
|
function parseFlyToml(dir) {
|
|
4044
|
-
const tomlPath =
|
|
4230
|
+
const tomlPath = join9(dir, "fly.toml");
|
|
4045
4231
|
if (!existsSync5(tomlPath)) return {};
|
|
4046
4232
|
const content = readFileSync6(tomlPath, "utf-8");
|
|
4047
4233
|
const config = {};
|
|
@@ -4113,7 +4299,7 @@ function registerComputeDeployCommand(computeCmd2) {
|
|
|
4113
4299
|
checkFlyctl();
|
|
4114
4300
|
const flyToken = getFlyToken();
|
|
4115
4301
|
const dir = directory ?? process.cwd();
|
|
4116
|
-
const dockerfilePath =
|
|
4302
|
+
const dockerfilePath = join9(dir, "Dockerfile");
|
|
4117
4303
|
if (!existsSync5(dockerfilePath)) {
|
|
4118
4304
|
throw new CLIError(`No Dockerfile found in ${dir}`);
|
|
4119
4305
|
}
|
|
@@ -4159,8 +4345,8 @@ function registerComputeDeployCommand(computeCmd2) {
|
|
|
4159
4345
|
serviceId = service.id;
|
|
4160
4346
|
flyAppId = service.flyAppId;
|
|
4161
4347
|
}
|
|
4162
|
-
const existingTomlPath =
|
|
4163
|
-
const backupTomlPath =
|
|
4348
|
+
const existingTomlPath = join9(dir, "fly.toml");
|
|
4349
|
+
const backupTomlPath = join9(dir, "fly.toml.insforge-backup");
|
|
4164
4350
|
let hadExistingToml = false;
|
|
4165
4351
|
if (existsSync5(existingTomlPath)) {
|
|
4166
4352
|
hadExistingToml = true;
|
|
@@ -4888,7 +5074,7 @@ function registerDiagnoseCommands(diagnoseCmd2) {
|
|
|
4888
5074
|
const s = !json ? clack10.spinner() : null;
|
|
4889
5075
|
s?.start("Collecting diagnostic data...");
|
|
4890
5076
|
const data2 = await collectDiagnosticData(projectId, ossMode, apiUrl);
|
|
4891
|
-
const cliVersion = "0.1.
|
|
5077
|
+
const cliVersion = "0.1.51";
|
|
4892
5078
|
s?.stop("Data collected");
|
|
4893
5079
|
if (!json) {
|
|
4894
5080
|
console.log(`
|
|
@@ -5116,7 +5302,7 @@ function formatBytesCompact(bytes) {
|
|
|
5116
5302
|
|
|
5117
5303
|
// src/index.ts
|
|
5118
5304
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5119
|
-
var pkg = JSON.parse(readFileSync7(
|
|
5305
|
+
var pkg = JSON.parse(readFileSync7(join10(__dirname, "../package.json"), "utf-8"));
|
|
5120
5306
|
var INSFORGE_LOGO = `
|
|
5121
5307
|
\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
5122
5308
|
\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
|