@prisma/cli 3.0.0-beta.7 → 3.0.0-beta.9
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/dist/adapters/mock-api.js +75 -0
- package/dist/cli2.js +2 -0
- package/dist/commands/app/index.js +2 -2
- package/dist/commands/database/index.js +159 -0
- package/dist/controllers/app-env.js +2 -2
- package/dist/controllers/app.js +55 -8
- package/dist/controllers/database.js +316 -0
- package/dist/controllers/project.js +17 -3
- package/dist/lib/app/branch-database-deploy.js +116 -66
- package/dist/lib/app/env-file.js +2 -2
- package/dist/lib/app/env-vars.js +28 -2
- package/dist/lib/app/preview-build-settings.js +385 -0
- package/dist/lib/app/preview-build.js +196 -33
- package/dist/lib/app/preview-provider.js +2 -1
- package/dist/lib/app/production-deploy-gate.js +5 -4
- package/dist/lib/database/provider.js +167 -0
- package/dist/lib/project/local-pin.js +64 -14
- package/dist/lib/project/resolution.js +16 -2
- package/dist/presenters/app.js +7 -2
- package/dist/presenters/database.js +274 -0
- package/dist/shell/command-meta.js +102 -0
- package/dist/shell/command-runner.js +9 -2
- package/package.json +2 -1
|
@@ -56,6 +56,81 @@ var MockApi = class MockApi {
|
|
|
56
56
|
getDeployment(deploymentId) {
|
|
57
57
|
return this.data.deployments.find((deployment) => deployment.id === deploymentId);
|
|
58
58
|
}
|
|
59
|
+
listDatabasesForProject(projectId, branchName) {
|
|
60
|
+
return (this.data.databases ?? []).filter((database) => database.projectId === projectId && (!branchName || database.branchName === branchName));
|
|
61
|
+
}
|
|
62
|
+
getDatabase(databaseId) {
|
|
63
|
+
return (this.data.databases ?? []).find((database) => database.id === databaseId);
|
|
64
|
+
}
|
|
65
|
+
createDatabase(input) {
|
|
66
|
+
this.data.databases ??= [];
|
|
67
|
+
this.data.databaseConnections ??= [];
|
|
68
|
+
const database = {
|
|
69
|
+
id: `db_${this.data.databases.length + 1e3}`,
|
|
70
|
+
projectId: input.projectId,
|
|
71
|
+
branchId: input.branchName ? this.getBranchForProject(input.projectId, input.branchName)?.id ?? null : null,
|
|
72
|
+
branchName: input.branchName ?? null,
|
|
73
|
+
name: input.name,
|
|
74
|
+
region: input.region ?? null,
|
|
75
|
+
status: "ready",
|
|
76
|
+
isDefault: false,
|
|
77
|
+
createdAt: "2026-06-09T00:00:00.000Z"
|
|
78
|
+
};
|
|
79
|
+
const connectionString = `postgresql://${database.id}.example.prisma.io/postgres`;
|
|
80
|
+
const connection = {
|
|
81
|
+
id: `conn_${this.data.databaseConnections.length + 1e3}`,
|
|
82
|
+
databaseId: database.id,
|
|
83
|
+
name: "primary",
|
|
84
|
+
createdAt: "2026-06-09T00:00:00.000Z",
|
|
85
|
+
connectionString
|
|
86
|
+
};
|
|
87
|
+
this.data.databases.push(database);
|
|
88
|
+
this.data.databaseConnections.push(connection);
|
|
89
|
+
return {
|
|
90
|
+
database,
|
|
91
|
+
connection,
|
|
92
|
+
connectionString
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
removeDatabase(databaseId) {
|
|
96
|
+
this.data.databases ??= [];
|
|
97
|
+
this.data.databaseConnections ??= [];
|
|
98
|
+
const database = this.getDatabase(databaseId);
|
|
99
|
+
if (!database) return;
|
|
100
|
+
this.data.databases = this.data.databases.filter((candidate) => candidate.id !== databaseId);
|
|
101
|
+
this.data.databaseConnections = this.data.databaseConnections.filter((connection) => connection.databaseId !== databaseId);
|
|
102
|
+
return database;
|
|
103
|
+
}
|
|
104
|
+
listDatabaseConnections(databaseId) {
|
|
105
|
+
return (this.data.databaseConnections ?? []).filter((connection) => connection.databaseId === databaseId);
|
|
106
|
+
}
|
|
107
|
+
getDatabaseConnection(connectionId) {
|
|
108
|
+
return (this.data.databaseConnections ?? []).find((connection) => connection.id === connectionId);
|
|
109
|
+
}
|
|
110
|
+
createDatabaseConnection(input) {
|
|
111
|
+
if (!this.getDatabase(input.databaseId)) return;
|
|
112
|
+
this.data.databaseConnections ??= [];
|
|
113
|
+
const connectionString = `postgresql://${input.databaseId}-${this.data.databaseConnections.length + 1}.example.prisma.io/postgres`;
|
|
114
|
+
const connection = {
|
|
115
|
+
id: `conn_${this.data.databaseConnections.length + 1e3}`,
|
|
116
|
+
databaseId: input.databaseId,
|
|
117
|
+
name: input.name,
|
|
118
|
+
createdAt: "2026-06-09T00:00:00.000Z",
|
|
119
|
+
connectionString
|
|
120
|
+
};
|
|
121
|
+
this.data.databaseConnections.push(connection);
|
|
122
|
+
return {
|
|
123
|
+
connection,
|
|
124
|
+
connectionString
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
removeDatabaseConnection(connectionId) {
|
|
128
|
+
this.data.databaseConnections ??= [];
|
|
129
|
+
const connection = this.getDatabaseConnection(connectionId);
|
|
130
|
+
if (!connection) return;
|
|
131
|
+
this.data.databaseConnections = this.data.databaseConnections.filter((candidate) => candidate.id !== connectionId);
|
|
132
|
+
return connection;
|
|
133
|
+
}
|
|
59
134
|
};
|
|
60
135
|
//#endregion
|
|
61
136
|
export { MockApi };
|
package/dist/cli2.js
CHANGED
|
@@ -8,6 +8,7 @@ import "./shell/prompt.js";
|
|
|
8
8
|
import { createAppCommand } from "./commands/app/index.js";
|
|
9
9
|
import { createAuthCommand } from "./commands/auth/index.js";
|
|
10
10
|
import { createBranchCommand } from "./commands/branch/index.js";
|
|
11
|
+
import { createDatabaseCommand } from "./commands/database/index.js";
|
|
11
12
|
import { createGitCommand } from "./commands/git/index.js";
|
|
12
13
|
import { createProjectCommand } from "./commands/project/index.js";
|
|
13
14
|
import { getCliName, getCliVersion } from "./lib/version.js";
|
|
@@ -49,6 +50,7 @@ function createProgram(runtime) {
|
|
|
49
50
|
program.addCommand(createProjectCommand(runtime));
|
|
50
51
|
program.addCommand(createGitCommand(runtime));
|
|
51
52
|
program.addCommand(createBranchCommand(runtime));
|
|
53
|
+
program.addCommand(createDatabaseCommand(runtime));
|
|
52
54
|
program.addCommand(createAppCommand(runtime));
|
|
53
55
|
return program;
|
|
54
56
|
}
|
|
@@ -65,7 +65,7 @@ function createDeployCommand(runtime) {
|
|
|
65
65
|
"hono",
|
|
66
66
|
"tanstack-start",
|
|
67
67
|
"bun"
|
|
68
|
-
])).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)).addOption(new Option("--db", "Create and wire
|
|
68
|
+
])).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|file>", "Environment variable assignment or dotenv file").argParser(collectRepeatableValues)).addOption(new Option("--db", "Create and wire a Prisma Postgres database for this deploy target")).addOption(new Option("--no-db", "Skip database setup")).addOption(new Option("--prod", "Confirm intent to deploy to production"));
|
|
69
69
|
addGlobalFlags(command);
|
|
70
70
|
command.action(async (options) => {
|
|
71
71
|
const appName = options.app;
|
|
@@ -80,7 +80,7 @@ function createDeployCommand(runtime) {
|
|
|
80
80
|
const db = options.db;
|
|
81
81
|
const hasDbConflict = hasFlag(runtime.argv, "--db") && hasFlag(runtime.argv, "--no-db");
|
|
82
82
|
await runCommand(runtime, "app.deploy", options, (context) => {
|
|
83
|
-
if (hasDbConflict) throw usageError("app deploy accepts either --db or --no-db", "--db requests
|
|
83
|
+
if (hasDbConflict) throw usageError("app deploy accepts either --db or --no-db", "--db requests database setup, while --no-db disables it.", "Pass exactly one database setup flag.", ["prisma-cli app deploy --db", "prisma-cli app deploy --no-db"], "app");
|
|
84
84
|
return runAppDeploy(context, appName, {
|
|
85
85
|
projectRef,
|
|
86
86
|
createProjectName,
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
|
+
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
|
+
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
+
import { 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";
|
|
7
|
+
import { Command, Option } from "commander";
|
|
8
|
+
//#region src/commands/database/index.ts
|
|
9
|
+
function createDatabaseCommand(runtime) {
|
|
10
|
+
const database = attachCommandDescriptor(configureRuntimeCommand(new Command("database"), runtime), "database");
|
|
11
|
+
addCompactGlobalFlags(database);
|
|
12
|
+
database.addCommand(createDatabaseListCommand(runtime));
|
|
13
|
+
database.addCommand(createDatabaseShowCommand(runtime));
|
|
14
|
+
database.addCommand(createDatabaseCreateCommand(runtime));
|
|
15
|
+
database.addCommand(createDatabaseRemoveCommand(runtime));
|
|
16
|
+
database.addCommand(createDatabaseConnectionCommand(runtime));
|
|
17
|
+
return database;
|
|
18
|
+
}
|
|
19
|
+
function addProjectAndBranchOptions(command) {
|
|
20
|
+
return command.addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--branch <git-name>", "Branch git name"));
|
|
21
|
+
}
|
|
22
|
+
function createDatabaseListCommand(runtime) {
|
|
23
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "database.list");
|
|
24
|
+
addProjectAndBranchOptions(command);
|
|
25
|
+
addGlobalFlags(command);
|
|
26
|
+
command.action(async (options) => {
|
|
27
|
+
const projectRef = options.project;
|
|
28
|
+
const branchName = options.branch;
|
|
29
|
+
await runCommand(runtime, "database.list", options, (context) => runDatabaseList(context, {
|
|
30
|
+
projectRef,
|
|
31
|
+
branchName
|
|
32
|
+
}), {
|
|
33
|
+
renderHuman: (context, descriptor, result) => renderDatabaseList(context, descriptor, result),
|
|
34
|
+
renderJson: (result) => serializeDatabaseList(result)
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
return command;
|
|
38
|
+
}
|
|
39
|
+
function createDatabaseShowCommand(runtime) {
|
|
40
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "database.show");
|
|
41
|
+
command.argument("<database>", "Database id or name");
|
|
42
|
+
addProjectAndBranchOptions(command);
|
|
43
|
+
addGlobalFlags(command);
|
|
44
|
+
command.action(async (databaseRef, options) => {
|
|
45
|
+
const projectRef = options.project;
|
|
46
|
+
const branchName = options.branch;
|
|
47
|
+
await runCommand(runtime, "database.show", options, (context) => runDatabaseShow(context, databaseRef, {
|
|
48
|
+
projectRef,
|
|
49
|
+
branchName
|
|
50
|
+
}), {
|
|
51
|
+
renderHuman: (context, descriptor, result) => renderDatabaseShow(context, descriptor, result),
|
|
52
|
+
renderJson: (result) => serializeDatabaseShow(result)
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
return command;
|
|
56
|
+
}
|
|
57
|
+
function createDatabaseCreateCommand(runtime) {
|
|
58
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("create"), runtime), "database.create");
|
|
59
|
+
command.argument("<name>", "Database name").addOption(new Option("--region <region>", "Prisma Postgres region id"));
|
|
60
|
+
addProjectAndBranchOptions(command);
|
|
61
|
+
addGlobalFlags(command);
|
|
62
|
+
command.action(async (name, options) => {
|
|
63
|
+
const projectRef = options.project;
|
|
64
|
+
const branchName = options.branch;
|
|
65
|
+
const region = options.region;
|
|
66
|
+
await runCommand(runtime, "database.create", options, (context) => runDatabaseCreate(context, name, {
|
|
67
|
+
projectRef,
|
|
68
|
+
branchName,
|
|
69
|
+
region
|
|
70
|
+
}), {
|
|
71
|
+
renderStdout: (context, descriptor, result) => renderDatabaseCreateStdout(context, descriptor, result),
|
|
72
|
+
renderHuman: (context, descriptor, result) => renderDatabaseCreate(context, descriptor, result),
|
|
73
|
+
renderJson: (result) => serializeDatabaseCreate(result)
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
return command;
|
|
77
|
+
}
|
|
78
|
+
function createDatabaseRemoveCommand(runtime) {
|
|
79
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "database.remove");
|
|
80
|
+
command.argument("<database>", "Database id or name").addOption(new Option("--confirm <database-id>", "Exact database id required to remove"));
|
|
81
|
+
addProjectAndBranchOptions(command);
|
|
82
|
+
addGlobalFlags(command);
|
|
83
|
+
command.action(async (databaseRef, options) => {
|
|
84
|
+
const projectRef = options.project;
|
|
85
|
+
const branchName = options.branch;
|
|
86
|
+
const confirm = options.confirm;
|
|
87
|
+
await runCommand(runtime, "database.remove", options, (context) => runDatabaseRemove(context, databaseRef, {
|
|
88
|
+
projectRef,
|
|
89
|
+
branchName,
|
|
90
|
+
confirm
|
|
91
|
+
}), {
|
|
92
|
+
renderHuman: (context, descriptor, result) => renderDatabaseRemove(context, descriptor, result),
|
|
93
|
+
renderJson: (result) => serializeDatabaseRemove(result)
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
return command;
|
|
97
|
+
}
|
|
98
|
+
function createDatabaseConnectionCommand(runtime) {
|
|
99
|
+
const connection = attachCommandDescriptor(configureRuntimeCommand(new Command("connection"), runtime), "database.connection");
|
|
100
|
+
addCompactGlobalFlags(connection);
|
|
101
|
+
connection.addCommand(createDatabaseConnectionListCommand(runtime));
|
|
102
|
+
connection.addCommand(createDatabaseConnectionCreateCommand(runtime));
|
|
103
|
+
connection.addCommand(createDatabaseConnectionRemoveCommand(runtime));
|
|
104
|
+
return connection;
|
|
105
|
+
}
|
|
106
|
+
function createDatabaseConnectionListCommand(runtime) {
|
|
107
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "database.connection.list");
|
|
108
|
+
command.argument("<database>", "Database id or name");
|
|
109
|
+
addProjectAndBranchOptions(command);
|
|
110
|
+
addGlobalFlags(command);
|
|
111
|
+
command.action(async (databaseRef, options) => {
|
|
112
|
+
const projectRef = options.project;
|
|
113
|
+
const branchName = options.branch;
|
|
114
|
+
await runCommand(runtime, "database.connection.list", options, (context) => runDatabaseConnectionList(context, databaseRef, {
|
|
115
|
+
projectRef,
|
|
116
|
+
branchName
|
|
117
|
+
}), {
|
|
118
|
+
renderHuman: (context, descriptor, result) => renderDatabaseConnectionList(context, descriptor, result),
|
|
119
|
+
renderJson: (result) => serializeDatabaseConnectionList(result)
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
return command;
|
|
123
|
+
}
|
|
124
|
+
function createDatabaseConnectionCreateCommand(runtime) {
|
|
125
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("create"), runtime), "database.connection.create");
|
|
126
|
+
command.argument("<database>", "Database id or name").addOption(new Option("--name <name>", "Connection name"));
|
|
127
|
+
addProjectAndBranchOptions(command);
|
|
128
|
+
addGlobalFlags(command);
|
|
129
|
+
command.action(async (databaseRef, options) => {
|
|
130
|
+
const projectRef = options.project;
|
|
131
|
+
const branchName = options.branch;
|
|
132
|
+
const name = options.name;
|
|
133
|
+
await runCommand(runtime, "database.connection.create", options, (context) => runDatabaseConnectionCreate(context, databaseRef, {
|
|
134
|
+
projectRef,
|
|
135
|
+
branchName,
|
|
136
|
+
name
|
|
137
|
+
}), {
|
|
138
|
+
renderStdout: (context, descriptor, result) => renderDatabaseConnectionCreateStdout(context, descriptor, result),
|
|
139
|
+
renderHuman: (context, descriptor, result) => renderDatabaseConnectionCreate(context, descriptor, result),
|
|
140
|
+
renderJson: (result) => serializeDatabaseConnectionCreate(result)
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
return command;
|
|
144
|
+
}
|
|
145
|
+
function createDatabaseConnectionRemoveCommand(runtime) {
|
|
146
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "database.connection.remove");
|
|
147
|
+
command.argument("<connection>", "Connection id").addOption(new Option("--confirm <connection-id>", "Exact connection id required to remove"));
|
|
148
|
+
addGlobalFlags(command);
|
|
149
|
+
command.action(async (connectionRef, options) => {
|
|
150
|
+
const confirm = options.confirm;
|
|
151
|
+
await runCommand(runtime, "database.connection.remove", options, (context) => runDatabaseConnectionRemove(context, connectionRef, { confirm }), {
|
|
152
|
+
renderHuman: (context, descriptor, result) => renderDatabaseConnectionRemove(context, descriptor, result),
|
|
153
|
+
renderJson: (result) => serializeDatabaseConnectionRemove(result)
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
return command;
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
export { createDatabaseCommand };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { CliError, authRequiredError, usageError, workspaceRequiredError } from "../shell/errors.js";
|
|
2
2
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
3
|
+
import { formatScopeLabel, parseKeyValuePositional, resolveEnvScope } from "../lib/app/env-config.js";
|
|
4
|
+
import { readEnvFileAssignments } from "../lib/app/env-file.js";
|
|
3
5
|
import { resolveProjectTarget } from "../lib/project/resolution.js";
|
|
4
6
|
import { readLocalGitBranch } from "../lib/git/local-branch.js";
|
|
5
7
|
import { requireAuthenticatedAuthState } from "./auth.js";
|
|
6
8
|
import { listRealWorkspaceProjects } from "./project.js";
|
|
7
|
-
import { formatScopeLabel, parseKeyValuePositional, resolveEnvScope } from "../lib/app/env-config.js";
|
|
8
|
-
import { readEnvFileAssignments } from "../lib/app/env-file.js";
|
|
9
9
|
import { apiCallError, findVariableByNaturalKey, toMetadata } from "./app-env-api.js";
|
|
10
10
|
import { runEnvAddFile, runEnvUpdateFile } from "./app-env-file.js";
|
|
11
11
|
//#region src/controllers/app-env.ts
|
package/dist/controllers/app.js
CHANGED
|
@@ -7,7 +7,7 @@ import { canPrompt } from "../shell/runtime.js";
|
|
|
7
7
|
import { confirmPrompt, selectPrompt, textPrompt } from "../shell/prompt.js";
|
|
8
8
|
import { requireComputeAuth } from "../lib/auth/guard.js";
|
|
9
9
|
import { readAuthState } from "../lib/auth/auth-ops.js";
|
|
10
|
-
import { envVarNames,
|
|
10
|
+
import { envVarNames, parseEnvInputs } from "../lib/app/env-vars.js";
|
|
11
11
|
import { renderDeployOutputRows, renderDeploySettingsPreview } from "../lib/app/deploy-output.js";
|
|
12
12
|
import { readBunPackageEntrypoint, readBunPackageJson } from "../lib/app/bun-project.js";
|
|
13
13
|
import { DEFAULT_LOCAL_DEV_PORT, resolveLocalBuildType, runLocalApp } from "../lib/app/local-dev.js";
|
|
@@ -17,6 +17,7 @@ import { buildProjectSetupNextActions, inferTargetName, projectNotFoundError, re
|
|
|
17
17
|
import { bindProjectToDirectory, projectCreateFailedError, projectSetupNameRequiredError, resolveProjectForSetup, toProjectSummary } from "../lib/project/setup.js";
|
|
18
18
|
import { promptForProjectSetupChoice } from "../lib/project/interactive-setup.js";
|
|
19
19
|
import { readLocalGitBranch } from "../lib/git/local-branch.js";
|
|
20
|
+
import { resolveOrCreatePreviewBuildSettings } from "../lib/app/preview-build-settings.js";
|
|
20
21
|
import { PREVIEW_BUILD_TYPES, RESOLVED_PREVIEW_BUILD_TYPES, executePreviewBuild } from "../lib/app/preview-build.js";
|
|
21
22
|
import { PREVIEW_DEFAULT_REGION } from "../lib/app/preview-interaction.js";
|
|
22
23
|
import { maybeSetupBranchDatabase } from "../lib/app/branch-database-deploy.js";
|
|
@@ -30,6 +31,7 @@ import { listRealWorkspaceProjects } from "./project.js";
|
|
|
30
31
|
import { access, readFile } from "node:fs/promises";
|
|
31
32
|
import path from "node:path";
|
|
32
33
|
import open from "open";
|
|
34
|
+
import { Result, matchError } from "better-result";
|
|
33
35
|
//#region src/controllers/app.ts
|
|
34
36
|
const DEPLOY_FRAMEWORKS = [
|
|
35
37
|
"nextjs",
|
|
@@ -111,9 +113,9 @@ async function runAppDeploy(context, appName, options) {
|
|
|
111
113
|
createProjectName: options?.createProjectName,
|
|
112
114
|
envProjectId
|
|
113
115
|
});
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
const localPinReadResult = Boolean(envProjectId || options?.projectRef || options?.createProjectName) ? Result.ok({ kind: "missing" }) : await readLocalResolutionPin(context.runtime.cwd, context.runtime.signal);
|
|
117
|
+
if (localPinReadResult.isErr()) throw localPinReadErrorToDeployError(localPinReadResult.error);
|
|
118
|
+
const localPin = localPinReadResult.value;
|
|
117
119
|
const branch = await resolveDeployBranch(context, options?.branchName);
|
|
118
120
|
if (options?.httpPort) parseDeployHttpPort(options.httpPort);
|
|
119
121
|
assertSupportedEntrypointForRequestedDeployShape({
|
|
@@ -138,7 +140,7 @@ async function runAppDeploy(context, appName, options) {
|
|
|
138
140
|
});
|
|
139
141
|
let runtime = resolveDeployRuntime(options?.httpPort, framework);
|
|
140
142
|
assertSupportedEntrypoint(framework.buildType, options?.entrypoint, "deploy");
|
|
141
|
-
const envVars = toOptionalEnvVars(
|
|
143
|
+
const envVars = toOptionalEnvVars(await parseEnvInputs(context.runtime.cwd, options?.envAssignments, { commandName: "deploy" }));
|
|
142
144
|
const selectedApp = await resolveDeployAppSelection(context, projectId, await listApps(context, provider, projectId, target.branch.name), {
|
|
143
145
|
explicitAppName: appName,
|
|
144
146
|
explicitAppId: envAppId,
|
|
@@ -161,7 +163,7 @@ async function runAppDeploy(context, appName, options) {
|
|
|
161
163
|
});
|
|
162
164
|
framework = customized.framework;
|
|
163
165
|
runtime = customized.runtime;
|
|
164
|
-
await enforceProductionDeployGate(context, provider, {
|
|
166
|
+
const productionDeployGate = await enforceProductionDeployGate(context, provider, {
|
|
165
167
|
appId: selectedApp.appId,
|
|
166
168
|
appName: selectedApp.displayName,
|
|
167
169
|
branchKind: target.branch.kind,
|
|
@@ -170,10 +172,17 @@ async function runAppDeploy(context, appName, options) {
|
|
|
170
172
|
const buildType = framework.buildType;
|
|
171
173
|
assertSupportedEntrypoint(buildType, options?.entrypoint, "deploy");
|
|
172
174
|
const entrypoint = await resolveDeployEntrypoint(context.runtime.cwd, framework, options?.entrypoint, context.runtime.signal);
|
|
175
|
+
const buildSettingsResolution = await resolveOrCreatePreviewBuildSettings({
|
|
176
|
+
appPath: context.runtime.cwd,
|
|
177
|
+
buildType,
|
|
178
|
+
signal: context.runtime.signal
|
|
179
|
+
});
|
|
180
|
+
maybeRenderDeployBuildSettings(context, buildSettingsResolution);
|
|
173
181
|
const portMapping = parseDeployPortMapping(String(runtime.port));
|
|
174
182
|
const branchDatabaseSetup = await maybeSetupBranchDatabase(context, provider, projectId, toBranchDatabaseDeployBranch(target.branch), {
|
|
175
183
|
db: options?.db,
|
|
176
|
-
|
|
184
|
+
providedEnvVars: envVars,
|
|
185
|
+
firstProductionDeploy: productionDeployGate.firstProductionDeploy
|
|
177
186
|
});
|
|
178
187
|
const progressState = createPreviewDeployProgressState();
|
|
179
188
|
const deployStartedAt = Date.now();
|
|
@@ -186,6 +195,7 @@ async function runAppDeploy(context, appName, options) {
|
|
|
186
195
|
region: selectedApp.region,
|
|
187
196
|
entrypoint,
|
|
188
197
|
buildType,
|
|
198
|
+
buildSettings: buildSettingsResolution.settings,
|
|
189
199
|
portMapping,
|
|
190
200
|
envVars,
|
|
191
201
|
interaction: void 0,
|
|
@@ -214,6 +224,18 @@ async function runAppDeploy(context, appName, options) {
|
|
|
214
224
|
},
|
|
215
225
|
deployment: deployResult.deployment,
|
|
216
226
|
deploySettings: {
|
|
227
|
+
config: {
|
|
228
|
+
path: buildSettingsResolution.relativeConfigPath,
|
|
229
|
+
status: buildSettingsResolution.status
|
|
230
|
+
},
|
|
231
|
+
buildCommand: {
|
|
232
|
+
value: buildSettingsResolution.settings.buildCommand,
|
|
233
|
+
source: buildSettingsResolution.settings.buildCommandSource
|
|
234
|
+
},
|
|
235
|
+
outputDirectory: {
|
|
236
|
+
value: buildSettingsResolution.settings.outputDirectory,
|
|
237
|
+
source: buildSettingsResolution.settings.outputDirectorySource
|
|
238
|
+
},
|
|
217
239
|
framework: {
|
|
218
240
|
key: framework.key,
|
|
219
241
|
buildType,
|
|
@@ -1603,7 +1625,6 @@ async function detectNextConfig(cwd, signal) {
|
|
|
1603
1625
|
for (const candidate of [
|
|
1604
1626
|
"next.config.js",
|
|
1605
1627
|
"next.config.mjs",
|
|
1606
|
-
"next.config.cjs",
|
|
1607
1628
|
"next.config.ts",
|
|
1608
1629
|
"next.config.mts"
|
|
1609
1630
|
]) {
|
|
@@ -1696,6 +1717,20 @@ async function maybeRenderDeploySetupBlock(context, details) {
|
|
|
1696
1717
|
const prefix = details.includeDirectory ? `Deploying ${directory} to` : "Deploying to";
|
|
1697
1718
|
context.output.stderr.write(`${prefix} ${details.projectName} / ${details.branchName} / ${details.appName}\n\n`);
|
|
1698
1719
|
}
|
|
1720
|
+
function maybeRenderDeployBuildSettings(context, resolution) {
|
|
1721
|
+
if (context.flags.json || context.flags.quiet) return;
|
|
1722
|
+
const settings = resolution.settings;
|
|
1723
|
+
const title = resolution.status === "created" ? `Created ${resolution.relativeConfigPath}` : `Using ${resolution.relativeConfigPath}`;
|
|
1724
|
+
context.output.stderr.write(`${title}\n${renderDeployOutputRows(context.ui, [{
|
|
1725
|
+
label: "Build Command",
|
|
1726
|
+
value: settings.buildCommand ?? "none",
|
|
1727
|
+
origin: settings.buildCommandSource ?? void 0
|
|
1728
|
+
}, {
|
|
1729
|
+
label: "Output Directory",
|
|
1730
|
+
value: settings.outputDirectory,
|
|
1731
|
+
origin: settings.outputDirectorySource ?? void 0
|
|
1732
|
+
}]).join("\n")}\n\n`);
|
|
1733
|
+
}
|
|
1699
1734
|
function maybeRenderProjectLinked(context, directory, projectName, localPinPath) {
|
|
1700
1735
|
if (context.flags.json || context.flags.quiet) return;
|
|
1701
1736
|
context.output.stderr.write(`${context.ui.success("✔")} Linked "${directory}" to Project "${projectName}"\nSaved ${localPinPath}\n\n`);
|
|
@@ -1942,6 +1977,18 @@ function localResolutionPinStaleError() {
|
|
|
1942
1977
|
]
|
|
1943
1978
|
});
|
|
1944
1979
|
}
|
|
1980
|
+
function localPinReadErrorToDeployError(error) {
|
|
1981
|
+
return matchError(error, {
|
|
1982
|
+
LocalResolutionPinInvalidJsonError: () => localResolutionPinStaleError(),
|
|
1983
|
+
LocalResolutionPinInvalidShapeError: () => localResolutionPinStaleError(),
|
|
1984
|
+
LocalResolutionPinReadAbortedError: (error) => {
|
|
1985
|
+
throw error;
|
|
1986
|
+
},
|
|
1987
|
+
UnhandledException: (error) => {
|
|
1988
|
+
throw error;
|
|
1989
|
+
}
|
|
1990
|
+
});
|
|
1991
|
+
}
|
|
1945
1992
|
function readDeployEnvOverride(context, name) {
|
|
1946
1993
|
const value = context.runtime.env[name]?.trim();
|
|
1947
1994
|
return value ? value : void 0;
|