@prisma/cli 3.0.0-dev.53.1 → 3.0.0-dev.54.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.
@@ -48,7 +48,8 @@ async function runAppBuild(context, entrypoint, requestedBuildType) {
48
48
  const { artifact, buildType: actualBuildType } = await executePreviewBuild({
49
49
  appPath: context.runtime.cwd,
50
50
  entrypoint,
51
- buildType
51
+ buildType,
52
+ signal: context.runtime.signal
52
53
  });
53
54
  return {
54
55
  command: "app.build",
@@ -78,12 +79,13 @@ async function runAppRun(context, entrypoint, requestedBuildType, requestedPort)
78
79
  buildType: resolvedBuildType,
79
80
  entrypoint,
80
81
  port,
81
- env: context.runtime.env
82
+ env: context.runtime.env,
83
+ signal: context.runtime.signal
82
84
  });
83
85
  } catch (error) {
84
86
  throw runFailedError("Local app run failed", error);
85
87
  }
86
- if (runResult.signal === "SIGINT" || runResult.signal === "SIGTERM") process.exitCode = runResult.signal === "SIGINT" ? 130 : 143;
88
+ if (runResult.signal === "SIGINT" || runResult.signal === "SIGTERM") throw new DOMException("Command canceled", "AbortError");
87
89
  else if (runResult.exitCode !== 0) throw runFailedError("Local app run failed", `The ${formatFrameworkName(runResult.framework)} process exited with code ${runResult.exitCode}.`, runResult.exitCode);
88
90
  return {
89
91
  command: "app.run",
@@ -107,7 +109,7 @@ async function runAppDeploy(context, appName, options) {
107
109
  envProjectId
108
110
  });
109
111
  const skipLocalPin = Boolean(envProjectId || options?.projectRef || options?.createProjectName);
110
- const localPin = skipLocalPin ? { kind: "missing" } : await readLocalResolutionPin(context.runtime.cwd);
112
+ const localPin = skipLocalPin ? { kind: "missing" } : await readLocalResolutionPin(context.runtime.cwd, context.runtime.signal);
111
113
  if (!skipLocalPin && localPin.kind === "invalid") throw localResolutionPinStaleError();
112
114
  const branch = await resolveDeployBranch(context, options?.branchName);
113
115
  if (options?.httpPort) parseDeployHttpPort(options.httpPort);
@@ -138,7 +140,7 @@ async function runAppDeploy(context, appName, options) {
138
140
  explicitAppName: appName,
139
141
  explicitAppId: envAppId,
140
142
  firstDeploy: Boolean(target.localPinAction),
141
- inferName: () => inferTargetName(context.runtime.cwd)
143
+ inferName: () => inferTargetName(context.runtime.cwd, context.runtime.signal)
142
144
  });
143
145
  await maybeRenderDeploySetupBlock(context, {
144
146
  includeDirectory: !target.localPinAction,
@@ -158,7 +160,7 @@ async function runAppDeploy(context, appName, options) {
158
160
  runtime = customized.runtime;
159
161
  const buildType = framework.buildType;
160
162
  assertSupportedEntrypoint(buildType, options?.entrypoint, "deploy");
161
- const entrypoint = await resolveDeployEntrypoint(context.runtime.cwd, framework, options?.entrypoint);
163
+ const entrypoint = await resolveDeployEntrypoint(context.runtime.cwd, framework, options?.entrypoint, context.runtime.signal);
162
164
  const portMapping = parseDeployPortMapping(String(runtime.port));
163
165
  const progressState = createPreviewDeployProgressState();
164
166
  const deployStartedAt = Date.now();
@@ -174,6 +176,7 @@ async function runAppDeploy(context, appName, options) {
174
176
  portMapping,
175
177
  envVars,
176
178
  interaction: void 0,
179
+ signal: context.runtime.signal,
177
180
  progress: createPreviewDeployProgress(context.output.stderr, context.ui, !context.flags.json && !context.flags.quiet, progressState)
178
181
  }).catch((error) => {
179
182
  throw appDeployFailedError(error, progressState);
@@ -217,7 +220,7 @@ async function runAppListDeploys(context, appName, projectRef) {
217
220
  warnings: [],
218
221
  nextSteps: ["prisma-cli app deploy"]
219
222
  };
220
- const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
223
+ const deploymentsResult = await provider.listDeployments(selectedApp.id, { signal: context.runtime.signal }).catch((error) => {
221
224
  throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app deploy"]);
222
225
  });
223
226
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
@@ -256,7 +259,7 @@ async function runAppShow(context, appName, projectRef) {
256
259
  warnings: [],
257
260
  nextSteps: ["prisma-cli app deploy"]
258
261
  };
259
- const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
262
+ const deploymentsResult = await provider.listDeployments(selectedApp.id, { signal: context.runtime.signal }).catch((error) => {
260
263
  throw deployFailedError("Failed to inspect app", error, ["prisma-cli app list-deploys"]);
261
264
  });
262
265
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
@@ -284,7 +287,7 @@ async function runAppShow(context, appName, projectRef) {
284
287
  }
285
288
  async function runAppShowDeploy(context, deploymentId) {
286
289
  ensurePreviewAppMode(context);
287
- const deployment = await (await requirePreviewAppProvider(context)).showDeployment(deploymentId).catch((error) => {
290
+ const deployment = await (await requirePreviewAppProvider(context)).showDeployment(deploymentId, { signal: context.runtime.signal }).catch((error) => {
288
291
  throw deployFailedError("Failed to show deployment", error, ["prisma-cli app list-deploys"]);
289
292
  });
290
293
  if (!deployment) throw new CliError({
@@ -321,7 +324,7 @@ async function runAppOpen(context, appName, projectRef) {
321
324
  const { provider, target, projectId } = await requireProviderAndProjectContext(context, projectRef, { commandName: "app open" });
322
325
  const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId, target.branch.name), appName);
323
326
  if (!selectedApp) throw noDeploymentsError("No deployments available to open", "The resolved project does not have any deployed app yet.");
324
- const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
327
+ const deploymentsResult = await provider.listDeployments(selectedApp.id, { signal: context.runtime.signal }).catch((error) => {
325
328
  throw deployFailedError("Failed to resolve app URL", error, ["prisma-cli app show"]);
326
329
  });
327
330
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
@@ -334,7 +337,11 @@ async function runAppOpen(context, appName, projectRef) {
334
337
  if (!liveDeployment) throw noDeploymentsError("No deployments available to open", `The selected app "${deploymentsResult.app.name}" does not have any deployments yet.`);
335
338
  if (!deploymentsResult.app.liveUrl) throw featureUnavailableError("Live URL is not available for the selected app", "Deployments exist, but the provider does not expose a stable live service URL for this app yet.", "Run prisma-cli app show to inspect the current deployment state and try again after the app reports a live URL.", ["prisma-cli app show"], "app");
336
339
  const shouldOpen = canPrompt(context);
337
- if (shouldOpen) await open(deploymentsResult.app.liveUrl);
340
+ if (shouldOpen) {
341
+ context.runtime.signal.throwIfAborted();
342
+ await open(deploymentsResult.app.liveUrl);
343
+ context.runtime.signal.throwIfAborted();
344
+ }
338
345
  return {
339
346
  command: "app.open",
340
347
  result: {
@@ -355,7 +362,8 @@ async function runAppDomainAdd(context, hostname, options) {
355
362
  const target = await resolveAppDomainTarget(context, options, `app domain add ${normalizedHostname}`);
356
363
  const added = await target.provider.addDomain({
357
364
  appId: target.app.id,
358
- hostname: normalizedHostname
365
+ hostname: normalizedHostname,
366
+ signal: context.runtime.signal
359
367
  }).catch((error) => {
360
368
  throw domainCommandError("add", error, normalizedHostname);
361
369
  });
@@ -373,8 +381,8 @@ async function runAppDomainAdd(context, hostname, options) {
373
381
  async function runAppDomainShow(context, hostname, options) {
374
382
  const normalizedHostname = normalizeDomainHostname(hostname);
375
383
  const target = await resolveAppDomainTarget(context, options, `app domain show ${normalizedHostname}`);
376
- const domain = await resolveDomainByHostname(target.provider, target.app.id, normalizedHostname, "show");
377
- const detail = await target.provider.showDomain(domain.id).catch((error) => {
384
+ const domain = await resolveDomainByHostname(target.provider, target.app.id, normalizedHostname, "show", context.runtime.signal);
385
+ const detail = await target.provider.showDomain(domain.id, { signal: context.runtime.signal }).catch((error) => {
378
386
  throw domainCommandError("show", error, normalizedHostname);
379
387
  });
380
388
  return {
@@ -390,9 +398,9 @@ async function runAppDomainShow(context, hostname, options) {
390
398
  async function runAppDomainRemove(context, hostname, options) {
391
399
  const normalizedHostname = normalizeDomainHostname(hostname);
392
400
  const target = await resolveAppDomainTarget(context, options, `app domain remove ${normalizedHostname}`);
393
- const domain = await resolveDomainByHostname(target.provider, target.app.id, normalizedHostname, "remove");
401
+ const domain = await resolveDomainByHostname(target.provider, target.app.id, normalizedHostname, "remove", context.runtime.signal);
394
402
  await confirmDomainRemoval(context, target.resultTarget, normalizedHostname);
395
- await target.provider.removeDomain(domain.id).catch((error) => {
403
+ await target.provider.removeDomain(domain.id, { signal: context.runtime.signal }).catch((error) => {
396
404
  throw domainCommandError("remove", error, normalizedHostname);
397
405
  });
398
406
  return {
@@ -409,8 +417,8 @@ async function runAppDomainRemove(context, hostname, options) {
409
417
  async function runAppDomainRetry(context, hostname, options) {
410
418
  const normalizedHostname = normalizeDomainHostname(hostname);
411
419
  const target = await resolveAppDomainTarget(context, options, `app domain retry ${normalizedHostname}`);
412
- const domain = await resolveDomainByHostname(target.provider, target.app.id, normalizedHostname, "retry");
413
- const retried = await target.provider.retryDomain(domain.id).catch((error) => {
420
+ const domain = await resolveDomainByHostname(target.provider, target.app.id, normalizedHostname, "retry", context.runtime.signal);
421
+ const retried = await target.provider.retryDomain(domain.id, { signal: context.runtime.signal }).catch((error) => {
414
422
  throw domainCommandError("retry", error, normalizedHostname);
415
423
  });
416
424
  return {
@@ -427,7 +435,7 @@ async function runAppDomainWait(context, hostname, options) {
427
435
  const normalizedHostname = normalizeDomainHostname(hostname);
428
436
  const timeoutMs = parseDomainWaitTimeout(options?.timeout);
429
437
  const target = await resolveAppDomainTarget(context, options, `app domain wait ${normalizedHostname}`);
430
- const domain = await resolveDomainByHostname(target.provider, target.app.id, normalizedHostname, "wait");
438
+ const domain = await resolveDomainByHostname(target.provider, target.app.id, normalizedHostname, "wait", context.runtime.signal);
431
439
  if (!context.flags.json && !context.flags.quiet) context.output.stderr.write([
432
440
  `app domain wait -> Waiting for ${normalizedHostname} to become active.`,
433
441
  "",
@@ -470,8 +478,8 @@ async function runAppDomainWait(context, hostname, options) {
470
478
  exitCode: 1,
471
479
  nextSteps: [`prisma-cli app domain show ${normalizedHostname}`]
472
480
  });
473
- await sleep(Math.min(pollIntervalMs, Math.max(deadline - Date.now(), 0)));
474
- current = await target.provider.showDomain(current.id).catch((error) => {
481
+ await sleep(Math.min(pollIntervalMs, Math.max(deadline - Date.now(), 0)), context.runtime.signal);
482
+ current = await target.provider.showDomain(current.id, { signal: context.runtime.signal }).catch((error) => {
475
483
  throw domainCommandError("wait", error, normalizedHostname);
476
484
  });
477
485
  }
@@ -504,6 +512,7 @@ async function runAppLogs(context, appName, deploymentId, projectRef) {
504
512
  }
505
513
  await provider.streamDeploymentLogs({
506
514
  deploymentId: target.deployment.id,
515
+ signal: context.runtime.signal,
507
516
  onRecord: (record) => writeLogRecord(context, record)
508
517
  }).catch((error) => {
509
518
  throw deployFailedError("Failed to stream app logs", error, [`prisma-cli app show-deploy ${target.deployment.id}`, "prisma-cli app list-deploys"]);
@@ -513,7 +522,7 @@ async function resolveExplicitLogDeployment(context, provider, projectId, branch
513
522
  if (appName) {
514
523
  const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId, branchName), appName);
515
524
  if (!selectedApp) throw noDeploymentsError("No deployments available to stream logs", "The resolved project does not have any deployed app yet.");
516
- const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
525
+ const deploymentsResult = await provider.listDeployments(selectedApp.id, { signal: context.runtime.signal }).catch((error) => {
517
526
  throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
518
527
  });
519
528
  const deployment = requireDeploymentForApp(deploymentsResult.deployments, deploymentId, selectedApp.name);
@@ -526,7 +535,7 @@ async function resolveExplicitLogDeployment(context, provider, projectId, branch
526
535
  deployment
527
536
  };
528
537
  }
529
- const shown = await provider.showDeployment(deploymentId).catch((error) => {
538
+ const shown = await provider.showDeployment(deploymentId, { signal: context.runtime.signal }).catch((error) => {
530
539
  throw deployFailedError("Failed to show deployment", error, ["prisma-cli app list-deploys"]);
531
540
  });
532
541
  if (!shown) throw new CliError({
@@ -569,7 +578,7 @@ async function resolveExplicitLogDeployment(context, provider, projectId, branch
569
578
  async function resolveLiveLogDeployment(context, provider, projectId, branchName, appName) {
570
579
  const selectedApp = await resolveExistingAppSelection(context, projectId, await listApps(context, provider, projectId, branchName), appName);
571
580
  if (!selectedApp) throw noDeploymentsError("No deployments available to stream logs", "The resolved project does not have any deployed app yet.");
572
- const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
581
+ const deploymentsResult = await provider.listDeployments(selectedApp.id, { signal: context.runtime.signal }).catch((error) => {
573
582
  throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
574
583
  });
575
584
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
@@ -604,7 +613,7 @@ async function runAppPromote(context, deploymentId, appName, projectRef) {
604
613
  ensurePreviewAppMode(context);
605
614
  const { provider, target, projectId } = await requireProviderAndProjectContext(context, projectRef, { commandName: "app promote" });
606
615
  const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId, target.branch.name), appName, "promote");
607
- const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
616
+ const deploymentsResult = await provider.listDeployments(selectedApp.id, { signal: context.runtime.signal }).catch((error) => {
608
617
  throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
609
618
  });
610
619
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
@@ -617,6 +626,7 @@ async function runAppPromote(context, deploymentId, appName, projectRef) {
617
626
  if (!targetAlreadyLive) await provider.promoteDeployment({
618
627
  appId: selectedApp.id,
619
628
  deploymentId: targetDeployment.id,
629
+ signal: context.runtime.signal,
620
630
  progress: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
621
631
  }).catch((error) => {
622
632
  throw deployFailedError("Failed to promote deployment", error, ["prisma-cli app list-deploys"]);
@@ -644,7 +654,7 @@ async function runAppRollback(context, appName, deploymentId, projectRef) {
644
654
  ensurePreviewAppMode(context);
645
655
  const { provider, target, projectId } = await requireProviderAndProjectContext(context, projectRef, { commandName: "app rollback" });
646
656
  const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId, target.branch.name), appName, "rollback");
647
- const deploymentsResult = await provider.listDeployments(selectedApp.id).catch((error) => {
657
+ const deploymentsResult = await provider.listDeployments(selectedApp.id, { signal: context.runtime.signal }).catch((error) => {
648
658
  throw deployFailedError("Failed to list app deployments", error, ["prisma-cli app list-deploys"]);
649
659
  });
650
660
  const currentLiveDeploymentId = await resolveCurrentLiveDeploymentId(context, projectId, deploymentsResult.app, deploymentsResult.deployments);
@@ -658,6 +668,7 @@ async function runAppRollback(context, appName, deploymentId, projectRef) {
658
668
  if (!targetAlreadyLive) await provider.promoteDeployment({
659
669
  appId: selectedApp.id,
660
670
  deploymentId: targetDeployment.id,
671
+ signal: context.runtime.signal,
661
672
  progress: createPreviewPromoteProgress(context.output.stderr, !context.flags.json && !context.flags.quiet)
662
673
  }).catch((error) => {
663
674
  throw deployFailedError("Failed to roll back deployment", error, ["prisma-cli app list-deploys"]);
@@ -687,7 +698,7 @@ async function runAppRemove(context, appName, projectRef) {
687
698
  const { provider, target, projectId } = await requireProviderAndProjectContext(context, projectRef, { commandName: "app remove" });
688
699
  const selectedApp = await requireReleaseAppSelection(context, projectId, await listApps(context, provider, projectId, target.branch.name), appName, "remove");
689
700
  await confirmAppRemoval(context, selectedApp);
690
- const removedApp = await provider.removeApp(selectedApp.id).catch((error) => {
701
+ const removedApp = await provider.removeApp(selectedApp.id, { signal: context.runtime.signal }).catch((error) => {
691
702
  throw removeFailedError("Failed to remove app", error, ["prisma-cli app show", "prisma-cli app list-deploys"]);
692
703
  });
693
704
  const warnings = await cleanupRemovedAppState(context, projectId, removedApp.id);
@@ -762,8 +773,8 @@ async function resolveDomainAppSelection(context, projectId, apps, options) {
762
773
  if (selectedApp) return selectedApp;
763
774
  throw usageError("Custom domain requires an existing app on the production branch", "The resolved production branch does not have an app that can receive a custom domain.", "Deploy or promote an app to production first, then rerun the domain command.", ["prisma-cli app deploy --branch production", "prisma-cli app show"], "app");
764
775
  }
765
- async function resolveDomainByHostname(provider, appId, hostname, command) {
766
- const matched = (await provider.listDomains(appId).catch((error) => {
776
+ async function resolveDomainByHostname(provider, appId, hostname, command, signal) {
777
+ const matched = (await provider.listDomains(appId, { signal }).catch((error) => {
767
778
  throw domainCommandError(command, error, hostname);
768
779
  })).find((domain) => sameDomainHostname(domain.hostname, hostname));
769
780
  if (matched) return matched;
@@ -994,9 +1005,20 @@ function formatElapsed(milliseconds) {
994
1005
  const remainingSeconds = seconds % 60;
995
1006
  return `${minutes}:${String(remainingSeconds).padStart(2, "0")}`;
996
1007
  }
997
- async function sleep(milliseconds) {
1008
+ async function sleep(milliseconds, signal) {
998
1009
  if (milliseconds <= 0) return;
999
- await new Promise((resolve) => setTimeout(resolve, milliseconds));
1010
+ signal.throwIfAborted();
1011
+ await new Promise((resolve, reject) => {
1012
+ const onAbort = () => {
1013
+ clearTimeout(timeout);
1014
+ reject(signal.reason);
1015
+ };
1016
+ const timeout = setTimeout(() => {
1017
+ signal.removeEventListener("abort", onAbort);
1018
+ resolve();
1019
+ }, milliseconds);
1020
+ signal.addEventListener("abort", onAbort, { once: true });
1021
+ });
1000
1022
  }
1001
1023
  async function resolveDeployAppSelection(context, projectId, apps, options) {
1002
1024
  if (options.explicitAppName) {
@@ -1211,7 +1233,10 @@ function resolveRollbackTarget(deployments, currentLiveDeploymentId) {
1211
1233
  });
1212
1234
  }
1213
1235
  async function listApps(context, provider, projectId, branchName) {
1214
- return provider.listApps(projectId, { branchName }).then(sortApps).catch((error) => {
1236
+ return provider.listApps(projectId, {
1237
+ branchName,
1238
+ signal: context.runtime.signal
1239
+ }).then(sortApps).catch((error) => {
1215
1240
  if (isMissingProjectError(error)) throw new CliError({
1216
1241
  code: "PROJECT_NOT_FOUND",
1217
1242
  domain: "project",
@@ -1229,20 +1254,20 @@ async function requirePreviewAppProvider(context) {
1229
1254
  return provider;
1230
1255
  }
1231
1256
  async function requirePreviewAppProviderWithClient(context) {
1232
- const client = await requireComputeAuth(context.runtime.env);
1257
+ const client = await requireComputeAuth(context.runtime.env, context.runtime.signal);
1233
1258
  if (!client) throw authRequiredError(["prisma-cli auth login"]);
1234
1259
  return {
1235
1260
  client,
1236
- provider: createPreviewAppProvider(client, createPreviewLogAuthOptions(context.runtime.env))
1261
+ provider: createPreviewAppProvider(client, createPreviewLogAuthOptions(context.runtime.env, context.runtime.signal))
1237
1262
  };
1238
1263
  }
1239
- function createPreviewLogAuthOptions(env) {
1264
+ function createPreviewLogAuthOptions(env, signal) {
1240
1265
  const rawToken = env[SERVICE_TOKEN_ENV_VAR]?.trim();
1241
1266
  if (rawToken) return {
1242
1267
  baseUrl: getApiBaseUrl(env),
1243
1268
  getToken: async () => rawToken
1244
1269
  };
1245
- const tokenStorage = new FileTokenStorage(env);
1270
+ const tokenStorage = new FileTokenStorage(env, signal);
1246
1271
  return {
1247
1272
  baseUrl: getApiBaseUrl(env),
1248
1273
  getToken: async () => {
@@ -1280,7 +1305,7 @@ async function resolveProjectContext(context, client, explicitProject, options)
1280
1305
  workspace: authState.workspace,
1281
1306
  explicitProject,
1282
1307
  envProjectId: options?.envProjectId,
1283
- listProjects: () => listRealWorkspaceProjects(client, authState.workspace),
1308
+ listProjects: () => listRealWorkspaceProjects(client, authState.workspace, context.runtime.signal),
1284
1309
  commandName: options?.commandName
1285
1310
  });
1286
1311
  const branch = options?.branch ?? await resolveDeployBranch(context, void 0);
@@ -1296,7 +1321,7 @@ async function resolveDeployProjectContext(context, client, provider, explicitPr
1296
1321
  const workspace = (await requireAuthenticatedAuthState(context)).workspace;
1297
1322
  if (!workspace) throw workspaceRequiredError();
1298
1323
  const branch = options.branch ?? await resolveDeployBranch(context, void 0);
1299
- const projects = await listRealWorkspaceProjects(client, workspace);
1324
+ const projects = await listRealWorkspaceProjects(client, workspace, context.runtime.signal);
1300
1325
  if (explicitProject) return withDeployBranch({
1301
1326
  workspace,
1302
1327
  project: toProjectSummary(resolveProjectForSetup(explicitProject, projects, workspace)),
@@ -1312,7 +1337,7 @@ async function resolveDeployProjectContext(context, client, provider, explicitPr
1312
1337
  if (!projectName) throw projectSetupNameRequiredError("app deploy --create-project");
1313
1338
  return withDeployBranch({
1314
1339
  workspace,
1315
- project: toProjectSummary(await createProjectForDeploySetup(provider, projectName, workspace)),
1340
+ project: toProjectSummary(await createProjectForDeploySetup(provider, projectName, workspace, context.runtime.signal)),
1316
1341
  resolution: {
1317
1342
  projectSource: "created",
1318
1343
  targetName: projectName,
@@ -1360,13 +1385,13 @@ async function resolveDeployProjectContext(context, client, provider, explicitPr
1360
1385
  }
1361
1386
  }, branch);
1362
1387
  if (canPrompt(context) && !context.flags.yes) return withDeployBranch(await resolveInteractiveDeployProjectSetup(context, provider, workspace, projects), branch);
1363
- throw projectSetupRequiredError(projects, await inferTargetName(context.runtime.cwd));
1388
+ throw projectSetupRequiredError(projects, await inferTargetName(context.runtime.cwd, context.runtime.signal));
1364
1389
  }
1365
1390
  async function resolveInteractiveDeployProjectSetup(context, provider, workspace, projects) {
1366
1391
  const setup = await promptForProjectSetupChoice({
1367
1392
  context,
1368
1393
  projects,
1369
- createProject: (projectName) => createProjectForDeploySetup(provider, projectName, workspace),
1394
+ createProject: (projectName) => createProjectForDeploySetup(provider, projectName, workspace, context.runtime.signal),
1370
1395
  cancel: {
1371
1396
  why: "Deploy needs a Project before it can continue.",
1372
1397
  fix: "Choose an existing Project or create a new one, then rerun deploy.",
@@ -1384,8 +1409,11 @@ async function resolveInteractiveDeployProjectSetup(context, provider, workspace
1384
1409
  localPinAction: setup.action
1385
1410
  };
1386
1411
  }
1387
- async function createProjectForDeploySetup(provider, projectName, workspace) {
1388
- const created = await provider.createProject({ name: projectName }).catch((error) => {
1412
+ async function createProjectForDeploySetup(provider, projectName, workspace, signal) {
1413
+ const created = await provider.createProject({
1414
+ name: projectName,
1415
+ signal
1416
+ }).catch((error) => {
1389
1417
  throw projectCreateFailedError(error, projectName, workspace, {
1390
1418
  nextSteps: [
1391
1419
  "prisma-cli project list",
@@ -1432,7 +1460,7 @@ async function resolveDeployBranch(context, explicitBranchName) {
1432
1460
  name: explicitBranchName,
1433
1461
  annotation: "set by --branch"
1434
1462
  };
1435
- const gitBranch = await readLocalGitBranch(context.runtime.cwd);
1463
+ const gitBranch = await readLocalGitBranch(context.runtime.cwd, context.runtime.signal);
1436
1464
  if (gitBranch) return {
1437
1465
  name: gitBranch,
1438
1466
  annotation: "from local Git branch"
@@ -1442,26 +1470,39 @@ async function resolveDeployBranch(context, explicitBranchName) {
1442
1470
  annotation: "default"
1443
1471
  };
1444
1472
  }
1445
- async function readLocalGitBranch(cwd) {
1446
- const headPath = await resolveGitHeadPath(path.join(cwd, ".git"));
1473
+ async function readLocalGitBranch(cwd, signal) {
1474
+ const headPath = await resolveGitHeadPath(path.join(cwd, ".git"), signal);
1447
1475
  if (!headPath) return null;
1448
1476
  try {
1449
- const head = (await readFile(headPath, "utf8")).trim();
1477
+ const head = (await readFile(headPath, {
1478
+ encoding: "utf8",
1479
+ signal
1480
+ })).trim();
1450
1481
  if (head.startsWith("ref: refs/heads/")) return head.slice(16);
1451
- } catch {
1482
+ } catch (error) {
1483
+ if (signal.aborted) throw error;
1452
1484
  return null;
1453
1485
  }
1454
1486
  return null;
1455
1487
  }
1456
- async function resolveGitHeadPath(gitPath) {
1488
+ async function resolveGitHeadPath(gitPath, signal) {
1489
+ signal.throwIfAborted();
1457
1490
  try {
1458
- const raw = await readFile(gitPath, "utf8");
1491
+ const raw = await readFile(gitPath, {
1492
+ encoding: "utf8",
1493
+ signal
1494
+ });
1459
1495
  if (raw.startsWith("gitdir:")) return path.join(path.resolve(path.dirname(gitPath), raw.slice(7).trim()), "HEAD");
1460
- } catch {}
1496
+ } catch (error) {
1497
+ if (signal.aborted) throw error;
1498
+ }
1499
+ signal.throwIfAborted();
1461
1500
  try {
1462
1501
  await access(path.join(gitPath, "HEAD"));
1502
+ signal.throwIfAborted();
1463
1503
  return path.join(gitPath, "HEAD");
1464
- } catch {
1504
+ } catch (error) {
1505
+ if (signal.aborted) throw error;
1465
1506
  return null;
1466
1507
  }
1467
1508
  }
@@ -1473,7 +1514,7 @@ async function resolveDeployFramework(context, options) {
1473
1514
  displayName: "Bun",
1474
1515
  annotation: "set by --entry"
1475
1516
  };
1476
- const detected = await detectDeployFramework(context.runtime.cwd);
1517
+ const detected = await detectDeployFramework(context.runtime.cwd, context.runtime.signal);
1477
1518
  if (detected) return detected;
1478
1519
  throw frameworkNotDetectedError(context.runtime.cwd);
1479
1520
  }
@@ -1491,23 +1532,26 @@ function assertSupportedEntrypointForRequestedDeployShape(options) {
1491
1532
  if (!options.requestedFramework) return;
1492
1533
  assertSupportedEntrypoint(frameworkFromUserFacingValue(options.requestedFramework, "set by --framework").buildType, options.entrypoint, "deploy");
1493
1534
  }
1494
- async function resolveDeployEntrypoint(cwd, framework, explicitEntrypoint) {
1535
+ async function resolveDeployEntrypoint(cwd, framework, explicitEntrypoint, signal) {
1495
1536
  if (explicitEntrypoint || framework.buildType !== "bun") return explicitEntrypoint;
1496
- const packageEntrypoint = readBunPackageEntrypoint(await readBunPackageJson(cwd));
1537
+ const packageEntrypoint = readBunPackageEntrypoint(await readBunPackageJson(cwd, signal));
1497
1538
  if (packageEntrypoint) return packageEntrypoint;
1498
1539
  if (framework.key !== "hono") return;
1499
1540
  const defaultEntrypoint = "src/index.ts";
1541
+ signal.throwIfAborted();
1500
1542
  try {
1501
1543
  await access(path.join(cwd, defaultEntrypoint));
1544
+ signal.throwIfAborted();
1502
1545
  return defaultEntrypoint;
1503
1546
  } catch (error) {
1547
+ if (signal.aborted) throw error;
1504
1548
  if (error.code !== "ENOENT") throw error;
1505
1549
  return;
1506
1550
  }
1507
1551
  }
1508
- async function detectDeployFramework(cwd) {
1509
- const packageJson = await readBunPackageJson(cwd);
1510
- const nextConfig = await detectNextConfig(cwd);
1552
+ async function detectDeployFramework(cwd, signal) {
1553
+ const packageJson = await readBunPackageJson(cwd, signal);
1554
+ const nextConfig = await detectNextConfig(cwd, signal);
1511
1555
  if (nextConfig.exists || hasPackageDependency(packageJson, "next")) return {
1512
1556
  key: "nextjs",
1513
1557
  buildType: "nextjs",
@@ -1528,7 +1572,7 @@ async function detectDeployFramework(cwd) {
1528
1572
  };
1529
1573
  return null;
1530
1574
  }
1531
- async function detectNextConfig(cwd) {
1575
+ async function detectNextConfig(cwd, signal) {
1532
1576
  for (const candidate of [
1533
1577
  "next.config.js",
1534
1578
  "next.config.mjs",
@@ -1537,13 +1581,18 @@ async function detectNextConfig(cwd) {
1537
1581
  "next.config.mts"
1538
1582
  ]) {
1539
1583
  const filePath = path.join(cwd, candidate);
1584
+ signal.throwIfAborted();
1540
1585
  try {
1541
- const content = await readFile(filePath, "utf8");
1586
+ const content = await readFile(filePath, {
1587
+ encoding: "utf8",
1588
+ signal
1589
+ });
1542
1590
  return {
1543
1591
  exists: true,
1544
1592
  standalone: /\boutput\s*:\s*["'`]standalone["'`]/.test(content)
1545
1593
  };
1546
1594
  } catch (error) {
1595
+ if (signal.aborted) throw error;
1547
1596
  if (error.code !== "ENOENT") throw error;
1548
1597
  }
1549
1598
  }
@@ -1715,7 +1764,7 @@ function formatDeployDirectory(cwd) {
1715
1764
  async function readCurrentWorkspaceId(context) {
1716
1765
  const state = await context.stateStore.read();
1717
1766
  if (state.auth?.workspaceId) return state.auth.workspaceId;
1718
- return (await readAuthState(context.runtime.env)).workspace?.id ?? null;
1767
+ return (await readAuthState(context.runtime.env, context.runtime.signal)).workspace?.id ?? null;
1719
1768
  }
1720
1769
  function normalizeBuildType(requestedBuildType) {
1721
1770
  if (!requestedBuildType) return "auto";
@@ -1737,7 +1786,7 @@ function assertSupportedEntrypoint(buildType, entrypoint, commandName) {
1737
1786
  }
1738
1787
  }
1739
1788
  async function requireLocalBuildType(context, buildType, commandName) {
1740
- const resolvedBuildType = await resolveLocalBuildType(context.runtime.cwd, buildType);
1789
+ const resolvedBuildType = await resolveLocalBuildType(context.runtime.cwd, buildType, context.runtime.signal);
1741
1790
  if (resolvedBuildType) return resolvedBuildType;
1742
1791
  throw usageError(`App ${commandName} requires an explicit framework when detection is ambiguous`, "This preview only starts local dev servers for clear Next.js or Bun project shapes.", "Pass --build-type nextjs for a Next.js app, or pass --build-type bun with --entry <path> for a Bun app.", [`prisma-cli app ${commandName} --build-type nextjs`, `prisma-cli app ${commandName} --build-type bun --entry server.ts`], "app");
1743
1792
  }
@@ -11,32 +11,32 @@ function isRealMode(context) {
11
11
  async function runAuthLogin(context, options) {
12
12
  let result;
13
13
  if (isRealMode(context)) {
14
- await performLogin(context.runtime.env);
15
- result = await readAuthState(context.runtime.env);
14
+ await performLogin(context.runtime.env, context.runtime.signal);
15
+ result = await readAuthState(context.runtime.env, context.runtime.signal);
16
16
  } else result = await loginWithSelectionFlow(context, createAuthUseCases(createCliUseCaseGateways(context)), options);
17
17
  return createAuthSuccess("auth.login", result, ["prisma-cli auth whoami", "prisma-cli project list"]);
18
18
  }
19
19
  async function runAuthLogout(context) {
20
20
  let result;
21
21
  if (isRealMode(context)) {
22
- await performLogout(context.runtime.env);
23
- result = await readAuthState(context.runtime.env);
22
+ await performLogout(context.runtime.env, context.runtime.signal);
23
+ result = await readAuthState(context.runtime.env, context.runtime.signal);
24
24
  } else result = await createAuthUseCases(createCliUseCaseGateways(context)).logout();
25
25
  return createAuthSuccess("auth.logout", result, ["prisma-cli auth login"]);
26
26
  }
27
27
  async function runAuthWhoAmI(context) {
28
28
  let result;
29
- if (isRealMode(context)) result = await readAuthState(context.runtime.env);
29
+ if (isRealMode(context)) result = await readAuthState(context.runtime.env, context.runtime.signal);
30
30
  else result = await createAuthUseCases(createCliUseCaseGateways(context)).whoami();
31
31
  return createAuthSuccess("auth.whoami", result, result.authenticated ? [] : ["prisma-cli auth login"]);
32
32
  }
33
33
  async function requireAuthenticatedAuthState(context) {
34
34
  if (isRealMode(context)) {
35
- const current = await readAuthState(context.runtime.env);
35
+ const current = await readAuthState(context.runtime.env, context.runtime.signal);
36
36
  if (current.authenticated) return current;
37
37
  if (!canPrompt(context)) throw authRequiredError();
38
- await performLogin(context.runtime.env);
39
- return readAuthState(context.runtime.env);
38
+ await performLogin(context.runtime.env, context.runtime.signal);
39
+ return readAuthState(context.runtime.env, context.runtime.signal);
40
40
  }
41
41
  const useCases = createAuthUseCases(createCliUseCaseGateways(context));
42
42
  const current = await useCases.whoami();