@upstash/qstash 2.7.10 → 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-HIWMJGFU.mjs → dist/chunk-KWSSCN6R.mjs} +39 -20
- package/{chunk-O2RN672L.mjs → dist/chunk-XLCNEVA2.mjs} +1 -1
- package/{client-orcgOcAm.d.mts → dist/client-DkrYCqaq.d.mts} +26 -17
- package/{client-orcgOcAm.d.ts → dist/client-DkrYCqaq.d.ts} +26 -17
- package/{cloudflare.d.mts → dist/cloudflare.d.mts} +1 -1
- package/{cloudflare.d.ts → dist/cloudflare.d.ts} +1 -1
- package/{chunk-KZOQ64Z6.js → dist/cloudflare.js} +265 -255
- package/{cloudflare.mjs → dist/cloudflare.mjs} +1 -1
- package/{h3.d.mts → dist/h3.d.mts} +1 -1
- package/{h3.d.ts → dist/h3.d.ts} +1 -1
- package/dist/h3.js +3338 -0
- package/{h3.mjs → dist/h3.mjs} +2 -2
- package/{hono.d.mts → dist/hono.d.mts} +1 -1
- package/{hono.d.ts → dist/hono.d.ts} +1 -1
- package/dist/hono.js +2958 -0
- package/{hono.mjs → dist/hono.mjs} +1 -1
- package/{index.d.mts → dist/index.d.mts} +2 -2
- package/{index.d.ts → dist/index.d.ts} +2 -2
- package/dist/index.js +1639 -0
- package/{index.mjs → dist/index.mjs} +1 -1
- package/{nextjs.d.mts → dist/nextjs.d.mts} +1 -1
- package/{nextjs.d.ts → dist/nextjs.d.ts} +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/{solidjs.d.mts → dist/solidjs.d.mts} +1 -1
- package/{solidjs.d.ts → dist/solidjs.d.ts} +1 -1
- package/dist/solidjs.js +2991 -0
- package/{solidjs.mjs → dist/solidjs.mjs} +1 -1
- package/{svelte.d.mts → dist/svelte.d.mts} +1 -1
- package/{svelte.d.ts → dist/svelte.d.ts} +1 -1
- package/dist/svelte.js +2988 -0
- package/{svelte.mjs → dist/svelte.mjs} +1 -1
- package/{workflow.d.mts → dist/workflow.d.mts} +1 -1
- package/{workflow.d.ts → dist/workflow.d.ts} +1 -1
- package/dist/workflow.js +2954 -0
- package/{workflow.mjs → dist/workflow.mjs} +1 -1
- package/package.json +1 -1
- package/chunk-Q6JW7JKT.js +0 -403
- package/chunk-VN7YQ2UN.js +0 -1
- 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/{nuxt.d.mts → dist/nuxt.d.mts} +0 -0
- /package/{nuxt.d.ts → dist/nuxt.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/cloudflare.ts
|
|
31
|
+
var cloudflare_exports = {};
|
|
32
|
+
__export(cloudflare_exports, {
|
|
33
|
+
serve: () => serve2
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(cloudflare_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,43 +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
|
-
organization: void 0
|
|
357
|
-
};
|
|
358
|
-
};
|
|
359
|
-
var openai = ({
|
|
360
|
-
token,
|
|
361
|
-
organization
|
|
362
|
-
}) => {
|
|
363
|
-
return {
|
|
364
|
-
token,
|
|
365
|
-
owner: "openai",
|
|
366
|
-
baseUrl: "https://api.openai.com",
|
|
367
|
-
organization
|
|
368
|
-
};
|
|
369
|
-
};
|
|
370
|
-
var custom = ({
|
|
371
|
-
baseUrl,
|
|
372
|
-
token
|
|
373
|
-
}) => {
|
|
374
|
-
const trimmedBaseUrl = baseUrl.replace(/\/(v1\/)?chat\/completions$/, "");
|
|
375
|
-
return {
|
|
376
|
-
token,
|
|
377
|
-
owner: "custom",
|
|
378
|
-
baseUrl: trimmedBaseUrl,
|
|
379
|
-
organization: void 0
|
|
380
|
-
};
|
|
381
|
-
};
|
|
382
387
|
|
|
383
388
|
// src/client/llm/chat.ts
|
|
384
|
-
var Chat =
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
constructor(http, token) {
|
|
389
|
+
var Chat = class _Chat {
|
|
390
|
+
http;
|
|
391
|
+
token;
|
|
392
|
+
constructor(http, token) {
|
|
388
393
|
this.http = http;
|
|
389
394
|
this.token = token;
|
|
390
395
|
}
|
|
@@ -406,7 +411,7 @@ var Chat = (_class2 = class _Chat {
|
|
|
406
411
|
* @param request ChatRequest with messages
|
|
407
412
|
* @returns Chat completion or stream
|
|
408
413
|
*/
|
|
409
|
-
|
|
414
|
+
create = async (request) => {
|
|
410
415
|
if (request.provider.owner != "upstash")
|
|
411
416
|
return this.createThirdParty(request);
|
|
412
417
|
const body = JSON.stringify(request);
|
|
@@ -444,7 +449,7 @@ var Chat = (_class2 = class _Chat {
|
|
|
444
449
|
baseUrl,
|
|
445
450
|
body
|
|
446
451
|
});
|
|
447
|
-
}
|
|
452
|
+
};
|
|
448
453
|
/**
|
|
449
454
|
* Calls the Upstash completions api given a ChatRequest.
|
|
450
455
|
*
|
|
@@ -455,8 +460,8 @@ var Chat = (_class2 = class _Chat {
|
|
|
455
460
|
* @returns Chat completion or stream
|
|
456
461
|
*/
|
|
457
462
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
458
|
-
|
|
459
|
-
const { baseUrl, token, owner
|
|
463
|
+
createThirdParty = async (request) => {
|
|
464
|
+
const { baseUrl, token, owner } = request.provider;
|
|
460
465
|
if (owner === "upstash")
|
|
461
466
|
throw new Error("Upstash is not 3rd party provider!");
|
|
462
467
|
delete request.provider;
|
|
@@ -464,15 +469,12 @@ var Chat = (_class2 = class _Chat {
|
|
|
464
469
|
const analytics = request.analytics;
|
|
465
470
|
delete request.analytics;
|
|
466
471
|
const body = JSON.stringify(request);
|
|
467
|
-
const isAnalyticsEnabled =
|
|
468
|
-
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 };
|
|
469
474
|
const isStream = "stream" in request && request.stream;
|
|
470
475
|
const headers = {
|
|
471
476
|
"Content-Type": "application/json",
|
|
472
477
|
Authorization: `Bearer ${token}`,
|
|
473
|
-
...organization ? {
|
|
474
|
-
"OpenAI-Organization": organization
|
|
475
|
-
} : {},
|
|
476
478
|
...isStream ? {
|
|
477
479
|
Connection: "keep-alive",
|
|
478
480
|
Accept: "text/event-stream",
|
|
@@ -488,7 +490,7 @@ var Chat = (_class2 = class _Chat {
|
|
|
488
490
|
baseUrl: analyticsConfig.baseURL
|
|
489
491
|
});
|
|
490
492
|
return response;
|
|
491
|
-
}
|
|
493
|
+
};
|
|
492
494
|
// Helper method to get the authorization token
|
|
493
495
|
getAuthorizationToken() {
|
|
494
496
|
const authHeader = String(this.http.authorization);
|
|
@@ -509,11 +511,11 @@ var Chat = (_class2 = class _Chat {
|
|
|
509
511
|
* mistralai/Mistral-7B-Instruct-v0.2 model.
|
|
510
512
|
* @returns Chat completion or stream
|
|
511
513
|
*/
|
|
512
|
-
|
|
514
|
+
prompt = async (request) => {
|
|
513
515
|
const chatRequest = _Chat.toChatRequest(request);
|
|
514
516
|
return this.create(chatRequest);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
+
};
|
|
518
|
+
};
|
|
517
519
|
|
|
518
520
|
// src/client/llm/utils.ts
|
|
519
521
|
function appendLLMOptionsIfNeeded(request, headers, http) {
|
|
@@ -521,7 +523,7 @@ function appendLLMOptionsIfNeeded(request, headers, http) {
|
|
|
521
523
|
return;
|
|
522
524
|
const provider = request.api.provider;
|
|
523
525
|
const analytics = request.api.analytics;
|
|
524
|
-
if (
|
|
526
|
+
if (provider?.owner === "upstash") {
|
|
525
527
|
handleUpstashProvider(request, headers, http, analytics);
|
|
526
528
|
return;
|
|
527
529
|
}
|
|
@@ -543,7 +545,7 @@ function handleUpstashProvider(request, headers, http, analytics) {
|
|
|
543
545
|
{ name: analytics.name, token: analytics.token },
|
|
544
546
|
//@ts-expect-error hacky way to get bearer token
|
|
545
547
|
String(http.authorization).split("Bearer ")[1],
|
|
546
|
-
|
|
548
|
+
request.api?.provider?.baseUrl,
|
|
547
549
|
"upstash"
|
|
548
550
|
);
|
|
549
551
|
setAnalyticsHeaders(headers, analyticsConfig);
|
|
@@ -553,28 +555,28 @@ function handleUpstashProvider(request, headers, http, analytics) {
|
|
|
553
555
|
}
|
|
554
556
|
}
|
|
555
557
|
function validateProviderConfig(provider) {
|
|
556
|
-
if (!
|
|
558
|
+
if (!provider?.baseUrl)
|
|
557
559
|
throw new Error("baseUrl cannot be empty or undefined!");
|
|
558
560
|
if (!provider.token)
|
|
559
561
|
throw new Error("token cannot be empty or undefined!");
|
|
560
562
|
return { baseUrl: provider.baseUrl, token: provider.token };
|
|
561
563
|
}
|
|
562
564
|
function setAnalyticsHeaders(headers, analyticsConfig) {
|
|
563
|
-
headers.set("Helicone-Auth",
|
|
564
|
-
headers.set("Authorization",
|
|
565
|
-
if (
|
|
565
|
+
headers.set("Helicone-Auth", analyticsConfig.defaultHeaders?.["Helicone-Auth"] ?? "");
|
|
566
|
+
headers.set("Authorization", analyticsConfig.defaultHeaders?.Authorization ?? "");
|
|
567
|
+
if (analyticsConfig.defaultHeaders?.["Helicone-Target-Url"]) {
|
|
566
568
|
headers.set("Helicone-Target-Url", analyticsConfig.defaultHeaders["Helicone-Target-Url"]);
|
|
567
569
|
}
|
|
568
570
|
}
|
|
569
571
|
function ensureCallbackPresent(request) {
|
|
570
|
-
if (
|
|
572
|
+
if (request.api?.name === "llm" && !request.callback) {
|
|
571
573
|
throw new TypeError("Callback cannot be undefined when using LLM");
|
|
572
574
|
}
|
|
573
575
|
}
|
|
574
576
|
|
|
575
577
|
// src/client/messages.ts
|
|
576
578
|
var Messages = class {
|
|
577
|
-
|
|
579
|
+
http;
|
|
578
580
|
constructor(http) {
|
|
579
581
|
this.http = http;
|
|
580
582
|
}
|
|
@@ -638,7 +640,7 @@ function prefixHeaders(headers) {
|
|
|
638
640
|
}
|
|
639
641
|
function processHeaders(request) {
|
|
640
642
|
const headers = prefixHeaders(new Headers(request.headers));
|
|
641
|
-
headers.set("Upstash-Method",
|
|
643
|
+
headers.set("Upstash-Method", request.method ?? "POST");
|
|
642
644
|
if (request.delay !== void 0) {
|
|
643
645
|
if (typeof request.delay === "string") {
|
|
644
646
|
headers.set("Upstash-Delay", request.delay);
|
|
@@ -674,7 +676,7 @@ function processHeaders(request) {
|
|
|
674
676
|
return headers;
|
|
675
677
|
}
|
|
676
678
|
function getRequestPath(request) {
|
|
677
|
-
return
|
|
679
|
+
return request.url ?? request.urlGroup ?? request.topic ?? `api/${request.api?.name}`;
|
|
678
680
|
}
|
|
679
681
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
680
682
|
var NANOID_LENGTH = 21;
|
|
@@ -688,7 +690,7 @@ function decodeBase64(base64) {
|
|
|
688
690
|
return new TextDecoder().decode(intArray);
|
|
689
691
|
} catch (error) {
|
|
690
692
|
console.warn(
|
|
691
|
-
`Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
|
|
693
|
+
`Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. Error: ${error}`
|
|
692
694
|
);
|
|
693
695
|
return atob(base64);
|
|
694
696
|
}
|
|
@@ -696,8 +698,8 @@ function decodeBase64(base64) {
|
|
|
696
698
|
|
|
697
699
|
// src/client/queue.ts
|
|
698
700
|
var Queue = class {
|
|
699
|
-
|
|
700
|
-
|
|
701
|
+
http;
|
|
702
|
+
queueName;
|
|
701
703
|
constructor(http, queueName) {
|
|
702
704
|
this.http = http;
|
|
703
705
|
this.queueName = queueName;
|
|
@@ -711,8 +713,8 @@ var Queue = class {
|
|
|
711
713
|
}
|
|
712
714
|
const body = {
|
|
713
715
|
queueName: this.queueName,
|
|
714
|
-
parallelism:
|
|
715
|
-
paused:
|
|
716
|
+
parallelism: request.parallelism ?? 1,
|
|
717
|
+
paused: request.paused ?? false
|
|
716
718
|
};
|
|
717
719
|
await this.http.request({
|
|
718
720
|
method: "POST",
|
|
@@ -823,7 +825,7 @@ var Queue = class {
|
|
|
823
825
|
|
|
824
826
|
// src/client/schedules.ts
|
|
825
827
|
var Schedules = class {
|
|
826
|
-
|
|
828
|
+
http;
|
|
827
829
|
constructor(http) {
|
|
828
830
|
this.http = http;
|
|
829
831
|
}
|
|
@@ -927,7 +929,7 @@ var Schedules = class {
|
|
|
927
929
|
|
|
928
930
|
// src/client/url-groups.ts
|
|
929
931
|
var UrlGroups = class {
|
|
930
|
-
|
|
932
|
+
http;
|
|
931
933
|
constructor(http) {
|
|
932
934
|
this.http = http;
|
|
933
935
|
}
|
|
@@ -987,8 +989,8 @@ var UrlGroups = class {
|
|
|
987
989
|
|
|
988
990
|
// src/client/client.ts
|
|
989
991
|
var Client = class {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
+
http;
|
|
993
|
+
token;
|
|
992
994
|
constructor(config) {
|
|
993
995
|
this.http = new HttpClient({
|
|
994
996
|
retry: config.retry,
|
|
@@ -1053,7 +1055,7 @@ var Client = class {
|
|
|
1053
1055
|
* Create, read, update or delete queues.
|
|
1054
1056
|
*/
|
|
1055
1057
|
queue(request) {
|
|
1056
|
-
return new Queue(this.http,
|
|
1058
|
+
return new Queue(this.http, request?.queueName);
|
|
1057
1059
|
}
|
|
1058
1060
|
/**
|
|
1059
1061
|
* Access the Chat API
|
|
@@ -1152,12 +1154,12 @@ var Client = class {
|
|
|
1152
1154
|
*/
|
|
1153
1155
|
async events(request) {
|
|
1154
1156
|
const query = {};
|
|
1155
|
-
if (typeof
|
|
1157
|
+
if (typeof request?.cursor === "number" && request.cursor > 0) {
|
|
1156
1158
|
query.cursor = request.cursor.toString();
|
|
1157
|
-
} else if (typeof
|
|
1159
|
+
} else if (typeof request?.cursor === "string" && request.cursor !== "") {
|
|
1158
1160
|
query.cursor = request.cursor;
|
|
1159
1161
|
}
|
|
1160
|
-
for (const [key, value] of Object.entries(
|
|
1162
|
+
for (const [key, value] of Object.entries(request?.filter ?? {})) {
|
|
1161
1163
|
if (typeof value === "number" && value < 0) {
|
|
1162
1164
|
continue;
|
|
1163
1165
|
}
|
|
@@ -1581,11 +1583,11 @@ var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
|
1581
1583
|
workflowContext.failureUrl,
|
|
1582
1584
|
retries
|
|
1583
1585
|
);
|
|
1584
|
-
await
|
|
1586
|
+
await debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
|
|
1585
1587
|
headers,
|
|
1586
1588
|
requestPayload: workflowContext.requestPayload,
|
|
1587
1589
|
url: workflowContext.url
|
|
1588
|
-
})
|
|
1590
|
+
});
|
|
1589
1591
|
try {
|
|
1590
1592
|
await workflowContext.qstashClient.publishJSON({
|
|
1591
1593
|
headers,
|
|
@@ -1613,15 +1615,15 @@ var triggerRouteFunction = async ({
|
|
|
1613
1615
|
}
|
|
1614
1616
|
};
|
|
1615
1617
|
var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
1616
|
-
await
|
|
1618
|
+
await debug?.log("SUBMIT", "SUBMIT_CLEANUP", {
|
|
1617
1619
|
deletedWorkflowRunId: workflowContext.workflowRunId
|
|
1618
|
-
})
|
|
1620
|
+
});
|
|
1619
1621
|
const result = await workflowContext.qstashClient.http.request({
|
|
1620
1622
|
path: ["v2", "workflows", "runs", `${workflowContext.workflowRunId}?cancel=${cancel}`],
|
|
1621
1623
|
method: "DELETE",
|
|
1622
1624
|
parseResponseAsJson: false
|
|
1623
1625
|
});
|
|
1624
|
-
await
|
|
1626
|
+
await debug?.log("SUBMIT", "SUBMIT_CLEANUP", result);
|
|
1625
1627
|
};
|
|
1626
1628
|
var recreateUserHeaders = (headers) => {
|
|
1627
1629
|
const filteredHeaders = new Headers();
|
|
@@ -1639,13 +1641,13 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
|
|
|
1639
1641
|
if (request.headers.get("Upstash-Workflow-Callback")) {
|
|
1640
1642
|
const callbackMessage = JSON.parse(requestPayload);
|
|
1641
1643
|
if (!(callbackMessage.status >= 200 && callbackMessage.status < 300)) {
|
|
1642
|
-
await
|
|
1644
|
+
await debug?.log("WARN", "SUBMIT_THIRD_PARTY_RESULT", {
|
|
1643
1645
|
status: callbackMessage.status,
|
|
1644
|
-
body:
|
|
1645
|
-
})
|
|
1646
|
+
body: decodeBase64(callbackMessage.body)
|
|
1647
|
+
});
|
|
1646
1648
|
console.warn(
|
|
1647
1649
|
`Workflow Warning: "context.call" failed with status ${callbackMessage.status} and will retry (if there are retries remaining). Error Message:
|
|
1648
|
-
${
|
|
1650
|
+
${decodeBase64(callbackMessage.body)}`
|
|
1649
1651
|
);
|
|
1650
1652
|
return ok("call-will-retry");
|
|
1651
1653
|
}
|
|
@@ -1681,23 +1683,23 @@ ${atob(callbackMessage.body)}`
|
|
|
1681
1683
|
stepId: Number(stepIdString),
|
|
1682
1684
|
stepName,
|
|
1683
1685
|
stepType,
|
|
1684
|
-
out:
|
|
1686
|
+
out: decodeBase64(callbackMessage.body),
|
|
1685
1687
|
concurrent: Number(concurrentString)
|
|
1686
1688
|
};
|
|
1687
|
-
await
|
|
1689
|
+
await debug?.log("SUBMIT", "SUBMIT_THIRD_PARTY_RESULT", {
|
|
1688
1690
|
step: callResultStep,
|
|
1689
1691
|
headers: requestHeaders,
|
|
1690
1692
|
url: workflowUrl
|
|
1691
|
-
})
|
|
1693
|
+
});
|
|
1692
1694
|
const result = await client.publishJSON({
|
|
1693
1695
|
headers: requestHeaders,
|
|
1694
1696
|
method: "POST",
|
|
1695
1697
|
body: callResultStep,
|
|
1696
1698
|
url: workflowUrl
|
|
1697
1699
|
});
|
|
1698
|
-
await
|
|
1700
|
+
await debug?.log("SUBMIT", "SUBMIT_THIRD_PARTY_RESULT", {
|
|
1699
1701
|
messageId: result.messageId
|
|
1700
|
-
})
|
|
1702
|
+
});
|
|
1701
1703
|
return ok("is-call-return");
|
|
1702
1704
|
} else {
|
|
1703
1705
|
return ok("continue-workflow");
|
|
@@ -1727,14 +1729,14 @@ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step
|
|
|
1727
1729
|
};
|
|
1728
1730
|
if (userHeaders) {
|
|
1729
1731
|
for (const header of userHeaders.keys()) {
|
|
1730
|
-
if (
|
|
1732
|
+
if (step?.callHeaders) {
|
|
1731
1733
|
baseHeaders[`Upstash-Callback-Forward-${header}`] = userHeaders.get(header);
|
|
1732
1734
|
} else {
|
|
1733
1735
|
baseHeaders[`Upstash-Forward-${header}`] = userHeaders.get(header);
|
|
1734
1736
|
}
|
|
1735
1737
|
}
|
|
1736
1738
|
}
|
|
1737
|
-
if (
|
|
1739
|
+
if (step?.callHeaders) {
|
|
1738
1740
|
const forwardedHeaders = Object.fromEntries(
|
|
1739
1741
|
Object.entries(step.callHeaders).map(([header, value]) => [
|
|
1740
1742
|
`Upstash-Forward-${header}`,
|
|
@@ -1755,7 +1757,7 @@ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step
|
|
|
1755
1757
|
"Upstash-Callback-Forward-Upstash-Workflow-StepName": step.stepName,
|
|
1756
1758
|
"Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
|
|
1757
1759
|
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
1758
|
-
"Upstash-Callback-Forward-Upstash-Workflow-ContentType":
|
|
1760
|
+
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType ?? DEFAULT_CONTENT_TYPE,
|
|
1759
1761
|
"Upstash-Workflow-CallType": "toCallback"
|
|
1760
1762
|
};
|
|
1761
1763
|
}
|
|
@@ -1788,18 +1790,18 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
1788
1790
|
};
|
|
1789
1791
|
|
|
1790
1792
|
// src/client/workflow/auto-executor.ts
|
|
1791
|
-
var AutoExecutor =
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
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) {
|
|
1803
1805
|
this.context = context;
|
|
1804
1806
|
this.debug = debug;
|
|
1805
1807
|
this.steps = steps;
|
|
@@ -1829,7 +1831,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1829
1831
|
);
|
|
1830
1832
|
}
|
|
1831
1833
|
this.stepCount += 1;
|
|
1832
|
-
const lazyStepList =
|
|
1834
|
+
const lazyStepList = this.activeLazyStepList ?? [];
|
|
1833
1835
|
if (!this.activeLazyStepList) {
|
|
1834
1836
|
this.activeLazyStepList = lazyStepList;
|
|
1835
1837
|
this.indexInCurrentList = 0;
|
|
@@ -1880,19 +1882,19 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1880
1882
|
if (this.stepCount < this.nonPlanStepCount) {
|
|
1881
1883
|
const step = this.steps[this.stepCount + this.planStepCount];
|
|
1882
1884
|
validateStep(lazyStep, step);
|
|
1883
|
-
await
|
|
1885
|
+
await this.debug?.log("INFO", "RUN_SINGLE", {
|
|
1884
1886
|
fromRequest: true,
|
|
1885
1887
|
step,
|
|
1886
1888
|
stepCount: this.stepCount
|
|
1887
|
-
})
|
|
1889
|
+
});
|
|
1888
1890
|
return step.out;
|
|
1889
1891
|
}
|
|
1890
1892
|
const resultStep = await lazyStep.getResultStep(NO_CONCURRENCY, this.stepCount);
|
|
1891
|
-
await
|
|
1893
|
+
await this.debug?.log("INFO", "RUN_SINGLE", {
|
|
1892
1894
|
fromRequest: false,
|
|
1893
1895
|
step: resultStep,
|
|
1894
1896
|
stepCount: this.stepCount
|
|
1895
|
-
})
|
|
1897
|
+
});
|
|
1896
1898
|
await this.submitStepsToQStash([resultStep]);
|
|
1897
1899
|
return resultStep.out;
|
|
1898
1900
|
}
|
|
@@ -1907,19 +1909,19 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1907
1909
|
const initialStepCount = this.stepCount - (parallelSteps.length - 1);
|
|
1908
1910
|
const parallelCallState = this.getParallelCallState(parallelSteps.length, initialStepCount);
|
|
1909
1911
|
const sortedSteps = sortSteps(this.steps);
|
|
1910
|
-
const plannedParallelStepCount =
|
|
1912
|
+
const plannedParallelStepCount = sortedSteps[initialStepCount + this.planStepCount]?.concurrent;
|
|
1911
1913
|
if (parallelCallState !== "first" && plannedParallelStepCount !== parallelSteps.length) {
|
|
1912
1914
|
throw new QStashWorkflowError(
|
|
1913
1915
|
`Incompatible number of parallel steps when call state was '${parallelCallState}'. Expected ${parallelSteps.length}, got ${plannedParallelStepCount} from the request.`
|
|
1914
1916
|
);
|
|
1915
1917
|
}
|
|
1916
|
-
await
|
|
1918
|
+
await this.debug?.log("INFO", "RUN_PARALLEL", {
|
|
1917
1919
|
parallelCallState,
|
|
1918
1920
|
initialStepCount,
|
|
1919
1921
|
plannedParallelStepCount,
|
|
1920
1922
|
stepCount: this.stepCount,
|
|
1921
1923
|
planStepCount: this.planStepCount
|
|
1922
|
-
})
|
|
1924
|
+
});
|
|
1923
1925
|
switch (parallelCallState) {
|
|
1924
1926
|
case "first": {
|
|
1925
1927
|
const planSteps = parallelSteps.map(
|
|
@@ -1986,13 +1988,13 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1986
1988
|
*/
|
|
1987
1989
|
getParallelCallState(parallelStepCount, initialStepCount) {
|
|
1988
1990
|
const remainingSteps = this.steps.filter(
|
|
1989
|
-
(step) => (
|
|
1991
|
+
(step) => (step.targetStep ?? step.stepId) >= initialStepCount
|
|
1990
1992
|
);
|
|
1991
1993
|
if (remainingSteps.length === 0) {
|
|
1992
1994
|
return "first";
|
|
1993
1995
|
} else if (remainingSteps.length >= 2 * parallelStepCount) {
|
|
1994
1996
|
return "last";
|
|
1995
|
-
} else if (
|
|
1997
|
+
} else if (remainingSteps.at(-1)?.targetStep) {
|
|
1996
1998
|
return "partial";
|
|
1997
1999
|
} else {
|
|
1998
2000
|
return "discard";
|
|
@@ -2009,7 +2011,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2009
2011
|
`Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`
|
|
2010
2012
|
);
|
|
2011
2013
|
}
|
|
2012
|
-
await
|
|
2014
|
+
await this.debug?.log("SUBMIT", "SUBMIT_STEP", { length: steps.length, steps });
|
|
2013
2015
|
const result = await this.context.qstashClient.batchJSON(
|
|
2014
2016
|
steps.map((singleStep) => {
|
|
2015
2017
|
const headers = getHeaders(
|
|
@@ -2050,13 +2052,13 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2050
2052
|
);
|
|
2051
2053
|
})
|
|
2052
2054
|
);
|
|
2053
|
-
await
|
|
2055
|
+
await this.debug?.log("INFO", "SUBMIT_STEP", {
|
|
2054
2056
|
messageIds: result.map((message) => {
|
|
2055
2057
|
return {
|
|
2056
2058
|
message: message.messageId
|
|
2057
2059
|
};
|
|
2058
2060
|
})
|
|
2059
|
-
})
|
|
2061
|
+
});
|
|
2060
2062
|
throw new QStashWorkflowAbort(steps[0].stepName, steps[0]);
|
|
2061
2063
|
}
|
|
2062
2064
|
/**
|
|
@@ -2075,6 +2077,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2075
2077
|
* @param index index of the current step
|
|
2076
2078
|
* @returns result[index] if lazyStepList > 1, otherwise result
|
|
2077
2079
|
*/
|
|
2080
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2078
2081
|
static getResult(lazyStepList, result, index) {
|
|
2079
2082
|
if (lazyStepList.length === 1) {
|
|
2080
2083
|
return result;
|
|
@@ -2090,7 +2093,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2090
2093
|
await Promise.resolve();
|
|
2091
2094
|
await Promise.resolve();
|
|
2092
2095
|
}
|
|
2093
|
-
}
|
|
2096
|
+
};
|
|
2094
2097
|
var validateStep = (lazyStep, stepFromRequest) => {
|
|
2095
2098
|
if (lazyStep.stepName !== stepFromRequest.stepName) {
|
|
2096
2099
|
throw new QStashWorkflowError(
|
|
@@ -2126,23 +2129,23 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2126
2129
|
}
|
|
2127
2130
|
};
|
|
2128
2131
|
var sortSteps = (steps) => {
|
|
2129
|
-
const getStepId = (step) =>
|
|
2132
|
+
const getStepId = (step) => step.targetStep ?? step.stepId;
|
|
2130
2133
|
return steps.toSorted((step, stepOther) => getStepId(step) - getStepId(stepOther));
|
|
2131
2134
|
};
|
|
2132
2135
|
|
|
2133
2136
|
// src/client/workflow/steps.ts
|
|
2134
2137
|
var BaseLazyStep = class {
|
|
2135
|
-
|
|
2138
|
+
stepName;
|
|
2136
2139
|
// will be set in the subclasses
|
|
2137
2140
|
constructor(stepName) {
|
|
2138
2141
|
this.stepName = stepName;
|
|
2139
2142
|
}
|
|
2140
2143
|
};
|
|
2141
|
-
var LazyFunctionStep =
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
+
var LazyFunctionStep = class extends BaseLazyStep {
|
|
2145
|
+
stepFunction;
|
|
2146
|
+
stepType = "Run";
|
|
2144
2147
|
constructor(stepName, stepFunction) {
|
|
2145
|
-
super(stepName);
|
|
2148
|
+
super(stepName);
|
|
2146
2149
|
this.stepFunction = stepFunction;
|
|
2147
2150
|
}
|
|
2148
2151
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -2169,12 +2172,12 @@ var LazyFunctionStep = (_class4 = class extends BaseLazyStep {
|
|
|
2169
2172
|
concurrent
|
|
2170
2173
|
};
|
|
2171
2174
|
}
|
|
2172
|
-
}
|
|
2173
|
-
var LazySleepStep =
|
|
2174
|
-
|
|
2175
|
-
|
|
2175
|
+
};
|
|
2176
|
+
var LazySleepStep = class extends BaseLazyStep {
|
|
2177
|
+
sleep;
|
|
2178
|
+
stepType = "SleepFor";
|
|
2176
2179
|
constructor(stepName, sleep) {
|
|
2177
|
-
super(stepName);
|
|
2180
|
+
super(stepName);
|
|
2178
2181
|
this.sleep = sleep;
|
|
2179
2182
|
}
|
|
2180
2183
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -2198,12 +2201,12 @@ var LazySleepStep = (_class5 = class extends BaseLazyStep {
|
|
|
2198
2201
|
concurrent
|
|
2199
2202
|
});
|
|
2200
2203
|
}
|
|
2201
|
-
}
|
|
2202
|
-
var LazySleepUntilStep =
|
|
2203
|
-
|
|
2204
|
-
|
|
2204
|
+
};
|
|
2205
|
+
var LazySleepUntilStep = class extends BaseLazyStep {
|
|
2206
|
+
sleepUntil;
|
|
2207
|
+
stepType = "SleepUntil";
|
|
2205
2208
|
constructor(stepName, sleepUntil) {
|
|
2206
|
-
super(stepName);
|
|
2209
|
+
super(stepName);
|
|
2207
2210
|
this.sleepUntil = sleepUntil;
|
|
2208
2211
|
}
|
|
2209
2212
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -2227,15 +2230,15 @@ var LazySleepUntilStep = (_class6 = class extends BaseLazyStep {
|
|
|
2227
2230
|
concurrent
|
|
2228
2231
|
});
|
|
2229
2232
|
}
|
|
2230
|
-
}
|
|
2231
|
-
var LazyCallStep =
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2233
|
+
};
|
|
2234
|
+
var LazyCallStep = class extends BaseLazyStep {
|
|
2235
|
+
url;
|
|
2236
|
+
method;
|
|
2237
|
+
body;
|
|
2238
|
+
headers;
|
|
2239
|
+
stepType = "Call";
|
|
2237
2240
|
constructor(stepName, url, method, body, headers) {
|
|
2238
|
-
super(stepName);
|
|
2241
|
+
super(stepName);
|
|
2239
2242
|
this.url = url;
|
|
2240
2243
|
this.method = method;
|
|
2241
2244
|
this.body = body;
|
|
@@ -2264,12 +2267,12 @@ var LazyCallStep = (_class7 = class extends BaseLazyStep {
|
|
|
2264
2267
|
callHeaders: this.headers
|
|
2265
2268
|
});
|
|
2266
2269
|
}
|
|
2267
|
-
}
|
|
2270
|
+
};
|
|
2268
2271
|
|
|
2269
2272
|
// src/client/workflow/context.ts
|
|
2270
2273
|
var WorkflowContext = class {
|
|
2271
|
-
|
|
2272
|
-
|
|
2274
|
+
executor;
|
|
2275
|
+
steps;
|
|
2273
2276
|
/**
|
|
2274
2277
|
* QStash client of the workflow
|
|
2275
2278
|
*
|
|
@@ -2288,11 +2291,11 @@ var WorkflowContext = class {
|
|
|
2288
2291
|
* )
|
|
2289
2292
|
* ```
|
|
2290
2293
|
*/
|
|
2291
|
-
|
|
2294
|
+
qstashClient;
|
|
2292
2295
|
/**
|
|
2293
2296
|
* Run id of the workflow
|
|
2294
2297
|
*/
|
|
2295
|
-
|
|
2298
|
+
workflowRunId;
|
|
2296
2299
|
/**
|
|
2297
2300
|
* URL of the workflow
|
|
2298
2301
|
*
|
|
@@ -2309,7 +2312,7 @@ var WorkflowContext = class {
|
|
|
2309
2312
|
* )
|
|
2310
2313
|
* ```
|
|
2311
2314
|
*/
|
|
2312
|
-
|
|
2315
|
+
url;
|
|
2313
2316
|
/**
|
|
2314
2317
|
* URL to call in case of workflow failure with QStash failure callback
|
|
2315
2318
|
*
|
|
@@ -2328,7 +2331,7 @@ var WorkflowContext = class {
|
|
|
2328
2331
|
* )
|
|
2329
2332
|
* ```
|
|
2330
2333
|
*/
|
|
2331
|
-
|
|
2334
|
+
failureUrl;
|
|
2332
2335
|
/**
|
|
2333
2336
|
* Payload of the request which started the workflow.
|
|
2334
2337
|
*
|
|
@@ -2358,15 +2361,15 @@ var WorkflowContext = class {
|
|
|
2358
2361
|
* )
|
|
2359
2362
|
* ```
|
|
2360
2363
|
*/
|
|
2361
|
-
|
|
2364
|
+
requestPayload;
|
|
2362
2365
|
/**
|
|
2363
2366
|
* headers of the initial request
|
|
2364
2367
|
*/
|
|
2365
|
-
|
|
2368
|
+
headers;
|
|
2366
2369
|
/**
|
|
2367
2370
|
* initial payload as a raw string
|
|
2368
2371
|
*/
|
|
2369
|
-
|
|
2372
|
+
rawInitialPayload;
|
|
2370
2373
|
/**
|
|
2371
2374
|
* Map of environment variables and their values.
|
|
2372
2375
|
*
|
|
@@ -2387,11 +2390,11 @@ var WorkflowContext = class {
|
|
|
2387
2390
|
*
|
|
2388
2391
|
* Default value is set to `process.env`.
|
|
2389
2392
|
*/
|
|
2390
|
-
|
|
2393
|
+
env;
|
|
2391
2394
|
/**
|
|
2392
2395
|
* Number of retries
|
|
2393
2396
|
*/
|
|
2394
|
-
|
|
2397
|
+
retries;
|
|
2395
2398
|
constructor({
|
|
2396
2399
|
qstashClient,
|
|
2397
2400
|
workflowRunId,
|
|
@@ -2412,9 +2415,9 @@ var WorkflowContext = class {
|
|
|
2412
2415
|
this.failureUrl = failureUrl;
|
|
2413
2416
|
this.headers = headers;
|
|
2414
2417
|
this.requestPayload = initialPayload;
|
|
2415
|
-
this.rawInitialPayload =
|
|
2416
|
-
this.env =
|
|
2417
|
-
this.retries =
|
|
2418
|
+
this.rawInitialPayload = rawInitialPayload ?? JSON.stringify(this.requestPayload);
|
|
2419
|
+
this.env = env ?? {};
|
|
2420
|
+
this.retries = retries ?? DEFAULT_RETRIES;
|
|
2418
2421
|
this.executor = new AutoExecutor(this, this.steps, debug);
|
|
2419
2422
|
}
|
|
2420
2423
|
/**
|
|
@@ -2500,13 +2503,14 @@ var WorkflowContext = class {
|
|
|
2500
2503
|
* @param headers call headers
|
|
2501
2504
|
* @returns call result (parsed as JSON if possible)
|
|
2502
2505
|
*/
|
|
2506
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2503
2507
|
async call(stepName, url, method, body, headers) {
|
|
2504
2508
|
const result = await this.addStep(
|
|
2505
|
-
new LazyCallStep(stepName, url, method, body,
|
|
2509
|
+
new LazyCallStep(stepName, url, method, body, headers ?? {})
|
|
2506
2510
|
);
|
|
2507
2511
|
try {
|
|
2508
2512
|
return JSON.parse(result);
|
|
2509
|
-
} catch
|
|
2513
|
+
} catch {
|
|
2510
2514
|
return result;
|
|
2511
2515
|
}
|
|
2512
2516
|
}
|
|
@@ -2518,8 +2522,8 @@ var WorkflowContext = class {
|
|
|
2518
2522
|
return await this.executor.addStep(step);
|
|
2519
2523
|
}
|
|
2520
2524
|
};
|
|
2521
|
-
var DisabledWorkflowContext =
|
|
2522
|
-
static
|
|
2525
|
+
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
2526
|
+
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
2523
2527
|
/**
|
|
2524
2528
|
* overwrite the WorkflowContext.addStep method to always raise QStashWorkflowAbort
|
|
2525
2529
|
* error in order to stop the execution whenever we encounter a step.
|
|
@@ -2564,15 +2568,15 @@ var DisabledWorkflowContext = (_class8 = class _DisabledWorkflowContext extends
|
|
|
2564
2568
|
}
|
|
2565
2569
|
return ok("run-ended");
|
|
2566
2570
|
}
|
|
2567
|
-
}
|
|
2571
|
+
};
|
|
2568
2572
|
|
|
2569
2573
|
// src/client/workflow/logger.ts
|
|
2570
2574
|
var LOG_LEVELS = ["DEBUG", "INFO", "SUBMIT", "WARN", "ERROR"];
|
|
2571
|
-
var WorkflowLogger =
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
constructor(options) {
|
|
2575
|
+
var WorkflowLogger = class _WorkflowLogger {
|
|
2576
|
+
logs = [];
|
|
2577
|
+
options;
|
|
2578
|
+
workflowRunId = void 0;
|
|
2579
|
+
constructor(options) {
|
|
2576
2580
|
this.options = options;
|
|
2577
2581
|
}
|
|
2578
2582
|
async log(level, eventType, details) {
|
|
@@ -2580,7 +2584,7 @@ var WorkflowLogger = (_class9 = class _WorkflowLogger {
|
|
|
2580
2584
|
const timestamp = Date.now();
|
|
2581
2585
|
const logEntry = {
|
|
2582
2586
|
timestamp,
|
|
2583
|
-
workflowRunId:
|
|
2587
|
+
workflowRunId: this.workflowRunId ?? "",
|
|
2584
2588
|
logLevel: level,
|
|
2585
2589
|
eventType,
|
|
2586
2590
|
details
|
|
@@ -2612,13 +2616,13 @@ var WorkflowLogger = (_class9 = class _WorkflowLogger {
|
|
|
2612
2616
|
}) : void 0;
|
|
2613
2617
|
}
|
|
2614
2618
|
}
|
|
2615
|
-
}
|
|
2619
|
+
};
|
|
2616
2620
|
|
|
2617
2621
|
// src/client/workflow/workflow-parser.ts
|
|
2618
2622
|
var getPayload = async (request) => {
|
|
2619
2623
|
try {
|
|
2620
2624
|
return await request.text();
|
|
2621
|
-
} catch
|
|
2625
|
+
} catch {
|
|
2622
2626
|
return;
|
|
2623
2627
|
}
|
|
2624
2628
|
};
|
|
@@ -2648,9 +2652,9 @@ var deduplicateSteps = (steps) => {
|
|
|
2648
2652
|
const deduplicatedSteps = [];
|
|
2649
2653
|
for (const step of steps) {
|
|
2650
2654
|
if (step.stepId === 0) {
|
|
2651
|
-
if (!targetStepIds.includes(
|
|
2655
|
+
if (!targetStepIds.includes(step.targetStep ?? 0)) {
|
|
2652
2656
|
deduplicatedSteps.push(step);
|
|
2653
|
-
targetStepIds.push(
|
|
2657
|
+
targetStepIds.push(step.targetStep ?? 0);
|
|
2654
2658
|
}
|
|
2655
2659
|
} else {
|
|
2656
2660
|
if (!stepIds.includes(step.stepId)) {
|
|
@@ -2672,7 +2676,7 @@ var checkIfLastOneIsDuplicate = async (steps, debug) => {
|
|
|
2672
2676
|
const step = steps[index];
|
|
2673
2677
|
if (step.stepId === lastStepId && step.targetStep === lastTargetStepId) {
|
|
2674
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.`;
|
|
2675
|
-
await
|
|
2679
|
+
await debug?.log("WARN", "RESPONSE_DEFAULT", message);
|
|
2676
2680
|
console.warn(message);
|
|
2677
2681
|
return true;
|
|
2678
2682
|
}
|
|
@@ -2687,7 +2691,7 @@ var validateRequest = (request) => {
|
|
|
2687
2691
|
`Incompatible workflow sdk protocol version. Expected ${WORKFLOW_PROTOCOL_VERSION}, got ${versionHeader} from the request.`
|
|
2688
2692
|
);
|
|
2689
2693
|
}
|
|
2690
|
-
const workflowRunId = isFirstInvocation ? `wfr_${nanoid()}` :
|
|
2694
|
+
const workflowRunId = isFirstInvocation ? `wfr_${nanoid()}` : request.headers.get(WORKFLOW_ID_HEADER) ?? "";
|
|
2691
2695
|
if (workflowRunId.length === 0) {
|
|
2692
2696
|
throw new QStashWorkflowError("Couldn't get workflow id from header");
|
|
2693
2697
|
}
|
|
@@ -2699,7 +2703,7 @@ var validateRequest = (request) => {
|
|
|
2699
2703
|
var parseRequest = async (requestPayload, isFirstInvocation, debug) => {
|
|
2700
2704
|
if (isFirstInvocation) {
|
|
2701
2705
|
return {
|
|
2702
|
-
rawInitialPayload:
|
|
2706
|
+
rawInitialPayload: requestPayload ?? "",
|
|
2703
2707
|
steps: [],
|
|
2704
2708
|
isLastDuplicate: false
|
|
2705
2709
|
};
|
|
@@ -2759,7 +2763,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2759
2763
|
|
|
2760
2764
|
// src/client/workflow/serve.ts
|
|
2761
2765
|
var processOptions = (options) => {
|
|
2762
|
-
const environment =
|
|
2766
|
+
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
2763
2767
|
const receiverEnvironmentVariablesSet = Boolean(
|
|
2764
2768
|
environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
|
|
2765
2769
|
);
|
|
@@ -2810,21 +2814,21 @@ var serve = (routeFunction, options) => {
|
|
|
2810
2814
|
} = processOptions(options);
|
|
2811
2815
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
2812
2816
|
const handler = async (request) => {
|
|
2813
|
-
const initialWorkflowUrl =
|
|
2817
|
+
const initialWorkflowUrl = url ?? request.url;
|
|
2814
2818
|
const workflowUrl = baseUrl ? initialWorkflowUrl.replace(/^(https?:\/\/[^/]+)(\/.*)?$/, (_, matchedBaseUrl, path) => {
|
|
2815
2819
|
return baseUrl + (path || "");
|
|
2816
2820
|
}) : initialWorkflowUrl;
|
|
2817
2821
|
if (workflowUrl !== initialWorkflowUrl) {
|
|
2818
|
-
await
|
|
2822
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
2819
2823
|
warning: `QStash Workflow: replacing the base of the url with "${baseUrl}" and using it as workflow endpoint.`,
|
|
2820
2824
|
originalURL: initialWorkflowUrl,
|
|
2821
2825
|
updatedURL: workflowUrl
|
|
2822
|
-
})
|
|
2826
|
+
});
|
|
2823
2827
|
}
|
|
2824
2828
|
const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
|
|
2825
|
-
const requestPayload = await
|
|
2829
|
+
const requestPayload = await getPayload(request) ?? "";
|
|
2826
2830
|
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
|
|
2827
|
-
await
|
|
2831
|
+
await debug?.log("INFO", "ENDPOINT_START");
|
|
2828
2832
|
const failureCheck = await handleFailure(
|
|
2829
2833
|
request,
|
|
2830
2834
|
requestPayload,
|
|
@@ -2835,11 +2839,11 @@ var serve = (routeFunction, options) => {
|
|
|
2835
2839
|
if (failureCheck.isErr()) {
|
|
2836
2840
|
throw failureCheck.error;
|
|
2837
2841
|
} else if (failureCheck.value === "is-failure-callback") {
|
|
2838
|
-
await
|
|
2842
|
+
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
2839
2843
|
return onStepFinish("no-workflow-id", "failure-callback");
|
|
2840
2844
|
}
|
|
2841
2845
|
const { isFirstInvocation, workflowRunId } = validateRequest(request);
|
|
2842
|
-
|
|
2846
|
+
debug?.setWorkflowRunId(workflowRunId);
|
|
2843
2847
|
const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
|
|
2844
2848
|
requestPayload,
|
|
2845
2849
|
isFirstInvocation,
|
|
@@ -2865,7 +2869,7 @@ var serve = (routeFunction, options) => {
|
|
|
2865
2869
|
workflowContext
|
|
2866
2870
|
);
|
|
2867
2871
|
if (authCheck.isErr()) {
|
|
2868
|
-
await
|
|
2872
|
+
await debug?.log("ERROR", "ERROR", { error: authCheck.error.message });
|
|
2869
2873
|
throw authCheck.error;
|
|
2870
2874
|
} else if (authCheck.value === "run-ended") {
|
|
2871
2875
|
return onStepFinish("no-workflow-id", "auth-fail");
|
|
@@ -2880,9 +2884,9 @@ var serve = (routeFunction, options) => {
|
|
|
2880
2884
|
debug
|
|
2881
2885
|
);
|
|
2882
2886
|
if (callReturnCheck.isErr()) {
|
|
2883
|
-
await
|
|
2887
|
+
await debug?.log("ERROR", "SUBMIT_THIRD_PARTY_RESULT", {
|
|
2884
2888
|
error: callReturnCheck.error.message
|
|
2885
|
-
})
|
|
2889
|
+
});
|
|
2886
2890
|
throw callReturnCheck.error;
|
|
2887
2891
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
2888
2892
|
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, debug) : await triggerRouteFunction({
|
|
@@ -2892,13 +2896,13 @@ var serve = (routeFunction, options) => {
|
|
|
2892
2896
|
}
|
|
2893
2897
|
});
|
|
2894
2898
|
if (result.isErr()) {
|
|
2895
|
-
await
|
|
2899
|
+
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
2896
2900
|
throw result.error;
|
|
2897
2901
|
}
|
|
2898
|
-
await
|
|
2902
|
+
await debug?.log("INFO", "RESPONSE_WORKFLOW");
|
|
2899
2903
|
return onStepFinish(workflowContext.workflowRunId, "success");
|
|
2900
2904
|
}
|
|
2901
|
-
await
|
|
2905
|
+
await debug?.log("INFO", "RESPONSE_DEFAULT");
|
|
2902
2906
|
return onStepFinish("no-workflow-id", "fromCallback");
|
|
2903
2907
|
};
|
|
2904
2908
|
return async (request) => {
|
|
@@ -2913,7 +2917,7 @@ var serve = (routeFunction, options) => {
|
|
|
2913
2917
|
|
|
2914
2918
|
// src/client/workflow/index.ts
|
|
2915
2919
|
var Workflow = class {
|
|
2916
|
-
|
|
2920
|
+
http;
|
|
2917
2921
|
constructor(http) {
|
|
2918
2922
|
this.http = http;
|
|
2919
2923
|
}
|
|
@@ -2929,35 +2933,41 @@ var Workflow = class {
|
|
|
2929
2933
|
method: "DELETE",
|
|
2930
2934
|
parseResponseAsJson: false
|
|
2931
2935
|
});
|
|
2932
|
-
return
|
|
2936
|
+
return result ?? true;
|
|
2933
2937
|
}
|
|
2934
2938
|
};
|
|
2935
2939
|
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2940
|
+
// platforms/cloudflare.ts
|
|
2941
|
+
var getArgs = (args) => {
|
|
2942
|
+
if (!Array.isArray(args) || args.length === 0) {
|
|
2943
|
+
throw new Error("No arguments passed to serve handler");
|
|
2944
|
+
}
|
|
2945
|
+
if (typeof args[0] === "object" && "request" in args[0] && "env" in args[0]) {
|
|
2946
|
+
return {
|
|
2947
|
+
request: args[0].request,
|
|
2948
|
+
env: args[0].env
|
|
2949
|
+
};
|
|
2950
|
+
}
|
|
2951
|
+
if (args.length > 1 && typeof args[1] === "object") {
|
|
2952
|
+
return {
|
|
2953
|
+
request: args[0],
|
|
2954
|
+
env: args[1]
|
|
2955
|
+
};
|
|
2956
|
+
}
|
|
2957
|
+
throw new Error("Could not derive handler arguments from input. Please check how serve is used.");
|
|
2958
|
+
};
|
|
2959
|
+
var serve2 = (routeFunction, options) => {
|
|
2960
|
+
const handler = async (...args) => {
|
|
2961
|
+
const { request, env } = getArgs(args);
|
|
2962
|
+
const serveHandler = serve(routeFunction, {
|
|
2963
|
+
env,
|
|
2964
|
+
...options
|
|
2965
|
+
});
|
|
2966
|
+
return await serveHandler(request);
|
|
2967
|
+
};
|
|
2968
|
+
return handler;
|
|
2969
|
+
};
|
|
2970
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2971
|
+
0 && (module.exports = {
|
|
2972
|
+
serve
|
|
2973
|
+
});
|