@prisma/cli 3.0.0-dev.97.1 → 8.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -14
- package/dist/adapters/local-state.js +14 -3
- package/dist/{lib/auth → auth}/client.js +11 -3
- package/dist/auth/errors.js +50 -0
- package/dist/{lib/auth → auth}/guard.js +7 -6
- package/dist/{lib/auth → auth}/login.js +147 -6
- package/dist/{lib/auth/auth-ops.js → auth/operations.js} +63 -13
- package/dist/auth/recipient.js +42 -0
- package/dist/{adapters → auth}/token-storage.js +28 -7
- package/dist/auth/workspaces.js +171 -0
- package/dist/cli-command.js +14 -0
- package/dist/cli-name.js +12 -0
- package/dist/cli.js +1 -1
- package/dist/cli2.js +25 -8
- package/dist/command-arguments.js +12 -0
- package/dist/commands/agent/index.js +60 -0
- package/dist/commands/app/index.js +11 -6
- package/dist/commands/auth/index.js +2 -3
- package/dist/commands/bucket/index.js +123 -0
- package/dist/commands/build/index.js +29 -0
- package/dist/commands/database/index.js +92 -2
- package/dist/commands/feedback/index.js +20 -0
- package/dist/commands/git/index.js +1 -1
- package/dist/commands/init/index.js +33 -0
- package/dist/commands/project/index.js +54 -5
- package/dist/controllers/agent-setup.js +52 -0
- package/dist/controllers/agent.js +228 -0
- package/dist/controllers/app-env-api.js +3 -2
- package/dist/controllers/app-env-file.js +1 -1
- package/dist/controllers/app-env.js +5 -5
- package/dist/controllers/app.js +423 -358
- package/dist/controllers/auth.js +62 -254
- package/dist/controllers/branch.js +5 -16
- package/dist/controllers/bucket.js +184 -0
- package/dist/controllers/build.js +88 -0
- package/dist/controllers/database.js +230 -85
- package/dist/controllers/feedback.js +90 -0
- package/dist/controllers/init.js +814 -0
- package/dist/controllers/project.js +345 -184
- package/dist/controllers/select-prompt-port.js +1 -0
- package/dist/{shell/errors.js → errors.js} +8 -40
- package/dist/lib/agent/cli-command.js +20 -0
- package/dist/lib/agent/constants.js +12 -0
- package/dist/lib/agent/package-manager.js +99 -0
- package/dist/lib/agent/setup-status.js +83 -0
- package/dist/lib/app/app-provider.js +168 -95
- package/dist/lib/app/branch-database-deploy.js +70 -42
- package/dist/lib/app/branch-database.js +39 -20
- package/dist/lib/app/build-settings.js +8 -3
- package/dist/lib/app/build.js +16 -14
- package/dist/lib/app/bun-project.js +1 -1
- package/dist/lib/app/compute-config.js +29 -31
- package/dist/lib/app/deploy-plan.js +1 -0
- package/dist/lib/app/deploy-progress.js +7 -7
- package/dist/lib/app/env-config.js +1 -1
- package/dist/lib/app/env-file.js +2 -2
- package/dist/lib/app/env-vars.js +1 -1
- package/dist/lib/app/local-dev.js +1 -1
- package/dist/lib/app/production-deploy-gate.js +3 -2
- package/dist/lib/bucket/provider.js +139 -0
- package/dist/lib/database/provider.js +235 -17
- package/dist/lib/diagnostics.js +2 -1
- package/dist/lib/feedback.js +15 -0
- package/dist/lib/git/local-branch.js +1 -1
- package/dist/lib/project/interactive-setup.js +6 -5
- package/dist/lib/project/local-pin.js +1 -1
- package/dist/lib/project/provider.js +93 -0
- package/dist/lib/project/resolution.js +11 -8
- package/dist/lib/project/setup.js +9 -6
- package/dist/lib/version.js +3 -2
- package/dist/lib/workspace-id.js +18 -0
- package/dist/payload-B88Qvzxk-CrtTXSOe.js +34 -0
- package/dist/presenters/agent.js +74 -0
- package/dist/presenters/app.js +33 -7
- package/dist/presenters/auth.js +3 -2
- package/dist/presenters/bucket.js +174 -0
- package/dist/presenters/database.js +193 -5
- package/dist/presenters/feedback.js +26 -0
- package/dist/presenters/init.js +30 -0
- package/dist/presenters/project.js +98 -4
- package/dist/shell/cli-command.js +2 -0
- package/dist/shell/command-meta.js +303 -4
- package/dist/shell/command-runner.js +13 -6
- package/dist/shell/help.js +6 -5
- package/dist/shell/output.js +65 -3
- package/dist/shell/prompt.js +12 -5
- package/dist/shell/runtime.js +4 -21
- package/dist/state-dir.js +12 -0
- package/dist/{shell/update-check.js → update-check.js} +6 -5
- package/dist/v8/cli.js +14699 -0
- package/dist/v8/sender.js +192 -0
- package/package.json +21 -13
- package/dist/adapters/mock-api.js +0 -136
- package/dist/lib/app/app-interaction.js +0 -5
- package/dist/shell/command-arguments.js +0 -6
- package/dist/use-cases/auth.js +0 -145
- package/dist/use-cases/branch.js +0 -47
- package/dist/use-cases/create-cli-gateways.js +0 -68
- package/dist/use-cases/project.js +0 -30
|
@@ -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 { runCommand } from "../../shell/command-runner.js";
|
|
5
|
-
import { runDatabaseConnectionCreate, runDatabaseConnectionList, runDatabaseConnectionRemove, runDatabaseCreate, runDatabaseList, runDatabaseRemove, runDatabaseShow } from "../../controllers/database.js";
|
|
6
|
-
import { renderDatabaseConnectionCreate, renderDatabaseConnectionCreateStdout, renderDatabaseConnectionList, renderDatabaseConnectionRemove, renderDatabaseCreate, renderDatabaseCreateStdout, renderDatabaseList, renderDatabaseRemove, renderDatabaseShow, serializeDatabaseConnectionCreate, serializeDatabaseConnectionList, serializeDatabaseConnectionRemove, serializeDatabaseCreate, serializeDatabaseList, serializeDatabaseRemove, serializeDatabaseShow } from "../../presenters/database.js";
|
|
5
|
+
import { runDatabaseBackupList, runDatabaseConnectionCreate, runDatabaseConnectionList, runDatabaseConnectionRemove, runDatabaseConnectionRotate, runDatabaseCreate, runDatabaseList, runDatabaseRemove, runDatabaseRestore, runDatabaseShow, runDatabaseUsage } from "../../controllers/database.js";
|
|
6
|
+
import { renderDatabaseBackupList, renderDatabaseConnectionCreate, renderDatabaseConnectionCreateStdout, renderDatabaseConnectionList, renderDatabaseConnectionRemove, renderDatabaseConnectionRotate, renderDatabaseConnectionRotateStdout, renderDatabaseCreate, renderDatabaseCreateStdout, renderDatabaseList, renderDatabaseRemove, renderDatabaseRestore, renderDatabaseShow, renderDatabaseUsage, serializeDatabaseBackupList, serializeDatabaseConnectionCreate, serializeDatabaseConnectionList, serializeDatabaseConnectionRemove, serializeDatabaseConnectionRotate, serializeDatabaseCreate, serializeDatabaseList, serializeDatabaseRemove, serializeDatabaseRestore, serializeDatabaseShow, serializeDatabaseUsage } from "../../presenters/database.js";
|
|
7
7
|
import { Command, Option } from "commander";
|
|
8
8
|
//#region src/commands/database/index.ts
|
|
9
9
|
function createDatabaseCommand(runtime) {
|
|
@@ -12,7 +12,10 @@ function createDatabaseCommand(runtime) {
|
|
|
12
12
|
database.addCommand(createDatabaseListCommand(runtime));
|
|
13
13
|
database.addCommand(createDatabaseShowCommand(runtime));
|
|
14
14
|
database.addCommand(createDatabaseCreateCommand(runtime));
|
|
15
|
+
database.addCommand(createDatabaseUsageCommand(runtime));
|
|
16
|
+
database.addCommand(createDatabaseRestoreCommand(runtime));
|
|
15
17
|
database.addCommand(createDatabaseRemoveCommand(runtime));
|
|
18
|
+
database.addCommand(createDatabaseBackupCommand(runtime));
|
|
16
19
|
database.addCommand(createDatabaseConnectionCommand(runtime));
|
|
17
20
|
return database;
|
|
18
21
|
}
|
|
@@ -75,6 +78,78 @@ function createDatabaseCreateCommand(runtime) {
|
|
|
75
78
|
});
|
|
76
79
|
return command;
|
|
77
80
|
}
|
|
81
|
+
function createDatabaseUsageCommand(runtime) {
|
|
82
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("usage"), runtime), "database.usage");
|
|
83
|
+
command.argument("<database>", "Database id or name").addOption(new Option("--from <iso-date>", "Start of the usage period")).addOption(new Option("--to <iso-date>", "End of the usage period"));
|
|
84
|
+
addProjectAndBranchOptions(command);
|
|
85
|
+
addGlobalFlags(command);
|
|
86
|
+
command.action(async (databaseRef, options) => {
|
|
87
|
+
const projectRef = options.project;
|
|
88
|
+
const branchName = options.branch;
|
|
89
|
+
const from = options.from;
|
|
90
|
+
const to = options.to;
|
|
91
|
+
await runCommand(runtime, "database.usage", options, (context) => runDatabaseUsage(context, databaseRef, {
|
|
92
|
+
projectRef,
|
|
93
|
+
branchName,
|
|
94
|
+
from,
|
|
95
|
+
to
|
|
96
|
+
}), {
|
|
97
|
+
renderHuman: (context, descriptor, result) => renderDatabaseUsage(context, descriptor, result),
|
|
98
|
+
renderJson: (result) => serializeDatabaseUsage(result)
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
return command;
|
|
102
|
+
}
|
|
103
|
+
function createDatabaseRestoreCommand(runtime) {
|
|
104
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("restore"), runtime), "database.restore");
|
|
105
|
+
command.argument("<database>", "Target database id or name").addOption(new Option("--backup <backup-id>", "Backup to restore from")).addOption(new Option("--source-database <database>", "Database the backup belongs to (defaults to the target)")).addOption(new Option("--confirm <database-id>", "Exact target database id required to restore"));
|
|
106
|
+
addProjectAndBranchOptions(command);
|
|
107
|
+
addGlobalFlags(command);
|
|
108
|
+
command.action(async (databaseRef, options) => {
|
|
109
|
+
const projectRef = options.project;
|
|
110
|
+
const branchName = options.branch;
|
|
111
|
+
const backupId = options.backup;
|
|
112
|
+
const sourceDatabaseRef = options.sourceDatabase;
|
|
113
|
+
const confirm = options.confirm;
|
|
114
|
+
await runCommand(runtime, "database.restore", options, (context) => runDatabaseRestore(context, databaseRef, {
|
|
115
|
+
projectRef,
|
|
116
|
+
branchName,
|
|
117
|
+
backupId,
|
|
118
|
+
sourceDatabaseRef,
|
|
119
|
+
confirm
|
|
120
|
+
}), {
|
|
121
|
+
renderHuman: (context, descriptor, result) => renderDatabaseRestore(context, descriptor, result),
|
|
122
|
+
renderJson: (result) => serializeDatabaseRestore(result)
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
return command;
|
|
126
|
+
}
|
|
127
|
+
function createDatabaseBackupCommand(runtime) {
|
|
128
|
+
const backup = attachCommandDescriptor(configureRuntimeCommand(new Command("backup"), runtime), "database.backup");
|
|
129
|
+
addCompactGlobalFlags(backup);
|
|
130
|
+
backup.addCommand(createDatabaseBackupListCommand(runtime));
|
|
131
|
+
return backup;
|
|
132
|
+
}
|
|
133
|
+
function createDatabaseBackupListCommand(runtime) {
|
|
134
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "database.backup.list");
|
|
135
|
+
command.argument("<database>", "Database id or name").addOption(new Option("--limit <n>", "Maximum number of backups to return"));
|
|
136
|
+
addProjectAndBranchOptions(command);
|
|
137
|
+
addGlobalFlags(command);
|
|
138
|
+
command.action(async (databaseRef, options) => {
|
|
139
|
+
const projectRef = options.project;
|
|
140
|
+
const branchName = options.branch;
|
|
141
|
+
const limit = options.limit;
|
|
142
|
+
await runCommand(runtime, "database.backup.list", options, (context) => runDatabaseBackupList(context, databaseRef, {
|
|
143
|
+
projectRef,
|
|
144
|
+
branchName,
|
|
145
|
+
limit
|
|
146
|
+
}), {
|
|
147
|
+
renderHuman: (context, descriptor, result) => renderDatabaseBackupList(context, descriptor, result),
|
|
148
|
+
renderJson: (result) => serializeDatabaseBackupList(result)
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
return command;
|
|
152
|
+
}
|
|
78
153
|
function createDatabaseRemoveCommand(runtime) {
|
|
79
154
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "database.remove");
|
|
80
155
|
command.argument("<database>", "Database id or name").addOption(new Option("--confirm <database-id>", "Exact database id required to remove"));
|
|
@@ -100,9 +175,24 @@ function createDatabaseConnectionCommand(runtime) {
|
|
|
100
175
|
addCompactGlobalFlags(connection);
|
|
101
176
|
connection.addCommand(createDatabaseConnectionListCommand(runtime));
|
|
102
177
|
connection.addCommand(createDatabaseConnectionCreateCommand(runtime));
|
|
178
|
+
connection.addCommand(createDatabaseConnectionRotateCommand(runtime));
|
|
103
179
|
connection.addCommand(createDatabaseConnectionRemoveCommand(runtime));
|
|
104
180
|
return connection;
|
|
105
181
|
}
|
|
182
|
+
function createDatabaseConnectionRotateCommand(runtime) {
|
|
183
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("rotate"), runtime), "database.connection.rotate");
|
|
184
|
+
command.argument("<connection>", "Connection id").addOption(new Option("--confirm <connection-id>", "Exact connection id required to rotate"));
|
|
185
|
+
addGlobalFlags(command);
|
|
186
|
+
command.action(async (connectionRef, options) => {
|
|
187
|
+
const confirm = options.confirm;
|
|
188
|
+
await runCommand(runtime, "database.connection.rotate", options, (context) => runDatabaseConnectionRotate(context, connectionRef, { confirm }), {
|
|
189
|
+
renderStdout: (context, descriptor, result) => renderDatabaseConnectionRotateStdout(context, descriptor, result),
|
|
190
|
+
renderHuman: (context, descriptor, result) => renderDatabaseConnectionRotate(context, descriptor, result),
|
|
191
|
+
renderJson: (result) => serializeDatabaseConnectionRotate(result)
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
return command;
|
|
195
|
+
}
|
|
106
196
|
function createDatabaseConnectionListCommand(runtime) {
|
|
107
197
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "database.connection.list");
|
|
108
198
|
command.argument("<database>", "Database id or name");
|
|
@@ -0,0 +1,20 @@
|
|
|
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 { runFeedback } from "../../controllers/feedback.js";
|
|
6
|
+
import { renderFeedbackSuccess } from "../../presenters/feedback.js";
|
|
7
|
+
import { Command, Option } from "commander";
|
|
8
|
+
//#region src/commands/feedback/index.ts
|
|
9
|
+
function createFeedbackCommand(runtime) {
|
|
10
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("feedback"), runtime), "feedback");
|
|
11
|
+
command.argument("<message>", "Feedback text (up to 4000 characters)").addOption(new Option("--email <address>", "Contact email if you want a reply; feedback is anonymous without it"));
|
|
12
|
+
addGlobalFlags(command);
|
|
13
|
+
command.action(async (message, options) => {
|
|
14
|
+
const flags = options;
|
|
15
|
+
await runCommand(runtime, "feedback", options, (context) => runFeedback(context, message, { email: flags.email }), { renderHuman: (context, descriptor, result) => renderFeedbackSuccess(context, descriptor, result) });
|
|
16
|
+
});
|
|
17
|
+
return command;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { createFeedbackCommand };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
2
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runGitConnect, runGitDisconnect } from "../../controllers/project.js";
|
|
5
4
|
import { runCommand } from "../../shell/command-runner.js";
|
|
5
|
+
import { runGitConnect, runGitDisconnect } from "../../controllers/project.js";
|
|
6
6
|
import { renderGitConnect, renderGitDisconnect } from "../../presenters/project.js";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
//#region src/commands/git/index.ts
|
|
@@ -0,0 +1,33 @@
|
|
|
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 { runInit } from "../../controllers/init.js";
|
|
6
|
+
import { renderInit, serializeInit } from "../../presenters/init.js";
|
|
7
|
+
import { Command, Option } from "commander";
|
|
8
|
+
//#region src/commands/init/index.ts
|
|
9
|
+
function createInitCommand(runtime) {
|
|
10
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("init"), runtime), "init");
|
|
11
|
+
command.addOption(new Option("--framework <framework>", "Framework override; detected when omitted")).addOption(new Option("--entry <path>", "Source entrypoint for entrypoint frameworks (Bun, Hono)")).addOption(new Option("--http-port <port>", "HTTP port the app listens on")).addOption(new Option("--region <region>", "Region used when deploy creates the app")).addOption(new Option("--name <app-name>", "App name")).addOption(new Option("--link", "Link this directory to a Project")).addOption(new Option("--no-link", "Skip the Project link step")).addOption(new Option("--project <id-or-name>", "Project to link this directory to")).addOption(new Option("--install", "Install @prisma/compute-sdk for config types")).addOption(new Option("--no-install", "Skip the types install step")).addOption(new Option("--format <ts|json>", "Config file format: ts (default) writes prisma.compute.ts, json writes dependency-free prisma.compute.json; --format ts converts an existing prisma.compute.json"));
|
|
12
|
+
addGlobalFlags(command);
|
|
13
|
+
command.action(async (options) => {
|
|
14
|
+
const flags = options;
|
|
15
|
+
await runCommand(runtime, "init", options, (context) => runInit(context, {
|
|
16
|
+
framework: flags.framework,
|
|
17
|
+
entry: flags.entry,
|
|
18
|
+
httpPort: flags.httpPort,
|
|
19
|
+
region: flags.region,
|
|
20
|
+
name: flags.name,
|
|
21
|
+
link: flags.link,
|
|
22
|
+
project: flags.project,
|
|
23
|
+
install: flags.install,
|
|
24
|
+
format: flags.format
|
|
25
|
+
}), {
|
|
26
|
+
renderHuman: (context, descriptor, result) => renderInit(context, descriptor, result),
|
|
27
|
+
renderJson: (result) => serializeInit(result)
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
return command;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { createInitCommand };
|
|
@@ -1,11 +1,11 @@
|
|
|
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 { runProjectCreate, runProjectLink, runProjectList, runProjectShow } from "../../controllers/project.js";
|
|
5
4
|
import { runCommand } from "../../shell/command-runner.js";
|
|
6
|
-
import {
|
|
5
|
+
import { runProjectCreate, runProjectLink, runProjectList, runProjectRemove, runProjectRename, runProjectShow, runProjectTransfer } from "../../controllers/project.js";
|
|
6
|
+
import { renderProjectList, renderProjectRemove, renderProjectRename, renderProjectSetup, renderProjectShow, renderProjectTransfer, serializeProjectList, serializeProjectRemove, serializeProjectRename, serializeProjectSetup, serializeProjectShow, serializeProjectTransfer } from "../../presenters/project.js";
|
|
7
7
|
import { createEnvCommand } from "../env.js";
|
|
8
|
-
import { Command } from "commander";
|
|
8
|
+
import { Command, Option } from "commander";
|
|
9
9
|
//#region src/commands/project/index.ts
|
|
10
10
|
function createProjectCommand(runtime) {
|
|
11
11
|
const project = attachCommandDescriptor(configureRuntimeCommand(new Command("project"), runtime), "project");
|
|
@@ -14,15 +14,64 @@ function createProjectCommand(runtime) {
|
|
|
14
14
|
project.addCommand(createProjectShowCommand(runtime));
|
|
15
15
|
project.addCommand(createProjectCreateCommand(runtime));
|
|
16
16
|
project.addCommand(createProjectLinkCommand(runtime));
|
|
17
|
+
project.addCommand(createProjectRenameCommand(runtime));
|
|
18
|
+
project.addCommand(createProjectRemoveCommand(runtime));
|
|
19
|
+
project.addCommand(createProjectTransferCommand(runtime));
|
|
17
20
|
project.addCommand(createEnvCommand(runtime));
|
|
18
21
|
return project;
|
|
19
22
|
}
|
|
23
|
+
function createProjectRenameCommand(runtime) {
|
|
24
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("rename"), runtime), "project.rename");
|
|
25
|
+
command.argument("<name>", "New project name").addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
26
|
+
addGlobalFlags(command);
|
|
27
|
+
command.action(async (name, options) => {
|
|
28
|
+
const projectRef = options.project;
|
|
29
|
+
await runCommand(runtime, "project.rename", options, (context) => runProjectRename(context, name, { project: projectRef }), {
|
|
30
|
+
renderHuman: (context, descriptor, result) => renderProjectRename(context, descriptor, result),
|
|
31
|
+
renderJson: (result) => serializeProjectRename(result)
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
return command;
|
|
35
|
+
}
|
|
36
|
+
function createProjectRemoveCommand(runtime) {
|
|
37
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "project.remove");
|
|
38
|
+
command.argument("<project>", "Project id or name").addOption(new Option("--confirm <project-id>", "Exact project id required to remove"));
|
|
39
|
+
addGlobalFlags(command);
|
|
40
|
+
command.action(async (projectRef, options) => {
|
|
41
|
+
const confirm = options.confirm;
|
|
42
|
+
await runCommand(runtime, "project.remove", options, (context) => runProjectRemove(context, projectRef, { confirm }), {
|
|
43
|
+
renderHuman: (context, descriptor, result) => renderProjectRemove(context, descriptor, result),
|
|
44
|
+
renderJson: (result) => serializeProjectRemove(result)
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
return command;
|
|
48
|
+
}
|
|
49
|
+
function createProjectTransferCommand(runtime) {
|
|
50
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("transfer"), runtime), "project.transfer");
|
|
51
|
+
command.argument("<project>", "Project id or name").addOption(new Option("--to-workspace <id-or-name>", "Locally authenticated workspace to receive the project")).addOption(new Option("--recipient-token <token>", "Access token for the receiving workspace")).addOption(new Option("--confirm <project-id>", "Exact project id required to transfer"));
|
|
52
|
+
addGlobalFlags(command);
|
|
53
|
+
command.action(async (projectRef, options) => {
|
|
54
|
+
const toWorkspace = options.toWorkspace;
|
|
55
|
+
const recipientToken = options.recipientToken;
|
|
56
|
+
const confirm = options.confirm;
|
|
57
|
+
await runCommand(runtime, "project.transfer", options, (context) => runProjectTransfer(context, projectRef, {
|
|
58
|
+
toWorkspace,
|
|
59
|
+
recipientToken,
|
|
60
|
+
confirm
|
|
61
|
+
}), {
|
|
62
|
+
renderHuman: (context, descriptor, result) => renderProjectTransfer(context, descriptor, result),
|
|
63
|
+
renderJson: (result) => serializeProjectTransfer(result)
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
return command;
|
|
67
|
+
}
|
|
20
68
|
function createProjectCreateCommand(runtime) {
|
|
21
69
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("create"), runtime), "project.create");
|
|
22
|
-
command.argument("<name>", "Project name");
|
|
70
|
+
command.argument("<name>", "Project name").addOption(new Option("--region <region>", "Prisma Compute region id"));
|
|
23
71
|
addGlobalFlags(command);
|
|
24
72
|
command.action(async (name, options) => {
|
|
25
|
-
|
|
73
|
+
const region = options.region;
|
|
74
|
+
await runCommand(runtime, "project.create", options, (context) => runProjectCreate(context, String(name), { region }), {
|
|
26
75
|
renderHuman: (context, descriptor, result) => renderProjectSetup(context, descriptor, result),
|
|
27
76
|
renderJson: (result) => serializeProjectSetup(result)
|
|
28
77
|
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { resolvePrismaCliPackageCommand } from "../lib/agent/cli-command.js";
|
|
2
|
+
import { PRISMA_AGENT_INSTALL_ARGS, PRISMA_COMPUTE_AGENT_SKILL } from "../lib/agent/constants.js";
|
|
3
|
+
import { readPrismaAgentSetupStatus, shouldOfferPrismaAgentSetup } from "../lib/agent/setup-status.js";
|
|
4
|
+
import { runAgentInstall } from "./agent.js";
|
|
5
|
+
import { renderSummaryLine } from "../shell/ui.js";
|
|
6
|
+
import { canPrompt } from "../shell/runtime.js";
|
|
7
|
+
import { confirmPrompt } from "../shell/prompt.js";
|
|
8
|
+
//#region src/controllers/agent-setup.ts
|
|
9
|
+
/**
|
|
10
|
+
* One-time interactive offer to install the Prisma Compute skill for the
|
|
11
|
+
* project. Shared by the commands that establish a project setup (init,
|
|
12
|
+
* deploy); the answer is remembered, so whichever command runs first asks.
|
|
13
|
+
* Returns warnings; a failed install must not fail the calling command.
|
|
14
|
+
*/
|
|
15
|
+
async function maybePromptForAgentSetup(context, projectDir) {
|
|
16
|
+
if (!canPrompt(context) || context.flags.yes || context.flags.quiet) return [];
|
|
17
|
+
if (!shouldOfferPrismaAgentSetup(await readPrismaAgentSetupStatus({
|
|
18
|
+
cwd: projectDir,
|
|
19
|
+
stateStore: context.stateStore,
|
|
20
|
+
signal: context.runtime.signal,
|
|
21
|
+
requiredSkill: "prisma-compute"
|
|
22
|
+
}))) return [];
|
|
23
|
+
if (!await confirmPrompt({
|
|
24
|
+
input: context.runtime.stdin,
|
|
25
|
+
output: context.runtime.stderr,
|
|
26
|
+
signal: context.runtime.signal,
|
|
27
|
+
message: "Install the Prisma Compute skill for this project?",
|
|
28
|
+
initialValue: true
|
|
29
|
+
})) {
|
|
30
|
+
await context.stateStore.setAgentSetupPromptDismissedAt((/* @__PURE__ */ new Date()).toISOString());
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
await runAgentInstall(context, { skill: [PRISMA_COMPUTE_AGENT_SKILL] }, "install", { cwd: projectDir });
|
|
35
|
+
if (!context.flags.quiet && !context.flags.json) context.output.stderr.write(`${renderSummaryLine(context.ui, "success", "Installed the Prisma Compute skill for this project.")}\n\n`);
|
|
36
|
+
return [];
|
|
37
|
+
} catch (error) {
|
|
38
|
+
const message = error instanceof Error ? error.message : "Prisma skill install failed.";
|
|
39
|
+
if (!context.flags.quiet && !context.flags.json) context.output.stderr.write(`${renderSummaryLine(context.ui, "warning", `Skipped Prisma skill install: ${message}`)}\n\n`);
|
|
40
|
+
return [`The Prisma Compute skill was not installed. Run ${await resolvePrismaCliPackageCommand({
|
|
41
|
+
cwd: projectDir,
|
|
42
|
+
signal: context.runtime.signal,
|
|
43
|
+
args: [
|
|
44
|
+
...PRISMA_AGENT_INSTALL_ARGS,
|
|
45
|
+
"--skill",
|
|
46
|
+
PRISMA_COMPUTE_AGENT_SKILL
|
|
47
|
+
]
|
|
48
|
+
})} to try again.`];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { maybePromptForAgentSetup };
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { resolveSkillsPackageRunner } from "../lib/agent/package-manager.js";
|
|
2
|
+
import { resolvePrismaCliPackageCommand } from "../lib/agent/cli-command.js";
|
|
3
|
+
import { DEFAULT_PRISMA_AGENT_SKILLS, DEFAULT_PRISMA_AGENT_TARGETS, PRISMA_AGENT_INSTALL_ARGS, PRISMA_AGENT_STATUS_ARGS, PRISMA_SKILLS_SOURCE, SKILLS_CLI_PACKAGE } from "../lib/agent/constants.js";
|
|
4
|
+
import { readPrismaAgentSetupStatus, resolvePrismaAgentSetupCwd } from "../lib/agent/setup-status.js";
|
|
5
|
+
import { formatShellCommand } from "../command-arguments.js";
|
|
6
|
+
import { CliError } from "../errors.js";
|
|
7
|
+
import { execa } from "execa";
|
|
8
|
+
//#region src/controllers/agent.ts
|
|
9
|
+
async function runAgentInstall(context, options, operation = "install", runOptions = {}) {
|
|
10
|
+
const dryRun = options.dryRun === true;
|
|
11
|
+
const cwd = await resolvePrismaAgentSetupCwd({
|
|
12
|
+
cwd: runOptions.cwd ?? context.runtime.cwd,
|
|
13
|
+
signal: context.runtime.signal
|
|
14
|
+
});
|
|
15
|
+
const skills = await installSkills(context, {
|
|
16
|
+
command: await buildSkillsInstallCommand(context, options, cwd),
|
|
17
|
+
cwd,
|
|
18
|
+
dryRun
|
|
19
|
+
});
|
|
20
|
+
const nextSteps = await resolveAgentInstallNextSteps(context, {
|
|
21
|
+
cwd,
|
|
22
|
+
dryRun,
|
|
23
|
+
global: options.global === true
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
command: `agent.${operation}`,
|
|
27
|
+
result: {
|
|
28
|
+
operation,
|
|
29
|
+
skills
|
|
30
|
+
},
|
|
31
|
+
warnings: [],
|
|
32
|
+
nextSteps
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async function resolveAgentInstallNextSteps(context, options) {
|
|
36
|
+
if (options.dryRun) return [];
|
|
37
|
+
return [`Run ${await resolvePrismaCliPackageCommand({
|
|
38
|
+
cwd: options.cwd,
|
|
39
|
+
signal: context.runtime.signal,
|
|
40
|
+
args: options.global ? [...PRISMA_AGENT_STATUS_ARGS, "--global"] : PRISMA_AGENT_STATUS_ARGS
|
|
41
|
+
})} to verify the installed Prisma skills.`];
|
|
42
|
+
}
|
|
43
|
+
async function runAgentStatus(context, options = {}) {
|
|
44
|
+
const statusScope = options.global ? "global" : "project";
|
|
45
|
+
const cwd = await resolvePrismaAgentSetupCwd({
|
|
46
|
+
cwd: context.runtime.cwd,
|
|
47
|
+
signal: context.runtime.signal
|
|
48
|
+
});
|
|
49
|
+
const status = await readPrismaAgentSetupStatus({
|
|
50
|
+
cwd,
|
|
51
|
+
stateStore: context.stateStore,
|
|
52
|
+
signal: context.runtime.signal
|
|
53
|
+
});
|
|
54
|
+
const installCommand = await resolvePrismaCliPackageCommand({
|
|
55
|
+
cwd,
|
|
56
|
+
signal: context.runtime.signal,
|
|
57
|
+
args: options.global ? [...PRISMA_AGENT_INSTALL_ARGS, "--global"] : PRISMA_AGENT_INSTALL_ARGS
|
|
58
|
+
});
|
|
59
|
+
const skillsList = await listInstalledPrismaSkills(context, cwd, statusScope);
|
|
60
|
+
const skillsInstalled = skillsList.status === "ok" ? skillsList.skills.length > 0 : statusScope === "project" && status.skillsInstalled;
|
|
61
|
+
const warnings = skillsList.status === "ok" ? [] : [statusScope === "project" ? `Could not read installed skills with ${formatShellCommand(skillsList.command)}: ${skillsList.message}. Falling back to ${status.skillsLockPath}.` : `Could not read globally installed skills with ${formatShellCommand(skillsList.command)}: ${skillsList.message}.`];
|
|
62
|
+
const statusSource = resolveStatusSource(skillsList, statusScope);
|
|
63
|
+
return {
|
|
64
|
+
command: "agent.status",
|
|
65
|
+
result: {
|
|
66
|
+
skills: skillsList.status === "ok" ? skillsList.skills : [],
|
|
67
|
+
skillsListCommand: skillsList.command,
|
|
68
|
+
statusScope,
|
|
69
|
+
skillsLockPath: status.skillsLockPath,
|
|
70
|
+
skillsLockInstalled: status.skillsInstalled,
|
|
71
|
+
skillsInstalled,
|
|
72
|
+
statusSource,
|
|
73
|
+
promptDismissedAt: status.promptDismissedAt
|
|
74
|
+
},
|
|
75
|
+
warnings,
|
|
76
|
+
nextSteps: skillsInstalled ? [] : [`Run ${installCommand} to install or refresh Prisma skills.`]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
async function buildSkillsInstallCommand(context, options, cwd) {
|
|
80
|
+
const command = [
|
|
81
|
+
...await resolveSkillsPackageRunner({
|
|
82
|
+
cwd,
|
|
83
|
+
signal: context.runtime.signal
|
|
84
|
+
}),
|
|
85
|
+
SKILLS_CLI_PACKAGE,
|
|
86
|
+
"add",
|
|
87
|
+
PRISMA_SKILLS_SOURCE
|
|
88
|
+
];
|
|
89
|
+
const skills = options.skill && options.skill.length > 0 ? options.skill : DEFAULT_PRISMA_AGENT_SKILLS;
|
|
90
|
+
const agents = resolveTargetAgents(options);
|
|
91
|
+
for (const skill of skills) command.push("--skill", skill);
|
|
92
|
+
for (const agent of agents) command.push("--agent", agent);
|
|
93
|
+
if (options.global) command.push("--global");
|
|
94
|
+
if (options.copy || process.platform === "win32") command.push("--copy");
|
|
95
|
+
command.push("--yes");
|
|
96
|
+
return command;
|
|
97
|
+
}
|
|
98
|
+
function resolveTargetAgents(options) {
|
|
99
|
+
if (options.allAgents) return ["*"];
|
|
100
|
+
if (options.agent && options.agent.length > 0) return options.agent;
|
|
101
|
+
return DEFAULT_PRISMA_AGENT_TARGETS;
|
|
102
|
+
}
|
|
103
|
+
async function installSkills(context, options) {
|
|
104
|
+
if (options.dryRun) return {
|
|
105
|
+
status: "would-install",
|
|
106
|
+
command: options.command
|
|
107
|
+
};
|
|
108
|
+
await runChildProcess(context, options.command, options.cwd);
|
|
109
|
+
return {
|
|
110
|
+
status: "installed",
|
|
111
|
+
command: options.command
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
async function listInstalledPrismaSkills(context, cwd, scope) {
|
|
115
|
+
const command = [
|
|
116
|
+
...await resolveSkillsPackageRunner({
|
|
117
|
+
cwd,
|
|
118
|
+
signal: context.runtime.signal
|
|
119
|
+
}),
|
|
120
|
+
SKILLS_CLI_PACKAGE,
|
|
121
|
+
"list",
|
|
122
|
+
...scope === "global" ? ["-g"] : [],
|
|
123
|
+
"--json"
|
|
124
|
+
];
|
|
125
|
+
try {
|
|
126
|
+
const { stdout } = await runChildProcessCapture(context, command, cwd);
|
|
127
|
+
return {
|
|
128
|
+
status: "ok",
|
|
129
|
+
command,
|
|
130
|
+
skills: parseSkillsListOutput(stdout).filter((skill) => isPrismaSkillName(skill.name))
|
|
131
|
+
};
|
|
132
|
+
} catch (error) {
|
|
133
|
+
if (isAbortError(error) || context.runtime.signal.aborted) throw error;
|
|
134
|
+
return {
|
|
135
|
+
status: "failed",
|
|
136
|
+
command,
|
|
137
|
+
message: error instanceof Error ? error.message : String(error)
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async function runChildProcess(context, command, cwd) {
|
|
142
|
+
const [executable, args] = splitCommand(command);
|
|
143
|
+
try {
|
|
144
|
+
await execa(executable, args, {
|
|
145
|
+
cwd,
|
|
146
|
+
env: context.runtime.env,
|
|
147
|
+
cancelSignal: context.runtime.signal,
|
|
148
|
+
stdin: "ignore"
|
|
149
|
+
});
|
|
150
|
+
} catch (error) {
|
|
151
|
+
if (isAbortError(error)) throw error;
|
|
152
|
+
throw skillsInstallFailed(command, exitCodeFromError(error), error);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function runChildProcessCapture(context, command, cwd) {
|
|
156
|
+
const [executable, args] = splitCommand(command);
|
|
157
|
+
const result = await execa(executable, args, {
|
|
158
|
+
cwd,
|
|
159
|
+
env: context.runtime.env,
|
|
160
|
+
cancelSignal: context.runtime.signal,
|
|
161
|
+
stdin: "ignore"
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
stdout: result.stdout ?? "",
|
|
165
|
+
stderr: result.stderr ?? ""
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function splitCommand(command) {
|
|
169
|
+
const [executable, ...args] = command;
|
|
170
|
+
if (!executable) throw new Error("Cannot run an empty command.");
|
|
171
|
+
return [executable, args];
|
|
172
|
+
}
|
|
173
|
+
function isAbortError(error) {
|
|
174
|
+
return error instanceof Error && error.name === "AbortError" || isObject(error) && error.isCanceled === true;
|
|
175
|
+
}
|
|
176
|
+
function exitCodeFromError(error) {
|
|
177
|
+
if (!isObject(error) || typeof error.exitCode !== "number") return null;
|
|
178
|
+
return error.exitCode;
|
|
179
|
+
}
|
|
180
|
+
function isObject(value) {
|
|
181
|
+
return typeof value === "object" && value !== null;
|
|
182
|
+
}
|
|
183
|
+
function resolveStatusSource(skillsList, statusScope) {
|
|
184
|
+
if (skillsList.status === "ok") return "skills-cli";
|
|
185
|
+
return statusScope === "project" ? "skills-lock" : "unavailable";
|
|
186
|
+
}
|
|
187
|
+
function parseSkillsListOutput(output) {
|
|
188
|
+
const parsed = JSON.parse(output);
|
|
189
|
+
if (!Array.isArray(parsed)) throw new Error("skills list did not return a JSON array");
|
|
190
|
+
return parsed.flatMap((item) => {
|
|
191
|
+
const skill = parseInstalledSkill(item);
|
|
192
|
+
return skill ? [skill] : [];
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function parseInstalledSkill(value) {
|
|
196
|
+
if (typeof value !== "object" || value === null) return null;
|
|
197
|
+
const candidate = value;
|
|
198
|
+
if (typeof candidate.name !== "string" || typeof candidate.path !== "string" || typeof candidate.scope !== "string" || !Array.isArray(candidate.agents)) return null;
|
|
199
|
+
return {
|
|
200
|
+
name: candidate.name,
|
|
201
|
+
path: candidate.path,
|
|
202
|
+
scope: candidate.scope,
|
|
203
|
+
agents: candidate.agents.filter((agent) => typeof agent === "string")
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function isPrismaSkillName(name) {
|
|
207
|
+
return name === "prisma" || name.startsWith("prisma-");
|
|
208
|
+
}
|
|
209
|
+
function skillsInstallFailed(command, code, error) {
|
|
210
|
+
const commandText = formatShellCommand(command);
|
|
211
|
+
return new CliError({
|
|
212
|
+
code: "AGENT_SKILLS_INSTALL_FAILED",
|
|
213
|
+
domain: "cli",
|
|
214
|
+
summary: "Prisma skills install failed",
|
|
215
|
+
why: `The skills installer exited with code ${code ?? "unknown"}.`,
|
|
216
|
+
fix: "Run the command below to retry the installer directly.",
|
|
217
|
+
debug: formatErrorDebug(error),
|
|
218
|
+
exitCode: 1,
|
|
219
|
+
nextSteps: [commandText]
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
function formatErrorDebug(error) {
|
|
223
|
+
if (error instanceof Error) return error.stack ?? error.message;
|
|
224
|
+
if (error === void 0) return;
|
|
225
|
+
return String(error);
|
|
226
|
+
}
|
|
227
|
+
//#endregion
|
|
228
|
+
export { runAgentInstall, runAgentStatus };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { CliError, authRequiredError } from "../
|
|
1
|
+
import { CliError, authRequiredError } from "../errors.js";
|
|
2
2
|
//#region src/controllers/app-env-api.ts
|
|
3
3
|
async function findVariableByNaturalKey(client, projectId, key, resolved, signal) {
|
|
4
4
|
const { data, error, response } = await client.GET("/v1/environment-variables", {
|
|
5
5
|
params: { query: {
|
|
6
6
|
projectId,
|
|
7
7
|
class: resolved.apiTarget.class,
|
|
8
|
-
key
|
|
8
|
+
key,
|
|
9
|
+
...resolved.apiTarget.branchId !== null ? { branchId: resolved.apiTarget.branchId } : {}
|
|
9
10
|
} },
|
|
10
11
|
signal
|
|
11
12
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CliError } from "../
|
|
1
|
+
import { CliError } from "../errors.js";
|
|
2
2
|
import { formatScopeLabel } from "../lib/app/env-config.js";
|
|
3
3
|
import { apiCallError, findVariableByNaturalKey, toMetadata } from "./app-env-api.js";
|
|
4
4
|
//#region src/controllers/app-env-file.ts
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { CliError, authRequiredError, usageError, workspaceRequiredError } from "../
|
|
1
|
+
import { CliError, authRequiredError, usageError, workspaceRequiredError } from "../errors.js";
|
|
2
|
+
import { authenticatedManagementApiClient } from "../auth/guard.js";
|
|
2
3
|
import { formatScopeLabel, parseKeyValuePositional, resolveEnvScope } from "../lib/app/env-config.js";
|
|
3
4
|
import { readEnvFileAssignments } from "../lib/app/env-file.js";
|
|
4
|
-
import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
|
|
5
|
-
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
6
5
|
import { readLocalGitBranch } from "../lib/git/local-branch.js";
|
|
6
|
+
import { projectResolutionErrorToCliError, resolveProjectTarget } from "../lib/project/resolution.js";
|
|
7
7
|
import { requireAuthenticatedAuthState } from "./auth.js";
|
|
8
8
|
import { listRealWorkspaceProjects } from "./project.js";
|
|
9
9
|
import { apiCallError, findVariableByNaturalKey, toMetadata } from "./app-env-api.js";
|
|
@@ -202,7 +202,7 @@ async function runEnvRemove(context, key, flags) {
|
|
|
202
202
|
}
|
|
203
203
|
async function requireClientAndProject(context, explicitProject, commandName) {
|
|
204
204
|
const authState = await requireAuthenticatedAuthState(context);
|
|
205
|
-
const client = await
|
|
205
|
+
const client = await authenticatedManagementApiClient(context.runtime.env, context.runtime.signal);
|
|
206
206
|
if (!client) throw authRequiredError(["prisma-cli auth login"]);
|
|
207
207
|
const workspace = authState.workspace;
|
|
208
208
|
if (!workspace) throw workspaceRequiredError();
|
|
@@ -210,7 +210,7 @@ async function requireClientAndProject(context, explicitProject, commandName) {
|
|
|
210
210
|
context,
|
|
211
211
|
workspace,
|
|
212
212
|
explicitProject,
|
|
213
|
-
listProjects: () => listRealWorkspaceProjects(client,
|
|
213
|
+
listProjects: () => listRealWorkspaceProjects(client, context.runtime.signal),
|
|
214
214
|
commandName
|
|
215
215
|
});
|
|
216
216
|
if (targetResult.isErr()) throw projectResolutionErrorToCliError(targetResult.error);
|