@upstash/qstash 2.6.4-workflow-alpha.4 → 2.6.5

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-5DADTJQL.js DELETED
@@ -1,2596 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9;// src/receiver.ts
2
- var _jose = require('jose'); var jose = _interopRequireWildcard(_jose);
3
- var _cryptojs = require('crypto-js'); var _cryptojs2 = _interopRequireDefault(_cryptojs);
4
- var SignatureError = class extends Error {
5
- constructor(message) {
6
- super(message);
7
- this.name = "SignatureError";
8
- }
9
- };
10
- var Receiver = class {
11
-
12
-
13
- constructor(config) {
14
- this.currentSigningKey = config.currentSigningKey;
15
- this.nextSigningKey = config.nextSigningKey;
16
- }
17
- /**
18
- * Verify the signature of a request.
19
- *
20
- * Tries to verify the signature with the current signing key.
21
- * If that fails, maybe because you have rotated the keys recently, it will
22
- * try to verify the signature with the next signing key.
23
- *
24
- * If that fails, the signature is invalid and a `SignatureError` is thrown.
25
- */
26
- async verify(request) {
27
- const isValid = await this.verifyWithKey(this.currentSigningKey, request);
28
- if (isValid) {
29
- return true;
30
- }
31
- return this.verifyWithKey(this.nextSigningKey, request);
32
- }
33
- /**
34
- * Verify signature with a specific signing key
35
- */
36
- async verifyWithKey(key, request) {
37
- const jwt = await jose.jwtVerify(request.signature, new TextEncoder().encode(key), {
38
- issuer: "Upstash",
39
- clockTolerance: request.clockTolerance
40
- }).catch((error) => {
41
- throw new SignatureError(error.message);
42
- });
43
- const p = jwt.payload;
44
- if (request.url !== void 0 && p.sub !== request.url) {
45
- throw new SignatureError(`invalid subject: ${p.sub}, want: ${request.url}`);
46
- }
47
- const bodyHash = _cryptojs2.default.SHA256(request.body).toString(_cryptojs2.default.enc.Base64url);
48
- const padding = new RegExp(/=+$/);
49
- if (p.body.replace(padding, "") !== bodyHash.replace(padding, "")) {
50
- throw new SignatureError(`body hash does not match, want: ${p.body}, got: ${bodyHash}`);
51
- }
52
- return true;
53
- }
54
- };
55
-
56
- // src/client/dlq.ts
57
- var DLQ = class {
58
-
59
- constructor(http) {
60
- this.http = http;
61
- }
62
- /**
63
- * List messages in the dlq
64
- */
65
- async listMessages(options) {
66
- const filterPayload = {
67
- ..._optionalChain([options, 'optionalAccess', _2 => _2.filter]),
68
- topicName: _optionalChain([options, 'optionalAccess', _3 => _3.filter, 'optionalAccess', _4 => _4.urlGroup])
69
- };
70
- const messagesPayload = await this.http.request({
71
- method: "GET",
72
- path: ["v2", "dlq"],
73
- query: {
74
- cursor: _optionalChain([options, 'optionalAccess', _5 => _5.cursor]),
75
- count: _optionalChain([options, 'optionalAccess', _6 => _6.count]),
76
- ...filterPayload
77
- }
78
- });
79
- return {
80
- messages: messagesPayload.messages.map((message) => {
81
- return {
82
- ...message,
83
- urlGroup: message.topicName
84
- };
85
- }),
86
- cursor: messagesPayload.cursor
87
- };
88
- }
89
- /**
90
- * Remove a message from the dlq using it's `dlqId`
91
- */
92
- async delete(dlqMessageId) {
93
- return await this.http.request({
94
- method: "DELETE",
95
- path: ["v2", "dlq", dlqMessageId],
96
- parseResponseAsJson: false
97
- // there is no response
98
- });
99
- }
100
- /**
101
- * Remove multiple messages from the dlq using their `dlqId`s
102
- */
103
- async deleteMany(request) {
104
- return await this.http.request({
105
- method: "DELETE",
106
- path: ["v2", "dlq"],
107
- headers: { "Content-Type": "application/json" },
108
- body: JSON.stringify({ dlqIds: request.dlqIds })
109
- });
110
- }
111
- };
112
-
113
- // src/client/error.ts
114
- var QstashError = class extends Error {
115
- constructor(message) {
116
- super(message);
117
- this.name = "QstashError";
118
- }
119
- };
120
- var QstashRatelimitError = class extends QstashError {
121
-
122
-
123
-
124
- constructor(args) {
125
- super(`Exceeded burst rate limit. ${JSON.stringify(args)} `);
126
- this.name = "QstashRatelimitError";
127
- this.limit = args.limit;
128
- this.remaining = args.remaining;
129
- this.reset = args.reset;
130
- }
131
- };
132
- var QstashChatRatelimitError = class extends QstashError {
133
-
134
-
135
-
136
-
137
-
138
-
139
- constructor(args) {
140
- super(`Exceeded chat rate limit. ${JSON.stringify(args)} `);
141
- this.limitRequests = args["limit-requests"];
142
- this.limitTokens = args["limit-tokens"];
143
- this.remainingRequests = args["remaining-requests"];
144
- this.remainingTokens = args["remaining-tokens"];
145
- this.resetRequests = args["reset-requests"];
146
- this.resetTokens = args["reset-tokens"];
147
- }
148
- };
149
- var QstashDailyRatelimitError = class extends QstashError {
150
-
151
-
152
-
153
- constructor(args) {
154
- super(`Exceeded daily rate limit. ${JSON.stringify(args)} `);
155
- this.limit = args.limit;
156
- this.remaining = args.remaining;
157
- this.reset = args.reset;
158
- this.name = "QstashChatRatelimitError";
159
- }
160
- };
161
- var QstashWorkflowError = class extends QstashError {
162
- constructor(message) {
163
- super(message);
164
- this.name = "QstashWorkflowError";
165
- }
166
- };
167
- var QstashWorkflowAbort = class extends Error {
168
-
169
-
170
- constructor(stepName, stepInfo) {
171
- super(`Aborting workflow after executing step '${stepName}'.`);
172
- this.name = "QstashWorkflowAbort";
173
- this.stepName = stepName;
174
- this.stepInfo = stepInfo;
175
- }
176
- };
177
- var formatWorkflowError = (error) => {
178
- return error instanceof Error ? {
179
- error: error.name,
180
- message: error.message,
181
- stack: error.stack
182
- } : {
183
- error: "Error",
184
- message: "An error occured while executing workflow."
185
- };
186
- };
187
-
188
- // src/client/http.ts
189
- var HttpClient = (_class = class {
190
-
191
-
192
-
193
-
194
- constructor(config) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
195
- this.baseUrl = config.baseUrl.replace(/\/$/, "");
196
- this.authorization = config.authorization;
197
- this.retry = // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
198
- typeof config.retry === "boolean" && !config.retry ? {
199
- attempts: 1,
200
- backoff: () => 0
201
- } : {
202
- attempts: _optionalChain([config, 'access', _7 => _7.retry, 'optionalAccess', _8 => _8.retries]) ? config.retry.retries + 1 : 5,
203
- backoff: _nullishCoalesce(_optionalChain([config, 'access', _9 => _9.retry, 'optionalAccess', _10 => _10.backoff]), () => ( ((retryCount) => Math.exp(retryCount) * 50)))
204
- };
205
- }
206
- async request(request) {
207
- const { response } = await this.requestWithBackoff(request);
208
- if (request.parseResponseAsJson === false) {
209
- return void 0;
210
- }
211
- return await response.json();
212
- }
213
- async *requestStream(request) {
214
- const { response } = await this.requestWithBackoff(request);
215
- if (!response.body) {
216
- throw new Error("No response body");
217
- }
218
- const body = response.body;
219
- const reader = body.getReader();
220
- const decoder = new TextDecoder();
221
- try {
222
- while (true) {
223
- const { done, value } = await reader.read();
224
- if (done) {
225
- break;
226
- }
227
- const chunkText = decoder.decode(value, { stream: true });
228
- const chunks = chunkText.split("\n").filter(Boolean);
229
- for (const chunk of chunks) {
230
- if (chunk.startsWith("data: ")) {
231
- const data = chunk.slice(6);
232
- if (data === "[DONE]") {
233
- break;
234
- }
235
- yield JSON.parse(data);
236
- }
237
- }
238
- }
239
- } finally {
240
- await reader.cancel();
241
- }
242
- }
243
- __init() {this.requestWithBackoff = async (request) => {
244
- const [url, requestOptions] = this.processRequest(request);
245
- let response = void 0;
246
- let error = void 0;
247
- for (let index = 0; index < this.retry.attempts; index++) {
248
- try {
249
- response = await fetch(url.toString(), requestOptions);
250
- break;
251
- } catch (error_) {
252
- error = error_;
253
- await new Promise((r) => setTimeout(r, this.retry.backoff(index)));
254
- }
255
- }
256
- if (!response) {
257
- throw _nullishCoalesce(error, () => ( new Error("Exhausted all retries")));
258
- }
259
- await this.checkResponse(response);
260
- return {
261
- response,
262
- error
263
- };
264
- }}
265
- __init2() {this.processRequest = (request) => {
266
- const headers = new Headers(request.headers);
267
- if (!headers.has("Authorization")) {
268
- headers.set("Authorization", this.authorization);
269
- }
270
- const requestOptions = {
271
- method: request.method,
272
- headers,
273
- body: request.body,
274
- keepalive: request.keepalive
275
- };
276
- const url = new URL([_nullishCoalesce(request.baseUrl, () => ( this.baseUrl)), ...request.path].join("/"));
277
- if (request.query) {
278
- for (const [key, value] of Object.entries(request.query)) {
279
- if (value !== void 0) {
280
- url.searchParams.set(key, value.toString());
281
- }
282
- }
283
- }
284
- return [url.toString(), requestOptions];
285
- }}
286
- async checkResponse(response) {
287
- if (response.status === 429) {
288
- if (response.headers.get("x-ratelimit-limit-requests")) {
289
- throw new QstashChatRatelimitError({
290
- "limit-requests": response.headers.get("x-ratelimit-limit-requests"),
291
- "limit-tokens": response.headers.get("x-ratelimit-limit-tokens"),
292
- "remaining-requests": response.headers.get("x-ratelimit-remaining-requests"),
293
- "remaining-tokens": response.headers.get("x-ratelimit-remaining-tokens"),
294
- "reset-requests": response.headers.get("x-ratelimit-reset-requests"),
295
- "reset-tokens": response.headers.get("x-ratelimit-reset-tokens")
296
- });
297
- } else if (response.headers.get("RateLimit-Limit")) {
298
- throw new QstashDailyRatelimitError({
299
- limit: response.headers.get("RateLimit-Limit"),
300
- remaining: response.headers.get("RateLimit-Remaining"),
301
- reset: response.headers.get("RateLimit-Reset")
302
- });
303
- }
304
- throw new QstashRatelimitError({
305
- limit: response.headers.get("Burst-RateLimit-Limit"),
306
- remaining: response.headers.get("Burst-RateLimit-Remaining"),
307
- reset: response.headers.get("Burst-RateLimit-Reset")
308
- });
309
- }
310
- if (response.status < 200 || response.status >= 300) {
311
- const body = await response.text();
312
- throw new QstashError(body.length > 0 ? body : `Error: status=${response.status}`);
313
- }
314
- }
315
- }, _class);
316
-
317
- // src/client/llm/chat.ts
318
- var Chat = (_class2 = class _Chat {
319
-
320
-
321
- constructor(http, token) {;_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);
322
- this.http = http;
323
- this.token = token;
324
- }
325
- static toChatRequest(request) {
326
- const messages = [];
327
- messages.push(
328
- { role: "system", content: request.system },
329
- { role: "user", content: request.user }
330
- );
331
- const chatRequest = { ...request, messages };
332
- return chatRequest;
333
- }
334
- /**
335
- * Calls the Upstash completions api given a ChatRequest.
336
- *
337
- * Returns a ChatCompletion or a stream of ChatCompletionChunks
338
- * if stream is enabled.
339
- *
340
- * @param request ChatRequest with messages
341
- * @returns Chat completion or stream
342
- */
343
- __init3() {this.create = async (request) => {
344
- if (request.provider.owner != "upstash")
345
- return this.createThirdParty(request);
346
- const body = JSON.stringify(request);
347
- if ("stream" in request && request.stream) {
348
- return this.http.requestStream({
349
- path: ["llm", "v1", "chat", "completions"],
350
- method: "POST",
351
- headers: {
352
- "Content-Type": "application/json",
353
- Connection: "keep-alive",
354
- Accept: "text/event-stream",
355
- "Cache-Control": "no-cache",
356
- Authorization: `Bearer ${this.token}`
357
- },
358
- body
359
- });
360
- }
361
- return this.http.request({
362
- path: ["llm", "v1", "chat", "completions"],
363
- method: "POST",
364
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${this.token}` },
365
- body
366
- });
367
- }}
368
- /**
369
- * Calls the Upstash completions api given a ChatRequest.
370
- *
371
- * Returns a ChatCompletion or a stream of ChatCompletionChunks
372
- * if stream is enabled.
373
- *
374
- * @param request ChatRequest with messages
375
- * @returns Chat completion or stream
376
- */
377
- __init4() {this.createThirdParty = async (request) => {
378
- const { baseUrl, token, owner } = request.provider;
379
- if (owner === "upstash")
380
- throw new Error("Upstash is not 3rd party provider!");
381
- delete request.provider;
382
- delete request.system;
383
- const body = JSON.stringify(request);
384
- if ("stream" in request && request.stream) {
385
- return this.http.requestStream({
386
- path: ["v1", "chat", "completions"],
387
- method: "POST",
388
- headers: {
389
- "Content-Type": "application/json",
390
- Connection: "keep-alive",
391
- Accept: "text/event-stream",
392
- "Cache-Control": "no-cache",
393
- Authorization: `Bearer ${token}`
394
- },
395
- body,
396
- baseUrl
397
- });
398
- }
399
- return this.http.request({
400
- path: ["v1", "chat", "completions"],
401
- method: "POST",
402
- headers: {
403
- "Content-Type": "application/json",
404
- Authorization: `Bearer ${token}`
405
- },
406
- body,
407
- baseUrl
408
- });
409
- }}
410
- /**
411
- * Calls the Upstash completions api given a PromptRequest.
412
- *
413
- * Returns a ChatCompletion or a stream of ChatCompletionChunks
414
- * if stream is enabled.
415
- *
416
- * @param request PromptRequest with system and user messages.
417
- * Note that system parameter shouldn't be passed in the case of
418
- * mistralai/Mistral-7B-Instruct-v0.2 model.
419
- * @returns Chat completion or stream
420
- */
421
- __init5() {this.prompt = async (request) => {
422
- const chatRequest = _Chat.toChatRequest(request);
423
- return this.create(chatRequest);
424
- }}
425
- }, _class2);
426
-
427
- // src/client/llm/utils.ts
428
- function appendLLMOptionsIfNeeded(request, headers) {
429
- if (_optionalChain([request, 'access', _11 => _11.api, 'optionalAccess', _12 => _12.provider, 'optionalAccess', _13 => _13.owner]) === "upstash") {
430
- request.api = { name: "llm" };
431
- return;
432
- }
433
- if (request.api && "provider" in request.api) {
434
- const provider = request.api.provider;
435
- if (!_optionalChain([provider, 'optionalAccess', _14 => _14.baseUrl]))
436
- throw new Error("baseUrl cannot be empty or undefined!");
437
- if (!provider.token)
438
- throw new Error("token cannot be empty or undefined!");
439
- request.url = `${provider.baseUrl}/v1/chat/completions`;
440
- headers.set("Authorization", `Bearer ${provider.token}`);
441
- }
442
- }
443
- function ensureCallbackPresent(request) {
444
- if (_optionalChain([request, 'access', _15 => _15.api, 'optionalAccess', _16 => _16.name]) === "llm" && !request.callback) {
445
- throw new TypeError("Callback cannot be undefined when using LLM");
446
- }
447
- }
448
-
449
- // src/client/messages.ts
450
- var Messages = class {
451
-
452
- constructor(http) {
453
- this.http = http;
454
- }
455
- /**
456
- * Get a message
457
- */
458
- async get(messageId) {
459
- const messagePayload = await this.http.request({
460
- method: "GET",
461
- path: ["v2", "messages", messageId]
462
- });
463
- const message = {
464
- ...messagePayload,
465
- urlGroup: messagePayload.topicName
466
- };
467
- return message;
468
- }
469
- /**
470
- * Cancel a message
471
- */
472
- async delete(messageId) {
473
- return await this.http.request({
474
- method: "DELETE",
475
- path: ["v2", "messages", messageId],
476
- parseResponseAsJson: false
477
- });
478
- }
479
- async deleteMany(messageIds) {
480
- const result = await this.http.request({
481
- method: "DELETE",
482
- path: ["v2", "messages"],
483
- headers: { "Content-Type": "application/json" },
484
- body: JSON.stringify({ messageIds })
485
- });
486
- return result.cancelled;
487
- }
488
- async deleteAll() {
489
- const result = await this.http.request({
490
- method: "DELETE",
491
- path: ["v2", "messages"]
492
- });
493
- return result.cancelled;
494
- }
495
- };
496
-
497
- // src/client/utils.ts
498
- var isIgnoredHeader = (header) => {
499
- const lowerCaseHeader = header.toLowerCase();
500
- return lowerCaseHeader.startsWith("content-type") || lowerCaseHeader.startsWith("upstash-");
501
- };
502
- function prefixHeaders(headers) {
503
- const keysToBePrefixed = [...headers.keys()].filter((key) => !isIgnoredHeader(key));
504
- for (const key of keysToBePrefixed) {
505
- const value = headers.get(key);
506
- if (value !== null) {
507
- headers.set(`Upstash-Forward-${key}`, value);
508
- }
509
- headers.delete(key);
510
- }
511
- return headers;
512
- }
513
- function processHeaders(request) {
514
- const headers = prefixHeaders(new Headers(request.headers));
515
- headers.set("Upstash-Method", _nullishCoalesce(request.method, () => ( "POST")));
516
- if (request.delay !== void 0) {
517
- headers.set("Upstash-Delay", `${request.delay.toFixed(0)}s`);
518
- }
519
- if (request.notBefore !== void 0) {
520
- headers.set("Upstash-Not-Before", request.notBefore.toFixed(0));
521
- }
522
- if (request.deduplicationId !== void 0) {
523
- headers.set("Upstash-Deduplication-Id", request.deduplicationId);
524
- }
525
- if (request.contentBasedDeduplication !== void 0) {
526
- headers.set("Upstash-Content-Based-Deduplication", "true");
527
- }
528
- if (request.retries !== void 0) {
529
- headers.set("Upstash-Retries", request.retries.toFixed(0));
530
- }
531
- if (request.callback !== void 0) {
532
- headers.set("Upstash-Callback", request.callback);
533
- }
534
- if (request.failureCallback !== void 0) {
535
- headers.set("Upstash-Failure-Callback", request.failureCallback);
536
- }
537
- if (request.timeout !== void 0) {
538
- headers.set("Upstash-Timeout", `${request.timeout}s`);
539
- }
540
- return headers;
541
- }
542
- function getRequestPath(request) {
543
- return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(request.url, () => ( request.urlGroup)), () => ( request.topic)), () => ( `api/${_optionalChain([request, 'access', _17 => _17.api, 'optionalAccess', _18 => _18.name])}`));
544
- }
545
-
546
- // src/client/queue.ts
547
- var Queue = class {
548
-
549
-
550
- constructor(http, queueName) {
551
- this.http = http;
552
- this.queueName = queueName;
553
- }
554
- /**
555
- * Create or update the queue
556
- */
557
- async upsert(request) {
558
- if (!this.queueName) {
559
- throw new Error("Please provide a queue name to the Queue constructor");
560
- }
561
- const body = {
562
- queueName: this.queueName,
563
- parallelism: _nullishCoalesce(request.parallelism, () => ( 1)),
564
- paused: _nullishCoalesce(request.paused, () => ( false))
565
- };
566
- await this.http.request({
567
- method: "POST",
568
- path: ["v2", "queues"],
569
- headers: {
570
- "Content-Type": "application/json"
571
- },
572
- body: JSON.stringify(body),
573
- parseResponseAsJson: false
574
- });
575
- }
576
- /**
577
- * Get the queue details
578
- */
579
- async get() {
580
- if (!this.queueName) {
581
- throw new Error("Please provide a queue name to the Queue constructor");
582
- }
583
- return await this.http.request({
584
- method: "GET",
585
- path: ["v2", "queues", this.queueName]
586
- });
587
- }
588
- /**
589
- * List queues
590
- */
591
- async list() {
592
- return await this.http.request({
593
- method: "GET",
594
- path: ["v2", "queues"]
595
- });
596
- }
597
- /**
598
- * Delete the queue
599
- */
600
- async delete() {
601
- if (!this.queueName) {
602
- throw new Error("Please provide a queue name to the Queue constructor");
603
- }
604
- await this.http.request({
605
- method: "DELETE",
606
- path: ["v2", "queues", this.queueName],
607
- parseResponseAsJson: false
608
- });
609
- }
610
- /**
611
- * Enqueue a message to a queue.
612
- */
613
- async enqueue(request) {
614
- if (!this.queueName) {
615
- throw new Error("Please provide a queue name to the Queue constructor");
616
- }
617
- const headers = processHeaders(request);
618
- const destination = getRequestPath(request);
619
- const response = await this.http.request({
620
- path: ["v2", "enqueue", this.queueName, destination],
621
- body: request.body,
622
- headers,
623
- method: "POST"
624
- });
625
- return response;
626
- }
627
- /**
628
- * Enqueue a message to a queue, serializing the body to JSON.
629
- */
630
- async enqueueJSON(request) {
631
- const headers = prefixHeaders(new Headers(request.headers));
632
- headers.set("Content-Type", "application/json");
633
- ensureCallbackPresent(request);
634
- appendLLMOptionsIfNeeded(request, headers);
635
- const response = await this.enqueue({
636
- ...request,
637
- body: JSON.stringify(request.body),
638
- headers
639
- });
640
- return response;
641
- }
642
- /**
643
- * Pauses the queue.
644
- *
645
- * A paused queue will not deliver messages until
646
- * it is resumed.
647
- */
648
- async pause() {
649
- if (!this.queueName) {
650
- throw new Error("Please provide a queue name to the Queue constructor");
651
- }
652
- await this.http.request({
653
- method: "POST",
654
- path: ["v2", "queues", this.queueName, "pause"],
655
- parseResponseAsJson: false
656
- });
657
- }
658
- /**
659
- * Resumes the queue.
660
- */
661
- async resume() {
662
- if (!this.queueName) {
663
- throw new Error("Please provide a queue name to the Queue constructor");
664
- }
665
- await this.http.request({
666
- method: "POST",
667
- path: ["v2", "queues", this.queueName, "resume"],
668
- parseResponseAsJson: false
669
- });
670
- }
671
- };
672
-
673
- // src/client/schedules.ts
674
- var Schedules = class {
675
-
676
- constructor(http) {
677
- this.http = http;
678
- }
679
- /**
680
- * Create a schedule
681
- */
682
- async create(request) {
683
- const headers = prefixHeaders(new Headers(request.headers));
684
- if (!headers.has("Content-Type")) {
685
- headers.set("Content-Type", "application/json");
686
- }
687
- headers.set("Upstash-Cron", request.cron);
688
- if (request.method !== void 0) {
689
- headers.set("Upstash-Method", request.method);
690
- }
691
- if (request.delay !== void 0) {
692
- headers.set("Upstash-Delay", `${request.delay.toFixed(0)}s`);
693
- }
694
- if (request.retries !== void 0) {
695
- headers.set("Upstash-Retries", request.retries.toFixed(0));
696
- }
697
- if (request.callback !== void 0) {
698
- headers.set("Upstash-Callback", request.callback);
699
- }
700
- if (request.failureCallback !== void 0) {
701
- headers.set("Upstash-Failure-Callback", request.failureCallback);
702
- }
703
- if (request.timeout !== void 0) {
704
- headers.set("Upstash-Timeout", `${request.timeout}s`);
705
- }
706
- return await this.http.request({
707
- method: "POST",
708
- headers,
709
- path: ["v2", "schedules", request.destination],
710
- body: request.body
711
- });
712
- }
713
- /**
714
- * Get a schedule
715
- */
716
- async get(scheduleId) {
717
- return await this.http.request({
718
- method: "GET",
719
- path: ["v2", "schedules", scheduleId]
720
- });
721
- }
722
- /**
723
- * List your schedules
724
- */
725
- async list() {
726
- return await this.http.request({
727
- method: "GET",
728
- path: ["v2", "schedules"]
729
- });
730
- }
731
- /**
732
- * Delete a schedule
733
- */
734
- async delete(scheduleId) {
735
- return await this.http.request({
736
- method: "DELETE",
737
- path: ["v2", "schedules", scheduleId],
738
- parseResponseAsJson: false
739
- });
740
- }
741
- /**
742
- * Pauses the schedule.
743
- *
744
- * A paused schedule will not deliver messages until
745
- * it is resumed.
746
- */
747
- async pause({ schedule }) {
748
- await this.http.request({
749
- method: "PATCH",
750
- path: ["v2", "schedules", schedule, "pause"],
751
- parseResponseAsJson: false
752
- });
753
- }
754
- /**
755
- * Resumes the schedule.
756
- */
757
- async resume({ schedule }) {
758
- await this.http.request({
759
- method: "PATCH",
760
- path: ["v2", "schedules", schedule, "resume"],
761
- parseResponseAsJson: false
762
- });
763
- }
764
- };
765
-
766
- // src/client/url-groups.ts
767
- var UrlGroups = class {
768
-
769
- constructor(http) {
770
- this.http = http;
771
- }
772
- /**
773
- * Create a new url group with the given name and endpoints
774
- */
775
- async addEndpoints(request) {
776
- await this.http.request({
777
- method: "POST",
778
- path: ["v2", "topics", request.name, "endpoints"],
779
- headers: { "Content-Type": "application/json" },
780
- body: JSON.stringify({ endpoints: request.endpoints }),
781
- parseResponseAsJson: false
782
- });
783
- }
784
- /**
785
- * Remove endpoints from a url group.
786
- */
787
- async removeEndpoints(request) {
788
- await this.http.request({
789
- method: "DELETE",
790
- path: ["v2", "topics", request.name, "endpoints"],
791
- headers: { "Content-Type": "application/json" },
792
- body: JSON.stringify({ endpoints: request.endpoints }),
793
- parseResponseAsJson: false
794
- });
795
- }
796
- /**
797
- * Get a list of all url groups.
798
- */
799
- async list() {
800
- return await this.http.request({
801
- method: "GET",
802
- path: ["v2", "topics"]
803
- });
804
- }
805
- /**
806
- * Get a single url group
807
- */
808
- async get(name) {
809
- return await this.http.request({
810
- method: "GET",
811
- path: ["v2", "topics", name]
812
- });
813
- }
814
- /**
815
- * Delete a url group
816
- */
817
- async delete(name) {
818
- return await this.http.request({
819
- method: "DELETE",
820
- path: ["v2", "topics", name],
821
- parseResponseAsJson: false
822
- });
823
- }
824
- };
825
-
826
- // src/client/client.ts
827
- var Client = class {
828
-
829
-
830
- constructor(config) {
831
- this.http = new HttpClient({
832
- retry: config.retry,
833
- baseUrl: config.baseUrl ? config.baseUrl.replace(/\/$/, "") : "https://qstash.upstash.io",
834
- authorization: `Bearer ${config.token}`
835
- });
836
- this.token = config.token;
837
- }
838
- /**
839
- * Access the urlGroup API.
840
- *
841
- * Create, read, update or delete urlGroups.
842
- */
843
- get urlGroups() {
844
- return new UrlGroups(this.http);
845
- }
846
- /**
847
- * Deprecated. Use urlGroups instead.
848
- *
849
- * Access the topic API.
850
- *
851
- * Create, read, update or delete topics.
852
- */
853
- get topics() {
854
- return this.urlGroups;
855
- }
856
- /**
857
- * Access the dlq API.
858
- *
859
- * List or remove messages from the DLQ.
860
- */
861
- get dlq() {
862
- return new DLQ(this.http);
863
- }
864
- /**
865
- * Access the message API.
866
- *
867
- * Read or cancel messages.
868
- */
869
- get messages() {
870
- return new Messages(this.http);
871
- }
872
- /**
873
- * Access the schedule API.
874
- *
875
- * Create, read or delete schedules.
876
- */
877
- get schedules() {
878
- return new Schedules(this.http);
879
- }
880
- /**
881
- * Access the workflow API.
882
- *
883
- * cancel workflows.
884
- */
885
- get workflow() {
886
- return new Workflow(this.http);
887
- }
888
- /**
889
- * Access the queue API.
890
- *
891
- * Create, read, update or delete queues.
892
- */
893
- queue(request) {
894
- return new Queue(this.http, _optionalChain([request, 'optionalAccess', _19 => _19.queueName]));
895
- }
896
- /**
897
- * Access the Chat API
898
- *
899
- * Call the create or prompt methods
900
- */
901
- chat() {
902
- return new Chat(this.http, this.token);
903
- }
904
- async publish(request) {
905
- const headers = processHeaders(request);
906
- const response = await this.http.request({
907
- path: ["v2", "publish", getRequestPath(request)],
908
- body: request.body,
909
- headers,
910
- method: "POST"
911
- });
912
- return response;
913
- }
914
- /**
915
- * publishJSON is a utility wrapper around `publish` that automatically serializes the body
916
- * and sets the `Content-Type` header to `application/json`.
917
- */
918
- async publishJSON(request) {
919
- const headers = prefixHeaders(new Headers(request.headers));
920
- headers.set("Content-Type", "application/json");
921
- ensureCallbackPresent(request);
922
- appendLLMOptionsIfNeeded(request, headers);
923
- const response = await this.publish({
924
- ...request,
925
- headers,
926
- body: JSON.stringify(request.body)
927
- });
928
- return response;
929
- }
930
- /**
931
- * Batch publish messages to QStash.
932
- */
933
- async batch(request) {
934
- const messages = [];
935
- for (const message of request) {
936
- const headers = processHeaders(message);
937
- const headerEntries = Object.fromEntries(headers.entries());
938
- messages.push({
939
- destination: getRequestPath(message),
940
- headers: headerEntries,
941
- body: message.body,
942
- ...message.queueName && { queue: message.queueName }
943
- });
944
- }
945
- const response = await this.http.request({
946
- path: ["v2", "batch"],
947
- body: JSON.stringify(messages),
948
- headers: {
949
- "Content-Type": "application/json"
950
- },
951
- method: "POST"
952
- });
953
- const arrayResposne = Array.isArray(response) ? response : [response];
954
- return arrayResposne;
955
- }
956
- /**
957
- * Batch publish messages to QStash, serializing each body to JSON.
958
- */
959
- async batchJSON(request) {
960
- for (const message of request) {
961
- if ("body" in message) {
962
- message.body = JSON.stringify(message.body);
963
- }
964
- message.headers = new Headers(message.headers);
965
- ensureCallbackPresent(message);
966
- appendLLMOptionsIfNeeded(message, message.headers);
967
- message.headers.set("Content-Type", "application/json");
968
- }
969
- const response = await this.batch(request);
970
- return response;
971
- }
972
- /**
973
- * Retrieve your logs.
974
- *
975
- * The logs endpoint is paginated and returns only 100 logs at a time.
976
- * If you want to receive more logs, you can use the cursor to paginate.
977
- *
978
- * The cursor is a unix timestamp with millisecond precision
979
- *
980
- * @example
981
- * ```ts
982
- * let cursor = Date.now()
983
- * const logs: Log[] = []
984
- * while (cursor > 0) {
985
- * const res = await qstash.logs({ cursor })
986
- * logs.push(...res.logs)
987
- * cursor = res.cursor ?? 0
988
- * }
989
- * ```
990
- */
991
- async events(request) {
992
- const query = {};
993
- if (_optionalChain([request, 'optionalAccess', _20 => _20.cursor]) && request.cursor > 0) {
994
- query.cursor = request.cursor.toString();
995
- }
996
- for (const [key, value] of Object.entries(_nullishCoalesce(_optionalChain([request, 'optionalAccess', _21 => _21.filter]), () => ( {})))) {
997
- if (typeof value === "number" && value < 0) {
998
- continue;
999
- }
1000
- if (key === "urlGroup") {
1001
- query.topicName = value.toString();
1002
- } else if (typeof value !== "undefined") {
1003
- query[key] = value.toString();
1004
- }
1005
- }
1006
- const responsePayload = await this.http.request({
1007
- path: ["v2", "events"],
1008
- method: "GET",
1009
- query
1010
- });
1011
- return {
1012
- cursor: responsePayload.cursor,
1013
- events: responsePayload.events.map((event) => {
1014
- return {
1015
- ...event,
1016
- urlGroup: event.topicName
1017
- };
1018
- })
1019
- };
1020
- }
1021
- };
1022
-
1023
- // node_modules/neverthrow/dist/index.es.js
1024
- var defaultErrorConfig = {
1025
- withStackTrace: false
1026
- };
1027
- var createNeverThrowError = (message, result, config = defaultErrorConfig) => {
1028
- const data = result.isOk() ? { type: "Ok", value: result.value } : { type: "Err", value: result.error };
1029
- const maybeStack = config.withStackTrace ? new Error().stack : void 0;
1030
- return {
1031
- data,
1032
- message,
1033
- stack: maybeStack
1034
- };
1035
- };
1036
- function __awaiter(thisArg, _arguments, P, generator) {
1037
- function adopt(value) {
1038
- return value instanceof P ? value : new P(function(resolve) {
1039
- resolve(value);
1040
- });
1041
- }
1042
- return new (P || (P = Promise))(function(resolve, reject) {
1043
- function fulfilled(value) {
1044
- try {
1045
- step(generator.next(value));
1046
- } catch (e) {
1047
- reject(e);
1048
- }
1049
- }
1050
- function rejected(value) {
1051
- try {
1052
- step(generator["throw"](value));
1053
- } catch (e) {
1054
- reject(e);
1055
- }
1056
- }
1057
- function step(result) {
1058
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
1059
- }
1060
- step((generator = generator.apply(thisArg, [])).next());
1061
- });
1062
- }
1063
- function __values(o) {
1064
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
1065
- if (m)
1066
- return m.call(o);
1067
- if (o && typeof o.length === "number")
1068
- return {
1069
- next: function() {
1070
- if (o && i >= o.length)
1071
- o = void 0;
1072
- return { value: o && o[i++], done: !o };
1073
- }
1074
- };
1075
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
1076
- }
1077
- function __await(v) {
1078
- return this instanceof __await ? (this.v = v, this) : new __await(v);
1079
- }
1080
- function __asyncGenerator(thisArg, _arguments, generator) {
1081
- if (!Symbol.asyncIterator)
1082
- throw new TypeError("Symbol.asyncIterator is not defined.");
1083
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
1084
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
1085
- return this;
1086
- }, i;
1087
- function verb(n) {
1088
- if (g[n])
1089
- i[n] = function(v) {
1090
- return new Promise(function(a, b) {
1091
- q.push([n, v, a, b]) > 1 || resume(n, v);
1092
- });
1093
- };
1094
- }
1095
- function resume(n, v) {
1096
- try {
1097
- step(g[n](v));
1098
- } catch (e) {
1099
- settle(q[0][3], e);
1100
- }
1101
- }
1102
- function step(r) {
1103
- r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
1104
- }
1105
- function fulfill(value) {
1106
- resume("next", value);
1107
- }
1108
- function reject(value) {
1109
- resume("throw", value);
1110
- }
1111
- function settle(f, v) {
1112
- if (f(v), q.shift(), q.length)
1113
- resume(q[0][0], q[0][1]);
1114
- }
1115
- }
1116
- function __asyncDelegator(o) {
1117
- var i, p;
1118
- return i = {}, verb("next"), verb("throw", function(e) {
1119
- throw e;
1120
- }), verb("return"), i[Symbol.iterator] = function() {
1121
- return this;
1122
- }, i;
1123
- function verb(n, f) {
1124
- i[n] = o[n] ? function(v) {
1125
- return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v;
1126
- } : f;
1127
- }
1128
- }
1129
- function __asyncValues(o) {
1130
- if (!Symbol.asyncIterator)
1131
- throw new TypeError("Symbol.asyncIterator is not defined.");
1132
- var m = o[Symbol.asyncIterator], i;
1133
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
1134
- return this;
1135
- }, i);
1136
- function verb(n) {
1137
- i[n] = o[n] && function(v) {
1138
- return new Promise(function(resolve, reject) {
1139
- v = o[n](v), settle(resolve, reject, v.done, v.value);
1140
- });
1141
- };
1142
- }
1143
- function settle(resolve, reject, d, v) {
1144
- Promise.resolve(v).then(function(v2) {
1145
- resolve({ value: v2, done: d });
1146
- }, reject);
1147
- }
1148
- }
1149
- var ResultAsync = class _ResultAsync {
1150
- constructor(res) {
1151
- this._promise = res;
1152
- }
1153
- static fromSafePromise(promise) {
1154
- const newPromise = promise.then((value) => new Ok(value));
1155
- return new _ResultAsync(newPromise);
1156
- }
1157
- static fromPromise(promise, errorFn) {
1158
- const newPromise = promise.then((value) => new Ok(value)).catch((e) => new Err(errorFn(e)));
1159
- return new _ResultAsync(newPromise);
1160
- }
1161
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1162
- static fromThrowable(fn, errorFn) {
1163
- return (...args) => {
1164
- return new _ResultAsync((() => __awaiter(this, void 0, void 0, function* () {
1165
- try {
1166
- return new Ok(yield fn(...args));
1167
- } catch (error) {
1168
- return new Err(errorFn ? errorFn(error) : error);
1169
- }
1170
- }))());
1171
- };
1172
- }
1173
- static combine(asyncResultList) {
1174
- return combineResultAsyncList(asyncResultList);
1175
- }
1176
- static combineWithAllErrors(asyncResultList) {
1177
- return combineResultAsyncListWithAllErrors(asyncResultList);
1178
- }
1179
- map(f) {
1180
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
1181
- if (res.isErr()) {
1182
- return new Err(res.error);
1183
- }
1184
- return new Ok(yield f(res.value));
1185
- })));
1186
- }
1187
- mapErr(f) {
1188
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
1189
- if (res.isOk()) {
1190
- return new Ok(res.value);
1191
- }
1192
- return new Err(yield f(res.error));
1193
- })));
1194
- }
1195
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1196
- andThen(f) {
1197
- return new _ResultAsync(this._promise.then((res) => {
1198
- if (res.isErr()) {
1199
- return new Err(res.error);
1200
- }
1201
- const newValue = f(res.value);
1202
- return newValue instanceof _ResultAsync ? newValue._promise : newValue;
1203
- }));
1204
- }
1205
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1206
- orElse(f) {
1207
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
1208
- if (res.isErr()) {
1209
- return f(res.error);
1210
- }
1211
- return new Ok(res.value);
1212
- })));
1213
- }
1214
- match(ok2, _err) {
1215
- return this._promise.then((res) => res.match(ok2, _err));
1216
- }
1217
- unwrapOr(t) {
1218
- return this._promise.then((res) => res.unwrapOr(t));
1219
- }
1220
- /**
1221
- * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.
1222
- */
1223
- safeUnwrap() {
1224
- return __asyncGenerator(this, arguments, function* safeUnwrap_1() {
1225
- return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(yield __await(this._promise.then((res) => res.safeUnwrap()))))));
1226
- });
1227
- }
1228
- // Makes ResultAsync implement PromiseLike<Result>
1229
- then(successCallback, failureCallback) {
1230
- return this._promise.then(successCallback, failureCallback);
1231
- }
1232
- };
1233
- var errAsync = (err2) => new ResultAsync(Promise.resolve(new Err(err2)));
1234
- var fromPromise = ResultAsync.fromPromise;
1235
- var fromSafePromise = ResultAsync.fromSafePromise;
1236
- var fromAsyncThrowable = ResultAsync.fromThrowable;
1237
- var combineResultList = (resultList) => {
1238
- let acc = ok([]);
1239
- for (const result of resultList) {
1240
- if (result.isErr()) {
1241
- acc = err(result.error);
1242
- break;
1243
- } else {
1244
- acc.map((list) => list.push(result.value));
1245
- }
1246
- }
1247
- return acc;
1248
- };
1249
- var combineResultAsyncList = (asyncResultList) => ResultAsync.fromSafePromise(Promise.all(asyncResultList)).andThen(combineResultList);
1250
- var combineResultListWithAllErrors = (resultList) => {
1251
- let acc = ok([]);
1252
- for (const result of resultList) {
1253
- if (result.isErr() && acc.isErr()) {
1254
- acc.error.push(result.error);
1255
- } else if (result.isErr() && acc.isOk()) {
1256
- acc = err([result.error]);
1257
- } else if (result.isOk() && acc.isOk()) {
1258
- acc.value.push(result.value);
1259
- }
1260
- }
1261
- return acc;
1262
- };
1263
- var combineResultAsyncListWithAllErrors = (asyncResultList) => ResultAsync.fromSafePromise(Promise.all(asyncResultList)).andThen(combineResultListWithAllErrors);
1264
- var Result;
1265
- (function(Result2) {
1266
- function fromThrowable2(fn, errorFn) {
1267
- return (...args) => {
1268
- try {
1269
- const result = fn(...args);
1270
- return ok(result);
1271
- } catch (e) {
1272
- return err(errorFn ? errorFn(e) : e);
1273
- }
1274
- };
1275
- }
1276
- Result2.fromThrowable = fromThrowable2;
1277
- function combine(resultList) {
1278
- return combineResultList(resultList);
1279
- }
1280
- Result2.combine = combine;
1281
- function combineWithAllErrors(resultList) {
1282
- return combineResultListWithAllErrors(resultList);
1283
- }
1284
- Result2.combineWithAllErrors = combineWithAllErrors;
1285
- })(Result || (Result = {}));
1286
- var ok = (value) => new Ok(value);
1287
- var err = (err2) => new Err(err2);
1288
- var Ok = class {
1289
- constructor(value) {
1290
- this.value = value;
1291
- }
1292
- isOk() {
1293
- return true;
1294
- }
1295
- isErr() {
1296
- return !this.isOk();
1297
- }
1298
- map(f) {
1299
- return ok(f(this.value));
1300
- }
1301
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1302
- mapErr(_f) {
1303
- return ok(this.value);
1304
- }
1305
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1306
- andThen(f) {
1307
- return f(this.value);
1308
- }
1309
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1310
- orElse(_f) {
1311
- return ok(this.value);
1312
- }
1313
- asyncAndThen(f) {
1314
- return f(this.value);
1315
- }
1316
- asyncMap(f) {
1317
- return ResultAsync.fromSafePromise(f(this.value));
1318
- }
1319
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1320
- unwrapOr(_v) {
1321
- return this.value;
1322
- }
1323
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1324
- match(ok2, _err) {
1325
- return ok2(this.value);
1326
- }
1327
- safeUnwrap() {
1328
- const value = this.value;
1329
- return function* () {
1330
- return value;
1331
- }();
1332
- }
1333
- _unsafeUnwrap(_) {
1334
- return this.value;
1335
- }
1336
- _unsafeUnwrapErr(config) {
1337
- throw createNeverThrowError("Called `_unsafeUnwrapErr` on an Ok", this, config);
1338
- }
1339
- };
1340
- var Err = class {
1341
- constructor(error) {
1342
- this.error = error;
1343
- }
1344
- isOk() {
1345
- return false;
1346
- }
1347
- isErr() {
1348
- return !this.isOk();
1349
- }
1350
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1351
- map(_f) {
1352
- return err(this.error);
1353
- }
1354
- mapErr(f) {
1355
- return err(f(this.error));
1356
- }
1357
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1358
- andThen(_f) {
1359
- return err(this.error);
1360
- }
1361
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1362
- orElse(f) {
1363
- return f(this.error);
1364
- }
1365
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1366
- asyncAndThen(_f) {
1367
- return errAsync(this.error);
1368
- }
1369
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1370
- asyncMap(_f) {
1371
- return errAsync(this.error);
1372
- }
1373
- unwrapOr(v) {
1374
- return v;
1375
- }
1376
- match(_ok, err2) {
1377
- return err2(this.error);
1378
- }
1379
- safeUnwrap() {
1380
- const error = this.error;
1381
- return function* () {
1382
- yield err(error);
1383
- throw new Error("Do not use this generator out of `safeTry`");
1384
- }();
1385
- }
1386
- _unsafeUnwrap(config) {
1387
- throw createNeverThrowError("Called `_unsafeUnwrap` on an Err", this, config);
1388
- }
1389
- _unsafeUnwrapErr(_) {
1390
- return this.error;
1391
- }
1392
- };
1393
- var fromThrowable = Result.fromThrowable;
1394
-
1395
- // src/client/workflow/constants.ts
1396
- var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
1397
- var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
1398
- var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
1399
- var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
1400
- var WORKFLOW_PROTOCOL_VERSION = "1";
1401
- var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
1402
- var DEFAULT_CONTENT_TYPE = "application/json";
1403
- var NO_CONCURRENCY = 1;
1404
-
1405
- // src/client/workflow/types.ts
1406
- var StepTypes = ["Initial", "Run", "SleepFor", "SleepUntil", "Call"];
1407
-
1408
- // src/client/workflow/workflow-requests.ts
1409
- var triggerFirstInvocation = async (workflowContext, debug) => {
1410
- const headers = getHeaders(
1411
- "true",
1412
- workflowContext.workflowRunId,
1413
- workflowContext.url,
1414
- workflowContext.headers,
1415
- void 0,
1416
- workflowContext.failureUrl
1417
- );
1418
- await _optionalChain([debug, 'optionalAccess', _22 => _22.log, 'call', _23 => _23("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
1419
- headers,
1420
- requestPayload: workflowContext.requestPayload,
1421
- url: workflowContext.url
1422
- })]);
1423
- try {
1424
- await workflowContext.qstashClient.publishJSON({
1425
- headers,
1426
- method: "POST",
1427
- body: workflowContext.requestPayload,
1428
- url: workflowContext.url
1429
- });
1430
- return ok("success");
1431
- } catch (error) {
1432
- const error_ = error;
1433
- return err(error_);
1434
- }
1435
- };
1436
- var triggerRouteFunction = async ({
1437
- onCleanup,
1438
- onStep
1439
- }) => {
1440
- try {
1441
- await onStep();
1442
- await onCleanup();
1443
- return ok("workflow-finished");
1444
- } catch (error) {
1445
- const error_ = error;
1446
- return error_ instanceof QstashWorkflowAbort ? ok("step-finished") : err(error_);
1447
- }
1448
- };
1449
- var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
1450
- await _optionalChain([debug, 'optionalAccess', _24 => _24.log, 'call', _25 => _25("SUBMIT", "SUBMIT_CLEANUP", {
1451
- deletedWorkflowRunId: workflowContext.workflowRunId
1452
- })]);
1453
- const result = await workflowContext.qstashClient.http.request({
1454
- path: ["v2", "workflows", "runs", `${workflowContext.workflowRunId}?cancel=${cancel}`],
1455
- method: "DELETE",
1456
- parseResponseAsJson: false
1457
- });
1458
- await _optionalChain([debug, 'optionalAccess', _26 => _26.log, 'call', _27 => _27("SUBMIT", "SUBMIT_CLEANUP", result)]);
1459
- };
1460
- var recreateUserHeaders = (headers) => {
1461
- const filteredHeaders = new Headers();
1462
- const pairs = headers.entries();
1463
- for (const [header, value] of pairs) {
1464
- const headerLowerCase = header.toLowerCase();
1465
- if (!headerLowerCase.startsWith("upstash-workflow-") && !headerLowerCase.startsWith("x-vercel-")) {
1466
- filteredHeaders.append(header, value);
1467
- }
1468
- }
1469
- return filteredHeaders;
1470
- };
1471
- var handleThirdPartyCallResult = async (request, requestPayload, client, workflowUrl, failureUrl, debug) => {
1472
- try {
1473
- if (request.headers.get("Upstash-Workflow-Callback")) {
1474
- const callbackMessage = JSON.parse(requestPayload);
1475
- if (!(callbackMessage.status >= 200 && callbackMessage.status < 300)) {
1476
- await _optionalChain([debug, 'optionalAccess', _28 => _28.log, 'call', _29 => _29("WARN", "SUBMIT_THIRD_PARTY_RESULT", callbackMessage)]);
1477
- return ok("call-will-retry");
1478
- }
1479
- const workflowRunId = request.headers.get(WORKFLOW_ID_HEADER);
1480
- const stepIdString = request.headers.get("Upstash-Workflow-StepId");
1481
- const stepName = request.headers.get("Upstash-Workflow-StepName");
1482
- const stepType = request.headers.get("Upstash-Workflow-StepType");
1483
- const concurrentString = request.headers.get("Upstash-Workflow-Concurrent");
1484
- const contentType = request.headers.get("Upstash-Workflow-ContentType");
1485
- if (!(workflowRunId && stepIdString && stepName && StepTypes.includes(stepType) && concurrentString && contentType)) {
1486
- throw new Error(
1487
- `Missing info in callback message source header: ${JSON.stringify({
1488
- workflowRunId,
1489
- stepIdString,
1490
- stepName,
1491
- stepType,
1492
- concurrentString,
1493
- contentType
1494
- })}`
1495
- );
1496
- }
1497
- const userHeaders = recreateUserHeaders(request.headers);
1498
- const requestHeaders = getHeaders(
1499
- "false",
1500
- workflowRunId,
1501
- workflowUrl,
1502
- userHeaders,
1503
- void 0,
1504
- failureUrl
1505
- );
1506
- const callResultStep = {
1507
- stepId: Number(stepIdString),
1508
- stepName,
1509
- stepType,
1510
- out: Buffer.from(callbackMessage.body, "base64").toString(),
1511
- concurrent: Number(concurrentString)
1512
- };
1513
- await _optionalChain([debug, 'optionalAccess', _30 => _30.log, 'call', _31 => _31("SUBMIT", "SUBMIT_THIRD_PARTY_RESULT", {
1514
- step: callResultStep,
1515
- headers: requestHeaders,
1516
- url: workflowUrl
1517
- })]);
1518
- const result = await client.publishJSON({
1519
- headers: requestHeaders,
1520
- method: "POST",
1521
- body: callResultStep,
1522
- url: workflowUrl
1523
- });
1524
- await _optionalChain([debug, 'optionalAccess', _32 => _32.log, 'call', _33 => _33("SUBMIT", "SUBMIT_THIRD_PARTY_RESULT", {
1525
- messageId: result.messageId
1526
- })]);
1527
- return ok("is-call-return");
1528
- } else {
1529
- return ok("continue-workflow");
1530
- }
1531
- } catch (error) {
1532
- const isCallReturn = request.headers.get("Upstash-Workflow-Callback");
1533
- return err(
1534
- new QstashWorkflowError(
1535
- `Error when handling call return (isCallReturn=${isCallReturn}): ${error}`
1536
- )
1537
- );
1538
- }
1539
- };
1540
- var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step, failureUrl) => {
1541
- const baseHeaders = {
1542
- [WORKFLOW_INIT_HEADER]: initHeaderValue,
1543
- [WORKFLOW_ID_HEADER]: workflowRunId,
1544
- [WORKFLOW_URL_HEADER]: workflowUrl,
1545
- [`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`]: WORKFLOW_PROTOCOL_VERSION,
1546
- ...failureUrl ? {
1547
- [`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`]: "true",
1548
- "Upstash-Failure-Callback": failureUrl
1549
- } : {}
1550
- };
1551
- if (userHeaders) {
1552
- for (const header of userHeaders.keys()) {
1553
- baseHeaders[`Upstash-Forward-${header}`] = userHeaders.get(header);
1554
- if (_optionalChain([step, 'optionalAccess', _34 => _34.callHeaders])) {
1555
- baseHeaders[`Upstash-Callback-Forward-${header}`] = userHeaders.get(header);
1556
- }
1557
- }
1558
- }
1559
- if (_optionalChain([step, 'optionalAccess', _35 => _35.callHeaders])) {
1560
- const forwardedHeaders = Object.fromEntries(
1561
- Object.entries(step.callHeaders).map(([header, value]) => [
1562
- `Upstash-Forward-${header}`,
1563
- value
1564
- ])
1565
- );
1566
- const contentType = step.callHeaders["Content-Type"];
1567
- return {
1568
- ...baseHeaders,
1569
- ...forwardedHeaders,
1570
- "Upstash-Callback": workflowUrl,
1571
- "Upstash-Callback-Workflow-RunId": workflowRunId,
1572
- "Upstash-Callback-Workflow-CallType": "fromCallback",
1573
- "Upstash-Callback-Workflow-Init": "false",
1574
- "Upstash-Callback-Workflow-Url": workflowUrl,
1575
- "Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
1576
- "Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
1577
- "Upstash-Callback-Forward-Upstash-Workflow-StepName": step.stepName,
1578
- "Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
1579
- "Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
1580
- "Upstash-Callback-Forward-Upstash-Workflow-ContentType": _nullishCoalesce(contentType, () => ( DEFAULT_CONTENT_TYPE)),
1581
- "Upstash-Workflow-CallType": "toCallback"
1582
- };
1583
- }
1584
- return baseHeaders;
1585
- };
1586
- var verifyRequest = async (body, signature, verifier) => {
1587
- if (!verifier) {
1588
- return;
1589
- }
1590
- if (!signature) {
1591
- throw new QstashWorkflowError("`Upstash-Signature` header is not a string");
1592
- }
1593
- const isValid = await verifier.verify({
1594
- body,
1595
- signature
1596
- });
1597
- if (!isValid) {
1598
- throw new QstashWorkflowError("Invalid signature");
1599
- }
1600
- };
1601
-
1602
- // src/client/workflow/auto-executor.ts
1603
- var AutoExecutor = (_class3 = class _AutoExecutor {
1604
-
1605
- __init6() {this.promises = /* @__PURE__ */ new WeakMap()}
1606
-
1607
-
1608
-
1609
-
1610
- __init7() {this.indexInCurrentList = 0}
1611
- __init8() {this.stepCount = 0}
1612
- __init9() {this.planStepCount = 0}
1613
- __init10() {this.executingStep = false}
1614
- constructor(context, steps, debug) {;_class3.prototype.__init6.call(this);_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);_class3.prototype.__init10.call(this);
1615
- this.context = context;
1616
- this.debug = debug;
1617
- this.steps = steps;
1618
- this.nonPlanStepCount = this.steps.filter((step) => !step.targetStep).length;
1619
- }
1620
- /**
1621
- * Adds the step function to the list of step functions to run in
1622
- * parallel. After adding the function, defers the execution, so
1623
- * that if there is another step function to be added, it's also
1624
- * added.
1625
- *
1626
- * After all functions are added, list of functions are executed.
1627
- * If there is a single function, it's executed by itself. If there
1628
- * are multiple, they are run in parallel.
1629
- *
1630
- * If a function is already executing (this.executingStep), this
1631
- * means that there is a nested step which is not allowed. In this
1632
- * case, addStep throws QstashWorkflowError.
1633
- *
1634
- * @param stepInfo step plan to add
1635
- * @returns result of the step function
1636
- */
1637
- async addStep(stepInfo) {
1638
- if (this.executingStep) {
1639
- throw new QstashWorkflowError(
1640
- `A step can not be run inside another step. Tried to run '${stepInfo.stepName}' inside '${this.executingStep}'`
1641
- );
1642
- }
1643
- this.stepCount += 1;
1644
- const lazyStepList = _nullishCoalesce(this.activeLazyStepList, () => ( []));
1645
- if (!this.activeLazyStepList) {
1646
- this.activeLazyStepList = lazyStepList;
1647
- this.indexInCurrentList = 0;
1648
- }
1649
- lazyStepList.push(stepInfo);
1650
- const index = this.indexInCurrentList++;
1651
- const requestComplete = this.deferExecution().then(async () => {
1652
- if (!this.promises.has(lazyStepList)) {
1653
- const promise2 = this.getExecutionPromise(lazyStepList);
1654
- this.promises.set(lazyStepList, promise2);
1655
- this.activeLazyStepList = void 0;
1656
- this.planStepCount += lazyStepList.length > 1 ? lazyStepList.length : 0;
1657
- }
1658
- const promise = this.promises.get(lazyStepList);
1659
- return promise;
1660
- });
1661
- const result = await requestComplete;
1662
- return _AutoExecutor.getResult(lazyStepList, result, index);
1663
- }
1664
- /**
1665
- * Wraps a step function to set this.executingStep to step name
1666
- * before running and set this.executingStep to False after execution
1667
- * ends.
1668
- *
1669
- * this.executingStep allows us to detect nested steps which are not
1670
- * allowed.
1671
- *
1672
- * @param stepName name of the step being wrapped
1673
- * @param stepFunction step function to wrap
1674
- * @returns wrapped step function
1675
- */
1676
- async wrapStep(stepName, stepFunction) {
1677
- this.executingStep = stepName;
1678
- const result = await stepFunction();
1679
- this.executingStep = false;
1680
- return result;
1681
- }
1682
- /**
1683
- * Executes a step:
1684
- * - If the step result is available in the steps, returns the result
1685
- * - If the result is not avaiable, runs the function
1686
- * - Sends the result to QStash
1687
- *
1688
- * @param lazyStep lazy step to execute
1689
- * @returns step result
1690
- */
1691
- async runSingle(lazyStep) {
1692
- if (this.stepCount < this.nonPlanStepCount) {
1693
- const step = this.steps[this.stepCount + this.planStepCount];
1694
- validateStep(lazyStep, step);
1695
- await _optionalChain([this, 'access', _36 => _36.debug, 'optionalAccess', _37 => _37.log, 'call', _38 => _38("INFO", "RUN_SINGLE", {
1696
- fromRequest: true,
1697
- step,
1698
- stepCount: this.stepCount
1699
- })]);
1700
- return step.out;
1701
- }
1702
- const resultStep = await lazyStep.getResultStep(NO_CONCURRENCY, this.stepCount);
1703
- await _optionalChain([this, 'access', _39 => _39.debug, 'optionalAccess', _40 => _40.log, 'call', _41 => _41("INFO", "RUN_SINGLE", {
1704
- fromRequest: false,
1705
- step: resultStep,
1706
- stepCount: this.stepCount
1707
- })]);
1708
- await this.submitStepsToQstash([resultStep]);
1709
- return resultStep.out;
1710
- }
1711
- /**
1712
- * Runs steps in parallel.
1713
- *
1714
- * @param stepName parallel step name
1715
- * @param stepFunctions list of async functions to run in parallel
1716
- * @returns results of the functions run in parallel
1717
- */
1718
- async runParallel(parallelSteps) {
1719
- const initialStepCount = this.stepCount - (parallelSteps.length - 1);
1720
- const parallelCallState = this.getParallelCallState(parallelSteps.length, initialStepCount);
1721
- const sortedSteps = sortSteps(this.steps);
1722
- const plannedParallelStepCount = _optionalChain([sortedSteps, 'access', _42 => _42[initialStepCount + this.planStepCount], 'optionalAccess', _43 => _43.concurrent]);
1723
- if (parallelCallState !== "first" && plannedParallelStepCount !== parallelSteps.length) {
1724
- throw new QstashWorkflowError(
1725
- `Incompatible number of parallel steps when call state was '${parallelCallState}'. Expected ${parallelSteps.length}, got ${plannedParallelStepCount} from the request.`
1726
- );
1727
- }
1728
- await _optionalChain([this, 'access', _44 => _44.debug, 'optionalAccess', _45 => _45.log, 'call', _46 => _46("INFO", "RUN_PARALLEL", {
1729
- parallelCallState,
1730
- initialStepCount,
1731
- plannedParallelStepCount,
1732
- stepCount: this.stepCount,
1733
- planStepCount: this.planStepCount
1734
- })]);
1735
- switch (parallelCallState) {
1736
- case "first": {
1737
- const planSteps = parallelSteps.map(
1738
- (parallelStep, index) => parallelStep.getPlanStep(parallelSteps.length, initialStepCount + index)
1739
- );
1740
- await this.submitStepsToQstash(planSteps);
1741
- break;
1742
- }
1743
- case "partial": {
1744
- const planStep = this.steps.at(-1);
1745
- if (!planStep || planStep.targetStep === void 0) {
1746
- throw new QstashWorkflowError(
1747
- `There must be a last step and it should have targetStep larger than 0.Received: ${JSON.stringify(planStep)}`
1748
- );
1749
- }
1750
- const stepIndex = planStep.targetStep - initialStepCount;
1751
- validateStep(parallelSteps[stepIndex], planStep);
1752
- try {
1753
- const resultStep = await parallelSteps[stepIndex].getResultStep(
1754
- parallelSteps.length,
1755
- planStep.targetStep
1756
- );
1757
- await this.submitStepsToQstash([resultStep]);
1758
- } catch (error) {
1759
- if (error instanceof QstashWorkflowAbort) {
1760
- throw error;
1761
- }
1762
- throw new QstashWorkflowError(
1763
- `Error submitting steps to qstash in partial parallel step execution: ${error}`
1764
- );
1765
- }
1766
- break;
1767
- }
1768
- case "discard": {
1769
- throw new QstashWorkflowAbort("discarded parallel");
1770
- }
1771
- case "last": {
1772
- const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
1773
- validateParallelSteps(parallelSteps, parallelResultSteps);
1774
- return parallelResultSteps.map((step) => step.out);
1775
- }
1776
- }
1777
- const fillValue = void 0;
1778
- return Array.from({ length: parallelSteps.length }).fill(fillValue);
1779
- }
1780
- /**
1781
- * Determines the parallel call state
1782
- *
1783
- * First filters the steps to get the steps which are after `initialStepCount` parameter.
1784
- *
1785
- * Depending on the remaining steps, decides the parallel state:
1786
- * - "first": If there are no steps
1787
- * - "last" If there are equal to or more than `2 * parallelStepCount`. We multiply by two
1788
- * because each step in a parallel execution will have 2 steps: a plan step and a result
1789
- * step.
1790
- * - "partial": If the last step is a plan step
1791
- * - "discard": If the last step is not a plan step. This means that the parallel execution
1792
- * is in progress (there are still steps to run) and one step has finished and submitted
1793
- * its result to QStash
1794
- *
1795
- * @param parallelStepCount number of steps to run in parallel
1796
- * @param initialStepCount steps after the parallel invocation
1797
- * @returns parallel call state
1798
- */
1799
- getParallelCallState(parallelStepCount, initialStepCount) {
1800
- const remainingSteps = this.steps.filter(
1801
- (step) => (_nullishCoalesce(step.targetStep, () => ( step.stepId))) >= initialStepCount
1802
- );
1803
- if (remainingSteps.length === 0) {
1804
- return "first";
1805
- } else if (remainingSteps.length >= 2 * parallelStepCount) {
1806
- return "last";
1807
- } else if (_optionalChain([remainingSteps, 'access', _47 => _47.at, 'call', _48 => _48(-1), 'optionalAccess', _49 => _49.targetStep])) {
1808
- return "partial";
1809
- } else {
1810
- return "discard";
1811
- }
1812
- }
1813
- /**
1814
- * sends the steps to QStash as batch
1815
- *
1816
- * @param steps steps to send
1817
- */
1818
- async submitStepsToQstash(steps) {
1819
- if (steps.length === 0) {
1820
- throw new QstashWorkflowError(
1821
- `Unable to submit steps to Qstash. Provided list is empty. Current step: ${this.stepCount}`
1822
- );
1823
- }
1824
- await _optionalChain([this, 'access', _50 => _50.debug, 'optionalAccess', _51 => _51.log, 'call', _52 => _52("SUBMIT", "SUBMIT_STEP", { length: steps.length, steps })]);
1825
- const result = await this.context.qstashClient.batchJSON(
1826
- steps.map((singleStep) => {
1827
- const headers = getHeaders(
1828
- "false",
1829
- this.context.workflowRunId,
1830
- this.context.url,
1831
- this.context.headers,
1832
- singleStep,
1833
- this.context.failureUrl
1834
- );
1835
- const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
1836
- return singleStep.callUrl ? (
1837
- // if the step is a third party call, we call the third party
1838
- // url (singleStep.callUrl) and pass information about the workflow
1839
- // in the headers (handled in getHeaders). QStash makes the request
1840
- // to callUrl and returns the result to Workflow endpoint.
1841
- // handleThirdPartyCallResult method sends the result of the third
1842
- // party call to QStash.
1843
- {
1844
- headers,
1845
- method: singleStep.callMethod,
1846
- body: singleStep.callBody,
1847
- url: singleStep.callUrl
1848
- }
1849
- ) : (
1850
- // if the step is not a third party call, we use workflow
1851
- // endpoint (context.url) as URL when calling QStash. QStash
1852
- // calls us back with the updated steps list.
1853
- {
1854
- headers,
1855
- method: "POST",
1856
- body: singleStep,
1857
- url: this.context.url,
1858
- notBefore: willWait ? singleStep.sleepUntil : void 0,
1859
- delay: willWait ? singleStep.sleepFor : void 0
1860
- }
1861
- );
1862
- })
1863
- );
1864
- await _optionalChain([this, 'access', _53 => _53.debug, 'optionalAccess', _54 => _54.log, 'call', _55 => _55("INFO", "SUBMIT_STEP", {
1865
- messageIds: result.map((message) => {
1866
- return {
1867
- message: message.messageId
1868
- };
1869
- })
1870
- })]);
1871
- throw new QstashWorkflowAbort(steps[0].stepName, steps[0]);
1872
- }
1873
- /**
1874
- * Get the promise by executing the lazt steps list. If there is a single
1875
- * step, we call `runSingle`. Otherwise `runParallel` is called.
1876
- *
1877
- * @param lazyStepList steps list to execute
1878
- * @returns promise corresponding to the execution
1879
- */
1880
- getExecutionPromise(lazyStepList) {
1881
- return lazyStepList.length === 1 ? this.runSingle(lazyStepList[0]) : this.runParallel(lazyStepList);
1882
- }
1883
- /**
1884
- * @param lazyStepList steps we executed
1885
- * @param result result of the promise from `getExecutionPromise`
1886
- * @param index index of the current step
1887
- * @returns result[index] if lazyStepList > 1, otherwise result
1888
- */
1889
- static getResult(lazyStepList, result, index) {
1890
- if (lazyStepList.length === 1) {
1891
- return result;
1892
- } else if (Array.isArray(result) && lazyStepList.length === result.length && index < lazyStepList.length) {
1893
- return result[index];
1894
- } else {
1895
- throw new QstashWorkflowError(
1896
- `Unexpected parallel call result while executing step ${index}: '${result}'. Expected ${lazyStepList.length} many items`
1897
- );
1898
- }
1899
- }
1900
- async deferExecution() {
1901
- await Promise.resolve();
1902
- await Promise.resolve();
1903
- }
1904
- }, _class3);
1905
- var validateStep = (lazyStep, stepFromRequest) => {
1906
- if (lazyStep.stepName !== stepFromRequest.stepName) {
1907
- throw new QstashWorkflowError(
1908
- `Incompatible step name. Expected '${lazyStep.stepName}', got '${stepFromRequest.stepName}' from the request`
1909
- );
1910
- }
1911
- if (lazyStep.stepType !== stepFromRequest.stepType) {
1912
- throw new QstashWorkflowError(
1913
- `Incompatible step type. Expected '${lazyStep.stepType}', got '${stepFromRequest.stepType}' from the request`
1914
- );
1915
- }
1916
- };
1917
- var validateParallelSteps = (lazySteps, stepsFromRequest) => {
1918
- try {
1919
- for (const [index, stepFromRequest] of stepsFromRequest.entries()) {
1920
- validateStep(lazySteps[index], stepFromRequest);
1921
- }
1922
- } catch (error) {
1923
- if (error instanceof QstashWorkflowError) {
1924
- const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
1925
- const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
1926
- const requestStepNames = stepsFromRequest.map((step) => step.stepName);
1927
- const requestStepTypes = stepsFromRequest.map((step) => step.stepType);
1928
- throw new QstashWorkflowError(
1929
- `Incompatible steps detected in parallel execution: ${error.message}
1930
- > Step Names from the request: ${JSON.stringify(requestStepNames)}
1931
- Step Types from the request: ${JSON.stringify(requestStepTypes)}
1932
- > Step Names expected: ${JSON.stringify(lazyStepNames)}
1933
- Step Types expected: ${JSON.stringify(lazyStepTypes)}`
1934
- );
1935
- }
1936
- throw error;
1937
- }
1938
- };
1939
- var sortSteps = (steps) => {
1940
- const getStepId = (step) => _nullishCoalesce(step.targetStep, () => ( step.stepId));
1941
- return steps.toSorted((step, stepOther) => getStepId(step) - getStepId(stepOther));
1942
- };
1943
-
1944
- // src/client/workflow/steps.ts
1945
- var BaseLazyStep = class {
1946
-
1947
- // will be set in the subclasses
1948
- constructor(stepName) {
1949
- this.stepName = stepName;
1950
- }
1951
- };
1952
- var LazyFunctionStep = (_class4 = class extends BaseLazyStep {
1953
-
1954
- __init11() {this.stepType = "Run"}
1955
- constructor(stepName, stepFunction) {
1956
- super(stepName);_class4.prototype.__init11.call(this);;
1957
- this.stepFunction = stepFunction;
1958
- }
1959
- getPlanStep(concurrent, targetStep) {
1960
- {
1961
- return {
1962
- stepId: 0,
1963
- stepName: this.stepName,
1964
- stepType: this.stepType,
1965
- concurrent,
1966
- targetStep
1967
- };
1968
- }
1969
- }
1970
- async getResultStep(concurrent, stepId) {
1971
- const result = await this.stepFunction();
1972
- return {
1973
- stepId,
1974
- stepName: this.stepName,
1975
- stepType: this.stepType,
1976
- out: result,
1977
- concurrent
1978
- };
1979
- }
1980
- }, _class4);
1981
- var LazySleepStep = (_class5 = class extends BaseLazyStep {
1982
-
1983
- __init12() {this.stepType = "SleepFor"}
1984
- constructor(stepName, sleep) {
1985
- super(stepName);_class5.prototype.__init12.call(this);;
1986
- this.sleep = sleep;
1987
- }
1988
- getPlanStep(concurrent, targetStep) {
1989
- {
1990
- return {
1991
- stepId: 0,
1992
- stepName: this.stepName,
1993
- stepType: this.stepType,
1994
- sleepFor: this.sleep,
1995
- concurrent,
1996
- targetStep
1997
- };
1998
- }
1999
- }
2000
- async getResultStep(concurrent, stepId) {
2001
- return await Promise.resolve({
2002
- stepId,
2003
- stepName: this.stepName,
2004
- stepType: this.stepType,
2005
- sleepFor: this.sleep,
2006
- concurrent
2007
- });
2008
- }
2009
- }, _class5);
2010
- var LazySleepUntilStep = (_class6 = class extends BaseLazyStep {
2011
-
2012
- __init13() {this.stepType = "SleepUntil"}
2013
- constructor(stepName, sleepUntil) {
2014
- super(stepName);_class6.prototype.__init13.call(this);;
2015
- this.sleepUntil = sleepUntil;
2016
- }
2017
- getPlanStep(concurrent, targetStep) {
2018
- {
2019
- return {
2020
- stepId: 0,
2021
- stepName: this.stepName,
2022
- stepType: this.stepType,
2023
- sleepUntil: this.sleepUntil,
2024
- concurrent,
2025
- targetStep
2026
- };
2027
- }
2028
- }
2029
- async getResultStep(concurrent, stepId) {
2030
- return await Promise.resolve({
2031
- stepId,
2032
- stepName: this.stepName,
2033
- stepType: this.stepType,
2034
- sleepUntil: this.sleepUntil,
2035
- concurrent
2036
- });
2037
- }
2038
- }, _class6);
2039
- var LazyCallStep = (_class7 = class extends BaseLazyStep {
2040
-
2041
-
2042
-
2043
-
2044
- __init14() {this.stepType = "Call"}
2045
- constructor(stepName, url, method, body, headers) {
2046
- super(stepName);_class7.prototype.__init14.call(this);;
2047
- this.url = url;
2048
- this.method = method;
2049
- this.body = body;
2050
- this.headers = headers;
2051
- }
2052
- getPlanStep(concurrent, targetStep) {
2053
- {
2054
- return {
2055
- stepId: 0,
2056
- stepName: this.stepName,
2057
- stepType: this.stepType,
2058
- concurrent,
2059
- targetStep
2060
- };
2061
- }
2062
- }
2063
- async getResultStep(concurrent, stepId) {
2064
- return await Promise.resolve({
2065
- stepId,
2066
- stepName: this.stepName,
2067
- stepType: this.stepType,
2068
- concurrent,
2069
- callUrl: this.url,
2070
- callMethod: this.method,
2071
- callBody: this.body,
2072
- callHeaders: this.headers
2073
- });
2074
- }
2075
- }, _class7);
2076
-
2077
- // src/client/workflow/context.ts
2078
- var WorkflowContext = class {
2079
-
2080
-
2081
-
2082
-
2083
-
2084
-
2085
-
2086
-
2087
-
2088
- constructor({
2089
- qstashClient,
2090
- workflowRunId,
2091
- headers,
2092
- steps,
2093
- url,
2094
- failureUrl,
2095
- debug,
2096
- initialPayload,
2097
- rawInitialPayload
2098
- }) {
2099
- this.qstashClient = qstashClient;
2100
- this.workflowRunId = workflowRunId;
2101
- this.steps = steps;
2102
- this.url = url;
2103
- this.failureUrl = failureUrl;
2104
- this.headers = headers;
2105
- this.requestPayload = initialPayload;
2106
- this.rawInitialPayload = _nullishCoalesce(rawInitialPayload, () => ( JSON.stringify(this.requestPayload)));
2107
- this.executor = new AutoExecutor(this, this.steps, debug);
2108
- }
2109
- /**
2110
- * Executes a workflow step
2111
- *
2112
- * ```typescript
2113
- * const result = await context.run("step 1", async () => {
2114
- * return await Promise.resolve("result")
2115
- * })
2116
- * ```
2117
- *
2118
- * Can also be called in parallel and the steps will be executed
2119
- * simulatenously:
2120
- *
2121
- * ```typescript
2122
- * const [result1, result2] = await Promise.all([
2123
- * context.run("step 1", async () => {
2124
- * return await Promise.resolve("result1")
2125
- * })
2126
- * context.run("step 2", async () => {
2127
- * return await Promise.resolve("result2")
2128
- * })
2129
- * ])
2130
- * ```
2131
- *
2132
- * @param stepName name of the step
2133
- * @param stepFunction step function to be executed
2134
- * @returns result of the step function
2135
- */
2136
- async run(stepName, stepFunction) {
2137
- const wrappedStepFunction = async () => this.executor.wrapStep(stepName, stepFunction);
2138
- return this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
2139
- }
2140
- /**
2141
- * Stops the execution for the duration provided.
2142
- *
2143
- * @param stepName
2144
- * @param duration sleep duration in seconds
2145
- * @returns
2146
- */
2147
- async sleep(stepName, duration) {
2148
- await this.addStep(new LazySleepStep(stepName, duration));
2149
- }
2150
- /**
2151
- * Stops the execution until the date time provided.
2152
- *
2153
- * @param stepName
2154
- * @param datetime time to sleep until. Can be provided as a number (in unix seconds),
2155
- * as a Date object or a string (passed to `new Date(datetimeString)`)
2156
- * @returns
2157
- */
2158
- async sleepUntil(stepName, datetime) {
2159
- let time;
2160
- if (typeof datetime === "number") {
2161
- time = datetime;
2162
- } else {
2163
- datetime = typeof datetime === "string" ? new Date(datetime) : datetime;
2164
- time = Math.round(datetime.getTime() / 1e3);
2165
- }
2166
- await this.addStep(new LazySleepUntilStep(stepName, time));
2167
- }
2168
- async call(stepName, url, method, body, headers) {
2169
- return await this.addStep(
2170
- new LazyCallStep(stepName, url, method, body, _nullishCoalesce(headers, () => ( {})))
2171
- );
2172
- }
2173
- /**
2174
- * Adds steps to the executor. Needed so that it can be overwritten in
2175
- * DisabledWorkflowContext.
2176
- */
2177
- async addStep(step) {
2178
- return await this.executor.addStep(step);
2179
- }
2180
- };
2181
- var DisabledWorkflowContext = (_class8 = class _DisabledWorkflowContext extends WorkflowContext {
2182
- static __initStatic() {this.disabledMessage = "disabled-qstash-worklfow-run"}
2183
- /**
2184
- * overwrite the WorkflowContext.addStep method to always raise QstashWorkflowAbort
2185
- * error in order to stop the execution whenever we encounter a step.
2186
- *
2187
- * @param _step
2188
- */
2189
- // eslint-disable-next-line @typescript-eslint/require-await
2190
- async addStep(_step) {
2191
- throw new QstashWorkflowAbort(_DisabledWorkflowContext.disabledMessage);
2192
- }
2193
- /**
2194
- * copies the passed context to create a DisabledWorkflowContext. Then, runs the
2195
- * route function with the new context.
2196
- *
2197
- * - returns "run-ended" if there are no steps found or
2198
- * if the auth failed and user called `return`
2199
- * - returns "step-found" if DisabledWorkflowContext.addStep is called.
2200
- * - if there is another error, returns the error.
2201
- *
2202
- * @param routeFunction
2203
- */
2204
- static async tryAuthentication(routeFunction, context) {
2205
- const disabledContext = new _DisabledWorkflowContext({
2206
- qstashClient: new Client({ baseUrl: "disabled-client", token: "disabled-client" }),
2207
- workflowRunId: context.workflowRunId,
2208
- headers: context.headers,
2209
- steps: [],
2210
- url: context.url,
2211
- failureUrl: context.failureUrl,
2212
- initialPayload: context.requestPayload,
2213
- rawInitialPayload: context.rawInitialPayload
2214
- });
2215
- try {
2216
- await routeFunction(disabledContext);
2217
- } catch (error) {
2218
- if (error instanceof QstashWorkflowAbort && error.stepName === this.disabledMessage) {
2219
- return ok("step-found");
2220
- }
2221
- return err(error);
2222
- }
2223
- return ok("run-ended");
2224
- }
2225
- }, _class8.__initStatic(), _class8);
2226
-
2227
- // src/client/workflow/logger.ts
2228
- var LOG_LEVELS = ["DEBUG", "INFO", "SUBMIT", "WARN", "ERROR"];
2229
- var WorkflowLogger = (_class9 = class _WorkflowLogger {
2230
- __init15() {this.logs = []}
2231
-
2232
- constructor(options) {;_class9.prototype.__init15.call(this);
2233
- this.options = options;
2234
- }
2235
- async log(level, eventType, details) {
2236
- if (this.shouldLog(level)) {
2237
- const timestamp = Date.now();
2238
- const logEntry = {
2239
- timestamp,
2240
- logLevel: level,
2241
- eventType,
2242
- details
2243
- };
2244
- this.logs.push(logEntry);
2245
- if (this.options.logOutput === "console") {
2246
- this.writeToConsole(logEntry);
2247
- }
2248
- await new Promise((resolve) => setTimeout(resolve, 100));
2249
- }
2250
- }
2251
- writeToConsole(logEntry) {
2252
- const JSON_SPACING = 2;
2253
- console.log(JSON.stringify(logEntry, void 0, JSON_SPACING));
2254
- }
2255
- shouldLog(level) {
2256
- return LOG_LEVELS.indexOf(level) >= LOG_LEVELS.indexOf(this.options.logLevel);
2257
- }
2258
- static getLogger(verbose) {
2259
- if (typeof verbose === "object") {
2260
- return verbose;
2261
- } else {
2262
- return verbose ? new _WorkflowLogger({
2263
- logLevel: "INFO",
2264
- logOutput: "console"
2265
- }) : void 0;
2266
- }
2267
- }
2268
- }, _class9);
2269
-
2270
- // node_modules/nanoid/index.js
2271
- var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
2272
-
2273
- // node_modules/nanoid/url-alphabet/index.js
2274
- var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
2275
-
2276
- // node_modules/nanoid/index.js
2277
- var POOL_SIZE_MULTIPLIER = 128;
2278
- var pool;
2279
- var poolOffset;
2280
- var fillPool = (bytes) => {
2281
- if (!pool || pool.length < bytes) {
2282
- pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
2283
- _crypto2.default.randomFillSync(pool);
2284
- poolOffset = 0;
2285
- } else if (poolOffset + bytes > pool.length) {
2286
- _crypto2.default.randomFillSync(pool);
2287
- poolOffset = 0;
2288
- }
2289
- poolOffset += bytes;
2290
- };
2291
- var nanoid = (size = 21) => {
2292
- fillPool(size -= 0);
2293
- let id = "";
2294
- for (let i = poolOffset - size; i < poolOffset; i++) {
2295
- id += urlAlphabet[pool[i] & 63];
2296
- }
2297
- return id;
2298
- };
2299
-
2300
- // src/client/workflow/workflow-parser.ts
2301
- var getPayload = async (request) => {
2302
- try {
2303
- return await request.text();
2304
- } catch (e2) {
2305
- return;
2306
- }
2307
- };
2308
- var decodeBase64 = (encodedString) => {
2309
- return Buffer.from(encodedString, "base64").toString();
2310
- };
2311
- var parsePayload = (rawPayload) => {
2312
- const [encodedInitialPayload, ...encodedSteps] = JSON.parse(rawPayload);
2313
- const rawInitialPayload = decodeBase64(encodedInitialPayload.body);
2314
- const initialStep = {
2315
- stepId: 0,
2316
- stepName: "init",
2317
- stepType: "Initial",
2318
- out: rawInitialPayload,
2319
- concurrent: NO_CONCURRENCY
2320
- };
2321
- const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
2322
- const otherSteps = stepsToDecode.map((rawStep) => {
2323
- return JSON.parse(decodeBase64(rawStep.body));
2324
- });
2325
- const steps = [initialStep, ...otherSteps];
2326
- return {
2327
- rawInitialPayload,
2328
- steps
2329
- };
2330
- };
2331
- var deduplicateSteps = (steps) => {
2332
- const targetStepIds = [];
2333
- const stepIds = [];
2334
- const deduplicatedSteps = [];
2335
- for (const step of steps) {
2336
- if (step.stepId === 0) {
2337
- if (!targetStepIds.includes(_nullishCoalesce(step.targetStep, () => ( 0)))) {
2338
- deduplicatedSteps.push(step);
2339
- targetStepIds.push(_nullishCoalesce(step.targetStep, () => ( 0)));
2340
- }
2341
- } else {
2342
- if (!stepIds.includes(step.stepId)) {
2343
- deduplicatedSteps.push(step);
2344
- stepIds.push(step.stepId);
2345
- }
2346
- }
2347
- }
2348
- return deduplicatedSteps;
2349
- };
2350
- var checkIfLastOneIsDuplicate = async (steps, debug) => {
2351
- if (steps.length < 2) {
2352
- return false;
2353
- }
2354
- const lastStep = steps.at(-1);
2355
- const lastStepId = lastStep.stepId;
2356
- const lastTargetStepId = lastStep.targetStep;
2357
- for (let index = 0; index < steps.length - 1; index++) {
2358
- const step = steps[index];
2359
- if (step.stepId === lastStepId && step.targetStep === lastTargetStepId) {
2360
- 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.`;
2361
- await _optionalChain([debug, 'optionalAccess', _56 => _56.log, 'call', _57 => _57("WARN", "RESPONSE_DEFAULT", message)]);
2362
- console.warn(message);
2363
- return true;
2364
- }
2365
- }
2366
- return false;
2367
- };
2368
- var validateRequest = (request) => {
2369
- const versionHeader = request.headers.get(WORKFLOW_PROTOCOL_VERSION_HEADER);
2370
- const isFirstInvocation = !versionHeader;
2371
- if (!isFirstInvocation && versionHeader !== WORKFLOW_PROTOCOL_VERSION) {
2372
- throw new QstashWorkflowError(
2373
- `Incompatible workflow sdk protocol version. Expected ${WORKFLOW_PROTOCOL_VERSION}, got ${versionHeader} from the request.`
2374
- );
2375
- }
2376
- const workflowRunId = isFirstInvocation ? `wfr_${nanoid()}` : _nullishCoalesce(request.headers.get(WORKFLOW_ID_HEADER), () => ( ""));
2377
- if (workflowRunId.length === 0) {
2378
- throw new QstashWorkflowError("Couldn't get workflow id from header");
2379
- }
2380
- return {
2381
- isFirstInvocation,
2382
- workflowRunId
2383
- };
2384
- };
2385
- var parseRequest = async (request, isFirstInvocation, verifier, debug) => {
2386
- const payload = await getPayload(request);
2387
- await verifyRequest(_nullishCoalesce(payload, () => ( "")), request.headers.get("upstash-signature"), verifier);
2388
- if (isFirstInvocation) {
2389
- return {
2390
- rawInitialPayload: _nullishCoalesce(payload, () => ( "")),
2391
- steps: [],
2392
- isLastDuplicate: false
2393
- };
2394
- } else {
2395
- if (!payload) {
2396
- throw new QstashWorkflowError("Only first call can have an empty body");
2397
- }
2398
- const { rawInitialPayload, steps } = parsePayload(payload);
2399
- const isLastDuplicate = await checkIfLastOneIsDuplicate(steps, debug);
2400
- const deduplicatedSteps = deduplicateSteps(steps);
2401
- return {
2402
- rawInitialPayload,
2403
- steps: deduplicatedSteps,
2404
- isLastDuplicate
2405
- };
2406
- }
2407
- };
2408
- var handleFailure = async (request, failureFunction) => {
2409
- if (request.headers.get(WORKFLOW_FAILURE_HEADER) !== "true") {
2410
- return ok("not-failure-callback");
2411
- }
2412
- if (!failureFunction) {
2413
- return err(
2414
- new QstashWorkflowError(
2415
- "Workflow endpoint is called to handle a failure, but a failureFunction is not provided in serve options. Either provide a failureUrl or a failureFunction."
2416
- )
2417
- );
2418
- }
2419
- try {
2420
- const { status, header, body, workflowRunId } = await request.json();
2421
- const decodedBody = body ? atob(body) : "{}";
2422
- const payload = JSON.parse(decodedBody);
2423
- await failureFunction(status, header, payload, workflowRunId);
2424
- } catch (error) {
2425
- return err(error);
2426
- }
2427
- return ok("is-failure-callback");
2428
- };
2429
-
2430
- // src/client/workflow/serve.ts
2431
- var processOptions = (options) => {
2432
- const receiverEnvironmentVariablesSet = Boolean(
2433
- process.env.QSTASH_CURRENT_SIGNING_KEY && process.env.QSTASH_NEXT_SIGNING_KEY
2434
- );
2435
- return {
2436
- qstashClient: new Client({
2437
- baseUrl: process.env.QSTASH_URL,
2438
- token: process.env.QSTASH_TOKEN
2439
- }),
2440
- onStepFinish: (workflowRunId, finishCondition) => new Response(JSON.stringify({ workflowRunId, finishCondition }), {
2441
- status: 200
2442
- }),
2443
- initialPayloadParser: (initialRequest) => {
2444
- if (!initialRequest) {
2445
- return void 0;
2446
- }
2447
- try {
2448
- return JSON.parse(initialRequest);
2449
- } catch (error) {
2450
- if (error instanceof SyntaxError) {
2451
- return initialRequest;
2452
- }
2453
- throw error;
2454
- }
2455
- },
2456
- receiver: receiverEnvironmentVariablesSet ? new Receiver({
2457
- currentSigningKey: process.env.QSTASH_CURRENT_SIGNING_KEY,
2458
- nextSigningKey: process.env.QSTASH_NEXT_SIGNING_KEY
2459
- }) : void 0,
2460
- ...options
2461
- };
2462
- };
2463
- var serve = ({
2464
- routeFunction,
2465
- options
2466
- }) => {
2467
- const {
2468
- qstashClient,
2469
- onStepFinish,
2470
- initialPayloadParser,
2471
- url,
2472
- verbose,
2473
- receiver,
2474
- failureUrl,
2475
- failureFunction
2476
- } = processOptions(options);
2477
- const debug = WorkflowLogger.getLogger(verbose);
2478
- return async (request) => {
2479
- const workflowUrl = _nullishCoalesce(url, () => ( request.url));
2480
- const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
2481
- await _optionalChain([debug, 'optionalAccess', _58 => _58.log, 'call', _59 => _59("INFO", "ENDPOINT_START")]);
2482
- const failureCheck = await handleFailure(request, failureFunction);
2483
- if (failureCheck.isErr()) {
2484
- throw failureCheck.error;
2485
- } else if (failureCheck.value === "is-failure-callback") {
2486
- return onStepFinish("no-workflow-id", "failure-callback");
2487
- }
2488
- const { isFirstInvocation, workflowRunId } = validateRequest(request);
2489
- const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
2490
- request,
2491
- isFirstInvocation,
2492
- receiver,
2493
- debug
2494
- );
2495
- if (isLastDuplicate) {
2496
- return onStepFinish("no-workflow-id", "duplicate-step");
2497
- }
2498
- const workflowContext = new WorkflowContext({
2499
- qstashClient,
2500
- workflowRunId,
2501
- initialPayload: initialPayloadParser(rawInitialPayload),
2502
- rawInitialPayload,
2503
- headers: recreateUserHeaders(request.headers),
2504
- steps,
2505
- url: workflowUrl,
2506
- failureUrl: workflowFailureUrl,
2507
- debug
2508
- });
2509
- const authCheck = await DisabledWorkflowContext.tryAuthentication(
2510
- routeFunction,
2511
- workflowContext
2512
- );
2513
- if (authCheck.isErr()) {
2514
- await _optionalChain([debug, 'optionalAccess', _60 => _60.log, 'call', _61 => _61("ERROR", "ERROR", { error: authCheck.error.message })]);
2515
- throw authCheck.error;
2516
- } else if (authCheck.value === "run-ended") {
2517
- return onStepFinish("no-workflow-id", "auth-fail");
2518
- }
2519
- const callReturnCheck = await handleThirdPartyCallResult(
2520
- request,
2521
- rawInitialPayload,
2522
- qstashClient,
2523
- workflowUrl,
2524
- workflowFailureUrl,
2525
- debug
2526
- );
2527
- if (callReturnCheck.isErr()) {
2528
- await _optionalChain([debug, 'optionalAccess', _62 => _62.log, 'call', _63 => _63("ERROR", "SUBMIT_THIRD_PARTY_RESULT", {
2529
- error: callReturnCheck.error.message
2530
- })]);
2531
- throw callReturnCheck.error;
2532
- } else if (callReturnCheck.value === "continue-workflow") {
2533
- const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, debug) : await triggerRouteFunction({
2534
- onStep: async () => routeFunction(workflowContext),
2535
- onCleanup: async () => {
2536
- await triggerWorkflowDelete(workflowContext, debug);
2537
- }
2538
- });
2539
- if (result.isErr()) {
2540
- await _optionalChain([debug, 'optionalAccess', _64 => _64.log, 'call', _65 => _65("ERROR", "ERROR", { error: result.error.message })]);
2541
- throw result.error;
2542
- }
2543
- await _optionalChain([debug, 'optionalAccess', _66 => _66.log, 'call', _67 => _67("INFO", "RESPONSE_WORKFLOW", {
2544
- workflowRunId: workflowContext.workflowRunId
2545
- })]);
2546
- return onStepFinish(workflowContext.workflowRunId, "success");
2547
- }
2548
- await _optionalChain([debug, 'optionalAccess', _68 => _68.log, 'call', _69 => _69("INFO", "RESPONSE_DEFAULT")]);
2549
- return onStepFinish("no-workflow-id", "fromCallback");
2550
- };
2551
- };
2552
-
2553
- // src/client/workflow/index.ts
2554
- var Workflow = class {
2555
-
2556
- constructor(http) {
2557
- this.http = http;
2558
- }
2559
- /**
2560
- * Cancel an ongoing workflow
2561
- *
2562
- * @param workflowRunId run id of the workflow to delete
2563
- * @returns true if workflow is succesfully deleted. Otherwise throws QStashError
2564
- */
2565
- async cancel(workflowRunId) {
2566
- const result = await this.http.request({
2567
- path: ["v2", "workflows", "runs", `${workflowRunId}?cancel=true`],
2568
- method: "DELETE",
2569
- parseResponseAsJson: false
2570
- });
2571
- return _nullishCoalesce(result, () => ( true));
2572
- }
2573
- };
2574
-
2575
-
2576
-
2577
-
2578
-
2579
-
2580
-
2581
-
2582
-
2583
-
2584
-
2585
-
2586
-
2587
-
2588
-
2589
-
2590
-
2591
-
2592
-
2593
-
2594
-
2595
-
2596
- 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.Chat = Chat; exports.Messages = Messages; exports.Schedules = Schedules; exports.UrlGroups = UrlGroups; exports.StepTypes = StepTypes; exports.WorkflowContext = WorkflowContext; exports.DisabledWorkflowContext = DisabledWorkflowContext; exports.WorkflowLogger = WorkflowLogger; exports.serve = serve; exports.Workflow = Workflow; exports.Client = Client;