@upstash/qstash 2.7.12 → 2.7.14

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Receiver,
3
3
  serve
4
- } from "./chunk-Q6E5NF42.mjs";
4
+ } from "./chunk-Q2AGFQYM.mjs";
5
5
 
6
6
  // node_modules/defu/dist/defu.mjs
7
7
  function isPlainObject(value) {
@@ -0,0 +1,15 @@
1
+ // src/client/api/email.ts
2
+ var resend = ({
3
+ token,
4
+ batch = false
5
+ }) => {
6
+ return {
7
+ owner: "resend",
8
+ baseUrl: `https://api.resend.com/emails${batch ? "/batch" : ""}`,
9
+ token
10
+ };
11
+ };
12
+
13
+ export {
14
+ resend
15
+ };
@@ -24,11 +24,14 @@ var Receiver = class {
24
24
  * If that fails, the signature is invalid and a `SignatureError` is thrown.
25
25
  */
26
26
  async verify(request) {
27
- const isValid = await this.verifyWithKey(this.currentSigningKey, request);
28
- if (isValid) {
29
- return true;
27
+ let payload;
28
+ try {
29
+ payload = await this.verifyWithKey(this.currentSigningKey, request);
30
+ } catch {
31
+ payload = await this.verifyWithKey(this.nextSigningKey, request);
30
32
  }
31
- return this.verifyWithKey(this.nextSigningKey, request);
33
+ this.verifyBodyAndUrl(payload, request);
34
+ return true;
32
35
  }
33
36
  /**
34
37
  * Verify signature with a specific signing key
@@ -40,7 +43,10 @@ var Receiver = class {
40
43
  }).catch((error) => {
41
44
  throw new SignatureError(error.message);
42
45
  });
43
- const p = jwt.payload;
46
+ return jwt.payload;
47
+ }
48
+ verifyBodyAndUrl(payload, request) {
49
+ const p = payload;
44
50
  if (request.url !== void 0 && p.sub !== request.url) {
45
51
  throw new SignatureError(`invalid subject: ${p.sub}, want: ${request.url}`);
46
52
  }
@@ -49,7 +55,14 @@ var Receiver = class {
49
55
  if (p.body.replace(padding, "") !== bodyHash.replace(padding, "")) {
50
56
  throw new SignatureError(`body hash does not match, want: ${p.body}, got: ${bodyHash}`);
51
57
  }
52
- return true;
58
+ }
59
+ };
60
+
61
+ // src/client/api/utils.ts
62
+ var appendAPIOptions = (request, headers) => {
63
+ if (request.api?.name === "email") {
64
+ headers.set("Authorization", request.api.provider.token);
65
+ request.method = request.method ?? "POST";
53
66
  }
54
67
  };
55
68
 
@@ -517,7 +530,7 @@ var Chat = class _Chat {
517
530
 
518
531
  // src/client/llm/utils.ts
519
532
  function appendLLMOptionsIfNeeded(request, headers, http) {
520
- if (!request.api)
533
+ if (request.api?.name === "email" || !request.api)
521
534
  return;
522
535
  const provider = request.api.provider;
523
536
  const analytics = request.api.analytics;
@@ -674,7 +687,15 @@ function processHeaders(request) {
674
687
  return headers;
675
688
  }
676
689
  function getRequestPath(request) {
677
- return request.url ?? request.urlGroup ?? request.topic ?? `api/${request.api?.name}`;
690
+ const nonApiPath = request.url ?? request.urlGroup ?? request.topic;
691
+ if (nonApiPath)
692
+ return nonApiPath;
693
+ if (request.api?.name === "llm")
694
+ return `api/${request.api.name}`;
695
+ if (request.api?.name === "email") {
696
+ return request.api.provider.baseUrl;
697
+ }
698
+ throw new QstashError(`Failed to infer request path for ${JSON.stringify(request)}`);
678
699
  }
679
700
  var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
680
701
  var NANOID_LENGTH = 21;
@@ -687,10 +708,18 @@ function decodeBase64(base64) {
687
708
  const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
688
709
  return new TextDecoder().decode(intArray);
689
710
  } catch (error) {
690
- console.warn(
691
- `Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
692
- );
693
- return atob(base64);
711
+ try {
712
+ const result = atob(base64);
713
+ console.warn(
714
+ `Upstash QStash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
715
+ );
716
+ return result;
717
+ } catch (error2) {
718
+ console.warn(
719
+ `Upstash QStash: Failed to decode base64 "${base64}" with atob. Returning it as it is. ${error2}`
720
+ );
721
+ return base64;
722
+ }
694
723
  }
695
724
  }
696
725
 
@@ -783,6 +812,7 @@ var Queue = class {
783
812
  headers.set("Content-Type", "application/json");
784
813
  ensureCallbackPresent(request);
785
814
  appendLLMOptionsIfNeeded(request, headers, this.http);
815
+ appendAPIOptions(request, headers);
786
816
  const response = await this.enqueue({
787
817
  ...request,
788
818
  body: JSON.stringify(request.body),
@@ -865,6 +895,9 @@ var Schedules = class {
865
895
  if (request.scheduleId !== void 0) {
866
896
  headers.set("Upstash-Schedule-Id", request.scheduleId);
867
897
  }
898
+ if (request.queueName !== void 0) {
899
+ headers.set("Upstash-Queue-Name", request.queueName);
900
+ }
868
901
  return await this.http.request({
869
902
  method: "POST",
870
903
  headers,
@@ -1082,6 +1115,7 @@ var Client = class {
1082
1115
  headers.set("Content-Type", "application/json");
1083
1116
  ensureCallbackPresent(request);
1084
1117
  appendLLMOptionsIfNeeded(request, headers, this.http);
1118
+ appendAPIOptions(request, headers);
1085
1119
  const response = await this.publish({
1086
1120
  ...request,
1087
1121
  headers,
@@ -1126,6 +1160,7 @@ var Client = class {
1126
1160
  message.headers = new Headers(message.headers);
1127
1161
  ensureCallbackPresent(message);
1128
1162
  appendLLMOptionsIfNeeded(message, message.headers, this.http);
1163
+ appendAPIOptions(message, message.headers);
1129
1164
  message.headers.set("Content-Type", "application/json");
1130
1165
  }
1131
1166
  const response = await this.batch(request);
@@ -59,8 +59,19 @@ declare class Receiver {
59
59
  * Verify signature with a specific signing key
60
60
  */
61
61
  private verifyWithKey;
62
+ private verifyBodyAndUrl;
62
63
  }
63
64
 
65
+ type EmailProviderReturnType = {
66
+ owner: "resend";
67
+ baseUrl: "https://api.resend.com/emails" | "https://api.resend.com/emails/batch";
68
+ token: string;
69
+ };
70
+ declare const resend: ({ token, batch, }: {
71
+ token: string;
72
+ batch?: boolean;
73
+ }) => EmailProviderReturnType;
74
+
64
75
  type State = "CREATED" | "ACTIVE" | "DELIVERED" | "ERROR" | "RETRY" | "FAILED";
65
76
  type HTTPMethods = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
66
77
  type Event = {
@@ -608,6 +619,7 @@ type Schedule = {
608
619
  failureCallback?: string;
609
620
  callerIp?: string;
610
621
  isPaused: boolean;
622
+ queueName?: string;
611
623
  };
612
624
  type CreateScheduleRequest = {
613
625
  /**
@@ -687,11 +699,15 @@ type CreateScheduleRequest = {
687
699
  /**
688
700
  * Schedule id to use.
689
701
  *
690
- * Can be used to updatine the settings of an existing schedule.
702
+ * Can be used to update the settings of an existing schedule.
691
703
  *
692
704
  * @default undefined
693
705
  */
694
706
  scheduleId?: string;
707
+ /**
708
+ * Queue name to schedule the message over.
709
+ */
710
+ queueName?: string;
695
711
  };
696
712
  declare class Schedules {
697
713
  private readonly http;
@@ -1625,6 +1641,7 @@ type PublishRequest<TBody = BodyInit> = {
1625
1641
  token: string;
1626
1642
  };
1627
1643
  };
1644
+ topic?: never;
1628
1645
  /**
1629
1646
  * Use a callback url to forward the response of your destination server to your callback url.
1630
1647
  *
@@ -1633,13 +1650,26 @@ type PublishRequest<TBody = BodyInit> = {
1633
1650
  * @default undefined
1634
1651
  */
1635
1652
  callback: string;
1653
+ } | {
1654
+ url?: never;
1655
+ urlGroup?: never;
1656
+ /**
1657
+ * The api endpoint the request should be sent to.
1658
+ */
1659
+ api: {
1660
+ name: "email";
1661
+ provider: EmailProviderReturnType;
1662
+ };
1636
1663
  topic?: never;
1664
+ callback?: string;
1637
1665
  } | {
1638
1666
  url?: never;
1639
1667
  urlGroup?: never;
1640
- api: never;
1668
+ api?: never;
1641
1669
  /**
1642
1670
  * Deprecated. The topic the message should be sent to. Same as urlGroup
1671
+ *
1672
+ * @deprecated
1643
1673
  */
1644
1674
  topic?: string;
1645
1675
  /**
@@ -1785,4 +1815,4 @@ type PublishResponse<TRequest> = TRequest extends {
1785
1815
  urlGroup: string;
1786
1816
  } ? PublishToUrlGroupsResponse : PublishToApiResponse;
1787
1817
 
1788
- export { type AnalyticsConfig as $, type AddEndpointsRequest as A, type BodyInit as B, type ChatRateLimit as C, type ChatCompletion as D, type EventsRequest as E, type FailureFunctionPayload as F, type GetEventsResponse as G, type HTTPMethods as H, type ChatCompletionChunk as I, type StreamEnabled as J, type StreamDisabled as K, type StreamParameter as L, type Message as M, type PromptChatRequest as N, type OpenAIChatModel as O, type PublishBatchRequest as P, type QueueRequest as Q, type RateLimit as R, type Step as S, type ChatRequest as T, type UrlGroup as U, type VerifyRequest as V, type WithCursor as W, custom as X, openai as Y, upstash as Z, type ProviderReturnType as _, type ReceiverConfig as a, type AnalyticsSetup as a0, setupAnalytics as a1, type RouteFunction as a2, type WorkflowServeOptions as a3, Workflow as a4, processOptions as a5, serve as a6, WorkflowContext as a7, DisabledWorkflowContext as a8, type WorkflowClient as a9, type WorkflowReceiver as aa, StepTypes as ab, type StepType as ac, type RawStep as ad, type SyncStepFunction as ae, type AsyncStepFunction as af, type StepFunction as ag, type ParallelCallState as ah, type FinishCondition as ai, type RequiredExceptFields as aj, type LogLevel as ak, type WorkflowLoggerOptions as al, WorkflowLogger as am, SignatureError as b, Receiver as c, type PublishRequest as d, type PublishJsonRequest as e, Client as f, type PublishToApiResponse as g, type PublishToUrlResponse as h, type PublishToUrlGroupsResponse as i, type PublishResponse as j, type MessagePayload as k, Messages as l, type Schedule as m, type CreateScheduleRequest as n, Schedules as o, type Endpoint as p, type RemoveEndpointsRequest as q, UrlGroups as r, type State as s, type Event as t, type EventPayload as u, type GetEventsPayload as v, type HeadersInit as w, type RequestOptions as x, Chat as y, type ChatCompletionMessage as z };
1818
+ export { type AnalyticsConfig as $, type AddEndpointsRequest as A, type BodyInit as B, type ChatRateLimit as C, type ChatCompletion as D, type EventsRequest as E, type FailureFunctionPayload as F, type GetEventsResponse as G, type HTTPMethods as H, type ChatCompletionChunk as I, type StreamEnabled as J, type StreamDisabled as K, type StreamParameter as L, type Message as M, type PromptChatRequest as N, type OpenAIChatModel as O, type PublishBatchRequest as P, type QueueRequest as Q, type RateLimit as R, type Step as S, type ChatRequest as T, type UrlGroup as U, type VerifyRequest as V, type WithCursor as W, custom as X, openai as Y, upstash as Z, type ProviderReturnType as _, type ReceiverConfig as a, type AnalyticsSetup as a0, setupAnalytics as a1, resend as a2, type RouteFunction as a3, type WorkflowServeOptions as a4, Workflow as a5, processOptions as a6, serve as a7, WorkflowContext as a8, DisabledWorkflowContext as a9, type WorkflowClient as aa, type WorkflowReceiver as ab, StepTypes as ac, type StepType as ad, type RawStep as ae, type SyncStepFunction as af, type AsyncStepFunction as ag, type StepFunction as ah, type ParallelCallState as ai, type FinishCondition as aj, type RequiredExceptFields as ak, type LogLevel as al, type WorkflowLoggerOptions as am, WorkflowLogger as an, SignatureError as b, Receiver as c, type PublishRequest as d, type PublishJsonRequest as e, Client as f, type PublishToApiResponse as g, type PublishToUrlResponse as h, type PublishToUrlGroupsResponse as i, type PublishResponse as j, type MessagePayload as k, Messages as l, type Schedule as m, type CreateScheduleRequest as n, Schedules as o, type Endpoint as p, type RemoveEndpointsRequest as q, UrlGroups as r, type State as s, type Event as t, type EventPayload as u, type GetEventsPayload as v, type HeadersInit as w, type RequestOptions as x, Chat as y, type ChatCompletionMessage as z };
@@ -59,8 +59,19 @@ declare class Receiver {
59
59
  * Verify signature with a specific signing key
60
60
  */
61
61
  private verifyWithKey;
62
+ private verifyBodyAndUrl;
62
63
  }
63
64
 
65
+ type EmailProviderReturnType = {
66
+ owner: "resend";
67
+ baseUrl: "https://api.resend.com/emails" | "https://api.resend.com/emails/batch";
68
+ token: string;
69
+ };
70
+ declare const resend: ({ token, batch, }: {
71
+ token: string;
72
+ batch?: boolean;
73
+ }) => EmailProviderReturnType;
74
+
64
75
  type State = "CREATED" | "ACTIVE" | "DELIVERED" | "ERROR" | "RETRY" | "FAILED";
65
76
  type HTTPMethods = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
66
77
  type Event = {
@@ -608,6 +619,7 @@ type Schedule = {
608
619
  failureCallback?: string;
609
620
  callerIp?: string;
610
621
  isPaused: boolean;
622
+ queueName?: string;
611
623
  };
612
624
  type CreateScheduleRequest = {
613
625
  /**
@@ -687,11 +699,15 @@ type CreateScheduleRequest = {
687
699
  /**
688
700
  * Schedule id to use.
689
701
  *
690
- * Can be used to updatine the settings of an existing schedule.
702
+ * Can be used to update the settings of an existing schedule.
691
703
  *
692
704
  * @default undefined
693
705
  */
694
706
  scheduleId?: string;
707
+ /**
708
+ * Queue name to schedule the message over.
709
+ */
710
+ queueName?: string;
695
711
  };
696
712
  declare class Schedules {
697
713
  private readonly http;
@@ -1625,6 +1641,7 @@ type PublishRequest<TBody = BodyInit> = {
1625
1641
  token: string;
1626
1642
  };
1627
1643
  };
1644
+ topic?: never;
1628
1645
  /**
1629
1646
  * Use a callback url to forward the response of your destination server to your callback url.
1630
1647
  *
@@ -1633,13 +1650,26 @@ type PublishRequest<TBody = BodyInit> = {
1633
1650
  * @default undefined
1634
1651
  */
1635
1652
  callback: string;
1653
+ } | {
1654
+ url?: never;
1655
+ urlGroup?: never;
1656
+ /**
1657
+ * The api endpoint the request should be sent to.
1658
+ */
1659
+ api: {
1660
+ name: "email";
1661
+ provider: EmailProviderReturnType;
1662
+ };
1636
1663
  topic?: never;
1664
+ callback?: string;
1637
1665
  } | {
1638
1666
  url?: never;
1639
1667
  urlGroup?: never;
1640
- api: never;
1668
+ api?: never;
1641
1669
  /**
1642
1670
  * Deprecated. The topic the message should be sent to. Same as urlGroup
1671
+ *
1672
+ * @deprecated
1643
1673
  */
1644
1674
  topic?: string;
1645
1675
  /**
@@ -1785,4 +1815,4 @@ type PublishResponse<TRequest> = TRequest extends {
1785
1815
  urlGroup: string;
1786
1816
  } ? PublishToUrlGroupsResponse : PublishToApiResponse;
1787
1817
 
1788
- export { type AnalyticsConfig as $, type AddEndpointsRequest as A, type BodyInit as B, type ChatRateLimit as C, type ChatCompletion as D, type EventsRequest as E, type FailureFunctionPayload as F, type GetEventsResponse as G, type HTTPMethods as H, type ChatCompletionChunk as I, type StreamEnabled as J, type StreamDisabled as K, type StreamParameter as L, type Message as M, type PromptChatRequest as N, type OpenAIChatModel as O, type PublishBatchRequest as P, type QueueRequest as Q, type RateLimit as R, type Step as S, type ChatRequest as T, type UrlGroup as U, type VerifyRequest as V, type WithCursor as W, custom as X, openai as Y, upstash as Z, type ProviderReturnType as _, type ReceiverConfig as a, type AnalyticsSetup as a0, setupAnalytics as a1, type RouteFunction as a2, type WorkflowServeOptions as a3, Workflow as a4, processOptions as a5, serve as a6, WorkflowContext as a7, DisabledWorkflowContext as a8, type WorkflowClient as a9, type WorkflowReceiver as aa, StepTypes as ab, type StepType as ac, type RawStep as ad, type SyncStepFunction as ae, type AsyncStepFunction as af, type StepFunction as ag, type ParallelCallState as ah, type FinishCondition as ai, type RequiredExceptFields as aj, type LogLevel as ak, type WorkflowLoggerOptions as al, WorkflowLogger as am, SignatureError as b, Receiver as c, type PublishRequest as d, type PublishJsonRequest as e, Client as f, type PublishToApiResponse as g, type PublishToUrlResponse as h, type PublishToUrlGroupsResponse as i, type PublishResponse as j, type MessagePayload as k, Messages as l, type Schedule as m, type CreateScheduleRequest as n, Schedules as o, type Endpoint as p, type RemoveEndpointsRequest as q, UrlGroups as r, type State as s, type Event as t, type EventPayload as u, type GetEventsPayload as v, type HeadersInit as w, type RequestOptions as x, Chat as y, type ChatCompletionMessage as z };
1818
+ export { type AnalyticsConfig as $, type AddEndpointsRequest as A, type BodyInit as B, type ChatRateLimit as C, type ChatCompletion as D, type EventsRequest as E, type FailureFunctionPayload as F, type GetEventsResponse as G, type HTTPMethods as H, type ChatCompletionChunk as I, type StreamEnabled as J, type StreamDisabled as K, type StreamParameter as L, type Message as M, type PromptChatRequest as N, type OpenAIChatModel as O, type PublishBatchRequest as P, type QueueRequest as Q, type RateLimit as R, type Step as S, type ChatRequest as T, type UrlGroup as U, type VerifyRequest as V, type WithCursor as W, custom as X, openai as Y, upstash as Z, type ProviderReturnType as _, type ReceiverConfig as a, type AnalyticsSetup as a0, setupAnalytics as a1, resend as a2, type RouteFunction as a3, type WorkflowServeOptions as a4, Workflow as a5, processOptions as a6, serve as a7, WorkflowContext as a8, DisabledWorkflowContext as a9, type WorkflowClient as aa, type WorkflowReceiver as ab, StepTypes as ac, type StepType as ad, type RawStep as ae, type SyncStepFunction as af, type AsyncStepFunction as ag, type StepFunction as ah, type ParallelCallState as ai, type FinishCondition as aj, type RequiredExceptFields as ak, type LogLevel as al, type WorkflowLoggerOptions as am, WorkflowLogger as an, SignatureError as b, Receiver as c, type PublishRequest as d, type PublishJsonRequest as e, Client as f, type PublishToApiResponse as g, type PublishToUrlResponse as h, type PublishToUrlGroupsResponse as i, type PublishResponse as j, type MessagePayload as k, Messages as l, type Schedule as m, type CreateScheduleRequest as n, Schedules as o, type Endpoint as p, type RemoveEndpointsRequest as q, UrlGroups as r, type State as s, type Event as t, type EventPayload as u, type GetEventsPayload as v, type HeadersInit as w, type RequestOptions as x, Chat as y, type ChatCompletionMessage as z };
package/cloudflare.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.mjs';
1
+ import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-kxUsvnWj.mjs';
2
2
  import 'neverthrow';
3
3
 
4
4
  type WorkflowBindings = {
package/cloudflare.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js';
1
+ import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-kxUsvnWj.js';
2
2
  import 'neverthrow';
3
3
 
4
4
  type WorkflowBindings = {
package/cloudflare.js CHANGED
@@ -60,11 +60,14 @@ var Receiver = class {
60
60
  * If that fails, the signature is invalid and a `SignatureError` is thrown.
61
61
  */
62
62
  async verify(request) {
63
- const isValid = await this.verifyWithKey(this.currentSigningKey, request);
64
- if (isValid) {
65
- return true;
63
+ let payload;
64
+ try {
65
+ payload = await this.verifyWithKey(this.currentSigningKey, request);
66
+ } catch {
67
+ payload = await this.verifyWithKey(this.nextSigningKey, request);
66
68
  }
67
- return this.verifyWithKey(this.nextSigningKey, request);
69
+ this.verifyBodyAndUrl(payload, request);
70
+ return true;
68
71
  }
69
72
  /**
70
73
  * Verify signature with a specific signing key
@@ -76,7 +79,10 @@ var Receiver = class {
76
79
  }).catch((error) => {
77
80
  throw new SignatureError(error.message);
78
81
  });
79
- const p = jwt.payload;
82
+ return jwt.payload;
83
+ }
84
+ verifyBodyAndUrl(payload, request) {
85
+ const p = payload;
80
86
  if (request.url !== void 0 && p.sub !== request.url) {
81
87
  throw new SignatureError(`invalid subject: ${p.sub}, want: ${request.url}`);
82
88
  }
@@ -85,7 +91,14 @@ var Receiver = class {
85
91
  if (p.body.replace(padding, "") !== bodyHash.replace(padding, "")) {
86
92
  throw new SignatureError(`body hash does not match, want: ${p.body}, got: ${bodyHash}`);
87
93
  }
88
- return true;
94
+ }
95
+ };
96
+
97
+ // src/client/api/utils.ts
98
+ var appendAPIOptions = (request, headers) => {
99
+ if (request.api?.name === "email") {
100
+ headers.set("Authorization", request.api.provider.token);
101
+ request.method = request.method ?? "POST";
89
102
  }
90
103
  };
91
104
 
@@ -522,7 +535,7 @@ var Chat = class _Chat {
522
535
 
523
536
  // src/client/llm/utils.ts
524
537
  function appendLLMOptionsIfNeeded(request, headers, http) {
525
- if (!request.api)
538
+ if (request.api?.name === "email" || !request.api)
526
539
  return;
527
540
  const provider = request.api.provider;
528
541
  const analytics = request.api.analytics;
@@ -679,7 +692,15 @@ function processHeaders(request) {
679
692
  return headers;
680
693
  }
681
694
  function getRequestPath(request) {
682
- return request.url ?? request.urlGroup ?? request.topic ?? `api/${request.api?.name}`;
695
+ const nonApiPath = request.url ?? request.urlGroup ?? request.topic;
696
+ if (nonApiPath)
697
+ return nonApiPath;
698
+ if (request.api?.name === "llm")
699
+ return `api/${request.api.name}`;
700
+ if (request.api?.name === "email") {
701
+ return request.api.provider.baseUrl;
702
+ }
703
+ throw new QstashError(`Failed to infer request path for ${JSON.stringify(request)}`);
683
704
  }
684
705
  var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
685
706
  var NANOID_LENGTH = 21;
@@ -692,10 +713,18 @@ function decodeBase64(base64) {
692
713
  const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
693
714
  return new TextDecoder().decode(intArray);
694
715
  } catch (error) {
695
- console.warn(
696
- `Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
697
- );
698
- return atob(base64);
716
+ try {
717
+ const result = atob(base64);
718
+ console.warn(
719
+ `Upstash QStash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
720
+ );
721
+ return result;
722
+ } catch (error2) {
723
+ console.warn(
724
+ `Upstash QStash: Failed to decode base64 "${base64}" with atob. Returning it as it is. ${error2}`
725
+ );
726
+ return base64;
727
+ }
699
728
  }
700
729
  }
701
730
 
@@ -788,6 +817,7 @@ var Queue = class {
788
817
  headers.set("Content-Type", "application/json");
789
818
  ensureCallbackPresent(request);
790
819
  appendLLMOptionsIfNeeded(request, headers, this.http);
820
+ appendAPIOptions(request, headers);
791
821
  const response = await this.enqueue({
792
822
  ...request,
793
823
  body: JSON.stringify(request.body),
@@ -870,6 +900,9 @@ var Schedules = class {
870
900
  if (request.scheduleId !== void 0) {
871
901
  headers.set("Upstash-Schedule-Id", request.scheduleId);
872
902
  }
903
+ if (request.queueName !== void 0) {
904
+ headers.set("Upstash-Queue-Name", request.queueName);
905
+ }
873
906
  return await this.http.request({
874
907
  method: "POST",
875
908
  headers,
@@ -1087,6 +1120,7 @@ var Client = class {
1087
1120
  headers.set("Content-Type", "application/json");
1088
1121
  ensureCallbackPresent(request);
1089
1122
  appendLLMOptionsIfNeeded(request, headers, this.http);
1123
+ appendAPIOptions(request, headers);
1090
1124
  const response = await this.publish({
1091
1125
  ...request,
1092
1126
  headers,
@@ -1131,6 +1165,7 @@ var Client = class {
1131
1165
  message.headers = new Headers(message.headers);
1132
1166
  ensureCallbackPresent(message);
1133
1167
  appendLLMOptionsIfNeeded(message, message.headers, this.http);
1168
+ appendAPIOptions(message, message.headers);
1134
1169
  message.headers.set("Content-Type", "application/json");
1135
1170
  }
1136
1171
  const response = await this.batch(request);
package/cloudflare.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  serve
3
- } from "./chunk-Q6E5NF42.mjs";
3
+ } from "./chunk-Q2AGFQYM.mjs";
4
4
 
5
5
  // platforms/cloudflare.ts
6
6
  var getArgs = (args) => {
package/h3.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as h3 from 'h3';
2
2
  import { H3Event } from 'h3';
3
- import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.mjs';
3
+ import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-kxUsvnWj.mjs';
4
4
  import 'neverthrow';
5
5
 
6
6
  type VerifySignatureConfig = {
package/h3.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as h3 from 'h3';
2
2
  import { H3Event } from 'h3';
3
- import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js';
3
+ import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-kxUsvnWj.js';
4
4
  import 'neverthrow';
5
5
 
6
6
  type VerifySignatureConfig = {
package/h3.js CHANGED
@@ -384,11 +384,14 @@ var Receiver = class {
384
384
  * If that fails, the signature is invalid and a `SignatureError` is thrown.
385
385
  */
386
386
  async verify(request) {
387
- const isValid = await this.verifyWithKey(this.currentSigningKey, request);
388
- if (isValid) {
389
- return true;
387
+ let payload;
388
+ try {
389
+ payload = await this.verifyWithKey(this.currentSigningKey, request);
390
+ } catch {
391
+ payload = await this.verifyWithKey(this.nextSigningKey, request);
390
392
  }
391
- return this.verifyWithKey(this.nextSigningKey, request);
393
+ this.verifyBodyAndUrl(payload, request);
394
+ return true;
392
395
  }
393
396
  /**
394
397
  * Verify signature with a specific signing key
@@ -400,7 +403,10 @@ var Receiver = class {
400
403
  }).catch((error) => {
401
404
  throw new SignatureError(error.message);
402
405
  });
403
- const p = jwt.payload;
406
+ return jwt.payload;
407
+ }
408
+ verifyBodyAndUrl(payload, request) {
409
+ const p = payload;
404
410
  if (request.url !== void 0 && p.sub !== request.url) {
405
411
  throw new SignatureError(`invalid subject: ${p.sub}, want: ${request.url}`);
406
412
  }
@@ -409,7 +415,14 @@ var Receiver = class {
409
415
  if (p.body.replace(padding, "") !== bodyHash.replace(padding, "")) {
410
416
  throw new SignatureError(`body hash does not match, want: ${p.body}, got: ${bodyHash}`);
411
417
  }
412
- return true;
418
+ }
419
+ };
420
+
421
+ // src/client/api/utils.ts
422
+ var appendAPIOptions = (request, headers) => {
423
+ if (request.api?.name === "email") {
424
+ headers.set("Authorization", request.api.provider.token);
425
+ request.method = request.method ?? "POST";
413
426
  }
414
427
  };
415
428
 
@@ -846,7 +859,7 @@ var Chat = class _Chat {
846
859
 
847
860
  // src/client/llm/utils.ts
848
861
  function appendLLMOptionsIfNeeded(request, headers, http) {
849
- if (!request.api)
862
+ if (request.api?.name === "email" || !request.api)
850
863
  return;
851
864
  const provider = request.api.provider;
852
865
  const analytics = request.api.analytics;
@@ -1003,7 +1016,15 @@ function processHeaders(request) {
1003
1016
  return headers;
1004
1017
  }
1005
1018
  function getRequestPath(request) {
1006
- return request.url ?? request.urlGroup ?? request.topic ?? `api/${request.api?.name}`;
1019
+ const nonApiPath = request.url ?? request.urlGroup ?? request.topic;
1020
+ if (nonApiPath)
1021
+ return nonApiPath;
1022
+ if (request.api?.name === "llm")
1023
+ return `api/${request.api.name}`;
1024
+ if (request.api?.name === "email") {
1025
+ return request.api.provider.baseUrl;
1026
+ }
1027
+ throw new QstashError(`Failed to infer request path for ${JSON.stringify(request)}`);
1007
1028
  }
1008
1029
  var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1009
1030
  var NANOID_LENGTH = 21;
@@ -1016,10 +1037,18 @@ function decodeBase64(base64) {
1016
1037
  const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
1017
1038
  return new TextDecoder().decode(intArray);
1018
1039
  } catch (error) {
1019
- console.warn(
1020
- `Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
1021
- );
1022
- return atob(base64);
1040
+ try {
1041
+ const result = atob(base64);
1042
+ console.warn(
1043
+ `Upstash QStash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
1044
+ );
1045
+ return result;
1046
+ } catch (error2) {
1047
+ console.warn(
1048
+ `Upstash QStash: Failed to decode base64 "${base64}" with atob. Returning it as it is. ${error2}`
1049
+ );
1050
+ return base64;
1051
+ }
1023
1052
  }
1024
1053
  }
1025
1054
 
@@ -1112,6 +1141,7 @@ var Queue = class {
1112
1141
  headers.set("Content-Type", "application/json");
1113
1142
  ensureCallbackPresent(request);
1114
1143
  appendLLMOptionsIfNeeded(request, headers, this.http);
1144
+ appendAPIOptions(request, headers);
1115
1145
  const response = await this.enqueue({
1116
1146
  ...request,
1117
1147
  body: JSON.stringify(request.body),
@@ -1194,6 +1224,9 @@ var Schedules = class {
1194
1224
  if (request.scheduleId !== void 0) {
1195
1225
  headers.set("Upstash-Schedule-Id", request.scheduleId);
1196
1226
  }
1227
+ if (request.queueName !== void 0) {
1228
+ headers.set("Upstash-Queue-Name", request.queueName);
1229
+ }
1197
1230
  return await this.http.request({
1198
1231
  method: "POST",
1199
1232
  headers,
@@ -2797,6 +2830,7 @@ var Client = class {
2797
2830
  headers.set("Content-Type", "application/json");
2798
2831
  ensureCallbackPresent(request);
2799
2832
  appendLLMOptionsIfNeeded(request, headers, this.http);
2833
+ appendAPIOptions(request, headers);
2800
2834
  const response = await this.publish({
2801
2835
  ...request,
2802
2836
  headers,
@@ -2841,6 +2875,7 @@ var Client = class {
2841
2875
  message.headers = new Headers(message.headers);
2842
2876
  ensureCallbackPresent(message);
2843
2877
  appendLLMOptionsIfNeeded(message, message.headers, this.http);
2878
+ appendAPIOptions(message, message.headers);
2844
2879
  message.headers.set("Content-Type", "application/json");
2845
2880
  }
2846
2881
  const response = await this.batch(request);
package/h3.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  serve,
3
3
  verifySignatureH3
4
- } from "./chunk-IYU467WN.mjs";
5
- import "./chunk-CIVGPRQN.mjs";
6
- import "./chunk-Q6E5NF42.mjs";
4
+ } from "./chunk-2OTIVTGG.mjs";
5
+ import "./chunk-AROUU44N.mjs";
6
+ import "./chunk-Q2AGFQYM.mjs";
7
7
  export {
8
8
  serve,
9
9
  verifySignatureH3
package/hono.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Context } from 'hono';
2
- import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.mjs';
2
+ import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-kxUsvnWj.mjs';
3
3
  import 'neverthrow';
4
4
 
5
5
  type WorkflowBindings = {
package/hono.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Context } from 'hono';
2
- import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js';
2
+ import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-kxUsvnWj.js';
3
3
  import 'neverthrow';
4
4
 
5
5
  type WorkflowBindings = {