@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/solidjs.js
CHANGED
|
@@ -25,7 +25,95 @@ __export(solidjs_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(solidjs_exports);
|
|
26
26
|
|
|
27
27
|
// src/client/utils.ts
|
|
28
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
29
|
+
|
|
30
|
+
// src/error.ts
|
|
28
31
|
var import_qstash = require("@upstash/qstash");
|
|
32
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
33
|
+
constructor(message) {
|
|
34
|
+
super(message);
|
|
35
|
+
this.name = "WorkflowError";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var WorkflowAbort = class extends Error {
|
|
39
|
+
stepInfo;
|
|
40
|
+
stepName;
|
|
41
|
+
/**
|
|
42
|
+
* whether workflow is to be canceled on abort
|
|
43
|
+
*/
|
|
44
|
+
cancelWorkflow;
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param stepName name of the aborting step
|
|
48
|
+
* @param stepInfo step information
|
|
49
|
+
* @param cancelWorkflow
|
|
50
|
+
*/
|
|
51
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
52
|
+
super(
|
|
53
|
+
`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}'.`
|
|
54
|
+
);
|
|
55
|
+
this.name = "WorkflowAbort";
|
|
56
|
+
this.stepName = stepName;
|
|
57
|
+
this.stepInfo = stepInfo;
|
|
58
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
62
|
+
/**
|
|
63
|
+
* @param message error message to be displayed
|
|
64
|
+
*/
|
|
65
|
+
constructor(message) {
|
|
66
|
+
super("fail", void 0, false);
|
|
67
|
+
this.name = "WorkflowNonRetryableError";
|
|
68
|
+
if (message) this.message = message;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
72
|
+
retryAfter;
|
|
73
|
+
/**
|
|
74
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
75
|
+
* @param message error message to be displayed
|
|
76
|
+
*/
|
|
77
|
+
constructor(message, retryAfter) {
|
|
78
|
+
super("retry", void 0, false);
|
|
79
|
+
this.name = "WorkflowRetryAfterError";
|
|
80
|
+
this.retryAfter = retryAfter;
|
|
81
|
+
if (message) this.message = message;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var formatWorkflowError = (error) => {
|
|
85
|
+
return error instanceof Error ? {
|
|
86
|
+
error: error.name,
|
|
87
|
+
message: error.message,
|
|
88
|
+
stack: error.stack
|
|
89
|
+
} : {
|
|
90
|
+
error: "Error",
|
|
91
|
+
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
function getConstructorName(obj) {
|
|
95
|
+
if (obj === null || obj === void 0) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const ctor = obj.constructor;
|
|
99
|
+
if (!ctor || ctor.name === "Object") {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return ctor.name;
|
|
103
|
+
}
|
|
104
|
+
function getConstructorNames(obj) {
|
|
105
|
+
const proto = Object.getPrototypeOf(obj);
|
|
106
|
+
const name = getConstructorName(proto);
|
|
107
|
+
if (name === null) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
return [name, ...getConstructorNames(proto)];
|
|
111
|
+
}
|
|
112
|
+
function isInstanceOf(v, ctor) {
|
|
113
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/client/utils.ts
|
|
29
117
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
30
118
|
const result = await requester.request({
|
|
31
119
|
path: ["v2", "notify", eventId],
|
|
@@ -65,7 +153,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
65
153
|
return { steps: filteredSteps, workflowRunEnded: false };
|
|
66
154
|
}
|
|
67
155
|
} catch (error) {
|
|
68
|
-
if (error
|
|
156
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
69
157
|
await debug?.log("WARN", "ENDPOINT_START", {
|
|
70
158
|
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
71
159
|
error
|
|
@@ -90,65 +178,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
90
178
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
91
179
|
var NO_CONCURRENCY = 1;
|
|
92
180
|
var DEFAULT_RETRIES = 3;
|
|
93
|
-
var VERSION = "v0.2.
|
|
181
|
+
var VERSION = "v0.2.22";
|
|
94
182
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
95
183
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
96
184
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
97
185
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
98
186
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
99
187
|
|
|
100
|
-
// src/error.ts
|
|
101
|
-
var import_qstash2 = require("@upstash/qstash");
|
|
102
|
-
var WorkflowError = class extends import_qstash2.QstashError {
|
|
103
|
-
constructor(message) {
|
|
104
|
-
super(message);
|
|
105
|
-
this.name = "WorkflowError";
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
var WorkflowAbort = class extends Error {
|
|
109
|
-
stepInfo;
|
|
110
|
-
stepName;
|
|
111
|
-
/**
|
|
112
|
-
* whether workflow is to be canceled on abort
|
|
113
|
-
*/
|
|
114
|
-
cancelWorkflow;
|
|
115
|
-
/**
|
|
116
|
-
*
|
|
117
|
-
* @param stepName name of the aborting step
|
|
118
|
-
* @param stepInfo step information
|
|
119
|
-
* @param cancelWorkflow
|
|
120
|
-
*/
|
|
121
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
122
|
-
super(
|
|
123
|
-
`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}'.`
|
|
124
|
-
);
|
|
125
|
-
this.name = "WorkflowAbort";
|
|
126
|
-
this.stepName = stepName;
|
|
127
|
-
this.stepInfo = stepInfo;
|
|
128
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
132
|
-
/**
|
|
133
|
-
* @param message error message to be displayed
|
|
134
|
-
*/
|
|
135
|
-
constructor(message) {
|
|
136
|
-
super("fail", void 0, false);
|
|
137
|
-
this.name = "WorkflowNonRetryableError";
|
|
138
|
-
if (message) this.message = message;
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
var formatWorkflowError = (error) => {
|
|
142
|
-
return error instanceof Error ? {
|
|
143
|
-
error: error.name,
|
|
144
|
-
message: error.message,
|
|
145
|
-
stack: error.stack
|
|
146
|
-
} : {
|
|
147
|
-
error: "Error",
|
|
148
|
-
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
149
|
-
};
|
|
150
|
-
};
|
|
151
|
-
|
|
152
188
|
// src/context/auto-executor.ts
|
|
153
189
|
var import_qstash5 = require("@upstash/qstash");
|
|
154
190
|
|
|
@@ -161,8 +197,8 @@ var NANOID_LENGTH = 21;
|
|
|
161
197
|
function getRandomInt() {
|
|
162
198
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
163
199
|
}
|
|
164
|
-
function nanoid() {
|
|
165
|
-
return Array.from({ length
|
|
200
|
+
function nanoid(length = NANOID_LENGTH) {
|
|
201
|
+
return Array.from({ length }).map(() => NANOID_CHARS[getRandomInt()]).join("");
|
|
166
202
|
}
|
|
167
203
|
function getWorkflowRunId(id) {
|
|
168
204
|
return `wfr_${id ?? nanoid()}`;
|
|
@@ -179,6 +215,37 @@ function decodeBase64(base64) {
|
|
|
179
215
|
return binString;
|
|
180
216
|
}
|
|
181
217
|
}
|
|
218
|
+
function getUserIdFromToken(qstashClient) {
|
|
219
|
+
try {
|
|
220
|
+
const token = qstashClient.token;
|
|
221
|
+
const decodedToken = decodeBase64(token);
|
|
222
|
+
const tokenPayload = JSON.parse(decodedToken);
|
|
223
|
+
const userId = tokenPayload.UserID;
|
|
224
|
+
if (!userId) {
|
|
225
|
+
throw new WorkflowError("QStash token payload does not contain userId");
|
|
226
|
+
}
|
|
227
|
+
return userId;
|
|
228
|
+
} catch (error) {
|
|
229
|
+
throw new WorkflowError(
|
|
230
|
+
`Failed to decode QStash token while running create webhook step: ${error.message}`
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function getQStashUrl(qstashClient) {
|
|
235
|
+
try {
|
|
236
|
+
const requester = qstashClient.http;
|
|
237
|
+
const baseUrl = requester.baseUrl;
|
|
238
|
+
if (!baseUrl) {
|
|
239
|
+
throw new WorkflowError("QStash client does not have a baseUrl");
|
|
240
|
+
}
|
|
241
|
+
return baseUrl;
|
|
242
|
+
} catch (error) {
|
|
243
|
+
throw new WorkflowError(`Failed to get QStash URL from client: ${error.message}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function getEventId() {
|
|
247
|
+
return `evt_${nanoid(15)}`;
|
|
248
|
+
}
|
|
182
249
|
|
|
183
250
|
// node_modules/neverthrow/dist/index.es.js
|
|
184
251
|
var defaultErrorConfig = {
|
|
@@ -604,7 +671,9 @@ var StepTypes = [
|
|
|
604
671
|
"Call",
|
|
605
672
|
"Wait",
|
|
606
673
|
"Notify",
|
|
607
|
-
"Invoke"
|
|
674
|
+
"Invoke",
|
|
675
|
+
"CreateWebhook",
|
|
676
|
+
"WaitForWebhook"
|
|
608
677
|
];
|
|
609
678
|
|
|
610
679
|
// src/workflow-requests.ts
|
|
@@ -708,17 +777,17 @@ var triggerRouteFunction = async ({
|
|
|
708
777
|
return ok("workflow-finished");
|
|
709
778
|
} catch (error) {
|
|
710
779
|
const error_ = error;
|
|
711
|
-
if (error
|
|
780
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
712
781
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
713
782
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
714
783
|
name: error.name,
|
|
715
784
|
errorMessage: error.message
|
|
716
785
|
});
|
|
717
786
|
return ok("workflow-was-finished");
|
|
718
|
-
} else if (
|
|
719
|
-
return err(error_);
|
|
720
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
787
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
721
788
|
return ok(error_);
|
|
789
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
790
|
+
return err(error_);
|
|
722
791
|
} else if (error_.cancelWorkflow) {
|
|
723
792
|
await onCancel();
|
|
724
793
|
return ok("workflow-finished");
|
|
@@ -916,7 +985,9 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
916
985
|
// src/context/steps.ts
|
|
917
986
|
var BaseLazyStep = class _BaseLazyStep {
|
|
918
987
|
stepName;
|
|
919
|
-
|
|
988
|
+
context;
|
|
989
|
+
constructor(context, stepName) {
|
|
990
|
+
this.context = context;
|
|
920
991
|
if (!stepName) {
|
|
921
992
|
throw new WorkflowError(
|
|
922
993
|
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
@@ -934,13 +1005,14 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
934
1005
|
*
|
|
935
1006
|
* will be called when returning the steps to the context from auto executor
|
|
936
1007
|
*
|
|
937
|
-
* @param
|
|
1008
|
+
* @param step step
|
|
938
1009
|
* @returns parsed out field
|
|
939
1010
|
*/
|
|
940
|
-
parseOut(
|
|
1011
|
+
parseOut(step) {
|
|
1012
|
+
const out = step.out;
|
|
941
1013
|
if (out === void 0) {
|
|
942
1014
|
if (this.allowUndefinedOut) {
|
|
943
|
-
return
|
|
1015
|
+
return this.handleUndefinedOut(step);
|
|
944
1016
|
} else {
|
|
945
1017
|
throw new WorkflowError(
|
|
946
1018
|
`Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
|
|
@@ -948,27 +1020,26 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
948
1020
|
}
|
|
949
1021
|
}
|
|
950
1022
|
if (typeof out === "object") {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
return out;
|
|
956
|
-
}
|
|
957
|
-
return {
|
|
958
|
-
...out,
|
|
959
|
-
eventData: _BaseLazyStep.tryParsing(out.eventData)
|
|
960
|
-
};
|
|
1023
|
+
console.warn(
|
|
1024
|
+
`Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
|
|
1025
|
+
);
|
|
1026
|
+
return out;
|
|
961
1027
|
}
|
|
962
1028
|
if (typeof out !== "string") {
|
|
963
1029
|
throw new WorkflowError(
|
|
964
1030
|
`Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
|
|
965
1031
|
);
|
|
966
1032
|
}
|
|
967
|
-
return this.safeParseOut(out);
|
|
1033
|
+
return this.safeParseOut(out, step);
|
|
968
1034
|
}
|
|
969
|
-
|
|
1035
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1036
|
+
safeParseOut(out, step) {
|
|
970
1037
|
return _BaseLazyStep.tryParsing(out);
|
|
971
1038
|
}
|
|
1039
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1040
|
+
handleUndefinedOut(step) {
|
|
1041
|
+
return void 0;
|
|
1042
|
+
}
|
|
972
1043
|
static tryParsing(stepOut) {
|
|
973
1044
|
try {
|
|
974
1045
|
return JSON.parse(stepOut);
|
|
@@ -1019,8 +1090,8 @@ var LazyFunctionStep = class extends BaseLazyStep {
|
|
|
1019
1090
|
stepFunction;
|
|
1020
1091
|
stepType = "Run";
|
|
1021
1092
|
allowUndefinedOut = true;
|
|
1022
|
-
constructor(stepName, stepFunction) {
|
|
1023
|
-
super(stepName);
|
|
1093
|
+
constructor(context, stepName, stepFunction) {
|
|
1094
|
+
super(context, stepName);
|
|
1024
1095
|
this.stepFunction = stepFunction;
|
|
1025
1096
|
}
|
|
1026
1097
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1050,8 +1121,8 @@ var LazySleepStep = class extends BaseLazyStep {
|
|
|
1050
1121
|
sleep;
|
|
1051
1122
|
stepType = "SleepFor";
|
|
1052
1123
|
allowUndefinedOut = true;
|
|
1053
|
-
constructor(stepName, sleep) {
|
|
1054
|
-
super(stepName);
|
|
1124
|
+
constructor(context, stepName, sleep) {
|
|
1125
|
+
super(context, stepName);
|
|
1055
1126
|
this.sleep = sleep;
|
|
1056
1127
|
}
|
|
1057
1128
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1092,8 +1163,8 @@ var LazySleepUntilStep = class extends BaseLazyStep {
|
|
|
1092
1163
|
sleepUntil;
|
|
1093
1164
|
stepType = "SleepUntil";
|
|
1094
1165
|
allowUndefinedOut = true;
|
|
1095
|
-
constructor(stepName, sleepUntil) {
|
|
1096
|
-
super(stepName);
|
|
1166
|
+
constructor(context, stepName, sleepUntil) {
|
|
1167
|
+
super(context, stepName);
|
|
1097
1168
|
this.sleepUntil = sleepUntil;
|
|
1098
1169
|
}
|
|
1099
1170
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1145,8 +1216,8 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1145
1216
|
stringifyBody;
|
|
1146
1217
|
stepType = "Call";
|
|
1147
1218
|
allowUndefinedOut = false;
|
|
1148
|
-
constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1149
|
-
super(stepName);
|
|
1219
|
+
constructor(context, stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1220
|
+
super(context, stepName);
|
|
1150
1221
|
this.url = url;
|
|
1151
1222
|
this.method = method;
|
|
1152
1223
|
this.body = body;
|
|
@@ -1290,13 +1361,12 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1290
1361
|
]);
|
|
1291
1362
|
}
|
|
1292
1363
|
};
|
|
1293
|
-
var
|
|
1364
|
+
var LazyWaitEventStep = class extends BaseLazyStep {
|
|
1294
1365
|
eventId;
|
|
1295
1366
|
timeout;
|
|
1296
|
-
stepType = "Wait";
|
|
1297
1367
|
allowUndefinedOut = false;
|
|
1298
|
-
constructor(stepName, eventId, timeout) {
|
|
1299
|
-
super(stepName);
|
|
1368
|
+
constructor(context, stepName, eventId, timeout) {
|
|
1369
|
+
super(context, stepName);
|
|
1300
1370
|
this.eventId = eventId;
|
|
1301
1371
|
this.timeout = timeout;
|
|
1302
1372
|
}
|
|
@@ -1321,13 +1391,6 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1321
1391
|
concurrent
|
|
1322
1392
|
});
|
|
1323
1393
|
}
|
|
1324
|
-
safeParseOut(out) {
|
|
1325
|
-
const result = JSON.parse(out);
|
|
1326
|
-
return {
|
|
1327
|
-
...result,
|
|
1328
|
-
eventData: BaseLazyStep.tryParsing(result.eventData)
|
|
1329
|
-
};
|
|
1330
|
-
}
|
|
1331
1394
|
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1332
1395
|
const headers = super.getHeaders({ context, telemetry, invokeCount, step });
|
|
1333
1396
|
headers.headers["Upstash-Workflow-CallType"] = "step";
|
|
@@ -1361,7 +1424,7 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1361
1424
|
timeoutHeaders,
|
|
1362
1425
|
step: {
|
|
1363
1426
|
stepId: step.stepId,
|
|
1364
|
-
stepType:
|
|
1427
|
+
stepType: this.stepType,
|
|
1365
1428
|
stepName: step.stepName,
|
|
1366
1429
|
concurrent: step.concurrent,
|
|
1367
1430
|
targetStep: step.targetStep
|
|
@@ -1382,8 +1445,8 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1382
1445
|
};
|
|
1383
1446
|
var LazyNotifyStep = class extends LazyFunctionStep {
|
|
1384
1447
|
stepType = "Notify";
|
|
1385
|
-
constructor(stepName, eventId, eventData, requester) {
|
|
1386
|
-
super(stepName, async () => {
|
|
1448
|
+
constructor(context, stepName, eventId, eventData, requester) {
|
|
1449
|
+
super(context, stepName, async () => {
|
|
1387
1450
|
const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
|
|
1388
1451
|
return {
|
|
1389
1452
|
eventId,
|
|
@@ -1408,7 +1471,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1408
1471
|
* workflow id of the invoked workflow
|
|
1409
1472
|
*/
|
|
1410
1473
|
workflowId;
|
|
1411
|
-
constructor(stepName, {
|
|
1474
|
+
constructor(context, stepName, {
|
|
1412
1475
|
workflow,
|
|
1413
1476
|
body,
|
|
1414
1477
|
headers = {},
|
|
@@ -1418,7 +1481,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1418
1481
|
flowControl,
|
|
1419
1482
|
stringifyBody = true
|
|
1420
1483
|
}) {
|
|
1421
|
-
super(stepName);
|
|
1484
|
+
super(context, stepName);
|
|
1422
1485
|
this.params = {
|
|
1423
1486
|
workflow,
|
|
1424
1487
|
body,
|
|
@@ -1479,6 +1542,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1479
1542
|
userHeaders: context.headers,
|
|
1480
1543
|
invokeCount
|
|
1481
1544
|
});
|
|
1545
|
+
context.qstashClient.http.headers?.forEach((value, key) => {
|
|
1546
|
+
invokerHeaders[key] = value;
|
|
1547
|
+
});
|
|
1482
1548
|
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1483
1549
|
let invokeBody;
|
|
1484
1550
|
if (this.params.stringifyBody) {
|
|
@@ -1550,6 +1616,91 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1550
1616
|
return [result];
|
|
1551
1617
|
}
|
|
1552
1618
|
};
|
|
1619
|
+
var LazyCreateWebhookStep = class extends BaseLazyStep {
|
|
1620
|
+
stepType = "CreateWebhook";
|
|
1621
|
+
allowUndefinedOut = false;
|
|
1622
|
+
getPlanStep(concurrent, targetStep) {
|
|
1623
|
+
return {
|
|
1624
|
+
stepId: 0,
|
|
1625
|
+
stepName: this.stepName,
|
|
1626
|
+
stepType: this.stepType,
|
|
1627
|
+
concurrent,
|
|
1628
|
+
targetStep
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
async getResultStep(concurrent, stepId) {
|
|
1632
|
+
return {
|
|
1633
|
+
stepId,
|
|
1634
|
+
stepName: this.stepName,
|
|
1635
|
+
stepType: this.stepType,
|
|
1636
|
+
out: void 0,
|
|
1637
|
+
concurrent
|
|
1638
|
+
};
|
|
1639
|
+
}
|
|
1640
|
+
getBody({ step, context }) {
|
|
1641
|
+
const userId = getUserIdFromToken(context.qstashClient);
|
|
1642
|
+
const out = [userId, context.workflowRunId, getEventId()].join("/");
|
|
1643
|
+
return JSON.stringify({
|
|
1644
|
+
...step,
|
|
1645
|
+
out
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
safeParseOut(out) {
|
|
1649
|
+
const [userId, workflowRunId, eventId] = out.split("/");
|
|
1650
|
+
const qstashUrl = getQStashUrl(this.context.qstashClient);
|
|
1651
|
+
return {
|
|
1652
|
+
webhookUrl: `${qstashUrl}/v2/workflows/hooks/${userId}/${workflowRunId}/${eventId}`,
|
|
1653
|
+
eventId
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
};
|
|
1657
|
+
var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
|
|
1658
|
+
stepType = "WaitForWebhook";
|
|
1659
|
+
allowUndefinedOut = true;
|
|
1660
|
+
constructor(context, stepName, webhook, timeout) {
|
|
1661
|
+
super(context, stepName, webhook.eventId, timeout);
|
|
1662
|
+
}
|
|
1663
|
+
safeParseOut(out) {
|
|
1664
|
+
const eventData = decodeBase64(out);
|
|
1665
|
+
const parsedEventData = BaseLazyStep.tryParsing(eventData);
|
|
1666
|
+
const body = parsedEventData.body;
|
|
1667
|
+
const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
|
|
1668
|
+
const request = new Request(
|
|
1669
|
+
`${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
|
|
1670
|
+
{
|
|
1671
|
+
method: parsedEventData.method,
|
|
1672
|
+
headers: parsedEventData.header,
|
|
1673
|
+
body: parsedBody
|
|
1674
|
+
}
|
|
1675
|
+
);
|
|
1676
|
+
return {
|
|
1677
|
+
request,
|
|
1678
|
+
timeout: false
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
handleUndefinedOut() {
|
|
1682
|
+
return {
|
|
1683
|
+
timeout: true,
|
|
1684
|
+
request: void 0
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
};
|
|
1688
|
+
var LazyWaitForEventStep = class extends LazyWaitEventStep {
|
|
1689
|
+
stepType = "Wait";
|
|
1690
|
+
allowUndefinedOut = true;
|
|
1691
|
+
parseWaitForEventOut(out, waitTimeout) {
|
|
1692
|
+
return {
|
|
1693
|
+
eventData: out ? BaseLazyStep.tryParsing(decodeBase64(out)) : void 0,
|
|
1694
|
+
timeout: waitTimeout ?? false
|
|
1695
|
+
};
|
|
1696
|
+
}
|
|
1697
|
+
safeParseOut(out, step) {
|
|
1698
|
+
return this.parseWaitForEventOut(out, step.waitTimeout);
|
|
1699
|
+
}
|
|
1700
|
+
handleUndefinedOut(step) {
|
|
1701
|
+
return this.parseWaitForEventOut(void 0, step.waitTimeout);
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1553
1704
|
|
|
1554
1705
|
// src/agents/constants.ts
|
|
1555
1706
|
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
@@ -1954,7 +2105,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1954
2105
|
step,
|
|
1955
2106
|
stepCount: this.stepCount
|
|
1956
2107
|
});
|
|
1957
|
-
return lazyStep.parseOut(step
|
|
2108
|
+
return lazyStep.parseOut(step);
|
|
1958
2109
|
}
|
|
1959
2110
|
const resultStep = await submitSingleStep({
|
|
1960
2111
|
context: this.context,
|
|
@@ -2025,7 +2176,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2025
2176
|
});
|
|
2026
2177
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2027
2178
|
} catch (error) {
|
|
2028
|
-
if (error
|
|
2179
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2029
2180
|
throw error;
|
|
2030
2181
|
}
|
|
2031
2182
|
throw new WorkflowError(
|
|
@@ -2041,7 +2192,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2041
2192
|
const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
|
|
2042
2193
|
validateParallelSteps(parallelSteps, parallelResultSteps);
|
|
2043
2194
|
return parallelResultSteps.map(
|
|
2044
|
-
(step, index) => parallelSteps[index].parseOut(step
|
|
2195
|
+
(step, index) => parallelSteps[index].parseOut(step)
|
|
2045
2196
|
);
|
|
2046
2197
|
}
|
|
2047
2198
|
}
|
|
@@ -2097,7 +2248,6 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2097
2248
|
* @param index index of the current step
|
|
2098
2249
|
* @returns result[index] if lazyStepList > 1, otherwise result
|
|
2099
2250
|
*/
|
|
2100
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2101
2251
|
static getResult(lazyStepList, result, index) {
|
|
2102
2252
|
if (lazyStepList.length === 1) {
|
|
2103
2253
|
return result;
|
|
@@ -2132,7 +2282,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2132
2282
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2133
2283
|
}
|
|
2134
2284
|
} catch (error) {
|
|
2135
|
-
if (error
|
|
2285
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2136
2286
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2137
2287
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2138
2288
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2313,7 +2463,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2313
2463
|
headers: responseHeaders
|
|
2314
2464
|
});
|
|
2315
2465
|
} catch (error) {
|
|
2316
|
-
if (error instanceof Error && error
|
|
2466
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2317
2467
|
throw error;
|
|
2318
2468
|
} else {
|
|
2319
2469
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2415,10 +2565,10 @@ var Agent = class {
|
|
|
2415
2565
|
});
|
|
2416
2566
|
return { text: result.text };
|
|
2417
2567
|
} catch (error) {
|
|
2418
|
-
if (error
|
|
2419
|
-
if (error.cause instanceof Error && error.cause
|
|
2568
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2569
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2420
2570
|
throw error.cause;
|
|
2421
|
-
} else if (error.cause
|
|
2571
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2422
2572
|
throw error.cause.cause;
|
|
2423
2573
|
} else {
|
|
2424
2574
|
throw error;
|
|
@@ -2822,7 +2972,7 @@ var WorkflowContext = class {
|
|
|
2822
2972
|
*/
|
|
2823
2973
|
async run(stepName, stepFunction) {
|
|
2824
2974
|
const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
|
|
2825
|
-
return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
|
|
2975
|
+
return await this.addStep(new LazyFunctionStep(this, stepName, wrappedStepFunction));
|
|
2826
2976
|
}
|
|
2827
2977
|
/**
|
|
2828
2978
|
* Stops the execution for the duration provided.
|
|
@@ -2836,7 +2986,7 @@ var WorkflowContext = class {
|
|
|
2836
2986
|
* @returns undefined
|
|
2837
2987
|
*/
|
|
2838
2988
|
async sleep(stepName, duration) {
|
|
2839
|
-
await this.addStep(new LazySleepStep(stepName, duration));
|
|
2989
|
+
await this.addStep(new LazySleepStep(this, stepName, duration));
|
|
2840
2990
|
}
|
|
2841
2991
|
/**
|
|
2842
2992
|
* Stops the execution until the date time provided.
|
|
@@ -2858,13 +3008,14 @@ var WorkflowContext = class {
|
|
|
2858
3008
|
datetime = typeof datetime === "string" ? new Date(datetime) : datetime;
|
|
2859
3009
|
time = Math.round(datetime.getTime() / 1e3);
|
|
2860
3010
|
}
|
|
2861
|
-
await this.addStep(new LazySleepUntilStep(stepName, time));
|
|
3011
|
+
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
2862
3012
|
}
|
|
2863
3013
|
async call(stepName, settings) {
|
|
2864
3014
|
let callStep;
|
|
2865
3015
|
if ("workflow" in settings) {
|
|
2866
3016
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2867
3017
|
callStep = new LazyCallStep(
|
|
3018
|
+
this,
|
|
2868
3019
|
stepName,
|
|
2869
3020
|
url,
|
|
2870
3021
|
"POST",
|
|
@@ -2889,6 +3040,7 @@ var WorkflowContext = class {
|
|
|
2889
3040
|
stringifyBody = true
|
|
2890
3041
|
} = settings;
|
|
2891
3042
|
callStep = new LazyCallStep(
|
|
3043
|
+
this,
|
|
2892
3044
|
stepName,
|
|
2893
3045
|
url,
|
|
2894
3046
|
method,
|
|
@@ -2940,7 +3092,9 @@ var WorkflowContext = class {
|
|
|
2940
3092
|
async waitForEvent(stepName, eventId, options = {}) {
|
|
2941
3093
|
const { timeout = "7d" } = options;
|
|
2942
3094
|
const timeoutStr = typeof timeout === "string" ? timeout : `${timeout}s`;
|
|
2943
|
-
return await this.addStep(
|
|
3095
|
+
return await this.addStep(
|
|
3096
|
+
new LazyWaitForEventStep(this, stepName, eventId, timeoutStr)
|
|
3097
|
+
);
|
|
2944
3098
|
}
|
|
2945
3099
|
/**
|
|
2946
3100
|
* Notify workflow runs waiting for an event
|
|
@@ -2965,11 +3119,19 @@ var WorkflowContext = class {
|
|
|
2965
3119
|
*/
|
|
2966
3120
|
async notify(stepName, eventId, eventData) {
|
|
2967
3121
|
return await this.addStep(
|
|
2968
|
-
new LazyNotifyStep(stepName, eventId, eventData, this.qstashClient.http)
|
|
3122
|
+
new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
|
|
2969
3123
|
);
|
|
2970
3124
|
}
|
|
2971
3125
|
async invoke(stepName, settings) {
|
|
2972
|
-
return await this.addStep(
|
|
3126
|
+
return await this.addStep(
|
|
3127
|
+
new LazyInvokeStep(this, stepName, settings)
|
|
3128
|
+
);
|
|
3129
|
+
}
|
|
3130
|
+
async createWebhook(stepName) {
|
|
3131
|
+
return await this.addStep(new LazyCreateWebhookStep(this, stepName));
|
|
3132
|
+
}
|
|
3133
|
+
async waitForWebhook(stepName, webhook, timeout) {
|
|
3134
|
+
return await this.addStep(new LazyWaitForWebhookStep(this, stepName, webhook, timeout));
|
|
2973
3135
|
}
|
|
2974
3136
|
/**
|
|
2975
3137
|
* Cancel the current workflow run
|
|
@@ -3100,7 +3262,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3100
3262
|
try {
|
|
3101
3263
|
await routeFunction(disabledContext);
|
|
3102
3264
|
} catch (error) {
|
|
3103
|
-
if (error
|
|
3265
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3104
3266
|
return ok("step-found");
|
|
3105
3267
|
}
|
|
3106
3268
|
console.warn(
|
|
@@ -3133,13 +3295,6 @@ var processRawSteps = (rawSteps) => {
|
|
|
3133
3295
|
const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
|
|
3134
3296
|
const otherSteps = stepsToDecode.map((rawStep) => {
|
|
3135
3297
|
const step = JSON.parse(decodeBase64(rawStep.body));
|
|
3136
|
-
if (step.waitEventId) {
|
|
3137
|
-
const newOut = {
|
|
3138
|
-
eventData: step.out ? decodeBase64(step.out) : void 0,
|
|
3139
|
-
timeout: step.waitTimeout ?? false
|
|
3140
|
-
};
|
|
3141
|
-
step.out = newOut;
|
|
3142
|
-
}
|
|
3143
3298
|
return step;
|
|
3144
3299
|
});
|
|
3145
3300
|
const steps = [initialStep, ...otherSteps];
|
|
@@ -3353,13 +3508,24 @@ var processOptions = (options) => {
|
|
|
3353
3508
|
},
|
|
3354
3509
|
status: 489
|
|
3355
3510
|
});
|
|
3356
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3357
|
-
return new Response(detailedFinishCondition.result
|
|
3358
|
-
status: 200,
|
|
3511
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3512
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3359
3513
|
headers: {
|
|
3514
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3360
3515
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3361
|
-
}
|
|
3516
|
+
},
|
|
3517
|
+
status: 429
|
|
3362
3518
|
});
|
|
3519
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3520
|
+
return new Response(
|
|
3521
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3522
|
+
{
|
|
3523
|
+
status: 200,
|
|
3524
|
+
headers: {
|
|
3525
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
);
|
|
3363
3529
|
}
|
|
3364
3530
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3365
3531
|
status: 200,
|
|
@@ -3569,12 +3735,18 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3569
3735
|
},
|
|
3570
3736
|
debug
|
|
3571
3737
|
});
|
|
3572
|
-
if (result.isOk() && result.value
|
|
3738
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3573
3739
|
return onStepFinish(workflowRunId, result.value, {
|
|
3574
3740
|
condition: "non-retryable-error",
|
|
3575
3741
|
result: result.value
|
|
3576
3742
|
});
|
|
3577
3743
|
}
|
|
3744
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3745
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3746
|
+
condition: "retry-after-error",
|
|
3747
|
+
result: result.value
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3578
3750
|
if (result.isErr()) {
|
|
3579
3751
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3580
3752
|
throw result.error;
|
|
@@ -3605,7 +3777,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3605
3777
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3606
3778
|
Original error: '${formattedError.message}'`;
|
|
3607
3779
|
console.error(errorMessage);
|
|
3608
|
-
return new Response(errorMessage, {
|
|
3780
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3609
3781
|
status: 500,
|
|
3610
3782
|
headers: {
|
|
3611
3783
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|