@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/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 g } from "@voltro/env";
5
- import { composeRpcInterceptors as re, definePlugin as ie, pluginInstanceName as ae } from "@voltro/protocol";
6
- import { and as _, eq as v, gte as y, id as b, integer as x, registerRetention as S, retentionTtlMsFromEnv as C, table as w, text as T, timestamp as E } from "@voltro/database";
7
- import { createLogger as D } from "@voltro/logger";
8
- import O from "stripe";
9
- import { defineIncomingWebhook as oe, mountIncomingWebhook as k } from "@voltro/plugin-webhooks";
10
- import { stripeProvider as A } from "@voltro/plugin-webhooks/providers";
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 j = (e, t, n, r) => ({
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
- }), M = (e) => e.tenantId, se = (e, n, i) => p.gen(function* () {
19
- let a = M(e.request.subject);
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
- }), N = (e) => p.gen(function* () {
28
- let n = M(e.request.subject);
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
- }), ce = (e, t) => (n, i) => {
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
- }, P = "_voltro_billing_customers", F = "_voltro_billing_subscriptions", I = "_voltro_billing_invoices", L = "_voltro_billing_usage", le = w(P, {
48
- id: b({ prefix: "bcust" }),
49
- tenantId: T(),
50
- provider: T(),
51
- providerCustomerId: T(),
52
- createdAt: E(),
53
- updatedAt: E()
54
- }).index("byBillingCustomerTenant", ["tenantId"]).index("byBillingProviderCustomer", ["providerCustomerId"]), ue = w(F, {
55
- id: b({ prefix: "bsub" }),
56
- tenantId: T(),
57
- provider: T(),
58
- providerSubscriptionId: T(),
59
- plan: T(),
60
- status: T(),
61
- quantity: x().default(1),
62
- currentPeriodStart: E().nullable(),
63
- currentPeriodEnd: E().nullable(),
64
- cancelAt: E().nullable(),
65
- pastDueSince: E().nullable(),
66
- statusEventAt: E().nullable(),
67
- createdAt: E(),
68
- updatedAt: E()
69
- }).index("byBillingSubscriptionTenant", ["tenantId"]).index("byBillingProviderSubscription", ["providerSubscriptionId"]).index("byBillingSubscriptionStatus", ["status"]), de = w(I, {
70
- id: b({ prefix: "binv" }),
71
- tenantId: T(),
72
- provider: T(),
73
- providerInvoiceId: T(),
74
- amountMinor: x(),
75
- currency: T(),
76
- status: T(),
77
- statusEventAt: E().nullable(),
78
- createdAt: E()
79
- }).index("byBillingInvoiceTenant", ["tenantId"]).index("byBillingProviderInvoice", ["providerInvoiceId"]), fe = w(L, {
80
- id: b({ prefix: "buse" }),
81
- tenantId: T().maxLength(191),
82
- entitlementKey: T().maxLength(191),
83
- period: T().maxLength(16),
84
- used: x().default(0),
85
- reportedToProvider: x().default(0),
86
- updatedAt: E()
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
- ]), pe = () => [
92
- le,
93
- ue,
94
- de,
95
- fe
96
- ], R = "_voltro_billing_dunning_notices", me = w(R, {
97
- id: b({ prefix: "bdun" }),
98
- tenantId: T().maxLength(191),
99
- episode: T().maxLength(32),
100
- stepId: T().maxLength(64),
101
- sentAt: E()
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
- ]), he = "locked", ge = [
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
- ], _e = 168, ve = "hard", ye = (e, t, n) => {
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
- }, be = (e, t) => {
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 = ye(t.VOLTRO_BILLING_GRACE_HOURS, e?.graceHours ?? 168, "VOLTRO_BILLING_GRACE_HOURS"), s = e?.steps ?? ge, c = t.VOLTRO_BILLING_DUNNING_STEP_HOURS, l = s;
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: ye(e[n], t.afterHours, "VOLTRO_BILLING_DUNNING_STEP_HOURS")
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: '${he}' is the reserved lockout step id`);
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
- }, xe = 36e5, Se = (e) => String(e.getTime()), Ce = (e, t) => new Date(e.getTime() + t * xe), we = (e, t, n) => {
154
- let r = (n.getTime() - t.getTime()) / xe;
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
- }, z = (e, t, r, i) => {
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 = Ce(e.pastDueSince, t.graceHours), o = r.getTime() >= i.getTime();
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
- }, Te = (e) => e.toISOString().slice(0, 10), Ee = (e) => {
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 = Te(e.graceEndsAt), a = e.stepId === "payment-failed" ? "Your last payment could not be collected." : "Your payment is still outstanding.";
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
- }, De = (e) => (t) => t.to === null ? p.void : e.send({
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), Oe = (e, t, n) => `${e}\u0000${t}\u0000${n}`, ke = () => {
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 = Oe(t, n, r);
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
- }, Ae = () => `bdun_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`, je = (t) => ({
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 = Ae(), o = await t.insertIgnore(R, {
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: R,
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
- }), B = (e) => `${e}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`, V = (t, n) => p.tryPromise({
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
- }), H = (e) => ({
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
- }), Me = () => {
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
- }, Ne = (e) => ({
321
+ }, ze = (e) => ({
321
322
  tenantId: String(e.tenantId),
322
323
  provider: String(e.provider),
323
324
  providerCustomerId: String(e.providerCustomerId)
324
- }), Pe = (e) => ({
325
- upsert: (t) => V(async () => {
326
- let n = await e.query(H({
327
- table: P,
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(P, String(n[0].id), {
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(P, {
336
- id: B("bcust"),
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) => V(async () => {
343
- let n = await e.query(H({
344
- table: P,
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] ? Ne(n[0]) : null;
349
+ return n[0] ? ze(n[0]) : null;
349
350
  }, "customerStore")
350
- }), U = (e, t) => e === null ? !1 : t === null || t.getTime() < e.getTime(), Fe = () => {
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 && U(n.statusEventAt, t.statusEventAt) || e.set(t.tenantId, {
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
- }, Ie = (e) => ({
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
- }), Le = async (e, t) => (await e.query(H({
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, Re = (e) => ({
399
- upsert: (t) => V(async () => {
400
- let n = await Le(e, t.providerSubscriptionId), r = /* @__PURE__ */ new Date();
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 (U(n.statusEventAt == null ? null : new Date(n.statusEventAt), t.statusEventAt)) return;
403
- await e.update(F, String(n.id), {
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(F, {
416
- id: B("bsub"),
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) => V(async () => {
433
- let n = await e.query(H({
434
- table: F,
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] ? Ie(n[0]) : null;
443
+ return n[0] ? He(n[0]) : null;
443
444
  }, "subscriptionStore"),
444
- listByStatus: (t) => V(async () => (await e.query(H({
445
- table: F,
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(Ie), "subscriptionStore"),
452
- markCanceled: (t) => V(async () => {
453
- let n = await Le(e, t);
454
- n && await e.update(F, String(n.id), {
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) => V(async () => {
460
- let r = (await e.query(H({
461
- table: F,
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(F, String(r.id), {
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) => V(async () => {
481
- let r = await Le(e, t);
482
- r && await e.update(F, String(r.id), {
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
- }), ze = () => {
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 && U(n.statusEventAt, t.statusEventAt) || e.set(t.providerInvoiceId, t);
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
- }, Be = (e) => ({
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
- }), Ve = (e) => ({
505
- upsert: (t) => V(async () => {
506
- let n = (await e.query(H({
507
- table: I,
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 (U(n.statusEventAt == null ? null : new Date(n.statusEventAt), t.statusEventAt)) return;
513
- await e.update(I, String(n.id), {
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(I, {
520
- id: B("binv"),
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) => V(async () => (await e.query(H({
526
- table: I,
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(Be), "invoiceStore")
533
- }), W = (e, t, n) => `${e}\u0000${t}\u0000${n}`, He = () => {
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(W(t, n, r))?.used ?? 0),
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 = W(t, n, r), s = e.get(o), c = s?.used ?? 0, l = c + i <= a;
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 = W(t, n, r), o = e.get(a), s = (o?.used ?? 0) + i;
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 = W(t, n, r), o = e.get(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
- }, Ue = (e) => ({
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
- }), G = async (e, t, n, r) => (await e.query(H({
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, We = (e) => ({
583
- used: (t, n, r) => V(async () => {
584
- let i = await G(e, t, n, r);
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) => V(async () => {
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 G(e, t, n, r), c = s ? Number(s.used ?? 0) : 0;
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 = B("buse"), s = await e.insertIgnore(L, {
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) => V(async () => {
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 G(e, t, n, r);
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 = B("buse"), o = await e.insertIgnore(L, {
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: () => V(async () => (await e.query(H({ table: L }))).map(Ue).filter((e) => e.used > e.reportedToProvider), "usageStore"),
664
- markReported: (t, n, r, i) => V(async () => {
665
- let a = await G(e, t, n, r);
666
- a && await e.update(L, String(a.id), {
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
- }), Ge = () => ({
672
- customers: Me(),
673
- subscriptions: Fe(),
674
- invoices: ze(),
675
- usage: He(),
676
- dunningNotices: ke()
677
- }), Ke = (e) => ({
678
- customers: Pe(e),
679
- subscriptions: Re(e),
680
- invoices: Ve(e),
681
- usage: We(e),
682
- dunningNotices: je(e)
683
- }), K = D({ scope: "@voltro/plugin-billing" }), q = (e = /* @__PURE__ */ new Date()) => `${e.getUTCFullYear()}-${String(e.getUTCMonth() + 1).padStart(2, "0")}`, qe = (e) => ({ stores: e ?? Ge() }), J = (e, t) => e.pipe(p.retry({
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
- })), Je = (t) => {
687
- let { provider: n, plans: i } = t, a = t.attempts ?? 3, o = t.checkout, s = t.now ?? (() => /* @__PURE__ */ new Date()), c = qe(t.stores), l = t.dunning ?? be(void 0, {}), u = (e) => c.stores.subscriptions.getByTenant(e).pipe(p.map((t) => z(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* () {
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 j(t, yield* ee(e, t), yield* c.stores.usage.used(e, t, q(s())), n);
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 = q(s()), o = yield* c.stores.usage.consume(e, t, a, n, i);
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, q(s()), n).pipe(p.asVoid), ne = () => p.gen(function* () {
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* J(n.reportUsage({
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
- }), g = (t) => p.gen(function* () {
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* J(n.createCheckoutSession({
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
- }), re = (t, r) => p.gen(function* () {
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* J(n.createPortalSession({
742
+ })) : yield* q(n.createPortalSession({
742
743
  tenantId: t,
743
744
  providerCustomerId: i.providerCustomerId,
744
745
  returnUrl: r
745
746
  }), a);
746
- }), ie = (e) => p.gen(function* () {
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
- }), ae = (e) => {
755
+ }), oe = (e) => {
755
756
  let t = l.portalReturnUrl;
756
- return t === void 0 ? p.succeed(null) : re(e, t).pipe(p.map((e) => e.url), p.catchAll(() => p.succeed(null)));
757
- }, _ = (e, t, n, r, i) => p.gen(function* () {
758
- let a = yield* ie(e.tenantId).pipe(p.catchAll(() => p.succeed(null))), o = yield* ae(e.tenantId), s = t.lockedSince !== null, c = Ee({
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
- K.info("billing dunning notice", {
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
- K.warn("billing dunning notify failed", {
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
- }), v = (e) => p.gen(function* () {
792
+ }), _ = (e) => p.gen(function* () {
792
793
  let t = yield* c.stores.subscriptions.getByTenant(e);
793
- if (t === null) return z(null, l, s(), e);
794
- let r = yield* n.fetchSubscription(t.providerSubscriptionId).pipe(p.catchAll((t) => p.sync(() => (K.warn("billing dunning reconcile: provider unreachable, not escalating", {
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 = z(i, l, s(), e);
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 = Se(o), d = a.graceEndsAt ?? o, f = we(l.steps, o, s()).map((e) => e.id);
823
- a.lockedSince !== null && f.push(he);
824
- for (let t of f) (yield* c.stores.dunningNotices.claim(e, u, t, s())) && (yield* _(i, a, t, o, d));
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
- }), y = () => p.gen(function* () {
827
+ }), se = () => p.gen(function* () {
827
828
  let e = yield* c.stores.subscriptions.listByStatus("pastDue"), t = 0;
828
- for (let n of e) yield* v(n.tenantId).pipe(p.catchAll((e) => p.sync(() => {
829
- K.warn("billing dunning sweep: tenant failed", {
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
- }), b = (e) => {
836
+ }), ce = (e) => {
836
837
  if (!l.enabled) return p.void;
837
- if (e._tag === "invoicePaymentFailed") return v(e.tenantId).pipe(p.asVoid);
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) ? v(t).pipe(p.asVoid) : p.void));
841
- }, x = (e) => {
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
- }, S = (e) => x(e).pipe(p.zipRight(b(e))), C = (t, r) => p.gen(function* () {
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* J(n.updateSubscription({
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: v,
924
- dunningSweep: y,
924
+ reconcileDunning: _,
925
+ dunningSweep: se,
925
926
  checkEntitlement: te,
926
927
  consumeEntitlement: m,
927
928
  reportUsage: h,
928
929
  flushUsage: ne,
929
- startCheckout: g,
930
- portalUrl: re,
931
- applyEvent: S,
932
- changePlan: (e, t) => C(e, { plan: t }),
933
- changeSeats: (e, t) => C(e, { quantity: 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* J(n.previewSubscriptionChange({
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* J(n.listInvoices({ providerCustomerId: t.providerCustomerId }), a);
958
+ return t === null ? [] : yield* q(n.listInvoices({ providerCustomerId: t.providerCustomerId }), a);
958
959
  })
959
960
  },
960
961
  holder: c
961
962
  };
962
- }, Ye = (e) => m.succeed(t, e), Xe = "_voltro_ai_usage", Ze = (e) => {
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
- }, Qe = /* @__PURE__ */ new WeakMap(), $e = (e) => {
972
+ }, it = /* @__PURE__ */ new WeakMap(), at = (e) => {
972
973
  if (!e.global && !e.sticky) return e;
973
- let t = Qe.get(e);
974
- return t === void 0 && (t = new RegExp(e.source, e.flags.replace(/[gy]/g, "")), Qe.set(e, t)), t;
975
- }, et = (e, t) => typeof e == "string" ? t === e : $e(e).test(t), tt = (e, t, n) => Object.entries(e).filter(([, e]) => e.from === "rpc" && (e.kind === void 0 || e.kind === n) && et(e.match, t)).map(([e]) => e), nt = (e, t, n) => Object.entries(e).filter(([, e]) => e.from === "cdc" && e.table === t && (e.op ?? "insert") === n).map(([e]) => e), rt = (e) => Object.entries(e).filter(([, e]) => e.from === "ai").map(([e, t]) => [e, t.metric ?? "tokens"]), it = (e) => e.tenantId, at = (e, t, n, r) => p.forEach(n, (n) => e.reportUsage(t, n, r).pipe(p.catchAll(() => p.void)), { discard: !0 }), ot = (e, t) => (n, r) => {
976
- let i = tt(t, r.tag, r.kind);
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 = it(r.subject);
979
- return a === null ? n : n.pipe(p.tap(() => at(e, a, i, 1)));
980
- }, st = (e, t) => (n) => {
981
- let r = nt(t, n.table, n.op);
982
- if (r.length === 0) return p.void;
983
- let i = n.new?.tenantId ?? n.old?.tenantId ?? null;
984
- return i === null ? p.void : at(e, i, r, 1);
985
- }, ct = (e) => new Date(Date.UTC(e.getUTCFullYear(), e.getUTCMonth(), 1, 0, 0, 0, 0)), lt = (e, t, n, r = () => /* @__PURE__ */ new Date()) => p.gen(function* () {
986
- let i = rt(n);
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
- q(a);
1006
+ K(a);
990
1007
  let o = {
991
- table: Xe,
992
- predicate: y("calledAt", ct(a)),
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
- }), ut = (e, t, n, r) => lt(e, t, n, r).pipe(p.andThen(e.flushUsage().pipe(p.catchAll(() => p.void)))), dt = (e) => Object.values(e).some((e) => e.from === "cdc"), ft = (e) => e === void 0 ? 0 : e === "unlimited" ? Infinity : e, pt = (e) => {
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 : ft(r.entitlements[n]);
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
- }, mt = () => pt({ [n]: { entitlements: {} } }), Y = "_voltro_billing_flush_claims", ht = w(Y, {
1032
- id: b({ scheme: "numeric" }),
1033
- windowKey: T(),
1034
- claimedBy: T(),
1035
- claimedAt: E().default("now")
1036
- }).unique("billingFlushClaimWindow", ["windowKey"]), gt = (e, t) => `billing-flush:${Math.floor(e / Math.max(1, t))}`, _t = async (e, t, n, r) => {
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(Y, {
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
- }, vt = 3, yt = 2e4, bt = (e) => e.client ?? new O(e.apiKey, {
1047
- maxNetworkRetries: vt,
1048
- timeout: yt,
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
- }), xt = (e) => e instanceof O.errors.StripeConnectionError || e instanceof O.errors.StripeAPIError || e instanceof O.errors.StripeRateLimitError, St = (e) => e instanceof O.errors.StripeError ? e.code ?? e.type : void 0, X = (t, n) => p.tryPromise({
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: Ct(n),
1058
- transient: xt(n)
1074
+ message: jt(n),
1075
+ transient: kt(n)
1059
1076
  })
1060
- }), Ct = (e) => {
1061
- if (e instanceof O.errors.StripeError) {
1062
- let t = St(e);
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
- }, wt = (e) => {
1083
+ }, Mt = (e) => {
1067
1084
  let t = e.items?.data?.[0];
1068
1085
  return {
1069
- start: Z(t?.current_period_start),
1070
- end: Z(t?.current_period_end)
1086
+ start: X(t?.current_period_start),
1087
+ end: X(t?.current_period_end)
1071
1088
  };
1072
- }, Z = (e) => typeof e == "number" && Number.isFinite(e) ? /* @__PURE__ */ new Date(e * 1e3) : null, Tt = (e) => {
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
- }, Et = {
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
- }, Q = (e) => {
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
- }, Dt = (e) => {
1108
+ }, Ft = (e) => {
1092
1109
  let t = e.items?.data?.[0]?.price;
1093
1110
  return typeof t?.id == "string" ? t.id : null;
1094
- }, Ot = (e, t) => {
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 = Dt(e);
1114
+ let r = Ft(e);
1098
1115
  return r !== null && t ? t(r) : null;
1099
- }, kt = (e, t) => {
1100
- let n = Z(e.created);
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 = Q(r), a = Ot(r, t), o = Et[r.status];
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 = wt(r);
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: Tt(r),
1132
+ quantity: Nt(r),
1116
1133
  currentPeriodStart: s.start,
1117
1134
  currentPeriodEnd: s.end,
1118
- cancelAt: Z(r.cancel_at),
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 = Q(t);
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 = Q(t);
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 = Q(t);
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
- }, At = {
1171
+ }, Lt = {
1155
1172
  prorate: "create_prorations",
1156
1173
  none: "none",
1157
1174
  always_invoice: "always_invoice"
1158
- }, jt = (t) => {
1159
- let n = bt(t), r = t.planForPriceId, i = (e) => n.subscriptions.retrieve(e, { expand: ["items.data.price"] }), a = (e, t) => {
1160
- let n = wt(e), i = e.items?.data?.[0]?.price;
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: Ot(e, r) ?? "free",
1163
- quantity: Tt(e),
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: At[t.proration ?? "prorate"],
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) => X("stripe.checkout.sessions.create", async () => {
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) => X("stripe.billingPortal.sessions.create", async () => ({ url: (await n.billingPortal.sessions.create({
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) => X("stripe.billing.meterEvents.create", async () => {
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) => X("stripe.subscriptions.update", async () => {
1234
- let t = await i(e.providerSubscriptionId), r = await n.subscriptions.update(e.providerSubscriptionId, o(t, e)), s = await Nt(n, r);
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) => X("stripe.invoices.createPreview", async () => {
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) => X("stripe.subscriptions.retrieve", async () => {
1268
+ fetchSubscription: (e) => Y("stripe.subscriptions.retrieve", async () => {
1252
1269
  try {
1253
- let t = await i(e), n = wt(t);
1270
+ let t = await i(e), n = Mt(t);
1254
1271
  return {
1255
- status: Et[t.status] ?? "incomplete",
1256
- plan: Ot(t, r),
1257
- quantity: Tt(t),
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: Z(t.cancel_at)
1277
+ cancelAt: X(t.cancel_at)
1261
1278
  };
1262
1279
  } catch (e) {
1263
- if (e instanceof O.errors.StripeInvalidRequestError && e.statusCode === 404) return null;
1280
+ if (e instanceof D.errors.StripeInvalidRequestError && e.statusCode === 404) return null;
1264
1281
  throw e;
1265
1282
  }
1266
1283
  }),
1267
- customerEmail: (e) => X("stripe.customers.retrieve", async () => {
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) => X("stripe.invoices.list", async () => (await n.invoices.list({
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: Z(e.created),
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(Mt(e) ? kt(e, r) : null)
1308
+ normalizeEvent: (e) => p.succeed(zt(e) ? It(e, r) : null)
1292
1309
  };
1293
- }, Mt = (e) => typeof e == "object" && !!e && typeof e.type == "string" && typeof e.data == "object", Nt = async (e, t) => {
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
- }, Pt = (e) => {
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
- }, Ft = (e) => {
1356
+ }, Ht = (e) => {
1340
1357
  let { provider: t, env: n } = e;
1341
1358
  if (t !== void 0 && typeof t == "object") return t;
1342
- if ((t ?? (n.STRIPE_SECRET_KEY ? "stripe" : "mock")) === "stripe") {
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 jt({
1363
+ return Rt({
1346
1364
  apiKey: t,
1347
1365
  ...e.planForPriceId ? { planForPriceId: e.planForPriceId } : {}
1348
1366
  });
1349
1367
  }
1350
- return Pt();
1351
- }, It = D({ scope: "@voltro/plugin-billing" }), Lt = "billing", $ = "/billing/webhook", Rt = (e) => oe({
1352
- id: Lt,
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: A(),
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
- It.warn("billing onEvent side effect failed", {
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
- }), zt = (e) => k(Rt(e), {
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 && It.warn("billing webhook rejected", { ...e });
1394
+ e.status >= 400 && Ut.warn("billing webhook rejected", { ...e });
1377
1395
  }
1378
- }), Bt = (e) => e === null ? null : {
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
- }, Vt = g([{
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
- }]), Ht = "@voltro/plugin-billing", Ut = (t = {}) => {
1395
- let n = process.env, m = pt(t.plans ?? {}), h = Ft({
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 ?? Vt.read("STRIPE_WEBHOOK_SECRET") ?? null, g = be(t.dunning, n);
1401
- S({
1421
+ }), ne = t.webhookSecret ?? Jt.read("STRIPE_WEBHOOK_SECRET") ?? null, re = L(t.dunning, n);
1422
+ x({
1402
1423
  source: "plugin",
1403
- table: L,
1424
+ table: P,
1404
1425
  timeColumn: "updatedAt",
1405
- ttlMs: C(process.env.VOLTRO_BILLING_USAGE_TTL_HOURS, 9600),
1426
+ ttlMs: S(process.env.VOLTRO_BILLING_USAGE_TTL_HOURS, 9600),
1406
1427
  label: "billing usage counters"
1407
- }), S({
1428
+ }), x({
1408
1429
  source: "plugin",
1409
- table: Y,
1430
+ table: J,
1410
1431
  timeColumn: "claimedAt",
1411
- ttlMs: C(process.env.VOLTRO_BILLING_FLUSH_CLAIM_TTL_HOURS, 1),
1432
+ ttlMs: S(process.env.VOLTRO_BILLING_FLUSH_CLAIM_TTL_HOURS, 1),
1412
1433
  label: "billing flush claims"
1413
- }), S({
1434
+ }), x({
1414
1435
  source: "plugin",
1415
- table: R,
1436
+ table: F,
1416
1437
  timeColumn: "sentAt",
1417
- ttlMs: C(process.env.VOLTRO_BILLING_DUNNING_TTL_HOURS, 9600),
1438
+ ttlMs: S(process.env.VOLTRO_BILLING_DUNNING_TTL_HOURS, 9600),
1418
1439
  label: "billing dunning notices"
1419
1440
  });
1420
- let { service: _, holder: v } = Je({
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: g
1427
- }), y = Ye(_), b = zt({
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
- }), x = {
1453
+ }), v = {
1433
1454
  method: "POST",
1434
1455
  path: $,
1435
1456
  originGuard: "exempt",
1436
1457
  handle: async (e) => {
1437
- let t = await b({
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
- }, w = [
1471
+ }, le = [
1451
1472
  {
1452
1473
  ...ee,
1453
1474
  execute: (e, t) => {
1454
1475
  let n = e;
1455
- return _.startCheckout({
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 _.portalUrl(t.request.subject.tenantId ?? "", n.returnUrl);
1489
+ return g.portalUrl(t.request.subject.tenantId ?? "", n.returnUrl);
1469
1490
  }
1470
1491
  },
1471
1492
  {
1472
1493
  ...te,
1473
- execute: (e, t) => _.subscription(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({ subscription: Bt(e) })))
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) => _.entitlementStatus(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({
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 _.previewChange(t.request.subject.tenantId ?? "", {
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) => _.invoices(t.request.subject.tenantId ?? "").pipe(p.map((e) => ({ invoices: e.map((e) => ({
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 _.reportUsage(t.request.subject.tenantId ?? "", n.key, n.quantity).pipe(p.map(() => ({ ok: !0 })));
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 _.changePlan(t.request.subject.tenantId ?? "", n.plan).pipe(p.map((e) => ({
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 _.changeSeats(t.request.subject.tenantId ?? "", n.quantity).pipe(p.map((e) => ({
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
- ], T = (e, t) => ({
1562
+ ], y = (e, t) => ({
1542
1563
  kind: "json",
1543
1564
  status: e,
1544
1565
  data: { error: t }
1545
- }), E = [{
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: () => v.stores.usage.pending().pipe(p.map((e) => ({
1584
+ handler: () => _.stores.usage.pending().pipe(p.map((e) => ({
1564
1585
  kind: "json",
1565
1586
  data: { usage: e }
1566
- })), p.catchAll((e) => p.succeed(T(500, e.message))))
1567
- }], D = [
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
- ], O = t.enforce, oe = O !== void 0 && Object.keys(O).length > 0 ? ce(O, _) : void 0, k = t.metering;
1590
- k !== void 0 && Ze(k);
1591
- let A = k !== void 0 && Object.keys(k).length > 0 ? ot(_, k) : void 0, j = k !== void 0 && dt(k), M = re([A, oe].filter((e) => e !== void 0)), se, N, P = [
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
- ...M === void 0 ? [] : ["rpc:intercept:mutation", "rpc:intercept:action"],
1597
- ...A === void 0 ? [] : ["rpc:intercept:query"],
1598
- ...j ? ["store:changes:read"] : []
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 ie({
1601
- name: ae({
1602
- base: Ht,
1626
+ return ae({
1627
+ name: oe({
1628
+ base: Yt,
1603
1629
  alias: t.alias,
1604
1630
  instance: t.name
1605
1631
  }),
1606
- baseName: Ht,
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: P,
1609
- declaredEnv: Vt.declared,
1610
- services: y,
1611
- routes: w,
1634
+ permissions: me,
1635
+ declaredEnv: Jt.declared,
1636
+ services: se,
1637
+ routes: le,
1612
1638
  rpcClientDescriptors: a,
1613
- httpRoutes: [x],
1614
- inspectEndpoints: E,
1639
+ httpRoutes: [v],
1640
+ inspectEndpoints: b,
1615
1641
  extendSchema: { tables: [
1616
- ...pe(),
1617
- ht,
1618
- me
1642
+ ...xe(),
1643
+ Ct,
1644
+ Se
1619
1645
  ] },
1620
- errorSchemas: D,
1621
- ...M === void 0 ? {} : {
1622
- interceptMutation: M,
1623
- interceptAction: M
1646
+ errorSchemas: ue,
1647
+ ...O === void 0 ? {} : {
1648
+ interceptMutation: O,
1649
+ interceptAction: O
1624
1650
  },
1625
- ...A === void 0 ? {} : { interceptQuery: A },
1626
- ...j ? { onChangeEvent: st(_, k) } : {},
1627
- bindDataStore: (e) => {
1628
- v.stores = Ke(e), se = e;
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: O ? Object.keys(O).length : 0,
1635
- metering: k ? Object.keys(k).length : 0,
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 = k, i = r !== void 0 && Object.keys(r).length > 0;
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 = process.env.HOSTNAME ?? `pid-${process.pid}`;
1641
- N = setInterval(() => {
1642
- let t = se;
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 _t(t, gt(a, n), e, a) && i && await p.runPromise(ut(_, t, r).pipe(p.catchAll(() => p.void)));
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), N.unref?.();
1674
+ }, n), A.unref?.();
1649
1675
  }
1650
1676
  }),
1651
1677
  onDeactivate: () => p.sync(() => {
1652
- N !== void 0 && (clearInterval(N), N = void 0);
1678
+ A !== void 0 && (clearInterval(A), A = void 0);
1653
1679
  })
1654
1680
  });
1655
1681
  };
1656
1682
  //#endregion
1657
- export { P as BILLING_CUSTOMERS_TABLE, R as BILLING_DUNNING_NOTICES_TABLE, Y as BILLING_FLUSH_CLAIMS_TABLE, I as BILLING_INVOICES_TABLE, F as BILLING_SUBSCRIPTIONS_TABLE, L as BILLING_USAGE_TABLE, Lt as BILLING_WEBHOOK_ID, $ as BILLING_WEBHOOK_PATH, e as BillingError, t as BillingService, ge as DEFAULT_DUNNING_STEPS, _e as DEFAULT_GRACE_HOURS, ve as DEFAULT_LOCKOUT, n as DEFAULT_PLAN, he as DUNNING_LOCK_STEP_ID, r as EntitlementExceeded, i as SubscriptionLocked, le as billingCustomersTable, me as billingDunningNoticesTable, ht as billingFlushClaimsTable, de as billingInvoicesTable, Ut as billingPlugin, Ye as billingServiceLayer, ue as billingSubscriptionsTable, pe as billingTables, fe as billingUsageTable, Rt as billingWebhookDescriptor, Je as buildBillingService, ce as buildEnforceInterceptor, pt as buildPlanRegistry, _t as claimFlushWindow, je as dataStoreDunningNoticeStore, Ke as dataStoreStores, Ee as defaultDunningEmail, we as dueSteps, De as dunningMailNotifier, mt as emptyPlanRegistry, Se as episodeKeyOf, z as evaluateBillingEntitlement, j as evaluateEntitlement, gt as flushWindowKey, Ce as graceEndOf, U as isStaleStatusEvent, ke as memoryDunningNoticeStore, Ge as memoryStores, Pt as mockProvider, zt as mountBillingWebhook, kt as normalizeStripeEvent, q as periodKey, N as requireEntitled, se as requireEntitlement, be as resolveDunningConfig, Ft as resolveProvider, jt as stripeProvider };
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 };