@prisma/cli 3.0.0-dev.97.1 → 8.0.0-rc.1
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 +3 -14
- package/dist/adapters/local-state.js +14 -3
- package/dist/{lib/auth → auth}/client.js +11 -3
- package/dist/auth/errors.js +50 -0
- package/dist/{lib/auth → auth}/guard.js +7 -6
- package/dist/{lib/auth → auth}/login.js +147 -6
- package/dist/{lib/auth/auth-ops.js → auth/operations.js} +63 -13
- package/dist/auth/recipient.js +42 -0
- package/dist/{adapters → auth}/token-storage.js +28 -7
- package/dist/auth/workspaces.js +171 -0
- package/dist/cli-command.js +14 -0
- package/dist/cli-name.js +12 -0
- package/dist/cli.js +1 -1
- package/dist/cli2.js +25 -8
- package/dist/command-arguments.js +12 -0
- package/dist/commands/agent/index.js +60 -0
- package/dist/commands/app/index.js +11 -6
- package/dist/commands/auth/index.js +2 -3
- package/dist/commands/bucket/index.js +123 -0
- package/dist/commands/build/index.js +29 -0
- package/dist/commands/database/index.js +92 -2
- package/dist/commands/feedback/index.js +20 -0
- package/dist/commands/git/index.js +1 -1
- package/dist/commands/init/index.js +33 -0
- package/dist/commands/project/index.js +54 -5
- package/dist/controllers/agent-setup.js +52 -0
- package/dist/controllers/agent.js +228 -0
- package/dist/controllers/app-env-api.js +3 -2
- package/dist/controllers/app-env-file.js +1 -1
- package/dist/controllers/app-env.js +5 -5
- package/dist/controllers/app.js +423 -358
- package/dist/controllers/auth.js +62 -254
- package/dist/controllers/branch.js +5 -16
- package/dist/controllers/bucket.js +184 -0
- package/dist/controllers/build.js +88 -0
- package/dist/controllers/database.js +230 -85
- package/dist/controllers/feedback.js +90 -0
- package/dist/controllers/init.js +814 -0
- package/dist/controllers/project.js +345 -184
- package/dist/controllers/select-prompt-port.js +1 -0
- package/dist/{shell/errors.js → errors.js} +8 -40
- package/dist/lib/agent/cli-command.js +20 -0
- package/dist/lib/agent/constants.js +12 -0
- package/dist/lib/agent/package-manager.js +99 -0
- package/dist/lib/agent/setup-status.js +83 -0
- package/dist/lib/app/app-provider.js +168 -95
- package/dist/lib/app/branch-database-deploy.js +70 -42
- package/dist/lib/app/branch-database.js +39 -20
- package/dist/lib/app/build-settings.js +8 -3
- package/dist/lib/app/build.js +16 -14
- package/dist/lib/app/bun-project.js +1 -1
- package/dist/lib/app/compute-config.js +29 -31
- package/dist/lib/app/deploy-plan.js +1 -0
- package/dist/lib/app/deploy-progress.js +7 -7
- package/dist/lib/app/env-config.js +1 -1
- package/dist/lib/app/env-file.js +2 -2
- package/dist/lib/app/env-vars.js +1 -1
- package/dist/lib/app/local-dev.js +1 -1
- package/dist/lib/app/production-deploy-gate.js +3 -2
- package/dist/lib/bucket/provider.js +139 -0
- package/dist/lib/database/provider.js +235 -17
- package/dist/lib/diagnostics.js +2 -1
- package/dist/lib/feedback.js +15 -0
- package/dist/lib/git/local-branch.js +1 -1
- package/dist/lib/project/interactive-setup.js +6 -5
- package/dist/lib/project/local-pin.js +1 -1
- package/dist/lib/project/provider.js +93 -0
- package/dist/lib/project/resolution.js +11 -8
- package/dist/lib/project/setup.js +9 -6
- package/dist/lib/version.js +3 -2
- package/dist/lib/workspace-id.js +18 -0
- package/dist/payload-B88Qvzxk-CrtTXSOe.js +34 -0
- package/dist/presenters/agent.js +74 -0
- package/dist/presenters/app.js +33 -7
- package/dist/presenters/auth.js +3 -2
- package/dist/presenters/bucket.js +174 -0
- package/dist/presenters/database.js +193 -5
- package/dist/presenters/feedback.js +26 -0
- package/dist/presenters/init.js +30 -0
- package/dist/presenters/project.js +98 -4
- package/dist/shell/cli-command.js +2 -0
- package/dist/shell/command-meta.js +303 -4
- package/dist/shell/command-runner.js +13 -6
- package/dist/shell/help.js +6 -5
- package/dist/shell/output.js +65 -3
- package/dist/shell/prompt.js +12 -5
- package/dist/shell/runtime.js +4 -21
- package/dist/state-dir.js +12 -0
- package/dist/{shell/update-check.js → update-check.js} +6 -5
- package/dist/v8/cli.js +14699 -0
- package/dist/v8/sender.js +192 -0
- package/package.json +21 -13
- package/dist/adapters/mock-api.js +0 -136
- package/dist/lib/app/app-interaction.js +0 -5
- package/dist/shell/command-arguments.js +0 -6
- package/dist/use-cases/auth.js +0 -145
- package/dist/use-cases/branch.js +0 -47
- package/dist/use-cases/create-cli-gateways.js +0 -68
- package/dist/use-cases/project.js +0 -30
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { CLIENT_ID, UNUSED_REDIRECT_URI, getApiBaseUrl } from "./client.js";
|
|
2
|
+
import { FileTokenStorage, WorkspaceSelectionError } from "./token-storage.js";
|
|
3
|
+
import { readAuthState } from "./operations.js";
|
|
4
|
+
import { workspaceAmbiguousError, workspaceNotAuthenticatedError, workspaceSwitchUnavailableError } from "./errors.js";
|
|
5
|
+
import { createManagementApiSdk } from "@prisma/management-api-sdk";
|
|
6
|
+
import { SERVICE_TOKEN_ENV_VAR } from "@prisma/cli-engine";
|
|
7
|
+
//#region src/auth/workspaces.ts
|
|
8
|
+
async function listAuthWorkspaces(context) {
|
|
9
|
+
const rawServiceToken = context.env[SERVICE_TOKEN_ENV_VAR];
|
|
10
|
+
const storage = new FileTokenStorage(context.env, context.signal);
|
|
11
|
+
const localWorkspaces = await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
|
|
12
|
+
if (rawServiceToken !== void 0) {
|
|
13
|
+
const authState = await readAuthState(context.env, context.signal);
|
|
14
|
+
return {
|
|
15
|
+
authSource: authState.authenticated ? "service_token" : "none",
|
|
16
|
+
activeWorkspace: authState.workspace,
|
|
17
|
+
workspaces: [...authState.workspace ? [{
|
|
18
|
+
...authState.workspace,
|
|
19
|
+
credentialWorkspaceId: null,
|
|
20
|
+
active: true,
|
|
21
|
+
source: "service_token",
|
|
22
|
+
switchable: false,
|
|
23
|
+
lastSeenAt: null
|
|
24
|
+
}] : [], ...localWorkspaces.map((workspace) => ({
|
|
25
|
+
...toAuthWorkspace(workspace),
|
|
26
|
+
credentialWorkspaceId: workspace.credentialWorkspaceId,
|
|
27
|
+
active: false,
|
|
28
|
+
source: "oauth",
|
|
29
|
+
switchable: false,
|
|
30
|
+
lastSeenAt: workspace.lastSeenAt
|
|
31
|
+
}))]
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const active = localWorkspaces.find((workspace) => workspace.active) ?? null;
|
|
35
|
+
return {
|
|
36
|
+
authSource: localWorkspaces.length > 0 ? "oauth" : "none",
|
|
37
|
+
activeWorkspace: active ? toAuthWorkspace(active) : null,
|
|
38
|
+
workspaces: localWorkspaces.map((workspace) => ({
|
|
39
|
+
...toAuthWorkspace(workspace),
|
|
40
|
+
credentialWorkspaceId: workspace.credentialWorkspaceId,
|
|
41
|
+
active: workspace.active,
|
|
42
|
+
source: "oauth",
|
|
43
|
+
switchable: true,
|
|
44
|
+
lastSeenAt: workspace.lastSeenAt
|
|
45
|
+
}))
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function switchAuthWorkspace(context, workspaceRef) {
|
|
49
|
+
if (context.env[SERVICE_TOKEN_ENV_VAR] !== void 0) throw workspaceSwitchUnavailableError();
|
|
50
|
+
const storage = new FileTokenStorage(context.env, context.signal);
|
|
51
|
+
await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
|
|
52
|
+
try {
|
|
53
|
+
const result = await storage.useWorkspace(workspaceRef);
|
|
54
|
+
return {
|
|
55
|
+
previousWorkspace: result.previous ? toAuthWorkspace(result.previous) : null,
|
|
56
|
+
workspace: toAuthWorkspace(result.selected)
|
|
57
|
+
};
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (error instanceof WorkspaceSelectionError) {
|
|
60
|
+
if (error.reason === "ambiguous") throw workspaceAmbiguousError(error.workspaceRef ?? workspaceRef, error.matches.map((match) => ({
|
|
61
|
+
id: match.id,
|
|
62
|
+
name: match.name,
|
|
63
|
+
credentialWorkspaceId: match.credentialWorkspaceId
|
|
64
|
+
})));
|
|
65
|
+
throw workspaceNotAuthenticatedError(error.workspaceRef ?? workspaceRef);
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function logoutAuthWorkspace(context, workspaceRef) {
|
|
71
|
+
const storage = new FileTokenStorage(context.env, context.signal);
|
|
72
|
+
await hydrateLocalAuthWorkspaces(context, storage, await storage.listWorkspaces());
|
|
73
|
+
try {
|
|
74
|
+
const result = await storage.logoutWorkspace(workspaceRef);
|
|
75
|
+
return {
|
|
76
|
+
workspace: toAuthWorkspace(result.workspace),
|
|
77
|
+
wasActive: result.wasActive,
|
|
78
|
+
activeWorkspace: result.activeWorkspace ? toAuthWorkspace(result.activeWorkspace) : null
|
|
79
|
+
};
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error instanceof WorkspaceSelectionError) {
|
|
82
|
+
if (error.reason === "ambiguous") throw workspaceAmbiguousError(error.workspaceRef ?? workspaceRef, error.matches.map((match) => ({
|
|
83
|
+
id: match.id,
|
|
84
|
+
name: match.name,
|
|
85
|
+
credentialWorkspaceId: match.credentialWorkspaceId
|
|
86
|
+
})));
|
|
87
|
+
throw workspaceNotAuthenticatedError(error.workspaceRef ?? workspaceRef);
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function hydrateLocalAuthWorkspaces(context, storage, workspaces) {
|
|
93
|
+
const candidates = workspaces.filter(needsWorkspaceMetadataHydration);
|
|
94
|
+
if (candidates.length === 0) return workspaces;
|
|
95
|
+
const tokensByCredentialWorkspaceId = new Map((await storage.listWorkspaceTokens()).map((tokens) => [tokens.workspaceId, tokens]));
|
|
96
|
+
let nextWorkspaces = workspaces;
|
|
97
|
+
for (const workspace of candidates) {
|
|
98
|
+
const tokens = tokensByCredentialWorkspaceId.get(workspace.credentialWorkspaceId);
|
|
99
|
+
if (!tokens) continue;
|
|
100
|
+
const resolved = await resolveOAuthWorkspaceMetadata(context, tokens);
|
|
101
|
+
if (!resolved) continue;
|
|
102
|
+
await rememberResolvedWorkspaceMetadata(context, storage, tokens, resolved);
|
|
103
|
+
nextWorkspaces = nextWorkspaces.map((candidate) => candidate.credentialWorkspaceId === workspace.credentialWorkspaceId ? {
|
|
104
|
+
...candidate,
|
|
105
|
+
id: resolved.id,
|
|
106
|
+
name: resolved.name,
|
|
107
|
+
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
108
|
+
} : candidate);
|
|
109
|
+
}
|
|
110
|
+
return nextWorkspaces;
|
|
111
|
+
}
|
|
112
|
+
async function rememberResolvedWorkspaceMetadata(context, storage, tokens, resolved) {
|
|
113
|
+
try {
|
|
114
|
+
await storage.rememberWorkspace(tokens.workspaceId, resolved);
|
|
115
|
+
} catch {
|
|
116
|
+
context.signal?.throwIfAborted();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function needsWorkspaceMetadataHydration(workspace) {
|
|
120
|
+
return workspace.id === workspace.credentialWorkspaceId || workspace.name === "Unknown workspace" || workspace.name === workspace.credentialWorkspaceId;
|
|
121
|
+
}
|
|
122
|
+
async function resolveOAuthWorkspaceMetadata(context, tokens) {
|
|
123
|
+
const sdk = createManagementApiSdk({
|
|
124
|
+
clientId: CLIENT_ID,
|
|
125
|
+
redirectUri: UNUSED_REDIRECT_URI,
|
|
126
|
+
tokenStorage: createSingleWorkspaceTokenStorage(new FileTokenStorage(context.env, context.signal, { activateOnSetTokens: false }), tokens),
|
|
127
|
+
apiBaseUrl: getApiBaseUrl(context.env)
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
const { data } = await sdk.client.GET("/v1/workspaces/{id}", {
|
|
131
|
+
params: { path: { id: tokens.workspaceId } },
|
|
132
|
+
signal: context.signal
|
|
133
|
+
});
|
|
134
|
+
const id = stringOrNull(data?.data?.id) ?? tokens.workspaceId;
|
|
135
|
+
const name = stringOrNull(data?.data?.name) ?? id;
|
|
136
|
+
if (id === tokens.workspaceId && name === tokens.workspaceId) return null;
|
|
137
|
+
return {
|
|
138
|
+
id,
|
|
139
|
+
name
|
|
140
|
+
};
|
|
141
|
+
} catch {
|
|
142
|
+
context.signal?.throwIfAborted();
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function createSingleWorkspaceTokenStorage(storage, initialTokens) {
|
|
147
|
+
let currentTokens = initialTokens;
|
|
148
|
+
return {
|
|
149
|
+
getTokens: async () => currentTokens,
|
|
150
|
+
setTokens: async (tokens) => {
|
|
151
|
+
currentTokens = tokens;
|
|
152
|
+
await storage.setTokens(tokens);
|
|
153
|
+
},
|
|
154
|
+
clearTokens: async () => {
|
|
155
|
+
const tokens = currentTokens;
|
|
156
|
+
currentTokens = null;
|
|
157
|
+
if (tokens) await storage.clearTokensIfCurrent(tokens);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function stringOrNull(value) {
|
|
162
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
163
|
+
}
|
|
164
|
+
function toAuthWorkspace(workspace) {
|
|
165
|
+
return {
|
|
166
|
+
id: workspace.id,
|
|
167
|
+
name: workspace.name
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
export { listAuthWorkspaces, logoutAuthWorkspace, switchAuthWorkspace };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/cli-command.ts
|
|
2
|
+
const PRISMA_CLI_PACKAGE_NAME = "@prisma/cli";
|
|
3
|
+
const PRISMA_CLI_PACKAGE_SPEC = `${PRISMA_CLI_PACKAGE_NAME}@latest`;
|
|
4
|
+
const DEFAULT_PRISMA_CLI_PACKAGE_RUNNER = ["npx", "-y"];
|
|
5
|
+
const PRISMA_CLI_BINARY = "prisma-cli";
|
|
6
|
+
function formatPrismaCliCommand(args, options = {}) {
|
|
7
|
+
return [...getPrismaCliCommandPrefix(options), ...args].join(" ");
|
|
8
|
+
}
|
|
9
|
+
function getPrismaCliCommandPrefix({ invocation = "package", packageRunner = DEFAULT_PRISMA_CLI_PACKAGE_RUNNER }) {
|
|
10
|
+
if (invocation === "binary") return [PRISMA_CLI_BINARY];
|
|
11
|
+
return [...packageRunner, PRISMA_CLI_PACKAGE_SPEC];
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { DEFAULT_PRISMA_CLI_PACKAGE_RUNNER, PRISMA_CLI_BINARY, PRISMA_CLI_PACKAGE_NAME, PRISMA_CLI_PACKAGE_SPEC, formatPrismaCliCommand };
|
package/dist/cli-name.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/cli-name.ts
|
|
2
|
+
/**
|
|
3
|
+
* The CLI's user-facing identity, in one place. The npm package is
|
|
4
|
+
* "@prisma/cli" but the binary on PATH is "prisma-cli" (the S1
|
|
5
|
+
* convention) — every user-facing command string and notice consumes
|
|
6
|
+
* this constant rather than restating the name.
|
|
7
|
+
*/
|
|
8
|
+
const CLI_NAME = "prisma-cli";
|
|
9
|
+
/** The CLI docs page (also the update-check fallback instruction URL). */
|
|
10
|
+
const CLI_DOCS_URL = "https://www.prisma.io/docs/orm/tools/prisma-cli";
|
|
11
|
+
//#endregion
|
|
12
|
+
export { CLI_DOCS_URL, CLI_NAME };
|
package/dist/cli.js
CHANGED
package/dist/cli2.js
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import { CliError } from "./
|
|
2
|
-
import "./shell/prompt.js";
|
|
1
|
+
import { CliError } from "./errors.js";
|
|
3
2
|
import { attachCommandDescriptor } from "./shell/command-meta.js";
|
|
4
|
-
import { addCompactGlobalFlags } from "./shell/global-flags.js";
|
|
5
3
|
import { createShellUi } from "./shell/ui.js";
|
|
4
|
+
import { addCompactGlobalFlags } from "./shell/global-flags.js";
|
|
6
5
|
import { configureRuntimeCommand, createCommandContext } from "./shell/runtime.js";
|
|
7
|
-
import { formatUnexpectedError, writeHumanError, writeJsonError, writeJsonSuccess } from "./shell/output.js";
|
|
6
|
+
import { formatUnexpectedError, unexpectedErrorFeedbackCommand, writeHumanError, writeJsonError, writeJsonSuccess, writeJsonUnexpectedError } from "./shell/output.js";
|
|
7
|
+
import { createAgentCommand } from "./commands/agent/index.js";
|
|
8
|
+
import "./shell/prompt.js";
|
|
8
9
|
import { createAppCommand } from "./commands/app/index.js";
|
|
9
10
|
import { createAuthCommand } from "./commands/auth/index.js";
|
|
10
11
|
import { createBranchCommand } from "./commands/branch/index.js";
|
|
12
|
+
import { createBucketCommand } from "./commands/bucket/index.js";
|
|
13
|
+
import { createBuildCommand } from "./commands/build/index.js";
|
|
11
14
|
import { createDatabaseCommand } from "./commands/database/index.js";
|
|
15
|
+
import { getCliName, getCliVersion } from "./lib/version.js";
|
|
16
|
+
import { createFeedbackCommand } from "./commands/feedback/index.js";
|
|
12
17
|
import { createGitCommand } from "./commands/git/index.js";
|
|
18
|
+
import { createInitCommand } from "./commands/init/index.js";
|
|
13
19
|
import { createProjectCommand } from "./commands/project/index.js";
|
|
14
|
-
import { getCliName, getCliVersion } from "./lib/version.js";
|
|
15
20
|
import { runVersion } from "./controllers/version.js";
|
|
16
21
|
import { createVersionCommand } from "./commands/version/index.js";
|
|
17
|
-
import { maybeWriteCachedUpdateNotification } from "./
|
|
22
|
+
import { maybeWriteCachedUpdateNotification } from "./update-check.js";
|
|
18
23
|
import process from "node:process";
|
|
19
24
|
import { Command, CommanderError, Option } from "commander";
|
|
20
25
|
//#region src/cli.ts
|
|
@@ -34,7 +39,15 @@ async function runCli(options = {}) {
|
|
|
34
39
|
return process.exitCode ?? 0;
|
|
35
40
|
} catch (error) {
|
|
36
41
|
if (error instanceof CommanderError) return error.code === "commander.helpDisplayed" ? 0 : 2;
|
|
37
|
-
|
|
42
|
+
if (runtime.argv.includes("--json")) {
|
|
43
|
+
writeJsonUnexpectedError({
|
|
44
|
+
stdout: runtime.stdout,
|
|
45
|
+
stderr: runtime.stderr
|
|
46
|
+
}, runtime.argv, error);
|
|
47
|
+
return 1;
|
|
48
|
+
}
|
|
49
|
+
const quiet = runtime.argv.includes("--quiet") || runtime.argv.includes("-q");
|
|
50
|
+
runtime.stderr.write(formatUnexpectedError(error, runtime.argv.includes("--trace"), quiet ? void 0 : unexpectedErrorFeedbackCommand(runtime.argv, error)));
|
|
38
51
|
return 1;
|
|
39
52
|
} finally {
|
|
40
53
|
runtime.stdin;
|
|
@@ -46,11 +59,16 @@ function createProgram(runtime) {
|
|
|
46
59
|
program.addOption(new Option("--version", "Print the CLI version and exit."));
|
|
47
60
|
program.name("prisma").showSuggestionAfterError();
|
|
48
61
|
program.addCommand(createVersionCommand(runtime));
|
|
62
|
+
program.addCommand(createInitCommand(runtime));
|
|
63
|
+
program.addCommand(createFeedbackCommand(runtime));
|
|
64
|
+
program.addCommand(createAgentCommand(runtime));
|
|
49
65
|
program.addCommand(createAuthCommand(runtime));
|
|
50
66
|
program.addCommand(createProjectCommand(runtime));
|
|
51
67
|
program.addCommand(createGitCommand(runtime));
|
|
52
68
|
program.addCommand(createBranchCommand(runtime));
|
|
69
|
+
program.addCommand(createBuildCommand(runtime));
|
|
53
70
|
program.addCommand(createDatabaseCommand(runtime));
|
|
71
|
+
program.addCommand(createBucketCommand(runtime));
|
|
54
72
|
program.addCommand(createAppCommand(runtime));
|
|
55
73
|
return program;
|
|
56
74
|
}
|
|
@@ -111,7 +129,6 @@ function resolveRuntime(options) {
|
|
|
111
129
|
stdin: options.stdin ?? process.stdin,
|
|
112
130
|
stdout: options.stdout ?? process.stdout,
|
|
113
131
|
stderr: options.stderr ?? process.stderr,
|
|
114
|
-
fixturePath: options.fixturePath,
|
|
115
132
|
stateDir: options.stateDir
|
|
116
133
|
};
|
|
117
134
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/command-arguments.ts
|
|
2
|
+
function formatCommandArgument(value) {
|
|
3
|
+
return /^[A-Za-z0-9._/-]+$/.test(value) && !value.startsWith("-") ? value : `'${value.replace(/'/g, "'\\''")}'`;
|
|
4
|
+
}
|
|
5
|
+
function formatShellCommand(command) {
|
|
6
|
+
return command.map(formatShellCommandWord).join(" ");
|
|
7
|
+
}
|
|
8
|
+
function formatShellCommandWord(value) {
|
|
9
|
+
return /^[A-Za-z0-9_./:@=-]+$/.test(value) ? value : `'${value.replace(/'/g, "'\\''")}'`;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { formatCommandArgument, formatShellCommand };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { runAgentInstall, runAgentStatus } from "../../controllers/agent.js";
|
|
2
|
+
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
3
|
+
import { renderAgentInstall, renderAgentStatus, serializeAgentInstall, serializeAgentStatus } from "../../presenters/agent.js";
|
|
4
|
+
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
5
|
+
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
6
|
+
import { runCommand } from "../../shell/command-runner.js";
|
|
7
|
+
import { Command, Option } from "commander";
|
|
8
|
+
//#region src/commands/agent/index.ts
|
|
9
|
+
function createAgentCommand(runtime) {
|
|
10
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("agent"), runtime), "agent");
|
|
11
|
+
addCompactGlobalFlags(command);
|
|
12
|
+
command.addCommand(createAgentInstallCommand(runtime));
|
|
13
|
+
command.addCommand(createAgentUpdateCommand(runtime));
|
|
14
|
+
command.addCommand(createAgentStatusCommand(runtime));
|
|
15
|
+
return command;
|
|
16
|
+
}
|
|
17
|
+
function createAgentInstallCommand(runtime) {
|
|
18
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("install"), runtime), "agent.install");
|
|
19
|
+
addAgentInstallOptions(command);
|
|
20
|
+
addGlobalFlags(command);
|
|
21
|
+
command.action(async (options) => {
|
|
22
|
+
await runCommand(runtime, "agent.install", options, (context) => runAgentInstall(context, options, "install"), {
|
|
23
|
+
renderHuman: (context, descriptor, result) => renderAgentInstall(context, descriptor, result),
|
|
24
|
+
renderJson: (result) => serializeAgentInstall(result)
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
return command;
|
|
28
|
+
}
|
|
29
|
+
function createAgentUpdateCommand(runtime) {
|
|
30
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("update"), runtime), "agent.update");
|
|
31
|
+
addAgentInstallOptions(command);
|
|
32
|
+
addGlobalFlags(command);
|
|
33
|
+
command.action(async (options) => {
|
|
34
|
+
await runCommand(runtime, "agent.update", options, (context) => runAgentInstall(context, options, "update"), {
|
|
35
|
+
renderHuman: (context, descriptor, result) => renderAgentInstall(context, descriptor, result),
|
|
36
|
+
renderJson: (result) => serializeAgentInstall(result)
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
return command;
|
|
40
|
+
}
|
|
41
|
+
function createAgentStatusCommand(runtime) {
|
|
42
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("status"), runtime), "agent.status");
|
|
43
|
+
command.addOption(new Option("--global", "Check globally installed Prisma skills instead of project skills"));
|
|
44
|
+
addGlobalFlags(command);
|
|
45
|
+
command.action(async (options) => {
|
|
46
|
+
await runCommand(runtime, "agent.status", options, (context) => runAgentStatus(context, options), {
|
|
47
|
+
renderHuman: (context, descriptor, result) => renderAgentStatus(context, descriptor, result),
|
|
48
|
+
renderJson: (result) => serializeAgentStatus(result)
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
return command;
|
|
52
|
+
}
|
|
53
|
+
function addAgentInstallOptions(command) {
|
|
54
|
+
command.addOption(new Option("--agent <agent>", "Agent target for Prisma skills; repeat for multiple agents").argParser(collectValues)).addOption(new Option("--all-agents", "Install Prisma skills for every agent supported by the skills CLI")).addOption(new Option("--skill <skill>", "Prisma skill to install; repeat for multiple skills").argParser(collectValues)).addOption(new Option("--global", "Install skills into the user directory instead of the project")).addOption(new Option("--copy", "Ask the skills CLI to copy files instead of symlinking them")).addOption(new Option("--dry-run", "Show changes without writing files"));
|
|
55
|
+
}
|
|
56
|
+
function collectValues(value, previous) {
|
|
57
|
+
return [...previous ?? [], value];
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { createAgentCommand };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { usageError } from "../../
|
|
2
|
-
import { APP_BUILD_TYPES } from "../../lib/app/build.js";
|
|
1
|
+
import { usageError } from "../../errors.js";
|
|
3
2
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
4
3
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
5
4
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
5
|
+
import { runCommand, runStreamingCommand } from "../../shell/command-runner.js";
|
|
6
|
+
import { APP_BUILD_TYPES } from "../../lib/app/build.js";
|
|
6
7
|
import { runAppBuild, runAppDeploy, runAppDomainAdd, runAppDomainRemove, runAppDomainRetry, runAppDomainShow, runAppDomainWait, runAppListDeploys, runAppLogs, runAppOpen, runAppPromote, runAppRemove, runAppRollback, runAppRun, runAppShow, runAppShowDeploy } from "../../controllers/app.js";
|
|
7
8
|
import { isAppDeployAllResult, renderAppBuild, renderAppDeploy, renderAppDeployAll, renderAppDomainAdd, renderAppDomainRemove, renderAppDomainRetry, renderAppDomainShow, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppDeployAll, serializeAppDomainAdd, serializeAppDomainRemove, serializeAppDomainRetry, serializeAppDomainShow, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy } from "../../presenters/app.js";
|
|
8
|
-
import { runCommand, runStreamingCommand } from "../../shell/command-runner.js";
|
|
9
9
|
import { Command, Option } from "commander";
|
|
10
10
|
import { FRAMEWORK_KEYS, LOCAL_DEV_BUILD_TYPES } from "@prisma/compute-sdk/config";
|
|
11
11
|
//#region src/commands/app/index.ts
|
|
@@ -66,7 +66,7 @@ function createRunCommand(runtime) {
|
|
|
66
66
|
}
|
|
67
67
|
function createDeployCommand(runtime) {
|
|
68
68
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("deploy"), runtime), "app.deploy");
|
|
69
|
-
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--create-project <name>", "Create and link a new Project before deploying")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([...FRAMEWORK_KEYS])).addOption(new Option("--entry <path>", "Entrypoint path for Bun deploys")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--env <name=value|file>", "Environment variable assignment or dotenv file").argParser(collectRepeatableValues)).addOption(new Option("--db", "Create and wire a Prisma Postgres database for this deploy target")).addOption(new Option("--no-db", "Skip database setup")).addOption(new Option("--prod", "Confirm intent to deploy to production"));
|
|
69
|
+
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--create-project <name>", "Create and link a new Project before deploying")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([...FRAMEWORK_KEYS])).addOption(new Option("--entry <path>", "Entrypoint path for Bun deploys")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--region <region>", "Region for a newly created app; existing apps keep their region")).addOption(new Option("--env <name=value|file>", "Environment variable assignment or dotenv file").argParser(collectRepeatableValues)).addOption(new Option("--db", "Create and wire a Prisma Postgres database for this deploy target")).addOption(new Option("--no-db", "Skip database setup")).addOption(new Option("--prod", "Confirm intent to deploy to production")).addOption(new Option("--no-promote", "Build the new deployment without promoting it to live (promote later with app promote <id>)"));
|
|
70
70
|
addGlobalFlags(command);
|
|
71
71
|
command.action(async (configTarget, options) => {
|
|
72
72
|
const appName = options.app;
|
|
@@ -74,10 +74,12 @@ function createDeployCommand(runtime) {
|
|
|
74
74
|
const branchName = options.branch;
|
|
75
75
|
const framework = options.framework;
|
|
76
76
|
const httpPort = options.httpPort;
|
|
77
|
+
const region = options.region;
|
|
77
78
|
const envAssignments = options.env;
|
|
78
79
|
const projectRef = options.project;
|
|
79
80
|
const createProjectName = options.createProject;
|
|
80
81
|
const prod = options.prod;
|
|
82
|
+
const noPromote = options.promote === false;
|
|
81
83
|
const db = options.db;
|
|
82
84
|
const hasDbConflict = hasFlag(runtime.argv, "--db") && hasFlag(runtime.argv, "--no-db");
|
|
83
85
|
await runCommand(runtime, "app.deploy", options, (context) => {
|
|
@@ -89,8 +91,10 @@ function createDeployCommand(runtime) {
|
|
|
89
91
|
entrypoint: entry,
|
|
90
92
|
framework,
|
|
91
93
|
httpPort,
|
|
94
|
+
region,
|
|
92
95
|
envAssignments,
|
|
93
96
|
prod: prod === true,
|
|
97
|
+
noPromote,
|
|
94
98
|
db,
|
|
95
99
|
configTarget
|
|
96
100
|
});
|
|
@@ -329,12 +333,13 @@ function createRollbackCommand(runtime) {
|
|
|
329
333
|
}
|
|
330
334
|
function createRemoveCommand(runtime) {
|
|
331
335
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "app.remove");
|
|
332
|
-
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
336
|
+
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").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"));
|
|
333
337
|
addGlobalFlags(command);
|
|
334
338
|
command.action(async (configTarget, options) => {
|
|
335
339
|
const appName = options.app;
|
|
336
340
|
const projectRef = options.project;
|
|
337
|
-
|
|
341
|
+
const branchName = options.branch;
|
|
342
|
+
await runCommand(runtime, "app.remove", options, (context) => runAppRemove(context, appName, projectRef, configTarget, branchName), {
|
|
338
343
|
renderHuman: (context, descriptor, result) => renderAppRemove(context, descriptor, result),
|
|
339
344
|
renderJson: (result) => serializeAppRemove(result)
|
|
340
345
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
2
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runAuthLogin, runAuthLogout, runAuthWhoAmI, runAuthWorkspaceList, runAuthWorkspaceLogout, runAuthWorkspaceUse } from "../../controllers/auth.js";
|
|
5
4
|
import { runCommand } from "../../shell/command-runner.js";
|
|
5
|
+
import { runAuthLogin, runAuthLogout, runAuthWhoAmI, runAuthWorkspaceList, runAuthWorkspaceLogout, runAuthWorkspaceUse } from "../../controllers/auth.js";
|
|
6
6
|
import { renderAuthSuccess, renderAuthWorkspaceList, renderAuthWorkspaceLogout, renderAuthWorkspaceUse, serializeAuthWorkspaceList, serializeAuthWorkspaceLogout, serializeAuthWorkspaceUse } from "../../presenters/auth.js";
|
|
7
7
|
import { Command, Option } from "commander";
|
|
8
8
|
//#region src/commands/auth/index.ts
|
|
@@ -17,10 +17,9 @@ function createAuthCommand(runtime) {
|
|
|
17
17
|
}
|
|
18
18
|
function createAuthLoginCommand(runtime) {
|
|
19
19
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("login"), runtime), "auth.login");
|
|
20
|
-
command.addOption(new Option("--provider <provider>").hideHelp()).addOption(new Option("--user <id>").hideHelp()).addOption(new Option("--workspace <id>").hideHelp());
|
|
21
20
|
addGlobalFlags(command);
|
|
22
21
|
command.action(async (options) => {
|
|
23
|
-
await runCommand(runtime, "auth.login", options, (context) => runAuthLogin(context
|
|
22
|
+
await runCommand(runtime, "auth.login", options, (context) => runAuthLogin(context), { renderHuman: (context, descriptor, result) => renderAuthSuccess(context, descriptor, "auth.login", result) });
|
|
24
23
|
});
|
|
25
24
|
return command;
|
|
26
25
|
}
|
|
@@ -0,0 +1,123 @@
|
|
|
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 { runCommand } from "../../shell/command-runner.js";
|
|
5
|
+
import { runBucketCreate, runBucketDelete, runBucketKeyCreate, runBucketKeyDelete, runBucketKeyList, runBucketList } from "../../controllers/bucket.js";
|
|
6
|
+
import { renderBucketCreate, renderBucketDelete, renderBucketKeyCreate, renderBucketKeyCreateStdout, renderBucketKeyDelete, renderBucketKeyList, renderBucketList, serializeBucketCreate, serializeBucketDelete, serializeBucketKeyCreate, serializeBucketKeyDelete, serializeBucketKeyList, serializeBucketList } from "../../presenters/bucket.js";
|
|
7
|
+
import { Command, Option } from "commander";
|
|
8
|
+
//#region src/commands/bucket/index.ts
|
|
9
|
+
function createBucketCommand(runtime) {
|
|
10
|
+
const bucket = attachCommandDescriptor(configureRuntimeCommand(new Command("bucket"), runtime), "bucket");
|
|
11
|
+
addCompactGlobalFlags(bucket);
|
|
12
|
+
bucket.addCommand(createBucketListCommand(runtime));
|
|
13
|
+
bucket.addCommand(createBucketCreateCommand(runtime));
|
|
14
|
+
bucket.addCommand(createBucketDeleteCommand(runtime));
|
|
15
|
+
bucket.addCommand(createBucketKeyCommand(runtime));
|
|
16
|
+
return bucket;
|
|
17
|
+
}
|
|
18
|
+
function addProjectAndBranchOptions(command) {
|
|
19
|
+
return command.addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--branch <git-name>", "Branch git name"));
|
|
20
|
+
}
|
|
21
|
+
function createBucketListCommand(runtime) {
|
|
22
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "bucket.list");
|
|
23
|
+
addProjectAndBranchOptions(command);
|
|
24
|
+
addGlobalFlags(command);
|
|
25
|
+
command.action(async (options) => {
|
|
26
|
+
const projectRef = options.project;
|
|
27
|
+
const branchName = options.branch;
|
|
28
|
+
await runCommand(runtime, "bucket.list", options, (context) => runBucketList(context, {
|
|
29
|
+
projectRef,
|
|
30
|
+
branchName
|
|
31
|
+
}), {
|
|
32
|
+
renderHuman: (context, descriptor, result) => renderBucketList(context, descriptor, result),
|
|
33
|
+
renderJson: (result) => serializeBucketList(result)
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
return command;
|
|
37
|
+
}
|
|
38
|
+
function createBucketCreateCommand(runtime) {
|
|
39
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("create"), runtime), "bucket.create");
|
|
40
|
+
command.addOption(new Option("--name <name>", "Bucket display name (auto-generated if omitted)"));
|
|
41
|
+
addProjectAndBranchOptions(command);
|
|
42
|
+
addGlobalFlags(command);
|
|
43
|
+
command.action(async (options) => {
|
|
44
|
+
const projectRef = options.project;
|
|
45
|
+
const branchName = options.branch;
|
|
46
|
+
const name = options.name;
|
|
47
|
+
await runCommand(runtime, "bucket.create", options, (context) => runBucketCreate(context, {
|
|
48
|
+
projectRef,
|
|
49
|
+
branchName,
|
|
50
|
+
name
|
|
51
|
+
}), {
|
|
52
|
+
renderHuman: (context, descriptor, result) => renderBucketCreate(context, descriptor, result),
|
|
53
|
+
renderJson: (result) => serializeBucketCreate(result)
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
return command;
|
|
57
|
+
}
|
|
58
|
+
function createBucketDeleteCommand(runtime) {
|
|
59
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("delete"), runtime), "bucket.delete");
|
|
60
|
+
command.argument("<bucketId>", "Bucket id");
|
|
61
|
+
command.addOption(new Option("--confirm <bucket-id>", "Exact bucket id to confirm deletion"));
|
|
62
|
+
addGlobalFlags(command);
|
|
63
|
+
command.action(async (bucketId, options) => {
|
|
64
|
+
const confirm = options.confirm;
|
|
65
|
+
await runCommand(runtime, "bucket.delete", options, (context) => runBucketDelete(context, bucketId, { confirm }), {
|
|
66
|
+
renderHuman: (context, descriptor, result) => renderBucketDelete(context, descriptor, result),
|
|
67
|
+
renderJson: (result) => serializeBucketDelete(result)
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
return command;
|
|
71
|
+
}
|
|
72
|
+
function createBucketKeyCommand(runtime) {
|
|
73
|
+
const key = attachCommandDescriptor(configureRuntimeCommand(new Command("key"), runtime), "bucket.key");
|
|
74
|
+
addCompactGlobalFlags(key);
|
|
75
|
+
key.addCommand(createBucketKeyListCommand(runtime));
|
|
76
|
+
key.addCommand(createBucketKeyCreateCommand(runtime));
|
|
77
|
+
key.addCommand(createBucketKeyDeleteCommand(runtime));
|
|
78
|
+
return key;
|
|
79
|
+
}
|
|
80
|
+
function createBucketKeyListCommand(runtime) {
|
|
81
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "bucket.key.list");
|
|
82
|
+
command.argument("<bucketId>", "Bucket id");
|
|
83
|
+
addGlobalFlags(command);
|
|
84
|
+
command.action(async (bucketId, options) => {
|
|
85
|
+
await runCommand(runtime, "bucket.key.list", options, (context) => runBucketKeyList(context, bucketId), {
|
|
86
|
+
renderHuman: (context, descriptor, result) => renderBucketKeyList(context, descriptor, result),
|
|
87
|
+
renderJson: (result) => serializeBucketKeyList(result)
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
return command;
|
|
91
|
+
}
|
|
92
|
+
function createBucketKeyCreateCommand(runtime) {
|
|
93
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("create"), runtime), "bucket.key.create");
|
|
94
|
+
command.argument("<bucketId>", "Bucket id").addOption(new Option("--role <role>", "Access role (default: read_write)").choices(["read", "read_write"])).addOption(new Option("--name <name>", "Key display name (auto-generated if omitted)"));
|
|
95
|
+
addGlobalFlags(command);
|
|
96
|
+
command.action(async (bucketId, options) => {
|
|
97
|
+
const role = options.role;
|
|
98
|
+
const name = options.name;
|
|
99
|
+
await runCommand(runtime, "bucket.key.create", options, (context) => runBucketKeyCreate(context, bucketId, {
|
|
100
|
+
role,
|
|
101
|
+
name
|
|
102
|
+
}), {
|
|
103
|
+
renderStdout: (context, descriptor, result) => renderBucketKeyCreateStdout(context, descriptor, result),
|
|
104
|
+
renderHuman: (context, descriptor, result) => renderBucketKeyCreate(context, descriptor, result),
|
|
105
|
+
renderJson: (result) => serializeBucketKeyCreate(result)
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
return command;
|
|
109
|
+
}
|
|
110
|
+
function createBucketKeyDeleteCommand(runtime) {
|
|
111
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("delete"), runtime), "bucket.key.delete");
|
|
112
|
+
command.argument("<bucketId>", "Bucket id").argument("<keyId>", "Key id");
|
|
113
|
+
addGlobalFlags(command);
|
|
114
|
+
command.action(async (bucketId, keyId, options) => {
|
|
115
|
+
await runCommand(runtime, "bucket.key.delete", options, (context) => runBucketKeyDelete(context, bucketId, keyId), {
|
|
116
|
+
renderHuman: (context, descriptor, result) => renderBucketKeyDelete(context, descriptor, result),
|
|
117
|
+
renderJson: (result) => serializeBucketKeyDelete(result)
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
return command;
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { createBucketCommand };
|
|
@@ -0,0 +1,29 @@
|
|
|
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 { runStreamingCommand } from "../../shell/command-runner.js";
|
|
5
|
+
import { runBuildLogs } from "../../controllers/build.js";
|
|
6
|
+
import { Command, Option } from "commander";
|
|
7
|
+
//#region src/commands/build/index.ts
|
|
8
|
+
function createBuildCommand(runtime) {
|
|
9
|
+
const build = attachCommandDescriptor(configureRuntimeCommand(new Command("build"), runtime), "build");
|
|
10
|
+
addCompactGlobalFlags(build);
|
|
11
|
+
build.addCommand(createLogsCommand(runtime));
|
|
12
|
+
return build;
|
|
13
|
+
}
|
|
14
|
+
function createLogsCommand(runtime) {
|
|
15
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("logs"), runtime), "build.logs");
|
|
16
|
+
command.argument("<buildId>", "Build id from a git-push or Console deploy").addOption(new Option("--follow", "Keep the connection open and stream new logs as the build runs")).addOption(new Option("--cursor <cursor>", "Resume from a prior terminal cursor"));
|
|
17
|
+
addGlobalFlags(command);
|
|
18
|
+
command.action(async (buildId, options) => {
|
|
19
|
+
const follow = options.follow;
|
|
20
|
+
const cursor = options.cursor;
|
|
21
|
+
await runStreamingCommand(runtime, "build.logs", options, (context) => runBuildLogs(context, buildId, {
|
|
22
|
+
follow,
|
|
23
|
+
cursor
|
|
24
|
+
}), { emitJsonSuccessEvent: false });
|
|
25
|
+
});
|
|
26
|
+
return command;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { createBuildCommand };
|