sermon-js 0.2.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 +407 -47
- package/dist/presets/index.cjs.map +1 -1
- package/dist/presets/index.d.cts +173 -14
- package/dist/presets/index.d.ts +173 -14
- package/dist/presets/index.js +402 -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()({
|
|
@@ -359,38 +584,6 @@ var postgresPing = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
359
584
|
});
|
|
360
585
|
var postgres = { ping: postgresPing };
|
|
361
586
|
|
|
362
|
-
// src/presets/providers/shared.ts
|
|
363
|
-
var bearer = (token) => ({ Authorization: `Bearer ${token}` });
|
|
364
|
-
var round = (value, digits = 1) => Math.round(value * 10 ** digits) / 10 ** digits;
|
|
365
|
-
function base64(text) {
|
|
366
|
-
const bytes = new TextEncoder().encode(text);
|
|
367
|
-
let binary = "";
|
|
368
|
-
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
369
|
-
return btoa(binary);
|
|
370
|
-
}
|
|
371
|
-
async function call(http, url, init, refine) {
|
|
372
|
-
const response = await http(url, init);
|
|
373
|
-
if (!response.ok || !refine) return response.outcome;
|
|
374
|
-
return { ...response.outcome, ...chunkXHXEKB3Q_cjs.normalizeReturn(refine(response)) };
|
|
375
|
-
}
|
|
376
|
-
function quota({
|
|
377
|
-
label,
|
|
378
|
-
used,
|
|
379
|
-
limit,
|
|
380
|
-
unit,
|
|
381
|
-
resetsAt,
|
|
382
|
-
warnAbovePct,
|
|
383
|
-
warning
|
|
384
|
-
}) {
|
|
385
|
-
const pct = limit > 0 ? used / limit * 100 : 0;
|
|
386
|
-
const over = pct >= warnAbovePct;
|
|
387
|
-
return {
|
|
388
|
-
status: over ? "degraded" : "up",
|
|
389
|
-
error: over ? warning : void 0,
|
|
390
|
-
usage: [{ label, used, limit, unit, resetsAt }]
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
|
|
394
587
|
// src/presets/providers/ai.ts
|
|
395
588
|
var deepgram = chunkXHXEKB3Q_cjs.definePreset()({
|
|
396
589
|
kind: "deepgram",
|
|
@@ -454,13 +647,33 @@ var openai = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
454
647
|
}
|
|
455
648
|
)
|
|
456
649
|
});
|
|
650
|
+
var API2 = "https://api.anthropic.com/v1/models";
|
|
457
651
|
var anthropic = chunkXHXEKB3Q_cjs.definePreset()({
|
|
458
652
|
kind: "anthropic",
|
|
459
653
|
requiredSecrets: ["apiKey"],
|
|
460
|
-
derive: () => ({
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
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
|
+
}
|
|
464
677
|
});
|
|
465
678
|
var gemini = chunkXHXEKB3Q_cjs.definePreset()({
|
|
466
679
|
kind: "gemini",
|
|
@@ -880,12 +1093,12 @@ var pusher = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
880
1093
|
let countingDisabled = false;
|
|
881
1094
|
const counts = await mapLimit(queried, CONCURRENCY, async (name) => {
|
|
882
1095
|
const res = await get(`/channels/${encodeURIComponent(name)}`, { info: "subscription_count" });
|
|
883
|
-
const
|
|
1096
|
+
const count2 = res.json?.subscription_count;
|
|
884
1097
|
if (!res.ok) failed += 1;
|
|
885
|
-
else if (typeof
|
|
886
|
-
return typeof
|
|
1098
|
+
else if (typeof count2 !== "number") countingDisabled = true;
|
|
1099
|
+
return typeof count2 === "number" ? count2 : 0;
|
|
887
1100
|
});
|
|
888
|
-
const connections = counts.reduce((sum,
|
|
1101
|
+
const connections = counts.reduce((sum, count2) => sum + count2, 0);
|
|
889
1102
|
const signedInUsers = queried.reduce(
|
|
890
1103
|
(sum, name, index) => name.startsWith("#server-to-user-") ? sum + (counts[index] ?? 0) : sum,
|
|
891
1104
|
0
|
|
@@ -968,6 +1181,147 @@ var blob = chunkXHXEKB3Q_cjs.definePreset()({
|
|
|
968
1181
|
});
|
|
969
1182
|
var vercel = { aiGateway, blob };
|
|
970
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
|
+
|
|
971
1325
|
Object.defineProperty(exports, "generic", {
|
|
972
1326
|
enumerable: true,
|
|
973
1327
|
get: function () { return chunkELV4ZU6G_cjs.generic; }
|
|
@@ -984,6 +1338,8 @@ exports.crashReason = crashReason;
|
|
|
984
1338
|
exports.deepgram = deepgram;
|
|
985
1339
|
exports.deepl = deepl;
|
|
986
1340
|
exports.elevenlabs = elevenlabs;
|
|
1341
|
+
exports.emelia = emelia;
|
|
1342
|
+
exports.exa = exa;
|
|
987
1343
|
exports.fly = fly;
|
|
988
1344
|
exports.gcp = gcp;
|
|
989
1345
|
exports.gemini = gemini;
|
|
@@ -995,6 +1351,8 @@ exports.mailersend = mailersend;
|
|
|
995
1351
|
exports.meilisearch = meilisearch;
|
|
996
1352
|
exports.mongodb = mongodb;
|
|
997
1353
|
exports.mux = mux;
|
|
1354
|
+
exports.neon = neon;
|
|
1355
|
+
exports.nimble = nimble;
|
|
998
1356
|
exports.openai = openai;
|
|
999
1357
|
exports.parseServiceAccount = parseServiceAccount;
|
|
1000
1358
|
exports.postgres = postgres;
|
|
@@ -1006,6 +1364,8 @@ exports.signGoogleAssertion = signGoogleAssertion;
|
|
|
1006
1364
|
exports.signPusherRequest = signPusherRequest;
|
|
1007
1365
|
exports.speechmatics = speechmatics;
|
|
1008
1366
|
exports.statuspage = statuspage;
|
|
1367
|
+
exports.stripe = stripe;
|
|
1368
|
+
exports.tavily = tavily;
|
|
1009
1369
|
exports.upstashRedis = upstashRedis;
|
|
1010
1370
|
exports.vercel = vercel;
|
|
1011
1371
|
//# sourceMappingURL=index.cjs.map
|