@workflow/world-vercel 5.0.0-beta.2 → 5.0.0-beta.3
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/dist/encryption.d.ts.map +1 -1
- package/dist/encryption.js +3 -1
- package/dist/encryption.js.map +1 -1
- package/dist/resolve-latest-deployment.d.ts +1 -1
- package/dist/resolve-latest-deployment.d.ts.map +1 -1
- package/dist/resolve-latest-deployment.js +3 -1
- package/dist/resolve-latest-deployment.js.map +1 -1
- package/dist/runs.d.ts +1 -1
- package/dist/steps.d.ts +1 -1
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +36 -8
- package/dist/utils.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +3 -3
package/dist/encryption.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAO1D;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,aAAa,EAAE,UAAU,EACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CAmCrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,WAAW,CAC/B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IACR,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAwDjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACb,KAAK,CAAC,wBAAwB,CAAC,CA8CjC"}
|
package/dist/encryption.js
CHANGED
|
@@ -13,6 +13,7 @@ import { webcrypto } from 'node:crypto';
|
|
|
13
13
|
import { getVercelOidcToken } from '@vercel/oidc';
|
|
14
14
|
import * as z from 'zod';
|
|
15
15
|
import { getDispatcher } from './http-client.js';
|
|
16
|
+
import { getProtectionBypassHeader } from './utils.js';
|
|
16
17
|
const KEY_BYTES = 32; // 256 bits = 32 bytes (AES-256)
|
|
17
18
|
/**
|
|
18
19
|
* Derive a per-run AES-256 encryption key using HKDF-SHA256.
|
|
@@ -83,7 +84,8 @@ export async function fetchRunKey(deploymentId, projectId, runId, options) {
|
|
|
83
84
|
const response = await fetch(`https://api.vercel.com/v1/workflow/run-key/${deploymentId}?${params}`, {
|
|
84
85
|
method: 'GET',
|
|
85
86
|
headers: {
|
|
86
|
-
|
|
87
|
+
Authorization: `Bearer ${token}`,
|
|
88
|
+
...getProtectionBypassHeader(),
|
|
87
89
|
},
|
|
88
90
|
// @ts-expect-error -- undici dispatcher is accepted by Node.js fetch but not in @types/node's RequestInit
|
|
89
91
|
dispatcher: getDispatcher(),
|
package/dist/encryption.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Vercel-specific key management for workflow encryption.\n *\n * This module handles:\n * - HKDF key derivation (deployment key + projectId + runId → per-run key)\n * - Cross-deployment key retrieval via the Vercel API\n *\n * The actual AES-GCM encrypt/decrypt operations are in @workflow/core/encryption\n * which is browser-compatible. This module is Node.js only (uses node:crypto\n * for HKDF and the Vercel API for key retrieval).\n */\n\nimport { webcrypto } from 'node:crypto';\nimport { getVercelOidcToken } from '@vercel/oidc';\nimport type { WorkflowRun, World } from '@workflow/world';\nimport * as z from 'zod';\nimport { getDispatcher } from './http-client.js';\n\nconst KEY_BYTES = 32; // 256 bits = 32 bytes (AES-256)\n\n/**\n * Derive a per-run AES-256 encryption key using HKDF-SHA256.\n *\n * The derivation uses `projectId|runId` as the HKDF info parameter,\n * ensuring that each run has a unique encryption key even when sharing\n * the same deployment key.\n *\n * @param deploymentKey - Raw 32-byte deployment key\n * @param projectId - Vercel project ID for context isolation\n * @param runId - Workflow run ID for per-run key isolation\n * @returns Raw 32-byte AES-256 key\n */\nexport async function deriveRunKey(\n deploymentKey: Uint8Array,\n projectId: string,\n runId: string\n): Promise<Uint8Array> {\n if (deploymentKey.length !== KEY_BYTES) {\n throw new Error(\n `Invalid deployment key length: expected ${KEY_BYTES} bytes for AES-256, got ${deploymentKey.length} bytes`\n );\n }\n if (!projectId || typeof projectId !== 'string') {\n throw new Error('projectId must be a non-empty string');\n }\n\n const baseKey = await webcrypto.subtle.importKey(\n 'raw',\n deploymentKey,\n 'HKDF',\n false,\n ['deriveBits']\n );\n\n const info = new TextEncoder().encode(`${projectId}|${runId}`);\n\n // Zero salt is acceptable per RFC 5869 Section 3.1 when the input key\n // material has high entropy (as is the case with our random deployment key).\n // The `info` parameter provides per-run context separation.\n const derivedBits = await webcrypto.subtle.deriveBits(\n {\n name: 'HKDF',\n hash: 'SHA-256',\n salt: new Uint8Array(32),\n info,\n },\n baseKey,\n KEY_BYTES * 8 // bits\n );\n\n return new Uint8Array(derivedBits);\n}\n\n/**\n * Fetch the per-run encryption key from the Vercel API.\n *\n * The API performs HKDF-SHA256 derivation server-side, so the raw\n * deployment key never leaves the API boundary. The returned key\n * is ready-to-use for AES-GCM encrypt/decrypt operations.\n *\n * Uses OIDC token authentication (for cross-deployment runtime calls like\n * resumeHook) or falls back to VERCEL_TOKEN (for external tooling like o11y).\n *\n * @param deploymentId - The deployment ID that holds the base key material\n * @param projectId - The project ID for HKDF context isolation\n * @param runId - The workflow run ID for per-run key derivation\n * @param options.token - Auth token (from config). Falls back to OIDC or VERCEL_TOKEN.\n * @returns Derived 32-byte per-run AES-256 key, or `undefined` when the\n * deployment has no key (encryption disabled for that run)\n */\nexport async function fetchRunKey(\n deploymentId: string,\n projectId: string,\n runId: string,\n options?: {\n /** Auth token (from config). Falls back to OIDC or VERCEL_TOKEN. */\n token?: string;\n /** Team ID for team-scoped API requests. */\n teamId?: string;\n }\n): Promise<Uint8Array | undefined> {\n // Authenticate via provided token (CLI/config), VERCEL_TOKEN env var\n // (external tooling), or OIDC token (runtime) — in that order.\n // OIDC is last to avoid an unnecessary network call when a token is\n // already available (e.g. CLI or CI contexts).\n const token =\n options?.token ??\n process.env.VERCEL_TOKEN ??\n (await getVercelOidcToken().catch(() => null));\n if (!token) {\n throw new Error(\n 'Cannot fetch run key: no OIDC token or VERCEL_TOKEN available'\n );\n }\n\n const params = new URLSearchParams({ projectId, runId });\n if (options?.teamId) {\n params.set('teamId', options.teamId);\n }\n // 429/5xx retries are handled by the shared RetryAgent from getDispatcher()\n const response = await fetch(\n `https://api.vercel.com/v1/workflow/run-key/${deploymentId}?${params}`,\n {\n method: 'GET',\n headers: {\n authorization: `Bearer ${token}`,\n },\n // @ts-expect-error -- undici dispatcher is accepted by Node.js fetch but not in @types/node's RequestInit\n dispatcher: getDispatcher(),\n }\n );\n\n if (!response.ok) {\n let body: string;\n try {\n body = await response.text();\n } catch {\n body = '<unable to read response body>';\n }\n throw new Error(\n `Failed to fetch run key for ${runId} (deployment ${deploymentId}): HTTP ${response.status} ${response.statusText}${body ? ` — ${body}` : ''}`\n );\n }\n\n const data = await response.json();\n const result = z.object({ key: z.string().nullable() }).safeParse(data);\n if (!result.success) {\n throw new Error(\n `Invalid response from Vercel API: expected { key: string | null }. Zod error: ${result.error.message}`\n );\n }\n if (result.data.key === null) {\n return undefined;\n }\n return Buffer.from(result.data.key, 'base64');\n}\n\n/**\n * Create the `getEncryptionKeyForRun` implementation for a Vercel World.\n *\n * Resolves the per-run AES-256 key by either:\n * - Deriving it locally via HKDF when the run belongs to the current deployment\n * - Fetching it from the Vercel API when the run belongs to a different deployment\n *\n * @param projectId - Vercel project ID for HKDF context isolation\n * @param teamId - Optional team ID for team-scoped API requests\n * @param token - Optional auth token from config\n * @returns The `getEncryptionKeyForRun` function, or `undefined` if no projectId\n */\nexport function createGetEncryptionKeyForRun(\n projectId: string | undefined,\n teamId?: string,\n token?: string\n): World['getEncryptionKeyForRun'] {\n if (!projectId) return undefined;\n\n // VERCEL=1 is set inside Vercel serverless functions. When true, we can\n // use the local deployment key for HKDF derivation. When false (e.g., e2e\n // test runner, CLI, external tooling), we must fetch the key from the API\n // even for same-deployment runs.\n const isServerlessRuntime = process.env.VERCEL === '1';\n\n // Parse the local deployment key from env (lazy, only when encryption is used)\n let localDeploymentKey: Uint8Array | undefined;\n function getLocalDeploymentKey(): Uint8Array | undefined {\n if (localDeploymentKey) return localDeploymentKey;\n const deploymentKeyBase64 = process.env.VERCEL_DEPLOYMENT_KEY;\n if (!deploymentKeyBase64) return undefined;\n localDeploymentKey = Buffer.from(deploymentKeyBase64, 'base64');\n return localDeploymentKey;\n }\n\n return async function getEncryptionKeyForRun(\n run: WorkflowRun | string,\n context?: Record<string, unknown>\n ): Promise<Uint8Array | undefined> {\n const runId = typeof run === 'string' ? run : run.runId;\n const deploymentId =\n typeof run === 'string'\n ? (context?.deploymentId as string | undefined)\n : run.deploymentId;\n\n // Inside the Vercel serverless runtime with a local deployment key:\n // use local HKDF derivation for same-deployment or unknown-deployment runs.\n if (isServerlessRuntime) {\n if (!deploymentId || deploymentId === process.env.VERCEL_DEPLOYMENT_ID) {\n const localKey = getLocalDeploymentKey();\n if (!localKey) return undefined;\n return deriveRunKey(localKey, projectId, runId);\n }\n }\n\n // External context (CLI, e2e tests, web dashboard) or cross-deployment:\n // fetch the derived per-run key from the Vercel API. The API performs\n // HKDF derivation server-side so the raw deployment key never leaves\n // the API boundary.\n if (!deploymentId) return undefined;\n return fetchRunKey(deploymentId, projectId, runId, { token, teamId });\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Vercel-specific key management for workflow encryption.\n *\n * This module handles:\n * - HKDF key derivation (deployment key + projectId + runId → per-run key)\n * - Cross-deployment key retrieval via the Vercel API\n *\n * The actual AES-GCM encrypt/decrypt operations are in @workflow/core/encryption\n * which is browser-compatible. This module is Node.js only (uses node:crypto\n * for HKDF and the Vercel API for key retrieval).\n */\n\nimport { webcrypto } from 'node:crypto';\nimport { getVercelOidcToken } from '@vercel/oidc';\nimport type { WorkflowRun, World } from '@workflow/world';\nimport * as z from 'zod';\nimport { getDispatcher } from './http-client.js';\nimport { getProtectionBypassHeader } from './utils.js';\n\nconst KEY_BYTES = 32; // 256 bits = 32 bytes (AES-256)\n\n/**\n * Derive a per-run AES-256 encryption key using HKDF-SHA256.\n *\n * The derivation uses `projectId|runId` as the HKDF info parameter,\n * ensuring that each run has a unique encryption key even when sharing\n * the same deployment key.\n *\n * @param deploymentKey - Raw 32-byte deployment key\n * @param projectId - Vercel project ID for context isolation\n * @param runId - Workflow run ID for per-run key isolation\n * @returns Raw 32-byte AES-256 key\n */\nexport async function deriveRunKey(\n deploymentKey: Uint8Array,\n projectId: string,\n runId: string\n): Promise<Uint8Array> {\n if (deploymentKey.length !== KEY_BYTES) {\n throw new Error(\n `Invalid deployment key length: expected ${KEY_BYTES} bytes for AES-256, got ${deploymentKey.length} bytes`\n );\n }\n if (!projectId || typeof projectId !== 'string') {\n throw new Error('projectId must be a non-empty string');\n }\n\n const baseKey = await webcrypto.subtle.importKey(\n 'raw',\n deploymentKey,\n 'HKDF',\n false,\n ['deriveBits']\n );\n\n const info = new TextEncoder().encode(`${projectId}|${runId}`);\n\n // Zero salt is acceptable per RFC 5869 Section 3.1 when the input key\n // material has high entropy (as is the case with our random deployment key).\n // The `info` parameter provides per-run context separation.\n const derivedBits = await webcrypto.subtle.deriveBits(\n {\n name: 'HKDF',\n hash: 'SHA-256',\n salt: new Uint8Array(32),\n info,\n },\n baseKey,\n KEY_BYTES * 8 // bits\n );\n\n return new Uint8Array(derivedBits);\n}\n\n/**\n * Fetch the per-run encryption key from the Vercel API.\n *\n * The API performs HKDF-SHA256 derivation server-side, so the raw\n * deployment key never leaves the API boundary. The returned key\n * is ready-to-use for AES-GCM encrypt/decrypt operations.\n *\n * Uses OIDC token authentication (for cross-deployment runtime calls like\n * resumeHook) or falls back to VERCEL_TOKEN (for external tooling like o11y).\n *\n * @param deploymentId - The deployment ID that holds the base key material\n * @param projectId - The project ID for HKDF context isolation\n * @param runId - The workflow run ID for per-run key derivation\n * @param options.token - Auth token (from config). Falls back to OIDC or VERCEL_TOKEN.\n * @returns Derived 32-byte per-run AES-256 key, or `undefined` when the\n * deployment has no key (encryption disabled for that run)\n */\nexport async function fetchRunKey(\n deploymentId: string,\n projectId: string,\n runId: string,\n options?: {\n /** Auth token (from config). Falls back to OIDC or VERCEL_TOKEN. */\n token?: string;\n /** Team ID for team-scoped API requests. */\n teamId?: string;\n }\n): Promise<Uint8Array | undefined> {\n // Authenticate via provided token (CLI/config), VERCEL_TOKEN env var\n // (external tooling), or OIDC token (runtime) — in that order.\n // OIDC is last to avoid an unnecessary network call when a token is\n // already available (e.g. CLI or CI contexts).\n const token =\n options?.token ??\n process.env.VERCEL_TOKEN ??\n (await getVercelOidcToken().catch(() => null));\n if (!token) {\n throw new Error(\n 'Cannot fetch run key: no OIDC token or VERCEL_TOKEN available'\n );\n }\n\n const params = new URLSearchParams({ projectId, runId });\n if (options?.teamId) {\n params.set('teamId', options.teamId);\n }\n // 429/5xx retries are handled by the shared RetryAgent from getDispatcher()\n const response = await fetch(\n `https://api.vercel.com/v1/workflow/run-key/${deploymentId}?${params}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n ...getProtectionBypassHeader(),\n },\n // @ts-expect-error -- undici dispatcher is accepted by Node.js fetch but not in @types/node's RequestInit\n dispatcher: getDispatcher(),\n }\n );\n\n if (!response.ok) {\n let body: string;\n try {\n body = await response.text();\n } catch {\n body = '<unable to read response body>';\n }\n throw new Error(\n `Failed to fetch run key for ${runId} (deployment ${deploymentId}): HTTP ${response.status} ${response.statusText}${body ? ` — ${body}` : ''}`\n );\n }\n\n const data = await response.json();\n const result = z.object({ key: z.string().nullable() }).safeParse(data);\n if (!result.success) {\n throw new Error(\n `Invalid response from Vercel API: expected { key: string | null }. Zod error: ${result.error.message}`\n );\n }\n if (result.data.key === null) {\n return undefined;\n }\n return Buffer.from(result.data.key, 'base64');\n}\n\n/**\n * Create the `getEncryptionKeyForRun` implementation for a Vercel World.\n *\n * Resolves the per-run AES-256 key by either:\n * - Deriving it locally via HKDF when the run belongs to the current deployment\n * - Fetching it from the Vercel API when the run belongs to a different deployment\n *\n * @param projectId - Vercel project ID for HKDF context isolation\n * @param teamId - Optional team ID for team-scoped API requests\n * @param token - Optional auth token from config\n * @returns The `getEncryptionKeyForRun` function, or `undefined` if no projectId\n */\nexport function createGetEncryptionKeyForRun(\n projectId: string | undefined,\n teamId?: string,\n token?: string\n): World['getEncryptionKeyForRun'] {\n if (!projectId) return undefined;\n\n // VERCEL=1 is set inside Vercel serverless functions. When true, we can\n // use the local deployment key for HKDF derivation. When false (e.g., e2e\n // test runner, CLI, external tooling), we must fetch the key from the API\n // even for same-deployment runs.\n const isServerlessRuntime = process.env.VERCEL === '1';\n\n // Parse the local deployment key from env (lazy, only when encryption is used)\n let localDeploymentKey: Uint8Array | undefined;\n function getLocalDeploymentKey(): Uint8Array | undefined {\n if (localDeploymentKey) return localDeploymentKey;\n const deploymentKeyBase64 = process.env.VERCEL_DEPLOYMENT_KEY;\n if (!deploymentKeyBase64) return undefined;\n localDeploymentKey = Buffer.from(deploymentKeyBase64, 'base64');\n return localDeploymentKey;\n }\n\n return async function getEncryptionKeyForRun(\n run: WorkflowRun | string,\n context?: Record<string, unknown>\n ): Promise<Uint8Array | undefined> {\n const runId = typeof run === 'string' ? run : run.runId;\n const deploymentId =\n typeof run === 'string'\n ? (context?.deploymentId as string | undefined)\n : run.deploymentId;\n\n // Inside the Vercel serverless runtime with a local deployment key:\n // use local HKDF derivation for same-deployment or unknown-deployment runs.\n if (isServerlessRuntime) {\n if (!deploymentId || deploymentId === process.env.VERCEL_DEPLOYMENT_ID) {\n const localKey = getLocalDeploymentKey();\n if (!localKey) return undefined;\n return deriveRunKey(localKey, projectId, runId);\n }\n }\n\n // External context (CLI, e2e tests, web dashboard) or cross-deployment:\n // fetch the derived per-run key from the Vercel API. The API performs\n // HKDF derivation server-side so the raw deployment key never leaves\n // the API boundary.\n if (!deploymentId) return undefined;\n return fetchRunKey(deploymentId, projectId, runId, { token, teamId });\n };\n}\n"]}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* environment (e.g., same "production" target or same git branch for "preview"
|
|
6
6
|
* deployments) as the provided current deployment.
|
|
7
7
|
*/
|
|
8
|
-
import type
|
|
8
|
+
import { type APIConfig } from './utils.js';
|
|
9
9
|
/**
|
|
10
10
|
* Create the `resolveLatestDeploymentId` implementation for a Vercel World.
|
|
11
11
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-latest-deployment.d.ts","sourceRoot":"","sources":["../src/resolve-latest-deployment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"resolve-latest-deployment.d.ts","sourceRoot":"","sources":["../src/resolve-latest-deployment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,KAAK,SAAS,EAA6B,MAAM,YAAY,CAAC;AAMvE;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,CAAC,EAAE,SAAS,GACjB,MAAM,OAAO,CAAC,MAAM,CAAC,CA0DvB"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { getVercelOidcToken } from '@vercel/oidc';
|
|
9
9
|
import * as z from 'zod';
|
|
10
10
|
import { getDispatcher } from './http-client.js';
|
|
11
|
+
import { getProtectionBypassHeader } from './utils.js';
|
|
11
12
|
const ResolveLatestDeploymentResponseSchema = z.object({
|
|
12
13
|
id: z.string(),
|
|
13
14
|
});
|
|
@@ -41,7 +42,8 @@ export function createResolveLatestDeploymentId(config) {
|
|
|
41
42
|
const response = await fetch(url, {
|
|
42
43
|
method: 'GET',
|
|
43
44
|
headers: {
|
|
44
|
-
|
|
45
|
+
Authorization: `Bearer ${token}`,
|
|
46
|
+
...getProtectionBypassHeader(),
|
|
45
47
|
},
|
|
46
48
|
// @ts-expect-error -- undici dispatcher is accepted by Node.js fetch but not in @types/node's RequestInit
|
|
47
49
|
dispatcher: getDispatcher(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-latest-deployment.js","sourceRoot":"","sources":["../src/resolve-latest-deployment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-latest-deployment.js","sourceRoot":"","sources":["../src/resolve-latest-deployment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAkB,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEvE,MAAM,qCAAqC,GAAG,CAAC,CAAC,MAAM,CAAC;IACrD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;CACf,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,+BAA+B,CAC7C,MAAkB;IAElB,OAAO,KAAK,UAAU,yBAAyB;QAC7C,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;QAC7D,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;QACJ,CAAC;QAED,qEAAqE;QACrE,+DAA+D;QAC/D,oEAAoE;QACpE,+CAA+C;QAC/C,MAAM,KAAK,GACT,MAAM,EAAE,KAAK;YACb,OAAO,CAAC,GAAG,CAAC,YAAY;YACxB,CAAC,MAAM,kBAAkB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,GAAG,gEAAgE,kBAAkB,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAEtH,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,GAAG,yBAAyB,EAAE;aAC/B;YACD,0GAA0G;YAC1G,UAAU,EAAE,aAAa,EAAE;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,IAAY,CAAC;YACjB,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,GAAG,gCAAgC,CAAC;YAC1C,CAAC;YACD,MAAM,IAAI,KAAK,CACb,2CAA2C,mBAAmB,UAAU,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5I,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,qCAAqC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,yEAAyE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAChG,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Resolve the latest deployment ID for the current deployment's environment.\n *\n * Calls the Vercel API to find the most recent deployment that shares the same\n * environment (e.g., same \"production\" target or same git branch for \"preview\"\n * deployments) as the provided current deployment.\n */\n\nimport { getVercelOidcToken } from '@vercel/oidc';\nimport * as z from 'zod';\nimport { getDispatcher } from './http-client.js';\nimport { type APIConfig, getProtectionBypassHeader } from './utils.js';\n\nconst ResolveLatestDeploymentResponseSchema = z.object({\n id: z.string(),\n});\n\n/**\n * Create the `resolveLatestDeploymentId` implementation for a Vercel World.\n *\n * Resolves the most recent deployment ID for the same environment as the\n * current deployment by calling the Vercel API.\n *\n * @param config - API configuration (token, project config, etc.)\n * @returns The `resolveLatestDeploymentId` function\n */\nexport function createResolveLatestDeploymentId(\n config?: APIConfig\n): () => Promise<string> {\n return async function resolveLatestDeploymentId(): Promise<string> {\n const currentDeploymentId = process.env.VERCEL_DEPLOYMENT_ID;\n if (!currentDeploymentId) {\n throw new Error(\n 'Cannot resolve latest deployment: VERCEL_DEPLOYMENT_ID environment variable is not set'\n );\n }\n\n // Authenticate via provided token (CLI/config), VERCEL_TOKEN env var\n // (external tooling), or OIDC token (runtime) — in that order.\n // OIDC is last to avoid an unnecessary network call when a token is\n // already available (e.g. CLI or CI contexts).\n const token =\n config?.token ??\n process.env.VERCEL_TOKEN ??\n (await getVercelOidcToken().catch(() => null));\n if (!token) {\n throw new Error(\n 'Cannot resolve latest deployment: no OIDC token or VERCEL_TOKEN available'\n );\n }\n\n const url = `https://api.vercel.com/v1/workflow/resolve-latest-deployment/${encodeURIComponent(currentDeploymentId)}`;\n\n // 429/5xx retries are handled by the shared RetryAgent from getDispatcher()\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n ...getProtectionBypassHeader(),\n },\n // @ts-expect-error -- undici dispatcher is accepted by Node.js fetch but not in @types/node's RequestInit\n dispatcher: getDispatcher(),\n });\n\n if (!response.ok) {\n let body: string;\n try {\n body = await response.text();\n } catch {\n body = '<unable to read response body>';\n }\n throw new Error(\n `Failed to resolve latest deployment for ${currentDeploymentId}: HTTP ${response.status} ${response.statusText}${body ? ` — ${body}` : ''}`\n );\n }\n\n const data = await response.json();\n const result = ResolveLatestDeploymentResponseSchema.safeParse(data);\n if (!result.success) {\n throw new Error(\n `Invalid response from Vercel API: expected { id: string }. Zod error: ${result.error.message}`\n );\n }\n\n return result.data.id;\n };\n}\n"]}
|
package/dist/runs.d.ts
CHANGED
|
@@ -13,7 +13,6 @@ import type { APIConfig } from './utils.js';
|
|
|
13
13
|
export declare const WorkflowRunWireBaseSchema: z.ZodObject<{
|
|
14
14
|
output: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>]>>;
|
|
15
15
|
input: z.ZodUnion<readonly [z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>]>;
|
|
16
|
-
runId: z.ZodString;
|
|
17
16
|
status: z.ZodEnum<{
|
|
18
17
|
pending: "pending";
|
|
19
18
|
running: "running";
|
|
@@ -21,6 +20,7 @@ export declare const WorkflowRunWireBaseSchema: z.ZodObject<{
|
|
|
21
20
|
failed: "failed";
|
|
22
21
|
cancelled: "cancelled";
|
|
23
22
|
}>;
|
|
23
|
+
runId: z.ZodString;
|
|
24
24
|
deploymentId: z.ZodString;
|
|
25
25
|
workflowName: z.ZodString;
|
|
26
26
|
specVersion: z.ZodOptional<z.ZodNumber>;
|
package/dist/steps.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ export declare const StepWireSchema: z.ZodObject<{
|
|
|
9
9
|
retryAfter: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
10
10
|
output: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>]>>;
|
|
11
11
|
input: z.ZodUnion<readonly [z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>]>;
|
|
12
|
-
runId: z.ZodString;
|
|
13
12
|
status: z.ZodEnum<{
|
|
14
13
|
pending: "pending";
|
|
15
14
|
running: "running";
|
|
@@ -17,6 +16,7 @@ export declare const StepWireSchema: z.ZodObject<{
|
|
|
17
16
|
failed: "failed";
|
|
18
17
|
cancelled: "cancelled";
|
|
19
18
|
}>;
|
|
19
|
+
runId: z.ZodString;
|
|
20
20
|
specVersion: z.ZodOptional<z.ZodNumber>;
|
|
21
21
|
startedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
22
22
|
createdAt: z.ZodCoercedDate<unknown>;
|
package/dist/utils.d.ts
CHANGED
|
@@ -47,6 +47,15 @@ export interface HttpConfig {
|
|
|
47
47
|
headers: Headers;
|
|
48
48
|
usingProxy: boolean;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns an object with the Vercel Deployment Protection bypass header
|
|
52
|
+
* if the `VERCEL_WORKFLOW_SERVER_PROTECTION_BYPASS` env var is set, otherwise
|
|
53
|
+
* returns an empty object. Useful for spreading into a headers init object
|
|
54
|
+
* for direct fetch() calls that don't go through `getHeaders()`.
|
|
55
|
+
*
|
|
56
|
+
* See: https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation
|
|
57
|
+
*/
|
|
58
|
+
export declare function getProtectionBypassHeader(): Record<string, string>;
|
|
50
59
|
export declare const getHttpUrl: (config?: APIConfig) => {
|
|
51
60
|
baseUrl: string;
|
|
52
61
|
usingProxy: boolean;
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,eAAe,EAAyB,MAAM,iBAAiB,CAAC;AAE9E,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,eAAe,EAAyB,MAAM,iBAAiB,CAAC;AAE9E,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA8D7B,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE;QACd,iDAAiD;QACjD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,oEAAoE;QACpE,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,eAAO,MAAM,2BAA2B,QAAQ,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS;IAAE,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,EAClE,IAAI,EAAE,CAAC,GACN,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAgBvC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,CAqD3E;AAUD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMlE;AAED,eAAO,MAAM,UAAU,GACrB,SAAS,SAAS,KACjB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAcxC,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,QAAQ,SAAS,GAAG,SAAS,EAC7B,SAAS;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,KAC/B,OA2BF,CAAC;AAEF,wBAAsB,aAAa,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ3E;AAED,wBAAsB,WAAW,CAAC,CAAC,EAAE,EACnC,QAAQ,EACR,OAAY,EACZ,MAAW,EACX,MAAM,EACN,IAAI,EACJ,UAAU,GACX,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACvB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6GAA6G;IAC7G,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC3C,GAAG,OAAO,CAAC,CAAC,CAAC,CAoLb"}
|
package/dist/utils.js
CHANGED
|
@@ -24,13 +24,22 @@ function httpLog(method, endpoint, status, ms) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* Example: 'https://workflow-server-git-branch-name.vercel.sh'
|
|
27
|
+
* Inline workflow-server URL override. Must remain an empty string on
|
|
28
|
+
* `main` — rewritten by external CI for branch-deployment testing.
|
|
29
|
+
* Prefer `VERCEL_WORKFLOW_SERVER_URL` for deployment-time configuration.
|
|
32
30
|
*/
|
|
33
31
|
const WORKFLOW_SERVER_URL_OVERRIDE = '';
|
|
32
|
+
/**
|
|
33
|
+
* Effective workflow-server URL override. The inline constant wins when
|
|
34
|
+
* set; otherwise falls back to the `VERCEL_WORKFLOW_SERVER_URL` env var.
|
|
35
|
+
*
|
|
36
|
+
* When set, requests bypass the default production host
|
|
37
|
+
* (`https://vercel-workflow.com`). When using the proxy
|
|
38
|
+
* (`api.vercel.com/v1/workflow`), this value is forwarded via the
|
|
39
|
+
* `x-vercel-workflow-api-url` header so the proxy routes the request to
|
|
40
|
+
* the override URL.
|
|
41
|
+
*/
|
|
42
|
+
const getWorkflowServerUrlOverride = () => WORKFLOW_SERVER_URL_OVERRIDE || process.env.VERCEL_WORKFLOW_SERVER_URL || '';
|
|
34
43
|
export const DEFAULT_RESOLVE_DATA_OPTION = 'all';
|
|
35
44
|
/**
|
|
36
45
|
* Helper to serialize error into a JSON string in the error field.
|
|
@@ -127,9 +136,24 @@ const getUserAgent = () => {
|
|
|
127
136
|
}
|
|
128
137
|
return `@workflow/world-vercel/${version} node-${process.version} ${os.platform()} (${os.arch()})`;
|
|
129
138
|
};
|
|
139
|
+
/**
|
|
140
|
+
* Returns an object with the Vercel Deployment Protection bypass header
|
|
141
|
+
* if the `VERCEL_WORKFLOW_SERVER_PROTECTION_BYPASS` env var is set, otherwise
|
|
142
|
+
* returns an empty object. Useful for spreading into a headers init object
|
|
143
|
+
* for direct fetch() calls that don't go through `getHeaders()`.
|
|
144
|
+
*
|
|
145
|
+
* See: https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation
|
|
146
|
+
*/
|
|
147
|
+
export function getProtectionBypassHeader() {
|
|
148
|
+
const bypassSecret = process.env.VERCEL_WORKFLOW_SERVER_PROTECTION_BYPASS;
|
|
149
|
+
if (bypassSecret) {
|
|
150
|
+
return { 'x-vercel-protection-bypass': bypassSecret };
|
|
151
|
+
}
|
|
152
|
+
return {};
|
|
153
|
+
}
|
|
130
154
|
export const getHttpUrl = (config) => {
|
|
131
155
|
const projectConfig = config?.projectConfig;
|
|
132
|
-
const defaultHost =
|
|
156
|
+
const defaultHost = getWorkflowServerUrlOverride() || 'https://vercel-workflow.com';
|
|
133
157
|
const customProxyUrl = process.env.WORKFLOW_VERCEL_BACKEND_URL;
|
|
134
158
|
const defaultProxyUrl = 'https://api.vercel.com/v1/workflow';
|
|
135
159
|
// Use proxy when we have project config (for authentication via Vercel API)
|
|
@@ -157,8 +181,12 @@ export const getHeaders = (config, options) => {
|
|
|
157
181
|
// Only set workflow-api-url header when using the proxy, since the proxy
|
|
158
182
|
// forwards it to the workflow-server. When not using proxy, requests go
|
|
159
183
|
// directly to the workflow-server so this header has no effect.
|
|
160
|
-
|
|
161
|
-
|
|
184
|
+
const workflowServerUrlOverride = getWorkflowServerUrlOverride();
|
|
185
|
+
if (workflowServerUrlOverride && options.usingProxy) {
|
|
186
|
+
headers.set('x-vercel-workflow-api-url', workflowServerUrlOverride);
|
|
187
|
+
}
|
|
188
|
+
for (const [key, value] of Object.entries(getProtectionBypassHeader())) {
|
|
189
|
+
headers.set(key, value);
|
|
162
190
|
}
|
|
163
191
|
return headers;
|
|
164
192
|
};
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'node:os';\nimport { inspect } from 'node:util';\nimport { getVercelOidcToken } from '@vercel/oidc';\nimport {\n EntityConflictError,\n RunExpiredError,\n ThrottleError,\n TooEarlyError,\n WorkflowWorldError,\n} from '@workflow/errors';\nimport { type StructuredError, StructuredErrorSchema } from '@workflow/world';\nimport { decode, encode } from 'cbor-x';\nimport type { z } from 'zod';\nimport { getDispatcher } from './http-client.js';\nimport {\n ErrorType,\n getSpanKind,\n HttpRequestMethod,\n HttpResponseStatusCode,\n PeerService,\n RpcService,\n RpcSystem,\n ServerAddress,\n ServerPort,\n trace,\n UrlFull,\n WorldParseFormat,\n} from './telemetry.js';\nimport { version } from './version.js';\n\n/**\n * Lightweight debug logger for HTTP requests. Activated when the DEBUG\n * env var contains \"workflow:\" or is \"*\".\n *\n * Note: this does not implement full `debug` module semantics (e.g.\n * comma-separated globs, negation with `-`). It is a simple check\n * sufficient for enabling HTTP-level debug output.\n */\nconst HTTP_DEBUG_ENABLED =\n typeof process !== 'undefined' &&\n typeof process.env.DEBUG === 'string' &&\n (process.env.DEBUG.includes('workflow:') || process.env.DEBUG === '*');\n\nfunction httpLog(\n method: string,\n endpoint: string,\n status: number,\n ms: number\n): void {\n if (HTTP_DEBUG_ENABLED) {\n console.debug(\n `[workflow:world-vercel:http] ${method} ${endpoint} -> ${status} (${ms}ms)`\n );\n }\n}\n\n/**\n * Hard-coded workflow-server URL override for testing.\n * Set this to test against a different workflow-server version.\n * Leave empty string for production (uses default vercel-workflow.com).\n *\n * Example: 'https://workflow-server-git-branch-name.vercel.sh'\n */\nconst WORKFLOW_SERVER_URL_OVERRIDE = '';\n\nexport interface APIConfig {\n token?: string;\n headers?: RequestInit['headers'];\n projectConfig?: {\n /** The real Vercel project ID (e.g., prj_xxx) */\n projectId?: string;\n /** The project name/slug (e.g., my-app), used for dashboard URLs */\n projectName?: string;\n teamId?: string;\n environment?: string;\n };\n}\n\nexport const DEFAULT_RESOLVE_DATA_OPTION = 'all';\n\n/**\n * Helper to serialize error into a JSON string in the error field.\n * The error field can be either:\n * - A plain string (legacy format, just the error message)\n * - A JSON string with { message, stack, code } (new format)\n */\nexport function serializeError<T extends { error?: StructuredError }>(\n data: T\n): Omit<T, 'error'> & { error?: string } {\n const { error, ...rest } = data;\n\n // If we have an error, serialize as JSON string\n if (error !== undefined) {\n return {\n ...rest,\n error: JSON.stringify({\n message: error.message,\n stack: error.stack,\n code: error.code,\n }),\n } as Omit<T, 'error'> & { error: string };\n }\n\n return data as Omit<T, 'error'>;\n}\n\n/**\n * Helper to deserialize error field from the backend into a StructuredError object.\n * Handles multiple formats from the backend:\n * - If error is already a structured object → validate and use directly\n * - If error is a JSON string with {message, stack, code} → parse into StructuredError\n * - If error is a plain string → treat as error message with no stack\n * - If no error → undefined\n *\n * This function transforms objects from wire format (where error may be a JSON string\n * or already structured) to domain format (where error is a StructuredError object).\n * The generic type parameter should be the expected output type (WorkflowRun or Step).\n *\n * Note: The type assertion is necessary because the wire format types from Zod schemas\n * have `error?: string | StructuredError` while the domain types have complex error types\n * (e.g., discriminated unions with `error: void` or `error: StructuredError` depending on\n * status), but the transformation preserves all other fields correctly.\n */\nexport function deserializeError<T extends Record<string, any>>(obj: any): T {\n const { error, errorCode, ...rest } = obj;\n\n if (!error) {\n return obj as T;\n }\n\n // errorCode is stored as a separate inline field on the run entity (not\n // inside errorRef). Merge it into StructuredError.code so consumers see it.\n // If the error already has a code from the ref, errorCode takes precedence.\n\n // If error is already an object (new format), validate and use directly\n if (typeof error === 'object' && error !== null) {\n const result = StructuredErrorSchema.safeParse(error);\n if (result.success) {\n return {\n ...rest,\n error: {\n message: result.data.message,\n stack: result.data.stack,\n code: errorCode ?? result.data.code,\n },\n } as T;\n }\n // Fall through to treat as unknown format\n }\n\n // If error is a string, try to parse as structured error JSON\n if (typeof error === 'string') {\n try {\n const parsed = StructuredErrorSchema.parse(JSON.parse(error));\n return {\n ...rest,\n error: {\n message: parsed.message,\n stack: parsed.stack,\n code: errorCode ?? parsed.code,\n },\n } as T;\n } catch {\n // Backwards compatibility: error is just a plain string\n return {\n ...rest,\n error: {\n message: error,\n code: errorCode,\n },\n } as T;\n }\n }\n\n // Unknown format - return as-is and let downstream handle it\n return obj as T;\n}\n\nconst getUserAgent = () => {\n const deploymentId = process.env.VERCEL_DEPLOYMENT_ID;\n if (deploymentId) {\n return `@workflow/world-vercel/${version} node-${process.version} ${os.platform()} (${os.arch()}) ${deploymentId}`;\n }\n return `@workflow/world-vercel/${version} node-${process.version} ${os.platform()} (${os.arch()})`;\n};\n\nexport interface HttpConfig {\n baseUrl: string;\n headers: Headers;\n usingProxy: boolean;\n}\n\nexport const getHttpUrl = (\n config?: APIConfig\n): { baseUrl: string; usingProxy: boolean } => {\n const projectConfig = config?.projectConfig;\n const defaultHost =\n WORKFLOW_SERVER_URL_OVERRIDE || 'https://vercel-workflow.com';\n const customProxyUrl = process.env.WORKFLOW_VERCEL_BACKEND_URL;\n const defaultProxyUrl = 'https://api.vercel.com/v1/workflow';\n // Use proxy when we have project config (for authentication via Vercel API)\n const usingProxy = Boolean(projectConfig?.projectId && projectConfig?.teamId);\n // When using proxy, requests go through api.vercel.com (with x-vercel-workflow-api-url header if override is set)\n // When not using proxy, use the default workflow-server URL (with /api path appended)\n const baseUrl = usingProxy\n ? customProxyUrl || defaultProxyUrl\n : `${defaultHost}/api`;\n return { baseUrl, usingProxy };\n};\n\nexport const getHeaders = (\n config: APIConfig | undefined,\n options: { usingProxy: boolean }\n): Headers => {\n const projectConfig = config?.projectConfig;\n const headers = new Headers(config?.headers);\n headers.set('User-Agent', getUserAgent());\n if (projectConfig) {\n headers.set(\n 'x-vercel-environment',\n projectConfig.environment || 'production'\n );\n if (projectConfig.projectId) {\n headers.set('x-vercel-project-id', projectConfig.projectId);\n }\n if (projectConfig.teamId) {\n headers.set('x-vercel-team-id', projectConfig.teamId);\n }\n }\n // Only set workflow-api-url header when using the proxy, since the proxy\n // forwards it to the workflow-server. When not using proxy, requests go\n // directly to the workflow-server so this header has no effect.\n if (WORKFLOW_SERVER_URL_OVERRIDE && options.usingProxy) {\n headers.set('x-vercel-workflow-api-url', WORKFLOW_SERVER_URL_OVERRIDE);\n }\n return headers;\n};\n\nexport async function getHttpConfig(config?: APIConfig): Promise<HttpConfig> {\n const { baseUrl, usingProxy } = getHttpUrl(config);\n const headers = getHeaders(config, { usingProxy });\n const token = config?.token ?? (await getVercelOidcToken());\n if (token) {\n headers.set('Authorization', `Bearer ${token}`);\n }\n return { baseUrl, headers, usingProxy };\n}\n\nexport async function makeRequest<T>({\n endpoint,\n options = {},\n config = {},\n schema,\n data,\n onResponse,\n}: {\n endpoint: string;\n options?: Omit<RequestInit, 'body'>;\n config?: APIConfig;\n schema: z.ZodSchema<T>;\n /** Request body data - will be CBOR encoded */\n data?: unknown;\n /** Optional callback invoked with the raw Response before body consumption. Use to read response headers. */\n onResponse?: (response: Response) => void;\n}): Promise<T> {\n const method = options.method || 'GET';\n const { baseUrl, headers } = await getHttpConfig(config);\n const url = `${baseUrl}${endpoint}`;\n\n // Parse server address and port from URL for OTEL attributes\n let serverAddress: string | undefined;\n let serverPort: number | undefined;\n try {\n const parsedUrl = new URL(url);\n serverAddress = parsedUrl.hostname;\n serverPort = parsedUrl.port\n ? parseInt(parsedUrl.port, 10)\n : parsedUrl.protocol === 'https:'\n ? 443\n : 80;\n } catch {\n // URL parsing failed, skip these attributes\n }\n\n // Standard OTEL span name for HTTP client: \"{method}\"\n // See: https://opentelemetry.io/docs/specs/semconv/http/http-spans/#name\n return trace(\n `http ${method}`,\n { kind: await getSpanKind('CLIENT') },\n async (span) => {\n // Set standard OTEL HTTP client attributes\n span?.setAttributes({\n ...HttpRequestMethod(method),\n ...UrlFull(url),\n ...(serverAddress && ServerAddress(serverAddress)),\n ...(serverPort && ServerPort(serverPort)),\n // Peer service for Datadog service maps\n ...PeerService('workflow-server'),\n ...RpcSystem('http'),\n ...RpcService('workflow-server'),\n });\n\n headers.set('Accept', 'application/cbor');\n // NOTE: Add a unique header to bypass RSC request memoization.\n // See: https://github.com/vercel/workflow/issues/618\n headers.set('X-Request-Time', Date.now().toString());\n\n // Encode body as CBOR if data is provided\n let body: Buffer | undefined;\n if (data !== undefined) {\n headers.set('Content-Type', 'application/cbor');\n body = encode(data);\n }\n\n const request = new Request(url, {\n ...options,\n body,\n headers,\n });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici v7 dispatcher types don't match @types/node's RequestInit\n const fetchStart = Date.now();\n const response = await fetch(request, {\n dispatcher: getDispatcher(),\n } as any);\n const fetchMs = Date.now() - fetchStart;\n\n httpLog(method, endpoint, response.status, fetchMs);\n\n span?.setAttributes({\n ...HttpResponseStatusCode(response.status),\n });\n\n if (!response.ok) {\n const errorData: { message?: string; code?: string } =\n await parseResponseBody(response)\n .then((r) => r.data as { message?: string; code?: string })\n .catch(() => ({}));\n if (process.env.DEBUG) {\n const stringifiedHeaders = Array.from(headers.entries())\n .filter(([key]) => key.toLowerCase() !== 'authorization')\n .map(([key, value]: [string, string]) => `-H \"${key}: ${value}\"`)\n .join(' ');\n console.error(\n `Failed to fetch, reproduce with:\\ncurl -X ${request.method} ${stringifiedHeaders} \"${url}\"`\n );\n }\n\n // Parse Retry-After header (value is in seconds).\n // Used by both 425 (TooEarlyError) and 429 (ThrottleError).\n // Note: RetryAgent handles most 429 retries automatically, but this\n // catches the case where retries are exhausted.\n let retryAfter: number | undefined;\n const retryAfterHeader = response.headers.get('Retry-After');\n if (retryAfterHeader) {\n const parsed = parseInt(retryAfterHeader, 10);\n if (!Number.isNaN(parsed)) {\n retryAfter = parsed;\n }\n }\n\n const defaultMessage =\n errorData.message ||\n `${request.method} ${endpoint} -> HTTP ${response.status}: ${response.statusText}`;\n\n // Map specific HTTP status codes to semantic error types\n const throwWithTrace = (error: Error): never => {\n span?.setAttributes({\n ...ErrorType(errorData.code || `HTTP ${response.status}`),\n });\n span?.recordException?.(error);\n throw error;\n };\n\n if (response.status === 409) {\n throwWithTrace(new EntityConflictError(defaultMessage));\n }\n if (response.status === 410) {\n throwWithTrace(new RunExpiredError(defaultMessage));\n }\n if (response.status === 425) {\n throwWithTrace(new TooEarlyError(defaultMessage, { retryAfter }));\n }\n if (response.status === 429) {\n throwWithTrace(new ThrottleError(defaultMessage, { retryAfter }));\n }\n\n throwWithTrace(\n new WorkflowWorldError(defaultMessage, {\n url,\n status: response.status,\n code: errorData.code,\n retryAfter,\n })\n );\n }\n\n // Expose response headers to caller before consuming the body\n onResponse?.(response);\n\n // Parse the response body (CBOR or JSON) with tracing\n let parseResult: ParseResult;\n try {\n parseResult = await trace('world.parse', async (parseSpan) => {\n const result = await parseResponseBody(response);\n // Extract format and size from debug context for attributes\n const contentType = response.headers.get('Content-Type') || '';\n const isCbor = contentType.includes('application/cbor');\n parseSpan?.setAttributes({\n ...WorldParseFormat(isCbor ? 'cbor' : 'json'),\n });\n return result;\n });\n } catch (error) {\n const contentType = response.headers.get('Content-Type') || 'unknown';\n throw new WorkflowWorldError(\n `Failed to parse response body for ${request.method} ${endpoint} (Content-Type: ${contentType}):\\n\\n${error}`,\n { url, cause: error }\n );\n }\n\n // Validate against the schema with tracing\n const result = await trace('world.validate', async () => {\n const validationResult = schema.safeParse(parseResult.data);\n if (!validationResult.success) {\n const issues = validationResult.error.issues\n .map(\n (i) =>\n ` ${i.path.length > 0 ? i.path.join('.') : '<root>'}: ${i.message}`\n )\n .join('\\n');\n const debugContext = process.env.DEBUG\n ? `\\n\\nResponse context: ${parseResult.getDebugContext()}`\n : '';\n throw new WorkflowWorldError(\n `Schema validation failed for ${method} ${endpoint}:\\n${issues}${debugContext}`,\n { url, cause: validationResult.error }\n );\n }\n return validationResult.data;\n });\n\n return result;\n }\n );\n}\n\ninterface ParseResult {\n data: unknown;\n /** Lazily generates debug context for error messages (only called on failure) */\n getDebugContext: () => string;\n}\n\n/** Max length for response preview in error messages */\nconst MAX_PREVIEW_LENGTH = 500;\n\n/**\n * Create a truncated preview of data for error messages.\n */\nfunction createPreview(data: unknown): string {\n const str = inspect(data, { depth: 3, maxArrayLength: 10, breakLength: 120 });\n return str.length > MAX_PREVIEW_LENGTH\n ? `${str.slice(0, MAX_PREVIEW_LENGTH)}...`\n : str;\n}\n\n/**\n * Parse response body based on Content-Type header.\n * Supports both CBOR and JSON responses.\n * Returns parsed data along with a lazy debug context generator for error reporting.\n */\nasync function parseResponseBody(response: Response): Promise<ParseResult> {\n const contentType = response.headers.get('Content-Type') || '';\n\n if (contentType.includes('application/cbor')) {\n const buffer = await response.arrayBuffer();\n const data = decode(new Uint8Array(buffer));\n return {\n data,\n getDebugContext: () =>\n `Content-Type: ${contentType}, ${buffer.byteLength} bytes (CBOR), preview: ${createPreview(data)}`,\n };\n }\n\n // Fall back to JSON parsing\n const text = await response.text();\n const data = JSON.parse(text);\n return {\n data,\n getDebugContext: () =>\n `Content-Type: ${contentType}, ${text.length} bytes, preview: ${createPreview(data)}`,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'node:os';\nimport { inspect } from 'node:util';\nimport { getVercelOidcToken } from '@vercel/oidc';\nimport {\n EntityConflictError,\n RunExpiredError,\n ThrottleError,\n TooEarlyError,\n WorkflowWorldError,\n} from '@workflow/errors';\nimport { type StructuredError, StructuredErrorSchema } from '@workflow/world';\nimport { decode, encode } from 'cbor-x';\nimport type { z } from 'zod';\nimport { getDispatcher } from './http-client.js';\nimport {\n ErrorType,\n getSpanKind,\n HttpRequestMethod,\n HttpResponseStatusCode,\n PeerService,\n RpcService,\n RpcSystem,\n ServerAddress,\n ServerPort,\n trace,\n UrlFull,\n WorldParseFormat,\n} from './telemetry.js';\nimport { version } from './version.js';\n\n/**\n * Lightweight debug logger for HTTP requests. Activated when the DEBUG\n * env var contains \"workflow:\" or is \"*\".\n *\n * Note: this does not implement full `debug` module semantics (e.g.\n * comma-separated globs, negation with `-`). It is a simple check\n * sufficient for enabling HTTP-level debug output.\n */\nconst HTTP_DEBUG_ENABLED =\n typeof process !== 'undefined' &&\n typeof process.env.DEBUG === 'string' &&\n (process.env.DEBUG.includes('workflow:') || process.env.DEBUG === '*');\n\nfunction httpLog(\n method: string,\n endpoint: string,\n status: number,\n ms: number\n): void {\n if (HTTP_DEBUG_ENABLED) {\n console.debug(\n `[workflow:world-vercel:http] ${method} ${endpoint} -> ${status} (${ms}ms)`\n );\n }\n}\n/**\n * Inline workflow-server URL override. Must remain an empty string on\n * `main` — rewritten by external CI for branch-deployment testing.\n * Prefer `VERCEL_WORKFLOW_SERVER_URL` for deployment-time configuration.\n */\nconst WORKFLOW_SERVER_URL_OVERRIDE = '';\n\n/**\n * Effective workflow-server URL override. The inline constant wins when\n * set; otherwise falls back to the `VERCEL_WORKFLOW_SERVER_URL` env var.\n *\n * When set, requests bypass the default production host\n * (`https://vercel-workflow.com`). When using the proxy\n * (`api.vercel.com/v1/workflow`), this value is forwarded via the\n * `x-vercel-workflow-api-url` header so the proxy routes the request to\n * the override URL.\n */\nconst getWorkflowServerUrlOverride = (): string =>\n WORKFLOW_SERVER_URL_OVERRIDE || process.env.VERCEL_WORKFLOW_SERVER_URL || '';\nexport interface APIConfig {\n token?: string;\n headers?: RequestInit['headers'];\n projectConfig?: {\n /** The real Vercel project ID (e.g., prj_xxx) */\n projectId?: string;\n /** The project name/slug (e.g., my-app), used for dashboard URLs */\n projectName?: string;\n teamId?: string;\n environment?: string;\n };\n}\n\nexport const DEFAULT_RESOLVE_DATA_OPTION = 'all';\n\n/**\n * Helper to serialize error into a JSON string in the error field.\n * The error field can be either:\n * - A plain string (legacy format, just the error message)\n * - A JSON string with { message, stack, code } (new format)\n */\nexport function serializeError<T extends { error?: StructuredError }>(\n data: T\n): Omit<T, 'error'> & { error?: string } {\n const { error, ...rest } = data;\n\n // If we have an error, serialize as JSON string\n if (error !== undefined) {\n return {\n ...rest,\n error: JSON.stringify({\n message: error.message,\n stack: error.stack,\n code: error.code,\n }),\n } as Omit<T, 'error'> & { error: string };\n }\n\n return data as Omit<T, 'error'>;\n}\n\n/**\n * Helper to deserialize error field from the backend into a StructuredError object.\n * Handles multiple formats from the backend:\n * - If error is already a structured object → validate and use directly\n * - If error is a JSON string with {message, stack, code} → parse into StructuredError\n * - If error is a plain string → treat as error message with no stack\n * - If no error → undefined\n *\n * This function transforms objects from wire format (where error may be a JSON string\n * or already structured) to domain format (where error is a StructuredError object).\n * The generic type parameter should be the expected output type (WorkflowRun or Step).\n *\n * Note: The type assertion is necessary because the wire format types from Zod schemas\n * have `error?: string | StructuredError` while the domain types have complex error types\n * (e.g., discriminated unions with `error: void` or `error: StructuredError` depending on\n * status), but the transformation preserves all other fields correctly.\n */\nexport function deserializeError<T extends Record<string, any>>(obj: any): T {\n const { error, errorCode, ...rest } = obj;\n\n if (!error) {\n return obj as T;\n }\n\n // errorCode is stored as a separate inline field on the run entity (not\n // inside errorRef). Merge it into StructuredError.code so consumers see it.\n // If the error already has a code from the ref, errorCode takes precedence.\n\n // If error is already an object (new format), validate and use directly\n if (typeof error === 'object' && error !== null) {\n const result = StructuredErrorSchema.safeParse(error);\n if (result.success) {\n return {\n ...rest,\n error: {\n message: result.data.message,\n stack: result.data.stack,\n code: errorCode ?? result.data.code,\n },\n } as T;\n }\n // Fall through to treat as unknown format\n }\n\n // If error is a string, try to parse as structured error JSON\n if (typeof error === 'string') {\n try {\n const parsed = StructuredErrorSchema.parse(JSON.parse(error));\n return {\n ...rest,\n error: {\n message: parsed.message,\n stack: parsed.stack,\n code: errorCode ?? parsed.code,\n },\n } as T;\n } catch {\n // Backwards compatibility: error is just a plain string\n return {\n ...rest,\n error: {\n message: error,\n code: errorCode,\n },\n } as T;\n }\n }\n\n // Unknown format - return as-is and let downstream handle it\n return obj as T;\n}\n\nconst getUserAgent = () => {\n const deploymentId = process.env.VERCEL_DEPLOYMENT_ID;\n if (deploymentId) {\n return `@workflow/world-vercel/${version} node-${process.version} ${os.platform()} (${os.arch()}) ${deploymentId}`;\n }\n return `@workflow/world-vercel/${version} node-${process.version} ${os.platform()} (${os.arch()})`;\n};\n\nexport interface HttpConfig {\n baseUrl: string;\n headers: Headers;\n usingProxy: boolean;\n}\n\n/**\n * Returns an object with the Vercel Deployment Protection bypass header\n * if the `VERCEL_WORKFLOW_SERVER_PROTECTION_BYPASS` env var is set, otherwise\n * returns an empty object. Useful for spreading into a headers init object\n * for direct fetch() calls that don't go through `getHeaders()`.\n *\n * See: https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation\n */\nexport function getProtectionBypassHeader(): Record<string, string> {\n const bypassSecret = process.env.VERCEL_WORKFLOW_SERVER_PROTECTION_BYPASS;\n if (bypassSecret) {\n return { 'x-vercel-protection-bypass': bypassSecret };\n }\n return {};\n}\n\nexport const getHttpUrl = (\n config?: APIConfig\n): { baseUrl: string; usingProxy: boolean } => {\n const projectConfig = config?.projectConfig;\n const defaultHost =\n getWorkflowServerUrlOverride() || 'https://vercel-workflow.com';\n const customProxyUrl = process.env.WORKFLOW_VERCEL_BACKEND_URL;\n const defaultProxyUrl = 'https://api.vercel.com/v1/workflow';\n // Use proxy when we have project config (for authentication via Vercel API)\n const usingProxy = Boolean(projectConfig?.projectId && projectConfig?.teamId);\n // When using proxy, requests go through api.vercel.com (with x-vercel-workflow-api-url header if override is set)\n // When not using proxy, use the default workflow-server URL (with /api path appended)\n const baseUrl = usingProxy\n ? customProxyUrl || defaultProxyUrl\n : `${defaultHost}/api`;\n return { baseUrl, usingProxy };\n};\n\nexport const getHeaders = (\n config: APIConfig | undefined,\n options: { usingProxy: boolean }\n): Headers => {\n const projectConfig = config?.projectConfig;\n const headers = new Headers(config?.headers);\n headers.set('User-Agent', getUserAgent());\n if (projectConfig) {\n headers.set(\n 'x-vercel-environment',\n projectConfig.environment || 'production'\n );\n if (projectConfig.projectId) {\n headers.set('x-vercel-project-id', projectConfig.projectId);\n }\n if (projectConfig.teamId) {\n headers.set('x-vercel-team-id', projectConfig.teamId);\n }\n }\n // Only set workflow-api-url header when using the proxy, since the proxy\n // forwards it to the workflow-server. When not using proxy, requests go\n // directly to the workflow-server so this header has no effect.\n const workflowServerUrlOverride = getWorkflowServerUrlOverride();\n if (workflowServerUrlOverride && options.usingProxy) {\n headers.set('x-vercel-workflow-api-url', workflowServerUrlOverride);\n }\n for (const [key, value] of Object.entries(getProtectionBypassHeader())) {\n headers.set(key, value);\n }\n return headers;\n};\n\nexport async function getHttpConfig(config?: APIConfig): Promise<HttpConfig> {\n const { baseUrl, usingProxy } = getHttpUrl(config);\n const headers = getHeaders(config, { usingProxy });\n const token = config?.token ?? (await getVercelOidcToken());\n if (token) {\n headers.set('Authorization', `Bearer ${token}`);\n }\n return { baseUrl, headers, usingProxy };\n}\n\nexport async function makeRequest<T>({\n endpoint,\n options = {},\n config = {},\n schema,\n data,\n onResponse,\n}: {\n endpoint: string;\n options?: Omit<RequestInit, 'body'>;\n config?: APIConfig;\n schema: z.ZodSchema<T>;\n /** Request body data - will be CBOR encoded */\n data?: unknown;\n /** Optional callback invoked with the raw Response before body consumption. Use to read response headers. */\n onResponse?: (response: Response) => void;\n}): Promise<T> {\n const method = options.method || 'GET';\n const { baseUrl, headers } = await getHttpConfig(config);\n const url = `${baseUrl}${endpoint}`;\n\n // Parse server address and port from URL for OTEL attributes\n let serverAddress: string | undefined;\n let serverPort: number | undefined;\n try {\n const parsedUrl = new URL(url);\n serverAddress = parsedUrl.hostname;\n serverPort = parsedUrl.port\n ? parseInt(parsedUrl.port, 10)\n : parsedUrl.protocol === 'https:'\n ? 443\n : 80;\n } catch {\n // URL parsing failed, skip these attributes\n }\n\n // Standard OTEL span name for HTTP client: \"{method}\"\n // See: https://opentelemetry.io/docs/specs/semconv/http/http-spans/#name\n return trace(\n `http ${method}`,\n { kind: await getSpanKind('CLIENT') },\n async (span) => {\n // Set standard OTEL HTTP client attributes\n span?.setAttributes({\n ...HttpRequestMethod(method),\n ...UrlFull(url),\n ...(serverAddress && ServerAddress(serverAddress)),\n ...(serverPort && ServerPort(serverPort)),\n // Peer service for Datadog service maps\n ...PeerService('workflow-server'),\n ...RpcSystem('http'),\n ...RpcService('workflow-server'),\n });\n\n headers.set('Accept', 'application/cbor');\n // NOTE: Add a unique header to bypass RSC request memoization.\n // See: https://github.com/vercel/workflow/issues/618\n headers.set('X-Request-Time', Date.now().toString());\n\n // Encode body as CBOR if data is provided\n let body: Buffer | undefined;\n if (data !== undefined) {\n headers.set('Content-Type', 'application/cbor');\n body = encode(data);\n }\n\n const request = new Request(url, {\n ...options,\n body,\n headers,\n });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici v7 dispatcher types don't match @types/node's RequestInit\n const fetchStart = Date.now();\n const response = await fetch(request, {\n dispatcher: getDispatcher(),\n } as any);\n const fetchMs = Date.now() - fetchStart;\n\n httpLog(method, endpoint, response.status, fetchMs);\n\n span?.setAttributes({\n ...HttpResponseStatusCode(response.status),\n });\n\n if (!response.ok) {\n const errorData: { message?: string; code?: string } =\n await parseResponseBody(response)\n .then((r) => r.data as { message?: string; code?: string })\n .catch(() => ({}));\n if (process.env.DEBUG) {\n const stringifiedHeaders = Array.from(headers.entries())\n .filter(([key]) => key.toLowerCase() !== 'authorization')\n .map(([key, value]: [string, string]) => `-H \"${key}: ${value}\"`)\n .join(' ');\n console.error(\n `Failed to fetch, reproduce with:\\ncurl -X ${request.method} ${stringifiedHeaders} \"${url}\"`\n );\n }\n\n // Parse Retry-After header (value is in seconds).\n // Used by both 425 (TooEarlyError) and 429 (ThrottleError).\n // Note: RetryAgent handles most 429 retries automatically, but this\n // catches the case where retries are exhausted.\n let retryAfter: number | undefined;\n const retryAfterHeader = response.headers.get('Retry-After');\n if (retryAfterHeader) {\n const parsed = parseInt(retryAfterHeader, 10);\n if (!Number.isNaN(parsed)) {\n retryAfter = parsed;\n }\n }\n\n const defaultMessage =\n errorData.message ||\n `${request.method} ${endpoint} -> HTTP ${response.status}: ${response.statusText}`;\n\n // Map specific HTTP status codes to semantic error types\n const throwWithTrace = (error: Error): never => {\n span?.setAttributes({\n ...ErrorType(errorData.code || `HTTP ${response.status}`),\n });\n span?.recordException?.(error);\n throw error;\n };\n\n if (response.status === 409) {\n throwWithTrace(new EntityConflictError(defaultMessage));\n }\n if (response.status === 410) {\n throwWithTrace(new RunExpiredError(defaultMessage));\n }\n if (response.status === 425) {\n throwWithTrace(new TooEarlyError(defaultMessage, { retryAfter }));\n }\n if (response.status === 429) {\n throwWithTrace(new ThrottleError(defaultMessage, { retryAfter }));\n }\n\n throwWithTrace(\n new WorkflowWorldError(defaultMessage, {\n url,\n status: response.status,\n code: errorData.code,\n retryAfter,\n })\n );\n }\n\n // Expose response headers to caller before consuming the body\n onResponse?.(response);\n\n // Parse the response body (CBOR or JSON) with tracing\n let parseResult: ParseResult;\n try {\n parseResult = await trace('world.parse', async (parseSpan) => {\n const result = await parseResponseBody(response);\n // Extract format and size from debug context for attributes\n const contentType = response.headers.get('Content-Type') || '';\n const isCbor = contentType.includes('application/cbor');\n parseSpan?.setAttributes({\n ...WorldParseFormat(isCbor ? 'cbor' : 'json'),\n });\n return result;\n });\n } catch (error) {\n const contentType = response.headers.get('Content-Type') || 'unknown';\n throw new WorkflowWorldError(\n `Failed to parse response body for ${request.method} ${endpoint} (Content-Type: ${contentType}):\\n\\n${error}`,\n { url, cause: error }\n );\n }\n\n // Validate against the schema with tracing\n const result = await trace('world.validate', async () => {\n const validationResult = schema.safeParse(parseResult.data);\n if (!validationResult.success) {\n const issues = validationResult.error.issues\n .map(\n (i) =>\n ` ${i.path.length > 0 ? i.path.join('.') : '<root>'}: ${i.message}`\n )\n .join('\\n');\n const debugContext = process.env.DEBUG\n ? `\\n\\nResponse context: ${parseResult.getDebugContext()}`\n : '';\n throw new WorkflowWorldError(\n `Schema validation failed for ${method} ${endpoint}:\\n${issues}${debugContext}`,\n { url, cause: validationResult.error }\n );\n }\n return validationResult.data;\n });\n\n return result;\n }\n );\n}\n\ninterface ParseResult {\n data: unknown;\n /** Lazily generates debug context for error messages (only called on failure) */\n getDebugContext: () => string;\n}\n\n/** Max length for response preview in error messages */\nconst MAX_PREVIEW_LENGTH = 500;\n\n/**\n * Create a truncated preview of data for error messages.\n */\nfunction createPreview(data: unknown): string {\n const str = inspect(data, { depth: 3, maxArrayLength: 10, breakLength: 120 });\n return str.length > MAX_PREVIEW_LENGTH\n ? `${str.slice(0, MAX_PREVIEW_LENGTH)}...`\n : str;\n}\n\n/**\n * Parse response body based on Content-Type header.\n * Supports both CBOR and JSON responses.\n * Returns parsed data along with a lazy debug context generator for error reporting.\n */\nasync function parseResponseBody(response: Response): Promise<ParseResult> {\n const contentType = response.headers.get('Content-Type') || '';\n\n if (contentType.includes('application/cbor')) {\n const buffer = await response.arrayBuffer();\n const data = decode(new Uint8Array(buffer));\n return {\n data,\n getDebugContext: () =>\n `Content-Type: ${contentType}, ${buffer.byteLength} bytes (CBOR), preview: ${createPreview(data)}`,\n };\n }\n\n // Fall back to JSON parsing\n const text = await response.text();\n const data = JSON.parse(text);\n return {\n data,\n getDebugContext: () =>\n `Content-Type: ${contentType}, ${text.length} bytes, preview: ${createPreview(data)}`,\n };\n}\n"]}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "5.0.0-beta.
|
|
1
|
+
export declare const version = "5.0.0-beta.3";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '5.0.0-beta.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '5.0.0-beta.3'\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workflow/world-vercel",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.3",
|
|
4
4
|
"description": "Vercel platform World implementation for Workflow SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"cbor-x": "1.6.0",
|
|
29
29
|
"undici": "7.22.0",
|
|
30
30
|
"zod": "4.3.6",
|
|
31
|
-
"@workflow/
|
|
32
|
-
"@workflow/
|
|
31
|
+
"@workflow/world": "5.0.0-beta.1",
|
|
32
|
+
"@workflow/errors": "5.0.0-beta.1"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@opentelemetry/api": "1"
|