@upstash/workflow 1.2.0-demo-rc.1 → 1.2.1

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 +72 -69
  5. package/astro.mjs +1 -1
  6. package/{chunk-NZCQPOPR.mjs → chunk-THS5AX2D.mjs} +128 -257
  7. package/cloudflare.d.mts +2 -2
  8. package/cloudflare.d.ts +2 -2
  9. package/cloudflare.js +72 -69
  10. package/cloudflare.mjs +1 -1
  11. package/express.d.mts +2 -2
  12. package/express.d.ts +2 -2
  13. package/express.js +72 -69
  14. package/express.mjs +1 -1
  15. package/h3.d.mts +2 -2
  16. package/h3.d.ts +2 -2
  17. package/h3.js +76 -73
  18. package/h3.mjs +5 -5
  19. package/hono.d.mts +2 -2
  20. package/hono.d.ts +2 -2
  21. package/hono.js +73 -265
  22. package/hono.mjs +2 -7
  23. package/index.d.mts +229 -138
  24. package/index.d.ts +229 -138
  25. package/index.js +275 -454
  26. package/index.mjs +144 -196
  27. package/nextjs.d.mts +2 -2
  28. package/nextjs.d.ts +2 -2
  29. package/nextjs.js +72 -263
  30. package/nextjs.mjs +1 -5
  31. package/package.json +1 -1
  32. package/react-router.d.mts +38 -0
  33. package/react-router.d.ts +38 -0
  34. package/react-router.js +3881 -0
  35. package/react-router.mjs +45 -0
  36. package/{serve-many-Bi8XaOyq.d.ts → serve-many-B-fe7bh7.d.ts} +1 -1
  37. package/{serve-many-CppVPJrh.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 +72 -69
  41. package/solidjs.mjs +1 -1
  42. package/svelte.d.mts +2 -2
  43. package/svelte.d.ts +2 -2
  44. package/svelte.js +72 -69
  45. package/svelte.mjs +1 -1
  46. package/tanstack.d.mts +2 -2
  47. package/tanstack.d.ts +2 -2
  48. package/tanstack.js +72 -69
  49. package/tanstack.mjs +1 -1
  50. package/{types-CUwgrpCM.d.ts → types-B2S08hRU.d.mts} +18 -3
  51. package/{types-CUwgrpCM.d.mts → types-B2S08hRU.d.ts} +18 -3
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
  });
@@ -195,11 +196,72 @@ var getSteps = async (requester, workflowRunId, messageId, dispatchDebug) => {
195
196
  }
196
197
  }
197
198
  };
199
+ function normalizeCursor(response) {
200
+ const cursor = response.cursor;
201
+ return { ...response, cursor: cursor || void 0 };
202
+ }
203
+ var DEFAULT_BULK_COUNT = 100;
204
+ function buildBulkActionQueryParameters(request, options) {
205
+ const cursor = "cursor" in request ? request.cursor : void 0;
206
+ if ("all" in request) {
207
+ return { count: request.count ?? DEFAULT_BULK_COUNT, cursor };
208
+ }
209
+ if ("dlqIds" in request) {
210
+ const ids = request.dlqIds;
211
+ if (Array.isArray(ids) && ids.length === 0) {
212
+ throw new import_qstash2.QstashError(
213
+ "Empty dlqIds array provided. If you intend to target all DLQ messages, use { all: true } explicitly."
214
+ );
215
+ }
216
+ return { dlqIds: ids, cursor };
217
+ }
218
+ if ("workflowRunIds" in request && request.workflowRunIds) {
219
+ if (request.workflowRunIds.length === 0) {
220
+ throw new import_qstash2.QstashError(
221
+ "Empty workflowRunIds array provided. If you intend to target all workflow runs, use { all: true } explicitly."
222
+ );
223
+ }
224
+ return { workflowRunIds: request.workflowRunIds };
225
+ }
226
+ const filter = request.filter;
227
+ if (!filter) {
228
+ throw new import_qstash2.QstashError(
229
+ "No filter provided. Use { filter: { ... } } with at least one filter field, or { all: true }."
230
+ );
231
+ }
232
+ if (options?.translateWorkflowUrl) {
233
+ const { workflowUrlStartingWith, workflowUrl, ...rest } = filter;
234
+ if (workflowUrlStartingWith && workflowUrl) {
235
+ throw new import_qstash2.QstashError(
236
+ "workflowUrl and workflowUrlStartingWith are mutually exclusive. Use workflowUrl for exact match or workflowUrlStartingWith for prefix match."
237
+ );
238
+ }
239
+ const urlParams = {};
240
+ if (workflowUrlStartingWith) {
241
+ urlParams.workflowUrl = workflowUrlStartingWith;
242
+ } else if (workflowUrl) {
243
+ urlParams.workflowUrl = workflowUrl;
244
+ urlParams.workflowUrlExactMatch = true;
245
+ }
246
+ return {
247
+ ...rest,
248
+ ...urlParams,
249
+ count: request.count ?? DEFAULT_BULK_COUNT,
250
+ cursor
251
+ };
252
+ }
253
+ return {
254
+ ...filter,
255
+ count: request.count ?? DEFAULT_BULK_COUNT,
256
+ cursor
257
+ };
258
+ }
198
259
 
199
260
  // src/constants.ts
200
261
  var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
201
262
  var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
202
263
  var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
264
+ var WORKFLOW_CREATED_AT_HEADER = "Upstash-Workflow-CreatedAt";
203
265
  var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
204
266
  var WORKFLOW_FAILURE_CALLBACK_HEADER = "Upstash-Workflow-Failure-Callback";
205
267
  var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
@@ -735,6 +797,7 @@ var triggerFirstInvocation = async (params) => {
735
797
  retries,
736
798
  retryDelay,
737
799
  flowControl,
800
+ redact,
738
801
  unknownSdk
739
802
  }) => {
740
803
  const { headers } = getHeaders({
@@ -771,7 +834,8 @@ var triggerFirstInvocation = async (params) => {
771
834
  body,
772
835
  url: workflowContext.url,
773
836
  delay,
774
- notBefore
837
+ notBefore,
838
+ redact
775
839
  };
776
840
  }
777
841
  );
@@ -930,7 +994,6 @@ ${atob(callbackMessage.body ?? "")}`
930
994
  })}`
931
995
  );
932
996
  }
933
- const userHeaders = recreateUserHeaders(request.headers);
934
997
  const { headers: requestHeaders } = getHeaders({
935
998
  initHeaderValue: "false",
936
999
  workflowConfig: {
@@ -938,7 +1001,6 @@ ${atob(callbackMessage.body ?? "")}`
938
1001
  workflowUrl,
939
1002
  telemetry
940
1003
  },
941
- userHeaders,
942
1004
  invokeCount: Number(invokeCount)
943
1005
  });
944
1006
  const callResponse = {
@@ -1087,7 +1149,6 @@ var BaseLazyStep = class _BaseLazyStep {
1087
1149
  useJSONContent: false,
1088
1150
  telemetry
1089
1151
  },
1090
- userHeaders: context.headers,
1091
1152
  invokeCount,
1092
1153
  stepInfo: {
1093
1154
  step,
@@ -1445,9 +1506,9 @@ var LazyWaitEventStep = class extends BaseLazyStep {
1445
1506
  };
1446
1507
  var LazyNotifyStep = class extends LazyFunctionStep {
1447
1508
  stepType = "Notify";
1448
- constructor(context, stepName, eventId, eventData, requester) {
1509
+ constructor(context, stepName, eventId, eventData, requester, workflowRunId) {
1449
1510
  super(context, stepName, async () => {
1450
- const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
1511
+ const notifyResponse = await makeNotifyRequest(requester, eventId, eventData, workflowRunId);
1451
1512
  return {
1452
1513
  eventId,
1453
1514
  eventData,
@@ -1517,7 +1578,6 @@ var LazyInvokeStep = class extends BaseLazyStep {
1517
1578
  telemetry,
1518
1579
  useJSONContent: false
1519
1580
  },
1520
- userHeaders: context.headers,
1521
1581
  invokeCount
1522
1582
  });
1523
1583
  context.qstashClient.http.headers?.forEach((value, key) => {
@@ -1530,6 +1590,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1530
1590
  Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
1531
1591
  ),
1532
1592
  workflowRunId: context.workflowRunId,
1593
+ workflowRunCreatedAt: context.workflowRunCreatedAt,
1533
1594
  workflowUrl: context.url,
1534
1595
  step
1535
1596
  };
@@ -1625,12 +1686,14 @@ var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
1625
1686
  const parsedEventData = BaseLazyStep.tryParsing(eventData);
1626
1687
  const body = parsedEventData.body;
1627
1688
  const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
1689
+ const methodUpper = parsedEventData.method.toUpperCase();
1690
+ const canHaveBody = methodUpper !== "GET" && methodUpper !== "HEAD";
1628
1691
  const request = new Request(
1629
1692
  `${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
1630
1693
  {
1631
1694
  method: parsedEventData.method,
1632
1695
  headers: parsedEventData.header,
1633
- body: parsedBody
1696
+ body: canHaveBody ? parsedBody : void 0
1634
1697
  }
1635
1698
  );
1636
1699
  return {
@@ -1764,6 +1827,9 @@ var WorkflowHeaders = class {
1764
1827
  }
1765
1828
  }
1766
1829
  addUserHeaders() {
1830
+ if (!this.userHeaders) {
1831
+ return;
1832
+ }
1767
1833
  for (const [key, value] of this.userHeaders.entries()) {
1768
1834
  const forwardKey = `Forward-${key}`;
1769
1835
  this.headers.workflowHeaders[forwardKey] = value;
@@ -1870,7 +1936,6 @@ var submitParallelSteps = async ({
1870
1936
  workflowUrl: context.url,
1871
1937
  telemetry
1872
1938
  },
1873
- userHeaders: context.headers,
1874
1939
  invokeCount
1875
1940
  });
1876
1941
  return {
@@ -2123,7 +2188,7 @@ var AutoExecutor = class _AutoExecutor {
2123
2188
  });
2124
2189
  throw new WorkflowAbort(parallelStep.stepName, resultStep);
2125
2190
  } catch (error) {
2126
- if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
2191
+ if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400 || isInstanceOf(error, import_qstash5.QstashError) && error.status === 412) {
2127
2192
  throw error;
2128
2193
  }
2129
2194
  throw new WorkflowError(
@@ -2530,6 +2595,7 @@ var MiddlewareManager = class {
2530
2595
  };
2531
2596
 
2532
2597
  // src/context/context.ts
2598
+ var import_qstash9 = require("@upstash/qstash");
2533
2599
  var WorkflowContext = class {
2534
2600
  executor;
2535
2601
  steps;
@@ -2556,6 +2622,10 @@ var WorkflowContext = class {
2556
2622
  * Run id of the workflow
2557
2623
  */
2558
2624
  workflowRunId;
2625
+ /**
2626
+ * Creation time of the workflow run
2627
+ */
2628
+ workflowRunCreatedAt;
2559
2629
  /**
2560
2630
  * URL of the workflow
2561
2631
  *
@@ -2647,6 +2717,7 @@ var WorkflowContext = class {
2647
2717
  constructor({
2648
2718
  qstashClient,
2649
2719
  workflowRunId,
2720
+ workflowRunCreatedAt,
2650
2721
  headers,
2651
2722
  steps,
2652
2723
  url,
@@ -2659,6 +2730,7 @@ var WorkflowContext = class {
2659
2730
  }) {
2660
2731
  this.qstashClient = qstashClient;
2661
2732
  this.workflowRunId = workflowRunId;
2733
+ this.workflowRunCreatedAt = workflowRunCreatedAt;
2662
2734
  this.steps = steps;
2663
2735
  this.url = url;
2664
2736
  this.headers = headers;
@@ -2833,14 +2905,23 @@ var WorkflowContext = class {
2833
2905
  * a notifyResponse field which contains a list of `Waiter` objects, each corresponding
2834
2906
  * to a notified workflow run.
2835
2907
  *
2908
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
2909
+ *
2910
+ * ```ts
2911
+ * const { eventId, eventData, notifyResponse } = await context.notify(
2912
+ * "notify step", "event-id", "event-data", "wfr_123"
2913
+ * );
2914
+ * ```
2915
+ *
2836
2916
  * @param stepName
2837
2917
  * @param eventId event id to notify
2838
2918
  * @param eventData event data to notify with
2919
+ * @param workflowRunId optional workflow run id for lookback support
2839
2920
  * @returns notify response which has event id, event data and list of waiters which were notified
2840
2921
  */
2841
- async notify(stepName, eventId, eventData) {
2922
+ async notify(stepName, eventId, eventData, workflowRunId) {
2842
2923
  return await this.addStep(
2843
- new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
2924
+ new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http, workflowRunId)
2844
2925
  );
2845
2926
  }
2846
2927
  async invoke(stepName, settings) {
@@ -2868,7 +2949,14 @@ var WorkflowContext = class {
2868
2949
  * DisabledWorkflowContext.
2869
2950
  */
2870
2951
  async addStep(step) {
2871
- return await this.executor.addStep(step);
2952
+ try {
2953
+ return await this.executor.addStep(step);
2954
+ } catch (error) {
2955
+ if (isInstanceOf(error, import_qstash9.QstashError) && error.status === 412) {
2956
+ throw new WorkflowNonRetryableError(error.message);
2957
+ }
2958
+ throw error;
2959
+ }
2872
2960
  }
2873
2961
  get api() {
2874
2962
  return new WorkflowApi({
@@ -2877,214 +2965,8 @@ var WorkflowContext = class {
2877
2965
  }
2878
2966
  };
2879
2967
 
2880
- // src/dev-server.ts
2881
- var import_child_process = require("child_process");
2882
- var import_fs = require("fs");
2883
- var import_https = require("https");
2884
- var import_http = require("http");
2885
- var import_path = require("path");
2886
- var import_os = require("os");
2887
- var DEV_QSTASH_TOKEN = "eyJVc2VySUQiOiJkZWZhdWx0VXNlciIsIlBhc3N3b3JkIjoiZGVmYXVsdFBhc3N3b3JkIn0=";
2888
- var DEV_QSTASH_CURRENT_SIGNING_KEY = "sig_7kYjw48mhY7kAjqNGcy6cr29RJ6r";
2889
- var DEV_QSTASH_NEXT_SIGNING_KEY = "sig_5ZB6DVzB1wjE8S6rZ7eenA8Pdnhs";
2890
- function getDevCredentials(port) {
2891
- return {
2892
- QSTASH_URL: `http://localhost:${port}`,
2893
- QSTASH_TOKEN: DEV_QSTASH_TOKEN,
2894
- QSTASH_CURRENT_SIGNING_KEY: DEV_QSTASH_CURRENT_SIGNING_KEY,
2895
- QSTASH_NEXT_SIGNING_KEY: DEV_QSTASH_NEXT_SIGNING_KEY
2896
- };
2897
- }
2898
- var CACHE_DIR = (0, import_path.join)("node_modules", ".cache", "upstash");
2899
- function getPlatformArch() {
2900
- const platform = process.platform === "darwin" ? "darwin" : "linux";
2901
- const arch = process.arch === "arm64" ? "arm64" : "amd64";
2902
- return { platform, arch };
2903
- }
2904
- function httpsGet(url) {
2905
- return new Promise((resolve, reject) => {
2906
- const request = (currentUrl) => {
2907
- (0, import_https.get)(currentUrl, { headers: { "User-Agent": "upstash-workflow" } }, (res) => {
2908
- if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
2909
- request(res.headers.location);
2910
- return;
2911
- }
2912
- if (res.statusCode && res.statusCode >= 400) {
2913
- reject(new Error(`HTTP ${res.statusCode} fetching ${currentUrl}`));
2914
- return;
2915
- }
2916
- const chunks = [];
2917
- res.on("data", (chunk) => chunks.push(chunk));
2918
- res.on("end", () => resolve(Buffer.concat(chunks)));
2919
- res.on("error", reject);
2920
- }).on("error", reject);
2921
- };
2922
- request(url);
2923
- });
2924
- }
2925
- function downloadToFile(url, dest) {
2926
- return new Promise((resolve, reject) => {
2927
- const request = (currentUrl) => {
2928
- (0, import_https.get)(currentUrl, { headers: { "User-Agent": "upstash-workflow" } }, (res) => {
2929
- if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
2930
- request(res.headers.location);
2931
- return;
2932
- }
2933
- if (res.statusCode && res.statusCode >= 400) {
2934
- reject(new Error(`HTTP ${res.statusCode} downloading ${currentUrl}`));
2935
- return;
2936
- }
2937
- const file = (0, import_fs.createWriteStream)(dest);
2938
- res.pipe(file);
2939
- file.on("finish", () => {
2940
- file.close(() => resolve());
2941
- });
2942
- file.on("error", reject);
2943
- }).on("error", reject);
2944
- };
2945
- request(url);
2946
- });
2947
- }
2948
- async function resolveLatestVersion() {
2949
- const data = await httpsGet("https://api.github.com/repos/upstash/qstash-cli/releases/latest");
2950
- const json = JSON.parse(data.toString());
2951
- return json.tag_name;
2952
- }
2953
- async function ensureBinary() {
2954
- const version = await resolveLatestVersion();
2955
- const cacheDir = (0, import_path.join)(CACHE_DIR, `qstash-server-${version}`);
2956
- const binaryPath = (0, import_path.join)(cacheDir, "qstash");
2957
- if ((0, import_fs.existsSync)(binaryPath)) {
2958
- return binaryPath;
2959
- }
2960
- const { platform, arch } = getPlatformArch();
2961
- const downloadUrl = `https://artifacts.upstash.com/qstash/versions/${version}/qstash-server_${version}_${platform}_${arch}.tar.gz`;
2962
- console.log(`[workflow-dev] Downloading QStash server...`);
2963
- (0, import_fs.mkdirSync)(cacheDir, { recursive: true });
2964
- const tempFile = (0, import_path.join)((0, import_os.tmpdir)(), `qstash-server-${version}-${Date.now()}.tar.gz`);
2965
- await downloadToFile(downloadUrl, tempFile);
2966
- (0, import_child_process.execSync)(`tar -xzf "${tempFile}" -C "${cacheDir}"`);
2967
- (0, import_fs.chmodSync)(binaryPath, 493);
2968
- return binaryPath;
2969
- }
2970
- function startServer(binaryPath, port) {
2971
- return new Promise((resolve, reject) => {
2972
- const child = (0, import_child_process.spawn)(binaryPath, ["dev", "-port", String(port)], {
2973
- stdio: ["ignore", "pipe", "pipe"]
2974
- });
2975
- let resolved = false;
2976
- const cleanup = () => {
2977
- if (!child.killed) {
2978
- child.kill("SIGTERM");
2979
- }
2980
- };
2981
- process.on("exit", cleanup);
2982
- process.on("SIGINT", () => {
2983
- cleanup();
2984
- process.exit(0);
2985
- });
2986
- process.on("SIGTERM", () => {
2987
- cleanup();
2988
- process.exit(0);
2989
- });
2990
- let stdoutBuffer = "";
2991
- child.stdout.on("data", (data) => {
2992
- const text = data.toString();
2993
- stdoutBuffer += text;
2994
- const lines = stdoutBuffer.split("\n");
2995
- stdoutBuffer = lines.pop() ?? "";
2996
- for (const line of lines) {
2997
- if (line.match(/runn+ing at/) && !resolved) {
2998
- resolved = true;
2999
- const creds = getDevCredentials(port);
3000
- console.log(`[workflow-dev] QStash server running at ${creds.QSTASH_URL}`);
3001
- console.log(
3002
- `[workflow-dev] View logs at \x1B[1;32mhttps://console.upstash.com/workflow/local-mode-user/logs\x1B[0m`
3003
- );
3004
- resolve(cleanup);
3005
- }
3006
- }
3007
- });
3008
- child.stderr.on("data", (data) => {
3009
- const text = data.toString();
3010
- if (!resolved) {
3011
- process.stderr.write(`[workflow-dev] ${text}`);
3012
- }
3013
- });
3014
- child.on("error", (err2) => {
3015
- if (!resolved) {
3016
- reject(new Error(`[workflow-dev] Failed to start QStash server: ${err2.message}`));
3017
- }
3018
- });
3019
- child.on("exit", (code) => {
3020
- if (!resolved) {
3021
- reject(
3022
- new Error(`[workflow-dev] QStash server exited with code ${code} before becoming ready`)
3023
- );
3024
- }
3025
- });
3026
- setTimeout(() => {
3027
- if (!resolved) {
3028
- cleanup();
3029
- reject(new Error("[workflow-dev] QStash server did not become ready within 30 seconds"));
3030
- }
3031
- }, 3e4);
3032
- });
3033
- }
3034
- function isDevServerRunning(port) {
3035
- return new Promise((resolve) => {
3036
- const req = (0, import_http.get)(
3037
- `http://127.0.0.1:${port}/v2/keys`,
3038
- {
3039
- headers: { Authorization: `Bearer ${DEV_QSTASH_TOKEN}` },
3040
- timeout: 2e3
3041
- },
3042
- (res) => {
3043
- if (res.statusCode !== 200) {
3044
- resolve(false);
3045
- return;
3046
- }
3047
- const chunks = [];
3048
- res.on("data", (chunk) => chunks.push(chunk));
3049
- res.on("end", () => {
3050
- try {
3051
- const body = JSON.parse(Buffer.concat(chunks).toString());
3052
- resolve(
3053
- body.current === DEV_QSTASH_CURRENT_SIGNING_KEY && body.next === DEV_QSTASH_NEXT_SIGNING_KEY
3054
- );
3055
- } catch {
3056
- resolve(false);
3057
- }
3058
- });
3059
- res.on("error", () => resolve(false));
3060
- }
3061
- );
3062
- req.on("error", () => resolve(false));
3063
- req.on("timeout", () => {
3064
- req.destroy();
3065
- resolve(false);
3066
- });
3067
- });
3068
- }
3069
- var serverPromise = null;
3070
- var serverCleanup = null;
3071
- function ensureDevServer(environment) {
3072
- if (!serverPromise) {
3073
- const port = Number(environment.WORKFLOW_DEV_PORT) || 8080;
3074
- serverPromise = isDevServerRunning(port).then((alreadyRunning) => {
3075
- if (alreadyRunning) {
3076
- return;
3077
- }
3078
- return ensureBinary().then((binaryPath) => startServer(binaryPath, port)).then((cleanup) => {
3079
- serverCleanup = cleanup;
3080
- });
3081
- });
3082
- }
3083
- return serverPromise;
3084
- }
3085
-
3086
2968
  // src/serve/authorization.ts
3087
- var import_qstash9 = require("@upstash/qstash");
2969
+ var import_qstash10 = require("@upstash/qstash");
3088
2970
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
3089
2971
  static disabledMessage = "disabled-qstash-worklfow-run";
3090
2972
  disabled = true;
@@ -3116,11 +2998,12 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3116
2998
  */
3117
2999
  static async tryAuthentication(routeFunction, context) {
3118
3000
  const disabledContext = new _DisabledWorkflowContext({
3119
- qstashClient: new import_qstash9.Client({
3001
+ qstashClient: new import_qstash10.Client({
3120
3002
  baseUrl: "disabled-client",
3121
3003
  token: "disabled-client"
3122
3004
  }),
3123
3005
  workflowRunId: context.workflowRunId,
3006
+ workflowRunCreatedAt: context.workflowRunCreatedAt,
3124
3007
  headers: context.headers,
3125
3008
  steps: [],
3126
3009
  url: context.url,
@@ -3322,7 +3205,9 @@ var handleFailure = async ({
3322
3205
  return ok({ result: "failure-function-undefined" });
3323
3206
  }
3324
3207
  try {
3325
- const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
3208
+ const { status, header, body, url, sourceBody, workflowRunId, workflowCreatedAt } = JSON.parse(
3209
+ requestPayload
3210
+ );
3326
3211
  const decodedBody = body ? decodeBase64(body) : "{}";
3327
3212
  let errorMessage = "";
3328
3213
  let failStack = "";
@@ -3351,6 +3236,7 @@ var handleFailure = async ({
3351
3236
  telemetry: void 0,
3352
3237
  // not going to make requests in authentication check
3353
3238
  label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0,
3239
+ workflowRunCreatedAt: workflowCreatedAt,
3354
3240
  middlewareManager: void 0
3355
3241
  });
3356
3242
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
@@ -3379,7 +3265,7 @@ var handleFailure = async ({
3379
3265
  };
3380
3266
 
3381
3267
  // src/serve/multi-region/handlers.ts
3382
- var import_qstash10 = require("@upstash/qstash");
3268
+ var import_qstash11 = require("@upstash/qstash");
3383
3269
 
3384
3270
  // src/serve/multi-region/utils.ts
3385
3271
  var VALID_REGIONS = ["EU_CENTRAL_1", "US_EAST_1"];
@@ -3444,7 +3330,7 @@ var getHandlersForRequest = (qstashHandlers, regionHeader, isFirstInvocation) =>
3444
3330
  };
3445
3331
  var createRegionalHandler = (environment, receiverConfig, region, clientOptions) => {
3446
3332
  const clientEnv = readClientEnvironmentVariables(environment, region);
3447
- const client = new import_qstash10.Client({
3333
+ const client = new import_qstash11.Client({
3448
3334
  ...clientOptions,
3449
3335
  baseUrl: clientEnv.QSTASH_URL,
3450
3336
  token: clientEnv.QSTASH_TOKEN
@@ -3494,7 +3380,7 @@ var getQStashHandlers = ({
3494
3380
  return {
3495
3381
  mode: "single-region",
3496
3382
  handlers: {
3497
- client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new import_qstash10.Client({
3383
+ client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new import_qstash11.Client({
3498
3384
  ...qstashClientOption,
3499
3385
  baseUrl: environment.QSTASH_URL,
3500
3386
  token: environment.QSTASH_TOKEN
@@ -3510,7 +3396,7 @@ var getReceiver = (environment, receiverConfig, region) => {
3510
3396
  return void 0;
3511
3397
  }
3512
3398
  const receiverEnv = readReceiverEnvironmentVariables(environment, region);
3513
- return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash10.Receiver({
3399
+ return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash11.Receiver({
3514
3400
  currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
3515
3401
  nextSigningKey: receiverEnv.QSTASH_NEXT_SIGNING_KEY
3516
3402
  }) : void 0;
@@ -3736,33 +3622,19 @@ var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is une
3736
3622
 
3737
3623
  // src/serve/index.ts
3738
3624
  var serveBase = (routeFunction, telemetry, options, internalOptions) => {
3739
- const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
3740
- const devMode = environment.WORKFLOW_DEV === "true";
3741
- if (devMode) {
3742
- const port = Number(environment.WORKFLOW_DEV_PORT) || 8080;
3743
- const creds = getDevCredentials(port);
3744
- for (const [k, v] of Object.entries(creds)) {
3745
- if (!environment[k]) {
3746
- environment[k] = v;
3747
- }
3748
- }
3749
- }
3750
- const resolvedOptions = processOptions(
3751
- options,
3752
- internalOptions
3753
- );
3625
+ const {
3626
+ initialPayloadParser,
3627
+ url,
3628
+ failureFunction,
3629
+ baseUrl,
3630
+ env,
3631
+ disableTelemetry,
3632
+ middlewares,
3633
+ internal
3634
+ } = processOptions(options, internalOptions);
3635
+ telemetry = disableTelemetry ? void 0 : telemetry;
3636
+ const { generateResponse: responseGenerator, useJSONContent } = internal;
3754
3637
  const handler = async (request, middlewareManager) => {
3755
- const {
3756
- initialPayloadParser,
3757
- url,
3758
- failureFunction,
3759
- baseUrl,
3760
- env,
3761
- disableTelemetry: optDisableTelemetry,
3762
- internal
3763
- } = resolvedOptions;
3764
- const currentTelemetry = optDisableTelemetry ? void 0 : telemetry;
3765
- const { generateResponse: responseGenerator, useJSONContent } = internal;
3766
3638
  await middlewareManager.dispatchDebug("onInfo", {
3767
3639
  info: `Received request for workflow execution.`
3768
3640
  });
@@ -3842,6 +3714,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
3842
3714
  }
3843
3715
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3844
3716
  const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
3717
+ const workflowRunCreatedAt = request.headers.get(WORKFLOW_CREATED_AT_HEADER);
3845
3718
  const workflowContext = new WorkflowContext({
3846
3719
  qstashClient: regionalClient,
3847
3720
  workflowRunId,
@@ -3850,9 +3723,10 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
3850
3723
  steps,
3851
3724
  url: workflowUrl,
3852
3725
  env,
3853
- telemetry: currentTelemetry,
3726
+ telemetry,
3854
3727
  invokeCount,
3855
3728
  label,
3729
+ workflowRunCreatedAt: Number(workflowRunCreatedAt),
3856
3730
  middlewareManager
3857
3731
  });
3858
3732
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
@@ -3876,7 +3750,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
3876
3750
  requestPayload: rawInitialPayload,
3877
3751
  client: regionalClient,
3878
3752
  workflowUrl,
3879
- telemetry: currentTelemetry,
3753
+ telemetry,
3880
3754
  middlewareManager
3881
3755
  });
3882
3756
  if (callReturnCheck.isErr()) {
@@ -3885,7 +3759,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
3885
3759
  const result = isFirstInvocation ? await triggerFirstInvocation({
3886
3760
  workflowContext,
3887
3761
  useJSONContent,
3888
- telemetry: currentTelemetry,
3762
+ telemetry,
3889
3763
  invokeCount,
3890
3764
  middlewareManager,
3891
3765
  unknownSdk
@@ -3953,9 +3827,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
3953
3827
  );
3954
3828
  };
3955
3829
  const safeHandler = async (request) => {
3956
- const middlewareManager = new MiddlewareManager(
3957
- resolvedOptions.middlewares
3958
- );
3830
+ const middlewareManager = new MiddlewareManager(middlewares);
3959
3831
  try {
3960
3832
  return await handler(request, middlewareManager);
3961
3833
  } catch (error) {
@@ -3985,10 +3857,22 @@ var serve = (routeFunction, options) => {
3985
3857
  };
3986
3858
 
3987
3859
  // src/client/index.ts
3988
- var import_qstash11 = require("@upstash/qstash");
3860
+ var import_qstash12 = require("@upstash/qstash");
3989
3861
 
3990
3862
  // src/client/dlq.ts
3991
- var DLQ = class _DLQ {
3863
+ function buildResumeRestartHeaders(options) {
3864
+ const headers = {};
3865
+ if (options?.flowControl) {
3866
+ const { flowControlKey, flowControlValue } = prepareFlowControl(options.flowControl);
3867
+ headers["Upstash-Flow-Control-Key"] = flowControlKey;
3868
+ headers["Upstash-Flow-Control-Value"] = flowControlValue;
3869
+ }
3870
+ if (options?.retries !== void 0) {
3871
+ headers["Upstash-Retries"] = options.retries.toString();
3872
+ }
3873
+ return headers;
3874
+ }
3875
+ var DLQ = class {
3992
3876
  constructor(client) {
3993
3877
  this.client = client;
3994
3878
  }
@@ -4011,40 +3895,66 @@ var DLQ = class _DLQ {
4011
3895
  */
4012
3896
  async list(parameters) {
4013
3897
  const { cursor, count, filter } = parameters || {};
4014
- return await this.client.http.request({
4015
- path: ["v2", "dlq"],
4016
- method: "GET",
4017
- query: {
4018
- cursor,
4019
- count,
4020
- ...filter,
4021
- source: "workflow"
4022
- }
4023
- });
3898
+ return normalizeCursor(
3899
+ await this.client.http.request({
3900
+ path: ["v2", "dlq"],
3901
+ method: "GET",
3902
+ query: {
3903
+ cursor,
3904
+ count,
3905
+ ...filter,
3906
+ source: "workflow"
3907
+ }
3908
+ })
3909
+ );
4024
3910
  }
4025
- async resume(parameters) {
4026
- const { headers, queryParams } = _DLQ.handleDLQOptions(parameters);
4027
- const { workflowRuns } = await this.client.http.request({
4028
- path: ["v2", "workflows", "dlq", `resume?${queryParams}`],
4029
- headers,
4030
- method: "POST"
4031
- });
4032
- if (Array.isArray(parameters.dlqId)) {
4033
- return workflowRuns;
3911
+ async resume(request, options) {
3912
+ if (typeof request === "object" && !Array.isArray(request) && "dlqId" in request) {
3913
+ const { dlqId, flowControl, retries } = request;
3914
+ const dlqIds = Array.isArray(dlqId) ? dlqId : [dlqId];
3915
+ const { workflowRuns } = await this.client.http.request({
3916
+ path: ["v2", "workflows", "dlq", "resume"],
3917
+ query: { dlqIds },
3918
+ method: "POST",
3919
+ headers: buildResumeRestartHeaders({ flowControl, retries })
3920
+ });
3921
+ return Array.isArray(dlqId) ? workflowRuns : workflowRuns[0];
4034
3922
  }
4035
- return workflowRuns[0];
3923
+ if (typeof request === "string") request = [request];
3924
+ if (Array.isArray(request) && request.length === 0) return { workflowRuns: [] };
3925
+ const filters = Array.isArray(request) ? { dlqIds: request } : request;
3926
+ return normalizeCursor(
3927
+ await this.client.http.request({
3928
+ path: ["v2", "workflows", "dlq", "resume"],
3929
+ query: buildBulkActionQueryParameters(filters),
3930
+ method: "POST",
3931
+ headers: buildResumeRestartHeaders(options)
3932
+ })
3933
+ );
4036
3934
  }
4037
- async restart(parameters) {
4038
- const { headers, queryParams } = _DLQ.handleDLQOptions(parameters);
4039
- const { workflowRuns } = await this.client.http.request({
4040
- path: ["v2", "workflows", "dlq", `restart?${queryParams}`],
4041
- headers,
4042
- method: "POST"
4043
- });
4044
- if (Array.isArray(parameters.dlqId)) {
4045
- return workflowRuns;
3935
+ async restart(request, options) {
3936
+ if (typeof request === "object" && !Array.isArray(request) && "dlqId" in request) {
3937
+ const { dlqId, flowControl, retries } = request;
3938
+ const dlqIds = Array.isArray(dlqId) ? dlqId : [dlqId];
3939
+ const { workflowRuns } = await this.client.http.request({
3940
+ path: ["v2", "workflows", "dlq", "restart"],
3941
+ query: { dlqIds },
3942
+ method: "POST",
3943
+ headers: buildResumeRestartHeaders({ flowControl, retries })
3944
+ });
3945
+ return Array.isArray(dlqId) ? workflowRuns : workflowRuns[0];
4046
3946
  }
4047
- return workflowRuns[0];
3947
+ if (typeof request === "string") request = [request];
3948
+ if (Array.isArray(request) && request.length === 0) return { workflowRuns: [] };
3949
+ const filters = Array.isArray(request) ? { dlqIds: request } : request;
3950
+ return normalizeCursor(
3951
+ await this.client.http.request({
3952
+ path: ["v2", "workflows", "dlq", "restart"],
3953
+ query: buildBulkActionQueryParameters(filters),
3954
+ method: "POST",
3955
+ headers: buildResumeRestartHeaders(options)
3956
+ })
3957
+ );
4048
3958
  }
4049
3959
  /**
4050
3960
  * Retry the failure callback of a workflow run whose failureUrl/failureFunction
@@ -4061,148 +3971,64 @@ var DLQ = class _DLQ {
4061
3971
  return response;
4062
3972
  }
4063
3973
  /**
4064
- * Handles DLQ options and prepares headers and query parameters.
3974
+ * Delete DLQ messages.
4065
3975
  *
4066
- * @param options - DLQ resume/restart options
4067
- */
4068
- static handleDLQOptions(options) {
4069
- const { dlqId, flowControl, retries } = options;
4070
- const headers = {};
4071
- if (flowControl) {
4072
- const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
4073
- headers["Upstash-Flow-Control-Key"] = flowControlKey;
4074
- headers["Upstash-Flow-Control-Value"] = flowControlValue;
4075
- }
4076
- if (retries !== void 0) {
4077
- headers["Upstash-Retries"] = retries.toString();
4078
- }
4079
- return {
4080
- queryParams: _DLQ.getDlqIdQueryParameter(dlqId),
4081
- headers
4082
- };
4083
- }
4084
- /**
4085
- * Converts DLQ ID(s) to query parameter string.
3976
+ * Can be called with:
3977
+ * - A single dlqId: `delete("id")`
3978
+ * - An array of dlqIds: `delete(["id1", "id2"])`
3979
+ * - A filter object: `delete({ filter: { label: "my-label", fromDate: 1640995200000 } })`
3980
+ * - To target all entries: `delete({ all: true })`
4086
3981
  *
4087
- * @param dlqId - Single DLQ ID or array of DLQ IDs
3982
+ * Processes up to `count` messages per call (defaults to 100).
3983
+ * Call in a loop until cursor is undefined to process all:
3984
+ *
3985
+ * ```ts
3986
+ * let cursor: string | undefined;
3987
+ * do {
3988
+ * const result = await client.dlq.delete({ all: true, count: 100, cursor });
3989
+ * cursor = result.cursor;
3990
+ * } while (cursor);
3991
+ * ```
4088
3992
  */
4089
- static getDlqIdQueryParameter(dlqId) {
4090
- const dlqIds = Array.isArray(dlqId) ? dlqId : [dlqId];
4091
- const paramsArray = dlqIds.map((id) => ["dlqIds", id]);
4092
- return new URLSearchParams(paramsArray).toString();
3993
+ async delete(request) {
3994
+ if (typeof request === "string") request = [request];
3995
+ if (Array.isArray(request) && request.length === 0) return { deleted: 0 };
3996
+ const filters = Array.isArray(request) ? { dlqIds: request } : request;
3997
+ return normalizeCursor(
3998
+ await this.client.http.request({
3999
+ path: ["v2", "workflows", "dlq"],
4000
+ method: "DELETE",
4001
+ query: buildBulkActionQueryParameters(filters)
4002
+ })
4003
+ );
4093
4004
  }
4094
4005
  };
4095
4006
 
4096
4007
  // src/client/index.ts
4097
4008
  var Client4 = class {
4098
4009
  client;
4099
- devMode;
4100
4010
  constructor(clientConfig) {
4101
- const env = typeof process === "undefined" ? {} : process.env;
4102
- this.devMode = env.WORKFLOW_DEV === "true";
4103
- if (this.devMode) {
4104
- const port = Number(env.WORKFLOW_DEV_PORT) || 8080;
4105
- const creds = getDevCredentials(port);
4106
- this.client = new import_qstash11.Client({
4107
- ...clientConfig,
4108
- token: DEV_QSTASH_TOKEN,
4109
- baseUrl: creds.QSTASH_URL
4110
- });
4111
- } else if (!clientConfig) {
4112
- throw new Error(
4113
- "[Upstash Workflow] Client requires a token. Either pass { token: '...' } or set WORKFLOW_DEV=true."
4114
- );
4115
- } else {
4116
- this.client = new import_qstash11.Client(clientConfig);
4117
- }
4118
- }
4119
- /**
4120
- * In dev mode, ensures the dev server is running before making requests.
4121
- * If a server is already listening on the port (started by another process
4122
- * or by a platform's serve()), this is a no-op.
4123
- */
4124
- async ensureReady() {
4125
- if (this.devMode) {
4126
- await ensureDevServer(process.env);
4127
- }
4128
- }
4129
- /**
4130
- * Cancel an ongoing workflow
4131
- *
4132
- * Returns true if workflow is canceled succesfully. Otherwise, throws error.
4133
- *
4134
- * There are multiple ways you can cancel workflows:
4135
- * - pass one or more workflow run ids to cancel them
4136
- * - pass a workflow url to cancel all runs starting with this url
4137
- * - cancel all pending or active workflow runs
4138
- *
4139
- * ### Cancel a set of workflow runs
4140
- *
4141
- * ```ts
4142
- * // cancel a single workflow
4143
- * await client.cancel({ ids: "<WORKFLOW_RUN_ID>" })
4144
- *
4145
- * // cancel a set of workflow runs
4146
- * await client.cancel({ ids: [
4147
- * "<WORKFLOW_RUN_ID_1>",
4148
- * "<WORKFLOW_RUN_ID_2>",
4149
- * ]})
4150
- * ```
4151
- *
4152
- * ### Cancel workflows starting with a url
4153
- *
4154
- * If you have an endpoint called `https://your-endpoint.com` and you
4155
- * want to cancel all workflow runs on it, you can use `urlStartingWith`.
4156
- *
4157
- * Note that this will cancel workflows in all endpoints under
4158
- * `https://your-endpoint.com`.
4159
- *
4160
- * ```ts
4161
- * await client.cancel({ urlStartingWith: "https://your-endpoint.com" })
4162
- * ```
4163
- *
4164
- * ### Cancel *all* workflows
4165
- *
4166
- * To cancel all pending and currently running workflows, you can
4167
- * do it like this:
4168
- *
4169
- * ```ts
4170
- * await client.cancel({ all: true })
4171
- * ```
4172
- *
4173
- * @param ids run id of the workflow to delete
4174
- * @param urlStartingWith cancel workflows starting with this url. Will be ignored
4175
- * if `ids` parameter is set.
4176
- * @param all set to true in order to cancel all workflows. Will be ignored
4177
- * if `ids` or `urlStartingWith` parameters are set.
4178
- * @returns true if workflow is succesfully deleted. Otherwise throws QStashError
4179
- */
4180
- async cancel({
4181
- ids,
4182
- urlStartingWith,
4183
- all
4184
- }) {
4185
- await this.ensureReady();
4186
- let body;
4187
- if (ids) {
4188
- const runIdArray = typeof ids === "string" ? [ids] : ids;
4189
- body = JSON.stringify({ workflowRunIds: runIdArray });
4190
- } else if (urlStartingWith) {
4191
- body = JSON.stringify({ workflowUrl: urlStartingWith });
4192
- } else if (all) {
4193
- body = "{}";
4194
- } else {
4195
- throw new TypeError("The `cancel` method cannot be called without any options.");
4011
+ this.client = new import_qstash12.Client(clientConfig);
4012
+ }
4013
+ async cancel(request) {
4014
+ if (typeof request === "object" && !Array.isArray(request) && ("ids" in request || "urlStartingWith" in request)) {
4015
+ const legacy = request;
4016
+ if (legacy.ids) {
4017
+ const ids = typeof legacy.ids === "string" ? [legacy.ids] : legacy.ids;
4018
+ return this.cancel(ids);
4019
+ }
4020
+ if (legacy.urlStartingWith) {
4021
+ return this.cancel({ filter: { workflowUrlStartingWith: legacy.urlStartingWith } });
4022
+ }
4196
4023
  }
4197
- const result = await this.client.http.request({
4024
+ if (typeof request === "string") request = [request];
4025
+ if (Array.isArray(request) && request.length === 0) return { cancelled: 0 };
4026
+ const filters = Array.isArray(request) ? { workflowRunIds: request } : request;
4027
+ return await this.client.http.request({
4198
4028
  path: ["v2", "workflows", "runs"],
4199
4029
  method: "DELETE",
4200
- body,
4201
- headers: {
4202
- "Content-Type": "application/json"
4203
- }
4030
+ query: buildBulkActionQueryParameters(filters, { translateWorkflowUrl: true })
4204
4031
  });
4205
- return result;
4206
4032
  }
4207
4033
  /**
4208
4034
  * Notify a workflow run waiting for an event
@@ -4217,15 +4043,26 @@ var Client4 = class {
4217
4043
  * });
4218
4044
  * ```
4219
4045
  *
4046
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
4047
+ *
4048
+ * ```ts
4049
+ * await client.notify({
4050
+ * eventId: "my-event-id",
4051
+ * eventData: "my-data",
4052
+ * workflowRunId: "wfr_123" // enables lookback
4053
+ * });
4054
+ * ```
4055
+ *
4220
4056
  * @param eventId event id to notify
4221
4057
  * @param eventData data to provide to the workflow
4058
+ * @param workflowRunId optional workflow run id for lookback support
4222
4059
  */
4223
4060
  async notify({
4224
4061
  eventId,
4225
- eventData
4062
+ eventData,
4063
+ workflowRunId
4226
4064
  }) {
4227
- await this.ensureReady();
4228
- return await makeNotifyRequest(this.client.http, eventId, eventData);
4065
+ return await makeNotifyRequest(this.client.http, eventId, eventData, workflowRunId);
4229
4066
  }
4230
4067
  /**
4231
4068
  * Check waiters of an event
@@ -4242,11 +4079,9 @@ var Client4 = class {
4242
4079
  * @param eventId event id to check
4243
4080
  */
4244
4081
  async getWaiters({ eventId }) {
4245
- await this.ensureReady();
4246
4082
  return await makeGetWaitersRequest(this.client.http, eventId);
4247
4083
  }
4248
4084
  async trigger(params) {
4249
- await this.ensureReady();
4250
4085
  const isBatchInput = Array.isArray(params);
4251
4086
  const options = isBatchInput ? params : [params];
4252
4087
  const invocations = options.map((option) => {
@@ -4263,7 +4098,9 @@ var Client4 = class {
4263
4098
  url: option.url,
4264
4099
  workflowRunId: finalWorkflowRunId,
4265
4100
  telemetry: option.disableTelemetry ? void 0 : { sdk: SDK_TELEMETRY },
4266
- label: option.label
4101
+ label: option.label,
4102
+ workflowRunCreatedAt: Date.now()
4103
+ // pass a timestamp (server will override it)
4267
4104
  });
4268
4105
  return {
4269
4106
  workflowContext: context,
@@ -4273,7 +4110,8 @@ var Client4 = class {
4273
4110
  failureUrl,
4274
4111
  retries: option.retries,
4275
4112
  retryDelay: option.retryDelay,
4276
- flowControl: option.flowControl
4113
+ flowControl: option.flowControl,
4114
+ redact: option.redact
4277
4115
  };
4278
4116
  });
4279
4117
  const result = await triggerFirstInvocation(invocations);
@@ -4314,34 +4152,17 @@ var Client4 = class {
4314
4152
  * ```
4315
4153
  */
4316
4154
  async logs(params) {
4317
- await this.ensureReady();
4318
- const { workflowRunId, cursor, count, state, workflowUrl, workflowCreatedAt } = params ?? {};
4319
- const urlParams = new URLSearchParams({ groupBy: "workflowRunId" });
4320
- if (workflowRunId) {
4321
- urlParams.append("workflowRunId", workflowRunId);
4322
- }
4323
- if (cursor) {
4324
- urlParams.append("cursor", cursor);
4325
- }
4326
- if (count) {
4327
- urlParams.append("count", count.toString());
4328
- }
4329
- if (state) {
4330
- urlParams.append("state", state);
4331
- }
4332
- if (workflowUrl) {
4333
- urlParams.append("workflowUrl", workflowUrl);
4334
- }
4335
- if (workflowCreatedAt) {
4336
- urlParams.append("workflowCreatedAt", workflowCreatedAt.toString());
4337
- }
4338
- if (params?.label) {
4339
- urlParams.append("label", params.label);
4340
- }
4341
- const result = await this.client.http.request({
4342
- path: ["v2", "workflows", `events?${urlParams.toString()}`]
4155
+ const { cursor, count, filter, ...legacyFilter } = params ?? {};
4156
+ return await this.client.http.request({
4157
+ path: ["v2", "workflows", "events"],
4158
+ query: {
4159
+ groupBy: "workflowRunId",
4160
+ ...legacyFilter,
4161
+ cursor,
4162
+ count,
4163
+ ...filter
4164
+ }
4343
4165
  });
4344
- return result;
4345
4166
  }
4346
4167
  get dlq() {
4347
4168
  return new DLQ(this.client);