@prisma/cli 3.0.0-alpha.1 → 3.0.0-alpha.3
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/cli2.js +2 -0
- package/dist/commands/app/index.js +4 -3
- package/dist/commands/auth/index.js +2 -1
- package/dist/commands/branch/index.js +2 -1
- package/dist/commands/env.js +71 -0
- package/dist/commands/project/index.js +4 -1
- package/dist/controllers/app-env.js +221 -0
- package/dist/controllers/app.js +234 -78
- package/dist/controllers/auth.js +7 -7
- package/dist/controllers/branch.js +5 -5
- package/dist/controllers/project.js +14 -14
- package/dist/lib/app/env-config.js +46 -0
- package/dist/lib/app/env-vars.js +4 -4
- package/dist/lib/app/preview-provider.js +15 -2
- package/dist/lib/auth/auth-ops.js +6 -6
- package/dist/lib/auth/login.js +115 -4
- package/dist/output/patterns.js +15 -17
- package/dist/presenters/app-env.js +129 -0
- package/dist/presenters/auth.js +2 -2
- package/dist/shell/command-meta.js +115 -88
- package/dist/shell/command-runner.js +32 -2
- package/dist/shell/errors.js +2 -2
- package/dist/shell/global-flags.js +12 -1
- package/dist/shell/help.js +8 -7
- package/dist/shell/output.js +18 -12
- package/dist/shell/runtime.js +1 -1
- package/dist/shell/ui.js +19 -1
- package/dist/use-cases/auth.js +5 -5
- package/dist/use-cases/create-cli-gateways.js +1 -1
- package/dist/use-cases/project.js +2 -2
- package/package.json +2 -2
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
|
|
package/dist/cli2.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "./shell/command-meta.js";
|
|
2
|
+
import { addCompactGlobalFlags } from "./shell/global-flags.js";
|
|
2
3
|
import { configureRuntimeCommand } from "./shell/runtime.js";
|
|
3
4
|
import "./shell/prompt.js";
|
|
4
5
|
import { createAppCommand } from "./commands/app/index.js";
|
|
@@ -31,6 +32,7 @@ async function runCli(options = {}) {
|
|
|
31
32
|
}
|
|
32
33
|
function createProgram(runtime) {
|
|
33
34
|
const program = attachCommandDescriptor(configureRuntimeCommand(new Command(), runtime), "root");
|
|
35
|
+
addCompactGlobalFlags(program);
|
|
34
36
|
program.name("prisma").showSuggestionAfterError();
|
|
35
37
|
program.addCommand(createAuthCommand(runtime));
|
|
36
38
|
program.addCommand(createBranchCommand(runtime));
|
|
@@ -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));
|
|
@@ -139,7 +140,7 @@ function createLogsCommand(runtime) {
|
|
|
139
140
|
command.action(async (options) => {
|
|
140
141
|
const appName = options.app;
|
|
141
142
|
const deploymentId = options.deployment;
|
|
142
|
-
await
|
|
143
|
+
await runStreamingCommand(runtime, "app.logs", options, (context) => runAppLogs(context, appName, deploymentId));
|
|
143
144
|
});
|
|
144
145
|
return command;
|
|
145
146
|
}
|
|
@@ -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 { runAuthLogin, runAuthLogout, runAuthWhoAmI } from "../../controllers/auth.js";
|
|
@@ -8,6 +8,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,71 @@
|
|
|
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 linked 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 in KEY=VALUE form").addOption(new Option("--role <role>", "Project template scope (production or preview)").choices(["production", "preview"]));
|
|
21
|
+
addGlobalFlags(command);
|
|
22
|
+
command.action(async (assignment, options) => {
|
|
23
|
+
const roleName = options.role;
|
|
24
|
+
await runCommand(runtime, "project.env.add", options, (context) => runEnvAdd(context, assignment, { roleName }), {
|
|
25
|
+
renderHuman: (context, descriptor, result) => renderEnvAdd(context, descriptor, result),
|
|
26
|
+
renderJson: (result) => serializeEnvAdd(result)
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
return command;
|
|
30
|
+
}
|
|
31
|
+
function createEnvUpdateCommand(runtime) {
|
|
32
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("update"), runtime), "project.env.update");
|
|
33
|
+
command.argument("<assignment>", "Variable assignment in KEY=VALUE form").addOption(new Option("--role <role>", "Project template scope (production or preview)").choices(["production", "preview"]));
|
|
34
|
+
addGlobalFlags(command);
|
|
35
|
+
command.action(async (assignment, options) => {
|
|
36
|
+
const roleName = options.role;
|
|
37
|
+
await runCommand(runtime, "project.env.update", options, (context) => runEnvUpdate(context, assignment, { roleName }), {
|
|
38
|
+
renderHuman: (context, descriptor, result) => renderEnvUpdate(context, descriptor, result),
|
|
39
|
+
renderJson: (result) => serializeEnvUpdate(result)
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return command;
|
|
43
|
+
}
|
|
44
|
+
function createEnvListCommand(runtime) {
|
|
45
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "project.env.list");
|
|
46
|
+
command.addOption(new Option("--role <role>", "Project template scope").choices(["production", "preview"]));
|
|
47
|
+
addGlobalFlags(command);
|
|
48
|
+
command.action(async (options) => {
|
|
49
|
+
const roleName = options.role;
|
|
50
|
+
await runCommand(runtime, "project.env.list", options, (context) => runEnvList(context, { roleName }), {
|
|
51
|
+
renderHuman: (context, descriptor, result) => renderEnvList(context, descriptor, result),
|
|
52
|
+
renderJson: (result) => serializeEnvList(result)
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
return command;
|
|
56
|
+
}
|
|
57
|
+
function createEnvRmCommand(runtime) {
|
|
58
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("rm"), runtime), "project.env.rm");
|
|
59
|
+
command.argument("<key>", "Variable key to remove").addOption(new Option("--role <role>", "Project template scope (production or preview)").choices(["production", "preview"]));
|
|
60
|
+
addGlobalFlags(command);
|
|
61
|
+
command.action(async (key, options) => {
|
|
62
|
+
const roleName = options.role;
|
|
63
|
+
await runCommand(runtime, "project.env.rm", options, (context) => runEnvRm(context, key, { roleName }), {
|
|
64
|
+
renderHuman: (context, descriptor, result) => renderEnvRm(context, descriptor, result),
|
|
65
|
+
renderJson: (result) => serializeEnvRm(result)
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
return command;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { createEnvCommand };
|
|
@@ -1,16 +1,19 @@
|
|
|
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 { runProjectLink, runProjectList, runProjectShow } from "../../controllers/project.js";
|
|
6
6
|
import { renderProjectLink, renderProjectList, renderProjectShow, serializeProjectList } from "../../presenters/project.js";
|
|
7
|
+
import { createEnvCommand } from "../env.js";
|
|
7
8
|
import { Command } from "commander";
|
|
8
9
|
//#region src/commands/project/index.ts
|
|
9
10
|
function createProjectCommand(runtime) {
|
|
10
11
|
const project = attachCommandDescriptor(configureRuntimeCommand(new Command("project"), runtime), "project");
|
|
12
|
+
addCompactGlobalFlags(project);
|
|
11
13
|
project.addCommand(createProjectListCommand(runtime));
|
|
12
14
|
project.addCommand(createProjectShowCommand(runtime));
|
|
13
15
|
project.addCommand(createProjectLinkCommand(runtime));
|
|
16
|
+
project.addCommand(createEnvCommand(runtime));
|
|
14
17
|
return project;
|
|
15
18
|
}
|
|
16
19
|
function createProjectListCommand(runtime) {
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { readLinkedProjectId } from "../adapters/config.js";
|
|
2
|
+
import { CliError, authRequiredError, usageError } from "../shell/errors.js";
|
|
3
|
+
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
4
|
+
import { formatScopeLabel, parseKeyValuePositional, resolveEnvScope } from "../lib/app/env-config.js";
|
|
5
|
+
//#region src/controllers/app-env.ts
|
|
6
|
+
function defaultRoleScope() {
|
|
7
|
+
return {
|
|
8
|
+
kind: "role",
|
|
9
|
+
role: "production"
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
async function runEnvAdd(context, rawAssignment, flags) {
|
|
13
|
+
const { key, value } = parseKeyValuePositional(rawAssignment, "add");
|
|
14
|
+
const scope = resolveEnvScope(flags, {
|
|
15
|
+
requireExplicit: true,
|
|
16
|
+
command: "add"
|
|
17
|
+
});
|
|
18
|
+
if (!scope) throw usageError(`prisma-cli project env add requires --role`, "Writing without an explicit scope is rejected.", "Pass --role production or --role preview.", [`prisma-cli project env add ${key}=${value} --role production`], "app");
|
|
19
|
+
const { client, projectId } = await requireClientAndProject(context);
|
|
20
|
+
const resolved = resolveScopeToApi(scope);
|
|
21
|
+
if (await findVariableByNaturalKey(client, projectId, key, resolved)) throw new CliError({
|
|
22
|
+
code: "ENV_VARIABLE_ALREADY_EXISTS",
|
|
23
|
+
domain: "app",
|
|
24
|
+
summary: `Variable "${key}" already exists in ${formatScopeLabel(scope)}`,
|
|
25
|
+
why: "A variable with this key already exists in the targeted scope.",
|
|
26
|
+
fix: "Use `prisma-cli project env update` to change an existing variable's value.",
|
|
27
|
+
exitCode: 1,
|
|
28
|
+
nextSteps: [`prisma-cli project env update ${key}=<new-value> --role ${scope.role}`]
|
|
29
|
+
});
|
|
30
|
+
const { data, error, response } = await client.POST("/v1/environment-variables", { body: {
|
|
31
|
+
projectId,
|
|
32
|
+
class: resolved.apiTarget.class,
|
|
33
|
+
key,
|
|
34
|
+
value
|
|
35
|
+
} });
|
|
36
|
+
if (error || !data) throw apiCallError(`Failed to add ${key}`, response, error);
|
|
37
|
+
return {
|
|
38
|
+
command: "project.env.add",
|
|
39
|
+
result: {
|
|
40
|
+
projectId,
|
|
41
|
+
scope: resolved.descriptor,
|
|
42
|
+
variable: toMetadata(data.data, resolved.descriptor)
|
|
43
|
+
},
|
|
44
|
+
warnings: [],
|
|
45
|
+
nextSteps: []
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function runEnvUpdate(context, rawAssignment, flags) {
|
|
49
|
+
const { key, value } = parseKeyValuePositional(rawAssignment, "update");
|
|
50
|
+
const scope = resolveEnvScope(flags, {
|
|
51
|
+
requireExplicit: true,
|
|
52
|
+
command: "update"
|
|
53
|
+
});
|
|
54
|
+
if (!scope) throw usageError(`prisma-cli project env update requires --role`, "Writing without an explicit scope is rejected.", "Pass --role production or --role preview.", [`prisma-cli project env update ${key}=${value} --role production`], "app");
|
|
55
|
+
const { client, projectId } = await requireClientAndProject(context);
|
|
56
|
+
const resolved = resolveScopeToApi(scope);
|
|
57
|
+
const existing = await findVariableByNaturalKey(client, projectId, key, resolved);
|
|
58
|
+
if (!existing) throw new CliError({
|
|
59
|
+
code: "ENV_VARIABLE_NOT_FOUND",
|
|
60
|
+
domain: "app",
|
|
61
|
+
summary: `Variable "${key}" not found in ${formatScopeLabel(scope)}`,
|
|
62
|
+
why: "No variable with this key exists in the targeted scope.",
|
|
63
|
+
fix: "Use `prisma-cli project env add` to create a new variable.",
|
|
64
|
+
exitCode: 1,
|
|
65
|
+
nextSteps: [`prisma-cli project env add ${key}=<value> --role ${scope.role}`]
|
|
66
|
+
});
|
|
67
|
+
const { data, error, response } = await client.PATCH("/v1/environment-variables/{envVarId}", {
|
|
68
|
+
params: { path: { envVarId: existing.id } },
|
|
69
|
+
body: { value }
|
|
70
|
+
});
|
|
71
|
+
if (error || !data) throw apiCallError(`Failed to update value for ${key}`, response, error);
|
|
72
|
+
return {
|
|
73
|
+
command: "project.env.update",
|
|
74
|
+
result: {
|
|
75
|
+
projectId,
|
|
76
|
+
scope: resolved.descriptor,
|
|
77
|
+
variable: toMetadata(data.data, resolved.descriptor)
|
|
78
|
+
},
|
|
79
|
+
warnings: [],
|
|
80
|
+
nextSteps: []
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async function runEnvList(context, flags) {
|
|
84
|
+
const scope = resolveEnvScope(flags, {
|
|
85
|
+
requireExplicit: false,
|
|
86
|
+
command: "list"
|
|
87
|
+
}) ?? defaultRoleScope();
|
|
88
|
+
const { client, projectId } = await requireClientAndProject(context);
|
|
89
|
+
const resolved = resolveScopeToApi(scope);
|
|
90
|
+
const variables = await listVariables(client, projectId, resolved);
|
|
91
|
+
return {
|
|
92
|
+
command: "project.env.list",
|
|
93
|
+
result: {
|
|
94
|
+
projectId,
|
|
95
|
+
scope: resolved.descriptor,
|
|
96
|
+
variables: variables.map((row) => toMetadata(row, resolved.descriptor))
|
|
97
|
+
},
|
|
98
|
+
warnings: [],
|
|
99
|
+
nextSteps: variables.length === 0 ? [`prisma-cli project env add KEY=value --role ${scope.role}`] : []
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function runEnvRm(context, key, flags) {
|
|
103
|
+
if (!key) throw usageError("prisma-cli project env rm requires KEY", "No KEY positional argument was supplied.", "Pass the variable name to remove, e.g. STRIPE_KEY.", ["prisma-cli project env rm STRIPE_KEY --role production"], "app");
|
|
104
|
+
const scope = resolveEnvScope(flags, {
|
|
105
|
+
requireExplicit: true,
|
|
106
|
+
command: "rm"
|
|
107
|
+
});
|
|
108
|
+
if (!scope) throw usageError("prisma-cli project env rm requires --role", "Writing without an explicit scope is rejected.", "Pass --role production or --role preview.", [`prisma-cli project env rm ${key} --role production`], "app");
|
|
109
|
+
const { client, projectId } = await requireClientAndProject(context);
|
|
110
|
+
const resolved = resolveScopeToApi(scope);
|
|
111
|
+
const existing = await findVariableByNaturalKey(client, projectId, key, resolved);
|
|
112
|
+
if (!existing) throw new CliError({
|
|
113
|
+
code: "ENV_VARIABLE_NOT_FOUND",
|
|
114
|
+
domain: "app",
|
|
115
|
+
summary: `Variable "${key}" not found in ${formatScopeLabel(scope)}`,
|
|
116
|
+
why: "No variable with this key exists in the targeted scope, so there is nothing to remove.",
|
|
117
|
+
fix: "Run prisma-cli project env list with the same scope to see the available variables.",
|
|
118
|
+
exitCode: 1,
|
|
119
|
+
nextSteps: [`prisma-cli project env list --role ${scope.role}`]
|
|
120
|
+
});
|
|
121
|
+
const { error, response } = await client.DELETE("/v1/environment-variables/{envVarId}", { params: { path: { envVarId: existing.id } } });
|
|
122
|
+
if (error) throw apiCallError(`Failed to remove ${key}`, response, error);
|
|
123
|
+
return {
|
|
124
|
+
command: "project.env.rm",
|
|
125
|
+
result: {
|
|
126
|
+
projectId,
|
|
127
|
+
scope: resolved.descriptor,
|
|
128
|
+
key
|
|
129
|
+
},
|
|
130
|
+
warnings: [],
|
|
131
|
+
nextSteps: []
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
async function requireClientAndProject(context) {
|
|
135
|
+
const projectId = await readLinkedProjectId(context.runtime.cwd);
|
|
136
|
+
if (!projectId) throw new CliError({
|
|
137
|
+
code: "PROJECT_NOT_LINKED",
|
|
138
|
+
domain: "project",
|
|
139
|
+
summary: "Project link required",
|
|
140
|
+
why: "prisma-cli project env needs a linked project for the current repo.",
|
|
141
|
+
fix: "Run prisma project link before managing environment variables.",
|
|
142
|
+
exitCode: 1,
|
|
143
|
+
nextSteps: ["prisma project link"]
|
|
144
|
+
});
|
|
145
|
+
const client = await requireComputeAuth(context.runtime.env);
|
|
146
|
+
if (!client) throw authRequiredError(["prisma auth login"]);
|
|
147
|
+
return {
|
|
148
|
+
client,
|
|
149
|
+
projectId
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function resolveScopeToApi(scope) {
|
|
153
|
+
return {
|
|
154
|
+
scope,
|
|
155
|
+
descriptor: {
|
|
156
|
+
kind: "role",
|
|
157
|
+
role: scope.role
|
|
158
|
+
},
|
|
159
|
+
apiTarget: {
|
|
160
|
+
class: scope.role,
|
|
161
|
+
branchId: null
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
async function findVariableByNaturalKey(client, projectId, key, resolved) {
|
|
166
|
+
const { data, error, response } = await client.GET("/v1/environment-variables", { params: { query: {
|
|
167
|
+
projectId,
|
|
168
|
+
class: resolved.apiTarget.class,
|
|
169
|
+
key
|
|
170
|
+
} } });
|
|
171
|
+
if (error || !data) throw apiCallError(`Failed to look up ${key}`, response, error);
|
|
172
|
+
return data.data.filter((row) => rowMatchesScope(row, resolved))[0] ?? null;
|
|
173
|
+
}
|
|
174
|
+
async function listVariables(client, projectId, resolved) {
|
|
175
|
+
const collected = [];
|
|
176
|
+
let cursor;
|
|
177
|
+
while (true) {
|
|
178
|
+
const query = {
|
|
179
|
+
projectId,
|
|
180
|
+
class: resolved.apiTarget.class
|
|
181
|
+
};
|
|
182
|
+
if (cursor !== void 0) query.cursor = cursor;
|
|
183
|
+
const result = await client.GET("/v1/environment-variables", { params: { query } });
|
|
184
|
+
if (result.error || !result.data) throw apiCallError(`Failed to list environment variables`, result.response, result.error);
|
|
185
|
+
const page = result.data.data.filter((row) => rowMatchesScope(row, resolved));
|
|
186
|
+
collected.push(...page);
|
|
187
|
+
if (!result.data.pagination.hasMore || !result.data.pagination.nextCursor) break;
|
|
188
|
+
cursor = result.data.pagination.nextCursor;
|
|
189
|
+
}
|
|
190
|
+
return collected;
|
|
191
|
+
}
|
|
192
|
+
function rowMatchesScope(row, resolved) {
|
|
193
|
+
return row.branchId === null && row.class === resolved.apiTarget.class;
|
|
194
|
+
}
|
|
195
|
+
function toMetadata(row, scope) {
|
|
196
|
+
return {
|
|
197
|
+
id: row.id,
|
|
198
|
+
key: row.key,
|
|
199
|
+
scope,
|
|
200
|
+
isManagedBySystem: row.isManagedBySystem,
|
|
201
|
+
updatedAt: row.updatedAt
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function apiCallError(summary, response, error) {
|
|
205
|
+
const status = response?.status ?? 0;
|
|
206
|
+
const apiCode = error?.error?.code;
|
|
207
|
+
const apiMessage = error?.error?.message;
|
|
208
|
+
const apiHint = error?.error?.hint;
|
|
209
|
+
if (status === 401 || status === 403) return authRequiredError(["prisma auth login"]);
|
|
210
|
+
return new CliError({
|
|
211
|
+
code: apiCode ?? "ENV_API_ERROR",
|
|
212
|
+
domain: "app",
|
|
213
|
+
summary,
|
|
214
|
+
why: apiMessage ?? `The Management API returned status ${status || "unknown"}.`,
|
|
215
|
+
fix: apiHint ?? "Re-run with --trace for the underlying API response details.",
|
|
216
|
+
exitCode: 1,
|
|
217
|
+
nextSteps: []
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
export { runEnvAdd, runEnvList, runEnvRm, runEnvUpdate };
|