sermon-js 0.2.0 → 0.3.1
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 +3 -2
- package/dist/api/index.cjs +5 -5
- package/dist/api/index.d.cts +4 -4
- package/dist/api/index.d.ts +4 -4
- package/dist/api/index.js +1 -1
- package/dist/{chunk-APC2HVSI.js → chunk-NUSAZZYR.js} +12 -6
- package/dist/chunk-NUSAZZYR.js.map +1 -0
- 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/{chunk-NP3YYVRZ.cjs → chunk-ZAZ6VTGV.cjs} +12 -5
- package/dist/chunk-ZAZ6VTGV.cjs.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 +29 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -10
- package/dist/index.d.ts +19 -10
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- 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-APC2HVSI.js.map +0 -1
- package/dist/chunk-NP3YYVRZ.cjs.map +0 -1
- package/dist/chunk-PARE6EUZ.cjs.map +0 -1
package/dist/presets/index.js
CHANGED
|
@@ -17,9 +17,9 @@ function withKeys(machines) {
|
|
|
17
17
|
const seen = /* @__PURE__ */ new Map();
|
|
18
18
|
return [...machines].sort((a, b) => (a.region ?? "").localeCompare(b.region ?? "") || a.id.localeCompare(b.id)).map((machine) => {
|
|
19
19
|
const region = machine.region ?? "unknown";
|
|
20
|
-
const
|
|
21
|
-
seen.set(region,
|
|
22
|
-
return { machine, region, key:
|
|
20
|
+
const count2 = (seen.get(region) ?? 0) + 1;
|
|
21
|
+
seen.set(region, count2);
|
|
22
|
+
return { machine, region, key: count2 === 1 ? region : `${region}#${count2}` };
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
25
|
function median(values) {
|
|
@@ -221,8 +221,8 @@ var instance = definePreset()({
|
|
|
221
221
|
}),
|
|
222
222
|
check: async ({ options, secrets, http, now }) => {
|
|
223
223
|
const account = parseServiceAccount(secrets.serviceAccount);
|
|
224
|
-
const
|
|
225
|
-
if (!account || !
|
|
224
|
+
const project2 = options.project ?? account?.project_id;
|
|
225
|
+
if (!account || !project2) {
|
|
226
226
|
return { status: "down", probed: false, error: "The service account secret is not a service-account JSON key" };
|
|
227
227
|
}
|
|
228
228
|
let token;
|
|
@@ -237,7 +237,7 @@ var instance = definePreset()({
|
|
|
237
237
|
return { status: "down", probed: false, error: error instanceof Error ? error.message : String(error) };
|
|
238
238
|
}
|
|
239
239
|
const info = await http(
|
|
240
|
-
`https://compute.googleapis.com/compute/v1/projects/${
|
|
240
|
+
`https://compute.googleapis.com/compute/v1/projects/${project2}/zones/${options.zone}/instances/${options.instance}`,
|
|
241
241
|
{ headers: { Authorization: `Bearer ${token}` } }
|
|
242
242
|
);
|
|
243
243
|
const state = info.json?.status;
|
|
@@ -260,6 +260,68 @@ var instance = definePreset()({
|
|
|
260
260
|
}
|
|
261
261
|
});
|
|
262
262
|
var gcp = { instance };
|
|
263
|
+
|
|
264
|
+
// src/presets/providers/shared.ts
|
|
265
|
+
var bearer = (token) => ({ Authorization: `Bearer ${token}` });
|
|
266
|
+
var round = (value, digits = 1) => Math.round(value * 10 ** digits) / 10 ** digits;
|
|
267
|
+
function base64(text) {
|
|
268
|
+
const bytes = new TextEncoder().encode(text);
|
|
269
|
+
let binary = "";
|
|
270
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
271
|
+
return btoa(binary);
|
|
272
|
+
}
|
|
273
|
+
async function call(http, url, init, refine) {
|
|
274
|
+
const response = await http(url, init);
|
|
275
|
+
if (!response.ok || !refine) return response.outcome;
|
|
276
|
+
return { ...response.outcome, ...normalizeReturn(refine(response)) };
|
|
277
|
+
}
|
|
278
|
+
function quota({
|
|
279
|
+
label,
|
|
280
|
+
used,
|
|
281
|
+
limit,
|
|
282
|
+
unit,
|
|
283
|
+
resetsAt,
|
|
284
|
+
warnAbovePct,
|
|
285
|
+
warning
|
|
286
|
+
}) {
|
|
287
|
+
const pct = limit > 0 ? used / limit * 100 : 0;
|
|
288
|
+
const over = pct >= warnAbovePct;
|
|
289
|
+
return {
|
|
290
|
+
status: over ? "degraded" : "up",
|
|
291
|
+
error: over ? warning : void 0,
|
|
292
|
+
usage: [{ label, used, limit, unit, resetsAt }]
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function summarize(instances, noun) {
|
|
296
|
+
const down = instances.filter((instance2) => instance2.status === "down");
|
|
297
|
+
const degraded = instances.filter((instance2) => instance2.status === "degraded");
|
|
298
|
+
const awake = instances.filter((instance2) => instance2.status === "up" || instance2.status === "degraded");
|
|
299
|
+
const keysOf = (items) => items.map((instance2) => instance2.key).join(", ");
|
|
300
|
+
const latencies = instances.map((instance2) => instance2.latencyMs).filter((l) => l !== void 0);
|
|
301
|
+
const latencyMs = latencies.length ? Math.max(...latencies) : void 0;
|
|
302
|
+
if (instances.length > 0 && down.length === instances.length) {
|
|
303
|
+
return { status: "down", latencyMs, error: `All ${instances.length} ${noun}(s) failing` };
|
|
304
|
+
}
|
|
305
|
+
if (down.length > 0) {
|
|
306
|
+
return { status: "degraded", latencyMs, error: `${down.length}/${instances.length} ${noun}(s) failing: ${keysOf(down)}` };
|
|
307
|
+
}
|
|
308
|
+
if (degraded.length > 0) return { status: "degraded", latencyMs, error: `Degraded: ${keysOf(degraded)}` };
|
|
309
|
+
return { status: awake.length || instances.length === 0 ? "up" : "sleeping", latencyMs };
|
|
310
|
+
}
|
|
311
|
+
function keyAccepted(res) {
|
|
312
|
+
if (res.status === 400 || res.status === 422) return { status: "up", latencyMs: res.latencyMs, httpStatus: res.status };
|
|
313
|
+
if (res.status === 402) {
|
|
314
|
+
return { status: "degraded", latencyMs: res.latencyMs, httpStatus: 402, error: "Out of credits, or payment required" };
|
|
315
|
+
}
|
|
316
|
+
return res.outcome;
|
|
317
|
+
}
|
|
318
|
+
var emptyPost = (headers) => ({
|
|
319
|
+
method: "POST",
|
|
320
|
+
headers: { "content-type": "application/json", ...headers },
|
|
321
|
+
body: "{}"
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
// src/presets/aws.ts
|
|
263
325
|
async function signedCall({
|
|
264
326
|
http,
|
|
265
327
|
secrets,
|
|
@@ -319,7 +381,170 @@ var s3Bucket = definePreset()({
|
|
|
319
381
|
return response.outcome;
|
|
320
382
|
}
|
|
321
383
|
});
|
|
322
|
-
|
|
384
|
+
function pingBody(model) {
|
|
385
|
+
if (/(^|\.)cohere\.embed/.test(model)) return { texts: ["ping"], input_type: "search_query" };
|
|
386
|
+
return { anthropic_version: "bedrock-2023-05-31", max_tokens: 1, messages: [{ role: "user", content: "ping" }] };
|
|
387
|
+
}
|
|
388
|
+
var bedrockPreset = definePreset()({
|
|
389
|
+
kind: "aws.bedrock",
|
|
390
|
+
requiredFields: ["region"],
|
|
391
|
+
requiredSecrets: "all",
|
|
392
|
+
defaults: { slowMs: 5e3, timeoutMs: 2e4 },
|
|
393
|
+
derive: () => ({
|
|
394
|
+
name: "Amazon Bedrock",
|
|
395
|
+
identity: "aws.bedrock",
|
|
396
|
+
description: "Invokes each monitored model with one token"
|
|
397
|
+
}),
|
|
398
|
+
check: async ({ options, secrets, http }) => {
|
|
399
|
+
const signer = secrets.accessKeyId && secrets.secretAccessKey ? new AwsClient({
|
|
400
|
+
accessKeyId: secrets.accessKeyId,
|
|
401
|
+
secretAccessKey: secrets.secretAccessKey,
|
|
402
|
+
service: "bedrock",
|
|
403
|
+
region: options.region
|
|
404
|
+
}) : void 0;
|
|
405
|
+
const invoke = async (model) => {
|
|
406
|
+
const url = `https://bedrock-runtime.${options.region}.amazonaws.com/model/${encodeURIComponent(model)}/invoke`;
|
|
407
|
+
const init = {
|
|
408
|
+
method: "POST",
|
|
409
|
+
headers: { "content-type": "application/json", accept: "application/json" },
|
|
410
|
+
body: JSON.stringify(pingBody(model))
|
|
411
|
+
};
|
|
412
|
+
if (!signer) return http(url, { ...init, headers: { ...init.headers, ...bearer(secrets.bearerToken ?? "") } });
|
|
413
|
+
const signed = await signer.sign(url, init);
|
|
414
|
+
return http(signed.url, { ...init, headers: Object.fromEntries(signed.headers.entries()) });
|
|
415
|
+
};
|
|
416
|
+
const instances = await Promise.all(
|
|
417
|
+
[...new Set(options.models)].map(async (model) => {
|
|
418
|
+
const res = await invoke(model);
|
|
419
|
+
return {
|
|
420
|
+
key: model,
|
|
421
|
+
status: res.outcome.status,
|
|
422
|
+
latencyMs: res.status === void 0 ? void 0 : res.latencyMs,
|
|
423
|
+
httpStatus: res.status,
|
|
424
|
+
error: res.outcome.error
|
|
425
|
+
};
|
|
426
|
+
})
|
|
427
|
+
);
|
|
428
|
+
return { ...summarize(instances, "model"), instances, instanceLabels: { key: "Model" } };
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
function bedrock(options) {
|
|
432
|
+
const { bearerToken, accessKeyId, secretAccessKey } = options.secrets;
|
|
433
|
+
return bedrockPreset({ ...options, secrets: bearerToken ? { bearerToken } : { accessKeyId, secretAccessKey } });
|
|
434
|
+
}
|
|
435
|
+
var aws = { credentials, s3Bucket, bedrock };
|
|
436
|
+
|
|
437
|
+
// src/presets/neon.ts
|
|
438
|
+
var API = "https://console.neon.tech/api/v2";
|
|
439
|
+
var GB = 1024 ** 3;
|
|
440
|
+
function withKeys2(endpoints, branches) {
|
|
441
|
+
const seen = /* @__PURE__ */ new Map();
|
|
442
|
+
return endpoints.map((endpoint) => {
|
|
443
|
+
const name = branches.get(endpoint.branch_id)?.name ?? endpoint.branch_id;
|
|
444
|
+
const count2 = (seen.get(name) ?? 0) + 1;
|
|
445
|
+
seen.set(name, count2);
|
|
446
|
+
return { endpoint, key: count2 === 1 ? name : `${name}#${count2}` };
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
var project = definePreset()({
|
|
450
|
+
kind: "neon.project",
|
|
451
|
+
requiredFields: ["projectId"],
|
|
452
|
+
requiredSecrets: ["apiKey"],
|
|
453
|
+
defaults: { slowMs: 1e3 },
|
|
454
|
+
derive: (options) => ({
|
|
455
|
+
name: "Neon",
|
|
456
|
+
identity: `neon.project:${options.projectId ?? ""}`,
|
|
457
|
+
description: "Compute states from the Neon API, then `select 1` on an active compute only"
|
|
458
|
+
}),
|
|
459
|
+
check: async ({ options, secrets, http, measure }) => {
|
|
460
|
+
const base = `${API}/projects/${encodeURIComponent(options.projectId)}`;
|
|
461
|
+
const headers = { ...bearer(secrets.apiKey), accept: "application/json" };
|
|
462
|
+
const [list, info, branchList] = await Promise.all([
|
|
463
|
+
http(`${base}/endpoints`, { headers }),
|
|
464
|
+
http(base, { headers }),
|
|
465
|
+
http(`${base}/branches`, { headers })
|
|
466
|
+
]);
|
|
467
|
+
if (list.status === 404) {
|
|
468
|
+
return { status: "down", probed: false, httpStatus: 404, error: `Project "${options.projectId}" not found on Neon` };
|
|
469
|
+
}
|
|
470
|
+
const endpoints = list.json?.endpoints;
|
|
471
|
+
if (!list.ok || !Array.isArray(endpoints)) {
|
|
472
|
+
return {
|
|
473
|
+
status: "degraded",
|
|
474
|
+
probed: false,
|
|
475
|
+
httpStatus: list.status,
|
|
476
|
+
error: list.status ? `Neon API HTTP ${list.status}` : `Neon API unreachable: ${list.outcome.error ?? "no response"}`
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
if (endpoints.length === 0) return { status: "down", probed: false, error: "No compute: nothing can connect" };
|
|
480
|
+
const branches = branchList.json?.branches ?? [];
|
|
481
|
+
const details = info.json?.project;
|
|
482
|
+
const byId = new Map(branches.map((branch) => [branch.id, branch]));
|
|
483
|
+
const defaultBranch = branches.find((branch) => branch.default)?.id;
|
|
484
|
+
const keyed = withKeys2(endpoints, byId);
|
|
485
|
+
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"));
|
|
486
|
+
const ping = options.query && target?.endpoint.current_state === "active" && !target.endpoint.disabled ? await measure(async () => void await options.query("select 1")) : void 0;
|
|
487
|
+
const instances = keyed.map(({ endpoint, key }) => {
|
|
488
|
+
const row = { key, region: endpoint.region_id, id: endpoint.id };
|
|
489
|
+
if (endpoint.disabled) return { ...row, state: "disabled", status: "sleeping" };
|
|
490
|
+
if (endpoint.current_state === "idle") return { ...row, state: "idle", status: "sleeping" };
|
|
491
|
+
if (endpoint.current_state !== "active") return { ...row, state: endpoint.current_state, status: "degraded" };
|
|
492
|
+
if (ping && endpoint.id === target?.endpoint.id) {
|
|
493
|
+
return { ...row, state: "active", status: ping.status, latencyMs: ping.latencyMs, error: ping.error };
|
|
494
|
+
}
|
|
495
|
+
return { ...row, state: "active", status: "up" };
|
|
496
|
+
});
|
|
497
|
+
const usage = [];
|
|
498
|
+
const warnings = [];
|
|
499
|
+
const bar = (entry, warnAbovePct = 90) => {
|
|
500
|
+
usage.push(entry);
|
|
501
|
+
if (entry.limit > 0 && entry.used / entry.limit * 100 >= warnAbovePct) warnings.push(`${entry.label} close to the plan limit`);
|
|
502
|
+
};
|
|
503
|
+
const compute = options.track?.compute;
|
|
504
|
+
if (compute && typeof details?.compute_time_seconds === "number") {
|
|
505
|
+
bar(
|
|
506
|
+
{
|
|
507
|
+
label: "Compute this period",
|
|
508
|
+
used: round(details.compute_time_seconds / 3600),
|
|
509
|
+
limit: compute.maxHours,
|
|
510
|
+
unit: "CU-hours",
|
|
511
|
+
resetsAt: details.consumption_period_end ? Date.parse(details.consumption_period_end) || void 0 : void 0
|
|
512
|
+
},
|
|
513
|
+
compute.warnAbovePct
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
const storage = options.track?.storage;
|
|
517
|
+
if (storage && branches.length > 0) {
|
|
518
|
+
const bytes = branches.reduce((sum, branch) => sum + (branch.logical_size ?? 0), 0);
|
|
519
|
+
bar({ label: "Storage", used: round(bytes / GB, 2), limit: storage.maxGb, unit: "GB" }, storage.warnAbovePct);
|
|
520
|
+
}
|
|
521
|
+
const main = instances.find((instance2) => instance2.id === target?.endpoint.id) ?? instances[0];
|
|
522
|
+
const active = instances.filter((instance2) => instance2.state === "active").length;
|
|
523
|
+
let status = main.status;
|
|
524
|
+
let error = main.error;
|
|
525
|
+
if (status === "degraded" && !error) error = `Compute is ${main.state}`;
|
|
526
|
+
if ((status === "up" || status === "sleeping") && warnings.length) {
|
|
527
|
+
status = "degraded";
|
|
528
|
+
error = warnings.join("; ");
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
status,
|
|
532
|
+
probed: !!ping,
|
|
533
|
+
latencyMs: ping?.latencyMs ?? list.latencyMs,
|
|
534
|
+
error,
|
|
535
|
+
metrics: {
|
|
536
|
+
...details?.pg_version ? { postgres: details.pg_version } : {},
|
|
537
|
+
...details?.region_id ? { region: details.region_id } : {},
|
|
538
|
+
...branches.length ? { branches: branches.length } : {},
|
|
539
|
+
computes: `${active}/${instances.length} active`
|
|
540
|
+
},
|
|
541
|
+
usage: usage.length ? usage : void 0,
|
|
542
|
+
instances,
|
|
543
|
+
instanceLabels: { key: "Compute", detail: "Endpoint" }
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
var neon = { project };
|
|
323
548
|
|
|
324
549
|
// src/presets/databases.ts
|
|
325
550
|
var mongoPing = definePreset()({
|
|
@@ -357,38 +582,6 @@ var postgresPing = definePreset()({
|
|
|
357
582
|
});
|
|
358
583
|
var postgres = { ping: postgresPing };
|
|
359
584
|
|
|
360
|
-
// src/presets/providers/shared.ts
|
|
361
|
-
var bearer = (token) => ({ Authorization: `Bearer ${token}` });
|
|
362
|
-
var round = (value, digits = 1) => Math.round(value * 10 ** digits) / 10 ** digits;
|
|
363
|
-
function base64(text) {
|
|
364
|
-
const bytes = new TextEncoder().encode(text);
|
|
365
|
-
let binary = "";
|
|
366
|
-
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
367
|
-
return btoa(binary);
|
|
368
|
-
}
|
|
369
|
-
async function call(http, url, init, refine) {
|
|
370
|
-
const response = await http(url, init);
|
|
371
|
-
if (!response.ok || !refine) return response.outcome;
|
|
372
|
-
return { ...response.outcome, ...normalizeReturn(refine(response)) };
|
|
373
|
-
}
|
|
374
|
-
function quota({
|
|
375
|
-
label,
|
|
376
|
-
used,
|
|
377
|
-
limit,
|
|
378
|
-
unit,
|
|
379
|
-
resetsAt,
|
|
380
|
-
warnAbovePct,
|
|
381
|
-
warning
|
|
382
|
-
}) {
|
|
383
|
-
const pct = limit > 0 ? used / limit * 100 : 0;
|
|
384
|
-
const over = pct >= warnAbovePct;
|
|
385
|
-
return {
|
|
386
|
-
status: over ? "degraded" : "up",
|
|
387
|
-
error: over ? warning : void 0,
|
|
388
|
-
usage: [{ label, used, limit, unit, resetsAt }]
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
|
|
392
585
|
// src/presets/providers/ai.ts
|
|
393
586
|
var deepgram = definePreset()({
|
|
394
587
|
kind: "deepgram",
|
|
@@ -452,13 +645,33 @@ var openai = definePreset()({
|
|
|
452
645
|
}
|
|
453
646
|
)
|
|
454
647
|
});
|
|
648
|
+
var API2 = "https://api.anthropic.com/v1/models";
|
|
455
649
|
var anthropic = definePreset()({
|
|
456
650
|
kind: "anthropic",
|
|
457
651
|
requiredSecrets: ["apiKey"],
|
|
458
|
-
derive: () => ({
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
652
|
+
derive: (options) => ({
|
|
653
|
+
name: "Anthropic",
|
|
654
|
+
identity: "anthropic",
|
|
655
|
+
description: options.track?.models?.length ? "Reads each monitored model" : "Lists models"
|
|
656
|
+
}),
|
|
657
|
+
check: async ({ options, secrets, http }) => {
|
|
658
|
+
const headers = { "x-api-key": secrets.apiKey, "anthropic-version": "2023-06-01" };
|
|
659
|
+
const models = [...new Set(options.track?.models ?? [])];
|
|
660
|
+
if (models.length === 0) return (await http(`${API2}?limit=1`, { headers })).outcome;
|
|
661
|
+
const responses = await Promise.all(
|
|
662
|
+
models.map(async (model) => ({ model, res: await http(`${API2}/${encodeURIComponent(model)}`, { headers }) }))
|
|
663
|
+
);
|
|
664
|
+
const rejected = responses.find(({ res }) => res.status === 401 || res.status === 403);
|
|
665
|
+
if (rejected) return rejected.res.outcome;
|
|
666
|
+
const instances = responses.map(({ model, res }) => {
|
|
667
|
+
const base = { key: model, latencyMs: res.status === void 0 ? void 0 : res.latencyMs, httpStatus: res.status };
|
|
668
|
+
if (res.ok) return { ...base, status: "up" };
|
|
669
|
+
if (res.status === 404) return { ...base, status: "down", error: "Model not found: retired, or not available to this key" };
|
|
670
|
+
if (res.status === 529) return { ...base, status: "degraded", error: "Overloaded" };
|
|
671
|
+
return { ...base, status: res.outcome.status, error: res.outcome.error };
|
|
672
|
+
});
|
|
673
|
+
return { ...summarize(instances, "model"), instances, instanceLabels: { key: "Model" } };
|
|
674
|
+
}
|
|
462
675
|
});
|
|
463
676
|
var gemini = definePreset()({
|
|
464
677
|
kind: "gemini",
|
|
@@ -878,12 +1091,12 @@ var pusher = definePreset()({
|
|
|
878
1091
|
let countingDisabled = false;
|
|
879
1092
|
const counts = await mapLimit(queried, CONCURRENCY, async (name) => {
|
|
880
1093
|
const res = await get(`/channels/${encodeURIComponent(name)}`, { info: "subscription_count" });
|
|
881
|
-
const
|
|
1094
|
+
const count2 = res.json?.subscription_count;
|
|
882
1095
|
if (!res.ok) failed += 1;
|
|
883
|
-
else if (typeof
|
|
884
|
-
return typeof
|
|
1096
|
+
else if (typeof count2 !== "number") countingDisabled = true;
|
|
1097
|
+
return typeof count2 === "number" ? count2 : 0;
|
|
885
1098
|
});
|
|
886
|
-
const connections = counts.reduce((sum,
|
|
1099
|
+
const connections = counts.reduce((sum, count2) => sum + count2, 0);
|
|
887
1100
|
const signedInUsers = queried.reduce(
|
|
888
1101
|
(sum, name, index) => name.startsWith("#server-to-user-") ? sum + (counts[index] ?? 0) : sum,
|
|
889
1102
|
0
|
|
@@ -966,6 +1179,147 @@ var blob = definePreset()({
|
|
|
966
1179
|
});
|
|
967
1180
|
var vercel = { aiGateway, blob };
|
|
968
1181
|
|
|
969
|
-
|
|
1182
|
+
// src/presets/providers/stripe.ts
|
|
1183
|
+
var API3 = "https://api.stripe.com/v1";
|
|
1184
|
+
var DAY_S = 24 * 60 * 60;
|
|
1185
|
+
var ZERO_DECIMAL = /* @__PURE__ */ new Set(["bif", "clp", "djf", "gnf", "jpy", "kmf", "krw", "mga", "pyg", "rwf", "ugx", "vnd", "vuv", "xaf", "xof", "xpf"]);
|
|
1186
|
+
function money(amounts) {
|
|
1187
|
+
return (amounts ?? []).slice(0, 3).map(({ amount, currency }) => {
|
|
1188
|
+
const value = ZERO_DECIMAL.has(currency) ? String(amount) : (amount / 100).toFixed(2);
|
|
1189
|
+
return `${value} ${currency.toUpperCase()}`;
|
|
1190
|
+
}).join(", ");
|
|
1191
|
+
}
|
|
1192
|
+
function endpointKey(url) {
|
|
1193
|
+
try {
|
|
1194
|
+
const { host, pathname } = new URL(url);
|
|
1195
|
+
return `${host}${pathname}`;
|
|
1196
|
+
} catch {
|
|
1197
|
+
return "endpoint";
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
var count = (list) => `${list.data?.length ?? 0}${list.has_more ? "+" : ""}`;
|
|
1201
|
+
var stripe = definePreset()({
|
|
1202
|
+
kind: "stripe",
|
|
1203
|
+
requiredSecrets: ["apiKey"],
|
|
1204
|
+
derive: () => ({ name: "Stripe", identity: "stripe", description: "Reads the balance, account and webhook endpoints" }),
|
|
1205
|
+
check: async ({ options, secrets, http, now }) => {
|
|
1206
|
+
const { account = true, webhooks = true, disputes = true } = options.track ?? {};
|
|
1207
|
+
const get = (path) => http(`${API3}${path}`, { headers: bearer(secrets.apiKey) });
|
|
1208
|
+
const skip = Promise.resolve(void 0);
|
|
1209
|
+
const [balance, accountRes, endpoints, undelivered, disputeList] = await Promise.all([
|
|
1210
|
+
get("/balance"),
|
|
1211
|
+
account ? get("/account") : skip,
|
|
1212
|
+
webhooks ? get("/webhook_endpoints?limit=100") : skip,
|
|
1213
|
+
webhooks ? get(`/events?delivery_success=false&limit=100&created[gte]=${Math.floor(now / 1e3) - DAY_S}`) : skip,
|
|
1214
|
+
disputes ? get("/disputes?limit=100") : skip
|
|
1215
|
+
]);
|
|
1216
|
+
if (!balance.ok && balance.status !== 403) return balance.outcome;
|
|
1217
|
+
const metrics = {};
|
|
1218
|
+
const warnings = [];
|
|
1219
|
+
const funds = balance.ok ? balance.json : void 0;
|
|
1220
|
+
if (funds) {
|
|
1221
|
+
metrics.mode = funds.livemode ? "live" : "test";
|
|
1222
|
+
if (funds.available?.length) metrics.available = money(funds.available);
|
|
1223
|
+
if (funds.pending?.length) metrics.pending = money(funds.pending);
|
|
1224
|
+
} else {
|
|
1225
|
+
metrics.key = "restricted";
|
|
1226
|
+
}
|
|
1227
|
+
if (accountRes?.ok && funds?.livemode) {
|
|
1228
|
+
const body = accountRes.json;
|
|
1229
|
+
if (body.charges_enabled === false) warnings.push("Charges are disabled");
|
|
1230
|
+
if (body.payouts_enabled === false) warnings.push("Payouts are disabled");
|
|
1231
|
+
const overdue = body.requirements?.past_due?.length ?? 0;
|
|
1232
|
+
if (overdue > 0) warnings.push(`${overdue} account requirement(s) past due`);
|
|
1233
|
+
}
|
|
1234
|
+
let instances;
|
|
1235
|
+
if (endpoints?.ok) {
|
|
1236
|
+
const list = endpoints.json.data ?? [];
|
|
1237
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1238
|
+
instances = list.map((endpoint) => {
|
|
1239
|
+
let key = endpointKey(endpoint.url);
|
|
1240
|
+
for (let n = 2; seen.has(key); n++) key = `${endpointKey(endpoint.url)}#${n}`;
|
|
1241
|
+
seen.add(key);
|
|
1242
|
+
const enabled = endpoint.status === "enabled";
|
|
1243
|
+
return { key, id: endpoint.id, state: endpoint.status, status: enabled ? "up" : "down", error: enabled ? void 0 : "Endpoint disabled" };
|
|
1244
|
+
});
|
|
1245
|
+
metrics.webhookEndpoints = list.length;
|
|
1246
|
+
const disabled = instances.filter((instance2) => instance2.status === "down").length;
|
|
1247
|
+
if (disabled > 0) warnings.push(`${disabled} webhook endpoint(s) disabled`);
|
|
1248
|
+
}
|
|
1249
|
+
if (undelivered?.ok) {
|
|
1250
|
+
const list = undelivered.json;
|
|
1251
|
+
metrics.undelivered24h = count(list);
|
|
1252
|
+
if (list.data?.length) warnings.push(`${count(list)} event(s) not delivered in the last 24 h`);
|
|
1253
|
+
}
|
|
1254
|
+
if (disputeList?.ok) {
|
|
1255
|
+
const open = (disputeList.json.data ?? []).filter(
|
|
1256
|
+
(dispute) => dispute.status.endsWith("needs_response")
|
|
1257
|
+
);
|
|
1258
|
+
metrics.openDisputes = open.length;
|
|
1259
|
+
}
|
|
1260
|
+
return {
|
|
1261
|
+
status: warnings.length ? "degraded" : "up",
|
|
1262
|
+
latencyMs: balance.latencyMs,
|
|
1263
|
+
httpStatus: balance.status,
|
|
1264
|
+
error: warnings.join("; ") || void 0,
|
|
1265
|
+
metrics,
|
|
1266
|
+
instances: instances?.length ? instances : void 0,
|
|
1267
|
+
instanceLabels: { key: "Webhook endpoint", detail: "ID" }
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
});
|
|
1271
|
+
|
|
1272
|
+
// src/presets/providers/search.ts
|
|
1273
|
+
var exa = definePreset()({
|
|
1274
|
+
kind: "exa",
|
|
1275
|
+
requiredSecrets: ["apiKey"],
|
|
1276
|
+
derive: () => ({ name: "Exa", identity: "exa", description: "Validates the API key (no search is run)" }),
|
|
1277
|
+
check: async ({ secrets, http }) => keyAccepted(await http("https://api.exa.ai/search", emptyPost({ "x-api-key": secrets.apiKey })))
|
|
1278
|
+
});
|
|
1279
|
+
var nimble = definePreset()({
|
|
1280
|
+
kind: "nimble",
|
|
1281
|
+
requiredSecrets: ["apiKey"],
|
|
1282
|
+
derive: () => ({ name: "Nimble", identity: "nimble", description: "Validates the API key (no search is run)" }),
|
|
1283
|
+
check: async ({ secrets, http }) => keyAccepted(await http("https://sdk.nimbleway.com/v1/search", emptyPost(bearer(secrets.apiKey))))
|
|
1284
|
+
});
|
|
1285
|
+
var tavily = definePreset()({
|
|
1286
|
+
kind: "tavily",
|
|
1287
|
+
requiredSecrets: ["apiKey"],
|
|
1288
|
+
derive: () => ({ name: "Tavily", identity: "tavily", description: "Reads the credits used this period" }),
|
|
1289
|
+
check: async ({ options, secrets, http }) => {
|
|
1290
|
+
const res = await http("https://api.tavily.com/usage", { headers: bearer(secrets.apiKey) });
|
|
1291
|
+
if (!res.ok) return res.outcome;
|
|
1292
|
+
const { key, account } = res.json ?? {};
|
|
1293
|
+
const metrics = account?.current_plan ? { plan: account.current_plan } : void 0;
|
|
1294
|
+
const [used, limit] = key?.limit ? [key.usage, key.limit] : [account?.plan_usage, account?.plan_limit];
|
|
1295
|
+
if (typeof used !== "number" || !limit) return { ...res.outcome, metrics };
|
|
1296
|
+
return {
|
|
1297
|
+
...res.outcome,
|
|
1298
|
+
...quota({
|
|
1299
|
+
label: "Credits",
|
|
1300
|
+
used,
|
|
1301
|
+
limit,
|
|
1302
|
+
unit: "credits",
|
|
1303
|
+
warnAbovePct: options.track?.quota?.warnAbovePct ?? 90,
|
|
1304
|
+
warning: "Credits almost exhausted"
|
|
1305
|
+
}),
|
|
1306
|
+
metrics
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
});
|
|
1310
|
+
var emelia = definePreset()({
|
|
1311
|
+
kind: "emelia",
|
|
1312
|
+
requiredSecrets: ["apiKey"],
|
|
1313
|
+
derive: () => ({ name: "Emelia", identity: "emelia", description: "Validates the API key (no lookup is run)" }),
|
|
1314
|
+
check: async ({ options, secrets, http }) => keyAccepted(
|
|
1315
|
+
await http(
|
|
1316
|
+
`${(options.baseUrl ?? "https://api.emelia.io").replace(/\/+$/, "")}/tools/find/email`,
|
|
1317
|
+
// Emelia takes the bare key, without a scheme
|
|
1318
|
+
emptyPost({ Authorization: secrets.apiKey })
|
|
1319
|
+
)
|
|
1320
|
+
)
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1323
|
+
export { anthropic, attendee, aws, axiom, azureTranslator, cambai, clearGoogleTokens, cloudflareStream, crashReason, deepgram, deepl, elevenlabs, emelia, exa, fly, gcp, gemini, github, gladia, googleServiceAccountToken, googleTranslate, mailersend, meilisearch, mongodb, mux, neon, nimble, openai, parseServiceAccount, postgres, pusher, redis, resend, revolut, signGoogleAssertion, signPusherRequest, speechmatics, statuspage, stripe, tavily, upstashRedis, vercel };
|
|
970
1324
|
//# sourceMappingURL=index.js.map
|
|
971
1325
|
//# sourceMappingURL=index.js.map
|