@prisma/cli 3.0.0-beta.9 → 3.0.0-dev.102.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +0 -13
  2. package/dist/adapters/token-storage.js +311 -33
  3. package/dist/cli.js +7 -7
  4. package/dist/cli2.js +3 -3
  5. package/dist/commands/app/index.js +65 -52
  6. package/dist/commands/auth/index.js +55 -2
  7. package/dist/controllers/app-env.js +10 -7
  8. package/dist/controllers/app.js +539 -210
  9. package/dist/controllers/auth.js +211 -2
  10. package/dist/controllers/branch.js +5 -6
  11. package/dist/controllers/database.js +7 -5
  12. package/dist/controllers/project.js +33 -18
  13. package/dist/lib/app/app-interaction.js +5 -0
  14. package/dist/lib/app/{preview-provider.js → app-provider.js} +82 -78
  15. package/dist/lib/app/{preview-branch-database.js → branch-database-api.js} +1 -1
  16. package/dist/lib/app/branch-database-deploy.js +12 -60
  17. package/dist/lib/app/branch-database.js +1 -102
  18. package/dist/lib/app/build-settings.js +93 -0
  19. package/dist/lib/app/build.js +82 -0
  20. package/dist/lib/app/bun-project.js +2 -3
  21. package/dist/lib/app/compute-config.js +147 -0
  22. package/dist/lib/app/deploy-plan.js +58 -0
  23. package/dist/lib/app/{preview-progress.js → deploy-progress.js} +12 -12
  24. package/dist/lib/app/local-dev.js +3 -60
  25. package/dist/lib/app/production-deploy-gate.js +3 -3
  26. package/dist/lib/app/read-branch.js +30 -0
  27. package/dist/lib/auth/auth-ops.js +10 -4
  28. package/dist/lib/auth/guard.js +4 -1
  29. package/dist/lib/auth/login.js +32 -25
  30. package/dist/lib/diagnostics.js +1 -1
  31. package/dist/lib/fs/home-path.js +24 -0
  32. package/dist/lib/git/local-branch.js +15 -3
  33. package/dist/lib/project/local-pin.js +106 -26
  34. package/dist/lib/project/resolution.js +162 -71
  35. package/dist/lib/project/setup.js +65 -19
  36. package/dist/output/patterns.js +1 -1
  37. package/dist/presenters/app.js +44 -39
  38. package/dist/presenters/auth.js +98 -1
  39. package/dist/presenters/branch.js +1 -1
  40. package/dist/presenters/database.js +2 -2
  41. package/dist/presenters/project.js +3 -9
  42. package/dist/shell/command-meta.js +52 -2
  43. package/dist/shell/command-runner.js +39 -28
  44. package/dist/shell/diagnostics-output.js +2 -8
  45. package/dist/shell/errors.js +50 -1
  46. package/dist/shell/help.js +30 -20
  47. package/dist/shell/runtime.js +8 -4
  48. package/dist/shell/ui.js +19 -2
  49. package/dist/use-cases/auth.js +68 -1
  50. package/package.json +18 -4
  51. package/dist/lib/app/preview-build-settings.js +0 -385
  52. package/dist/lib/app/preview-build.js +0 -475
  53. package/dist/lib/app/preview-interaction.js +0 -5
@@ -1,22 +1,22 @@
1
+ import { createBranchDatabase, createEnvironmentVariable, deleteBranchDatabase, deleteEnvironmentVariable, listEnvironmentVariables, updateEnvironmentVariable } from "./branch-database-api.js";
2
+ import { AppBuildStrategy } from "./build.js";
1
3
  import { envVarNames } from "./env-vars.js";
2
- import { PreviewBuildStrategy } from "./preview-build.js";
3
- import { createBranchDatabase, createEnvironmentVariable, deleteBranchDatabase, deleteEnvironmentVariable, listEnvironmentVariables, updateEnvironmentVariable } from "./preview-branch-database.js";
4
4
  import path from "node:path";
5
5
  import { ApiError, CancelledError, ComputeClient, streamLogs } from "@prisma/compute-sdk";
6
- //#region src/lib/app/preview-provider.ts
7
- var PreviewDomainApiError = class extends Error {
6
+ //#region src/lib/app/app-provider.ts
7
+ var DomainApiError = class extends Error {
8
8
  status;
9
9
  code;
10
10
  hint;
11
11
  constructor(options) {
12
12
  super(`${options.summary}: ${options.message}${options.hint ? ` ${options.hint}` : ""}`);
13
- this.name = "PreviewDomainApiError";
13
+ this.name = "DomainApiError";
14
14
  this.status = options.status;
15
15
  this.code = options.code ?? null;
16
16
  this.hint = options.hint ?? null;
17
17
  }
18
18
  };
19
- function createPreviewAppProvider(client, options) {
19
+ function createAppProvider(client, options) {
20
20
  const sdk = new ComputeClient(client);
21
21
  return {
22
22
  async createProject(options) {
@@ -68,14 +68,14 @@ function createPreviewAppProvider(client, options) {
68
68
  return deleteEnvironmentVariable(client, options);
69
69
  },
70
70
  async removeApp(appId, options) {
71
- const appResult = await sdk.showService({
72
- serviceId: appId,
71
+ const appResult = await sdk.showApp({
72
+ appId,
73
73
  signal: options?.signal
74
74
  });
75
75
  if (appResult.isErr()) throw new Error(appResult.error.message);
76
- const destroyResult = await sdk.destroyService({
77
- serviceId: appId,
78
- keepService: false,
76
+ const destroyResult = await sdk.destroyApp({
77
+ appId,
78
+ keepApp: false,
79
79
  timeoutSeconds: 120,
80
80
  pollIntervalMs: 2e3,
81
81
  signal: options?.signal
@@ -90,8 +90,8 @@ function createPreviewAppProvider(client, options) {
90
90
  return listComputeServiceDomains(client, appId, options?.signal);
91
91
  },
92
92
  async addDomain(options) {
93
- const result = await client.POST("/v1/compute-services/{computeServiceId}/domains", {
94
- params: { path: { computeServiceId: options.appId } },
93
+ const result = await client.POST("/v1/apps/{appId}/domains", {
94
+ params: { path: { appId: options.appId } },
95
95
  body: { hostname: options.hostname },
96
96
  signal: options.signal
97
97
  });
@@ -135,8 +135,8 @@ function createPreviewAppProvider(client, options) {
135
135
  },
136
136
  async promoteDeployment(options) {
137
137
  const promoteResult = await sdk.promote({
138
- serviceId: options.appId,
139
- versionId: options.deploymentId,
138
+ appId: options.appId,
139
+ deploymentId: options.deploymentId,
140
140
  timeoutSeconds: 120,
141
141
  pollIntervalMs: 2e3,
142
142
  signal: options.signal,
@@ -161,7 +161,7 @@ function createPreviewAppProvider(client, options) {
161
161
  region: options.region
162
162
  };
163
163
  const deployResult = await sdk.deploy({
164
- strategy: new PreviewBuildStrategy({
164
+ strategy: new AppBuildStrategy({
165
165
  appPath: path.resolve(options.cwd),
166
166
  entrypoint: options.entrypoint,
167
167
  buildType: options.buildType,
@@ -169,8 +169,8 @@ function createPreviewAppProvider(client, options) {
169
169
  buildSettings: options.buildSettings
170
170
  }),
171
171
  projectId: options.projectId,
172
- serviceId: resolvedApp.appId,
173
- serviceName: resolvedApp.appName,
172
+ appId: resolvedApp.appId,
173
+ appName: resolvedApp.appName,
174
174
  region: resolvedApp.region,
175
175
  portMapping: options.portMapping,
176
176
  envVars: options.envVars,
@@ -185,22 +185,22 @@ function createPreviewAppProvider(client, options) {
185
185
  return {
186
186
  projectId: deployed.projectId,
187
187
  app: {
188
- id: deployed.serviceId,
189
- name: deployed.serviceName,
188
+ id: deployed.appId,
189
+ name: deployed.appName,
190
190
  region: deployed.region ?? null,
191
- liveDeploymentId: deployed.versionId,
192
- liveUrl: toAbsoluteUrl(deployed.serviceEndpointDomain ?? null)
191
+ liveDeploymentId: deployed.deploymentId,
192
+ liveUrl: toAbsoluteUrl(deployed.appEndpointDomain ?? null)
193
193
  },
194
194
  deployment: {
195
- id: deployed.versionId,
195
+ id: deployed.deploymentId,
196
196
  status: "running",
197
- url: toAbsoluteUrl(deployed.serviceEndpointDomain ?? deployed.versionEndpointDomain ?? null)
197
+ url: toAbsoluteUrl(deployed.appEndpointDomain ?? deployed.deploymentEndpointDomain ?? null)
198
198
  }
199
199
  };
200
200
  },
201
201
  async updateAppEnv(options) {
202
202
  const updateResult = await sdk.updateEnv({
203
- serviceId: options.appId,
203
+ appId: options.appId,
204
204
  envVars: options.envVars,
205
205
  timeoutSeconds: 120,
206
206
  pollIntervalMs: 2e3,
@@ -209,19 +209,19 @@ function createPreviewAppProvider(client, options) {
209
209
  });
210
210
  if (updateResult.isErr()) throw new Error(updateResult.error.message);
211
211
  const promoteResult = await sdk.promote({
212
- serviceId: options.appId,
213
- versionId: updateResult.value.versionId,
212
+ appId: options.appId,
213
+ deploymentId: updateResult.value.deploymentId,
214
214
  timeoutSeconds: 120,
215
215
  pollIntervalMs: 2e3,
216
216
  signal: options.signal,
217
217
  progress: options.promoteProgress
218
218
  });
219
219
  if (promoteResult.isErr()) throw new Error(promoteResult.error.message);
220
- const [serviceResult, versionResult] = await Promise.all([sdk.showService({
221
- serviceId: options.appId,
220
+ const [serviceResult, versionResult] = await Promise.all([sdk.showApp({
221
+ appId: options.appId,
222
222
  signal: options.signal
223
- }), sdk.showVersion({
224
- versionId: updateResult.value.versionId,
223
+ }), sdk.showDeployment({
224
+ deploymentId: updateResult.value.deploymentId,
225
225
  signal: options.signal
226
226
  })]);
227
227
  if (serviceResult.isErr()) throw new Error(serviceResult.error.message);
@@ -232,25 +232,25 @@ function createPreviewAppProvider(client, options) {
232
232
  id: serviceResult.value.id,
233
233
  name: serviceResult.value.name,
234
234
  region: serviceResult.value.region ?? null,
235
- liveDeploymentId: serviceResult.value.latestVersionId ?? null,
236
- liveUrl: toAbsoluteUrl(serviceResult.value.serviceEndpointDomain ?? null)
235
+ liveDeploymentId: serviceResult.value.latestDeploymentId ?? null,
236
+ liveUrl: toAbsoluteUrl(serviceResult.value.appEndpointDomain ?? null)
237
237
  },
238
238
  deployment: {
239
239
  id: versionResult.value.id,
240
240
  status: versionResult.value.status,
241
241
  createdAt: versionResult.value.createdAt,
242
- url: toAbsoluteUrl(serviceResult.value.serviceEndpointDomain ?? versionResult.value.previewDomain ?? null),
242
+ url: toAbsoluteUrl(serviceResult.value.appEndpointDomain ?? versionResult.value.previewDomain ?? null),
243
243
  live: true
244
244
  },
245
245
  variables: envVarNames(versionResult.value.envVars)
246
246
  };
247
247
  },
248
248
  async listAppEnvNames(options) {
249
- const [serviceResult, versionResult] = await Promise.all([sdk.showService({
250
- serviceId: options.appId,
249
+ const [serviceResult, versionResult] = await Promise.all([sdk.showApp({
250
+ appId: options.appId,
251
251
  signal: options.signal
252
- }), sdk.showVersion({
253
- versionId: options.deploymentId,
252
+ }), sdk.showDeployment({
253
+ deploymentId: options.deploymentId,
254
254
  signal: options.signal
255
255
  })]);
256
256
  if (serviceResult.isErr()) throw new Error(serviceResult.error.message);
@@ -261,25 +261,25 @@ function createPreviewAppProvider(client, options) {
261
261
  id: serviceResult.value.id,
262
262
  name: serviceResult.value.name,
263
263
  region: serviceResult.value.region ?? null,
264
- liveDeploymentId: serviceResult.value.latestVersionId ?? null,
265
- liveUrl: toAbsoluteUrl(serviceResult.value.serviceEndpointDomain ?? null)
264
+ liveDeploymentId: serviceResult.value.latestDeploymentId ?? null,
265
+ liveUrl: toAbsoluteUrl(serviceResult.value.appEndpointDomain ?? null)
266
266
  },
267
267
  deployment: {
268
268
  id: versionResult.value.id,
269
269
  status: versionResult.value.status,
270
270
  createdAt: versionResult.value.createdAt,
271
271
  url: toAbsoluteUrl(versionResult.value.previewDomain ?? null),
272
- live: serviceResult.value.latestVersionId === versionResult.value.id
272
+ live: serviceResult.value.latestDeploymentId === versionResult.value.id
273
273
  },
274
274
  variables: envVarNames(versionResult.value.envVars)
275
275
  };
276
276
  },
277
277
  async listDeployments(appId, options) {
278
- const [appResult, versionsResult] = await Promise.all([sdk.showService({
279
- serviceId: appId,
278
+ const [appResult, versionsResult] = await Promise.all([sdk.showApp({
279
+ appId,
280
280
  signal: options?.signal
281
- }), sdk.listVersions({
282
- serviceId: appId,
281
+ }), sdk.listDeployments({
282
+ appId,
283
283
  signal: options?.signal
284
284
  })]);
285
285
  if (appResult.isErr()) throw new Error(appResult.error.message);
@@ -289,8 +289,8 @@ function createPreviewAppProvider(client, options) {
289
289
  id: appResult.value.id,
290
290
  name: appResult.value.name,
291
291
  region: appResult.value.region ?? null,
292
- liveDeploymentId: appResult.value.latestVersionId ?? null,
293
- liveUrl: toAbsoluteUrl(appResult.value.serviceEndpointDomain ?? null)
292
+ liveDeploymentId: appResult.value.latestDeploymentId ?? null,
293
+ liveUrl: toAbsoluteUrl(appResult.value.appEndpointDomain ?? null)
294
294
  },
295
295
  deployments: versionsResult.value.slice().sort((left, right) => {
296
296
  const byDate = right.createdAt.localeCompare(left.createdAt);
@@ -305,8 +305,8 @@ function createPreviewAppProvider(client, options) {
305
305
  };
306
306
  },
307
307
  async showDeployment(deploymentId, options) {
308
- const deploymentResult = await sdk.showVersion({
309
- versionId: deploymentId,
308
+ const deploymentResult = await sdk.showDeployment({
309
+ deploymentId,
310
310
  signal: options?.signal
311
311
  });
312
312
  if (deploymentResult.isErr()) {
@@ -329,7 +329,7 @@ function createPreviewAppProvider(client, options) {
329
329
  const result = await streamLogs({
330
330
  baseUrl: options.baseUrl,
331
331
  token: await options.getToken(),
332
- versionId: streamOptions.deploymentId,
332
+ deploymentId: streamOptions.deploymentId,
333
333
  signal: streamOptions.signal
334
334
  }, streamOptions.onRecord);
335
335
  if (result.isErr()) {
@@ -382,7 +382,7 @@ async function listComputeServices(client, options) {
382
382
  const services = [];
383
383
  let cursor;
384
384
  while (true) {
385
- const result = await client.GET("/v1/compute-services", {
385
+ const result = await client.GET("/v1/apps", {
386
386
  params: { query: {
387
387
  projectId: options.projectId,
388
388
  branchGitName: options.branchGitName,
@@ -400,13 +400,13 @@ async function listComputeServices(client, options) {
400
400
  name: service.name,
401
401
  region: service.region.id ?? null,
402
402
  branchId: service.branchId,
403
- liveDeploymentId: service.latestVersionId ?? null,
404
- liveUrl: toAbsoluteUrl(service.serviceEndpointDomain ?? null)
403
+ liveDeploymentId: service.latestDeploymentId ?? null,
404
+ liveUrl: toAbsoluteUrl(service.appEndpointDomain ?? null)
405
405
  }));
406
406
  }
407
407
  async function listComputeServiceDomains(client, computeServiceId, signal) {
408
- const result = await client.GET("/v1/compute-services/{computeServiceId}/domains", {
409
- params: { path: { computeServiceId } },
408
+ const result = await client.GET("/v1/apps/{appId}/domains", {
409
+ params: { path: { appId: computeServiceId } },
410
410
  signal
411
411
  });
412
412
  if (result.error || !result.data) throw domainApiCallError("Failed to list custom domains", result.response, result.error);
@@ -453,7 +453,7 @@ async function createBranchApp(client, options) {
453
453
  gitName: options.branchName,
454
454
  signal: options.signal
455
455
  });
456
- const result = await client.POST("/v1/compute-services", {
456
+ const result = await client.POST("/v1/apps", {
457
457
  body: {
458
458
  projectId: options.projectId,
459
459
  branchId: branch.id,
@@ -491,7 +491,7 @@ function apiCallError(summary, response, error) {
491
491
  return /* @__PURE__ */ new Error(`${summary}: ${message}${hint}`);
492
492
  }
493
493
  function domainApiCallError(summary, response, error) {
494
- return new PreviewDomainApiError({
494
+ return new DomainApiError({
495
495
  summary,
496
496
  status: response.status,
497
497
  code: error.error?.code ?? null,
@@ -503,38 +503,42 @@ async function findAppForDeployment(sdk, deploymentId, signal) {
503
503
  const projectsResult = await sdk.listProjects({ signal });
504
504
  if (projectsResult.isErr()) throw new Error(projectsResult.error.message);
505
505
  for (const project of projectsResult.value) {
506
- const servicesResult = await sdk.listServices({
506
+ const servicesResult = await sdk.listApps({
507
507
  projectId: project.id,
508
508
  signal
509
509
  });
510
510
  if (servicesResult.isErr()) throw new Error(servicesResult.error.message);
511
511
  for (const service of servicesResult.value) {
512
- const detailResult = await sdk.showService({
513
- serviceId: service.id,
514
- signal
515
- });
516
- if (detailResult.isErr()) throw new Error(detailResult.error.message);
517
- const app = {
518
- id: detailResult.value.id,
519
- name: detailResult.value.name,
520
- region: detailResult.value.region ?? null,
521
- liveDeploymentId: detailResult.value.latestVersionId ?? null,
522
- liveUrl: toAbsoluteUrl(detailResult.value.serviceEndpointDomain ?? null)
523
- };
524
- if (app.liveDeploymentId === deploymentId) return app;
525
- const versionsResult = await sdk.listVersions({
526
- serviceId: service.id,
527
- signal
528
- });
529
- if (versionsResult.isErr()) throw new Error(versionsResult.error.message);
530
- if (versionsResult.value.some((version) => version.id === deploymentId)) return app;
512
+ const app = await findServiceAppForDeployment(sdk, service.id, deploymentId, signal);
513
+ if (app) return app;
531
514
  }
532
515
  }
533
516
  return null;
534
517
  }
518
+ async function findServiceAppForDeployment(sdk, serviceId, deploymentId, signal) {
519
+ const detailResult = await sdk.showApp({
520
+ appId: serviceId,
521
+ signal
522
+ });
523
+ if (detailResult.isErr()) throw new Error(detailResult.error.message);
524
+ const app = {
525
+ id: detailResult.value.id,
526
+ name: detailResult.value.name,
527
+ region: detailResult.value.region ?? null,
528
+ liveDeploymentId: detailResult.value.latestDeploymentId ?? null,
529
+ liveUrl: toAbsoluteUrl(detailResult.value.appEndpointDomain ?? null)
530
+ };
531
+ if (app.liveDeploymentId === deploymentId) return app;
532
+ const versionsResult = await sdk.listDeployments({
533
+ appId: serviceId,
534
+ signal
535
+ });
536
+ if (versionsResult.isErr()) throw new Error(versionsResult.error.message);
537
+ return versionsResult.value.some((version) => version.id === deploymentId) ? app : null;
538
+ }
535
539
  function toAbsoluteUrl(url) {
536
540
  if (!url) return null;
537
541
  return url.startsWith("https://") || url.startsWith("http://") ? url : `https://${url}`;
538
542
  }
539
543
  //#endregion
540
- export { PreviewDomainApiError, createPreviewAppProvider };
544
+ export { DomainApiError, createAppProvider };
@@ -1,4 +1,4 @@
1
- //#region src/lib/app/preview-branch-database.ts
1
+ //#region src/lib/app/branch-database-api.ts
2
2
  async function createBranchDatabase(client, options) {
3
3
  const result = await client.POST("/v1/databases", {
4
4
  body: {
@@ -1,10 +1,10 @@
1
1
  import { CliError, usageError } from "../../shell/errors.js";
2
+ import { confirmPrompt } from "../../shell/prompt.js";
2
3
  import { renderSummaryLine } from "../../shell/ui.js";
3
4
  import { canPrompt } from "../../shell/runtime.js";
4
- import { confirmPrompt } from "../../shell/prompt.js";
5
5
  import { formatCommandArgument } from "../../shell/command-arguments.js";
6
6
  import "../project/setup.js";
7
- import { hasBranchDatabaseSignal, inspectBranchDatabaseSignal, runBranchDatabaseSchemaSetup } from "./branch-database.js";
7
+ import { hasBranchDatabaseSignal, inspectBranchDatabaseSignal } from "./branch-database.js";
8
8
  import path from "node:path";
9
9
  //#region src/lib/app/branch-database-deploy.ts
10
10
  async function maybeSetupBranchDatabase(context, provider, projectId, branch, options) {
@@ -26,13 +26,12 @@ async function maybeSetupBranchDatabase(context, provider, projectId, branch, op
26
26
  result: options.db === true ? {
27
27
  status: "skipped",
28
28
  reason: existingDatabaseEnvReason(branch),
29
- envVars: targetEnvVars,
30
- schema: null
29
+ envVars: targetEnvVars
31
30
  } : void 0,
32
31
  warnings: warning ? [warning] : []
33
32
  };
34
33
  }
35
- const localSignal = await inspectBranchDatabaseSignal(context.runtime.cwd, context.runtime.signal);
34
+ const localSignal = await inspectBranchDatabaseSignal(options.projectDir, context.runtime.signal);
36
35
  if (localSignal.unsupportedSchema) {
37
36
  if (options.db === true) throw unsupportedBranchDatabaseSchemaError(localSignal.unsupportedSchema, branch, context);
38
37
  return emptyBranchDatabaseSetupOutcome();
@@ -56,9 +55,9 @@ async function maybeSetupBranchDatabase(context, provider, projectId, branch, op
56
55
  initialValue: false
57
56
  })) return emptyBranchDatabaseSetupOutcome();
58
57
  } else if (!canPrompt(context) && !context.flags.yes) throw nonInteractiveDatabaseSetupRequiresYesError(branch);
59
- return setupBranchDatabase(context, provider, projectId, branch, localSignal, envState);
58
+ return setupBranchDatabase(context, provider, projectId, branch, localSignal, envState, options.projectDir);
60
59
  }
61
- async function setupBranchDatabase(context, provider, projectId, branch, signal, envState) {
60
+ async function setupBranchDatabase(context, provider, projectId, branch, signal, envState, projectDir) {
62
61
  emitBranchDatabaseProgress(context, "pending", "Creating database");
63
62
  const database = await provider.createBranchDatabase({
64
63
  projectId,
@@ -70,27 +69,11 @@ async function setupBranchDatabase(context, provider, projectId, branch, signal,
70
69
  });
71
70
  emitBranchDatabaseProgress(context, "success", "Created database");
72
71
  try {
73
- let schemaSetup = null;
74
- const warnings = [];
75
- let skippedSchemaWarning = null;
76
- if (signal.schema) {
77
- emitBranchDatabaseProgress(context, "pending", `Applying database schema with ${formatSchemaSetupCommand(signal.schema.command)}`);
78
- schemaSetup = await runBranchDatabaseSchemaSetup({
79
- context,
80
- schema: signal.schema,
81
- databaseUrl: database.databaseUrl,
82
- directUrl: database.directUrl
83
- }).catch((error) => {
84
- throw schemaSetupFailedError(error, signal.schema, branch, context.runtime.cwd);
85
- });
86
- emitBranchDatabaseProgress(context, "success", "Applied database schema");
87
- } else skippedSchemaWarning = "No supported Prisma schema source was found. Database env vars were created, but schema setup was skipped.";
88
72
  const envVars = await upsertBranchDatabaseEnvVars(context, provider, projectId, branch, database, envState);
89
- emitBranchDatabaseProgress(context, "success", `Added ${envScopeLabel(branch)} env var${envVars.length === 1 ? "" : "s"} ${envVars.join(", ")}`);
90
- if (skippedSchemaWarning) {
91
- emitBranchDatabaseWarning(context, skippedSchemaWarning);
92
- warnings.push(skippedSchemaWarning);
93
- }
73
+ emitBranchDatabaseProgress(context, "success", `Added ${envScopeLabel(branch)} env var${envVars.length === 1 ? "" : "s"} ${envVars.join(", ")} — shared by every app on ${envScopeLabel(branch) === "production" ? "production" : `branch "${branch.name}"`}`);
74
+ const schemaCommand = signal.schema ? `DATABASE_URL=<url> npx ${formatSchemaSetupCommand(signal.schema.command)} (detected ${path.relative(projectDir, signal.schema.path) || signal.schema.path})` : "your own migration tooling";
75
+ const schemaSuggestion = `The new database is empty. Get a connection URL with \`prisma-cli database connection create ${database.id}\`, then apply your schema with ${schemaCommand}.`;
76
+ emitBranchDatabaseWarning(context, schemaSuggestion);
94
77
  return {
95
78
  result: {
96
79
  status: "created",
@@ -98,14 +81,9 @@ async function setupBranchDatabase(context, provider, projectId, branch, signal,
98
81
  id: database.id,
99
82
  name: database.name
100
83
  },
101
- envVars,
102
- schema: schemaSetup ? {
103
- command: schemaSetup.command,
104
- source: schemaSetup.source,
105
- path: schemaSetup.schemaPath
106
- } : null
84
+ envVars
107
85
  },
108
- warnings
86
+ warnings: [schemaSuggestion]
109
87
  };
110
88
  } catch (error) {
111
89
  throw await cleanupCreatedBranchDatabaseAfterFailure(context, provider, database, branch, error);
@@ -307,24 +285,6 @@ function branchDatabaseCleanupFailedError(setupError, cleanupError, database, br
307
285
  nextSteps: []
308
286
  });
309
287
  }
310
- function schemaSetupFailedError(error, schema, branch, cwd) {
311
- return new CliError({
312
- code: "SCHEMA_SETUP_FAILED",
313
- domain: "app",
314
- summary: "Database schema setup failed",
315
- why: error instanceof Error ? error.message : String(error),
316
- fix: "Fix the Prisma schema or migrations, then rerun deploy with --db.",
317
- debug: formatDebugDetails(error),
318
- meta: {
319
- branch: branch.name,
320
- schemaPath: schema.path,
321
- source: schema.kind,
322
- command: schema.command
323
- },
324
- exitCode: 1,
325
- nextSteps: [...formatSchemaSetupNextSteps(schema, cwd), formatAppDeployWithDbNextStep(branch)]
326
- });
327
- }
328
288
  function unsupportedBranchDatabaseSchemaError(schema, branch, context) {
329
289
  return usageError("Database setup is not available for this Prisma schema", `${path.relative(context.runtime.cwd, schema.path) || defaultUnsupportedSchemaSourcePath(schema)} targets ${formatUnsupportedSchemaTarget(schema.target)}, but --db creates Prisma Postgres databases.`, "Use project env commands to provide a database URL, or switch the Prisma schema source to PostgreSQL before using --db.", [formatProjectEnvAddNextStep(branch), `prisma-cli app deploy --branch ${formatCommandArgument(branch.name)}`], "app");
330
290
  }
@@ -337,14 +297,6 @@ function formatProjectEnvListNextStep(branch) {
337
297
  function formatProjectEnvAddNextStep(branch) {
338
298
  return branch.kind === "production" ? "prisma-cli project env add DATABASE_URL=<value> --role production" : `prisma-cli project env add DATABASE_URL=<value> --branch ${formatCommandArgument(branch.name)}`;
339
299
  }
340
- function formatSchemaSetupNextSteps(schema, cwd) {
341
- const sourcePath = path.relative(cwd, schema.path) || defaultSchemaSourcePath(schema);
342
- switch (schema.command) {
343
- case "migrate-deploy": return [`npx --no-install prisma migrate deploy --schema ${formatCommandArgument(sourcePath)}`];
344
- case "db-push": return [`npx --no-install prisma db push --schema ${formatCommandArgument(sourcePath)}`];
345
- case "prisma-next-db-init": return [`npx --no-install prisma-next contract emit --config ${formatCommandArgument(sourcePath)}`, `npx --no-install prisma-next db init --config ${formatCommandArgument(sourcePath)} --db <DATABASE_URL>`];
346
- }
347
- }
348
300
  function defaultSchemaSourcePath(schema) {
349
301
  return schema.kind === "prisma-next" ? "prisma-next.config.ts" : "schema.prisma";
350
302
  }
@@ -1,6 +1,5 @@
1
1
  import { access, readFile, readdir, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { spawn } from "node:child_process";
4
3
  //#region src/lib/app/branch-database.ts
5
4
  const SKIPPED_DIRECTORIES = new Set([
6
5
  ".git",
@@ -67,23 +66,6 @@ function hasBranchDatabaseSignal(signal) {
67
66
  if (signal.unsupportedSchema) return false;
68
67
  return Boolean(signal.schema || signal.databaseUrlReferences.length > 0);
69
68
  }
70
- async function runBranchDatabaseSchemaSetup(options) {
71
- const schemaPath = path.relative(options.context.runtime.cwd, options.schema.path) || defaultSchemaSourcePath(options.schema);
72
- const commands = buildSchemaSetupCommands(options.schema, schemaPath, options.databaseUrl);
73
- for (const command of commands) await runPrismaCommand({
74
- context: options.context,
75
- ...command,
76
- env: {
77
- DATABASE_URL: options.databaseUrl,
78
- ...options.directUrl ? { DIRECT_URL: options.directUrl } : {}
79
- }
80
- });
81
- return {
82
- command: options.schema.command,
83
- source: options.schema.kind,
84
- schemaPath
85
- };
86
- }
87
69
  async function scanDirectory(cwd, directory, depth, state, signal) {
88
70
  signal.throwIfAborted();
89
71
  if (depth > MAX_SCAN_DEPTH || state.filesVisited >= MAX_SCAN_FILES) return;
@@ -229,88 +211,5 @@ async function readTextFileIfSmall(filePath, signal) {
229
211
  signal
230
212
  });
231
213
  }
232
- function buildSchemaSetupCommands(schema, schemaPath, databaseUrl) {
233
- if (schema.command === "migrate-deploy") return [{
234
- args: [
235
- "--no-install",
236
- "prisma",
237
- "migrate",
238
- "deploy",
239
- "--schema",
240
- schemaPath
241
- ],
242
- displayCommand: "npx --no-install prisma migrate deploy"
243
- }];
244
- if (schema.command === "db-push") return [{
245
- args: [
246
- "--no-install",
247
- "prisma",
248
- "db",
249
- "push",
250
- "--schema",
251
- schemaPath
252
- ],
253
- displayCommand: "npx --no-install prisma db push"
254
- }];
255
- return [{
256
- args: [
257
- "--no-install",
258
- "prisma-next",
259
- "contract",
260
- "emit",
261
- "--config",
262
- schemaPath
263
- ],
264
- displayCommand: "npx --no-install prisma-next contract emit"
265
- }, {
266
- args: [
267
- "--no-install",
268
- "prisma-next",
269
- "db",
270
- "init",
271
- "--config",
272
- schemaPath,
273
- "--db",
274
- databaseUrl
275
- ],
276
- displayCommand: "npx --no-install prisma-next db init"
277
- }];
278
- }
279
- function defaultSchemaSourcePath(schema) {
280
- return schema.kind === "prisma-next" ? "prisma-next.config.ts" : "schema.prisma";
281
- }
282
- async function runPrismaCommand(options) {
283
- const shouldPipeOutput = !options.context.flags.json && !options.context.flags.quiet;
284
- const child = spawn("npx", options.args, {
285
- cwd: options.context.runtime.cwd,
286
- env: {
287
- ...options.context.runtime.env,
288
- ...options.env
289
- },
290
- signal: options.context.runtime.signal,
291
- stdio: shouldPipeOutput ? [
292
- "ignore",
293
- "pipe",
294
- "pipe"
295
- ] : [
296
- "ignore",
297
- "ignore",
298
- "ignore"
299
- ]
300
- });
301
- if (shouldPipeOutput) {
302
- child.stdout?.pipe(options.context.output.stderr, { end: false });
303
- child.stderr?.pipe(options.context.output.stderr, { end: false });
304
- }
305
- const exit = await new Promise((resolve, reject) => {
306
- child.once("error", reject);
307
- child.once("close", (code, signal) => resolve({
308
- code,
309
- signal
310
- }));
311
- });
312
- if (exit.signal) throw new Error(`${options.displayCommand} was terminated by ${exit.signal}.`);
313
- if (exit.code !== 0) throw new Error(`${options.displayCommand} exited with code ${exit.code ?? 1}.`);
314
- }
315
214
  //#endregion
316
- export { hasBranchDatabaseSignal, inspectBranchDatabaseSignal, runBranchDatabaseSchemaSetup };
215
+ export { hasBranchDatabaseSignal, inspectBranchDatabaseSignal };