@upstash/workflow 1.1.1 → 1.2.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 +1 -0
  2. package/astro.d.mts +2 -2
  3. package/astro.d.ts +2 -2
  4. package/astro.js +41 -21
  5. package/astro.mjs +1 -1
  6. package/{chunk-QRCGBBFJ.mjs → chunk-V5ZUHMAF.mjs} +35 -15
  7. package/cloudflare.d.mts +2 -2
  8. package/cloudflare.d.ts +2 -2
  9. package/cloudflare.js +41 -21
  10. package/cloudflare.mjs +1 -1
  11. package/express.d.mts +2 -2
  12. package/express.d.ts +2 -2
  13. package/express.js +41 -21
  14. package/express.mjs +1 -1
  15. package/h3.d.mts +2 -2
  16. package/h3.d.ts +2 -2
  17. package/h3.js +41 -21
  18. package/h3.mjs +1 -1
  19. package/hono.d.mts +2 -2
  20. package/hono.d.ts +2 -2
  21. package/hono.js +41 -21
  22. package/hono.mjs +1 -1
  23. package/index.d.mts +28 -3
  24. package/index.d.ts +28 -3
  25. package/index.js +59 -26
  26. package/index.mjs +17 -4
  27. package/nextjs.d.mts +2 -2
  28. package/nextjs.d.ts +2 -2
  29. package/nextjs.js +41 -21
  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 +41 -21
  35. package/react-router.mjs +1 -1
  36. package/{serve-many-BP-8Ytbc.d.ts → serve-many-B-fe7bh7.d.ts} +1 -1
  37. package/{serve-many-BsycEL_d.d.mts → serve-many-C6sa_DxN.d.mts} +1 -1
  38. package/solidjs.d.mts +1 -1
  39. package/solidjs.d.ts +1 -1
  40. package/solidjs.js +41 -21
  41. package/solidjs.mjs +1 -1
  42. package/svelte.d.mts +2 -2
  43. package/svelte.d.ts +2 -2
  44. package/svelte.js +41 -21
  45. package/svelte.mjs +1 -1
  46. package/tanstack.d.mts +2 -2
  47. package/tanstack.d.ts +2 -2
  48. package/tanstack.js +41 -21
  49. package/tanstack.mjs +1 -1
  50. package/{types-B90SJYZV.d.ts → types-B2S08hRU.d.mts} +10 -1
  51. package/{types-B90SJYZV.d.mts → types-B2S08hRU.d.ts} +10 -1
package/hono.js CHANGED
@@ -126,9 +126,10 @@ function isInstanceOf(v, ctor) {
126
126
  }
127
127
 
128
128
  // src/client/utils.ts
129
- var makeNotifyRequest = async (requester, eventId, eventData) => {
129
+ var makeNotifyRequest = async (requester, eventId, eventData, workflowRunId) => {
130
+ const path = workflowRunId ? ["v2", "notify", workflowRunId, eventId] : ["v2", "notify", eventId];
130
131
  const result = await requester.request({
131
- path: ["v2", "notify", eventId],
132
+ path,
132
133
  method: "POST",
133
134
  body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
134
135
  });
@@ -722,6 +723,7 @@ var triggerFirstInvocation = async (params) => {
722
723
  retries,
723
724
  retryDelay,
724
725
  flowControl,
726
+ redact,
725
727
  unknownSdk
726
728
  }) => {
727
729
  const { headers } = getHeaders({
@@ -758,7 +760,8 @@ var triggerFirstInvocation = async (params) => {
758
760
  body,
759
761
  url: workflowContext.url,
760
762
  delay,
761
- notBefore
763
+ notBefore,
764
+ redact
762
765
  };
763
766
  }
764
767
  );
@@ -917,7 +920,6 @@ ${atob(callbackMessage.body ?? "")}`
917
920
  })}`
918
921
  );
919
922
  }
920
- const userHeaders = recreateUserHeaders(request.headers);
921
923
  const { headers: requestHeaders } = getHeaders({
922
924
  initHeaderValue: "false",
923
925
  workflowConfig: {
@@ -925,7 +927,6 @@ ${atob(callbackMessage.body ?? "")}`
925
927
  workflowUrl,
926
928
  telemetry: telemetry2
927
929
  },
928
- userHeaders,
929
930
  invokeCount: Number(invokeCount)
930
931
  });
931
932
  const callResponse = {
@@ -1074,7 +1075,6 @@ var BaseLazyStep = class _BaseLazyStep {
1074
1075
  useJSONContent: false,
1075
1076
  telemetry: telemetry2
1076
1077
  },
1077
- userHeaders: context.headers,
1078
1078
  invokeCount,
1079
1079
  stepInfo: {
1080
1080
  step,
@@ -1432,9 +1432,9 @@ var LazyWaitEventStep = class extends BaseLazyStep {
1432
1432
  };
1433
1433
  var LazyNotifyStep = class extends LazyFunctionStep {
1434
1434
  stepType = "Notify";
1435
- constructor(context, stepName, eventId, eventData, requester) {
1435
+ constructor(context, stepName, eventId, eventData, requester, workflowRunId) {
1436
1436
  super(context, stepName, async () => {
1437
- const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
1437
+ const notifyResponse = await makeNotifyRequest(requester, eventId, eventData, workflowRunId);
1438
1438
  return {
1439
1439
  eventId,
1440
1440
  eventData,
@@ -1504,7 +1504,6 @@ var LazyInvokeStep = class extends BaseLazyStep {
1504
1504
  telemetry: telemetry2,
1505
1505
  useJSONContent: false
1506
1506
  },
1507
- userHeaders: context.headers,
1508
1507
  invokeCount
1509
1508
  });
1510
1509
  context.qstashClient.http.headers?.forEach((value, key) => {
@@ -1613,12 +1612,14 @@ var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
1613
1612
  const parsedEventData = BaseLazyStep.tryParsing(eventData);
1614
1613
  const body = parsedEventData.body;
1615
1614
  const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
1615
+ const methodUpper = parsedEventData.method.toUpperCase();
1616
+ const canHaveBody = methodUpper !== "GET" && methodUpper !== "HEAD";
1616
1617
  const request = new Request(
1617
1618
  `${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
1618
1619
  {
1619
1620
  method: parsedEventData.method,
1620
1621
  headers: parsedEventData.header,
1621
- body: parsedBody
1622
+ body: canHaveBody ? parsedBody : void 0
1622
1623
  }
1623
1624
  );
1624
1625
  return {
@@ -1752,6 +1753,9 @@ var WorkflowHeaders = class {
1752
1753
  }
1753
1754
  }
1754
1755
  addUserHeaders() {
1756
+ if (!this.userHeaders) {
1757
+ return;
1758
+ }
1755
1759
  for (const [key, value] of this.userHeaders.entries()) {
1756
1760
  const forwardKey = `Forward-${key}`;
1757
1761
  this.headers.workflowHeaders[forwardKey] = value;
@@ -1858,7 +1862,6 @@ var submitParallelSteps = async ({
1858
1862
  workflowUrl: context.url,
1859
1863
  telemetry: telemetry2
1860
1864
  },
1861
- userHeaders: context.headers,
1862
1865
  invokeCount
1863
1866
  });
1864
1867
  return {
@@ -2111,7 +2114,7 @@ var AutoExecutor = class _AutoExecutor {
2111
2114
  });
2112
2115
  throw new WorkflowAbort(parallelStep.stepName, resultStep);
2113
2116
  } catch (error) {
2114
- if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
2117
+ if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400 || isInstanceOf(error, import_qstash5.QstashError) && error.status === 412) {
2115
2118
  throw error;
2116
2119
  }
2117
2120
  throw new WorkflowError(
@@ -2585,6 +2588,7 @@ var MiddlewareManager = class {
2585
2588
  };
2586
2589
 
2587
2590
  // src/context/context.ts
2591
+ var import_qstash9 = require("@upstash/qstash");
2588
2592
  var WorkflowContext = class {
2589
2593
  executor;
2590
2594
  steps;
@@ -2894,14 +2898,23 @@ var WorkflowContext = class {
2894
2898
  * a notifyResponse field which contains a list of `Waiter` objects, each corresponding
2895
2899
  * to a notified workflow run.
2896
2900
  *
2901
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
2902
+ *
2903
+ * ```ts
2904
+ * const { eventId, eventData, notifyResponse } = await context.notify(
2905
+ * "notify step", "event-id", "event-data", "wfr_123"
2906
+ * );
2907
+ * ```
2908
+ *
2897
2909
  * @param stepName
2898
2910
  * @param eventId event id to notify
2899
2911
  * @param eventData event data to notify with
2912
+ * @param workflowRunId optional workflow run id for lookback support
2900
2913
  * @returns notify response which has event id, event data and list of waiters which were notified
2901
2914
  */
2902
- async notify(stepName, eventId, eventData) {
2915
+ async notify(stepName, eventId, eventData, workflowRunId) {
2903
2916
  return await this.addStep(
2904
- new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
2917
+ new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http, workflowRunId)
2905
2918
  );
2906
2919
  }
2907
2920
  async invoke(stepName, settings) {
@@ -2929,7 +2942,14 @@ var WorkflowContext = class {
2929
2942
  * DisabledWorkflowContext.
2930
2943
  */
2931
2944
  async addStep(step) {
2932
- return await this.executor.addStep(step);
2945
+ try {
2946
+ return await this.executor.addStep(step);
2947
+ } catch (error) {
2948
+ if (isInstanceOf(error, import_qstash9.QstashError) && error.status === 412) {
2949
+ throw new WorkflowNonRetryableError(error.message);
2950
+ }
2951
+ throw error;
2952
+ }
2933
2953
  }
2934
2954
  get api() {
2935
2955
  return new WorkflowApi({
@@ -2939,7 +2959,7 @@ var WorkflowContext = class {
2939
2959
  };
2940
2960
 
2941
2961
  // src/serve/authorization.ts
2942
- var import_qstash9 = require("@upstash/qstash");
2962
+ var import_qstash10 = require("@upstash/qstash");
2943
2963
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
2944
2964
  static disabledMessage = "disabled-qstash-worklfow-run";
2945
2965
  disabled = true;
@@ -2971,7 +2991,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
2971
2991
  */
2972
2992
  static async tryAuthentication(routeFunction, context) {
2973
2993
  const disabledContext = new _DisabledWorkflowContext({
2974
- qstashClient: new import_qstash9.Client({
2994
+ qstashClient: new import_qstash10.Client({
2975
2995
  baseUrl: "disabled-client",
2976
2996
  token: "disabled-client"
2977
2997
  }),
@@ -3238,7 +3258,7 @@ var handleFailure = async ({
3238
3258
  };
3239
3259
 
3240
3260
  // src/serve/multi-region/handlers.ts
3241
- var import_qstash10 = require("@upstash/qstash");
3261
+ var import_qstash11 = require("@upstash/qstash");
3242
3262
 
3243
3263
  // src/serve/multi-region/utils.ts
3244
3264
  var VALID_REGIONS = ["EU_CENTRAL_1", "US_EAST_1"];
@@ -3303,7 +3323,7 @@ var getHandlersForRequest = (qstashHandlers, regionHeader, isFirstInvocation) =>
3303
3323
  };
3304
3324
  var createRegionalHandler = (environment, receiverConfig, region, clientOptions) => {
3305
3325
  const clientEnv = readClientEnvironmentVariables(environment, region);
3306
- const client = new import_qstash10.Client({
3326
+ const client = new import_qstash11.Client({
3307
3327
  ...clientOptions,
3308
3328
  baseUrl: clientEnv.QSTASH_URL,
3309
3329
  token: clientEnv.QSTASH_TOKEN
@@ -3353,7 +3373,7 @@ var getQStashHandlers = ({
3353
3373
  return {
3354
3374
  mode: "single-region",
3355
3375
  handlers: {
3356
- client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new import_qstash10.Client({
3376
+ client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new import_qstash11.Client({
3357
3377
  ...qstashClientOption,
3358
3378
  baseUrl: environment.QSTASH_URL,
3359
3379
  token: environment.QSTASH_TOKEN
@@ -3369,7 +3389,7 @@ var getReceiver = (environment, receiverConfig, region) => {
3369
3389
  return void 0;
3370
3390
  }
3371
3391
  const receiverEnv = readReceiverEnvironmentVariables(environment, region);
3372
- return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash10.Receiver({
3392
+ return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash11.Receiver({
3373
3393
  currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
3374
3394
  nextSigningKey: receiverEnv.QSTASH_NEXT_SIGNING_KEY
3375
3395
  }) : void 0;
package/hono.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-QRCGBBFJ.mjs";
5
+ } from "./chunk-V5ZUHMAF.mjs";
6
6
 
7
7
  // platforms/hono.ts
8
8
  var telemetry = {
package/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as StepType, R as RawStep, W as WorkflowMiddleware, a as WorkflowClient, b as WorkflowReceiver, c as RouteFunction, d as WorkflowServeOptions, T as Telemetry, N as NotifyResponse, e as Waiter } from './types-B90SJYZV.mjs';
2
- export { A as AsyncStepFunction, C as CallResponse, f as CallSettings, D as DetailedFinishCondition, g as Duration, E as ExclusiveValidationOptions, F as FailureFunctionPayload, h as FinishCondition, H as HeaderParams, I as InvokableWorkflow, i as InvokeStepResponse, j as InvokeWorkflowRequest, L as LazyInvokeStepParams, k as NotifyStepResponse, P as ParallelCallState, Q as QStashClientExtraConfig, l as RequiredExceptFields, m as Step, n as StepFunction, o as StepTypes, p as SyncStepFunction, q as WaitEventOptions, r as WaitRequest, s as WaitStepResponse, t as WorkflowAbort, u as WorkflowContext, v as WorkflowError, w as WorkflowNonRetryableError, x as WorkflowRetryAfterError } from './types-B90SJYZV.mjs';
1
+ import { S as StepType, R as RawStep, W as WorkflowMiddleware, a as WorkflowClient, b as WorkflowReceiver, c as RouteFunction, d as WorkflowServeOptions, T as Telemetry, N as NotifyResponse, e as Waiter } from './types-B2S08hRU.mjs';
2
+ export { A as AsyncStepFunction, C as CallResponse, f as CallSettings, D as DetailedFinishCondition, g as Duration, E as ExclusiveValidationOptions, F as FailureFunctionPayload, h as FinishCondition, H as HeaderParams, I as InvokableWorkflow, i as InvokeStepResponse, j as InvokeWorkflowRequest, L as LazyInvokeStepParams, k as NotifyStepResponse, P as ParallelCallState, Q as QStashClientExtraConfig, l as RequiredExceptFields, m as Step, n as StepFunction, o as StepTypes, p as SyncStepFunction, q as WaitEventOptions, r as WaitRequest, s as WaitStepResponse, t as WorkflowAbort, u as WorkflowContext, v as WorkflowError, w as WorkflowNonRetryableError, x as WorkflowRetryAfterError } from './types-B2S08hRU.mjs';
3
3
  import { FlowControl, PublishRequest, HTTPMethods, Client as Client$1 } from '@upstash/qstash';
4
4
  import 'zod';
5
5
 
@@ -417,6 +417,19 @@ type TriggerOptions = {
417
417
  * URL to call if the first request to the workflow endpoint fails
418
418
  */
419
419
  failureUrl?: string;
420
+ /**
421
+ * Configure which fields should be redacted in logs.
422
+ *
423
+ * - `{ body: true }` to redact the request body
424
+ * - `{ header: true }` to redact all headers
425
+ * - `{ header: ["Authorization"] }` to redact specific headers
426
+ *
427
+ * @default undefined
428
+ */
429
+ redact?: {
430
+ body?: true;
431
+ header?: true | string[];
432
+ };
420
433
  };
421
434
  type DLQResumeRestartOptions<TDLQId extends string | string[] = string | string[]> = {
422
435
  dlqId: TDLQId;
@@ -777,12 +790,24 @@ declare class Client {
777
790
  * });
778
791
  * ```
779
792
  *
793
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
794
+ *
795
+ * ```ts
796
+ * await client.notify({
797
+ * eventId: "my-event-id",
798
+ * eventData: "my-data",
799
+ * workflowRunId: "wfr_123" // enables lookback
800
+ * });
801
+ * ```
802
+ *
780
803
  * @param eventId event id to notify
781
804
  * @param eventData data to provide to the workflow
805
+ * @param workflowRunId optional workflow run id for lookback support
782
806
  */
783
- notify({ eventId, eventData, }: {
807
+ notify({ eventId, eventData, workflowRunId, }: {
784
808
  eventId: string;
785
809
  eventData?: unknown;
810
+ workflowRunId?: string;
786
811
  }): Promise<NotifyResponse[]>;
787
812
  /**
788
813
  * Check waiters of an event
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as StepType, R as RawStep, W as WorkflowMiddleware, a as WorkflowClient, b as WorkflowReceiver, c as RouteFunction, d as WorkflowServeOptions, T as Telemetry, N as NotifyResponse, e as Waiter } from './types-B90SJYZV.js';
2
- export { A as AsyncStepFunction, C as CallResponse, f as CallSettings, D as DetailedFinishCondition, g as Duration, E as ExclusiveValidationOptions, F as FailureFunctionPayload, h as FinishCondition, H as HeaderParams, I as InvokableWorkflow, i as InvokeStepResponse, j as InvokeWorkflowRequest, L as LazyInvokeStepParams, k as NotifyStepResponse, P as ParallelCallState, Q as QStashClientExtraConfig, l as RequiredExceptFields, m as Step, n as StepFunction, o as StepTypes, p as SyncStepFunction, q as WaitEventOptions, r as WaitRequest, s as WaitStepResponse, t as WorkflowAbort, u as WorkflowContext, v as WorkflowError, w as WorkflowNonRetryableError, x as WorkflowRetryAfterError } from './types-B90SJYZV.js';
1
+ import { S as StepType, R as RawStep, W as WorkflowMiddleware, a as WorkflowClient, b as WorkflowReceiver, c as RouteFunction, d as WorkflowServeOptions, T as Telemetry, N as NotifyResponse, e as Waiter } from './types-B2S08hRU.js';
2
+ export { A as AsyncStepFunction, C as CallResponse, f as CallSettings, D as DetailedFinishCondition, g as Duration, E as ExclusiveValidationOptions, F as FailureFunctionPayload, h as FinishCondition, H as HeaderParams, I as InvokableWorkflow, i as InvokeStepResponse, j as InvokeWorkflowRequest, L as LazyInvokeStepParams, k as NotifyStepResponse, P as ParallelCallState, Q as QStashClientExtraConfig, l as RequiredExceptFields, m as Step, n as StepFunction, o as StepTypes, p as SyncStepFunction, q as WaitEventOptions, r as WaitRequest, s as WaitStepResponse, t as WorkflowAbort, u as WorkflowContext, v as WorkflowError, w as WorkflowNonRetryableError, x as WorkflowRetryAfterError } from './types-B2S08hRU.js';
3
3
  import { FlowControl, PublishRequest, HTTPMethods, Client as Client$1 } from '@upstash/qstash';
4
4
  import 'zod';
5
5
 
@@ -417,6 +417,19 @@ type TriggerOptions = {
417
417
  * URL to call if the first request to the workflow endpoint fails
418
418
  */
419
419
  failureUrl?: string;
420
+ /**
421
+ * Configure which fields should be redacted in logs.
422
+ *
423
+ * - `{ body: true }` to redact the request body
424
+ * - `{ header: true }` to redact all headers
425
+ * - `{ header: ["Authorization"] }` to redact specific headers
426
+ *
427
+ * @default undefined
428
+ */
429
+ redact?: {
430
+ body?: true;
431
+ header?: true | string[];
432
+ };
420
433
  };
421
434
  type DLQResumeRestartOptions<TDLQId extends string | string[] = string | string[]> = {
422
435
  dlqId: TDLQId;
@@ -777,12 +790,24 @@ declare class Client {
777
790
  * });
778
791
  * ```
779
792
  *
793
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
794
+ *
795
+ * ```ts
796
+ * await client.notify({
797
+ * eventId: "my-event-id",
798
+ * eventData: "my-data",
799
+ * workflowRunId: "wfr_123" // enables lookback
800
+ * });
801
+ * ```
802
+ *
780
803
  * @param eventId event id to notify
781
804
  * @param eventData data to provide to the workflow
805
+ * @param workflowRunId optional workflow run id for lookback support
782
806
  */
783
- notify({ eventId, eventData, }: {
807
+ notify({ eventId, eventData, workflowRunId, }: {
784
808
  eventId: string;
785
809
  eventData?: unknown;
810
+ workflowRunId?: string;
786
811
  }): Promise<NotifyResponse[]>;
787
812
  /**
788
813
  * Check waiters of an event
package/index.js CHANGED
@@ -133,9 +133,10 @@ function isInstanceOf(v, ctor) {
133
133
  }
134
134
 
135
135
  // src/client/utils.ts
136
- var makeNotifyRequest = async (requester, eventId, eventData) => {
136
+ var makeNotifyRequest = async (requester, eventId, eventData, workflowRunId) => {
137
+ const path = workflowRunId ? ["v2", "notify", workflowRunId, eventId] : ["v2", "notify", eventId];
137
138
  const result = await requester.request({
138
- path: ["v2", "notify", eventId],
139
+ path,
139
140
  method: "POST",
140
141
  body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
141
142
  });
@@ -736,6 +737,7 @@ var triggerFirstInvocation = async (params) => {
736
737
  retries,
737
738
  retryDelay,
738
739
  flowControl,
740
+ redact,
739
741
  unknownSdk
740
742
  }) => {
741
743
  const { headers } = getHeaders({
@@ -772,7 +774,8 @@ var triggerFirstInvocation = async (params) => {
772
774
  body,
773
775
  url: workflowContext.url,
774
776
  delay,
775
- notBefore
777
+ notBefore,
778
+ redact
776
779
  };
777
780
  }
778
781
  );
@@ -931,7 +934,6 @@ ${atob(callbackMessage.body ?? "")}`
931
934
  })}`
932
935
  );
933
936
  }
934
- const userHeaders = recreateUserHeaders(request.headers);
935
937
  const { headers: requestHeaders } = getHeaders({
936
938
  initHeaderValue: "false",
937
939
  workflowConfig: {
@@ -939,7 +941,6 @@ ${atob(callbackMessage.body ?? "")}`
939
941
  workflowUrl,
940
942
  telemetry
941
943
  },
942
- userHeaders,
943
944
  invokeCount: Number(invokeCount)
944
945
  });
945
946
  const callResponse = {
@@ -1088,7 +1089,6 @@ var BaseLazyStep = class _BaseLazyStep {
1088
1089
  useJSONContent: false,
1089
1090
  telemetry
1090
1091
  },
1091
- userHeaders: context.headers,
1092
1092
  invokeCount,
1093
1093
  stepInfo: {
1094
1094
  step,
@@ -1446,9 +1446,9 @@ var LazyWaitEventStep = class extends BaseLazyStep {
1446
1446
  };
1447
1447
  var LazyNotifyStep = class extends LazyFunctionStep {
1448
1448
  stepType = "Notify";
1449
- constructor(context, stepName, eventId, eventData, requester) {
1449
+ constructor(context, stepName, eventId, eventData, requester, workflowRunId) {
1450
1450
  super(context, stepName, async () => {
1451
- const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
1451
+ const notifyResponse = await makeNotifyRequest(requester, eventId, eventData, workflowRunId);
1452
1452
  return {
1453
1453
  eventId,
1454
1454
  eventData,
@@ -1518,7 +1518,6 @@ var LazyInvokeStep = class extends BaseLazyStep {
1518
1518
  telemetry,
1519
1519
  useJSONContent: false
1520
1520
  },
1521
- userHeaders: context.headers,
1522
1521
  invokeCount
1523
1522
  });
1524
1523
  context.qstashClient.http.headers?.forEach((value, key) => {
@@ -1627,12 +1626,14 @@ var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
1627
1626
  const parsedEventData = BaseLazyStep.tryParsing(eventData);
1628
1627
  const body = parsedEventData.body;
1629
1628
  const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
1629
+ const methodUpper = parsedEventData.method.toUpperCase();
1630
+ const canHaveBody = methodUpper !== "GET" && methodUpper !== "HEAD";
1630
1631
  const request = new Request(
1631
1632
  `${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
1632
1633
  {
1633
1634
  method: parsedEventData.method,
1634
1635
  headers: parsedEventData.header,
1635
- body: parsedBody
1636
+ body: canHaveBody ? parsedBody : void 0
1636
1637
  }
1637
1638
  );
1638
1639
  return {
@@ -1766,6 +1767,9 @@ var WorkflowHeaders = class {
1766
1767
  }
1767
1768
  }
1768
1769
  addUserHeaders() {
1770
+ if (!this.userHeaders) {
1771
+ return;
1772
+ }
1769
1773
  for (const [key, value] of this.userHeaders.entries()) {
1770
1774
  const forwardKey = `Forward-${key}`;
1771
1775
  this.headers.workflowHeaders[forwardKey] = value;
@@ -1872,7 +1876,6 @@ var submitParallelSteps = async ({
1872
1876
  workflowUrl: context.url,
1873
1877
  telemetry
1874
1878
  },
1875
- userHeaders: context.headers,
1876
1879
  invokeCount
1877
1880
  });
1878
1881
  return {
@@ -2125,7 +2128,7 @@ var AutoExecutor = class _AutoExecutor {
2125
2128
  });
2126
2129
  throw new WorkflowAbort(parallelStep.stepName, resultStep);
2127
2130
  } catch (error) {
2128
- if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
2131
+ if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400 || isInstanceOf(error, import_qstash5.QstashError) && error.status === 412) {
2129
2132
  throw error;
2130
2133
  }
2131
2134
  throw new WorkflowError(
@@ -2532,6 +2535,7 @@ var MiddlewareManager = class {
2532
2535
  };
2533
2536
 
2534
2537
  // src/context/context.ts
2538
+ var import_qstash9 = require("@upstash/qstash");
2535
2539
  var WorkflowContext = class {
2536
2540
  executor;
2537
2541
  steps;
@@ -2841,14 +2845,23 @@ var WorkflowContext = class {
2841
2845
  * a notifyResponse field which contains a list of `Waiter` objects, each corresponding
2842
2846
  * to a notified workflow run.
2843
2847
  *
2848
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
2849
+ *
2850
+ * ```ts
2851
+ * const { eventId, eventData, notifyResponse } = await context.notify(
2852
+ * "notify step", "event-id", "event-data", "wfr_123"
2853
+ * );
2854
+ * ```
2855
+ *
2844
2856
  * @param stepName
2845
2857
  * @param eventId event id to notify
2846
2858
  * @param eventData event data to notify with
2859
+ * @param workflowRunId optional workflow run id for lookback support
2847
2860
  * @returns notify response which has event id, event data and list of waiters which were notified
2848
2861
  */
2849
- async notify(stepName, eventId, eventData) {
2862
+ async notify(stepName, eventId, eventData, workflowRunId) {
2850
2863
  return await this.addStep(
2851
- new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
2864
+ new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http, workflowRunId)
2852
2865
  );
2853
2866
  }
2854
2867
  async invoke(stepName, settings) {
@@ -2876,7 +2889,14 @@ var WorkflowContext = class {
2876
2889
  * DisabledWorkflowContext.
2877
2890
  */
2878
2891
  async addStep(step) {
2879
- return await this.executor.addStep(step);
2892
+ try {
2893
+ return await this.executor.addStep(step);
2894
+ } catch (error) {
2895
+ if (isInstanceOf(error, import_qstash9.QstashError) && error.status === 412) {
2896
+ throw new WorkflowNonRetryableError(error.message);
2897
+ }
2898
+ throw error;
2899
+ }
2880
2900
  }
2881
2901
  get api() {
2882
2902
  return new WorkflowApi({
@@ -2886,7 +2906,7 @@ var WorkflowContext = class {
2886
2906
  };
2887
2907
 
2888
2908
  // src/serve/authorization.ts
2889
- var import_qstash9 = require("@upstash/qstash");
2909
+ var import_qstash10 = require("@upstash/qstash");
2890
2910
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
2891
2911
  static disabledMessage = "disabled-qstash-worklfow-run";
2892
2912
  disabled = true;
@@ -2918,7 +2938,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
2918
2938
  */
2919
2939
  static async tryAuthentication(routeFunction, context) {
2920
2940
  const disabledContext = new _DisabledWorkflowContext({
2921
- qstashClient: new import_qstash9.Client({
2941
+ qstashClient: new import_qstash10.Client({
2922
2942
  baseUrl: "disabled-client",
2923
2943
  token: "disabled-client"
2924
2944
  }),
@@ -3185,7 +3205,7 @@ var handleFailure = async ({
3185
3205
  };
3186
3206
 
3187
3207
  // src/serve/multi-region/handlers.ts
3188
- var import_qstash10 = require("@upstash/qstash");
3208
+ var import_qstash11 = require("@upstash/qstash");
3189
3209
 
3190
3210
  // src/serve/multi-region/utils.ts
3191
3211
  var VALID_REGIONS = ["EU_CENTRAL_1", "US_EAST_1"];
@@ -3250,7 +3270,7 @@ var getHandlersForRequest = (qstashHandlers, regionHeader, isFirstInvocation) =>
3250
3270
  };
3251
3271
  var createRegionalHandler = (environment, receiverConfig, region, clientOptions) => {
3252
3272
  const clientEnv = readClientEnvironmentVariables(environment, region);
3253
- const client = new import_qstash10.Client({
3273
+ const client = new import_qstash11.Client({
3254
3274
  ...clientOptions,
3255
3275
  baseUrl: clientEnv.QSTASH_URL,
3256
3276
  token: clientEnv.QSTASH_TOKEN
@@ -3300,7 +3320,7 @@ var getQStashHandlers = ({
3300
3320
  return {
3301
3321
  mode: "single-region",
3302
3322
  handlers: {
3303
- client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new import_qstash10.Client({
3323
+ client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new import_qstash11.Client({
3304
3324
  ...qstashClientOption,
3305
3325
  baseUrl: environment.QSTASH_URL,
3306
3326
  token: environment.QSTASH_TOKEN
@@ -3316,7 +3336,7 @@ var getReceiver = (environment, receiverConfig, region) => {
3316
3336
  return void 0;
3317
3337
  }
3318
3338
  const receiverEnv = readReceiverEnvironmentVariables(environment, region);
3319
- return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash10.Receiver({
3339
+ return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash11.Receiver({
3320
3340
  currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
3321
3341
  nextSigningKey: receiverEnv.QSTASH_NEXT_SIGNING_KEY
3322
3342
  }) : void 0;
@@ -3777,7 +3797,7 @@ var serve = (routeFunction, options) => {
3777
3797
  };
3778
3798
 
3779
3799
  // src/client/index.ts
3780
- var import_qstash11 = require("@upstash/qstash");
3800
+ var import_qstash12 = require("@upstash/qstash");
3781
3801
 
3782
3802
  // src/client/dlq.ts
3783
3803
  var DLQ = class _DLQ {
@@ -3889,7 +3909,7 @@ var DLQ = class _DLQ {
3889
3909
  var Client4 = class {
3890
3910
  client;
3891
3911
  constructor(clientConfig) {
3892
- this.client = new import_qstash11.Client(clientConfig);
3912
+ this.client = new import_qstash12.Client(clientConfig);
3893
3913
  }
3894
3914
  /**
3895
3915
  * Cancel an ongoing workflow
@@ -3981,14 +4001,26 @@ var Client4 = class {
3981
4001
  * });
3982
4002
  * ```
3983
4003
  *
4004
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
4005
+ *
4006
+ * ```ts
4007
+ * await client.notify({
4008
+ * eventId: "my-event-id",
4009
+ * eventData: "my-data",
4010
+ * workflowRunId: "wfr_123" // enables lookback
4011
+ * });
4012
+ * ```
4013
+ *
3984
4014
  * @param eventId event id to notify
3985
4015
  * @param eventData data to provide to the workflow
4016
+ * @param workflowRunId optional workflow run id for lookback support
3986
4017
  */
3987
4018
  async notify({
3988
4019
  eventId,
3989
- eventData
4020
+ eventData,
4021
+ workflowRunId
3990
4022
  }) {
3991
- return await makeNotifyRequest(this.client.http, eventId, eventData);
4023
+ return await makeNotifyRequest(this.client.http, eventId, eventData, workflowRunId);
3992
4024
  }
3993
4025
  /**
3994
4026
  * Check waiters of an event
@@ -4036,7 +4068,8 @@ var Client4 = class {
4036
4068
  failureUrl,
4037
4069
  retries: option.retries,
4038
4070
  retryDelay: option.retryDelay,
4039
- flowControl: option.flowControl
4071
+ flowControl: option.flowControl,
4072
+ redact: option.redact
4040
4073
  };
4041
4074
  });
4042
4075
  const result = await triggerFirstInvocation(invocations);
package/index.mjs CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  prepareFlowControl,
16
16
  serve,
17
17
  triggerFirstInvocation
18
- } from "./chunk-QRCGBBFJ.mjs";
18
+ } from "./chunk-V5ZUHMAF.mjs";
19
19
 
20
20
  // src/client/index.ts
21
21
  import { Client as QStashClient } from "@upstash/qstash";
@@ -222,14 +222,26 @@ var Client = class {
222
222
  * });
223
223
  * ```
224
224
  *
225
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
226
+ *
227
+ * ```ts
228
+ * await client.notify({
229
+ * eventId: "my-event-id",
230
+ * eventData: "my-data",
231
+ * workflowRunId: "wfr_123" // enables lookback
232
+ * });
233
+ * ```
234
+ *
225
235
  * @param eventId event id to notify
226
236
  * @param eventData data to provide to the workflow
237
+ * @param workflowRunId optional workflow run id for lookback support
227
238
  */
228
239
  async notify({
229
240
  eventId,
230
- eventData
241
+ eventData,
242
+ workflowRunId
231
243
  }) {
232
- return await makeNotifyRequest(this.client.http, eventId, eventData);
244
+ return await makeNotifyRequest(this.client.http, eventId, eventData, workflowRunId);
233
245
  }
234
246
  /**
235
247
  * Check waiters of an event
@@ -277,7 +289,8 @@ var Client = class {
277
289
  failureUrl,
278
290
  retries: option.retries,
279
291
  retryDelay: option.retryDelay,
280
- flowControl: option.flowControl
292
+ flowControl: option.flowControl,
293
+ redact: option.redact
281
294
  };
282
295
  });
283
296
  const result = await triggerFirstInvocation(invocations);
package/nextjs.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B90SJYZV.mjs';
3
- import { s as serveManyBase } from './serve-many-BsycEL_d.mjs';
2
+ import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.mjs';
3
+ import { s as serveManyBase } from './serve-many-C6sa_DxN.mjs';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
 
package/nextjs.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B90SJYZV.js';
3
- import { s as serveManyBase } from './serve-many-BP-8Ytbc.js';
2
+ import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.js';
3
+ import { s as serveManyBase } from './serve-many-B-fe7bh7.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6