@prisma/cli 3.0.0-alpha.1 → 3.0.0-alpha.11
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 +1 -16
- package/dist/adapters/git.js +49 -0
- package/dist/adapters/local-state.js +39 -1
- package/dist/adapters/token-storage.js +57 -1
- package/dist/cli2.js +60 -4
- package/dist/commands/app/index.js +41 -21
- package/dist/commands/auth/index.js +3 -2
- package/dist/commands/branch/index.js +2 -1
- package/dist/commands/env.js +87 -0
- package/dist/commands/git/index.js +36 -0
- package/dist/commands/project/index.js +12 -14
- package/dist/commands/version/index.js +18 -0
- package/dist/controllers/app-env.js +223 -0
- package/dist/controllers/app.js +1026 -169
- package/dist/controllers/auth.js +9 -9
- package/dist/controllers/branch.js +6 -6
- package/dist/controllers/project.js +451 -161
- package/dist/controllers/version.js +12 -0
- package/dist/lib/app/bun-project.js +1 -1
- package/dist/lib/app/deploy-output.js +15 -0
- package/dist/lib/app/env-config.js +57 -0
- package/dist/lib/app/env-vars.js +4 -4
- package/dist/lib/app/local-dev.js +1 -1
- package/dist/lib/app/preview-build.js +128 -1
- package/dist/lib/app/preview-interaction.js +2 -35
- package/dist/lib/app/preview-progress.js +43 -58
- package/dist/lib/app/preview-provider.js +125 -24
- package/dist/lib/auth/auth-ops.js +58 -13
- package/dist/lib/auth/client.js +1 -1
- package/dist/lib/auth/guard.js +1 -1
- package/dist/lib/auth/login.js +115 -4
- package/dist/lib/project/local-pin.js +51 -0
- package/dist/lib/project/resolution.js +201 -0
- package/dist/lib/version.js +55 -0
- package/dist/output/patterns.js +15 -18
- package/dist/presenters/app-env.js +129 -0
- package/dist/presenters/app.js +16 -29
- package/dist/presenters/auth.js +2 -2
- package/dist/presenters/branch.js +6 -6
- package/dist/presenters/project.js +87 -44
- package/dist/presenters/version.js +29 -0
- package/dist/shell/command-meta.js +148 -91
- package/dist/shell/command-runner.js +45 -7
- package/dist/shell/errors.js +9 -3
- package/dist/shell/global-flags.js +13 -1
- package/dist/shell/help.js +8 -7
- package/dist/shell/output.js +29 -12
- package/dist/shell/prompt.js +12 -2
- package/dist/shell/runtime.js +1 -1
- package/dist/shell/ui.js +19 -1
- package/dist/use-cases/auth.js +9 -12
- package/dist/use-cases/branch.js +20 -20
- package/dist/use-cases/create-cli-gateways.js +3 -13
- package/dist/use-cases/project.js +2 -48
- package/package.json +3 -3
- package/dist/adapters/config.js +0 -74
package/README.md
CHANGED
|
@@ -18,22 +18,7 @@ pnpm prisma-cli app list-env
|
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
The package exposes `prisma-cli` so it can coexist with the existing `prisma`
|
|
21
|
-
executable.
|
|
22
|
-
add:
|
|
23
|
-
|
|
24
|
-
```json
|
|
25
|
-
{
|
|
26
|
-
"scripts": {
|
|
27
|
-
"prisma": "prisma-cli"
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Then run:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
pnpm prisma app deploy
|
|
36
|
-
```
|
|
21
|
+
executable.
|
|
37
22
|
|
|
38
23
|
Notes:
|
|
39
24
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
//#region src/adapters/git.ts
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
async function readGitOriginRemote(cwd) {
|
|
6
|
+
try {
|
|
7
|
+
const { stdout } = await execFileAsync("git", [
|
|
8
|
+
"config",
|
|
9
|
+
"--get",
|
|
10
|
+
"remote.origin.url"
|
|
11
|
+
], {
|
|
12
|
+
cwd,
|
|
13
|
+
timeout: 5e3
|
|
14
|
+
});
|
|
15
|
+
const remote = stdout.trim();
|
|
16
|
+
return remote.length > 0 ? remote : null;
|
|
17
|
+
} catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function parseGitHubRepositoryUrl(value) {
|
|
22
|
+
const input = value.trim();
|
|
23
|
+
const shorthand = input.match(/^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/);
|
|
24
|
+
if (shorthand) return toGitHubRepositoryReference(shorthand[1], shorthand[2]);
|
|
25
|
+
let parsed;
|
|
26
|
+
try {
|
|
27
|
+
parsed = new URL(input);
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
if (parsed.hostname !== "github.com") return null;
|
|
32
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:" && parsed.protocol !== "ssh:") return null;
|
|
33
|
+
const parts = parsed.pathname.split("/").filter(Boolean);
|
|
34
|
+
if (parts.length !== 2) return null;
|
|
35
|
+
const [owner, rawName] = parts;
|
|
36
|
+
return toGitHubRepositoryReference(owner, rawName.endsWith(".git") ? rawName.slice(0, -4) : rawName);
|
|
37
|
+
}
|
|
38
|
+
function toGitHubRepositoryReference(owner, name) {
|
|
39
|
+
if (!owner || !name || owner.includes("/") || name.includes("/")) return null;
|
|
40
|
+
return {
|
|
41
|
+
provider: "github",
|
|
42
|
+
owner,
|
|
43
|
+
name,
|
|
44
|
+
fullName: `${owner}/${name}`,
|
|
45
|
+
url: `https://github.com/${owner}/${name}`
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { parseGitHubRepositoryUrl, readGitOriginRemote };
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
//#region src/adapters/local-state.ts
|
|
4
4
|
const DEFAULT_STATE = {
|
|
5
5
|
auth: null,
|
|
6
|
+
project: {
|
|
7
|
+
rememberedByWorkspace: {},
|
|
8
|
+
lastResolved: null,
|
|
9
|
+
repositoryConnectionsByProject: {}
|
|
10
|
+
},
|
|
6
11
|
branch: { active: "preview" },
|
|
7
12
|
app: {
|
|
8
13
|
selectedByProject: {},
|
|
@@ -24,6 +29,11 @@ var LocalStateStore = class {
|
|
|
24
29
|
const parsed = JSON.parse(raw);
|
|
25
30
|
return {
|
|
26
31
|
auth: parsed.auth ?? structuredClone(DEFAULT_STATE.auth),
|
|
32
|
+
project: {
|
|
33
|
+
rememberedByWorkspace: parsed.project?.rememberedByWorkspace ?? {},
|
|
34
|
+
lastResolved: parsed.project?.lastResolved ?? null,
|
|
35
|
+
repositoryConnectionsByProject: parsed.project?.repositoryConnectionsByProject ?? {}
|
|
36
|
+
},
|
|
27
37
|
branch: { active: parsed.branch?.active ?? DEFAULT_STATE.branch.active },
|
|
28
38
|
app: {
|
|
29
39
|
selectedByProject: parsed.app?.selectedByProject ?? {},
|
|
@@ -57,6 +67,34 @@ var LocalStateStore = class {
|
|
|
57
67
|
await this.write(state);
|
|
58
68
|
return state;
|
|
59
69
|
}
|
|
70
|
+
async readRememberedProject(workspaceId) {
|
|
71
|
+
return (await this.read()).project.rememberedByWorkspace[workspaceId] ?? null;
|
|
72
|
+
}
|
|
73
|
+
async readLastResolvedProject() {
|
|
74
|
+
return (await this.read()).project.lastResolved;
|
|
75
|
+
}
|
|
76
|
+
async setRememberedProject(project) {
|
|
77
|
+
const state = await this.read();
|
|
78
|
+
state.project.rememberedByWorkspace[project.workspaceId] = project;
|
|
79
|
+
state.project.lastResolved = project;
|
|
80
|
+
await this.write(state);
|
|
81
|
+
return state;
|
|
82
|
+
}
|
|
83
|
+
async readRepositoryConnection(projectId) {
|
|
84
|
+
return (await this.read()).project.repositoryConnectionsByProject[projectId] ?? null;
|
|
85
|
+
}
|
|
86
|
+
async setRepositoryConnection(projectId, connection) {
|
|
87
|
+
const state = await this.read();
|
|
88
|
+
state.project.repositoryConnectionsByProject[projectId] = connection;
|
|
89
|
+
await this.write(state);
|
|
90
|
+
return state;
|
|
91
|
+
}
|
|
92
|
+
async clearRepositoryConnection(projectId) {
|
|
93
|
+
const state = await this.read();
|
|
94
|
+
delete state.project.repositoryConnectionsByProject[projectId];
|
|
95
|
+
await this.write(state);
|
|
96
|
+
return state;
|
|
97
|
+
}
|
|
60
98
|
async readSelectedApp(projectId) {
|
|
61
99
|
return (await this.read()).app.selectedByProject[projectId] ?? null;
|
|
62
100
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { getAuthFilePath } from "../lib/auth/client.js";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
2
4
|
import { CredentialsStore } from "@prisma/credentials-store";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
3
6
|
//#region src/adapters/token-storage.ts
|
|
4
7
|
function findLatestValidTokens(allCredentials) {
|
|
5
8
|
for (let i = allCredentials.length - 1; i >= 0; i -= 1) {
|
|
@@ -14,10 +17,19 @@ function findLatestValidTokens(allCredentials) {
|
|
|
14
17
|
}
|
|
15
18
|
return null;
|
|
16
19
|
}
|
|
20
|
+
function tokensEqual(a, b) {
|
|
21
|
+
return a?.workspaceId === b?.workspaceId && a?.accessToken === b?.accessToken && a?.refreshToken === b?.refreshToken;
|
|
22
|
+
}
|
|
23
|
+
function sleep(ms) {
|
|
24
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
25
|
+
}
|
|
17
26
|
var FileTokenStorage = class {
|
|
18
27
|
credentialsStore;
|
|
28
|
+
lockFilePath;
|
|
19
29
|
constructor(env = process.env) {
|
|
20
|
-
|
|
30
|
+
const authFilePath = getAuthFilePath(env);
|
|
31
|
+
this.credentialsStore = new CredentialsStore(authFilePath);
|
|
32
|
+
this.lockFilePath = `${authFilePath}.lock`;
|
|
21
33
|
}
|
|
22
34
|
async getTokens() {
|
|
23
35
|
try {
|
|
@@ -38,6 +50,50 @@ var FileTokenStorage = class {
|
|
|
38
50
|
if (!tokens) return;
|
|
39
51
|
await this.credentialsStore.deleteCredentials(tokens.workspaceId);
|
|
40
52
|
}
|
|
53
|
+
async clearTokensIfCurrent(tokens) {
|
|
54
|
+
if (!tokensEqual(await this.getTokens(), tokens)) return;
|
|
55
|
+
await this.clearTokens();
|
|
56
|
+
}
|
|
57
|
+
async withRefreshLock(fn) {
|
|
58
|
+
const lockId = await this.acquireRefreshLock();
|
|
59
|
+
try {
|
|
60
|
+
return await fn();
|
|
61
|
+
} finally {
|
|
62
|
+
await this.releaseRefreshLock(lockId);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async acquireRefreshLock() {
|
|
66
|
+
const lockId = randomUUID();
|
|
67
|
+
await fs.mkdir(path.dirname(this.lockFilePath), { recursive: true });
|
|
68
|
+
while (true) try {
|
|
69
|
+
const handle = await fs.open(this.lockFilePath, "wx");
|
|
70
|
+
try {
|
|
71
|
+
await handle.writeFile(lockId, "utf8");
|
|
72
|
+
} finally {
|
|
73
|
+
await handle.close();
|
|
74
|
+
}
|
|
75
|
+
return lockId;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error.code !== "EEXIST") throw error;
|
|
78
|
+
const staleLockId = await this.getStaleRefreshLockId();
|
|
79
|
+
if (staleLockId) {
|
|
80
|
+
await this.releaseRefreshLock(staleLockId);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
await sleep(100);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async getStaleRefreshLockId() {
|
|
87
|
+
const lockId = await fs.readFile(this.lockFilePath, "utf8").catch(() => null);
|
|
88
|
+
if (lockId === null) return null;
|
|
89
|
+
const stats = await fs.stat(this.lockFilePath).catch(() => null);
|
|
90
|
+
if (!stats) return null;
|
|
91
|
+
return Date.now() - stats.mtimeMs > 3e4 ? lockId : null;
|
|
92
|
+
}
|
|
93
|
+
async releaseRefreshLock(lockId) {
|
|
94
|
+
if (await fs.readFile(this.lockFilePath, "utf8").catch(() => null) !== lockId) return;
|
|
95
|
+
await fs.unlink(this.lockFilePath).catch(() => {});
|
|
96
|
+
}
|
|
41
97
|
};
|
|
42
98
|
//#endregion
|
|
43
99
|
export { FileTokenStorage };
|
package/dist/cli2.js
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
+
import { CliError } from "./shell/errors.js";
|
|
2
|
+
import { createShellUi } from "./shell/ui.js";
|
|
3
|
+
import { writeHumanError, writeJsonError, writeJsonSuccess } from "./shell/output.js";
|
|
1
4
|
import { attachCommandDescriptor } from "./shell/command-meta.js";
|
|
2
|
-
import {
|
|
5
|
+
import { addCompactGlobalFlags } from "./shell/global-flags.js";
|
|
6
|
+
import { configureRuntimeCommand, createCommandContext } from "./shell/runtime.js";
|
|
3
7
|
import "./shell/prompt.js";
|
|
4
8
|
import { createAppCommand } from "./commands/app/index.js";
|
|
5
9
|
import { createAuthCommand } from "./commands/auth/index.js";
|
|
6
10
|
import { createBranchCommand } from "./commands/branch/index.js";
|
|
11
|
+
import { createGitCommand } from "./commands/git/index.js";
|
|
7
12
|
import { createProjectCommand } from "./commands/project/index.js";
|
|
13
|
+
import { getCliName, getCliVersion } from "./lib/version.js";
|
|
14
|
+
import { runVersion } from "./controllers/version.js";
|
|
15
|
+
import { createVersionCommand } from "./commands/version/index.js";
|
|
8
16
|
import process from "node:process";
|
|
9
|
-
import { Command, CommanderError } from "commander";
|
|
17
|
+
import { Command, CommanderError, Option } from "commander";
|
|
10
18
|
//#region src/cli.ts
|
|
11
19
|
async function runCli(options = {}) {
|
|
12
20
|
const runtime = resolveRuntime(options);
|
|
13
21
|
const program = createProgram(runtime);
|
|
14
22
|
process.exitCode = 0;
|
|
15
23
|
try {
|
|
24
|
+
if (runtime.argv.includes("--version")) return await handleVersionFlag(runtime);
|
|
16
25
|
const bareHelpCommand = resolveBareHelpCommand(program, runtime.argv);
|
|
17
26
|
if (bareHelpCommand) {
|
|
18
27
|
runtime.stderr.write(bareHelpCommand.helpInformation());
|
|
@@ -31,17 +40,64 @@ async function runCli(options = {}) {
|
|
|
31
40
|
}
|
|
32
41
|
function createProgram(runtime) {
|
|
33
42
|
const program = attachCommandDescriptor(configureRuntimeCommand(new Command(), runtime), "root");
|
|
43
|
+
addCompactGlobalFlags(program);
|
|
44
|
+
program.addOption(new Option("--version", "Print the CLI version and exit."));
|
|
34
45
|
program.name("prisma").showSuggestionAfterError();
|
|
46
|
+
program.addCommand(createVersionCommand(runtime));
|
|
35
47
|
program.addCommand(createAuthCommand(runtime));
|
|
36
|
-
program.addCommand(createBranchCommand(runtime));
|
|
37
48
|
program.addCommand(createProjectCommand(runtime));
|
|
49
|
+
program.addCommand(createGitCommand(runtime));
|
|
50
|
+
program.addCommand(createBranchCommand(runtime));
|
|
38
51
|
program.addCommand(createAppCommand(runtime));
|
|
39
52
|
return program;
|
|
40
53
|
}
|
|
54
|
+
async function handleVersionFlag(runtime) {
|
|
55
|
+
const wantsJson = runtime.argv.includes("--json");
|
|
56
|
+
const output = {
|
|
57
|
+
stdout: runtime.stdout,
|
|
58
|
+
stderr: runtime.stderr
|
|
59
|
+
};
|
|
60
|
+
try {
|
|
61
|
+
if (wantsJson) {
|
|
62
|
+
const success = await runVersion(await createCommandContext(runtime, buildVersionFlagFlags(runtime)));
|
|
63
|
+
writeJsonSuccess(output, {
|
|
64
|
+
command: success.command,
|
|
65
|
+
result: { version: success.result.cli.version },
|
|
66
|
+
warnings: success.warnings,
|
|
67
|
+
nextSteps: success.nextSteps
|
|
68
|
+
});
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
const versionLine = `${getCliName()} ${getCliVersion()}`;
|
|
72
|
+
runtime.stdout.write(`${versionLine}\n`);
|
|
73
|
+
return 0;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error instanceof CliError) {
|
|
76
|
+
if (wantsJson) writeJsonError(output, "version", error);
|
|
77
|
+
else writeHumanError(output, createShellUi(runtime, buildVersionFlagFlags(runtime)), error, { trace: false });
|
|
78
|
+
return error.exitCode;
|
|
79
|
+
}
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function buildVersionFlagFlags(runtime) {
|
|
84
|
+
return {
|
|
85
|
+
json: runtime.argv.includes("--json"),
|
|
86
|
+
quiet: false,
|
|
87
|
+
verbose: false,
|
|
88
|
+
trace: false,
|
|
89
|
+
yes: false,
|
|
90
|
+
interactive: void 0,
|
|
91
|
+
color: void 0
|
|
92
|
+
};
|
|
93
|
+
}
|
|
41
94
|
function resolveBareHelpCommand(program, argv) {
|
|
42
95
|
if (argv.length === 0) return program;
|
|
43
96
|
if (argv.length !== 1) return null;
|
|
44
|
-
|
|
97
|
+
const candidate = program.commands.find((command) => command.name() === argv[0]) ?? null;
|
|
98
|
+
if (!candidate) return null;
|
|
99
|
+
if (candidate.commands.length === 0) return null;
|
|
100
|
+
return candidate;
|
|
45
101
|
}
|
|
46
102
|
function resolveRuntime(options) {
|
|
47
103
|
return {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
|
-
import { addGlobalFlags } from "../../shell/global-flags.js";
|
|
2
|
+
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
4
|
import { PREVIEW_BUILD_TYPES } from "../../lib/app/preview-build.js";
|
|
5
5
|
import { runAppBuild, runAppDeploy, runAppListDeploys, runAppListEnv, runAppLogs, runAppOpen, runAppPromote, runAppRemove, runAppRollback, runAppRun, runAppShow, runAppShowDeploy, runAppUpdateEnv } from "../../controllers/app.js";
|
|
6
6
|
import { renderAppBuild, renderAppDeploy, renderAppListDeploys, renderAppListEnv, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, renderAppUpdateEnv, serializeAppBuild, serializeAppDeploy, serializeAppListDeploys, serializeAppListEnv, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy, serializeAppUpdateEnv } from "../../presenters/app.js";
|
|
7
|
-
import { runCommand } from "../../shell/command-runner.js";
|
|
7
|
+
import { runCommand, runStreamingCommand } from "../../shell/command-runner.js";
|
|
8
8
|
import { Command, Option } from "commander";
|
|
9
9
|
//#region src/commands/app/index.ts
|
|
10
10
|
function createAppCommand(runtime) {
|
|
11
11
|
const app = attachCommandDescriptor(configureRuntimeCommand(new Command("app"), runtime), "app");
|
|
12
|
+
addCompactGlobalFlags(app);
|
|
12
13
|
app.addCommand(createBuildCommand(runtime));
|
|
13
14
|
app.addCommand(createRunCommand(runtime));
|
|
14
15
|
app.addCommand(createDeployCommand(runtime));
|
|
@@ -59,17 +60,27 @@ function createRunCommand(runtime) {
|
|
|
59
60
|
}
|
|
60
61
|
function createDeployCommand(runtime) {
|
|
61
62
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("deploy"), runtime), "app.deploy");
|
|
62
|
-
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--
|
|
63
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([
|
|
64
|
+
"nextjs",
|
|
65
|
+
"hono",
|
|
66
|
+
"tanstack-start"
|
|
67
|
+
])).addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto deploys")).addOption(new Option("--build-type <type>", "Legacy deploy build type").choices([...PREVIEW_BUILD_TYPES]).default("auto").hideHelp()).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--env <name=value>", "Environment variable").argParser(collectRepeatableValues));
|
|
63
68
|
addGlobalFlags(command);
|
|
64
69
|
command.action(async (options) => {
|
|
65
70
|
const appName = options.app;
|
|
66
71
|
const entry = options.entry;
|
|
67
72
|
const buildType = options.buildType;
|
|
73
|
+
const branchName = options.branch;
|
|
74
|
+
const framework = options.framework;
|
|
68
75
|
const httpPort = options.httpPort;
|
|
69
76
|
const envAssignments = options.env;
|
|
77
|
+
const projectRef = options.project;
|
|
70
78
|
await runCommand(runtime, "app.deploy", options, (context) => runAppDeploy(context, appName, {
|
|
79
|
+
projectRef,
|
|
80
|
+
branchName,
|
|
71
81
|
entrypoint: entry,
|
|
72
82
|
buildType,
|
|
83
|
+
framework,
|
|
73
84
|
httpPort,
|
|
74
85
|
envAssignments
|
|
75
86
|
}), {
|
|
@@ -81,12 +92,13 @@ function createDeployCommand(runtime) {
|
|
|
81
92
|
}
|
|
82
93
|
function createUpdateEnvCommand(runtime) {
|
|
83
94
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("update-env"), runtime), "app.update-env");
|
|
84
|
-
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--env <name=value>", "Environment variable").argParser(collectRepeatableValues));
|
|
95
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--env <name=value>", "Environment variable").argParser(collectRepeatableValues));
|
|
85
96
|
addGlobalFlags(command);
|
|
86
97
|
command.action(async (options) => {
|
|
87
98
|
const appName = options.app;
|
|
88
99
|
const envAssignments = options.env;
|
|
89
|
-
|
|
100
|
+
const projectRef = options.project;
|
|
101
|
+
await runCommand(runtime, "app.update-env", options, (context) => runAppUpdateEnv(context, appName, envAssignments, projectRef), {
|
|
90
102
|
renderHuman: (context, descriptor, result) => renderAppUpdateEnv(context, descriptor, result),
|
|
91
103
|
renderJson: (result) => serializeAppUpdateEnv(result)
|
|
92
104
|
});
|
|
@@ -95,11 +107,12 @@ function createUpdateEnvCommand(runtime) {
|
|
|
95
107
|
}
|
|
96
108
|
function createListEnvCommand(runtime) {
|
|
97
109
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list-env"), runtime), "app.list-env");
|
|
98
|
-
command.addOption(new Option("--app <name>", "App name"));
|
|
110
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
99
111
|
addGlobalFlags(command);
|
|
100
112
|
command.action(async (options) => {
|
|
101
113
|
const appName = options.app;
|
|
102
|
-
|
|
114
|
+
const projectRef = options.project;
|
|
115
|
+
await runCommand(runtime, "app.list-env", options, (context) => runAppListEnv(context, appName, projectRef), {
|
|
103
116
|
renderHuman: (context, descriptor, result) => renderAppListEnv(context, descriptor, result),
|
|
104
117
|
renderJson: (result) => serializeAppListEnv(result)
|
|
105
118
|
});
|
|
@@ -108,11 +121,12 @@ function createListEnvCommand(runtime) {
|
|
|
108
121
|
}
|
|
109
122
|
function createShowCommand(runtime) {
|
|
110
123
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "app.show");
|
|
111
|
-
command.addOption(new Option("--app <name>", "App name"));
|
|
124
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
112
125
|
addGlobalFlags(command);
|
|
113
126
|
command.action(async (options) => {
|
|
114
127
|
const appName = options.app;
|
|
115
|
-
|
|
128
|
+
const projectRef = options.project;
|
|
129
|
+
await runCommand(runtime, "app.show", options, (context) => runAppShow(context, appName, projectRef), {
|
|
116
130
|
renderHuman: (context, descriptor, result) => renderAppShow(context, descriptor, result),
|
|
117
131
|
renderJson: (result) => serializeAppShow(result)
|
|
118
132
|
});
|
|
@@ -121,11 +135,12 @@ function createShowCommand(runtime) {
|
|
|
121
135
|
}
|
|
122
136
|
function createOpenCommand(runtime) {
|
|
123
137
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("open"), runtime), "app.open");
|
|
124
|
-
command.addOption(new Option("--app <name>", "App name"));
|
|
138
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
125
139
|
addGlobalFlags(command);
|
|
126
140
|
command.action(async (options) => {
|
|
127
141
|
const appName = options.app;
|
|
128
|
-
|
|
142
|
+
const projectRef = options.project;
|
|
143
|
+
await runCommand(runtime, "app.open", options, (context) => runAppOpen(context, appName, projectRef), {
|
|
129
144
|
renderHuman: (context, descriptor, result) => renderAppOpen(context, descriptor, result),
|
|
130
145
|
renderJson: (result) => serializeAppOpen(result)
|
|
131
146
|
});
|
|
@@ -134,12 +149,13 @@ function createOpenCommand(runtime) {
|
|
|
134
149
|
}
|
|
135
150
|
function createLogsCommand(runtime) {
|
|
136
151
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("logs"), runtime), "app.logs");
|
|
137
|
-
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--deployment <id>", "Deployment id"));
|
|
152
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--deployment <id>", "Deployment id"));
|
|
138
153
|
addGlobalFlags(command);
|
|
139
154
|
command.action(async (options) => {
|
|
140
155
|
const appName = options.app;
|
|
141
156
|
const deploymentId = options.deployment;
|
|
142
|
-
|
|
157
|
+
const projectRef = options.project;
|
|
158
|
+
await runStreamingCommand(runtime, "app.logs", options, (context) => runAppLogs(context, appName, deploymentId, projectRef));
|
|
143
159
|
});
|
|
144
160
|
return command;
|
|
145
161
|
}
|
|
@@ -148,11 +164,12 @@ function collectRepeatableValues(value, previous) {
|
|
|
148
164
|
}
|
|
149
165
|
function createListDeploysCommand(runtime) {
|
|
150
166
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list-deploys"), runtime), "app.list-deploys");
|
|
151
|
-
command.addOption(new Option("--app <name>", "App name"));
|
|
167
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
152
168
|
addGlobalFlags(command);
|
|
153
169
|
command.action(async (options) => {
|
|
154
170
|
const appName = options.app;
|
|
155
|
-
|
|
171
|
+
const projectRef = options.project;
|
|
172
|
+
await runCommand(runtime, "app.list-deploys", options, (context) => runAppListDeploys(context, appName, projectRef), {
|
|
156
173
|
renderHuman: (context, descriptor, result) => renderAppListDeploys(context, descriptor, result),
|
|
157
174
|
renderJson: (result) => serializeAppListDeploys(result)
|
|
158
175
|
});
|
|
@@ -174,11 +191,12 @@ function createShowDeployCommand(runtime) {
|
|
|
174
191
|
function createPromoteCommand(runtime) {
|
|
175
192
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("promote"), runtime), "app.promote");
|
|
176
193
|
command.argument("<deployment>", "Deployment id");
|
|
177
|
-
command.addOption(new Option("--app <name>", "App name"));
|
|
194
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
178
195
|
addGlobalFlags(command);
|
|
179
196
|
command.action(async (deploymentId, options) => {
|
|
180
197
|
const appName = options.app;
|
|
181
|
-
|
|
198
|
+
const projectRef = options.project;
|
|
199
|
+
await runCommand(runtime, "app.promote", options, (context) => runAppPromote(context, deploymentId, appName, projectRef), {
|
|
182
200
|
renderHuman: (context, descriptor, result) => renderAppPromote(context, descriptor, result),
|
|
183
201
|
renderJson: (result) => serializeAppPromote(result)
|
|
184
202
|
});
|
|
@@ -187,12 +205,13 @@ function createPromoteCommand(runtime) {
|
|
|
187
205
|
}
|
|
188
206
|
function createRollbackCommand(runtime) {
|
|
189
207
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("rollback"), runtime), "app.rollback");
|
|
190
|
-
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--to <deployment>", "Deployment id"));
|
|
208
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--to <deployment>", "Deployment id"));
|
|
191
209
|
addGlobalFlags(command);
|
|
192
210
|
command.action(async (options) => {
|
|
193
211
|
const appName = options.app;
|
|
194
212
|
const deploymentId = options.to;
|
|
195
|
-
|
|
213
|
+
const projectRef = options.project;
|
|
214
|
+
await runCommand(runtime, "app.rollback", options, (context) => runAppRollback(context, appName, deploymentId, projectRef), {
|
|
196
215
|
renderHuman: (context, descriptor, result) => renderAppRollback(context, descriptor, result),
|
|
197
216
|
renderJson: (result) => serializeAppRollback(result)
|
|
198
217
|
});
|
|
@@ -201,11 +220,12 @@ function createRollbackCommand(runtime) {
|
|
|
201
220
|
}
|
|
202
221
|
function createRemoveCommand(runtime) {
|
|
203
222
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "app.remove");
|
|
204
|
-
command.addOption(new Option("--app <name>", "App name"));
|
|
223
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
205
224
|
addGlobalFlags(command);
|
|
206
225
|
command.action(async (options) => {
|
|
207
226
|
const appName = options.app;
|
|
208
|
-
|
|
227
|
+
const projectRef = options.project;
|
|
228
|
+
await runCommand(runtime, "app.remove", options, (context) => runAppRemove(context, appName, projectRef), {
|
|
209
229
|
renderHuman: (context, descriptor, result) => renderAppRemove(context, descriptor, result),
|
|
210
230
|
renderJson: (result) => serializeAppRemove(result)
|
|
211
231
|
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
|
-
import { addGlobalFlags } from "../../shell/global-flags.js";
|
|
2
|
+
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runCommand } from "../../shell/command-runner.js";
|
|
5
4
|
import { runAuthLogin, runAuthLogout, runAuthWhoAmI } from "../../controllers/auth.js";
|
|
5
|
+
import { runCommand } from "../../shell/command-runner.js";
|
|
6
6
|
import { renderAuthSuccess } from "../../presenters/auth.js";
|
|
7
7
|
import { Command, Option } from "commander";
|
|
8
8
|
//#region src/commands/auth/index.ts
|
|
9
9
|
function createAuthCommand(runtime) {
|
|
10
10
|
const auth = attachCommandDescriptor(configureRuntimeCommand(new Command("auth"), runtime), "auth");
|
|
11
|
+
addCompactGlobalFlags(auth);
|
|
11
12
|
auth.addCommand(createAuthLoginCommand(runtime));
|
|
12
13
|
auth.addCommand(createAuthLogoutCommand(runtime));
|
|
13
14
|
auth.addCommand(createAuthWhoAmICommand(runtime));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
|
-
import { addGlobalFlags } from "../../shell/global-flags.js";
|
|
2
|
+
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
4
|
import { runCommand } from "../../shell/command-runner.js";
|
|
5
5
|
import { runBranchList, runBranchShow, runBranchUse } from "../../controllers/branch.js";
|
|
@@ -8,6 +8,7 @@ import { Command } from "commander";
|
|
|
8
8
|
//#region src/commands/branch/index.ts
|
|
9
9
|
function createBranchCommand(runtime) {
|
|
10
10
|
const branch = attachCommandDescriptor(configureRuntimeCommand(new Command("branch"), runtime), "branch");
|
|
11
|
+
addCompactGlobalFlags(branch);
|
|
11
12
|
branch.addCommand(createBranchListCommand(runtime));
|
|
12
13
|
branch.addCommand(createBranchShowCommand(runtime));
|
|
13
14
|
branch.addCommand(createBranchUseCommand(runtime));
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { attachCommandDescriptor } from "../shell/command-meta.js";
|
|
2
|
+
import { addGlobalFlags } from "../shell/global-flags.js";
|
|
3
|
+
import { configureRuntimeCommand } from "../shell/runtime.js";
|
|
4
|
+
import { runCommand } from "../shell/command-runner.js";
|
|
5
|
+
import { runEnvAdd, runEnvList, runEnvRm, runEnvUpdate } from "../controllers/app-env.js";
|
|
6
|
+
import { renderEnvAdd, renderEnvList, renderEnvRm, renderEnvUpdate, serializeEnvAdd, serializeEnvList, serializeEnvRm, serializeEnvUpdate } from "../presenters/app-env.js";
|
|
7
|
+
import { Command, Option } from "commander";
|
|
8
|
+
//#region src/commands/env.ts
|
|
9
|
+
function createEnvCommand(runtime) {
|
|
10
|
+
const env = attachCommandDescriptor(configureRuntimeCommand(new Command("env"), runtime), "project.env");
|
|
11
|
+
env.description("Manage environment variables for the active project");
|
|
12
|
+
env.addCommand(createEnvAddCommand(runtime));
|
|
13
|
+
env.addCommand(createEnvUpdateCommand(runtime));
|
|
14
|
+
env.addCommand(createEnvListCommand(runtime));
|
|
15
|
+
env.addCommand(createEnvRmCommand(runtime));
|
|
16
|
+
return env;
|
|
17
|
+
}
|
|
18
|
+
function createEnvAddCommand(runtime) {
|
|
19
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("add"), runtime), "project.env.add");
|
|
20
|
+
command.argument("<assignment>", "Variable assignment as KEY=VALUE or KEY from the current environment").addOption(new Option("--role <role>", "Project template scope (production or preview)").choices(["production", "preview"])).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
21
|
+
addGlobalFlags(command);
|
|
22
|
+
command.action(async (assignment, options) => {
|
|
23
|
+
const roleName = options.role;
|
|
24
|
+
const projectRef = options.project;
|
|
25
|
+
await runCommand(runtime, "project.env.add", options, (context) => runEnvAdd(context, assignment, {
|
|
26
|
+
roleName,
|
|
27
|
+
projectRef
|
|
28
|
+
}), {
|
|
29
|
+
renderHuman: (context, descriptor, result) => renderEnvAdd(context, descriptor, result),
|
|
30
|
+
renderJson: (result) => serializeEnvAdd(result)
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
return command;
|
|
34
|
+
}
|
|
35
|
+
function createEnvUpdateCommand(runtime) {
|
|
36
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("update"), runtime), "project.env.update");
|
|
37
|
+
command.argument("<assignment>", "Variable assignment as KEY=VALUE or KEY from the current environment").addOption(new Option("--role <role>", "Project template scope (production or preview)").choices(["production", "preview"])).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
38
|
+
addGlobalFlags(command);
|
|
39
|
+
command.action(async (assignment, options) => {
|
|
40
|
+
const roleName = options.role;
|
|
41
|
+
const projectRef = options.project;
|
|
42
|
+
await runCommand(runtime, "project.env.update", options, (context) => runEnvUpdate(context, assignment, {
|
|
43
|
+
roleName,
|
|
44
|
+
projectRef
|
|
45
|
+
}), {
|
|
46
|
+
renderHuman: (context, descriptor, result) => renderEnvUpdate(context, descriptor, result),
|
|
47
|
+
renderJson: (result) => serializeEnvUpdate(result)
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
return command;
|
|
51
|
+
}
|
|
52
|
+
function createEnvListCommand(runtime) {
|
|
53
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "project.env.list");
|
|
54
|
+
command.addOption(new Option("--role <role>", "Project template scope").choices(["production", "preview"])).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
55
|
+
addGlobalFlags(command);
|
|
56
|
+
command.action(async (options) => {
|
|
57
|
+
const roleName = options.role;
|
|
58
|
+
const projectRef = options.project;
|
|
59
|
+
await runCommand(runtime, "project.env.list", options, (context) => runEnvList(context, {
|
|
60
|
+
roleName,
|
|
61
|
+
projectRef
|
|
62
|
+
}), {
|
|
63
|
+
renderHuman: (context, descriptor, result) => renderEnvList(context, descriptor, result),
|
|
64
|
+
renderJson: (result) => serializeEnvList(result)
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
return command;
|
|
68
|
+
}
|
|
69
|
+
function createEnvRmCommand(runtime) {
|
|
70
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("rm"), runtime), "project.env.rm");
|
|
71
|
+
command.argument("<key>", "Variable key to remove").addOption(new Option("--role <role>", "Project template scope (production or preview)").choices(["production", "preview"])).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
72
|
+
addGlobalFlags(command);
|
|
73
|
+
command.action(async (key, options) => {
|
|
74
|
+
const roleName = options.role;
|
|
75
|
+
const projectRef = options.project;
|
|
76
|
+
await runCommand(runtime, "project.env.rm", options, (context) => runEnvRm(context, key, {
|
|
77
|
+
roleName,
|
|
78
|
+
projectRef
|
|
79
|
+
}), {
|
|
80
|
+
renderHuman: (context, descriptor, result) => renderEnvRm(context, descriptor, result),
|
|
81
|
+
renderJson: (result) => serializeEnvRm(result)
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
return command;
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { createEnvCommand };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
|
+
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
|
+
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
+
import { runGitConnect, runGitDisconnect } from "../../controllers/project.js";
|
|
5
|
+
import { runCommand } from "../../shell/command-runner.js";
|
|
6
|
+
import { renderGitConnect, renderGitDisconnect } from "../../presenters/project.js";
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
//#region src/commands/git/index.ts
|
|
9
|
+
function createGitCommand(runtime) {
|
|
10
|
+
const git = attachCommandDescriptor(configureRuntimeCommand(new Command("git"), runtime), "git");
|
|
11
|
+
addCompactGlobalFlags(git);
|
|
12
|
+
git.addCommand(createGitConnectCommand(runtime));
|
|
13
|
+
git.addCommand(createGitDisconnectCommand(runtime));
|
|
14
|
+
return git;
|
|
15
|
+
}
|
|
16
|
+
function createGitConnectCommand(runtime) {
|
|
17
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("connect"), runtime), "git.connect");
|
|
18
|
+
command.argument("[git-url]", "GitHub repository URL");
|
|
19
|
+
command.option("--project <id-or-name>", "Project id or name");
|
|
20
|
+
addGlobalFlags(command);
|
|
21
|
+
command.action(async (gitUrl, options) => {
|
|
22
|
+
await runCommand(runtime, "git.connect", options, (context) => runGitConnect(context, gitUrl, { project: typeof options.project === "string" ? options.project : void 0 }), { renderHuman: (context, descriptor, result) => renderGitConnect(context, descriptor, result) });
|
|
23
|
+
});
|
|
24
|
+
return command;
|
|
25
|
+
}
|
|
26
|
+
function createGitDisconnectCommand(runtime) {
|
|
27
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("disconnect"), runtime), "git.disconnect");
|
|
28
|
+
command.option("--project <id-or-name>", "Project id or name");
|
|
29
|
+
addGlobalFlags(command);
|
|
30
|
+
command.action(async (options) => {
|
|
31
|
+
await runCommand(runtime, "git.disconnect", options, (context) => runGitDisconnect(context, { project: typeof options.project === "string" ? options.project : void 0 }), { renderHuman: (context, descriptor, result) => renderGitDisconnect(context, descriptor, result) });
|
|
32
|
+
});
|
|
33
|
+
return command;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { createGitCommand };
|