veryfront 0.1.1066 → 0.1.1068

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.
@@ -82,10 +82,20 @@ interface Release {
82
82
  build_status: string;
83
83
  deploy_status: string;
84
84
  }
85
- interface Deployment {
85
+ export type DeploymentRoutingConvergence = {
86
+ status: "converged";
87
+ acknowledged: number;
88
+ recipients: number;
89
+ } | {
90
+ status: "pending";
91
+ } | {
92
+ status: "skipped";
93
+ };
94
+ export interface Deployment {
86
95
  id: string;
87
96
  release_id: string;
88
97
  environment_id: string;
98
+ routing_convergence?: DeploymentRoutingConvergence;
89
99
  }
90
100
  export interface DeploymentVerification {
91
101
  projectId: string;
@@ -128,6 +138,7 @@ interface DeploymentVerificationOptions {
128
138
  delayMs?: number;
129
139
  verifiedRelease?: ReleaseSourceVerification;
130
140
  }
141
+ export declare function getDeploymentRoutingConvergenceWarning(deployment: Deployment): string | null;
131
142
  export declare function assertProjectOwnership(resourceType: "Environment" | "Release", resource: {
132
143
  id: string;
133
144
  project_id?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/deploy/command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/deploy/command.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ import { defineSchema, lazySchema } from "../../../src/schemas/index.js";
10
10
  import { cwd } from "../../../src/platform/index.js";
11
11
  import { createApiClient, resolveConfigWithAuth } from "../../shared/config.js";
12
12
  import { CommonArgs, createArgParser } from "../../shared/args.js";
13
- import { confirmPrompt, logInfo, logSuccess } from "../../utils/index.js";
13
+ import { confirmPrompt, logInfo, logSuccess, logWarning } from "../../utils/index.js";
14
14
  import { createNoopSpinner, createSpinner, muted } from "../../ui/index.js";
15
15
  import { isJsonMode, streamJsonLine } from "../../shared/json-output.js";
16
16
  import { computeSourceDigest, getProjectTarget, normalizeControlPlane, readPushReceipt, resolveGitSource, validatePushReceipt, } from "../../shared/deployment-provenance.js";
@@ -60,8 +60,20 @@ function normalizeDeployment(deployment) {
60
60
  id: deployment.id,
61
61
  release_id: releaseId,
62
62
  environment_id: environmentId,
63
+ routing_convergence: deployment.routing_convergence,
63
64
  };
64
65
  }
66
+ export function getDeploymentRoutingConvergenceWarning(deployment) {
67
+ const convergence = deployment.routing_convergence;
68
+ if (!convergence)
69
+ return null;
70
+ if (convergence.status === "converged" &&
71
+ convergence.recipients > 0 &&
72
+ convergence.acknowledged >= convergence.recipients) {
73
+ return null;
74
+ }
75
+ return `Deployment ${deployment.id} committed, but data-plane routing convergence was not confirmed; bounded cache expiry remains the recovery path`;
76
+ }
65
77
  export function assertProjectOwnership(resourceType, resource, projectId) {
66
78
  if (resource.project_id && resource.project_id !== projectId) {
67
79
  throw new Error(`${resourceType} ${resource.id} does not belong to resolved project ${projectId}`);
@@ -348,6 +360,12 @@ export async function deployCommand(options) {
348
360
  logInfo(` Environment: ${env} (${verification.environmentId})`);
349
361
  logInfo(` Release: ${release.name} (${verification.releaseVersion}, ${verification.releaseId})`);
350
362
  logInfo(` Deployment: ${verification.deploymentId}`);
363
+ if (deployment.routing_convergence?.status === "converged") {
364
+ logInfo(` Data plane: ${deployment.routing_convergence.acknowledged}/${deployment.routing_convergence.recipients} proxy replicas converged`);
365
+ }
366
+ const routingConvergenceWarning = getDeploymentRoutingConvergenceWarning(deployment);
367
+ if (routingConvergenceWarning)
368
+ logWarning(routingConvergenceWarning);
351
369
  logInfo(` Commit: ${verification.commitSha}`);
352
370
  logInfo(` Source digest: ${verification.sourceDigest}`);
353
371
  logInfo(` Control plane: ${normalizeControlPlane(config.apiUrl)}`);
@@ -448,6 +466,14 @@ async function deployCommandJson(options) {
448
466
  sourceDigest: source.sourceDigest,
449
467
  }, { verifiedRelease });
450
468
  streamJsonLine({ type: "step", name: "verify-deployment", status: "completed" });
469
+ const routingConvergenceWarning = getDeploymentRoutingConvergenceWarning(deployment);
470
+ if (routingConvergenceWarning) {
471
+ streamJsonLine({
472
+ type: "warning",
473
+ code: "routing-convergence-unconfirmed",
474
+ message: routingConvergenceWarning,
475
+ });
476
+ }
451
477
  streamJsonLine({
452
478
  type: "result",
453
479
  success: true,
@@ -462,6 +488,7 @@ async function deployCommandJson(options) {
462
488
  environment: env,
463
489
  environmentId: verification.environmentId,
464
490
  deploymentId: verification.deploymentId,
491
+ routingConvergence: deployment.routing_convergence ?? null,
465
492
  commitSha: verification.commitSha,
466
493
  sourceDigest: verification.sourceDigest,
467
494
  controlPlane: normalizeControlPlane(config.apiUrl),
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Deploy command - Create and deploy releases
3
3
  */
4
- export { assertProjectOwnership, createDeployment, createRelease, DeployArgsSchema, deployCommand, getDeployment, getEnvironmentByName, getProject, getRelease, getReleaseSourceDigest, parseDeployArgs, resolvePushedSource, verifyDeployment, verifyReleaseSource, } from "./command.js";
5
- export type { DeploymentVerification, DeployOptions, ReleaseSourceVerification, } from "./command.js";
4
+ export { assertProjectOwnership, createDeployment, createRelease, DeployArgsSchema, deployCommand, getDeployment, getDeploymentRoutingConvergenceWarning, getEnvironmentByName, getProject, getRelease, getReleaseSourceDigest, parseDeployArgs, resolvePushedSource, verifyDeployment, verifyReleaseSource, } from "./command.js";
5
+ export type { Deployment, DeploymentRoutingConvergence, DeploymentVerification, DeployOptions, ReleaseSourceVerification, } from "./command.js";
6
6
  export { handleDeployCommand } from "./handler.js";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/deploy/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/deploy/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,sCAAsC,EACtC,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,UAAU,EACV,4BAA4B,EAC5B,sBAAsB,EACtB,aAAa,EACb,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Deploy command - Create and deploy releases
3
3
  */
4
- export { assertProjectOwnership, createDeployment, createRelease, DeployArgsSchema, deployCommand, getDeployment, getEnvironmentByName, getProject, getRelease, getReleaseSourceDigest, parseDeployArgs, resolvePushedSource, verifyDeployment, verifyReleaseSource, } from "./command.js";
4
+ export { assertProjectOwnership, createDeployment, createRelease, DeployArgsSchema, deployCommand, getDeployment, getDeploymentRoutingConvergenceWarning, getEnvironmentByName, getProject, getRelease, getReleaseSourceDigest, parseDeployArgs, resolvePushedSource, verifyDeployment, verifyReleaseSource, } from "./command.js";
5
5
  export { handleDeployCommand } from "./handler.js";
@@ -98,6 +98,7 @@ export interface PullOptions {
98
98
  export declare function resolvePullSource(options: PullOptions): PullSource;
99
99
  interface ProjectFile {
100
100
  path: string;
101
+ content: string;
101
102
  size: number;
102
103
  type: string;
103
104
  created_at: string;
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pull/command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAM3E,OAAO,EACL,eAAe,EAIhB,MAAM,wBAAwB,CAAC;AAiBhC;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;GAa7B,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;GAAgC,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;GAWxB,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAKlE;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAkCD,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmB/D;AA+CD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAWjF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAoBxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAmBjG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,CAAC,CAKjB;AAkdD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoKpE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pull/command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAM3E,OAAO,EACL,eAAe,EAIhB,MAAM,wBAAwB,CAAC;AAiBhC;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;GAa7B,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;GAAgC,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;GAWxB,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAKlE;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAsCD,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmB/D;AAkDD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAWjF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAoBxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAmBjG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,CAAC,CAKjB;AA8aD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoKpE"}
@@ -181,18 +181,9 @@ export async function getFileContent(client, projectSlug, path, source) {
181
181
  const response = await client.get(url);
182
182
  return response.content;
183
183
  }
184
- /** Concurrency limit for parallel file fetches */
184
+ /** Concurrency limit for parallel file writes. */
185
185
  const CONCURRENCY = 20;
186
- async function fetchFile(op, client, projectSlug, source) {
187
- try {
188
- const content = await getFileContent(client, projectSlug, op.relativePath, source);
189
- return { success: true, op: { ...op, content } };
190
- }
191
- catch (error) {
192
- return { success: false, path: op.relativePath, error: error };
193
- }
194
- }
195
- async function writePreparedFile(op, fs) {
186
+ async function writeFile(op, fs) {
196
187
  try {
197
188
  await fs.mkdir(dirname(op.path), { recursive: true });
198
189
  await fs.writeTextFile(op.path, op.content);
@@ -202,33 +193,18 @@ async function writePreparedFile(op, fs) {
202
193
  return { success: false, path: op.relativePath, error: error };
203
194
  }
204
195
  }
205
- async function writeFiles(ops, client, projectSlug, source, dryRun) {
196
+ async function writeFiles(ops, dryRun) {
206
197
  if (dryRun) {
207
198
  for (const op of ops)
208
199
  cliLogger.info(` Would write: ${op.relativePath}`);
209
200
  return { written: ops.length, failed: 0 };
210
201
  }
211
202
  const fs = createFileSystem();
212
- const prepared = [];
213
203
  let failed = 0;
204
+ let written = 0;
214
205
  for (let i = 0; i < ops.length; i += CONCURRENCY) {
215
206
  const batch = ops.slice(i, i + CONCURRENCY);
216
- const results = await Promise.all(batch.map((op) => fetchFile(op, client, projectSlug, source)));
217
- for (const result of results) {
218
- if (result.success) {
219
- prepared.push(result.op);
220
- continue;
221
- }
222
- cliLogger.error(`Failed to fetch ${result.path}:`, result.error);
223
- failed++;
224
- }
225
- }
226
- if (failed > 0)
227
- return { written: 0, failed };
228
- let written = 0;
229
- for (let i = 0; i < prepared.length; i += CONCURRENCY) {
230
- const batch = prepared.slice(i, i + CONCURRENCY);
231
- const results = await Promise.all(batch.map((op) => writePreparedFile(op, fs)));
207
+ const results = await Promise.all(batch.map((op) => writeFile(op, fs)));
232
208
  for (const result of results) {
233
209
  if (result.success) {
234
210
  written++;
@@ -452,18 +428,13 @@ async function pullSingleProject(projectSlug, projectDir, source, force, dryRun,
452
428
  const writeOps = [];
453
429
  const remotePaths = new Set();
454
430
  for (const file of files) {
431
+ let op;
455
432
  try {
456
- const op = await validateFilePath(file.path, projectDir);
433
+ op = await validateFilePath(file.path, projectDir);
457
434
  if (remotePaths.has(op.relativePath)) {
458
435
  throw new Error(`Duplicate remote file path: "${op.relativePath}"`);
459
436
  }
460
437
  remotePaths.add(op.relativePath);
461
- if (pruneIgnoreChecker &&
462
- (pruneIgnoreChecker.isIgnored(op.relativePath) ||
463
- !pruneIgnoreChecker.isSupportedExtension(op.relativePath))) {
464
- continue;
465
- }
466
- writeOps.push(op);
467
438
  }
468
439
  catch (error) {
469
440
  throw INVALID_ARGUMENT.create({
@@ -471,6 +442,17 @@ async function pullSingleProject(projectSlug, projectDir, source, force, dryRun,
471
442
  cause: error,
472
443
  });
473
444
  }
445
+ if (pruneIgnoreChecker &&
446
+ (pruneIgnoreChecker.isIgnored(op.relativePath) ||
447
+ !pruneIgnoreChecker.isSupportedExtension(op.relativePath))) {
448
+ continue;
449
+ }
450
+ if (typeof file.content !== "string") {
451
+ throw INVALID_ARGUMENT.create({
452
+ detail: `Veryfront returned invalid content for file "${file.path}". No local files were changed.`,
453
+ });
454
+ }
455
+ writeOps.push({ ...op, content: file.content });
474
456
  }
475
457
  let deleteOps = [];
476
458
  if (pruneIgnoreChecker) {
@@ -495,7 +477,7 @@ async function pullSingleProject(projectSlug, projectDir, source, force, dryRun,
495
477
  }
496
478
  }
497
479
  spinner = quiet ? createNoopSpinner() : createSpinner(`Writing files to ${projectDir}...`);
498
- const writeResult = await writeFiles(writeOps, client, projectSlug, source, dryRun);
480
+ const writeResult = await writeFiles(writeOps, dryRun);
499
481
  if (writeResult.failed > 0) {
500
482
  spinner.stop();
501
483
  throw new Error(`Failed to pull ${writeResult.failed} file${writeResult.failed === 1 ? "" : "s"}. No local files were pruned. Review git status and restore a clean worktree before retrying if any files were written.`);
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.1066",
3
+ "version": "0.1.1068",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -5,7 +5,7 @@
5
5
  * (Deno, Node.js) and handles veryfront package resolution.
6
6
  */
7
7
  import { createFileSystem } from "../platform/compat/fs.js";
8
- export declare const DISCOVERY_GLOBAL_VERYFRONT_MODULES: readonly ["veryfront/agent", "veryfront/tool", "veryfront/platform", "veryfront/prompt", "veryfront/resource", "veryfront/embedding", "veryfront/knowledge", "veryfront/workflow", "veryfront/eval", "veryfront/metrics", "veryfront/schemas", "veryfront/chat/uploads"];
8
+ export declare const DISCOVERY_GLOBAL_VERYFRONT_MODULES: readonly ["veryfront/agent", "veryfront/tool", "veryfront/platform", "veryfront/prompt", "veryfront/resource", "veryfront/embedding", "veryfront/knowledge", "veryfront/workflow", "veryfront/eval", "veryfront/metrics", "veryfront/schemas", "veryfront/integrations", "veryfront/chat/uploads"];
9
9
  interface DenoRewriteOptions {
10
10
  compiled?: boolean;
11
11
  resolveSpecifier?: (specifier: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"import-rewriter.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/import-rewriter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAI5D,eAAO,MAAM,kCAAkC,0QAcrC,CAAC;AAEX,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;CAClD;AAkHD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CA2BR;AAqFD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EACvC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CA2PjB"}
1
+ {"version":3,"file":"import-rewriter.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/import-rewriter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAI5D,eAAO,MAAM,kCAAkC,oSAerC,CAAC;AAEX,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;CAClD;AAkHD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CA2BR;AAqFD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EACvC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CA2PjB"}
@@ -19,6 +19,7 @@ export const DISCOVERY_GLOBAL_VERYFRONT_MODULES = [
19
19
  "veryfront/eval",
20
20
  "veryfront/metrics",
21
21
  "veryfront/schemas",
22
+ "veryfront/integrations",
22
23
  // Server-side chat upload route handler (app/api/uploads/route.ts).
23
24
  "veryfront/chat/uploads",
24
25
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"transpiler.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/transpiler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA0MvD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAgIlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
1
+ {"version":3,"file":"transpiler.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/transpiler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA4MvD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAgIlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -25,6 +25,7 @@ import * as workflowMod from "../workflow/index.js";
25
25
  import * as evalMod from "../eval/index.js";
26
26
  import * as metricsMod from "../metrics/index.js";
27
27
  import * as schemasMod from "../schemas/index.js";
28
+ import * as integrationsMod from "../integrations/index.js";
28
29
  import * as chatUploadsMod from "../chat/upload-handler.js";
29
30
  // Keyed by entry file + entry source hash; each entry additionally records the
30
31
  // bundled dependency contents it was built from and is only served while those
@@ -90,6 +91,7 @@ async function ensureVeryfrontGlobals() {
90
91
  "veryfront/eval": evalMod,
91
92
  "veryfront/metrics": metricsMod,
92
93
  "veryfront/schemas": schemasMod,
94
+ "veryfront/integrations": integrationsMod,
93
95
  "veryfront/chat/uploads": chatUploadsMod,
94
96
  };
95
97
  dntShim.dntGlobalThis.__VERYFRONT_MODULES__ = modules;
@@ -48,6 +48,20 @@ export interface ProxyRequestOptions {
48
48
  url?: URL;
49
49
  timing?: ProxyServerTiming;
50
50
  }
51
+ export interface ProxyRoutingInvalidation {
52
+ projectId: string;
53
+ projectSlug?: string;
54
+ deploymentId?: string;
55
+ environmentId?: string;
56
+ environmentName?: string;
57
+ releaseId?: string;
58
+ }
59
+ export interface ConfirmedProxyRoutingInvalidation extends ProxyRoutingInvalidation {
60
+ projectSlug: string;
61
+ environmentId: string;
62
+ environmentName: string;
63
+ releaseId: string;
64
+ }
51
65
  export declare function createProxyHandler(options: ProxyHandlerOptions): {
52
66
  processRequest: (req: Request, options?: ProxyRequestOptions) => Promise<ProxyContext>;
53
67
  getTokenForApi: (req: Request, options?: ProxyRequestOptions) => Promise<string | undefined>;
@@ -59,6 +73,11 @@ export declare function createProxyHandler(options: ProxyHandlerOptions): {
59
73
  }>;
60
74
  close: () => Promise<void>;
61
75
  validateConfig: () => string[];
76
+ invalidateRoutingLookup: (input: ProxyRoutingInvalidation) => {
77
+ evictedEntries: number;
78
+ generation: number;
79
+ };
80
+ invalidateAndConfirmRoutingLookup: (input: ConfirmedProxyRoutingInvalidation) => Promise<void>;
62
81
  localProjects: Record<string, string>;
63
82
  };
64
83
  export type ProxyHandler = ReturnType<typeof createProxyHandler>;
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/src/proxy/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/src/proxy/handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,kCAAkC,CAAC;AACzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAenD,OAAO,EAAiC,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG3F,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAE9E,eAAO,MAAM,sBAAsB,0MAYzB,CAAC;AAoSX,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,SAAS,GAAG,YAAY,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAMD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC9D,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC7D,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC7D,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC9E;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iCAAkC,SAAQ,wBAAwB;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAsBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB;0BA4atD,OAAO,YACH,mBAAmB,KAC3B,OAAO,CAAC,YAAY,CAAC;0BAwYjB,OAAO,YACH,mBAAmB,KAC3B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;;;;;;;;0BAtgBH,MAAM,EAAE;qCA7KK,wBAAwB,KAAG;QACjE,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;KACpB;+CAkIQ,iCAAiC,KACvC,OAAO,CAAC,IAAI,CAAC;;EAqlBjB;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEjE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CA+B7E"}
@@ -26,6 +26,7 @@ export const INTERNAL_PROXY_HEADERS = [
26
26
  ];
27
27
  const DEFAULT_PROXY_ROUTING_CACHE_TTL_MS = 60_000;
28
28
  const DEFAULT_PROXY_ROUTING_CACHE_MAX_ENTRIES = 1_000;
29
+ const MAX_ROUTING_LOOKUP_INVALIDATION_RETRIES = 2;
29
30
  function readNonNegativeIntegerEnv(name, fallback) {
30
31
  const raw = getEnv(name);
31
32
  if (!raw)
@@ -46,6 +47,12 @@ class ProxyLookupAuthError extends Error {
46
47
  this.name = "ProxyLookupAuthError";
47
48
  }
48
49
  }
50
+ class ProxyRoutingInvalidationRaceError extends Error {
51
+ constructor() {
52
+ super("Project routing changed during request; retry");
53
+ this.name = "ProxyRoutingInvalidationRaceError";
54
+ }
55
+ }
49
56
  function isProxyLookupAuthError(error) {
50
57
  return error instanceof ProxyLookupAuthError;
51
58
  }
@@ -225,6 +232,11 @@ export function createProxyHandler(options) {
225
232
  const routingCacheMaxEntries = readNonNegativeIntegerEnv("VERYFRONT_PROXY_ROUTING_CACHE_MAX_ENTRIES", DEFAULT_PROXY_ROUTING_CACHE_MAX_ENTRIES);
226
233
  const routingLookupCache = new Map();
227
234
  const routingLookupInflight = new Map();
235
+ const projectInvalidationGenerations = new Map();
236
+ const lookupKeyInvalidationGenerations = new Map();
237
+ const activeRoutingLookupGenerations = new Map();
238
+ const maxTrackedInvalidationGenerations = Math.max(routingCacheMaxEntries, DEFAULT_PROXY_ROUTING_CACHE_MAX_ENTRIES);
239
+ let routingLookupGeneration = 0;
228
240
  async function resolveProjectLookup(lookupKey, token, timing) {
229
241
  return await profileProxyServerTimingPhase(timing ?? { enabled: false, startedAt: 0, phases: new Map() }, "proxy.project_lookup", () => lookupProjectByDomain(lookupKey, config.apiBaseUrl, token, logger));
230
242
  }
@@ -261,6 +273,71 @@ export function createProxyHandler(options) {
261
273
  expiresAt: Date.now() + routingCacheTtlMs,
262
274
  });
263
275
  }
276
+ function pruneInvalidationGenerations(generations) {
277
+ const oldestActiveGeneration = activeRoutingLookupGenerations.size > 0
278
+ ? Math.min(...activeRoutingLookupGenerations.keys())
279
+ : Number.POSITIVE_INFINITY;
280
+ while (generations.size > maxTrackedInvalidationGenerations) {
281
+ const oldestEntry = generations.entries().next().value;
282
+ if (!oldestEntry || oldestEntry[1] > oldestActiveGeneration)
283
+ break;
284
+ generations.delete(oldestEntry[0]);
285
+ }
286
+ }
287
+ function rememberInvalidationGeneration(generations, key, generation) {
288
+ generations.delete(key);
289
+ generations.set(key, generation);
290
+ pruneInvalidationGenerations(generations);
291
+ }
292
+ function beginRoutingLookup(generation) {
293
+ activeRoutingLookupGenerations.set(generation, (activeRoutingLookupGenerations.get(generation) ?? 0) + 1);
294
+ }
295
+ function endRoutingLookup(generation) {
296
+ const activeCount = activeRoutingLookupGenerations.get(generation) ?? 0;
297
+ if (activeCount <= 1)
298
+ activeRoutingLookupGenerations.delete(generation);
299
+ else
300
+ activeRoutingLookupGenerations.set(generation, activeCount - 1);
301
+ pruneInvalidationGenerations(projectInvalidationGenerations);
302
+ pruneInvalidationGenerations(lookupKeyInvalidationGenerations);
303
+ }
304
+ function wasRoutingLookupInvalidated(cacheKey, result, startedAtGeneration) {
305
+ const keyGeneration = lookupKeyInvalidationGenerations.get(cacheKey) ?? 0;
306
+ if (keyGeneration > startedAtGeneration)
307
+ return true;
308
+ if (!result)
309
+ return false;
310
+ return (projectInvalidationGenerations.get(result.id) ?? 0) > startedAtGeneration;
311
+ }
312
+ function invalidateRoutingLookup(input) {
313
+ const generation = ++routingLookupGeneration;
314
+ rememberInvalidationGeneration(projectInvalidationGenerations, input.projectId, generation);
315
+ const normalizedProjectSlug = input.projectSlug
316
+ ? normalizeProjectLookupKey(input.projectSlug)
317
+ : undefined;
318
+ if (normalizedProjectSlug) {
319
+ rememberInvalidationGeneration(lookupKeyInvalidationGenerations, normalizedProjectSlug, generation);
320
+ }
321
+ let evictedEntries = 0;
322
+ for (const [cacheKey, entry] of routingLookupCache) {
323
+ if (entry.value.id !== input.projectId && cacheKey !== normalizedProjectSlug)
324
+ continue;
325
+ routingLookupCache.delete(cacheKey);
326
+ rememberInvalidationGeneration(lookupKeyInvalidationGenerations, cacheKey, generation);
327
+ evictedEntries++;
328
+ }
329
+ logger?.info("Proxy routing metadata invalidated after deployment activation", {
330
+ projectId: input.projectId,
331
+ projectSlug: input.projectSlug,
332
+ deploymentId: input.deploymentId,
333
+ environmentId: input.environmentId,
334
+ environmentName: input.environmentName,
335
+ releaseId: input.releaseId,
336
+ generation,
337
+ evictedEntries,
338
+ });
339
+ return { evictedEntries, generation };
340
+ }
264
341
  async function resolveProjectRoutingLookup(lookupKey, token, timing) {
265
342
  const cacheKey = normalizeProjectLookupKey(lookupKey);
266
343
  return await profileProxyServerTimingPhase(timing ?? { enabled: false, startedAt: 0, phases: new Map() }, "proxy.routing_lookup", async () => {
@@ -270,27 +347,89 @@ export function createProxyHandler(options) {
270
347
  return cached;
271
348
  }
272
349
  const existingLookup = routingLookupInflight.get(cacheKey);
273
- if (existingLookup) {
350
+ if (existingLookup?.generation === routingLookupGeneration) {
274
351
  logger?.debug("Proxy routing metadata lookup joined in-flight request", { lookupKey });
275
- return await existingLookup;
352
+ return await existingLookup.promise;
276
353
  }
277
- const lookupPromise = lookupProjectRoutingMetadata(lookupKey, config.apiBaseUrl, token, logger)
278
- .then((result) => {
279
- if (result) {
280
- setCachedRoutingLookup(cacheKey, result);
354
+ const lookupPromise = (async () => {
355
+ for (let attempt = 0; attempt <= MAX_ROUTING_LOOKUP_INVALIDATION_RETRIES; attempt++) {
356
+ const startedAtGeneration = routingLookupGeneration;
357
+ beginRoutingLookup(startedAtGeneration);
358
+ try {
359
+ const result = await lookupProjectRoutingMetadata(lookupKey, config.apiBaseUrl, token, logger);
360
+ if (!wasRoutingLookupInvalidated(cacheKey, result, startedAtGeneration)) {
361
+ if (result)
362
+ setCachedRoutingLookup(cacheKey, result);
363
+ return result;
364
+ }
365
+ logger?.info("Retrying proxy routing metadata lookup after invalidation race", {
366
+ lookupKey,
367
+ attempt: attempt + 1,
368
+ generation: routingLookupGeneration,
369
+ });
370
+ if (attempt === MAX_ROUTING_LOOKUP_INVALIDATION_RETRIES) {
371
+ logger?.warn("Proxy routing metadata changed repeatedly during lookup; failing request closed", {
372
+ lookupKey,
373
+ attempts: attempt + 1,
374
+ });
375
+ throw new ProxyRoutingInvalidationRaceError();
376
+ }
377
+ }
378
+ finally {
379
+ endRoutingLookup(startedAtGeneration);
380
+ }
281
381
  }
282
- return result;
283
- })
284
- .finally(() => {
285
- routingLookupInflight.delete(cacheKey);
286
- });
287
- routingLookupInflight.set(cacheKey, lookupPromise);
288
- return await lookupPromise;
382
+ return null;
383
+ })();
384
+ const inflightEntry = {
385
+ generation: routingLookupGeneration,
386
+ promise: lookupPromise,
387
+ };
388
+ routingLookupInflight.set(cacheKey, inflightEntry);
389
+ try {
390
+ return await lookupPromise;
391
+ }
392
+ finally {
393
+ if (routingLookupInflight.get(cacheKey) === inflightEntry) {
394
+ routingLookupInflight.delete(cacheKey);
395
+ }
396
+ }
289
397
  });
290
398
  }
291
399
  async function resolveProjectAccessLookup(lookupKey, token, includeUsers, timing) {
292
400
  return await profileProxyServerTimingPhase(timing ?? { enabled: false, startedAt: 0, phases: new Map() }, "proxy.access_lookup", () => lookupProjectAccessMetadata(lookupKey, config.apiBaseUrl, token, includeUsers, logger));
293
401
  }
402
+ async function invalidateAndConfirmRoutingLookup(input) {
403
+ invalidateRoutingLookup(input);
404
+ const scope = getScope(input.environmentName.toLowerCase());
405
+ const resolveWithToken = async (token) => {
406
+ const result = await resolveProjectRoutingLookup(input.projectSlug, token);
407
+ const environment = result?.environments?.find((candidate) => candidate.id === input.environmentId);
408
+ if (result?.id !== input.projectId ||
409
+ environment?.active_release_id !== input.releaseId) {
410
+ throw new Error(`Proxy routing metadata did not converge for project ${input.projectId} environment ${input.environmentId}`);
411
+ }
412
+ };
413
+ let token = await tokenManager.getToken(scope, input.projectSlug);
414
+ try {
415
+ await resolveWithToken(token);
416
+ }
417
+ catch (error) {
418
+ if (!isProxyLookupAuthError(error))
419
+ throw error;
420
+ await tokenManager.invalidateToken(scope, input.projectSlug);
421
+ token = await tokenManager.getToken(scope, input.projectSlug);
422
+ await resolveWithToken(token);
423
+ }
424
+ logger?.info("Proxy routing metadata converged after deployment activation", {
425
+ projectId: input.projectId,
426
+ projectSlug: input.projectSlug,
427
+ deploymentId: input.deploymentId,
428
+ environmentId: input.environmentId,
429
+ environmentName: input.environmentName,
430
+ releaseId: input.releaseId,
431
+ });
432
+ }
294
433
  function validateConfig() {
295
434
  const missing = [];
296
435
  if (!config.apiClientId)
@@ -410,6 +549,9 @@ export function createProxyHandler(options) {
410
549
  return await resolveWithCurrentToken();
411
550
  }
412
551
  catch (error) {
552
+ if (error instanceof ProxyRoutingInvalidationRaceError) {
553
+ return { error: { status: 503, message: error.message } };
554
+ }
413
555
  if (!isProxyLookupAuthError(error))
414
556
  throw error;
415
557
  const projectKey = tokenIdentity.projectSlug ?? tokenIdentity.customDomain;
@@ -444,6 +586,9 @@ export function createProxyHandler(options) {
444
586
  return await resolveWithCurrentToken();
445
587
  }
446
588
  catch (retryError) {
589
+ if (retryError instanceof ProxyRoutingInvalidationRaceError) {
590
+ return { error: { status: 503, message: retryError.message } };
591
+ }
447
592
  if (!isProxyLookupAuthError(retryError))
448
593
  throw retryError;
449
594
  logger?.error("Proxy API token rejected after refresh", retryError, {
@@ -689,6 +834,8 @@ export function createProxyHandler(options) {
689
834
  getStats,
690
835
  close,
691
836
  validateConfig,
837
+ invalidateRoutingLookup,
838
+ invalidateAndConfirmRoutingLookup,
692
839
  localProjects,
693
840
  };
694
841
  }