@upstash/workflow 1.0.0 → 1.1.0-rc
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/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +173 -23
- package/astro.mjs +1 -1
- package/{chunk-5GWDM6XJ.mjs → chunk-2Z32SOYM.mjs} +175 -23
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +173 -23
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +173 -23
- package/express.mjs +1 -1
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +173 -23
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +173 -23
- package/hono.mjs +1 -1
- package/index.d.mts +28 -3
- package/index.d.ts +28 -3
- package/index.js +175 -30
- package/index.mjs +1 -6
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +173 -23
- package/nextjs.mjs +1 -1
- package/package.json +1 -1
- package/{serve-many-qpxb-yr-.d.mts → serve-many-DhB8-zPD.d.mts} +1 -1
- package/{serve-many-CFlNO2Iq.d.ts → serve-many-qnfynN1x.d.ts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +173 -23
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +173 -23
- package/svelte.mjs +1 -1
- package/tanstack.d.mts +2 -2
- package/tanstack.d.ts +2 -2
- package/tanstack.js +173 -23
- package/tanstack.mjs +1 -1
- package/{types-ByzQdZjb.d.ts → types-pEje3VEB.d.mts} +8 -3
- package/{types-ByzQdZjb.d.mts → types-pEje3VEB.d.ts} +8 -3
package/astro.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { APIContext, APIRoute } from 'astro';
|
|
2
|
-
import {
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { j as WorkflowContext, d as WorkflowServeOptions, x as InvokableWorkflow } from './types-pEje3VEB.mjs';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-DhB8-zPD.mjs';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
package/astro.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { APIContext, APIRoute } from 'astro';
|
|
2
|
-
import {
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { j as WorkflowContext, d as WorkflowServeOptions, x as InvokableWorkflow } from './types-pEje3VEB.js';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-qnfynN1x.js';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
package/astro.js
CHANGED
|
@@ -841,7 +841,7 @@ var recreateUserHeaders = (headers) => {
|
|
|
841
841
|
const pairs = headers.entries();
|
|
842
842
|
for (const [header, value] of pairs) {
|
|
843
843
|
const headerLowerCase = header.toLowerCase();
|
|
844
|
-
const isUserHeader = !headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
|
|
844
|
+
const isUserHeader = headerLowerCase !== "upstash-region" && !headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
|
|
845
845
|
!headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && // https://blog.cloudflare.com/preventing-request-loops-using-cdn-loop/
|
|
846
846
|
headerLowerCase !== "cf-connecting-ip" && headerLowerCase !== "cdn-loop" && headerLowerCase !== "cf-ew-via" && headerLowerCase !== "cf-ray" && // For Render https://render.com
|
|
847
847
|
headerLowerCase !== "render-proxy-ttl" || headerLowerCase === WORKFLOW_LABEL_HEADER.toLocaleLowerCase();
|
|
@@ -3213,9 +3213,154 @@ var handleFailure = async ({
|
|
|
3213
3213
|
}
|
|
3214
3214
|
};
|
|
3215
3215
|
|
|
3216
|
-
// src/serve/
|
|
3216
|
+
// src/serve/multi-region/handlers.ts
|
|
3217
3217
|
var import_qstash10 = require("@upstash/qstash");
|
|
3218
|
-
|
|
3218
|
+
|
|
3219
|
+
// src/serve/multi-region/utils.ts
|
|
3220
|
+
var VALID_REGIONS = ["EU_CENTRAL_1", "US_EAST_1"];
|
|
3221
|
+
var getRegionFromEnvironment = (environment) => {
|
|
3222
|
+
const region = environment.QSTASH_REGION;
|
|
3223
|
+
return normalizeRegionHeader(region);
|
|
3224
|
+
};
|
|
3225
|
+
function readEnvironmentVariables(environmentVariables, environment, region) {
|
|
3226
|
+
const result = {};
|
|
3227
|
+
for (const variable of environmentVariables) {
|
|
3228
|
+
const key = region ? `${region}_${variable}` : variable;
|
|
3229
|
+
result[variable] = environment[key];
|
|
3230
|
+
}
|
|
3231
|
+
return result;
|
|
3232
|
+
}
|
|
3233
|
+
function readClientEnvironmentVariables(environment, region) {
|
|
3234
|
+
return readEnvironmentVariables(["QSTASH_URL", "QSTASH_TOKEN"], environment, region);
|
|
3235
|
+
}
|
|
3236
|
+
function readReceiverEnvironmentVariables(environment, region) {
|
|
3237
|
+
return readEnvironmentVariables(
|
|
3238
|
+
["QSTASH_CURRENT_SIGNING_KEY", "QSTASH_NEXT_SIGNING_KEY"],
|
|
3239
|
+
environment,
|
|
3240
|
+
region
|
|
3241
|
+
);
|
|
3242
|
+
}
|
|
3243
|
+
function normalizeRegionHeader(region) {
|
|
3244
|
+
if (!region) {
|
|
3245
|
+
return void 0;
|
|
3246
|
+
}
|
|
3247
|
+
region = region.replaceAll("-", "_").toUpperCase();
|
|
3248
|
+
if (VALID_REGIONS.includes(region)) {
|
|
3249
|
+
return region;
|
|
3250
|
+
}
|
|
3251
|
+
console.warn(
|
|
3252
|
+
`[Upstash Workflow] Invalid UPSTASH-REGION header value: "${region}". Expected one of: ${VALID_REGIONS.join(
|
|
3253
|
+
", "
|
|
3254
|
+
)}.`
|
|
3255
|
+
);
|
|
3256
|
+
return void 0;
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
// src/serve/multi-region/handlers.ts
|
|
3260
|
+
var getHandlersForRequest = (qstashHandlers, regionHeader, isFirstInvocation) => {
|
|
3261
|
+
if (qstashHandlers.mode === "single-region") {
|
|
3262
|
+
return qstashHandlers.handlers;
|
|
3263
|
+
}
|
|
3264
|
+
let targetRegion;
|
|
3265
|
+
if (isFirstInvocation) {
|
|
3266
|
+
targetRegion = qstashHandlers.defaultRegion;
|
|
3267
|
+
} else {
|
|
3268
|
+
const normalizedRegion = regionHeader ? normalizeRegionHeader(regionHeader) : void 0;
|
|
3269
|
+
targetRegion = normalizedRegion ?? qstashHandlers.defaultRegion;
|
|
3270
|
+
}
|
|
3271
|
+
const handler = qstashHandlers.handlers[targetRegion];
|
|
3272
|
+
if (!handler) {
|
|
3273
|
+
console.warn(
|
|
3274
|
+
`[Upstash Workflow] No handler found for region "${targetRegion}". Falling back to default region.`
|
|
3275
|
+
);
|
|
3276
|
+
return qstashHandlers.handlers[qstashHandlers.defaultRegion];
|
|
3277
|
+
}
|
|
3278
|
+
return handler;
|
|
3279
|
+
};
|
|
3280
|
+
var createRegionalHandler = (environment, receiverConfig, region, clientOptions) => {
|
|
3281
|
+
const clientEnv = readClientEnvironmentVariables(environment, region);
|
|
3282
|
+
const client = new import_qstash10.Client({
|
|
3283
|
+
...clientOptions,
|
|
3284
|
+
baseUrl: clientEnv.QSTASH_URL,
|
|
3285
|
+
token: clientEnv.QSTASH_TOKEN
|
|
3286
|
+
});
|
|
3287
|
+
const receiver = getReceiver(environment, receiverConfig, region);
|
|
3288
|
+
return { client, receiver };
|
|
3289
|
+
};
|
|
3290
|
+
var shouldUseMultiRegionMode = (environment, qstashClientOption) => {
|
|
3291
|
+
const hasRegionEnv = Boolean(getRegionFromEnvironment(environment));
|
|
3292
|
+
if (hasRegionEnv && (!qstashClientOption || !("http" in qstashClientOption))) {
|
|
3293
|
+
return {
|
|
3294
|
+
isMultiRegion: true,
|
|
3295
|
+
defaultRegion: getRegionFromEnvironment(environment),
|
|
3296
|
+
clientOptions: qstashClientOption
|
|
3297
|
+
};
|
|
3298
|
+
} else {
|
|
3299
|
+
return { isMultiRegion: false };
|
|
3300
|
+
}
|
|
3301
|
+
};
|
|
3302
|
+
var getQStashHandlers = ({
|
|
3303
|
+
environment,
|
|
3304
|
+
qstashClientOption,
|
|
3305
|
+
receiverConfig
|
|
3306
|
+
}) => {
|
|
3307
|
+
const multiRegion = shouldUseMultiRegionMode(environment, qstashClientOption);
|
|
3308
|
+
if (multiRegion.isMultiRegion) {
|
|
3309
|
+
const regions = ["US_EAST_1", "EU_CENTRAL_1"];
|
|
3310
|
+
const handlers = {};
|
|
3311
|
+
for (const region of regions) {
|
|
3312
|
+
try {
|
|
3313
|
+
handlers[region] = createRegionalHandler(
|
|
3314
|
+
environment,
|
|
3315
|
+
receiverConfig,
|
|
3316
|
+
region,
|
|
3317
|
+
multiRegion.clientOptions
|
|
3318
|
+
);
|
|
3319
|
+
} catch (error) {
|
|
3320
|
+
console.warn(`[Upstash Workflow] Failed to create handler for region ${region}:`, error);
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
return {
|
|
3324
|
+
mode: "multi-region",
|
|
3325
|
+
handlers,
|
|
3326
|
+
defaultRegion: multiRegion.defaultRegion
|
|
3327
|
+
};
|
|
3328
|
+
} else {
|
|
3329
|
+
return {
|
|
3330
|
+
mode: "single-region",
|
|
3331
|
+
handlers: {
|
|
3332
|
+
client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new import_qstash10.Client({
|
|
3333
|
+
...qstashClientOption,
|
|
3334
|
+
baseUrl: environment.QSTASH_URL,
|
|
3335
|
+
token: environment.QSTASH_TOKEN
|
|
3336
|
+
}),
|
|
3337
|
+
receiver: getReceiver(environment, receiverConfig)
|
|
3338
|
+
}
|
|
3339
|
+
};
|
|
3340
|
+
}
|
|
3341
|
+
};
|
|
3342
|
+
var getReceiver = (environment, receiverConfig, region) => {
|
|
3343
|
+
if (typeof receiverConfig === "string") {
|
|
3344
|
+
if (receiverConfig === "set-to-undefined") {
|
|
3345
|
+
return void 0;
|
|
3346
|
+
}
|
|
3347
|
+
const receiverEnv = readReceiverEnvironmentVariables(environment, region);
|
|
3348
|
+
return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash10.Receiver({
|
|
3349
|
+
currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
|
|
3350
|
+
nextSigningKey: receiverEnv.QSTASH_NEXT_SIGNING_KEY
|
|
3351
|
+
}) : void 0;
|
|
3352
|
+
} else {
|
|
3353
|
+
return receiverConfig;
|
|
3354
|
+
}
|
|
3355
|
+
};
|
|
3356
|
+
var getQStashHandlerOptions = (...params) => {
|
|
3357
|
+
const handlers = getQStashHandlers(...params);
|
|
3358
|
+
return {
|
|
3359
|
+
qstashHandlers: handlers,
|
|
3360
|
+
defaultReceiver: handlers.mode === "single-region" ? handlers.handlers.receiver : handlers.handlers[handlers.defaultRegion].receiver,
|
|
3361
|
+
defaultClient: handlers.mode === "single-region" ? handlers.handlers.client : handlers.handlers[handlers.defaultRegion].client
|
|
3362
|
+
};
|
|
3363
|
+
};
|
|
3219
3364
|
|
|
3220
3365
|
// src/middleware/middleware.ts
|
|
3221
3366
|
var WorkflowMiddleware = class {
|
|
@@ -3354,14 +3499,17 @@ var createResponseData = (workflowRunId, detailedFinishCondition) => {
|
|
|
3354
3499
|
};
|
|
3355
3500
|
var processOptions = (options, internalOptions) => {
|
|
3356
3501
|
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
3357
|
-
const
|
|
3358
|
-
|
|
3359
|
-
|
|
3502
|
+
const {
|
|
3503
|
+
qstashHandlers,
|
|
3504
|
+
defaultClient: qstashClient,
|
|
3505
|
+
defaultReceiver: receiver
|
|
3506
|
+
} = getQStashHandlerOptions({
|
|
3507
|
+
environment,
|
|
3508
|
+
qstashClientOption: options?.qstashClient,
|
|
3509
|
+
receiverConfig: options && "receiver" in options ? options.receiver ? options.receiver : "set-to-undefined" : "not-set"
|
|
3510
|
+
});
|
|
3360
3511
|
return {
|
|
3361
|
-
qstashClient
|
|
3362
|
-
baseUrl: environment.QSTASH_URL,
|
|
3363
|
-
token: environment.QSTASH_TOKEN
|
|
3364
|
-
}),
|
|
3512
|
+
qstashClient,
|
|
3365
3513
|
initialPayloadParser: (initialRequest) => {
|
|
3366
3514
|
if (!initialRequest) {
|
|
3367
3515
|
return void 0;
|
|
@@ -3376,10 +3524,7 @@ var processOptions = (options, internalOptions) => {
|
|
|
3376
3524
|
throw error;
|
|
3377
3525
|
}
|
|
3378
3526
|
},
|
|
3379
|
-
receiver
|
|
3380
|
-
currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
|
|
3381
|
-
nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
|
|
3382
|
-
}) : void 0,
|
|
3527
|
+
receiver,
|
|
3383
3528
|
baseUrl: environment.UPSTASH_WORKFLOW_URL,
|
|
3384
3529
|
env: environment,
|
|
3385
3530
|
disableTelemetry: false,
|
|
@@ -3393,7 +3538,8 @@ var processOptions = (options, internalOptions) => {
|
|
|
3393
3538
|
headers: responseData.headers
|
|
3394
3539
|
});
|
|
3395
3540
|
}),
|
|
3396
|
-
useJSONContent: internalOptions?.useJSONContent ?? false
|
|
3541
|
+
useJSONContent: internalOptions?.useJSONContent ?? false,
|
|
3542
|
+
qstashHandlers
|
|
3397
3543
|
}
|
|
3398
3544
|
};
|
|
3399
3545
|
};
|
|
@@ -3426,10 +3572,8 @@ var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is une
|
|
|
3426
3572
|
// src/serve/index.ts
|
|
3427
3573
|
var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
|
|
3428
3574
|
const {
|
|
3429
|
-
qstashClient,
|
|
3430
3575
|
initialPayloadParser,
|
|
3431
3576
|
url,
|
|
3432
|
-
receiver,
|
|
3433
3577
|
failureFunction,
|
|
3434
3578
|
baseUrl,
|
|
3435
3579
|
env,
|
|
@@ -3449,9 +3593,15 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
|
|
|
3449
3593
|
baseUrl,
|
|
3450
3594
|
middlewareManager.dispatchDebug.bind(middlewareManager)
|
|
3451
3595
|
);
|
|
3452
|
-
const requestPayload = await getPayload(request) ?? "";
|
|
3453
|
-
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
|
|
3454
3596
|
const { isFirstInvocation, workflowRunId, unknownSdk } = validateRequest(request);
|
|
3597
|
+
const regionHeader = request.headers.get("upstash-region");
|
|
3598
|
+
const { client: regionalClient, receiver: regionalReceiver } = getHandlersForRequest(
|
|
3599
|
+
internal.qstashHandlers,
|
|
3600
|
+
regionHeader,
|
|
3601
|
+
isFirstInvocation
|
|
3602
|
+
);
|
|
3603
|
+
const requestPayload = await getPayload(request) ?? "";
|
|
3604
|
+
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), regionalReceiver);
|
|
3455
3605
|
middlewareManager.assignWorkflowRunId(workflowRunId);
|
|
3456
3606
|
await middlewareManager.dispatchDebug("onInfo", {
|
|
3457
3607
|
info: `Run id identified. isFirstInvocation: ${isFirstInvocation}, unknownSdk: ${unknownSdk}`
|
|
@@ -3461,7 +3611,7 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
|
|
|
3461
3611
|
isFirstInvocation,
|
|
3462
3612
|
unknownSdk,
|
|
3463
3613
|
workflowRunId,
|
|
3464
|
-
requester:
|
|
3614
|
+
requester: regionalClient.http,
|
|
3465
3615
|
messageId: request.headers.get("upstash-message-id"),
|
|
3466
3616
|
dispatchDebug: middlewareManager.dispatchDebug.bind(middlewareManager)
|
|
3467
3617
|
});
|
|
@@ -3482,7 +3632,7 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
|
|
|
3482
3632
|
const failureCheck = await handleFailure({
|
|
3483
3633
|
request,
|
|
3484
3634
|
requestPayload,
|
|
3485
|
-
qstashClient,
|
|
3635
|
+
qstashClient: regionalClient,
|
|
3486
3636
|
initialPayloadParser,
|
|
3487
3637
|
routeFunction,
|
|
3488
3638
|
failureFunction,
|
|
@@ -3514,7 +3664,7 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
|
|
|
3514
3664
|
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
3515
3665
|
const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
|
|
3516
3666
|
const workflowContext = new WorkflowContext({
|
|
3517
|
-
qstashClient,
|
|
3667
|
+
qstashClient: regionalClient,
|
|
3518
3668
|
workflowRunId,
|
|
3519
3669
|
initialPayload: initialPayloadParser(rawInitialPayload),
|
|
3520
3670
|
headers: recreateUserHeaders(request.headers),
|
|
@@ -3545,7 +3695,7 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
|
|
|
3545
3695
|
const callReturnCheck = await handleThirdPartyCallResult({
|
|
3546
3696
|
request,
|
|
3547
3697
|
requestPayload: rawInitialPayload,
|
|
3548
|
-
client:
|
|
3698
|
+
client: regionalClient,
|
|
3549
3699
|
workflowUrl,
|
|
3550
3700
|
telemetry: telemetry2,
|
|
3551
3701
|
middlewareManager
|
package/astro.mjs
CHANGED
|
@@ -893,7 +893,7 @@ var recreateUserHeaders = (headers) => {
|
|
|
893
893
|
const pairs = headers.entries();
|
|
894
894
|
for (const [header, value] of pairs) {
|
|
895
895
|
const headerLowerCase = header.toLowerCase();
|
|
896
|
-
const isUserHeader = !headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
|
|
896
|
+
const isUserHeader = headerLowerCase !== "upstash-region" && !headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
|
|
897
897
|
!headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && // https://blog.cloudflare.com/preventing-request-loops-using-cdn-loop/
|
|
898
898
|
headerLowerCase !== "cf-connecting-ip" && headerLowerCase !== "cdn-loop" && headerLowerCase !== "cf-ew-via" && headerLowerCase !== "cf-ray" && // For Render https://render.com
|
|
899
899
|
headerLowerCase !== "render-proxy-ttl" || headerLowerCase === WORKFLOW_LABEL_HEADER.toLocaleLowerCase();
|
|
@@ -3264,9 +3264,156 @@ var handleFailure = async ({
|
|
|
3264
3264
|
}
|
|
3265
3265
|
};
|
|
3266
3266
|
|
|
3267
|
+
// src/serve/multi-region/handlers.ts
|
|
3268
|
+
import { Client as Client3, Receiver } from "@upstash/qstash";
|
|
3269
|
+
|
|
3270
|
+
// src/serve/multi-region/utils.ts
|
|
3271
|
+
var VALID_REGIONS = ["EU_CENTRAL_1", "US_EAST_1"];
|
|
3272
|
+
var getRegionFromEnvironment = (environment) => {
|
|
3273
|
+
const region = environment.QSTASH_REGION;
|
|
3274
|
+
return normalizeRegionHeader(region);
|
|
3275
|
+
};
|
|
3276
|
+
function readEnvironmentVariables(environmentVariables, environment, region) {
|
|
3277
|
+
const result = {};
|
|
3278
|
+
for (const variable of environmentVariables) {
|
|
3279
|
+
const key = region ? `${region}_${variable}` : variable;
|
|
3280
|
+
result[variable] = environment[key];
|
|
3281
|
+
}
|
|
3282
|
+
return result;
|
|
3283
|
+
}
|
|
3284
|
+
function readClientEnvironmentVariables(environment, region) {
|
|
3285
|
+
return readEnvironmentVariables(["QSTASH_URL", "QSTASH_TOKEN"], environment, region);
|
|
3286
|
+
}
|
|
3287
|
+
function readReceiverEnvironmentVariables(environment, region) {
|
|
3288
|
+
return readEnvironmentVariables(
|
|
3289
|
+
["QSTASH_CURRENT_SIGNING_KEY", "QSTASH_NEXT_SIGNING_KEY"],
|
|
3290
|
+
environment,
|
|
3291
|
+
region
|
|
3292
|
+
);
|
|
3293
|
+
}
|
|
3294
|
+
function normalizeRegionHeader(region) {
|
|
3295
|
+
if (!region) {
|
|
3296
|
+
return void 0;
|
|
3297
|
+
}
|
|
3298
|
+
region = region.replaceAll("-", "_").toUpperCase();
|
|
3299
|
+
if (VALID_REGIONS.includes(region)) {
|
|
3300
|
+
return region;
|
|
3301
|
+
}
|
|
3302
|
+
console.warn(
|
|
3303
|
+
`[Upstash Workflow] Invalid UPSTASH-REGION header value: "${region}". Expected one of: ${VALID_REGIONS.join(
|
|
3304
|
+
", "
|
|
3305
|
+
)}.`
|
|
3306
|
+
);
|
|
3307
|
+
return void 0;
|
|
3308
|
+
}
|
|
3309
|
+
|
|
3310
|
+
// src/serve/multi-region/handlers.ts
|
|
3311
|
+
var getHandlersForRequest = (qstashHandlers, regionHeader, isFirstInvocation) => {
|
|
3312
|
+
if (qstashHandlers.mode === "single-region") {
|
|
3313
|
+
return qstashHandlers.handlers;
|
|
3314
|
+
}
|
|
3315
|
+
let targetRegion;
|
|
3316
|
+
if (isFirstInvocation) {
|
|
3317
|
+
targetRegion = qstashHandlers.defaultRegion;
|
|
3318
|
+
} else {
|
|
3319
|
+
const normalizedRegion = regionHeader ? normalizeRegionHeader(regionHeader) : void 0;
|
|
3320
|
+
targetRegion = normalizedRegion ?? qstashHandlers.defaultRegion;
|
|
3321
|
+
}
|
|
3322
|
+
const handler = qstashHandlers.handlers[targetRegion];
|
|
3323
|
+
if (!handler) {
|
|
3324
|
+
console.warn(
|
|
3325
|
+
`[Upstash Workflow] No handler found for region "${targetRegion}". Falling back to default region.`
|
|
3326
|
+
);
|
|
3327
|
+
return qstashHandlers.handlers[qstashHandlers.defaultRegion];
|
|
3328
|
+
}
|
|
3329
|
+
return handler;
|
|
3330
|
+
};
|
|
3331
|
+
var createRegionalHandler = (environment, receiverConfig, region, clientOptions) => {
|
|
3332
|
+
const clientEnv = readClientEnvironmentVariables(environment, region);
|
|
3333
|
+
const client = new Client3({
|
|
3334
|
+
...clientOptions,
|
|
3335
|
+
baseUrl: clientEnv.QSTASH_URL,
|
|
3336
|
+
token: clientEnv.QSTASH_TOKEN
|
|
3337
|
+
});
|
|
3338
|
+
const receiver = getReceiver(environment, receiverConfig, region);
|
|
3339
|
+
return { client, receiver };
|
|
3340
|
+
};
|
|
3341
|
+
var shouldUseMultiRegionMode = (environment, qstashClientOption) => {
|
|
3342
|
+
const hasRegionEnv = Boolean(getRegionFromEnvironment(environment));
|
|
3343
|
+
if (hasRegionEnv && (!qstashClientOption || !("http" in qstashClientOption))) {
|
|
3344
|
+
return {
|
|
3345
|
+
isMultiRegion: true,
|
|
3346
|
+
defaultRegion: getRegionFromEnvironment(environment),
|
|
3347
|
+
clientOptions: qstashClientOption
|
|
3348
|
+
};
|
|
3349
|
+
} else {
|
|
3350
|
+
return { isMultiRegion: false };
|
|
3351
|
+
}
|
|
3352
|
+
};
|
|
3353
|
+
var getQStashHandlers = ({
|
|
3354
|
+
environment,
|
|
3355
|
+
qstashClientOption,
|
|
3356
|
+
receiverConfig
|
|
3357
|
+
}) => {
|
|
3358
|
+
const multiRegion = shouldUseMultiRegionMode(environment, qstashClientOption);
|
|
3359
|
+
if (multiRegion.isMultiRegion) {
|
|
3360
|
+
const regions = ["US_EAST_1", "EU_CENTRAL_1"];
|
|
3361
|
+
const handlers = {};
|
|
3362
|
+
for (const region of regions) {
|
|
3363
|
+
try {
|
|
3364
|
+
handlers[region] = createRegionalHandler(
|
|
3365
|
+
environment,
|
|
3366
|
+
receiverConfig,
|
|
3367
|
+
region,
|
|
3368
|
+
multiRegion.clientOptions
|
|
3369
|
+
);
|
|
3370
|
+
} catch (error) {
|
|
3371
|
+
console.warn(`[Upstash Workflow] Failed to create handler for region ${region}:`, error);
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
return {
|
|
3375
|
+
mode: "multi-region",
|
|
3376
|
+
handlers,
|
|
3377
|
+
defaultRegion: multiRegion.defaultRegion
|
|
3378
|
+
};
|
|
3379
|
+
} else {
|
|
3380
|
+
return {
|
|
3381
|
+
mode: "single-region",
|
|
3382
|
+
handlers: {
|
|
3383
|
+
client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new Client3({
|
|
3384
|
+
...qstashClientOption,
|
|
3385
|
+
baseUrl: environment.QSTASH_URL,
|
|
3386
|
+
token: environment.QSTASH_TOKEN
|
|
3387
|
+
}),
|
|
3388
|
+
receiver: getReceiver(environment, receiverConfig)
|
|
3389
|
+
}
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
};
|
|
3393
|
+
var getReceiver = (environment, receiverConfig, region) => {
|
|
3394
|
+
if (typeof receiverConfig === "string") {
|
|
3395
|
+
if (receiverConfig === "set-to-undefined") {
|
|
3396
|
+
return void 0;
|
|
3397
|
+
}
|
|
3398
|
+
const receiverEnv = readReceiverEnvironmentVariables(environment, region);
|
|
3399
|
+
return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new Receiver({
|
|
3400
|
+
currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
|
|
3401
|
+
nextSigningKey: receiverEnv.QSTASH_NEXT_SIGNING_KEY
|
|
3402
|
+
}) : void 0;
|
|
3403
|
+
} else {
|
|
3404
|
+
return receiverConfig;
|
|
3405
|
+
}
|
|
3406
|
+
};
|
|
3407
|
+
var getQStashHandlerOptions = (...params) => {
|
|
3408
|
+
const handlers = getQStashHandlers(...params);
|
|
3409
|
+
return {
|
|
3410
|
+
qstashHandlers: handlers,
|
|
3411
|
+
defaultReceiver: handlers.mode === "single-region" ? handlers.handlers.receiver : handlers.handlers[handlers.defaultRegion].receiver,
|
|
3412
|
+
defaultClient: handlers.mode === "single-region" ? handlers.handlers.client : handlers.handlers[handlers.defaultRegion].client
|
|
3413
|
+
};
|
|
3414
|
+
};
|
|
3415
|
+
|
|
3267
3416
|
// src/serve/options.ts
|
|
3268
|
-
import { Receiver } from "@upstash/qstash";
|
|
3269
|
-
import { Client as Client3 } from "@upstash/qstash";
|
|
3270
3417
|
var createResponseData = (workflowRunId, detailedFinishCondition) => {
|
|
3271
3418
|
const baseHeaders = {
|
|
3272
3419
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
|
|
@@ -3329,14 +3476,17 @@ var createResponseData = (workflowRunId, detailedFinishCondition) => {
|
|
|
3329
3476
|
};
|
|
3330
3477
|
var processOptions = (options, internalOptions) => {
|
|
3331
3478
|
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
3332
|
-
const
|
|
3333
|
-
|
|
3334
|
-
|
|
3479
|
+
const {
|
|
3480
|
+
qstashHandlers,
|
|
3481
|
+
defaultClient: qstashClient,
|
|
3482
|
+
defaultReceiver: receiver
|
|
3483
|
+
} = getQStashHandlerOptions({
|
|
3484
|
+
environment,
|
|
3485
|
+
qstashClientOption: options?.qstashClient,
|
|
3486
|
+
receiverConfig: options && "receiver" in options ? options.receiver ? options.receiver : "set-to-undefined" : "not-set"
|
|
3487
|
+
});
|
|
3335
3488
|
return {
|
|
3336
|
-
qstashClient
|
|
3337
|
-
baseUrl: environment.QSTASH_URL,
|
|
3338
|
-
token: environment.QSTASH_TOKEN
|
|
3339
|
-
}),
|
|
3489
|
+
qstashClient,
|
|
3340
3490
|
initialPayloadParser: (initialRequest) => {
|
|
3341
3491
|
if (!initialRequest) {
|
|
3342
3492
|
return void 0;
|
|
@@ -3351,10 +3501,7 @@ var processOptions = (options, internalOptions) => {
|
|
|
3351
3501
|
throw error;
|
|
3352
3502
|
}
|
|
3353
3503
|
},
|
|
3354
|
-
receiver
|
|
3355
|
-
currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
|
|
3356
|
-
nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
|
|
3357
|
-
}) : void 0,
|
|
3504
|
+
receiver,
|
|
3358
3505
|
baseUrl: environment.UPSTASH_WORKFLOW_URL,
|
|
3359
3506
|
env: environment,
|
|
3360
3507
|
disableTelemetry: false,
|
|
@@ -3368,7 +3515,8 @@ var processOptions = (options, internalOptions) => {
|
|
|
3368
3515
|
headers: responseData.headers
|
|
3369
3516
|
});
|
|
3370
3517
|
}),
|
|
3371
|
-
useJSONContent: internalOptions?.useJSONContent ?? false
|
|
3518
|
+
useJSONContent: internalOptions?.useJSONContent ?? false,
|
|
3519
|
+
qstashHandlers
|
|
3372
3520
|
}
|
|
3373
3521
|
};
|
|
3374
3522
|
};
|
|
@@ -3401,10 +3549,8 @@ var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is une
|
|
|
3401
3549
|
// src/serve/index.ts
|
|
3402
3550
|
var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
3403
3551
|
const {
|
|
3404
|
-
qstashClient,
|
|
3405
3552
|
initialPayloadParser,
|
|
3406
3553
|
url,
|
|
3407
|
-
receiver,
|
|
3408
3554
|
failureFunction,
|
|
3409
3555
|
baseUrl,
|
|
3410
3556
|
env,
|
|
@@ -3424,9 +3570,15 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3424
3570
|
baseUrl,
|
|
3425
3571
|
middlewareManager.dispatchDebug.bind(middlewareManager)
|
|
3426
3572
|
);
|
|
3427
|
-
const requestPayload = await getPayload(request) ?? "";
|
|
3428
|
-
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
|
|
3429
3573
|
const { isFirstInvocation, workflowRunId, unknownSdk } = validateRequest(request);
|
|
3574
|
+
const regionHeader = request.headers.get("upstash-region");
|
|
3575
|
+
const { client: regionalClient, receiver: regionalReceiver } = getHandlersForRequest(
|
|
3576
|
+
internal.qstashHandlers,
|
|
3577
|
+
regionHeader,
|
|
3578
|
+
isFirstInvocation
|
|
3579
|
+
);
|
|
3580
|
+
const requestPayload = await getPayload(request) ?? "";
|
|
3581
|
+
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), regionalReceiver);
|
|
3430
3582
|
middlewareManager.assignWorkflowRunId(workflowRunId);
|
|
3431
3583
|
await middlewareManager.dispatchDebug("onInfo", {
|
|
3432
3584
|
info: `Run id identified. isFirstInvocation: ${isFirstInvocation}, unknownSdk: ${unknownSdk}`
|
|
@@ -3436,7 +3588,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3436
3588
|
isFirstInvocation,
|
|
3437
3589
|
unknownSdk,
|
|
3438
3590
|
workflowRunId,
|
|
3439
|
-
requester:
|
|
3591
|
+
requester: regionalClient.http,
|
|
3440
3592
|
messageId: request.headers.get("upstash-message-id"),
|
|
3441
3593
|
dispatchDebug: middlewareManager.dispatchDebug.bind(middlewareManager)
|
|
3442
3594
|
});
|
|
@@ -3457,7 +3609,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3457
3609
|
const failureCheck = await handleFailure({
|
|
3458
3610
|
request,
|
|
3459
3611
|
requestPayload,
|
|
3460
|
-
qstashClient,
|
|
3612
|
+
qstashClient: regionalClient,
|
|
3461
3613
|
initialPayloadParser,
|
|
3462
3614
|
routeFunction,
|
|
3463
3615
|
failureFunction,
|
|
@@ -3489,7 +3641,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3489
3641
|
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
3490
3642
|
const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
|
|
3491
3643
|
const workflowContext = new WorkflowContext({
|
|
3492
|
-
qstashClient,
|
|
3644
|
+
qstashClient: regionalClient,
|
|
3493
3645
|
workflowRunId,
|
|
3494
3646
|
initialPayload: initialPayloadParser(rawInitialPayload),
|
|
3495
3647
|
headers: recreateUserHeaders(request.headers),
|
|
@@ -3520,7 +3672,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3520
3672
|
const callReturnCheck = await handleThirdPartyCallResult({
|
|
3521
3673
|
request,
|
|
3522
3674
|
requestPayload: rawInitialPayload,
|
|
3523
|
-
client:
|
|
3675
|
+
client: regionalClient,
|
|
3524
3676
|
workflowUrl,
|
|
3525
3677
|
telemetry,
|
|
3526
3678
|
middlewareManager
|
package/cloudflare.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { s as serveManyBase } from './serve-many-
|
|
1
|
+
import { c as RouteFunction, d as WorkflowServeOptions, x as InvokableWorkflow } from './types-pEje3VEB.mjs';
|
|
2
|
+
import { s as serveManyBase } from './serve-many-DhB8-zPD.mjs';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
package/cloudflare.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { s as serveManyBase } from './serve-many-
|
|
1
|
+
import { c as RouteFunction, d as WorkflowServeOptions, x as InvokableWorkflow } from './types-pEje3VEB.js';
|
|
2
|
+
import { s as serveManyBase } from './serve-many-qnfynN1x.js';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|