@voltro/plugin-billing 0.85.0 → 0.86.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.
@@ -0,0 +1,74 @@
1
+ import { periodKey as e } from "./service.js";
2
+ import { Effect as t } from "effect";
3
+ import { OccurrenceCounter as n, changeDigest as r, composeChangeKey as i, gte as a, occurrenceWindowMs as o } from "@voltro/database";
4
+ //#region src/metering.ts
5
+ var s = "_voltro_ai_usage", c = (e) => {
6
+ for (let [t, n] of Object.entries(e)) {
7
+ if (t.length === 0) throw Error("billing metering: a meter key must be non-empty");
8
+ if (n.from === "rpc") {
9
+ if (n.match === void 0 || typeof n.match == "string" && n.match.length === 0) throw Error(`billing metering: rpc meter '${t}' needs a non-empty 'match'`);
10
+ } else if (n.from === "cdc") {
11
+ if (typeof n.table != "string" || n.table.length === 0) throw Error(`billing metering: cdc meter '${t}' needs a 'table'`);
12
+ } else if (n.from !== "ai") throw Error(`billing metering: meter '${t}' has unknown source '${String(n.from)}'`);
13
+ }
14
+ }, l = /* @__PURE__ */ new WeakMap(), u = (e) => {
15
+ if (!e.global && !e.sticky) return e;
16
+ let t = l.get(e);
17
+ return t === void 0 && (t = new RegExp(e.source, e.flags.replace(/[gy]/g, "")), l.set(e, t)), t;
18
+ }, d = (e, t) => typeof e == "string" ? t === e : u(e).test(t), f = (e, t, n) => Object.entries(e).filter(([, e]) => e.from === "rpc" && (e.kind === void 0 || e.kind === n) && d(e.match, t)).map(([e]) => e), p = (e, t, n) => Object.entries(e).filter(([, e]) => e.from === "cdc" && e.table === t && (e.op ?? "insert") === n).map(([e]) => e), m = (e) => Object.entries(e).filter(([, e]) => e.from === "ai").map(([e, t]) => [e, t.metric ?? "tokens"]), h = (e) => e.tenantId, g = (e, n, r, i) => t.forEach(r, (r) => e.reportUsage(n, r, i).pipe(t.catch(() => t.void)), { discard: !0 }), _ = (e, n) => (r, i) => {
19
+ let a = f(n, i.tag, i.kind);
20
+ if (a.length === 0) return r;
21
+ let o = h(i.subject);
22
+ return o === null ? r : r.pipe(t.tap(() => g(e, o, a, 1)));
23
+ }, v = "billing-meter", y = 5e4, b = (e, a, s = {}) => {
24
+ let c = new n({
25
+ windowMs: o(),
26
+ maxEntries: y
27
+ }), l = s.now ?? (() => Date.now()), u = !1;
28
+ return (n) => {
29
+ let o = p(a, n.table, n.op);
30
+ if (o.length === 0) return t.void;
31
+ let d = n.new?.tenantId ?? n.old?.tenantId ?? null;
32
+ if (d === null) return t.void;
33
+ let f = s.claimChange?.();
34
+ if (f === void 0) return u || (u = !0, s.onUngated?.()), g(e, d, o, 1);
35
+ let m = String(n.new?.id ?? n.old?.id ?? ""), h = r({
36
+ pipe: v,
37
+ op: n.op,
38
+ key: m,
39
+ next: n.new ?? null,
40
+ prev: n.old ?? null
41
+ }), _ = i(h, c.next(h, l()));
42
+ return t.promise(() => f(v, _)).pipe(t.flatMap((n) => n ? g(e, d, o, 1) : t.void));
43
+ };
44
+ }, x = (e) => new Date(Date.UTC(e.getUTCFullYear(), e.getUTCMonth(), 1, 0, 0, 0, 0)), S = (n, r, i, o = () => /* @__PURE__ */ new Date()) => t.gen(function* () {
45
+ let c = m(i);
46
+ if (c.length === 0) return;
47
+ let l = o();
48
+ e(l);
49
+ let u = {
50
+ table: s,
51
+ predicate: a("calledAt", x(l)),
52
+ order: [],
53
+ take: void 0,
54
+ skip: void 0,
55
+ projection: void 0
56
+ }, d = yield* t.promise(() => Promise.resolve(r.query(u)).then((e) => e).catch(() => [])), f = /* @__PURE__ */ new Map();
57
+ for (let e of d) {
58
+ let t = e.tenantId ?? null;
59
+ if (t === null) continue;
60
+ let n = f.get(t) ?? {
61
+ tokens: 0,
62
+ cost: 0
63
+ };
64
+ n.tokens += (Number(e.inputTokens) || 0) + (Number(e.outputTokens) || 0), n.cost += Number(e.costMicroUsd) || 0, f.set(t, n);
65
+ }
66
+ for (let [e, r] of c) for (let [i, a] of f) {
67
+ let o = r === "costMicroUsd" ? a.cost : a.tokens;
68
+ if (o <= 0) continue;
69
+ let s = o - (yield* n.checkEntitlement(i, e, 0).pipe(t.map((e) => e.used), t.catch(() => t.succeed(0))));
70
+ s > 0 && (yield* n.reportUsage(i, e, s).pipe(t.catch(() => t.void)));
71
+ }
72
+ }), C = (e, n, r, i) => S(e, n, r, i).pipe(t.andThen(e.flushUsage().pipe(t.catch(() => t.void)))), w = (e) => Object.values(e).some((e) => e.from === "cdc");
73
+ //#endregion
74
+ export { v as METERING_CLAIM_SCOPE, b as buildMeteringChangeTap, _ as buildMeteringInterceptor, p as cdcMetersFor, w as hasCdcMeters, S as reconcileAiMeters, f as rpcMetersFor, C as runAutopilotFlush, c as validateMeteringConfig };
package/dist/plans.js ADDED
@@ -0,0 +1,24 @@
1
+ import { DEFAULT_PLAN as e } from "./types.js";
2
+ //#region src/plans.ts
3
+ var t = (e) => e === void 0 ? 0 : e === "unlimited" ? Infinity : e, n = (e) => {
4
+ let n = /* @__PURE__ */ new Map();
5
+ for (let [t, r] of Object.entries(e)) r.priceId !== void 0 && n.set(r.priceId, t);
6
+ return {
7
+ has: (t) => Object.prototype.hasOwnProperty.call(e, t),
8
+ entitlementLimit: (n, r) => {
9
+ let i = e[n];
10
+ return i === void 0 ? 0 : t(i.entitlements[r]);
11
+ },
12
+ planForPriceId: (e) => n.get(e) ?? null,
13
+ priceIdFor: (t) => e[t]?.priceId ?? null,
14
+ meteredPriceIdsFor: (t) => e[t]?.meteredPriceIds ?? [],
15
+ unitAmountFor: (t) => {
16
+ let n = e[t]?.unitAmountMinor;
17
+ return n !== void 0 && Number.isFinite(n) ? n : 0;
18
+ },
19
+ currencyFor: (t) => (e[t]?.currency ?? "usd").toLowerCase(),
20
+ planIds: () => Object.keys(e)
21
+ };
22
+ }, r = () => n({ [e]: { entitlements: {} } });
23
+ //#endregion
24
+ export { n as buildPlanRegistry, r as emptyPlanRegistry };
@@ -0,0 +1,133 @@
1
+ import { STRIPE_WEBHOOK_EVENTS as e, normalizeStripeEvent as t, stripeProvider as n } from "./stripeProvider.js";
2
+ import { Effect as r } from "effect";
3
+ //#region src/providers.ts
4
+ var i = (e) => {
5
+ let t = e?.baseUrl ?? "https://mock.billing.local", n = [], i = [], a = [], o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), l = [], u = [], d = [], f = [], p = [], m = [], h = /* @__PURE__ */ new Map(), g = [], _ = 0, v = (e, t) => {
6
+ let n = {
7
+ ...o.get(e) ?? {
8
+ status: "active",
9
+ plan: null,
10
+ quantity: 1,
11
+ currentPeriodStart: null,
12
+ currentPeriodEnd: null,
13
+ cancelAt: null
14
+ },
15
+ ...t
16
+ };
17
+ o.set(e, n);
18
+ let r = s.get(e);
19
+ return r !== void 0 && s.set(e, {
20
+ ...r,
21
+ ...t
22
+ }), n;
23
+ }, y = (e) => typeof e == "object" && !!e && typeof e._tag == "string";
24
+ return {
25
+ name: "mock",
26
+ supportsMeteredUsage: e?.supportsMeteredUsage ?? !0,
27
+ pushed: n,
28
+ updates: i,
29
+ fetched: a,
30
+ cancels: l,
31
+ resumes: u,
32
+ priceAdds: d,
33
+ checkouts: f,
34
+ customersCreated: p,
35
+ expiredFor: m,
36
+ setUndelivered: (e) => {
37
+ g = e;
38
+ },
39
+ undeliveredReads: () => _,
40
+ listUndeliveredEvents: () => r.sync(() => (_ += 1, g)),
41
+ ensureCustomer: (e) => r.sync(() => {
42
+ let t = h.get(e.tenantId);
43
+ if (t !== void 0) return t;
44
+ let n = `mock_cus_${e.tenantId}`;
45
+ return h.set(e.tenantId, n), p.push(e.tenantId), n;
46
+ }),
47
+ expireOpenCheckouts: (e) => r.sync(() => (m.push(e.providerCustomerId), 0)),
48
+ listSubscription: (e) => {
49
+ s.set(e.providerSubscriptionId, e), o.set(e.providerSubscriptionId, e);
50
+ },
51
+ setSubscription: (e, t) => {
52
+ t === null ? o.delete(e) : o.set(e, t);
53
+ },
54
+ setCustomerEmail: (e, t) => {
55
+ t === null ? c.delete(e) : c.set(e, t);
56
+ },
57
+ fetchSubscription: (e) => r.sync(() => (a.push(e), o.get(e) ?? null)),
58
+ listSubscriptions: (e) => r.sync(() => [...s.values()].filter((t) => t.status !== "canceled" && (e.providerCustomerId === void 0 || t.providerCustomerId === e.providerCustomerId))),
59
+ cancelSubscription: (e) => r.sync(() => {
60
+ l.push({
61
+ providerSubscriptionId: e.providerSubscriptionId,
62
+ mode: e.mode
63
+ });
64
+ let t = o.get(e.providerSubscriptionId);
65
+ return e.mode === "close" ? v(e.providerSubscriptionId, { cancelAt: new Date(Date.now() + 6e5) }) : v(e.providerSubscriptionId, { cancelAt: t?.currentPeriodEnd ?? /* @__PURE__ */ new Date(0) });
66
+ }),
67
+ resumeSubscription: (e) => r.sync(() => (u.push(e), v(e, { cancelAt: null }))),
68
+ addSubscriptionPrices: (e) => r.sync(() => {
69
+ d.push({
70
+ providerSubscriptionId: e.providerSubscriptionId,
71
+ priceIds: e.priceIds
72
+ });
73
+ let t = s.get(e.providerSubscriptionId);
74
+ t !== void 0 && v(e.providerSubscriptionId, { priceIds: [...t.priceIds, ...e.priceIds] });
75
+ }),
76
+ customerEmail: (e) => r.sync(() => c.get(e) ?? null),
77
+ createCheckoutSession: (e) => r.sync(() => (f.push(e), { url: `${t}/checkout?tenant=${encodeURIComponent(e.tenantId)}&price=${encodeURIComponent(e.priceId)}` })),
78
+ createPortalSession: (e) => r.succeed({ url: `${t}/portal?customer=${encodeURIComponent(e.providerCustomerId)}` }),
79
+ reportUsage: (e) => r.sync(() => {
80
+ n.push(e);
81
+ }),
82
+ updateSubscription: (e) => r.sync(() => (i.push(e), {
83
+ plan: e.priceId ?? "mock-plan",
84
+ quantity: e.quantity ?? 1,
85
+ prorationMinor: 0,
86
+ currency: "usd",
87
+ currentPeriodStart: null,
88
+ currentPeriodEnd: null
89
+ })),
90
+ previewSubscriptionChange: (e) => r.succeed({
91
+ plan: e.priceId ?? "mock-plan",
92
+ quantity: e.quantity ?? 1,
93
+ prorationMinor: 0,
94
+ currency: "usd",
95
+ currentPeriodStart: null,
96
+ currentPeriodEnd: null
97
+ }),
98
+ listInvoices: () => r.succeed([]),
99
+ normalizeEvent: (e) => r.succeed(y(e) ? e : null)
100
+ };
101
+ }, a = /* @__PURE__ */ new Set([
102
+ "",
103
+ "development",
104
+ "dev",
105
+ "test"
106
+ ]), o = (e) => !a.has((e ?? "").trim().toLowerCase()), s = (e) => {
107
+ if (o(e.env.NODE_ENV)) {
108
+ if (e.resolvedName === "mock" && e.providerOption === void 0) throw Error("billingPlugin: no STRIPE_SECRET_KEY in a production boot — refusing to run the MOCK billing provider, which answers every charge and subscription call successfully and reaches nobody. Set STRIPE_SECRET_KEY, or declare `billingPlugin({ provider: 'mock' })` if this deployment does not sell.");
109
+ if (e.resolvedName === "stripe") {
110
+ if (e.webhookSecret === null || e.webhookSecret.trim() === "") throw Error("billingPlugin: Stripe in a production boot needs STRIPE_WEBHOOK_SECRET — without it no provider event can be verified, so subscriptions, cancellations and payments would never reach this app.");
111
+ if (e.redirectOrigins === void 0 || e.redirectOrigins.length === 0) throw Error("billingPlugin: Stripe in a production boot needs `redirectOrigins` — the origins checkout and the customer portal may send a customer back to. Without it any URL a caller names is accepted.");
112
+ }
113
+ }
114
+ }, c = (e) => {
115
+ let { provider: t, env: r } = e;
116
+ if (t !== void 0 && typeof t == "object") return t;
117
+ if ((t ?? (r.STRIPE_SECRET_KEY ? "stripe" : "mock")) === "stripe") {
118
+ let t = e.apiKey ?? r.STRIPE_SECRET_KEY;
119
+ if (!t) throw Error("billingPlugin: provider 'stripe' needs an apiKey (option or STRIPE_SECRET_KEY env)");
120
+ return n({
121
+ apiKey: t,
122
+ ...e.planForPriceId ? { planForPriceId: e.planForPriceId } : {}
123
+ });
124
+ }
125
+ return i();
126
+ }, l = (e) => e.name === "mock" ? [] : [{
127
+ destination: e.name === "stripe" ? "api.stripe.com" : `runtime:the '${e.name}' billing provider`,
128
+ purpose: "customers, subscriptions, checkout and metered usage",
129
+ data: ["personal", "metadata"],
130
+ disable: "without STRIPE_SECRET_KEY the mock provider answers, and nothing leaves (production refuses to boot on it)"
131
+ }];
132
+ //#endregion
133
+ export { e as STRIPE_WEBHOOK_EVENTS, s as assertBillingProductionReady, l as billingEgressOf, o as isProductionBoot, i as mockProvider, t as normalizeStripeEvent, c as resolveProvider, n as stripeProvider };
@@ -0,0 +1,153 @@
1
+ import { diffMeter as e, diffPortal as t, diffPrice as n, diffProduct as r, diffTaxSettings as i, diffWebhook as a, sellingReadiness as o } from "./catalog.js";
2
+ import { redactStripeKeys as s, stripeRest as c } from "./stripeRest.js";
3
+ import { execFileSync as l } from "node:child_process";
4
+ import { chmodSync as u, existsSync as d, readFileSync as f, realpathSync as p, writeFileSync as m } from "node:fs";
5
+ import { dirname as h, resolve as g } from "node:path";
6
+ //#region src/provision.ts
7
+ var _ = (e) => e.filter((e) => e.applied !== !0 && (e.kind === "create" || e.kind === "update" || e.kind === "adopt" || e.kind === "drift")), v = async (s, c, l) => {
8
+ let u = c.environments[l.env], d = await s.get("/v1/tax/settings"), f = l.env === "live";
9
+ if (d.livemode !== f) throw Error(`the key reaches a ${d.livemode ? "LIVE" : "test"} account, not ${l.env}`);
10
+ let p = [], m = {}, h = async (e, t) => {
11
+ let n = "apply" in e ? e.apply : void 0;
12
+ if (l.apply && n !== void 0) {
13
+ let r = await s.post(n.path, n.params);
14
+ t?.(r), p.push({
15
+ ...e,
16
+ applied: !0
17
+ });
18
+ } else p.push(e);
19
+ }, g = await s.list("/v1/billing/meters"), _ = /* @__PURE__ */ new Map();
20
+ for (let t of c.meters) {
21
+ let n = e(t, g);
22
+ _.set(t.eventName, n.id), await h(n.finding, (e) => {
23
+ _.set(t.eventName, e.id);
24
+ });
25
+ }
26
+ let v = await s.list("/v1/products"), y = [];
27
+ for (let e of c.products) {
28
+ let t = r(e, v), n = {
29
+ inPortal: e.inPortal,
30
+ productId: t.id,
31
+ priceId: null
32
+ };
33
+ await h(t.finding, (e) => {
34
+ n.productId = e.id;
35
+ }), y.push(n);
36
+ }
37
+ for (let [e, t] of c.products.entries()) {
38
+ let r = y[e], i = t.price.meter;
39
+ if (t.price.usageType === "metered" && (i === void 0 || !_.has(i))) {
40
+ p.push({
41
+ kind: "manual",
42
+ object: `price ${t.price.lookupKey}`,
43
+ detail: `metered, but names no catalog meter (${i ?? "none"})`
44
+ });
45
+ continue;
46
+ }
47
+ let a = i === void 0 ? null : _.get(i) ?? null, o = r.productId ?? (l.apply ? null : `pending:${t.key}`), c = a ?? (l.apply || t.price.usageType !== "metered" ? a : `pending:${i}`), u = (await s.list("/v1/prices", { lookup_keys: [t.price.lookupKey] }))[0] ?? null, d = r.productId === null ? [] : await s.list("/v1/prices", { product: r.productId }), f = n(t.price, o, c, u, d, l.allowPriceChange);
48
+ r.priceId = f.id, await h(f.finding, (e) => {
49
+ r.priceId = e.id;
50
+ }), r.priceId !== null && (m[t.price.envName] = r.priceId);
51
+ }
52
+ await h(i(c.tax, d));
53
+ let b = y.filter((e) => e.inPortal), x = b.every((e) => e.productId !== null && e.priceId !== null) ? b.map((e) => ({
54
+ productId: e.productId,
55
+ priceId: e.priceId
56
+ })) : null, S = await s.list("/v1/billing_portal/configurations", { expand: ["data.features.subscription_update.products"] });
57
+ for (let e of t(c.portal, u, x, S)) await h(e);
58
+ let C = a(u, await s.list("/v1/webhook_endpoints"));
59
+ C.kind === "create" && l.apply && l.envOut === null ? p.push({
60
+ kind: "manual",
61
+ object: C.object,
62
+ detail: "not created: pass --env-out so its signing secret is captured (Stripe shows it once)"
63
+ }) : await h(C, (e) => {
64
+ typeof e.secret == "string" && (m.STRIPE_WEBHOOK_SECRET = e.secret);
65
+ });
66
+ let w = await s.get("/v1/account").catch(() => null), T = await s.list("/v1/tax_ids", { owner: { type: "account" } }).catch(() => null), E = await s.list("/v1/tax/registrations", { status: "active" }).catch(() => []);
67
+ return p.push(...o({
68
+ catalog: c,
69
+ env: u,
70
+ chargesEnabled: w === null ? null : w.charges_enabled === !0,
71
+ accountTaxIds: T === null ? null : T.length,
72
+ activeRegistrations: E.map((e) => e.country)
73
+ })), {
74
+ livemode: d.livemode,
75
+ findings: p,
76
+ envOut: m
77
+ };
78
+ }, y = (e, t) => {
79
+ let n = new Set(Object.keys(t)), r = e.split("\n").filter((e) => !n.has(e.split("=")[0] ?? ""));
80
+ for (; r.length > 0 && r[r.length - 1] === "";) r.pop();
81
+ return [
82
+ ...r,
83
+ ...Object.entries(t).map(([e, t]) => `${e}=${t}`),
84
+ ""
85
+ ].join("\n");
86
+ }, b = (e, t) => {
87
+ try {
88
+ return l("git", [...e], {
89
+ cwd: t,
90
+ stdio: "ignore"
91
+ }), !0;
92
+ } catch {
93
+ return !1;
94
+ }
95
+ }, x = (e, t = b, n = (e) => d(e) ? p(e) : e) => {
96
+ for (let r of /* @__PURE__ */ new Set([g(e), g(n(g(e)))])) {
97
+ let n = h(r);
98
+ if (t(["rev-parse", "--is-inside-work-tree"], n) && !t([
99
+ "check-ignore",
100
+ "-q",
101
+ r
102
+ ], n)) return `${e} is inside a git work tree and not ignored — write it to a gitignored file or outside the repo`;
103
+ }
104
+ return null;
105
+ }, S = (e) => {
106
+ let t = (t) => {
107
+ let n = e.indexOf(t);
108
+ return n < 0 ? null : e[n + 1];
109
+ }, n = t("--env");
110
+ if (n !== "sandbox" && n !== "live") return "--env sandbox|live is required";
111
+ let r = t("--env-out");
112
+ if (r === void 0 || r?.startsWith("--")) return "--env-out needs a file path";
113
+ let i = {
114
+ env: n,
115
+ apply: e.includes("--apply"),
116
+ allowPriceChange: e.includes("--allow-price-change"),
117
+ confirmLive: e.includes("--confirm-live"),
118
+ strict: e.includes("--strict"),
119
+ envOut: r
120
+ };
121
+ return i.env === "live" && i.apply && !i.confirmLive ? "writing to LIVE needs --confirm-live (run without --apply first to see the plan)" : i;
122
+ }, C = (e, t, n) => {
123
+ let r = t.STRIPE_PROVISION_KEY?.trim() || (e === "sandbox" ? n?.trim() : void 0);
124
+ return r === void 0 || r.length === 0 ? { refusal: "set STRIPE_PROVISION_KEY (a sandbox run also reads STRIPE_SECRET_KEY from the dotenv file)" } : e === "live" && !/^(sk|rk)_live_/.test(r) ? { refusal: "--env live needs a live key (sk_live_/rk_live_)" } : e === "sandbox" && !/^(sk|rk)_test_/.test(r) ? { refusal: "--env sandbox needs a test key (sk_test_/rk_test_)" } : { key: r };
125
+ }, w = (e, t) => d(e) ? f(e, "utf8").split("\n").find((e) => e.startsWith(`${t}=`))?.slice(t.length + 1).trim() : void 0, T = async (e, t, n = {}) => {
126
+ let r = n.vars ?? process.env, i = (e) => (console.error(`stripe provision: ${e}`), 2), a = S(t);
127
+ if (typeof a == "string") return i(a);
128
+ if (a.envOut !== null) {
129
+ let e = x(a.envOut);
130
+ if (e !== null) return i(e);
131
+ }
132
+ let o = C(a.env, r, n.dotenv === void 0 ? void 0 : w(n.dotenv, "STRIPE_SECRET_KEY"));
133
+ if ("refusal" in o) return i(o.refusal);
134
+ let l;
135
+ try {
136
+ l = await v((n.rest ?? c)(o.key), e, a);
137
+ } catch (e) {
138
+ return console.error(`stripe provision: ${s(e instanceof Error ? e.message : String(e))}`), 1;
139
+ }
140
+ console.log(`Stripe ${a.env} (${l.livemode ? "LIVE" : "test mode"}) — ${a.apply ? "apply" : "check"}`);
141
+ for (let e of l.findings) {
142
+ let t = e.applied === !0 ? `${e.kind} ✓` : e.kind;
143
+ console.log(` ${t.padEnd(10)} ${e.object}${"detail" in e ? ` — ${e.detail}` : ""}`);
144
+ }
145
+ if (a.envOut !== null) {
146
+ let e = a.envOut;
147
+ m(e, y(d(e) ? f(e, "utf8") : "", l.envOut), { mode: 384 }), u(e, 384), console.log(` wrote ${Object.keys(l.envOut).sort().join(", ")} to ${e}`);
148
+ }
149
+ let p = _(l.findings), h = l.findings.filter((e) => e.kind === "manual");
150
+ return console.log(` ${p.length} open, ${h.length} manual`), p.length > 0 || a.strict && h.length > 0 ? 1 : 0;
151
+ };
152
+ //#endregion
153
+ export { x as envOutRefusal, y as mergeEnvFile, _ as openFindings, S as parseProvisionArgs, v as provisionStripeCatalog, C as resolveProvisionKey, T as runStripeProvision };