@voltro/plugin-billing 0.55.0 → 0.56.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/CHANGELOG.md +497 -0
- package/dist/index.js +397 -375
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { BillingError as e, BillingService as t, DEFAULT_PLAN as n, EntitlementExceeded as r, SubscriptionLocked as i } from "./types.js";
|
|
2
2
|
import { billingRpcClientImports as a, changePlanDescriptor as o, changeSeatsDescriptor as s, entitlementStatusDescriptor as c, invoicesDescriptor as l, portalUrlDescriptor as u, previewChangeDescriptor as d, reportUsageDescriptor as f, startCheckoutDescriptor as ee, subscriptionDescriptor as te } from "./rpc.js";
|
|
3
3
|
import { Effect as p, Layer as m, Schedule as h, Schema as ne } from "effect";
|
|
4
|
-
import { pluginEnv as
|
|
5
|
-
import { composeRpcInterceptors as
|
|
6
|
-
import { and as _, eq as v, gte as
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
4
|
+
import { pluginEnv as re } from "@voltro/env";
|
|
5
|
+
import { composeRpcInterceptors as ie, definePlugin as ae, pluginInstanceName as oe } from "@voltro/protocol";
|
|
6
|
+
import { OccurrenceCounter as g, and as _, changeDigest as se, composeChangeKey as ce, eq as v, gte as le, id as y, integer as b, occurrenceWindowMs as ue, registerRetention as x, retentionTtlMsFromEnv as S, table as C, text as w, timestamp as T } from "@voltro/database";
|
|
7
|
+
import { replicaId as de } from "@voltro/protocol/identity";
|
|
8
|
+
import { createLogger as E } from "@voltro/logger";
|
|
9
|
+
import D from "stripe";
|
|
10
|
+
import { defineIncomingWebhook as fe, mountIncomingWebhook as pe } from "@voltro/plugin-webhooks";
|
|
11
|
+
import { stripeProvider as O } from "@voltro/plugin-webhooks/providers";
|
|
11
12
|
//#region src/entitlement.ts
|
|
12
|
-
var
|
|
13
|
+
var k = (e, t, n, r) => ({
|
|
13
14
|
allowed: !Number.isFinite(t) || r <= 0 || n + r <= t,
|
|
14
15
|
entitlement: e,
|
|
15
16
|
limit: t,
|
|
16
17
|
used: n,
|
|
17
18
|
cost: r
|
|
18
|
-
}),
|
|
19
|
-
let a =
|
|
19
|
+
}), A = (e) => e.tenantId, me = (e, n, i) => p.gen(function* () {
|
|
20
|
+
let a = A(e.request.subject);
|
|
20
21
|
if (a === null) return i <= 0 ? void 0 : yield* p.fail(new r({
|
|
21
22
|
entitlement: n,
|
|
22
23
|
limit: 0,
|
|
@@ -24,8 +25,8 @@ var j = (e, t, n, r) => ({
|
|
|
24
25
|
cost: i
|
|
25
26
|
}));
|
|
26
27
|
yield* (yield* t).consumeEntitlement(a, n, i);
|
|
27
|
-
}),
|
|
28
|
-
let n =
|
|
28
|
+
}), he = (e) => p.gen(function* () {
|
|
29
|
+
let n = A(e.request.subject);
|
|
29
30
|
if (n === null) return;
|
|
30
31
|
let r = yield* (yield* t).entitlementStatus(n);
|
|
31
32
|
if (!r.entitled) return yield* p.fail(new i({
|
|
@@ -34,7 +35,7 @@ var j = (e, t, n, r) => ({
|
|
|
34
35
|
lockedSince: (r.lockedSince ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
35
36
|
lockout: r.lockout
|
|
36
37
|
}));
|
|
37
|
-
}),
|
|
38
|
+
}), ge = (e, t) => (n, i) => {
|
|
38
39
|
let a = e[i.tag];
|
|
39
40
|
if (a === void 0) return n;
|
|
40
41
|
let o = a.cost ?? 1, s = i.subject.tenantId;
|
|
@@ -44,66 +45,66 @@ var j = (e, t, n, r) => ({
|
|
|
44
45
|
used: 0,
|
|
45
46
|
cost: o
|
|
46
47
|
})) : p.flatMap(t.consumeEntitlement(s, a.entitlement, o), () => n);
|
|
47
|
-
},
|
|
48
|
-
id:
|
|
49
|
-
tenantId:
|
|
50
|
-
provider:
|
|
51
|
-
providerCustomerId:
|
|
52
|
-
createdAt:
|
|
53
|
-
updatedAt:
|
|
54
|
-
}).index("byBillingCustomerTenant", ["tenantId"]).index("byBillingProviderCustomer", ["providerCustomerId"]),
|
|
55
|
-
id:
|
|
56
|
-
tenantId:
|
|
57
|
-
provider:
|
|
58
|
-
providerSubscriptionId:
|
|
59
|
-
plan:
|
|
60
|
-
status:
|
|
61
|
-
quantity:
|
|
62
|
-
currentPeriodStart:
|
|
63
|
-
currentPeriodEnd:
|
|
64
|
-
cancelAt:
|
|
65
|
-
pastDueSince:
|
|
66
|
-
statusEventAt:
|
|
67
|
-
createdAt:
|
|
68
|
-
updatedAt:
|
|
69
|
-
}).index("byBillingSubscriptionTenant", ["tenantId"]).index("byBillingProviderSubscription", ["providerSubscriptionId"]).index("byBillingSubscriptionStatus", ["status"]),
|
|
70
|
-
id:
|
|
71
|
-
tenantId:
|
|
72
|
-
provider:
|
|
73
|
-
providerInvoiceId:
|
|
74
|
-
amountMinor:
|
|
75
|
-
currency:
|
|
76
|
-
status:
|
|
77
|
-
statusEventAt:
|
|
78
|
-
createdAt:
|
|
79
|
-
}).index("byBillingInvoiceTenant", ["tenantId"]).index("byBillingProviderInvoice", ["providerInvoiceId"]),
|
|
80
|
-
id:
|
|
81
|
-
tenantId:
|
|
82
|
-
entitlementKey:
|
|
83
|
-
period:
|
|
84
|
-
used:
|
|
85
|
-
reportedToProvider:
|
|
86
|
-
updatedAt:
|
|
48
|
+
}, j = "_voltro_billing_customers", M = "_voltro_billing_subscriptions", N = "_voltro_billing_invoices", P = "_voltro_billing_usage", _e = C(j, {
|
|
49
|
+
id: y({ prefix: "bcust" }),
|
|
50
|
+
tenantId: w(),
|
|
51
|
+
provider: w(),
|
|
52
|
+
providerCustomerId: w(),
|
|
53
|
+
createdAt: T(),
|
|
54
|
+
updatedAt: T()
|
|
55
|
+
}).index("byBillingCustomerTenant", ["tenantId"]).index("byBillingProviderCustomer", ["providerCustomerId"]), ve = C(M, {
|
|
56
|
+
id: y({ prefix: "bsub" }),
|
|
57
|
+
tenantId: w(),
|
|
58
|
+
provider: w(),
|
|
59
|
+
providerSubscriptionId: w(),
|
|
60
|
+
plan: w(),
|
|
61
|
+
status: w(),
|
|
62
|
+
quantity: b().default(1),
|
|
63
|
+
currentPeriodStart: T().nullable(),
|
|
64
|
+
currentPeriodEnd: T().nullable(),
|
|
65
|
+
cancelAt: T().nullable(),
|
|
66
|
+
pastDueSince: T().nullable(),
|
|
67
|
+
statusEventAt: T().nullable(),
|
|
68
|
+
createdAt: T(),
|
|
69
|
+
updatedAt: T()
|
|
70
|
+
}).index("byBillingSubscriptionTenant", ["tenantId"]).index("byBillingProviderSubscription", ["providerSubscriptionId"]).index("byBillingSubscriptionStatus", ["status"]), ye = C(N, {
|
|
71
|
+
id: y({ prefix: "binv" }),
|
|
72
|
+
tenantId: w(),
|
|
73
|
+
provider: w(),
|
|
74
|
+
providerInvoiceId: w(),
|
|
75
|
+
amountMinor: b(),
|
|
76
|
+
currency: w(),
|
|
77
|
+
status: w(),
|
|
78
|
+
statusEventAt: T().nullable(),
|
|
79
|
+
createdAt: T()
|
|
80
|
+
}).index("byBillingInvoiceTenant", ["tenantId"]).index("byBillingProviderInvoice", ["providerInvoiceId"]), be = C(P, {
|
|
81
|
+
id: y({ prefix: "buse" }),
|
|
82
|
+
tenantId: w().maxLength(191),
|
|
83
|
+
entitlementKey: w().maxLength(191),
|
|
84
|
+
period: w().maxLength(16),
|
|
85
|
+
used: b().default(0),
|
|
86
|
+
reportedToProvider: b().default(0),
|
|
87
|
+
updatedAt: T()
|
|
87
88
|
}).unique("byBillingUsageWindow", [
|
|
88
89
|
"tenantId",
|
|
89
90
|
"entitlementKey",
|
|
90
91
|
"period"
|
|
91
|
-
]),
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
],
|
|
97
|
-
id:
|
|
98
|
-
tenantId:
|
|
99
|
-
episode:
|
|
100
|
-
stepId:
|
|
101
|
-
sentAt:
|
|
92
|
+
]), xe = () => [
|
|
93
|
+
_e,
|
|
94
|
+
ve,
|
|
95
|
+
ye,
|
|
96
|
+
be
|
|
97
|
+
], F = "_voltro_billing_dunning_notices", Se = C(F, {
|
|
98
|
+
id: y({ prefix: "bdun" }),
|
|
99
|
+
tenantId: w().maxLength(191),
|
|
100
|
+
episode: w().maxLength(32),
|
|
101
|
+
stepId: w().maxLength(64),
|
|
102
|
+
sentAt: T()
|
|
102
103
|
}).unique("byBillingDunningNotice", [
|
|
103
104
|
"tenantId",
|
|
104
105
|
"episode",
|
|
105
106
|
"stepId"
|
|
106
|
-
]),
|
|
107
|
+
]), I = "locked", Ce = [
|
|
107
108
|
{
|
|
108
109
|
id: "payment-failed",
|
|
109
110
|
afterHours: 0
|
|
@@ -116,28 +117,28 @@ var j = (e, t, n, r) => ({
|
|
|
116
117
|
id: "final-warning",
|
|
117
118
|
afterHours: 144
|
|
118
119
|
}
|
|
119
|
-
],
|
|
120
|
+
], we = 168, Te = "hard", Ee = (e, t, n) => {
|
|
120
121
|
if (e === void 0 || e.trim() === "") return t;
|
|
121
122
|
let r = Number(e);
|
|
122
123
|
if (!Number.isFinite(r) || r < 0) throw Error(`billingPlugin: ${n} must be a non-negative number, got '${e}'`);
|
|
123
124
|
return r;
|
|
124
|
-
},
|
|
125
|
+
}, L = (e, t) => {
|
|
125
126
|
let n = t.VOLTRO_BILLING_DUNNING;
|
|
126
127
|
if (n !== void 0 && n !== "" && n !== "on" && n !== "off") throw Error(`billingPlugin: VOLTRO_BILLING_DUNNING must be 'on' or 'off', got '${n}'`);
|
|
127
128
|
let r = n === "off" ? !1 : n === "on" ? !0 : e?.enabled ?? !0, i = t.VOLTRO_BILLING_LOCKOUT;
|
|
128
129
|
if (i !== void 0 && i !== "" && i !== "hard" && i !== "soft") throw Error(`billingPlugin: VOLTRO_BILLING_LOCKOUT must be 'hard' or 'soft', got '${i}'`);
|
|
129
|
-
let a = i === "hard" || i === "soft" ? i : e?.lockout ?? "hard", o =
|
|
130
|
+
let a = i === "hard" || i === "soft" ? i : e?.lockout ?? "hard", o = Ee(t.VOLTRO_BILLING_GRACE_HOURS, e?.graceHours ?? 168, "VOLTRO_BILLING_GRACE_HOURS"), s = e?.steps ?? Ce, c = t.VOLTRO_BILLING_DUNNING_STEP_HOURS, l = s;
|
|
130
131
|
if (c !== void 0 && c.trim() !== "") {
|
|
131
132
|
let e = c.split(",").map((e) => e.trim());
|
|
132
133
|
if (e.length !== s.length) throw Error(`billingPlugin: VOLTRO_BILLING_DUNNING_STEP_HOURS lists ${e.length} value(s) but the sequence declares ${s.length} step(s) (${s.map((e) => e.id).join(", ")})`);
|
|
133
134
|
l = s.map((t, n) => ({
|
|
134
135
|
id: t.id,
|
|
135
|
-
afterHours:
|
|
136
|
+
afterHours: Ee(e[n], t.afterHours, "VOLTRO_BILLING_DUNNING_STEP_HOURS")
|
|
136
137
|
}));
|
|
137
138
|
}
|
|
138
139
|
let u = /* @__PURE__ */ new Set();
|
|
139
140
|
for (let e of l) {
|
|
140
|
-
if (e.id === "locked") throw Error(`billingPlugin: '${
|
|
141
|
+
if (e.id === "locked") throw Error(`billingPlugin: '${I}' is the reserved lockout step id`);
|
|
141
142
|
if (u.has(e.id)) throw Error(`billingPlugin: duplicate dunning step id '${e.id}'`);
|
|
142
143
|
u.add(e.id);
|
|
143
144
|
}
|
|
@@ -150,10 +151,10 @@ var j = (e, t, n, r) => ({
|
|
|
150
151
|
...e?.resolveRecipient === void 0 ? {} : { resolveRecipient: e.resolveRecipient },
|
|
151
152
|
...e?.portalReturnUrl === void 0 ? {} : { portalReturnUrl: e.portalReturnUrl }
|
|
152
153
|
};
|
|
153
|
-
},
|
|
154
|
-
let r = (n.getTime() - t.getTime()) /
|
|
154
|
+
}, De = 36e5, Oe = (e) => String(e.getTime()), ke = (e, t) => new Date(e.getTime() + t * De), Ae = (e, t, n) => {
|
|
155
|
+
let r = (n.getTime() - t.getTime()) / De;
|
|
155
156
|
return e.filter((e) => r >= e.afterHours);
|
|
156
|
-
},
|
|
157
|
+
}, R = (e, t, r, i) => {
|
|
157
158
|
let a = {
|
|
158
159
|
tenantId: e?.tenantId ?? i ?? "",
|
|
159
160
|
lockout: t.lockout
|
|
@@ -199,7 +200,7 @@ var j = (e, t, n, r) => ({
|
|
|
199
200
|
graceEndsAt: null,
|
|
200
201
|
lockedSince: null
|
|
201
202
|
};
|
|
202
|
-
let i =
|
|
203
|
+
let i = ke(e.pastDueSince, t.graceHours), o = r.getTime() >= i.getTime();
|
|
203
204
|
return {
|
|
204
205
|
...a,
|
|
205
206
|
plan: o && t.lockout === "hard" ? n : e.plan,
|
|
@@ -221,29 +222,29 @@ var j = (e, t, n, r) => ({
|
|
|
221
222
|
graceEndsAt: null,
|
|
222
223
|
lockedSince: null
|
|
223
224
|
};
|
|
224
|
-
},
|
|
225
|
+
}, je = (e) => e.toISOString().slice(0, 10), Me = (e) => {
|
|
225
226
|
let t = e.portalUrl, n = t === null ? "<p>Please update your payment method in the billing settings.</p>" : `<p><a href="${t}">Update your payment method</a></p>`, r = t === null ? "Please update your payment method in the billing settings." : `Update your payment method: ${t}`;
|
|
226
227
|
if (e.locked) return {
|
|
227
228
|
subject: "Your subscription has been suspended",
|
|
228
229
|
html: `<p>We were unable to collect payment, and your subscription is now suspended.</p>${n}`,
|
|
229
230
|
text: `We were unable to collect payment, and your subscription is now suspended.\n\n${r}`
|
|
230
231
|
};
|
|
231
|
-
let i =
|
|
232
|
+
let i = je(e.graceEndsAt), a = e.stepId === "payment-failed" ? "Your last payment could not be collected." : "Your payment is still outstanding.";
|
|
232
233
|
return {
|
|
233
234
|
subject: "Action needed: your payment could not be collected",
|
|
234
235
|
html: `<p>${a} Your subscription stays active until ${i}.</p>${n}`,
|
|
235
236
|
text: `${a} Your subscription stays active until ${i}.\n\n${r}`
|
|
236
237
|
};
|
|
237
|
-
},
|
|
238
|
+
}, Ne = (e) => (t) => t.to === null ? p.void : e.send({
|
|
238
239
|
to: t.to,
|
|
239
240
|
subject: t.subject,
|
|
240
241
|
html: t.html,
|
|
241
242
|
text: t.text
|
|
242
|
-
}).pipe(p.asVoid),
|
|
243
|
+
}).pipe(p.asVoid), Pe = (e, t, n) => `${e}\u0000${t}\u0000${n}`, Fe = () => {
|
|
243
244
|
let e = /* @__PURE__ */ new Map();
|
|
244
245
|
return {
|
|
245
246
|
claim: (t, n, r, i) => p.sync(() => {
|
|
246
|
-
let a =
|
|
247
|
+
let a = Pe(t, n, r);
|
|
247
248
|
return !e.has(a) && (e.set(a, {
|
|
248
249
|
tenantId: t,
|
|
249
250
|
episode: n,
|
|
@@ -253,10 +254,10 @@ var j = (e, t, n, r) => ({
|
|
|
253
254
|
}),
|
|
254
255
|
sentSteps: (t, n) => p.sync(() => [...e.values()].filter((e) => e.tenantId === t && e.episode === n))
|
|
255
256
|
};
|
|
256
|
-
},
|
|
257
|
+
}, Ie = () => `bdun_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`, Le = (t) => ({
|
|
257
258
|
claim: (n, r, i, a) => p.tryPromise({
|
|
258
259
|
try: async () => {
|
|
259
|
-
let e =
|
|
260
|
+
let e = Ie(), o = await t.insertIgnore(F, {
|
|
260
261
|
id: e,
|
|
261
262
|
tenantId: n,
|
|
262
263
|
episode: r,
|
|
@@ -277,7 +278,7 @@ var j = (e, t, n, r) => ({
|
|
|
277
278
|
}),
|
|
278
279
|
sentSteps: (n, r) => p.tryPromise({
|
|
279
280
|
try: async () => (await t.query({
|
|
280
|
-
table:
|
|
281
|
+
table: F,
|
|
281
282
|
predicate: _(v("tenantId", n), v("episode", r)),
|
|
282
283
|
order: [],
|
|
283
284
|
take: void 0,
|
|
@@ -295,21 +296,21 @@ var j = (e, t, n, r) => ({
|
|
|
295
296
|
transient: !0
|
|
296
297
|
})
|
|
297
298
|
})
|
|
298
|
-
}),
|
|
299
|
+
}), z = (e) => `${e}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`, B = (t, n) => p.tryPromise({
|
|
299
300
|
try: t,
|
|
300
301
|
catch: (t) => new e({
|
|
301
302
|
source: n,
|
|
302
303
|
message: String(t?.message ?? t),
|
|
303
304
|
transient: !0
|
|
304
305
|
})
|
|
305
|
-
}),
|
|
306
|
+
}), V = (e) => ({
|
|
306
307
|
table: e.table,
|
|
307
308
|
predicate: e.predicate,
|
|
308
309
|
order: e.order ?? [],
|
|
309
310
|
take: e.take,
|
|
310
311
|
skip: void 0,
|
|
311
312
|
projection: void 0
|
|
312
|
-
}),
|
|
313
|
+
}), Re = () => {
|
|
313
314
|
let e = /* @__PURE__ */ new Map();
|
|
314
315
|
return {
|
|
315
316
|
upsert: (t) => p.sync(() => {
|
|
@@ -317,42 +318,42 @@ var j = (e, t, n, r) => ({
|
|
|
317
318
|
}),
|
|
318
319
|
getByTenant: (t) => p.sync(() => e.get(t) ?? null)
|
|
319
320
|
};
|
|
320
|
-
},
|
|
321
|
+
}, ze = (e) => ({
|
|
321
322
|
tenantId: String(e.tenantId),
|
|
322
323
|
provider: String(e.provider),
|
|
323
324
|
providerCustomerId: String(e.providerCustomerId)
|
|
324
|
-
}),
|
|
325
|
-
upsert: (t) =>
|
|
326
|
-
let n = await e.query(
|
|
327
|
-
table:
|
|
325
|
+
}), Be = (e) => ({
|
|
326
|
+
upsert: (t) => B(async () => {
|
|
327
|
+
let n = await e.query(V({
|
|
328
|
+
table: j,
|
|
328
329
|
predicate: v("tenantId", t.tenantId),
|
|
329
330
|
take: 1
|
|
330
331
|
})), r = /* @__PURE__ */ new Date();
|
|
331
|
-
n[0] ? await e.update(
|
|
332
|
+
n[0] ? await e.update(j, String(n[0].id), {
|
|
332
333
|
provider: t.provider,
|
|
333
334
|
providerCustomerId: t.providerCustomerId,
|
|
334
335
|
updatedAt: r
|
|
335
|
-
}) : await e.insert(
|
|
336
|
-
id:
|
|
336
|
+
}) : await e.insert(j, {
|
|
337
|
+
id: z("bcust"),
|
|
337
338
|
...t,
|
|
338
339
|
createdAt: r,
|
|
339
340
|
updatedAt: r
|
|
340
341
|
});
|
|
341
342
|
}, "customerStore"),
|
|
342
|
-
getByTenant: (t) =>
|
|
343
|
-
let n = await e.query(
|
|
344
|
-
table:
|
|
343
|
+
getByTenant: (t) => B(async () => {
|
|
344
|
+
let n = await e.query(V({
|
|
345
|
+
table: j,
|
|
345
346
|
predicate: v("tenantId", t),
|
|
346
347
|
take: 1
|
|
347
348
|
}));
|
|
348
|
-
return n[0] ?
|
|
349
|
+
return n[0] ? ze(n[0]) : null;
|
|
349
350
|
}, "customerStore")
|
|
350
|
-
}),
|
|
351
|
+
}), H = (e, t) => e === null ? !1 : t === null || t.getTime() < e.getTime(), Ve = () => {
|
|
351
352
|
let e = /* @__PURE__ */ new Map();
|
|
352
353
|
return {
|
|
353
354
|
upsert: (t) => p.sync(() => {
|
|
354
355
|
let n = e.get(t.tenantId);
|
|
355
|
-
n &&
|
|
356
|
+
n && H(n.statusEventAt, t.statusEventAt) || e.set(t.tenantId, {
|
|
356
357
|
...t,
|
|
357
358
|
pastDueSince: n ? n.pastDueSince : t.pastDueSince
|
|
358
359
|
});
|
|
@@ -379,7 +380,7 @@ var j = (e, t, n, r) => ({
|
|
|
379
380
|
});
|
|
380
381
|
})
|
|
381
382
|
};
|
|
382
|
-
},
|
|
383
|
+
}, He = (e) => ({
|
|
383
384
|
tenantId: String(e.tenantId),
|
|
384
385
|
provider: String(e.provider),
|
|
385
386
|
providerSubscriptionId: String(e.providerSubscriptionId),
|
|
@@ -391,16 +392,16 @@ var j = (e, t, n, r) => ({
|
|
|
391
392
|
cancelAt: e.cancelAt == null ? null : new Date(e.cancelAt),
|
|
392
393
|
pastDueSince: e.pastDueSince == null ? null : new Date(e.pastDueSince),
|
|
393
394
|
statusEventAt: e.statusEventAt == null ? null : new Date(e.statusEventAt)
|
|
394
|
-
}),
|
|
395
|
+
}), Ue = async (e, t) => (await e.query(V({
|
|
395
396
|
table: "_voltro_billing_subscriptions",
|
|
396
397
|
predicate: v("providerSubscriptionId", t),
|
|
397
398
|
take: 1
|
|
398
|
-
})))[0] ?? null,
|
|
399
|
-
upsert: (t) =>
|
|
400
|
-
let n = await
|
|
399
|
+
})))[0] ?? null, We = (e) => ({
|
|
400
|
+
upsert: (t) => B(async () => {
|
|
401
|
+
let n = await Ue(e, t.providerSubscriptionId), r = /* @__PURE__ */ new Date();
|
|
401
402
|
if (n) {
|
|
402
|
-
if (
|
|
403
|
-
await e.update(
|
|
403
|
+
if (H(n.statusEventAt == null ? null : new Date(n.statusEventAt), t.statusEventAt)) return;
|
|
404
|
+
await e.update(M, String(n.id), {
|
|
404
405
|
tenantId: t.tenantId,
|
|
405
406
|
provider: t.provider,
|
|
406
407
|
plan: t.plan,
|
|
@@ -412,8 +413,8 @@ var j = (e, t, n, r) => ({
|
|
|
412
413
|
statusEventAt: t.statusEventAt,
|
|
413
414
|
updatedAt: r
|
|
414
415
|
});
|
|
415
|
-
} else await e.insert(
|
|
416
|
-
id:
|
|
416
|
+
} else await e.insert(M, {
|
|
417
|
+
id: z("bsub"),
|
|
417
418
|
tenantId: t.tenantId,
|
|
418
419
|
provider: t.provider,
|
|
419
420
|
providerSubscriptionId: t.providerSubscriptionId,
|
|
@@ -429,9 +430,9 @@ var j = (e, t, n, r) => ({
|
|
|
429
430
|
updatedAt: r
|
|
430
431
|
});
|
|
431
432
|
}, "subscriptionStore"),
|
|
432
|
-
getByTenant: (t) =>
|
|
433
|
-
let n = await e.query(
|
|
434
|
-
table:
|
|
433
|
+
getByTenant: (t) => B(async () => {
|
|
434
|
+
let n = await e.query(V({
|
|
435
|
+
table: M,
|
|
435
436
|
predicate: v("tenantId", t),
|
|
436
437
|
order: [{
|
|
437
438
|
column: "updatedAt",
|
|
@@ -439,26 +440,26 @@ var j = (e, t, n, r) => ({
|
|
|
439
440
|
}],
|
|
440
441
|
take: 1
|
|
441
442
|
}));
|
|
442
|
-
return n[0] ?
|
|
443
|
+
return n[0] ? He(n[0]) : null;
|
|
443
444
|
}, "subscriptionStore"),
|
|
444
|
-
listByStatus: (t) =>
|
|
445
|
-
table:
|
|
445
|
+
listByStatus: (t) => B(async () => (await e.query(V({
|
|
446
|
+
table: M,
|
|
446
447
|
predicate: v("status", t),
|
|
447
448
|
order: [{
|
|
448
449
|
column: "updatedAt",
|
|
449
450
|
direction: "asc"
|
|
450
451
|
}]
|
|
451
|
-
}))).map(
|
|
452
|
-
markCanceled: (t) =>
|
|
453
|
-
let n = await
|
|
454
|
-
n && await e.update(
|
|
452
|
+
}))).map(He), "subscriptionStore"),
|
|
453
|
+
markCanceled: (t) => B(async () => {
|
|
454
|
+
let n = await Ue(e, t);
|
|
455
|
+
n && await e.update(M, String(n.id), {
|
|
455
456
|
status: "canceled",
|
|
456
457
|
updatedAt: /* @__PURE__ */ new Date()
|
|
457
458
|
});
|
|
458
459
|
}, "subscriptionStore"),
|
|
459
|
-
patchByTenant: (t, n) =>
|
|
460
|
-
let r = (await e.query(
|
|
461
|
-
table:
|
|
460
|
+
patchByTenant: (t, n) => B(async () => {
|
|
461
|
+
let r = (await e.query(V({
|
|
462
|
+
table: M,
|
|
462
463
|
predicate: v("tenantId", t),
|
|
463
464
|
order: [{
|
|
464
465
|
column: "updatedAt",
|
|
@@ -466,7 +467,7 @@ var j = (e, t, n, r) => ({
|
|
|
466
467
|
}],
|
|
467
468
|
take: 1
|
|
468
469
|
})))[0];
|
|
469
|
-
r && await e.update(
|
|
470
|
+
r && await e.update(M, String(r.id), {
|
|
470
471
|
...n.plan === void 0 ? {} : { plan: n.plan },
|
|
471
472
|
...n.quantity === void 0 ? {} : { quantity: n.quantity },
|
|
472
473
|
...n.status === void 0 ? {} : { status: n.status },
|
|
@@ -477,23 +478,23 @@ var j = (e, t, n, r) => ({
|
|
|
477
478
|
updatedAt: /* @__PURE__ */ new Date()
|
|
478
479
|
});
|
|
479
480
|
}, "subscriptionStore"),
|
|
480
|
-
setStatus: (t, n) =>
|
|
481
|
-
let r = await
|
|
482
|
-
r && await e.update(
|
|
481
|
+
setStatus: (t, n) => B(async () => {
|
|
482
|
+
let r = await Ue(e, t);
|
|
483
|
+
r && await e.update(M, String(r.id), {
|
|
483
484
|
status: n,
|
|
484
485
|
updatedAt: /* @__PURE__ */ new Date()
|
|
485
486
|
});
|
|
486
487
|
}, "subscriptionStore")
|
|
487
|
-
}),
|
|
488
|
+
}), Ge = () => {
|
|
488
489
|
let e = /* @__PURE__ */ new Map();
|
|
489
490
|
return {
|
|
490
491
|
upsert: (t) => p.sync(() => {
|
|
491
492
|
let n = e.get(t.providerInvoiceId);
|
|
492
|
-
n &&
|
|
493
|
+
n && H(n.statusEventAt, t.statusEventAt) || e.set(t.providerInvoiceId, t);
|
|
493
494
|
}),
|
|
494
495
|
listByTenant: (t) => p.sync(() => [...e.values()].filter((e) => e.tenantId === t))
|
|
495
496
|
};
|
|
496
|
-
},
|
|
497
|
+
}, Ke = (e) => ({
|
|
497
498
|
tenantId: String(e.tenantId),
|
|
498
499
|
provider: String(e.provider),
|
|
499
500
|
providerInvoiceId: String(e.providerInvoiceId),
|
|
@@ -501,41 +502,41 @@ var j = (e, t, n, r) => ({
|
|
|
501
502
|
currency: String(e.currency),
|
|
502
503
|
status: String(e.status),
|
|
503
504
|
statusEventAt: e.statusEventAt == null ? null : new Date(e.statusEventAt)
|
|
504
|
-
}),
|
|
505
|
-
upsert: (t) =>
|
|
506
|
-
let n = (await e.query(
|
|
507
|
-
table:
|
|
505
|
+
}), qe = (e) => ({
|
|
506
|
+
upsert: (t) => B(async () => {
|
|
507
|
+
let n = (await e.query(V({
|
|
508
|
+
table: N,
|
|
508
509
|
predicate: v("providerInvoiceId", t.providerInvoiceId),
|
|
509
510
|
take: 1
|
|
510
511
|
})))[0];
|
|
511
512
|
if (n) {
|
|
512
|
-
if (
|
|
513
|
-
await e.update(
|
|
513
|
+
if (H(n.statusEventAt == null ? null : new Date(n.statusEventAt), t.statusEventAt)) return;
|
|
514
|
+
await e.update(N, String(n.id), {
|
|
514
515
|
amountMinor: t.amountMinor,
|
|
515
516
|
currency: t.currency,
|
|
516
517
|
status: t.status,
|
|
517
518
|
statusEventAt: t.statusEventAt
|
|
518
519
|
});
|
|
519
|
-
} else await e.insert(
|
|
520
|
-
id:
|
|
520
|
+
} else await e.insert(N, {
|
|
521
|
+
id: z("binv"),
|
|
521
522
|
...t,
|
|
522
523
|
createdAt: /* @__PURE__ */ new Date()
|
|
523
524
|
});
|
|
524
525
|
}, "invoiceStore"),
|
|
525
|
-
listByTenant: (t) =>
|
|
526
|
-
table:
|
|
526
|
+
listByTenant: (t) => B(async () => (await e.query(V({
|
|
527
|
+
table: N,
|
|
527
528
|
predicate: v("tenantId", t),
|
|
528
529
|
order: [{
|
|
529
530
|
column: "createdAt",
|
|
530
531
|
direction: "desc"
|
|
531
532
|
}]
|
|
532
|
-
}))).map(
|
|
533
|
-
}),
|
|
533
|
+
}))).map(Ke), "invoiceStore")
|
|
534
|
+
}), U = (e, t, n) => `${e}\u0000${t}\u0000${n}`, Je = () => {
|
|
534
535
|
let e = /* @__PURE__ */ new Map();
|
|
535
536
|
return {
|
|
536
|
-
used: (t, n, r) => p.sync(() => e.get(
|
|
537
|
+
used: (t, n, r) => p.sync(() => e.get(U(t, n, r))?.used ?? 0),
|
|
537
538
|
consume: (t, n, r, i, a) => p.sync(() => {
|
|
538
|
-
let o =
|
|
539
|
+
let o = U(t, n, r), s = e.get(o), c = s?.used ?? 0, l = c + i <= a;
|
|
539
540
|
return l && e.set(o, {
|
|
540
541
|
tenantId: t,
|
|
541
542
|
entitlementKey: n,
|
|
@@ -551,7 +552,7 @@ var j = (e, t, n, r) => ({
|
|
|
551
552
|
};
|
|
552
553
|
}),
|
|
553
554
|
increment: (t, n, r, i) => p.sync(() => {
|
|
554
|
-
let a =
|
|
555
|
+
let a = U(t, n, r), o = e.get(a), s = (o?.used ?? 0) + i;
|
|
555
556
|
return e.set(a, {
|
|
556
557
|
tenantId: t,
|
|
557
558
|
entitlementKey: n,
|
|
@@ -562,32 +563,32 @@ var j = (e, t, n, r) => ({
|
|
|
562
563
|
}),
|
|
563
564
|
pending: () => p.sync(() => [...e.values()].filter((e) => e.used > e.reportedToProvider)),
|
|
564
565
|
markReported: (t, n, r, i) => p.sync(() => {
|
|
565
|
-
let a =
|
|
566
|
+
let a = U(t, n, r), o = e.get(a);
|
|
566
567
|
o && e.set(a, {
|
|
567
568
|
...o,
|
|
568
569
|
reportedToProvider: i
|
|
569
570
|
});
|
|
570
571
|
})
|
|
571
572
|
};
|
|
572
|
-
},
|
|
573
|
+
}, Ye = (e) => ({
|
|
573
574
|
tenantId: String(e.tenantId),
|
|
574
575
|
entitlementKey: String(e.entitlementKey),
|
|
575
576
|
period: String(e.period),
|
|
576
577
|
used: Number(e.used ?? 0),
|
|
577
578
|
reportedToProvider: Number(e.reportedToProvider ?? 0)
|
|
578
|
-
}),
|
|
579
|
+
}), W = async (e, t, n, r) => (await e.query(V({
|
|
579
580
|
table: "_voltro_billing_usage",
|
|
580
581
|
predicate: _(v("tenantId", t), v("entitlementKey", n), v("period", r)),
|
|
581
582
|
take: 1
|
|
582
|
-
})))[0] ?? null,
|
|
583
|
-
used: (t, n, r) =>
|
|
584
|
-
let i = await
|
|
583
|
+
})))[0] ?? null, Xe = (e) => ({
|
|
584
|
+
used: (t, n, r) => B(async () => {
|
|
585
|
+
let i = await W(e, t, n, r);
|
|
585
586
|
return i ? Number(i.used ?? 0) : 0;
|
|
586
587
|
}, "usageStore"),
|
|
587
|
-
consume: (t, n, r, i, a) =>
|
|
588
|
+
consume: (t, n, r, i, a) => B(async () => {
|
|
588
589
|
for (let o = 0; o < 32; o++) {
|
|
589
590
|
o > 0 && await new Promise((e) => setTimeout(e, o));
|
|
590
|
-
let s = await
|
|
591
|
+
let s = await W(e, t, n, r), c = s ? Number(s.used ?? 0) : 0;
|
|
591
592
|
if (c + i > a) return {
|
|
592
593
|
allowed: !1,
|
|
593
594
|
entitlement: n,
|
|
@@ -607,7 +608,7 @@ var j = (e, t, n, r) => ({
|
|
|
607
608
|
cost: i
|
|
608
609
|
};
|
|
609
610
|
} else {
|
|
610
|
-
let o =
|
|
611
|
+
let o = z("buse"), s = await e.insertIgnore(P, {
|
|
611
612
|
id: o,
|
|
612
613
|
tenantId: t,
|
|
613
614
|
entitlementKey: n,
|
|
@@ -631,10 +632,10 @@ var j = (e, t, n, r) => ({
|
|
|
631
632
|
}
|
|
632
633
|
throw Error(`billing usage consume: contention on (${t}, ${n}, ${r}) exceeded 32 attempts`);
|
|
633
634
|
}, "usageStore"),
|
|
634
|
-
increment: (t, n, r, i) =>
|
|
635
|
+
increment: (t, n, r, i) => B(async () => {
|
|
635
636
|
for (let a = 0; a < 32; a++) {
|
|
636
637
|
a > 0 && await new Promise((e) => setTimeout(e, a));
|
|
637
|
-
let o = await
|
|
638
|
+
let o = await W(e, t, n, r);
|
|
638
639
|
if (o) {
|
|
639
640
|
let t = Number(o.used ?? 0);
|
|
640
641
|
if (await e.updateMany("_voltro_billing_usage", {
|
|
@@ -642,7 +643,7 @@ var j = (e, t, n, r) => ({
|
|
|
642
643
|
updatedAt: /* @__PURE__ */ new Date()
|
|
643
644
|
}, { where: _(v("id", String(o.id)), v("used", t)) }) === 1) return t + i;
|
|
644
645
|
} else {
|
|
645
|
-
let a =
|
|
646
|
+
let a = z("buse"), o = await e.insertIgnore(P, {
|
|
646
647
|
id: a,
|
|
647
648
|
tenantId: t,
|
|
648
649
|
entitlementKey: n,
|
|
@@ -660,31 +661,31 @@ var j = (e, t, n, r) => ({
|
|
|
660
661
|
}
|
|
661
662
|
throw Error(`billing usage increment: contention on (${t}, ${n}, ${r}) exceeded 32 attempts`);
|
|
662
663
|
}, "usageStore"),
|
|
663
|
-
pending: () =>
|
|
664
|
-
markReported: (t, n, r, i) =>
|
|
665
|
-
let a = await
|
|
666
|
-
a && await e.update(
|
|
664
|
+
pending: () => B(async () => (await e.query(V({ table: P }))).map(Ye).filter((e) => e.used > e.reportedToProvider), "usageStore"),
|
|
665
|
+
markReported: (t, n, r, i) => B(async () => {
|
|
666
|
+
let a = await W(e, t, n, r);
|
|
667
|
+
a && await e.update(P, String(a.id), {
|
|
667
668
|
reportedToProvider: i,
|
|
668
669
|
updatedAt: /* @__PURE__ */ new Date()
|
|
669
670
|
});
|
|
670
671
|
}, "usageStore")
|
|
671
|
-
}),
|
|
672
|
-
customers:
|
|
673
|
-
subscriptions:
|
|
674
|
-
invoices:
|
|
675
|
-
usage:
|
|
676
|
-
dunningNotices:
|
|
677
|
-
}),
|
|
678
|
-
customers:
|
|
679
|
-
subscriptions:
|
|
680
|
-
invoices:
|
|
681
|
-
usage:
|
|
682
|
-
dunningNotices:
|
|
683
|
-
}),
|
|
672
|
+
}), Ze = () => ({
|
|
673
|
+
customers: Re(),
|
|
674
|
+
subscriptions: Ve(),
|
|
675
|
+
invoices: Ge(),
|
|
676
|
+
usage: Je(),
|
|
677
|
+
dunningNotices: Fe()
|
|
678
|
+
}), Qe = (e) => ({
|
|
679
|
+
customers: Be(e),
|
|
680
|
+
subscriptions: We(e),
|
|
681
|
+
invoices: qe(e),
|
|
682
|
+
usage: Xe(e),
|
|
683
|
+
dunningNotices: Le(e)
|
|
684
|
+
}), G = E({ scope: "@voltro/plugin-billing" }), K = (e = /* @__PURE__ */ new Date()) => `${e.getUTCFullYear()}-${String(e.getUTCMonth() + 1).padStart(2, "0")}`, $e = (e) => ({ stores: e ?? Ze() }), q = (e, t) => e.pipe(p.retry({
|
|
684
685
|
schedule: h.recurs(Math.max(0, t - 1)),
|
|
685
686
|
while: (e) => e.transient
|
|
686
|
-
})),
|
|
687
|
-
let { provider: n, plans: i } = t, a = t.attempts ?? 3, o = t.checkout, s = t.now ?? (() => /* @__PURE__ */ new Date()), c =
|
|
687
|
+
})), et = (t) => {
|
|
688
|
+
let { provider: n, plans: i } = t, a = t.attempts ?? 3, o = t.checkout, s = t.now ?? (() => /* @__PURE__ */ new Date()), c = $e(t.stores), l = t.dunning ?? L(void 0, {}), u = (e) => c.stores.subscriptions.getByTenant(e).pipe(p.map((t) => R(t, l, s(), e))), d = (e) => u(e).pipe(p.map((e) => e.plan)), f = (e) => c.stores.subscriptions.getByTenant(e), ee = (e, n) => p.gen(function* () {
|
|
688
689
|
if (t.resolveEntitlementLimit !== void 0) {
|
|
689
690
|
let r = yield* t.resolveEntitlementLimit(e, n);
|
|
690
691
|
if (r !== null) return r;
|
|
@@ -692,29 +693,29 @@ var j = (e, t, n, r) => ({
|
|
|
692
693
|
let r = yield* d(e);
|
|
693
694
|
return i.entitlementLimit(r, n);
|
|
694
695
|
}), te = (e, t, n) => p.gen(function* () {
|
|
695
|
-
return
|
|
696
|
+
return k(t, yield* ee(e, t), yield* c.stores.usage.used(e, t, K(s())), n);
|
|
696
697
|
}), m = (e, t, n) => p.gen(function* () {
|
|
697
698
|
let i = yield* ee(e, t);
|
|
698
699
|
if (!Number.isFinite(i) || n <= 0) return;
|
|
699
|
-
let a =
|
|
700
|
+
let a = K(s()), o = yield* c.stores.usage.consume(e, t, a, n, i);
|
|
700
701
|
if (!o.allowed) return yield* p.fail(new r({
|
|
701
702
|
entitlement: t,
|
|
702
703
|
limit: o.limit,
|
|
703
704
|
used: o.used,
|
|
704
705
|
cost: n
|
|
705
706
|
}));
|
|
706
|
-
}), h = (e, t, n) => n <= 0 ? p.void : c.stores.usage.increment(e, t,
|
|
707
|
+
}), h = (e, t, n) => n <= 0 ? p.void : c.stores.usage.increment(e, t, K(s()), n).pipe(p.asVoid), ne = () => p.gen(function* () {
|
|
707
708
|
if (!n.supportsMeteredUsage) return;
|
|
708
709
|
let e = yield* c.stores.usage.pending();
|
|
709
710
|
for (let t of e) {
|
|
710
711
|
let e = t.used - t.reportedToProvider;
|
|
711
|
-
e <= 0 || (yield*
|
|
712
|
+
e <= 0 || (yield* q(n.reportUsage({
|
|
712
713
|
tenantId: t.tenantId,
|
|
713
714
|
entitlementKey: t.entitlementKey,
|
|
714
715
|
quantity: e
|
|
715
716
|
}), a), yield* c.stores.usage.markReported(t.tenantId, t.entitlementKey, t.period, t.used));
|
|
716
717
|
}
|
|
717
|
-
}),
|
|
718
|
+
}), re = (t) => p.gen(function* () {
|
|
718
719
|
let r = i.priceIdFor(t.plan);
|
|
719
720
|
if (r === null) return yield* p.fail(new e({
|
|
720
721
|
source: "billing",
|
|
@@ -722,7 +723,7 @@ var j = (e, t, n, r) => ({
|
|
|
722
723
|
transient: !1
|
|
723
724
|
}));
|
|
724
725
|
let s = yield* c.stores.customers.getByTenant(t.tenantId);
|
|
725
|
-
return yield*
|
|
726
|
+
return yield* q(n.createCheckoutSession({
|
|
726
727
|
tenantId: t.tenantId,
|
|
727
728
|
priceId: r,
|
|
728
729
|
successUrl: t.successUrl,
|
|
@@ -732,18 +733,18 @@ var j = (e, t, n, r) => ({
|
|
|
732
733
|
...o?.adjustableQuantity === void 0 ? {} : { adjustableQuantity: o.adjustableQuantity },
|
|
733
734
|
...o?.trialDays === void 0 ? {} : { trialDays: o.trialDays }
|
|
734
735
|
}), a);
|
|
735
|
-
}),
|
|
736
|
+
}), ie = (t, r) => p.gen(function* () {
|
|
736
737
|
let i = yield* c.stores.customers.getByTenant(t);
|
|
737
738
|
return i === null ? yield* p.fail(new e({
|
|
738
739
|
source: "billing",
|
|
739
740
|
message: `no provider customer linked for tenant '${t}'`,
|
|
740
741
|
transient: !1
|
|
741
|
-
})) : yield*
|
|
742
|
+
})) : yield* q(n.createPortalSession({
|
|
742
743
|
tenantId: t,
|
|
743
744
|
providerCustomerId: i.providerCustomerId,
|
|
744
745
|
returnUrl: r
|
|
745
746
|
}), a);
|
|
746
|
-
}),
|
|
747
|
+
}), ae = (e) => p.gen(function* () {
|
|
747
748
|
if (l.resolveRecipient !== void 0) {
|
|
748
749
|
let t = yield* l.resolveRecipient(e);
|
|
749
750
|
if (t !== null) return t;
|
|
@@ -751,11 +752,11 @@ var j = (e, t, n, r) => ({
|
|
|
751
752
|
if (n.customerEmail === void 0) return null;
|
|
752
753
|
let t = yield* c.stores.customers.getByTenant(e);
|
|
753
754
|
return t === null ? null : yield* n.customerEmail(t.providerCustomerId);
|
|
754
|
-
}),
|
|
755
|
+
}), oe = (e) => {
|
|
755
756
|
let t = l.portalReturnUrl;
|
|
756
|
-
return t === void 0 ? p.succeed(null) :
|
|
757
|
-
},
|
|
758
|
-
let a = yield*
|
|
757
|
+
return t === void 0 ? p.succeed(null) : ie(e, t).pipe(p.map((e) => e.url), p.catchAll(() => p.succeed(null)));
|
|
758
|
+
}, g = (e, t, n, r, i) => p.gen(function* () {
|
|
759
|
+
let a = yield* ae(e.tenantId).pipe(p.catchAll(() => p.succeed(null))), o = yield* oe(e.tenantId), s = t.lockedSince !== null, c = Me({
|
|
759
760
|
stepId: n,
|
|
760
761
|
locked: s,
|
|
761
762
|
graceEndsAt: i,
|
|
@@ -773,7 +774,7 @@ var j = (e, t, n, r) => ({
|
|
|
773
774
|
portalUrl: o,
|
|
774
775
|
...c
|
|
775
776
|
};
|
|
776
|
-
|
|
777
|
+
G.info("billing dunning notice", {
|
|
777
778
|
tenant: e.tenantId,
|
|
778
779
|
step: n,
|
|
779
780
|
locked: s,
|
|
@@ -782,16 +783,16 @@ var j = (e, t, n, r) => ({
|
|
|
782
783
|
});
|
|
783
784
|
let d = l.notify;
|
|
784
785
|
d !== void 0 && (yield* d(u).pipe(p.catchAllCause((t) => p.sync(() => {
|
|
785
|
-
|
|
786
|
+
G.warn("billing dunning notify failed", {
|
|
786
787
|
tenant: e.tenantId,
|
|
787
788
|
step: n,
|
|
788
789
|
cause: String(t)
|
|
789
790
|
});
|
|
790
791
|
}))));
|
|
791
|
-
}),
|
|
792
|
+
}), _ = (e) => p.gen(function* () {
|
|
792
793
|
let t = yield* c.stores.subscriptions.getByTenant(e);
|
|
793
|
-
if (t === null) return
|
|
794
|
-
let r = yield* n.fetchSubscription(t.providerSubscriptionId).pipe(p.catchAll((t) => p.sync(() => (
|
|
794
|
+
if (t === null) return R(null, l, s(), e);
|
|
795
|
+
let r = yield* n.fetchSubscription(t.providerSubscriptionId).pipe(p.catchAll((t) => p.sync(() => (G.warn("billing dunning reconcile: provider unreachable, not escalating", {
|
|
795
796
|
tenant: e,
|
|
796
797
|
source: t.source,
|
|
797
798
|
message: t.message
|
|
@@ -817,28 +818,28 @@ var j = (e, t, n, r) => ({
|
|
|
817
818
|
statusEventAt: n
|
|
818
819
|
};
|
|
819
820
|
}
|
|
820
|
-
let a =
|
|
821
|
+
let a = R(i, l, s(), e);
|
|
821
822
|
if (!l.enabled || i.status !== "pastDue" || i.pastDueSince === null) return a;
|
|
822
|
-
let o = i.pastDueSince, u =
|
|
823
|
-
a.lockedSince !== null && f.push(
|
|
824
|
-
for (let t of f) (yield* c.stores.dunningNotices.claim(e, u, t, s())) && (yield*
|
|
823
|
+
let o = i.pastDueSince, u = Oe(o), d = a.graceEndsAt ?? o, f = Ae(l.steps, o, s()).map((e) => e.id);
|
|
824
|
+
a.lockedSince !== null && f.push(I);
|
|
825
|
+
for (let t of f) (yield* c.stores.dunningNotices.claim(e, u, t, s())) && (yield* g(i, a, t, o, d));
|
|
825
826
|
return a;
|
|
826
|
-
}),
|
|
827
|
+
}), se = () => p.gen(function* () {
|
|
827
828
|
let e = yield* c.stores.subscriptions.listByStatus("pastDue"), t = 0;
|
|
828
|
-
for (let n of e) yield*
|
|
829
|
-
|
|
829
|
+
for (let n of e) yield* _(n.tenantId).pipe(p.catchAll((e) => p.sync(() => {
|
|
830
|
+
G.warn("billing dunning sweep: tenant failed", {
|
|
830
831
|
tenant: n.tenantId,
|
|
831
832
|
message: e.message
|
|
832
833
|
});
|
|
833
834
|
}))), t += 1;
|
|
834
835
|
return t;
|
|
835
|
-
}),
|
|
836
|
+
}), ce = (e) => {
|
|
836
837
|
if (!l.enabled) return p.void;
|
|
837
|
-
if (e._tag === "invoicePaymentFailed") return
|
|
838
|
+
if (e._tag === "invoicePaymentFailed") return _(e.tenantId).pipe(p.asVoid);
|
|
838
839
|
if (e._tag !== "invoicePaid" && e._tag !== "subscriptionUpserted") return p.void;
|
|
839
840
|
let t = e.tenantId;
|
|
840
|
-
return c.stores.subscriptions.getByTenant(t).pipe(p.flatMap((e) => e !== null && (e.status === "pastDue" || e.pastDueSince !== null) ?
|
|
841
|
-
},
|
|
841
|
+
return c.stores.subscriptions.getByTenant(t).pipe(p.flatMap((e) => e !== null && (e.status === "pastDue" || e.pastDueSince !== null) ? _(t).pipe(p.asVoid) : p.void));
|
|
842
|
+
}, v = (e) => {
|
|
842
843
|
switch (e._tag) {
|
|
843
844
|
case "subscriptionUpserted": return c.stores.subscriptions.upsert({
|
|
844
845
|
tenantId: e.tenantId,
|
|
@@ -878,7 +879,7 @@ var j = (e, t, n, r) => ({
|
|
|
878
879
|
providerCustomerId: e.providerCustomerId
|
|
879
880
|
});
|
|
880
881
|
}
|
|
881
|
-
},
|
|
882
|
+
}, le = (e) => v(e).pipe(p.zipRight(ce(e))), y = (t, r) => p.gen(function* () {
|
|
882
883
|
let o = yield* c.stores.subscriptions.getByTenant(t);
|
|
883
884
|
if (o === null) return yield* p.fail(new e({
|
|
884
885
|
source: "billing",
|
|
@@ -896,7 +897,7 @@ var j = (e, t, n, r) => ({
|
|
|
896
897
|
message: `seat quantity must be a positive integer, got ${l}`,
|
|
897
898
|
transient: !1
|
|
898
899
|
}));
|
|
899
|
-
let u = yield*
|
|
900
|
+
let u = yield* q(n.updateSubscription({
|
|
900
901
|
providerSubscriptionId: o.providerSubscriptionId,
|
|
901
902
|
...r.plan === void 0 ? {} : { priceId: i.priceIdFor(s) ?? s },
|
|
902
903
|
...r.quantity === void 0 ? {} : { quantity: l },
|
|
@@ -920,17 +921,17 @@ var j = (e, t, n, r) => ({
|
|
|
920
921
|
subscription: f,
|
|
921
922
|
plan: d,
|
|
922
923
|
entitlementStatus: u,
|
|
923
|
-
reconcileDunning:
|
|
924
|
-
dunningSweep:
|
|
924
|
+
reconcileDunning: _,
|
|
925
|
+
dunningSweep: se,
|
|
925
926
|
checkEntitlement: te,
|
|
926
927
|
consumeEntitlement: m,
|
|
927
928
|
reportUsage: h,
|
|
928
929
|
flushUsage: ne,
|
|
929
|
-
startCheckout:
|
|
930
|
-
portalUrl:
|
|
931
|
-
applyEvent:
|
|
932
|
-
changePlan: (e, t) =>
|
|
933
|
-
changeSeats: (e, t) =>
|
|
930
|
+
startCheckout: re,
|
|
931
|
+
portalUrl: ie,
|
|
932
|
+
applyEvent: le,
|
|
933
|
+
changePlan: (e, t) => y(e, { plan: t }),
|
|
934
|
+
changeSeats: (e, t) => y(e, { quantity: t }),
|
|
934
935
|
previewChange: (t, r) => p.gen(function* () {
|
|
935
936
|
let o = yield* c.stores.subscriptions.getByTenant(t);
|
|
936
937
|
if (o === null) return yield* p.fail(new e({
|
|
@@ -938,7 +939,7 @@ var j = (e, t, n, r) => ({
|
|
|
938
939
|
message: `no subscription for tenant '${t}' to preview`,
|
|
939
940
|
transient: !1
|
|
940
941
|
}));
|
|
941
|
-
let s = r.plan ?? o.plan, l = yield*
|
|
942
|
+
let s = r.plan ?? o.plan, l = yield* q(n.previewSubscriptionChange({
|
|
942
943
|
providerSubscriptionId: o.providerSubscriptionId,
|
|
943
944
|
...r.plan === void 0 ? {} : { priceId: i.priceIdFor(s) ?? s },
|
|
944
945
|
...r.quantity === void 0 ? {} : { quantity: r.quantity },
|
|
@@ -954,12 +955,12 @@ var j = (e, t, n, r) => ({
|
|
|
954
955
|
}),
|
|
955
956
|
invoices: (e) => p.gen(function* () {
|
|
956
957
|
let t = yield* c.stores.customers.getByTenant(e);
|
|
957
|
-
return t === null ? [] : yield*
|
|
958
|
+
return t === null ? [] : yield* q(n.listInvoices({ providerCustomerId: t.providerCustomerId }), a);
|
|
958
959
|
})
|
|
959
960
|
},
|
|
960
961
|
holder: c
|
|
961
962
|
};
|
|
962
|
-
},
|
|
963
|
+
}, tt = (e) => m.succeed(t, e), nt = "_voltro_ai_usage", rt = (e) => {
|
|
963
964
|
for (let [t, n] of Object.entries(e)) {
|
|
964
965
|
if (t.length === 0) throw Error("billing metering: a meter key must be non-empty");
|
|
965
966
|
if (n.from === "rpc") {
|
|
@@ -968,28 +969,44 @@ var j = (e, t, n, r) => ({
|
|
|
968
969
|
if (typeof n.table != "string" || n.table.length === 0) throw Error(`billing metering: cdc meter '${t}' needs a 'table'`);
|
|
969
970
|
} else if (n.from !== "ai") throw Error(`billing metering: meter '${t}' has unknown source '${String(n.from)}'`);
|
|
970
971
|
}
|
|
971
|
-
},
|
|
972
|
+
}, it = /* @__PURE__ */ new WeakMap(), at = (e) => {
|
|
972
973
|
if (!e.global && !e.sticky) return e;
|
|
973
|
-
let t =
|
|
974
|
-
return t === void 0 && (t = new RegExp(e.source, e.flags.replace(/[gy]/g, "")),
|
|
975
|
-
},
|
|
976
|
-
let i =
|
|
974
|
+
let t = it.get(e);
|
|
975
|
+
return t === void 0 && (t = new RegExp(e.source, e.flags.replace(/[gy]/g, "")), it.set(e, t)), t;
|
|
976
|
+
}, ot = (e, t) => typeof e == "string" ? t === e : at(e).test(t), st = (e, t, n) => Object.entries(e).filter(([, e]) => e.from === "rpc" && (e.kind === void 0 || e.kind === n) && ot(e.match, t)).map(([e]) => e), ct = (e, t, n) => Object.entries(e).filter(([, e]) => e.from === "cdc" && e.table === t && (e.op ?? "insert") === n).map(([e]) => e), lt = (e) => Object.entries(e).filter(([, e]) => e.from === "ai").map(([e, t]) => [e, t.metric ?? "tokens"]), ut = (e) => e.tenantId, dt = (e, t, n, r) => p.forEach(n, (n) => e.reportUsage(t, n, r).pipe(p.catchAll(() => p.void)), { discard: !0 }), ft = (e, t) => (n, r) => {
|
|
977
|
+
let i = st(t, r.tag, r.kind);
|
|
977
978
|
if (i.length === 0) return n;
|
|
978
|
-
let a =
|
|
979
|
-
return a === null ? n : n.pipe(p.tap(() =>
|
|
980
|
-
},
|
|
981
|
-
let r =
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
979
|
+
let a = ut(r.subject);
|
|
980
|
+
return a === null ? n : n.pipe(p.tap(() => dt(e, a, i, 1)));
|
|
981
|
+
}, pt = "billing-meter", mt = 5e4, ht = (e, t, n = {}) => {
|
|
982
|
+
let r = new g({
|
|
983
|
+
windowMs: ue(),
|
|
984
|
+
maxEntries: mt
|
|
985
|
+
}), i = n.now ?? (() => Date.now()), a = !1;
|
|
986
|
+
return (o) => {
|
|
987
|
+
let s = ct(t, o.table, o.op);
|
|
988
|
+
if (s.length === 0) return p.void;
|
|
989
|
+
let c = o.new?.tenantId ?? o.old?.tenantId ?? null;
|
|
990
|
+
if (c === null) return p.void;
|
|
991
|
+
let l = n.claimChange?.();
|
|
992
|
+
if (l === void 0) return a || (a = !0, n.onUngated?.()), dt(e, c, s, 1);
|
|
993
|
+
let u = String(o.new?.id ?? o.old?.id ?? ""), d = se({
|
|
994
|
+
pipe: pt,
|
|
995
|
+
op: o.op,
|
|
996
|
+
key: u,
|
|
997
|
+
next: o.new ?? null,
|
|
998
|
+
prev: o.old ?? null
|
|
999
|
+
}), f = ce(d, r.next(d, i()));
|
|
1000
|
+
return p.promise(() => l(pt, f)).pipe(p.flatMap((t) => t ? dt(e, c, s, 1) : p.void));
|
|
1001
|
+
};
|
|
1002
|
+
}, gt = (e) => new Date(Date.UTC(e.getUTCFullYear(), e.getUTCMonth(), 1, 0, 0, 0, 0)), _t = (e, t, n, r = () => /* @__PURE__ */ new Date()) => p.gen(function* () {
|
|
1003
|
+
let i = lt(n);
|
|
987
1004
|
if (i.length === 0) return;
|
|
988
1005
|
let a = r();
|
|
989
|
-
|
|
1006
|
+
K(a);
|
|
990
1007
|
let o = {
|
|
991
|
-
table:
|
|
992
|
-
predicate:
|
|
1008
|
+
table: nt,
|
|
1009
|
+
predicate: le("calledAt", gt(a)),
|
|
993
1010
|
order: [],
|
|
994
1011
|
take: void 0,
|
|
995
1012
|
skip: void 0,
|
|
@@ -1010,14 +1027,14 @@ var j = (e, t, n, r) => ({
|
|
|
1010
1027
|
let o = a - (yield* e.checkEntitlement(r, t, 0).pipe(p.map((e) => e.used), p.catchAll(() => p.succeed(0))));
|
|
1011
1028
|
o > 0 && (yield* e.reportUsage(r, t, o).pipe(p.catchAll(() => p.void)));
|
|
1012
1029
|
}
|
|
1013
|
-
}),
|
|
1030
|
+
}), vt = (e, t, n, r) => _t(e, t, n, r).pipe(p.andThen(e.flushUsage().pipe(p.catchAll(() => p.void)))), yt = (e) => Object.values(e).some((e) => e.from === "cdc"), bt = (e) => e === void 0 ? 0 : e === "unlimited" ? Infinity : e, xt = (e) => {
|
|
1014
1031
|
let t = /* @__PURE__ */ new Map();
|
|
1015
1032
|
for (let [n, r] of Object.entries(e)) r.priceId !== void 0 && t.set(r.priceId, n);
|
|
1016
1033
|
return {
|
|
1017
1034
|
has: (t) => Object.prototype.hasOwnProperty.call(e, t),
|
|
1018
1035
|
entitlementLimit: (t, n) => {
|
|
1019
1036
|
let r = e[t];
|
|
1020
|
-
return r === void 0 ? 0 :
|
|
1037
|
+
return r === void 0 ? 0 : bt(r.entitlements[n]);
|
|
1021
1038
|
},
|
|
1022
1039
|
planForPriceId: (e) => t.get(e) ?? null,
|
|
1023
1040
|
priceIdFor: (t) => e[t]?.priceId ?? null,
|
|
@@ -1028,14 +1045,14 @@ var j = (e, t, n, r) => ({
|
|
|
1028
1045
|
currencyFor: (t) => (e[t]?.currency ?? "usd").toLowerCase(),
|
|
1029
1046
|
planIds: () => Object.keys(e)
|
|
1030
1047
|
};
|
|
1031
|
-
},
|
|
1032
|
-
id:
|
|
1033
|
-
windowKey:
|
|
1034
|
-
claimedBy:
|
|
1035
|
-
claimedAt:
|
|
1036
|
-
}).unique("billingFlushClaimWindow", ["windowKey"]),
|
|
1048
|
+
}, St = () => xt({ [n]: { entitlements: {} } }), J = "_voltro_billing_flush_claims", Ct = C(J, {
|
|
1049
|
+
id: y({ scheme: "numeric" }),
|
|
1050
|
+
windowKey: w(),
|
|
1051
|
+
claimedBy: w(),
|
|
1052
|
+
claimedAt: T().default("now")
|
|
1053
|
+
}).unique("billingFlushClaimWindow", ["windowKey"]), wt = (e, t) => `billing-flush:${Math.floor(e / Math.max(1, t))}`, Tt = async (e, t, n, r) => {
|
|
1037
1054
|
try {
|
|
1038
|
-
return (await e.insertIgnore(
|
|
1055
|
+
return (await e.insertIgnore(J, {
|
|
1039
1056
|
windowKey: t,
|
|
1040
1057
|
claimedBy: n,
|
|
1041
1058
|
claimedAt: new Date(r)
|
|
@@ -1043,38 +1060,38 @@ var j = (e, t, n, r) => ({
|
|
|
1043
1060
|
} catch {
|
|
1044
1061
|
return !0;
|
|
1045
1062
|
}
|
|
1046
|
-
},
|
|
1047
|
-
maxNetworkRetries:
|
|
1048
|
-
timeout:
|
|
1063
|
+
}, Et = 3, Dt = 2e4, Ot = (e) => e.client ?? new D(e.apiKey, {
|
|
1064
|
+
maxNetworkRetries: Et,
|
|
1065
|
+
timeout: Dt,
|
|
1049
1066
|
appInfo: {
|
|
1050
1067
|
name: "voltro",
|
|
1051
1068
|
url: "https://voltro.dev"
|
|
1052
1069
|
}
|
|
1053
|
-
}),
|
|
1070
|
+
}), kt = (e) => e instanceof D.errors.StripeConnectionError || e instanceof D.errors.StripeAPIError || e instanceof D.errors.StripeRateLimitError, At = (e) => e instanceof D.errors.StripeError ? e.code ?? e.type : void 0, Y = (t, n) => p.tryPromise({
|
|
1054
1071
|
try: n,
|
|
1055
1072
|
catch: (n) => new e({
|
|
1056
1073
|
source: t,
|
|
1057
|
-
message:
|
|
1058
|
-
transient:
|
|
1074
|
+
message: jt(n),
|
|
1075
|
+
transient: kt(n)
|
|
1059
1076
|
})
|
|
1060
|
-
}),
|
|
1061
|
-
if (e instanceof
|
|
1062
|
-
let t =
|
|
1077
|
+
}), jt = (e) => {
|
|
1078
|
+
if (e instanceof D.errors.StripeError) {
|
|
1079
|
+
let t = At(e);
|
|
1063
1080
|
return t === void 0 ? e.message : `${e.message} (${t})`;
|
|
1064
1081
|
}
|
|
1065
1082
|
return String(e?.message ?? e);
|
|
1066
|
-
},
|
|
1083
|
+
}, Mt = (e) => {
|
|
1067
1084
|
let t = e.items?.data?.[0];
|
|
1068
1085
|
return {
|
|
1069
|
-
start:
|
|
1070
|
-
end:
|
|
1086
|
+
start: X(t?.current_period_start),
|
|
1087
|
+
end: X(t?.current_period_end)
|
|
1071
1088
|
};
|
|
1072
|
-
},
|
|
1089
|
+
}, X = (e) => typeof e == "number" && Number.isFinite(e) ? /* @__PURE__ */ new Date(e * 1e3) : null, Nt = (e) => {
|
|
1073
1090
|
let t = e.items?.data ?? [];
|
|
1074
1091
|
if (t.length === 0) return 1;
|
|
1075
1092
|
let n = t.reduce((e, t) => e + (t.quantity ?? 0), 0);
|
|
1076
1093
|
return n > 0 ? n : 1;
|
|
1077
|
-
},
|
|
1094
|
+
}, Pt = {
|
|
1078
1095
|
active: "active",
|
|
1079
1096
|
trialing: "trialing",
|
|
1080
1097
|
past_due: "pastDue",
|
|
@@ -1083,44 +1100,44 @@ var j = (e, t, n, r) => ({
|
|
|
1083
1100
|
incomplete: "incomplete",
|
|
1084
1101
|
incomplete_expired: "canceled",
|
|
1085
1102
|
paused: "pastDue"
|
|
1086
|
-
},
|
|
1103
|
+
}, Z = (e) => {
|
|
1087
1104
|
let t = e.metadata?.tenantId;
|
|
1088
1105
|
if (typeof t == "string" && t.length > 0) return t;
|
|
1089
1106
|
let n = e.client_reference_id;
|
|
1090
1107
|
return typeof n == "string" && n.length > 0 ? n : null;
|
|
1091
|
-
},
|
|
1108
|
+
}, Ft = (e) => {
|
|
1092
1109
|
let t = e.items?.data?.[0]?.price;
|
|
1093
1110
|
return typeof t?.id == "string" ? t.id : null;
|
|
1094
|
-
},
|
|
1111
|
+
}, Q = (e, t) => {
|
|
1095
1112
|
let n = e.metadata?.plan;
|
|
1096
1113
|
if (typeof n == "string" && n.length > 0) return n;
|
|
1097
|
-
let r =
|
|
1114
|
+
let r = Ft(e);
|
|
1098
1115
|
return r !== null && t ? t(r) : null;
|
|
1099
|
-
},
|
|
1100
|
-
let n =
|
|
1116
|
+
}, It = (e, t) => {
|
|
1117
|
+
let n = X(e.created);
|
|
1101
1118
|
switch (e.type) {
|
|
1102
1119
|
case "customer.subscription.created":
|
|
1103
1120
|
case "customer.subscription.updated":
|
|
1104
1121
|
case "customer.subscription.resumed":
|
|
1105
1122
|
case "customer.subscription.paused": {
|
|
1106
|
-
let r = e.data.object, i =
|
|
1123
|
+
let r = e.data.object, i = Z(r), a = Q(r, t), o = Pt[r.status];
|
|
1107
1124
|
if (i === null || a === null || o === void 0) return null;
|
|
1108
|
-
let s =
|
|
1125
|
+
let s = Mt(r);
|
|
1109
1126
|
return {
|
|
1110
1127
|
_tag: "subscriptionUpserted",
|
|
1111
1128
|
tenantId: i,
|
|
1112
1129
|
providerSubscriptionId: r.id,
|
|
1113
1130
|
plan: a,
|
|
1114
1131
|
status: o,
|
|
1115
|
-
quantity:
|
|
1132
|
+
quantity: Nt(r),
|
|
1116
1133
|
currentPeriodStart: s.start,
|
|
1117
1134
|
currentPeriodEnd: s.end,
|
|
1118
|
-
cancelAt:
|
|
1135
|
+
cancelAt: X(r.cancel_at),
|
|
1119
1136
|
occurredAt: n
|
|
1120
1137
|
};
|
|
1121
1138
|
}
|
|
1122
1139
|
case "customer.subscription.deleted": {
|
|
1123
|
-
let t = e.data.object, r =
|
|
1140
|
+
let t = e.data.object, r = Z(t);
|
|
1124
1141
|
return r === null ? null : {
|
|
1125
1142
|
_tag: "subscriptionCanceled",
|
|
1126
1143
|
tenantId: r,
|
|
@@ -1130,7 +1147,7 @@ var j = (e, t, n, r) => ({
|
|
|
1130
1147
|
}
|
|
1131
1148
|
case "invoice.paid":
|
|
1132
1149
|
case "invoice.payment_failed": {
|
|
1133
|
-
let t = e.data.object, r =
|
|
1150
|
+
let t = e.data.object, r = Z(t);
|
|
1134
1151
|
return r === null || typeof t.id != "string" ? null : {
|
|
1135
1152
|
_tag: e.type === "invoice.paid" ? "invoicePaid" : "invoicePaymentFailed",
|
|
1136
1153
|
tenantId: r,
|
|
@@ -1141,7 +1158,7 @@ var j = (e, t, n, r) => ({
|
|
|
1141
1158
|
};
|
|
1142
1159
|
}
|
|
1143
1160
|
case "customer.created": {
|
|
1144
|
-
let t = e.data.object, r =
|
|
1161
|
+
let t = e.data.object, r = Z(t);
|
|
1145
1162
|
return r === null ? null : {
|
|
1146
1163
|
_tag: "customerLinked",
|
|
1147
1164
|
tenantId: r,
|
|
@@ -1151,16 +1168,16 @@ var j = (e, t, n, r) => ({
|
|
|
1151
1168
|
}
|
|
1152
1169
|
default: return null;
|
|
1153
1170
|
}
|
|
1154
|
-
},
|
|
1171
|
+
}, Lt = {
|
|
1155
1172
|
prorate: "create_prorations",
|
|
1156
1173
|
none: "none",
|
|
1157
1174
|
always_invoice: "always_invoice"
|
|
1158
|
-
},
|
|
1159
|
-
let n =
|
|
1160
|
-
let n =
|
|
1175
|
+
}, Rt = (t) => {
|
|
1176
|
+
let n = Ot(t), r = t.planForPriceId, i = (e) => n.subscriptions.retrieve(e, { expand: ["items.data.price"] }), a = (e, t) => {
|
|
1177
|
+
let n = Mt(e), i = e.items?.data?.[0]?.price;
|
|
1161
1178
|
return {
|
|
1162
|
-
plan:
|
|
1163
|
-
quantity:
|
|
1179
|
+
plan: Q(e, r) ?? "free",
|
|
1180
|
+
quantity: Nt(e),
|
|
1164
1181
|
prorationMinor: t,
|
|
1165
1182
|
currency: (i?.currency ?? "usd").toLowerCase(),
|
|
1166
1183
|
currentPeriodStart: n.start,
|
|
@@ -1174,7 +1191,7 @@ var j = (e, t, n, r) => ({
|
|
|
1174
1191
|
...t.priceId === void 0 ? {} : { price: t.priceId },
|
|
1175
1192
|
...t.quantity === void 0 ? {} : { quantity: t.quantity }
|
|
1176
1193
|
}],
|
|
1177
|
-
proration_behavior:
|
|
1194
|
+
proration_behavior: Lt[t.proration ?? "prorate"],
|
|
1178
1195
|
...t.priceId !== void 0 && r ? { metadata: {
|
|
1179
1196
|
...e.metadata,
|
|
1180
1197
|
plan: r(t.priceId) ?? ""
|
|
@@ -1184,7 +1201,7 @@ var j = (e, t, n, r) => ({
|
|
|
1184
1201
|
return {
|
|
1185
1202
|
name: "stripe",
|
|
1186
1203
|
supportsMeteredUsage: t.supportsMeteredUsage ?? !0,
|
|
1187
|
-
createCheckoutSession: (e) =>
|
|
1204
|
+
createCheckoutSession: (e) => Y("stripe.checkout.sessions.create", async () => {
|
|
1188
1205
|
let t = await n.checkout.sessions.create({
|
|
1189
1206
|
mode: "subscription",
|
|
1190
1207
|
line_items: [{
|
|
@@ -1216,11 +1233,11 @@ var j = (e, t, n, r) => ({
|
|
|
1216
1233
|
if (typeof t.url != "string") throw Error("checkout session has no url");
|
|
1217
1234
|
return { url: t.url };
|
|
1218
1235
|
}),
|
|
1219
|
-
createPortalSession: (e) =>
|
|
1236
|
+
createPortalSession: (e) => Y("stripe.billingPortal.sessions.create", async () => ({ url: (await n.billingPortal.sessions.create({
|
|
1220
1237
|
customer: e.providerCustomerId,
|
|
1221
1238
|
return_url: e.returnUrl
|
|
1222
1239
|
})).url })),
|
|
1223
|
-
reportUsage: (e) =>
|
|
1240
|
+
reportUsage: (e) => Y("stripe.billing.meterEvents.create", async () => {
|
|
1224
1241
|
await n.billing.meterEvents.create({
|
|
1225
1242
|
event_name: e.entitlementKey,
|
|
1226
1243
|
identifier: `${e.tenantId}:${e.entitlementKey}:${e.periodEnd?.toISOString() ?? "current"}`,
|
|
@@ -1230,11 +1247,11 @@ var j = (e, t, n, r) => ({
|
|
|
1230
1247
|
}
|
|
1231
1248
|
});
|
|
1232
1249
|
}),
|
|
1233
|
-
updateSubscription: (e) =>
|
|
1234
|
-
let t = await i(e.providerSubscriptionId), r = await n.subscriptions.update(e.providerSubscriptionId, o(t, e)), s = await
|
|
1250
|
+
updateSubscription: (e) => Y("stripe.subscriptions.update", async () => {
|
|
1251
|
+
let t = await i(e.providerSubscriptionId), r = await n.subscriptions.update(e.providerSubscriptionId, o(t, e)), s = await Bt(n, r);
|
|
1235
1252
|
return a(r, s);
|
|
1236
1253
|
}),
|
|
1237
|
-
previewSubscriptionChange: (e) =>
|
|
1254
|
+
previewSubscriptionChange: (e) => Y("stripe.invoices.createPreview", async () => {
|
|
1238
1255
|
let t = await i(e.providerSubscriptionId), s = o(t, e), c = (await n.invoices.createPreview({
|
|
1239
1256
|
subscription: e.providerSubscriptionId,
|
|
1240
1257
|
subscription_details: {
|
|
@@ -1248,27 +1265,27 @@ var j = (e, t, n, r) => ({
|
|
|
1248
1265
|
...e.priceId !== void 0 && r ? { plan: r(e.priceId) ?? "free" } : {}
|
|
1249
1266
|
};
|
|
1250
1267
|
}),
|
|
1251
|
-
fetchSubscription: (e) =>
|
|
1268
|
+
fetchSubscription: (e) => Y("stripe.subscriptions.retrieve", async () => {
|
|
1252
1269
|
try {
|
|
1253
|
-
let t = await i(e), n =
|
|
1270
|
+
let t = await i(e), n = Mt(t);
|
|
1254
1271
|
return {
|
|
1255
|
-
status:
|
|
1256
|
-
plan:
|
|
1257
|
-
quantity:
|
|
1272
|
+
status: Pt[t.status] ?? "incomplete",
|
|
1273
|
+
plan: Q(t, r),
|
|
1274
|
+
quantity: Nt(t),
|
|
1258
1275
|
currentPeriodStart: n.start,
|
|
1259
1276
|
currentPeriodEnd: n.end,
|
|
1260
|
-
cancelAt:
|
|
1277
|
+
cancelAt: X(t.cancel_at)
|
|
1261
1278
|
};
|
|
1262
1279
|
} catch (e) {
|
|
1263
|
-
if (e instanceof
|
|
1280
|
+
if (e instanceof D.errors.StripeInvalidRequestError && e.statusCode === 404) return null;
|
|
1264
1281
|
throw e;
|
|
1265
1282
|
}
|
|
1266
1283
|
}),
|
|
1267
|
-
customerEmail: (e) =>
|
|
1284
|
+
customerEmail: (e) => Y("stripe.customers.retrieve", async () => {
|
|
1268
1285
|
let t = await n.customers.retrieve(e);
|
|
1269
1286
|
return t.deleted === !0 ? null : typeof t.email == "string" && t.email.length > 0 ? t.email : null;
|
|
1270
1287
|
}),
|
|
1271
|
-
listInvoices: (e) =>
|
|
1288
|
+
listInvoices: (e) => Y("stripe.invoices.list", async () => (await n.invoices.list({
|
|
1272
1289
|
customer: e.providerCustomerId,
|
|
1273
1290
|
limit: e.limit ?? 20
|
|
1274
1291
|
})).data.map((e) => ({
|
|
@@ -1276,7 +1293,7 @@ var j = (e, t, n, r) => ({
|
|
|
1276
1293
|
amountMinor: e.amount_due,
|
|
1277
1294
|
currency: e.currency,
|
|
1278
1295
|
status: e.status ?? "unknown",
|
|
1279
|
-
createdAt:
|
|
1296
|
+
createdAt: X(e.created),
|
|
1280
1297
|
hostedUrl: e.hosted_invoice_url ?? null,
|
|
1281
1298
|
pdfUrl: e.invoice_pdf ?? null
|
|
1282
1299
|
}))),
|
|
@@ -1288,15 +1305,15 @@ var j = (e, t, n, r) => ({
|
|
|
1288
1305
|
transient: !1
|
|
1289
1306
|
})
|
|
1290
1307
|
}),
|
|
1291
|
-
normalizeEvent: (e) => p.succeed(
|
|
1308
|
+
normalizeEvent: (e) => p.succeed(zt(e) ? It(e, r) : null)
|
|
1292
1309
|
};
|
|
1293
|
-
},
|
|
1310
|
+
}, zt = (e) => typeof e == "object" && !!e && typeof e.type == "string" && typeof e.data == "object", Bt = async (e, t) => {
|
|
1294
1311
|
try {
|
|
1295
1312
|
return (await e.invoices.createPreview({ subscription: t.id })).lines.data.filter((e) => e.parent?.subscription_item_details?.proration === !0).reduce((e, t) => e + t.amount, 0);
|
|
1296
1313
|
} catch {
|
|
1297
1314
|
return 0;
|
|
1298
1315
|
}
|
|
1299
|
-
},
|
|
1316
|
+
}, Vt = (e) => {
|
|
1300
1317
|
let t = e?.baseUrl ?? "https://mock.billing.local", n = [], r = [], i = [], a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), s = (e) => typeof e == "object" && !!e && typeof e._tag == "string";
|
|
1301
1318
|
return {
|
|
1302
1319
|
name: "mock",
|
|
@@ -1336,22 +1353,22 @@ var j = (e, t, n, r) => ({
|
|
|
1336
1353
|
listInvoices: () => p.succeed([]),
|
|
1337
1354
|
normalizeEvent: (e) => p.succeed(s(e) ? e : null)
|
|
1338
1355
|
};
|
|
1339
|
-
},
|
|
1356
|
+
}, Ht = (e) => {
|
|
1340
1357
|
let { provider: t, env: n } = e;
|
|
1341
1358
|
if (t !== void 0 && typeof t == "object") return t;
|
|
1342
1359
|
if ((t ?? (n.STRIPE_SECRET_KEY ? "stripe" : "mock")) === "stripe") {
|
|
1343
1360
|
let t = e.apiKey ?? n.STRIPE_SECRET_KEY;
|
|
1344
1361
|
if (!t) throw Error("billingPlugin: provider 'stripe' needs an apiKey (option or STRIPE_SECRET_KEY env)");
|
|
1345
|
-
return
|
|
1362
|
+
return Rt({
|
|
1346
1363
|
apiKey: t,
|
|
1347
1364
|
...e.planForPriceId ? { planForPriceId: e.planForPriceId } : {}
|
|
1348
1365
|
});
|
|
1349
1366
|
}
|
|
1350
|
-
return
|
|
1351
|
-
},
|
|
1352
|
-
id:
|
|
1367
|
+
return Vt();
|
|
1368
|
+
}, Ut = E({ scope: "@voltro/plugin-billing" }), Wt = "billing", $ = "/billing/webhook", Gt = (e) => fe({
|
|
1369
|
+
id: Wt,
|
|
1353
1370
|
path: $,
|
|
1354
|
-
provider:
|
|
1371
|
+
provider: O(),
|
|
1355
1372
|
payload: ne.Unknown,
|
|
1356
1373
|
handler: async (t) => {
|
|
1357
1374
|
let n = e.provider.verifyWebhook !== void 0 && e.webhookSecret !== null && e.webhookSecret !== void 0 ? await p.runPromise(e.provider.verifyWebhook({
|
|
@@ -1363,25 +1380,25 @@ var j = (e, t, n, r) => ({
|
|
|
1363
1380
|
await p.runPromise(e.service.applyEvent(r));
|
|
1364
1381
|
let i = e.onEvent?.[r._tag];
|
|
1365
1382
|
i !== void 0 && await p.runPromise(i(r).pipe(p.catchAllCause((e) => p.sync(() => {
|
|
1366
|
-
|
|
1383
|
+
Ut.warn("billing onEvent side effect failed", {
|
|
1367
1384
|
event: r._tag,
|
|
1368
1385
|
cause: String(e)
|
|
1369
1386
|
});
|
|
1370
1387
|
}))));
|
|
1371
1388
|
}
|
|
1372
|
-
}),
|
|
1389
|
+
}), Kt = (e) => pe(Gt(e), {
|
|
1373
1390
|
resolveSecret: () => Promise.resolve(e.webhookSecret),
|
|
1374
1391
|
...e.idempotencyCache === void 0 ? {} : { idempotencyCache: e.idempotencyCache },
|
|
1375
1392
|
log: (e) => {
|
|
1376
|
-
e.status >= 400 &&
|
|
1393
|
+
e.status >= 400 && Ut.warn("billing webhook rejected", { ...e });
|
|
1377
1394
|
}
|
|
1378
|
-
}),
|
|
1395
|
+
}), qt = (e) => e === null ? null : {
|
|
1379
1396
|
plan: e.plan,
|
|
1380
1397
|
status: e.status,
|
|
1381
1398
|
quantity: e.quantity,
|
|
1382
1399
|
currentPeriodEnd: e.currentPeriodEnd ? e.currentPeriodEnd.toISOString() : null,
|
|
1383
1400
|
cancelAt: e.cancelAt ? e.cancelAt.toISOString() : null
|
|
1384
|
-
},
|
|
1401
|
+
}, Jt = re([{
|
|
1385
1402
|
name: "STRIPE_SECRET_KEY",
|
|
1386
1403
|
required: !1,
|
|
1387
1404
|
secret: !0,
|
|
@@ -1391,50 +1408,50 @@ var j = (e, t, n, r) => ({
|
|
|
1391
1408
|
required: !1,
|
|
1392
1409
|
secret: !0,
|
|
1393
1410
|
description: "Stripe webhook signing secret (whsec_…) for verifying webhook payloads."
|
|
1394
|
-
}]),
|
|
1395
|
-
let n = process.env, m =
|
|
1411
|
+
}]), Yt = "@voltro/plugin-billing", Xt = (t = {}) => {
|
|
1412
|
+
let n = process.env, m = xt(t.plans ?? {}), h = Ht({
|
|
1396
1413
|
...t.provider === void 0 ? {} : { provider: t.provider },
|
|
1397
1414
|
...t.apiKey === void 0 ? {} : { apiKey: t.apiKey },
|
|
1398
1415
|
planForPriceId: m.planForPriceId,
|
|
1399
1416
|
env: n
|
|
1400
|
-
}), ne = t.webhookSecret ??
|
|
1401
|
-
|
|
1417
|
+
}), ne = t.webhookSecret ?? Jt.read("STRIPE_WEBHOOK_SECRET") ?? null, re = L(t.dunning, n);
|
|
1418
|
+
x({
|
|
1402
1419
|
source: "plugin",
|
|
1403
|
-
table:
|
|
1420
|
+
table: P,
|
|
1404
1421
|
timeColumn: "updatedAt",
|
|
1405
|
-
ttlMs:
|
|
1422
|
+
ttlMs: S(process.env.VOLTRO_BILLING_USAGE_TTL_HOURS, 9600),
|
|
1406
1423
|
label: "billing usage counters"
|
|
1407
|
-
}),
|
|
1424
|
+
}), x({
|
|
1408
1425
|
source: "plugin",
|
|
1409
|
-
table:
|
|
1426
|
+
table: J,
|
|
1410
1427
|
timeColumn: "claimedAt",
|
|
1411
|
-
ttlMs:
|
|
1428
|
+
ttlMs: S(process.env.VOLTRO_BILLING_FLUSH_CLAIM_TTL_HOURS, 1),
|
|
1412
1429
|
label: "billing flush claims"
|
|
1413
|
-
}),
|
|
1430
|
+
}), x({
|
|
1414
1431
|
source: "plugin",
|
|
1415
|
-
table:
|
|
1432
|
+
table: F,
|
|
1416
1433
|
timeColumn: "sentAt",
|
|
1417
|
-
ttlMs:
|
|
1434
|
+
ttlMs: S(process.env.VOLTRO_BILLING_DUNNING_TTL_HOURS, 9600),
|
|
1418
1435
|
label: "billing dunning notices"
|
|
1419
1436
|
});
|
|
1420
|
-
let { service:
|
|
1437
|
+
let { service: g, holder: _ } = et({
|
|
1421
1438
|
provider: h,
|
|
1422
1439
|
plans: m,
|
|
1423
1440
|
...t.attempts === void 0 ? {} : { attempts: t.attempts },
|
|
1424
1441
|
...t.checkout === void 0 ? {} : { checkout: t.checkout },
|
|
1425
1442
|
...t.resolveEntitlementLimit === void 0 ? {} : { resolveEntitlementLimit: t.resolveEntitlementLimit },
|
|
1426
|
-
dunning:
|
|
1427
|
-
}),
|
|
1443
|
+
dunning: re
|
|
1444
|
+
}), se = tt(g), ce = Kt({
|
|
1428
1445
|
provider: h,
|
|
1429
|
-
service:
|
|
1446
|
+
service: g,
|
|
1430
1447
|
webhookSecret: ne,
|
|
1431
1448
|
...t.onEvent === void 0 ? {} : { onEvent: t.onEvent }
|
|
1432
|
-
}),
|
|
1449
|
+
}), v = {
|
|
1433
1450
|
method: "POST",
|
|
1434
1451
|
path: $,
|
|
1435
1452
|
originGuard: "exempt",
|
|
1436
1453
|
handle: async (e) => {
|
|
1437
|
-
let t = await
|
|
1454
|
+
let t = await ce({
|
|
1438
1455
|
method: e.method,
|
|
1439
1456
|
path: e.path,
|
|
1440
1457
|
headers: e.headers,
|
|
@@ -1447,12 +1464,12 @@ var j = (e, t, n, r) => ({
|
|
|
1447
1464
|
...t.headers === void 0 ? {} : { headers: { ...t.headers } }
|
|
1448
1465
|
};
|
|
1449
1466
|
}
|
|
1450
|
-
},
|
|
1467
|
+
}, le = [
|
|
1451
1468
|
{
|
|
1452
1469
|
...ee,
|
|
1453
1470
|
execute: (e, t) => {
|
|
1454
1471
|
let n = e;
|
|
1455
|
-
return
|
|
1472
|
+
return g.startCheckout({
|
|
1456
1473
|
tenantId: t.request.subject.tenantId ?? "",
|
|
1457
1474
|
plan: n.plan,
|
|
1458
1475
|
successUrl: n.successUrl,
|
|
@@ -1465,16 +1482,16 @@ var j = (e, t, n, r) => ({
|
|
|
1465
1482
|
...u,
|
|
1466
1483
|
execute: (e, t) => {
|
|
1467
1484
|
let n = e;
|
|
1468
|
-
return
|
|
1485
|
+
return g.portalUrl(t.request.subject.tenantId ?? "", n.returnUrl);
|
|
1469
1486
|
}
|
|
1470
1487
|
},
|
|
1471
1488
|
{
|
|
1472
1489
|
...te,
|
|
1473
|
-
execute: (e, t) =>
|
|
1490
|
+
execute: (e, t) => g.subscription(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({ subscription: qt(e) })))
|
|
1474
1491
|
},
|
|
1475
1492
|
{
|
|
1476
1493
|
...c,
|
|
1477
|
-
execute: (e, t) =>
|
|
1494
|
+
execute: (e, t) => g.entitlementStatus(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({
|
|
1478
1495
|
plan: e.plan,
|
|
1479
1496
|
billedPlan: e.billedPlan,
|
|
1480
1497
|
status: e.status,
|
|
@@ -1489,7 +1506,7 @@ var j = (e, t, n, r) => ({
|
|
|
1489
1506
|
...d,
|
|
1490
1507
|
execute: (e, t) => {
|
|
1491
1508
|
let n = e;
|
|
1492
|
-
return
|
|
1509
|
+
return g.previewChange(t.request.subject.tenantId ?? "", {
|
|
1493
1510
|
...n.plan === void 0 ? {} : { plan: n.plan },
|
|
1494
1511
|
...n.quantity === void 0 ? {} : { quantity: n.quantity }
|
|
1495
1512
|
}).pipe(p.map((e) => ({
|
|
@@ -1502,7 +1519,7 @@ var j = (e, t, n, r) => ({
|
|
|
1502
1519
|
},
|
|
1503
1520
|
{
|
|
1504
1521
|
...l,
|
|
1505
|
-
execute: (e, t) =>
|
|
1522
|
+
execute: (e, t) => g.invoices(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({ invoices: e.map((e) => ({
|
|
1506
1523
|
...e,
|
|
1507
1524
|
createdAt: e.createdAt?.toISOString() ?? null
|
|
1508
1525
|
})) })))
|
|
@@ -1511,14 +1528,14 @@ var j = (e, t, n, r) => ({
|
|
|
1511
1528
|
...f,
|
|
1512
1529
|
execute: (e, t) => {
|
|
1513
1530
|
let n = e;
|
|
1514
|
-
return
|
|
1531
|
+
return g.reportUsage(t.request.subject.tenantId ?? "", n.key, n.quantity).pipe(p.map(() => ({ ok: !0 })));
|
|
1515
1532
|
}
|
|
1516
1533
|
},
|
|
1517
1534
|
{
|
|
1518
1535
|
...o,
|
|
1519
1536
|
execute: (e, t) => {
|
|
1520
1537
|
let n = e;
|
|
1521
|
-
return
|
|
1538
|
+
return g.changePlan(t.request.subject.tenantId ?? "", n.plan).pipe(p.map((e) => ({
|
|
1522
1539
|
plan: e.plan,
|
|
1523
1540
|
quantity: e.quantity,
|
|
1524
1541
|
prorationMinor: e.prorationMinor,
|
|
@@ -1530,7 +1547,7 @@ var j = (e, t, n, r) => ({
|
|
|
1530
1547
|
...s,
|
|
1531
1548
|
execute: (e, t) => {
|
|
1532
1549
|
let n = e;
|
|
1533
|
-
return
|
|
1550
|
+
return g.changeSeats(t.request.subject.tenantId ?? "", n.quantity).pipe(p.map((e) => ({
|
|
1534
1551
|
plan: e.plan,
|
|
1535
1552
|
quantity: e.quantity,
|
|
1536
1553
|
prorationMinor: e.prorationMinor,
|
|
@@ -1538,11 +1555,11 @@ var j = (e, t, n, r) => ({
|
|
|
1538
1555
|
})));
|
|
1539
1556
|
}
|
|
1540
1557
|
}
|
|
1541
|
-
],
|
|
1558
|
+
], y = (e, t) => ({
|
|
1542
1559
|
kind: "json",
|
|
1543
1560
|
status: e,
|
|
1544
1561
|
data: { error: t }
|
|
1545
|
-
}),
|
|
1562
|
+
}), b = [{
|
|
1546
1563
|
method: "GET",
|
|
1547
1564
|
path: "/stats",
|
|
1548
1565
|
description: "Billing config: provider, declared plans, enforced tags",
|
|
@@ -1560,11 +1577,11 @@ var j = (e, t, n, r) => ({
|
|
|
1560
1577
|
method: "GET",
|
|
1561
1578
|
path: "/usage",
|
|
1562
1579
|
description: "Pending (un-flushed) metered usage counters",
|
|
1563
|
-
handler: () =>
|
|
1580
|
+
handler: () => _.stores.usage.pending().pipe(p.map((e) => ({
|
|
1564
1581
|
kind: "json",
|
|
1565
1582
|
data: { usage: e }
|
|
1566
|
-
})), p.catchAll((e) => p.succeed(
|
|
1567
|
-
}],
|
|
1583
|
+
})), p.catchAll((e) => p.succeed(y(500, e.message))))
|
|
1584
|
+
}], ue = [
|
|
1568
1585
|
{
|
|
1569
1586
|
schema: e,
|
|
1570
1587
|
import: {
|
|
@@ -1586,72 +1603,77 @@ var j = (e, t, n, r) => ({
|
|
|
1586
1603
|
name: "SubscriptionLocked"
|
|
1587
1604
|
}
|
|
1588
1605
|
}
|
|
1589
|
-
],
|
|
1590
|
-
|
|
1591
|
-
let
|
|
1606
|
+
], C = t.enforce, w = C !== void 0 && Object.keys(C).length > 0 ? ge(C, g) : void 0, T = t.metering;
|
|
1607
|
+
T !== void 0 && rt(T);
|
|
1608
|
+
let E = T !== void 0 && Object.keys(T).length > 0 ? ft(g, T) : void 0, D = T !== void 0 && yt(T), fe = { claim: void 0 }, pe = T === void 0 ? void 0 : ht(g, T, {
|
|
1609
|
+
claimChange: () => fe.claim,
|
|
1610
|
+
onUngated: () => {
|
|
1611
|
+
p.runSync(p.logWarning("metering: CDC meters are accruing PER PROCESS — with N replicas a tenant is billed N times. The framework did not hand this plugin a change claimer (expected on the memory store; on a SQL store this is a bug worth reporting).").pipe(p.annotateLogs({ scope: "voltro:billing" })));
|
|
1612
|
+
}
|
|
1613
|
+
}), O = ie([E, w].filter((e) => e !== void 0)), k, A, me = [
|
|
1592
1614
|
"store:write",
|
|
1593
1615
|
"inspect:read",
|
|
1594
1616
|
"inspect:write",
|
|
1595
1617
|
"network:outbound:*",
|
|
1596
|
-
...
|
|
1597
|
-
...
|
|
1598
|
-
...
|
|
1618
|
+
...O === void 0 ? [] : ["rpc:intercept:mutation", "rpc:intercept:action"],
|
|
1619
|
+
...E === void 0 ? [] : ["rpc:intercept:query"],
|
|
1620
|
+
...D ? ["store:changes:read"] : []
|
|
1599
1621
|
];
|
|
1600
|
-
return
|
|
1601
|
-
name:
|
|
1602
|
-
base:
|
|
1622
|
+
return ae({
|
|
1623
|
+
name: oe({
|
|
1624
|
+
base: Yt,
|
|
1603
1625
|
alias: t.alias,
|
|
1604
1626
|
instance: t.name
|
|
1605
1627
|
}),
|
|
1606
|
-
baseName:
|
|
1628
|
+
baseName: Yt,
|
|
1607
1629
|
description: "Billing — subscriptions, plans, entitlements + usage metering over a pluggable BillingProvider (Stripe + mock). Ships the BillingService, the requireEntitlement() in-handler guard + the enforce-map interceptor, the /billing/webhook receiver (riding @voltro/plugin-webhooks for signature + idempotency), and the _voltro_billing_* tables. Money is integer minor units.",
|
|
1608
|
-
permissions:
|
|
1609
|
-
declaredEnv:
|
|
1610
|
-
services:
|
|
1611
|
-
routes:
|
|
1630
|
+
permissions: me,
|
|
1631
|
+
declaredEnv: Jt.declared,
|
|
1632
|
+
services: se,
|
|
1633
|
+
routes: le,
|
|
1612
1634
|
rpcClientDescriptors: a,
|
|
1613
|
-
httpRoutes: [
|
|
1614
|
-
inspectEndpoints:
|
|
1635
|
+
httpRoutes: [v],
|
|
1636
|
+
inspectEndpoints: b,
|
|
1615
1637
|
extendSchema: { tables: [
|
|
1616
|
-
...
|
|
1617
|
-
|
|
1618
|
-
|
|
1638
|
+
...xe(),
|
|
1639
|
+
Ct,
|
|
1640
|
+
Se
|
|
1619
1641
|
] },
|
|
1620
|
-
errorSchemas:
|
|
1621
|
-
...
|
|
1622
|
-
interceptMutation:
|
|
1623
|
-
interceptAction:
|
|
1642
|
+
errorSchemas: ue,
|
|
1643
|
+
...O === void 0 ? {} : {
|
|
1644
|
+
interceptMutation: O,
|
|
1645
|
+
interceptAction: O
|
|
1624
1646
|
},
|
|
1625
|
-
...
|
|
1626
|
-
...
|
|
1627
|
-
bindDataStore: (e) => {
|
|
1628
|
-
|
|
1647
|
+
...E === void 0 ? {} : { interceptQuery: E },
|
|
1648
|
+
...D ? { onChangeEvent: pe } : {},
|
|
1649
|
+
bindDataStore: (e, t) => {
|
|
1650
|
+
_.stores = Qe(e), k = e, fe.claim = t?.claimChange;
|
|
1629
1651
|
},
|
|
1630
1652
|
onActivate: (e) => p.sync(() => {
|
|
1631
1653
|
e.logger.info("billing active", {
|
|
1632
1654
|
provider: h.name,
|
|
1633
1655
|
plans: m.planIds().length,
|
|
1634
|
-
enforce:
|
|
1635
|
-
metering:
|
|
1656
|
+
enforce: C ? Object.keys(C).length : 0,
|
|
1657
|
+
metering: T ? Object.keys(T).length : 0,
|
|
1636
1658
|
webhook: $
|
|
1637
1659
|
});
|
|
1638
|
-
let n = t.flushIntervalMs ?? 6e4, r =
|
|
1660
|
+
let n = t.flushIntervalMs ?? 6e4, r = T, i = r !== void 0 && Object.keys(r).length > 0;
|
|
1639
1661
|
if (n > 0) {
|
|
1640
|
-
let e =
|
|
1641
|
-
|
|
1642
|
-
let t =
|
|
1662
|
+
let e = de();
|
|
1663
|
+
A = setInterval(() => {
|
|
1664
|
+
let t = k;
|
|
1643
1665
|
if (t === void 0) return;
|
|
1644
1666
|
let a = Date.now();
|
|
1645
1667
|
(async () => {
|
|
1646
|
-
await
|
|
1668
|
+
await Tt(t, wt(a, n), e, a) && i && await p.runPromise(vt(g, t, r).pipe(p.catchAll(() => p.void)));
|
|
1647
1669
|
})();
|
|
1648
|
-
}, n),
|
|
1670
|
+
}, n), A.unref?.();
|
|
1649
1671
|
}
|
|
1650
1672
|
}),
|
|
1651
1673
|
onDeactivate: () => p.sync(() => {
|
|
1652
|
-
|
|
1674
|
+
A !== void 0 && (clearInterval(A), A = void 0);
|
|
1653
1675
|
})
|
|
1654
1676
|
});
|
|
1655
1677
|
};
|
|
1656
1678
|
//#endregion
|
|
1657
|
-
export {
|
|
1679
|
+
export { j as BILLING_CUSTOMERS_TABLE, F as BILLING_DUNNING_NOTICES_TABLE, J as BILLING_FLUSH_CLAIMS_TABLE, N as BILLING_INVOICES_TABLE, M as BILLING_SUBSCRIPTIONS_TABLE, P as BILLING_USAGE_TABLE, Wt as BILLING_WEBHOOK_ID, $ as BILLING_WEBHOOK_PATH, e as BillingError, t as BillingService, Ce as DEFAULT_DUNNING_STEPS, we as DEFAULT_GRACE_HOURS, Te as DEFAULT_LOCKOUT, n as DEFAULT_PLAN, I as DUNNING_LOCK_STEP_ID, r as EntitlementExceeded, i as SubscriptionLocked, _e as billingCustomersTable, Se as billingDunningNoticesTable, Ct as billingFlushClaimsTable, ye as billingInvoicesTable, Xt as billingPlugin, tt as billingServiceLayer, ve as billingSubscriptionsTable, xe as billingTables, be as billingUsageTable, Gt as billingWebhookDescriptor, et as buildBillingService, ge as buildEnforceInterceptor, xt as buildPlanRegistry, Tt as claimFlushWindow, Le as dataStoreDunningNoticeStore, Qe as dataStoreStores, Me as defaultDunningEmail, Ae as dueSteps, Ne as dunningMailNotifier, St as emptyPlanRegistry, Oe as episodeKeyOf, R as evaluateBillingEntitlement, k as evaluateEntitlement, wt as flushWindowKey, ke as graceEndOf, H as isStaleStatusEvent, Fe as memoryDunningNoticeStore, Ze as memoryStores, Vt as mockProvider, Kt as mountBillingWebhook, It as normalizeStripeEvent, K as periodKey, he as requireEntitled, me as requireEntitlement, L as resolveDunningConfig, Ht as resolveProvider, Rt as stripeProvider };
|