@upstash/workflow 0.2.0 → 0.2.2

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.
@@ -71,7 +71,19 @@ var formatWorkflowError = (error) => {
71
71
  };
72
72
  };
73
73
 
74
+ // src/types.ts
75
+ var StepTypes = [
76
+ "Initial",
77
+ "Run",
78
+ "SleepFor",
79
+ "SleepUntil",
80
+ "Call",
81
+ "Wait",
82
+ "Notify"
83
+ ];
84
+
74
85
  // src/client/utils.ts
86
+ import { QstashError as QstashError2 } from "@upstash/qstash";
75
87
  var makeNotifyRequest = async (requester, eventId, eventData) => {
76
88
  const result = await requester.request({
77
89
  path: ["v2", "notify", eventId],
@@ -105,24 +117,28 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
105
117
  await debug?.log("INFO", "ENDPOINT_START", {
106
118
  message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
107
119
  });
108
- return steps;
120
+ return { steps, workflowRunEnded: false };
109
121
  } else {
110
122
  const index = steps.findIndex((item) => item.messageId === messageId);
111
123
  if (index === -1) {
112
- return [];
124
+ return { steps: [], workflowRunEnded: false };
113
125
  }
114
126
  const filteredSteps = steps.slice(0, index + 1);
115
127
  await debug?.log("INFO", "ENDPOINT_START", {
116
128
  message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
117
129
  });
118
- return filteredSteps;
130
+ return { steps: filteredSteps, workflowRunEnded: false };
119
131
  }
120
132
  } catch (error) {
121
- await debug?.log("ERROR", "ERROR", {
122
- message: "failed while fetching steps.",
123
- error
124
- });
125
- throw new WorkflowError(`Failed while pulling steps. ${error}`);
133
+ if (error instanceof QstashError2 && error.status === 404) {
134
+ await debug?.log("WARN", "ENDPOINT_START", {
135
+ message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
136
+ error
137
+ });
138
+ return { steps: void 0, workflowRunEnded: true };
139
+ } else {
140
+ throw error;
141
+ }
126
142
  }
127
143
  };
128
144
 
@@ -131,6 +147,11 @@ var BaseLazyStep = class {
131
147
  stepName;
132
148
  // will be set in the subclasses
133
149
  constructor(stepName) {
150
+ if (!stepName) {
151
+ throw new WorkflowError(
152
+ "A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
153
+ );
154
+ }
134
155
  this.stepName = stepName;
135
156
  }
136
157
  };
@@ -223,15 +244,17 @@ var LazyCallStep = class extends BaseLazyStep {
223
244
  method;
224
245
  body;
225
246
  headers;
226
- stepType = "Call";
227
247
  retries;
228
- constructor(stepName, url, method, body, headers, retries) {
248
+ timeout;
249
+ stepType = "Call";
250
+ constructor(stepName, url, method, body, headers, retries, timeout) {
229
251
  super(stepName);
230
252
  this.url = url;
231
253
  this.method = method;
232
254
  this.body = body;
233
255
  this.headers = headers;
234
256
  this.retries = retries;
257
+ this.timeout = timeout;
235
258
  }
236
259
  getPlanStep(concurrent, targetStep) {
237
260
  return {
@@ -727,20 +750,9 @@ var DEFAULT_CONTENT_TYPE = "application/json";
727
750
  var NO_CONCURRENCY = 1;
728
751
  var DEFAULT_RETRIES = 3;
729
752
 
730
- // src/types.ts
731
- var StepTypes = [
732
- "Initial",
733
- "Run",
734
- "SleepFor",
735
- "SleepUntil",
736
- "Call",
737
- "Wait",
738
- "Notify"
739
- ];
740
-
741
753
  // src/workflow-requests.ts
742
- import { QstashError as QstashError2 } from "@upstash/qstash";
743
- var triggerFirstInvocation = async (workflowContext, retries, debug) => {
754
+ import { QstashError as QstashError3 } from "@upstash/qstash";
755
+ var triggerFirstInvocation = async (workflowContext, retries, useJSONContent, debug) => {
744
756
  const { headers } = getHeaders(
745
757
  "true",
746
758
  workflowContext.workflowRunId,
@@ -750,6 +762,9 @@ var triggerFirstInvocation = async (workflowContext, retries, debug) => {
750
762
  workflowContext.failureUrl,
751
763
  retries
752
764
  );
765
+ if (useJSONContent) {
766
+ headers["content-type"] = "application/json";
767
+ }
753
768
  try {
754
769
  const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
755
770
  const result = await workflowContext.qstashClient.publish({
@@ -793,7 +808,7 @@ var triggerRouteFunction = async ({
793
808
  return ok("workflow-finished");
794
809
  } catch (error) {
795
810
  const error_ = error;
796
- if (error instanceof QstashError2 && error.status === 400) {
811
+ if (error instanceof QstashError3 && error.status === 400) {
797
812
  await debug?.log("WARN", "RESPONSE_WORKFLOW", {
798
813
  message: `tried to append to a cancelled workflow. exiting without publishing.`,
799
814
  name: error.name,
@@ -827,7 +842,7 @@ var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
827
842
  );
828
843
  return { deleted: true };
829
844
  } catch (error) {
830
- if (error instanceof QstashError2 && error.status === 404) {
845
+ if (error instanceof QstashError3 && error.status === 404) {
831
846
  await debug?.log("WARN", "SUBMIT_CLEANUP", {
832
847
  message: `Failed to remove workflow run ${workflowContext.workflowRunId} as it doesn't exist.`,
833
848
  name: error.name,
@@ -843,7 +858,10 @@ var recreateUserHeaders = (headers) => {
843
858
  const pairs = headers.entries();
844
859
  for (const [header, value] of pairs) {
845
860
  const headerLowerCase = header.toLowerCase();
846
- if (!headerLowerCase.startsWith("upstash-workflow-") && !headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && headerLowerCase !== "cf-connecting-ip") {
861
+ if (!headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
862
+ !headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && // https://blog.cloudflare.com/preventing-request-loops-using-cdn-loop/
863
+ headerLowerCase !== "cf-connecting-ip" && headerLowerCase !== "cdn-loop" && headerLowerCase !== "cf-ew-via" && headerLowerCase !== "cf-ray" && // For Render https://render.com
864
+ headerLowerCase !== "render-proxy-ttl") {
847
865
  filteredHeaders.append(header, value);
848
866
  }
849
867
  }
@@ -861,11 +879,19 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
861
879
  if (!workflowRunId2)
862
880
  throw new WorkflowError("workflow run id missing in context.call lazy fetch.");
863
881
  if (!messageId) throw new WorkflowError("message id missing in context.call lazy fetch.");
864
- const steps = await getSteps(client.http, workflowRunId2, messageId, debug);
882
+ const { steps, workflowRunEnded } = await getSteps(
883
+ client.http,
884
+ workflowRunId2,
885
+ messageId,
886
+ debug
887
+ );
888
+ if (workflowRunEnded) {
889
+ return ok("workflow-ended");
890
+ }
865
891
  const failingStep = steps.find((step) => step.messageId === messageId);
866
892
  if (!failingStep)
867
893
  throw new WorkflowError(
868
- "Failed to submit the context.call." + (steps.length === 0 ? "No steps found." : `No step was found with matching messageId ${messageId} out of ${steps.length} steps.`)
894
+ "Failed to submit the context.call. " + (steps.length === 0 ? "No steps found." : `No step was found with matching messageId ${messageId} out of ${steps.length} steps.`)
869
895
  );
870
896
  callbackPayload = atob(failingStep.body);
871
897
  }
@@ -946,7 +972,7 @@ ${atob(callbackMessage.body ?? "")}`
946
972
  );
947
973
  }
948
974
  };
949
- var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step, failureUrl, retries, callRetries) => {
975
+ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step, failureUrl, retries, callRetries, callTimeout) => {
950
976
  const baseHeaders = {
951
977
  [WORKFLOW_INIT_HEADER]: initHeaderValue,
952
978
  [WORKFLOW_ID_HEADER]: workflowRunId,
@@ -956,6 +982,9 @@ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step
956
982
  if (!step?.callUrl) {
957
983
  baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
958
984
  }
985
+ if (callTimeout) {
986
+ baseHeaders[`Upstash-Timeout`] = callTimeout.toString();
987
+ }
959
988
  if (failureUrl) {
960
989
  baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
961
990
  if (!step?.callUrl) {
@@ -1331,7 +1360,8 @@ var AutoExecutor = class _AutoExecutor {
1331
1360
  singleStep,
1332
1361
  this.context.failureUrl,
1333
1362
  this.context.retries,
1334
- lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0
1363
+ lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
1364
+ lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0
1335
1365
  );
1336
1366
  const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
1337
1367
  singleStep.out = JSON.stringify(singleStep.out);
@@ -1681,6 +1711,7 @@ var WorkflowContext = class {
1681
1711
  * @param body call body
1682
1712
  * @param headers call headers
1683
1713
  * @param retries number of call retries. 0 by default
1714
+ * @param timeout max duration to wait for the endpoint to respond. in seconds.
1684
1715
  * @returns call result as {
1685
1716
  * status: number;
1686
1717
  * body: unknown;
@@ -1688,9 +1719,17 @@ var WorkflowContext = class {
1688
1719
  * }
1689
1720
  */
1690
1721
  async call(stepName, settings) {
1691
- const { url, method = "GET", body, headers = {}, retries = 0 } = settings;
1722
+ const { url, method = "GET", body, headers = {}, retries = 0, timeout } = settings;
1692
1723
  const result = await this.addStep(
1693
- new LazyCallStep(stepName, url, method, body, headers, retries)
1724
+ new LazyCallStep(
1725
+ stepName,
1726
+ url,
1727
+ method,
1728
+ body,
1729
+ headers,
1730
+ retries,
1731
+ timeout
1732
+ )
1694
1733
  );
1695
1734
  if (typeof result === "string") {
1696
1735
  try {
@@ -1891,7 +1930,7 @@ function decodeBase64(base64) {
1891
1930
  }
1892
1931
 
1893
1932
  // src/serve/authorization.ts
1894
- import { Client } from "@upstash/qstash";
1933
+ import { Client as Client2 } from "@upstash/qstash";
1895
1934
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
1896
1935
  static disabledMessage = "disabled-qstash-worklfow-run";
1897
1936
  /**
@@ -1922,7 +1961,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
1922
1961
  */
1923
1962
  static async tryAuthentication(routeFunction, context) {
1924
1963
  const disabledContext = new _DisabledWorkflowContext({
1925
- qstashClient: new Client({
1964
+ qstashClient: new Client2({
1926
1965
  baseUrl: "disabled-client",
1927
1966
  token: "disabled-client"
1928
1967
  }),
@@ -2046,7 +2085,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
2046
2085
  return {
2047
2086
  rawInitialPayload: requestPayload ?? "",
2048
2087
  steps: [],
2049
- isLastDuplicate: false
2088
+ isLastDuplicate: false,
2089
+ workflowRunEnded: false
2050
2090
  };
2051
2091
  } else {
2052
2092
  let rawSteps;
@@ -2056,7 +2096,21 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
2056
2096
  "ENDPOINT_START",
2057
2097
  "request payload is empty, steps will be fetched from QStash."
2058
2098
  );
2059
- rawSteps = await getSteps(requester, workflowRunId, messageId, debug);
2099
+ const { steps: fetchedSteps, workflowRunEnded } = await getSteps(
2100
+ requester,
2101
+ workflowRunId,
2102
+ messageId,
2103
+ debug
2104
+ );
2105
+ if (workflowRunEnded) {
2106
+ return {
2107
+ rawInitialPayload: void 0,
2108
+ steps: void 0,
2109
+ isLastDuplicate: void 0,
2110
+ workflowRunEnded: true
2111
+ };
2112
+ }
2113
+ rawSteps = fetchedSteps;
2060
2114
  } else {
2061
2115
  rawSteps = JSON.parse(requestPayload);
2062
2116
  }
@@ -2066,7 +2120,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
2066
2120
  return {
2067
2121
  rawInitialPayload,
2068
2122
  steps: deduplicatedSteps,
2069
- isLastDuplicate
2123
+ isLastDuplicate,
2124
+ workflowRunEnded: false
2070
2125
  };
2071
2126
  }
2072
2127
  };
@@ -2090,7 +2145,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
2090
2145
  const workflowContext = new WorkflowContext({
2091
2146
  qstashClient,
2092
2147
  workflowRunId,
2093
- initialPayload: initialPayloadParser(decodeBase64(sourceBody)),
2148
+ initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
2094
2149
  headers: recreateUserHeaders(new Headers(sourceHeader)),
2095
2150
  steps: [],
2096
2151
  url,
@@ -2121,21 +2176,34 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
2121
2176
 
2122
2177
  // src/serve/options.ts
2123
2178
  import { Receiver } from "@upstash/qstash";
2124
- import { Client as Client2 } from "@upstash/qstash";
2179
+ import { Client as Client3 } from "@upstash/qstash";
2125
2180
  var processOptions = (options) => {
2126
2181
  const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
2127
2182
  const receiverEnvironmentVariablesSet = Boolean(
2128
2183
  environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
2129
2184
  );
2130
2185
  return {
2131
- qstashClient: new Client2({
2186
+ qstashClient: new Client3({
2132
2187
  baseUrl: environment.QSTASH_URL,
2133
2188
  token: environment.QSTASH_TOKEN
2134
2189
  }),
2135
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2136
- onStepFinish: (workflowRunId, _finishCondition) => new Response(JSON.stringify({ workflowRunId }), {
2137
- status: 200
2138
- }),
2190
+ onStepFinish: (workflowRunId, finishCondition) => {
2191
+ if (finishCondition === "auth-fail") {
2192
+ console.error(AUTH_FAIL_MESSAGE);
2193
+ return new Response(
2194
+ JSON.stringify({
2195
+ message: AUTH_FAIL_MESSAGE,
2196
+ workflowRunId
2197
+ }),
2198
+ {
2199
+ status: 400
2200
+ }
2201
+ );
2202
+ }
2203
+ return new Response(JSON.stringify({ workflowRunId }), {
2204
+ status: 200
2205
+ });
2206
+ },
2139
2207
  initialPayloadParser: (initialRequest) => {
2140
2208
  if (!initialRequest) {
2141
2209
  return void 0;
@@ -2156,6 +2224,7 @@ var processOptions = (options) => {
2156
2224
  baseUrl: environment.UPSTASH_WORKFLOW_URL,
2157
2225
  env: environment,
2158
2226
  retries: DEFAULT_RETRIES,
2227
+ useJSONContent: false,
2159
2228
  ...options
2160
2229
  };
2161
2230
  };
@@ -2172,14 +2241,25 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
2172
2241
  });
2173
2242
  }
2174
2243
  const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
2244
+ if (workflowUrl.includes("localhost")) {
2245
+ await debug?.log("WARN", "ENDPOINT_START", {
2246
+ message: `Workflow URL contains localhost. This can happen in local development, but shouldn't happen in production unless you have a route which contains localhost. Received: ${workflowUrl}`
2247
+ });
2248
+ }
2249
+ if (!(workflowUrl.startsWith("http://") || workflowUrl.startsWith("https://"))) {
2250
+ throw new WorkflowError(
2251
+ `Workflow URL should start with 'http://' or 'https://'. Recevied is '${workflowUrl}'`
2252
+ );
2253
+ }
2175
2254
  return {
2176
2255
  workflowUrl,
2177
2256
  workflowFailureUrl
2178
2257
  };
2179
2258
  };
2259
+ var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is unexpected, see the caveat https://upstash.com/docs/workflow/basics/caveats#avoid-non-deterministic-code-outside-context-run`;
2180
2260
 
2181
2261
  // src/serve/index.ts
2182
- var serve = (routeFunction, options) => {
2262
+ var serveBase = (routeFunction, options) => {
2183
2263
  const {
2184
2264
  qstashClient,
2185
2265
  onStepFinish,
@@ -2191,7 +2271,8 @@ var serve = (routeFunction, options) => {
2191
2271
  failureFunction,
2192
2272
  baseUrl,
2193
2273
  env,
2194
- retries
2274
+ retries,
2275
+ useJSONContent
2195
2276
  } = processOptions(options);
2196
2277
  const debug = WorkflowLogger.getLogger(verbose);
2197
2278
  const handler = async (request) => {
@@ -2208,7 +2289,7 @@ var serve = (routeFunction, options) => {
2208
2289
  await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
2209
2290
  const { isFirstInvocation, workflowRunId } = validateRequest(request);
2210
2291
  debug?.setWorkflowRunId(workflowRunId);
2211
- const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
2292
+ const { rawInitialPayload, steps, isLastDuplicate, workflowRunEnded } = await parseRequest(
2212
2293
  requestPayload,
2213
2294
  isFirstInvocation,
2214
2295
  workflowRunId,
@@ -2216,8 +2297,11 @@ var serve = (routeFunction, options) => {
2216
2297
  request.headers.get("upstash-message-id"),
2217
2298
  debug
2218
2299
  );
2300
+ if (workflowRunEnded) {
2301
+ return onStepFinish(workflowRunId, "workflow-already-ended");
2302
+ }
2219
2303
  if (isLastDuplicate) {
2220
- return onStepFinish("no-workflow-id", "duplicate-step");
2304
+ return onStepFinish(workflowRunId, "duplicate-step");
2221
2305
  }
2222
2306
  const failureCheck = await handleFailure(
2223
2307
  request,
@@ -2231,7 +2315,7 @@ var serve = (routeFunction, options) => {
2231
2315
  throw failureCheck.error;
2232
2316
  } else if (failureCheck.value === "is-failure-callback") {
2233
2317
  await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
2234
- return onStepFinish("no-workflow-id", "failure-callback");
2318
+ return onStepFinish(workflowRunId, "failure-callback");
2235
2319
  }
2236
2320
  const workflowContext = new WorkflowContext({
2237
2321
  qstashClient,
@@ -2253,7 +2337,11 @@ var serve = (routeFunction, options) => {
2253
2337
  await debug?.log("ERROR", "ERROR", { error: authCheck.error.message });
2254
2338
  throw authCheck.error;
2255
2339
  } else if (authCheck.value === "run-ended") {
2256
- return onStepFinish("no-workflow-id", "auth-fail");
2340
+ await debug?.log("ERROR", "ERROR", { error: AUTH_FAIL_MESSAGE });
2341
+ return onStepFinish(
2342
+ isFirstInvocation ? "no-workflow-id" : workflowContext.workflowRunId,
2343
+ "auth-fail"
2344
+ );
2257
2345
  }
2258
2346
  const callReturnCheck = await handleThirdPartyCallResult(
2259
2347
  request,
@@ -2270,7 +2358,7 @@ var serve = (routeFunction, options) => {
2270
2358
  });
2271
2359
  throw callReturnCheck.error;
2272
2360
  } else if (callReturnCheck.value === "continue-workflow") {
2273
- const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, debug) : await triggerRouteFunction({
2361
+ const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, useJSONContent, debug) : await triggerRouteFunction({
2274
2362
  onStep: async () => routeFunction(workflowContext),
2275
2363
  onCleanup: async () => {
2276
2364
  await triggerWorkflowDelete(workflowContext, debug);
@@ -2286,6 +2374,8 @@ var serve = (routeFunction, options) => {
2286
2374
  }
2287
2375
  await debug?.log("INFO", "RESPONSE_WORKFLOW");
2288
2376
  return onStepFinish(workflowContext.workflowRunId, "success");
2377
+ } else if (callReturnCheck.value === "workflow-ended") {
2378
+ return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended");
2289
2379
  }
2290
2380
  await debug?.log("INFO", "RESPONSE_DEFAULT");
2291
2381
  return onStepFinish("no-workflow-id", "fromCallback");
@@ -2302,198 +2392,24 @@ var serve = (routeFunction, options) => {
2302
2392
  };
2303
2393
  return { handler: safeHandler };
2304
2394
  };
2305
-
2306
- // src/client/index.ts
2307
- import { Client as QStashClient } from "@upstash/qstash";
2308
- var Client3 = class {
2309
- client;
2310
- constructor(clientConfig) {
2311
- if (!clientConfig.token) {
2312
- console.error(
2313
- "QStash token is required for Upstash Workflow!\n\nTo fix this:\n1. Get your token from the Upstash Console (https://console.upstash.com/qstash)\n2. Initialize the workflow client with:\n\n const client = new Client({\n token: '<YOUR_QSTASH_TOKEN>'\n });"
2314
- );
2315
- }
2316
- this.client = new QStashClient(clientConfig);
2317
- }
2318
- /**
2319
- * Cancel an ongoing workflow
2320
- *
2321
- * Returns true if workflow is canceled succesfully. Otherwise, throws error.
2322
- *
2323
- * There are multiple ways you can cancel workflows:
2324
- * - pass one or more workflow run ids to cancel them
2325
- * - pass a workflow url to cancel all runs starting with this url
2326
- * - cancel all pending or active workflow runs
2327
- *
2328
- * ### Cancel a set of workflow runs
2329
- *
2330
- * ```ts
2331
- * // cancel a single workflow
2332
- * await client.cancel({ ids: "<WORKFLOW_RUN_ID>" })
2333
- *
2334
- * // cancel a set of workflow runs
2335
- * await client.cancel({ ids: [
2336
- * "<WORKFLOW_RUN_ID_1>",
2337
- * "<WORKFLOW_RUN_ID_2>",
2338
- * ]})
2339
- * ```
2340
- *
2341
- * ### Cancel workflows starting with a url
2342
- *
2343
- * If you have an endpoint called `https://your-endpoint.com` and you
2344
- * want to cancel all workflow runs on it, you can use `urlStartingWith`.
2345
- *
2346
- * Note that this will cancel workflows in all endpoints under
2347
- * `https://your-endpoint.com`.
2348
- *
2349
- * ```ts
2350
- * await client.cancel({ urlStartingWith: "https://your-endpoint.com" })
2351
- * ```
2352
- *
2353
- * ### Cancel *all* workflows
2354
- *
2355
- * To cancel all pending and currently running workflows, you can
2356
- * do it like this:
2357
- *
2358
- * ```ts
2359
- * await client.cancel({ all: true })
2360
- * ```
2361
- *
2362
- * @param ids run id of the workflow to delete
2363
- * @param urlStartingWith cancel workflows starting with this url. Will be ignored
2364
- * if `ids` parameter is set.
2365
- * @param all set to true in order to cancel all workflows. Will be ignored
2366
- * if `ids` or `urlStartingWith` parameters are set.
2367
- * @returns true if workflow is succesfully deleted. Otherwise throws QStashError
2368
- */
2369
- async cancel({
2370
- ids,
2371
- urlStartingWith,
2372
- all
2373
- }) {
2374
- let body;
2375
- if (ids) {
2376
- const runIdArray = typeof ids === "string" ? [ids] : ids;
2377
- body = JSON.stringify({ workflowRunIds: runIdArray });
2378
- } else if (urlStartingWith) {
2379
- body = JSON.stringify({ workflowUrl: urlStartingWith });
2380
- } else if (all) {
2381
- body = "{}";
2382
- } else {
2383
- throw new TypeError("The `cancel` method cannot be called without any options.");
2384
- }
2385
- const result = await this.client.http.request({
2386
- path: ["v2", "workflows", "runs"],
2387
- method: "DELETE",
2388
- body,
2389
- headers: {
2390
- "Content-Type": "application/json"
2391
- }
2392
- });
2393
- return result;
2394
- }
2395
- /**
2396
- * Notify a workflow run waiting for an event
2397
- *
2398
- * ```ts
2399
- * import { Client } from "@upstash/workflow";
2400
- *
2401
- * const client = new Client({ token: "<QSTASH_TOKEN>" })
2402
- * await client.notify({
2403
- * eventId: "my-event-id",
2404
- * eventData: "my-data" // data passed to the workflow run
2405
- * });
2406
- * ```
2407
- *
2408
- * @param eventId event id to notify
2409
- * @param eventData data to provide to the workflow
2410
- */
2411
- async notify({
2412
- eventId,
2413
- eventData
2414
- }) {
2415
- return await makeNotifyRequest(this.client.http, eventId, eventData);
2416
- }
2417
- /**
2418
- * Check waiters of an event
2419
- *
2420
- * ```ts
2421
- * import { Client } from "@upstash/workflow";
2422
- *
2423
- * const client = new Client({ token: "<QSTASH_TOKEN>" })
2424
- * const result = await client.getWaiters({
2425
- * eventId: "my-event-id"
2426
- * })
2427
- * ```
2428
- *
2429
- * @param eventId event id to check
2430
- */
2431
- async getWaiters({ eventId }) {
2432
- return await makeGetWaitersRequest(this.client.http, eventId);
2433
- }
2434
- /**
2435
- * Trigger new workflow run and returns the workflow run id
2436
- *
2437
- * ```ts
2438
- * const { workflowRunId } = await client.trigger({
2439
- * url: "https://workflow-endpoint.com",
2440
- * body: "hello there!", // Optional body
2441
- * headers: { ... }, // Optional headers
2442
- * workflowRunId: "my-workflow", // Optional workflow run ID
2443
- * retries: 3 // Optional retries for the initial request
2444
- * });
2445
- *
2446
- * console.log(workflowRunId)
2447
- * // wfr_my-workflow
2448
- * ```
2449
- *
2450
- * @param url URL of the workflow
2451
- * @param body body to start the workflow with
2452
- * @param headers headers to use in the request
2453
- * @param workflowRunId optional workflow run id to use. mind that
2454
- * you should pass different workflow run ids for different runs.
2455
- * The final workflowRunId will be `wfr_${workflowRunId}`, in
2456
- * other words: the workflow run id you pass will be prefixed
2457
- * with `wfr_`.
2458
- * @param retries retry to use in the initial request. in the rest of
2459
- * the workflow, `retries` option of the `serve` will be used.
2460
- * @returns workflow run id
2461
- */
2462
- async trigger({
2463
- url,
2464
- body,
2465
- headers,
2466
- workflowRunId,
2467
- retries
2468
- }) {
2469
- const finalWorkflowRunId = getWorkflowRunId(workflowRunId);
2470
- const context = new WorkflowContext({
2471
- qstashClient: this.client,
2472
- // @ts-expect-error headers type mismatch
2473
- headers: new Headers(headers ?? {}),
2474
- initialPayload: body,
2475
- steps: [],
2476
- url,
2477
- workflowRunId: finalWorkflowRunId
2478
- });
2479
- const result = await triggerFirstInvocation(context, retries ?? DEFAULT_RETRIES);
2480
- if (result.isOk()) {
2481
- return { workflowRunId: finalWorkflowRunId };
2482
- } else {
2483
- throw result.error;
2484
- }
2485
- }
2395
+ var serve = (routeFunction, options) => {
2396
+ return serveBase(routeFunction, options);
2486
2397
  };
2487
2398
 
2488
2399
  export {
2489
2400
  __require,
2490
2401
  __commonJS,
2491
2402
  __toESM,
2403
+ makeNotifyRequest,
2404
+ makeGetWaitersRequest,
2492
2405
  WorkflowError,
2493
2406
  WorkflowAbort,
2407
+ DEFAULT_RETRIES,
2494
2408
  StepTypes,
2409
+ triggerFirstInvocation,
2495
2410
  WorkflowContext,
2496
2411
  WorkflowLogger,
2497
- serve,
2498
- Client3 as Client
2412
+ getWorkflowRunId,
2413
+ serveBase,
2414
+ serve
2499
2415
  };
package/cloudflare.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as RouteFunction, W as WorkflowServeOptions } from './types-Cki_MHrh.mjs';
1
+ import { R as RouteFunction, j as PublicServeOptions } from './types-APRap-aV.mjs';
2
2
  import '@upstash/qstash';
3
3
 
4
4
  type WorkflowBindings = {
@@ -28,7 +28,7 @@ type WorkersHandlerArgs = [Request, Record<string, string | undefined>];
28
28
  * @param options workflow options
29
29
  * @returns
30
30
  */
31
- declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => {
31
+ declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
32
32
  fetch: (...args: PagesHandlerArgs | WorkersHandlerArgs) => Promise<Response>;
33
33
  };
34
34
 
package/cloudflare.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as RouteFunction, W as WorkflowServeOptions } from './types-Cki_MHrh.js';
1
+ import { R as RouteFunction, j as PublicServeOptions } from './types-APRap-aV.js';
2
2
  import '@upstash/qstash';
3
3
 
4
4
  type WorkflowBindings = {
@@ -28,7 +28,7 @@ type WorkersHandlerArgs = [Request, Record<string, string | undefined>];
28
28
  * @param options workflow options
29
29
  * @returns
30
30
  */
31
- declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => {
31
+ declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
32
32
  fetch: (...args: PagesHandlerArgs | WorkersHandlerArgs) => Promise<Response>;
33
33
  };
34
34