@upstash/workflow 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +10 -0
  2. package/astro.d.mts +2 -2
  3. package/astro.d.ts +2 -2
  4. package/astro.js +31 -5
  5. package/astro.mjs +1 -1
  6. package/{chunk-V5ZUHMAF.mjs → chunk-G24J5PCC.mjs} +93 -5
  7. package/cloudflare.d.mts +2 -2
  8. package/cloudflare.d.ts +2 -2
  9. package/cloudflare.js +31 -5
  10. package/cloudflare.mjs +1 -1
  11. package/express.d.mts +2 -2
  12. package/express.d.ts +2 -2
  13. package/express.js +31 -5
  14. package/express.mjs +1 -1
  15. package/h3.d.mts +2 -2
  16. package/h3.d.ts +2 -2
  17. package/h3.js +31 -5
  18. package/h3.mjs +1 -1
  19. package/hono.d.mts +2 -2
  20. package/hono.d.ts +2 -2
  21. package/hono.js +31 -5
  22. package/hono.mjs +1 -1
  23. package/index.d.mts +201 -128
  24. package/index.d.ts +201 -128
  25. package/index.js +212 -160
  26. package/index.mjs +124 -156
  27. package/nextjs.d.mts +2 -2
  28. package/nextjs.d.ts +2 -2
  29. package/nextjs.js +31 -5
  30. package/nextjs.mjs +1 -1
  31. package/package.json +1 -1
  32. package/react-router.d.mts +2 -2
  33. package/react-router.d.ts +2 -2
  34. package/react-router.js +31 -5
  35. package/react-router.mjs +1 -1
  36. package/{serve-many-C6sa_DxN.d.mts → serve-many-D3D9uE4u.d.mts} +1 -1
  37. package/{serve-many-B-fe7bh7.d.ts → serve-many-kPOasiyb.d.ts} +1 -1
  38. package/solidjs.d.mts +1 -1
  39. package/solidjs.d.ts +1 -1
  40. package/solidjs.js +31 -5
  41. package/solidjs.mjs +1 -1
  42. package/svelte.d.mts +2 -2
  43. package/svelte.d.ts +2 -2
  44. package/svelte.js +31 -5
  45. package/svelte.mjs +1 -1
  46. package/tanstack.d.mts +2 -2
  47. package/tanstack.d.ts +2 -2
  48. package/tanstack.js +31 -5
  49. package/tanstack.mjs +1 -1
  50. package/{types-B2S08hRU.d.ts → types-B_E1VAK6.d.mts} +9 -1
  51. package/{types-B2S08hRU.d.mts → types-B_E1VAK6.d.ts} +9 -1
package/README.md CHANGED
@@ -108,6 +108,16 @@ const result = await client.getWaiters({
108
108
  });
109
109
  ```
110
110
 
111
+ ## Local Development
112
+
113
+ For local development, set `QSTASH_DEV=true` in your environment and the SDK will automatically download and run a local QStash dev server. No tokens or signing keys required: workflow endpoints will verify signatures against the dev server's keys automatically.
114
+
115
+ ```bash .env
116
+ QSTASH_DEV=true
117
+ ```
118
+
119
+ See [Local Development](https://upstash.com/docs/workflow/howto/local-development/development-server) for details.
120
+
111
121
  ## Telemetry
112
122
 
113
123
  This sdk sends anonymous telemetry headers to help us improve your experience.
package/astro.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { APIContext, APIRoute } from 'astro';
2
- import { u as WorkflowContext, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.mjs';
3
- import { s as serveManyBase } from './serve-many-C6sa_DxN.mjs';
2
+ import { u as WorkflowContext, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B_E1VAK6.mjs';
3
+ import { s as serveManyBase } from './serve-many-D3D9uE4u.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 { u as WorkflowContext, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.js';
3
- import { s as serveManyBase } from './serve-many-B-fe7bh7.js';
2
+ import { u as WorkflowContext, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B_E1VAK6.js';
3
+ import { s as serveManyBase } from './serve-many-kPOasiyb.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
 
package/astro.js CHANGED
@@ -192,6 +192,7 @@ var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
192
192
  var WORKFLOW_FAILURE_CALLBACK_HEADER = "Upstash-Workflow-Failure-Callback";
193
193
  var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
194
194
  var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
195
+ var WORKFLOW_RETRIED_HEADER = "Upstash-Retried";
195
196
  var WORKFLOW_LABEL_HEADER = "Upstash-Label";
196
197
  var WORKFLOW_UNKOWN_SDK_VERSION_HEADER = "Upstash-Workflow-Unknown-Sdk";
197
198
  var WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER = "upstash-workflow-trigger-by-sdk";
@@ -200,7 +201,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
200
201
  var DEFAULT_CONTENT_TYPE = "application/json";
201
202
  var NO_CONCURRENCY = 1;
202
203
  var DEFAULT_RETRIES = 3;
203
- var VERSION = "v1.0.0";
204
+ var VERSION = "v1.2.1";
204
205
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
205
206
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
206
207
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -855,6 +856,9 @@ var recreateUserHeaders = (headers) => {
855
856
  }
856
857
  return filteredHeaders;
857
858
  };
859
+ var isThirdPartyCallResult = (request) => {
860
+ return request.headers.get("Upstash-Workflow-Callback") !== null;
861
+ };
858
862
  var handleThirdPartyCallResult = async ({
859
863
  request,
860
864
  requestPayload,
@@ -864,7 +868,7 @@ var handleThirdPartyCallResult = async ({
864
868
  middlewareManager
865
869
  }) => {
866
870
  try {
867
- if (request.headers.get("Upstash-Workflow-Callback")) {
871
+ if (isThirdPartyCallResult(request)) {
868
872
  let callbackPayload;
869
873
  if (requestPayload) {
870
874
  callbackPayload = requestPayload;
@@ -2707,6 +2711,13 @@ var WorkflowContext = class {
2707
2711
  * ```
2708
2712
  */
2709
2713
  label;
2714
+ /**
2715
+ * Number of times QStash has retried delivering the current request.
2716
+ *
2717
+ * Sourced from the `Upstash-Retried` header. `0` on the first delivery,
2718
+ * `1` on the first retry, `2` on the second, and so on.
2719
+ */
2720
+ retried;
2710
2721
  constructor({
2711
2722
  qstashClient,
2712
2723
  workflowRunId,
@@ -2719,6 +2730,7 @@ var WorkflowContext = class {
2719
2730
  telemetry: telemetry2,
2720
2731
  invokeCount,
2721
2732
  label,
2733
+ retried,
2722
2734
  middlewareManager
2723
2735
  }) {
2724
2736
  this.qstashClient = qstashClient;
@@ -2730,6 +2742,7 @@ var WorkflowContext = class {
2730
2742
  this.requestPayload = initialPayload;
2731
2743
  this.env = env ?? {};
2732
2744
  this.label = label;
2745
+ this.retried = retried ?? 0;
2733
2746
  const middlewareManagerInstance = middlewareManager ?? new MiddlewareManager([]);
2734
2747
  middlewareManagerInstance.assignContext(this);
2735
2748
  this.executor = new AutoExecutor(
@@ -2993,7 +3006,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
2993
3006
  const disabledContext = new _DisabledWorkflowContext({
2994
3007
  qstashClient: new import_qstash10.Client({
2995
3008
  baseUrl: "disabled-client",
2996
- token: "disabled-client"
3009
+ token: "disabled-client",
3010
+ devMode: false
2997
3011
  }),
2998
3012
  workflowRunId: context.workflowRunId,
2999
3013
  workflowRunCreatedAt: context.workflowRunCreatedAt,
@@ -3002,7 +3016,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3002
3016
  url: context.url,
3003
3017
  initialPayload: context.requestPayload,
3004
3018
  env: context.env,
3005
- label: context.label
3019
+ label: context.label,
3020
+ retried: context.retried
3006
3021
  });
3007
3022
  try {
3008
3023
  await routeFunction(disabledContext);
@@ -3218,6 +3233,7 @@ var handleFailure = async ({
3218
3233
  errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
3219
3234
  }
3220
3235
  const userHeaders = recreateUserHeaders(request.headers);
3236
+ const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
3221
3237
  const workflowContext = new WorkflowContext({
3222
3238
  qstashClient,
3223
3239
  workflowRunId,
@@ -3229,6 +3245,7 @@ var handleFailure = async ({
3229
3245
  telemetry: void 0,
3230
3246
  // not going to make requests in authentication check
3231
3247
  label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0,
3248
+ retried,
3232
3249
  workflowRunCreatedAt: workflowCreatedAt,
3233
3250
  middlewareManager: void 0
3234
3251
  });
@@ -3388,6 +3405,9 @@ var getReceiver = (environment, receiverConfig, region) => {
3388
3405
  if (receiverConfig === "set-to-undefined") {
3389
3406
  return void 0;
3390
3407
  }
3408
+ if (isQStashDevModeEnabled(environment)) {
3409
+ return new import_qstash11.Receiver({ devMode: true });
3410
+ }
3391
3411
  const receiverEnv = readReceiverEnvironmentVariables(environment, region);
3392
3412
  return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash11.Receiver({
3393
3413
  currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
@@ -3397,6 +3417,10 @@ var getReceiver = (environment, receiverConfig, region) => {
3397
3417
  return receiverConfig;
3398
3418
  }
3399
3419
  };
3420
+ var isQStashDevModeEnabled = (env) => {
3421
+ const value = env.QSTASH_DEV;
3422
+ return value === "true" || value === "1";
3423
+ };
3400
3424
  var getQStashHandlerOptions = (...params) => {
3401
3425
  const handlers = getQStashHandlers(...params);
3402
3426
  return {
@@ -3706,12 +3730,13 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
3706
3730
  );
3707
3731
  }
3708
3732
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3733
+ const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
3709
3734
  const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
3710
3735
  const workflowRunCreatedAt = request.headers.get(WORKFLOW_CREATED_AT_HEADER);
3711
3736
  const workflowContext = new WorkflowContext({
3712
3737
  qstashClient: regionalClient,
3713
3738
  workflowRunId,
3714
- initialPayload: initialPayloadParser(rawInitialPayload),
3739
+ initialPayload: isThirdPartyCallResult(request) ? JSON.parse(rawInitialPayload) : initialPayloadParser(rawInitialPayload),
3715
3740
  headers: recreateUserHeaders(request.headers),
3716
3741
  steps,
3717
3742
  url: workflowUrl,
@@ -3719,6 +3744,7 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
3719
3744
  telemetry: telemetry2,
3720
3745
  invokeCount,
3721
3746
  label,
3747
+ retried,
3722
3748
  workflowRunCreatedAt: Number(workflowRunCreatedAt),
3723
3749
  middlewareManager
3724
3750
  });
package/astro.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-V5ZUHMAF.mjs";
5
+ } from "./chunk-G24J5PCC.mjs";
6
6
 
7
7
  // platforms/astro.ts
8
8
  var telemetry = {
@@ -103,6 +103,7 @@ var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
103
103
  var WORKFLOW_FAILURE_CALLBACK_HEADER = "Upstash-Workflow-Failure-Callback";
104
104
  var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
105
105
  var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
106
+ var WORKFLOW_RETRIED_HEADER = "Upstash-Retried";
106
107
  var WORKFLOW_LABEL_HEADER = "Upstash-Label";
107
108
  var WORKFLOW_UNKOWN_SDK_VERSION_HEADER = "Upstash-Workflow-Unknown-Sdk";
108
109
  var WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER = "upstash-workflow-trigger-by-sdk";
@@ -111,7 +112,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
111
112
  var DEFAULT_CONTENT_TYPE = "application/json";
112
113
  var NO_CONCURRENCY = 1;
113
114
  var DEFAULT_RETRIES = 3;
114
- var VERSION = "v1.0.0";
115
+ var VERSION = "v1.2.1";
115
116
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
116
117
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
117
118
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -277,6 +278,66 @@ var getSteps = async (requester, workflowRunId, messageId, dispatchDebug) => {
277
278
  }
278
279
  }
279
280
  };
281
+ function normalizeCursor(response) {
282
+ const cursor = response.cursor;
283
+ return { ...response, cursor: cursor || void 0 };
284
+ }
285
+ var DEFAULT_BULK_COUNT = 100;
286
+ function buildBulkActionQueryParameters(request, options) {
287
+ const cursor = "cursor" in request ? request.cursor : void 0;
288
+ if ("all" in request) {
289
+ return { count: request.count ?? DEFAULT_BULK_COUNT, cursor };
290
+ }
291
+ if ("dlqIds" in request) {
292
+ const ids = request.dlqIds;
293
+ if (Array.isArray(ids) && ids.length === 0) {
294
+ throw new QstashError2(
295
+ "Empty dlqIds array provided. If you intend to target all DLQ messages, use { all: true } explicitly."
296
+ );
297
+ }
298
+ return { dlqIds: ids, cursor };
299
+ }
300
+ if ("workflowRunIds" in request && request.workflowRunIds) {
301
+ if (request.workflowRunIds.length === 0) {
302
+ throw new QstashError2(
303
+ "Empty workflowRunIds array provided. If you intend to target all workflow runs, use { all: true } explicitly."
304
+ );
305
+ }
306
+ return { workflowRunIds: request.workflowRunIds };
307
+ }
308
+ const filter = request.filter;
309
+ if (!filter) {
310
+ throw new QstashError2(
311
+ "No filter provided. Use { filter: { ... } } with at least one filter field, or { all: true }."
312
+ );
313
+ }
314
+ if (options?.translateWorkflowUrl) {
315
+ const { workflowUrlStartingWith, workflowUrl, ...rest } = filter;
316
+ if (workflowUrlStartingWith && workflowUrl) {
317
+ throw new QstashError2(
318
+ "workflowUrl and workflowUrlStartingWith are mutually exclusive. Use workflowUrl for exact match or workflowUrlStartingWith for prefix match."
319
+ );
320
+ }
321
+ const urlParams = {};
322
+ if (workflowUrlStartingWith) {
323
+ urlParams.workflowUrl = workflowUrlStartingWith;
324
+ } else if (workflowUrl) {
325
+ urlParams.workflowUrl = workflowUrl;
326
+ urlParams.workflowUrlExactMatch = true;
327
+ }
328
+ return {
329
+ ...rest,
330
+ ...urlParams,
331
+ count: request.count ?? DEFAULT_BULK_COUNT,
332
+ cursor
333
+ };
334
+ }
335
+ return {
336
+ ...filter,
337
+ count: request.count ?? DEFAULT_BULK_COUNT,
338
+ cursor
339
+ };
340
+ }
280
341
 
281
342
  // src/utils.ts
282
343
  var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
@@ -907,6 +968,9 @@ var recreateUserHeaders = (headers) => {
907
968
  }
908
969
  return filteredHeaders;
909
970
  };
971
+ var isThirdPartyCallResult = (request) => {
972
+ return request.headers.get("Upstash-Workflow-Callback") !== null;
973
+ };
910
974
  var handleThirdPartyCallResult = async ({
911
975
  request,
912
976
  requestPayload,
@@ -916,7 +980,7 @@ var handleThirdPartyCallResult = async ({
916
980
  middlewareManager
917
981
  }) => {
918
982
  try {
919
- if (request.headers.get("Upstash-Workflow-Callback")) {
983
+ if (isThirdPartyCallResult(request)) {
920
984
  let callbackPayload;
921
985
  if (requestPayload) {
922
986
  callbackPayload = requestPayload;
@@ -2684,6 +2748,13 @@ var WorkflowContext = class {
2684
2748
  * ```
2685
2749
  */
2686
2750
  label;
2751
+ /**
2752
+ * Number of times QStash has retried delivering the current request.
2753
+ *
2754
+ * Sourced from the `Upstash-Retried` header. `0` on the first delivery,
2755
+ * `1` on the first retry, `2` on the second, and so on.
2756
+ */
2757
+ retried;
2687
2758
  constructor({
2688
2759
  qstashClient,
2689
2760
  workflowRunId,
@@ -2696,6 +2767,7 @@ var WorkflowContext = class {
2696
2767
  telemetry,
2697
2768
  invokeCount,
2698
2769
  label,
2770
+ retried,
2699
2771
  middlewareManager
2700
2772
  }) {
2701
2773
  this.qstashClient = qstashClient;
@@ -2707,6 +2779,7 @@ var WorkflowContext = class {
2707
2779
  this.requestPayload = initialPayload;
2708
2780
  this.env = env ?? {};
2709
2781
  this.label = label;
2782
+ this.retried = retried ?? 0;
2710
2783
  const middlewareManagerInstance = middlewareManager ?? new MiddlewareManager([]);
2711
2784
  middlewareManagerInstance.assignContext(this);
2712
2785
  this.executor = new AutoExecutor(
@@ -3044,7 +3117,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3044
3117
  const disabledContext = new _DisabledWorkflowContext({
3045
3118
  qstashClient: new Client2({
3046
3119
  baseUrl: "disabled-client",
3047
- token: "disabled-client"
3120
+ token: "disabled-client",
3121
+ devMode: false
3048
3122
  }),
3049
3123
  workflowRunId: context.workflowRunId,
3050
3124
  workflowRunCreatedAt: context.workflowRunCreatedAt,
@@ -3053,7 +3127,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3053
3127
  url: context.url,
3054
3128
  initialPayload: context.requestPayload,
3055
3129
  env: context.env,
3056
- label: context.label
3130
+ label: context.label,
3131
+ retried: context.retried
3057
3132
  });
3058
3133
  try {
3059
3134
  await routeFunction(disabledContext);
@@ -3269,6 +3344,7 @@ var handleFailure = async ({
3269
3344
  errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
3270
3345
  }
3271
3346
  const userHeaders = recreateUserHeaders(request.headers);
3347
+ const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
3272
3348
  const workflowContext = new WorkflowContext({
3273
3349
  qstashClient,
3274
3350
  workflowRunId,
@@ -3280,6 +3356,7 @@ var handleFailure = async ({
3280
3356
  telemetry: void 0,
3281
3357
  // not going to make requests in authentication check
3282
3358
  label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0,
3359
+ retried,
3283
3360
  workflowRunCreatedAt: workflowCreatedAt,
3284
3361
  middlewareManager: void 0
3285
3362
  });
@@ -3439,6 +3516,9 @@ var getReceiver = (environment, receiverConfig, region) => {
3439
3516
  if (receiverConfig === "set-to-undefined") {
3440
3517
  return void 0;
3441
3518
  }
3519
+ if (isQStashDevModeEnabled(environment)) {
3520
+ return new Receiver({ devMode: true });
3521
+ }
3442
3522
  const receiverEnv = readReceiverEnvironmentVariables(environment, region);
3443
3523
  return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new Receiver({
3444
3524
  currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
@@ -3448,6 +3528,10 @@ var getReceiver = (environment, receiverConfig, region) => {
3448
3528
  return receiverConfig;
3449
3529
  }
3450
3530
  };
3531
+ var isQStashDevModeEnabled = (env) => {
3532
+ const value = env.QSTASH_DEV;
3533
+ return value === "true" || value === "1";
3534
+ };
3451
3535
  var getQStashHandlerOptions = (...params) => {
3452
3536
  const handlers = getQStashHandlers(...params);
3453
3537
  return {
@@ -3683,12 +3767,13 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
3683
3767
  );
3684
3768
  }
3685
3769
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3770
+ const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
3686
3771
  const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
3687
3772
  const workflowRunCreatedAt = request.headers.get(WORKFLOW_CREATED_AT_HEADER);
3688
3773
  const workflowContext = new WorkflowContext({
3689
3774
  qstashClient: regionalClient,
3690
3775
  workflowRunId,
3691
- initialPayload: initialPayloadParser(rawInitialPayload),
3776
+ initialPayload: isThirdPartyCallResult(request) ? JSON.parse(rawInitialPayload) : initialPayloadParser(rawInitialPayload),
3692
3777
  headers: recreateUserHeaders(request.headers),
3693
3778
  steps,
3694
3779
  url: workflowUrl,
@@ -3696,6 +3781,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
3696
3781
  telemetry,
3697
3782
  invokeCount,
3698
3783
  label,
3784
+ retried,
3699
3785
  workflowRunCreatedAt: Number(workflowRunCreatedAt),
3700
3786
  middlewareManager
3701
3787
  });
@@ -3833,6 +3919,8 @@ export {
3833
3919
  WorkflowRetryAfterError,
3834
3920
  makeNotifyRequest,
3835
3921
  makeGetWaitersRequest,
3922
+ normalizeCursor,
3923
+ buildBulkActionQueryParameters,
3836
3924
  WORKFLOW_LABEL_HEADER,
3837
3925
  SDK_TELEMETRY,
3838
3926
  getWorkflowRunId,
package/cloudflare.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.mjs';
2
- import { s as serveManyBase } from './serve-many-C6sa_DxN.mjs';
1
+ import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B_E1VAK6.mjs';
2
+ import { s as serveManyBase } from './serve-many-D3D9uE4u.mjs';
3
3
  import '@upstash/qstash';
4
4
  import 'zod';
5
5
 
package/cloudflare.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.js';
2
- import { s as serveManyBase } from './serve-many-B-fe7bh7.js';
1
+ import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B_E1VAK6.js';
2
+ import { s as serveManyBase } from './serve-many-kPOasiyb.js';
3
3
  import '@upstash/qstash';
4
4
  import 'zod';
5
5
 
package/cloudflare.js CHANGED
@@ -35,6 +35,7 @@ var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
35
35
  var WORKFLOW_FAILURE_CALLBACK_HEADER = "Upstash-Workflow-Failure-Callback";
36
36
  var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
37
37
  var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
38
+ var WORKFLOW_RETRIED_HEADER = "Upstash-Retried";
38
39
  var WORKFLOW_LABEL_HEADER = "Upstash-Label";
39
40
  var WORKFLOW_UNKOWN_SDK_VERSION_HEADER = "Upstash-Workflow-Unknown-Sdk";
40
41
  var WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER = "upstash-workflow-trigger-by-sdk";
@@ -43,7 +44,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
43
44
  var DEFAULT_CONTENT_TYPE = "application/json";
44
45
  var NO_CONCURRENCY = 1;
45
46
  var DEFAULT_RETRIES = 3;
46
- var VERSION = "v1.0.0";
47
+ var VERSION = "v1.2.1";
47
48
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
48
49
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
49
50
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -855,6 +856,9 @@ var recreateUserHeaders = (headers) => {
855
856
  }
856
857
  return filteredHeaders;
857
858
  };
859
+ var isThirdPartyCallResult = (request) => {
860
+ return request.headers.get("Upstash-Workflow-Callback") !== null;
861
+ };
858
862
  var handleThirdPartyCallResult = async ({
859
863
  request,
860
864
  requestPayload,
@@ -864,7 +868,7 @@ var handleThirdPartyCallResult = async ({
864
868
  middlewareManager
865
869
  }) => {
866
870
  try {
867
- if (request.headers.get("Upstash-Workflow-Callback")) {
871
+ if (isThirdPartyCallResult(request)) {
868
872
  let callbackPayload;
869
873
  if (requestPayload) {
870
874
  callbackPayload = requestPayload;
@@ -2707,6 +2711,13 @@ var WorkflowContext = class {
2707
2711
  * ```
2708
2712
  */
2709
2713
  label;
2714
+ /**
2715
+ * Number of times QStash has retried delivering the current request.
2716
+ *
2717
+ * Sourced from the `Upstash-Retried` header. `0` on the first delivery,
2718
+ * `1` on the first retry, `2` on the second, and so on.
2719
+ */
2720
+ retried;
2710
2721
  constructor({
2711
2722
  qstashClient,
2712
2723
  workflowRunId,
@@ -2719,6 +2730,7 @@ var WorkflowContext = class {
2719
2730
  telemetry: telemetry2,
2720
2731
  invokeCount,
2721
2732
  label,
2733
+ retried,
2722
2734
  middlewareManager
2723
2735
  }) {
2724
2736
  this.qstashClient = qstashClient;
@@ -2730,6 +2742,7 @@ var WorkflowContext = class {
2730
2742
  this.requestPayload = initialPayload;
2731
2743
  this.env = env ?? {};
2732
2744
  this.label = label;
2745
+ this.retried = retried ?? 0;
2733
2746
  const middlewareManagerInstance = middlewareManager ?? new MiddlewareManager([]);
2734
2747
  middlewareManagerInstance.assignContext(this);
2735
2748
  this.executor = new AutoExecutor(
@@ -2993,7 +3006,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
2993
3006
  const disabledContext = new _DisabledWorkflowContext({
2994
3007
  qstashClient: new import_qstash10.Client({
2995
3008
  baseUrl: "disabled-client",
2996
- token: "disabled-client"
3009
+ token: "disabled-client",
3010
+ devMode: false
2997
3011
  }),
2998
3012
  workflowRunId: context.workflowRunId,
2999
3013
  workflowRunCreatedAt: context.workflowRunCreatedAt,
@@ -3002,7 +3016,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3002
3016
  url: context.url,
3003
3017
  initialPayload: context.requestPayload,
3004
3018
  env: context.env,
3005
- label: context.label
3019
+ label: context.label,
3020
+ retried: context.retried
3006
3021
  });
3007
3022
  try {
3008
3023
  await routeFunction(disabledContext);
@@ -3218,6 +3233,7 @@ var handleFailure = async ({
3218
3233
  errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
3219
3234
  }
3220
3235
  const userHeaders = recreateUserHeaders(request.headers);
3236
+ const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
3221
3237
  const workflowContext = new WorkflowContext({
3222
3238
  qstashClient,
3223
3239
  workflowRunId,
@@ -3229,6 +3245,7 @@ var handleFailure = async ({
3229
3245
  telemetry: void 0,
3230
3246
  // not going to make requests in authentication check
3231
3247
  label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0,
3248
+ retried,
3232
3249
  workflowRunCreatedAt: workflowCreatedAt,
3233
3250
  middlewareManager: void 0
3234
3251
  });
@@ -3388,6 +3405,9 @@ var getReceiver = (environment, receiverConfig, region) => {
3388
3405
  if (receiverConfig === "set-to-undefined") {
3389
3406
  return void 0;
3390
3407
  }
3408
+ if (isQStashDevModeEnabled(environment)) {
3409
+ return new import_qstash11.Receiver({ devMode: true });
3410
+ }
3391
3411
  const receiverEnv = readReceiverEnvironmentVariables(environment, region);
3392
3412
  return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash11.Receiver({
3393
3413
  currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
@@ -3397,6 +3417,10 @@ var getReceiver = (environment, receiverConfig, region) => {
3397
3417
  return receiverConfig;
3398
3418
  }
3399
3419
  };
3420
+ var isQStashDevModeEnabled = (env) => {
3421
+ const value = env.QSTASH_DEV;
3422
+ return value === "true" || value === "1";
3423
+ };
3400
3424
  var getQStashHandlerOptions = (...params) => {
3401
3425
  const handlers = getQStashHandlers(...params);
3402
3426
  return {
@@ -3706,12 +3730,13 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
3706
3730
  );
3707
3731
  }
3708
3732
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3733
+ const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
3709
3734
  const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
3710
3735
  const workflowRunCreatedAt = request.headers.get(WORKFLOW_CREATED_AT_HEADER);
3711
3736
  const workflowContext = new WorkflowContext({
3712
3737
  qstashClient: regionalClient,
3713
3738
  workflowRunId,
3714
- initialPayload: initialPayloadParser(rawInitialPayload),
3739
+ initialPayload: isThirdPartyCallResult(request) ? JSON.parse(rawInitialPayload) : initialPayloadParser(rawInitialPayload),
3715
3740
  headers: recreateUserHeaders(request.headers),
3716
3741
  steps,
3717
3742
  url: workflowUrl,
@@ -3719,6 +3744,7 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
3719
3744
  telemetry: telemetry2,
3720
3745
  invokeCount,
3721
3746
  label,
3747
+ retried,
3722
3748
  workflowRunCreatedAt: Number(workflowRunCreatedAt),
3723
3749
  middlewareManager
3724
3750
  });
package/cloudflare.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-V5ZUHMAF.mjs";
5
+ } from "./chunk-G24J5PCC.mjs";
6
6
 
7
7
  // platforms/cloudflare.ts
8
8
  var getArgs = (args) => {
package/express.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as express_serve_static_core from 'express-serve-static-core';
2
- import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.mjs';
2
+ import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B_E1VAK6.mjs';
3
3
  import { Router } from 'express';
4
- import { s as serveManyBase } from './serve-many-C6sa_DxN.mjs';
4
+ import { s as serveManyBase } from './serve-many-D3D9uE4u.mjs';
5
5
  import '@upstash/qstash';
6
6
  import 'zod';
7
7
 
package/express.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as express_serve_static_core from 'express-serve-static-core';
2
- import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.js';
2
+ import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B_E1VAK6.js';
3
3
  import { Router } from 'express';
4
- import { s as serveManyBase } from './serve-many-B-fe7bh7.js';
4
+ import { s as serveManyBase } from './serve-many-kPOasiyb.js';
5
5
  import '@upstash/qstash';
6
6
  import 'zod';
7
7