@prisma/cli 3.0.0-alpha.9 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -14
- package/dist/adapters/token-storage.js +57 -1
- package/dist/commands/app/index.js +119 -35
- package/dist/commands/env.js +17 -9
- package/dist/commands/project/index.js +28 -2
- package/dist/controllers/app-env.js +156 -32
- package/dist/controllers/app.js +682 -396
- package/dist/controllers/project.js +177 -21
- package/dist/lib/app/domain-guidance.js +14 -0
- package/dist/lib/app/env-config.js +16 -6
- package/dist/lib/app/preview-build.js +50 -5
- package/dist/lib/app/preview-progress.js +1 -25
- package/dist/lib/app/preview-provider.js +99 -1
- package/dist/lib/auth/auth-ops.js +49 -8
- package/dist/lib/project/interactive-setup.js +56 -0
- package/dist/lib/project/resolution.js +124 -96
- package/dist/lib/project/setup.js +88 -0
- package/dist/presenters/app-env.js +4 -3
- package/dist/presenters/app.js +172 -73
- package/dist/presenters/auth.js +19 -6
- package/dist/presenters/project.js +44 -15
- package/dist/shell/command-arguments.js +6 -0
- package/dist/shell/command-meta.js +120 -24
- package/dist/shell/command-runner.js +21 -11
- package/dist/shell/errors.js +4 -1
- package/dist/shell/output.js +3 -1
- package/dist/use-cases/auth.js +15 -4
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,27 +1,145 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://i.imgur.com/h6UIYTu.png" alt="Prisma" width="360" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
# Prisma CLI
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
[](https://www.npmjs.com/package/@prisma/cli)
|
|
8
|
+
[](https://github.com/prisma/prisma-cli/blob/main/LICENSE)
|
|
9
|
+
[](https://www.npmjs.com/package/@prisma/cli)
|
|
10
|
+
|
|
11
|
+
[Quickstart](#quickstart) • [Commands](#commands) • [Beta notes](#beta-notes) • [Documentation](#documentation) • [Support](#support)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
`@prisma/cli` is the public beta of the new CLI for the
|
|
16
|
+
Prisma Developer Platform.
|
|
17
|
+
|
|
18
|
+
It is the terminal surface managing your platform projects, branches, apps,
|
|
19
|
+
deployments, and environment variables.
|
|
20
|
+
|
|
21
|
+
The command model is under active development to include tooling for your
|
|
22
|
+
schema, database, migration, and broader platform workflows.
|
|
23
|
+
|
|
24
|
+
Looking for Prisma ORM commands such as `prisma generate`, `prisma migrate`, or
|
|
25
|
+
`prisma studio`? Use the [`prisma`](https://www.npmjs.com/package/prisma)
|
|
26
|
+
package.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Quickstart
|
|
31
|
+
|
|
32
|
+
Install the beta package locally:
|
|
6
33
|
|
|
7
34
|
```bash
|
|
8
|
-
|
|
35
|
+
npm install --save-dev @prisma/cli
|
|
9
36
|
```
|
|
10
37
|
|
|
11
|
-
Run:
|
|
38
|
+
Run the binary exposed by this package:
|
|
12
39
|
|
|
13
40
|
```bash
|
|
14
|
-
|
|
41
|
+
npx prisma-cli --help
|
|
42
|
+
npx prisma-cli auth login
|
|
43
|
+
npx prisma-cli app deploy
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
With `pnpm`:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm add -D @prisma/cli
|
|
15
50
|
pnpm prisma-cli auth login
|
|
16
|
-
pnpm prisma-cli app deploy
|
|
17
|
-
|
|
51
|
+
pnpm prisma-cli app deploy
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Useful next commands:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx prisma-cli app logs
|
|
58
|
+
npx prisma-cli app open
|
|
59
|
+
npx prisma-cli project env add DATABASE_URL=postgresql://example --role preview
|
|
60
|
+
npx prisma-cli project env list --role preview
|
|
18
61
|
```
|
|
19
62
|
|
|
20
|
-
The package exposes `prisma-cli` so it can coexist with the existing
|
|
21
|
-
executable.
|
|
63
|
+
The beta package exposes `prisma-cli` so it can coexist with the existing
|
|
64
|
+
`prisma` executable.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Commands
|
|
69
|
+
|
|
70
|
+
| Group | What it does |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `version` | Show the installed CLI build and host environment. |
|
|
73
|
+
| `auth` | Log in, log out, and inspect the active Prisma account. |
|
|
74
|
+
| `project` | List projects, show the resolved project, and manage project environment variables. |
|
|
75
|
+
| `git` | Connect or disconnect a project from a GitHub repository. |
|
|
76
|
+
| `branch` | Inspect the Prisma branch that maps to the current work context. |
|
|
77
|
+
| `app` | Build, run, deploy, inspect, open, stream logs, promote, roll back, and remove apps. |
|
|
78
|
+
|
|
79
|
+
Common examples:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx prisma-cli version
|
|
83
|
+
npx prisma-cli auth whoami
|
|
84
|
+
npx prisma-cli project show
|
|
85
|
+
npx prisma-cli branch show
|
|
86
|
+
npx prisma-cli app deploy --branch feat-login --framework nextjs
|
|
87
|
+
npx prisma-cli app promote <deployment-id>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Built for humans, CI, and agents
|
|
91
|
+
|
|
92
|
+
- Human-readable output by default.
|
|
93
|
+
- `--json` for structured output.
|
|
94
|
+
- `--no-interactive` and `--yes` for automation.
|
|
95
|
+
- `PRISMA_SERVICE_TOKEN` for headless authenticated commands.
|
|
96
|
+
- Stable command groups, flags, and error codes for scripts and agents.
|
|
97
|
+
- Environment variable values are not printed back to the terminal.
|
|
98
|
+
|
|
99
|
+
### Agent skills
|
|
100
|
+
|
|
101
|
+
For agent-guided Next.js deploys, install the Prisma CLI skill cluster at the
|
|
102
|
+
project level. Match the skill ref to the installed CLI version:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npx prisma-cli version
|
|
106
|
+
pnpm dlx skills@latest add prisma/prisma-cli/skills#cli-v<cli-version> --all
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The skills teach agents how to prepare a Next.js app, run `app deploy`, verify
|
|
110
|
+
the result, and route CLI / Compute feedback to the right Prisma channel.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Beta notes
|
|
115
|
+
|
|
116
|
+
- Requires Node.js 20 or newer.
|
|
117
|
+
- This is a beta package and may change quickly.
|
|
118
|
+
- Official beta releases publish as `@prisma/cli`.
|
|
119
|
+
- The package binary is `prisma-cli`, not `prisma`, during beta.
|
|
120
|
+
- Local project context is cached in `.prisma/local.json`, which is gitignored and not a declarative repo config file.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Documentation
|
|
125
|
+
|
|
126
|
+
- [CLI docs index](https://github.com/prisma/prisma-cli/blob/main/docs/README.md)
|
|
127
|
+
- [Resource model](https://github.com/prisma/prisma-cli/blob/main/docs/product/resource-model.md)
|
|
128
|
+
- [Command principles](https://github.com/prisma/prisma-cli/blob/main/docs/product/command-principles.md)
|
|
129
|
+
- [Command spec](https://github.com/prisma/prisma-cli/blob/main/docs/product/command-spec.md)
|
|
130
|
+
- [Output conventions](https://github.com/prisma/prisma-cli/blob/main/docs/product/output-conventions.md)
|
|
131
|
+
- [Error conventions](https://github.com/prisma/prisma-cli/blob/main/docs/product/error-conventions.md)
|
|
132
|
+
|
|
133
|
+
## Support
|
|
134
|
+
|
|
135
|
+
Issues and feedback are welcome while the CLI is in public beta. Please use
|
|
136
|
+
[GitHub issues](https://github.com/prisma/prisma-cli/issues) for bug reports and
|
|
137
|
+
feature requests.
|
|
138
|
+
|
|
139
|
+
Security reports should follow Prisma's
|
|
140
|
+
[security policy](https://github.com/prisma/prisma-cli/blob/main/SECURITY.md)
|
|
141
|
+
and should not be filed as public issues.
|
|
22
142
|
|
|
23
|
-
|
|
143
|
+
## License
|
|
24
144
|
|
|
25
|
-
-
|
|
26
|
-
- `prisma.config.ts` stores linked project context for this CLI.
|
|
27
|
-
- Environment variable values passed with `--env` are not printed back to the terminal.
|
|
145
|
+
Apache-2.0
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { getAuthFilePath } from "../lib/auth/client.js";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
2
4
|
import { CredentialsStore } from "@prisma/credentials-store";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
3
6
|
//#region src/adapters/token-storage.ts
|
|
4
7
|
function findLatestValidTokens(allCredentials) {
|
|
5
8
|
for (let i = allCredentials.length - 1; i >= 0; i -= 1) {
|
|
@@ -14,10 +17,19 @@ function findLatestValidTokens(allCredentials) {
|
|
|
14
17
|
}
|
|
15
18
|
return null;
|
|
16
19
|
}
|
|
20
|
+
function tokensEqual(a, b) {
|
|
21
|
+
return a?.workspaceId === b?.workspaceId && a?.accessToken === b?.accessToken && a?.refreshToken === b?.refreshToken;
|
|
22
|
+
}
|
|
23
|
+
function sleep(ms) {
|
|
24
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
25
|
+
}
|
|
17
26
|
var FileTokenStorage = class {
|
|
18
27
|
credentialsStore;
|
|
28
|
+
lockFilePath;
|
|
19
29
|
constructor(env = process.env) {
|
|
20
|
-
|
|
30
|
+
const authFilePath = getAuthFilePath(env);
|
|
31
|
+
this.credentialsStore = new CredentialsStore(authFilePath);
|
|
32
|
+
this.lockFilePath = `${authFilePath}.lock`;
|
|
21
33
|
}
|
|
22
34
|
async getTokens() {
|
|
23
35
|
try {
|
|
@@ -38,6 +50,50 @@ var FileTokenStorage = class {
|
|
|
38
50
|
if (!tokens) return;
|
|
39
51
|
await this.credentialsStore.deleteCredentials(tokens.workspaceId);
|
|
40
52
|
}
|
|
53
|
+
async clearTokensIfCurrent(tokens) {
|
|
54
|
+
if (!tokensEqual(await this.getTokens(), tokens)) return;
|
|
55
|
+
await this.clearTokens();
|
|
56
|
+
}
|
|
57
|
+
async withRefreshLock(fn) {
|
|
58
|
+
const lockId = await this.acquireRefreshLock();
|
|
59
|
+
try {
|
|
60
|
+
return await fn();
|
|
61
|
+
} finally {
|
|
62
|
+
await this.releaseRefreshLock(lockId);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async acquireRefreshLock() {
|
|
66
|
+
const lockId = randomUUID();
|
|
67
|
+
await fs.mkdir(path.dirname(this.lockFilePath), { recursive: true });
|
|
68
|
+
while (true) try {
|
|
69
|
+
const handle = await fs.open(this.lockFilePath, "wx");
|
|
70
|
+
try {
|
|
71
|
+
await handle.writeFile(lockId, "utf8");
|
|
72
|
+
} finally {
|
|
73
|
+
await handle.close();
|
|
74
|
+
}
|
|
75
|
+
return lockId;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error.code !== "EEXIST") throw error;
|
|
78
|
+
const staleLockId = await this.getStaleRefreshLockId();
|
|
79
|
+
if (staleLockId) {
|
|
80
|
+
await this.releaseRefreshLock(staleLockId);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
await sleep(100);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async getStaleRefreshLockId() {
|
|
87
|
+
const lockId = await fs.readFile(this.lockFilePath, "utf8").catch(() => null);
|
|
88
|
+
if (lockId === null) return null;
|
|
89
|
+
const stats = await fs.stat(this.lockFilePath).catch(() => null);
|
|
90
|
+
if (!stats) return null;
|
|
91
|
+
return Date.now() - stats.mtimeMs > 3e4 ? lockId : null;
|
|
92
|
+
}
|
|
93
|
+
async releaseRefreshLock(lockId) {
|
|
94
|
+
if (await fs.readFile(this.lockFilePath, "utf8").catch(() => null) !== lockId) return;
|
|
95
|
+
await fs.unlink(this.lockFilePath).catch(() => {});
|
|
96
|
+
}
|
|
41
97
|
};
|
|
42
98
|
//#endregion
|
|
43
99
|
export { FileTokenStorage };
|
|
@@ -2,8 +2,8 @@ import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
|
2
2
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
4
|
import { PREVIEW_BUILD_TYPES } from "../../lib/app/preview-build.js";
|
|
5
|
-
import { runAppBuild, runAppDeploy,
|
|
6
|
-
import { renderAppBuild, renderAppDeploy,
|
|
5
|
+
import { runAppBuild, runAppDeploy, runAppDomainAdd, runAppDomainRemove, runAppDomainRetry, runAppDomainShow, runAppDomainWait, runAppListDeploys, runAppLogs, runAppOpen, runAppPromote, runAppRemove, runAppRollback, runAppRun, runAppShow, runAppShowDeploy } from "../../controllers/app.js";
|
|
6
|
+
import { renderAppBuild, renderAppDeploy, renderAppDomainAdd, renderAppDomainRemove, renderAppDomainRetry, renderAppDomainShow, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppDomainAdd, serializeAppDomainRemove, serializeAppDomainRetry, serializeAppDomainShow, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy } from "../../presenters/app.js";
|
|
7
7
|
import { runCommand, runStreamingCommand } from "../../shell/command-runner.js";
|
|
8
8
|
import { Command, Option } from "commander";
|
|
9
9
|
//#region src/commands/app/index.ts
|
|
@@ -13,10 +13,9 @@ function createAppCommand(runtime) {
|
|
|
13
13
|
app.addCommand(createBuildCommand(runtime));
|
|
14
14
|
app.addCommand(createRunCommand(runtime));
|
|
15
15
|
app.addCommand(createDeployCommand(runtime));
|
|
16
|
-
app.addCommand(createUpdateEnvCommand(runtime));
|
|
17
|
-
app.addCommand(createListEnvCommand(runtime));
|
|
18
16
|
app.addCommand(createShowCommand(runtime));
|
|
19
17
|
app.addCommand(createOpenCommand(runtime));
|
|
18
|
+
app.addCommand(createDomainCommand(runtime));
|
|
20
19
|
app.addCommand(createLogsCommand(runtime));
|
|
21
20
|
app.addCommand(createListDeploysCommand(runtime));
|
|
22
21
|
app.addCommand(createShowDeployCommand(runtime));
|
|
@@ -60,26 +59,27 @@ function createRunCommand(runtime) {
|
|
|
60
59
|
}
|
|
61
60
|
function createDeployCommand(runtime) {
|
|
62
61
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("deploy"), runtime), "app.deploy");
|
|
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([
|
|
62
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--create-project <name>", "Create and link a new Project before deploying")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([
|
|
64
63
|
"nextjs",
|
|
65
64
|
"hono",
|
|
66
|
-
"tanstack-start"
|
|
67
|
-
|
|
65
|
+
"tanstack-start",
|
|
66
|
+
"bun"
|
|
67
|
+
])).addOption(new Option("--entry <path>", "Entrypoint path for Bun deploys")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--env <name=value>", "Environment variable").argParser(collectRepeatableValues));
|
|
68
68
|
addGlobalFlags(command);
|
|
69
69
|
command.action(async (options) => {
|
|
70
70
|
const appName = options.app;
|
|
71
71
|
const entry = options.entry;
|
|
72
|
-
const buildType = options.buildType;
|
|
73
72
|
const branchName = options.branch;
|
|
74
73
|
const framework = options.framework;
|
|
75
74
|
const httpPort = options.httpPort;
|
|
76
75
|
const envAssignments = options.env;
|
|
77
76
|
const projectRef = options.project;
|
|
77
|
+
const createProjectName = options.createProject;
|
|
78
78
|
await runCommand(runtime, "app.deploy", options, (context) => runAppDeploy(context, appName, {
|
|
79
79
|
projectRef,
|
|
80
|
+
createProjectName,
|
|
80
81
|
branchName,
|
|
81
82
|
entrypoint: entry,
|
|
82
|
-
buildType,
|
|
83
83
|
framework,
|
|
84
84
|
httpPort,
|
|
85
85
|
envAssignments
|
|
@@ -90,63 +90,147 @@ function createDeployCommand(runtime) {
|
|
|
90
90
|
});
|
|
91
91
|
return command;
|
|
92
92
|
}
|
|
93
|
-
function
|
|
94
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("
|
|
95
|
-
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"))
|
|
93
|
+
function createShowCommand(runtime) {
|
|
94
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "app.show");
|
|
95
|
+
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
96
96
|
addGlobalFlags(command);
|
|
97
97
|
command.action(async (options) => {
|
|
98
98
|
const appName = options.app;
|
|
99
|
-
const envAssignments = options.env;
|
|
100
99
|
const projectRef = options.project;
|
|
101
|
-
await runCommand(runtime, "app.
|
|
102
|
-
renderHuman: (context, descriptor, result) =>
|
|
103
|
-
renderJson: (result) =>
|
|
100
|
+
await runCommand(runtime, "app.show", options, (context) => runAppShow(context, appName, projectRef), {
|
|
101
|
+
renderHuman: (context, descriptor, result) => renderAppShow(context, descriptor, result),
|
|
102
|
+
renderJson: (result) => serializeAppShow(result)
|
|
104
103
|
});
|
|
105
104
|
});
|
|
106
105
|
return command;
|
|
107
106
|
}
|
|
108
|
-
function
|
|
109
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("
|
|
107
|
+
function createOpenCommand(runtime) {
|
|
108
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("open"), runtime), "app.open");
|
|
110
109
|
command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
111
110
|
addGlobalFlags(command);
|
|
112
111
|
command.action(async (options) => {
|
|
113
112
|
const appName = options.app;
|
|
114
113
|
const projectRef = options.project;
|
|
115
|
-
await runCommand(runtime, "app.
|
|
116
|
-
renderHuman: (context, descriptor, result) =>
|
|
117
|
-
renderJson: (result) =>
|
|
114
|
+
await runCommand(runtime, "app.open", options, (context) => runAppOpen(context, appName, projectRef), {
|
|
115
|
+
renderHuman: (context, descriptor, result) => renderAppOpen(context, descriptor, result),
|
|
116
|
+
renderJson: (result) => serializeAppOpen(result)
|
|
118
117
|
});
|
|
119
118
|
});
|
|
120
119
|
return command;
|
|
121
120
|
}
|
|
122
|
-
function
|
|
123
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("
|
|
124
|
-
command
|
|
121
|
+
function createDomainCommand(runtime) {
|
|
122
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("domain"), runtime), "app.domain");
|
|
123
|
+
addCompactGlobalFlags(command);
|
|
124
|
+
command.addCommand(createDomainAddCommand(runtime));
|
|
125
|
+
command.addCommand(createDomainShowCommand(runtime));
|
|
126
|
+
command.addCommand(createDomainRemoveCommand(runtime));
|
|
127
|
+
command.addCommand(createDomainRetryCommand(runtime));
|
|
128
|
+
command.addCommand(createDomainWaitCommand(runtime));
|
|
129
|
+
return command;
|
|
130
|
+
}
|
|
131
|
+
function addDomainTargetOptions(command) {
|
|
132
|
+
return 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"));
|
|
133
|
+
}
|
|
134
|
+
function createDomainAddCommand(runtime) {
|
|
135
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("add"), runtime), "app.domain.add");
|
|
136
|
+
command.argument("<hostname>", "Custom domain hostname");
|
|
137
|
+
addDomainTargetOptions(command);
|
|
125
138
|
addGlobalFlags(command);
|
|
126
|
-
command.action(async (options) => {
|
|
139
|
+
command.action(async (hostname, options) => {
|
|
127
140
|
const appName = options.app;
|
|
128
141
|
const projectRef = options.project;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
142
|
+
const branchName = options.branch;
|
|
143
|
+
await runCommand(runtime, "app.domain.add", options, (context) => runAppDomainAdd(context, hostname, {
|
|
144
|
+
appName,
|
|
145
|
+
projectRef,
|
|
146
|
+
branchName
|
|
147
|
+
}), {
|
|
148
|
+
renderHuman: (context, descriptor, result) => renderAppDomainAdd(context, descriptor, result),
|
|
149
|
+
renderJson: (result) => serializeAppDomainAdd(result)
|
|
132
150
|
});
|
|
133
151
|
});
|
|
134
152
|
return command;
|
|
135
153
|
}
|
|
136
|
-
function
|
|
137
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("
|
|
138
|
-
command.
|
|
154
|
+
function createDomainShowCommand(runtime) {
|
|
155
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "app.domain.show");
|
|
156
|
+
command.argument("<hostname>", "Custom domain hostname");
|
|
157
|
+
addDomainTargetOptions(command);
|
|
139
158
|
addGlobalFlags(command);
|
|
140
|
-
command.action(async (options) => {
|
|
159
|
+
command.action(async (hostname, options) => {
|
|
141
160
|
const appName = options.app;
|
|
142
161
|
const projectRef = options.project;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
162
|
+
const branchName = options.branch;
|
|
163
|
+
await runCommand(runtime, "app.domain.show", options, (context) => runAppDomainShow(context, hostname, {
|
|
164
|
+
appName,
|
|
165
|
+
projectRef,
|
|
166
|
+
branchName
|
|
167
|
+
}), {
|
|
168
|
+
renderHuman: (context, descriptor, result) => renderAppDomainShow(context, descriptor, result),
|
|
169
|
+
renderJson: (result) => serializeAppDomainShow(result)
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
return command;
|
|
173
|
+
}
|
|
174
|
+
function createDomainRemoveCommand(runtime) {
|
|
175
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "app.domain.remove");
|
|
176
|
+
command.argument("<hostname>", "Custom domain hostname");
|
|
177
|
+
addDomainTargetOptions(command);
|
|
178
|
+
addGlobalFlags(command);
|
|
179
|
+
command.action(async (hostname, options) => {
|
|
180
|
+
const appName = options.app;
|
|
181
|
+
const projectRef = options.project;
|
|
182
|
+
const branchName = options.branch;
|
|
183
|
+
await runCommand(runtime, "app.domain.remove", options, (context) => runAppDomainRemove(context, hostname, {
|
|
184
|
+
appName,
|
|
185
|
+
projectRef,
|
|
186
|
+
branchName
|
|
187
|
+
}), {
|
|
188
|
+
renderHuman: (context, descriptor, result) => renderAppDomainRemove(context, descriptor, result),
|
|
189
|
+
renderJson: (result) => serializeAppDomainRemove(result)
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
return command;
|
|
193
|
+
}
|
|
194
|
+
function createDomainRetryCommand(runtime) {
|
|
195
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("retry"), runtime), "app.domain.retry");
|
|
196
|
+
command.argument("<hostname>", "Custom domain hostname");
|
|
197
|
+
addDomainTargetOptions(command);
|
|
198
|
+
addGlobalFlags(command);
|
|
199
|
+
command.action(async (hostname, options) => {
|
|
200
|
+
const appName = options.app;
|
|
201
|
+
const projectRef = options.project;
|
|
202
|
+
const branchName = options.branch;
|
|
203
|
+
await runCommand(runtime, "app.domain.retry", options, (context) => runAppDomainRetry(context, hostname, {
|
|
204
|
+
appName,
|
|
205
|
+
projectRef,
|
|
206
|
+
branchName
|
|
207
|
+
}), {
|
|
208
|
+
renderHuman: (context, descriptor, result) => renderAppDomainRetry(context, descriptor, result),
|
|
209
|
+
renderJson: (result) => serializeAppDomainRetry(result)
|
|
146
210
|
});
|
|
147
211
|
});
|
|
148
212
|
return command;
|
|
149
213
|
}
|
|
214
|
+
function createDomainWaitCommand(runtime) {
|
|
215
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("wait"), runtime), "app.domain.wait");
|
|
216
|
+
command.argument("<hostname>", "Custom domain hostname");
|
|
217
|
+
addDomainTargetOptions(command);
|
|
218
|
+
command.addOption(new Option("--timeout <duration>", "Maximum time to wait").default("15m"));
|
|
219
|
+
addGlobalFlags(command);
|
|
220
|
+
command.action(async (hostname, options) => {
|
|
221
|
+
const appName = options.app;
|
|
222
|
+
const projectRef = options.project;
|
|
223
|
+
const branchName = options.branch;
|
|
224
|
+
const timeout = options.timeout;
|
|
225
|
+
await runStreamingCommand(runtime, "app.domain.wait", options, (context) => runAppDomainWait(context, hostname, {
|
|
226
|
+
appName,
|
|
227
|
+
projectRef,
|
|
228
|
+
branchName,
|
|
229
|
+
timeout
|
|
230
|
+
}));
|
|
231
|
+
});
|
|
232
|
+
return command;
|
|
233
|
+
}
|
|
150
234
|
function createLogsCommand(runtime) {
|
|
151
235
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("logs"), runtime), "app.logs");
|
|
152
236
|
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"));
|
package/dist/commands/env.js
CHANGED
|
@@ -2,7 +2,7 @@ import { attachCommandDescriptor } from "../shell/command-meta.js";
|
|
|
2
2
|
import { addGlobalFlags } from "../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../shell/runtime.js";
|
|
4
4
|
import { runCommand } from "../shell/command-runner.js";
|
|
5
|
-
import { runEnvAdd, runEnvList,
|
|
5
|
+
import { runEnvAdd, runEnvList, runEnvRemove, runEnvUpdate } from "../controllers/app-env.js";
|
|
6
6
|
import { renderEnvAdd, renderEnvList, renderEnvRm, renderEnvUpdate, serializeEnvAdd, serializeEnvList, serializeEnvRm, serializeEnvUpdate } from "../presenters/app-env.js";
|
|
7
7
|
import { Command, Option } from "commander";
|
|
8
8
|
//#region src/commands/env.ts
|
|
@@ -12,18 +12,20 @@ function createEnvCommand(runtime) {
|
|
|
12
12
|
env.addCommand(createEnvAddCommand(runtime));
|
|
13
13
|
env.addCommand(createEnvUpdateCommand(runtime));
|
|
14
14
|
env.addCommand(createEnvListCommand(runtime));
|
|
15
|
-
env.addCommand(
|
|
15
|
+
env.addCommand(createEnvRemoveCommand(runtime));
|
|
16
16
|
return env;
|
|
17
17
|
}
|
|
18
18
|
function createEnvAddCommand(runtime) {
|
|
19
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"));
|
|
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("--branch <git-name>", "Preview branch override scope")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
21
21
|
addGlobalFlags(command);
|
|
22
22
|
command.action(async (assignment, options) => {
|
|
23
23
|
const roleName = options.role;
|
|
24
|
+
const branchName = options.branch;
|
|
24
25
|
const projectRef = options.project;
|
|
25
26
|
await runCommand(runtime, "project.env.add", options, (context) => runEnvAdd(context, assignment, {
|
|
26
27
|
roleName,
|
|
28
|
+
branchName,
|
|
27
29
|
projectRef
|
|
28
30
|
}), {
|
|
29
31
|
renderHuman: (context, descriptor, result) => renderEnvAdd(context, descriptor, result),
|
|
@@ -34,13 +36,15 @@ function createEnvAddCommand(runtime) {
|
|
|
34
36
|
}
|
|
35
37
|
function createEnvUpdateCommand(runtime) {
|
|
36
38
|
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"));
|
|
39
|
+
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("--branch <git-name>", "Preview branch override scope")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
38
40
|
addGlobalFlags(command);
|
|
39
41
|
command.action(async (assignment, options) => {
|
|
40
42
|
const roleName = options.role;
|
|
43
|
+
const branchName = options.branch;
|
|
41
44
|
const projectRef = options.project;
|
|
42
45
|
await runCommand(runtime, "project.env.update", options, (context) => runEnvUpdate(context, assignment, {
|
|
43
46
|
roleName,
|
|
47
|
+
branchName,
|
|
44
48
|
projectRef
|
|
45
49
|
}), {
|
|
46
50
|
renderHuman: (context, descriptor, result) => renderEnvUpdate(context, descriptor, result),
|
|
@@ -51,13 +55,15 @@ function createEnvUpdateCommand(runtime) {
|
|
|
51
55
|
}
|
|
52
56
|
function createEnvListCommand(runtime) {
|
|
53
57
|
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"));
|
|
58
|
+
command.addOption(new Option("--role <role>", "Project template scope").choices(["production", "preview"])).addOption(new Option("--branch <git-name>", "Preview branch resolved scope")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
55
59
|
addGlobalFlags(command);
|
|
56
60
|
command.action(async (options) => {
|
|
57
61
|
const roleName = options.role;
|
|
62
|
+
const branchName = options.branch;
|
|
58
63
|
const projectRef = options.project;
|
|
59
64
|
await runCommand(runtime, "project.env.list", options, (context) => runEnvList(context, {
|
|
60
65
|
roleName,
|
|
66
|
+
branchName,
|
|
61
67
|
projectRef
|
|
62
68
|
}), {
|
|
63
69
|
renderHuman: (context, descriptor, result) => renderEnvList(context, descriptor, result),
|
|
@@ -66,15 +72,17 @@ function createEnvListCommand(runtime) {
|
|
|
66
72
|
});
|
|
67
73
|
return command;
|
|
68
74
|
}
|
|
69
|
-
function
|
|
70
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("
|
|
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"));
|
|
75
|
+
function createEnvRemoveCommand(runtime) {
|
|
76
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "project.env.remove");
|
|
77
|
+
command.alias("rm").argument("<key>", "Variable key to remove").addOption(new Option("--role <role>", "Project template scope (production or preview)").choices(["production", "preview"])).addOption(new Option("--branch <git-name>", "Preview branch override scope")).addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
72
78
|
addGlobalFlags(command);
|
|
73
79
|
command.action(async (key, options) => {
|
|
74
80
|
const roleName = options.role;
|
|
81
|
+
const branchName = options.branch;
|
|
75
82
|
const projectRef = options.project;
|
|
76
|
-
await runCommand(runtime, "project.env.
|
|
83
|
+
await runCommand(runtime, "project.env.remove", options, (context) => runEnvRemove(context, key, {
|
|
77
84
|
roleName,
|
|
85
|
+
branchName,
|
|
78
86
|
projectRef
|
|
79
87
|
}), {
|
|
80
88
|
renderHuman: (context, descriptor, result) => renderEnvRm(context, descriptor, result),
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
2
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runProjectList, runProjectShow } from "../../controllers/project.js";
|
|
4
|
+
import { runProjectCreate, runProjectLink, runProjectList, runProjectShow } from "../../controllers/project.js";
|
|
5
5
|
import { runCommand } from "../../shell/command-runner.js";
|
|
6
|
-
import { renderProjectList, renderProjectShow, serializeProjectList, serializeProjectShow } from "../../presenters/project.js";
|
|
6
|
+
import { renderProjectList, renderProjectSetup, renderProjectShow, serializeProjectList, serializeProjectSetup, serializeProjectShow } from "../../presenters/project.js";
|
|
7
7
|
import { createEnvCommand } from "../env.js";
|
|
8
8
|
import { Command } from "commander";
|
|
9
9
|
//#region src/commands/project/index.ts
|
|
@@ -12,9 +12,35 @@ function createProjectCommand(runtime) {
|
|
|
12
12
|
addCompactGlobalFlags(project);
|
|
13
13
|
project.addCommand(createProjectListCommand(runtime));
|
|
14
14
|
project.addCommand(createProjectShowCommand(runtime));
|
|
15
|
+
project.addCommand(createProjectCreateCommand(runtime));
|
|
16
|
+
project.addCommand(createProjectLinkCommand(runtime));
|
|
15
17
|
project.addCommand(createEnvCommand(runtime));
|
|
16
18
|
return project;
|
|
17
19
|
}
|
|
20
|
+
function createProjectCreateCommand(runtime) {
|
|
21
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("create"), runtime), "project.create");
|
|
22
|
+
command.argument("<name>", "Project name");
|
|
23
|
+
addGlobalFlags(command);
|
|
24
|
+
command.action(async (name, options) => {
|
|
25
|
+
await runCommand(runtime, "project.create", options, (context) => runProjectCreate(context, String(name)), {
|
|
26
|
+
renderHuman: (context, descriptor, result) => renderProjectSetup(context, descriptor, result),
|
|
27
|
+
renderJson: (result) => serializeProjectSetup(result)
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
return command;
|
|
31
|
+
}
|
|
32
|
+
function createProjectLinkCommand(runtime) {
|
|
33
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("link"), runtime), "project.link");
|
|
34
|
+
command.argument("[id-or-name]", "Project id or name");
|
|
35
|
+
addGlobalFlags(command);
|
|
36
|
+
command.action(async (projectRef, options) => {
|
|
37
|
+
await runCommand(runtime, "project.link", options, (context) => runProjectLink(context, typeof projectRef === "string" ? projectRef : void 0), {
|
|
38
|
+
renderHuman: (context, descriptor, result) => renderProjectSetup(context, descriptor, result),
|
|
39
|
+
renderJson: (result) => serializeProjectSetup(result)
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return command;
|
|
43
|
+
}
|
|
18
44
|
function createProjectListCommand(runtime) {
|
|
19
45
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "project.list");
|
|
20
46
|
addGlobalFlags(command);
|