@voltro/plugin-billing 0.55.0 → 0.57.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 +691 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +402 -376
- 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,23 @@ 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
|
+
let r = t ?? (n.STRIPE_SECRET_KEY ? "stripe" : "mock");
|
|
1360
|
+
if (r === "mock" && t === void 0 && n.NODE_ENV === "production" && e.log?.warn("billing: no STRIPE_SECRET_KEY and no explicit `provider` — running the MOCK billing provider. Every charge, subscription and invoice call will SUCCEED and reach nobody. Set STRIPE_SECRET_KEY, or declare `billingPlugin({ provider: 'mock' })` to say this is deliberate."), r === "stripe") {
|
|
1343
1361
|
let t = e.apiKey ?? n.STRIPE_SECRET_KEY;
|
|
1344
1362
|
if (!t) throw Error("billingPlugin: provider 'stripe' needs an apiKey (option or STRIPE_SECRET_KEY env)");
|
|
1345
|
-
return
|
|
1363
|
+
return Rt({
|
|
1346
1364
|
apiKey: t,
|
|
1347
1365
|
...e.planForPriceId ? { planForPriceId: e.planForPriceId } : {}
|
|
1348
1366
|
});
|
|
1349
1367
|
}
|
|
1350
|
-
return
|
|
1351
|
-
},
|
|
1352
|
-
id:
|
|
1368
|
+
return Vt();
|
|
1369
|
+
}, Ut = E({ scope: "@voltro/plugin-billing" }), Wt = "billing", $ = "/billing/webhook", Gt = (e) => fe({
|
|
1370
|
+
id: Wt,
|
|
1353
1371
|
path: $,
|
|
1354
|
-
provider:
|
|
1372
|
+
provider: O(),
|
|
1355
1373
|
payload: ne.Unknown,
|
|
1356
1374
|
handler: async (t) => {
|
|
1357
1375
|
let n = e.provider.verifyWebhook !== void 0 && e.webhookSecret !== null && e.webhookSecret !== void 0 ? await p.runPromise(e.provider.verifyWebhook({
|
|
@@ -1363,25 +1381,25 @@ var j = (e, t, n, r) => ({
|
|
|
1363
1381
|
await p.runPromise(e.service.applyEvent(r));
|
|
1364
1382
|
let i = e.onEvent?.[r._tag];
|
|
1365
1383
|
i !== void 0 && await p.runPromise(i(r).pipe(p.catchAllCause((e) => p.sync(() => {
|
|
1366
|
-
|
|
1384
|
+
Ut.warn("billing onEvent side effect failed", {
|
|
1367
1385
|
event: r._tag,
|
|
1368
1386
|
cause: String(e)
|
|
1369
1387
|
});
|
|
1370
1388
|
}))));
|
|
1371
1389
|
}
|
|
1372
|
-
}),
|
|
1390
|
+
}), Kt = (e) => pe(Gt(e), {
|
|
1373
1391
|
resolveSecret: () => Promise.resolve(e.webhookSecret),
|
|
1374
1392
|
...e.idempotencyCache === void 0 ? {} : { idempotencyCache: e.idempotencyCache },
|
|
1375
1393
|
log: (e) => {
|
|
1376
|
-
e.status >= 400 &&
|
|
1394
|
+
e.status >= 400 && Ut.warn("billing webhook rejected", { ...e });
|
|
1377
1395
|
}
|
|
1378
|
-
}),
|
|
1396
|
+
}), qt = (e) => e === null ? null : {
|
|
1379
1397
|
plan: e.plan,
|
|
1380
1398
|
status: e.status,
|
|
1381
1399
|
quantity: e.quantity,
|
|
1382
1400
|
currentPeriodEnd: e.currentPeriodEnd ? e.currentPeriodEnd.toISOString() : null,
|
|
1383
1401
|
cancelAt: e.cancelAt ? e.cancelAt.toISOString() : null
|
|
1384
|
-
},
|
|
1402
|
+
}, Jt = re([{
|
|
1385
1403
|
name: "STRIPE_SECRET_KEY",
|
|
1386
1404
|
required: !1,
|
|
1387
1405
|
secret: !0,
|
|
@@ -1391,50 +1409,53 @@ var j = (e, t, n, r) => ({
|
|
|
1391
1409
|
required: !1,
|
|
1392
1410
|
secret: !0,
|
|
1393
1411
|
description: "Stripe webhook signing secret (whsec_…) for verifying webhook payloads."
|
|
1394
|
-
}]),
|
|
1395
|
-
let n = process.env, m =
|
|
1412
|
+
}]), Yt = "@voltro/plugin-billing", Xt = (t = {}) => {
|
|
1413
|
+
let n = process.env, m = xt(t.plans ?? {}), h = Ht({
|
|
1396
1414
|
...t.provider === void 0 ? {} : { provider: t.provider },
|
|
1397
1415
|
...t.apiKey === void 0 ? {} : { apiKey: t.apiKey },
|
|
1398
1416
|
planForPriceId: m.planForPriceId,
|
|
1417
|
+
log: { warn: (e) => {
|
|
1418
|
+
console.warn(e);
|
|
1419
|
+
} },
|
|
1399
1420
|
env: n
|
|
1400
|
-
}), ne = t.webhookSecret ??
|
|
1401
|
-
|
|
1421
|
+
}), ne = t.webhookSecret ?? Jt.read("STRIPE_WEBHOOK_SECRET") ?? null, re = L(t.dunning, n);
|
|
1422
|
+
x({
|
|
1402
1423
|
source: "plugin",
|
|
1403
|
-
table:
|
|
1424
|
+
table: P,
|
|
1404
1425
|
timeColumn: "updatedAt",
|
|
1405
|
-
ttlMs:
|
|
1426
|
+
ttlMs: S(process.env.VOLTRO_BILLING_USAGE_TTL_HOURS, 9600),
|
|
1406
1427
|
label: "billing usage counters"
|
|
1407
|
-
}),
|
|
1428
|
+
}), x({
|
|
1408
1429
|
source: "plugin",
|
|
1409
|
-
table:
|
|
1430
|
+
table: J,
|
|
1410
1431
|
timeColumn: "claimedAt",
|
|
1411
|
-
ttlMs:
|
|
1432
|
+
ttlMs: S(process.env.VOLTRO_BILLING_FLUSH_CLAIM_TTL_HOURS, 1),
|
|
1412
1433
|
label: "billing flush claims"
|
|
1413
|
-
}),
|
|
1434
|
+
}), x({
|
|
1414
1435
|
source: "plugin",
|
|
1415
|
-
table:
|
|
1436
|
+
table: F,
|
|
1416
1437
|
timeColumn: "sentAt",
|
|
1417
|
-
ttlMs:
|
|
1438
|
+
ttlMs: S(process.env.VOLTRO_BILLING_DUNNING_TTL_HOURS, 9600),
|
|
1418
1439
|
label: "billing dunning notices"
|
|
1419
1440
|
});
|
|
1420
|
-
let { service:
|
|
1441
|
+
let { service: g, holder: _ } = et({
|
|
1421
1442
|
provider: h,
|
|
1422
1443
|
plans: m,
|
|
1423
1444
|
...t.attempts === void 0 ? {} : { attempts: t.attempts },
|
|
1424
1445
|
...t.checkout === void 0 ? {} : { checkout: t.checkout },
|
|
1425
1446
|
...t.resolveEntitlementLimit === void 0 ? {} : { resolveEntitlementLimit: t.resolveEntitlementLimit },
|
|
1426
|
-
dunning:
|
|
1427
|
-
}),
|
|
1447
|
+
dunning: re
|
|
1448
|
+
}), se = tt(g), ce = Kt({
|
|
1428
1449
|
provider: h,
|
|
1429
|
-
service:
|
|
1450
|
+
service: g,
|
|
1430
1451
|
webhookSecret: ne,
|
|
1431
1452
|
...t.onEvent === void 0 ? {} : { onEvent: t.onEvent }
|
|
1432
|
-
}),
|
|
1453
|
+
}), v = {
|
|
1433
1454
|
method: "POST",
|
|
1434
1455
|
path: $,
|
|
1435
1456
|
originGuard: "exempt",
|
|
1436
1457
|
handle: async (e) => {
|
|
1437
|
-
let t = await
|
|
1458
|
+
let t = await ce({
|
|
1438
1459
|
method: e.method,
|
|
1439
1460
|
path: e.path,
|
|
1440
1461
|
headers: e.headers,
|
|
@@ -1447,12 +1468,12 @@ var j = (e, t, n, r) => ({
|
|
|
1447
1468
|
...t.headers === void 0 ? {} : { headers: { ...t.headers } }
|
|
1448
1469
|
};
|
|
1449
1470
|
}
|
|
1450
|
-
},
|
|
1471
|
+
}, le = [
|
|
1451
1472
|
{
|
|
1452
1473
|
...ee,
|
|
1453
1474
|
execute: (e, t) => {
|
|
1454
1475
|
let n = e;
|
|
1455
|
-
return
|
|
1476
|
+
return g.startCheckout({
|
|
1456
1477
|
tenantId: t.request.subject.tenantId ?? "",
|
|
1457
1478
|
plan: n.plan,
|
|
1458
1479
|
successUrl: n.successUrl,
|
|
@@ -1465,16 +1486,16 @@ var j = (e, t, n, r) => ({
|
|
|
1465
1486
|
...u,
|
|
1466
1487
|
execute: (e, t) => {
|
|
1467
1488
|
let n = e;
|
|
1468
|
-
return
|
|
1489
|
+
return g.portalUrl(t.request.subject.tenantId ?? "", n.returnUrl);
|
|
1469
1490
|
}
|
|
1470
1491
|
},
|
|
1471
1492
|
{
|
|
1472
1493
|
...te,
|
|
1473
|
-
execute: (e, t) =>
|
|
1494
|
+
execute: (e, t) => g.subscription(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({ subscription: qt(e) })))
|
|
1474
1495
|
},
|
|
1475
1496
|
{
|
|
1476
1497
|
...c,
|
|
1477
|
-
execute: (e, t) =>
|
|
1498
|
+
execute: (e, t) => g.entitlementStatus(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({
|
|
1478
1499
|
plan: e.plan,
|
|
1479
1500
|
billedPlan: e.billedPlan,
|
|
1480
1501
|
status: e.status,
|
|
@@ -1489,7 +1510,7 @@ var j = (e, t, n, r) => ({
|
|
|
1489
1510
|
...d,
|
|
1490
1511
|
execute: (e, t) => {
|
|
1491
1512
|
let n = e;
|
|
1492
|
-
return
|
|
1513
|
+
return g.previewChange(t.request.subject.tenantId ?? "", {
|
|
1493
1514
|
...n.plan === void 0 ? {} : { plan: n.plan },
|
|
1494
1515
|
...n.quantity === void 0 ? {} : { quantity: n.quantity }
|
|
1495
1516
|
}).pipe(p.map((e) => ({
|
|
@@ -1502,7 +1523,7 @@ var j = (e, t, n, r) => ({
|
|
|
1502
1523
|
},
|
|
1503
1524
|
{
|
|
1504
1525
|
...l,
|
|
1505
|
-
execute: (e, t) =>
|
|
1526
|
+
execute: (e, t) => g.invoices(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({ invoices: e.map((e) => ({
|
|
1506
1527
|
...e,
|
|
1507
1528
|
createdAt: e.createdAt?.toISOString() ?? null
|
|
1508
1529
|
})) })))
|
|
@@ -1511,14 +1532,14 @@ var j = (e, t, n, r) => ({
|
|
|
1511
1532
|
...f,
|
|
1512
1533
|
execute: (e, t) => {
|
|
1513
1534
|
let n = e;
|
|
1514
|
-
return
|
|
1535
|
+
return g.reportUsage(t.request.subject.tenantId ?? "", n.key, n.quantity).pipe(p.map(() => ({ ok: !0 })));
|
|
1515
1536
|
}
|
|
1516
1537
|
},
|
|
1517
1538
|
{
|
|
1518
1539
|
...o,
|
|
1519
1540
|
execute: (e, t) => {
|
|
1520
1541
|
let n = e;
|
|
1521
|
-
return
|
|
1542
|
+
return g.changePlan(t.request.subject.tenantId ?? "", n.plan).pipe(p.map((e) => ({
|
|
1522
1543
|
plan: e.plan,
|
|
1523
1544
|
quantity: e.quantity,
|
|
1524
1545
|
prorationMinor: e.prorationMinor,
|
|
@@ -1530,7 +1551,7 @@ var j = (e, t, n, r) => ({
|
|
|
1530
1551
|
...s,
|
|
1531
1552
|
execute: (e, t) => {
|
|
1532
1553
|
let n = e;
|
|
1533
|
-
return
|
|
1554
|
+
return g.changeSeats(t.request.subject.tenantId ?? "", n.quantity).pipe(p.map((e) => ({
|
|
1534
1555
|
plan: e.plan,
|
|
1535
1556
|
quantity: e.quantity,
|
|
1536
1557
|
prorationMinor: e.prorationMinor,
|
|
@@ -1538,11 +1559,11 @@ var j = (e, t, n, r) => ({
|
|
|
1538
1559
|
})));
|
|
1539
1560
|
}
|
|
1540
1561
|
}
|
|
1541
|
-
],
|
|
1562
|
+
], y = (e, t) => ({
|
|
1542
1563
|
kind: "json",
|
|
1543
1564
|
status: e,
|
|
1544
1565
|
data: { error: t }
|
|
1545
|
-
}),
|
|
1566
|
+
}), b = [{
|
|
1546
1567
|
method: "GET",
|
|
1547
1568
|
path: "/stats",
|
|
1548
1569
|
description: "Billing config: provider, declared plans, enforced tags",
|
|
@@ -1560,11 +1581,11 @@ var j = (e, t, n, r) => ({
|
|
|
1560
1581
|
method: "GET",
|
|
1561
1582
|
path: "/usage",
|
|
1562
1583
|
description: "Pending (un-flushed) metered usage counters",
|
|
1563
|
-
handler: () =>
|
|
1584
|
+
handler: () => _.stores.usage.pending().pipe(p.map((e) => ({
|
|
1564
1585
|
kind: "json",
|
|
1565
1586
|
data: { usage: e }
|
|
1566
|
-
})), p.catchAll((e) => p.succeed(
|
|
1567
|
-
}],
|
|
1587
|
+
})), p.catchAll((e) => p.succeed(y(500, e.message))))
|
|
1588
|
+
}], ue = [
|
|
1568
1589
|
{
|
|
1569
1590
|
schema: e,
|
|
1570
1591
|
import: {
|
|
@@ -1586,72 +1607,77 @@ var j = (e, t, n, r) => ({
|
|
|
1586
1607
|
name: "SubscriptionLocked"
|
|
1587
1608
|
}
|
|
1588
1609
|
}
|
|
1589
|
-
],
|
|
1590
|
-
|
|
1591
|
-
let
|
|
1610
|
+
], C = t.enforce, w = C !== void 0 && Object.keys(C).length > 0 ? ge(C, g) : void 0, T = t.metering;
|
|
1611
|
+
T !== void 0 && rt(T);
|
|
1612
|
+
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, {
|
|
1613
|
+
claimChange: () => fe.claim,
|
|
1614
|
+
onUngated: () => {
|
|
1615
|
+
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" })));
|
|
1616
|
+
}
|
|
1617
|
+
}), O = ie([E, w].filter((e) => e !== void 0)), k, A, me = [
|
|
1592
1618
|
"store:write",
|
|
1593
1619
|
"inspect:read",
|
|
1594
1620
|
"inspect:write",
|
|
1595
1621
|
"network:outbound:*",
|
|
1596
|
-
...
|
|
1597
|
-
...
|
|
1598
|
-
...
|
|
1622
|
+
...O === void 0 ? [] : ["rpc:intercept:mutation", "rpc:intercept:action"],
|
|
1623
|
+
...E === void 0 ? [] : ["rpc:intercept:query"],
|
|
1624
|
+
...D ? ["store:changes:read"] : []
|
|
1599
1625
|
];
|
|
1600
|
-
return
|
|
1601
|
-
name:
|
|
1602
|
-
base:
|
|
1626
|
+
return ae({
|
|
1627
|
+
name: oe({
|
|
1628
|
+
base: Yt,
|
|
1603
1629
|
alias: t.alias,
|
|
1604
1630
|
instance: t.name
|
|
1605
1631
|
}),
|
|
1606
|
-
baseName:
|
|
1632
|
+
baseName: Yt,
|
|
1607
1633
|
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:
|
|
1634
|
+
permissions: me,
|
|
1635
|
+
declaredEnv: Jt.declared,
|
|
1636
|
+
services: se,
|
|
1637
|
+
routes: le,
|
|
1612
1638
|
rpcClientDescriptors: a,
|
|
1613
|
-
httpRoutes: [
|
|
1614
|
-
inspectEndpoints:
|
|
1639
|
+
httpRoutes: [v],
|
|
1640
|
+
inspectEndpoints: b,
|
|
1615
1641
|
extendSchema: { tables: [
|
|
1616
|
-
...
|
|
1617
|
-
|
|
1618
|
-
|
|
1642
|
+
...xe(),
|
|
1643
|
+
Ct,
|
|
1644
|
+
Se
|
|
1619
1645
|
] },
|
|
1620
|
-
errorSchemas:
|
|
1621
|
-
...
|
|
1622
|
-
interceptMutation:
|
|
1623
|
-
interceptAction:
|
|
1646
|
+
errorSchemas: ue,
|
|
1647
|
+
...O === void 0 ? {} : {
|
|
1648
|
+
interceptMutation: O,
|
|
1649
|
+
interceptAction: O
|
|
1624
1650
|
},
|
|
1625
|
-
...
|
|
1626
|
-
...
|
|
1627
|
-
bindDataStore: (e) => {
|
|
1628
|
-
|
|
1651
|
+
...E === void 0 ? {} : { interceptQuery: E },
|
|
1652
|
+
...D ? { onChangeEvent: pe } : {},
|
|
1653
|
+
bindDataStore: (e, t) => {
|
|
1654
|
+
_.stores = Qe(e), k = e, fe.claim = t?.claimChange;
|
|
1629
1655
|
},
|
|
1630
1656
|
onActivate: (e) => p.sync(() => {
|
|
1631
1657
|
e.logger.info("billing active", {
|
|
1632
1658
|
provider: h.name,
|
|
1633
1659
|
plans: m.planIds().length,
|
|
1634
|
-
enforce:
|
|
1635
|
-
metering:
|
|
1660
|
+
enforce: C ? Object.keys(C).length : 0,
|
|
1661
|
+
metering: T ? Object.keys(T).length : 0,
|
|
1636
1662
|
webhook: $
|
|
1637
1663
|
});
|
|
1638
|
-
let n = t.flushIntervalMs ?? 6e4, r =
|
|
1664
|
+
let n = t.flushIntervalMs ?? 6e4, r = T, i = r !== void 0 && Object.keys(r).length > 0;
|
|
1639
1665
|
if (n > 0) {
|
|
1640
|
-
let e =
|
|
1641
|
-
|
|
1642
|
-
let t =
|
|
1666
|
+
let e = de();
|
|
1667
|
+
A = setInterval(() => {
|
|
1668
|
+
let t = k;
|
|
1643
1669
|
if (t === void 0) return;
|
|
1644
1670
|
let a = Date.now();
|
|
1645
1671
|
(async () => {
|
|
1646
|
-
await
|
|
1672
|
+
await Tt(t, wt(a, n), e, a) && i && await p.runPromise(vt(g, t, r).pipe(p.catchAll(() => p.void)));
|
|
1647
1673
|
})();
|
|
1648
|
-
}, n),
|
|
1674
|
+
}, n), A.unref?.();
|
|
1649
1675
|
}
|
|
1650
1676
|
}),
|
|
1651
1677
|
onDeactivate: () => p.sync(() => {
|
|
1652
|
-
|
|
1678
|
+
A !== void 0 && (clearInterval(A), A = void 0);
|
|
1653
1679
|
})
|
|
1654
1680
|
});
|
|
1655
1681
|
};
|
|
1656
1682
|
//#endregion
|
|
1657
|
-
export {
|
|
1683
|
+
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 };
|