@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/nextjs.js
CHANGED
|
@@ -30,7 +30,95 @@ __export(nextjs_exports, {
|
|
|
30
30
|
module.exports = __toCommonJS(nextjs_exports);
|
|
31
31
|
|
|
32
32
|
// src/client/utils.ts
|
|
33
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
34
|
+
|
|
35
|
+
// src/error.ts
|
|
33
36
|
var import_qstash = require("@upstash/qstash");
|
|
37
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
38
|
+
constructor(message) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = "WorkflowError";
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var WorkflowAbort = class extends Error {
|
|
44
|
+
stepInfo;
|
|
45
|
+
stepName;
|
|
46
|
+
/**
|
|
47
|
+
* whether workflow is to be canceled on abort
|
|
48
|
+
*/
|
|
49
|
+
cancelWorkflow;
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @param stepName name of the aborting step
|
|
53
|
+
* @param stepInfo step information
|
|
54
|
+
* @param cancelWorkflow
|
|
55
|
+
*/
|
|
56
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
57
|
+
super(
|
|
58
|
+
`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}'.`
|
|
59
|
+
);
|
|
60
|
+
this.name = "WorkflowAbort";
|
|
61
|
+
this.stepName = stepName;
|
|
62
|
+
this.stepInfo = stepInfo;
|
|
63
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
67
|
+
/**
|
|
68
|
+
* @param message error message to be displayed
|
|
69
|
+
*/
|
|
70
|
+
constructor(message) {
|
|
71
|
+
super("fail", void 0, false);
|
|
72
|
+
this.name = "WorkflowNonRetryableError";
|
|
73
|
+
if (message) this.message = message;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
77
|
+
retryAfter;
|
|
78
|
+
/**
|
|
79
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
80
|
+
* @param message error message to be displayed
|
|
81
|
+
*/
|
|
82
|
+
constructor(message, retryAfter) {
|
|
83
|
+
super("retry", void 0, false);
|
|
84
|
+
this.name = "WorkflowRetryAfterError";
|
|
85
|
+
this.retryAfter = retryAfter;
|
|
86
|
+
if (message) this.message = message;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
var formatWorkflowError = (error) => {
|
|
90
|
+
return error instanceof Error ? {
|
|
91
|
+
error: error.name,
|
|
92
|
+
message: error.message,
|
|
93
|
+
stack: error.stack
|
|
94
|
+
} : {
|
|
95
|
+
error: "Error",
|
|
96
|
+
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
function getConstructorName(obj) {
|
|
100
|
+
if (obj === null || obj === void 0) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const ctor = obj.constructor;
|
|
104
|
+
if (!ctor || ctor.name === "Object") {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return ctor.name;
|
|
108
|
+
}
|
|
109
|
+
function getConstructorNames(obj) {
|
|
110
|
+
const proto = Object.getPrototypeOf(obj);
|
|
111
|
+
const name = getConstructorName(proto);
|
|
112
|
+
if (name === null) {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
return [name, ...getConstructorNames(proto)];
|
|
116
|
+
}
|
|
117
|
+
function isInstanceOf(v, ctor) {
|
|
118
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/client/utils.ts
|
|
34
122
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
35
123
|
const result = await requester.request({
|
|
36
124
|
path: ["v2", "notify", eventId],
|
|
@@ -70,7 +158,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
70
158
|
return { steps: filteredSteps, workflowRunEnded: false };
|
|
71
159
|
}
|
|
72
160
|
} catch (error) {
|
|
73
|
-
if (error
|
|
161
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
74
162
|
await debug?.log("WARN", "ENDPOINT_START", {
|
|
75
163
|
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
76
164
|
error
|
|
@@ -95,65 +183,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
95
183
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
96
184
|
var NO_CONCURRENCY = 1;
|
|
97
185
|
var DEFAULT_RETRIES = 3;
|
|
98
|
-
var VERSION = "v0.2.
|
|
186
|
+
var VERSION = "v0.2.22";
|
|
99
187
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
100
188
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
101
189
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
102
190
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
103
191
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
104
192
|
|
|
105
|
-
// src/error.ts
|
|
106
|
-
var import_qstash2 = require("@upstash/qstash");
|
|
107
|
-
var WorkflowError = class extends import_qstash2.QstashError {
|
|
108
|
-
constructor(message) {
|
|
109
|
-
super(message);
|
|
110
|
-
this.name = "WorkflowError";
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
var WorkflowAbort = class extends Error {
|
|
114
|
-
stepInfo;
|
|
115
|
-
stepName;
|
|
116
|
-
/**
|
|
117
|
-
* whether workflow is to be canceled on abort
|
|
118
|
-
*/
|
|
119
|
-
cancelWorkflow;
|
|
120
|
-
/**
|
|
121
|
-
*
|
|
122
|
-
* @param stepName name of the aborting step
|
|
123
|
-
* @param stepInfo step information
|
|
124
|
-
* @param cancelWorkflow
|
|
125
|
-
*/
|
|
126
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
127
|
-
super(
|
|
128
|
-
`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}'.`
|
|
129
|
-
);
|
|
130
|
-
this.name = "WorkflowAbort";
|
|
131
|
-
this.stepName = stepName;
|
|
132
|
-
this.stepInfo = stepInfo;
|
|
133
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
137
|
-
/**
|
|
138
|
-
* @param message error message to be displayed
|
|
139
|
-
*/
|
|
140
|
-
constructor(message) {
|
|
141
|
-
super("fail", void 0, false);
|
|
142
|
-
this.name = "WorkflowNonRetryableError";
|
|
143
|
-
if (message) this.message = message;
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
var formatWorkflowError = (error) => {
|
|
147
|
-
return error instanceof Error ? {
|
|
148
|
-
error: error.name,
|
|
149
|
-
message: error.message,
|
|
150
|
-
stack: error.stack
|
|
151
|
-
} : {
|
|
152
|
-
error: "Error",
|
|
153
|
-
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
154
|
-
};
|
|
155
|
-
};
|
|
156
|
-
|
|
157
193
|
// src/context/auto-executor.ts
|
|
158
194
|
var import_qstash5 = require("@upstash/qstash");
|
|
159
195
|
|
|
@@ -166,8 +202,8 @@ var NANOID_LENGTH = 21;
|
|
|
166
202
|
function getRandomInt() {
|
|
167
203
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
168
204
|
}
|
|
169
|
-
function nanoid() {
|
|
170
|
-
return Array.from({ length
|
|
205
|
+
function nanoid(length = NANOID_LENGTH) {
|
|
206
|
+
return Array.from({ length }).map(() => NANOID_CHARS[getRandomInt()]).join("");
|
|
171
207
|
}
|
|
172
208
|
function getWorkflowRunId(id) {
|
|
173
209
|
return `wfr_${id ?? nanoid()}`;
|
|
@@ -184,6 +220,37 @@ function decodeBase64(base64) {
|
|
|
184
220
|
return binString;
|
|
185
221
|
}
|
|
186
222
|
}
|
|
223
|
+
function getUserIdFromToken(qstashClient) {
|
|
224
|
+
try {
|
|
225
|
+
const token = qstashClient.token;
|
|
226
|
+
const decodedToken = decodeBase64(token);
|
|
227
|
+
const tokenPayload = JSON.parse(decodedToken);
|
|
228
|
+
const userId = tokenPayload.UserID;
|
|
229
|
+
if (!userId) {
|
|
230
|
+
throw new WorkflowError("QStash token payload does not contain userId");
|
|
231
|
+
}
|
|
232
|
+
return userId;
|
|
233
|
+
} catch (error) {
|
|
234
|
+
throw new WorkflowError(
|
|
235
|
+
`Failed to decode QStash token while running create webhook step: ${error.message}`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function getQStashUrl(qstashClient) {
|
|
240
|
+
try {
|
|
241
|
+
const requester = qstashClient.http;
|
|
242
|
+
const baseUrl = requester.baseUrl;
|
|
243
|
+
if (!baseUrl) {
|
|
244
|
+
throw new WorkflowError("QStash client does not have a baseUrl");
|
|
245
|
+
}
|
|
246
|
+
return baseUrl;
|
|
247
|
+
} catch (error) {
|
|
248
|
+
throw new WorkflowError(`Failed to get QStash URL from client: ${error.message}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function getEventId() {
|
|
252
|
+
return `evt_${nanoid(15)}`;
|
|
253
|
+
}
|
|
187
254
|
|
|
188
255
|
// node_modules/neverthrow/dist/index.es.js
|
|
189
256
|
var defaultErrorConfig = {
|
|
@@ -609,7 +676,9 @@ var StepTypes = [
|
|
|
609
676
|
"Call",
|
|
610
677
|
"Wait",
|
|
611
678
|
"Notify",
|
|
612
|
-
"Invoke"
|
|
679
|
+
"Invoke",
|
|
680
|
+
"CreateWebhook",
|
|
681
|
+
"WaitForWebhook"
|
|
613
682
|
];
|
|
614
683
|
|
|
615
684
|
// src/workflow-requests.ts
|
|
@@ -713,17 +782,17 @@ var triggerRouteFunction = async ({
|
|
|
713
782
|
return ok("workflow-finished");
|
|
714
783
|
} catch (error) {
|
|
715
784
|
const error_ = error;
|
|
716
|
-
if (error
|
|
785
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
717
786
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
718
787
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
719
788
|
name: error.name,
|
|
720
789
|
errorMessage: error.message
|
|
721
790
|
});
|
|
722
791
|
return ok("workflow-was-finished");
|
|
723
|
-
} else if (
|
|
724
|
-
return err(error_);
|
|
725
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
792
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
726
793
|
return ok(error_);
|
|
794
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
795
|
+
return err(error_);
|
|
727
796
|
} else if (error_.cancelWorkflow) {
|
|
728
797
|
await onCancel();
|
|
729
798
|
return ok("workflow-finished");
|
|
@@ -921,7 +990,9 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
921
990
|
// src/context/steps.ts
|
|
922
991
|
var BaseLazyStep = class _BaseLazyStep {
|
|
923
992
|
stepName;
|
|
924
|
-
|
|
993
|
+
context;
|
|
994
|
+
constructor(context, stepName) {
|
|
995
|
+
this.context = context;
|
|
925
996
|
if (!stepName) {
|
|
926
997
|
throw new WorkflowError(
|
|
927
998
|
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
@@ -939,13 +1010,14 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
939
1010
|
*
|
|
940
1011
|
* will be called when returning the steps to the context from auto executor
|
|
941
1012
|
*
|
|
942
|
-
* @param
|
|
1013
|
+
* @param step step
|
|
943
1014
|
* @returns parsed out field
|
|
944
1015
|
*/
|
|
945
|
-
parseOut(
|
|
1016
|
+
parseOut(step) {
|
|
1017
|
+
const out = step.out;
|
|
946
1018
|
if (out === void 0) {
|
|
947
1019
|
if (this.allowUndefinedOut) {
|
|
948
|
-
return
|
|
1020
|
+
return this.handleUndefinedOut(step);
|
|
949
1021
|
} else {
|
|
950
1022
|
throw new WorkflowError(
|
|
951
1023
|
`Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
|
|
@@ -953,27 +1025,26 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
953
1025
|
}
|
|
954
1026
|
}
|
|
955
1027
|
if (typeof out === "object") {
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
return out;
|
|
961
|
-
}
|
|
962
|
-
return {
|
|
963
|
-
...out,
|
|
964
|
-
eventData: _BaseLazyStep.tryParsing(out.eventData)
|
|
965
|
-
};
|
|
1028
|
+
console.warn(
|
|
1029
|
+
`Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
|
|
1030
|
+
);
|
|
1031
|
+
return out;
|
|
966
1032
|
}
|
|
967
1033
|
if (typeof out !== "string") {
|
|
968
1034
|
throw new WorkflowError(
|
|
969
1035
|
`Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
|
|
970
1036
|
);
|
|
971
1037
|
}
|
|
972
|
-
return this.safeParseOut(out);
|
|
1038
|
+
return this.safeParseOut(out, step);
|
|
973
1039
|
}
|
|
974
|
-
|
|
1040
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1041
|
+
safeParseOut(out, step) {
|
|
975
1042
|
return _BaseLazyStep.tryParsing(out);
|
|
976
1043
|
}
|
|
1044
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1045
|
+
handleUndefinedOut(step) {
|
|
1046
|
+
return void 0;
|
|
1047
|
+
}
|
|
977
1048
|
static tryParsing(stepOut) {
|
|
978
1049
|
try {
|
|
979
1050
|
return JSON.parse(stepOut);
|
|
@@ -1024,8 +1095,8 @@ var LazyFunctionStep = class extends BaseLazyStep {
|
|
|
1024
1095
|
stepFunction;
|
|
1025
1096
|
stepType = "Run";
|
|
1026
1097
|
allowUndefinedOut = true;
|
|
1027
|
-
constructor(stepName, stepFunction) {
|
|
1028
|
-
super(stepName);
|
|
1098
|
+
constructor(context, stepName, stepFunction) {
|
|
1099
|
+
super(context, stepName);
|
|
1029
1100
|
this.stepFunction = stepFunction;
|
|
1030
1101
|
}
|
|
1031
1102
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1055,8 +1126,8 @@ var LazySleepStep = class extends BaseLazyStep {
|
|
|
1055
1126
|
sleep;
|
|
1056
1127
|
stepType = "SleepFor";
|
|
1057
1128
|
allowUndefinedOut = true;
|
|
1058
|
-
constructor(stepName, sleep) {
|
|
1059
|
-
super(stepName);
|
|
1129
|
+
constructor(context, stepName, sleep) {
|
|
1130
|
+
super(context, stepName);
|
|
1060
1131
|
this.sleep = sleep;
|
|
1061
1132
|
}
|
|
1062
1133
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1097,8 +1168,8 @@ var LazySleepUntilStep = class extends BaseLazyStep {
|
|
|
1097
1168
|
sleepUntil;
|
|
1098
1169
|
stepType = "SleepUntil";
|
|
1099
1170
|
allowUndefinedOut = true;
|
|
1100
|
-
constructor(stepName, sleepUntil) {
|
|
1101
|
-
super(stepName);
|
|
1171
|
+
constructor(context, stepName, sleepUntil) {
|
|
1172
|
+
super(context, stepName);
|
|
1102
1173
|
this.sleepUntil = sleepUntil;
|
|
1103
1174
|
}
|
|
1104
1175
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1150,8 +1221,8 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1150
1221
|
stringifyBody;
|
|
1151
1222
|
stepType = "Call";
|
|
1152
1223
|
allowUndefinedOut = false;
|
|
1153
|
-
constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1154
|
-
super(stepName);
|
|
1224
|
+
constructor(context, stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1225
|
+
super(context, stepName);
|
|
1155
1226
|
this.url = url;
|
|
1156
1227
|
this.method = method;
|
|
1157
1228
|
this.body = body;
|
|
@@ -1295,13 +1366,12 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1295
1366
|
]);
|
|
1296
1367
|
}
|
|
1297
1368
|
};
|
|
1298
|
-
var
|
|
1369
|
+
var LazyWaitEventStep = class extends BaseLazyStep {
|
|
1299
1370
|
eventId;
|
|
1300
1371
|
timeout;
|
|
1301
|
-
stepType = "Wait";
|
|
1302
1372
|
allowUndefinedOut = false;
|
|
1303
|
-
constructor(stepName, eventId, timeout) {
|
|
1304
|
-
super(stepName);
|
|
1373
|
+
constructor(context, stepName, eventId, timeout) {
|
|
1374
|
+
super(context, stepName);
|
|
1305
1375
|
this.eventId = eventId;
|
|
1306
1376
|
this.timeout = timeout;
|
|
1307
1377
|
}
|
|
@@ -1326,13 +1396,6 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1326
1396
|
concurrent
|
|
1327
1397
|
});
|
|
1328
1398
|
}
|
|
1329
|
-
safeParseOut(out) {
|
|
1330
|
-
const result = JSON.parse(out);
|
|
1331
|
-
return {
|
|
1332
|
-
...result,
|
|
1333
|
-
eventData: BaseLazyStep.tryParsing(result.eventData)
|
|
1334
|
-
};
|
|
1335
|
-
}
|
|
1336
1399
|
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1337
1400
|
const headers = super.getHeaders({ context, telemetry, invokeCount, step });
|
|
1338
1401
|
headers.headers["Upstash-Workflow-CallType"] = "step";
|
|
@@ -1366,7 +1429,7 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1366
1429
|
timeoutHeaders,
|
|
1367
1430
|
step: {
|
|
1368
1431
|
stepId: step.stepId,
|
|
1369
|
-
stepType:
|
|
1432
|
+
stepType: this.stepType,
|
|
1370
1433
|
stepName: step.stepName,
|
|
1371
1434
|
concurrent: step.concurrent,
|
|
1372
1435
|
targetStep: step.targetStep
|
|
@@ -1387,8 +1450,8 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1387
1450
|
};
|
|
1388
1451
|
var LazyNotifyStep = class extends LazyFunctionStep {
|
|
1389
1452
|
stepType = "Notify";
|
|
1390
|
-
constructor(stepName, eventId, eventData, requester) {
|
|
1391
|
-
super(stepName, async () => {
|
|
1453
|
+
constructor(context, stepName, eventId, eventData, requester) {
|
|
1454
|
+
super(context, stepName, async () => {
|
|
1392
1455
|
const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
|
|
1393
1456
|
return {
|
|
1394
1457
|
eventId,
|
|
@@ -1413,7 +1476,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1413
1476
|
* workflow id of the invoked workflow
|
|
1414
1477
|
*/
|
|
1415
1478
|
workflowId;
|
|
1416
|
-
constructor(stepName, {
|
|
1479
|
+
constructor(context, stepName, {
|
|
1417
1480
|
workflow,
|
|
1418
1481
|
body,
|
|
1419
1482
|
headers = {},
|
|
@@ -1423,7 +1486,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1423
1486
|
flowControl,
|
|
1424
1487
|
stringifyBody = true
|
|
1425
1488
|
}) {
|
|
1426
|
-
super(stepName);
|
|
1489
|
+
super(context, stepName);
|
|
1427
1490
|
this.params = {
|
|
1428
1491
|
workflow,
|
|
1429
1492
|
body,
|
|
@@ -1484,6 +1547,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1484
1547
|
userHeaders: context.headers,
|
|
1485
1548
|
invokeCount
|
|
1486
1549
|
});
|
|
1550
|
+
context.qstashClient.http.headers?.forEach((value, key) => {
|
|
1551
|
+
invokerHeaders[key] = value;
|
|
1552
|
+
});
|
|
1487
1553
|
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1488
1554
|
let invokeBody;
|
|
1489
1555
|
if (this.params.stringifyBody) {
|
|
@@ -1555,6 +1621,91 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1555
1621
|
return [result];
|
|
1556
1622
|
}
|
|
1557
1623
|
};
|
|
1624
|
+
var LazyCreateWebhookStep = class extends BaseLazyStep {
|
|
1625
|
+
stepType = "CreateWebhook";
|
|
1626
|
+
allowUndefinedOut = false;
|
|
1627
|
+
getPlanStep(concurrent, targetStep) {
|
|
1628
|
+
return {
|
|
1629
|
+
stepId: 0,
|
|
1630
|
+
stepName: this.stepName,
|
|
1631
|
+
stepType: this.stepType,
|
|
1632
|
+
concurrent,
|
|
1633
|
+
targetStep
|
|
1634
|
+
};
|
|
1635
|
+
}
|
|
1636
|
+
async getResultStep(concurrent, stepId) {
|
|
1637
|
+
return {
|
|
1638
|
+
stepId,
|
|
1639
|
+
stepName: this.stepName,
|
|
1640
|
+
stepType: this.stepType,
|
|
1641
|
+
out: void 0,
|
|
1642
|
+
concurrent
|
|
1643
|
+
};
|
|
1644
|
+
}
|
|
1645
|
+
getBody({ step, context }) {
|
|
1646
|
+
const userId = getUserIdFromToken(context.qstashClient);
|
|
1647
|
+
const out = [userId, context.workflowRunId, getEventId()].join("/");
|
|
1648
|
+
return JSON.stringify({
|
|
1649
|
+
...step,
|
|
1650
|
+
out
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
1653
|
+
safeParseOut(out) {
|
|
1654
|
+
const [userId, workflowRunId, eventId] = out.split("/");
|
|
1655
|
+
const qstashUrl = getQStashUrl(this.context.qstashClient);
|
|
1656
|
+
return {
|
|
1657
|
+
webhookUrl: `${qstashUrl}/v2/workflows/hooks/${userId}/${workflowRunId}/${eventId}`,
|
|
1658
|
+
eventId
|
|
1659
|
+
};
|
|
1660
|
+
}
|
|
1661
|
+
};
|
|
1662
|
+
var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
|
|
1663
|
+
stepType = "WaitForWebhook";
|
|
1664
|
+
allowUndefinedOut = true;
|
|
1665
|
+
constructor(context, stepName, webhook, timeout) {
|
|
1666
|
+
super(context, stepName, webhook.eventId, timeout);
|
|
1667
|
+
}
|
|
1668
|
+
safeParseOut(out) {
|
|
1669
|
+
const eventData = decodeBase64(out);
|
|
1670
|
+
const parsedEventData = BaseLazyStep.tryParsing(eventData);
|
|
1671
|
+
const body = parsedEventData.body;
|
|
1672
|
+
const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
|
|
1673
|
+
const request = new Request(
|
|
1674
|
+
`${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
|
|
1675
|
+
{
|
|
1676
|
+
method: parsedEventData.method,
|
|
1677
|
+
headers: parsedEventData.header,
|
|
1678
|
+
body: parsedBody
|
|
1679
|
+
}
|
|
1680
|
+
);
|
|
1681
|
+
return {
|
|
1682
|
+
request,
|
|
1683
|
+
timeout: false
|
|
1684
|
+
};
|
|
1685
|
+
}
|
|
1686
|
+
handleUndefinedOut() {
|
|
1687
|
+
return {
|
|
1688
|
+
timeout: true,
|
|
1689
|
+
request: void 0
|
|
1690
|
+
};
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
var LazyWaitForEventStep = class extends LazyWaitEventStep {
|
|
1694
|
+
stepType = "Wait";
|
|
1695
|
+
allowUndefinedOut = true;
|
|
1696
|
+
parseWaitForEventOut(out, waitTimeout) {
|
|
1697
|
+
return {
|
|
1698
|
+
eventData: out ? BaseLazyStep.tryParsing(decodeBase64(out)) : void 0,
|
|
1699
|
+
timeout: waitTimeout ?? false
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
safeParseOut(out, step) {
|
|
1703
|
+
return this.parseWaitForEventOut(out, step.waitTimeout);
|
|
1704
|
+
}
|
|
1705
|
+
handleUndefinedOut(step) {
|
|
1706
|
+
return this.parseWaitForEventOut(void 0, step.waitTimeout);
|
|
1707
|
+
}
|
|
1708
|
+
};
|
|
1558
1709
|
|
|
1559
1710
|
// src/agents/constants.ts
|
|
1560
1711
|
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
@@ -1959,7 +2110,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1959
2110
|
step,
|
|
1960
2111
|
stepCount: this.stepCount
|
|
1961
2112
|
});
|
|
1962
|
-
return lazyStep.parseOut(step
|
|
2113
|
+
return lazyStep.parseOut(step);
|
|
1963
2114
|
}
|
|
1964
2115
|
const resultStep = await submitSingleStep({
|
|
1965
2116
|
context: this.context,
|
|
@@ -2030,7 +2181,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2030
2181
|
});
|
|
2031
2182
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2032
2183
|
} catch (error) {
|
|
2033
|
-
if (error
|
|
2184
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2034
2185
|
throw error;
|
|
2035
2186
|
}
|
|
2036
2187
|
throw new WorkflowError(
|
|
@@ -2046,7 +2197,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2046
2197
|
const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
|
|
2047
2198
|
validateParallelSteps(parallelSteps, parallelResultSteps);
|
|
2048
2199
|
return parallelResultSteps.map(
|
|
2049
|
-
(step, index) => parallelSteps[index].parseOut(step
|
|
2200
|
+
(step, index) => parallelSteps[index].parseOut(step)
|
|
2050
2201
|
);
|
|
2051
2202
|
}
|
|
2052
2203
|
}
|
|
@@ -2102,7 +2253,6 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2102
2253
|
* @param index index of the current step
|
|
2103
2254
|
* @returns result[index] if lazyStepList > 1, otherwise result
|
|
2104
2255
|
*/
|
|
2105
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2106
2256
|
static getResult(lazyStepList, result, index) {
|
|
2107
2257
|
if (lazyStepList.length === 1) {
|
|
2108
2258
|
return result;
|
|
@@ -2137,7 +2287,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2137
2287
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2138
2288
|
}
|
|
2139
2289
|
} catch (error) {
|
|
2140
|
-
if (error
|
|
2290
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2141
2291
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2142
2292
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2143
2293
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2318,7 +2468,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2318
2468
|
headers: responseHeaders
|
|
2319
2469
|
});
|
|
2320
2470
|
} catch (error) {
|
|
2321
|
-
if (error instanceof Error && error
|
|
2471
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2322
2472
|
throw error;
|
|
2323
2473
|
} else {
|
|
2324
2474
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2420,10 +2570,10 @@ var Agent = class {
|
|
|
2420
2570
|
});
|
|
2421
2571
|
return { text: result.text };
|
|
2422
2572
|
} catch (error) {
|
|
2423
|
-
if (error
|
|
2424
|
-
if (error.cause instanceof Error && error.cause
|
|
2573
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2574
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2425
2575
|
throw error.cause;
|
|
2426
|
-
} else if (error.cause
|
|
2576
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2427
2577
|
throw error.cause.cause;
|
|
2428
2578
|
} else {
|
|
2429
2579
|
throw error;
|
|
@@ -2894,7 +3044,7 @@ var WorkflowContext = class {
|
|
|
2894
3044
|
*/
|
|
2895
3045
|
async run(stepName, stepFunction) {
|
|
2896
3046
|
const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
|
|
2897
|
-
return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
|
|
3047
|
+
return await this.addStep(new LazyFunctionStep(this, stepName, wrappedStepFunction));
|
|
2898
3048
|
}
|
|
2899
3049
|
/**
|
|
2900
3050
|
* Stops the execution for the duration provided.
|
|
@@ -2908,7 +3058,7 @@ var WorkflowContext = class {
|
|
|
2908
3058
|
* @returns undefined
|
|
2909
3059
|
*/
|
|
2910
3060
|
async sleep(stepName, duration) {
|
|
2911
|
-
await this.addStep(new LazySleepStep(stepName, duration));
|
|
3061
|
+
await this.addStep(new LazySleepStep(this, stepName, duration));
|
|
2912
3062
|
}
|
|
2913
3063
|
/**
|
|
2914
3064
|
* Stops the execution until the date time provided.
|
|
@@ -2930,13 +3080,14 @@ var WorkflowContext = class {
|
|
|
2930
3080
|
datetime = typeof datetime === "string" ? new Date(datetime) : datetime;
|
|
2931
3081
|
time = Math.round(datetime.getTime() / 1e3);
|
|
2932
3082
|
}
|
|
2933
|
-
await this.addStep(new LazySleepUntilStep(stepName, time));
|
|
3083
|
+
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
2934
3084
|
}
|
|
2935
3085
|
async call(stepName, settings) {
|
|
2936
3086
|
let callStep;
|
|
2937
3087
|
if ("workflow" in settings) {
|
|
2938
3088
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2939
3089
|
callStep = new LazyCallStep(
|
|
3090
|
+
this,
|
|
2940
3091
|
stepName,
|
|
2941
3092
|
url,
|
|
2942
3093
|
"POST",
|
|
@@ -2961,6 +3112,7 @@ var WorkflowContext = class {
|
|
|
2961
3112
|
stringifyBody = true
|
|
2962
3113
|
} = settings;
|
|
2963
3114
|
callStep = new LazyCallStep(
|
|
3115
|
+
this,
|
|
2964
3116
|
stepName,
|
|
2965
3117
|
url,
|
|
2966
3118
|
method,
|
|
@@ -3012,7 +3164,9 @@ var WorkflowContext = class {
|
|
|
3012
3164
|
async waitForEvent(stepName, eventId, options = {}) {
|
|
3013
3165
|
const { timeout = "7d" } = options;
|
|
3014
3166
|
const timeoutStr = typeof timeout === "string" ? timeout : `${timeout}s`;
|
|
3015
|
-
return await this.addStep(
|
|
3167
|
+
return await this.addStep(
|
|
3168
|
+
new LazyWaitForEventStep(this, stepName, eventId, timeoutStr)
|
|
3169
|
+
);
|
|
3016
3170
|
}
|
|
3017
3171
|
/**
|
|
3018
3172
|
* Notify workflow runs waiting for an event
|
|
@@ -3037,11 +3191,19 @@ var WorkflowContext = class {
|
|
|
3037
3191
|
*/
|
|
3038
3192
|
async notify(stepName, eventId, eventData) {
|
|
3039
3193
|
return await this.addStep(
|
|
3040
|
-
new LazyNotifyStep(stepName, eventId, eventData, this.qstashClient.http)
|
|
3194
|
+
new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
|
|
3041
3195
|
);
|
|
3042
3196
|
}
|
|
3043
3197
|
async invoke(stepName, settings) {
|
|
3044
|
-
return await this.addStep(
|
|
3198
|
+
return await this.addStep(
|
|
3199
|
+
new LazyInvokeStep(this, stepName, settings)
|
|
3200
|
+
);
|
|
3201
|
+
}
|
|
3202
|
+
async createWebhook(stepName) {
|
|
3203
|
+
return await this.addStep(new LazyCreateWebhookStep(this, stepName));
|
|
3204
|
+
}
|
|
3205
|
+
async waitForWebhook(stepName, webhook, timeout) {
|
|
3206
|
+
return await this.addStep(new LazyWaitForWebhookStep(this, stepName, webhook, timeout));
|
|
3045
3207
|
}
|
|
3046
3208
|
/**
|
|
3047
3209
|
* Cancel the current workflow run
|
|
@@ -3172,7 +3334,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3172
3334
|
try {
|
|
3173
3335
|
await routeFunction(disabledContext);
|
|
3174
3336
|
} catch (error) {
|
|
3175
|
-
if (error
|
|
3337
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3176
3338
|
return ok("step-found");
|
|
3177
3339
|
}
|
|
3178
3340
|
console.warn(
|
|
@@ -3205,13 +3367,6 @@ var processRawSteps = (rawSteps) => {
|
|
|
3205
3367
|
const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
|
|
3206
3368
|
const otherSteps = stepsToDecode.map((rawStep) => {
|
|
3207
3369
|
const step = JSON.parse(decodeBase64(rawStep.body));
|
|
3208
|
-
if (step.waitEventId) {
|
|
3209
|
-
const newOut = {
|
|
3210
|
-
eventData: step.out ? decodeBase64(step.out) : void 0,
|
|
3211
|
-
timeout: step.waitTimeout ?? false
|
|
3212
|
-
};
|
|
3213
|
-
step.out = newOut;
|
|
3214
|
-
}
|
|
3215
3370
|
return step;
|
|
3216
3371
|
});
|
|
3217
3372
|
const steps = [initialStep, ...otherSteps];
|
|
@@ -3425,13 +3580,24 @@ var processOptions = (options) => {
|
|
|
3425
3580
|
},
|
|
3426
3581
|
status: 489
|
|
3427
3582
|
});
|
|
3428
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3429
|
-
return new Response(detailedFinishCondition.result
|
|
3430
|
-
status: 200,
|
|
3583
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3584
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3431
3585
|
headers: {
|
|
3586
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3432
3587
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3433
|
-
}
|
|
3588
|
+
},
|
|
3589
|
+
status: 429
|
|
3434
3590
|
});
|
|
3591
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3592
|
+
return new Response(
|
|
3593
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3594
|
+
{
|
|
3595
|
+
status: 200,
|
|
3596
|
+
headers: {
|
|
3597
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
);
|
|
3435
3601
|
}
|
|
3436
3602
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3437
3603
|
status: 200,
|
|
@@ -3641,12 +3807,18 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3641
3807
|
},
|
|
3642
3808
|
debug
|
|
3643
3809
|
});
|
|
3644
|
-
if (result.isOk() && result.value
|
|
3810
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3645
3811
|
return onStepFinish(workflowRunId, result.value, {
|
|
3646
3812
|
condition: "non-retryable-error",
|
|
3647
3813
|
result: result.value
|
|
3648
3814
|
});
|
|
3649
3815
|
}
|
|
3816
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3817
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3818
|
+
condition: "retry-after-error",
|
|
3819
|
+
result: result.value
|
|
3820
|
+
});
|
|
3821
|
+
}
|
|
3650
3822
|
if (result.isErr()) {
|
|
3651
3823
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3652
3824
|
throw result.error;
|
|
@@ -3677,7 +3849,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3677
3849
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3678
3850
|
Original error: '${formattedError.message}'`;
|
|
3679
3851
|
console.error(errorMessage);
|
|
3680
|
-
return new Response(errorMessage, {
|
|
3852
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3681
3853
|
status: 500,
|
|
3682
3854
|
headers: {
|
|
3683
3855
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
@@ -3759,7 +3931,8 @@ var servePagesRouter = (routeFunction, options) => {
|
|
|
3759
3931
|
for (const [key, value] of response.headers.entries()) {
|
|
3760
3932
|
res.setHeader(key, value);
|
|
3761
3933
|
}
|
|
3762
|
-
|
|
3934
|
+
const responseData = await response.json();
|
|
3935
|
+
res.status(response.status).json(responseData);
|
|
3763
3936
|
};
|
|
3764
3937
|
return {
|
|
3765
3938
|
handler
|