@zerodeploy/cli 0.1.13 → 0.1.15
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/README.md +44 -584
- package/dist/cli.js +155 -17
- package/package.json +1 -1
- package/dist/index.js +0 -6915
package/dist/cli.js
CHANGED
|
@@ -4977,8 +4977,7 @@ var usageCommand = new Command2("usage").description("Show current usage and lim
|
|
|
4977
4977
|
}
|
|
4978
4978
|
console.log();
|
|
4979
4979
|
console.log("Account Usage:");
|
|
4980
|
-
console.log(formatUsageLine("
|
|
4981
|
-
console.log(formatUsageLine("Total Sites", data.usage.sites, data.limits.max_orgs * data.limits.max_sites_per_org));
|
|
4980
|
+
console.log(formatUsageLine("Total Sites", data.usage.sites, data.limits.max_sites_per_org));
|
|
4982
4981
|
console.log(formatUsageLine("Deployments (month)", data.usage.deployments_this_month, data.limits.max_deployments_per_month));
|
|
4983
4982
|
console.log();
|
|
4984
4983
|
console.log("Limits:");
|
|
@@ -7086,7 +7085,7 @@ var deployPromoteCommand = new Command2("promote").description("Promote a previe
|
|
|
7086
7085
|
});
|
|
7087
7086
|
|
|
7088
7087
|
// src/lib/version.ts
|
|
7089
|
-
var VERSION = "0.1.
|
|
7088
|
+
var VERSION = "0.1.15";
|
|
7090
7089
|
|
|
7091
7090
|
// src/commands/deploy/index.ts
|
|
7092
7091
|
function slugify(input) {
|
|
@@ -7544,6 +7543,7 @@ Error: Build failed`);
|
|
|
7544
7543
|
body: JSON.stringify({ preview: isPreview, mode: options.append ? "append" : "replace" })
|
|
7545
7544
|
}, {
|
|
7546
7545
|
maxRetries: 3,
|
|
7546
|
+
timeoutMs: 120000,
|
|
7547
7547
|
onRetry: (attempt, error, delayMs) => {
|
|
7548
7548
|
finalizeSpinner.update(`Finalizing... ${formatRetryMessage(attempt, 3, error)}, retrying in ${Math.round(delayMs / 1000)}s`);
|
|
7549
7549
|
}
|
|
@@ -7819,8 +7819,77 @@ var deploymentsShowCommand = new Command2("show").description("View deployment d
|
|
|
7819
7819
|
}
|
|
7820
7820
|
});
|
|
7821
7821
|
|
|
7822
|
+
// src/commands/deployments/logs.ts
|
|
7823
|
+
function colorLevel(level) {
|
|
7824
|
+
switch (level) {
|
|
7825
|
+
case "error":
|
|
7826
|
+
return `\x1B[31m${level}\x1B[0m`;
|
|
7827
|
+
case "warn":
|
|
7828
|
+
return `\x1B[33m${level}\x1B[0m`;
|
|
7829
|
+
case "info":
|
|
7830
|
+
return `\x1B[36m${level}\x1B[0m`;
|
|
7831
|
+
default:
|
|
7832
|
+
return level;
|
|
7833
|
+
}
|
|
7834
|
+
}
|
|
7835
|
+
function formatTime(timestamp) {
|
|
7836
|
+
const d = new Date(timestamp);
|
|
7837
|
+
return d.toLocaleTimeString(undefined, { hour12: false, fractionalSecondDigits: 3 });
|
|
7838
|
+
}
|
|
7839
|
+
var deploymentsLogsCommand = new Command2("logs").description("View deployment finalize logs").argument("<id>", "Deployment ID (full or short)").option("--json", "Output as JSON").action(async (id, options) => {
|
|
7840
|
+
const token = loadToken();
|
|
7841
|
+
if (!token) {
|
|
7842
|
+
handleAuthError();
|
|
7843
|
+
}
|
|
7844
|
+
try {
|
|
7845
|
+
const client = getClient(token);
|
|
7846
|
+
const res = await client.deployments[":id"].logs.$get({
|
|
7847
|
+
param: { id }
|
|
7848
|
+
});
|
|
7849
|
+
if (!res.ok) {
|
|
7850
|
+
if (res.status === 404) {
|
|
7851
|
+
displayError({
|
|
7852
|
+
code: "not_found",
|
|
7853
|
+
message: `Deployment not found: ${id}`,
|
|
7854
|
+
hint: "Use the full deployment ID or at least 8 characters."
|
|
7855
|
+
});
|
|
7856
|
+
process.exit(ExitCode.NOT_FOUND);
|
|
7857
|
+
}
|
|
7858
|
+
await handleApiError(res);
|
|
7859
|
+
}
|
|
7860
|
+
const { data: entries } = await res.json();
|
|
7861
|
+
if (options.json) {
|
|
7862
|
+
console.log(JSON.stringify(entries, null, 2));
|
|
7863
|
+
return;
|
|
7864
|
+
}
|
|
7865
|
+
if (entries.length === 0) {
|
|
7866
|
+
console.log("No logs available for this deployment.");
|
|
7867
|
+
console.log("Logs are only available for deployments created after this feature was enabled.");
|
|
7868
|
+
return;
|
|
7869
|
+
}
|
|
7870
|
+
console.log("Deployment Logs");
|
|
7871
|
+
console.log("=".repeat(60));
|
|
7872
|
+
console.log();
|
|
7873
|
+
for (const entry of entries) {
|
|
7874
|
+
const time = formatTime(entry.timestamp);
|
|
7875
|
+
const level = colorLevel(entry.level);
|
|
7876
|
+
const phase = `\x1B[90m[${entry.phase}]\x1B[0m`;
|
|
7877
|
+
const duration = entry.duration_ms !== undefined ? ` \x1B[90m(${entry.duration_ms}ms)\x1B[0m` : "";
|
|
7878
|
+
console.log(`${time} ${level} ${phase} ${entry.message}${duration}`);
|
|
7879
|
+
if (entry.metadata && Object.keys(entry.metadata).length > 0) {
|
|
7880
|
+
const meta = Object.entries(entry.metadata).map(([k, v]) => `${k}=${v}`).join(" ");
|
|
7881
|
+
console.log(` \x1B[90m${meta}\x1B[0m`);
|
|
7882
|
+
}
|
|
7883
|
+
}
|
|
7884
|
+
} catch (err) {
|
|
7885
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7886
|
+
displayError({ code: "network_error", message: `Failed to get deployment logs: ${message}` });
|
|
7887
|
+
process.exit(ExitCode.NETWORK_ERROR);
|
|
7888
|
+
}
|
|
7889
|
+
});
|
|
7890
|
+
|
|
7822
7891
|
// src/commands/deployments/index.ts
|
|
7823
|
-
var deploymentsCommand = new Command2("deployments").description("Manage deployments").addCommand(deploymentsListCommand).addCommand(deploymentsShowCommand);
|
|
7892
|
+
var deploymentsCommand = new Command2("deployments").description("Manage deployments").addCommand(deploymentsListCommand).addCommand(deploymentsShowCommand).addCommand(deploymentsLogsCommand);
|
|
7824
7893
|
|
|
7825
7894
|
// src/commands/rollback.ts
|
|
7826
7895
|
var rollbackCommand = new Command2("rollback").description("Rollback a site to a previous deployment").argument("<site>", "Site slug").requiredOption("--org <org>", "Organization slug").option("--to <deploymentId>", "Deployment ID to rollback to (defaults to previous deployment)").action(async (site, options) => {
|
|
@@ -8543,11 +8612,10 @@ function createInspectCommand(rootProgram) {
|
|
|
8543
8612
|
});
|
|
8544
8613
|
}
|
|
8545
8614
|
|
|
8546
|
-
// src/
|
|
8547
|
-
|
|
8615
|
+
// src/commands/update.ts
|
|
8616
|
+
import { execSync } from "child_process";
|
|
8548
8617
|
|
|
8549
8618
|
// src/lib/update-check.ts
|
|
8550
|
-
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
8551
8619
|
import { homedir } from "os";
|
|
8552
8620
|
import { join as join2 } from "path";
|
|
8553
8621
|
var PACKAGE_NAME = "@zerodeploy/cli";
|
|
@@ -8566,11 +8634,80 @@ function compareVersions(current, latest) {
|
|
|
8566
8634
|
}
|
|
8567
8635
|
return 0;
|
|
8568
8636
|
}
|
|
8637
|
+
async function fetchLatestVersion() {
|
|
8638
|
+
try {
|
|
8639
|
+
const controller = new AbortController;
|
|
8640
|
+
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
8641
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
|
|
8642
|
+
signal: controller.signal,
|
|
8643
|
+
headers: { Accept: "application/json" }
|
|
8644
|
+
});
|
|
8645
|
+
clearTimeout(timeout);
|
|
8646
|
+
if (!res.ok)
|
|
8647
|
+
return null;
|
|
8648
|
+
const data = await res.json();
|
|
8649
|
+
return data.version || null;
|
|
8650
|
+
} catch {
|
|
8651
|
+
return null;
|
|
8652
|
+
}
|
|
8653
|
+
}
|
|
8654
|
+
|
|
8655
|
+
// src/commands/update.ts
|
|
8656
|
+
var updateCommand = new Command2("update").description("Update ZeroDeploy CLI to the latest version").action(async () => {
|
|
8657
|
+
console.log(`Current version: ${VERSION}`);
|
|
8658
|
+
console.log("Checking for updates...");
|
|
8659
|
+
const latest = await fetchLatestVersion();
|
|
8660
|
+
if (!latest) {
|
|
8661
|
+
console.error("Failed to check for updates. Please try again later.");
|
|
8662
|
+
process.exit(6);
|
|
8663
|
+
}
|
|
8664
|
+
if (compareVersions(VERSION, latest) >= 0) {
|
|
8665
|
+
console.log(`Already up to date (${VERSION}).`);
|
|
8666
|
+
return;
|
|
8667
|
+
}
|
|
8668
|
+
console.log(`New version available: ${latest}`);
|
|
8669
|
+
console.log(`Updating...
|
|
8670
|
+
`);
|
|
8671
|
+
try {
|
|
8672
|
+
execSync("npm update -g @zerodeploy/cli", { stdio: "inherit" });
|
|
8673
|
+
console.log(`
|
|
8674
|
+
Updated to ${latest}.`);
|
|
8675
|
+
} catch {
|
|
8676
|
+
console.error(`
|
|
8677
|
+
Update failed. Try manually:`);
|
|
8678
|
+
console.error(" npm update -g @zerodeploy/cli");
|
|
8679
|
+
process.exit(1);
|
|
8680
|
+
}
|
|
8681
|
+
});
|
|
8682
|
+
|
|
8683
|
+
// src/lib/version.ts
|
|
8684
|
+
var VERSION2 = "0.1.15";
|
|
8685
|
+
|
|
8686
|
+
// src/lib/update-check.ts
|
|
8687
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
8688
|
+
import { homedir as homedir2 } from "os";
|
|
8689
|
+
import { join as join3 } from "path";
|
|
8690
|
+
var PACKAGE_NAME2 = "@zerodeploy/cli";
|
|
8691
|
+
var CACHE_FILE2 = join3(homedir2(), ".zerodeploy", "update-check.json");
|
|
8692
|
+
var CACHE_TTL_MS2 = 24 * 60 * 60 * 1000;
|
|
8693
|
+
function compareVersions2(current, latest) {
|
|
8694
|
+
const currentParts = current.split(".").map(Number);
|
|
8695
|
+
const latestParts = latest.split(".").map(Number);
|
|
8696
|
+
for (let i2 = 0;i2 < Math.max(currentParts.length, latestParts.length); i2++) {
|
|
8697
|
+
const a = currentParts[i2] || 0;
|
|
8698
|
+
const b = latestParts[i2] || 0;
|
|
8699
|
+
if (a < b)
|
|
8700
|
+
return -1;
|
|
8701
|
+
if (a > b)
|
|
8702
|
+
return 1;
|
|
8703
|
+
}
|
|
8704
|
+
return 0;
|
|
8705
|
+
}
|
|
8569
8706
|
function readCache() {
|
|
8570
8707
|
try {
|
|
8571
|
-
if (!existsSync3(
|
|
8708
|
+
if (!existsSync3(CACHE_FILE2))
|
|
8572
8709
|
return null;
|
|
8573
|
-
const data = JSON.parse(readFileSync2(
|
|
8710
|
+
const data = JSON.parse(readFileSync2(CACHE_FILE2, "utf-8"));
|
|
8574
8711
|
if (typeof data.latestVersion !== "string" || typeof data.checkedAt !== "number") {
|
|
8575
8712
|
return null;
|
|
8576
8713
|
}
|
|
@@ -8581,18 +8718,18 @@ function readCache() {
|
|
|
8581
8718
|
}
|
|
8582
8719
|
function writeCache(cache) {
|
|
8583
8720
|
try {
|
|
8584
|
-
const dir =
|
|
8721
|
+
const dir = join3(homedir2(), ".zerodeploy");
|
|
8585
8722
|
if (!existsSync3(dir)) {
|
|
8586
8723
|
mkdirSync(dir, { recursive: true });
|
|
8587
8724
|
}
|
|
8588
|
-
writeFileSync2(
|
|
8725
|
+
writeFileSync2(CACHE_FILE2, JSON.stringify(cache), "utf-8");
|
|
8589
8726
|
} catch {}
|
|
8590
8727
|
}
|
|
8591
|
-
async function
|
|
8728
|
+
async function fetchLatestVersion2() {
|
|
8592
8729
|
try {
|
|
8593
8730
|
const controller = new AbortController;
|
|
8594
8731
|
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
8595
|
-
const res = await fetch(`https://registry.npmjs.org/${
|
|
8732
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME2}/latest`, {
|
|
8596
8733
|
signal: controller.signal,
|
|
8597
8734
|
headers: { Accept: "application/json" }
|
|
8598
8735
|
});
|
|
@@ -8613,10 +8750,10 @@ async function checkForUpdates() {
|
|
|
8613
8750
|
const cache = readCache();
|
|
8614
8751
|
const now = Date.now();
|
|
8615
8752
|
let latestVersion = null;
|
|
8616
|
-
if (cache && now - cache.checkedAt <
|
|
8753
|
+
if (cache && now - cache.checkedAt < CACHE_TTL_MS2) {
|
|
8617
8754
|
latestVersion = cache.latestVersion;
|
|
8618
8755
|
} else {
|
|
8619
|
-
latestVersion = await
|
|
8756
|
+
latestVersion = await fetchLatestVersion2();
|
|
8620
8757
|
if (latestVersion) {
|
|
8621
8758
|
writeCache({ latestVersion, checkedAt: now });
|
|
8622
8759
|
} else if (cache) {
|
|
@@ -8625,14 +8762,14 @@ async function checkForUpdates() {
|
|
|
8625
8762
|
}
|
|
8626
8763
|
if (!latestVersion)
|
|
8627
8764
|
return;
|
|
8628
|
-
if (
|
|
8765
|
+
if (compareVersions2(VERSION, latestVersion) < 0) {
|
|
8629
8766
|
printUpdateBanner(latestVersion);
|
|
8630
8767
|
}
|
|
8631
8768
|
} catch {}
|
|
8632
8769
|
}
|
|
8633
8770
|
function printUpdateBanner(latestVersion) {
|
|
8634
8771
|
const message = `Update available: ${VERSION} → ${latestVersion}`;
|
|
8635
|
-
const command = "Run `
|
|
8772
|
+
const command = "Run `zerodeploy update` to update";
|
|
8636
8773
|
const width = Math.max(message.length, command.length) + 4;
|
|
8637
8774
|
const top = "╭" + "─".repeat(width) + "╮";
|
|
8638
8775
|
const bottom = "╰" + "─".repeat(width) + "╯";
|
|
@@ -8662,6 +8799,7 @@ program3.addCommand(tokenCommand);
|
|
|
8662
8799
|
program3.addCommand(billingCommand);
|
|
8663
8800
|
program3.addCommand(initCommand);
|
|
8664
8801
|
program3.addCommand(accountCommand);
|
|
8802
|
+
program3.addCommand(updateCommand);
|
|
8665
8803
|
program3.addCommand(createInspectCommand(program3));
|
|
8666
8804
|
await program3.parseAsync(process.argv);
|
|
8667
8805
|
await checkForUpdates();
|