@upstash/workflow 0.2.22-rc → 0.2.23-rc
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/README.md +39 -0
- package/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +302 -130
- package/astro.mjs +1 -1
- package/{chunk-CAQSUCHB.mjs → chunk-KAGTWBLF.mjs} +271 -100
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +302 -130
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +304 -131
- package/express.mjs +3 -2
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +302 -130
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +302 -130
- package/hono.mjs +1 -1
- package/index.d.mts +10 -2
- package/index.d.ts +10 -2
- package/index.js +306 -132
- package/index.mjs +5 -3
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +304 -131
- package/nextjs.mjs +3 -2
- package/package.json +1 -1
- package/{serve-many-BNusWYgt.d.mts → serve-many-B5Vbacm6.d.mts} +1 -1
- package/{serve-many-CXqQP3RI.d.ts → serve-many-BCV7INWe.d.ts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +302 -130
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +302 -130
- package/svelte.mjs +1 -1
- package/tanstack.d.mts +2 -2
- package/tanstack.d.ts +2 -2
- package/tanstack.js +302 -130
- package/tanstack.mjs +1 -1
- package/{types-Q3dM0UlR.d.ts → types-BD06btU6.d.mts} +32 -6
- package/{types-Q3dM0UlR.d.mts → types-BD06btU6.d.ts} +32 -6
package/index.js
CHANGED
|
@@ -27,13 +27,102 @@ __export(src_exports, {
|
|
|
27
27
|
WorkflowError: () => WorkflowError,
|
|
28
28
|
WorkflowLogger: () => WorkflowLogger,
|
|
29
29
|
WorkflowNonRetryableError: () => WorkflowNonRetryableError,
|
|
30
|
+
WorkflowRetryAfterError: () => WorkflowRetryAfterError,
|
|
30
31
|
WorkflowTool: () => WorkflowTool,
|
|
31
32
|
serve: () => serve
|
|
32
33
|
});
|
|
33
34
|
module.exports = __toCommonJS(src_exports);
|
|
34
35
|
|
|
35
36
|
// src/client/utils.ts
|
|
37
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
38
|
+
|
|
39
|
+
// src/error.ts
|
|
36
40
|
var import_qstash = require("@upstash/qstash");
|
|
41
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
42
|
+
constructor(message) {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = "WorkflowError";
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var WorkflowAbort = class extends Error {
|
|
48
|
+
stepInfo;
|
|
49
|
+
stepName;
|
|
50
|
+
/**
|
|
51
|
+
* whether workflow is to be canceled on abort
|
|
52
|
+
*/
|
|
53
|
+
cancelWorkflow;
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param stepName name of the aborting step
|
|
57
|
+
* @param stepInfo step information
|
|
58
|
+
* @param cancelWorkflow
|
|
59
|
+
*/
|
|
60
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
61
|
+
super(
|
|
62
|
+
`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}'.`
|
|
63
|
+
);
|
|
64
|
+
this.name = "WorkflowAbort";
|
|
65
|
+
this.stepName = stepName;
|
|
66
|
+
this.stepInfo = stepInfo;
|
|
67
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
71
|
+
/**
|
|
72
|
+
* @param message error message to be displayed
|
|
73
|
+
*/
|
|
74
|
+
constructor(message) {
|
|
75
|
+
super("fail", void 0, false);
|
|
76
|
+
this.name = "WorkflowNonRetryableError";
|
|
77
|
+
if (message) this.message = message;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
81
|
+
retryAfter;
|
|
82
|
+
/**
|
|
83
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
84
|
+
* @param message error message to be displayed
|
|
85
|
+
*/
|
|
86
|
+
constructor(message, retryAfter) {
|
|
87
|
+
super("retry", void 0, false);
|
|
88
|
+
this.name = "WorkflowRetryAfterError";
|
|
89
|
+
this.retryAfter = retryAfter;
|
|
90
|
+
if (message) this.message = message;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
var formatWorkflowError = (error) => {
|
|
94
|
+
return error instanceof Error ? {
|
|
95
|
+
error: error.name,
|
|
96
|
+
message: error.message,
|
|
97
|
+
stack: error.stack
|
|
98
|
+
} : {
|
|
99
|
+
error: "Error",
|
|
100
|
+
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
function getConstructorName(obj) {
|
|
104
|
+
if (obj === null || obj === void 0) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
const ctor = obj.constructor;
|
|
108
|
+
if (!ctor || ctor.name === "Object") {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
return ctor.name;
|
|
112
|
+
}
|
|
113
|
+
function getConstructorNames(obj) {
|
|
114
|
+
const proto = Object.getPrototypeOf(obj);
|
|
115
|
+
const name = getConstructorName(proto);
|
|
116
|
+
if (name === null) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
return [name, ...getConstructorNames(proto)];
|
|
120
|
+
}
|
|
121
|
+
function isInstanceOf(v, ctor) {
|
|
122
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/client/utils.ts
|
|
37
126
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
38
127
|
const result = await requester.request({
|
|
39
128
|
path: ["v2", "notify", eventId],
|
|
@@ -80,7 +169,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
80
169
|
return { steps: filteredSteps, workflowRunEnded: false };
|
|
81
170
|
}
|
|
82
171
|
} catch (error) {
|
|
83
|
-
if (error
|
|
172
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
84
173
|
await debug?.log("WARN", "ENDPOINT_START", {
|
|
85
174
|
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
86
175
|
error
|
|
@@ -105,65 +194,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
105
194
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
106
195
|
var NO_CONCURRENCY = 1;
|
|
107
196
|
var DEFAULT_RETRIES = 3;
|
|
108
|
-
var VERSION = "v0.2.
|
|
197
|
+
var VERSION = "v0.2.22";
|
|
109
198
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
110
199
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
111
200
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
112
201
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
113
202
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
114
203
|
|
|
115
|
-
// src/error.ts
|
|
116
|
-
var import_qstash2 = require("@upstash/qstash");
|
|
117
|
-
var WorkflowError = class extends import_qstash2.QstashError {
|
|
118
|
-
constructor(message) {
|
|
119
|
-
super(message);
|
|
120
|
-
this.name = "WorkflowError";
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
var WorkflowAbort = class extends Error {
|
|
124
|
-
stepInfo;
|
|
125
|
-
stepName;
|
|
126
|
-
/**
|
|
127
|
-
* whether workflow is to be canceled on abort
|
|
128
|
-
*/
|
|
129
|
-
cancelWorkflow;
|
|
130
|
-
/**
|
|
131
|
-
*
|
|
132
|
-
* @param stepName name of the aborting step
|
|
133
|
-
* @param stepInfo step information
|
|
134
|
-
* @param cancelWorkflow
|
|
135
|
-
*/
|
|
136
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
137
|
-
super(
|
|
138
|
-
`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}'.`
|
|
139
|
-
);
|
|
140
|
-
this.name = "WorkflowAbort";
|
|
141
|
-
this.stepName = stepName;
|
|
142
|
-
this.stepInfo = stepInfo;
|
|
143
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
147
|
-
/**
|
|
148
|
-
* @param message error message to be displayed
|
|
149
|
-
*/
|
|
150
|
-
constructor(message) {
|
|
151
|
-
super("fail", void 0, false);
|
|
152
|
-
this.name = "WorkflowNonRetryableError";
|
|
153
|
-
if (message) this.message = message;
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
var formatWorkflowError = (error) => {
|
|
157
|
-
return error instanceof Error ? {
|
|
158
|
-
error: error.name,
|
|
159
|
-
message: error.message,
|
|
160
|
-
stack: error.stack
|
|
161
|
-
} : {
|
|
162
|
-
error: "Error",
|
|
163
|
-
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
164
|
-
};
|
|
165
|
-
};
|
|
166
|
-
|
|
167
204
|
// src/context/auto-executor.ts
|
|
168
205
|
var import_qstash5 = require("@upstash/qstash");
|
|
169
206
|
|
|
@@ -176,8 +213,8 @@ var NANOID_LENGTH = 21;
|
|
|
176
213
|
function getRandomInt() {
|
|
177
214
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
178
215
|
}
|
|
179
|
-
function nanoid() {
|
|
180
|
-
return Array.from({ length
|
|
216
|
+
function nanoid(length = NANOID_LENGTH) {
|
|
217
|
+
return Array.from({ length }).map(() => NANOID_CHARS[getRandomInt()]).join("");
|
|
181
218
|
}
|
|
182
219
|
function getWorkflowRunId(id) {
|
|
183
220
|
return `wfr_${id ?? nanoid()}`;
|
|
@@ -194,6 +231,37 @@ function decodeBase64(base64) {
|
|
|
194
231
|
return binString;
|
|
195
232
|
}
|
|
196
233
|
}
|
|
234
|
+
function getUserIdFromToken(qstashClient) {
|
|
235
|
+
try {
|
|
236
|
+
const token = qstashClient.token;
|
|
237
|
+
const decodedToken = decodeBase64(token);
|
|
238
|
+
const tokenPayload = JSON.parse(decodedToken);
|
|
239
|
+
const userId = tokenPayload.UserID;
|
|
240
|
+
if (!userId) {
|
|
241
|
+
throw new WorkflowError("QStash token payload does not contain userId");
|
|
242
|
+
}
|
|
243
|
+
return userId;
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw new WorkflowError(
|
|
246
|
+
`Failed to decode QStash token while running create webhook step: ${error.message}`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function getQStashUrl(qstashClient) {
|
|
251
|
+
try {
|
|
252
|
+
const requester = qstashClient.http;
|
|
253
|
+
const baseUrl = requester.baseUrl;
|
|
254
|
+
if (!baseUrl) {
|
|
255
|
+
throw new WorkflowError("QStash client does not have a baseUrl");
|
|
256
|
+
}
|
|
257
|
+
return baseUrl;
|
|
258
|
+
} catch (error) {
|
|
259
|
+
throw new WorkflowError(`Failed to get QStash URL from client: ${error.message}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function getEventId() {
|
|
263
|
+
return `evt_${nanoid(15)}`;
|
|
264
|
+
}
|
|
197
265
|
|
|
198
266
|
// node_modules/neverthrow/dist/index.es.js
|
|
199
267
|
var defaultErrorConfig = {
|
|
@@ -619,7 +687,9 @@ var StepTypes = [
|
|
|
619
687
|
"Call",
|
|
620
688
|
"Wait",
|
|
621
689
|
"Notify",
|
|
622
|
-
"Invoke"
|
|
690
|
+
"Invoke",
|
|
691
|
+
"CreateWebhook",
|
|
692
|
+
"WaitForWebhook"
|
|
623
693
|
];
|
|
624
694
|
|
|
625
695
|
// src/workflow-requests.ts
|
|
@@ -723,17 +793,17 @@ var triggerRouteFunction = async ({
|
|
|
723
793
|
return ok("workflow-finished");
|
|
724
794
|
} catch (error) {
|
|
725
795
|
const error_ = error;
|
|
726
|
-
if (error
|
|
796
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
727
797
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
728
798
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
729
799
|
name: error.name,
|
|
730
800
|
errorMessage: error.message
|
|
731
801
|
});
|
|
732
802
|
return ok("workflow-was-finished");
|
|
733
|
-
} else if (
|
|
734
|
-
return err(error_);
|
|
735
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
803
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
736
804
|
return ok(error_);
|
|
805
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
806
|
+
return err(error_);
|
|
737
807
|
} else if (error_.cancelWorkflow) {
|
|
738
808
|
await onCancel();
|
|
739
809
|
return ok("workflow-finished");
|
|
@@ -931,7 +1001,9 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
931
1001
|
// src/context/steps.ts
|
|
932
1002
|
var BaseLazyStep = class _BaseLazyStep {
|
|
933
1003
|
stepName;
|
|
934
|
-
|
|
1004
|
+
context;
|
|
1005
|
+
constructor(context, stepName) {
|
|
1006
|
+
this.context = context;
|
|
935
1007
|
if (!stepName) {
|
|
936
1008
|
throw new WorkflowError(
|
|
937
1009
|
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
@@ -949,13 +1021,14 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
949
1021
|
*
|
|
950
1022
|
* will be called when returning the steps to the context from auto executor
|
|
951
1023
|
*
|
|
952
|
-
* @param
|
|
1024
|
+
* @param step step
|
|
953
1025
|
* @returns parsed out field
|
|
954
1026
|
*/
|
|
955
|
-
parseOut(
|
|
1027
|
+
parseOut(step) {
|
|
1028
|
+
const out = step.out;
|
|
956
1029
|
if (out === void 0) {
|
|
957
1030
|
if (this.allowUndefinedOut) {
|
|
958
|
-
return
|
|
1031
|
+
return this.handleUndefinedOut(step);
|
|
959
1032
|
} else {
|
|
960
1033
|
throw new WorkflowError(
|
|
961
1034
|
`Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
|
|
@@ -963,27 +1036,26 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
963
1036
|
}
|
|
964
1037
|
}
|
|
965
1038
|
if (typeof out === "object") {
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
return out;
|
|
971
|
-
}
|
|
972
|
-
return {
|
|
973
|
-
...out,
|
|
974
|
-
eventData: _BaseLazyStep.tryParsing(out.eventData)
|
|
975
|
-
};
|
|
1039
|
+
console.warn(
|
|
1040
|
+
`Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
|
|
1041
|
+
);
|
|
1042
|
+
return out;
|
|
976
1043
|
}
|
|
977
1044
|
if (typeof out !== "string") {
|
|
978
1045
|
throw new WorkflowError(
|
|
979
1046
|
`Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
|
|
980
1047
|
);
|
|
981
1048
|
}
|
|
982
|
-
return this.safeParseOut(out);
|
|
1049
|
+
return this.safeParseOut(out, step);
|
|
983
1050
|
}
|
|
984
|
-
|
|
1051
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1052
|
+
safeParseOut(out, step) {
|
|
985
1053
|
return _BaseLazyStep.tryParsing(out);
|
|
986
1054
|
}
|
|
1055
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1056
|
+
handleUndefinedOut(step) {
|
|
1057
|
+
return void 0;
|
|
1058
|
+
}
|
|
987
1059
|
static tryParsing(stepOut) {
|
|
988
1060
|
try {
|
|
989
1061
|
return JSON.parse(stepOut);
|
|
@@ -1034,8 +1106,8 @@ var LazyFunctionStep = class extends BaseLazyStep {
|
|
|
1034
1106
|
stepFunction;
|
|
1035
1107
|
stepType = "Run";
|
|
1036
1108
|
allowUndefinedOut = true;
|
|
1037
|
-
constructor(stepName, stepFunction) {
|
|
1038
|
-
super(stepName);
|
|
1109
|
+
constructor(context, stepName, stepFunction) {
|
|
1110
|
+
super(context, stepName);
|
|
1039
1111
|
this.stepFunction = stepFunction;
|
|
1040
1112
|
}
|
|
1041
1113
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1065,8 +1137,8 @@ var LazySleepStep = class extends BaseLazyStep {
|
|
|
1065
1137
|
sleep;
|
|
1066
1138
|
stepType = "SleepFor";
|
|
1067
1139
|
allowUndefinedOut = true;
|
|
1068
|
-
constructor(stepName, sleep) {
|
|
1069
|
-
super(stepName);
|
|
1140
|
+
constructor(context, stepName, sleep) {
|
|
1141
|
+
super(context, stepName);
|
|
1070
1142
|
this.sleep = sleep;
|
|
1071
1143
|
}
|
|
1072
1144
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1107,8 +1179,8 @@ var LazySleepUntilStep = class extends BaseLazyStep {
|
|
|
1107
1179
|
sleepUntil;
|
|
1108
1180
|
stepType = "SleepUntil";
|
|
1109
1181
|
allowUndefinedOut = true;
|
|
1110
|
-
constructor(stepName, sleepUntil) {
|
|
1111
|
-
super(stepName);
|
|
1182
|
+
constructor(context, stepName, sleepUntil) {
|
|
1183
|
+
super(context, stepName);
|
|
1112
1184
|
this.sleepUntil = sleepUntil;
|
|
1113
1185
|
}
|
|
1114
1186
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1160,8 +1232,8 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1160
1232
|
stringifyBody;
|
|
1161
1233
|
stepType = "Call";
|
|
1162
1234
|
allowUndefinedOut = false;
|
|
1163
|
-
constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1164
|
-
super(stepName);
|
|
1235
|
+
constructor(context, stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1236
|
+
super(context, stepName);
|
|
1165
1237
|
this.url = url;
|
|
1166
1238
|
this.method = method;
|
|
1167
1239
|
this.body = body;
|
|
@@ -1305,13 +1377,12 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1305
1377
|
]);
|
|
1306
1378
|
}
|
|
1307
1379
|
};
|
|
1308
|
-
var
|
|
1380
|
+
var LazyWaitEventStep = class extends BaseLazyStep {
|
|
1309
1381
|
eventId;
|
|
1310
1382
|
timeout;
|
|
1311
|
-
stepType = "Wait";
|
|
1312
1383
|
allowUndefinedOut = false;
|
|
1313
|
-
constructor(stepName, eventId, timeout) {
|
|
1314
|
-
super(stepName);
|
|
1384
|
+
constructor(context, stepName, eventId, timeout) {
|
|
1385
|
+
super(context, stepName);
|
|
1315
1386
|
this.eventId = eventId;
|
|
1316
1387
|
this.timeout = timeout;
|
|
1317
1388
|
}
|
|
@@ -1336,13 +1407,6 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1336
1407
|
concurrent
|
|
1337
1408
|
});
|
|
1338
1409
|
}
|
|
1339
|
-
safeParseOut(out) {
|
|
1340
|
-
const result = JSON.parse(out);
|
|
1341
|
-
return {
|
|
1342
|
-
...result,
|
|
1343
|
-
eventData: BaseLazyStep.tryParsing(result.eventData)
|
|
1344
|
-
};
|
|
1345
|
-
}
|
|
1346
1410
|
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1347
1411
|
const headers = super.getHeaders({ context, telemetry, invokeCount, step });
|
|
1348
1412
|
headers.headers["Upstash-Workflow-CallType"] = "step";
|
|
@@ -1376,7 +1440,7 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1376
1440
|
timeoutHeaders,
|
|
1377
1441
|
step: {
|
|
1378
1442
|
stepId: step.stepId,
|
|
1379
|
-
stepType:
|
|
1443
|
+
stepType: this.stepType,
|
|
1380
1444
|
stepName: step.stepName,
|
|
1381
1445
|
concurrent: step.concurrent,
|
|
1382
1446
|
targetStep: step.targetStep
|
|
@@ -1397,8 +1461,8 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1397
1461
|
};
|
|
1398
1462
|
var LazyNotifyStep = class extends LazyFunctionStep {
|
|
1399
1463
|
stepType = "Notify";
|
|
1400
|
-
constructor(stepName, eventId, eventData, requester) {
|
|
1401
|
-
super(stepName, async () => {
|
|
1464
|
+
constructor(context, stepName, eventId, eventData, requester) {
|
|
1465
|
+
super(context, stepName, async () => {
|
|
1402
1466
|
const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
|
|
1403
1467
|
return {
|
|
1404
1468
|
eventId,
|
|
@@ -1423,7 +1487,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1423
1487
|
* workflow id of the invoked workflow
|
|
1424
1488
|
*/
|
|
1425
1489
|
workflowId;
|
|
1426
|
-
constructor(stepName, {
|
|
1490
|
+
constructor(context, stepName, {
|
|
1427
1491
|
workflow,
|
|
1428
1492
|
body,
|
|
1429
1493
|
headers = {},
|
|
@@ -1433,7 +1497,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1433
1497
|
flowControl,
|
|
1434
1498
|
stringifyBody = true
|
|
1435
1499
|
}) {
|
|
1436
|
-
super(stepName);
|
|
1500
|
+
super(context, stepName);
|
|
1437
1501
|
this.params = {
|
|
1438
1502
|
workflow,
|
|
1439
1503
|
body,
|
|
@@ -1494,6 +1558,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1494
1558
|
userHeaders: context.headers,
|
|
1495
1559
|
invokeCount
|
|
1496
1560
|
});
|
|
1561
|
+
context.qstashClient.http.headers?.forEach((value, key) => {
|
|
1562
|
+
invokerHeaders[key] = value;
|
|
1563
|
+
});
|
|
1497
1564
|
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1498
1565
|
let invokeBody;
|
|
1499
1566
|
if (this.params.stringifyBody) {
|
|
@@ -1565,6 +1632,91 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1565
1632
|
return [result];
|
|
1566
1633
|
}
|
|
1567
1634
|
};
|
|
1635
|
+
var LazyCreateWebhookStep = class extends BaseLazyStep {
|
|
1636
|
+
stepType = "CreateWebhook";
|
|
1637
|
+
allowUndefinedOut = false;
|
|
1638
|
+
getPlanStep(concurrent, targetStep) {
|
|
1639
|
+
return {
|
|
1640
|
+
stepId: 0,
|
|
1641
|
+
stepName: this.stepName,
|
|
1642
|
+
stepType: this.stepType,
|
|
1643
|
+
concurrent,
|
|
1644
|
+
targetStep
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
async getResultStep(concurrent, stepId) {
|
|
1648
|
+
return {
|
|
1649
|
+
stepId,
|
|
1650
|
+
stepName: this.stepName,
|
|
1651
|
+
stepType: this.stepType,
|
|
1652
|
+
out: void 0,
|
|
1653
|
+
concurrent
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
getBody({ step, context }) {
|
|
1657
|
+
const userId = getUserIdFromToken(context.qstashClient);
|
|
1658
|
+
const out = [userId, context.workflowRunId, getEventId()].join("/");
|
|
1659
|
+
return JSON.stringify({
|
|
1660
|
+
...step,
|
|
1661
|
+
out
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
safeParseOut(out) {
|
|
1665
|
+
const [userId, workflowRunId, eventId] = out.split("/");
|
|
1666
|
+
const qstashUrl = getQStashUrl(this.context.qstashClient);
|
|
1667
|
+
return {
|
|
1668
|
+
webhookUrl: `${qstashUrl}/v2/workflows/hooks/${userId}/${workflowRunId}/${eventId}`,
|
|
1669
|
+
eventId
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1672
|
+
};
|
|
1673
|
+
var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
|
|
1674
|
+
stepType = "WaitForWebhook";
|
|
1675
|
+
allowUndefinedOut = true;
|
|
1676
|
+
constructor(context, stepName, webhook, timeout) {
|
|
1677
|
+
super(context, stepName, webhook.eventId, timeout);
|
|
1678
|
+
}
|
|
1679
|
+
safeParseOut(out) {
|
|
1680
|
+
const eventData = decodeBase64(out);
|
|
1681
|
+
const parsedEventData = BaseLazyStep.tryParsing(eventData);
|
|
1682
|
+
const body = parsedEventData.body;
|
|
1683
|
+
const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
|
|
1684
|
+
const request = new Request(
|
|
1685
|
+
`${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
|
|
1686
|
+
{
|
|
1687
|
+
method: parsedEventData.method,
|
|
1688
|
+
headers: parsedEventData.header,
|
|
1689
|
+
body: parsedBody
|
|
1690
|
+
}
|
|
1691
|
+
);
|
|
1692
|
+
return {
|
|
1693
|
+
request,
|
|
1694
|
+
timeout: false
|
|
1695
|
+
};
|
|
1696
|
+
}
|
|
1697
|
+
handleUndefinedOut() {
|
|
1698
|
+
return {
|
|
1699
|
+
timeout: true,
|
|
1700
|
+
request: void 0
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1704
|
+
var LazyWaitForEventStep = class extends LazyWaitEventStep {
|
|
1705
|
+
stepType = "Wait";
|
|
1706
|
+
allowUndefinedOut = true;
|
|
1707
|
+
parseWaitForEventOut(out, waitTimeout) {
|
|
1708
|
+
return {
|
|
1709
|
+
eventData: out ? BaseLazyStep.tryParsing(decodeBase64(out)) : void 0,
|
|
1710
|
+
timeout: waitTimeout ?? false
|
|
1711
|
+
};
|
|
1712
|
+
}
|
|
1713
|
+
safeParseOut(out, step) {
|
|
1714
|
+
return this.parseWaitForEventOut(out, step.waitTimeout);
|
|
1715
|
+
}
|
|
1716
|
+
handleUndefinedOut(step) {
|
|
1717
|
+
return this.parseWaitForEventOut(void 0, step.waitTimeout);
|
|
1718
|
+
}
|
|
1719
|
+
};
|
|
1568
1720
|
|
|
1569
1721
|
// src/agents/constants.ts
|
|
1570
1722
|
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
@@ -1969,7 +2121,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1969
2121
|
step,
|
|
1970
2122
|
stepCount: this.stepCount
|
|
1971
2123
|
});
|
|
1972
|
-
return lazyStep.parseOut(step
|
|
2124
|
+
return lazyStep.parseOut(step);
|
|
1973
2125
|
}
|
|
1974
2126
|
const resultStep = await submitSingleStep({
|
|
1975
2127
|
context: this.context,
|
|
@@ -2040,7 +2192,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2040
2192
|
});
|
|
2041
2193
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2042
2194
|
} catch (error) {
|
|
2043
|
-
if (error
|
|
2195
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2044
2196
|
throw error;
|
|
2045
2197
|
}
|
|
2046
2198
|
throw new WorkflowError(
|
|
@@ -2056,7 +2208,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2056
2208
|
const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
|
|
2057
2209
|
validateParallelSteps(parallelSteps, parallelResultSteps);
|
|
2058
2210
|
return parallelResultSteps.map(
|
|
2059
|
-
(step, index) => parallelSteps[index].parseOut(step
|
|
2211
|
+
(step, index) => parallelSteps[index].parseOut(step)
|
|
2060
2212
|
);
|
|
2061
2213
|
}
|
|
2062
2214
|
}
|
|
@@ -2112,7 +2264,6 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2112
2264
|
* @param index index of the current step
|
|
2113
2265
|
* @returns result[index] if lazyStepList > 1, otherwise result
|
|
2114
2266
|
*/
|
|
2115
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2116
2267
|
static getResult(lazyStepList, result, index) {
|
|
2117
2268
|
if (lazyStepList.length === 1) {
|
|
2118
2269
|
return result;
|
|
@@ -2147,7 +2298,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2147
2298
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2148
2299
|
}
|
|
2149
2300
|
} catch (error) {
|
|
2150
|
-
if (error
|
|
2301
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2151
2302
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2152
2303
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2153
2304
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2328,7 +2479,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2328
2479
|
headers: responseHeaders
|
|
2329
2480
|
});
|
|
2330
2481
|
} catch (error) {
|
|
2331
|
-
if (error instanceof Error && error
|
|
2482
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2332
2483
|
throw error;
|
|
2333
2484
|
} else {
|
|
2334
2485
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2461,10 +2612,10 @@ var Agent = class {
|
|
|
2461
2612
|
});
|
|
2462
2613
|
return { text: result.text };
|
|
2463
2614
|
} catch (error) {
|
|
2464
|
-
if (error
|
|
2465
|
-
if (error.cause instanceof Error && error.cause
|
|
2615
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2616
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2466
2617
|
throw error.cause;
|
|
2467
|
-
} else if (error.cause
|
|
2618
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2468
2619
|
throw error.cause.cause;
|
|
2469
2620
|
} else {
|
|
2470
2621
|
throw error;
|
|
@@ -2868,7 +3019,7 @@ var WorkflowContext = class {
|
|
|
2868
3019
|
*/
|
|
2869
3020
|
async run(stepName, stepFunction) {
|
|
2870
3021
|
const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
|
|
2871
|
-
return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
|
|
3022
|
+
return await this.addStep(new LazyFunctionStep(this, stepName, wrappedStepFunction));
|
|
2872
3023
|
}
|
|
2873
3024
|
/**
|
|
2874
3025
|
* Stops the execution for the duration provided.
|
|
@@ -2882,7 +3033,7 @@ var WorkflowContext = class {
|
|
|
2882
3033
|
* @returns undefined
|
|
2883
3034
|
*/
|
|
2884
3035
|
async sleep(stepName, duration) {
|
|
2885
|
-
await this.addStep(new LazySleepStep(stepName, duration));
|
|
3036
|
+
await this.addStep(new LazySleepStep(this, stepName, duration));
|
|
2886
3037
|
}
|
|
2887
3038
|
/**
|
|
2888
3039
|
* Stops the execution until the date time provided.
|
|
@@ -2904,13 +3055,14 @@ var WorkflowContext = class {
|
|
|
2904
3055
|
datetime = typeof datetime === "string" ? new Date(datetime) : datetime;
|
|
2905
3056
|
time = Math.round(datetime.getTime() / 1e3);
|
|
2906
3057
|
}
|
|
2907
|
-
await this.addStep(new LazySleepUntilStep(stepName, time));
|
|
3058
|
+
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
2908
3059
|
}
|
|
2909
3060
|
async call(stepName, settings) {
|
|
2910
3061
|
let callStep;
|
|
2911
3062
|
if ("workflow" in settings) {
|
|
2912
3063
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2913
3064
|
callStep = new LazyCallStep(
|
|
3065
|
+
this,
|
|
2914
3066
|
stepName,
|
|
2915
3067
|
url,
|
|
2916
3068
|
"POST",
|
|
@@ -2935,6 +3087,7 @@ var WorkflowContext = class {
|
|
|
2935
3087
|
stringifyBody = true
|
|
2936
3088
|
} = settings;
|
|
2937
3089
|
callStep = new LazyCallStep(
|
|
3090
|
+
this,
|
|
2938
3091
|
stepName,
|
|
2939
3092
|
url,
|
|
2940
3093
|
method,
|
|
@@ -2986,7 +3139,9 @@ var WorkflowContext = class {
|
|
|
2986
3139
|
async waitForEvent(stepName, eventId, options = {}) {
|
|
2987
3140
|
const { timeout = "7d" } = options;
|
|
2988
3141
|
const timeoutStr = typeof timeout === "string" ? timeout : `${timeout}s`;
|
|
2989
|
-
return await this.addStep(
|
|
3142
|
+
return await this.addStep(
|
|
3143
|
+
new LazyWaitForEventStep(this, stepName, eventId, timeoutStr)
|
|
3144
|
+
);
|
|
2990
3145
|
}
|
|
2991
3146
|
/**
|
|
2992
3147
|
* Notify workflow runs waiting for an event
|
|
@@ -3011,11 +3166,19 @@ var WorkflowContext = class {
|
|
|
3011
3166
|
*/
|
|
3012
3167
|
async notify(stepName, eventId, eventData) {
|
|
3013
3168
|
return await this.addStep(
|
|
3014
|
-
new LazyNotifyStep(stepName, eventId, eventData, this.qstashClient.http)
|
|
3169
|
+
new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
|
|
3015
3170
|
);
|
|
3016
3171
|
}
|
|
3017
3172
|
async invoke(stepName, settings) {
|
|
3018
|
-
return await this.addStep(
|
|
3173
|
+
return await this.addStep(
|
|
3174
|
+
new LazyInvokeStep(this, stepName, settings)
|
|
3175
|
+
);
|
|
3176
|
+
}
|
|
3177
|
+
async createWebhook(stepName) {
|
|
3178
|
+
return await this.addStep(new LazyCreateWebhookStep(this, stepName));
|
|
3179
|
+
}
|
|
3180
|
+
async waitForWebhook(stepName, webhook, timeout) {
|
|
3181
|
+
return await this.addStep(new LazyWaitForWebhookStep(this, stepName, webhook, timeout));
|
|
3019
3182
|
}
|
|
3020
3183
|
/**
|
|
3021
3184
|
* Cancel the current workflow run
|
|
@@ -3146,7 +3309,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3146
3309
|
try {
|
|
3147
3310
|
await routeFunction(disabledContext);
|
|
3148
3311
|
} catch (error) {
|
|
3149
|
-
if (error
|
|
3312
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3150
3313
|
return ok("step-found");
|
|
3151
3314
|
}
|
|
3152
3315
|
console.warn(
|
|
@@ -3179,13 +3342,6 @@ var processRawSteps = (rawSteps) => {
|
|
|
3179
3342
|
const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
|
|
3180
3343
|
const otherSteps = stepsToDecode.map((rawStep) => {
|
|
3181
3344
|
const step = JSON.parse(decodeBase64(rawStep.body));
|
|
3182
|
-
if (step.waitEventId) {
|
|
3183
|
-
const newOut = {
|
|
3184
|
-
eventData: step.out ? decodeBase64(step.out) : void 0,
|
|
3185
|
-
timeout: step.waitTimeout ?? false
|
|
3186
|
-
};
|
|
3187
|
-
step.out = newOut;
|
|
3188
|
-
}
|
|
3189
3345
|
return step;
|
|
3190
3346
|
});
|
|
3191
3347
|
const steps = [initialStep, ...otherSteps];
|
|
@@ -3399,13 +3555,24 @@ var processOptions = (options) => {
|
|
|
3399
3555
|
},
|
|
3400
3556
|
status: 489
|
|
3401
3557
|
});
|
|
3402
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3403
|
-
return new Response(detailedFinishCondition.result
|
|
3404
|
-
status: 200,
|
|
3558
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3559
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3405
3560
|
headers: {
|
|
3561
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3406
3562
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3407
|
-
}
|
|
3563
|
+
},
|
|
3564
|
+
status: 429
|
|
3408
3565
|
});
|
|
3566
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3567
|
+
return new Response(
|
|
3568
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3569
|
+
{
|
|
3570
|
+
status: 200,
|
|
3571
|
+
headers: {
|
|
3572
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
);
|
|
3409
3576
|
}
|
|
3410
3577
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3411
3578
|
status: 200,
|
|
@@ -3615,12 +3782,18 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3615
3782
|
},
|
|
3616
3783
|
debug
|
|
3617
3784
|
});
|
|
3618
|
-
if (result.isOk() && result.value
|
|
3785
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3619
3786
|
return onStepFinish(workflowRunId, result.value, {
|
|
3620
3787
|
condition: "non-retryable-error",
|
|
3621
3788
|
result: result.value
|
|
3622
3789
|
});
|
|
3623
3790
|
}
|
|
3791
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3792
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3793
|
+
condition: "retry-after-error",
|
|
3794
|
+
result: result.value
|
|
3795
|
+
});
|
|
3796
|
+
}
|
|
3624
3797
|
if (result.isErr()) {
|
|
3625
3798
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3626
3799
|
throw result.error;
|
|
@@ -3651,7 +3824,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3651
3824
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3652
3825
|
Original error: '${formattedError.message}'`;
|
|
3653
3826
|
console.error(errorMessage);
|
|
3654
|
-
return new Response(errorMessage, {
|
|
3827
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3655
3828
|
status: 500,
|
|
3656
3829
|
headers: {
|
|
3657
3830
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
@@ -3920,14 +4093,14 @@ var Client4 = class {
|
|
|
3920
4093
|
workflowRunId: finalWorkflowRunId,
|
|
3921
4094
|
retries: option.retries,
|
|
3922
4095
|
retryDelay: option.retryDelay,
|
|
3923
|
-
telemetry: { sdk: SDK_TELEMETRY },
|
|
4096
|
+
telemetry: option.disableTelemetry ? void 0 : { sdk: SDK_TELEMETRY },
|
|
3924
4097
|
flowControl: option.flowControl,
|
|
3925
4098
|
failureUrl,
|
|
3926
4099
|
label: option.label
|
|
3927
4100
|
});
|
|
3928
4101
|
return {
|
|
3929
4102
|
workflowContext: context,
|
|
3930
|
-
telemetry: { sdk: SDK_TELEMETRY },
|
|
4103
|
+
telemetry: option.disableTelemetry ? void 0 : { sdk: SDK_TELEMETRY },
|
|
3931
4104
|
delay: option.delay,
|
|
3932
4105
|
notBefore: option.notBefore,
|
|
3933
4106
|
keepTriggerConfig: option.keepTriggerConfig
|
|
@@ -4012,6 +4185,7 @@ var Client4 = class {
|
|
|
4012
4185
|
WorkflowError,
|
|
4013
4186
|
WorkflowLogger,
|
|
4014
4187
|
WorkflowNonRetryableError,
|
|
4188
|
+
WorkflowRetryAfterError,
|
|
4015
4189
|
WorkflowTool,
|
|
4016
4190
|
serve
|
|
4017
4191
|
});
|