@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.
- package/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +175 -88
- package/astro.mjs +5 -5
- package/{chunk-5R2BFC3N.mjs → chunk-Z7WS5XIR.mjs} +150 -234
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +175 -88
- package/cloudflare.mjs +5 -5
- package/express.d.mts +1 -1
- package/express.d.ts +1 -1
- package/express.js +187 -93
- package/express.mjs +17 -10
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +175 -88
- package/h3.mjs +5 -5
- package/hono.d.mts +4 -2
- package/hono.d.ts +4 -2
- package/hono.js +175 -88
- package/hono.mjs +5 -5
- package/index.d.mts +3 -3
- package/index.d.ts +3 -3
- package/index.js +179 -86
- package/index.mjs +189 -3
- package/nextjs.d.mts +3 -3
- package/nextjs.d.ts +3 -3
- package/nextjs.js +179 -92
- package/nextjs.mjs +9 -9
- package/package.json +1 -1
- package/solidjs.d.mts +2 -2
- package/solidjs.d.ts +2 -2
- package/solidjs.js +175 -88
- package/solidjs.mjs +5 -5
- package/svelte.d.mts +3 -3
- package/svelte.d.ts +3 -3
- package/svelte.js +178 -88
- package/svelte.mjs +8 -5
- package/{types-Cki_MHrh.d.mts → types-APRap-aV.d.mts} +12 -2
- package/{types-Cki_MHrh.d.ts → types-APRap-aV.d.ts} +12 -2
package/hono.js
CHANGED
|
@@ -20,52 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// platforms/hono.ts
|
|
21
21
|
var hono_exports = {};
|
|
22
22
|
__export(hono_exports, {
|
|
23
|
-
serve: () =>
|
|
23
|
+
serve: () => serve
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(hono_exports);
|
|
26
26
|
|
|
27
|
-
// src/error.ts
|
|
28
|
-
var import_qstash = require("@upstash/qstash");
|
|
29
|
-
var WorkflowError = class extends import_qstash.QstashError {
|
|
30
|
-
constructor(message) {
|
|
31
|
-
super(message);
|
|
32
|
-
this.name = "WorkflowError";
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
var WorkflowAbort = class extends Error {
|
|
36
|
-
stepInfo;
|
|
37
|
-
stepName;
|
|
38
|
-
/**
|
|
39
|
-
* whether workflow is to be canceled on abort
|
|
40
|
-
*/
|
|
41
|
-
cancelWorkflow;
|
|
42
|
-
/**
|
|
43
|
-
*
|
|
44
|
-
* @param stepName name of the aborting step
|
|
45
|
-
* @param stepInfo step information
|
|
46
|
-
* @param cancelWorkflow
|
|
47
|
-
*/
|
|
48
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
49
|
-
super(
|
|
50
|
-
`This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
|
|
51
|
-
);
|
|
52
|
-
this.name = "WorkflowAbort";
|
|
53
|
-
this.stepName = stepName;
|
|
54
|
-
this.stepInfo = stepInfo;
|
|
55
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
var formatWorkflowError = (error) => {
|
|
59
|
-
return error instanceof Error ? {
|
|
60
|
-
error: error.name,
|
|
61
|
-
message: error.message
|
|
62
|
-
} : {
|
|
63
|
-
error: "Error",
|
|
64
|
-
message: "An error occured while executing workflow."
|
|
65
|
-
};
|
|
66
|
-
};
|
|
67
|
-
|
|
68
27
|
// src/client/utils.ts
|
|
28
|
+
var import_qstash = require("@upstash/qstash");
|
|
69
29
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
70
30
|
const result = await requester.request({
|
|
71
31
|
path: ["v2", "notify", eventId],
|
|
@@ -92,32 +52,82 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
92
52
|
await debug?.log("INFO", "ENDPOINT_START", {
|
|
93
53
|
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
94
54
|
});
|
|
95
|
-
return steps;
|
|
55
|
+
return { steps, workflowRunEnded: false };
|
|
96
56
|
} else {
|
|
97
57
|
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
98
58
|
if (index === -1) {
|
|
99
|
-
return [];
|
|
59
|
+
return { steps: [], workflowRunEnded: false };
|
|
100
60
|
}
|
|
101
61
|
const filteredSteps = steps.slice(0, index + 1);
|
|
102
62
|
await debug?.log("INFO", "ENDPOINT_START", {
|
|
103
63
|
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
104
64
|
});
|
|
105
|
-
return filteredSteps;
|
|
65
|
+
return { steps: filteredSteps, workflowRunEnded: false };
|
|
106
66
|
}
|
|
107
67
|
} catch (error) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
68
|
+
if (error instanceof import_qstash.QstashError && error.status === 404) {
|
|
69
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
70
|
+
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
71
|
+
error
|
|
72
|
+
});
|
|
73
|
+
return { steps: void 0, workflowRunEnded: true };
|
|
74
|
+
} else {
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
113
77
|
}
|
|
114
78
|
};
|
|
115
79
|
|
|
80
|
+
// src/error.ts
|
|
81
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
82
|
+
var WorkflowError = class extends import_qstash2.QstashError {
|
|
83
|
+
constructor(message) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.name = "WorkflowError";
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var WorkflowAbort = class extends Error {
|
|
89
|
+
stepInfo;
|
|
90
|
+
stepName;
|
|
91
|
+
/**
|
|
92
|
+
* whether workflow is to be canceled on abort
|
|
93
|
+
*/
|
|
94
|
+
cancelWorkflow;
|
|
95
|
+
/**
|
|
96
|
+
*
|
|
97
|
+
* @param stepName name of the aborting step
|
|
98
|
+
* @param stepInfo step information
|
|
99
|
+
* @param cancelWorkflow
|
|
100
|
+
*/
|
|
101
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
102
|
+
super(
|
|
103
|
+
`This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
|
|
104
|
+
);
|
|
105
|
+
this.name = "WorkflowAbort";
|
|
106
|
+
this.stepName = stepName;
|
|
107
|
+
this.stepInfo = stepInfo;
|
|
108
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var formatWorkflowError = (error) => {
|
|
112
|
+
return error instanceof Error ? {
|
|
113
|
+
error: error.name,
|
|
114
|
+
message: error.message
|
|
115
|
+
} : {
|
|
116
|
+
error: "Error",
|
|
117
|
+
message: "An error occured while executing workflow."
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
116
121
|
// src/context/steps.ts
|
|
117
122
|
var BaseLazyStep = class {
|
|
118
123
|
stepName;
|
|
119
124
|
// will be set in the subclasses
|
|
120
125
|
constructor(stepName) {
|
|
126
|
+
if (!stepName) {
|
|
127
|
+
throw new WorkflowError(
|
|
128
|
+
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
129
|
+
);
|
|
130
|
+
}
|
|
121
131
|
this.stepName = stepName;
|
|
122
132
|
}
|
|
123
133
|
};
|
|
@@ -210,15 +220,17 @@ var LazyCallStep = class extends BaseLazyStep {
|
|
|
210
220
|
method;
|
|
211
221
|
body;
|
|
212
222
|
headers;
|
|
213
|
-
stepType = "Call";
|
|
214
223
|
retries;
|
|
215
|
-
|
|
224
|
+
timeout;
|
|
225
|
+
stepType = "Call";
|
|
226
|
+
constructor(stepName, url, method, body, headers, retries, timeout) {
|
|
216
227
|
super(stepName);
|
|
217
228
|
this.url = url;
|
|
218
229
|
this.method = method;
|
|
219
230
|
this.body = body;
|
|
220
231
|
this.headers = headers;
|
|
221
232
|
this.retries = retries;
|
|
233
|
+
this.timeout = timeout;
|
|
222
234
|
}
|
|
223
235
|
getPlanStep(concurrent, targetStep) {
|
|
224
236
|
return {
|
|
@@ -726,8 +738,8 @@ var StepTypes = [
|
|
|
726
738
|
];
|
|
727
739
|
|
|
728
740
|
// src/workflow-requests.ts
|
|
729
|
-
var
|
|
730
|
-
var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
741
|
+
var import_qstash3 = require("@upstash/qstash");
|
|
742
|
+
var triggerFirstInvocation = async (workflowContext, retries, useJSONContent, debug) => {
|
|
731
743
|
const { headers } = getHeaders(
|
|
732
744
|
"true",
|
|
733
745
|
workflowContext.workflowRunId,
|
|
@@ -737,6 +749,9 @@ var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
|
737
749
|
workflowContext.failureUrl,
|
|
738
750
|
retries
|
|
739
751
|
);
|
|
752
|
+
if (useJSONContent) {
|
|
753
|
+
headers["content-type"] = "application/json";
|
|
754
|
+
}
|
|
740
755
|
try {
|
|
741
756
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
742
757
|
const result = await workflowContext.qstashClient.publish({
|
|
@@ -780,7 +795,7 @@ var triggerRouteFunction = async ({
|
|
|
780
795
|
return ok("workflow-finished");
|
|
781
796
|
} catch (error) {
|
|
782
797
|
const error_ = error;
|
|
783
|
-
if (error instanceof
|
|
798
|
+
if (error instanceof import_qstash3.QstashError && error.status === 400) {
|
|
784
799
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
785
800
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
786
801
|
name: error.name,
|
|
@@ -814,7 +829,7 @@ var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
|
814
829
|
);
|
|
815
830
|
return { deleted: true };
|
|
816
831
|
} catch (error) {
|
|
817
|
-
if (error instanceof
|
|
832
|
+
if (error instanceof import_qstash3.QstashError && error.status === 404) {
|
|
818
833
|
await debug?.log("WARN", "SUBMIT_CLEANUP", {
|
|
819
834
|
message: `Failed to remove workflow run ${workflowContext.workflowRunId} as it doesn't exist.`,
|
|
820
835
|
name: error.name,
|
|
@@ -830,7 +845,10 @@ var recreateUserHeaders = (headers) => {
|
|
|
830
845
|
const pairs = headers.entries();
|
|
831
846
|
for (const [header, value] of pairs) {
|
|
832
847
|
const headerLowerCase = header.toLowerCase();
|
|
833
|
-
if (!headerLowerCase.startsWith("upstash-workflow-") &&
|
|
848
|
+
if (!headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
|
|
849
|
+
!headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && // https://blog.cloudflare.com/preventing-request-loops-using-cdn-loop/
|
|
850
|
+
headerLowerCase !== "cf-connecting-ip" && headerLowerCase !== "cdn-loop" && headerLowerCase !== "cf-ew-via" && headerLowerCase !== "cf-ray" && // For Render https://render.com
|
|
851
|
+
headerLowerCase !== "render-proxy-ttl") {
|
|
834
852
|
filteredHeaders.append(header, value);
|
|
835
853
|
}
|
|
836
854
|
}
|
|
@@ -848,11 +866,19 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
|
|
|
848
866
|
if (!workflowRunId2)
|
|
849
867
|
throw new WorkflowError("workflow run id missing in context.call lazy fetch.");
|
|
850
868
|
if (!messageId) throw new WorkflowError("message id missing in context.call lazy fetch.");
|
|
851
|
-
const steps = await getSteps(
|
|
869
|
+
const { steps, workflowRunEnded } = await getSteps(
|
|
870
|
+
client.http,
|
|
871
|
+
workflowRunId2,
|
|
872
|
+
messageId,
|
|
873
|
+
debug
|
|
874
|
+
);
|
|
875
|
+
if (workflowRunEnded) {
|
|
876
|
+
return ok("workflow-ended");
|
|
877
|
+
}
|
|
852
878
|
const failingStep = steps.find((step) => step.messageId === messageId);
|
|
853
879
|
if (!failingStep)
|
|
854
880
|
throw new WorkflowError(
|
|
855
|
-
"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.`)
|
|
881
|
+
"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.`)
|
|
856
882
|
);
|
|
857
883
|
callbackPayload = atob(failingStep.body);
|
|
858
884
|
}
|
|
@@ -933,7 +959,7 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
933
959
|
);
|
|
934
960
|
}
|
|
935
961
|
};
|
|
936
|
-
var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step, failureUrl, retries, callRetries) => {
|
|
962
|
+
var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step, failureUrl, retries, callRetries, callTimeout) => {
|
|
937
963
|
const baseHeaders = {
|
|
938
964
|
[WORKFLOW_INIT_HEADER]: initHeaderValue,
|
|
939
965
|
[WORKFLOW_ID_HEADER]: workflowRunId,
|
|
@@ -943,6 +969,9 @@ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step
|
|
|
943
969
|
if (!step?.callUrl) {
|
|
944
970
|
baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
945
971
|
}
|
|
972
|
+
if (callTimeout) {
|
|
973
|
+
baseHeaders[`Upstash-Timeout`] = callTimeout.toString();
|
|
974
|
+
}
|
|
946
975
|
if (failureUrl) {
|
|
947
976
|
baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
948
977
|
if (!step?.callUrl) {
|
|
@@ -1318,7 +1347,8 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1318
1347
|
singleStep,
|
|
1319
1348
|
this.context.failureUrl,
|
|
1320
1349
|
this.context.retries,
|
|
1321
|
-
lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0
|
|
1350
|
+
lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
|
|
1351
|
+
lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0
|
|
1322
1352
|
);
|
|
1323
1353
|
const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
|
|
1324
1354
|
singleStep.out = JSON.stringify(singleStep.out);
|
|
@@ -1668,6 +1698,7 @@ var WorkflowContext = class {
|
|
|
1668
1698
|
* @param body call body
|
|
1669
1699
|
* @param headers call headers
|
|
1670
1700
|
* @param retries number of call retries. 0 by default
|
|
1701
|
+
* @param timeout max duration to wait for the endpoint to respond. in seconds.
|
|
1671
1702
|
* @returns call result as {
|
|
1672
1703
|
* status: number;
|
|
1673
1704
|
* body: unknown;
|
|
@@ -1675,9 +1706,17 @@ var WorkflowContext = class {
|
|
|
1675
1706
|
* }
|
|
1676
1707
|
*/
|
|
1677
1708
|
async call(stepName, settings) {
|
|
1678
|
-
const { url, method = "GET", body, headers = {}, retries = 0 } = settings;
|
|
1709
|
+
const { url, method = "GET", body, headers = {}, retries = 0, timeout } = settings;
|
|
1679
1710
|
const result = await this.addStep(
|
|
1680
|
-
new LazyCallStep(
|
|
1711
|
+
new LazyCallStep(
|
|
1712
|
+
stepName,
|
|
1713
|
+
url,
|
|
1714
|
+
method,
|
|
1715
|
+
body,
|
|
1716
|
+
headers,
|
|
1717
|
+
retries,
|
|
1718
|
+
timeout
|
|
1719
|
+
)
|
|
1681
1720
|
);
|
|
1682
1721
|
if (typeof result === "string") {
|
|
1683
1722
|
try {
|
|
@@ -1878,7 +1917,7 @@ function decodeBase64(base64) {
|
|
|
1878
1917
|
}
|
|
1879
1918
|
|
|
1880
1919
|
// src/serve/authorization.ts
|
|
1881
|
-
var
|
|
1920
|
+
var import_qstash4 = require("@upstash/qstash");
|
|
1882
1921
|
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
1883
1922
|
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
1884
1923
|
/**
|
|
@@ -1909,7 +1948,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
1909
1948
|
*/
|
|
1910
1949
|
static async tryAuthentication(routeFunction, context) {
|
|
1911
1950
|
const disabledContext = new _DisabledWorkflowContext({
|
|
1912
|
-
qstashClient: new
|
|
1951
|
+
qstashClient: new import_qstash4.Client({
|
|
1913
1952
|
baseUrl: "disabled-client",
|
|
1914
1953
|
token: "disabled-client"
|
|
1915
1954
|
}),
|
|
@@ -2033,7 +2072,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2033
2072
|
return {
|
|
2034
2073
|
rawInitialPayload: requestPayload ?? "",
|
|
2035
2074
|
steps: [],
|
|
2036
|
-
isLastDuplicate: false
|
|
2075
|
+
isLastDuplicate: false,
|
|
2076
|
+
workflowRunEnded: false
|
|
2037
2077
|
};
|
|
2038
2078
|
} else {
|
|
2039
2079
|
let rawSteps;
|
|
@@ -2043,7 +2083,21 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2043
2083
|
"ENDPOINT_START",
|
|
2044
2084
|
"request payload is empty, steps will be fetched from QStash."
|
|
2045
2085
|
);
|
|
2046
|
-
|
|
2086
|
+
const { steps: fetchedSteps, workflowRunEnded } = await getSteps(
|
|
2087
|
+
requester,
|
|
2088
|
+
workflowRunId,
|
|
2089
|
+
messageId,
|
|
2090
|
+
debug
|
|
2091
|
+
);
|
|
2092
|
+
if (workflowRunEnded) {
|
|
2093
|
+
return {
|
|
2094
|
+
rawInitialPayload: void 0,
|
|
2095
|
+
steps: void 0,
|
|
2096
|
+
isLastDuplicate: void 0,
|
|
2097
|
+
workflowRunEnded: true
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
rawSteps = fetchedSteps;
|
|
2047
2101
|
} else {
|
|
2048
2102
|
rawSteps = JSON.parse(requestPayload);
|
|
2049
2103
|
}
|
|
@@ -2053,7 +2107,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2053
2107
|
return {
|
|
2054
2108
|
rawInitialPayload,
|
|
2055
2109
|
steps: deduplicatedSteps,
|
|
2056
|
-
isLastDuplicate
|
|
2110
|
+
isLastDuplicate,
|
|
2111
|
+
workflowRunEnded: false
|
|
2057
2112
|
};
|
|
2058
2113
|
}
|
|
2059
2114
|
};
|
|
@@ -2077,7 +2132,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2077
2132
|
const workflowContext = new WorkflowContext({
|
|
2078
2133
|
qstashClient,
|
|
2079
2134
|
workflowRunId,
|
|
2080
|
-
initialPayload: initialPayloadParser(decodeBase64(sourceBody)),
|
|
2135
|
+
initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
|
|
2081
2136
|
headers: recreateUserHeaders(new Headers(sourceHeader)),
|
|
2082
2137
|
steps: [],
|
|
2083
2138
|
url,
|
|
@@ -2107,22 +2162,35 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2107
2162
|
};
|
|
2108
2163
|
|
|
2109
2164
|
// src/serve/options.ts
|
|
2110
|
-
var import_qstash4 = require("@upstash/qstash");
|
|
2111
2165
|
var import_qstash5 = require("@upstash/qstash");
|
|
2166
|
+
var import_qstash6 = require("@upstash/qstash");
|
|
2112
2167
|
var processOptions = (options) => {
|
|
2113
2168
|
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
2114
2169
|
const receiverEnvironmentVariablesSet = Boolean(
|
|
2115
2170
|
environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
|
|
2116
2171
|
);
|
|
2117
2172
|
return {
|
|
2118
|
-
qstashClient: new
|
|
2173
|
+
qstashClient: new import_qstash6.Client({
|
|
2119
2174
|
baseUrl: environment.QSTASH_URL,
|
|
2120
2175
|
token: environment.QSTASH_TOKEN
|
|
2121
2176
|
}),
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2177
|
+
onStepFinish: (workflowRunId, finishCondition) => {
|
|
2178
|
+
if (finishCondition === "auth-fail") {
|
|
2179
|
+
console.error(AUTH_FAIL_MESSAGE);
|
|
2180
|
+
return new Response(
|
|
2181
|
+
JSON.stringify({
|
|
2182
|
+
message: AUTH_FAIL_MESSAGE,
|
|
2183
|
+
workflowRunId
|
|
2184
|
+
}),
|
|
2185
|
+
{
|
|
2186
|
+
status: 400
|
|
2187
|
+
}
|
|
2188
|
+
);
|
|
2189
|
+
}
|
|
2190
|
+
return new Response(JSON.stringify({ workflowRunId }), {
|
|
2191
|
+
status: 200
|
|
2192
|
+
});
|
|
2193
|
+
},
|
|
2126
2194
|
initialPayloadParser: (initialRequest) => {
|
|
2127
2195
|
if (!initialRequest) {
|
|
2128
2196
|
return void 0;
|
|
@@ -2136,13 +2204,14 @@ var processOptions = (options) => {
|
|
|
2136
2204
|
throw error;
|
|
2137
2205
|
}
|
|
2138
2206
|
},
|
|
2139
|
-
receiver: receiverEnvironmentVariablesSet ? new
|
|
2207
|
+
receiver: receiverEnvironmentVariablesSet ? new import_qstash5.Receiver({
|
|
2140
2208
|
currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
|
|
2141
2209
|
nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
|
|
2142
2210
|
}) : void 0,
|
|
2143
2211
|
baseUrl: environment.UPSTASH_WORKFLOW_URL,
|
|
2144
2212
|
env: environment,
|
|
2145
2213
|
retries: DEFAULT_RETRIES,
|
|
2214
|
+
useJSONContent: false,
|
|
2146
2215
|
...options
|
|
2147
2216
|
};
|
|
2148
2217
|
};
|
|
@@ -2159,14 +2228,25 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
|
|
|
2159
2228
|
});
|
|
2160
2229
|
}
|
|
2161
2230
|
const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
|
|
2231
|
+
if (workflowUrl.includes("localhost")) {
|
|
2232
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
2233
|
+
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}`
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
if (!(workflowUrl.startsWith("http://") || workflowUrl.startsWith("https://"))) {
|
|
2237
|
+
throw new WorkflowError(
|
|
2238
|
+
`Workflow URL should start with 'http://' or 'https://'. Recevied is '${workflowUrl}'`
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2162
2241
|
return {
|
|
2163
2242
|
workflowUrl,
|
|
2164
2243
|
workflowFailureUrl
|
|
2165
2244
|
};
|
|
2166
2245
|
};
|
|
2246
|
+
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`;
|
|
2167
2247
|
|
|
2168
2248
|
// src/serve/index.ts
|
|
2169
|
-
var
|
|
2249
|
+
var serveBase = (routeFunction, options) => {
|
|
2170
2250
|
const {
|
|
2171
2251
|
qstashClient,
|
|
2172
2252
|
onStepFinish,
|
|
@@ -2178,7 +2258,8 @@ var serve = (routeFunction, options) => {
|
|
|
2178
2258
|
failureFunction,
|
|
2179
2259
|
baseUrl,
|
|
2180
2260
|
env,
|
|
2181
|
-
retries
|
|
2261
|
+
retries,
|
|
2262
|
+
useJSONContent
|
|
2182
2263
|
} = processOptions(options);
|
|
2183
2264
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
2184
2265
|
const handler = async (request) => {
|
|
@@ -2195,7 +2276,7 @@ var serve = (routeFunction, options) => {
|
|
|
2195
2276
|
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
|
|
2196
2277
|
const { isFirstInvocation, workflowRunId } = validateRequest(request);
|
|
2197
2278
|
debug?.setWorkflowRunId(workflowRunId);
|
|
2198
|
-
const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
|
|
2279
|
+
const { rawInitialPayload, steps, isLastDuplicate, workflowRunEnded } = await parseRequest(
|
|
2199
2280
|
requestPayload,
|
|
2200
2281
|
isFirstInvocation,
|
|
2201
2282
|
workflowRunId,
|
|
@@ -2203,8 +2284,11 @@ var serve = (routeFunction, options) => {
|
|
|
2203
2284
|
request.headers.get("upstash-message-id"),
|
|
2204
2285
|
debug
|
|
2205
2286
|
);
|
|
2287
|
+
if (workflowRunEnded) {
|
|
2288
|
+
return onStepFinish(workflowRunId, "workflow-already-ended");
|
|
2289
|
+
}
|
|
2206
2290
|
if (isLastDuplicate) {
|
|
2207
|
-
return onStepFinish(
|
|
2291
|
+
return onStepFinish(workflowRunId, "duplicate-step");
|
|
2208
2292
|
}
|
|
2209
2293
|
const failureCheck = await handleFailure(
|
|
2210
2294
|
request,
|
|
@@ -2218,7 +2302,7 @@ var serve = (routeFunction, options) => {
|
|
|
2218
2302
|
throw failureCheck.error;
|
|
2219
2303
|
} else if (failureCheck.value === "is-failure-callback") {
|
|
2220
2304
|
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
2221
|
-
return onStepFinish(
|
|
2305
|
+
return onStepFinish(workflowRunId, "failure-callback");
|
|
2222
2306
|
}
|
|
2223
2307
|
const workflowContext = new WorkflowContext({
|
|
2224
2308
|
qstashClient,
|
|
@@ -2240,7 +2324,11 @@ var serve = (routeFunction, options) => {
|
|
|
2240
2324
|
await debug?.log("ERROR", "ERROR", { error: authCheck.error.message });
|
|
2241
2325
|
throw authCheck.error;
|
|
2242
2326
|
} else if (authCheck.value === "run-ended") {
|
|
2243
|
-
|
|
2327
|
+
await debug?.log("ERROR", "ERROR", { error: AUTH_FAIL_MESSAGE });
|
|
2328
|
+
return onStepFinish(
|
|
2329
|
+
isFirstInvocation ? "no-workflow-id" : workflowContext.workflowRunId,
|
|
2330
|
+
"auth-fail"
|
|
2331
|
+
);
|
|
2244
2332
|
}
|
|
2245
2333
|
const callReturnCheck = await handleThirdPartyCallResult(
|
|
2246
2334
|
request,
|
|
@@ -2257,7 +2345,7 @@ var serve = (routeFunction, options) => {
|
|
|
2257
2345
|
});
|
|
2258
2346
|
throw callReturnCheck.error;
|
|
2259
2347
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
2260
|
-
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, debug) : await triggerRouteFunction({
|
|
2348
|
+
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, useJSONContent, debug) : await triggerRouteFunction({
|
|
2261
2349
|
onStep: async () => routeFunction(workflowContext),
|
|
2262
2350
|
onCleanup: async () => {
|
|
2263
2351
|
await triggerWorkflowDelete(workflowContext, debug);
|
|
@@ -2273,6 +2361,8 @@ var serve = (routeFunction, options) => {
|
|
|
2273
2361
|
}
|
|
2274
2362
|
await debug?.log("INFO", "RESPONSE_WORKFLOW");
|
|
2275
2363
|
return onStepFinish(workflowContext.workflowRunId, "success");
|
|
2364
|
+
} else if (callReturnCheck.value === "workflow-ended") {
|
|
2365
|
+
return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended");
|
|
2276
2366
|
}
|
|
2277
2367
|
await debug?.log("INFO", "RESPONSE_DEFAULT");
|
|
2278
2368
|
return onStepFinish("no-workflow-id", "fromCallback");
|
|
@@ -2290,15 +2380,12 @@ var serve = (routeFunction, options) => {
|
|
|
2290
2380
|
return { handler: safeHandler };
|
|
2291
2381
|
};
|
|
2292
2382
|
|
|
2293
|
-
// src/client/index.ts
|
|
2294
|
-
var import_qstash6 = require("@upstash/qstash");
|
|
2295
|
-
|
|
2296
2383
|
// platforms/hono.ts
|
|
2297
|
-
var
|
|
2384
|
+
var serve = (routeFunction, options) => {
|
|
2298
2385
|
const handler = async (context) => {
|
|
2299
2386
|
const environment = context.env;
|
|
2300
2387
|
const request = context.req.raw;
|
|
2301
|
-
const { handler: serveHandler } =
|
|
2388
|
+
const { handler: serveHandler } = serveBase(routeFunction, {
|
|
2302
2389
|
// when hono is used without cf workers, it sends a DebugHTTPServer
|
|
2303
2390
|
// object in `context.env`. don't pass env if this is the case:
|
|
2304
2391
|
env: "QSTASH_TOKEN" in environment ? environment : void 0,
|
package/hono.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
serveBase
|
|
3
|
+
} from "./chunk-Z7WS5XIR.mjs";
|
|
4
4
|
|
|
5
5
|
// platforms/hono.ts
|
|
6
|
-
var
|
|
6
|
+
var serve = (routeFunction, options) => {
|
|
7
7
|
const handler = async (context) => {
|
|
8
8
|
const environment = context.env;
|
|
9
9
|
const request = context.req.raw;
|
|
10
|
-
const { handler: serveHandler } =
|
|
10
|
+
const { handler: serveHandler } = serveBase(routeFunction, {
|
|
11
11
|
// when hono is used without cf workers, it sends a DebugHTTPServer
|
|
12
12
|
// object in `context.env`. don't pass env if this is the case:
|
|
13
13
|
env: "QSTASH_TOKEN" in environment ? environment : void 0,
|
|
@@ -18,5 +18,5 @@ var serve2 = (routeFunction, options) => {
|
|
|
18
18
|
return handler;
|
|
19
19
|
};
|
|
20
20
|
export {
|
|
21
|
-
|
|
21
|
+
serve
|
|
22
22
|
};
|
package/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RouteFunction, W as WorkflowServeOptions, N as NotifyResponse, a as Waiter, S as Step } from './types-
|
|
2
|
-
export { A as AsyncStepFunction, C as CallResponse, D as Duration,
|
|
1
|
+
import { R as RouteFunction, W as WorkflowServeOptions, N as NotifyResponse, a as Waiter, S as Step } from './types-APRap-aV.mjs';
|
|
2
|
+
export { A as AsyncStepFunction, C as CallResponse, D as Duration, k as FailureFunctionPayload, F as FinishCondition, L as LogLevel, o as NotifyStepResponse, P as ParallelCallState, j as PublicServeOptions, g as RawStep, l as RequiredExceptFields, i as StepFunction, f as StepType, e as StepTypes, h as SyncStepFunction, p as WaitEventOptions, m as WaitRequest, n as WaitStepResponse, c as WorkflowClient, b as WorkflowContext, r as WorkflowLogger, q as WorkflowLoggerOptions, d as WorkflowReceiver } from './types-APRap-aV.mjs';
|
|
3
3
|
import { Client as Client$1, QstashError } from '@upstash/qstash';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -10,7 +10,7 @@ import { Client as Client$1, QstashError } from '@upstash/qstash';
|
|
|
10
10
|
* @param options - Options including the client, onFinish callback, and initialPayloadParser.
|
|
11
11
|
* @returns An async method that consumes incoming requests and runs the workflow.
|
|
12
12
|
*/
|
|
13
|
-
declare const serve: <TInitialPayload = unknown, TRequest extends Request = Request, TResponse extends Response = Response>(routeFunction: RouteFunction<TInitialPayload>, options?: WorkflowServeOptions<TResponse, TInitialPayload>) => {
|
|
13
|
+
declare const serve: <TInitialPayload = unknown, TRequest extends Request = Request, TResponse extends Response = Response>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<TResponse, TInitialPayload>, "useJSONContent">) => {
|
|
14
14
|
handler: (request: TRequest) => Promise<TResponse>;
|
|
15
15
|
};
|
|
16
16
|
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RouteFunction, W as WorkflowServeOptions, N as NotifyResponse, a as Waiter, S as Step } from './types-
|
|
2
|
-
export { A as AsyncStepFunction, C as CallResponse, D as Duration,
|
|
1
|
+
import { R as RouteFunction, W as WorkflowServeOptions, N as NotifyResponse, a as Waiter, S as Step } from './types-APRap-aV.js';
|
|
2
|
+
export { A as AsyncStepFunction, C as CallResponse, D as Duration, k as FailureFunctionPayload, F as FinishCondition, L as LogLevel, o as NotifyStepResponse, P as ParallelCallState, j as PublicServeOptions, g as RawStep, l as RequiredExceptFields, i as StepFunction, f as StepType, e as StepTypes, h as SyncStepFunction, p as WaitEventOptions, m as WaitRequest, n as WaitStepResponse, c as WorkflowClient, b as WorkflowContext, r as WorkflowLogger, q as WorkflowLoggerOptions, d as WorkflowReceiver } from './types-APRap-aV.js';
|
|
3
3
|
import { Client as Client$1, QstashError } from '@upstash/qstash';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -10,7 +10,7 @@ import { Client as Client$1, QstashError } from '@upstash/qstash';
|
|
|
10
10
|
* @param options - Options including the client, onFinish callback, and initialPayloadParser.
|
|
11
11
|
* @returns An async method that consumes incoming requests and runs the workflow.
|
|
12
12
|
*/
|
|
13
|
-
declare const serve: <TInitialPayload = unknown, TRequest extends Request = Request, TResponse extends Response = Response>(routeFunction: RouteFunction<TInitialPayload>, options?: WorkflowServeOptions<TResponse, TInitialPayload>) => {
|
|
13
|
+
declare const serve: <TInitialPayload = unknown, TRequest extends Request = Request, TResponse extends Response = Response>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<TResponse, TInitialPayload>, "useJSONContent">) => {
|
|
14
14
|
handler: (request: TRequest) => Promise<TResponse>;
|
|
15
15
|
};
|
|
16
16
|
|