@particle-academy/fancy-connector-core 0.6.2 → 0.8.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/dist/index.js CHANGED
@@ -595,21 +595,21 @@ async function prepare(service, connection, options) {
595
595
  }
596
596
  function encodeForm(form) {
597
597
  const pairs = [];
598
- const walk = (prefix, value) => {
598
+ const walk2 = (prefix, value) => {
599
599
  if (value === void 0 || value === null) return;
600
600
  if (Array.isArray(value)) {
601
- value.forEach((item, index) => walk(`${prefix}[${index}]`, item));
601
+ value.forEach((item, index) => walk2(`${prefix}[${index}]`, item));
602
602
  return;
603
603
  }
604
604
  if (typeof value === "object") {
605
605
  for (const [key, nested] of Object.entries(value)) {
606
- walk(prefix === "" ? key : `${prefix}[${key}]`, nested);
606
+ walk2(prefix === "" ? key : `${prefix}[${key}]`, nested);
607
607
  }
608
608
  return;
609
609
  }
610
610
  pairs.push(`${encodeURIComponent(prefix)}=${encodeURIComponent(String(value))}`);
611
611
  };
612
- walk("", form);
612
+ walk2("", form);
613
613
  return pairs.join("&");
614
614
  }
615
615
  var fetchTransport = async (request) => {
@@ -913,6 +913,107 @@ function fnv1a(value) {
913
913
  return hash.toString(16).padStart(8, "0");
914
914
  }
915
915
 
916
+ // src/lease.ts
917
+ var EXPIRES_AT_UNITS = ["rfc3339", "epoch-ms"];
918
+ var INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}:\d{2})$/;
919
+ var DEFAULT_CONTEXT = { service: "", operation: "subscription" };
920
+ function instantMs(value, field, at) {
921
+ if (typeof value !== "string" || !INSTANT.test(value)) {
922
+ throw new ConnectorConfigError(
923
+ `${field} must be an RFC 3339 instant such as "2026-09-22T00:00:00Z", got ${JSON.stringify(value)}. A provider's own shape \u2014 Google's epoch milliseconds, say \u2014 is converted by the connector, never guessed at here.`,
924
+ at
925
+ );
926
+ }
927
+ const ms = Date.parse(value.replace(/(\.\d{3})\d+/, "$1"));
928
+ if (Number.isNaN(ms)) {
929
+ throw new ConnectorConfigError(`${field} is not a real instant: ${JSON.stringify(value)}`, at);
930
+ }
931
+ return ms;
932
+ }
933
+ function leaseFromResponse(declaration, response, at = DEFAULT_CONTEXT) {
934
+ const { expiresAtFrom: path, expiresAtUnit: unit } = declaration;
935
+ if (!EXPIRES_AT_UNITS.includes(unit)) {
936
+ throw new ConnectorConfigError(
937
+ `expiresAtUnit must be one of ${EXPIRES_AT_UNITS.join(" | ")}, got ${JSON.stringify(unit)}.`,
938
+ at
939
+ );
940
+ }
941
+ const value = readPath(response, path);
942
+ if (value === void 0 || value === null) {
943
+ throw new ConnectorConfigError(
944
+ `${path} is not present in the response, so no lease can be built \u2014 a subscription with no known expiry is one nobody renews.`,
945
+ at
946
+ );
947
+ }
948
+ let expiresAt;
949
+ if (unit === "epoch-ms") {
950
+ const ms = typeof value === "number" ? value : typeof value === "string" && /^\d+$/.test(value) ? Number(value) : Number.NaN;
951
+ if (!Number.isSafeInteger(ms)) {
952
+ throw new ConnectorConfigError(
953
+ `${path} must be epoch milliseconds as digits under "epoch-ms", got ${JSON.stringify(value)}.`,
954
+ at
955
+ );
956
+ }
957
+ expiresAt = new Date(ms).toISOString();
958
+ } else {
959
+ if (typeof value !== "string" || !INSTANT.test(value)) {
960
+ throw new ConnectorConfigError(
961
+ `${path} must be an RFC 3339 instant under "rfc3339", got ${JSON.stringify(value)}.`,
962
+ at
963
+ );
964
+ }
965
+ expiresAt = new Date(instantMs(value, path, at)).toISOString();
966
+ }
967
+ return subscriptionLease(
968
+ { expiresAt, renewBeforeSeconds: declaration.renewBeforeSeconds, renewOperation: declaration.renewOperation },
969
+ at
970
+ );
971
+ }
972
+ function readPath(value, path) {
973
+ let current = value;
974
+ for (const segment of path.split(".")) {
975
+ if (current === null || typeof current !== "object") return void 0;
976
+ current = current[segment];
977
+ }
978
+ return current;
979
+ }
980
+ function subscriptionLease(input, at = DEFAULT_CONTEXT) {
981
+ instantMs(input.expiresAt, "expiresAt", at);
982
+ if (!Number.isInteger(input.renewBeforeSeconds) || input.renewBeforeSeconds <= 0) {
983
+ throw new ConnectorConfigError(
984
+ `renewBeforeSeconds must be a positive whole number of seconds, got ${JSON.stringify(input.renewBeforeSeconds)}. Zero would make the lease due only at the instant it expires, which is a lease nobody renews.`,
985
+ at
986
+ );
987
+ }
988
+ if (typeof input.renewOperation !== "string" || input.renewOperation.trim() === "") {
989
+ throw new ConnectorConfigError(
990
+ "renewOperation must name the operation the host calls when the lease is due; a due lease with nothing to call is one nobody renews.",
991
+ at
992
+ );
993
+ }
994
+ return { expiresAt: input.expiresAt, renewBeforeSeconds: input.renewBeforeSeconds, renewOperation: input.renewOperation };
995
+ }
996
+ function leaseRenewAt(lease) {
997
+ return new Date(instantMs(lease.expiresAt, "expiresAt", DEFAULT_CONTEXT) - lease.renewBeforeSeconds * 1e3).toISOString();
998
+ }
999
+ function leaseState(lease, now) {
1000
+ const at = now instanceof Date ? now.getTime() : instantMs(now, "now", DEFAULT_CONTEXT);
1001
+ const expires = instantMs(lease.expiresAt, "expiresAt", DEFAULT_CONTEXT);
1002
+ if (at >= expires) return "expired";
1003
+ if (at >= expires - lease.renewBeforeSeconds * 1e3) return "due";
1004
+ return "active";
1005
+ }
1006
+ function leaseAction(lease, now) {
1007
+ switch (leaseState(lease, now)) {
1008
+ case "active":
1009
+ return "none";
1010
+ case "due":
1011
+ return "renew";
1012
+ case "expired":
1013
+ return "resync";
1014
+ }
1015
+ }
1016
+
916
1017
  // src/metrics.ts
917
1018
  function compareShape(connectorId, declared, produced) {
918
1019
  const declaredKeys = new Set((declared ?? []).map((metric) => metric.key));
@@ -1007,6 +1108,245 @@ function providerSandboxIsSelectable(provider) {
1007
1108
  return sandboxIsSelectable(provider.sandbox);
1008
1109
  }
1009
1110
 
1111
+ // src/mime.ts
1112
+ var CR = 13;
1113
+ var LF = 10;
1114
+ function latin1(bytes) {
1115
+ let s = "";
1116
+ for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);
1117
+ return s;
1118
+ }
1119
+ function bytesOfLatin1(s) {
1120
+ const out = new Uint8Array(s.length);
1121
+ for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 255;
1122
+ return out;
1123
+ }
1124
+ function splitEntity(bytes) {
1125
+ for (let i = 0; i < bytes.length; i++) {
1126
+ if (bytes[i] === LF) {
1127
+ if (bytes[i + 1] === LF) return [i, i + 2];
1128
+ if (bytes[i + 1] === CR && bytes[i + 2] === LF) return [i, i + 3];
1129
+ }
1130
+ }
1131
+ return [bytes.length, bytes.length];
1132
+ }
1133
+ function parseHeaders(block) {
1134
+ const lines = block.split(/\r?\n/);
1135
+ const unfolded = [];
1136
+ for (const line of lines) {
1137
+ if (line === "") continue;
1138
+ if ((line.startsWith(" ") || line.startsWith(" ")) && unfolded.length > 0) {
1139
+ unfolded[unfolded.length - 1] += " " + line.trim();
1140
+ } else {
1141
+ unfolded.push(line);
1142
+ }
1143
+ }
1144
+ const headers = [];
1145
+ for (const line of unfolded) {
1146
+ const colon = line.indexOf(":");
1147
+ if (colon <= 0) continue;
1148
+ headers.push({ name: line.slice(0, colon).trim().toLowerCase(), value: decodeWords(line.slice(colon + 1).trim()) });
1149
+ }
1150
+ return headers;
1151
+ }
1152
+ function header(headers, name) {
1153
+ return headers.find((h) => h.name === name)?.value ?? null;
1154
+ }
1155
+ var ENCODED_WORD = /=\?([^?\s]+)\?([BbQq])\?([^?\s]*)\?=/g;
1156
+ function decodeWords(value) {
1157
+ const joined = value.replace(/(\?=)[ \t\r\n]+(=\?)/g, "$1$2");
1158
+ return joined.replace(ENCODED_WORD, (whole, charset, encoding, text) => {
1159
+ const bytes = encoding.toUpperCase() === "B" ? base64Bytes(text) : bytesOfLatin1(text.replace(/_/g, " ").replace(/=([0-9A-Fa-f]{2})/g, (_m, h) => String.fromCharCode(parseInt(h, 16))));
1160
+ const decoded = decodeCharset(bytes, charset);
1161
+ return decoded ?? whole;
1162
+ });
1163
+ }
1164
+ function parseParams(value) {
1165
+ const [head, ...rest] = value.split(";");
1166
+ const params = {};
1167
+ const continued = {};
1168
+ for (const piece of rest) {
1169
+ const eq = piece.indexOf("=");
1170
+ if (eq < 0) continue;
1171
+ let key = piece.slice(0, eq).trim().toLowerCase();
1172
+ let raw = piece.slice(eq + 1).trim();
1173
+ if (raw.startsWith('"') && raw.endsWith('"') && raw.length >= 2) raw = raw.slice(1, -1).replace(/\\(.)/g, "$1");
1174
+ const segment = /^(.+?)\*(\d+)(\*)?$/.exec(key);
1175
+ if (segment) {
1176
+ const [, base, n, star] = segment;
1177
+ (continued[base] ??= [])[Number(n)] = star ? decode2231(raw, Number(n) === 0) : raw;
1178
+ continue;
1179
+ }
1180
+ if (key.endsWith("*")) {
1181
+ key = key.slice(0, -1);
1182
+ params[key] = decode2231(raw, true);
1183
+ continue;
1184
+ }
1185
+ params[key] ??= raw;
1186
+ }
1187
+ for (const [base, parts] of Object.entries(continued)) params[base] = parts.join("");
1188
+ return { main: (head ?? "").trim().toLowerCase(), params };
1189
+ }
1190
+ var pendingCharset2231 = "utf-8";
1191
+ function decode2231(raw, first) {
1192
+ let text = raw;
1193
+ if (first) {
1194
+ const m = /^([^']*)'[^']*'(.*)$/s.exec(raw);
1195
+ if (m) {
1196
+ pendingCharset2231 = m[1] || "utf-8";
1197
+ text = m[2];
1198
+ }
1199
+ }
1200
+ const bytes = bytesOfLatin1(text.replace(/%([0-9A-Fa-f]{2})/g, (_m, h) => String.fromCharCode(parseInt(h, 16))));
1201
+ return decodeCharset(bytes, pendingCharset2231) ?? text;
1202
+ }
1203
+ function base64Bytes(text) {
1204
+ return new Uint8Array(Buffer.from(text.replace(/[^A-Za-z0-9+/=]/g, ""), "base64"));
1205
+ }
1206
+ function quotedPrintableBytes(bytes) {
1207
+ const out = [];
1208
+ for (let i = 0; i < bytes.length; i++) {
1209
+ const b = bytes[i];
1210
+ if (b !== 61) {
1211
+ out.push(b);
1212
+ continue;
1213
+ }
1214
+ const a = bytes[i + 1];
1215
+ const c = bytes[i + 2];
1216
+ if (a === LF) {
1217
+ i += 1;
1218
+ continue;
1219
+ }
1220
+ if (a === CR && c === LF) {
1221
+ i += 2;
1222
+ continue;
1223
+ }
1224
+ if (a !== void 0 && c !== void 0 && isHex(a) && isHex(c)) {
1225
+ out.push(parseInt(String.fromCharCode(a, c), 16));
1226
+ i += 2;
1227
+ continue;
1228
+ }
1229
+ out.push(b);
1230
+ }
1231
+ return new Uint8Array(out);
1232
+ }
1233
+ function isHex(b) {
1234
+ return b >= 48 && b <= 57 || b >= 65 && b <= 70 || b >= 97 && b <= 102;
1235
+ }
1236
+ function transferDecode(body, encoding) {
1237
+ switch ((encoding ?? "7bit").trim().toLowerCase()) {
1238
+ case "base64":
1239
+ return base64Bytes(latin1(body));
1240
+ case "quoted-printable":
1241
+ return quotedPrintableBytes(body);
1242
+ default:
1243
+ return body;
1244
+ }
1245
+ }
1246
+ function decodeCharset(bytes, charset) {
1247
+ switch (charset.trim().toLowerCase()) {
1248
+ case "utf-8":
1249
+ case "utf8":
1250
+ return new TextDecoder("utf-8").decode(bytes);
1251
+ case "us-ascii":
1252
+ case "ascii":
1253
+ case "iso-8859-1":
1254
+ case "latin1":
1255
+ return Buffer.from(bytes).toString("latin1");
1256
+ case "windows-1252":
1257
+ case "cp1252":
1258
+ return new TextDecoder("windows-1252").decode(bytes);
1259
+ case "iso-8859-15":
1260
+ case "latin9":
1261
+ return new TextDecoder("iso-8859-15").decode(bytes);
1262
+ default:
1263
+ return null;
1264
+ }
1265
+ }
1266
+ function walk(bytes, entityHeaders, acc) {
1267
+ const [headerEnd, bodyStart] = splitEntity(bytes);
1268
+ const headers = entityHeaders ?? parseHeaders(latin1(bytes.subarray(0, headerEnd)));
1269
+ const body = bytes.subarray(entityHeaders ? 0 : bodyStart);
1270
+ const type = parseParams(header(headers, "content-type") ?? "text/plain");
1271
+ if (type.main.startsWith("multipart/") && type.params.boundary) {
1272
+ for (const child of splitMultipart(body, type.params.boundary)) walk(child, null, acc);
1273
+ return;
1274
+ }
1275
+ const disposition = parseParams(header(headers, "content-disposition") ?? "");
1276
+ const decoded = transferDecode(body, header(headers, "content-transfer-encoding"));
1277
+ const declaredDisposition = disposition.main === "attachment" || disposition.main === "inline" ? disposition.main : null;
1278
+ const filename = disposition.params.filename ?? type.params.name ?? null;
1279
+ const contentId = header(headers, "content-id")?.replace(/^<|>$/g, "") ?? null;
1280
+ const isText = type.main.startsWith("text/");
1281
+ const isAttachment = declaredDisposition === "attachment" || !isText;
1282
+ const part = {
1283
+ index: acc.parts.length,
1284
+ contentType: type.main,
1285
+ charset: type.params.charset?.toLowerCase() ?? null,
1286
+ disposition: declaredDisposition,
1287
+ filename,
1288
+ contentId,
1289
+ size: decoded.length,
1290
+ headers
1291
+ };
1292
+ acc.parts.push(part);
1293
+ if (isAttachment) {
1294
+ acc.attachments.push({ ...part, content: Buffer.from(decoded).toString("base64") });
1295
+ return;
1296
+ }
1297
+ const text = decodeCharset(decoded, type.params.charset ?? "utf-8");
1298
+ if (text === null) return;
1299
+ if (type.main === "text/plain" && acc.text === null) acc.text = text;
1300
+ if (type.main === "text/html" && acc.html === null) acc.html = text;
1301
+ }
1302
+ function splitMultipart(body, boundary) {
1303
+ const delimiter = bytesOfLatin1(`--${boundary}`);
1304
+ const children = [];
1305
+ let partStart = -1;
1306
+ for (let i = 0; i <= body.length - delimiter.length; i++) {
1307
+ if (i !== 0 && body[i - 1] !== LF) continue;
1308
+ if (!startsWith(body, i, delimiter)) continue;
1309
+ let partEnd = i;
1310
+ if (partEnd > 0 && body[partEnd - 1] === LF) partEnd -= 1;
1311
+ if (partEnd > 0 && body[partEnd - 1] === CR) partEnd -= 1;
1312
+ if (partStart >= 0) children.push(body.subarray(partStart, partEnd));
1313
+ let j = i + delimiter.length;
1314
+ const closing = body[j] === 45 && body[j + 1] === 45;
1315
+ if (closing) return children;
1316
+ while (j < body.length && body[j] !== LF) j++;
1317
+ partStart = j + 1;
1318
+ i = j;
1319
+ }
1320
+ if (partStart >= 0 && partStart <= body.length) children.push(body.subarray(partStart));
1321
+ return children;
1322
+ }
1323
+ function startsWith(haystack, at, needle) {
1324
+ for (let k = 0; k < needle.length; k++) if (haystack[at + k] !== needle[k]) return false;
1325
+ return true;
1326
+ }
1327
+ function parseMime(raw) {
1328
+ const bytes = typeof raw === "string" ? new Uint8Array(Buffer.from(raw, "utf8")) : raw;
1329
+ const [headerEnd, bodyStart] = splitEntity(bytes);
1330
+ const headers = parseHeaders(latin1(bytes.subarray(0, headerEnd)));
1331
+ const body = bytes.subarray(bodyStart);
1332
+ const acc = { parts: [], attachments: [], text: null, html: null };
1333
+ const type = parseParams(header(headers, "content-type") ?? "text/plain");
1334
+ if (type.main.startsWith("multipart/") && type.params.boundary) {
1335
+ for (const child of splitMultipart(body, type.params.boundary)) walk(child, null, acc);
1336
+ } else {
1337
+ walk(body, headers.filter((h) => h.name.startsWith("content-")), acc);
1338
+ }
1339
+ return {
1340
+ headers,
1341
+ subject: header(headers, "subject"),
1342
+ messageId: header(headers, "message-id"),
1343
+ text: acc.text,
1344
+ html: acc.html,
1345
+ parts: acc.parts,
1346
+ attachments: acc.attachments
1347
+ };
1348
+ }
1349
+
1010
1350
  // src/probe.ts
1011
1351
  async function probe(spec) {
1012
1352
  let response;
@@ -1266,7 +1606,53 @@ function constantTimeEquals(a, b) {
1266
1606
  for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
1267
1607
  return diff === 0;
1268
1608
  }
1269
- function header(headers, name) {
1609
+ function isSharedTokenScheme(scheme) {
1610
+ return "kind" in scheme && scheme.kind === "shared-token";
1611
+ }
1612
+ function verifySharedToken(options) {
1613
+ const { raw, headers, secret, scheme } = options;
1614
+ if (!secret) {
1615
+ return { ok: false, reason: "no shared token configured for this trigger" };
1616
+ }
1617
+ let tokens;
1618
+ if (scheme.in === "header") {
1619
+ tokens = [header2(headers, scheme.name)];
1620
+ } else {
1621
+ let parsed;
1622
+ try {
1623
+ parsed = JSON.parse(raw);
1624
+ } catch {
1625
+ return { ok: false, reason: "delivery body is not JSON" };
1626
+ }
1627
+ tokens = readTokens(parsed, scheme.path.split("."));
1628
+ }
1629
+ const present = tokens.filter((t) => t !== void 0 && t !== null && t !== "");
1630
+ if (present.length === 0) return { ok: false, reason: "delivery carried no token" };
1631
+ let matched = present.length === tokens.length;
1632
+ for (const token of present) {
1633
+ matched = typeof token === "string" && constantTimeEquals(secret, token) && matched;
1634
+ }
1635
+ return matched ? { ok: true } : { ok: false, reason: "token did not match" };
1636
+ }
1637
+ function readTokens(value, segments) {
1638
+ if (segments.length === 0) return [value];
1639
+ const [head, ...rest] = segments;
1640
+ const eachElement = head.endsWith("[]");
1641
+ const key = eachElement ? head.slice(0, -2) : head;
1642
+ if (value === null || typeof value !== "object") return [void 0];
1643
+ const next = value[key];
1644
+ if (!eachElement) return readTokens(next, rest);
1645
+ if (!Array.isArray(next)) return [void 0];
1646
+ return next.flatMap((element) => readTokens(element, rest));
1647
+ }
1648
+ function handshakeResponse(handshake, query) {
1649
+ if (!handshake) return void 0;
1650
+ const raw = query[handshake.param];
1651
+ const token = Array.isArray(raw) ? raw[0] : raw;
1652
+ if (!token) return void 0;
1653
+ return { status: 200, contentType: handshake.contentType ?? "text/plain", body: token };
1654
+ }
1655
+ function header2(headers, name) {
1270
1656
  const wanted = name.toLowerCase();
1271
1657
  for (const [key, value] of Object.entries(headers)) {
1272
1658
  if (key.toLowerCase() !== wanted) continue;
@@ -1276,6 +1662,9 @@ function header(headers, name) {
1276
1662
  }
1277
1663
 
1278
1664
  // src/trigger.ts
1665
+ function isSharedTokenSpec(spec) {
1666
+ return isSharedTokenScheme(spec.scheme);
1667
+ }
1279
1668
  async function verifyDelivery(trigger, delivery, secret, now) {
1280
1669
  const spec = trigger.verification;
1281
1670
  if (!spec) {
@@ -1284,9 +1673,12 @@ async function verifyDelivery(trigger, delivery, secret, now) {
1284
1673
  reason: `${trigger.service}.${trigger.operation} declares no signature scheme, so a delivery cannot be trusted.`
1285
1674
  };
1286
1675
  }
1287
- const rawHeader = header(delivery.headers, spec.signatureHeader);
1676
+ if (isSharedTokenSpec(spec)) {
1677
+ return verifySharedToken({ raw: delivery.raw, headers: delivery.headers, secret, scheme: spec.scheme });
1678
+ }
1679
+ const rawHeader = header2(delivery.headers, spec.signatureHeader);
1288
1680
  const parsed = spec.parse && rawHeader ? spec.parse(rawHeader) : { signature: rawHeader };
1289
- const timestamp = parsed.timestamp ?? (spec.timestampHeader ? header(delivery.headers, spec.timestampHeader) : void 0);
1681
+ const timestamp = parsed.timestamp ?? (spec.timestampHeader ? header2(delivery.headers, spec.timestampHeader) : void 0);
1290
1682
  return verifyHmac({
1291
1683
  raw: delivery.raw,
1292
1684
  signature: parsed.signature,
@@ -1333,6 +1725,7 @@ export {
1333
1725
  ConnectorUnreachable,
1334
1726
  DEFAULT_IDEMPOTENCY_WINDOW_SECONDS,
1335
1727
  DEFAULT_RETRY,
1728
+ EXPIRES_AT_UNITS,
1336
1729
  FAKE_EPOCH,
1337
1730
  MAX_IDEMPOTENCY_KEY_LENGTH,
1338
1731
  NO_IDEMPOTENCY_KEY_WARNING,
@@ -1359,15 +1752,23 @@ export {
1359
1752
  fakeValues,
1360
1753
  getConnectionHost,
1361
1754
  graphemes,
1362
- header,
1755
+ handshakeResponse,
1756
+ header2 as header,
1363
1757
  hmac,
1364
1758
  httpFailure,
1365
1759
  idempotencyKeyFor,
1366
1760
  isEmptyPayload,
1367
1761
  isRemote,
1762
+ isSharedTokenScheme,
1763
+ isSharedTokenSpec,
1368
1764
  isUnconditionallyRetryable,
1765
+ leaseAction,
1766
+ leaseFromResponse,
1767
+ leaseRenewAt,
1768
+ leaseState,
1369
1769
  linkRanges,
1370
1770
  measure,
1771
+ parseMime,
1371
1772
  payloadHash,
1372
1773
  postChain,
1373
1774
  probe,
@@ -1392,11 +1793,13 @@ export {
1392
1793
  shouldRetry,
1393
1794
  sliceByteRange,
1394
1795
  splitToFit,
1796
+ subscriptionLease,
1395
1797
  triggerEvent,
1396
1798
  unchecked,
1397
1799
  utf8Length,
1398
1800
  verifyDelivery,
1399
1801
  verifyHmac,
1802
+ verifySharedToken,
1400
1803
  withResolvedLimit
1401
1804
  };
1402
1805
  //# sourceMappingURL=index.js.map