@arnaudjnn/billing-tools 2.13.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-billing.d.ts +25 -1
- package/dist/create-billing.d.ts.map +1 -1
- package/dist/create-billing.js +9 -3
- package/dist/create-billing.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/usage-counters.d.ts +102 -0
- package/dist/usage-counters.d.ts.map +1 -0
- package/dist/usage-counters.js +212 -0
- package/dist/usage-counters.js.map +1 -0
- package/package.json +1 -1
package/dist/create-billing.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type AgentAuthBranding, type AgentAuthPaths, type AgentAuthPolicy, type
|
|
|
6
6
|
import type { ClaimStore } from "./agent-auth/claim-store.js";
|
|
7
7
|
import { type MachinePaymentOptions } from "./machine-payment/index.js";
|
|
8
8
|
import { type OAuthProxyOptions } from "./oauth-proxy/index.js";
|
|
9
|
+
import { type UsageCounterStore } from "./usage-counters.js";
|
|
9
10
|
import { type SqlClient, type UsageLedger } from "./usage-ledger.js";
|
|
10
11
|
import type { PlanCatalog } from "./plans.js";
|
|
11
12
|
export interface CreateBillingOptions {
|
|
@@ -109,9 +110,32 @@ export interface CreateBillingOptions {
|
|
|
109
110
|
*
|
|
110
111
|
* Run `ensureUsageLedgerTable(db)` once from your migrations first.
|
|
111
112
|
*
|
|
112
|
-
* `ledger` wins if both are given, for a consumer with their own store
|
|
113
|
+
* `ledger` wins if both are given, for a consumer with their own store, and
|
|
114
|
+
* `counters` below wins over this — it answers the same questions without the
|
|
115
|
+
* per-call row.
|
|
113
116
|
*/
|
|
114
117
|
db?: SqlClient;
|
|
118
|
+
/**
|
|
119
|
+
* A COUNTER store for the per-caller leg — the scale-correct choice, and the
|
|
120
|
+
* one that does not need SQL.
|
|
121
|
+
*
|
|
122
|
+
* `db` above keeps one row per metered call and answers a window by aggregating
|
|
123
|
+
* a range of them on the hot path. Counters keep one row per (org, scope, hour),
|
|
124
|
+
* so a caller making a thousand calls in an hour writes ONE row and every read
|
|
125
|
+
* is a point lookup: the store stops growing with traffic, and the read stops
|
|
126
|
+
* scaling with it. At the volumes a plan actually declares — an Enterprise
|
|
127
|
+
* window of 200 000 credits a week — that is the difference between a bounded
|
|
128
|
+
* working set and a partitioning project.
|
|
129
|
+
*
|
|
130
|
+
* `sqlUsageCounters(pool)` uses the database you already have;
|
|
131
|
+
* `redisUsageCounters(client)` needs no SQL at all (`redis`, `ioredis`,
|
|
132
|
+
* `@upstash/redis` and Vercel KV all satisfy the duck type). Run
|
|
133
|
+
* `ensureUsageCountersTable(pool)` from your migrations for the SQL one.
|
|
134
|
+
*
|
|
135
|
+
* What it gives up: per-action history. A counter cannot say WHICH actions made
|
|
136
|
+
* up a total — pass `db` instead if you want that trail.
|
|
137
|
+
*/
|
|
138
|
+
counters?: UsageCounterStore;
|
|
115
139
|
};
|
|
116
140
|
}
|
|
117
141
|
export declare function createBilling(opts: CreateBillingOptions): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-billing.d.ts","sourceRoot":"","sources":["../src/create-billing.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"create-billing.d.ts","sourceRoot":"","sources":["../src/create-billing.ts"],"names":[],"mappings":"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"}
|
package/dist/create-billing.js
CHANGED
|
@@ -8,6 +8,7 @@ import { CLAIM_GRANT_TYPE, createAgentAuth, } from "./agent-auth/index.js";
|
|
|
8
8
|
import { createMachinePaymentHandler, createPaymentMd } from "./machine-payment/index.js";
|
|
9
9
|
import { createOAuthProxy } from "./oauth-proxy/index.js";
|
|
10
10
|
import { createMeter, createApiMeterGuard } from "./metering.js";
|
|
11
|
+
import { counterUsageLedger } from "./usage-counters.js";
|
|
11
12
|
import { defaultUsageLedger, postgresUsageLedger, stripeUsageLedger, } from "./usage-ledger.js";
|
|
12
13
|
export function createBilling(opts) {
|
|
13
14
|
const resolved = resolveConfig(opts.config);
|
|
@@ -107,9 +108,14 @@ export function createBilling(opts) {
|
|
|
107
108
|
// previously impossible: the old default was the debits themselves, so an
|
|
108
109
|
// included call counted as 0 and every window read 0%.
|
|
109
110
|
const ledger = opts.meter?.ledger ??
|
|
110
|
-
(opts.meter?.
|
|
111
|
-
?
|
|
112
|
-
|
|
111
|
+
(opts.meter?.counters
|
|
112
|
+
? // Counters answer a per-member window with a point read instead of a range
|
|
113
|
+
// aggregate, so they are the scale-correct per-caller leg. Org-wide windows
|
|
114
|
+
// still go to the Stripe meter, which needs no store at any volume.
|
|
115
|
+
stripeUsageLedger({ perCaller: counterUsageLedger(opts.meter.counters) })
|
|
116
|
+
: opts.meter?.db
|
|
117
|
+
? stripeUsageLedger({ perCaller: postgresUsageLedger(opts.meter.db) })
|
|
118
|
+
: defaultUsageLedger());
|
|
113
119
|
// What the wired ledger cannot count is warned about by `createMeter` below,
|
|
114
120
|
// which every metered call goes through whichever constructor composed the app —
|
|
115
121
|
// so the rule lives in one place (`warnLedgerGaps`) instead of once per entry
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-billing.js","sourceRoot":"","sources":["../src/create-billing.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAoC,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAuB,MAAM,qBAAqB,CAAC;AACtF,OAAO,EACL,gBAAgB,EAChB,eAAe,GAKhB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAA8B,MAAM,4BAA4B,CAAC;AACtH,OAAO,EAAE,gBAAgB,EAA0B,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAGlB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"create-billing.js","sourceRoot":"","sources":["../src/create-billing.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { derivePlanViews, derivePlanView, renderPlansMarkdown, renderRateCardMar
|
|
|
11
11
|
export { resolveAllowance, fundingFor, describeDenial, currentCycle, type AllowanceState, type AllowanceInput, type FundingDecision, type DenialReason, type LimitState, } from "./allowance.js";
|
|
12
12
|
export { usageSummary, memberUsage, resolveSeat, type UsageSummary, type UsageSummaryInput, type UsageWindow, type UsageSeat, type MemberUsage, } from "./usage.js";
|
|
13
13
|
export { stripeBalanceUsageLedger, postgresUsageLedger, ensureUsageLedgerTable, USAGE_EVENTS_DDL, type SqlClient, stripeMeterUsageLedger, stripeUsageLedger, defaultUsageLedger, warnLedgerGaps, ensureMeters, invalidateMeters, USAGE_METER_EVENT, type UsageLedger, type UsageEvent, type UsageQuery, type FundingSource, } from "./usage-ledger.js";
|
|
14
|
+
export { counterUsageLedger, sqlUsageCounters, redisUsageCounters, memoryUsageCounters, ensureUsageCountersTable, pruneUsageCounters, USAGE_COUNTERS_DDL, BUCKET_MS, bucketOf, scopeOf, scopesFor, counterKey, type UsageCounterStore, type CounterLedgerOptions, type SqlCounterClient, type RedisCounterClient, } from "./usage-counters.js";
|
|
14
15
|
export { meterUsage, createMeter, createApiMeterGuard, type MeterCaller, type MeterInput, type MeterResult, type MeterConfig, type MeterCallOpts, type Meter, type ApiMeterGuard, } from "./metering.js";
|
|
15
16
|
export { requestTopUp, listTopUpRequests, approveTopUp, denyTopUp, grantTopUp, grantExtraAllowance, extraAllowance, trimRequestsToBudget, METADATA_VALUE_LIMIT, type TopUpRequest, } from "./topup.js";
|
|
16
17
|
export { assignSeatType, listSeatAssignments, getSeatType, } from "./seats.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,10 @@ currentCycle, } from "./allowance.js";
|
|
|
46
46
|
export { usageSummary, memberUsage, resolveSeat, } from "./usage.js";
|
|
47
47
|
// Counting usage separately from moving money — the seam an included window needs.
|
|
48
48
|
export { stripeBalanceUsageLedger, postgresUsageLedger, ensureUsageLedgerTable, USAGE_EVENTS_DDL, stripeMeterUsageLedger, stripeUsageLedger, defaultUsageLedger, warnLedgerGaps, ensureMeters, invalidateMeters, USAGE_METER_EVENT, } from "./usage-ledger.js";
|
|
49
|
+
// Counters instead of events: one row per (org, scope, hour) rather than per call,
|
|
50
|
+
// so a per-member window is a point read and the store stops growing with traffic.
|
|
51
|
+
// Works without SQL — a Redis/KV client satisfies the same seam.
|
|
52
|
+
export { counterUsageLedger, sqlUsageCounters, redisUsageCounters, memoryUsageCounters, ensureUsageCountersTable, pruneUsageCounters, USAGE_COUNTERS_DDL, BUCKET_MS, bucketOf, scopeOf, scopesFor, counterKey, } from "./usage-counters.js";
|
|
49
53
|
// Per-execution metering engine (prepaid balance; per-seat packs or a global
|
|
50
54
|
// pool; usage summed from Stripe balance-transaction metadata — no new backend).
|
|
51
55
|
export { meterUsage, createMeter, createApiMeterGuard, } from "./metering.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { UsageEvent, UsageLedger } from "./usage-ledger.js";
|
|
2
|
+
/** Milliseconds in the bucket grain. The tightest window a plan can declare. */
|
|
3
|
+
export declare const BUCKET_MS = 3600000;
|
|
4
|
+
/** The bucket an instant falls in: hours since the epoch, UTC-aligned. */
|
|
5
|
+
export declare const bucketOf: (atMs: number) => number;
|
|
6
|
+
/**
|
|
7
|
+
* WHOSE counter. Derived identically on the write and read paths, which is the
|
|
8
|
+
* whole contract — a `total` that computed a different scope string from the same
|
|
9
|
+
* caller would read a counter nobody writes, and report 0 forever.
|
|
10
|
+
*
|
|
11
|
+
* `org` is every call in the workspace. A caller kind with no id is every caller
|
|
12
|
+
* of that kind (how a shared API seat is measured); with an id it is one member.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scopeOf(filter?: {
|
|
15
|
+
callerKind?: string;
|
|
16
|
+
callerId?: string;
|
|
17
|
+
}): string;
|
|
18
|
+
/** Every scope a single event counts toward. An event is counted once per scope,
|
|
19
|
+
* so an org-wide read and a per-member read both see it. */
|
|
20
|
+
export declare function scopesFor(event: UsageEvent): string[];
|
|
21
|
+
/** `org|scope|bucket` — derivable from either side, so no index is needed to find
|
|
22
|
+
* a counter and a KV store works as well as a table. */
|
|
23
|
+
export declare const counterKey: (orgId: string, scope: string, bucket: number) => string;
|
|
24
|
+
/**
|
|
25
|
+
* The store. Two operations, both of which every candidate backend already has.
|
|
26
|
+
*
|
|
27
|
+
* `add` must be ATOMIC per key — an increment, not a read-then-write. That is the
|
|
28
|
+
* whole reason this can live in Redis or Postgres but not in Stripe or WorkOS
|
|
29
|
+
* metadata: neither has an increment, so two concurrent metered calls would both
|
|
30
|
+
* read `n`, both write `n+1`, and one call would vanish.
|
|
31
|
+
*/
|
|
32
|
+
export interface UsageCounterStore {
|
|
33
|
+
/** Add `amount` to every key. `expiresAtMs` is a hint for stores with TTL; a
|
|
34
|
+
* table can ignore it and sweep on `bucket` instead. */
|
|
35
|
+
add(keys: string[], amount: number, expiresAtMs: number | null): Promise<void>;
|
|
36
|
+
/** Sum the given keys. Missing keys count as 0. ONE round trip. */
|
|
37
|
+
sum(keys: string[]): Promise<number>;
|
|
38
|
+
}
|
|
39
|
+
export interface CounterLedgerOptions {
|
|
40
|
+
/** How long a bucket is kept, for stores that expire. Default 400 days, which
|
|
41
|
+
* covers an annual window plus slack. */
|
|
42
|
+
retentionMs?: number;
|
|
43
|
+
/** Cap on keys per read, so a pathological window cannot issue an unbounded
|
|
44
|
+
* fetch. Default 8 784 (a leap year of hours). A window wider than this reads
|
|
45
|
+
* the most RECENT slice, which under-reports — the direction that refuses
|
|
46
|
+
* early rather than granting what nobody paid for. */
|
|
47
|
+
maxKeysPerRead?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A `UsageLedger` backed by counters. Counts EVERYTHING — included and
|
|
51
|
+
* wallet-funded, org-wide and per member — which is what `covers` declares.
|
|
52
|
+
*/
|
|
53
|
+
export declare function counterUsageLedger(store: UsageCounterStore, opts?: CounterLedgerOptions): UsageLedger;
|
|
54
|
+
/** The table + the one index its read uses. Idempotent, so it is safe to run from
|
|
55
|
+
* a migration on every deploy. Bounded by (orgs × scopes × hours kept), not by
|
|
56
|
+
* traffic — the reason to prefer it over `usage_events` at volume. */
|
|
57
|
+
export declare const USAGE_COUNTERS_DDL = "\nCREATE TABLE IF NOT EXISTS usage_counters (\n key text PRIMARY KEY,\n used bigint NOT NULL,\n -- Kept for bulk expiry; the read never filters on it.\n stale timestamptz\n);\nCREATE INDEX IF NOT EXISTS usage_counters_stale_idx ON usage_counters (stale);\n";
|
|
58
|
+
/** The one method this needs from a driver — the same duck type
|
|
59
|
+
* `postgresUsageLedger` uses, so `pg`'s Pool and Neon's driver both satisfy it. */
|
|
60
|
+
export interface SqlCounterClient {
|
|
61
|
+
query<R = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<{
|
|
62
|
+
rows: R[];
|
|
63
|
+
}>;
|
|
64
|
+
}
|
|
65
|
+
export declare function ensureUsageCountersTable(client: SqlCounterClient): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Counters in Postgres: one upsert per scope on write, one `SUM` over a primary-key
|
|
68
|
+
* lookup on read.
|
|
69
|
+
*
|
|
70
|
+
* `used = usage_counters.used + excluded.used` is the atomic increment — the row
|
|
71
|
+
* lock is held for the statement, so concurrent calls serialise instead of losing
|
|
72
|
+
* one another's writes.
|
|
73
|
+
*/
|
|
74
|
+
export declare function sqlUsageCounters(client: SqlCounterClient): UsageCounterStore;
|
|
75
|
+
/** Delete expired buckets. Call it from a cron; nothing depends on it running —
|
|
76
|
+
* a stale bucket is simply never read once its window has passed. */
|
|
77
|
+
export declare function pruneUsageCounters(client: SqlCounterClient, now?: number): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* The minimum a Redis-compatible client has to expose. Satisfied by `redis`,
|
|
80
|
+
* `ioredis`, `@upstash/redis` and Vercel KV — which is the point: a deployment
|
|
81
|
+
* with a KV and no SQL can still meter per member.
|
|
82
|
+
*/
|
|
83
|
+
export interface RedisCounterClient {
|
|
84
|
+
incrby(key: string, amount: number): Promise<unknown>;
|
|
85
|
+
pexpireat?(key: string, atMs: number): Promise<unknown>;
|
|
86
|
+
mget(keys: string[]): Promise<Array<string | number | null>>;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Counters in Redis: `INCRBY` per scope, one `MGET` per read.
|
|
90
|
+
*
|
|
91
|
+
* The expiry is set on every write rather than only on create. `PEXPIREAT` is
|
|
92
|
+
* idempotent and one round trip, whereas checking first is two and races — and a
|
|
93
|
+
* bucket that lost its expiry is a leak that only shows up as memory months later.
|
|
94
|
+
*/
|
|
95
|
+
export declare function redisUsageCounters(client: RedisCounterClient): UsageCounterStore;
|
|
96
|
+
/** In-memory counters, for tests and single-process development. Not for a
|
|
97
|
+
* deployment with more than one instance: each would count its own share, and the
|
|
98
|
+
* gate would allow the sum of every instance's window. */
|
|
99
|
+
export declare function memoryUsageCounters(): UsageCounterStore & {
|
|
100
|
+
readonly map: Map<string, number>;
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=usage-counters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-counters.d.ts","sourceRoot":"","sources":["../src/usage-counters.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAc,MAAM,mBAAmB,CAAC;AA2C7E,gFAAgF;AAChF,eAAO,MAAM,SAAS,UAAY,CAAC;AAEnC,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,KAAG,MAAsC,CAAC;AAE/E;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAInF;AAED;6DAC6D;AAC7D,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,CAKrD;AAED;yDACyD;AACzD,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,MAC3C,CAAC;AAEhC;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC;6DACyD;IACzD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,mEAAmE;IACnE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC;8CAC0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;2DAGuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,iBAAiB,EACxB,IAAI,GAAE,oBAAyB,GAC9B,WAAW,CAqCb;AAID;;uEAEuE;AACvE,eAAO,MAAM,kBAAkB,4QAQ9B,CAAC;AAEF;oFACoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,EAAE,CAAA;KAAE,CAAC,CAAC;CAC7F;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CA2B5E;AAED;sEACsE;AACtE,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,gBAAgB,EACxB,GAAG,GAAE,MAAmB,GACvB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,SAAS,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAC9D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,iBAAiB,CAgBhF;AAED;;2DAE2D;AAC3D,wBAAgB,mBAAmB,IAAI,iBAAiB,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAa/F"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// Counting usage as COUNTERS rather than as events — the scale-correct store, and
|
|
2
|
+
// the one that works without SQL.
|
|
3
|
+
//
|
|
4
|
+
// ── Why counters, when `postgresUsageLedger` already works ──────────────────
|
|
5
|
+
//
|
|
6
|
+
// Because of what the seam is actually asked. Every read in this library is the
|
|
7
|
+
// same shape — `sum(cost) where org, [start, end), callerKind?, callerId?` — and
|
|
8
|
+
// every window is FIXED and UTC-aligned (`rateWindowFor`, `cycleWindowFor`). An
|
|
9
|
+
// append-only event log answers that by aggregating a range on the hot path of
|
|
10
|
+
// every metered call, over a table that grows by one row per call forever. At the
|
|
11
|
+
// volumes a plan actually declares (an Enterprise window of 200 000 credits a
|
|
12
|
+
// week) that is millions of rows a month whose only purpose is to be summed back
|
|
13
|
+
// into a handful of integers, plus the retention and partitioning work that
|
|
14
|
+
// follows.
|
|
15
|
+
//
|
|
16
|
+
// Counters answer it with a point read. One row per (org, scope, hour), so a
|
|
17
|
+
// caller making a thousand calls in an hour writes ONE row instead of a thousand,
|
|
18
|
+
// and the row count is bounded by time rather than by traffic.
|
|
19
|
+
//
|
|
20
|
+
// ── Why HOURLY buckets rather than one counter per declared window ──────────
|
|
21
|
+
//
|
|
22
|
+
// A counter keyed by the plan's own windows would be smaller still, but `record`
|
|
23
|
+
// would have to know which windows exist — and a window it failed to bump is
|
|
24
|
+
// usage counted by nothing, which reads as 0% and refuses no one. That failure
|
|
25
|
+
// looks like generosity, which is the exact class of defect this file is written
|
|
26
|
+
// to avoid. Bucketing by a fixed grain instead means `record` needs no plan
|
|
27
|
+
// knowledge at all: it bumps the bucket the event falls in, and `total` sums the
|
|
28
|
+
// buckets its window covers. Any window is answerable, including one added to the
|
|
29
|
+
// config later.
|
|
30
|
+
//
|
|
31
|
+
// An hour is the grain because `every: "hour"` is the tightest window the plan
|
|
32
|
+
// model can express, so it is the finest anything can ask for. A month is then at
|
|
33
|
+
// most 744 keys in ONE batched read.
|
|
34
|
+
//
|
|
35
|
+
// ── What this gives up ──────────────────────────────────────────────────────
|
|
36
|
+
//
|
|
37
|
+
// The audit trail. A counter cannot say WHICH actions made up a total, or when
|
|
38
|
+
// inside the hour. `postgresUsageLedger` keeps that and stays the right choice for
|
|
39
|
+
// a consumer who wants per-action history; the two satisfy the same seam, so a
|
|
40
|
+
// deployment can even write to both.
|
|
41
|
+
/** Milliseconds in the bucket grain. The tightest window a plan can declare. */
|
|
42
|
+
export const BUCKET_MS = 3_600_000;
|
|
43
|
+
/** The bucket an instant falls in: hours since the epoch, UTC-aligned. */
|
|
44
|
+
export const bucketOf = (atMs) => Math.floor(atMs / BUCKET_MS);
|
|
45
|
+
/**
|
|
46
|
+
* WHOSE counter. Derived identically on the write and read paths, which is the
|
|
47
|
+
* whole contract — a `total` that computed a different scope string from the same
|
|
48
|
+
* caller would read a counter nobody writes, and report 0 forever.
|
|
49
|
+
*
|
|
50
|
+
* `org` is every call in the workspace. A caller kind with no id is every caller
|
|
51
|
+
* of that kind (how a shared API seat is measured); with an id it is one member.
|
|
52
|
+
*/
|
|
53
|
+
export function scopeOf(filter) {
|
|
54
|
+
if (filter?.callerId)
|
|
55
|
+
return `u:${filter.callerId}`;
|
|
56
|
+
if (filter?.callerKind)
|
|
57
|
+
return `k:${filter.callerKind}`;
|
|
58
|
+
return "org";
|
|
59
|
+
}
|
|
60
|
+
/** Every scope a single event counts toward. An event is counted once per scope,
|
|
61
|
+
* so an org-wide read and a per-member read both see it. */
|
|
62
|
+
export function scopesFor(event) {
|
|
63
|
+
const scopes = ["org"];
|
|
64
|
+
if (event.caller?.kind)
|
|
65
|
+
scopes.push(`k:${event.caller.kind}`);
|
|
66
|
+
if (event.caller?.id)
|
|
67
|
+
scopes.push(`u:${event.caller.id}`);
|
|
68
|
+
return scopes;
|
|
69
|
+
}
|
|
70
|
+
/** `org|scope|bucket` — derivable from either side, so no index is needed to find
|
|
71
|
+
* a counter and a KV store works as well as a table. */
|
|
72
|
+
export const counterKey = (orgId, scope, bucket) => `${orgId}|${scope}|${bucket}`;
|
|
73
|
+
/**
|
|
74
|
+
* A `UsageLedger` backed by counters. Counts EVERYTHING — included and
|
|
75
|
+
* wallet-funded, org-wide and per member — which is what `covers` declares.
|
|
76
|
+
*/
|
|
77
|
+
export function counterUsageLedger(store, opts = {}) {
|
|
78
|
+
const retentionMs = opts.retentionMs ?? 400 * 86_400_000;
|
|
79
|
+
const maxKeys = Math.max(1, opts.maxKeysPerRead ?? 8_784);
|
|
80
|
+
return {
|
|
81
|
+
covers: { orgIncluded: true, callerIncluded: true },
|
|
82
|
+
async record(event) {
|
|
83
|
+
if (!event.cost)
|
|
84
|
+
return; // a free call moves no counter
|
|
85
|
+
const at = event.at ?? Date.now();
|
|
86
|
+
const bucket = bucketOf(at);
|
|
87
|
+
const keys = scopesFor(event).map((s) => counterKey(event.orgId, s, bucket));
|
|
88
|
+
// One call for every scope: a store can pipeline them, and a table can do it
|
|
89
|
+
// in a single multi-row upsert.
|
|
90
|
+
await store.add(keys, event.cost, at + retentionMs);
|
|
91
|
+
},
|
|
92
|
+
async total(query) {
|
|
93
|
+
// [start, end): the half-open window this library defines everywhere. The
|
|
94
|
+
// END bucket is inclusive when the window ends mid-bucket, because an event
|
|
95
|
+
// in that hour may fall inside the window — a counter cannot say where in
|
|
96
|
+
// the hour it happened, so it is counted. The overshoot is bounded by one
|
|
97
|
+
// bucket and only ever at the CURRENT edge, where the alternative is to
|
|
98
|
+
// ignore the usage that just happened.
|
|
99
|
+
const from = bucketOf(query.start);
|
|
100
|
+
const to = bucketOf((query.end ?? Date.now()) - 1);
|
|
101
|
+
if (to < from)
|
|
102
|
+
return 0;
|
|
103
|
+
const scope = scopeOf(query.filter);
|
|
104
|
+
const keys = [];
|
|
105
|
+
// Newest-first when clamped, so a window wider than the cap keeps the slice
|
|
106
|
+
// that decides whether the NEXT call is allowed.
|
|
107
|
+
const first = Math.max(from, to - maxKeys + 1);
|
|
108
|
+
for (let b = first; b <= to; b++)
|
|
109
|
+
keys.push(counterKey(query.orgId, scope, b));
|
|
110
|
+
return store.sum(keys);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
// ── Backends ────────────────────────────────────────────────────────────────
|
|
115
|
+
/** The table + the one index its read uses. Idempotent, so it is safe to run from
|
|
116
|
+
* a migration on every deploy. Bounded by (orgs × scopes × hours kept), not by
|
|
117
|
+
* traffic — the reason to prefer it over `usage_events` at volume. */
|
|
118
|
+
export const USAGE_COUNTERS_DDL = `
|
|
119
|
+
CREATE TABLE IF NOT EXISTS usage_counters (
|
|
120
|
+
key text PRIMARY KEY,
|
|
121
|
+
used bigint NOT NULL,
|
|
122
|
+
-- Kept for bulk expiry; the read never filters on it.
|
|
123
|
+
stale timestamptz
|
|
124
|
+
);
|
|
125
|
+
CREATE INDEX IF NOT EXISTS usage_counters_stale_idx ON usage_counters (stale);
|
|
126
|
+
`;
|
|
127
|
+
export async function ensureUsageCountersTable(client) {
|
|
128
|
+
await client.query(USAGE_COUNTERS_DDL);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Counters in Postgres: one upsert per scope on write, one `SUM` over a primary-key
|
|
132
|
+
* lookup on read.
|
|
133
|
+
*
|
|
134
|
+
* `used = usage_counters.used + excluded.used` is the atomic increment — the row
|
|
135
|
+
* lock is held for the statement, so concurrent calls serialise instead of losing
|
|
136
|
+
* one another's writes.
|
|
137
|
+
*/
|
|
138
|
+
export function sqlUsageCounters(client) {
|
|
139
|
+
return {
|
|
140
|
+
async add(keys, amount, expiresAtMs) {
|
|
141
|
+
if (!keys.length)
|
|
142
|
+
return;
|
|
143
|
+
// One statement for every scope: unnest the keys rather than issuing N
|
|
144
|
+
// round trips on the hot path.
|
|
145
|
+
await client.query(`INSERT INTO usage_counters (key, used, stale)
|
|
146
|
+
SELECT k, $2::bigint, $3::timestamptz FROM unnest($1::text[]) AS k
|
|
147
|
+
ON CONFLICT (key) DO UPDATE
|
|
148
|
+
SET used = usage_counters.used + excluded.used,
|
|
149
|
+
stale = GREATEST(usage_counters.stale, excluded.stale)`, [keys, amount, expiresAtMs == null ? null : new Date(expiresAtMs).toISOString()]);
|
|
150
|
+
},
|
|
151
|
+
async sum(keys) {
|
|
152
|
+
if (!keys.length)
|
|
153
|
+
return 0;
|
|
154
|
+
const r = await client.query(`SELECT COALESCE(SUM(used), 0) AS total
|
|
155
|
+
FROM usage_counters WHERE key = ANY($1::text[])`, [keys]);
|
|
156
|
+
// bigint comes back as a string from `pg`; Number is exact to 2^53, far
|
|
157
|
+
// beyond any credit total.
|
|
158
|
+
return Number(r.rows[0]?.total ?? 0) || 0;
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/** Delete expired buckets. Call it from a cron; nothing depends on it running —
|
|
163
|
+
* a stale bucket is simply never read once its window has passed. */
|
|
164
|
+
export async function pruneUsageCounters(client, now = Date.now()) {
|
|
165
|
+
await client.query(`DELETE FROM usage_counters WHERE stale IS NOT NULL AND stale < $1`, [
|
|
166
|
+
new Date(now).toISOString(),
|
|
167
|
+
]);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Counters in Redis: `INCRBY` per scope, one `MGET` per read.
|
|
171
|
+
*
|
|
172
|
+
* The expiry is set on every write rather than only on create. `PEXPIREAT` is
|
|
173
|
+
* idempotent and one round trip, whereas checking first is two and races — and a
|
|
174
|
+
* bucket that lost its expiry is a leak that only shows up as memory months later.
|
|
175
|
+
*/
|
|
176
|
+
export function redisUsageCounters(client) {
|
|
177
|
+
return {
|
|
178
|
+
async add(keys, amount, expiresAtMs) {
|
|
179
|
+
await Promise.all(keys.map(async (key) => {
|
|
180
|
+
await client.incrby(key, amount);
|
|
181
|
+
if (expiresAtMs != null && client.pexpireat)
|
|
182
|
+
await client.pexpireat(key, expiresAtMs);
|
|
183
|
+
}));
|
|
184
|
+
},
|
|
185
|
+
async sum(keys) {
|
|
186
|
+
if (!keys.length)
|
|
187
|
+
return 0;
|
|
188
|
+
const values = await client.mget(keys);
|
|
189
|
+
return values.reduce((acc, v) => acc + (v == null ? 0 : Number(v) || 0), 0);
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/** In-memory counters, for tests and single-process development. Not for a
|
|
194
|
+
* deployment with more than one instance: each would count its own share, and the
|
|
195
|
+
* gate would allow the sum of every instance's window. */
|
|
196
|
+
export function memoryUsageCounters() {
|
|
197
|
+
const map = new Map();
|
|
198
|
+
return {
|
|
199
|
+
map,
|
|
200
|
+
async add(keys, amount) {
|
|
201
|
+
for (const key of keys)
|
|
202
|
+
map.set(key, (map.get(key) ?? 0) + amount);
|
|
203
|
+
},
|
|
204
|
+
async sum(keys) {
|
|
205
|
+
let total = 0;
|
|
206
|
+
for (const key of keys)
|
|
207
|
+
total += map.get(key) ?? 0;
|
|
208
|
+
return total;
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=usage-counters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-counters.js","sourceRoot":"","sources":["../src/usage-counters.ts"],"names":[],"mappings":"AAGA,kFAAkF;AAClF,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,EAAE;AACF,gFAAgF;AAChF,iFAAiF;AACjF,gFAAgF;AAChF,+EAA+E;AAC/E,kFAAkF;AAClF,8EAA8E;AAC9E,iFAAiF;AACjF,4EAA4E;AAC5E,WAAW;AACX,EAAE;AACF,6EAA6E;AAC7E,kFAAkF;AAClF,+DAA+D;AAC/D,EAAE;AACF,+EAA+E;AAC/E,EAAE;AACF,iFAAiF;AACjF,6EAA6E;AAC7E,+EAA+E;AAC/E,iFAAiF;AACjF,4EAA4E;AAC5E,iFAAiF;AACjF,kFAAkF;AAClF,gBAAgB;AAChB,EAAE;AACF,+EAA+E;AAC/E,kFAAkF;AAClF,qCAAqC;AACrC,EAAE;AACF,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,mFAAmF;AACnF,+EAA+E;AAC/E,qCAAqC;AAErC,gFAAgF;AAChF,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAC;AAEnC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;AAE/E;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,MAAmD;IACzE,IAAI,MAAM,EAAE,QAAQ;QAAE,OAAO,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;IACpD,IAAI,MAAM,EAAE,UAAU;QAAE,OAAO,KAAK,MAAM,CAAC,UAAU,EAAE,CAAC;IACxD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;6DAC6D;AAC7D,MAAM,UAAU,SAAS,CAAC,KAAiB;IACzC,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9D,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;yDACyD;AACzD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,KAAa,EAAE,MAAc,EAAU,EAAE,CACjF,GAAG,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;AA6BhC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAwB,EACxB,OAA6B,EAAE;IAE/B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,GAAG,GAAG,UAAU,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,CAAC;IAE1D,OAAO;QACL,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAA2B;QAE5E,KAAK,CAAC,MAAM,CAAC,KAAiB;YAC5B,IAAI,CAAC,KAAK,CAAC,IAAI;gBAAE,OAAO,CAAC,+BAA+B;YACxD,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC5B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAC7E,6EAA6E;YAC7E,gCAAgC;YAChC,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,WAAW,CAAC,CAAC;QACtD,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,KAAiB;YAC3B,0EAA0E;YAC1E,4EAA4E;YAC5E,0EAA0E;YAC1E,0EAA0E;YAC1E,wEAAwE;YACxE,uCAAuC;YACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACnD,IAAI,EAAE,GAAG,IAAI;gBAAE,OAAO,CAAC,CAAC;YAExB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,4EAA4E;YAC5E,iDAAiD;YACjD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC;YAC/C,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;gBAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/E,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+EAA+E;AAE/E;;uEAEuE;AACvE,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;CAQjC,CAAC;AAQF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAwB;IACrE,MAAM,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAwB;IACvD,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,OAAO;YACzB,uEAAuE;YACvE,+BAA+B;YAC/B,MAAM,MAAM,CAAC,KAAK,CAChB;;;;sEAI8D,EAC9D,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC,CACjF,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,IAAI;YACZ,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC3B,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,KAAK,CAC1B;2DACmD,EACnD,CAAC,IAAI,CAAC,CACP,CAAC;YACF,wEAAwE;YACxE,2BAA2B;YAC3B,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;KACF,CAAC;AACJ,CAAC;AAED;sEACsE;AACtE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAwB,EACxB,MAAc,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,MAAM,CAAC,KAAK,CAAC,mEAAmE,EAAE;QACtF,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;KAC5B,CAAC,CAAC;AACL,CAAC;AAaD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC3D,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW;YACjC,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBACrB,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBACjC,IAAI,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,SAAS;oBAAE,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YACxF,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,IAAI;YACZ,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,OAAO,MAAM,CAAC,MAAM,CAAS,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtF,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;2DAE2D;AAC3D,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,OAAO;QACL,GAAG;QACH,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM;YACpB,KAAK,MAAM,GAAG,IAAI,IAAI;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QACrE,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,IAAI;YACZ,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,GAAG,IAAI,IAAI;gBAAE,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arnaudjnn/billing-tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "The get-paid engine for Stripe + WorkOS apps, for humans and AI agents. Drop-in API-key auth, credit + subscription billing, auth.md agent registration, and MPP machine payments, as MCP tools, a REST API, and a CLI. Framework-agnostic, storage-pluggable.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Arnaud Jeannin",
|