@looma/prisma-cli 0.1.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.
Files changed (44) hide show
  1. package/README.md +39 -0
  2. package/dist/adapters/config.js +74 -0
  3. package/dist/adapters/local-state.js +98 -0
  4. package/dist/adapters/mock-api.js +57 -0
  5. package/dist/adapters/token-storage.js +43 -0
  6. package/dist/cli.js +9 -0
  7. package/dist/cli2.js +59 -0
  8. package/dist/commands/app/index.js +178 -0
  9. package/dist/commands/auth/index.js +42 -0
  10. package/dist/commands/env/index.js +51 -0
  11. package/dist/commands/project/index.js +45 -0
  12. package/dist/controllers/app.js +658 -0
  13. package/dist/controllers/auth.js +107 -0
  14. package/dist/controllers/env.js +73 -0
  15. package/dist/controllers/project.js +214 -0
  16. package/dist/controllers/select-prompt-port.js +12 -0
  17. package/dist/lib/app/local-dev.js +178 -0
  18. package/dist/lib/app/prototype-build.js +109 -0
  19. package/dist/lib/app/prototype-interaction.js +38 -0
  20. package/dist/lib/app/prototype-progress.js +115 -0
  21. package/dist/lib/app/prototype-provider.js +163 -0
  22. package/dist/lib/auth/auth-ops.js +57 -0
  23. package/dist/lib/auth/client.js +22 -0
  24. package/dist/lib/auth/guard.js +34 -0
  25. package/dist/lib/auth/login.js +117 -0
  26. package/dist/output/patterns.js +93 -0
  27. package/dist/presenters/app.js +333 -0
  28. package/dist/presenters/auth.js +73 -0
  29. package/dist/presenters/env.js +111 -0
  30. package/dist/presenters/project.js +84 -0
  31. package/dist/shell/command-meta.js +294 -0
  32. package/dist/shell/command-runner.js +33 -0
  33. package/dist/shell/errors.js +64 -0
  34. package/dist/shell/global-flags.js +25 -0
  35. package/dist/shell/help.js +78 -0
  36. package/dist/shell/output.js +48 -0
  37. package/dist/shell/prompt.js +31 -0
  38. package/dist/shell/runtime.js +51 -0
  39. package/dist/shell/ui.js +59 -0
  40. package/dist/use-cases/auth.js +70 -0
  41. package/dist/use-cases/create-cli-gateways.js +93 -0
  42. package/dist/use-cases/env.js +104 -0
  43. package/dist/use-cases/project.js +75 -0
  44. package/package.json +30 -0
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Prisma CLI Prototype
2
+
3
+ Prototype npm distribution for the Compute-focused Prisma CLI work in this repo.
4
+
5
+ Install:
6
+
7
+ ```bash
8
+ pnpm add -D @looma/prisma-cli
9
+ ```
10
+
11
+ Basic flow:
12
+
13
+ ```bash
14
+ pnpm prisma-cli auth login
15
+ pnpm prisma-cli app deploy
16
+ ```
17
+
18
+ Notes:
19
+
20
+ - the official Prisma ORM package still owns the `prisma` executable
21
+ - this prototype intentionally exposes `prisma-cli` so both CLIs can coexist in one app
22
+ - the canonical command shape is still `app deploy`, not `deploy`
23
+ - `prisma.config.ts` is project-only in this prototype and will be created as a plain object export when needed
24
+
25
+ If you want future-shaped local ergonomics in a test app, add:
26
+
27
+ ```json
28
+ {
29
+ "scripts": {
30
+ "prisma": "prisma-cli"
31
+ }
32
+ }
33
+ ```
34
+
35
+ Then run:
36
+
37
+ ```bash
38
+ pnpm prisma app deploy
39
+ ```
@@ -0,0 +1,74 @@
1
+ import path from "node:path";
2
+ import { copyFile, mkdir, mkdtemp, readFile, rm } from "node:fs/promises";
3
+ import os from "node:os";
4
+ import { updateConfig } from "c12/update";
5
+ //#region src/adapters/config.ts
6
+ const PROJECT_FIELD_PATTERN = /project\s*:\s*["']([^"']+)["']/;
7
+ async function readLinkedProjectId(cwd) {
8
+ const configPath = path.join(cwd, "prisma.config.ts");
9
+ try {
10
+ return (await readFile(configPath, "utf8")).match(PROJECT_FIELD_PATTERN)?.[1] ?? null;
11
+ } catch (error) {
12
+ if (error.code === "ENOENT") return null;
13
+ throw error;
14
+ }
15
+ }
16
+ var UnsafeConfigWriteError = class extends Error {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = "UnsafeConfigWriteError";
20
+ }
21
+ };
22
+ async function assertLinkedProjectIdWritable(cwd) {
23
+ const tempDir = await mkdtemp(path.join(os.tmpdir(), "prisma-cli-config-"));
24
+ const sourceConfigPath = path.join(cwd, "prisma.config.ts");
25
+ const tempConfigPath = path.join(tempDir, "prisma.config.ts");
26
+ try {
27
+ try {
28
+ await copyFile(sourceConfigPath, tempConfigPath);
29
+ } catch (error) {
30
+ if (error.code !== "ENOENT") throw error;
31
+ }
32
+ await applyLinkedProjectIdUpdate(tempDir, "proj_preflight");
33
+ } catch (error) {
34
+ throw toUnsafeConfigWriteError(error);
35
+ } finally {
36
+ await rm(tempDir, {
37
+ recursive: true,
38
+ force: true
39
+ });
40
+ }
41
+ }
42
+ async function writeLinkedProjectId(cwd, projectId) {
43
+ try {
44
+ await applyLinkedProjectIdUpdate(cwd, projectId);
45
+ } catch (error) {
46
+ if (error.code === "ENOENT") {
47
+ await mkdir(cwd, { recursive: true });
48
+ await applyLinkedProjectIdUpdate(cwd, projectId);
49
+ return;
50
+ }
51
+ throw toUnsafeConfigWriteError(error);
52
+ }
53
+ }
54
+ async function applyLinkedProjectIdUpdate(cwd, projectId) {
55
+ await updateConfig({
56
+ cwd,
57
+ configFile: "prisma.config",
58
+ onUpdate(config) {
59
+ config.project = projectId;
60
+ },
61
+ onCreate() {
62
+ return renderProjectConfig(projectId);
63
+ }
64
+ });
65
+ }
66
+ function renderProjectConfig(projectId) {
67
+ return `export default {\n project: "${projectId}",\n};\n`;
68
+ }
69
+ function toUnsafeConfigWriteError(error) {
70
+ if (error instanceof UnsafeConfigWriteError) return error;
71
+ return new UnsafeConfigWriteError("The existing prisma.config.ts file could not be updated safely.");
72
+ }
73
+ //#endregion
74
+ export { UnsafeConfigWriteError, assertLinkedProjectIdWritable, readLinkedProjectId, writeLinkedProjectId };
@@ -0,0 +1,98 @@
1
+ import path from "node:path";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ //#region src/adapters/local-state.ts
4
+ const DEFAULT_STATE = {
5
+ auth: null,
6
+ environment: { active: "local" },
7
+ app: {
8
+ selectedByProject: {},
9
+ knownLiveDeploymentByProject: {}
10
+ }
11
+ };
12
+ const DEFAULT_STATE_FILE_NAME = "state.json";
13
+ function resolveLocalStateFilePath(stateDir) {
14
+ return path.join(stateDir, DEFAULT_STATE_FILE_NAME);
15
+ }
16
+ var LocalStateStore = class {
17
+ stateFilePath;
18
+ constructor(stateDir) {
19
+ this.stateFilePath = resolveLocalStateFilePath(stateDir);
20
+ }
21
+ async read() {
22
+ try {
23
+ const raw = await readFile(this.stateFilePath, "utf8");
24
+ const parsed = JSON.parse(raw);
25
+ return {
26
+ auth: parsed.auth ?? structuredClone(DEFAULT_STATE.auth),
27
+ environment: { active: parsed.environment?.active ?? DEFAULT_STATE.environment.active },
28
+ app: {
29
+ selectedByProject: parsed.app?.selectedByProject ?? {},
30
+ knownLiveDeploymentByProject: parsed.app?.knownLiveDeploymentByProject ?? {}
31
+ }
32
+ };
33
+ } catch (error) {
34
+ if (error.code === "ENOENT") return structuredClone(DEFAULT_STATE);
35
+ throw error;
36
+ }
37
+ }
38
+ async write(state) {
39
+ await mkdir(path.dirname(this.stateFilePath), { recursive: true });
40
+ await writeFile(this.stateFilePath, `${JSON.stringify(state, null, 2)}\n`, "utf8");
41
+ }
42
+ async setAuthSession(session) {
43
+ const state = await this.read();
44
+ state.auth = session;
45
+ await this.write(state);
46
+ return state;
47
+ }
48
+ async clearAuthSession() {
49
+ const state = await this.read();
50
+ state.auth = null;
51
+ await this.write(state);
52
+ return state;
53
+ }
54
+ async setActiveEnvironment(active) {
55
+ const state = await this.read();
56
+ state.environment.active = active;
57
+ await this.write(state);
58
+ return state;
59
+ }
60
+ async readSelectedApp(projectId) {
61
+ return (await this.read()).app.selectedByProject[projectId] ?? null;
62
+ }
63
+ async setSelectedApp(projectId, app) {
64
+ const state = await this.read();
65
+ state.app.selectedByProject[projectId] = app;
66
+ await this.write(state);
67
+ return state;
68
+ }
69
+ async clearSelectedApp(projectId, appId) {
70
+ const state = await this.read();
71
+ const selectedApp = state.app.selectedByProject[projectId];
72
+ if (!selectedApp || selectedApp.id !== appId) return state;
73
+ delete state.app.selectedByProject[projectId];
74
+ await this.write(state);
75
+ return state;
76
+ }
77
+ async readKnownLiveDeployment(projectId, appId) {
78
+ return (await this.read()).app.knownLiveDeploymentByProject[projectId]?.[appId] ?? null;
79
+ }
80
+ async setKnownLiveDeployment(projectId, appId, deploymentId) {
81
+ const state = await this.read();
82
+ state.app.knownLiveDeploymentByProject[projectId] ??= {};
83
+ state.app.knownLiveDeploymentByProject[projectId][appId] = deploymentId;
84
+ await this.write(state);
85
+ return state;
86
+ }
87
+ async clearKnownLiveDeployment(projectId, appId) {
88
+ const state = await this.read();
89
+ const projectDeployments = state.app.knownLiveDeploymentByProject[projectId];
90
+ if (!projectDeployments || !(appId in projectDeployments)) return state;
91
+ delete projectDeployments[appId];
92
+ if (Object.keys(projectDeployments).length === 0) delete state.app.knownLiveDeploymentByProject[projectId];
93
+ await this.write(state);
94
+ return state;
95
+ }
96
+ };
97
+ //#endregion
98
+ export { LocalStateStore };
@@ -0,0 +1,57 @@
1
+ import { readFile } from "node:fs/promises";
2
+ //#region src/adapters/mock-api.ts
3
+ var MockApi = class MockApi {
4
+ data;
5
+ constructor(data) {
6
+ this.data = data;
7
+ }
8
+ static async load(fixturePath) {
9
+ const raw = await readFile(fixturePath, "utf8");
10
+ return new MockApi(JSON.parse(raw));
11
+ }
12
+ listProviders() {
13
+ return this.data.providers;
14
+ }
15
+ getProvider(providerId) {
16
+ return this.data.providers.find((provider) => provider.id === providerId);
17
+ }
18
+ listUsersForProvider(providerId) {
19
+ return this.data.users.filter((user) => user.providerIds.includes(providerId));
20
+ }
21
+ getUser(userId) {
22
+ return this.data.users.find((user) => user.id === userId);
23
+ }
24
+ getUserForProvider(providerId, userId) {
25
+ return this.listUsersForProvider(providerId).find((user) => user.id === userId);
26
+ }
27
+ listUserWorkspaces(userId) {
28
+ const workspaceIds = this.data.memberships.filter((membership) => membership.userId === userId).map((membership) => membership.workspaceId);
29
+ return this.data.workspaces.filter((workspace) => workspaceIds.includes(workspace.id));
30
+ }
31
+ getWorkspace(workspaceId) {
32
+ return this.data.workspaces.find((workspace) => workspace.id === workspaceId);
33
+ }
34
+ getUserWorkspace(userId, workspaceId) {
35
+ return this.listUserWorkspaces(userId).find((workspace) => workspace.id === workspaceId);
36
+ }
37
+ listProjectsForWorkspace(workspaceId) {
38
+ return this.data.projects.filter((project) => project.workspaceId === workspaceId);
39
+ }
40
+ getProject(projectId) {
41
+ return this.data.projects.find((project) => project.id === projectId);
42
+ }
43
+ getProjectForWorkspace(workspaceId, projectId) {
44
+ return this.listProjectsForWorkspace(workspaceId).find((project) => project.id === projectId);
45
+ }
46
+ listEnvironmentsForProject(projectId) {
47
+ return this.data.environments.filter((environment) => environment.projectId === projectId);
48
+ }
49
+ getEnvironmentForProject(projectId, name) {
50
+ return this.listEnvironmentsForProject(projectId).find((environment) => environment.name === name);
51
+ }
52
+ getDeployment(deploymentId) {
53
+ return this.data.deployments.find((deployment) => deployment.id === deploymentId);
54
+ }
55
+ };
56
+ //#endregion
57
+ export { MockApi };
@@ -0,0 +1,43 @@
1
+ import { getAuthFilePath } from "../lib/auth/client.js";
2
+ import { CredentialsStore } from "@prisma/credentials-store";
3
+ //#region src/adapters/token-storage.ts
4
+ function findLatestValidTokens(allCredentials) {
5
+ for (let i = allCredentials.length - 1; i >= 0; i -= 1) {
6
+ const credential = allCredentials[i];
7
+ if (!credential) continue;
8
+ if (typeof credential.workspaceId !== "string" || credential.workspaceId.length === 0 || typeof credential.token !== "string" || credential.token.length === 0 || typeof credential.refreshToken !== "string" || credential.refreshToken.length === 0) continue;
9
+ return {
10
+ workspaceId: credential.workspaceId,
11
+ accessToken: credential.token,
12
+ refreshToken: credential.refreshToken
13
+ };
14
+ }
15
+ return null;
16
+ }
17
+ var FileTokenStorage = class {
18
+ credentialsStore;
19
+ constructor(env = process.env) {
20
+ this.credentialsStore = new CredentialsStore(getAuthFilePath(env));
21
+ }
22
+ async getTokens() {
23
+ try {
24
+ return findLatestValidTokens(await this.credentialsStore.getCredentials());
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
29
+ async setTokens(tokens) {
30
+ await this.credentialsStore.storeCredentials({
31
+ workspaceId: tokens.workspaceId,
32
+ token: tokens.accessToken,
33
+ refreshToken: tokens.refreshToken
34
+ });
35
+ }
36
+ async clearTokens() {
37
+ const tokens = findLatestValidTokens(await this.credentialsStore.getCredentials());
38
+ if (!tokens) return;
39
+ await this.credentialsStore.deleteCredentials(tokens.workspaceId);
40
+ }
41
+ };
42
+ //#endregion
43
+ export { FileTokenStorage };
package/dist/cli.js ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "./cli2.js";
3
+ import process from "node:process";
4
+ //#region src/bin.ts
5
+ runCli().then((exitCode) => {
6
+ process.exitCode = exitCode;
7
+ });
8
+ //#endregion
9
+ export {};
package/dist/cli2.js ADDED
@@ -0,0 +1,59 @@
1
+ import { attachCommandDescriptor } from "./shell/command-meta.js";
2
+ import { configureRuntimeCommand } from "./shell/runtime.js";
3
+ import "./shell/prompt.js";
4
+ import { createAppCommand } from "./commands/app/index.js";
5
+ import { createAuthCommand } from "./commands/auth/index.js";
6
+ import { createEnvCommand } from "./commands/env/index.js";
7
+ import { createProjectCommand } from "./commands/project/index.js";
8
+ import process from "node:process";
9
+ import { Command, CommanderError } from "commander";
10
+ //#region src/cli.ts
11
+ async function runCli(options = {}) {
12
+ const runtime = resolveRuntime(options);
13
+ const program = createProgram(runtime);
14
+ process.exitCode = 0;
15
+ try {
16
+ const bareHelpCommand = resolveBareHelpCommand(program, runtime.argv);
17
+ if (bareHelpCommand) {
18
+ runtime.stderr.write(bareHelpCommand.helpInformation());
19
+ return 0;
20
+ }
21
+ await program.parseAsync(runtime.argv, { from: "user" });
22
+ return process.exitCode ?? 0;
23
+ } catch (error) {
24
+ if (error instanceof CommanderError) return error.code === "commander.helpDisplayed" ? 0 : 2;
25
+ const message = error instanceof Error ? error.stack ?? error.message : String(error);
26
+ runtime.stderr.write(`${message}\n`);
27
+ return 1;
28
+ } finally {
29
+ runtime.stdin;
30
+ }
31
+ }
32
+ function createProgram(runtime) {
33
+ const program = attachCommandDescriptor(configureRuntimeCommand(new Command(), runtime), "root");
34
+ program.name("prisma").showSuggestionAfterError();
35
+ program.addCommand(createAuthCommand(runtime));
36
+ program.addCommand(createEnvCommand(runtime));
37
+ program.addCommand(createProjectCommand(runtime));
38
+ program.addCommand(createAppCommand(runtime));
39
+ return program;
40
+ }
41
+ function resolveBareHelpCommand(program, argv) {
42
+ if (argv.length === 0) return program;
43
+ if (argv.length !== 1) return null;
44
+ return program.commands.find((command) => command.name() === argv[0]) ?? null;
45
+ }
46
+ function resolveRuntime(options) {
47
+ return {
48
+ argv: options.argv ?? process.argv.slice(2),
49
+ cwd: options.cwd ?? process.env.INIT_CWD ?? process.cwd(),
50
+ env: options.env ?? process.env,
51
+ stdin: options.stdin ?? process.stdin,
52
+ stdout: options.stdout ?? process.stdout,
53
+ stderr: options.stderr ?? process.stderr,
54
+ fixturePath: options.fixturePath,
55
+ stateDir: options.stateDir
56
+ };
57
+ }
58
+ //#endregion
59
+ export { runCli };
@@ -0,0 +1,178 @@
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 { runAppBuild, runAppDeploy, runAppListDeploys, runAppLogs, runAppOpen, runAppPromote, runAppRemove, runAppRollback, runAppRun, runAppShow, runAppShowDeploy } from "../../controllers/app.js";
5
+ import { renderAppBuild, renderAppDeploy, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy } from "../../presenters/app.js";
6
+ import { runCommand } from "../../shell/command-runner.js";
7
+ import { Command, Option } from "commander";
8
+ //#region src/commands/app/index.ts
9
+ function createAppCommand(runtime) {
10
+ const app = attachCommandDescriptor(configureRuntimeCommand(new Command("app"), runtime), "app");
11
+ app.addCommand(createBuildCommand(runtime));
12
+ app.addCommand(createRunCommand(runtime));
13
+ app.addCommand(createDeployCommand(runtime));
14
+ app.addCommand(createShowCommand(runtime));
15
+ app.addCommand(createOpenCommand(runtime));
16
+ app.addCommand(createLogsCommand(runtime));
17
+ app.addCommand(createListDeploysCommand(runtime));
18
+ app.addCommand(createShowDeployCommand(runtime));
19
+ app.addCommand(createPromoteCommand(runtime));
20
+ app.addCommand(createRollbackCommand(runtime));
21
+ app.addCommand(createRemoveCommand(runtime));
22
+ return app;
23
+ }
24
+ function createBuildCommand(runtime) {
25
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("build"), runtime), "app.build");
26
+ command.addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto builds")).addOption(new Option("--build-type <type>", "Local build type").choices([
27
+ "auto",
28
+ "bun",
29
+ "nextjs"
30
+ ]).default("auto"));
31
+ addGlobalFlags(command);
32
+ command.action(async (options) => {
33
+ const entry = options.entry;
34
+ const buildType = options.buildType;
35
+ await runCommand(runtime, "app.build", options, (context) => runAppBuild(context, entry, buildType), {
36
+ renderHuman: (context, descriptor, result) => renderAppBuild(context, descriptor, result),
37
+ renderJson: (result) => serializeAppBuild(result)
38
+ });
39
+ });
40
+ return command;
41
+ }
42
+ function createRunCommand(runtime) {
43
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("run"), runtime), "app.run");
44
+ command.addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto runs")).addOption(new Option("--build-type <type>", "Local framework type").choices([
45
+ "auto",
46
+ "bun",
47
+ "nextjs"
48
+ ]).default("auto")).addOption(new Option("--port <port>", "Local port"));
49
+ addGlobalFlags(command);
50
+ command.action(async (options) => {
51
+ const entry = options.entry;
52
+ const buildType = options.buildType;
53
+ const port = options.port;
54
+ await runCommand(runtime, "app.run", options, (context) => runAppRun(context, entry, buildType, port), {
55
+ renderHuman: (context, descriptor, result) => renderAppRun(context, descriptor, result),
56
+ renderJson: (result) => serializeAppRun(result)
57
+ });
58
+ });
59
+ return command;
60
+ }
61
+ function createDeployCommand(runtime) {
62
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("deploy"), runtime), "app.deploy");
63
+ command.addOption(new Option("--app <name>", "App name"));
64
+ addGlobalFlags(command);
65
+ command.action(async (options) => {
66
+ const appName = options.app;
67
+ await runCommand(runtime, "app.deploy", options, (context) => runAppDeploy(context, appName), {
68
+ renderHuman: (context, descriptor, result) => renderAppDeploy(context, descriptor, result),
69
+ renderJson: (result) => serializeAppDeploy(result)
70
+ });
71
+ });
72
+ return command;
73
+ }
74
+ function createShowCommand(runtime) {
75
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "app.show");
76
+ command.addOption(new Option("--app <name>", "App name"));
77
+ addGlobalFlags(command);
78
+ command.action(async (options) => {
79
+ const appName = options.app;
80
+ await runCommand(runtime, "app.show", options, (context) => runAppShow(context, appName), {
81
+ renderHuman: (context, descriptor, result) => renderAppShow(context, descriptor, result),
82
+ renderJson: (result) => serializeAppShow(result)
83
+ });
84
+ });
85
+ return command;
86
+ }
87
+ function createOpenCommand(runtime) {
88
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("open"), runtime), "app.open");
89
+ command.addOption(new Option("--app <name>", "App name"));
90
+ addGlobalFlags(command);
91
+ command.action(async (options) => {
92
+ const appName = options.app;
93
+ await runCommand(runtime, "app.open", options, (context) => runAppOpen(context, appName), {
94
+ renderHuman: (context, descriptor, result) => renderAppOpen(context, descriptor, result),
95
+ renderJson: (result) => serializeAppOpen(result)
96
+ });
97
+ });
98
+ return command;
99
+ }
100
+ function createLogsCommand(runtime) {
101
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("logs"), runtime), "app.logs");
102
+ command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--deployment <id>", "Deployment id"));
103
+ addGlobalFlags(command);
104
+ command.action(async (options) => {
105
+ const appName = options.app;
106
+ const deploymentId = options.deployment;
107
+ await runCommand(runtime, "app.logs", options, (context) => runAppLogs(context, appName, deploymentId), { renderHuman: () => [] });
108
+ });
109
+ return command;
110
+ }
111
+ function createListDeploysCommand(runtime) {
112
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list-deploys"), runtime), "app.list-deploys");
113
+ command.addOption(new Option("--app <name>", "App name"));
114
+ addGlobalFlags(command);
115
+ command.action(async (options) => {
116
+ const appName = options.app;
117
+ await runCommand(runtime, "app.list-deploys", options, (context) => runAppListDeploys(context, appName), {
118
+ renderHuman: (context, descriptor, result) => renderAppListDeploys(context, descriptor, result),
119
+ renderJson: (result) => serializeAppListDeploys(result)
120
+ });
121
+ });
122
+ return command;
123
+ }
124
+ function createShowDeployCommand(runtime) {
125
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show-deploy"), runtime), "app.show-deploy");
126
+ command.argument("<deployment>", "Deployment id");
127
+ addGlobalFlags(command);
128
+ command.action(async (deploymentId, options) => {
129
+ await runCommand(runtime, "app.show-deploy", options, (context) => runAppShowDeploy(context, deploymentId), {
130
+ renderHuman: (context, descriptor, result) => renderAppShowDeploy(context, descriptor, result),
131
+ renderJson: (result) => serializeAppShowDeploy(result)
132
+ });
133
+ });
134
+ return command;
135
+ }
136
+ function createPromoteCommand(runtime) {
137
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("promote"), runtime), "app.promote");
138
+ command.argument("<deployment>", "Deployment id");
139
+ command.addOption(new Option("--app <name>", "App name"));
140
+ addGlobalFlags(command);
141
+ command.action(async (deploymentId, options) => {
142
+ const appName = options.app;
143
+ await runCommand(runtime, "app.promote", options, (context) => runAppPromote(context, deploymentId, appName), {
144
+ renderHuman: (context, descriptor, result) => renderAppPromote(context, descriptor, result),
145
+ renderJson: (result) => serializeAppPromote(result)
146
+ });
147
+ });
148
+ return command;
149
+ }
150
+ function createRollbackCommand(runtime) {
151
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("rollback"), runtime), "app.rollback");
152
+ command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--to <deployment>", "Deployment id"));
153
+ addGlobalFlags(command);
154
+ command.action(async (options) => {
155
+ const appName = options.app;
156
+ const deploymentId = options.to;
157
+ await runCommand(runtime, "app.rollback", options, (context) => runAppRollback(context, appName, deploymentId), {
158
+ renderHuman: (context, descriptor, result) => renderAppRollback(context, descriptor, result),
159
+ renderJson: (result) => serializeAppRollback(result)
160
+ });
161
+ });
162
+ return command;
163
+ }
164
+ function createRemoveCommand(runtime) {
165
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "app.remove");
166
+ command.addOption(new Option("--app <name>", "App name"));
167
+ addGlobalFlags(command);
168
+ command.action(async (options) => {
169
+ const appName = options.app;
170
+ await runCommand(runtime, "app.remove", options, (context) => runAppRemove(context, appName), {
171
+ renderHuman: (context, descriptor, result) => renderAppRemove(context, descriptor, result),
172
+ renderJson: (result) => serializeAppRemove(result)
173
+ });
174
+ });
175
+ return command;
176
+ }
177
+ //#endregion
178
+ export { createAppCommand };
@@ -0,0 +1,42 @@
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 { runAuthLogin, runAuthLogout, runAuthWhoAmI } from "../../controllers/auth.js";
6
+ import { renderAuthSuccess } from "../../presenters/auth.js";
7
+ import { Command, Option } from "commander";
8
+ //#region src/commands/auth/index.ts
9
+ function createAuthCommand(runtime) {
10
+ const auth = attachCommandDescriptor(configureRuntimeCommand(new Command("auth"), runtime), "auth");
11
+ auth.addCommand(createAuthLoginCommand(runtime));
12
+ auth.addCommand(createAuthLogoutCommand(runtime));
13
+ auth.addCommand(createAuthWhoAmICommand(runtime));
14
+ return auth;
15
+ }
16
+ function createAuthLoginCommand(runtime) {
17
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("login"), runtime), "auth.login");
18
+ command.addOption(new Option("--provider <provider>").hideHelp()).addOption(new Option("--user <id>").hideHelp()).addOption(new Option("--workspace <id>").hideHelp());
19
+ addGlobalFlags(command);
20
+ command.action(async (options) => {
21
+ await runCommand(runtime, "auth.login", options, (context) => runAuthLogin(context, options), { renderHuman: (context, descriptor, result) => renderAuthSuccess(context, descriptor, "auth.login", result) });
22
+ });
23
+ return command;
24
+ }
25
+ function createAuthLogoutCommand(runtime) {
26
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("logout"), runtime), "auth.logout");
27
+ addGlobalFlags(command);
28
+ command.action(async (options) => {
29
+ await runCommand(runtime, "auth.logout", options, (context) => runAuthLogout(context), { renderHuman: (context, descriptor, result) => renderAuthSuccess(context, descriptor, "auth.logout", result) });
30
+ });
31
+ return command;
32
+ }
33
+ function createAuthWhoAmICommand(runtime) {
34
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("whoami"), runtime), "auth.whoami");
35
+ addGlobalFlags(command);
36
+ command.action(async (options) => {
37
+ await runCommand(runtime, "auth.whoami", options, (context) => runAuthWhoAmI(context), { renderHuman: (context, descriptor, result) => renderAuthSuccess(context, descriptor, "auth.whoami", result) });
38
+ });
39
+ return command;
40
+ }
41
+ //#endregion
42
+ export { createAuthCommand };
@@ -0,0 +1,51 @@
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 { runEnvList, runEnvShow, runEnvUse } from "../../controllers/env.js";
6
+ import { renderEnvList, renderEnvShow, renderEnvUse, serializeEnvList, serializeEnvShow } from "../../presenters/env.js";
7
+ import { Command } from "commander";
8
+ //#region src/commands/env/index.ts
9
+ function createEnvCommand(runtime) {
10
+ const env = attachCommandDescriptor(configureRuntimeCommand(new Command("env"), runtime), "env");
11
+ env.addCommand(createEnvListCommand(runtime));
12
+ env.addCommand(createEnvShowCommand(runtime));
13
+ env.addCommand(createEnvUseCommand(runtime));
14
+ return env;
15
+ }
16
+ function createEnvListCommand(runtime) {
17
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "env.list");
18
+ addGlobalFlags(command);
19
+ command.action(async (options) => {
20
+ await runCommand(runtime, "env.list", options, (context) => runEnvList(context), {
21
+ renderHuman: (context, descriptor, result) => renderEnvList(context, descriptor, result),
22
+ renderJson: (result) => serializeEnvList(result)
23
+ });
24
+ });
25
+ return command;
26
+ }
27
+ function createEnvShowCommand(runtime) {
28
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "env.show");
29
+ addGlobalFlags(command);
30
+ command.action(async (options) => {
31
+ await runCommand(runtime, "env.show", options, (context) => runEnvShow(context), {
32
+ renderHuman: (context, descriptor, result) => renderEnvShow(context, descriptor, result),
33
+ renderJson: (result) => serializeEnvShow(result)
34
+ });
35
+ });
36
+ return command;
37
+ }
38
+ function createEnvUseCommand(runtime) {
39
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("use"), runtime), "env.use");
40
+ command.argument("[name]", "Environment name");
41
+ addGlobalFlags(command);
42
+ command.action(async (environmentName, options) => {
43
+ await runCommand(runtime, "env.use", options, (context) => runEnvUse(context, environmentName), {
44
+ renderHuman: (context, descriptor, result) => renderEnvUse(context, descriptor, result),
45
+ renderJson: (result) => serializeEnvShow(result)
46
+ });
47
+ });
48
+ return command;
49
+ }
50
+ //#endregion
51
+ export { createEnvCommand };