@prisma/cli 3.0.0-alpha.0 → 3.0.0-alpha.10

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.
Files changed (55) hide show
  1. package/README.md +1 -16
  2. package/dist/adapters/git.js +49 -0
  3. package/dist/adapters/local-state.js +39 -1
  4. package/dist/cli2.js +60 -4
  5. package/dist/commands/app/index.js +43 -30
  6. package/dist/commands/auth/index.js +3 -2
  7. package/dist/commands/branch/index.js +2 -1
  8. package/dist/commands/env.js +87 -0
  9. package/dist/commands/git/index.js +36 -0
  10. package/dist/commands/project/index.js +12 -14
  11. package/dist/commands/version/index.js +18 -0
  12. package/dist/controllers/app-env.js +223 -0
  13. package/dist/controllers/app.js +1051 -173
  14. package/dist/controllers/auth.js +9 -9
  15. package/dist/controllers/branch.js +6 -6
  16. package/dist/controllers/project.js +451 -161
  17. package/dist/controllers/version.js +12 -0
  18. package/dist/lib/app/bun-project.js +1 -1
  19. package/dist/lib/app/deploy-output.js +15 -0
  20. package/dist/lib/app/env-config.js +57 -0
  21. package/dist/lib/app/env-vars.js +4 -4
  22. package/dist/lib/app/local-dev.js +2 -1
  23. package/dist/lib/app/preview-build.js +130 -144
  24. package/dist/lib/app/preview-interaction.js +2 -35
  25. package/dist/lib/app/preview-progress.js +43 -58
  26. package/dist/lib/app/preview-provider.js +125 -24
  27. package/dist/lib/auth/auth-ops.js +58 -13
  28. package/dist/lib/auth/client.js +1 -1
  29. package/dist/lib/auth/guard.js +1 -1
  30. package/dist/lib/auth/login.js +115 -4
  31. package/dist/lib/project/local-pin.js +51 -0
  32. package/dist/lib/project/resolution.js +201 -0
  33. package/dist/lib/version.js +55 -0
  34. package/dist/output/patterns.js +15 -18
  35. package/dist/presenters/app-env.js +129 -0
  36. package/dist/presenters/app.js +16 -29
  37. package/dist/presenters/auth.js +2 -2
  38. package/dist/presenters/branch.js +6 -6
  39. package/dist/presenters/project.js +87 -44
  40. package/dist/presenters/version.js +29 -0
  41. package/dist/shell/command-meta.js +150 -84
  42. package/dist/shell/command-runner.js +32 -2
  43. package/dist/shell/errors.js +8 -3
  44. package/dist/shell/global-flags.js +13 -1
  45. package/dist/shell/help.js +8 -7
  46. package/dist/shell/output.js +29 -12
  47. package/dist/shell/prompt.js +12 -2
  48. package/dist/shell/runtime.js +1 -1
  49. package/dist/shell/ui.js +19 -1
  50. package/dist/use-cases/auth.js +9 -12
  51. package/dist/use-cases/branch.js +20 -20
  52. package/dist/use-cases/create-cli-gateways.js +3 -13
  53. package/dist/use-cases/project.js +2 -48
  54. package/package.json +3 -3
  55. 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. If you want local project scripts that use the future command shape,
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
  }
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 { configureRuntimeCommand } from "./shell/runtime.js";
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
- return program.commands.find((command) => command.name() === argv[0]) ?? null;
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,13 +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
+ import { PREVIEW_BUILD_TYPES } from "../../lib/app/preview-build.js";
4
5
  import { runAppBuild, runAppDeploy, runAppListDeploys, runAppListEnv, runAppLogs, runAppOpen, runAppPromote, runAppRemove, runAppRollback, runAppRun, runAppShow, runAppShowDeploy, runAppUpdateEnv } from "../../controllers/app.js";
5
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";
6
- import { runCommand } from "../../shell/command-runner.js";
7
+ import { runCommand, runStreamingCommand } from "../../shell/command-runner.js";
7
8
  import { Command, Option } from "commander";
8
9
  //#region src/commands/app/index.ts
9
10
  function createAppCommand(runtime) {
10
11
  const app = attachCommandDescriptor(configureRuntimeCommand(new Command("app"), runtime), "app");
12
+ addCompactGlobalFlags(app);
11
13
  app.addCommand(createBuildCommand(runtime));
12
14
  app.addCommand(createRunCommand(runtime));
13
15
  app.addCommand(createDeployCommand(runtime));
@@ -25,11 +27,7 @@ function createAppCommand(runtime) {
25
27
  }
26
28
  function createBuildCommand(runtime) {
27
29
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("build"), runtime), "app.build");
28
- command.addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto builds")).addOption(new Option("--build-type <type>", "Local build type").choices([
29
- "auto",
30
- "bun",
31
- "nextjs"
32
- ]).default("auto"));
30
+ command.addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto builds")).addOption(new Option("--build-type <type>", "Local build type").choices([...PREVIEW_BUILD_TYPES]).default("auto"));
33
31
  addGlobalFlags(command);
34
32
  command.action(async (options) => {
35
33
  const entry = options.entry;
@@ -62,21 +60,27 @@ function createRunCommand(runtime) {
62
60
  }
63
61
  function createDeployCommand(runtime) {
64
62
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("deploy"), runtime), "app.deploy");
65
- command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto deploys")).addOption(new Option("--build-type <type>", "Deploy build type").choices([
66
- "auto",
67
- "bun",
68
- "nextjs"
69
- ]).default("auto")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--env <name=value>", "Environment variable").argParser(collectRepeatableValues));
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));
70
68
  addGlobalFlags(command);
71
69
  command.action(async (options) => {
72
70
  const appName = options.app;
73
71
  const entry = options.entry;
74
72
  const buildType = options.buildType;
73
+ const branchName = options.branch;
74
+ const framework = options.framework;
75
75
  const httpPort = options.httpPort;
76
76
  const envAssignments = options.env;
77
+ const projectRef = options.project;
77
78
  await runCommand(runtime, "app.deploy", options, (context) => runAppDeploy(context, appName, {
79
+ projectRef,
80
+ branchName,
78
81
  entrypoint: entry,
79
82
  buildType,
83
+ framework,
80
84
  httpPort,
81
85
  envAssignments
82
86
  }), {
@@ -88,12 +92,13 @@ function createDeployCommand(runtime) {
88
92
  }
89
93
  function createUpdateEnvCommand(runtime) {
90
94
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("update-env"), runtime), "app.update-env");
91
- 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));
92
96
  addGlobalFlags(command);
93
97
  command.action(async (options) => {
94
98
  const appName = options.app;
95
99
  const envAssignments = options.env;
96
- await runCommand(runtime, "app.update-env", options, (context) => runAppUpdateEnv(context, appName, envAssignments), {
100
+ const projectRef = options.project;
101
+ await runCommand(runtime, "app.update-env", options, (context) => runAppUpdateEnv(context, appName, envAssignments, projectRef), {
97
102
  renderHuman: (context, descriptor, result) => renderAppUpdateEnv(context, descriptor, result),
98
103
  renderJson: (result) => serializeAppUpdateEnv(result)
99
104
  });
@@ -102,11 +107,12 @@ function createUpdateEnvCommand(runtime) {
102
107
  }
103
108
  function createListEnvCommand(runtime) {
104
109
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list-env"), runtime), "app.list-env");
105
- 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"));
106
111
  addGlobalFlags(command);
107
112
  command.action(async (options) => {
108
113
  const appName = options.app;
109
- await runCommand(runtime, "app.list-env", options, (context) => runAppListEnv(context, appName), {
114
+ const projectRef = options.project;
115
+ await runCommand(runtime, "app.list-env", options, (context) => runAppListEnv(context, appName, projectRef), {
110
116
  renderHuman: (context, descriptor, result) => renderAppListEnv(context, descriptor, result),
111
117
  renderJson: (result) => serializeAppListEnv(result)
112
118
  });
@@ -115,11 +121,12 @@ function createListEnvCommand(runtime) {
115
121
  }
116
122
  function createShowCommand(runtime) {
117
123
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "app.show");
118
- 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"));
119
125
  addGlobalFlags(command);
120
126
  command.action(async (options) => {
121
127
  const appName = options.app;
122
- await runCommand(runtime, "app.show", options, (context) => runAppShow(context, appName), {
128
+ const projectRef = options.project;
129
+ await runCommand(runtime, "app.show", options, (context) => runAppShow(context, appName, projectRef), {
123
130
  renderHuman: (context, descriptor, result) => renderAppShow(context, descriptor, result),
124
131
  renderJson: (result) => serializeAppShow(result)
125
132
  });
@@ -128,11 +135,12 @@ function createShowCommand(runtime) {
128
135
  }
129
136
  function createOpenCommand(runtime) {
130
137
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("open"), runtime), "app.open");
131
- 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"));
132
139
  addGlobalFlags(command);
133
140
  command.action(async (options) => {
134
141
  const appName = options.app;
135
- await runCommand(runtime, "app.open", options, (context) => runAppOpen(context, appName), {
142
+ const projectRef = options.project;
143
+ await runCommand(runtime, "app.open", options, (context) => runAppOpen(context, appName, projectRef), {
136
144
  renderHuman: (context, descriptor, result) => renderAppOpen(context, descriptor, result),
137
145
  renderJson: (result) => serializeAppOpen(result)
138
146
  });
@@ -141,12 +149,13 @@ function createOpenCommand(runtime) {
141
149
  }
142
150
  function createLogsCommand(runtime) {
143
151
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("logs"), runtime), "app.logs");
144
- 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"));
145
153
  addGlobalFlags(command);
146
154
  command.action(async (options) => {
147
155
  const appName = options.app;
148
156
  const deploymentId = options.deployment;
149
- await runCommand(runtime, "app.logs", options, (context) => runAppLogs(context, appName, deploymentId), { renderHuman: () => [] });
157
+ const projectRef = options.project;
158
+ await runStreamingCommand(runtime, "app.logs", options, (context) => runAppLogs(context, appName, deploymentId, projectRef));
150
159
  });
151
160
  return command;
152
161
  }
@@ -155,11 +164,12 @@ function collectRepeatableValues(value, previous) {
155
164
  }
156
165
  function createListDeploysCommand(runtime) {
157
166
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list-deploys"), runtime), "app.list-deploys");
158
- 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"));
159
168
  addGlobalFlags(command);
160
169
  command.action(async (options) => {
161
170
  const appName = options.app;
162
- await runCommand(runtime, "app.list-deploys", options, (context) => runAppListDeploys(context, appName), {
171
+ const projectRef = options.project;
172
+ await runCommand(runtime, "app.list-deploys", options, (context) => runAppListDeploys(context, appName, projectRef), {
163
173
  renderHuman: (context, descriptor, result) => renderAppListDeploys(context, descriptor, result),
164
174
  renderJson: (result) => serializeAppListDeploys(result)
165
175
  });
@@ -181,11 +191,12 @@ function createShowDeployCommand(runtime) {
181
191
  function createPromoteCommand(runtime) {
182
192
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("promote"), runtime), "app.promote");
183
193
  command.argument("<deployment>", "Deployment id");
184
- 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"));
185
195
  addGlobalFlags(command);
186
196
  command.action(async (deploymentId, options) => {
187
197
  const appName = options.app;
188
- await runCommand(runtime, "app.promote", options, (context) => runAppPromote(context, deploymentId, appName), {
198
+ const projectRef = options.project;
199
+ await runCommand(runtime, "app.promote", options, (context) => runAppPromote(context, deploymentId, appName, projectRef), {
189
200
  renderHuman: (context, descriptor, result) => renderAppPromote(context, descriptor, result),
190
201
  renderJson: (result) => serializeAppPromote(result)
191
202
  });
@@ -194,12 +205,13 @@ function createPromoteCommand(runtime) {
194
205
  }
195
206
  function createRollbackCommand(runtime) {
196
207
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("rollback"), runtime), "app.rollback");
197
- 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"));
198
209
  addGlobalFlags(command);
199
210
  command.action(async (options) => {
200
211
  const appName = options.app;
201
212
  const deploymentId = options.to;
202
- await runCommand(runtime, "app.rollback", options, (context) => runAppRollback(context, appName, deploymentId), {
213
+ const projectRef = options.project;
214
+ await runCommand(runtime, "app.rollback", options, (context) => runAppRollback(context, appName, deploymentId, projectRef), {
203
215
  renderHuman: (context, descriptor, result) => renderAppRollback(context, descriptor, result),
204
216
  renderJson: (result) => serializeAppRollback(result)
205
217
  });
@@ -208,11 +220,12 @@ function createRollbackCommand(runtime) {
208
220
  }
209
221
  function createRemoveCommand(runtime) {
210
222
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "app.remove");
211
- 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"));
212
224
  addGlobalFlags(command);
213
225
  command.action(async (options) => {
214
226
  const appName = options.app;
215
- await runCommand(runtime, "app.remove", options, (context) => runAppRemove(context, appName), {
227
+ const projectRef = options.project;
228
+ await runCommand(runtime, "app.remove", options, (context) => runAppRemove(context, appName, projectRef), {
216
229
  renderHuman: (context, descriptor, result) => renderAppRemove(context, descriptor, result),
217
230
  renderJson: (result) => serializeAppRemove(result)
218
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 };
@@ -1,16 +1,18 @@
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 { runProjectList, runProjectShow } from "../../controllers/project.js";
4
5
  import { runCommand } from "../../shell/command-runner.js";
5
- import { runProjectLink, runProjectList, runProjectShow } from "../../controllers/project.js";
6
- import { renderProjectLink, renderProjectList, renderProjectShow, serializeProjectList } from "../../presenters/project.js";
6
+ import { renderProjectList, renderProjectShow, serializeProjectList, serializeProjectShow } 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
- project.addCommand(createProjectLinkCommand(runtime));
15
+ project.addCommand(createEnvCommand(runtime));
14
16
  return project;
15
17
  }
16
18
  function createProjectListCommand(runtime) {
@@ -26,18 +28,14 @@ function createProjectListCommand(runtime) {
26
28
  }
27
29
  function createProjectShowCommand(runtime) {
28
30
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "project.show");
31
+ command.option("--project <id-or-name>", "Project id or name");
29
32
  addGlobalFlags(command);
30
33
  command.action(async (options) => {
31
- await runCommand(runtime, "project.show", options, (context) => runProjectShow(context), { renderHuman: (context, descriptor, result) => renderProjectShow(context, descriptor, result) });
32
- });
33
- return command;
34
- }
35
- function createProjectLinkCommand(runtime) {
36
- const command = attachCommandDescriptor(configureRuntimeCommand(new Command("link"), runtime), "project.link");
37
- command.argument("[project]", "Project id");
38
- addGlobalFlags(command);
39
- command.action(async (projectId, options) => {
40
- await runCommand(runtime, "project.link", options, (context) => runProjectLink(context, projectId), { renderHuman: (context, descriptor, result) => renderProjectLink(context, descriptor, result) });
34
+ const projectRef = options.project;
35
+ await runCommand(runtime, "project.show", options, (context) => runProjectShow(context, projectRef), {
36
+ renderHuman: (context, descriptor, result) => renderProjectShow(context, descriptor, result),
37
+ renderJson: (result) => serializeProjectShow(result)
38
+ });
41
39
  });
42
40
  return command;
43
41
  }