@absolutejs/billing 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +28 -9
- package/dist/index.js.map +3 -3
- package/dist/manifest.d.ts +7 -0
- package/dist/manifest.js +9108 -0
- package/dist/manifest.js.map +125 -0
- package/dist/manifest.json +125 -0
- package/package.json +16 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
2
17
|
// src/balances.ts
|
|
3
18
|
var FETCH_TIMEOUT_MS = 6000;
|
|
19
|
+
var COST_FETCH_TIMEOUT_MS = 20000;
|
|
4
20
|
var MS_PER_SECOND = 1000;
|
|
5
21
|
var MS_PER_DAY = 86400000;
|
|
6
22
|
var MILLION = 1e6;
|
|
@@ -51,17 +67,20 @@ var errored = (provider, label, message) => {
|
|
|
51
67
|
};
|
|
52
68
|
return result;
|
|
53
69
|
};
|
|
54
|
-
var fetchJson = async (url, headers,
|
|
70
|
+
var fetchJson = async (url, headers, opts = {}) => {
|
|
55
71
|
const controller = new AbortController;
|
|
56
|
-
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
72
|
+
const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? FETCH_TIMEOUT_MS);
|
|
57
73
|
try {
|
|
58
74
|
const response = await fetch(url, {
|
|
59
75
|
headers,
|
|
60
|
-
method,
|
|
76
|
+
method: opts.method ?? "GET",
|
|
61
77
|
signal: controller.signal
|
|
62
78
|
});
|
|
63
|
-
if (!response.ok)
|
|
64
|
-
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
const body = await response.text().catch(() => "");
|
|
81
|
+
const snippet = body.replace(/\s+/g, " ").trim().slice(0, 160);
|
|
82
|
+
throw new Error(snippet ? `HTTP ${response.status}: ${snippet}` : `HTTP ${response.status}`);
|
|
83
|
+
}
|
|
65
84
|
const json = await response.json();
|
|
66
85
|
return json;
|
|
67
86
|
} finally {
|
|
@@ -210,7 +229,7 @@ var apolloBalance = async (creds) => {
|
|
|
210
229
|
if (!creds.apiKey)
|
|
211
230
|
return unconfigured("apollo", "Apollo", "API key unset");
|
|
212
231
|
try {
|
|
213
|
-
const data = await fetchJson("https://api.apollo.io/api/v1/usage_stats/api_usage_stats", { "Content-Type": "application/json", "X-Api-Key": creds.apiKey }, "POST");
|
|
232
|
+
const data = await fetchJson("https://api.apollo.io/api/v1/usage_stats/api_usage_stats", { "Content-Type": "application/json", "X-Api-Key": creds.apiKey }, { method: "POST" });
|
|
214
233
|
const { consumed, limit } = pickBusiestDayQuota(data);
|
|
215
234
|
return apolloResult(consumed, limit);
|
|
216
235
|
} catch (error) {
|
|
@@ -265,7 +284,7 @@ var openaiBalance = async (creds) => {
|
|
|
265
284
|
}
|
|
266
285
|
try {
|
|
267
286
|
const startTime = Math.floor(costWindowStart() / MS_PER_SECOND);
|
|
268
|
-
const data = await fetchJson(`https://api.openai.com/v1/organization/costs?start_time=${startTime}&limit=${COST_WINDOW_DAYS + 1}`, { Authorization: `Bearer ${creds.adminKey}` });
|
|
287
|
+
const data = await fetchJson(`https://api.openai.com/v1/organization/costs?start_time=${startTime}&limit=${COST_WINDOW_DAYS + 1}`, { Authorization: `Bearer ${creds.adminKey}` }, { timeoutMs: COST_FETCH_TIMEOUT_MS });
|
|
269
288
|
const result = {
|
|
270
289
|
...base("openai", "OpenAI"),
|
|
271
290
|
detail: `${usd(sumOpenAiCosts(data))} spent (30d)`,
|
|
@@ -298,7 +317,7 @@ var anthropicBalance = async (creds) => {
|
|
|
298
317
|
}
|
|
299
318
|
try {
|
|
300
319
|
const startedAt = new Date(costWindowStart()).toISOString();
|
|
301
|
-
const data = await fetchJson(`https://api.anthropic.com/v1/organizations/cost_report?starting_at=${startedAt}`, { "anthropic-version": "2023-06-01", "x-api-key": creds.adminKey });
|
|
320
|
+
const data = await fetchJson(`https://api.anthropic.com/v1/organizations/cost_report?starting_at=${startedAt}`, { "anthropic-version": "2023-06-01", "x-api-key": creds.adminKey }, { timeoutMs: COST_FETCH_TIMEOUT_MS });
|
|
302
321
|
const result = {
|
|
303
322
|
...base("anthropic", "Anthropic"),
|
|
304
323
|
detail: `${usd(sumAnthropicCosts(data))} spent (30d)`,
|
|
@@ -488,5 +507,5 @@ export {
|
|
|
488
507
|
computeInvoice
|
|
489
508
|
};
|
|
490
509
|
|
|
491
|
-
//# debugId=
|
|
510
|
+
//# debugId=C0D9028B844C873764756E2164756E21
|
|
492
511
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/balances.ts", "../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Provider balances — read each upstream vendor's OWN reported balance / quota /\n * spend from their billing-or-usage API, normalized to one shape. The inverse of\n * `computeInvoice`: that prices YOUR usage into an invoice; this reads what the\n * vendors you pay say you have left (or have spent). Useful for an ops dashboard\n * that reconciles your own metering against vendor truth.\n *\n * These are free reporting endpoints — they run no model and incur no per-call\n * charge (just rate limits). Pure + dependency-free: pass credentials in, get\n * snapshots out. One provider failing never affects the others.\n *\n * Coverage by what each vendor exposes:\n * - balance ($ left): Twilio, Deepgram\n * - quota (units left): ElevenLabs (chars), Apollo (calls/day), Brave (queries)\n * - cost ($ spent): Anthropic, OpenAI — no balance API exists, only spend\n *\n * Brave has no API at all; the host app captures rate-limit headers off its own\n * search calls and passes the latest snapshot in (`config.brave`).\n */\n\nconst FETCH_TIMEOUT_MS = 6000;\nconst MS_PER_SECOND = 1000;\nconst MS_PER_DAY = 86_400_000;\nconst MILLION = 1_000_000;\nconst THOUSAND = 1000;\nconst COST_WINDOW_DAYS = 30;\n\nexport type ProviderBalanceKind = \"balance\" | \"quota\" | \"cost\" | \"none\";\nexport type ProviderBalanceStatus = \"ok\" | \"unconfigured\" | \"error\";\n\nexport type ProviderBalance = {\n /** Human summary line, e.g. \"$42.10 left\" or \"1.2M / 2M chars\". */\n detail: string;\n checkedAt: string;\n kind: ProviderBalanceKind;\n label: string;\n /** The vendor's spend/limit when known; null when not exposed. */\n limit: number | null;\n /** Caveat for the tile (e.g. \"no balance API — Admin key needed\"). */\n note: string | null;\n provider: string;\n /** Remaining balance/quota for kind balance|quota; null otherwise. */\n remaining: number | null;\n resetDate: string | null;\n status: ProviderBalanceStatus;\n /** Vendor plan/tier where exposed (ElevenLabs \"pro\", Twilio \"Full\"); else null. */\n tier: string | null;\n unit: string;\n used: number | null;\n};\n\n/** Rate-limit snapshot the host app captures off its own Brave search responses\n * (Brave has no usage API). The 30-day-window header is `monthly*`. */\nexport type BraveUsageSnapshot = {\n capturedAt: string;\n monthlyLimit: number | null;\n monthlyRemaining: number | null;\n resetSeconds: number | null;\n};\n\n/**\n * Per-provider credentials. Include a provider's key to get its tile; omit it to\n * skip the provider entirely. A present-but-empty credential yields an\n * \"unconfigured\" tile (so a dashboard can show every provider it cares about and\n * label the ones missing a key).\n */\nexport type ProviderBalanceConfig = {\n anthropic?: { adminKey: string };\n apollo?: { apiKey: string };\n brave?: BraveUsageSnapshot | null;\n deepgram?: { apiKey: string };\n elevenlabs?: { apiKey: string };\n openai?: { adminKey: string };\n twilio?: { accountSid: string; authToken: string };\n};\n\nconst nowIso = () => new Date().toISOString();\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst numberOf = (value: unknown) =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n\nconst usd = (amount: number) => `$${amount.toFixed(2)}`;\n\nconst compact = (value: number) => {\n if (value >= MILLION) return `${(value / MILLION).toFixed(1)}M`;\n if (value >= THOUSAND) return `${(value / THOUSAND).toFixed(0)}K`;\n\n return String(value);\n};\n\nconst base = (provider: string, label: string) => {\n const result: ProviderBalance = {\n checkedAt: nowIso(),\n detail: \"\",\n kind: \"none\",\n label,\n limit: null,\n note: null,\n provider,\n remaining: null,\n resetDate: null,\n status: \"error\",\n tier: null,\n unit: \"\",\n used: null,\n };\n\n return result;\n};\n\nconst unconfigured = (provider: string, label: string, note: string) => {\n const result: ProviderBalance = {\n ...base(provider, label),\n note,\n status: \"unconfigured\",\n };\n\n return result;\n};\n\nconst errored = (provider: string, label: string, message: string) => {\n const result: ProviderBalance = {\n ...base(provider, label),\n detail: \"Couldn't reach provider\",\n note: message,\n };\n\n return result;\n};\n\nconst fetchJson = async (\n url: string,\n headers: Record<string, string>,\n method = \"GET\",\n) => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n try {\n const response = await fetch(url, {\n headers,\n method,\n signal: controller.signal,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n const json: unknown = await response.json();\n\n return json;\n } finally {\n clearTimeout(timer);\n }\n};\n\n// --- Twilio: real account balance + plan type -----------------------------\nconst twilioBalance = async (creds: {\n accountSid: string;\n authToken: string;\n}) => {\n if (!creds.accountSid || !creds.authToken) {\n return unconfigured(\"twilio\", \"Twilio\", \"Twilio credentials unset\");\n }\n try {\n const auth = Buffer.from(`${creds.accountSid}:${creds.authToken}`).toString(\n \"base64\",\n );\n const headers: Record<string, string> = { Authorization: `Basic ${auth}` };\n const [data, account] = await Promise.all([\n fetchJson(\n `https://api.twilio.com/2010-04-01/Accounts/${creds.accountSid}/Balance.json`,\n headers,\n ),\n fetchJson(\n `https://api.twilio.com/2010-04-01/Accounts/${creds.accountSid}.json`,\n headers,\n ),\n ]);\n const balance = isRecord(data) ? numberOf(Number(data.balance)) : null;\n const currency =\n isRecord(data) && typeof data.currency === \"string\"\n ? data.currency\n : \"USD\";\n const accountType =\n isRecord(account) && typeof account.type === \"string\"\n ? account.type\n : null;\n if (balance === null) throw new Error(\"no balance field\");\n const result: ProviderBalance = {\n ...base(\"twilio\", \"Twilio\"),\n detail: `${currency} ${balance.toFixed(2)} left`,\n kind: \"balance\",\n remaining: balance,\n status: \"ok\",\n tier: accountType,\n unit: currency,\n };\n\n return result;\n } catch (error) {\n return errored(\"twilio\", \"Twilio\", String(error));\n }\n};\n\n// --- Deepgram: real $ balance summed across projects ----------------------\nconst extractProjectIds = (projects: unknown) => {\n const list =\n isRecord(projects) && Array.isArray(projects.projects)\n ? projects.projects\n : [];\n\n return list\n .map((proj) =>\n isRecord(proj) && typeof proj.project_id === \"string\"\n ? proj.project_id\n : null,\n )\n .filter((id): id is string => id !== null);\n};\n\nconst sumBalances = (balances: unknown) => {\n const rows =\n isRecord(balances) && Array.isArray(balances.balances)\n ? balances.balances\n : [];\n\n return rows.reduce<number>(\n (total, row) => total + (isRecord(row) ? (numberOf(row.amount) ?? 0) : 0),\n 0,\n );\n};\n\nconst fetchDeepgramTotal = async (headers: Record<string, string>) => {\n const projects = await fetchJson(\n \"https://api.deepgram.com/v1/projects\",\n headers,\n );\n let total = 0;\n for (const projectId of extractProjectIds(projects)) {\n // eslint-disable-next-line no-await-in-loop -- a couple of projects at most\n const balances = await fetchJson(\n `https://api.deepgram.com/v1/projects/${projectId}/balances`,\n headers,\n );\n total += sumBalances(balances);\n }\n\n return total;\n};\n\nconst deepgramBalance = async (creds: { apiKey: string }) => {\n if (!creds.apiKey)\n return unconfigured(\"deepgram\", \"Deepgram\", \"API key unset\");\n try {\n const total = await fetchDeepgramTotal({\n Authorization: `Token ${creds.apiKey}`,\n });\n const result: ProviderBalance = {\n ...base(\"deepgram\", \"Deepgram\"),\n detail: `${usd(total)} left`,\n kind: \"balance\",\n remaining: total,\n status: \"ok\",\n unit: \"USD\",\n };\n\n return result;\n } catch (error) {\n return errored(\"deepgram\", \"Deepgram\", String(error));\n }\n};\n\n// --- ElevenLabs: real character quota used / limit + tier -----------------\nconst elevenLabsBalance = async (creds: { apiKey: string }) => {\n if (!creds.apiKey)\n return unconfigured(\"elevenlabs\", \"ElevenLabs\", \"API key unset\");\n try {\n const data = await fetchJson(\n \"https://api.elevenlabs.io/v1/user/subscription\",\n {\n \"xi-api-key\": creds.apiKey,\n },\n );\n const usedChars = isRecord(data) ? numberOf(data.character_count) : null;\n const limitChars = isRecord(data) ? numberOf(data.character_limit) : null;\n if (usedChars === null || limitChars === null) {\n throw new Error(\"no character fields\");\n }\n const resetUnix = isRecord(data)\n ? numberOf(data.next_character_count_reset_unix)\n : null;\n const tier =\n isRecord(data) && typeof data.tier === \"string\" ? data.tier : null;\n const remaining = Math.max(0, limitChars - usedChars);\n const result: ProviderBalance = {\n ...base(\"elevenlabs\", \"ElevenLabs\"),\n detail: `${compact(remaining)} / ${compact(limitChars)} chars left`,\n kind: \"quota\",\n limit: limitChars,\n remaining,\n resetDate: resetUnix\n ? new Date(resetUnix * MS_PER_SECOND).toISOString()\n : null,\n status: \"ok\",\n tier,\n unit: \"characters\",\n used: usedChars,\n };\n\n return result;\n } catch (error) {\n return errored(\"elevenlabs\", \"ElevenLabs\", String(error));\n }\n};\n\n// --- Apollo: real per-endpoint API quota (master key required) ------------\nconst pickBusiestDayQuota = (data: unknown) => {\n let consumed = 0;\n let limit = 0;\n if (!isRecord(data)) return { consumed, limit };\n for (const value of Object.values(data)) {\n const day = isRecord(value) && isRecord(value.day) ? value.day : null;\n if (!day) continue;\n const dayLimit = numberOf(day.limit) ?? 0;\n if (dayLimit <= limit) continue;\n limit = dayLimit;\n consumed = numberOf(day.consumed) ?? 0;\n }\n\n return { consumed, limit };\n};\n\nconst apolloResult = (consumed: number, limit: number) => {\n if (limit === 0) {\n const noQuota: ProviderBalance = {\n ...base(\"apollo\", \"Apollo\"),\n detail: \"Reached Apollo (no day quota in response)\",\n note: \"If usage stats 403, the key must be an Apollo master key.\",\n status: \"ok\",\n };\n\n return noQuota;\n }\n const result: ProviderBalance = {\n ...base(\"apollo\", \"Apollo\"),\n detail: `${Math.max(0, limit - consumed)} / ${limit} calls left today`,\n kind: \"quota\",\n limit,\n remaining: Math.max(0, limit - consumed),\n status: \"ok\",\n unit: \"calls\",\n used: consumed,\n };\n\n return result;\n};\n\nconst apolloBalance = async (creds: { apiKey: string }) => {\n if (!creds.apiKey) return unconfigured(\"apollo\", \"Apollo\", \"API key unset\");\n try {\n // POST (not GET) per Apollo's API; needs the master key.\n const data = await fetchJson(\n \"https://api.apollo.io/api/v1/usage_stats/api_usage_stats\",\n { \"Content-Type\": \"application/json\", \"X-Api-Key\": creds.apiKey },\n \"POST\",\n );\n const { consumed, limit } = pickBusiestDayQuota(data);\n\n return apolloResult(consumed, limit);\n } catch (error) {\n return errored(\n \"apollo\",\n \"Apollo\",\n `${error} — usage stats need the Apollo master key`,\n );\n }\n};\n\n// --- Brave: no API; read the snapshot the host captured off its own calls --\nconst braveBalance = (snap: BraveUsageSnapshot | null | undefined) => {\n if (!snap) {\n return unconfigured(\n \"brave\",\n \"Brave Search\",\n \"No usage captured yet — appears after the next web search.\",\n );\n }\n if (snap.monthlyLimit && snap.monthlyLimit > 0) {\n const remaining = snap.monthlyRemaining ?? 0;\n const quota: ProviderBalance = {\n ...base(\"brave\", \"Brave Search\"),\n checkedAt: snap.capturedAt,\n detail: `${remaining} / ${snap.monthlyLimit} queries left this month`,\n kind: \"quota\",\n limit: snap.monthlyLimit,\n remaining,\n status: \"ok\",\n unit: \"queries\",\n used: snap.monthlyLimit - remaining,\n };\n\n return quota;\n }\n const metered: ProviderBalance = {\n ...base(\"brave\", \"Brave Search\"),\n checkedAt: snap.capturedAt,\n detail: \"Metered · pay-as-you-go\",\n note: \"No prepaid cap — billed per query; the host's spend cap is the ceiling.\",\n status: \"ok\",\n tier: \"metered\",\n };\n\n return metered;\n};\n\nconst costWindowStart = () => Date.now() - COST_WINDOW_DAYS * MS_PER_DAY;\n\n// --- OpenAI: real spend (no balance API). Needs an sk-admin- Admin key. ----\nconst sumOpenAiCosts = (data: unknown) => {\n const buckets = isRecord(data) && Array.isArray(data.data) ? data.data : [];\n\n return buckets.reduce<number>((total, bucket) => {\n const results =\n isRecord(bucket) && Array.isArray(bucket.results) ? bucket.results : [];\n const bucketSum = results.reduce<number>((sub, row) => {\n const amount = isRecord(row) && isRecord(row.amount) ? row.amount : null;\n const value = amount ? Number(amount.value) : NaN;\n\n return sub + (Number.isFinite(value) ? value : 0);\n }, 0);\n\n return total + bucketSum;\n }, 0);\n};\n\nconst openaiBalance = async (creds: { adminKey: string }) => {\n if (!creds.adminKey) {\n return unconfigured(\n \"openai\",\n \"OpenAI\",\n \"No balance API. Provide an sk-admin- Admin key to show real spend.\",\n );\n }\n try {\n const startTime = Math.floor(costWindowStart() / MS_PER_SECOND);\n const data = await fetchJson(\n `https://api.openai.com/v1/organization/costs?start_time=${startTime}&limit=${COST_WINDOW_DAYS + 1}`,\n { Authorization: `Bearer ${creds.adminKey}` },\n );\n const result: ProviderBalance = {\n ...base(\"openai\", \"OpenAI\"),\n detail: `${usd(sumOpenAiCosts(data))} spent (30d)`,\n kind: \"cost\",\n note: \"No balance API — real provider-reported spend, not balance.\",\n status: \"ok\",\n };\n\n return result;\n } catch (error) {\n return errored(\"openai\", \"OpenAI\", String(error));\n }\n};\n\n// --- Anthropic: real spend (no balance API). Needs an sk-ant-admin key. ----\nconst sumAnthropicCosts = (data: unknown) => {\n const buckets = isRecord(data) && Array.isArray(data.data) ? data.data : [];\n\n return buckets.reduce<number>((total, bucket) => {\n const results =\n isRecord(bucket) && Array.isArray(bucket.results) ? bucket.results : [];\n const bucketSum = results.reduce<number>((sub, row) => {\n if (!isRecord(row)) return sub;\n const raw = row.amount ?? row.cost ?? row.value;\n const value = Number(isRecord(raw) ? (raw.value ?? raw.amount) : raw);\n\n return sub + (Number.isFinite(value) ? value : 0);\n }, 0);\n\n return total + bucketSum;\n }, 0);\n};\n\nconst anthropicBalance = async (creds: { adminKey: string }) => {\n if (!creds.adminKey) {\n return unconfigured(\n \"anthropic\",\n \"Anthropic\",\n \"No balance API. Provide an sk-ant-admin Admin key to show real spend.\",\n );\n }\n try {\n const startedAt = new Date(costWindowStart()).toISOString();\n const data = await fetchJson(\n `https://api.anthropic.com/v1/organizations/cost_report?starting_at=${startedAt}`,\n { \"anthropic-version\": \"2023-06-01\", \"x-api-key\": creds.adminKey },\n );\n const result: ProviderBalance = {\n ...base(\"anthropic\", \"Anthropic\"),\n detail: `${usd(sumAnthropicCosts(data))} spent (30d)`,\n kind: \"cost\",\n note: \"No balance API — real provider-reported spend, not balance.\",\n status: \"ok\",\n };\n\n return result;\n } catch (error) {\n return errored(\n \"anthropic\",\n \"Anthropic\",\n `${error} — needs an sk-ant-admin Admin key (a regular API key won't work).`,\n );\n }\n};\n\n/**\n * Read every configured provider's real balance/quota/spend in parallel. Only\n * providers present in `config` produce a tile. Each runs independently — one\n * failing returns an \"error\" tile, never rejects the whole call. Stateless: the\n * caller owns any caching (these are free reporting calls, ~1/min is plenty).\n */\nexport const readProviderBalances = async (\n config: ProviderBalanceConfig,\n): Promise<ProviderBalance[]> => {\n const jobs: Array<Promise<ProviderBalance>> = [];\n if (config.twilio) jobs.push(twilioBalance(config.twilio));\n if (config.deepgram) jobs.push(deepgramBalance(config.deepgram));\n if (config.elevenlabs) jobs.push(elevenLabsBalance(config.elevenlabs));\n if (config.apollo) jobs.push(apolloBalance(config.apollo));\n if (\"brave\" in config) jobs.push(Promise.resolve(braveBalance(config.brave)));\n if (config.anthropic) jobs.push(anthropicBalance(config.anthropic));\n if (config.openai) jobs.push(openaiBalance(config.openai));\n\n return Promise.all(jobs);\n};\n",
|
|
5
|
+
"/**\n * Provider balances — read each upstream vendor's OWN reported balance / quota /\n * spend from their billing-or-usage API, normalized to one shape. The inverse of\n * `computeInvoice`: that prices YOUR usage into an invoice; this reads what the\n * vendors you pay say you have left (or have spent). Useful for an ops dashboard\n * that reconciles your own metering against vendor truth.\n *\n * These are free reporting endpoints — they run no model and incur no per-call\n * charge (just rate limits). Pure + dependency-free: pass credentials in, get\n * snapshots out. One provider failing never affects the others.\n *\n * Coverage by what each vendor exposes:\n * - balance ($ left): Twilio, Deepgram\n * - quota (units left): ElevenLabs (chars), Apollo (calls/day), Brave (queries)\n * - cost ($ spent): Anthropic, OpenAI — no balance API exists, only spend\n *\n * Brave has no API at all; the host app captures rate-limit headers off its own\n * search calls and passes the latest snapshot in (`config.brave`).\n */\n\nconst FETCH_TIMEOUT_MS = 6000;\n// The LLM providers' org cost-report endpoints are slow (OpenAI's regularly\n// takes ~6s); give them a generous timeout since the result is cached.\nconst COST_FETCH_TIMEOUT_MS = 20_000;\nconst MS_PER_SECOND = 1000;\nconst MS_PER_DAY = 86_400_000;\nconst MILLION = 1_000_000;\nconst THOUSAND = 1000;\nconst COST_WINDOW_DAYS = 30;\n\nexport type ProviderBalanceKind = \"balance\" | \"quota\" | \"cost\" | \"none\";\nexport type ProviderBalanceStatus = \"ok\" | \"unconfigured\" | \"error\";\n\nexport type ProviderBalance = {\n /** Human summary line, e.g. \"$42.10 left\" or \"1.2M / 2M chars\". */\n detail: string;\n checkedAt: string;\n kind: ProviderBalanceKind;\n label: string;\n /** The vendor's spend/limit when known; null when not exposed. */\n limit: number | null;\n /** Caveat for the tile (e.g. \"no balance API — Admin key needed\"). */\n note: string | null;\n provider: string;\n /** Remaining balance/quota for kind balance|quota; null otherwise. */\n remaining: number | null;\n resetDate: string | null;\n status: ProviderBalanceStatus;\n /** Vendor plan/tier where exposed (ElevenLabs \"pro\", Twilio \"Full\"); else null. */\n tier: string | null;\n unit: string;\n used: number | null;\n};\n\n/** Rate-limit snapshot the host app captures off its own Brave search responses\n * (Brave has no usage API). The 30-day-window header is `monthly*`. */\nexport type BraveUsageSnapshot = {\n capturedAt: string;\n monthlyLimit: number | null;\n monthlyRemaining: number | null;\n resetSeconds: number | null;\n};\n\n/**\n * Per-provider credentials. Include a provider's key to get its tile; omit it to\n * skip the provider entirely. A present-but-empty credential yields an\n * \"unconfigured\" tile (so a dashboard can show every provider it cares about and\n * label the ones missing a key).\n */\nexport type ProviderBalanceConfig = {\n anthropic?: { adminKey: string };\n apollo?: { apiKey: string };\n brave?: BraveUsageSnapshot | null;\n deepgram?: { apiKey: string };\n elevenlabs?: { apiKey: string };\n openai?: { adminKey: string };\n twilio?: { accountSid: string; authToken: string };\n};\n\nconst nowIso = () => new Date().toISOString();\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst numberOf = (value: unknown) =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n\nconst usd = (amount: number) => `$${amount.toFixed(2)}`;\n\nconst compact = (value: number) => {\n if (value >= MILLION) return `${(value / MILLION).toFixed(1)}M`;\n if (value >= THOUSAND) return `${(value / THOUSAND).toFixed(0)}K`;\n\n return String(value);\n};\n\nconst base = (provider: string, label: string) => {\n const result: ProviderBalance = {\n checkedAt: nowIso(),\n detail: \"\",\n kind: \"none\",\n label,\n limit: null,\n note: null,\n provider,\n remaining: null,\n resetDate: null,\n status: \"error\",\n tier: null,\n unit: \"\",\n used: null,\n };\n\n return result;\n};\n\nconst unconfigured = (provider: string, label: string, note: string) => {\n const result: ProviderBalance = {\n ...base(provider, label),\n note,\n status: \"unconfigured\",\n };\n\n return result;\n};\n\nconst errored = (provider: string, label: string, message: string) => {\n const result: ProviderBalance = {\n ...base(provider, label),\n detail: \"Couldn't reach provider\",\n note: message,\n };\n\n return result;\n};\n\nconst fetchJson = async (\n url: string,\n headers: Record<string, string>,\n opts: { method?: string; timeoutMs?: number } = {},\n) => {\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n opts.timeoutMs ?? FETCH_TIMEOUT_MS,\n );\n try {\n const response = await fetch(url, {\n headers,\n method: opts.method ?? \"GET\",\n signal: controller.signal,\n });\n if (!response.ok) {\n // Surface the vendor's own error text (truncated) so the tile is\n // actionable — e.g. Deepgram's \"needs the billing:read scope\".\n const body = await response.text().catch(() => \"\");\n const snippet = body.replace(/\\s+/g, \" \").trim().slice(0, 160);\n throw new Error(\n snippet\n ? `HTTP ${response.status}: ${snippet}`\n : `HTTP ${response.status}`,\n );\n }\n const json: unknown = await response.json();\n\n return json;\n } finally {\n clearTimeout(timer);\n }\n};\n\n// --- Twilio: real account balance + plan type -----------------------------\nconst twilioBalance = async (creds: {\n accountSid: string;\n authToken: string;\n}) => {\n if (!creds.accountSid || !creds.authToken) {\n return unconfigured(\"twilio\", \"Twilio\", \"Twilio credentials unset\");\n }\n try {\n const auth = Buffer.from(`${creds.accountSid}:${creds.authToken}`).toString(\n \"base64\",\n );\n const headers: Record<string, string> = { Authorization: `Basic ${auth}` };\n const [data, account] = await Promise.all([\n fetchJson(\n `https://api.twilio.com/2010-04-01/Accounts/${creds.accountSid}/Balance.json`,\n headers,\n ),\n fetchJson(\n `https://api.twilio.com/2010-04-01/Accounts/${creds.accountSid}.json`,\n headers,\n ),\n ]);\n const balance = isRecord(data) ? numberOf(Number(data.balance)) : null;\n const currency =\n isRecord(data) && typeof data.currency === \"string\"\n ? data.currency\n : \"USD\";\n const accountType =\n isRecord(account) && typeof account.type === \"string\"\n ? account.type\n : null;\n if (balance === null) throw new Error(\"no balance field\");\n const result: ProviderBalance = {\n ...base(\"twilio\", \"Twilio\"),\n detail: `${currency} ${balance.toFixed(2)} left`,\n kind: \"balance\",\n remaining: balance,\n status: \"ok\",\n tier: accountType,\n unit: currency,\n };\n\n return result;\n } catch (error) {\n return errored(\"twilio\", \"Twilio\", String(error));\n }\n};\n\n// --- Deepgram: real $ balance summed across projects ----------------------\nconst extractProjectIds = (projects: unknown) => {\n const list =\n isRecord(projects) && Array.isArray(projects.projects)\n ? projects.projects\n : [];\n\n return list\n .map((proj) =>\n isRecord(proj) && typeof proj.project_id === \"string\"\n ? proj.project_id\n : null,\n )\n .filter((id): id is string => id !== null);\n};\n\nconst sumBalances = (balances: unknown) => {\n const rows =\n isRecord(balances) && Array.isArray(balances.balances)\n ? balances.balances\n : [];\n\n return rows.reduce<number>(\n (total, row) => total + (isRecord(row) ? (numberOf(row.amount) ?? 0) : 0),\n 0,\n );\n};\n\nconst fetchDeepgramTotal = async (headers: Record<string, string>) => {\n const projects = await fetchJson(\n \"https://api.deepgram.com/v1/projects\",\n headers,\n );\n let total = 0;\n for (const projectId of extractProjectIds(projects)) {\n // eslint-disable-next-line no-await-in-loop -- a couple of projects at most\n const balances = await fetchJson(\n `https://api.deepgram.com/v1/projects/${projectId}/balances`,\n headers,\n );\n total += sumBalances(balances);\n }\n\n return total;\n};\n\nconst deepgramBalance = async (creds: { apiKey: string }) => {\n if (!creds.apiKey)\n return unconfigured(\"deepgram\", \"Deepgram\", \"API key unset\");\n try {\n const total = await fetchDeepgramTotal({\n Authorization: `Token ${creds.apiKey}`,\n });\n const result: ProviderBalance = {\n ...base(\"deepgram\", \"Deepgram\"),\n detail: `${usd(total)} left`,\n kind: \"balance\",\n remaining: total,\n status: \"ok\",\n unit: \"USD\",\n };\n\n return result;\n } catch (error) {\n return errored(\"deepgram\", \"Deepgram\", String(error));\n }\n};\n\n// --- ElevenLabs: real character quota used / limit + tier -----------------\nconst elevenLabsBalance = async (creds: { apiKey: string }) => {\n if (!creds.apiKey)\n return unconfigured(\"elevenlabs\", \"ElevenLabs\", \"API key unset\");\n try {\n const data = await fetchJson(\n \"https://api.elevenlabs.io/v1/user/subscription\",\n {\n \"xi-api-key\": creds.apiKey,\n },\n );\n const usedChars = isRecord(data) ? numberOf(data.character_count) : null;\n const limitChars = isRecord(data) ? numberOf(data.character_limit) : null;\n if (usedChars === null || limitChars === null) {\n throw new Error(\"no character fields\");\n }\n const resetUnix = isRecord(data)\n ? numberOf(data.next_character_count_reset_unix)\n : null;\n const tier =\n isRecord(data) && typeof data.tier === \"string\" ? data.tier : null;\n const remaining = Math.max(0, limitChars - usedChars);\n const result: ProviderBalance = {\n ...base(\"elevenlabs\", \"ElevenLabs\"),\n detail: `${compact(remaining)} / ${compact(limitChars)} chars left`,\n kind: \"quota\",\n limit: limitChars,\n remaining,\n resetDate: resetUnix\n ? new Date(resetUnix * MS_PER_SECOND).toISOString()\n : null,\n status: \"ok\",\n tier,\n unit: \"characters\",\n used: usedChars,\n };\n\n return result;\n } catch (error) {\n return errored(\"elevenlabs\", \"ElevenLabs\", String(error));\n }\n};\n\n// --- Apollo: real per-endpoint API quota (master key required) ------------\nconst pickBusiestDayQuota = (data: unknown) => {\n let consumed = 0;\n let limit = 0;\n if (!isRecord(data)) return { consumed, limit };\n for (const value of Object.values(data)) {\n const day = isRecord(value) && isRecord(value.day) ? value.day : null;\n if (!day) continue;\n const dayLimit = numberOf(day.limit) ?? 0;\n if (dayLimit <= limit) continue;\n limit = dayLimit;\n consumed = numberOf(day.consumed) ?? 0;\n }\n\n return { consumed, limit };\n};\n\nconst apolloResult = (consumed: number, limit: number) => {\n if (limit === 0) {\n const noQuota: ProviderBalance = {\n ...base(\"apollo\", \"Apollo\"),\n detail: \"Reached Apollo (no day quota in response)\",\n note: \"If usage stats 403, the key must be an Apollo master key.\",\n status: \"ok\",\n };\n\n return noQuota;\n }\n const result: ProviderBalance = {\n ...base(\"apollo\", \"Apollo\"),\n detail: `${Math.max(0, limit - consumed)} / ${limit} calls left today`,\n kind: \"quota\",\n limit,\n remaining: Math.max(0, limit - consumed),\n status: \"ok\",\n unit: \"calls\",\n used: consumed,\n };\n\n return result;\n};\n\nconst apolloBalance = async (creds: { apiKey: string }) => {\n if (!creds.apiKey) return unconfigured(\"apollo\", \"Apollo\", \"API key unset\");\n try {\n // POST (not GET) per Apollo's API; needs the master key.\n const data = await fetchJson(\n \"https://api.apollo.io/api/v1/usage_stats/api_usage_stats\",\n { \"Content-Type\": \"application/json\", \"X-Api-Key\": creds.apiKey },\n { method: \"POST\" },\n );\n const { consumed, limit } = pickBusiestDayQuota(data);\n\n return apolloResult(consumed, limit);\n } catch (error) {\n return errored(\n \"apollo\",\n \"Apollo\",\n `${error} — usage stats need the Apollo master key`,\n );\n }\n};\n\n// --- Brave: no API; read the snapshot the host captured off its own calls --\nconst braveBalance = (snap: BraveUsageSnapshot | null | undefined) => {\n if (!snap) {\n return unconfigured(\n \"brave\",\n \"Brave Search\",\n \"No usage captured yet — appears after the next web search.\",\n );\n }\n if (snap.monthlyLimit && snap.monthlyLimit > 0) {\n const remaining = snap.monthlyRemaining ?? 0;\n const quota: ProviderBalance = {\n ...base(\"brave\", \"Brave Search\"),\n checkedAt: snap.capturedAt,\n detail: `${remaining} / ${snap.monthlyLimit} queries left this month`,\n kind: \"quota\",\n limit: snap.monthlyLimit,\n remaining,\n status: \"ok\",\n unit: \"queries\",\n used: snap.monthlyLimit - remaining,\n };\n\n return quota;\n }\n const metered: ProviderBalance = {\n ...base(\"brave\", \"Brave Search\"),\n checkedAt: snap.capturedAt,\n detail: \"Metered · pay-as-you-go\",\n note: \"No prepaid cap — billed per query; the host's spend cap is the ceiling.\",\n status: \"ok\",\n tier: \"metered\",\n };\n\n return metered;\n};\n\nconst costWindowStart = () => Date.now() - COST_WINDOW_DAYS * MS_PER_DAY;\n\n// --- OpenAI: real spend (no balance API). Needs an sk-admin- Admin key. ----\nconst sumOpenAiCosts = (data: unknown) => {\n const buckets = isRecord(data) && Array.isArray(data.data) ? data.data : [];\n\n return buckets.reduce<number>((total, bucket) => {\n const results =\n isRecord(bucket) && Array.isArray(bucket.results) ? bucket.results : [];\n const bucketSum = results.reduce<number>((sub, row) => {\n const amount = isRecord(row) && isRecord(row.amount) ? row.amount : null;\n const value = amount ? Number(amount.value) : NaN;\n\n return sub + (Number.isFinite(value) ? value : 0);\n }, 0);\n\n return total + bucketSum;\n }, 0);\n};\n\nconst openaiBalance = async (creds: { adminKey: string }) => {\n if (!creds.adminKey) {\n return unconfigured(\n \"openai\",\n \"OpenAI\",\n \"No balance API. Provide an sk-admin- Admin key to show real spend.\",\n );\n }\n try {\n const startTime = Math.floor(costWindowStart() / MS_PER_SECOND);\n const data = await fetchJson(\n `https://api.openai.com/v1/organization/costs?start_time=${startTime}&limit=${COST_WINDOW_DAYS + 1}`,\n { Authorization: `Bearer ${creds.adminKey}` },\n { timeoutMs: COST_FETCH_TIMEOUT_MS },\n );\n const result: ProviderBalance = {\n ...base(\"openai\", \"OpenAI\"),\n detail: `${usd(sumOpenAiCosts(data))} spent (30d)`,\n kind: \"cost\",\n note: \"No balance API — real provider-reported spend, not balance.\",\n status: \"ok\",\n };\n\n return result;\n } catch (error) {\n return errored(\"openai\", \"OpenAI\", String(error));\n }\n};\n\n// --- Anthropic: real spend (no balance API). Needs an sk-ant-admin key. ----\nconst sumAnthropicCosts = (data: unknown) => {\n const buckets = isRecord(data) && Array.isArray(data.data) ? data.data : [];\n\n return buckets.reduce<number>((total, bucket) => {\n const results =\n isRecord(bucket) && Array.isArray(bucket.results) ? bucket.results : [];\n const bucketSum = results.reduce<number>((sub, row) => {\n if (!isRecord(row)) return sub;\n const raw = row.amount ?? row.cost ?? row.value;\n const value = Number(isRecord(raw) ? (raw.value ?? raw.amount) : raw);\n\n return sub + (Number.isFinite(value) ? value : 0);\n }, 0);\n\n return total + bucketSum;\n }, 0);\n};\n\nconst anthropicBalance = async (creds: { adminKey: string }) => {\n if (!creds.adminKey) {\n return unconfigured(\n \"anthropic\",\n \"Anthropic\",\n \"No balance API. Provide an sk-ant-admin Admin key to show real spend.\",\n );\n }\n try {\n const startedAt = new Date(costWindowStart()).toISOString();\n const data = await fetchJson(\n `https://api.anthropic.com/v1/organizations/cost_report?starting_at=${startedAt}`,\n { \"anthropic-version\": \"2023-06-01\", \"x-api-key\": creds.adminKey },\n { timeoutMs: COST_FETCH_TIMEOUT_MS },\n );\n const result: ProviderBalance = {\n ...base(\"anthropic\", \"Anthropic\"),\n detail: `${usd(sumAnthropicCosts(data))} spent (30d)`,\n kind: \"cost\",\n note: \"No balance API — real provider-reported spend, not balance.\",\n status: \"ok\",\n };\n\n return result;\n } catch (error) {\n return errored(\n \"anthropic\",\n \"Anthropic\",\n `${error} — needs an sk-ant-admin Admin key (a regular API key won't work).`,\n );\n }\n};\n\n/**\n * Read every configured provider's real balance/quota/spend in parallel. Only\n * providers present in `config` produce a tile. Each runs independently — one\n * failing returns an \"error\" tile, never rejects the whole call. Stateless: the\n * caller owns any caching (these are free reporting calls, ~1/min is plenty).\n */\nexport const readProviderBalances = async (\n config: ProviderBalanceConfig,\n): Promise<ProviderBalance[]> => {\n const jobs: Array<Promise<ProviderBalance>> = [];\n if (config.twilio) jobs.push(twilioBalance(config.twilio));\n if (config.deepgram) jobs.push(deepgramBalance(config.deepgram));\n if (config.elevenlabs) jobs.push(elevenLabsBalance(config.elevenlabs));\n if (config.apollo) jobs.push(apolloBalance(config.apollo));\n if (\"brave\" in config) jobs.push(Promise.resolve(braveBalance(config.brave)));\n if (config.anthropic) jobs.push(anthropicBalance(config.anthropic));\n if (config.openai) jobs.push(openaiBalance(config.openai));\n\n return Promise.all(jobs);\n};\n",
|
|
6
6
|
"/**\n * @absolutejs/billing — cost-model substrate for the AbsoluteJS PaaS.\n *\n * Two pieces:\n *\n * - `createPlan(...)` — declarative pricing config: optional flat\n * base fee + per-dimension unit prices, with optional graduated\n * tiers and free-tier allowances per dimension.\n *\n * - `computeInvoice({ plan, period, tenant, usage, currency? })`\n * — pure function that turns a `@absolutejs/metering`-shaped\n * `Usage` snapshot (or any record of metered numbers) into an\n * `Invoice` of line items + total. All money math is done in\n * integer **micros** (1 micro = 1/1,000,000 of a currency unit\n * — the same denomination Stripe uses internally) so float\n * drift is structurally impossible.\n *\n * Invoice sinks (push to Stripe, post to QuickBooks, mail a PDF)\n * live OUTSIDE this package, in `@absolutejs/billing-adapters/*`.\n * Keeping the substrate pure means the control plane can preview\n * invoices, run dry-run \"would-charge\" projections, and replay an\n * old usage snapshot through a new plan without touching any\n * vendor SDK.\n */\n\n// =============================================================================\n// Money primitives\n// =============================================================================\n\n/** Integer micros — 1,000,000 micros = 1 unit of the currency. */\nexport type Micros = number;\n\n/**\n * Round a fractional micros value to an integer. The substrate uses\n * **truncation** (banker's-style would surprise callers expecting\n * \"$0.0009 → $0.00\" not \"$0.0009 → $0.001\"). Plans override per-plan.\n */\nexport type Rounding = \"truncate\" | \"round-half-up\";\n\nconst roundMicros = (value: number, rounding: Rounding): Micros => {\n if (rounding === \"truncate\") return Math.trunc(value);\n return Math.round(value);\n};\n\n// =============================================================================\n// Pricing config\n// =============================================================================\n\n/**\n * One step in a graduated-tier price table. `upTo` is the inclusive\n * upper bound (in metered units, NOT micros) for this band.\n * `perUnitMicros` is what the customer pays per single metered unit\n * within this band. The last entry must have `upTo: Infinity` to\n * cover any overflow.\n */\nexport type PricingTier = {\n upTo: number;\n perUnitMicros: number;\n};\n\n/**\n * Per-dimension pricing. Three shapes:\n *\n * - Flat per-unit: `{ perUnitMicros: 200, unit: 1024 * 1024 }`\n * charges 200 micros ($0.0002) per MB of usage.\n *\n * - Tiered: `{ tiers: [...], unit: 1 }` charges per the first\n * matching `PricingTier` band.\n *\n * - Custom: `{ price: (quantity) => micros, unit: 1 }` — escape\n * hatch for surge / caps / non-monotonic pricing. The substrate\n * stays pure; you ship whatever function you want.\n *\n * `freeTier` is subtracted from the metered quantity BEFORE pricing\n * — the conventional \"first N units free\" rule.\n *\n * `unit` is the metered-unit denominator: 1 means \"price per single\n * metered unit\", 1024*1024 means \"price per MB when quantity is in\n * bytes.\" Default 1.\n *\n * `label` overrides the line-item display name.\n */\nexport type PricedDimension = {\n label?: string;\n freeTier?: number;\n unit?: number;\n} & (\n | { perUnitMicros: number; tiers?: never; price?: never }\n | { tiers: PricingTier[]; perUnitMicros?: never; price?: never }\n | {\n price: (chargedQuantity: number) => Micros;\n perUnitMicros?: never;\n tiers?: never;\n }\n);\n\nexport type Plan = {\n /** Human label for the invoice (`'pro'`, `'enterprise'`, etc.). */\n name: string;\n /** Optional flat base fee charged once per invoice period. */\n basePriceMicros?: Micros;\n /**\n * Dimensions priced from usage. Keys must match keys on the\n * `usage` record passed to `computeInvoice`. Anything not listed\n * is ignored.\n */\n pricedDimensions: Record<string, PricedDimension>;\n /** Default currency for invoices generated from this plan. */\n currency?: string;\n /** Rounding strategy applied per line item. Default `'truncate'`. */\n rounding?: Rounding;\n /**\n * Minimum charge (in micros) — if the computed total is below\n * this floor, the invoice total is raised to the floor and a\n * single `'minimum-charge-adjustment'` line item captures the\n * difference. Defaults to 0 (no floor).\n */\n minimumChargeMicros?: Micros;\n /** Arbitrary plan-level metadata that flows through to invoices. */\n metadata?: Record<string, string>;\n};\n\nexport const createPlan = (plan: Plan): Plan => {\n for (const [key, dim] of Object.entries(plan.pricedDimensions)) {\n if (dim.tiers !== undefined) {\n if (dim.tiers.length === 0) {\n throw new Error(`billing: dimension '${key}' has no tiers`);\n }\n const last = dim.tiers[dim.tiers.length - 1];\n if (last !== undefined && Number.isFinite(last.upTo)) {\n throw new Error(\n `billing: dimension '${key}' final tier must have upTo: Infinity`,\n );\n }\n let prev = 0;\n for (let i = 0; i < dim.tiers.length; i += 1) {\n const tier = dim.tiers[i]!;\n if (tier.upTo < prev) {\n throw new Error(\n `billing: dimension '${key}' tier #${i} upTo (${tier.upTo}) must be >= previous (${prev})`,\n );\n }\n prev = tier.upTo;\n }\n }\n }\n return plan;\n};\n\n// =============================================================================\n// Invoice shape\n// =============================================================================\n\nexport type LineItem = {\n /**\n * Stable key for the line item. For priced dimensions it's the\n * usage-record key (`'requests'`, `'cpuMs'`, etc.). For the base\n * fee it's `'base'`. For minimum-charge top-up it's\n * `'minimum-charge-adjustment'`.\n */\n key: string;\n /** Human-readable label. */\n label: string;\n /** Metered units BEFORE applying free tier. 0 for the base fee. */\n quantity: number;\n /** Metered units AFTER applying free tier (what's actually charged). */\n chargedQuantity: number;\n /** Free-tier units subtracted from `quantity`. */\n freeTier?: number;\n /** Charge for this line in integer micros. */\n amountMicros: Micros;\n /**\n * Tier-by-tier breakdown when graduated pricing was used. Each\n * entry: `{ tierIndex, unitsInTier, perUnitMicros, amountMicros }`.\n */\n tierBreakdown?: Array<{\n tierIndex: number;\n unitsInTier: number;\n perUnitMicros: number;\n amountMicros: Micros;\n }>;\n};\n\nexport type InvoicePeriod = {\n /** Inclusive period start (`Date.now()` ms). */\n start: number;\n /** Exclusive period end. */\n end: number;\n};\n\nexport type Invoice = {\n tenant: string;\n plan: string;\n currency: string;\n period: InvoicePeriod;\n lineItems: LineItem[];\n /** Sum of all `lineItems[].amountMicros`. */\n totalMicros: Micros;\n /** Convenience: `totalMicros / 1_000_000` as a number. */\n totalUnits: number;\n /** Plan-level metadata copied through unchanged. */\n metadata?: Record<string, string>;\n};\n\n// =============================================================================\n// Pricing math\n// =============================================================================\n\ntype ComputeDimensionInput = {\n quantity: number;\n dim: PricedDimension;\n rounding: Rounding;\n};\n\ntype ComputeDimensionResult = {\n amountMicros: Micros;\n chargedQuantity: number;\n tierBreakdown?: LineItem[\"tierBreakdown\"];\n};\n\nconst computeDimension = ({\n quantity,\n dim,\n rounding,\n}: ComputeDimensionInput): ComputeDimensionResult => {\n const free = dim.freeTier ?? 0;\n const charged = Math.max(0, quantity - free);\n const unit = dim.unit ?? 1;\n const chargedUnits = unit === 1 ? charged : charged / unit;\n\n if (dim.perUnitMicros !== undefined) {\n const amountMicros = roundMicros(\n chargedUnits * dim.perUnitMicros,\n rounding,\n );\n return { amountMicros, chargedQuantity: charged };\n }\n\n if (dim.price !== undefined) {\n const amountMicros = roundMicros(dim.price(charged), rounding);\n return { amountMicros, chargedQuantity: charged };\n }\n\n // Tiered pricing — walk tiers, allocate chargedUnits into bands.\n const tierBreakdown: NonNullable<LineItem[\"tierBreakdown\"]> = [];\n let remaining = chargedUnits;\n let bandFloor = 0;\n let totalMicros = 0;\n for (let i = 0; i < dim.tiers!.length && remaining > 0; i += 1) {\n const tier = dim.tiers![i]!;\n const bandWidth = tier.upTo - bandFloor;\n const unitsInTier = Math.min(remaining, bandWidth);\n if (unitsInTier > 0) {\n const tierMicros = roundMicros(\n unitsInTier * tier.perUnitMicros,\n rounding,\n );\n tierBreakdown.push({\n amountMicros: tierMicros,\n perUnitMicros: tier.perUnitMicros,\n tierIndex: i,\n unitsInTier,\n });\n totalMicros += tierMicros;\n }\n remaining -= unitsInTier;\n bandFloor = tier.upTo;\n }\n return {\n amountMicros: totalMicros,\n chargedQuantity: charged,\n tierBreakdown,\n };\n};\n\n// =============================================================================\n// computeInvoice — pure\n// =============================================================================\n\nexport type ComputeInvoiceInput = {\n plan: Plan;\n tenant: string;\n period: InvoicePeriod;\n /** Metered numbers keyed by the same names as `plan.pricedDimensions`. */\n usage: Record<string, number>;\n /** Override the plan's currency (e.g. for tenant-local invoicing). */\n currency?: string;\n};\n\nexport const computeInvoice = ({\n plan,\n tenant,\n period,\n usage,\n currency,\n}: ComputeInvoiceInput): Invoice => {\n const rounding = plan.rounding ?? \"truncate\";\n const lineItems: LineItem[] = [];\n\n if (plan.basePriceMicros !== undefined && plan.basePriceMicros > 0) {\n lineItems.push({\n amountMicros: plan.basePriceMicros,\n chargedQuantity: 1,\n key: \"base\",\n label: `${plan.name} base fee`,\n quantity: 1,\n });\n }\n\n for (const [key, dim] of Object.entries(plan.pricedDimensions)) {\n const quantity = usage[key] ?? 0;\n if (!Number.isFinite(quantity) || quantity < 0) continue;\n const result = computeDimension({ dim, quantity, rounding });\n if (result.amountMicros === 0 && result.chargedQuantity === 0) continue;\n const item: LineItem = {\n amountMicros: result.amountMicros,\n chargedQuantity: result.chargedQuantity,\n key,\n label: dim.label ?? key,\n quantity,\n };\n if (dim.freeTier !== undefined) item.freeTier = dim.freeTier;\n if (result.tierBreakdown !== undefined && result.tierBreakdown.length > 0) {\n item.tierBreakdown = result.tierBreakdown;\n }\n lineItems.push(item);\n }\n\n let totalMicros = lineItems.reduce((sum, item) => sum + item.amountMicros, 0);\n\n const floor = plan.minimumChargeMicros ?? 0;\n if (floor > 0 && totalMicros < floor) {\n const gap = floor - totalMicros;\n lineItems.push({\n amountMicros: gap,\n chargedQuantity: 1,\n key: \"minimum-charge-adjustment\",\n label: \"Minimum charge adjustment\",\n quantity: 1,\n });\n totalMicros = floor;\n }\n\n const invoice: Invoice = {\n currency: currency ?? plan.currency ?? \"usd\",\n lineItems,\n period,\n plan: plan.name,\n tenant,\n totalMicros,\n totalUnits: totalMicros / 1_000_000,\n };\n if (plan.metadata !== undefined) invoice.metadata = plan.metadata;\n return invoice;\n};\n\n// =============================================================================\n// Display helpers\n// =============================================================================\n\n/**\n * Format an integer micros amount as a human currency string. Pure\n * — no Intl side effects. For locales / advanced formatting, pipe\n * through `Intl.NumberFormat` yourself.\n */\nexport const formatMicros = (\n amount: Micros,\n currency: string,\n { minorUnits = 2 }: { minorUnits?: number } = {},\n): string => {\n const sign = amount < 0 ? \"-\" : \"\";\n const abs = Math.abs(amount);\n const wholeMicrosPerMinor = 10 ** (6 - minorUnits);\n const minorTotal = Math.round(abs / wholeMicrosPerMinor);\n const divisor = 10 ** minorUnits;\n const whole = Math.trunc(minorTotal / divisor);\n const upper = currency.toUpperCase();\n if (minorUnits === 0) return `${sign}${whole} ${upper}`;\n const fraction = minorTotal % divisor;\n const fractionStr = fraction.toString().padStart(minorUnits, \"0\");\n return `${sign}${whole}.${fractionStr} ${upper}`;\n};\n\n// Provider balances — read upstream vendors' real balance/quota/spend (the\n// inverse of computeInvoice). See ./balances.\nexport {\n readProviderBalances,\n type ProviderBalance,\n type ProviderBalanceConfig,\n type ProviderBalanceKind,\n type ProviderBalanceStatus,\n type BraveUsageSnapshot,\n} from \"./balances\";\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": "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",
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "C0D9028B844C873764756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Plan, ProviderBalanceConfig } from "./index";
|
|
2
|
+
type BillingRuntime = {
|
|
3
|
+
plan: Plan;
|
|
4
|
+
balances?: ProviderBalanceConfig;
|
|
5
|
+
};
|
|
6
|
+
export declare const manifest: import("@absolutejs/manifest").PackageManifest<Record<never, never>, BillingRuntime>;
|
|
7
|
+
export {};
|