@upstash/qstash 2.7.9 → 2.8.0-canary
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/{chunk-QK55BUNQ.mjs → dist/chunk-KWSSCN6R.mjs} +30 -0
- package/{chunk-UPFTIDSI.mjs → dist/chunk-XLCNEVA2.mjs} +1 -1
- package/dist/cloudflare.js +2973 -0
- package/{cloudflare.mjs → dist/cloudflare.mjs} +1 -1
- package/dist/h3.js +3338 -0
- package/{h3.mjs → dist/h3.mjs} +2 -2
- package/{chunk-R5CZPV7H.js → dist/hono.js} +245 -239
- package/{hono.mjs → dist/hono.mjs} +1 -1
- package/dist/index.js +1639 -0
- package/{index.mjs → dist/index.mjs} +1 -1
- package/dist/nextjs.js +4742 -0
- package/dist/nextjs.mjs +1802 -0
- package/dist/nuxt.js +832 -0
- package/{nuxt.mjs → dist/nuxt.mjs} +2 -2
- package/dist/solidjs.js +2991 -0
- package/{solidjs.mjs → dist/solidjs.mjs} +1 -1
- package/dist/svelte.js +2988 -0
- package/{svelte.mjs → dist/svelte.mjs} +1 -1
- package/dist/workflow.js +2954 -0
- package/{workflow.mjs → dist/workflow.mjs} +1 -1
- package/package.json +1 -1
- package/chunk-VN7YQ2UN.js +0 -1
- package/chunk-YBZBGHDQ.js +0 -403
- package/cloudflare.js +0 -37
- package/h3.js +0 -10
- package/hono.js +0 -22
- package/index.js +0 -43
- package/nextjs.js +0 -178
- package/nextjs.mjs +0 -178
- package/nuxt.js +0 -11
- package/solidjs.js +0 -56
- package/svelte.js +0 -53
- package/workflow.js +0 -18
- /package/{chunk-CIVGPRQN.mjs → dist/chunk-CIVGPRQN.mjs} +0 -0
- /package/{client-DkrYCqaq.d.mts → dist/client-DkrYCqaq.d.mts} +0 -0
- /package/{client-DkrYCqaq.d.ts → dist/client-DkrYCqaq.d.ts} +0 -0
- /package/{cloudflare.d.mts → dist/cloudflare.d.mts} +0 -0
- /package/{cloudflare.d.ts → dist/cloudflare.d.ts} +0 -0
- /package/{h3.d.mts → dist/h3.d.mts} +0 -0
- /package/{h3.d.ts → dist/h3.d.ts} +0 -0
- /package/{hono.d.mts → dist/hono.d.mts} +0 -0
- /package/{hono.d.ts → dist/hono.d.ts} +0 -0
- /package/{index.d.mts → dist/index.d.mts} +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{nextjs.d.mts → dist/nextjs.d.mts} +0 -0
- /package/{nextjs.d.ts → dist/nextjs.d.ts} +0 -0
- /package/{nuxt.d.mts → dist/nuxt.d.mts} +0 -0
- /package/{nuxt.d.ts → dist/nuxt.d.ts} +0 -0
- /package/{solidjs.d.mts → dist/solidjs.d.mts} +0 -0
- /package/{solidjs.d.ts → dist/solidjs.d.ts} +0 -0
- /package/{svelte.d.mts → dist/svelte.d.mts} +0 -0
- /package/{svelte.d.ts → dist/svelte.d.ts} +0 -0
- /package/{workflow.d.mts → dist/workflow.d.mts} +0 -0
- /package/{workflow.d.ts → dist/workflow.d.ts} +0 -0
|
@@ -1,6 +1,42 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var
|
|
3
|
-
var
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// platforms/hono.ts
|
|
31
|
+
var hono_exports = {};
|
|
32
|
+
__export(hono_exports, {
|
|
33
|
+
serve: () => serve2
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(hono_exports);
|
|
36
|
+
|
|
37
|
+
// src/receiver.ts
|
|
38
|
+
var jose = __toESM(require("jose"));
|
|
39
|
+
var import_crypto_js = __toESM(require("crypto-js"));
|
|
4
40
|
var SignatureError = class extends Error {
|
|
5
41
|
constructor(message) {
|
|
6
42
|
super(message);
|
|
@@ -8,8 +44,8 @@ var SignatureError = class extends Error {
|
|
|
8
44
|
}
|
|
9
45
|
};
|
|
10
46
|
var Receiver = class {
|
|
11
|
-
|
|
12
|
-
|
|
47
|
+
currentSigningKey;
|
|
48
|
+
nextSigningKey;
|
|
13
49
|
constructor(config) {
|
|
14
50
|
this.currentSigningKey = config.currentSigningKey;
|
|
15
51
|
this.nextSigningKey = config.nextSigningKey;
|
|
@@ -44,7 +80,7 @@ var Receiver = class {
|
|
|
44
80
|
if (request.url !== void 0 && p.sub !== request.url) {
|
|
45
81
|
throw new SignatureError(`invalid subject: ${p.sub}, want: ${request.url}`);
|
|
46
82
|
}
|
|
47
|
-
const bodyHash =
|
|
83
|
+
const bodyHash = import_crypto_js.default.SHA256(request.body).toString(import_crypto_js.default.enc.Base64url);
|
|
48
84
|
const padding = new RegExp(/=+$/);
|
|
49
85
|
if (p.body.replace(padding, "") !== bodyHash.replace(padding, "")) {
|
|
50
86
|
throw new SignatureError(`body hash does not match, want: ${p.body}, got: ${bodyHash}`);
|
|
@@ -55,7 +91,7 @@ var Receiver = class {
|
|
|
55
91
|
|
|
56
92
|
// src/client/dlq.ts
|
|
57
93
|
var DLQ = class {
|
|
58
|
-
|
|
94
|
+
http;
|
|
59
95
|
constructor(http) {
|
|
60
96
|
this.http = http;
|
|
61
97
|
}
|
|
@@ -64,15 +100,15 @@ var DLQ = class {
|
|
|
64
100
|
*/
|
|
65
101
|
async listMessages(options) {
|
|
66
102
|
const filterPayload = {
|
|
67
|
-
...
|
|
68
|
-
topicName:
|
|
103
|
+
...options?.filter,
|
|
104
|
+
topicName: options?.filter?.urlGroup
|
|
69
105
|
};
|
|
70
106
|
const messagesPayload = await this.http.request({
|
|
71
107
|
method: "GET",
|
|
72
108
|
path: ["v2", "dlq"],
|
|
73
109
|
query: {
|
|
74
|
-
cursor:
|
|
75
|
-
count:
|
|
110
|
+
cursor: options?.cursor,
|
|
111
|
+
count: options?.count,
|
|
76
112
|
...filterPayload
|
|
77
113
|
}
|
|
78
114
|
});
|
|
@@ -118,9 +154,9 @@ var QstashError = class extends Error {
|
|
|
118
154
|
}
|
|
119
155
|
};
|
|
120
156
|
var QstashRatelimitError = class extends QstashError {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
157
|
+
limit;
|
|
158
|
+
remaining;
|
|
159
|
+
reset;
|
|
124
160
|
constructor(args) {
|
|
125
161
|
super(`Exceeded burst rate limit. ${JSON.stringify(args)} `);
|
|
126
162
|
this.name = "QstashRatelimitError";
|
|
@@ -130,12 +166,12 @@ var QstashRatelimitError = class extends QstashError {
|
|
|
130
166
|
}
|
|
131
167
|
};
|
|
132
168
|
var QstashChatRatelimitError = class extends QstashError {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
169
|
+
limitRequests;
|
|
170
|
+
limitTokens;
|
|
171
|
+
remainingRequests;
|
|
172
|
+
remainingTokens;
|
|
173
|
+
resetRequests;
|
|
174
|
+
resetTokens;
|
|
139
175
|
constructor(args) {
|
|
140
176
|
super(`Exceeded chat rate limit. ${JSON.stringify(args)} `);
|
|
141
177
|
this.limitRequests = args["limit-requests"];
|
|
@@ -147,9 +183,9 @@ var QstashChatRatelimitError = class extends QstashError {
|
|
|
147
183
|
}
|
|
148
184
|
};
|
|
149
185
|
var QstashDailyRatelimitError = class extends QstashError {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
186
|
+
limit;
|
|
187
|
+
remaining;
|
|
188
|
+
reset;
|
|
153
189
|
constructor(args) {
|
|
154
190
|
super(`Exceeded daily rate limit. ${JSON.stringify(args)} `);
|
|
155
191
|
this.limit = args.limit;
|
|
@@ -165,8 +201,8 @@ var QStashWorkflowError = class extends QstashError {
|
|
|
165
201
|
}
|
|
166
202
|
};
|
|
167
203
|
var QStashWorkflowAbort = class extends Error {
|
|
168
|
-
|
|
169
|
-
|
|
204
|
+
stepInfo;
|
|
205
|
+
stepName;
|
|
170
206
|
constructor(stepName, stepInfo) {
|
|
171
207
|
super(
|
|
172
208
|
`This is an QStash 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}'.`
|
|
@@ -187,12 +223,12 @@ var formatWorkflowError = (error) => {
|
|
|
187
223
|
};
|
|
188
224
|
|
|
189
225
|
// src/client/http.ts
|
|
190
|
-
var HttpClient =
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
constructor(config) {
|
|
226
|
+
var HttpClient = class {
|
|
227
|
+
baseUrl;
|
|
228
|
+
authorization;
|
|
229
|
+
options;
|
|
230
|
+
retry;
|
|
231
|
+
constructor(config) {
|
|
196
232
|
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
197
233
|
this.authorization = config.authorization;
|
|
198
234
|
this.retry = // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -200,8 +236,8 @@ var HttpClient = (_class = class {
|
|
|
200
236
|
attempts: 1,
|
|
201
237
|
backoff: () => 0
|
|
202
238
|
} : {
|
|
203
|
-
attempts:
|
|
204
|
-
backoff:
|
|
239
|
+
attempts: config.retry?.retries ? config.retry.retries + 1 : 5,
|
|
240
|
+
backoff: config.retry?.backoff ?? ((retryCount) => Math.exp(retryCount) * 50)
|
|
205
241
|
};
|
|
206
242
|
}
|
|
207
243
|
async request(request) {
|
|
@@ -241,7 +277,7 @@ var HttpClient = (_class = class {
|
|
|
241
277
|
await reader.cancel();
|
|
242
278
|
}
|
|
243
279
|
}
|
|
244
|
-
|
|
280
|
+
requestWithBackoff = async (request) => {
|
|
245
281
|
const [url, requestOptions] = this.processRequest(request);
|
|
246
282
|
let response = void 0;
|
|
247
283
|
let error = void 0;
|
|
@@ -255,15 +291,15 @@ var HttpClient = (_class = class {
|
|
|
255
291
|
}
|
|
256
292
|
}
|
|
257
293
|
if (!response) {
|
|
258
|
-
throw
|
|
294
|
+
throw error ?? new Error("Exhausted all retries");
|
|
259
295
|
}
|
|
260
296
|
await this.checkResponse(response);
|
|
261
297
|
return {
|
|
262
298
|
response,
|
|
263
299
|
error
|
|
264
300
|
};
|
|
265
|
-
}
|
|
266
|
-
|
|
301
|
+
};
|
|
302
|
+
processRequest = (request) => {
|
|
267
303
|
const headers = new Headers(request.headers);
|
|
268
304
|
if (!headers.has("Authorization")) {
|
|
269
305
|
headers.set("Authorization", this.authorization);
|
|
@@ -274,7 +310,7 @@ var HttpClient = (_class = class {
|
|
|
274
310
|
body: request.body,
|
|
275
311
|
keepalive: request.keepalive
|
|
276
312
|
};
|
|
277
|
-
const url = new URL([
|
|
313
|
+
const url = new URL([request.baseUrl ?? this.baseUrl, ...request.path].join("/"));
|
|
278
314
|
if (request.query) {
|
|
279
315
|
for (const [key, value] of Object.entries(request.query)) {
|
|
280
316
|
if (value !== void 0) {
|
|
@@ -283,7 +319,7 @@ var HttpClient = (_class = class {
|
|
|
283
319
|
}
|
|
284
320
|
}
|
|
285
321
|
return [url.toString(), requestOptions];
|
|
286
|
-
}
|
|
322
|
+
};
|
|
287
323
|
async checkResponse(response) {
|
|
288
324
|
if (response.status === 429) {
|
|
289
325
|
if (response.headers.get("x-ratelimit-limit-requests")) {
|
|
@@ -313,7 +349,7 @@ var HttpClient = (_class = class {
|
|
|
313
349
|
throw new QstashError(body.length > 0 ? body : `Error: status=${response.status}`);
|
|
314
350
|
}
|
|
315
351
|
}
|
|
316
|
-
}
|
|
352
|
+
};
|
|
317
353
|
|
|
318
354
|
// src/client/llm/providers.ts
|
|
319
355
|
var setupAnalytics = (analytics, providerApiKey, providerBaseUrl, provider) => {
|
|
@@ -348,35 +384,12 @@ var setupAnalytics = (analytics, providerApiKey, providerBaseUrl, provider) => {
|
|
|
348
384
|
}
|
|
349
385
|
}
|
|
350
386
|
};
|
|
351
|
-
var upstash = () => {
|
|
352
|
-
return {
|
|
353
|
-
owner: "upstash",
|
|
354
|
-
baseUrl: "https://qstash.upstash.io/llm",
|
|
355
|
-
token: ""
|
|
356
|
-
};
|
|
357
|
-
};
|
|
358
|
-
var openai = ({
|
|
359
|
-
token
|
|
360
|
-
}) => {
|
|
361
|
-
return { token, owner: "openai", baseUrl: "https://api.openai.com" };
|
|
362
|
-
};
|
|
363
|
-
var custom = ({
|
|
364
|
-
baseUrl,
|
|
365
|
-
token
|
|
366
|
-
}) => {
|
|
367
|
-
const trimmedBaseUrl = baseUrl.replace(/\/(v1\/)?chat\/completions$/, "");
|
|
368
|
-
return {
|
|
369
|
-
token,
|
|
370
|
-
owner: "custom",
|
|
371
|
-
baseUrl: trimmedBaseUrl
|
|
372
|
-
};
|
|
373
|
-
};
|
|
374
387
|
|
|
375
388
|
// src/client/llm/chat.ts
|
|
376
|
-
var Chat =
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
constructor(http, token) {
|
|
389
|
+
var Chat = class _Chat {
|
|
390
|
+
http;
|
|
391
|
+
token;
|
|
392
|
+
constructor(http, token) {
|
|
380
393
|
this.http = http;
|
|
381
394
|
this.token = token;
|
|
382
395
|
}
|
|
@@ -398,7 +411,7 @@ var Chat = (_class2 = class _Chat {
|
|
|
398
411
|
* @param request ChatRequest with messages
|
|
399
412
|
* @returns Chat completion or stream
|
|
400
413
|
*/
|
|
401
|
-
|
|
414
|
+
create = async (request) => {
|
|
402
415
|
if (request.provider.owner != "upstash")
|
|
403
416
|
return this.createThirdParty(request);
|
|
404
417
|
const body = JSON.stringify(request);
|
|
@@ -436,7 +449,7 @@ var Chat = (_class2 = class _Chat {
|
|
|
436
449
|
baseUrl,
|
|
437
450
|
body
|
|
438
451
|
});
|
|
439
|
-
}
|
|
452
|
+
};
|
|
440
453
|
/**
|
|
441
454
|
* Calls the Upstash completions api given a ChatRequest.
|
|
442
455
|
*
|
|
@@ -447,7 +460,7 @@ var Chat = (_class2 = class _Chat {
|
|
|
447
460
|
* @returns Chat completion or stream
|
|
448
461
|
*/
|
|
449
462
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
450
|
-
|
|
463
|
+
createThirdParty = async (request) => {
|
|
451
464
|
const { baseUrl, token, owner } = request.provider;
|
|
452
465
|
if (owner === "upstash")
|
|
453
466
|
throw new Error("Upstash is not 3rd party provider!");
|
|
@@ -456,8 +469,8 @@ var Chat = (_class2 = class _Chat {
|
|
|
456
469
|
const analytics = request.analytics;
|
|
457
470
|
delete request.analytics;
|
|
458
471
|
const body = JSON.stringify(request);
|
|
459
|
-
const isAnalyticsEnabled =
|
|
460
|
-
const analyticsConfig =
|
|
472
|
+
const isAnalyticsEnabled = analytics?.name && analytics.token;
|
|
473
|
+
const analyticsConfig = analytics?.name && analytics.token ? setupAnalytics({ name: analytics.name, token: analytics.token }, token, baseUrl, owner) : { defaultHeaders: void 0, baseURL: baseUrl };
|
|
461
474
|
const isStream = "stream" in request && request.stream;
|
|
462
475
|
const headers = {
|
|
463
476
|
"Content-Type": "application/json",
|
|
@@ -477,7 +490,7 @@ var Chat = (_class2 = class _Chat {
|
|
|
477
490
|
baseUrl: analyticsConfig.baseURL
|
|
478
491
|
});
|
|
479
492
|
return response;
|
|
480
|
-
}
|
|
493
|
+
};
|
|
481
494
|
// Helper method to get the authorization token
|
|
482
495
|
getAuthorizationToken() {
|
|
483
496
|
const authHeader = String(this.http.authorization);
|
|
@@ -498,11 +511,11 @@ var Chat = (_class2 = class _Chat {
|
|
|
498
511
|
* mistralai/Mistral-7B-Instruct-v0.2 model.
|
|
499
512
|
* @returns Chat completion or stream
|
|
500
513
|
*/
|
|
501
|
-
|
|
514
|
+
prompt = async (request) => {
|
|
502
515
|
const chatRequest = _Chat.toChatRequest(request);
|
|
503
516
|
return this.create(chatRequest);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
517
|
+
};
|
|
518
|
+
};
|
|
506
519
|
|
|
507
520
|
// src/client/llm/utils.ts
|
|
508
521
|
function appendLLMOptionsIfNeeded(request, headers, http) {
|
|
@@ -510,7 +523,7 @@ function appendLLMOptionsIfNeeded(request, headers, http) {
|
|
|
510
523
|
return;
|
|
511
524
|
const provider = request.api.provider;
|
|
512
525
|
const analytics = request.api.analytics;
|
|
513
|
-
if (
|
|
526
|
+
if (provider?.owner === "upstash") {
|
|
514
527
|
handleUpstashProvider(request, headers, http, analytics);
|
|
515
528
|
return;
|
|
516
529
|
}
|
|
@@ -532,7 +545,7 @@ function handleUpstashProvider(request, headers, http, analytics) {
|
|
|
532
545
|
{ name: analytics.name, token: analytics.token },
|
|
533
546
|
//@ts-expect-error hacky way to get bearer token
|
|
534
547
|
String(http.authorization).split("Bearer ")[1],
|
|
535
|
-
|
|
548
|
+
request.api?.provider?.baseUrl,
|
|
536
549
|
"upstash"
|
|
537
550
|
);
|
|
538
551
|
setAnalyticsHeaders(headers, analyticsConfig);
|
|
@@ -542,28 +555,28 @@ function handleUpstashProvider(request, headers, http, analytics) {
|
|
|
542
555
|
}
|
|
543
556
|
}
|
|
544
557
|
function validateProviderConfig(provider) {
|
|
545
|
-
if (!
|
|
558
|
+
if (!provider?.baseUrl)
|
|
546
559
|
throw new Error("baseUrl cannot be empty or undefined!");
|
|
547
560
|
if (!provider.token)
|
|
548
561
|
throw new Error("token cannot be empty or undefined!");
|
|
549
562
|
return { baseUrl: provider.baseUrl, token: provider.token };
|
|
550
563
|
}
|
|
551
564
|
function setAnalyticsHeaders(headers, analyticsConfig) {
|
|
552
|
-
headers.set("Helicone-Auth",
|
|
553
|
-
headers.set("Authorization",
|
|
554
|
-
if (
|
|
565
|
+
headers.set("Helicone-Auth", analyticsConfig.defaultHeaders?.["Helicone-Auth"] ?? "");
|
|
566
|
+
headers.set("Authorization", analyticsConfig.defaultHeaders?.Authorization ?? "");
|
|
567
|
+
if (analyticsConfig.defaultHeaders?.["Helicone-Target-Url"]) {
|
|
555
568
|
headers.set("Helicone-Target-Url", analyticsConfig.defaultHeaders["Helicone-Target-Url"]);
|
|
556
569
|
}
|
|
557
570
|
}
|
|
558
571
|
function ensureCallbackPresent(request) {
|
|
559
|
-
if (
|
|
572
|
+
if (request.api?.name === "llm" && !request.callback) {
|
|
560
573
|
throw new TypeError("Callback cannot be undefined when using LLM");
|
|
561
574
|
}
|
|
562
575
|
}
|
|
563
576
|
|
|
564
577
|
// src/client/messages.ts
|
|
565
578
|
var Messages = class {
|
|
566
|
-
|
|
579
|
+
http;
|
|
567
580
|
constructor(http) {
|
|
568
581
|
this.http = http;
|
|
569
582
|
}
|
|
@@ -627,7 +640,7 @@ function prefixHeaders(headers) {
|
|
|
627
640
|
}
|
|
628
641
|
function processHeaders(request) {
|
|
629
642
|
const headers = prefixHeaders(new Headers(request.headers));
|
|
630
|
-
headers.set("Upstash-Method",
|
|
643
|
+
headers.set("Upstash-Method", request.method ?? "POST");
|
|
631
644
|
if (request.delay !== void 0) {
|
|
632
645
|
if (typeof request.delay === "string") {
|
|
633
646
|
headers.set("Upstash-Delay", request.delay);
|
|
@@ -663,7 +676,7 @@ function processHeaders(request) {
|
|
|
663
676
|
return headers;
|
|
664
677
|
}
|
|
665
678
|
function getRequestPath(request) {
|
|
666
|
-
return
|
|
679
|
+
return request.url ?? request.urlGroup ?? request.topic ?? `api/${request.api?.name}`;
|
|
667
680
|
}
|
|
668
681
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
669
682
|
var NANOID_LENGTH = 21;
|
|
@@ -685,8 +698,8 @@ function decodeBase64(base64) {
|
|
|
685
698
|
|
|
686
699
|
// src/client/queue.ts
|
|
687
700
|
var Queue = class {
|
|
688
|
-
|
|
689
|
-
|
|
701
|
+
http;
|
|
702
|
+
queueName;
|
|
690
703
|
constructor(http, queueName) {
|
|
691
704
|
this.http = http;
|
|
692
705
|
this.queueName = queueName;
|
|
@@ -700,8 +713,8 @@ var Queue = class {
|
|
|
700
713
|
}
|
|
701
714
|
const body = {
|
|
702
715
|
queueName: this.queueName,
|
|
703
|
-
parallelism:
|
|
704
|
-
paused:
|
|
716
|
+
parallelism: request.parallelism ?? 1,
|
|
717
|
+
paused: request.paused ?? false
|
|
705
718
|
};
|
|
706
719
|
await this.http.request({
|
|
707
720
|
method: "POST",
|
|
@@ -812,7 +825,7 @@ var Queue = class {
|
|
|
812
825
|
|
|
813
826
|
// src/client/schedules.ts
|
|
814
827
|
var Schedules = class {
|
|
815
|
-
|
|
828
|
+
http;
|
|
816
829
|
constructor(http) {
|
|
817
830
|
this.http = http;
|
|
818
831
|
}
|
|
@@ -916,7 +929,7 @@ var Schedules = class {
|
|
|
916
929
|
|
|
917
930
|
// src/client/url-groups.ts
|
|
918
931
|
var UrlGroups = class {
|
|
919
|
-
|
|
932
|
+
http;
|
|
920
933
|
constructor(http) {
|
|
921
934
|
this.http = http;
|
|
922
935
|
}
|
|
@@ -976,8 +989,8 @@ var UrlGroups = class {
|
|
|
976
989
|
|
|
977
990
|
// src/client/client.ts
|
|
978
991
|
var Client = class {
|
|
979
|
-
|
|
980
|
-
|
|
992
|
+
http;
|
|
993
|
+
token;
|
|
981
994
|
constructor(config) {
|
|
982
995
|
this.http = new HttpClient({
|
|
983
996
|
retry: config.retry,
|
|
@@ -1042,7 +1055,7 @@ var Client = class {
|
|
|
1042
1055
|
* Create, read, update or delete queues.
|
|
1043
1056
|
*/
|
|
1044
1057
|
queue(request) {
|
|
1045
|
-
return new Queue(this.http,
|
|
1058
|
+
return new Queue(this.http, request?.queueName);
|
|
1046
1059
|
}
|
|
1047
1060
|
/**
|
|
1048
1061
|
* Access the Chat API
|
|
@@ -1141,12 +1154,12 @@ var Client = class {
|
|
|
1141
1154
|
*/
|
|
1142
1155
|
async events(request) {
|
|
1143
1156
|
const query = {};
|
|
1144
|
-
if (typeof
|
|
1157
|
+
if (typeof request?.cursor === "number" && request.cursor > 0) {
|
|
1145
1158
|
query.cursor = request.cursor.toString();
|
|
1146
|
-
} else if (typeof
|
|
1159
|
+
} else if (typeof request?.cursor === "string" && request.cursor !== "") {
|
|
1147
1160
|
query.cursor = request.cursor;
|
|
1148
1161
|
}
|
|
1149
|
-
for (const [key, value] of Object.entries(
|
|
1162
|
+
for (const [key, value] of Object.entries(request?.filter ?? {})) {
|
|
1150
1163
|
if (typeof value === "number" && value < 0) {
|
|
1151
1164
|
continue;
|
|
1152
1165
|
}
|
|
@@ -1570,11 +1583,11 @@ var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
|
1570
1583
|
workflowContext.failureUrl,
|
|
1571
1584
|
retries
|
|
1572
1585
|
);
|
|
1573
|
-
await
|
|
1586
|
+
await debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
|
|
1574
1587
|
headers,
|
|
1575
1588
|
requestPayload: workflowContext.requestPayload,
|
|
1576
1589
|
url: workflowContext.url
|
|
1577
|
-
})
|
|
1590
|
+
});
|
|
1578
1591
|
try {
|
|
1579
1592
|
await workflowContext.qstashClient.publishJSON({
|
|
1580
1593
|
headers,
|
|
@@ -1602,15 +1615,15 @@ var triggerRouteFunction = async ({
|
|
|
1602
1615
|
}
|
|
1603
1616
|
};
|
|
1604
1617
|
var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
1605
|
-
await
|
|
1618
|
+
await debug?.log("SUBMIT", "SUBMIT_CLEANUP", {
|
|
1606
1619
|
deletedWorkflowRunId: workflowContext.workflowRunId
|
|
1607
|
-
})
|
|
1620
|
+
});
|
|
1608
1621
|
const result = await workflowContext.qstashClient.http.request({
|
|
1609
1622
|
path: ["v2", "workflows", "runs", `${workflowContext.workflowRunId}?cancel=${cancel}`],
|
|
1610
1623
|
method: "DELETE",
|
|
1611
1624
|
parseResponseAsJson: false
|
|
1612
1625
|
});
|
|
1613
|
-
await
|
|
1626
|
+
await debug?.log("SUBMIT", "SUBMIT_CLEANUP", result);
|
|
1614
1627
|
};
|
|
1615
1628
|
var recreateUserHeaders = (headers) => {
|
|
1616
1629
|
const filteredHeaders = new Headers();
|
|
@@ -1628,10 +1641,10 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
|
|
|
1628
1641
|
if (request.headers.get("Upstash-Workflow-Callback")) {
|
|
1629
1642
|
const callbackMessage = JSON.parse(requestPayload);
|
|
1630
1643
|
if (!(callbackMessage.status >= 200 && callbackMessage.status < 300)) {
|
|
1631
|
-
await
|
|
1644
|
+
await debug?.log("WARN", "SUBMIT_THIRD_PARTY_RESULT", {
|
|
1632
1645
|
status: callbackMessage.status,
|
|
1633
1646
|
body: decodeBase64(callbackMessage.body)
|
|
1634
|
-
})
|
|
1647
|
+
});
|
|
1635
1648
|
console.warn(
|
|
1636
1649
|
`Workflow Warning: "context.call" failed with status ${callbackMessage.status} and will retry (if there are retries remaining). Error Message:
|
|
1637
1650
|
${decodeBase64(callbackMessage.body)}`
|
|
@@ -1673,20 +1686,20 @@ ${decodeBase64(callbackMessage.body)}`
|
|
|
1673
1686
|
out: decodeBase64(callbackMessage.body),
|
|
1674
1687
|
concurrent: Number(concurrentString)
|
|
1675
1688
|
};
|
|
1676
|
-
await
|
|
1689
|
+
await debug?.log("SUBMIT", "SUBMIT_THIRD_PARTY_RESULT", {
|
|
1677
1690
|
step: callResultStep,
|
|
1678
1691
|
headers: requestHeaders,
|
|
1679
1692
|
url: workflowUrl
|
|
1680
|
-
})
|
|
1693
|
+
});
|
|
1681
1694
|
const result = await client.publishJSON({
|
|
1682
1695
|
headers: requestHeaders,
|
|
1683
1696
|
method: "POST",
|
|
1684
1697
|
body: callResultStep,
|
|
1685
1698
|
url: workflowUrl
|
|
1686
1699
|
});
|
|
1687
|
-
await
|
|
1700
|
+
await debug?.log("SUBMIT", "SUBMIT_THIRD_PARTY_RESULT", {
|
|
1688
1701
|
messageId: result.messageId
|
|
1689
|
-
})
|
|
1702
|
+
});
|
|
1690
1703
|
return ok("is-call-return");
|
|
1691
1704
|
} else {
|
|
1692
1705
|
return ok("continue-workflow");
|
|
@@ -1716,14 +1729,14 @@ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step
|
|
|
1716
1729
|
};
|
|
1717
1730
|
if (userHeaders) {
|
|
1718
1731
|
for (const header of userHeaders.keys()) {
|
|
1719
|
-
if (
|
|
1732
|
+
if (step?.callHeaders) {
|
|
1720
1733
|
baseHeaders[`Upstash-Callback-Forward-${header}`] = userHeaders.get(header);
|
|
1721
1734
|
} else {
|
|
1722
1735
|
baseHeaders[`Upstash-Forward-${header}`] = userHeaders.get(header);
|
|
1723
1736
|
}
|
|
1724
1737
|
}
|
|
1725
1738
|
}
|
|
1726
|
-
if (
|
|
1739
|
+
if (step?.callHeaders) {
|
|
1727
1740
|
const forwardedHeaders = Object.fromEntries(
|
|
1728
1741
|
Object.entries(step.callHeaders).map(([header, value]) => [
|
|
1729
1742
|
`Upstash-Forward-${header}`,
|
|
@@ -1744,7 +1757,7 @@ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step
|
|
|
1744
1757
|
"Upstash-Callback-Forward-Upstash-Workflow-StepName": step.stepName,
|
|
1745
1758
|
"Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
|
|
1746
1759
|
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
1747
|
-
"Upstash-Callback-Forward-Upstash-Workflow-ContentType":
|
|
1760
|
+
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType ?? DEFAULT_CONTENT_TYPE,
|
|
1748
1761
|
"Upstash-Workflow-CallType": "toCallback"
|
|
1749
1762
|
};
|
|
1750
1763
|
}
|
|
@@ -1777,18 +1790,18 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
1777
1790
|
};
|
|
1778
1791
|
|
|
1779
1792
|
// src/client/workflow/auto-executor.ts
|
|
1780
|
-
var AutoExecutor =
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
constructor(context, steps, debug) {
|
|
1793
|
+
var AutoExecutor = class _AutoExecutor {
|
|
1794
|
+
context;
|
|
1795
|
+
promises = /* @__PURE__ */ new WeakMap();
|
|
1796
|
+
activeLazyStepList;
|
|
1797
|
+
debug;
|
|
1798
|
+
nonPlanStepCount;
|
|
1799
|
+
steps;
|
|
1800
|
+
indexInCurrentList = 0;
|
|
1801
|
+
stepCount = 0;
|
|
1802
|
+
planStepCount = 0;
|
|
1803
|
+
executingStep = false;
|
|
1804
|
+
constructor(context, steps, debug) {
|
|
1792
1805
|
this.context = context;
|
|
1793
1806
|
this.debug = debug;
|
|
1794
1807
|
this.steps = steps;
|
|
@@ -1818,7 +1831,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1818
1831
|
);
|
|
1819
1832
|
}
|
|
1820
1833
|
this.stepCount += 1;
|
|
1821
|
-
const lazyStepList =
|
|
1834
|
+
const lazyStepList = this.activeLazyStepList ?? [];
|
|
1822
1835
|
if (!this.activeLazyStepList) {
|
|
1823
1836
|
this.activeLazyStepList = lazyStepList;
|
|
1824
1837
|
this.indexInCurrentList = 0;
|
|
@@ -1869,19 +1882,19 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1869
1882
|
if (this.stepCount < this.nonPlanStepCount) {
|
|
1870
1883
|
const step = this.steps[this.stepCount + this.planStepCount];
|
|
1871
1884
|
validateStep(lazyStep, step);
|
|
1872
|
-
await
|
|
1885
|
+
await this.debug?.log("INFO", "RUN_SINGLE", {
|
|
1873
1886
|
fromRequest: true,
|
|
1874
1887
|
step,
|
|
1875
1888
|
stepCount: this.stepCount
|
|
1876
|
-
})
|
|
1889
|
+
});
|
|
1877
1890
|
return step.out;
|
|
1878
1891
|
}
|
|
1879
1892
|
const resultStep = await lazyStep.getResultStep(NO_CONCURRENCY, this.stepCount);
|
|
1880
|
-
await
|
|
1893
|
+
await this.debug?.log("INFO", "RUN_SINGLE", {
|
|
1881
1894
|
fromRequest: false,
|
|
1882
1895
|
step: resultStep,
|
|
1883
1896
|
stepCount: this.stepCount
|
|
1884
|
-
})
|
|
1897
|
+
});
|
|
1885
1898
|
await this.submitStepsToQStash([resultStep]);
|
|
1886
1899
|
return resultStep.out;
|
|
1887
1900
|
}
|
|
@@ -1896,19 +1909,19 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1896
1909
|
const initialStepCount = this.stepCount - (parallelSteps.length - 1);
|
|
1897
1910
|
const parallelCallState = this.getParallelCallState(parallelSteps.length, initialStepCount);
|
|
1898
1911
|
const sortedSteps = sortSteps(this.steps);
|
|
1899
|
-
const plannedParallelStepCount =
|
|
1912
|
+
const plannedParallelStepCount = sortedSteps[initialStepCount + this.planStepCount]?.concurrent;
|
|
1900
1913
|
if (parallelCallState !== "first" && plannedParallelStepCount !== parallelSteps.length) {
|
|
1901
1914
|
throw new QStashWorkflowError(
|
|
1902
1915
|
`Incompatible number of parallel steps when call state was '${parallelCallState}'. Expected ${parallelSteps.length}, got ${plannedParallelStepCount} from the request.`
|
|
1903
1916
|
);
|
|
1904
1917
|
}
|
|
1905
|
-
await
|
|
1918
|
+
await this.debug?.log("INFO", "RUN_PARALLEL", {
|
|
1906
1919
|
parallelCallState,
|
|
1907
1920
|
initialStepCount,
|
|
1908
1921
|
plannedParallelStepCount,
|
|
1909
1922
|
stepCount: this.stepCount,
|
|
1910
1923
|
planStepCount: this.planStepCount
|
|
1911
|
-
})
|
|
1924
|
+
});
|
|
1912
1925
|
switch (parallelCallState) {
|
|
1913
1926
|
case "first": {
|
|
1914
1927
|
const planSteps = parallelSteps.map(
|
|
@@ -1975,13 +1988,13 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1975
1988
|
*/
|
|
1976
1989
|
getParallelCallState(parallelStepCount, initialStepCount) {
|
|
1977
1990
|
const remainingSteps = this.steps.filter(
|
|
1978
|
-
(step) => (
|
|
1991
|
+
(step) => (step.targetStep ?? step.stepId) >= initialStepCount
|
|
1979
1992
|
);
|
|
1980
1993
|
if (remainingSteps.length === 0) {
|
|
1981
1994
|
return "first";
|
|
1982
1995
|
} else if (remainingSteps.length >= 2 * parallelStepCount) {
|
|
1983
1996
|
return "last";
|
|
1984
|
-
} else if (
|
|
1997
|
+
} else if (remainingSteps.at(-1)?.targetStep) {
|
|
1985
1998
|
return "partial";
|
|
1986
1999
|
} else {
|
|
1987
2000
|
return "discard";
|
|
@@ -1998,7 +2011,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1998
2011
|
`Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`
|
|
1999
2012
|
);
|
|
2000
2013
|
}
|
|
2001
|
-
await
|
|
2014
|
+
await this.debug?.log("SUBMIT", "SUBMIT_STEP", { length: steps.length, steps });
|
|
2002
2015
|
const result = await this.context.qstashClient.batchJSON(
|
|
2003
2016
|
steps.map((singleStep) => {
|
|
2004
2017
|
const headers = getHeaders(
|
|
@@ -2039,13 +2052,13 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2039
2052
|
);
|
|
2040
2053
|
})
|
|
2041
2054
|
);
|
|
2042
|
-
await
|
|
2055
|
+
await this.debug?.log("INFO", "SUBMIT_STEP", {
|
|
2043
2056
|
messageIds: result.map((message) => {
|
|
2044
2057
|
return {
|
|
2045
2058
|
message: message.messageId
|
|
2046
2059
|
};
|
|
2047
2060
|
})
|
|
2048
|
-
})
|
|
2061
|
+
});
|
|
2049
2062
|
throw new QStashWorkflowAbort(steps[0].stepName, steps[0]);
|
|
2050
2063
|
}
|
|
2051
2064
|
/**
|
|
@@ -2064,6 +2077,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2064
2077
|
* @param index index of the current step
|
|
2065
2078
|
* @returns result[index] if lazyStepList > 1, otherwise result
|
|
2066
2079
|
*/
|
|
2080
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2067
2081
|
static getResult(lazyStepList, result, index) {
|
|
2068
2082
|
if (lazyStepList.length === 1) {
|
|
2069
2083
|
return result;
|
|
@@ -2079,7 +2093,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2079
2093
|
await Promise.resolve();
|
|
2080
2094
|
await Promise.resolve();
|
|
2081
2095
|
}
|
|
2082
|
-
}
|
|
2096
|
+
};
|
|
2083
2097
|
var validateStep = (lazyStep, stepFromRequest) => {
|
|
2084
2098
|
if (lazyStep.stepName !== stepFromRequest.stepName) {
|
|
2085
2099
|
throw new QStashWorkflowError(
|
|
@@ -2115,23 +2129,23 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2115
2129
|
}
|
|
2116
2130
|
};
|
|
2117
2131
|
var sortSteps = (steps) => {
|
|
2118
|
-
const getStepId = (step) =>
|
|
2132
|
+
const getStepId = (step) => step.targetStep ?? step.stepId;
|
|
2119
2133
|
return steps.toSorted((step, stepOther) => getStepId(step) - getStepId(stepOther));
|
|
2120
2134
|
};
|
|
2121
2135
|
|
|
2122
2136
|
// src/client/workflow/steps.ts
|
|
2123
2137
|
var BaseLazyStep = class {
|
|
2124
|
-
|
|
2138
|
+
stepName;
|
|
2125
2139
|
// will be set in the subclasses
|
|
2126
2140
|
constructor(stepName) {
|
|
2127
2141
|
this.stepName = stepName;
|
|
2128
2142
|
}
|
|
2129
2143
|
};
|
|
2130
|
-
var LazyFunctionStep =
|
|
2131
|
-
|
|
2132
|
-
|
|
2144
|
+
var LazyFunctionStep = class extends BaseLazyStep {
|
|
2145
|
+
stepFunction;
|
|
2146
|
+
stepType = "Run";
|
|
2133
2147
|
constructor(stepName, stepFunction) {
|
|
2134
|
-
super(stepName);
|
|
2148
|
+
super(stepName);
|
|
2135
2149
|
this.stepFunction = stepFunction;
|
|
2136
2150
|
}
|
|
2137
2151
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -2158,12 +2172,12 @@ var LazyFunctionStep = (_class4 = class extends BaseLazyStep {
|
|
|
2158
2172
|
concurrent
|
|
2159
2173
|
};
|
|
2160
2174
|
}
|
|
2161
|
-
}
|
|
2162
|
-
var LazySleepStep =
|
|
2163
|
-
|
|
2164
|
-
|
|
2175
|
+
};
|
|
2176
|
+
var LazySleepStep = class extends BaseLazyStep {
|
|
2177
|
+
sleep;
|
|
2178
|
+
stepType = "SleepFor";
|
|
2165
2179
|
constructor(stepName, sleep) {
|
|
2166
|
-
super(stepName);
|
|
2180
|
+
super(stepName);
|
|
2167
2181
|
this.sleep = sleep;
|
|
2168
2182
|
}
|
|
2169
2183
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -2187,12 +2201,12 @@ var LazySleepStep = (_class5 = class extends BaseLazyStep {
|
|
|
2187
2201
|
concurrent
|
|
2188
2202
|
});
|
|
2189
2203
|
}
|
|
2190
|
-
}
|
|
2191
|
-
var LazySleepUntilStep =
|
|
2192
|
-
|
|
2193
|
-
|
|
2204
|
+
};
|
|
2205
|
+
var LazySleepUntilStep = class extends BaseLazyStep {
|
|
2206
|
+
sleepUntil;
|
|
2207
|
+
stepType = "SleepUntil";
|
|
2194
2208
|
constructor(stepName, sleepUntil) {
|
|
2195
|
-
super(stepName);
|
|
2209
|
+
super(stepName);
|
|
2196
2210
|
this.sleepUntil = sleepUntil;
|
|
2197
2211
|
}
|
|
2198
2212
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -2216,15 +2230,15 @@ var LazySleepUntilStep = (_class6 = class extends BaseLazyStep {
|
|
|
2216
2230
|
concurrent
|
|
2217
2231
|
});
|
|
2218
2232
|
}
|
|
2219
|
-
}
|
|
2220
|
-
var LazyCallStep =
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2233
|
+
};
|
|
2234
|
+
var LazyCallStep = class extends BaseLazyStep {
|
|
2235
|
+
url;
|
|
2236
|
+
method;
|
|
2237
|
+
body;
|
|
2238
|
+
headers;
|
|
2239
|
+
stepType = "Call";
|
|
2226
2240
|
constructor(stepName, url, method, body, headers) {
|
|
2227
|
-
super(stepName);
|
|
2241
|
+
super(stepName);
|
|
2228
2242
|
this.url = url;
|
|
2229
2243
|
this.method = method;
|
|
2230
2244
|
this.body = body;
|
|
@@ -2253,12 +2267,12 @@ var LazyCallStep = (_class7 = class extends BaseLazyStep {
|
|
|
2253
2267
|
callHeaders: this.headers
|
|
2254
2268
|
});
|
|
2255
2269
|
}
|
|
2256
|
-
}
|
|
2270
|
+
};
|
|
2257
2271
|
|
|
2258
2272
|
// src/client/workflow/context.ts
|
|
2259
2273
|
var WorkflowContext = class {
|
|
2260
|
-
|
|
2261
|
-
|
|
2274
|
+
executor;
|
|
2275
|
+
steps;
|
|
2262
2276
|
/**
|
|
2263
2277
|
* QStash client of the workflow
|
|
2264
2278
|
*
|
|
@@ -2277,11 +2291,11 @@ var WorkflowContext = class {
|
|
|
2277
2291
|
* )
|
|
2278
2292
|
* ```
|
|
2279
2293
|
*/
|
|
2280
|
-
|
|
2294
|
+
qstashClient;
|
|
2281
2295
|
/**
|
|
2282
2296
|
* Run id of the workflow
|
|
2283
2297
|
*/
|
|
2284
|
-
|
|
2298
|
+
workflowRunId;
|
|
2285
2299
|
/**
|
|
2286
2300
|
* URL of the workflow
|
|
2287
2301
|
*
|
|
@@ -2298,7 +2312,7 @@ var WorkflowContext = class {
|
|
|
2298
2312
|
* )
|
|
2299
2313
|
* ```
|
|
2300
2314
|
*/
|
|
2301
|
-
|
|
2315
|
+
url;
|
|
2302
2316
|
/**
|
|
2303
2317
|
* URL to call in case of workflow failure with QStash failure callback
|
|
2304
2318
|
*
|
|
@@ -2317,7 +2331,7 @@ var WorkflowContext = class {
|
|
|
2317
2331
|
* )
|
|
2318
2332
|
* ```
|
|
2319
2333
|
*/
|
|
2320
|
-
|
|
2334
|
+
failureUrl;
|
|
2321
2335
|
/**
|
|
2322
2336
|
* Payload of the request which started the workflow.
|
|
2323
2337
|
*
|
|
@@ -2347,15 +2361,15 @@ var WorkflowContext = class {
|
|
|
2347
2361
|
* )
|
|
2348
2362
|
* ```
|
|
2349
2363
|
*/
|
|
2350
|
-
|
|
2364
|
+
requestPayload;
|
|
2351
2365
|
/**
|
|
2352
2366
|
* headers of the initial request
|
|
2353
2367
|
*/
|
|
2354
|
-
|
|
2368
|
+
headers;
|
|
2355
2369
|
/**
|
|
2356
2370
|
* initial payload as a raw string
|
|
2357
2371
|
*/
|
|
2358
|
-
|
|
2372
|
+
rawInitialPayload;
|
|
2359
2373
|
/**
|
|
2360
2374
|
* Map of environment variables and their values.
|
|
2361
2375
|
*
|
|
@@ -2376,11 +2390,11 @@ var WorkflowContext = class {
|
|
|
2376
2390
|
*
|
|
2377
2391
|
* Default value is set to `process.env`.
|
|
2378
2392
|
*/
|
|
2379
|
-
|
|
2393
|
+
env;
|
|
2380
2394
|
/**
|
|
2381
2395
|
* Number of retries
|
|
2382
2396
|
*/
|
|
2383
|
-
|
|
2397
|
+
retries;
|
|
2384
2398
|
constructor({
|
|
2385
2399
|
qstashClient,
|
|
2386
2400
|
workflowRunId,
|
|
@@ -2401,9 +2415,9 @@ var WorkflowContext = class {
|
|
|
2401
2415
|
this.failureUrl = failureUrl;
|
|
2402
2416
|
this.headers = headers;
|
|
2403
2417
|
this.requestPayload = initialPayload;
|
|
2404
|
-
this.rawInitialPayload =
|
|
2405
|
-
this.env =
|
|
2406
|
-
this.retries =
|
|
2418
|
+
this.rawInitialPayload = rawInitialPayload ?? JSON.stringify(this.requestPayload);
|
|
2419
|
+
this.env = env ?? {};
|
|
2420
|
+
this.retries = retries ?? DEFAULT_RETRIES;
|
|
2407
2421
|
this.executor = new AutoExecutor(this, this.steps, debug);
|
|
2408
2422
|
}
|
|
2409
2423
|
/**
|
|
@@ -2489,13 +2503,14 @@ var WorkflowContext = class {
|
|
|
2489
2503
|
* @param headers call headers
|
|
2490
2504
|
* @returns call result (parsed as JSON if possible)
|
|
2491
2505
|
*/
|
|
2506
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2492
2507
|
async call(stepName, url, method, body, headers) {
|
|
2493
2508
|
const result = await this.addStep(
|
|
2494
|
-
new LazyCallStep(stepName, url, method, body,
|
|
2509
|
+
new LazyCallStep(stepName, url, method, body, headers ?? {})
|
|
2495
2510
|
);
|
|
2496
2511
|
try {
|
|
2497
2512
|
return JSON.parse(result);
|
|
2498
|
-
} catch
|
|
2513
|
+
} catch {
|
|
2499
2514
|
return result;
|
|
2500
2515
|
}
|
|
2501
2516
|
}
|
|
@@ -2507,8 +2522,8 @@ var WorkflowContext = class {
|
|
|
2507
2522
|
return await this.executor.addStep(step);
|
|
2508
2523
|
}
|
|
2509
2524
|
};
|
|
2510
|
-
var DisabledWorkflowContext =
|
|
2511
|
-
static
|
|
2525
|
+
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
2526
|
+
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
2512
2527
|
/**
|
|
2513
2528
|
* overwrite the WorkflowContext.addStep method to always raise QStashWorkflowAbort
|
|
2514
2529
|
* error in order to stop the execution whenever we encounter a step.
|
|
@@ -2553,15 +2568,15 @@ var DisabledWorkflowContext = (_class8 = class _DisabledWorkflowContext extends
|
|
|
2553
2568
|
}
|
|
2554
2569
|
return ok("run-ended");
|
|
2555
2570
|
}
|
|
2556
|
-
}
|
|
2571
|
+
};
|
|
2557
2572
|
|
|
2558
2573
|
// src/client/workflow/logger.ts
|
|
2559
2574
|
var LOG_LEVELS = ["DEBUG", "INFO", "SUBMIT", "WARN", "ERROR"];
|
|
2560
|
-
var WorkflowLogger =
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
constructor(options) {
|
|
2575
|
+
var WorkflowLogger = class _WorkflowLogger {
|
|
2576
|
+
logs = [];
|
|
2577
|
+
options;
|
|
2578
|
+
workflowRunId = void 0;
|
|
2579
|
+
constructor(options) {
|
|
2565
2580
|
this.options = options;
|
|
2566
2581
|
}
|
|
2567
2582
|
async log(level, eventType, details) {
|
|
@@ -2569,7 +2584,7 @@ var WorkflowLogger = (_class9 = class _WorkflowLogger {
|
|
|
2569
2584
|
const timestamp = Date.now();
|
|
2570
2585
|
const logEntry = {
|
|
2571
2586
|
timestamp,
|
|
2572
|
-
workflowRunId:
|
|
2587
|
+
workflowRunId: this.workflowRunId ?? "",
|
|
2573
2588
|
logLevel: level,
|
|
2574
2589
|
eventType,
|
|
2575
2590
|
details
|
|
@@ -2601,13 +2616,13 @@ var WorkflowLogger = (_class9 = class _WorkflowLogger {
|
|
|
2601
2616
|
}) : void 0;
|
|
2602
2617
|
}
|
|
2603
2618
|
}
|
|
2604
|
-
}
|
|
2619
|
+
};
|
|
2605
2620
|
|
|
2606
2621
|
// src/client/workflow/workflow-parser.ts
|
|
2607
2622
|
var getPayload = async (request) => {
|
|
2608
2623
|
try {
|
|
2609
2624
|
return await request.text();
|
|
2610
|
-
} catch
|
|
2625
|
+
} catch {
|
|
2611
2626
|
return;
|
|
2612
2627
|
}
|
|
2613
2628
|
};
|
|
@@ -2637,9 +2652,9 @@ var deduplicateSteps = (steps) => {
|
|
|
2637
2652
|
const deduplicatedSteps = [];
|
|
2638
2653
|
for (const step of steps) {
|
|
2639
2654
|
if (step.stepId === 0) {
|
|
2640
|
-
if (!targetStepIds.includes(
|
|
2655
|
+
if (!targetStepIds.includes(step.targetStep ?? 0)) {
|
|
2641
2656
|
deduplicatedSteps.push(step);
|
|
2642
|
-
targetStepIds.push(
|
|
2657
|
+
targetStepIds.push(step.targetStep ?? 0);
|
|
2643
2658
|
}
|
|
2644
2659
|
} else {
|
|
2645
2660
|
if (!stepIds.includes(step.stepId)) {
|
|
@@ -2661,7 +2676,7 @@ var checkIfLastOneIsDuplicate = async (steps, debug) => {
|
|
|
2661
2676
|
const step = steps[index];
|
|
2662
2677
|
if (step.stepId === lastStepId && step.targetStep === lastTargetStepId) {
|
|
2663
2678
|
const message = `QStash Workflow: The step '${step.stepName}' with id '${step.stepId}' has run twice during workflow execution. Rest of the workflow will continue running as usual.`;
|
|
2664
|
-
await
|
|
2679
|
+
await debug?.log("WARN", "RESPONSE_DEFAULT", message);
|
|
2665
2680
|
console.warn(message);
|
|
2666
2681
|
return true;
|
|
2667
2682
|
}
|
|
@@ -2676,7 +2691,7 @@ var validateRequest = (request) => {
|
|
|
2676
2691
|
`Incompatible workflow sdk protocol version. Expected ${WORKFLOW_PROTOCOL_VERSION}, got ${versionHeader} from the request.`
|
|
2677
2692
|
);
|
|
2678
2693
|
}
|
|
2679
|
-
const workflowRunId = isFirstInvocation ? `wfr_${nanoid()}` :
|
|
2694
|
+
const workflowRunId = isFirstInvocation ? `wfr_${nanoid()}` : request.headers.get(WORKFLOW_ID_HEADER) ?? "";
|
|
2680
2695
|
if (workflowRunId.length === 0) {
|
|
2681
2696
|
throw new QStashWorkflowError("Couldn't get workflow id from header");
|
|
2682
2697
|
}
|
|
@@ -2688,7 +2703,7 @@ var validateRequest = (request) => {
|
|
|
2688
2703
|
var parseRequest = async (requestPayload, isFirstInvocation, debug) => {
|
|
2689
2704
|
if (isFirstInvocation) {
|
|
2690
2705
|
return {
|
|
2691
|
-
rawInitialPayload:
|
|
2706
|
+
rawInitialPayload: requestPayload ?? "",
|
|
2692
2707
|
steps: [],
|
|
2693
2708
|
isLastDuplicate: false
|
|
2694
2709
|
};
|
|
@@ -2748,7 +2763,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2748
2763
|
|
|
2749
2764
|
// src/client/workflow/serve.ts
|
|
2750
2765
|
var processOptions = (options) => {
|
|
2751
|
-
const environment =
|
|
2766
|
+
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
2752
2767
|
const receiverEnvironmentVariablesSet = Boolean(
|
|
2753
2768
|
environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
|
|
2754
2769
|
);
|
|
@@ -2799,21 +2814,21 @@ var serve = (routeFunction, options) => {
|
|
|
2799
2814
|
} = processOptions(options);
|
|
2800
2815
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
2801
2816
|
const handler = async (request) => {
|
|
2802
|
-
const initialWorkflowUrl =
|
|
2817
|
+
const initialWorkflowUrl = url ?? request.url;
|
|
2803
2818
|
const workflowUrl = baseUrl ? initialWorkflowUrl.replace(/^(https?:\/\/[^/]+)(\/.*)?$/, (_, matchedBaseUrl, path) => {
|
|
2804
2819
|
return baseUrl + (path || "");
|
|
2805
2820
|
}) : initialWorkflowUrl;
|
|
2806
2821
|
if (workflowUrl !== initialWorkflowUrl) {
|
|
2807
|
-
await
|
|
2822
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
2808
2823
|
warning: `QStash Workflow: replacing the base of the url with "${baseUrl}" and using it as workflow endpoint.`,
|
|
2809
2824
|
originalURL: initialWorkflowUrl,
|
|
2810
2825
|
updatedURL: workflowUrl
|
|
2811
|
-
})
|
|
2826
|
+
});
|
|
2812
2827
|
}
|
|
2813
2828
|
const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
|
|
2814
|
-
const requestPayload = await
|
|
2829
|
+
const requestPayload = await getPayload(request) ?? "";
|
|
2815
2830
|
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
|
|
2816
|
-
await
|
|
2831
|
+
await debug?.log("INFO", "ENDPOINT_START");
|
|
2817
2832
|
const failureCheck = await handleFailure(
|
|
2818
2833
|
request,
|
|
2819
2834
|
requestPayload,
|
|
@@ -2824,11 +2839,11 @@ var serve = (routeFunction, options) => {
|
|
|
2824
2839
|
if (failureCheck.isErr()) {
|
|
2825
2840
|
throw failureCheck.error;
|
|
2826
2841
|
} else if (failureCheck.value === "is-failure-callback") {
|
|
2827
|
-
await
|
|
2842
|
+
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
2828
2843
|
return onStepFinish("no-workflow-id", "failure-callback");
|
|
2829
2844
|
}
|
|
2830
2845
|
const { isFirstInvocation, workflowRunId } = validateRequest(request);
|
|
2831
|
-
|
|
2846
|
+
debug?.setWorkflowRunId(workflowRunId);
|
|
2832
2847
|
const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
|
|
2833
2848
|
requestPayload,
|
|
2834
2849
|
isFirstInvocation,
|
|
@@ -2854,7 +2869,7 @@ var serve = (routeFunction, options) => {
|
|
|
2854
2869
|
workflowContext
|
|
2855
2870
|
);
|
|
2856
2871
|
if (authCheck.isErr()) {
|
|
2857
|
-
await
|
|
2872
|
+
await debug?.log("ERROR", "ERROR", { error: authCheck.error.message });
|
|
2858
2873
|
throw authCheck.error;
|
|
2859
2874
|
} else if (authCheck.value === "run-ended") {
|
|
2860
2875
|
return onStepFinish("no-workflow-id", "auth-fail");
|
|
@@ -2869,9 +2884,9 @@ var serve = (routeFunction, options) => {
|
|
|
2869
2884
|
debug
|
|
2870
2885
|
);
|
|
2871
2886
|
if (callReturnCheck.isErr()) {
|
|
2872
|
-
await
|
|
2887
|
+
await debug?.log("ERROR", "SUBMIT_THIRD_PARTY_RESULT", {
|
|
2873
2888
|
error: callReturnCheck.error.message
|
|
2874
|
-
})
|
|
2889
|
+
});
|
|
2875
2890
|
throw callReturnCheck.error;
|
|
2876
2891
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
2877
2892
|
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, debug) : await triggerRouteFunction({
|
|
@@ -2881,13 +2896,13 @@ var serve = (routeFunction, options) => {
|
|
|
2881
2896
|
}
|
|
2882
2897
|
});
|
|
2883
2898
|
if (result.isErr()) {
|
|
2884
|
-
await
|
|
2899
|
+
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
2885
2900
|
throw result.error;
|
|
2886
2901
|
}
|
|
2887
|
-
await
|
|
2902
|
+
await debug?.log("INFO", "RESPONSE_WORKFLOW");
|
|
2888
2903
|
return onStepFinish(workflowContext.workflowRunId, "success");
|
|
2889
2904
|
}
|
|
2890
|
-
await
|
|
2905
|
+
await debug?.log("INFO", "RESPONSE_DEFAULT");
|
|
2891
2906
|
return onStepFinish("no-workflow-id", "fromCallback");
|
|
2892
2907
|
};
|
|
2893
2908
|
return async (request) => {
|
|
@@ -2902,7 +2917,7 @@ var serve = (routeFunction, options) => {
|
|
|
2902
2917
|
|
|
2903
2918
|
// src/client/workflow/index.ts
|
|
2904
2919
|
var Workflow = class {
|
|
2905
|
-
|
|
2920
|
+
http;
|
|
2906
2921
|
constructor(http) {
|
|
2907
2922
|
this.http = http;
|
|
2908
2923
|
}
|
|
@@ -2918,35 +2933,26 @@ var Workflow = class {
|
|
|
2918
2933
|
method: "DELETE",
|
|
2919
2934
|
parseResponseAsJson: false
|
|
2920
2935
|
});
|
|
2921
|
-
return
|
|
2936
|
+
return result ?? true;
|
|
2922
2937
|
}
|
|
2923
2938
|
};
|
|
2924
2939
|
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
exports.SignatureError = SignatureError; exports.Receiver = Receiver; exports.QstashError = QstashError; exports.QstashRatelimitError = QstashRatelimitError; exports.QstashChatRatelimitError = QstashChatRatelimitError; exports.QstashDailyRatelimitError = QstashDailyRatelimitError; exports.QStashWorkflowError = QStashWorkflowError; exports.QStashWorkflowAbort = QStashWorkflowAbort; exports.formatWorkflowError = formatWorkflowError; exports.setupAnalytics = setupAnalytics; exports.upstash = upstash; exports.openai = openai; exports.custom = custom; exports.Chat = Chat; exports.Messages = Messages; exports.decodeBase64 = decodeBase64; exports.Schedules = Schedules; exports.UrlGroups = UrlGroups; exports.StepTypes = StepTypes; exports.WorkflowContext = WorkflowContext; exports.DisabledWorkflowContext = DisabledWorkflowContext; exports.WorkflowLogger = WorkflowLogger; exports.processOptions = processOptions; exports.serve = serve; exports.Workflow = Workflow; exports.Client = Client;
|
|
2940
|
+
// platforms/hono.ts
|
|
2941
|
+
var serve2 = (routeFunction, options) => {
|
|
2942
|
+
const handler = async (context) => {
|
|
2943
|
+
const environment = context.env;
|
|
2944
|
+
const request = context.req.raw;
|
|
2945
|
+
const serveHandler = serve(routeFunction, {
|
|
2946
|
+
// when hono is used without cf workers, it sends a DebugHTTPServer
|
|
2947
|
+
// object in `context.env`. don't pass env if this is the case:
|
|
2948
|
+
env: "QSTASH_TOKEN" in environment ? environment : void 0,
|
|
2949
|
+
...options
|
|
2950
|
+
});
|
|
2951
|
+
return await serveHandler(request);
|
|
2952
|
+
};
|
|
2953
|
+
return handler;
|
|
2954
|
+
};
|
|
2955
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2956
|
+
0 && (module.exports = {
|
|
2957
|
+
serve
|
|
2958
|
+
});
|