@run402/sdk 4.0.3 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -445,6 +445,8 @@ const resumed = await (await r.project(projectId)).apply.resume("op_...");
445
445
 
446
446
  Routed functions use Node 22 Fetch Request -> Response. `req.url` is the full public URL on managed subdomains, deployment hosts, and verified custom domains. The raw `run402.routed_http.v1` envelope is internal; direct `/functions/v1/:name` remains API-key protected.
447
447
 
448
+ Recipe — static home page + SPA shell: a root alias `{ pattern: "/", target: { type: "static", file: "home.html" } }` (with `home.html` shipped at the site root) serves real static bytes at `GET /` (`route_static_alias`) while unmatched app routes such as `/dashboard` keep the `index.html` shell (`spa_fallback`) — route matching runs before all static resolution, including the implicit `/` -> `index.html` root mapping, and SPA-fallback derivation is independent of the route table. Expect non-blocking `STATIC_ALIAS_SHADOWS_STATIC_PATH` (warn) and `STATIC_ALIAS_DUPLICATE_CANONICAL_URL` (info) plan lints; omitted `routes` carries the alias forward, and `routes.replace` is total, so include the alias every time your pipeline sends it.
449
+
448
450
  - URL-first public diagnostics:
449
451
 
450
452
  ```ts
@@ -19,7 +19,7 @@
19
19
  * behavior; this file is the implementation.
20
20
  */
21
21
  import type { Client } from "../kernel.js";
22
- import type { ApplyOptions, ActiveReleaseInventory, DeployEvent, DeployEventsResponse, DeployListOptions, DeployListResponse, DeployOperation, DeployResult, DeployResolveOptions, DeployResolveResponse, OperationSnapshot, PlanResponse, PromoteOptions, PromoteResult, ReleaseDiffOptions, ReleaseInventory, ReleaseInventoryByIdOptions, ReleaseInventoryOptions, ReleaseSpec, ReleaseToReleaseDiff, RehearsePlanOptions, RehearsePlanResult, StartOptions } from "./deploy.types.js";
22
+ import type { ApplyOptions, ActiveReleaseInventory, DeployEvent, DeployEventsResponse, DeployListOptions, DeployListResponse, DeployOperation, DeployResult, DeployResolveOptions, DeployResolveResponse, EdgeCoherenceReport, EdgeCoherenceWaitOptions, EdgeCoherenceWaitResult, OperationSnapshot, PlanResponse, PromoteOptions, PromoteResult, ReleaseDiffOptions, ReleaseInventory, ReleaseInventoryByIdOptions, ReleaseInventoryOptions, ReleaseSpec, ReleaseToReleaseDiff, RehearsePlanOptions, RehearsePlanResult, StartOptions } from "./deploy.types.js";
23
23
  export declare class Deploy {
24
24
  private readonly client;
25
25
  constructor(client: Client);
@@ -149,6 +149,20 @@ export declare class Deploy {
149
149
  events(operationId: string, opts: {
150
150
  project: string;
151
151
  }): Promise<DeployEventsResponse>;
152
+ /**
153
+ * Probe whether the gateway and edge pointers agree on the active release
154
+ * for an operation. The endpoint requires `apikey` auth, so `project` is
155
+ * required. Use `waitEdgeCoherent` when you want bounded polling.
156
+ */
157
+ edgeCoherence(operationId: string, opts: {
158
+ project: string;
159
+ }): Promise<EdgeCoherenceReport>;
160
+ /**
161
+ * Poll `edgeCoherence` until the report is coherent or the timeout elapses.
162
+ * Returns the last report either way so automation can explain stale paths
163
+ * without issuing a second request.
164
+ */
165
+ waitEdgeCoherent(operationId: string, opts: EdgeCoherenceWaitOptions): Promise<EdgeCoherenceWaitResult>;
152
166
  /**
153
167
  * Fetch a release inventory by id. The endpoint requires `apikey` auth, so
154
168
  * pass the owning project id. `siteLimit` controls how many site paths the
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/namespaces/deploy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/namespaces/deploy.ts"],"names":[],"mappings":"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"}
@@ -376,6 +376,57 @@ export class Deploy {
376
376
  throw translateDeployError(err, "events", null, operationId);
377
377
  }
378
378
  }
379
+ /**
380
+ * Probe whether the gateway and edge pointers agree on the active release
381
+ * for an operation. The endpoint requires `apikey` auth, so `project` is
382
+ * required. Use `waitEdgeCoherent` when you want bounded polling.
383
+ */
384
+ async edgeCoherence(operationId, opts) {
385
+ if (!operationId || !operationId.startsWith("op_")) {
386
+ throw new Run402DeployError(`Invalid operation id: "${operationId}"`, {
387
+ code: "OPERATION_NOT_FOUND",
388
+ retryable: false,
389
+ context: "verifying deploy edge coherence",
390
+ });
391
+ }
392
+ if (!opts?.project) {
393
+ throw new LocalError("apply.edgeCoherence requires a project id ({ project: 'prj_...' })", "verifying deploy edge coherence");
394
+ }
395
+ const headers = await apikeyHeaders(this.client, opts.project);
396
+ try {
397
+ return await this.client.request(`/apply/v1/operations/${encodeURIComponent(operationId)}/edge-coherence`, { headers, context: "verifying deploy edge coherence" });
398
+ }
399
+ catch (err) {
400
+ throw translateDeployError(err, "edge-coherence", null, operationId);
401
+ }
402
+ }
403
+ /**
404
+ * Poll `edgeCoherence` until the report is coherent or the timeout elapses.
405
+ * Returns the last report either way so automation can explain stale paths
406
+ * without issuing a second request.
407
+ */
408
+ async waitEdgeCoherent(operationId, opts) {
409
+ const timeoutMs = normalizePositiveSafeIntegerQueryOption(opts?.timeoutMs ?? 60_000, "apply.waitEdgeCoherent timeoutMs", "waiting for deploy edge coherence") ?? 60_000;
410
+ const intervalMs = normalizePositiveSafeIntegerQueryOption(opts?.intervalMs ?? 1_000, "apply.waitEdgeCoherent intervalMs", "waiting for deploy edge coherence") ?? 1_000;
411
+ if (!opts?.project) {
412
+ throw new LocalError("apply.waitEdgeCoherent requires a project id ({ project: 'prj_...' })", "waiting for deploy edge coherence");
413
+ }
414
+ const start = Date.now();
415
+ let attempts = 0;
416
+ while (true) {
417
+ attempts += 1;
418
+ const report = await this.edgeCoherence(operationId, { project: opts.project });
419
+ const elapsedMs = Date.now() - start;
420
+ opts.onPoll?.({ attempts, elapsedMs, report });
421
+ if (report.coherent) {
422
+ return { coherent: true, attempts, elapsedMs, report };
423
+ }
424
+ if (elapsedMs >= timeoutMs) {
425
+ return { coherent: false, attempts, elapsedMs, report };
426
+ }
427
+ await sleep(Math.min(intervalMs, Math.max(timeoutMs - elapsedMs, 0)));
428
+ }
429
+ }
379
430
  /**
380
431
  * Fetch a release inventory by id. The endpoint requires `apikey` auth, so
381
432
  * pass the owning project id. `siteLimit` controls how many site paths the
@@ -1645,6 +1696,7 @@ async function pollUntilReady(client, commit, diff, warnings, emit, projectId, s
1645
1696
  diff,
1646
1697
  warnings,
1647
1698
  ...(commit.subdomain_bindings ? { subdomain_bindings: commit.subdomain_bindings } : {}),
1699
+ ...(commit.edge ? { edge: commit.edge } : {}),
1648
1700
  };
1649
1701
  }
1650
1702
  const opHeaders = projectId ? await apikeyHeaders(client, projectId) : {};
@@ -1744,6 +1796,7 @@ async function pollSnapshotUntilReady(client, initial, diff, warnings, emit, pro
1744
1796
  diff,
1745
1797
  warnings,
1746
1798
  ...(snapshot.subdomain_bindings ? { subdomain_bindings: snapshot.subdomain_bindings } : {}),
1799
+ ...(snapshot.edge ? { edge: snapshot.edge } : {}),
1747
1800
  };
1748
1801
  }
1749
1802
  if (TERMINAL_STATUSES.includes(snapshot.status)) {