@upstash/qstash 2.7.21 → 2.7.23

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/workflow.js CHANGED
@@ -127,7 +127,8 @@ var DLQ = class {
127
127
  messages: messagesPayload.messages.map((message) => {
128
128
  return {
129
129
  ...message,
130
- urlGroup: message.topicName
130
+ urlGroup: message.topicName,
131
+ ratePerSecond: "rate" in message ? message.rate : void 0
131
132
  };
132
133
  }),
133
134
  cursor: messagesPayload.cursor
@@ -244,6 +245,7 @@ var HttpClient = class {
244
245
  options;
245
246
  retry;
246
247
  headers;
248
+ telemetryHeaders;
247
249
  constructor(config) {
248
250
  this.baseUrl = config.baseUrl.replace(/\/$/, "");
249
251
  this.authorization = config.authorization;
@@ -256,6 +258,7 @@ var HttpClient = class {
256
258
  backoff: config.retry?.backoff ?? ((retryCount) => Math.exp(retryCount) * 50)
257
259
  };
258
260
  this.headers = config.headers;
261
+ this.telemetryHeaders = config.telemetryHeaders;
259
262
  }
260
263
  async request(request) {
261
264
  const { response } = await this.requestWithBackoff(request);
@@ -557,7 +560,8 @@ var Messages = class {
557
560
  });
558
561
  const message = {
559
562
  ...messagePayload,
560
- urlGroup: messagePayload.topicName
563
+ urlGroup: messagePayload.topicName,
564
+ ratePerSecond: "rate" in messagePayload ? messagePayload.rate : void 0
561
565
  };
562
566
  return message;
563
567
  }
@@ -753,7 +757,7 @@ function prefixHeaders(headers) {
753
757
  }
754
758
  return headers;
755
759
  }
756
- function wrapWithGlobalHeaders(headers, globalHeaders) {
760
+ function wrapWithGlobalHeaders(headers, globalHeaders, telemetryHeaders) {
757
761
  if (!globalHeaders) {
758
762
  return headers;
759
763
  }
@@ -761,6 +765,11 @@ function wrapWithGlobalHeaders(headers, globalHeaders) {
761
765
  headers.forEach((value, key) => {
762
766
  finalHeaders.set(key, value);
763
767
  });
768
+ telemetryHeaders?.forEach((value, key) => {
769
+ if (!value)
770
+ return;
771
+ finalHeaders.append(key, value);
772
+ });
764
773
  return finalHeaders;
765
774
  }
766
775
  function processHeaders(request) {
@@ -798,6 +807,19 @@ function processHeaders(request) {
798
807
  headers.set("Upstash-Timeout", `${request.timeout}s`);
799
808
  }
800
809
  }
810
+ if (request.flowControl?.key) {
811
+ const parallelism = request.flowControl.parallelism?.toString();
812
+ const rate = request.flowControl.ratePerSecond?.toString();
813
+ const controlValue = [
814
+ parallelism ? `parallelism=${parallelism}` : void 0,
815
+ rate ? `rate=${rate}` : void 0
816
+ ].filter(Boolean);
817
+ if (controlValue.length === 0) {
818
+ throw new QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
819
+ }
820
+ headers.set("Upstash-Flow-Control-Key", request.flowControl.key);
821
+ headers.set("Upstash-Flow-Control-Value", controlValue.join(", "));
822
+ }
801
823
  return headers;
802
824
  }
803
825
  function getRequestPath(request) {
@@ -837,6 +859,15 @@ function decodeBase64(base64) {
837
859
  }
838
860
  }
839
861
  }
862
+ function getRuntime() {
863
+ if (typeof process === "object" && typeof process.versions == "object" && process.versions.bun)
864
+ return `bun@${process.versions.bun}`;
865
+ if (typeof EdgeRuntime === "string")
866
+ return "edge-light";
867
+ else if (typeof process === "object" && typeof process.version === "string")
868
+ return `node@${process.version}`;
869
+ return "";
870
+ }
840
871
 
841
872
  // src/client/queue.ts
842
873
  var Queue = class {
@@ -911,7 +942,8 @@ var Queue = class {
911
942
  }
912
943
  const headers = wrapWithGlobalHeaders(
913
944
  processHeaders(request),
914
- this.http.headers
945
+ this.http.headers,
946
+ this.http.telemetryHeaders
915
947
  );
916
948
  const destination = getRequestPath(request);
917
949
  const response = await this.http.request({
@@ -1014,9 +1046,24 @@ var Schedules = class {
1014
1046
  if (request.queueName !== void 0) {
1015
1047
  headers.set("Upstash-Queue-Name", request.queueName);
1016
1048
  }
1049
+ if (request.flowControl?.key) {
1050
+ const parallelism = request.flowControl.parallelism?.toString();
1051
+ const rate = request.flowControl.ratePerSecond?.toString();
1052
+ const controlValue = [
1053
+ parallelism ? `parallelism=${parallelism}` : void 0,
1054
+ rate ? `rate=${rate}` : void 0
1055
+ ].filter(Boolean);
1056
+ if (controlValue.length === 0) {
1057
+ throw new QstashError(
1058
+ "Provide at least one of parallelism or ratePerSecond for flowControl"
1059
+ );
1060
+ }
1061
+ headers.set("Upstash-Flow-Control-Key", request.flowControl.key);
1062
+ headers.set("Upstash-Flow-Control-Value", controlValue.join(", "));
1063
+ }
1017
1064
  return await this.http.request({
1018
1065
  method: "POST",
1019
- headers: wrapWithGlobalHeaders(headers, this.http.headers),
1066
+ headers: wrapWithGlobalHeaders(headers, this.http.headers, this.http.telemetryHeaders),
1020
1067
  path: ["v2", "schedules", request.destination],
1021
1068
  body: request.body
1022
1069
  });
@@ -1025,19 +1072,27 @@ var Schedules = class {
1025
1072
  * Get a schedule
1026
1073
  */
1027
1074
  async get(scheduleId) {
1028
- return await this.http.request({
1075
+ const schedule = await this.http.request({
1029
1076
  method: "GET",
1030
1077
  path: ["v2", "schedules", scheduleId]
1031
1078
  });
1079
+ if ("rate" in schedule)
1080
+ schedule.ratePerSecond = schedule.rate;
1081
+ return schedule;
1032
1082
  }
1033
1083
  /**
1034
1084
  * List your schedules
1035
1085
  */
1036
1086
  async list() {
1037
- return await this.http.request({
1087
+ const schedules = await this.http.request({
1038
1088
  method: "GET",
1039
1089
  path: ["v2", "schedules"]
1040
1090
  });
1091
+ for (const schedule of schedules) {
1092
+ if ("rate" in schedule)
1093
+ schedule.ratePerSecond = schedule.rate;
1094
+ }
1095
+ return schedules;
1041
1096
  }
1042
1097
  /**
1043
1098
  * Delete a schedule
@@ -1134,20 +1189,37 @@ var UrlGroups = class {
1134
1189
  }
1135
1190
  };
1136
1191
 
1192
+ // version.ts
1193
+ var VERSION = "v2.7.23";
1194
+
1137
1195
  // src/client/client.ts
1138
1196
  var Client = class {
1139
1197
  http;
1140
1198
  token;
1141
1199
  constructor(config) {
1142
1200
  const environment = typeof process === "undefined" ? {} : process.env;
1143
- const baseUrl = config?.baseUrl ? config.baseUrl.replace(/\/$/, "") : environment.QSTASH_URL ?? "https://qstash.upstash.io";
1201
+ let baseUrl = (config?.baseUrl ?? environment.QSTASH_URL ?? "https://qstash.upstash.io").replace(/\/$/, "");
1202
+ if (baseUrl === "https://qstash.upstash.io/v2/publish") {
1203
+ baseUrl = "https://qstash.upstash.io";
1204
+ }
1144
1205
  const token = config?.token ?? environment.QSTASH_TOKEN;
1206
+ const enableTelemetry = environment.UPSTASH_DISABLE_TELEMETRY ? false : config?.enableTelemetry ?? true;
1207
+ const isCloudflare = typeof caches !== "undefined" && "default" in caches;
1208
+ const telemetryHeaders = new Headers(
1209
+ enableTelemetry ? {
1210
+ "Upstash-Telemetry-Sdk": `upstash-qstash-js@${VERSION}`,
1211
+ "Upstash-Telemetry-Platform": isCloudflare ? "cloudflare" : environment.VERCEL ? "vercel" : environment.AWS_REGION ? "aws" : "",
1212
+ "Upstash-Telemetry-Runtime": getRuntime()
1213
+ } : {}
1214
+ );
1145
1215
  this.http = new HttpClient({
1146
1216
  retry: config?.retry,
1147
1217
  baseUrl,
1148
1218
  authorization: `Bearer ${token}`,
1149
1219
  //@ts-expect-error caused by undici and bunjs type overlap
1150
- headers: prefixHeaders(new Headers(config?.headers ?? {}))
1220
+ headers: prefixHeaders(new Headers(config?.headers ?? {})),
1221
+ //@ts-expect-error caused by undici and bunjs type overlap
1222
+ telemetryHeaders
1151
1223
  });
1152
1224
  if (!token) {
1153
1225
  console.warn(
@@ -1229,7 +1301,8 @@ var Client = class {
1229
1301
  async publish(request) {
1230
1302
  const headers = wrapWithGlobalHeaders(
1231
1303
  processHeaders(request),
1232
- this.http.headers
1304
+ this.http.headers,
1305
+ this.http.telemetryHeaders
1233
1306
  );
1234
1307
  const response = await this.http.request({
1235
1308
  path: ["v2", "publish", getRequestPath(request)],
@@ -1260,7 +1333,11 @@ var Client = class {
1260
1333
  async batch(request) {
1261
1334
  const messages = [];
1262
1335
  for (const message of request) {
1263
- const headers = wrapWithGlobalHeaders(processHeaders(message), this.http.headers);
1336
+ const headers = wrapWithGlobalHeaders(
1337
+ processHeaders(message),
1338
+ this.http.headers,
1339
+ this.http.telemetryHeaders
1340
+ );
1264
1341
  const headerEntries = Object.fromEntries(headers.entries());
1265
1342
  messages.push({
1266
1343
  destination: getRequestPath(message),
@@ -1315,7 +1392,7 @@ var Client = class {
1315
1392
  * }
1316
1393
  * ```
1317
1394
  */
1318
- async events(request) {
1395
+ async logs(request) {
1319
1396
  const query = {};
1320
1397
  if (typeof request?.cursor === "number" && request.cursor > 0) {
1321
1398
  query.cursor = request.cursor.toString();
@@ -1337,16 +1414,42 @@ var Client = class {
1337
1414
  method: "GET",
1338
1415
  query
1339
1416
  });
1417
+ const logs = responsePayload.events.map((event) => {
1418
+ return {
1419
+ ...event,
1420
+ urlGroup: event.topicName
1421
+ };
1422
+ });
1340
1423
  return {
1341
1424
  cursor: responsePayload.cursor,
1342
- events: responsePayload.events.map((event) => {
1343
- return {
1344
- ...event,
1345
- urlGroup: event.topicName
1346
- };
1347
- })
1425
+ logs,
1426
+ events: logs
1348
1427
  };
1349
1428
  }
1429
+ /**
1430
+ * @deprecated Will be removed in the next major release. Use the `logs` method instead.
1431
+ *
1432
+ * Retrieve your logs.
1433
+ *
1434
+ * The logs endpoint is paginated and returns only 100 logs at a time.
1435
+ * If you want to receive more logs, you can use the cursor to paginate.
1436
+ *
1437
+ * The cursor is a unix timestamp with millisecond precision
1438
+ *
1439
+ * @example
1440
+ * ```ts
1441
+ * let cursor = Date.now()
1442
+ * const logs: Log[] = []
1443
+ * while (cursor > 0) {
1444
+ * const res = await qstash.logs({ cursor })
1445
+ * logs.push(...res.logs)
1446
+ * cursor = res.cursor ?? 0
1447
+ * }
1448
+ * ```
1449
+ */
1450
+ async events(request) {
1451
+ return await this.logs(request);
1452
+ }
1350
1453
  };
1351
1454
 
1352
1455
  // src/client/workflow/constants.ts
package/workflow.mjs CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  WorkflowLogger,
7
7
  processOptions,
8
8
  serve
9
- } from "./chunk-QHCEWG63.mjs";
9
+ } from "./chunk-G7CVCBTL.mjs";
10
10
  export {
11
11
  DisabledWorkflowContext,
12
12
  StepTypes,