@lizard-build/cli 0.1.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/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.js +72 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/connect.d.ts +2 -0
- package/dist/commands/connect.js +117 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/context.d.ts +2 -0
- package/dist/commands/context.js +71 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/deploy.d.ts +2 -0
- package/dist/commands/deploy.js +120 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/destroy.d.ts +2 -0
- package/dist/commands/destroy.js +51 -0
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/git.d.ts +2 -0
- package/dist/commands/git.js +67 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +107 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/link.d.ts +2 -0
- package/dist/commands/link.js +50 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/login.d.ts +7 -0
- package/dist/commands/login.js +123 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.js +17 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +92 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/open.d.ts +2 -0
- package/dist/commands/open.js +16 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/projects.d.ts +2 -0
- package/dist/commands/projects.js +28 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/ps.d.ts +2 -0
- package/dist/commands/ps.js +52 -0
- package/dist/commands/ps.js.map +1 -0
- package/dist/commands/redeploy.d.ts +2 -0
- package/dist/commands/redeploy.js +69 -0
- package/dist/commands/redeploy.js.map +1 -0
- package/dist/commands/regions.d.ts +2 -0
- package/dist/commands/regions.js +23 -0
- package/dist/commands/regions.js.map +1 -0
- package/dist/commands/restart.d.ts +2 -0
- package/dist/commands/restart.js +21 -0
- package/dist/commands/restart.js.map +1 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +33 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/secrets.d.ts +2 -0
- package/dist/commands/secrets.js +138 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +51 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.js +41 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/version.d.ts +2 -0
- package/dist/commands/version.js +37 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +21 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +151 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +19 -0
- package/dist/lib/api.js +114 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +23 -0
- package/dist/lib/auth.js +89 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +23 -0
- package/dist/lib/config.js +77 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/format.d.ts +11 -0
- package/dist/lib/format.js +86 -0
- package/dist/lib/format.js.map +1 -0
- package/install.sh +59 -0
- package/package.json +35 -0
- package/src/commands/add.ts +100 -0
- package/src/commands/connect.ts +145 -0
- package/src/commands/context.ts +93 -0
- package/src/commands/deploy.ts +153 -0
- package/src/commands/destroy.ts +51 -0
- package/src/commands/git.ts +80 -0
- package/src/commands/init.ts +139 -0
- package/src/commands/link.ts +63 -0
- package/src/commands/login.ts +158 -0
- package/src/commands/logout.ts +17 -0
- package/src/commands/logs.ts +104 -0
- package/src/commands/open.ts +17 -0
- package/src/commands/projects.ts +45 -0
- package/src/commands/ps.ts +80 -0
- package/src/commands/redeploy.ts +74 -0
- package/src/commands/regions.ts +38 -0
- package/src/commands/restart.ts +24 -0
- package/src/commands/run.ts +43 -0
- package/src/commands/secrets.ts +175 -0
- package/src/commands/status.ts +65 -0
- package/src/commands/update.ts +44 -0
- package/src/commands/version.ts +37 -0
- package/src/commands/whoami.ts +27 -0
- package/src/index.ts +168 -0
- package/src/lib/api.ts +134 -0
- package/src/lib/auth.ts +113 -0
- package/src/lib/config.ts +93 -0
- package/src/lib/format.ts +95 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import { api } from "../lib/api.js";
|
|
6
|
+
import { findProjectConfig, saveProjectConfig, } from "../lib/config.js";
|
|
7
|
+
import { success, info, isJSONMode, printJSON, isTTY, } from "../lib/format.js";
|
|
8
|
+
/** Detect framework from files in cwd */
|
|
9
|
+
function detectFramework() {
|
|
10
|
+
const cwd = process.cwd();
|
|
11
|
+
const has = (f) => fs.existsSync(path.join(cwd, f));
|
|
12
|
+
if (has("next.config.js") || has("next.config.mjs") || has("next.config.ts"))
|
|
13
|
+
return { name: "Next.js", port: 3000, buildCmd: "npm run build", startCmd: "npm start" };
|
|
14
|
+
if (has("nuxt.config.ts") || has("nuxt.config.js"))
|
|
15
|
+
return { name: "Nuxt", port: 3000, buildCmd: "npm run build", startCmd: "npm start" };
|
|
16
|
+
if (has("remix.config.js") || has("remix.config.ts"))
|
|
17
|
+
return { name: "Remix", port: 3000, buildCmd: "npm run build", startCmd: "npm start" };
|
|
18
|
+
if (has("astro.config.mjs") || has("astro.config.ts"))
|
|
19
|
+
return { name: "Astro", port: 4321, buildCmd: "npm run build", startCmd: "npm start" };
|
|
20
|
+
if (has("vite.config.ts") || has("vite.config.js"))
|
|
21
|
+
return { name: "Vite", port: 3000, buildCmd: "npm run build", startCmd: "npm run preview" };
|
|
22
|
+
if (has("Dockerfile"))
|
|
23
|
+
return { name: "Docker", port: 8080, buildCmd: "", startCmd: "" };
|
|
24
|
+
if (has("go.mod"))
|
|
25
|
+
return { name: "Go", port: 8080, buildCmd: "go build -o app .", startCmd: "./app" };
|
|
26
|
+
if (has("requirements.txt") || has("pyproject.toml"))
|
|
27
|
+
return { name: "Python", port: 8000, buildCmd: "pip install -r requirements.txt", startCmd: "python app.py" };
|
|
28
|
+
if (has("package.json"))
|
|
29
|
+
return { name: "Node.js", port: 3000, buildCmd: "npm run build", startCmd: "npm start" };
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function writeLizardToml(framework) {
|
|
33
|
+
const port = framework?.port ?? 3000;
|
|
34
|
+
const build = framework?.buildCmd ?? "";
|
|
35
|
+
const start = framework?.startCmd ?? "";
|
|
36
|
+
let toml = `# lizard.toml\n\n`;
|
|
37
|
+
if (build)
|
|
38
|
+
toml += `[build]\ncommand = "${build}"\n\n`;
|
|
39
|
+
toml += `[deploy]\nport = ${port}\n`;
|
|
40
|
+
if (start)
|
|
41
|
+
toml += `start_command = "${start}"\n`;
|
|
42
|
+
toml += `\n[resources]\ncpu = 1\nmemory = 512\n`;
|
|
43
|
+
const tomlPath = path.join(process.cwd(), "lizard.toml");
|
|
44
|
+
if (!fs.existsSync(tomlPath)) {
|
|
45
|
+
fs.writeFileSync(tomlPath, toml);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function registerInit(program) {
|
|
49
|
+
program
|
|
50
|
+
.command("init")
|
|
51
|
+
.description("Create a new project and link current directory")
|
|
52
|
+
.option("--name <name>", "Project name")
|
|
53
|
+
.action(async (opts) => {
|
|
54
|
+
// Check if already initialized
|
|
55
|
+
const existing = findProjectConfig();
|
|
56
|
+
if (existing) {
|
|
57
|
+
throw new Error("Already initialized. Run `lizard link` to change project.");
|
|
58
|
+
}
|
|
59
|
+
// Detect framework
|
|
60
|
+
const framework = detectFramework();
|
|
61
|
+
if (framework && !isJSONMode()) {
|
|
62
|
+
info(`Detected framework: ${chalk.cyan(framework.name)}`);
|
|
63
|
+
}
|
|
64
|
+
// Get project name
|
|
65
|
+
let projectName = opts.name;
|
|
66
|
+
if (!projectName) {
|
|
67
|
+
if (!isTTY()) {
|
|
68
|
+
throw new Error("--name is required in non-interactive mode");
|
|
69
|
+
}
|
|
70
|
+
const result = await p.text({
|
|
71
|
+
message: "Project name",
|
|
72
|
+
defaultValue: path.basename(process.cwd()),
|
|
73
|
+
placeholder: path.basename(process.cwd()),
|
|
74
|
+
});
|
|
75
|
+
if (p.isCancel(result))
|
|
76
|
+
process.exit(5);
|
|
77
|
+
projectName = result;
|
|
78
|
+
}
|
|
79
|
+
// Create project via API
|
|
80
|
+
const project = await api.post("/api/projects", {
|
|
81
|
+
name: projectName,
|
|
82
|
+
});
|
|
83
|
+
// Save local config
|
|
84
|
+
saveProjectConfig({
|
|
85
|
+
projectId: project.id,
|
|
86
|
+
projectName: project.name,
|
|
87
|
+
});
|
|
88
|
+
// Write lizard.toml
|
|
89
|
+
writeLizardToml(framework);
|
|
90
|
+
if (isJSONMode()) {
|
|
91
|
+
printJSON({
|
|
92
|
+
projectId: project.id,
|
|
93
|
+
name: project.name,
|
|
94
|
+
framework: framework?.name,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
success(`Project "${chalk.bold(project.name)}" created`);
|
|
99
|
+
info(chalk.dim(" Linked to current directory"));
|
|
100
|
+
info(chalk.dim(" Config saved to .lizard/config.json"));
|
|
101
|
+
if (framework) {
|
|
102
|
+
info(chalk.dim(` lizard.toml created for ${framework.name}`));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
|
+
import { api } from "../lib/api.js";
|
|
4
|
+
import { saveProjectConfig, findProjectConfig } from "../lib/config.js";
|
|
5
|
+
import { success, isJSONMode, printJSON, isTTY } from "../lib/format.js";
|
|
6
|
+
export function registerLink(program) {
|
|
7
|
+
program
|
|
8
|
+
.command("link")
|
|
9
|
+
.description("Link current directory to an existing project")
|
|
10
|
+
.option("--project <id>", "Project ID")
|
|
11
|
+
.action(async (opts) => {
|
|
12
|
+
let projectId = opts.project;
|
|
13
|
+
let projectName;
|
|
14
|
+
if (!projectId) {
|
|
15
|
+
// Fetch projects and let user pick
|
|
16
|
+
const projects = await api.get("/api/projects");
|
|
17
|
+
if (projects.length === 0) {
|
|
18
|
+
throw new Error("No projects found. Run `lizard init` to create one.");
|
|
19
|
+
}
|
|
20
|
+
if (!isTTY()) {
|
|
21
|
+
throw new Error("Use --project <id> in non-interactive mode. Available: " +
|
|
22
|
+
projects.map((p) => `${p.name} (${p.id})`).join(", "));
|
|
23
|
+
}
|
|
24
|
+
const selected = await p.select({
|
|
25
|
+
message: "Select project",
|
|
26
|
+
options: projects.map((proj) => ({
|
|
27
|
+
value: proj.id,
|
|
28
|
+
label: proj.name,
|
|
29
|
+
hint: proj.id,
|
|
30
|
+
})),
|
|
31
|
+
});
|
|
32
|
+
if (p.isCancel(selected))
|
|
33
|
+
process.exit(5);
|
|
34
|
+
projectId = selected;
|
|
35
|
+
projectName = projects.find((p) => p.id === projectId)?.name;
|
|
36
|
+
}
|
|
37
|
+
const old = findProjectConfig();
|
|
38
|
+
saveProjectConfig({ projectId, projectName });
|
|
39
|
+
if (isJSONMode()) {
|
|
40
|
+
printJSON({ projectId, projectName });
|
|
41
|
+
}
|
|
42
|
+
else if (old?.projectId && old.projectId !== projectId) {
|
|
43
|
+
success(`Relinked to ${chalk.bold(projectName || projectId)} (was ${old.projectName || old.projectId})`);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
success(`Linked to ${chalk.bold(projectName || projectId)}`);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAQzE,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,gBAAgB,EAAE,YAAY,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,WAA+B,CAAC;QAEpC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,mCAAmC;YACnC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,GAAG,CAAY,eAAe,CAAC,CAAC;YAC3D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACzE,CAAC;YAED,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,yDAAyD;oBACvD,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACxD,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC;gBAC9B,OAAO,EAAE,gBAAgB;gBACzB,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBAC/B,KAAK,EAAE,IAAI,CAAC,EAAE;oBACd,KAAK,EAAE,IAAI,CAAC,IAAI;oBAChB,IAAI,EAAE,IAAI,CAAC,EAAE;iBACd,CAAC,CAAC;aACJ,CAAC,CAAC;YACH,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC1C,SAAS,GAAG,QAAkB,CAAC;YAC/B,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,IAAI,CAAC;QAC/D,CAAC;QAED,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,iBAAiB,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QAE9C,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QACxC,CAAC;aAAM,IAAI,GAAG,EAAE,SAAS,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACzD,OAAO,CACL,eAAe,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC,SAAS,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,SAAS,GAAG,CAChG,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,aAAa,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { type Credentials } from "../lib/auth.js";
|
|
3
|
+
/**
|
|
4
|
+
* Perform the login flow. Used by the login command and by auto-login in requireAuth.
|
|
5
|
+
*/
|
|
6
|
+
export declare function performLogin(): Promise<Credentials>;
|
|
7
|
+
export declare function registerLogin(program: Command): void;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { saveCredentials, openURL, } from "../lib/auth.js";
|
|
4
|
+
import { getBaseURL } from "../lib/api.js";
|
|
5
|
+
import { success, info, isJSONMode, printJSON } from "../lib/format.js";
|
|
6
|
+
const POLL_INTERVAL = 2000;
|
|
7
|
+
const SESSION_TIMEOUT = 300_000; // 5 min
|
|
8
|
+
/** Create a CLI login session on the server */
|
|
9
|
+
async function createSession() {
|
|
10
|
+
const res = await fetch(`${getBaseURL()}/api/auth/cli/session`, {
|
|
11
|
+
method: "POST",
|
|
12
|
+
headers: { "Content-Type": "application/json" },
|
|
13
|
+
});
|
|
14
|
+
if (!res.ok) {
|
|
15
|
+
throw new Error(`Failed to create login session: ${res.statusText}`);
|
|
16
|
+
}
|
|
17
|
+
return res.json();
|
|
18
|
+
}
|
|
19
|
+
/** Poll the server to check if the user completed login */
|
|
20
|
+
async function pollSession(sessionId, sessionSecret) {
|
|
21
|
+
const res = await fetch(`${getBaseURL()}/api/auth/cli/poll`, {
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: { "Content-Type": "application/json" },
|
|
24
|
+
body: JSON.stringify({ sessionId, sessionSecret }),
|
|
25
|
+
});
|
|
26
|
+
if (!res.ok) {
|
|
27
|
+
throw new Error(`Poll failed: ${res.statusText}`);
|
|
28
|
+
}
|
|
29
|
+
return res.json();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Perform the login flow. Used by the login command and by auto-login in requireAuth.
|
|
33
|
+
*/
|
|
34
|
+
export async function performLogin() {
|
|
35
|
+
// 1. Create session
|
|
36
|
+
const session = await createSession();
|
|
37
|
+
const loginURL = `${getBaseURL()}/auth/cli?session=${session.sessionId}`;
|
|
38
|
+
// 2. Try to open browser
|
|
39
|
+
const opened = await openURL(loginURL);
|
|
40
|
+
if (opened) {
|
|
41
|
+
info("Opening browser to log in...");
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
info(`Open this URL in your browser to log in:\n ${chalk.cyan(loginURL)}`);
|
|
45
|
+
}
|
|
46
|
+
// 3. Poll until complete
|
|
47
|
+
const spinner = ora("Waiting for login...").start();
|
|
48
|
+
const deadline = Date.now() + SESSION_TIMEOUT;
|
|
49
|
+
while (Date.now() < deadline) {
|
|
50
|
+
await sleep(POLL_INTERVAL);
|
|
51
|
+
try {
|
|
52
|
+
const result = await pollSession(session.sessionId, session.sessionSecret);
|
|
53
|
+
if (result.status === "complete" && result.accessToken && result.user) {
|
|
54
|
+
spinner.stop();
|
|
55
|
+
const creds = {
|
|
56
|
+
accessToken: result.accessToken,
|
|
57
|
+
refreshToken: result.refreshToken,
|
|
58
|
+
userId: result.user.id,
|
|
59
|
+
username: result.user.username,
|
|
60
|
+
email: result.user.email,
|
|
61
|
+
avatarUrl: result.user.avatarUrl,
|
|
62
|
+
};
|
|
63
|
+
saveCredentials(creds);
|
|
64
|
+
if (isJSONMode()) {
|
|
65
|
+
printJSON({ username: creds.username, email: creds.email });
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
success(`Logged in as ${chalk.bold(creds.username)}`);
|
|
69
|
+
}
|
|
70
|
+
return creds;
|
|
71
|
+
}
|
|
72
|
+
if (result.status === "expired") {
|
|
73
|
+
spinner.stop();
|
|
74
|
+
throw new Error("Login session expired. Please try again.");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
if (err.message?.includes("expired")) {
|
|
79
|
+
spinner.stop();
|
|
80
|
+
throw err;
|
|
81
|
+
}
|
|
82
|
+
// Network error — keep trying
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
spinner.stop();
|
|
86
|
+
throw new Error("Login timed out. Please try again.");
|
|
87
|
+
}
|
|
88
|
+
function sleep(ms) {
|
|
89
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
90
|
+
}
|
|
91
|
+
export function registerLogin(program) {
|
|
92
|
+
program
|
|
93
|
+
.command("login")
|
|
94
|
+
.description("Log in to Lizard")
|
|
95
|
+
.option("--token <token>", "Authenticate with an API token")
|
|
96
|
+
.action(async (opts) => {
|
|
97
|
+
if (opts.token) {
|
|
98
|
+
// Direct token auth — validate it
|
|
99
|
+
const res = await fetch(`${getBaseURL()}/api/auth/me`, {
|
|
100
|
+
headers: { Authorization: `Bearer ${opts.token}` },
|
|
101
|
+
});
|
|
102
|
+
if (!res.ok)
|
|
103
|
+
throw new Error("Invalid token");
|
|
104
|
+
const user = (await res.json());
|
|
105
|
+
saveCredentials({
|
|
106
|
+
accessToken: opts.token,
|
|
107
|
+
userId: user.id,
|
|
108
|
+
username: user.username,
|
|
109
|
+
email: user.email,
|
|
110
|
+
avatarUrl: user.avatarUrl,
|
|
111
|
+
});
|
|
112
|
+
if (isJSONMode()) {
|
|
113
|
+
printJSON({ username: user.username });
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
success(`Logged in as ${chalk.bold(user.username)}`);
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
await performLogin();
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { clearCredentials } from "../lib/auth.js";
|
|
2
|
+
import { success, isJSONMode, printJSON } from "../lib/format.js";
|
|
3
|
+
export function registerLogout(program) {
|
|
4
|
+
program
|
|
5
|
+
.command("logout")
|
|
6
|
+
.description("Log out of Lizard")
|
|
7
|
+
.action(async () => {
|
|
8
|
+
clearCredentials();
|
|
9
|
+
if (isJSONMode()) {
|
|
10
|
+
printJSON({ status: "logged_out" });
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
success("Logged out");
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElE,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,gBAAgB,EAAE,CAAC;QACnB,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,YAAY,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { streamSSE, api } from "../lib/api.js";
|
|
3
|
+
import { resolveProjectId } from "../lib/config.js";
|
|
4
|
+
import { info, error } from "../lib/format.js";
|
|
5
|
+
export function registerLogs(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("logs")
|
|
8
|
+
.description("Stream runtime logs")
|
|
9
|
+
.option("--build", "Show build logs instead of runtime")
|
|
10
|
+
.option("--service <id>", "Only show logs for a specific service")
|
|
11
|
+
.action(async (opts) => {
|
|
12
|
+
const projectId = resolveProjectId(program.opts().project);
|
|
13
|
+
if (opts.build) {
|
|
14
|
+
// Show build logs for the latest build
|
|
15
|
+
await showBuildLogs(opts.service, projectId);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (opts.service) {
|
|
19
|
+
// Stream logs for a specific app
|
|
20
|
+
info(chalk.dim("Streaming logs... (Ctrl+C to stop)\n"));
|
|
21
|
+
await streamSSE(`/api/apps/${opts.service}/logs`, (event, data) => {
|
|
22
|
+
if (event === "error") {
|
|
23
|
+
error(data);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
printLogLine(data);
|
|
27
|
+
return true;
|
|
28
|
+
});
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// Stream all project logs
|
|
32
|
+
info(chalk.dim("Streaming project logs... (Ctrl+C to stop)\n"));
|
|
33
|
+
await streamSSE(`/api/projects/${projectId}/logs/stream`, (event, data) => {
|
|
34
|
+
if (event === "error") {
|
|
35
|
+
error(data);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
printLogLine(data);
|
|
39
|
+
return true;
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function printLogLine(data) {
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(data);
|
|
46
|
+
if (parsed.service && parsed.line) {
|
|
47
|
+
const prefix = chalk.cyan(`[${parsed.service}]`);
|
|
48
|
+
process.stdout.write(`${prefix} ${parsed.line}\n`);
|
|
49
|
+
}
|
|
50
|
+
else if (parsed.line) {
|
|
51
|
+
process.stdout.write(parsed.line + "\n");
|
|
52
|
+
}
|
|
53
|
+
else if (parsed.message) {
|
|
54
|
+
process.stdout.write(parsed.message + "\n");
|
|
55
|
+
}
|
|
56
|
+
else if (typeof parsed === "string") {
|
|
57
|
+
process.stdout.write(parsed + "\n");
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
process.stdout.write(data + "\n");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
process.stdout.write(data + "\n");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function showBuildLogs(serviceId, projectId) {
|
|
68
|
+
let appId = serviceId;
|
|
69
|
+
if (!appId) {
|
|
70
|
+
// Get first app in project
|
|
71
|
+
const data = await api.get(`/api/projects/${projectId}/services`);
|
|
72
|
+
if (!data.apps?.length) {
|
|
73
|
+
throw new Error("No apps in project");
|
|
74
|
+
}
|
|
75
|
+
appId = data.apps[0].id;
|
|
76
|
+
}
|
|
77
|
+
// Get latest build
|
|
78
|
+
const app = await api.get(`/api/apps/${appId}`);
|
|
79
|
+
if (!app.builds?.length) {
|
|
80
|
+
throw new Error("No builds found");
|
|
81
|
+
}
|
|
82
|
+
const buildId = app.builds[0].id;
|
|
83
|
+
info(chalk.dim(`Build ${buildId}\n`));
|
|
84
|
+
await streamSSE(`/api/builds/${buildId}/logs`, (event, data) => {
|
|
85
|
+
if (event === "done" || event === "error") {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
printLogLine(data);
|
|
89
|
+
return true;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import open from "open";
|
|
2
|
+
import { resolveProjectId } from "../lib/config.js";
|
|
3
|
+
import { getBaseURL } from "../lib/api.js";
|
|
4
|
+
import { success } from "../lib/format.js";
|
|
5
|
+
export function registerOpen(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("open")
|
|
8
|
+
.description("Open project in browser")
|
|
9
|
+
.action(async () => {
|
|
10
|
+
const projectId = resolveProjectId(program.opts().project);
|
|
11
|
+
const url = `${getBaseURL()}/projects/${projectId}`;
|
|
12
|
+
await open(url);
|
|
13
|
+
success("Opened in browser");
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=open.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,yBAAyB,CAAC;SACtC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,GAAG,UAAU,EAAE,aAAa,SAAS,EAAE,CAAC;QACpD,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { api } from "../lib/api.js";
|
|
2
|
+
import { isJSONMode, printJSON, table } from "../lib/format.js";
|
|
3
|
+
export function registerProjects(program) {
|
|
4
|
+
const proj = program
|
|
5
|
+
.command("project")
|
|
6
|
+
.description("Project management");
|
|
7
|
+
proj
|
|
8
|
+
.command("list")
|
|
9
|
+
.description("List all projects")
|
|
10
|
+
.action(async () => {
|
|
11
|
+
const projects = await api.get("/api/projects");
|
|
12
|
+
if (isJSONMode()) {
|
|
13
|
+
printJSON(projects);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (projects.length === 0) {
|
|
17
|
+
console.log("No projects. Run `lizard init` to create one.");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
table(["Name", "ID", "Role", "Members"], projects.map((p) => [
|
|
21
|
+
p.name,
|
|
22
|
+
p.id,
|
|
23
|
+
p.role || "owner",
|
|
24
|
+
String(p.memberCount || 1),
|
|
25
|
+
]));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAWhE,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,oBAAoB,CAAC,CAAC;IAErC,IAAI;SACD,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,GAAG,CAAY,eAAe,CAAC,CAAC;QAE3D,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,QAAQ,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,KAAK,CACH,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EACjC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAClB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,IAAI,IAAI,OAAO;YACjB,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;SAC3B,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { api } from "../lib/api.js";
|
|
3
|
+
import { resolveProjectId } from "../lib/config.js";
|
|
4
|
+
import { isJSONMode, printJSON, table, statusColor, } from "../lib/format.js";
|
|
5
|
+
export function registerPs(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("ps")
|
|
8
|
+
.description("List all services in the project")
|
|
9
|
+
.action(async () => {
|
|
10
|
+
const projectId = resolveProjectId(program.opts().project);
|
|
11
|
+
const data = await api.get(`/api/projects/${projectId}/services`);
|
|
12
|
+
const services = [];
|
|
13
|
+
for (const app of data.apps || []) {
|
|
14
|
+
services.push({
|
|
15
|
+
id: app.id,
|
|
16
|
+
name: app.name,
|
|
17
|
+
type: "app",
|
|
18
|
+
status: app.status,
|
|
19
|
+
domain: app.domain,
|
|
20
|
+
createdAt: app.createdAt,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
for (const addon of data.addons || []) {
|
|
24
|
+
services.push({
|
|
25
|
+
id: addon.id,
|
|
26
|
+
name: addon.name || addon.addonType,
|
|
27
|
+
type: "addon",
|
|
28
|
+
addonType: addon.addonType,
|
|
29
|
+
status: addon.status,
|
|
30
|
+
hostname: addon.hostname,
|
|
31
|
+
createdAt: addon.createdAt,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (isJSONMode()) {
|
|
35
|
+
printJSON(services);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (services.length === 0) {
|
|
39
|
+
console.log("No services. Use `lizard add` or `lizard deploy`.");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
table(["Name", "Type", "Status", "URL/Host"], services.map((s) => [
|
|
43
|
+
s.name,
|
|
44
|
+
s.addonType || s.type,
|
|
45
|
+
statusColor(s.status),
|
|
46
|
+
s.domain
|
|
47
|
+
? `https://${s.domain}`
|
|
48
|
+
: s.hostname || chalk.dim("—"),
|
|
49
|
+
]));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ps.js","sourceRoot":"","sources":["../../src/commands/ps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,UAAU,EACV,SAAS,EACT,KAAK,EACL,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAa1B,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO;SACJ,OAAO,CAAC,IAAI,CAAC;SACb,WAAW,CAAC,kCAAkC,CAAC;SAC/C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CACxB,iBAAiB,SAAS,WAAW,CACtC,CAAC;QAEF,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,SAAS,EAAE,GAAG,CAAC,SAAS;aACzB,CAAC,CAAC;QACL,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS;gBACnC,IAAI,EAAE,OAAO;gBACb,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,KAAK,CAAC,SAAS;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,QAAQ,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,KAAK,CACH,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,EACtC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAClB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI;YACrB,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;YACrB,CAAC,CAAC,MAAM;gBACN,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE;gBACvB,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;SACjC,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { api, streamSSE } from "../lib/api.js";
|
|
4
|
+
import { success, info, error, isJSONMode, printJSON } from "../lib/format.js";
|
|
5
|
+
export function registerRedeploy(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("redeploy")
|
|
8
|
+
.argument("<id>", "Service ID to redeploy")
|
|
9
|
+
.description("Redeploy a service from latest build with current secrets")
|
|
10
|
+
.option("--detach", "Run in background")
|
|
11
|
+
.action(async (id, opts) => {
|
|
12
|
+
const spinner = ora("Starting redeploy...").start();
|
|
13
|
+
await api.post(`/api/apps/${id}/redeploy`);
|
|
14
|
+
spinner.stop();
|
|
15
|
+
if (opts.detach || isJSONMode()) {
|
|
16
|
+
if (isJSONMode()) {
|
|
17
|
+
printJSON({ id, status: "deploying" });
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
success("Redeploy started");
|
|
21
|
+
info(chalk.dim(` Check status: lizard deploy-status ${id}`));
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Stream build logs if not detached
|
|
26
|
+
info("Redeploying...");
|
|
27
|
+
// Poll for build
|
|
28
|
+
let buildId = null;
|
|
29
|
+
for (let i = 0; i < 30; i++) {
|
|
30
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
31
|
+
try {
|
|
32
|
+
const app = await api.get(`/api/apps/${id}`);
|
|
33
|
+
if (app.builds?.length) {
|
|
34
|
+
const latest = app.builds[0];
|
|
35
|
+
if (["building", "deploying", "running", "failed"].includes(latest.status)) {
|
|
36
|
+
buildId = latest.id;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
}
|
|
43
|
+
if (buildId) {
|
|
44
|
+
await streamSSE(`/api/builds/${buildId}/logs`, (event, data) => {
|
|
45
|
+
if (event === "done" || event === "error") {
|
|
46
|
+
if (event === "error")
|
|
47
|
+
error(`Build failed: ${data}`);
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(data);
|
|
52
|
+
process.stdout.write((parsed.line || data) + "\n");
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
process.stdout.write(data + "\n");
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const app = await api.get(`/api/apps/${id}`);
|
|
61
|
+
if (app.status === "running") {
|
|
62
|
+
success(`Redeployed! ${app.domain ? chalk.cyan(`https://${app.domain}`) : ""}`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
error("Redeploy failed");
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=redeploy.js.map
|