sermon-js 0.1.0 → 0.3.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/README.md +2 -1
- package/dist/api/index.d.cts +4 -4
- package/dist/api/index.d.ts +4 -4
- package/dist/{chunk-PARE6EUZ.cjs → chunk-NZTKXXW2.cjs} +7 -3
- package/dist/chunk-NZTKXXW2.cjs.map +1 -0
- package/dist/{chunk-2M4UBCDM.js → chunk-R7BDAQOM.js} +7 -3
- package/dist/chunk-R7BDAQOM.js.map +1 -0
- package/dist/{config-BEbP-uLf.d.cts → config-gro29syt.d.cts} +1 -1
- package/dist/{config-w1tm1bdu.d.ts → config-iY18j9IA.d.ts} +1 -1
- package/dist/{generic-lmrGxMDC.d.cts → generic-BUiaKpNp.d.cts} +2 -2
- package/dist/{generic-BJmlgtUM.d.ts → generic-CV2O4aNH.d.ts} +2 -2
- package/dist/index.cjs +6 -6
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +2 -2
- package/dist/presets/index.cjs +552 -47
- package/dist/presets/index.cjs.map +1 -1
- package/dist/presets/index.d.cts +261 -13
- package/dist/presets/index.d.ts +261 -13
- package/dist/presets/index.js +542 -48
- package/dist/presets/index.js.map +1 -1
- package/dist/react/heroui/index.cjs +27 -18
- package/dist/react/heroui/index.cjs.map +1 -1
- package/dist/react/heroui/index.d.cts +7 -2
- package/dist/react/heroui/index.d.ts +7 -2
- package/dist/react/heroui/index.js +13 -4
- package/dist/react/heroui/index.js.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/{status-DsWzgb9Q.d.cts → status-BExBb08T.d.cts} +3 -3
- package/dist/{status-zd04ZQ98.d.ts → status-DmRhwvVC.d.ts} +3 -3
- package/dist/{store-_GuzSP0z.d.ts → store-BfKP7CjW.d.ts} +1 -1
- package/dist/{store-DybhDphS.d.cts → store-CAIB7Esp.d.cts} +1 -1
- package/dist/stores/mongodb.d.cts +2 -2
- package/dist/stores/mongodb.d.ts +2 -2
- package/dist/stores/redis.d.cts +2 -2
- package/dist/stores/redis.d.ts +2 -2
- package/dist/stores/sql.d.cts +2 -2
- package/dist/stores/sql.d.ts +2 -2
- package/dist/stores/upstash.d.cts +2 -2
- package/dist/stores/upstash.d.ts +2 -2
- package/dist/testing/index.cjs +3 -3
- package/dist/testing/index.d.cts +3 -3
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +1 -1
- package/dist/{tree-BXbXfjF1.d.cts → tree-J3riUyI9.d.cts} +9 -0
- package/dist/{tree-BXbXfjF1.d.ts → tree-J3riUyI9.d.ts} +9 -0
- package/dist/{types-CctvUAs2.d.cts → types-BVa6vIKk.d.cts} +9 -0
- package/dist/{types-CctvUAs2.d.ts → types-BVa6vIKk.d.ts} +9 -0
- package/package.json +1 -1
- package/dist/chunk-2M4UBCDM.js.map +0 -1
- package/dist/chunk-PARE6EUZ.cjs.map +0 -1
package/dist/presets/index.cjs
CHANGED
|
@@ -19,9 +19,9 @@ function withKeys(machines) {
|
|
|
19
19
|
const seen = /* @__PURE__ */ new Map();
|
|
20
20
|
return [...machines].sort((a, b) => (a.region ?? "").localeCompare(b.region ?? "") || a.id.localeCompare(b.id)).map((machine) => {
|
|
21
21
|
const region = machine.region ?? "unknown";
|
|
22
|
-
const
|
|
23
|
-
seen.set(region,
|
|
24
|
-
return { machine, region, key:
|
|
22
|
+
const count2 = (seen.get(region) ?? 0) + 1;
|
|
23
|
+
seen.set(region, count2);
|
|
24
|
+
return { machine, region, key: count2 === 1 ? region : `${region}#${count2}` };
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
function median(values) {
|
|
@@ -223,8 +223,8 @@ var instance = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
223
223
|
}),
|
|
224
224
|
check: async ({ options, secrets, http, now }) => {
|
|
225
225
|
const account = parseServiceAccount(secrets.serviceAccount);
|
|
226
|
-
const
|
|
227
|
-
if (!account || !
|
|
226
|
+
const project2 = options.project ?? account?.project_id;
|
|
227
|
+
if (!account || !project2) {
|
|
228
228
|
return { status: "down", probed: false, error: "The service account secret is not a service-account JSON key" };
|
|
229
229
|
}
|
|
230
230
|
let token;
|
|
@@ -239,7 +239,7 @@ var instance = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
239
239
|
return { status: "down", probed: false, error: error instanceof Error ? error.message : String(error) };
|
|
240
240
|
}
|
|
241
241
|
const info = await http(
|
|
242
|
-
`https://compute.googleapis.com/compute/v1/projects/${
|
|
242
|
+
`https://compute.googleapis.com/compute/v1/projects/${project2}/zones/${options.zone}/instances/${options.instance}`,
|
|
243
243
|
{ headers: { Authorization: `Bearer ${token}` } }
|
|
244
244
|
);
|
|
245
245
|
const state = info.json?.status;
|
|
@@ -262,6 +262,68 @@ var instance = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
262
262
|
}
|
|
263
263
|
});
|
|
264
264
|
var gcp = { instance };
|
|
265
|
+
|
|
266
|
+
// src/presets/providers/shared.ts
|
|
267
|
+
var bearer = (token) => ({ Authorization: `Bearer ${token}` });
|
|
268
|
+
var round = (value, digits = 1) => Math.round(value * 10 ** digits) / 10 ** digits;
|
|
269
|
+
function base64(text) {
|
|
270
|
+
const bytes = new TextEncoder().encode(text);
|
|
271
|
+
let binary = "";
|
|
272
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
273
|
+
return btoa(binary);
|
|
274
|
+
}
|
|
275
|
+
async function call(http, url, init, refine) {
|
|
276
|
+
const response = await http(url, init);
|
|
277
|
+
if (!response.ok || !refine) return response.outcome;
|
|
278
|
+
return { ...response.outcome, ...chunkXHXEKB3Q_cjs.normalizeReturn(refine(response)) };
|
|
279
|
+
}
|
|
280
|
+
function quota({
|
|
281
|
+
label,
|
|
282
|
+
used,
|
|
283
|
+
limit,
|
|
284
|
+
unit,
|
|
285
|
+
resetsAt,
|
|
286
|
+
warnAbovePct,
|
|
287
|
+
warning
|
|
288
|
+
}) {
|
|
289
|
+
const pct = limit > 0 ? used / limit * 100 : 0;
|
|
290
|
+
const over = pct >= warnAbovePct;
|
|
291
|
+
return {
|
|
292
|
+
status: over ? "degraded" : "up",
|
|
293
|
+
error: over ? warning : void 0,
|
|
294
|
+
usage: [{ label, used, limit, unit, resetsAt }]
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
function summarize(instances, noun) {
|
|
298
|
+
const down = instances.filter((instance2) => instance2.status === "down");
|
|
299
|
+
const degraded = instances.filter((instance2) => instance2.status === "degraded");
|
|
300
|
+
const awake = instances.filter((instance2) => instance2.status === "up" || instance2.status === "degraded");
|
|
301
|
+
const keysOf = (items) => items.map((instance2) => instance2.key).join(", ");
|
|
302
|
+
const latencies = instances.map((instance2) => instance2.latencyMs).filter((l) => l !== void 0);
|
|
303
|
+
const latencyMs = latencies.length ? Math.max(...latencies) : void 0;
|
|
304
|
+
if (instances.length > 0 && down.length === instances.length) {
|
|
305
|
+
return { status: "down", latencyMs, error: `All ${instances.length} ${noun}(s) failing` };
|
|
306
|
+
}
|
|
307
|
+
if (down.length > 0) {
|
|
308
|
+
return { status: "degraded", latencyMs, error: `${down.length}/${instances.length} ${noun}(s) failing: ${keysOf(down)}` };
|
|
309
|
+
}
|
|
310
|
+
if (degraded.length > 0) return { status: "degraded", latencyMs, error: `Degraded: ${keysOf(degraded)}` };
|
|
311
|
+
return { status: awake.length || instances.length === 0 ? "up" : "sleeping", latencyMs };
|
|
312
|
+
}
|
|
313
|
+
function keyAccepted(res) {
|
|
314
|
+
if (res.status === 400 || res.status === 422) return { status: "up", latencyMs: res.latencyMs, httpStatus: res.status };
|
|
315
|
+
if (res.status === 402) {
|
|
316
|
+
return { status: "degraded", latencyMs: res.latencyMs, httpStatus: 402, error: "Out of credits, or payment required" };
|
|
317
|
+
}
|
|
318
|
+
return res.outcome;
|
|
319
|
+
}
|
|
320
|
+
var emptyPost = (headers) => ({
|
|
321
|
+
method: "POST",
|
|
322
|
+
headers: { "content-type": "application/json", ...headers },
|
|
323
|
+
body: "{}"
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// src/presets/aws.ts
|
|
265
327
|
async function signedCall({
|
|
266
328
|
http,
|
|
267
329
|
secrets,
|
|
@@ -321,7 +383,170 @@ var s3Bucket = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
321
383
|
return response.outcome;
|
|
322
384
|
}
|
|
323
385
|
});
|
|
324
|
-
|
|
386
|
+
function pingBody(model) {
|
|
387
|
+
if (/(^|\.)cohere\.embed/.test(model)) return { texts: ["ping"], input_type: "search_query" };
|
|
388
|
+
return { anthropic_version: "bedrock-2023-05-31", max_tokens: 1, messages: [{ role: "user", content: "ping" }] };
|
|
389
|
+
}
|
|
390
|
+
var bedrockPreset = chunkXHXEKB3Q_cjs.definePreset()({
|
|
391
|
+
kind: "aws.bedrock",
|
|
392
|
+
requiredFields: ["region"],
|
|
393
|
+
requiredSecrets: "all",
|
|
394
|
+
defaults: { slowMs: 5e3, timeoutMs: 2e4 },
|
|
395
|
+
derive: () => ({
|
|
396
|
+
name: "Amazon Bedrock",
|
|
397
|
+
identity: "aws.bedrock",
|
|
398
|
+
description: "Invokes each monitored model with one token"
|
|
399
|
+
}),
|
|
400
|
+
check: async ({ options, secrets, http }) => {
|
|
401
|
+
const signer = secrets.accessKeyId && secrets.secretAccessKey ? new aws4fetch.AwsClient({
|
|
402
|
+
accessKeyId: secrets.accessKeyId,
|
|
403
|
+
secretAccessKey: secrets.secretAccessKey,
|
|
404
|
+
service: "bedrock",
|
|
405
|
+
region: options.region
|
|
406
|
+
}) : void 0;
|
|
407
|
+
const invoke = async (model) => {
|
|
408
|
+
const url = `https://bedrock-runtime.${options.region}.amazonaws.com/model/${encodeURIComponent(model)}/invoke`;
|
|
409
|
+
const init = {
|
|
410
|
+
method: "POST",
|
|
411
|
+
headers: { "content-type": "application/json", accept: "application/json" },
|
|
412
|
+
body: JSON.stringify(pingBody(model))
|
|
413
|
+
};
|
|
414
|
+
if (!signer) return http(url, { ...init, headers: { ...init.headers, ...bearer(secrets.bearerToken ?? "") } });
|
|
415
|
+
const signed = await signer.sign(url, init);
|
|
416
|
+
return http(signed.url, { ...init, headers: Object.fromEntries(signed.headers.entries()) });
|
|
417
|
+
};
|
|
418
|
+
const instances = await Promise.all(
|
|
419
|
+
[...new Set(options.models)].map(async (model) => {
|
|
420
|
+
const res = await invoke(model);
|
|
421
|
+
return {
|
|
422
|
+
key: model,
|
|
423
|
+
status: res.outcome.status,
|
|
424
|
+
latencyMs: res.status === void 0 ? void 0 : res.latencyMs,
|
|
425
|
+
httpStatus: res.status,
|
|
426
|
+
error: res.outcome.error
|
|
427
|
+
};
|
|
428
|
+
})
|
|
429
|
+
);
|
|
430
|
+
return { ...summarize(instances, "model"), instances, instanceLabels: { key: "Model" } };
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
function bedrock(options) {
|
|
434
|
+
const { bearerToken, accessKeyId, secretAccessKey } = options.secrets;
|
|
435
|
+
return bedrockPreset({ ...options, secrets: bearerToken ? { bearerToken } : { accessKeyId, secretAccessKey } });
|
|
436
|
+
}
|
|
437
|
+
var aws = { credentials, s3Bucket, bedrock };
|
|
438
|
+
|
|
439
|
+
// src/presets/neon.ts
|
|
440
|
+
var API = "https://console.neon.tech/api/v2";
|
|
441
|
+
var GB = 1024 ** 3;
|
|
442
|
+
function withKeys2(endpoints, branches) {
|
|
443
|
+
const seen = /* @__PURE__ */ new Map();
|
|
444
|
+
return endpoints.map((endpoint) => {
|
|
445
|
+
const name = branches.get(endpoint.branch_id)?.name ?? endpoint.branch_id;
|
|
446
|
+
const count2 = (seen.get(name) ?? 0) + 1;
|
|
447
|
+
seen.set(name, count2);
|
|
448
|
+
return { endpoint, key: count2 === 1 ? name : `${name}#${count2}` };
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
var project = chunkXHXEKB3Q_cjs.definePreset()({
|
|
452
|
+
kind: "neon.project",
|
|
453
|
+
requiredFields: ["projectId"],
|
|
454
|
+
requiredSecrets: ["apiKey"],
|
|
455
|
+
defaults: { slowMs: 1e3 },
|
|
456
|
+
derive: (options) => ({
|
|
457
|
+
name: "Neon",
|
|
458
|
+
identity: `neon.project:${options.projectId ?? ""}`,
|
|
459
|
+
description: "Compute states from the Neon API, then `select 1` on an active compute only"
|
|
460
|
+
}),
|
|
461
|
+
check: async ({ options, secrets, http, measure }) => {
|
|
462
|
+
const base = `${API}/projects/${encodeURIComponent(options.projectId)}`;
|
|
463
|
+
const headers = { ...bearer(secrets.apiKey), accept: "application/json" };
|
|
464
|
+
const [list, info, branchList] = await Promise.all([
|
|
465
|
+
http(`${base}/endpoints`, { headers }),
|
|
466
|
+
http(base, { headers }),
|
|
467
|
+
http(`${base}/branches`, { headers })
|
|
468
|
+
]);
|
|
469
|
+
if (list.status === 404) {
|
|
470
|
+
return { status: "down", probed: false, httpStatus: 404, error: `Project "${options.projectId}" not found on Neon` };
|
|
471
|
+
}
|
|
472
|
+
const endpoints = list.json?.endpoints;
|
|
473
|
+
if (!list.ok || !Array.isArray(endpoints)) {
|
|
474
|
+
return {
|
|
475
|
+
status: "degraded",
|
|
476
|
+
probed: false,
|
|
477
|
+
httpStatus: list.status,
|
|
478
|
+
error: list.status ? `Neon API HTTP ${list.status}` : `Neon API unreachable: ${list.outcome.error ?? "no response"}`
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
if (endpoints.length === 0) return { status: "down", probed: false, error: "No compute: nothing can connect" };
|
|
482
|
+
const branches = branchList.json?.branches ?? [];
|
|
483
|
+
const details = info.json?.project;
|
|
484
|
+
const byId = new Map(branches.map((branch) => [branch.id, branch]));
|
|
485
|
+
const defaultBranch = branches.find((branch) => branch.default)?.id;
|
|
486
|
+
const keyed = withKeys2(endpoints, byId);
|
|
487
|
+
const target = keyed.find(({ endpoint }) => endpoint.id === options.endpoint) ?? (options.endpoint ? void 0 : keyed.find(({ endpoint }) => endpoint.type === "read_write" && endpoint.branch_id === defaultBranch) ?? keyed.find(({ endpoint }) => endpoint.type === "read_write"));
|
|
488
|
+
const ping = options.query && target?.endpoint.current_state === "active" && !target.endpoint.disabled ? await measure(async () => void await options.query("select 1")) : void 0;
|
|
489
|
+
const instances = keyed.map(({ endpoint, key }) => {
|
|
490
|
+
const row = { key, region: endpoint.region_id, id: endpoint.id };
|
|
491
|
+
if (endpoint.disabled) return { ...row, state: "disabled", status: "sleeping" };
|
|
492
|
+
if (endpoint.current_state === "idle") return { ...row, state: "idle", status: "sleeping" };
|
|
493
|
+
if (endpoint.current_state !== "active") return { ...row, state: endpoint.current_state, status: "degraded" };
|
|
494
|
+
if (ping && endpoint.id === target?.endpoint.id) {
|
|
495
|
+
return { ...row, state: "active", status: ping.status, latencyMs: ping.latencyMs, error: ping.error };
|
|
496
|
+
}
|
|
497
|
+
return { ...row, state: "active", status: "up" };
|
|
498
|
+
});
|
|
499
|
+
const usage = [];
|
|
500
|
+
const warnings = [];
|
|
501
|
+
const bar = (entry, warnAbovePct = 90) => {
|
|
502
|
+
usage.push(entry);
|
|
503
|
+
if (entry.limit > 0 && entry.used / entry.limit * 100 >= warnAbovePct) warnings.push(`${entry.label} close to the plan limit`);
|
|
504
|
+
};
|
|
505
|
+
const compute = options.track?.compute;
|
|
506
|
+
if (compute && typeof details?.compute_time_seconds === "number") {
|
|
507
|
+
bar(
|
|
508
|
+
{
|
|
509
|
+
label: "Compute this period",
|
|
510
|
+
used: round(details.compute_time_seconds / 3600),
|
|
511
|
+
limit: compute.maxHours,
|
|
512
|
+
unit: "CU-hours",
|
|
513
|
+
resetsAt: details.consumption_period_end ? Date.parse(details.consumption_period_end) || void 0 : void 0
|
|
514
|
+
},
|
|
515
|
+
compute.warnAbovePct
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
const storage = options.track?.storage;
|
|
519
|
+
if (storage && branches.length > 0) {
|
|
520
|
+
const bytes = branches.reduce((sum, branch) => sum + (branch.logical_size ?? 0), 0);
|
|
521
|
+
bar({ label: "Storage", used: round(bytes / GB, 2), limit: storage.maxGb, unit: "GB" }, storage.warnAbovePct);
|
|
522
|
+
}
|
|
523
|
+
const main = instances.find((instance2) => instance2.id === target?.endpoint.id) ?? instances[0];
|
|
524
|
+
const active = instances.filter((instance2) => instance2.state === "active").length;
|
|
525
|
+
let status = main.status;
|
|
526
|
+
let error = main.error;
|
|
527
|
+
if (status === "degraded" && !error) error = `Compute is ${main.state}`;
|
|
528
|
+
if ((status === "up" || status === "sleeping") && warnings.length) {
|
|
529
|
+
status = "degraded";
|
|
530
|
+
error = warnings.join("; ");
|
|
531
|
+
}
|
|
532
|
+
return {
|
|
533
|
+
status,
|
|
534
|
+
probed: !!ping,
|
|
535
|
+
latencyMs: ping?.latencyMs ?? list.latencyMs,
|
|
536
|
+
error,
|
|
537
|
+
metrics: {
|
|
538
|
+
...details?.pg_version ? { postgres: details.pg_version } : {},
|
|
539
|
+
...details?.region_id ? { region: details.region_id } : {},
|
|
540
|
+
...branches.length ? { branches: branches.length } : {},
|
|
541
|
+
computes: `${active}/${instances.length} active`
|
|
542
|
+
},
|
|
543
|
+
usage: usage.length ? usage : void 0,
|
|
544
|
+
instances,
|
|
545
|
+
instanceLabels: { key: "Compute", detail: "Endpoint" }
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
var neon = { project };
|
|
325
550
|
|
|
326
551
|
// src/presets/databases.ts
|
|
327
552
|
var mongoPing = chunkXHXEKB3Q_cjs.definePreset()({
|
|
@@ -348,38 +573,16 @@ var redisPing = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
348
573
|
})
|
|
349
574
|
});
|
|
350
575
|
var redis = { ping: redisPing };
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
async function call(http, url, init, refine) {
|
|
362
|
-
const response = await http(url, init);
|
|
363
|
-
if (!response.ok || !refine) return response.outcome;
|
|
364
|
-
return { ...response.outcome, ...chunkXHXEKB3Q_cjs.normalizeReturn(refine(response)) };
|
|
365
|
-
}
|
|
366
|
-
function quota({
|
|
367
|
-
label,
|
|
368
|
-
used,
|
|
369
|
-
limit,
|
|
370
|
-
unit,
|
|
371
|
-
resetsAt,
|
|
372
|
-
warnAbovePct,
|
|
373
|
-
warning
|
|
374
|
-
}) {
|
|
375
|
-
const pct = limit > 0 ? used / limit * 100 : 0;
|
|
376
|
-
const over = pct >= warnAbovePct;
|
|
377
|
-
return {
|
|
378
|
-
status: over ? "degraded" : "up",
|
|
379
|
-
error: over ? warning : void 0,
|
|
380
|
-
usage: [{ label, used, limit, unit, resetsAt }]
|
|
381
|
-
};
|
|
382
|
-
}
|
|
576
|
+
var postgresPing = chunkXHXEKB3Q_cjs.definePreset()({
|
|
577
|
+
kind: "postgres.ping",
|
|
578
|
+
requiredFields: ["query"],
|
|
579
|
+
defaults: { slowMs: 1e3 },
|
|
580
|
+
derive: () => ({ name: "PostgreSQL", description: "Runs `select 1`" }),
|
|
581
|
+
check: ({ options, measure }) => measure(async () => {
|
|
582
|
+
await options.query("select 1");
|
|
583
|
+
})
|
|
584
|
+
});
|
|
585
|
+
var postgres = { ping: postgresPing };
|
|
383
586
|
|
|
384
587
|
// src/presets/providers/ai.ts
|
|
385
588
|
var deepgram = chunkXHXEKB3Q_cjs.definePreset()({
|
|
@@ -444,13 +647,33 @@ var openai = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
444
647
|
}
|
|
445
648
|
)
|
|
446
649
|
});
|
|
650
|
+
var API2 = "https://api.anthropic.com/v1/models";
|
|
447
651
|
var anthropic = chunkXHXEKB3Q_cjs.definePreset()({
|
|
448
652
|
kind: "anthropic",
|
|
449
653
|
requiredSecrets: ["apiKey"],
|
|
450
|
-
derive: () => ({
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
654
|
+
derive: (options) => ({
|
|
655
|
+
name: "Anthropic",
|
|
656
|
+
identity: "anthropic",
|
|
657
|
+
description: options.track?.models?.length ? "Reads each monitored model" : "Lists models"
|
|
658
|
+
}),
|
|
659
|
+
check: async ({ options, secrets, http }) => {
|
|
660
|
+
const headers = { "x-api-key": secrets.apiKey, "anthropic-version": "2023-06-01" };
|
|
661
|
+
const models = [...new Set(options.track?.models ?? [])];
|
|
662
|
+
if (models.length === 0) return (await http(`${API2}?limit=1`, { headers })).outcome;
|
|
663
|
+
const responses = await Promise.all(
|
|
664
|
+
models.map(async (model) => ({ model, res: await http(`${API2}/${encodeURIComponent(model)}`, { headers }) }))
|
|
665
|
+
);
|
|
666
|
+
const rejected = responses.find(({ res }) => res.status === 401 || res.status === 403);
|
|
667
|
+
if (rejected) return rejected.res.outcome;
|
|
668
|
+
const instances = responses.map(({ model, res }) => {
|
|
669
|
+
const base = { key: model, latencyMs: res.status === void 0 ? void 0 : res.latencyMs, httpStatus: res.status };
|
|
670
|
+
if (res.ok) return { ...base, status: "up" };
|
|
671
|
+
if (res.status === 404) return { ...base, status: "down", error: "Model not found: retired, or not available to this key" };
|
|
672
|
+
if (res.status === 529) return { ...base, status: "degraded", error: "Overloaded" };
|
|
673
|
+
return { ...base, status: res.outcome.status, error: res.outcome.error };
|
|
674
|
+
});
|
|
675
|
+
return { ...summarize(instances, "model"), instances, instanceLabels: { key: "Model" } };
|
|
676
|
+
}
|
|
454
677
|
});
|
|
455
678
|
var gemini = chunkXHXEKB3Q_cjs.definePreset()({
|
|
456
679
|
kind: "gemini",
|
|
@@ -466,6 +689,38 @@ var cambai = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
466
689
|
derive: () => ({ name: "CAMB.AI", identity: "cambai", description: "Lists source languages" }),
|
|
467
690
|
check: ({ secrets, http }) => call(http, "https://client.camb.ai/apis/source-languages", { headers: { "x-api-key": secrets.apiKey } })
|
|
468
691
|
});
|
|
692
|
+
var elevenlabs = chunkXHXEKB3Q_cjs.definePreset()({
|
|
693
|
+
kind: "elevenlabs",
|
|
694
|
+
requiredSecrets: ["apiKey"],
|
|
695
|
+
derive: () => ({ name: "ElevenLabs", identity: "elevenlabs", description: "Reads the subscription" }),
|
|
696
|
+
check: async ({ options, secrets, http }) => {
|
|
697
|
+
const res = await http("https://api.elevenlabs.io/v1/user/subscription", {
|
|
698
|
+
headers: { "xi-api-key": secrets.apiKey }
|
|
699
|
+
});
|
|
700
|
+
const body = res.json ?? {};
|
|
701
|
+
if (res.status === 401 && body.detail?.status === "missing_permissions") {
|
|
702
|
+
return { status: "up", latencyMs: res.latencyMs, httpStatus: 401, metrics: { key: "restricted" } };
|
|
703
|
+
}
|
|
704
|
+
if (!res.ok) return res.outcome;
|
|
705
|
+
const metrics = body.tier ? { tier: body.tier } : void 0;
|
|
706
|
+
const { character_count: used, character_limit: limit } = body;
|
|
707
|
+
if (typeof used !== "number" || !limit) return { ...res.outcome, metrics };
|
|
708
|
+
return {
|
|
709
|
+
...res.outcome,
|
|
710
|
+
...quota({
|
|
711
|
+
label: "Credits",
|
|
712
|
+
used,
|
|
713
|
+
limit,
|
|
714
|
+
unit: "credits",
|
|
715
|
+
// ElevenLabs gives the reset as epoch seconds
|
|
716
|
+
resetsAt: body.next_character_count_reset_unix ? body.next_character_count_reset_unix * 1e3 : void 0,
|
|
717
|
+
warnAbovePct: 100 - (options.track?.quota?.warnBelowPct ?? 10),
|
|
718
|
+
warning: "Credits almost exhausted"
|
|
719
|
+
}),
|
|
720
|
+
metrics
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
});
|
|
469
724
|
|
|
470
725
|
// src/presets/providers/translation.ts
|
|
471
726
|
var deepl = chunkXHXEKB3Q_cjs.definePreset()({
|
|
@@ -697,6 +952,64 @@ var statuspage = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
697
952
|
return { status, error: status === "up" ? void 0 : description };
|
|
698
953
|
})
|
|
699
954
|
});
|
|
955
|
+
var resend = chunkXHXEKB3Q_cjs.definePreset()({
|
|
956
|
+
kind: "resend",
|
|
957
|
+
requiredSecrets: ["apiKey"],
|
|
958
|
+
derive: () => ({ name: "Resend", identity: "resend", description: "Lists domains" }),
|
|
959
|
+
check: async ({ secrets, http }) => {
|
|
960
|
+
const res = await http("https://api.resend.com/domains", { headers: bearer(secrets.apiKey) });
|
|
961
|
+
const body = res.json ?? {};
|
|
962
|
+
if (res.status === 401 && body.name === "restricted_api_key") {
|
|
963
|
+
return { status: "up", latencyMs: res.latencyMs, httpStatus: 401, metrics: { key: "sending only" } };
|
|
964
|
+
}
|
|
965
|
+
if (!res.ok || !Array.isArray(body.data)) return res.outcome;
|
|
966
|
+
const verified = body.data.filter((domain) => domain.status === "verified").length;
|
|
967
|
+
const unverified = body.data.length > 0 && verified === 0;
|
|
968
|
+
return {
|
|
969
|
+
...res.outcome,
|
|
970
|
+
status: unverified ? "degraded" : "up",
|
|
971
|
+
error: unverified ? "No verified domain" : void 0,
|
|
972
|
+
metrics: { domains: body.data.length, verified }
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
});
|
|
976
|
+
var meilisearch = chunkXHXEKB3Q_cjs.definePreset()({
|
|
977
|
+
kind: "meilisearch",
|
|
978
|
+
requiredFields: ["host"],
|
|
979
|
+
requiredSecrets: ["apiKey"],
|
|
980
|
+
derive: (options) => ({
|
|
981
|
+
name: "Meilisearch",
|
|
982
|
+
identity: options.index ? `meilisearch:${options.index}` : "meilisearch",
|
|
983
|
+
description: options.index ? `Reads the health and the ${options.index} index` : "Reads the health and lists indexes"
|
|
984
|
+
}),
|
|
985
|
+
check: async ({ options, secrets, http, combine }) => {
|
|
986
|
+
const host = options.host.replace(/\/+$/, "");
|
|
987
|
+
const headers = bearer(secrets.apiKey);
|
|
988
|
+
const index = options.index ? `/indexes/${encodeURIComponent(options.index)}` : void 0;
|
|
989
|
+
const health = call(
|
|
990
|
+
http,
|
|
991
|
+
`${host}/health`,
|
|
992
|
+
void 0,
|
|
993
|
+
(res2) => res2.json?.status === "available" ? void 0 : { status: "down", error: "Not available" }
|
|
994
|
+
);
|
|
995
|
+
const access = http(`${host}${index ?? "/indexes?limit=1"}`, { headers }).then((res2) => {
|
|
996
|
+
if (res2.status !== 404 || !options.index) return res2.outcome;
|
|
997
|
+
return {
|
|
998
|
+
status: "degraded",
|
|
999
|
+
latencyMs: res2.latencyMs,
|
|
1000
|
+
httpStatus: 404,
|
|
1001
|
+
error: `Index ${options.index} not found`
|
|
1002
|
+
};
|
|
1003
|
+
});
|
|
1004
|
+
const stats = http(`${host}${index ?? ""}/stats`, { headers });
|
|
1005
|
+
const outcome = combine(await Promise.all([health, access]));
|
|
1006
|
+
const res = await stats;
|
|
1007
|
+
if (!res.ok) return outcome;
|
|
1008
|
+
const body = res.json ?? {};
|
|
1009
|
+
const documents = body.numberOfDocuments ?? Object.values(body.indexes ?? {}).reduce((sum, entry) => sum + (entry.numberOfDocuments ?? 0), 0);
|
|
1010
|
+
return { ...outcome, metrics: { ...outcome.metrics, documents, ...body.isIndexing ? { indexing: "yes" } : {} } };
|
|
1011
|
+
}
|
|
1012
|
+
});
|
|
700
1013
|
|
|
701
1014
|
// src/presets/providers/pusher.ts
|
|
702
1015
|
var MAX_CHANNELS = 500;
|
|
@@ -780,12 +1093,12 @@ var pusher = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
780
1093
|
let countingDisabled = false;
|
|
781
1094
|
const counts = await mapLimit(queried, CONCURRENCY, async (name) => {
|
|
782
1095
|
const res = await get(`/channels/${encodeURIComponent(name)}`, { info: "subscription_count" });
|
|
783
|
-
const
|
|
1096
|
+
const count2 = res.json?.subscription_count;
|
|
784
1097
|
if (!res.ok) failed += 1;
|
|
785
|
-
else if (typeof
|
|
786
|
-
return typeof
|
|
1098
|
+
else if (typeof count2 !== "number") countingDisabled = true;
|
|
1099
|
+
return typeof count2 === "number" ? count2 : 0;
|
|
787
1100
|
});
|
|
788
|
-
const connections = counts.reduce((sum,
|
|
1101
|
+
const connections = counts.reduce((sum, count2) => sum + count2, 0);
|
|
789
1102
|
const signedInUsers = queried.reduce(
|
|
790
1103
|
(sum, name, index) => name.startsWith("#server-to-user-") ? sum + (counts[index] ?? 0) : sum,
|
|
791
1104
|
0
|
|
@@ -828,6 +1141,187 @@ var pusher = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
828
1141
|
}
|
|
829
1142
|
});
|
|
830
1143
|
|
|
1144
|
+
// src/presets/providers/vercel.ts
|
|
1145
|
+
var aiGateway = chunkXHXEKB3Q_cjs.definePreset()({
|
|
1146
|
+
kind: "vercel.aiGateway",
|
|
1147
|
+
requiredSecrets: ["apiKey"],
|
|
1148
|
+
derive: (options) => ({
|
|
1149
|
+
name: "Vercel AI Gateway",
|
|
1150
|
+
identity: "vercel.aiGateway",
|
|
1151
|
+
description: options.track?.credits === false ? "Lists models" : "Reads the credit balance"
|
|
1152
|
+
}),
|
|
1153
|
+
check: ({ options, secrets, http }) => {
|
|
1154
|
+
const headers = bearer(secrets.apiKey);
|
|
1155
|
+
if (options.track?.credits === false) return call(http, "https://ai-gateway.vercel.sh/v1/models", { headers });
|
|
1156
|
+
const warnBelow = options.track?.credits?.warnBelow ?? 5;
|
|
1157
|
+
return call(http, "https://ai-gateway.vercel.sh/v1/credits", { headers }, (res) => {
|
|
1158
|
+
const body = res.json ?? {};
|
|
1159
|
+
const balance = Number(body.balance);
|
|
1160
|
+
if (body.balance === void 0 || !Number.isFinite(balance)) return void 0;
|
|
1161
|
+
const used = Number(body.total_used);
|
|
1162
|
+
const low = balance < warnBelow;
|
|
1163
|
+
return {
|
|
1164
|
+
status: low ? "degraded" : "up",
|
|
1165
|
+
error: low ? "Low credit balance" : void 0,
|
|
1166
|
+
metrics: {
|
|
1167
|
+
balance: `${round(balance, 2)} USD`,
|
|
1168
|
+
...body.total_used !== void 0 && Number.isFinite(used) ? { used: `${round(used, 2)} USD` } : {}
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
var blob = chunkXHXEKB3Q_cjs.definePreset()({
|
|
1175
|
+
kind: "vercel.blob",
|
|
1176
|
+
requiredSecrets: ["token"],
|
|
1177
|
+
derive: () => ({ name: "Vercel Blob", identity: "vercel.blob", description: "Lists one blob of the store" }),
|
|
1178
|
+
check: ({ secrets, http }) => call(http, "https://vercel.com/api/blob?limit=1", {
|
|
1179
|
+
headers: { ...bearer(secrets.token), "x-api-version": "12" }
|
|
1180
|
+
})
|
|
1181
|
+
});
|
|
1182
|
+
var vercel = { aiGateway, blob };
|
|
1183
|
+
|
|
1184
|
+
// src/presets/providers/stripe.ts
|
|
1185
|
+
var API3 = "https://api.stripe.com/v1";
|
|
1186
|
+
var DAY_S = 24 * 60 * 60;
|
|
1187
|
+
var ZERO_DECIMAL = /* @__PURE__ */ new Set(["bif", "clp", "djf", "gnf", "jpy", "kmf", "krw", "mga", "pyg", "rwf", "ugx", "vnd", "vuv", "xaf", "xof", "xpf"]);
|
|
1188
|
+
function money(amounts) {
|
|
1189
|
+
return (amounts ?? []).slice(0, 3).map(({ amount, currency }) => {
|
|
1190
|
+
const value = ZERO_DECIMAL.has(currency) ? String(amount) : (amount / 100).toFixed(2);
|
|
1191
|
+
return `${value} ${currency.toUpperCase()}`;
|
|
1192
|
+
}).join(", ");
|
|
1193
|
+
}
|
|
1194
|
+
function endpointKey(url) {
|
|
1195
|
+
try {
|
|
1196
|
+
const { host, pathname } = new URL(url);
|
|
1197
|
+
return `${host}${pathname}`;
|
|
1198
|
+
} catch {
|
|
1199
|
+
return "endpoint";
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
var count = (list) => `${list.data?.length ?? 0}${list.has_more ? "+" : ""}`;
|
|
1203
|
+
var stripe = chunkXHXEKB3Q_cjs.definePreset()({
|
|
1204
|
+
kind: "stripe",
|
|
1205
|
+
requiredSecrets: ["apiKey"],
|
|
1206
|
+
derive: () => ({ name: "Stripe", identity: "stripe", description: "Reads the balance, account and webhook endpoints" }),
|
|
1207
|
+
check: async ({ options, secrets, http, now }) => {
|
|
1208
|
+
const { account = true, webhooks = true, disputes = true } = options.track ?? {};
|
|
1209
|
+
const get = (path) => http(`${API3}${path}`, { headers: bearer(secrets.apiKey) });
|
|
1210
|
+
const skip = Promise.resolve(void 0);
|
|
1211
|
+
const [balance, accountRes, endpoints, undelivered, disputeList] = await Promise.all([
|
|
1212
|
+
get("/balance"),
|
|
1213
|
+
account ? get("/account") : skip,
|
|
1214
|
+
webhooks ? get("/webhook_endpoints?limit=100") : skip,
|
|
1215
|
+
webhooks ? get(`/events?delivery_success=false&limit=100&created[gte]=${Math.floor(now / 1e3) - DAY_S}`) : skip,
|
|
1216
|
+
disputes ? get("/disputes?limit=100") : skip
|
|
1217
|
+
]);
|
|
1218
|
+
if (!balance.ok && balance.status !== 403) return balance.outcome;
|
|
1219
|
+
const metrics = {};
|
|
1220
|
+
const warnings = [];
|
|
1221
|
+
const funds = balance.ok ? balance.json : void 0;
|
|
1222
|
+
if (funds) {
|
|
1223
|
+
metrics.mode = funds.livemode ? "live" : "test";
|
|
1224
|
+
if (funds.available?.length) metrics.available = money(funds.available);
|
|
1225
|
+
if (funds.pending?.length) metrics.pending = money(funds.pending);
|
|
1226
|
+
} else {
|
|
1227
|
+
metrics.key = "restricted";
|
|
1228
|
+
}
|
|
1229
|
+
if (accountRes?.ok && funds?.livemode) {
|
|
1230
|
+
const body = accountRes.json;
|
|
1231
|
+
if (body.charges_enabled === false) warnings.push("Charges are disabled");
|
|
1232
|
+
if (body.payouts_enabled === false) warnings.push("Payouts are disabled");
|
|
1233
|
+
const overdue = body.requirements?.past_due?.length ?? 0;
|
|
1234
|
+
if (overdue > 0) warnings.push(`${overdue} account requirement(s) past due`);
|
|
1235
|
+
}
|
|
1236
|
+
let instances;
|
|
1237
|
+
if (endpoints?.ok) {
|
|
1238
|
+
const list = endpoints.json.data ?? [];
|
|
1239
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1240
|
+
instances = list.map((endpoint) => {
|
|
1241
|
+
let key = endpointKey(endpoint.url);
|
|
1242
|
+
for (let n = 2; seen.has(key); n++) key = `${endpointKey(endpoint.url)}#${n}`;
|
|
1243
|
+
seen.add(key);
|
|
1244
|
+
const enabled = endpoint.status === "enabled";
|
|
1245
|
+
return { key, id: endpoint.id, state: endpoint.status, status: enabled ? "up" : "down", error: enabled ? void 0 : "Endpoint disabled" };
|
|
1246
|
+
});
|
|
1247
|
+
metrics.webhookEndpoints = list.length;
|
|
1248
|
+
const disabled = instances.filter((instance2) => instance2.status === "down").length;
|
|
1249
|
+
if (disabled > 0) warnings.push(`${disabled} webhook endpoint(s) disabled`);
|
|
1250
|
+
}
|
|
1251
|
+
if (undelivered?.ok) {
|
|
1252
|
+
const list = undelivered.json;
|
|
1253
|
+
metrics.undelivered24h = count(list);
|
|
1254
|
+
if (list.data?.length) warnings.push(`${count(list)} event(s) not delivered in the last 24 h`);
|
|
1255
|
+
}
|
|
1256
|
+
if (disputeList?.ok) {
|
|
1257
|
+
const open = (disputeList.json.data ?? []).filter(
|
|
1258
|
+
(dispute) => dispute.status.endsWith("needs_response")
|
|
1259
|
+
);
|
|
1260
|
+
metrics.openDisputes = open.length;
|
|
1261
|
+
}
|
|
1262
|
+
return {
|
|
1263
|
+
status: warnings.length ? "degraded" : "up",
|
|
1264
|
+
latencyMs: balance.latencyMs,
|
|
1265
|
+
httpStatus: balance.status,
|
|
1266
|
+
error: warnings.join("; ") || void 0,
|
|
1267
|
+
metrics,
|
|
1268
|
+
instances: instances?.length ? instances : void 0,
|
|
1269
|
+
instanceLabels: { key: "Webhook endpoint", detail: "ID" }
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1273
|
+
|
|
1274
|
+
// src/presets/providers/search.ts
|
|
1275
|
+
var exa = chunkXHXEKB3Q_cjs.definePreset()({
|
|
1276
|
+
kind: "exa",
|
|
1277
|
+
requiredSecrets: ["apiKey"],
|
|
1278
|
+
derive: () => ({ name: "Exa", identity: "exa", description: "Validates the API key (no search is run)" }),
|
|
1279
|
+
check: async ({ secrets, http }) => keyAccepted(await http("https://api.exa.ai/search", emptyPost({ "x-api-key": secrets.apiKey })))
|
|
1280
|
+
});
|
|
1281
|
+
var nimble = chunkXHXEKB3Q_cjs.definePreset()({
|
|
1282
|
+
kind: "nimble",
|
|
1283
|
+
requiredSecrets: ["apiKey"],
|
|
1284
|
+
derive: () => ({ name: "Nimble", identity: "nimble", description: "Validates the API key (no search is run)" }),
|
|
1285
|
+
check: async ({ secrets, http }) => keyAccepted(await http("https://sdk.nimbleway.com/v1/search", emptyPost(bearer(secrets.apiKey))))
|
|
1286
|
+
});
|
|
1287
|
+
var tavily = chunkXHXEKB3Q_cjs.definePreset()({
|
|
1288
|
+
kind: "tavily",
|
|
1289
|
+
requiredSecrets: ["apiKey"],
|
|
1290
|
+
derive: () => ({ name: "Tavily", identity: "tavily", description: "Reads the credits used this period" }),
|
|
1291
|
+
check: async ({ options, secrets, http }) => {
|
|
1292
|
+
const res = await http("https://api.tavily.com/usage", { headers: bearer(secrets.apiKey) });
|
|
1293
|
+
if (!res.ok) return res.outcome;
|
|
1294
|
+
const { key, account } = res.json ?? {};
|
|
1295
|
+
const metrics = account?.current_plan ? { plan: account.current_plan } : void 0;
|
|
1296
|
+
const [used, limit] = key?.limit ? [key.usage, key.limit] : [account?.plan_usage, account?.plan_limit];
|
|
1297
|
+
if (typeof used !== "number" || !limit) return { ...res.outcome, metrics };
|
|
1298
|
+
return {
|
|
1299
|
+
...res.outcome,
|
|
1300
|
+
...quota({
|
|
1301
|
+
label: "Credits",
|
|
1302
|
+
used,
|
|
1303
|
+
limit,
|
|
1304
|
+
unit: "credits",
|
|
1305
|
+
warnAbovePct: options.track?.quota?.warnAbovePct ?? 90,
|
|
1306
|
+
warning: "Credits almost exhausted"
|
|
1307
|
+
}),
|
|
1308
|
+
metrics
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
var emelia = chunkXHXEKB3Q_cjs.definePreset()({
|
|
1313
|
+
kind: "emelia",
|
|
1314
|
+
requiredSecrets: ["apiKey"],
|
|
1315
|
+
derive: () => ({ name: "Emelia", identity: "emelia", description: "Validates the API key (no lookup is run)" }),
|
|
1316
|
+
check: async ({ options, secrets, http }) => keyAccepted(
|
|
1317
|
+
await http(
|
|
1318
|
+
`${(options.baseUrl ?? "https://api.emelia.io").replace(/\/+$/, "")}/tools/find/email`,
|
|
1319
|
+
// Emelia takes the bare key, without a scheme
|
|
1320
|
+
emptyPost({ Authorization: secrets.apiKey })
|
|
1321
|
+
)
|
|
1322
|
+
)
|
|
1323
|
+
});
|
|
1324
|
+
|
|
831
1325
|
Object.defineProperty(exports, "generic", {
|
|
832
1326
|
enumerable: true,
|
|
833
1327
|
get: function () { return chunkELV4ZU6G_cjs.generic; }
|
|
@@ -843,6 +1337,9 @@ exports.cloudflareStream = cloudflareStream;
|
|
|
843
1337
|
exports.crashReason = crashReason;
|
|
844
1338
|
exports.deepgram = deepgram;
|
|
845
1339
|
exports.deepl = deepl;
|
|
1340
|
+
exports.elevenlabs = elevenlabs;
|
|
1341
|
+
exports.emelia = emelia;
|
|
1342
|
+
exports.exa = exa;
|
|
846
1343
|
exports.fly = fly;
|
|
847
1344
|
exports.gcp = gcp;
|
|
848
1345
|
exports.gemini = gemini;
|
|
@@ -851,17 +1348,25 @@ exports.gladia = gladia;
|
|
|
851
1348
|
exports.googleServiceAccountToken = googleServiceAccountToken;
|
|
852
1349
|
exports.googleTranslate = googleTranslate;
|
|
853
1350
|
exports.mailersend = mailersend;
|
|
1351
|
+
exports.meilisearch = meilisearch;
|
|
854
1352
|
exports.mongodb = mongodb;
|
|
855
1353
|
exports.mux = mux;
|
|
1354
|
+
exports.neon = neon;
|
|
1355
|
+
exports.nimble = nimble;
|
|
856
1356
|
exports.openai = openai;
|
|
857
1357
|
exports.parseServiceAccount = parseServiceAccount;
|
|
1358
|
+
exports.postgres = postgres;
|
|
858
1359
|
exports.pusher = pusher;
|
|
859
1360
|
exports.redis = redis;
|
|
1361
|
+
exports.resend = resend;
|
|
860
1362
|
exports.revolut = revolut;
|
|
861
1363
|
exports.signGoogleAssertion = signGoogleAssertion;
|
|
862
1364
|
exports.signPusherRequest = signPusherRequest;
|
|
863
1365
|
exports.speechmatics = speechmatics;
|
|
864
1366
|
exports.statuspage = statuspage;
|
|
1367
|
+
exports.stripe = stripe;
|
|
1368
|
+
exports.tavily = tavily;
|
|
865
1369
|
exports.upstashRedis = upstashRedis;
|
|
1370
|
+
exports.vercel = vercel;
|
|
866
1371
|
//# sourceMappingURL=index.cjs.map
|
|
867
1372
|
//# sourceMappingURL=index.cjs.map
|