@prisma/cli 8.0.0-rc.2-dev.49 → 8.0.0-rc.2-dev.51

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 (2) hide show
  1. package/dist/cli.js +217 -49
  2. package/package.json +4 -4
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
3
  import process$1 from "node:process";
4
- import { SERVICE_TOKEN_ENV_VAR, claimedExpiresAt, claimedIdentity, createCli, credentialWorkspaceId, credentialWorkspaceMismatchError, credentialsRequiredError, defineCommand, defineCommandFamily, defineSessionCommand, emptyServiceTokenError, flag, loadConfig, noSessionForWorkspaceError, positional, telemetryCommandGroup } from "@prisma/cli-engine";
4
+ import { SERVICE_TOKEN_ENV_VAR, claimedExpiresAt, claimedIdentity, createCli, credentialWorkspaceId, credentialWorkspaceMismatchError, credentialsRequiredError, defineCommand, defineCommandFamily, defineSessionCommand, emptyServiceTokenError, flag, loadConfig, noSessionForWorkspaceError, positional, readActiveAccessToken, telemetryCommandGroup } from "@prisma/cli-engine";
5
5
  import { createComposerFamily } from "@prisma/composer/family";
6
6
  import { ormCommandFamily } from "@prisma/orm-toolchain/cli";
7
7
  import { CliStructuredError, notOk, ok } from "@prisma/cli-engine/protocol";
@@ -24,6 +24,8 @@ import { promisify } from "node:util";
24
24
  import { ApiError, CancelledError, ComputeClient, normalizeArtifactSymlinks, resolveBuildStrategy, streamLogs } from "@prisma/compute-sdk";
25
25
  import { parse } from "dotenv";
26
26
  import { fileURLToPath } from "node:url";
27
+ import { Writable } from "node:stream";
28
+ import { pipeline } from "node:stream/promises";
27
29
  //#region src/cli-name.ts
28
30
  /**
29
31
  * The CLI's user-facing identity, in one place. The npm package is
@@ -848,9 +850,9 @@ function sameWorkspaceId(left, right) {
848
850
  }
849
851
  //#endregion
850
852
  //#region src/auth/token-storage.ts
851
- const REFRESH_LOCK_RETRY_MS = 100;
852
- const REFRESH_LOCK_STALE_MS = 3e4;
853
- const REFRESH_LOCK_WAIT_TIMEOUT_MS = 25e3;
853
+ const REFRESH_LOCK_RETRY_MS$1 = 100;
854
+ const REFRESH_LOCK_STALE_MS$1 = 3e4;
855
+ const REFRESH_LOCK_WAIT_TIMEOUT_MS$1 = 25e3;
854
856
  const EMPTY_AUTH_CONTEXT = {
855
857
  activeWorkspaceId: null,
856
858
  workspaces: {}
@@ -1097,8 +1099,8 @@ var FileTokenStorage = class {
1097
1099
  async acquireRefreshLock() {
1098
1100
  const lockId = randomUUID();
1099
1101
  const startedAt = Date.now();
1100
- const retryMs = this.options.lockRetryMs ?? REFRESH_LOCK_RETRY_MS;
1101
- const waitTimeoutMs = this.options.lockWaitTimeoutMs ?? REFRESH_LOCK_WAIT_TIMEOUT_MS;
1102
+ const retryMs = this.options.lockRetryMs ?? REFRESH_LOCK_RETRY_MS$1;
1103
+ const waitTimeoutMs = this.options.lockWaitTimeoutMs ?? REFRESH_LOCK_WAIT_TIMEOUT_MS$1;
1102
1104
  this.signal?.throwIfAborted();
1103
1105
  await fs.mkdir(path.dirname(this.lockFilePath), { recursive: true });
1104
1106
  while (true) {
@@ -1152,7 +1154,7 @@ var FileTokenStorage = class {
1152
1154
  const stats = await fs.stat(this.lockFilePath).catch(() => null);
1153
1155
  this.signal?.throwIfAborted();
1154
1156
  if (!stats) return null;
1155
- const staleMs = this.options.lockStaleMs ?? REFRESH_LOCK_STALE_MS;
1157
+ const staleMs = this.options.lockStaleMs ?? REFRESH_LOCK_STALE_MS$1;
1156
1158
  return Date.now() - stats.mtimeMs > staleMs ? lockId : null;
1157
1159
  }
1158
1160
  async releaseRefreshLock(lockId) {
@@ -14315,6 +14317,19 @@ const FILE_MODE = 384;
14315
14317
  const LOCK_STALE_MS = 5e3;
14316
14318
  const LOCK_RETRY_MS = 10;
14317
14319
  const LOCK_WAIT_TIMEOUT_MS = 1e4;
14320
+ const REFRESH_LOCK_STALE_MS = 3e4;
14321
+ const REFRESH_LOCK_RETRY_MS = 100;
14322
+ const REFRESH_LOCK_WAIT_TIMEOUT_MS = 3e4;
14323
+ const STATE_LOCK_TIMINGS = {
14324
+ staleMs: LOCK_STALE_MS,
14325
+ retryMs: LOCK_RETRY_MS,
14326
+ waitTimeoutMs: LOCK_WAIT_TIMEOUT_MS
14327
+ };
14328
+ const REFRESH_LOCK_TIMINGS = {
14329
+ staleMs: REFRESH_LOCK_STALE_MS,
14330
+ retryMs: REFRESH_LOCK_RETRY_MS,
14331
+ waitTimeoutMs: REFRESH_LOCK_WAIT_TIMEOUT_MS
14332
+ };
14318
14333
  const EMPTY_STATE = {
14319
14334
  version: 1,
14320
14335
  sessions: [],
@@ -14417,9 +14432,9 @@ async function writeCredentialState(filePath, state) {
14417
14432
  await fs.chmod(filePath, FILE_MODE).catch(() => {});
14418
14433
  }
14419
14434
  var StateLockTimeoutError = class extends CliStructuredError {
14420
- constructor(lockPath) {
14435
+ constructor(lockPath, waitTimeoutMs) {
14421
14436
  super("CLI.CREDENTIALS_LOCKED", "Another prisma process is still updating your credentials.", {
14422
- why: `The credentials lock at ${lockPath} was held for longer than ${LOCK_WAIT_TIMEOUT_MS}ms.`,
14437
+ why: `The credentials lock at ${lockPath} was held for longer than ${waitTimeoutMs}ms.`,
14423
14438
  nextActions: [{
14424
14439
  kind: "user-choice",
14425
14440
  label: "Wait for the other command to finish, then try again."
@@ -14435,8 +14450,20 @@ var StateLockTimeoutError = class extends CliStructuredError {
14435
14450
  * small fixed staleness threshold.
14436
14451
  */
14437
14452
  async function withStateLock(filePath, debug, run) {
14438
- const lockPath = `${filePath}.lock`;
14439
- const lockId = await acquireStateLock(lockPath, debug);
14453
+ return withFileLock(`${filePath}.lock`, debug, STATE_LOCK_TIMINGS, run);
14454
+ }
14455
+ /**
14456
+ * The cross-process lock the delegated refresh holds for its whole
14457
+ * read → exchange → write sequence, so two processes never spend the
14458
+ * same refresh token. Distinct from the state lock: it IS held across
14459
+ * network I/O, so its staleness and wait budgets are larger, and it
14460
+ * uses its own lock path so short mutations are not queued behind it.
14461
+ */
14462
+ async function withRefreshFileLock(filePath, debug, run) {
14463
+ return withFileLock(`${filePath}.refresh-lock`, debug, REFRESH_LOCK_TIMINGS, run);
14464
+ }
14465
+ async function withFileLock(lockPath, debug, timings, run) {
14466
+ const lockId = await acquireStateLock(lockPath, debug, timings);
14440
14467
  debug(`lock acquired ${lockPath}`);
14441
14468
  try {
14442
14469
  return await run();
@@ -14445,15 +14472,15 @@ async function withStateLock(filePath, debug, run) {
14445
14472
  debug(`lock released ${lockPath}`);
14446
14473
  }
14447
14474
  }
14448
- async function acquireStateLock(lockPath, debug) {
14475
+ async function acquireStateLock(lockPath, debug, timings) {
14449
14476
  const lockId = randomUUID();
14450
14477
  const startedAt = Date.now();
14451
14478
  await fs.mkdir(path.dirname(lockPath), { recursive: true });
14452
14479
  while (true) {
14453
14480
  if (await tryCreateStateLock(lockPath, lockId)) return lockId;
14454
- const tookOver = await takeOverStaleStateLock(lockPath, debug);
14455
- if (Date.now() - startedAt >= LOCK_WAIT_TIMEOUT_MS) throw new StateLockTimeoutError(lockPath);
14456
- if (!tookOver) await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS));
14481
+ const tookOver = await takeOverStaleStateLock(lockPath, debug, timings);
14482
+ if (Date.now() - startedAt >= timings.waitTimeoutMs) throw new StateLockTimeoutError(lockPath, timings.waitTimeoutMs);
14483
+ if (!tookOver) await new Promise((resolve) => setTimeout(resolve, timings.retryMs));
14457
14484
  }
14458
14485
  }
14459
14486
  async function tryCreateStateLock(lockPath, lockId) {
@@ -14479,10 +14506,10 @@ async function tryCreateStateLock(lockPath, lockId) {
14479
14506
  * then run their read-modify-write at once and one update is lost,
14480
14507
  * which is the very thing the lock exists to prevent.
14481
14508
  */
14482
- async function takeOverStaleStateLock(lockPath, debug) {
14509
+ async function takeOverStaleStateLock(lockPath, debug, timings) {
14483
14510
  const stale = await fs.stat(lockPath).catch(() => null);
14484
14511
  if (stale === null) return true;
14485
- if (Date.now() - stale.mtimeMs <= LOCK_STALE_MS) return false;
14512
+ if (Date.now() - stale.mtimeMs <= timings.staleMs) return false;
14486
14513
  const takenPath = `${lockPath}.${randomUUID()}.stale`;
14487
14514
  try {
14488
14515
  await fs.rename(lockPath, takenPath);
@@ -14520,12 +14547,16 @@ function memoryBackedStorage(credential, withRefreshLock) {
14520
14547
  let tokens = {
14521
14548
  workspaceId: credentialWorkspaceId(credential.token) ?? NO_WORKSPACE_CLAIMED,
14522
14549
  accessToken: credential.token,
14523
- refreshToken: credential.refreshToken
14550
+ refreshToken: credential.refreshToken,
14551
+ expiresAt: claimedExpiresAt(credential.token) ?? credential.expiresAt
14524
14552
  };
14525
14553
  return {
14526
14554
  getTokens: async () => tokens,
14527
- setTokens: async (rotated) => {
14528
- tokens = rotated;
14555
+ setTokens: async (rotated, expiresAt) => {
14556
+ tokens = {
14557
+ ...rotated,
14558
+ expiresAt: claimedExpiresAt(rotated.accessToken) ?? expiresAt ?? tokens?.expiresAt
14559
+ };
14529
14560
  },
14530
14561
  clearTokens: async () => {
14531
14562
  tokens = null;
@@ -14544,6 +14575,7 @@ var FileCredentialManager = class {
14544
14575
  #filePath;
14545
14576
  #debug;
14546
14577
  #fetchWorkspaceName;
14578
+ #refreshCredential;
14547
14579
  #pin = { kind: "unresolved" };
14548
14580
  /** Built for one pinned credential. Every mutation that moves the
14549
14581
  * pin discards it, so a command that mutates and then reaches for
@@ -14556,6 +14588,7 @@ var FileCredentialManager = class {
14556
14588
  this.#filePath = resolveStateFilePath(options.env).filePath;
14557
14589
  this.#debug = makeDebugLog(options.env, options.debugWrite);
14558
14590
  this.#fetchWorkspaceName = options.fetchWorkspaceName;
14591
+ this.#refreshCredential = options.refreshCredential;
14559
14592
  this.#debug(`state file ${this.#filePath}`);
14560
14593
  }
14561
14594
  get stateFilePath() {
@@ -14666,14 +14699,13 @@ var FileCredentialManager = class {
14666
14699
  this.#activeStorage ??= this.#buildActiveStorage();
14667
14700
  return this.#activeStorage;
14668
14701
  }
14669
- /** The spawn path's read: the active credential's access token,
14702
+ /** The delegated path's read: the active credential's access token,
14670
14703
  * fresh on every call, never the refresh token. Null when there is
14671
14704
  * no active credential to read — storage exists only once
14672
14705
  * activeCredential() has returned non-null. */
14673
- async activeAccessToken() {
14706
+ async activeAccessToken(options) {
14674
14707
  if (await this.activeCredential() === null) return null;
14675
- const tokens = await (await this.activeCredentialStorage()).getTokens();
14676
- return tokens === null ? null : tokens.accessToken;
14708
+ return readActiveAccessToken(await this.activeCredentialStorage(), this.#refreshCredential, options);
14677
14709
  }
14678
14710
  /** §11.2: which storage is chosen once, when the pin resolves. Each
14679
14711
  * has exactly one source of truth — the file, or process memory. */
@@ -14701,10 +14733,11 @@ var FileCredentialManager = class {
14701
14733
  return {
14702
14734
  workspaceId,
14703
14735
  accessToken: record.token,
14704
- ...record.refreshToken === void 0 ? {} : { refreshToken: record.refreshToken }
14736
+ ...record.refreshToken === void 0 ? {} : { refreshToken: record.refreshToken },
14737
+ ...record.expiresAt === void 0 ? {} : { expiresAt: new Date(record.expiresAt) }
14705
14738
  };
14706
14739
  },
14707
- setTokens: async (tokens) => {
14740
+ setTokens: async (tokens, expiresAt) => {
14708
14741
  this.#debug(`rotation write for session ${workspaceId}`);
14709
14742
  const claimed = credentialWorkspaceId(tokens.accessToken);
14710
14743
  if (claimed !== void 0 && claimed !== workspaceId) throw credentialWorkspaceMismatchError(workspaceId);
@@ -14716,7 +14749,7 @@ var FileCredentialManager = class {
14716
14749
  ...record.name === void 0 ? {} : { name: record.name },
14717
14750
  token: tokens.accessToken,
14718
14751
  ...tokens.refreshToken === void 0 ? {} : { refreshToken: tokens.refreshToken },
14719
- ...expiresAtSlice(tokens.accessToken, void 0)
14752
+ ...expiresAtSlice(tokens.accessToken, expiresAt ?? (record.expiresAt === void 0 ? void 0 : new Date(record.expiresAt)))
14720
14753
  };
14721
14754
  return {
14722
14755
  state: {
@@ -14745,7 +14778,7 @@ var FileCredentialManager = class {
14745
14778
  };
14746
14779
  });
14747
14780
  },
14748
- withRefreshLock: (fn) => this.#withRefreshLock(fn)
14781
+ withRefreshLock: (fn) => this.#withRefreshLock(() => withRefreshFileLock(this.#filePath, this.#debug, fn))
14749
14782
  };
14750
14783
  }
14751
14784
  #withRefreshLock(fn) {
@@ -14881,6 +14914,45 @@ function environmentCredential(token) {
14881
14914
  };
14882
14915
  }
14883
14916
  //#endregion
14917
+ //#region src/auth/refresh.ts
14918
+ const TRAILING_SLASH = /\/$/;
14919
+ const CREDENTIAL_REFRESH_TIMEOUT_MS = 1e4;
14920
+ /** The dumb HTTP adapter behind the engine's delegated-credential policy. */
14921
+ function makeCredentialRefresher(authBaseUrl) {
14922
+ const endpoint = `${authBaseUrl.replace(TRAILING_SLASH, "")}/token`;
14923
+ return async ({ refreshToken, signal }) => {
14924
+ signal.throwIfAborted();
14925
+ const refreshSignal = AbortSignal.any([signal, AbortSignal.timeout(CREDENTIAL_REFRESH_TIMEOUT_MS)]);
14926
+ const response = await fetch(endpoint, {
14927
+ method: "POST",
14928
+ headers: { "content-type": "application/x-www-form-urlencoded" },
14929
+ body: new URLSearchParams({
14930
+ grant_type: "refresh_token",
14931
+ refresh_token: refreshToken,
14932
+ client_id: CLIENT_ID
14933
+ }),
14934
+ signal: refreshSignal
14935
+ });
14936
+ const body = await readBody(response);
14937
+ if (response.status >= 400 && response.status < 500 && body?.error === "invalid_grant") return { kind: "invalid" };
14938
+ if (!response.ok || typeof body?.access_token !== "string" || typeof body.refresh_token !== "string" || typeof body.expires_in !== "number" || !Number.isFinite(body.expires_in) || body.expires_in < 0) throw new Error(`OAuth token refresh failed (status ${String(response.status)})`);
14939
+ return {
14940
+ kind: "success",
14941
+ accessToken: body.access_token,
14942
+ refreshToken: body.refresh_token,
14943
+ expiresAt: new Date(Date.now() + body.expires_in * 1e3)
14944
+ };
14945
+ };
14946
+ }
14947
+ async function readBody(response) {
14948
+ try {
14949
+ const body = await response.json();
14950
+ return typeof body === "object" && body !== null ? body : null;
14951
+ } catch {
14952
+ return null;
14953
+ }
14954
+ }
14955
+ //#endregion
14884
14956
  //#region src/auth/workspace-name.ts
14885
14957
  /** The manager's injected name lookup: a static-token client over the
14886
14958
  * credential just minted. The manager constructs no API client and
@@ -14994,33 +15066,127 @@ const runPackageManager = async ({ file, args, cwd, signal, onOutput }) => {
14994
15066
  };
14995
15067
  //#endregion
14996
15068
  //#region src/spawn.ts
15069
+ /** How long after the child exits the relay keeps reading its pipes. A
15070
+ * grandchild that inherited them can hold EOF back forever; settlement
15071
+ * must not wait on it, so the pipes are destroyed after this grace. */
15072
+ const POST_EXIT_DRAIN_GRACE_MS = 5e3;
14997
15073
  /**
14998
- * The engine's spawn seam, adapted to node:child_process. Inherited
14999
- * stdio, no `detached`, no new console: the child stays in this
15000
- * process's group (POSIX) or console (Windows), so the terminal
15001
- * delivers Ctrl-C to it natively.
15074
+ * The engine's spawn seam, adapted to node:child_process. Human mode
15075
+ * inherits stdio; structured mode pipes both child output streams to
15076
+ * diagnostics. Neither mode detaches or opens a new console, so the child
15077
+ * stays in this process's group (POSIX) or console (Windows).
15078
+ *
15079
+ * The child's own status settles the run: `ended` resolves from the
15080
+ * process `exit` event, waits for the diagnostic relay only up to the
15081
+ * drain grace, and never rejects for a relay failure — rejection is
15082
+ * reserved for a child that could not be launched at all.
15002
15083
  */
15003
- const spawnChild = (request) => {
15004
- const child = spawn(request.command, [...request.args], {
15005
- cwd: request.cwd,
15006
- env: request.env,
15007
- stdio: "inherit"
15008
- });
15009
- return {
15010
- ended: new Promise((resolve, reject) => {
15084
+ function makeSpawnChild(diagnostics, options) {
15085
+ const drainGraceMs = options?.drainGraceMs ?? POST_EXIT_DRAIN_GRACE_MS;
15086
+ return (request) => {
15087
+ const structured = request.output === "diagnostic";
15088
+ const child = spawn(request.command, [...request.args], {
15089
+ cwd: request.cwd,
15090
+ env: request.env,
15091
+ stdio: structured ? [
15092
+ "inherit",
15093
+ "pipe",
15094
+ "pipe"
15095
+ ] : "inherit"
15096
+ });
15097
+ const processEnded = new Promise((resolve, reject) => {
15011
15098
  child.on("error", reject);
15012
- child.on("close", (exitCode, signal) => {
15099
+ child.on("exit", (exitCode, signal) => {
15013
15100
  resolve({
15014
15101
  exitCode,
15015
15102
  signal
15016
15103
  });
15017
15104
  });
15018
- }),
15019
- kill: (signal) => {
15020
- child.kill(signal);
15021
- }
15105
+ });
15106
+ if (!structured) return {
15107
+ ended: processEnded,
15108
+ kill: (signal) => {
15109
+ child.kill(signal);
15110
+ }
15111
+ };
15112
+ const forwarding = forwardStructuredOutput(child.stdout, child.stderr, diagnostics);
15113
+ return {
15114
+ ended: processEnded.then(async (result) => {
15115
+ const drainDeadline = setTimeout(() => {
15116
+ child.stdout?.destroy();
15117
+ child.stderr?.destroy();
15118
+ }, drainGraceMs);
15119
+ await forwarding;
15120
+ clearTimeout(drainDeadline);
15121
+ return result;
15122
+ }),
15123
+ kill: (signal) => {
15124
+ child.kill(signal);
15125
+ }
15126
+ };
15022
15127
  };
15023
- };
15128
+ }
15129
+ /** Best-effort relay: a forwarding failure never rejects, so the child's
15130
+ * real status still settles the run when the diagnostic sink dies. */
15131
+ function forwardStructuredOutput(stdout, stderr, diagnostics) {
15132
+ const sources = [stdout, stderr].filter((source) => source !== null);
15133
+ return Promise.all(sources.map((source) => forwardOutput(source, diagnostics))).then(() => void 0, () => void 0);
15134
+ }
15135
+ /** Decode each child stream continuously and stop reading while the
15136
+ * diagnostic destination applies backpressure. A destination that
15137
+ * errors or closes instead of draining fails the relay rather than
15138
+ * stalling it. */
15139
+ function forwardOutput(source, diagnostics) {
15140
+ let pendingDone;
15141
+ let pendingDrain;
15142
+ let failure;
15143
+ const fail = (cause) => {
15144
+ failure ??= cause;
15145
+ const done = pendingDone;
15146
+ pendingDone = void 0;
15147
+ done?.(cause);
15148
+ };
15149
+ const onSinkError = (cause) => {
15150
+ fail(toError(cause));
15151
+ };
15152
+ const onSinkClose = () => {
15153
+ fail(/* @__PURE__ */ new Error("the diagnostic stream closed during child output"));
15154
+ };
15155
+ diagnostics.once?.("error", onSinkError);
15156
+ diagnostics.once?.("close", onSinkClose);
15157
+ const destination = new Writable({
15158
+ decodeStrings: false,
15159
+ write: (text, _encoding, done) => {
15160
+ if (failure !== void 0) {
15161
+ done(failure);
15162
+ return;
15163
+ }
15164
+ try {
15165
+ if (diagnostics.write(text) === false && diagnostics.once !== void 0) {
15166
+ pendingDone = done;
15167
+ const onDrain = () => {
15168
+ pendingDrain = void 0;
15169
+ if (pendingDone !== done) return;
15170
+ pendingDone = void 0;
15171
+ done();
15172
+ };
15173
+ pendingDrain = onDrain;
15174
+ diagnostics.once("drain", onDrain);
15175
+ } else done();
15176
+ } catch (cause) {
15177
+ done(toError(cause));
15178
+ }
15179
+ }
15180
+ });
15181
+ return pipeline(source.setEncoding("utf8"), destination).finally(() => {
15182
+ diagnostics.off?.("error", onSinkError);
15183
+ diagnostics.off?.("close", onSinkClose);
15184
+ if (pendingDrain !== void 0) diagnostics.off?.("drain", pendingDrain);
15185
+ });
15186
+ }
15187
+ function toError(cause) {
15188
+ return cause instanceof Error ? cause : new Error(String(cause));
15189
+ }
15024
15190
  //#endregion
15025
15191
  //#region src/runtime.ts
15026
15192
  /** Dumb wiring: forwards process signals to the engine's subscribers.
@@ -15092,6 +15258,7 @@ async function assembleRuntime(proc) {
15092
15258
  };
15093
15259
  warnOnDeprecatedStateFileEnvVar(proc);
15094
15260
  const apiBaseUrl = getApiBaseUrl(proc.env);
15261
+ const authBaseUrl = getAuthBaseUrl(proc.env);
15095
15262
  return {
15096
15263
  stdout: { write: (text) => {
15097
15264
  proc.stdout.write(text);
@@ -15118,15 +15285,16 @@ async function assembleRuntime(proc) {
15118
15285
  loadConfig: (configPath) => loadConfig(proc.cwd(), configPath),
15119
15286
  credentialManager: new FileCredentialManager({
15120
15287
  env: proc.env,
15121
- fetchWorkspaceName: fetchWorkspaceName(apiBaseUrl)
15288
+ fetchWorkspaceName: fetchWorkspaceName(apiBaseUrl),
15289
+ refreshCredential: makeCredentialRefresher(authBaseUrl)
15122
15290
  }),
15123
15291
  managementApiClientConfig: {
15124
15292
  clientId: CLIENT_ID,
15125
15293
  redirectUri: DEFAULT_REDIRECT_URI,
15126
15294
  apiBaseUrl,
15127
- authBaseUrl: getAuthBaseUrl(proc.env)
15295
+ authBaseUrl
15128
15296
  },
15129
- spawn: spawnChild,
15297
+ spawn: makeSpawnChild(proc.stderr),
15130
15298
  /** The engine has already decided and composed; the bin only forks
15131
15299
  * the detached sender and hands the payload over. Every failure is
15132
15300
  * swallowed inside runTelemetry. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/cli",
3
- "version": "8.0.0-rc.2-dev.49",
3
+ "version": "8.0.0-rc.2-dev.51",
4
4
  "description": "Command-line interface for the Prisma Developer Platform.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -51,9 +51,9 @@
51
51
  "open": "^11.0.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@repo/cli-conformance": "8.0.0-rc.2-dev.49",
55
- "@repo/cli-telemetry": "8.0.0-rc.2-dev.49",
56
- "@repo/tsconfig": "8.0.0-rc.2-dev.49",
54
+ "@repo/cli-conformance": "8.0.0-rc.2-dev.51",
55
+ "@repo/cli-telemetry": "8.0.0-rc.2-dev.51",
56
+ "@repo/tsconfig": "8.0.0-rc.2-dev.51",
57
57
  "@types/node": "^22.19.19",
58
58
  "tsdown": "^0.21.10",
59
59
  "tsx": "^4.22.4",