@arnaudjnn/billing-tools 0.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/LICENSE +21 -0
- package/README.md +243 -0
- package/dist/adapters/workos-org.d.ts +80 -0
- package/dist/adapters/workos-org.d.ts.map +1 -0
- package/dist/adapters/workos-org.js +176 -0
- package/dist/adapters/workos-org.js.map +1 -0
- package/dist/agent-auth/claim-store.d.ts +37 -0
- package/dist/agent-auth/claim-store.d.ts.map +1 -0
- package/dist/agent-auth/claim-store.js +64 -0
- package/dist/agent-auth/claim-store.js.map +1 -0
- package/dist/agent-auth/index.d.ts +65 -0
- package/dist/agent-auth/index.d.ts.map +1 -0
- package/dist/agent-auth/index.js +365 -0
- package/dist/agent-auth/index.js.map +1 -0
- package/dist/auth.d.ts +16 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +80 -0
- package/dist/auth.js.map +1 -0
- package/dist/billing.d.ts +59 -0
- package/dist/billing.d.ts.map +1 -0
- package/dist/billing.js +258 -0
- package/dist/billing.js.map +1 -0
- package/dist/cli/client.d.ts +10 -0
- package/dist/cli/client.d.ts.map +1 -0
- package/dist/cli/client.js +22 -0
- package/dist/cli/client.js.map +1 -0
- package/dist/cli/commands.d.ts +4 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +94 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/config.d.ts +16 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +40 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/create-billing.d.ts +78 -0
- package/dist/create-billing.d.ts.map +1 -0
- package/dist/create-billing.js +59 -0
- package/dist/create-billing.js.map +1 -0
- package/dist/dispatch.d.ts +9 -0
- package/dist/dispatch.d.ts.map +1 -0
- package/dist/dispatch.js +73 -0
- package/dist/dispatch.js.map +1 -0
- package/dist/events.d.ts +26 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +72 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/invitations.d.ts +56 -0
- package/dist/invitations.d.ts.map +1 -0
- package/dist/invitations.js +117 -0
- package/dist/invitations.js.map +1 -0
- package/dist/machine-payment/index.d.ts +57 -0
- package/dist/machine-payment/index.d.ts.map +1 -0
- package/dist/machine-payment/index.js +117 -0
- package/dist/machine-payment/index.js.map +1 -0
- package/dist/magic-auth.d.ts +4 -0
- package/dist/magic-auth.d.ts.map +1 -0
- package/dist/magic-auth.js +30 -0
- package/dist/magic-auth.js.map +1 -0
- package/dist/mirror.d.ts +35 -0
- package/dist/mirror.d.ts.map +1 -0
- package/dist/mirror.js +63 -0
- package/dist/mirror.js.map +1 -0
- package/dist/plans.d.ts +38 -0
- package/dist/plans.d.ts.map +1 -0
- package/dist/plans.js +132 -0
- package/dist/plans.js.map +1 -0
- package/dist/routes/mcp.d.ts +19 -0
- package/dist/routes/mcp.d.ts.map +1 -0
- package/dist/routes/mcp.js +39 -0
- package/dist/routes/mcp.js.map +1 -0
- package/dist/routes/rest.d.ts +20 -0
- package/dist/routes/rest.d.ts.map +1 -0
- package/dist/routes/rest.js +66 -0
- package/dist/routes/rest.js.map +1 -0
- package/dist/routes/webhook.d.ts +8 -0
- package/dist/routes/webhook.d.ts.map +1 -0
- package/dist/routes/webhook.js +39 -0
- package/dist/routes/webhook.js.map +1 -0
- package/dist/sync.d.ts +58 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +202 -0
- package/dist/sync.js.map +1 -0
- package/dist/tools/billing.d.ts +4 -0
- package/dist/tools/billing.d.ts.map +1 -0
- package/dist/tools/billing.js +125 -0
- package/dist/tools/billing.js.map +1 -0
- package/dist/tools/keys.d.ts +4 -0
- package/dist/tools/keys.d.ts.map +1 -0
- package/dist/tools/keys.js +107 -0
- package/dist/tools/keys.js.map +1 -0
- package/dist/tools/register.d.ts +20 -0
- package/dist/tools/register.d.ts.map +1 -0
- package/dist/tools/register.js +87 -0
- package/dist/tools/register.js.map +1 -0
- package/dist/types.d.ts +90 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +28 -0
- package/dist/types.js.map +1 -0
- package/dist/util/clearout.d.ts +5 -0
- package/dist/util/clearout.d.ts.map +1 -0
- package/dist/util/clearout.js +18 -0
- package/dist/util/clearout.js.map +1 -0
- package/dist/workos.d.ts +6 -0
- package/dist/workos.d.ts.map +1 -0
- package/dist/workos.js +24 -0
- package/dist/workos.js.map +1 -0
- package/package.json +81 -0
package/dist/billing.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import Stripe from "stripe";
|
|
2
|
+
// Token model: 1 token = 1 cent. Held in the Stripe customer credit balance,
|
|
3
|
+
// where a negative balance = available credit. All functions keyed on a
|
|
4
|
+
// stripeCustomerId are pure Stripe math (identical across host apps); the
|
|
5
|
+
// customer-id pointer itself is stored by the host via the adapter.
|
|
6
|
+
// One memoized Stripe client for the whole lib (lazy — never construct at
|
|
7
|
+
// import; STRIPE_SECRET_KEY may be unset at module load in dev).
|
|
8
|
+
let _stripe = null;
|
|
9
|
+
export function getStripe() {
|
|
10
|
+
return (_stripe ??= new Stripe(process.env.STRIPE_SECRET_KEY));
|
|
11
|
+
}
|
|
12
|
+
export function stripeConfigured() {
|
|
13
|
+
return !!process.env.STRIPE_SECRET_KEY;
|
|
14
|
+
}
|
|
15
|
+
function toStripePrice(p) {
|
|
16
|
+
const product = typeof p.product === "object" && p.product && !("deleted" in p.product)
|
|
17
|
+
? p.product
|
|
18
|
+
: null;
|
|
19
|
+
return {
|
|
20
|
+
id: p.id,
|
|
21
|
+
productId: product?.id ?? (typeof p.product === "string" ? p.product : null),
|
|
22
|
+
productName: product?.name ?? null,
|
|
23
|
+
lookupKey: p.lookup_key ?? null,
|
|
24
|
+
nickname: p.nickname ?? null,
|
|
25
|
+
unitAmount: p.unit_amount,
|
|
26
|
+
currency: p.currency,
|
|
27
|
+
interval: p.recurring?.interval ?? null,
|
|
28
|
+
intervalCount: p.recurring?.interval_count ?? null,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** All active recurring (subscription) prices on the Stripe account. Uses the
|
|
32
|
+
* SDK's async auto-pagination so accounts with >1 page of prices aren't
|
|
33
|
+
* silently truncated. */
|
|
34
|
+
export async function listSubscriptionPrices() {
|
|
35
|
+
const out = [];
|
|
36
|
+
for await (const p of getStripe().prices.list({
|
|
37
|
+
active: true,
|
|
38
|
+
type: "recurring",
|
|
39
|
+
limit: 100,
|
|
40
|
+
expand: ["data.product"],
|
|
41
|
+
})) {
|
|
42
|
+
out.push(toStripePrice(p));
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
/** Resolve a single subscription price without any env config. Resolution
|
|
47
|
+
* order: explicit `priceId` → matching `lookupKey` → the sole recurring price.
|
|
48
|
+
* Returns null if nothing matches or the choice is ambiguous (multiple prices,
|
|
49
|
+
* no lookupKey) — the caller can then list options via listSubscriptionPrices.
|
|
50
|
+
* The priceId/lookupKey paths query Stripe directly (no full-list scan). */
|
|
51
|
+
export async function resolveSubscriptionPrice(opts = {}) {
|
|
52
|
+
const stripe = getStripe();
|
|
53
|
+
if (opts.priceId) {
|
|
54
|
+
try {
|
|
55
|
+
const p = await stripe.prices.retrieve(opts.priceId, { expand: ["product"] });
|
|
56
|
+
return p.active ? toStripePrice(p) : null;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (opts.lookupKey) {
|
|
63
|
+
const r = await stripe.prices.list({
|
|
64
|
+
lookup_keys: [opts.lookupKey],
|
|
65
|
+
active: true,
|
|
66
|
+
limit: 1,
|
|
67
|
+
expand: ["data.product"],
|
|
68
|
+
});
|
|
69
|
+
if (r.data[0])
|
|
70
|
+
return toStripePrice(r.data[0]);
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const all = await listSubscriptionPrices();
|
|
74
|
+
return all.length === 1 ? all[0] : null;
|
|
75
|
+
}
|
|
76
|
+
export async function getBillingCustomerId(adapter, orgId) {
|
|
77
|
+
return adapter.getBillingCustomerId(orgId);
|
|
78
|
+
}
|
|
79
|
+
// Idempotent: return the org's Stripe customer id, creating the customer +
|
|
80
|
+
// welcome credit and persisting the pointer via the adapter on first use.
|
|
81
|
+
export async function ensureStripeCustomer(adapter, orgId, email, config) {
|
|
82
|
+
const existing = await adapter.getBillingCustomerId(orgId);
|
|
83
|
+
if (existing)
|
|
84
|
+
return existing;
|
|
85
|
+
const stripe = getStripe();
|
|
86
|
+
const customer = await stripe.customers.create({
|
|
87
|
+
email,
|
|
88
|
+
metadata: { org_id: orgId },
|
|
89
|
+
});
|
|
90
|
+
if (config.freeTokens > 0) {
|
|
91
|
+
// Idempotency key so a race on first-use (two concurrent callers) can't
|
|
92
|
+
// grant the welcome bonus twice for the same org.
|
|
93
|
+
await stripe.customers.createBalanceTransaction(customer.id, {
|
|
94
|
+
amount: -config.freeTokens,
|
|
95
|
+
currency: config.currency,
|
|
96
|
+
description: `Welcome bonus: ${config.freeTokens} free tokens`,
|
|
97
|
+
}, { idempotencyKey: `welcome:${orgId}` });
|
|
98
|
+
}
|
|
99
|
+
await adapter.setBillingCustomerId(orgId, customer.id);
|
|
100
|
+
return customer.id;
|
|
101
|
+
}
|
|
102
|
+
export async function getTokenBalance(stripeCustomerId) {
|
|
103
|
+
const customer = await getStripe().customers.retrieve(stripeCustomerId);
|
|
104
|
+
if (customer.deleted)
|
|
105
|
+
return 0;
|
|
106
|
+
return -customer.balance; // negative balance = credit
|
|
107
|
+
}
|
|
108
|
+
export async function deductTokens(stripeCustomerId, toolName, cost, currency) {
|
|
109
|
+
await getStripe().customers.createBalanceTransaction(stripeCustomerId, {
|
|
110
|
+
amount: cost, // positive = debit
|
|
111
|
+
currency,
|
|
112
|
+
description: `Tool call: ${toolName} (${cost} tokens)`,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
export async function creditTokens(stripeCustomerId, amount, description, currency,
|
|
116
|
+
/** Pass a stable key (e.g. the source invoice/session id) so replayed events
|
|
117
|
+
* — a re-delivered webhook, an overlapping poll — credit exactly once. */
|
|
118
|
+
idempotencyKey) {
|
|
119
|
+
await getStripe().customers.createBalanceTransaction(stripeCustomerId, {
|
|
120
|
+
amount: -amount, // negative = credit
|
|
121
|
+
currency,
|
|
122
|
+
description,
|
|
123
|
+
}, idempotencyKey ? { idempotencyKey } : undefined);
|
|
124
|
+
}
|
|
125
|
+
export async function createTokenCheckoutSession(stripeCustomerId, orgId, amountMajor, config) {
|
|
126
|
+
const amountMinor = Math.round(amountMajor * 100);
|
|
127
|
+
const tokens = amountMinor; // 1 token = 1 minor unit
|
|
128
|
+
const session = await getStripe().checkout.sessions.create({
|
|
129
|
+
customer: stripeCustomerId,
|
|
130
|
+
mode: "payment",
|
|
131
|
+
// No payment_method_types → Checkout auto-offers every method enabled in the
|
|
132
|
+
// Dashboard (cards + Apple Pay / Google Pay / Link), maximizing conversion.
|
|
133
|
+
line_items: [
|
|
134
|
+
{
|
|
135
|
+
price_data: {
|
|
136
|
+
currency: config.currency,
|
|
137
|
+
product_data: {
|
|
138
|
+
name: `${tokens} tokens`,
|
|
139
|
+
description: `${amountMajor} = ${tokens} tokens`,
|
|
140
|
+
},
|
|
141
|
+
unit_amount: amountMinor,
|
|
142
|
+
},
|
|
143
|
+
quantity: 1,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
invoice_creation: { enabled: true },
|
|
147
|
+
payment_intent_data: {
|
|
148
|
+
setup_future_usage: "off_session",
|
|
149
|
+
metadata: { org_id: orgId, tokens: String(tokens) },
|
|
150
|
+
},
|
|
151
|
+
metadata: { org_id: orgId, tokens: String(tokens) },
|
|
152
|
+
success_url: `${config.baseUrl}/billing/success?tokens=${tokens}`,
|
|
153
|
+
cancel_url: `${config.baseUrl}/billing/cancel`,
|
|
154
|
+
});
|
|
155
|
+
return session.url;
|
|
156
|
+
}
|
|
157
|
+
/** A Stripe Billing Portal session URL — the no-code self-serve surface where a
|
|
158
|
+
* customer manages their subscription (upgrade/downgrade/cancel), updates the
|
|
159
|
+
* payment method (fixes a failing card), and views invoices. */
|
|
160
|
+
export async function createBillingPortalSession(stripeCustomerId, returnUrl) {
|
|
161
|
+
const session = await getStripe().billingPortal.sessions.create({
|
|
162
|
+
customer: stripeCustomerId,
|
|
163
|
+
return_url: returnUrl,
|
|
164
|
+
});
|
|
165
|
+
return session.url;
|
|
166
|
+
}
|
|
167
|
+
export async function getAutoReloadSettings(stripeCustomerId) {
|
|
168
|
+
const customer = await getStripe().customers.retrieve(stripeCustomerId);
|
|
169
|
+
if (customer.deleted)
|
|
170
|
+
return null;
|
|
171
|
+
const meta = customer.metadata;
|
|
172
|
+
if (meta.auto_reload_enabled !== "true")
|
|
173
|
+
return null;
|
|
174
|
+
return {
|
|
175
|
+
enabled: true,
|
|
176
|
+
threshold: parseInt(meta.auto_reload_threshold || "0", 10),
|
|
177
|
+
reload_to: parseInt(meta.auto_reload_to || "0", 10),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
export async function setAutoReloadSettings(stripeCustomerId, threshold, reloadTo, enabled) {
|
|
181
|
+
await getStripe().customers.update(stripeCustomerId, {
|
|
182
|
+
metadata: {
|
|
183
|
+
auto_reload_enabled: String(enabled),
|
|
184
|
+
auto_reload_threshold: String(threshold),
|
|
185
|
+
auto_reload_to: String(reloadTo),
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
export async function tryAutoReload(stripeCustomerId, currency) {
|
|
190
|
+
const settings = await getAutoReloadSettings(stripeCustomerId);
|
|
191
|
+
if (!settings || !settings.enabled)
|
|
192
|
+
return;
|
|
193
|
+
const balance = await getTokenBalance(stripeCustomerId);
|
|
194
|
+
if (balance > settings.threshold)
|
|
195
|
+
return;
|
|
196
|
+
const tokensNeeded = settings.reload_to - balance;
|
|
197
|
+
if (tokensNeeded <= 0)
|
|
198
|
+
return;
|
|
199
|
+
const stripe = getStripe();
|
|
200
|
+
const pms = await stripe.paymentMethods.list({
|
|
201
|
+
customer: stripeCustomerId,
|
|
202
|
+
type: "card",
|
|
203
|
+
limit: 1,
|
|
204
|
+
});
|
|
205
|
+
if (pms.data.length === 0)
|
|
206
|
+
return;
|
|
207
|
+
try {
|
|
208
|
+
const pi = await stripe.paymentIntents.create({
|
|
209
|
+
amount: tokensNeeded,
|
|
210
|
+
currency,
|
|
211
|
+
customer: stripeCustomerId,
|
|
212
|
+
payment_method: pms.data[0].id,
|
|
213
|
+
off_session: true,
|
|
214
|
+
confirm: true,
|
|
215
|
+
description: `Auto-reload: ${tokensNeeded} tokens`,
|
|
216
|
+
metadata: { auto_reload: "true", tokens: String(tokensNeeded) },
|
|
217
|
+
});
|
|
218
|
+
if (pi.status === "succeeded") {
|
|
219
|
+
await creditTokens(stripeCustomerId, tokensNeeded, `Auto-reload: ${tokensNeeded} tokens`, currency);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// card declined / off-session failure — never block the triggering call
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
export async function listInvoices(stripeCustomerId, limit = 10) {
|
|
227
|
+
const stripe = getStripe();
|
|
228
|
+
const [invoices, charges] = await Promise.all([
|
|
229
|
+
stripe.invoices.list({ customer: stripeCustomerId, limit }),
|
|
230
|
+
stripe.charges.list({ customer: stripeCustomerId, limit }),
|
|
231
|
+
]);
|
|
232
|
+
const invoiceEntries = invoices.data.map((inv) => ({
|
|
233
|
+
id: inv.id,
|
|
234
|
+
type: "purchase",
|
|
235
|
+
number: inv.number,
|
|
236
|
+
amount: inv.amount_paid,
|
|
237
|
+
status: inv.status,
|
|
238
|
+
created: new Date(inv.created * 1000).toISOString(),
|
|
239
|
+
invoice_url: inv.hosted_invoice_url ?? null,
|
|
240
|
+
invoice_pdf: inv.invoice_pdf ?? null,
|
|
241
|
+
}));
|
|
242
|
+
const autoReloadCharges = charges.data
|
|
243
|
+
.filter((ch) => ch.metadata?.auto_reload === "true" && ch.status === "succeeded")
|
|
244
|
+
.map((ch) => ({
|
|
245
|
+
id: ch.id,
|
|
246
|
+
type: "auto_reload",
|
|
247
|
+
number: null,
|
|
248
|
+
amount: ch.amount,
|
|
249
|
+
status: ch.status,
|
|
250
|
+
created: new Date(ch.created * 1000).toISOString(),
|
|
251
|
+
invoice_url: ch.receipt_url ?? null,
|
|
252
|
+
invoice_pdf: null,
|
|
253
|
+
}));
|
|
254
|
+
return [...invoiceEntries, ...autoReloadCharges]
|
|
255
|
+
.sort((a, b) => new Date(b.created).getTime() - new Date(a.created).getTime())
|
|
256
|
+
.slice(0, limit);
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=billing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"billing.js","sourceRoot":"","sources":["../src/billing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ApiClientConfig {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function callTool(config: ApiClientConfig, tool: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
6
|
+
export declare function listTools(config: ApiClientConfig): Promise<Array<{
|
|
7
|
+
name: string;
|
|
8
|
+
cost: number;
|
|
9
|
+
}>>;
|
|
10
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAOvG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export async function callTool(config, tool, args = {}) {
|
|
2
|
+
const res = await fetch(`${config.baseUrl}/api/v0/${tool}`, {
|
|
3
|
+
method: "POST",
|
|
4
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${config.apiKey}` },
|
|
5
|
+
body: JSON.stringify(args),
|
|
6
|
+
});
|
|
7
|
+
if (!res.ok) {
|
|
8
|
+
const text = await res.text().catch(() => "");
|
|
9
|
+
throw new Error(`${tool} failed (${res.status}): ${text}`);
|
|
10
|
+
}
|
|
11
|
+
return res.json();
|
|
12
|
+
}
|
|
13
|
+
export async function listTools(config) {
|
|
14
|
+
const res = await fetch(`${config.baseUrl}/api/v0`, {
|
|
15
|
+
headers: { Authorization: `Bearer ${config.apiKey}` },
|
|
16
|
+
});
|
|
17
|
+
if (!res.ok)
|
|
18
|
+
throw new Error(`Failed to list tools: ${res.status}`);
|
|
19
|
+
const data = (await res.json());
|
|
20
|
+
return data.tools;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAuB,EACvB,IAAY,EACZ,OAAgC,EAAE;IAElC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,WAAW,IAAI,EAAE,EAAE;QAC1D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE,EAAE;QACzF,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,YAAY,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAuB;IACrD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,SAAS,EAAE;QAClD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE,EAAE;KACtD,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqD,CAAC;IACpF,OAAO,IAAI,CAAC,KAAK,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EACL,KAAK,UAAU,EAMhB,MAAM,aAAa,CAAC;AAyBrB,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,QAwEzE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { rmSync } from "node:fs";
|
|
2
|
+
import { callTool } from "./client.js";
|
|
3
|
+
import { configPath, readConfig, writeConfig, resolveBaseUrl, resolveApiKey, } from "./config.js";
|
|
4
|
+
function extractApiKey(result) {
|
|
5
|
+
const visit = (v) => {
|
|
6
|
+
if (typeof v === "string") {
|
|
7
|
+
const m = v.match(/sk_[A-Za-z0-9_-]+/);
|
|
8
|
+
return m ? m[0] : undefined;
|
|
9
|
+
}
|
|
10
|
+
if (v && typeof v === "object") {
|
|
11
|
+
for (const x of Object.values(v)) {
|
|
12
|
+
const found = visit(x);
|
|
13
|
+
if (found)
|
|
14
|
+
return found;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
};
|
|
19
|
+
return visit(result);
|
|
20
|
+
}
|
|
21
|
+
function print(data) {
|
|
22
|
+
console.log(JSON.stringify(data, null, 2));
|
|
23
|
+
}
|
|
24
|
+
// Register the shared billing commands on a commander program (or subcommand).
|
|
25
|
+
// Reads global options --api-key / --url off `program`.
|
|
26
|
+
export function registerBillingCommands(program, opts) {
|
|
27
|
+
const requireConfig = () => {
|
|
28
|
+
const apiKey = resolveApiKey(opts, program.opts().apiKey);
|
|
29
|
+
if (!apiKey) {
|
|
30
|
+
console.error(`Error: API key required. Run 'auth <email> --code <code>' to log in,`);
|
|
31
|
+
console.error(`or pass --api-key / set ${opts.envPrefix}_API_KEY.`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
return { baseUrl: resolveBaseUrl(opts, program.opts().url), apiKey };
|
|
35
|
+
};
|
|
36
|
+
program
|
|
37
|
+
.command("auth <email>")
|
|
38
|
+
.description("Get an API key via email + 6-digit code")
|
|
39
|
+
.option("--code <code>", "6-digit verification code from email")
|
|
40
|
+
.action(async (email, o) => {
|
|
41
|
+
const baseUrl = resolveBaseUrl(opts, program.opts().url);
|
|
42
|
+
const apiKey = resolveApiKey(opts, program.opts().apiKey) || "bootstrap";
|
|
43
|
+
const args = { email };
|
|
44
|
+
if (o.code)
|
|
45
|
+
args.code = o.code;
|
|
46
|
+
const result = await callTool({ baseUrl, apiKey }, "get_api_key", args);
|
|
47
|
+
print(result);
|
|
48
|
+
const key = extractApiKey(result);
|
|
49
|
+
if (key) {
|
|
50
|
+
writeConfig(opts, { ...readConfig(opts), apiKey: key, email, baseUrl });
|
|
51
|
+
console.error(`\n✓ Logged in as ${email}. Credentials saved to ${configPath(opts)}.`);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
program
|
|
55
|
+
.command("logout")
|
|
56
|
+
.description("Sign out by clearing local credentials")
|
|
57
|
+
.action(() => {
|
|
58
|
+
try {
|
|
59
|
+
rmSync(configPath(opts), { force: true });
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
/* best effort */
|
|
63
|
+
}
|
|
64
|
+
console.log(`✓ Signed out. Removed ${configPath(opts)}.`);
|
|
65
|
+
});
|
|
66
|
+
program
|
|
67
|
+
.command("balance")
|
|
68
|
+
.description("Get current token balance and tool costs")
|
|
69
|
+
.action(async () => print(await callTool(requireConfig(), "get_token_balance")));
|
|
70
|
+
program
|
|
71
|
+
.command("buy <amount>")
|
|
72
|
+
.description("Buy tokens (returns a Stripe Checkout URL)")
|
|
73
|
+
.action(async (amount) => print(await callTool(requireConfig(), "buy_tokens", { amount: parseInt(amount, 10) })));
|
|
74
|
+
program
|
|
75
|
+
.command("invoices")
|
|
76
|
+
.description("List recent invoices")
|
|
77
|
+
.option("--limit <n>", "Number to return (default 10)", (v) => parseInt(v, 10))
|
|
78
|
+
.action(async (o) => {
|
|
79
|
+
const args = {};
|
|
80
|
+
if (o.limit)
|
|
81
|
+
args.limit = o.limit;
|
|
82
|
+
print(await callTool(requireConfig(), "list_invoices", args));
|
|
83
|
+
});
|
|
84
|
+
const keys = program.command("keys").description("List and revoke API keys");
|
|
85
|
+
keys
|
|
86
|
+
.command("list")
|
|
87
|
+
.description("List API keys")
|
|
88
|
+
.action(async () => print(await callTool(requireConfig(), "list_api_keys")));
|
|
89
|
+
keys
|
|
90
|
+
.command("revoke <id>")
|
|
91
|
+
.description("Revoke an API key by id")
|
|
92
|
+
.action(async (id) => print(await callTool(requireConfig(), "revoke_api_key", { api_key_id: id })));
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface CliOptions {
|
|
2
|
+
configDir: string;
|
|
3
|
+
envPrefix: string;
|
|
4
|
+
defaultUrl: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CliConfig {
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
email?: string;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function configPath(opts: CliOptions): string;
|
|
12
|
+
export declare function readConfig(opts: CliOptions): CliConfig;
|
|
13
|
+
export declare function writeConfig(opts: CliOptions, c: CliConfig): void;
|
|
14
|
+
export declare function resolveBaseUrl(opts: CliOptions, cliUrl?: string): string;
|
|
15
|
+
export declare function resolveApiKey(opts: CliOptions, cliKey?: string): string | undefined;
|
|
16
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEnD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAQtD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,GAAG,IAAI,CAShE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join, isAbsolute } from "node:path";
|
|
4
|
+
function expandHome(p) {
|
|
5
|
+
if (p === "~" || p.startsWith("~/"))
|
|
6
|
+
return join(homedir(), p.slice(1));
|
|
7
|
+
return isAbsolute(p) ? p : join(homedir(), p);
|
|
8
|
+
}
|
|
9
|
+
export function configPath(opts) {
|
|
10
|
+
return join(expandHome(opts.configDir), "config.json");
|
|
11
|
+
}
|
|
12
|
+
export function readConfig(opts) {
|
|
13
|
+
const p = configPath(opts);
|
|
14
|
+
if (!existsSync(p))
|
|
15
|
+
return {};
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(readFileSync(p, "utf-8"));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function writeConfig(opts, c) {
|
|
24
|
+
const p = configPath(opts);
|
|
25
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
26
|
+
writeFileSync(p, JSON.stringify(c, null, 2));
|
|
27
|
+
try {
|
|
28
|
+
chmodSync(p, 0o600);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
/* best effort */
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function resolveBaseUrl(opts, cliUrl) {
|
|
35
|
+
return cliUrl || process.env[`${opts.envPrefix}_API_URL`] || readConfig(opts).baseUrl || opts.defaultUrl;
|
|
36
|
+
}
|
|
37
|
+
export function resolveApiKey(opts, cliKey) {
|
|
38
|
+
return cliKey || process.env[`${opts.envPrefix}_API_KEY`] || readConfig(opts).apiKey;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAkBtD,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAgB;IACzC,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAgB;IACzC,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAc,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAgB,EAAE,CAAY;IACxD,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3B,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7C,IAAI,CAAC;QACH,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAgB,EAAE,MAAe;IAC9D,OAAO,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,UAAU,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC;AAC3G,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAgB,EAAE,MAAe;IAC7D,OAAO,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,UAAU,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACvF,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { BillingAdapter, BillingConfig } from "./types.js";
|
|
3
|
+
import { type AgentAuthBranding, type AgentAuthPaths, type AgentAuthPolicy, type AgentIdentityType } from "./agent-auth/index.js";
|
|
4
|
+
import type { ClaimStore } from "./agent-auth/claim-store.js";
|
|
5
|
+
import type { PlansConfig } from "./plans.js";
|
|
6
|
+
export interface CreateBillingOptions {
|
|
7
|
+
/** Storage adapter (WorkOSOrgAdapter or your own). */
|
|
8
|
+
adapter: BillingAdapter;
|
|
9
|
+
/** Billing config; resolved once internally. */
|
|
10
|
+
config: BillingConfig;
|
|
11
|
+
/** Per-tool token costs (echoed by get_token_balance + the REST tool list). */
|
|
12
|
+
toolCosts?: Record<string, number>;
|
|
13
|
+
/** WWW-Authenticate realm on 401s. */
|
|
14
|
+
realm?: string;
|
|
15
|
+
/** Declarative plans → auto-provisioned Stripe products/prices + list_plans. */
|
|
16
|
+
plans?: PlansConfig;
|
|
17
|
+
defaultPlan?: string;
|
|
18
|
+
/** Register your app's own product tools alongside the billing tools. */
|
|
19
|
+
registerTools?: (server: McpServer) => void;
|
|
20
|
+
/** Enable auth.md agent self-registration. Omit to leave it off. */
|
|
21
|
+
agentAuth?: {
|
|
22
|
+
branding: AgentAuthBranding;
|
|
23
|
+
identityTypes?: AgentIdentityType[];
|
|
24
|
+
baseUrl?: string | ((request: Request) => string);
|
|
25
|
+
policy?: AgentAuthPolicy;
|
|
26
|
+
asMetadataExtra?: Record<string, unknown>;
|
|
27
|
+
paths?: AgentAuthPaths;
|
|
28
|
+
claimStore?: ClaimStore;
|
|
29
|
+
};
|
|
30
|
+
/** Stripe webhook handler. Defaults on (currency from config); `false` to skip. */
|
|
31
|
+
webhook?: {
|
|
32
|
+
currency?: string;
|
|
33
|
+
} | false;
|
|
34
|
+
/** MCP transport overrides. */
|
|
35
|
+
mcp?: {
|
|
36
|
+
apiKeyPrefix?: string;
|
|
37
|
+
maxDuration?: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export declare function createBilling(opts: CreateBillingOptions): {
|
|
41
|
+
adapter: BillingAdapter;
|
|
42
|
+
config: Required<BillingConfig>;
|
|
43
|
+
register: (server: McpServer) => void;
|
|
44
|
+
dispatcher: {
|
|
45
|
+
dispatchTool: (name: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
46
|
+
getToolNames: () => string[];
|
|
47
|
+
};
|
|
48
|
+
/** MCP transport: mount `export const { GET, POST } = mcp` in app/[transport]/route.ts. */
|
|
49
|
+
mcp: {
|
|
50
|
+
GET: (request: Request) => Promise<Response>;
|
|
51
|
+
POST: (request: Request) => Promise<Response>;
|
|
52
|
+
maxDuration: number;
|
|
53
|
+
};
|
|
54
|
+
/** GET /api/v0 tool list handler. */
|
|
55
|
+
restList: (request: Request) => Promise<Response>;
|
|
56
|
+
/** POST /api/v0/[tool] dispatch handler. */
|
|
57
|
+
restDispatch: (request: Request, ctx: {
|
|
58
|
+
params: Promise<{
|
|
59
|
+
tool: string;
|
|
60
|
+
}>;
|
|
61
|
+
}) => Promise<Response>;
|
|
62
|
+
/** Stripe webhook POST handler (undefined if `webhook: false`). */
|
|
63
|
+
webhook: ((request: Request) => Promise<Response>) | undefined;
|
|
64
|
+
/** auth.md handlers (undefined unless `agentAuth` was configured). */
|
|
65
|
+
agentAuth: {
|
|
66
|
+
protectedResource: (request: Request) => Response;
|
|
67
|
+
authorizationServer: (request: Request) => Response;
|
|
68
|
+
authMd: (request: Request) => Response;
|
|
69
|
+
identity: (request: Request) => Promise<Response>;
|
|
70
|
+
claim: (request: Request) => Promise<Response>;
|
|
71
|
+
token: (request: Request) => Promise<Response>;
|
|
72
|
+
handleClaimGrant: (params: Record<string, string>) => Promise<Response>;
|
|
73
|
+
revoke: (request: Request) => Promise<Response>;
|
|
74
|
+
resourceMetadataUrl: (request: Request) => string;
|
|
75
|
+
wwwAuthenticate: (request: Request) => string;
|
|
76
|
+
} | undefined;
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=create-billing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-billing.d.ts","sourceRoot":"","sources":["../src/create-billing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhE,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQ9C,MAAM,WAAW,oBAAoB;IACnC,sDAAsD;IACtD,OAAO,EAAE,cAAc,CAAC;IACxB,gDAAgD;IAChD,MAAM,EAAE,aAAa,CAAC;IACtB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5C,oEAAoE;IACpE,SAAS,CAAC,EAAE;QACV,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;QACpC,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,EAAE,eAAe,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,KAAK,CAAC,EAAE,cAAc,CAAC;QACvB,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB,CAAC;IACF,mFAAmF;IACnF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACxC,+BAA+B;IAC/B,GAAG,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,oBAAoB;;;uBAY5B,SAAS;;;;;IAiCjC,2FAA2F;;;;;;IAE3F,qCAAqC;;IAErC,4CAA4C;;;;;;IAE5C,mEAAmE;;IAEnE,sEAAsE;;;;;;;;;;;;;EAGzE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { resolveConfig } from "./types.js";
|
|
2
|
+
import { registerBillingTools } from "./tools/register.js";
|
|
3
|
+
import { createDispatcher } from "./dispatch.js";
|
|
4
|
+
import { createToolListHandler, createToolDispatchHandler } from "./routes/rest.js";
|
|
5
|
+
import { createMcpTransport } from "./routes/mcp.js";
|
|
6
|
+
import { createStripeWebhookHandler } from "./routes/webhook.js";
|
|
7
|
+
import { createAgentAuth, } from "./agent-auth/index.js";
|
|
8
|
+
export function createBilling(opts) {
|
|
9
|
+
const resolved = resolveConfig(opts.config);
|
|
10
|
+
const agentAuth = opts.agentAuth
|
|
11
|
+
? createAgentAuth({ adapter: opts.adapter, config: resolved, ...opts.agentAuth })
|
|
12
|
+
: undefined;
|
|
13
|
+
const resourceMetadata = agentAuth
|
|
14
|
+
? (request) => agentAuth.resourceMetadataUrl(request)
|
|
15
|
+
: undefined;
|
|
16
|
+
// ONE registrar used by both the dispatcher (REST shadow server) and the live
|
|
17
|
+
// MCP server, so the two surfaces expose an identical tool set.
|
|
18
|
+
const register = (server) => {
|
|
19
|
+
registerBillingTools(server, {
|
|
20
|
+
adapter: opts.adapter,
|
|
21
|
+
config: resolved,
|
|
22
|
+
toolCosts: opts.toolCosts,
|
|
23
|
+
plans: opts.plans,
|
|
24
|
+
defaultPlan: opts.defaultPlan,
|
|
25
|
+
});
|
|
26
|
+
opts.registerTools?.(server);
|
|
27
|
+
};
|
|
28
|
+
const dispatcher = createDispatcher(register);
|
|
29
|
+
const restList = createToolListHandler({ dispatcher, toolCosts: opts.toolCosts });
|
|
30
|
+
const restDispatch = createToolDispatchHandler({ dispatcher, realm: opts.realm, resourceMetadata });
|
|
31
|
+
const mcp = createMcpTransport({
|
|
32
|
+
register,
|
|
33
|
+
adapter: opts.adapter,
|
|
34
|
+
realm: opts.realm,
|
|
35
|
+
apiKeyPrefix: opts.mcp?.apiKeyPrefix,
|
|
36
|
+
maxDuration: opts.mcp?.maxDuration,
|
|
37
|
+
resourceMetadata,
|
|
38
|
+
});
|
|
39
|
+
const webhook = opts.webhook === false
|
|
40
|
+
? undefined
|
|
41
|
+
: createStripeWebhookHandler({ currency: opts.webhook?.currency ?? resolved.currency });
|
|
42
|
+
return {
|
|
43
|
+
adapter: opts.adapter,
|
|
44
|
+
config: resolved,
|
|
45
|
+
register,
|
|
46
|
+
dispatcher,
|
|
47
|
+
/** MCP transport: mount `export const { GET, POST } = mcp` in app/[transport]/route.ts. */
|
|
48
|
+
mcp,
|
|
49
|
+
/** GET /api/v0 tool list handler. */
|
|
50
|
+
restList,
|
|
51
|
+
/** POST /api/v0/[tool] dispatch handler. */
|
|
52
|
+
restDispatch,
|
|
53
|
+
/** Stripe webhook POST handler (undefined if `webhook: false`). */
|
|
54
|
+
webhook,
|
|
55
|
+
/** auth.md handlers (undefined unless `agentAuth` was configured). */
|
|
56
|
+
agentAuth,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=create-billing.js.map
|
|
@@ -0,0 +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,EAAE,MAAM,qBAAqB,CAAC;AAC3D,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,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EACL,eAAe,GAKhB,MAAM,uBAAuB,CAAC;AAwC/B,MAAM,UAAU,aAAa,CAAC,IAA0B;IACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS;QAC9B,CAAC,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACjF,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,gBAAgB,GAAG,SAAS;QAChC,CAAC,CAAC,CAAC,OAAgB,EAAE,EAAE,CAAC,SAAS,CAAC,mBAAmB,CAAC,OAAO,CAAC;QAC9D,CAAC,CAAC,SAAS,CAAC;IAEd,8EAA8E;IAC9E,gEAAgE;IAChE,MAAM,QAAQ,GAAG,CAAC,MAAiB,EAAE,EAAE;QACrC,oBAAoB,CAAC,MAAM,EAAE;YAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAClF,MAAM,YAAY,GAAG,yBAAyB,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACpG,MAAM,GAAG,GAAG,kBAAkB,CAAC;QAC7B,QAAQ;QACR,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,YAAY;QACpC,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,WAAW;QAClC,gBAAgB;KACjB,CAAC,CAAC;IACH,MAAM,OAAO,GACX,IAAI,CAAC,OAAO,KAAK,KAAK;QACpB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,0BAA0B,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE5F,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,QAAQ;QAChB,QAAQ;QACR,UAAU;QACV,2FAA2F;QAC3F,GAAG;QACH,qCAAqC;QACrC,QAAQ;QACR,4CAA4C;QAC5C,YAAY;QACZ,mEAAmE;QACnE,OAAO;QACP,sEAAsE;QACtE,SAAS;KACV,CAAC;AACJ,CAAC"}
|