@upstash/qstash 2.9.1-rc.1 → 2.10.0

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/hono.js CHANGED
@@ -238,6 +238,14 @@ var QstashDailyRatelimitError = class extends QstashError {
238
238
  this.reset = args.reset;
239
239
  }
240
240
  };
241
+ var QstashEmptyArrayError = class extends QstashError {
242
+ constructor(parameterName) {
243
+ super(
244
+ `Empty array provided for query parameter "${parameterName}". This would result in no filter being applied, which could affect all resources.`
245
+ );
246
+ this.name = "QstashEmptyArrayError";
247
+ }
248
+ };
241
249
  var QStashWorkflowError = class extends QstashError {
242
250
  constructor(message) {
243
251
  super(message);
@@ -267,6 +275,7 @@ var formatWorkflowError = (error) => {
267
275
  };
268
276
 
269
277
  // src/client/utils.ts
278
+ var DEFAULT_BULK_COUNT = 100;
270
279
  var isIgnoredHeader = (header) => {
271
280
  const lowerCaseHeader = header.toLowerCase();
272
281
  return lowerCaseHeader.startsWith("content-type") || lowerCaseHeader.startsWith("upstash-");
@@ -353,6 +362,24 @@ function processHeaders(request) {
353
362
  if (request.label !== void 0) {
354
363
  headers.set("Upstash-Label", request.label);
355
364
  }
365
+ if (request.redact !== void 0) {
366
+ const redactParts = [];
367
+ if (request.redact.body) {
368
+ redactParts.push("body");
369
+ }
370
+ if (request.redact.header !== void 0) {
371
+ if (request.redact.header === true) {
372
+ redactParts.push("header");
373
+ } else if (Array.isArray(request.redact.header) && request.redact.header.length > 0) {
374
+ for (const headerName of request.redact.header) {
375
+ redactParts.push(`header[${headerName}]`);
376
+ }
377
+ }
378
+ }
379
+ if (redactParts.length > 0) {
380
+ headers.set("Upstash-Redact-Fields", redactParts.join(","));
381
+ }
382
+ }
356
383
  return headers;
357
384
  }
358
385
  function getRequestPath(request) {
@@ -392,38 +419,39 @@ function decodeBase64(base64) {
392
419
  }
393
420
  }
394
421
  }
395
- function buildBulkActionFilterPayload(request, options) {
396
- const hasDlqIds = "dlqIds" in request && request.dlqIds !== void 0;
397
- const hasAll = "all" in request && Boolean(request.all);
398
- const filterKeys = Object.keys(request).filter((k) => k !== "dlqIds" && k !== "all");
399
- const hasFilters = filterKeys.length > 0;
400
- if (hasDlqIds && hasAll) {
401
- throw new QstashError("dlqIds and all: true are mutually exclusive.");
402
- }
403
- if (hasDlqIds && hasFilters) {
404
- throw new QstashError(
405
- `dlqIds cannot be combined with filter fields: ${filterKeys.join(", ")}.`
406
- );
422
+ function buildBulkActionFilterPayload(request) {
423
+ const cursor = "cursor" in request ? request.cursor : void 0;
424
+ if ("all" in request) {
425
+ const count2 = "count" in request ? request.count ?? DEFAULT_BULK_COUNT : DEFAULT_BULK_COUNT;
426
+ return { count: count2, cursor };
427
+ }
428
+ if ("dlqIds" in request) {
429
+ const ids = request.dlqIds;
430
+ if (Array.isArray(ids) && ids.length === 0) {
431
+ throw new QstashError(
432
+ "Empty dlqIds array provided. If you intend to target all DLQ messages, use { all: true } explicitly."
433
+ );
434
+ }
435
+ return { dlqIds: ids, cursor };
407
436
  }
408
- if (hasAll && hasFilters) {
409
- throw new QstashError(
410
- `all: true cannot be combined with filter fields: ${filterKeys.join(", ")}.`
411
- );
437
+ if ("messageIds" in request && request.messageIds) {
438
+ if (request.messageIds.length === 0) {
439
+ throw new QstashError(
440
+ "Empty messageIds array provided. If you intend to target all messages, use { all: true } explicitly."
441
+ );
442
+ }
443
+ return { messageIds: request.messageIds, cursor };
412
444
  }
413
- if (hasAll)
414
- return {};
415
- const { urlGroup, callerIp, ...rest } = request;
416
- const payload = {
417
- ...rest,
418
- ...urlGroup === void 0 || typeof urlGroup !== "string" ? {} : { topicName: urlGroup },
419
- ...callerIp === void 0 || typeof callerIp !== "string" ? {} : options?.callerIpCasing ? { callerIP: callerIp } : { callerIp }
445
+ const count = "count" in request ? request.count ?? DEFAULT_BULK_COUNT : DEFAULT_BULK_COUNT;
446
+ return {
447
+ ...renameUrlGroup(request.filter),
448
+ count,
449
+ cursor
420
450
  };
421
- if (Object.keys(payload).length === 0) {
422
- throw new QstashError(
423
- "No filters provided. Pass { all: true } to explicitly target all messages."
424
- );
425
- }
426
- return payload;
451
+ }
452
+ function renameUrlGroup(filter) {
453
+ const { urlGroup, api, ...rest } = filter;
454
+ return { ...rest, ...urlGroup === void 0 ? {} : { topicName: urlGroup } };
427
455
  }
428
456
  function normalizeCursor(response) {
429
457
  const cursor = response.cursor;
@@ -657,23 +685,21 @@ var DLQ = class {
657
685
  }
658
686
  /**
659
687
  * List messages in the dlq
688
+ *
689
+ * Can be called with:
690
+ * - Filters: `listMessages({ filter: { url: "https://example.com" } })`
691
+ * - DLQ IDs: `listMessages({ dlqIds: ["id1", "id2"] })`
692
+ * - No filter (list all): `listMessages()`
660
693
  */
661
694
  async listMessages(options = {}) {
662
- const { urlGroup, ...restFilter } = options.filter ?? {};
663
- const filterPayload = {
664
- ...restFilter,
665
- ...urlGroup === void 0 ? {} : { topicName: urlGroup }
695
+ const query = {
696
+ count: options.count,
697
+ ..."dlqIds" in options ? { dlqIds: options.dlqIds } : { ...renameUrlGroup(options.filter ?? {}), cursor: options.cursor }
666
698
  };
667
699
  const messagesPayload = await this.http.request({
668
700
  method: "GET",
669
701
  path: ["v2", "dlq"],
670
- query: {
671
- cursor: options.cursor,
672
- count: options.count,
673
- order: options.order,
674
- trimBody: options.trimBody,
675
- ...filterPayload
676
- }
702
+ query
677
703
  });
678
704
  return {
679
705
  messages: messagesPayload.messages.map((message) => {
@@ -693,10 +719,19 @@ var DLQ = class {
693
719
  * - A single dlqId: `delete("id")`
694
720
  * - An array of dlqIds: `delete(["id1", "id2"])`
695
721
  * - An object with dlqIds: `delete({ dlqIds: ["id1", "id2"] })`
696
- * - A filter object: `delete({ url: "https://example.com", label: "label" })`
722
+ * - A filter object: `delete({ filter: { url: "https://example.com", label: "label" } })`
697
723
  * - All messages: `delete({ all: true })`
698
724
  *
699
- * Note: passing an empty array returns `{ deleted: 0 }` without making a request.
725
+ * Pass `count` to limit the number of messages processed per call (defaults to 100).
726
+ * Call in a loop until cursor is undefined:
727
+ *
728
+ * ```ts
729
+ * let cursor: string | undefined;
730
+ * do {
731
+ * const result = await dlq.delete({ all: true, count: 100, cursor });
732
+ * cursor = result.cursor;
733
+ * } while (cursor);
734
+ * ```
700
735
  */
701
736
  async delete(request) {
702
737
  if (typeof request === "string") {
@@ -710,13 +745,11 @@ var DLQ = class {
710
745
  if (Array.isArray(request) && request.length === 0)
711
746
  return { deleted: 0 };
712
747
  const filters = Array.isArray(request) ? { dlqIds: request } : request;
713
- return normalizeCursor(
714
- await this.http.request({
715
- method: "DELETE",
716
- path: ["v2", "dlq"],
717
- query: buildBulkActionFilterPayload(filters)
718
- })
719
- );
748
+ return await this.http.request({
749
+ method: "DELETE",
750
+ path: ["v2", "dlq"],
751
+ query: buildBulkActionFilterPayload(filters)
752
+ });
720
753
  }
721
754
  /**
722
755
  * Remove multiple messages from the dlq using their `dlqId`s
@@ -733,10 +766,19 @@ var DLQ = class {
733
766
  * - A single dlqId: `retry("id")`
734
767
  * - An array of dlqIds: `retry(["id1", "id2"])`
735
768
  * - An object with dlqIds: `retry({ dlqIds: ["id1", "id2"] })`
736
- * - A filter object: `retry({ url: "https://example.com", label: "label" })`
769
+ * - A filter object: `retry({ filter: { url: "https://example.com", label: "label" } })`
737
770
  * - All messages: `retry({ all: true })`
738
771
  *
739
- * Note: passing an empty array returns `{ responses: [] }` without making a request.
772
+ * Pass `count` to limit the number of messages processed per call (defaults to 100).
773
+ * Call in a loop until cursor is undefined:
774
+ *
775
+ * ```ts
776
+ * let cursor: string | undefined;
777
+ * do {
778
+ * const result = await dlq.retry({ all: true, count: 100, cursor });
779
+ * cursor = result.cursor;
780
+ * } while (cursor);
781
+ * ```
740
782
  */
741
783
  async retry(request) {
742
784
  if (typeof request === "string")
@@ -754,6 +796,107 @@ var DLQ = class {
754
796
  }
755
797
  };
756
798
 
799
+ // src/client/flow-control.ts
800
+ var FlowControlApi = class {
801
+ http;
802
+ constructor(http) {
803
+ this.http = http;
804
+ }
805
+ /**
806
+ * Get a single flow control by key.
807
+ */
808
+ async get(flowControlKey) {
809
+ return await this.http.request({
810
+ method: "GET",
811
+ path: ["v2", "flowControl", flowControlKey]
812
+ });
813
+ }
814
+ /**
815
+ * Get the global parallelism info.
816
+ */
817
+ async getGlobalParallelism() {
818
+ const response = await this.http.request({
819
+ method: "GET",
820
+ path: ["v2", "globalParallelism"]
821
+ });
822
+ return {
823
+ parallelismMax: response.parallelismMax ?? 0,
824
+ parallelismCount: response.parallelismCount ?? 0
825
+ };
826
+ }
827
+ /**
828
+ * Pause message delivery for a flow-control key.
829
+ *
830
+ * Messages already in the waitlist will remain there.
831
+ * New incoming messages will be added directly to the waitlist.
832
+ */
833
+ async pause(flowControlKey) {
834
+ await this.http.request({
835
+ method: "POST",
836
+ path: ["v2", "flowControl", flowControlKey, "pause"],
837
+ parseResponseAsJson: false
838
+ });
839
+ }
840
+ /**
841
+ * Resume message delivery for a flow-control key.
842
+ */
843
+ async resume(flowControlKey) {
844
+ await this.http.request({
845
+ method: "POST",
846
+ path: ["v2", "flowControl", flowControlKey, "resume"],
847
+ parseResponseAsJson: false
848
+ });
849
+ }
850
+ /**
851
+ * Pin a processing configuration for a flow-control key.
852
+ *
853
+ * While pinned, the system ignores configurations provided by incoming
854
+ * messages and uses the pinned configuration instead.
855
+ */
856
+ async pin(flowControlKey, options) {
857
+ await this.http.request({
858
+ method: "POST",
859
+ path: ["v2", "flowControl", flowControlKey, "pin"],
860
+ query: {
861
+ parallelism: options.parallelism,
862
+ rate: options.rate,
863
+ period: options.period
864
+ },
865
+ parseResponseAsJson: false
866
+ });
867
+ }
868
+ /**
869
+ * Remove the pinned configuration for a flow-control key.
870
+ *
871
+ * After unpinning, the system resumes updating the configuration
872
+ * based on incoming messages.
873
+ */
874
+ async unpin(flowControlKey, options) {
875
+ await this.http.request({
876
+ method: "POST",
877
+ path: ["v2", "flowControl", flowControlKey, "unpin"],
878
+ query: {
879
+ parallelism: options.parallelism,
880
+ rate: options.rate
881
+ },
882
+ parseResponseAsJson: false
883
+ });
884
+ }
885
+ /**
886
+ * Reset the rate configuration state for a flow-control key.
887
+ *
888
+ * Clears the current rate count and immediately ends the current period.
889
+ * The current timestamp becomes the start of the new rate period.
890
+ */
891
+ async resetRate(flowControlKey) {
892
+ await this.http.request({
893
+ method: "POST",
894
+ path: ["v2", "flowControl", flowControlKey, "resetRate"],
895
+ parseResponseAsJson: false
896
+ });
897
+ }
898
+ };
899
+
757
900
  // src/client/http.ts
758
901
  var HttpClient = class {
759
902
  baseUrl;
@@ -854,6 +997,9 @@ var HttpClient = class {
854
997
  if (value === void 0)
855
998
  continue;
856
999
  if (Array.isArray(value)) {
1000
+ if (value.length === 0) {
1001
+ throw new QstashEmptyArrayError(key);
1002
+ }
857
1003
  for (const item of value) {
858
1004
  url.searchParams.append(key, item);
859
1005
  }
@@ -1095,8 +1241,19 @@ var Messages = class {
1095
1241
  * Can be called with:
1096
1242
  * - A single messageId: `cancel("id")`
1097
1243
  * - An array of messageIds: `cancel(["id1", "id2"])`
1098
- * - A filter object: `cancel({ flowControlKey: "key", label: "label" })`
1244
+ * - A filter object: `cancel({ filter: { flowControlKey: "key", label: "label" } })`
1099
1245
  * - All messages: `cancel({ all: true })`
1246
+ *
1247
+ * Pass `count` to limit the number of messages processed per call (defaults to 100).
1248
+ * Call in a loop until `cancelled` is 0:
1249
+ *
1250
+ * ```ts
1251
+ * let cancelled: number;
1252
+ * do {
1253
+ * const result = await messages.cancel({ all: true, count: 100 });
1254
+ * cancelled = result.cancelled;
1255
+ * } while (cancelled > 0);
1256
+ * ```
1100
1257
  */
1101
1258
  async cancel(request) {
1102
1259
  if (typeof request === "string") {
@@ -1111,7 +1268,7 @@ var Messages = class {
1111
1268
  return await this.http.request({
1112
1269
  method: "DELETE",
1113
1270
  path: ["v2", "messages"],
1114
- query: buildBulkActionFilterPayload(filters, { callerIpCasing: true })
1271
+ query: buildBulkActionFilterPayload(filters)
1115
1272
  });
1116
1273
  }
1117
1274
  /**
@@ -1345,6 +1502,24 @@ var Schedules = class {
1345
1502
  if (request.label !== void 0) {
1346
1503
  headers.set("Upstash-Label", request.label);
1347
1504
  }
1505
+ if (request.redact !== void 0) {
1506
+ const redactParts = [];
1507
+ if (request.redact.body) {
1508
+ redactParts.push("body");
1509
+ }
1510
+ if (request.redact.header !== void 0) {
1511
+ if (request.redact.header === true) {
1512
+ redactParts.push("header");
1513
+ } else if (Array.isArray(request.redact.header) && request.redact.header.length > 0) {
1514
+ for (const headerName of request.redact.header) {
1515
+ redactParts.push(`header[${headerName}]`);
1516
+ }
1517
+ }
1518
+ }
1519
+ if (redactParts.length > 0) {
1520
+ headers.set("Upstash-Redact-Fields", redactParts.join(","));
1521
+ }
1522
+ }
1348
1523
  return await this.http.request({
1349
1524
  method: "POST",
1350
1525
  headers: wrapWithGlobalHeaders(headers, this.http.headers, this.http.telemetryHeaders),
@@ -1474,7 +1649,7 @@ var UrlGroups = class {
1474
1649
  };
1475
1650
 
1476
1651
  // version.ts
1477
- var VERSION = "v2.9.1-rc.1";
1652
+ var VERSION = "2.10.0";
1478
1653
 
1479
1654
  // src/client/client.ts
1480
1655
  var Client = class {
@@ -1545,6 +1720,14 @@ var Client = class {
1545
1720
  get schedules() {
1546
1721
  return new Schedules(this.http);
1547
1722
  }
1723
+ /**
1724
+ * Access the flow control API.
1725
+ *
1726
+ * List, get, or reset flow controls.
1727
+ */
1728
+ get flowControl() {
1729
+ return new FlowControlApi(this.http);
1730
+ }
1548
1731
  /**
1549
1732
  * Access the workflow API.
1550
1733
  *
@@ -1670,38 +1853,9 @@ var Client = class {
1670
1853
  * ```
1671
1854
  */
1672
1855
  async logs(request = {}) {
1673
- const {
1674
- urlGroup,
1675
- // eslint-disable-next-line @typescript-eslint/no-deprecated
1676
- topicName,
1677
- fromDate,
1678
- toDate,
1679
- callerIp,
1680
- messageIds,
1681
- // eslint-disable-next-line @typescript-eslint/no-deprecated
1682
- count: filterCount,
1683
- ...restFilter
1684
- } = request.filter ?? {};
1685
- const filterPayload = {
1686
- ...restFilter,
1687
- topicName: urlGroup ?? topicName,
1688
- fromDate,
1689
- toDate,
1690
- callerIp
1691
- };
1692
- let cursorString;
1693
- if (typeof request.cursor === "number" && request.cursor > 0) {
1694
- cursorString = request.cursor.toString();
1695
- } else if (typeof request.cursor === "string" && request.cursor !== "") {
1696
- cursorString = request.cursor;
1697
- }
1698
1856
  const query = {
1699
- cursor: cursorString,
1700
- count: request.count ?? filterCount,
1701
- order: request.order,
1702
- trimBody: request.trimBody,
1703
- messageIds,
1704
- ...filterPayload
1857
+ count: request.count,
1858
+ ..."messageIds" in request ? { messageIds: request.messageIds } : { ...renameUrlGroup(request.filter ?? {}), cursor: request.cursor }
1705
1859
  };
1706
1860
  const responsePayload = await this.http.request({
1707
1861
  path: ["v2", "events"],
package/hono.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  serve
3
- } from "./chunk-RUCOF5QZ.mjs";
3
+ } from "./chunk-X3MMU3BQ.mjs";
4
4
 
5
5
  // platforms/hono.ts
6
6
  var serve2 = (routeFunction, options) => {
package/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RateLimit, C as ChatRateLimit, S as Step, F as FailureFunctionPayload, L as LLMOwner, B as BaseProvider, E as EmailOwner, P as ProviderInfo } from './client-Gv4WRTxB.mjs';
2
- export { A as AddEndpointsRequest, N as BodyInit, Y as Chat, _ as ChatCompletion, $ as ChatCompletionChunk, Z as ChatCompletionMessage, a5 as ChatRequest, j as Client, r as CreateScheduleRequest, t as Endpoint, z as Event, I as EventPayload, h as EventsRequest, X as FlowControl, K as GetEventsPayload, i as GetEventsResponse, J as GetLogsPayload, G as GetLogsResponse, H as HTTPMethods, O as HeadersInit, y as Log, D as LogPayload, g as LogsRequest, M as Message, o as MessagePayload, p as Messages, a3 as OpenAIChatModel, a4 as PromptChatRequest, d as PublishBatchRequest, f as PublishJsonRequest, e as PublishRequest, n as PublishResponse, k as PublishToApiResponse, m as PublishToUrlGroupsResponse, l as PublishToUrlResponse, Q as QueueRequest, c as Receiver, a as ReceiverConfig, u as RemoveEndpointsRequest, T as RequestOptions, q as Schedule, s as Schedules, b as SignatureError, x as State, a1 as StreamDisabled, a0 as StreamEnabled, a2 as StreamParameter, U as UniversalFilterFields, v as UrlGroup, w as UrlGroups, V as VerifyRequest, W as WithCursor, a8 as anthropic, a9 as custom, a7 as openai, a6 as upstash } from './client-Gv4WRTxB.mjs';
1
+ import { R as RateLimit, C as ChatRateLimit, S as Step, F as FailureFunctionPayload, L as LLMOwner, B as BaseProvider, E as EmailOwner, P as ProviderInfo } from './client-CsM1dTnz.mjs';
2
+ export { A as AddEndpointsRequest, Y as BodyInit, a0 as Chat, a2 as ChatCompletion, a3 as ChatCompletionChunk, a1 as ChatCompletionMessage, a9 as ChatRequest, j as Client, v as CreateScheduleRequest, x as Endpoint, K as Event, O as EventPayload, h as EventsRequest, $ as FlowControl, r as FlowControlApi, o as FlowControlInfo, W as GetEventsPayload, i as GetEventsResponse, T as GetLogsPayload, G as GetLogsResponse, p as GlobalParallelismInfo, I as HTTPMethods, Z as HeadersInit, J as Log, N as LogPayload, g as LogsRequest, M as Message, s as MessagePayload, t as Messages, a7 as OpenAIChatModel, q as PinFlowControlOptions, a8 as PromptChatRequest, d as PublishBatchRequest, f as PublishJsonRequest, e as PublishRequest, n as PublishResponse, k as PublishToApiResponse, m as PublishToUrlGroupsResponse, l as PublishToUrlResponse, Q as QueueRequest, c as Receiver, a as ReceiverConfig, y as RemoveEndpointsRequest, _ as RequestOptions, u as Schedule, w as Schedules, b as SignatureError, H as State, a5 as StreamDisabled, a4 as StreamEnabled, a6 as StreamParameter, U as UnpinFlowControlOptions, z as UrlGroup, D as UrlGroups, V as VerifyRequest, X as WithCursor, ac as anthropic, ad as custom, ab as openai, aa as upstash } from './client-CsM1dTnz.mjs';
3
3
  import 'neverthrow';
4
4
 
5
5
  /**
@@ -30,6 +30,14 @@ declare class QstashDailyRatelimitError extends QstashError {
30
30
  reset: string | null;
31
31
  constructor(args: RateLimit);
32
32
  }
33
+ /**
34
+ * Raised when an empty array is passed as a query parameter.
35
+ * This is a safety net to prevent accidental bulk operations
36
+ * (e.g. delete-all, cancel-all) when no IDs were intended.
37
+ */
38
+ declare class QstashEmptyArrayError extends QstashError {
39
+ constructor(parameterName: string);
40
+ }
33
41
  /**
34
42
  * Error raised during Workflow execution
35
43
  */
@@ -89,4 +97,4 @@ declare const resend: ({ token, batch, }: {
89
97
  batch?: boolean;
90
98
  }) => EmailProvider;
91
99
 
92
- export { ChatRateLimit, QStashWorkflowAbort, QStashWorkflowError, QstashChatRatelimitError, QstashDailyRatelimitError, QstashError, QstashRatelimitError, RateLimit, decodeBase64, formatWorkflowError, resend, setupAnalytics };
100
+ export { ChatRateLimit, QStashWorkflowAbort, QStashWorkflowError, QstashChatRatelimitError, QstashDailyRatelimitError, QstashEmptyArrayError, QstashError, QstashRatelimitError, RateLimit, decodeBase64, formatWorkflowError, resend, setupAnalytics };
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RateLimit, C as ChatRateLimit, S as Step, F as FailureFunctionPayload, L as LLMOwner, B as BaseProvider, E as EmailOwner, P as ProviderInfo } from './client-Gv4WRTxB.js';
2
- export { A as AddEndpointsRequest, N as BodyInit, Y as Chat, _ as ChatCompletion, $ as ChatCompletionChunk, Z as ChatCompletionMessage, a5 as ChatRequest, j as Client, r as CreateScheduleRequest, t as Endpoint, z as Event, I as EventPayload, h as EventsRequest, X as FlowControl, K as GetEventsPayload, i as GetEventsResponse, J as GetLogsPayload, G as GetLogsResponse, H as HTTPMethods, O as HeadersInit, y as Log, D as LogPayload, g as LogsRequest, M as Message, o as MessagePayload, p as Messages, a3 as OpenAIChatModel, a4 as PromptChatRequest, d as PublishBatchRequest, f as PublishJsonRequest, e as PublishRequest, n as PublishResponse, k as PublishToApiResponse, m as PublishToUrlGroupsResponse, l as PublishToUrlResponse, Q as QueueRequest, c as Receiver, a as ReceiverConfig, u as RemoveEndpointsRequest, T as RequestOptions, q as Schedule, s as Schedules, b as SignatureError, x as State, a1 as StreamDisabled, a0 as StreamEnabled, a2 as StreamParameter, U as UniversalFilterFields, v as UrlGroup, w as UrlGroups, V as VerifyRequest, W as WithCursor, a8 as anthropic, a9 as custom, a7 as openai, a6 as upstash } from './client-Gv4WRTxB.js';
1
+ import { R as RateLimit, C as ChatRateLimit, S as Step, F as FailureFunctionPayload, L as LLMOwner, B as BaseProvider, E as EmailOwner, P as ProviderInfo } from './client-CsM1dTnz.js';
2
+ export { A as AddEndpointsRequest, Y as BodyInit, a0 as Chat, a2 as ChatCompletion, a3 as ChatCompletionChunk, a1 as ChatCompletionMessage, a9 as ChatRequest, j as Client, v as CreateScheduleRequest, x as Endpoint, K as Event, O as EventPayload, h as EventsRequest, $ as FlowControl, r as FlowControlApi, o as FlowControlInfo, W as GetEventsPayload, i as GetEventsResponse, T as GetLogsPayload, G as GetLogsResponse, p as GlobalParallelismInfo, I as HTTPMethods, Z as HeadersInit, J as Log, N as LogPayload, g as LogsRequest, M as Message, s as MessagePayload, t as Messages, a7 as OpenAIChatModel, q as PinFlowControlOptions, a8 as PromptChatRequest, d as PublishBatchRequest, f as PublishJsonRequest, e as PublishRequest, n as PublishResponse, k as PublishToApiResponse, m as PublishToUrlGroupsResponse, l as PublishToUrlResponse, Q as QueueRequest, c as Receiver, a as ReceiverConfig, y as RemoveEndpointsRequest, _ as RequestOptions, u as Schedule, w as Schedules, b as SignatureError, H as State, a5 as StreamDisabled, a4 as StreamEnabled, a6 as StreamParameter, U as UnpinFlowControlOptions, z as UrlGroup, D as UrlGroups, V as VerifyRequest, X as WithCursor, ac as anthropic, ad as custom, ab as openai, aa as upstash } from './client-CsM1dTnz.js';
3
3
  import 'neverthrow';
4
4
 
5
5
  /**
@@ -30,6 +30,14 @@ declare class QstashDailyRatelimitError extends QstashError {
30
30
  reset: string | null;
31
31
  constructor(args: RateLimit);
32
32
  }
33
+ /**
34
+ * Raised when an empty array is passed as a query parameter.
35
+ * This is a safety net to prevent accidental bulk operations
36
+ * (e.g. delete-all, cancel-all) when no IDs were intended.
37
+ */
38
+ declare class QstashEmptyArrayError extends QstashError {
39
+ constructor(parameterName: string);
40
+ }
33
41
  /**
34
42
  * Error raised during Workflow execution
35
43
  */
@@ -89,4 +97,4 @@ declare const resend: ({ token, batch, }: {
89
97
  batch?: boolean;
90
98
  }) => EmailProvider;
91
99
 
92
- export { ChatRateLimit, QStashWorkflowAbort, QStashWorkflowError, QstashChatRatelimitError, QstashDailyRatelimitError, QstashError, QstashRatelimitError, RateLimit, decodeBase64, formatWorkflowError, resend, setupAnalytics };
100
+ export { ChatRateLimit, QStashWorkflowAbort, QStashWorkflowError, QstashChatRatelimitError, QstashDailyRatelimitError, QstashEmptyArrayError, QstashError, QstashRatelimitError, RateLimit, decodeBase64, formatWorkflowError, resend, setupAnalytics };