@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/cloudflare.js
CHANGED
|
@@ -39,7 +39,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
39
39
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
40
40
|
var NO_CONCURRENCY = 1;
|
|
41
41
|
var DEFAULT_RETRIES = 3;
|
|
42
|
-
var VERSION = "v0.2.
|
|
42
|
+
var VERSION = "v0.2.22";
|
|
43
43
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
44
44
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
45
45
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
@@ -47,61 +47,11 @@ var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
|
47
47
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
48
48
|
|
|
49
49
|
// src/client/utils.ts
|
|
50
|
-
var
|
|
51
|
-
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
52
|
-
const result = await requester.request({
|
|
53
|
-
path: ["v2", "notify", eventId],
|
|
54
|
-
method: "POST",
|
|
55
|
-
body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
|
|
56
|
-
});
|
|
57
|
-
return result;
|
|
58
|
-
};
|
|
59
|
-
var makeCancelRequest = async (requester, workflowRunId) => {
|
|
60
|
-
await requester.request({
|
|
61
|
-
path: ["v2", "workflows", "runs", `${workflowRunId}?cancel=true`],
|
|
62
|
-
method: "DELETE",
|
|
63
|
-
parseResponseAsJson: false
|
|
64
|
-
});
|
|
65
|
-
return true;
|
|
66
|
-
};
|
|
67
|
-
var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
68
|
-
try {
|
|
69
|
-
const steps = await requester.request({
|
|
70
|
-
path: ["v2", "workflows", "runs", workflowRunId],
|
|
71
|
-
parseResponseAsJson: true
|
|
72
|
-
});
|
|
73
|
-
if (!messageId) {
|
|
74
|
-
await debug?.log("INFO", "ENDPOINT_START", {
|
|
75
|
-
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
76
|
-
});
|
|
77
|
-
return { steps, workflowRunEnded: false };
|
|
78
|
-
} else {
|
|
79
|
-
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
80
|
-
if (index === -1) {
|
|
81
|
-
return { steps: [], workflowRunEnded: false };
|
|
82
|
-
}
|
|
83
|
-
const filteredSteps = steps.slice(0, index + 1);
|
|
84
|
-
await debug?.log("INFO", "ENDPOINT_START", {
|
|
85
|
-
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
86
|
-
});
|
|
87
|
-
return { steps: filteredSteps, workflowRunEnded: false };
|
|
88
|
-
}
|
|
89
|
-
} catch (error) {
|
|
90
|
-
if (error instanceof import_qstash.QstashError && error.status === 404) {
|
|
91
|
-
await debug?.log("WARN", "ENDPOINT_START", {
|
|
92
|
-
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
93
|
-
error
|
|
94
|
-
});
|
|
95
|
-
return { steps: void 0, workflowRunEnded: true };
|
|
96
|
-
} else {
|
|
97
|
-
throw error;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
50
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
101
51
|
|
|
102
52
|
// src/error.ts
|
|
103
|
-
var
|
|
104
|
-
var WorkflowError = class extends
|
|
53
|
+
var import_qstash = require("@upstash/qstash");
|
|
54
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
105
55
|
constructor(message) {
|
|
106
56
|
super(message);
|
|
107
57
|
this.name = "WorkflowError";
|
|
@@ -140,6 +90,19 @@ var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
|
140
90
|
if (message) this.message = message;
|
|
141
91
|
}
|
|
142
92
|
};
|
|
93
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
94
|
+
retryAfter;
|
|
95
|
+
/**
|
|
96
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
97
|
+
* @param message error message to be displayed
|
|
98
|
+
*/
|
|
99
|
+
constructor(message, retryAfter) {
|
|
100
|
+
super("retry", void 0, false);
|
|
101
|
+
this.name = "WorkflowRetryAfterError";
|
|
102
|
+
this.retryAfter = retryAfter;
|
|
103
|
+
if (message) this.message = message;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
143
106
|
var formatWorkflowError = (error) => {
|
|
144
107
|
return error instanceof Error ? {
|
|
145
108
|
error: error.name,
|
|
@@ -150,6 +113,79 @@ var formatWorkflowError = (error) => {
|
|
|
150
113
|
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
151
114
|
};
|
|
152
115
|
};
|
|
116
|
+
function getConstructorName(obj) {
|
|
117
|
+
if (obj === null || obj === void 0) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const ctor = obj.constructor;
|
|
121
|
+
if (!ctor || ctor.name === "Object") {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return ctor.name;
|
|
125
|
+
}
|
|
126
|
+
function getConstructorNames(obj) {
|
|
127
|
+
const proto = Object.getPrototypeOf(obj);
|
|
128
|
+
const name = getConstructorName(proto);
|
|
129
|
+
if (name === null) {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
return [name, ...getConstructorNames(proto)];
|
|
133
|
+
}
|
|
134
|
+
function isInstanceOf(v, ctor) {
|
|
135
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/client/utils.ts
|
|
139
|
+
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
140
|
+
const result = await requester.request({
|
|
141
|
+
path: ["v2", "notify", eventId],
|
|
142
|
+
method: "POST",
|
|
143
|
+
body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
|
|
144
|
+
});
|
|
145
|
+
return result;
|
|
146
|
+
};
|
|
147
|
+
var makeCancelRequest = async (requester, workflowRunId) => {
|
|
148
|
+
await requester.request({
|
|
149
|
+
path: ["v2", "workflows", "runs", `${workflowRunId}?cancel=true`],
|
|
150
|
+
method: "DELETE",
|
|
151
|
+
parseResponseAsJson: false
|
|
152
|
+
});
|
|
153
|
+
return true;
|
|
154
|
+
};
|
|
155
|
+
var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
156
|
+
try {
|
|
157
|
+
const steps = await requester.request({
|
|
158
|
+
path: ["v2", "workflows", "runs", workflowRunId],
|
|
159
|
+
parseResponseAsJson: true
|
|
160
|
+
});
|
|
161
|
+
if (!messageId) {
|
|
162
|
+
await debug?.log("INFO", "ENDPOINT_START", {
|
|
163
|
+
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
164
|
+
});
|
|
165
|
+
return { steps, workflowRunEnded: false };
|
|
166
|
+
} else {
|
|
167
|
+
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
168
|
+
if (index === -1) {
|
|
169
|
+
return { steps: [], workflowRunEnded: false };
|
|
170
|
+
}
|
|
171
|
+
const filteredSteps = steps.slice(0, index + 1);
|
|
172
|
+
await debug?.log("INFO", "ENDPOINT_START", {
|
|
173
|
+
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
174
|
+
});
|
|
175
|
+
return { steps: filteredSteps, workflowRunEnded: false };
|
|
176
|
+
}
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
179
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
180
|
+
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
181
|
+
error
|
|
182
|
+
});
|
|
183
|
+
return { steps: void 0, workflowRunEnded: true };
|
|
184
|
+
} else {
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
153
189
|
|
|
154
190
|
// src/context/auto-executor.ts
|
|
155
191
|
var import_qstash5 = require("@upstash/qstash");
|
|
@@ -163,8 +199,8 @@ var NANOID_LENGTH = 21;
|
|
|
163
199
|
function getRandomInt() {
|
|
164
200
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
165
201
|
}
|
|
166
|
-
function nanoid() {
|
|
167
|
-
return Array.from({ length
|
|
202
|
+
function nanoid(length = NANOID_LENGTH) {
|
|
203
|
+
return Array.from({ length }).map(() => NANOID_CHARS[getRandomInt()]).join("");
|
|
168
204
|
}
|
|
169
205
|
function getWorkflowRunId(id) {
|
|
170
206
|
return `wfr_${id ?? nanoid()}`;
|
|
@@ -181,6 +217,37 @@ function decodeBase64(base64) {
|
|
|
181
217
|
return binString;
|
|
182
218
|
}
|
|
183
219
|
}
|
|
220
|
+
function getUserIdFromToken(qstashClient) {
|
|
221
|
+
try {
|
|
222
|
+
const token = qstashClient.token;
|
|
223
|
+
const decodedToken = decodeBase64(token);
|
|
224
|
+
const tokenPayload = JSON.parse(decodedToken);
|
|
225
|
+
const userId = tokenPayload.UserID;
|
|
226
|
+
if (!userId) {
|
|
227
|
+
throw new WorkflowError("QStash token payload does not contain userId");
|
|
228
|
+
}
|
|
229
|
+
return userId;
|
|
230
|
+
} catch (error) {
|
|
231
|
+
throw new WorkflowError(
|
|
232
|
+
`Failed to decode QStash token while running create webhook step: ${error.message}`
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function getQStashUrl(qstashClient) {
|
|
237
|
+
try {
|
|
238
|
+
const requester = qstashClient.http;
|
|
239
|
+
const baseUrl = requester.baseUrl;
|
|
240
|
+
if (!baseUrl) {
|
|
241
|
+
throw new WorkflowError("QStash client does not have a baseUrl");
|
|
242
|
+
}
|
|
243
|
+
return baseUrl;
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw new WorkflowError(`Failed to get QStash URL from client: ${error.message}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function getEventId() {
|
|
249
|
+
return `evt_${nanoid(15)}`;
|
|
250
|
+
}
|
|
184
251
|
|
|
185
252
|
// node_modules/neverthrow/dist/index.es.js
|
|
186
253
|
var defaultErrorConfig = {
|
|
@@ -606,7 +673,9 @@ var StepTypes = [
|
|
|
606
673
|
"Call",
|
|
607
674
|
"Wait",
|
|
608
675
|
"Notify",
|
|
609
|
-
"Invoke"
|
|
676
|
+
"Invoke",
|
|
677
|
+
"CreateWebhook",
|
|
678
|
+
"WaitForWebhook"
|
|
610
679
|
];
|
|
611
680
|
|
|
612
681
|
// src/workflow-requests.ts
|
|
@@ -710,17 +779,17 @@ var triggerRouteFunction = async ({
|
|
|
710
779
|
return ok("workflow-finished");
|
|
711
780
|
} catch (error) {
|
|
712
781
|
const error_ = error;
|
|
713
|
-
if (error
|
|
782
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
714
783
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
715
784
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
716
785
|
name: error.name,
|
|
717
786
|
errorMessage: error.message
|
|
718
787
|
});
|
|
719
788
|
return ok("workflow-was-finished");
|
|
720
|
-
} else if (
|
|
721
|
-
return err(error_);
|
|
722
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
789
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
723
790
|
return ok(error_);
|
|
791
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
792
|
+
return err(error_);
|
|
724
793
|
} else if (error_.cancelWorkflow) {
|
|
725
794
|
await onCancel();
|
|
726
795
|
return ok("workflow-finished");
|
|
@@ -918,7 +987,9 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
918
987
|
// src/context/steps.ts
|
|
919
988
|
var BaseLazyStep = class _BaseLazyStep {
|
|
920
989
|
stepName;
|
|
921
|
-
|
|
990
|
+
context;
|
|
991
|
+
constructor(context, stepName) {
|
|
992
|
+
this.context = context;
|
|
922
993
|
if (!stepName) {
|
|
923
994
|
throw new WorkflowError(
|
|
924
995
|
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
@@ -936,13 +1007,14 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
936
1007
|
*
|
|
937
1008
|
* will be called when returning the steps to the context from auto executor
|
|
938
1009
|
*
|
|
939
|
-
* @param
|
|
1010
|
+
* @param step step
|
|
940
1011
|
* @returns parsed out field
|
|
941
1012
|
*/
|
|
942
|
-
parseOut(
|
|
1013
|
+
parseOut(step) {
|
|
1014
|
+
const out = step.out;
|
|
943
1015
|
if (out === void 0) {
|
|
944
1016
|
if (this.allowUndefinedOut) {
|
|
945
|
-
return
|
|
1017
|
+
return this.handleUndefinedOut(step);
|
|
946
1018
|
} else {
|
|
947
1019
|
throw new WorkflowError(
|
|
948
1020
|
`Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
|
|
@@ -950,27 +1022,26 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
950
1022
|
}
|
|
951
1023
|
}
|
|
952
1024
|
if (typeof out === "object") {
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
return out;
|
|
958
|
-
}
|
|
959
|
-
return {
|
|
960
|
-
...out,
|
|
961
|
-
eventData: _BaseLazyStep.tryParsing(out.eventData)
|
|
962
|
-
};
|
|
1025
|
+
console.warn(
|
|
1026
|
+
`Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
|
|
1027
|
+
);
|
|
1028
|
+
return out;
|
|
963
1029
|
}
|
|
964
1030
|
if (typeof out !== "string") {
|
|
965
1031
|
throw new WorkflowError(
|
|
966
1032
|
`Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
|
|
967
1033
|
);
|
|
968
1034
|
}
|
|
969
|
-
return this.safeParseOut(out);
|
|
1035
|
+
return this.safeParseOut(out, step);
|
|
970
1036
|
}
|
|
971
|
-
|
|
1037
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1038
|
+
safeParseOut(out, step) {
|
|
972
1039
|
return _BaseLazyStep.tryParsing(out);
|
|
973
1040
|
}
|
|
1041
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1042
|
+
handleUndefinedOut(step) {
|
|
1043
|
+
return void 0;
|
|
1044
|
+
}
|
|
974
1045
|
static tryParsing(stepOut) {
|
|
975
1046
|
try {
|
|
976
1047
|
return JSON.parse(stepOut);
|
|
@@ -1021,8 +1092,8 @@ var LazyFunctionStep = class extends BaseLazyStep {
|
|
|
1021
1092
|
stepFunction;
|
|
1022
1093
|
stepType = "Run";
|
|
1023
1094
|
allowUndefinedOut = true;
|
|
1024
|
-
constructor(stepName, stepFunction) {
|
|
1025
|
-
super(stepName);
|
|
1095
|
+
constructor(context, stepName, stepFunction) {
|
|
1096
|
+
super(context, stepName);
|
|
1026
1097
|
this.stepFunction = stepFunction;
|
|
1027
1098
|
}
|
|
1028
1099
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1052,8 +1123,8 @@ var LazySleepStep = class extends BaseLazyStep {
|
|
|
1052
1123
|
sleep;
|
|
1053
1124
|
stepType = "SleepFor";
|
|
1054
1125
|
allowUndefinedOut = true;
|
|
1055
|
-
constructor(stepName, sleep) {
|
|
1056
|
-
super(stepName);
|
|
1126
|
+
constructor(context, stepName, sleep) {
|
|
1127
|
+
super(context, stepName);
|
|
1057
1128
|
this.sleep = sleep;
|
|
1058
1129
|
}
|
|
1059
1130
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1094,8 +1165,8 @@ var LazySleepUntilStep = class extends BaseLazyStep {
|
|
|
1094
1165
|
sleepUntil;
|
|
1095
1166
|
stepType = "SleepUntil";
|
|
1096
1167
|
allowUndefinedOut = true;
|
|
1097
|
-
constructor(stepName, sleepUntil) {
|
|
1098
|
-
super(stepName);
|
|
1168
|
+
constructor(context, stepName, sleepUntil) {
|
|
1169
|
+
super(context, stepName);
|
|
1099
1170
|
this.sleepUntil = sleepUntil;
|
|
1100
1171
|
}
|
|
1101
1172
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1147,8 +1218,8 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1147
1218
|
stringifyBody;
|
|
1148
1219
|
stepType = "Call";
|
|
1149
1220
|
allowUndefinedOut = false;
|
|
1150
|
-
constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1151
|
-
super(stepName);
|
|
1221
|
+
constructor(context, stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1222
|
+
super(context, stepName);
|
|
1152
1223
|
this.url = url;
|
|
1153
1224
|
this.method = method;
|
|
1154
1225
|
this.body = body;
|
|
@@ -1292,13 +1363,12 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1292
1363
|
]);
|
|
1293
1364
|
}
|
|
1294
1365
|
};
|
|
1295
|
-
var
|
|
1366
|
+
var LazyWaitEventStep = class extends BaseLazyStep {
|
|
1296
1367
|
eventId;
|
|
1297
1368
|
timeout;
|
|
1298
|
-
stepType = "Wait";
|
|
1299
1369
|
allowUndefinedOut = false;
|
|
1300
|
-
constructor(stepName, eventId, timeout) {
|
|
1301
|
-
super(stepName);
|
|
1370
|
+
constructor(context, stepName, eventId, timeout) {
|
|
1371
|
+
super(context, stepName);
|
|
1302
1372
|
this.eventId = eventId;
|
|
1303
1373
|
this.timeout = timeout;
|
|
1304
1374
|
}
|
|
@@ -1323,13 +1393,6 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1323
1393
|
concurrent
|
|
1324
1394
|
});
|
|
1325
1395
|
}
|
|
1326
|
-
safeParseOut(out) {
|
|
1327
|
-
const result = JSON.parse(out);
|
|
1328
|
-
return {
|
|
1329
|
-
...result,
|
|
1330
|
-
eventData: BaseLazyStep.tryParsing(result.eventData)
|
|
1331
|
-
};
|
|
1332
|
-
}
|
|
1333
1396
|
getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
|
|
1334
1397
|
const headers = super.getHeaders({ context, telemetry: telemetry2, invokeCount, step });
|
|
1335
1398
|
headers.headers["Upstash-Workflow-CallType"] = "step";
|
|
@@ -1363,7 +1426,7 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1363
1426
|
timeoutHeaders,
|
|
1364
1427
|
step: {
|
|
1365
1428
|
stepId: step.stepId,
|
|
1366
|
-
stepType:
|
|
1429
|
+
stepType: this.stepType,
|
|
1367
1430
|
stepName: step.stepName,
|
|
1368
1431
|
concurrent: step.concurrent,
|
|
1369
1432
|
targetStep: step.targetStep
|
|
@@ -1384,8 +1447,8 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1384
1447
|
};
|
|
1385
1448
|
var LazyNotifyStep = class extends LazyFunctionStep {
|
|
1386
1449
|
stepType = "Notify";
|
|
1387
|
-
constructor(stepName, eventId, eventData, requester) {
|
|
1388
|
-
super(stepName, async () => {
|
|
1450
|
+
constructor(context, stepName, eventId, eventData, requester) {
|
|
1451
|
+
super(context, stepName, async () => {
|
|
1389
1452
|
const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
|
|
1390
1453
|
return {
|
|
1391
1454
|
eventId,
|
|
@@ -1410,7 +1473,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1410
1473
|
* workflow id of the invoked workflow
|
|
1411
1474
|
*/
|
|
1412
1475
|
workflowId;
|
|
1413
|
-
constructor(stepName, {
|
|
1476
|
+
constructor(context, stepName, {
|
|
1414
1477
|
workflow,
|
|
1415
1478
|
body,
|
|
1416
1479
|
headers = {},
|
|
@@ -1420,7 +1483,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1420
1483
|
flowControl,
|
|
1421
1484
|
stringifyBody = true
|
|
1422
1485
|
}) {
|
|
1423
|
-
super(stepName);
|
|
1486
|
+
super(context, stepName);
|
|
1424
1487
|
this.params = {
|
|
1425
1488
|
workflow,
|
|
1426
1489
|
body,
|
|
@@ -1481,6 +1544,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1481
1544
|
userHeaders: context.headers,
|
|
1482
1545
|
invokeCount
|
|
1483
1546
|
});
|
|
1547
|
+
context.qstashClient.http.headers?.forEach((value, key) => {
|
|
1548
|
+
invokerHeaders[key] = value;
|
|
1549
|
+
});
|
|
1484
1550
|
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1485
1551
|
let invokeBody;
|
|
1486
1552
|
if (this.params.stringifyBody) {
|
|
@@ -1552,6 +1618,91 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1552
1618
|
return [result];
|
|
1553
1619
|
}
|
|
1554
1620
|
};
|
|
1621
|
+
var LazyCreateWebhookStep = class extends BaseLazyStep {
|
|
1622
|
+
stepType = "CreateWebhook";
|
|
1623
|
+
allowUndefinedOut = false;
|
|
1624
|
+
getPlanStep(concurrent, targetStep) {
|
|
1625
|
+
return {
|
|
1626
|
+
stepId: 0,
|
|
1627
|
+
stepName: this.stepName,
|
|
1628
|
+
stepType: this.stepType,
|
|
1629
|
+
concurrent,
|
|
1630
|
+
targetStep
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
async getResultStep(concurrent, stepId) {
|
|
1634
|
+
return {
|
|
1635
|
+
stepId,
|
|
1636
|
+
stepName: this.stepName,
|
|
1637
|
+
stepType: this.stepType,
|
|
1638
|
+
out: void 0,
|
|
1639
|
+
concurrent
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
getBody({ step, context }) {
|
|
1643
|
+
const userId = getUserIdFromToken(context.qstashClient);
|
|
1644
|
+
const out = [userId, context.workflowRunId, getEventId()].join("/");
|
|
1645
|
+
return JSON.stringify({
|
|
1646
|
+
...step,
|
|
1647
|
+
out
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1650
|
+
safeParseOut(out) {
|
|
1651
|
+
const [userId, workflowRunId, eventId] = out.split("/");
|
|
1652
|
+
const qstashUrl = getQStashUrl(this.context.qstashClient);
|
|
1653
|
+
return {
|
|
1654
|
+
webhookUrl: `${qstashUrl}/v2/workflows/hooks/${userId}/${workflowRunId}/${eventId}`,
|
|
1655
|
+
eventId
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
};
|
|
1659
|
+
var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
|
|
1660
|
+
stepType = "WaitForWebhook";
|
|
1661
|
+
allowUndefinedOut = true;
|
|
1662
|
+
constructor(context, stepName, webhook, timeout) {
|
|
1663
|
+
super(context, stepName, webhook.eventId, timeout);
|
|
1664
|
+
}
|
|
1665
|
+
safeParseOut(out) {
|
|
1666
|
+
const eventData = decodeBase64(out);
|
|
1667
|
+
const parsedEventData = BaseLazyStep.tryParsing(eventData);
|
|
1668
|
+
const body = parsedEventData.body;
|
|
1669
|
+
const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
|
|
1670
|
+
const request = new Request(
|
|
1671
|
+
`${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
|
|
1672
|
+
{
|
|
1673
|
+
method: parsedEventData.method,
|
|
1674
|
+
headers: parsedEventData.header,
|
|
1675
|
+
body: parsedBody
|
|
1676
|
+
}
|
|
1677
|
+
);
|
|
1678
|
+
return {
|
|
1679
|
+
request,
|
|
1680
|
+
timeout: false
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
handleUndefinedOut() {
|
|
1684
|
+
return {
|
|
1685
|
+
timeout: true,
|
|
1686
|
+
request: void 0
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1690
|
+
var LazyWaitForEventStep = class extends LazyWaitEventStep {
|
|
1691
|
+
stepType = "Wait";
|
|
1692
|
+
allowUndefinedOut = true;
|
|
1693
|
+
parseWaitForEventOut(out, waitTimeout) {
|
|
1694
|
+
return {
|
|
1695
|
+
eventData: out ? BaseLazyStep.tryParsing(decodeBase64(out)) : void 0,
|
|
1696
|
+
timeout: waitTimeout ?? false
|
|
1697
|
+
};
|
|
1698
|
+
}
|
|
1699
|
+
safeParseOut(out, step) {
|
|
1700
|
+
return this.parseWaitForEventOut(out, step.waitTimeout);
|
|
1701
|
+
}
|
|
1702
|
+
handleUndefinedOut(step) {
|
|
1703
|
+
return this.parseWaitForEventOut(void 0, step.waitTimeout);
|
|
1704
|
+
}
|
|
1705
|
+
};
|
|
1555
1706
|
|
|
1556
1707
|
// src/agents/constants.ts
|
|
1557
1708
|
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
@@ -1956,7 +2107,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1956
2107
|
step,
|
|
1957
2108
|
stepCount: this.stepCount
|
|
1958
2109
|
});
|
|
1959
|
-
return lazyStep.parseOut(step
|
|
2110
|
+
return lazyStep.parseOut(step);
|
|
1960
2111
|
}
|
|
1961
2112
|
const resultStep = await submitSingleStep({
|
|
1962
2113
|
context: this.context,
|
|
@@ -2027,7 +2178,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2027
2178
|
});
|
|
2028
2179
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2029
2180
|
} catch (error) {
|
|
2030
|
-
if (error
|
|
2181
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2031
2182
|
throw error;
|
|
2032
2183
|
}
|
|
2033
2184
|
throw new WorkflowError(
|
|
@@ -2043,7 +2194,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2043
2194
|
const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
|
|
2044
2195
|
validateParallelSteps(parallelSteps, parallelResultSteps);
|
|
2045
2196
|
return parallelResultSteps.map(
|
|
2046
|
-
(step, index) => parallelSteps[index].parseOut(step
|
|
2197
|
+
(step, index) => parallelSteps[index].parseOut(step)
|
|
2047
2198
|
);
|
|
2048
2199
|
}
|
|
2049
2200
|
}
|
|
@@ -2099,7 +2250,6 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2099
2250
|
* @param index index of the current step
|
|
2100
2251
|
* @returns result[index] if lazyStepList > 1, otherwise result
|
|
2101
2252
|
*/
|
|
2102
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2103
2253
|
static getResult(lazyStepList, result, index) {
|
|
2104
2254
|
if (lazyStepList.length === 1) {
|
|
2105
2255
|
return result;
|
|
@@ -2134,7 +2284,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2134
2284
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2135
2285
|
}
|
|
2136
2286
|
} catch (error) {
|
|
2137
|
-
if (error
|
|
2287
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2138
2288
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2139
2289
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2140
2290
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2315,7 +2465,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2315
2465
|
headers: responseHeaders
|
|
2316
2466
|
});
|
|
2317
2467
|
} catch (error) {
|
|
2318
|
-
if (error instanceof Error && error
|
|
2468
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2319
2469
|
throw error;
|
|
2320
2470
|
} else {
|
|
2321
2471
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2417,10 +2567,10 @@ var Agent = class {
|
|
|
2417
2567
|
});
|
|
2418
2568
|
return { text: result.text };
|
|
2419
2569
|
} catch (error) {
|
|
2420
|
-
if (error
|
|
2421
|
-
if (error.cause instanceof Error && error.cause
|
|
2570
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2571
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2422
2572
|
throw error.cause;
|
|
2423
|
-
} else if (error.cause
|
|
2573
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2424
2574
|
throw error.cause.cause;
|
|
2425
2575
|
} else {
|
|
2426
2576
|
throw error;
|
|
@@ -2891,7 +3041,7 @@ var WorkflowContext = class {
|
|
|
2891
3041
|
*/
|
|
2892
3042
|
async run(stepName, stepFunction) {
|
|
2893
3043
|
const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
|
|
2894
|
-
return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
|
|
3044
|
+
return await this.addStep(new LazyFunctionStep(this, stepName, wrappedStepFunction));
|
|
2895
3045
|
}
|
|
2896
3046
|
/**
|
|
2897
3047
|
* Stops the execution for the duration provided.
|
|
@@ -2905,7 +3055,7 @@ var WorkflowContext = class {
|
|
|
2905
3055
|
* @returns undefined
|
|
2906
3056
|
*/
|
|
2907
3057
|
async sleep(stepName, duration) {
|
|
2908
|
-
await this.addStep(new LazySleepStep(stepName, duration));
|
|
3058
|
+
await this.addStep(new LazySleepStep(this, stepName, duration));
|
|
2909
3059
|
}
|
|
2910
3060
|
/**
|
|
2911
3061
|
* Stops the execution until the date time provided.
|
|
@@ -2927,13 +3077,14 @@ var WorkflowContext = class {
|
|
|
2927
3077
|
datetime = typeof datetime === "string" ? new Date(datetime) : datetime;
|
|
2928
3078
|
time = Math.round(datetime.getTime() / 1e3);
|
|
2929
3079
|
}
|
|
2930
|
-
await this.addStep(new LazySleepUntilStep(stepName, time));
|
|
3080
|
+
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
2931
3081
|
}
|
|
2932
3082
|
async call(stepName, settings) {
|
|
2933
3083
|
let callStep;
|
|
2934
3084
|
if ("workflow" in settings) {
|
|
2935
3085
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2936
3086
|
callStep = new LazyCallStep(
|
|
3087
|
+
this,
|
|
2937
3088
|
stepName,
|
|
2938
3089
|
url,
|
|
2939
3090
|
"POST",
|
|
@@ -2958,6 +3109,7 @@ var WorkflowContext = class {
|
|
|
2958
3109
|
stringifyBody = true
|
|
2959
3110
|
} = settings;
|
|
2960
3111
|
callStep = new LazyCallStep(
|
|
3112
|
+
this,
|
|
2961
3113
|
stepName,
|
|
2962
3114
|
url,
|
|
2963
3115
|
method,
|
|
@@ -3009,7 +3161,9 @@ var WorkflowContext = class {
|
|
|
3009
3161
|
async waitForEvent(stepName, eventId, options = {}) {
|
|
3010
3162
|
const { timeout = "7d" } = options;
|
|
3011
3163
|
const timeoutStr = typeof timeout === "string" ? timeout : `${timeout}s`;
|
|
3012
|
-
return await this.addStep(
|
|
3164
|
+
return await this.addStep(
|
|
3165
|
+
new LazyWaitForEventStep(this, stepName, eventId, timeoutStr)
|
|
3166
|
+
);
|
|
3013
3167
|
}
|
|
3014
3168
|
/**
|
|
3015
3169
|
* Notify workflow runs waiting for an event
|
|
@@ -3034,11 +3188,19 @@ var WorkflowContext = class {
|
|
|
3034
3188
|
*/
|
|
3035
3189
|
async notify(stepName, eventId, eventData) {
|
|
3036
3190
|
return await this.addStep(
|
|
3037
|
-
new LazyNotifyStep(stepName, eventId, eventData, this.qstashClient.http)
|
|
3191
|
+
new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
|
|
3038
3192
|
);
|
|
3039
3193
|
}
|
|
3040
3194
|
async invoke(stepName, settings) {
|
|
3041
|
-
return await this.addStep(
|
|
3195
|
+
return await this.addStep(
|
|
3196
|
+
new LazyInvokeStep(this, stepName, settings)
|
|
3197
|
+
);
|
|
3198
|
+
}
|
|
3199
|
+
async createWebhook(stepName) {
|
|
3200
|
+
return await this.addStep(new LazyCreateWebhookStep(this, stepName));
|
|
3201
|
+
}
|
|
3202
|
+
async waitForWebhook(stepName, webhook, timeout) {
|
|
3203
|
+
return await this.addStep(new LazyWaitForWebhookStep(this, stepName, webhook, timeout));
|
|
3042
3204
|
}
|
|
3043
3205
|
/**
|
|
3044
3206
|
* Cancel the current workflow run
|
|
@@ -3169,7 +3331,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3169
3331
|
try {
|
|
3170
3332
|
await routeFunction(disabledContext);
|
|
3171
3333
|
} catch (error) {
|
|
3172
|
-
if (error
|
|
3334
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3173
3335
|
return ok("step-found");
|
|
3174
3336
|
}
|
|
3175
3337
|
console.warn(
|
|
@@ -3202,13 +3364,6 @@ var processRawSteps = (rawSteps) => {
|
|
|
3202
3364
|
const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
|
|
3203
3365
|
const otherSteps = stepsToDecode.map((rawStep) => {
|
|
3204
3366
|
const step = JSON.parse(decodeBase64(rawStep.body));
|
|
3205
|
-
if (step.waitEventId) {
|
|
3206
|
-
const newOut = {
|
|
3207
|
-
eventData: step.out ? decodeBase64(step.out) : void 0,
|
|
3208
|
-
timeout: step.waitTimeout ?? false
|
|
3209
|
-
};
|
|
3210
|
-
step.out = newOut;
|
|
3211
|
-
}
|
|
3212
3367
|
return step;
|
|
3213
3368
|
});
|
|
3214
3369
|
const steps = [initialStep, ...otherSteps];
|
|
@@ -3422,13 +3577,24 @@ var processOptions = (options) => {
|
|
|
3422
3577
|
},
|
|
3423
3578
|
status: 489
|
|
3424
3579
|
});
|
|
3425
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3426
|
-
return new Response(detailedFinishCondition.result
|
|
3427
|
-
status: 200,
|
|
3580
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3581
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3428
3582
|
headers: {
|
|
3583
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3429
3584
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3430
|
-
}
|
|
3585
|
+
},
|
|
3586
|
+
status: 429
|
|
3431
3587
|
});
|
|
3588
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3589
|
+
return new Response(
|
|
3590
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3591
|
+
{
|
|
3592
|
+
status: 200,
|
|
3593
|
+
headers: {
|
|
3594
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
);
|
|
3432
3598
|
}
|
|
3433
3599
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3434
3600
|
status: 200,
|
|
@@ -3638,12 +3804,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3638
3804
|
},
|
|
3639
3805
|
debug
|
|
3640
3806
|
});
|
|
3641
|
-
if (result.isOk() && result.value
|
|
3807
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3642
3808
|
return onStepFinish(workflowRunId, result.value, {
|
|
3643
3809
|
condition: "non-retryable-error",
|
|
3644
3810
|
result: result.value
|
|
3645
3811
|
});
|
|
3646
3812
|
}
|
|
3813
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3814
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3815
|
+
condition: "retry-after-error",
|
|
3816
|
+
result: result.value
|
|
3817
|
+
});
|
|
3818
|
+
}
|
|
3647
3819
|
if (result.isErr()) {
|
|
3648
3820
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3649
3821
|
throw result.error;
|
|
@@ -3674,7 +3846,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3674
3846
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3675
3847
|
Original error: '${formattedError.message}'`;
|
|
3676
3848
|
console.error(errorMessage);
|
|
3677
|
-
return new Response(errorMessage, {
|
|
3849
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3678
3850
|
status: 500,
|
|
3679
3851
|
headers: {
|
|
3680
3852
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|