@billfn/admin 0.1.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/domain-service.d.ts +11 -0
- package/dist/domain-service.d.ts.map +1 -0
- package/dist/domain-service.js +229 -0
- package/dist/domain-service.js.map +1 -0
- package/dist/index.d.ts +897 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +586 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BillableSubject, BillFnInstance } from "@billfn/core";
|
|
2
|
+
import { type AdminOperationContext } from "@superfunctions/admin";
|
|
3
|
+
import type { BillFnAdminService } from "./index.js";
|
|
4
|
+
export interface BillFnDomainAdminServiceOptions {
|
|
5
|
+
billfn: BillFnInstance;
|
|
6
|
+
/** Resolves the billable subject only after Super Console scope authorization. */
|
|
7
|
+
subject(context: AdminOperationContext): BillableSubject | Promise<BillableSubject>;
|
|
8
|
+
}
|
|
9
|
+
/** Delegates billing changes to BillFn so provider, catalog, entitlement and reconciliation invariants remain active. */
|
|
10
|
+
export declare function createBillFnDomainAdminService(options: BillFnDomainAdminServiceOptions): BillFnAdminService;
|
|
11
|
+
//# sourceMappingURL=domain-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-service.d.ts","sourceRoot":"","sources":["../src/domain-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAGf,MAAM,cAAc,CAAC;AACtB,OAAO,EAKL,KAAK,qBAAqB,EAE3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAwB,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAU3E,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,kFAAkF;IAClF,OAAO,CAAC,OAAO,EAAE,qBAAqB,GAAG,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACrF;AA4HD,yHAAyH;AACzH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,GACvC,kBAAkB,CAoHpB"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { AdminError, decodeAdminCursor, encodeAdminCursor, normalizeAdminPageLimit, } from "@superfunctions/admin";
|
|
2
|
+
function pageIdentity(operationId, input) {
|
|
3
|
+
const filter = Object.entries(input.filter ?? {}).sort(([left], [right]) => left.localeCompare(right));
|
|
4
|
+
const sort = (input.sort ?? []).map((descriptor) => [descriptor.field ?? null, descriptor.direction ?? null]);
|
|
5
|
+
return JSON.stringify([operationId, input.search?.trim().toLowerCase() ?? null, filter, sort]);
|
|
6
|
+
}
|
|
7
|
+
function string(value, name) {
|
|
8
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
9
|
+
throw new AdminError("invalid_argument", `${name} must be a non-empty string.`);
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
function optionalString(value, name) {
|
|
14
|
+
return value === undefined ? undefined : string(value, name);
|
|
15
|
+
}
|
|
16
|
+
function unwrap(value) {
|
|
17
|
+
if (value.ok)
|
|
18
|
+
return value.data;
|
|
19
|
+
const code = value.error.status === 404
|
|
20
|
+
? "not_found"
|
|
21
|
+
: value.error.status === 403
|
|
22
|
+
? "forbidden"
|
|
23
|
+
: value.error.status === 409
|
|
24
|
+
? "conflict"
|
|
25
|
+
: value.error.status >= 500
|
|
26
|
+
? "dependency_unavailable"
|
|
27
|
+
: "invalid_argument";
|
|
28
|
+
throw new AdminError(code, value.error.message, {
|
|
29
|
+
details: value.error.details,
|
|
30
|
+
retryable: value.error.retryable,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function asJson(value) {
|
|
34
|
+
return { ...value };
|
|
35
|
+
}
|
|
36
|
+
function compareAdminValues(left, right) {
|
|
37
|
+
if (typeof left === "number" && typeof right === "number") {
|
|
38
|
+
return left - right;
|
|
39
|
+
}
|
|
40
|
+
return String(left ?? "").localeCompare(String(right ?? ""));
|
|
41
|
+
}
|
|
42
|
+
function list(values, input, context, operationId) {
|
|
43
|
+
let records = values.map(asJson);
|
|
44
|
+
if (input.search?.trim()) {
|
|
45
|
+
const query = input.search.trim().toLowerCase();
|
|
46
|
+
records = records.filter((value) => JSON.stringify(value).toLowerCase().includes(query));
|
|
47
|
+
}
|
|
48
|
+
if (input.filter) {
|
|
49
|
+
records = records.filter((value) => Object.entries(input.filter).every(([key, expected]) => Object.is(value[key], expected)));
|
|
50
|
+
}
|
|
51
|
+
const sorts = input.sort ?? [];
|
|
52
|
+
records.sort((left, right) => {
|
|
53
|
+
for (const descriptor of sorts) {
|
|
54
|
+
if (!descriptor.field)
|
|
55
|
+
continue;
|
|
56
|
+
const compared = compareAdminValues(left[descriptor.field], right[descriptor.field]);
|
|
57
|
+
if (compared !== 0)
|
|
58
|
+
return compared * (descriptor.direction === "desc" ? -1 : 1);
|
|
59
|
+
}
|
|
60
|
+
return String(left.id ?? "").localeCompare(String(right.id ?? ""));
|
|
61
|
+
});
|
|
62
|
+
const identity = pageIdentity(operationId, input);
|
|
63
|
+
const decoded = input.cursor
|
|
64
|
+
? decodeAdminCursor(input.cursor, context.scope)
|
|
65
|
+
: { identity, offset: 0 };
|
|
66
|
+
if (!decoded || typeof decoded !== "object" || Array.isArray(decoded)) {
|
|
67
|
+
throw new AdminError("invalid_argument", "The BillFn cursor is invalid.");
|
|
68
|
+
}
|
|
69
|
+
if (decoded.identity !== identity) {
|
|
70
|
+
throw new AdminError("invalid_argument", "The BillFn cursor does not belong to this collection query.");
|
|
71
|
+
}
|
|
72
|
+
const offset = decoded.offset ?? 0;
|
|
73
|
+
if (!Number.isSafeInteger(offset) || offset < 0)
|
|
74
|
+
throw new AdminError("invalid_argument", "The BillFn cursor is invalid.");
|
|
75
|
+
const limit = normalizeAdminPageLimit(input.limit, { defaultLimit: 50, maxLimit: 200 });
|
|
76
|
+
const items = records.slice(offset, offset + limit);
|
|
77
|
+
const nextOffset = offset + items.length;
|
|
78
|
+
return { ok: true, data: { items, nextCursor: nextOffset < records.length ? encodeAdminCursor(context.scope, { identity, offset: nextOffset }) : null } };
|
|
79
|
+
}
|
|
80
|
+
function item(value) {
|
|
81
|
+
return { ok: true, data: { item: asJson(value) } };
|
|
82
|
+
}
|
|
83
|
+
function accepted(value) {
|
|
84
|
+
return { ok: true, data: { accepted: true, item: asJson(value) } };
|
|
85
|
+
}
|
|
86
|
+
function notFound(label) {
|
|
87
|
+
throw new AdminError("not_found", `${label} was not found for the active BillFn subject.`);
|
|
88
|
+
}
|
|
89
|
+
const BILLING_PROVIDERS = new Set([
|
|
90
|
+
"dodo",
|
|
91
|
+
"apple",
|
|
92
|
+
"stripe",
|
|
93
|
+
"polar",
|
|
94
|
+
"google-play",
|
|
95
|
+
"microsoft-store",
|
|
96
|
+
]);
|
|
97
|
+
function billingProvider(value) {
|
|
98
|
+
if (value === undefined)
|
|
99
|
+
return undefined;
|
|
100
|
+
if (!BILLING_PROVIDERS.has(value)) {
|
|
101
|
+
throw new AdminError("invalid_argument", "provider must be a configured BillFn provider name.");
|
|
102
|
+
}
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
function products(plans) {
|
|
106
|
+
const grouped = new Map();
|
|
107
|
+
for (const plan of plans) {
|
|
108
|
+
const existing = grouped.get(plan.productKey);
|
|
109
|
+
grouped.set(plan.productKey, {
|
|
110
|
+
id: plan.productKey,
|
|
111
|
+
productKey: plan.productKey,
|
|
112
|
+
planCount: (existing?.planCount ?? 0) + 1,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return [...grouped.values()];
|
|
116
|
+
}
|
|
117
|
+
/** Delegates billing changes to BillFn so provider, catalog, entitlement and reconciliation invariants remain active. */
|
|
118
|
+
export function createBillFnDomainAdminService(options) {
|
|
119
|
+
return {
|
|
120
|
+
async listProducts(input, context) {
|
|
121
|
+
const catalog = await options.billfn.getCatalog();
|
|
122
|
+
return list(products(catalog.plans), input, context, "billfn.products.list");
|
|
123
|
+
},
|
|
124
|
+
async getProduct(input) {
|
|
125
|
+
const catalog = await options.billfn.getCatalog();
|
|
126
|
+
const value = products(catalog.plans).find((entry) => entry.id === input.id);
|
|
127
|
+
return value ? item(value) : notFound("Product");
|
|
128
|
+
},
|
|
129
|
+
async listPlans(input, context) {
|
|
130
|
+
const catalog = await options.billfn.getCatalog();
|
|
131
|
+
const plans = catalog.plans.map((plan) => ({ ...plan, id: plan.planKey }));
|
|
132
|
+
return list(plans, input, context, "billfn.plans.list");
|
|
133
|
+
},
|
|
134
|
+
async getPlan(input) {
|
|
135
|
+
const catalog = await options.billfn.getCatalog();
|
|
136
|
+
const value = catalog.plans.map((plan) => ({ ...plan, id: plan.planKey })).find((entry) => entry.id === input.id);
|
|
137
|
+
return value ? item(value) : notFound("Plan");
|
|
138
|
+
},
|
|
139
|
+
async listPrices(input, context) {
|
|
140
|
+
const catalog = await options.billfn.getCatalog();
|
|
141
|
+
return list(catalog.plans.flatMap((plan) => plan.prices.map((price) => ({ ...price, id: price.priceId, planKey: plan.planKey, productKey: plan.productKey }))), input, context, "billfn.prices.list");
|
|
142
|
+
},
|
|
143
|
+
async getPrice(input) {
|
|
144
|
+
const catalog = await options.billfn.getCatalog();
|
|
145
|
+
const value = catalog.plans.flatMap((plan) => plan.prices.map((price) => ({ ...price, id: price.priceId, planKey: plan.planKey, productKey: plan.productKey }))).find((entry) => entry.id === input.id);
|
|
146
|
+
return value ? item(value) : notFound("Price");
|
|
147
|
+
},
|
|
148
|
+
async listSubscriptions(input, context) {
|
|
149
|
+
const subject = await options.subject(context);
|
|
150
|
+
const subscription = await options.billfn.subscriptionProvider.getActiveSubscription(subject);
|
|
151
|
+
return list(subscription ? [subscription] : [], input, context, "billfn.subscriptions.list");
|
|
152
|
+
},
|
|
153
|
+
async getSubscription(input, context) {
|
|
154
|
+
const subject = await options.subject(context);
|
|
155
|
+
const subscription = await options.billfn.subscriptionProvider.getActiveSubscription(subject);
|
|
156
|
+
return subscription?.id === input.id ? item(subscription) : notFound("Subscription");
|
|
157
|
+
},
|
|
158
|
+
async listEntitlements(input, context) {
|
|
159
|
+
const data = unwrap(await options.billfn.getEntitlements(await options.subject(context)));
|
|
160
|
+
return list(data.entitlements ? [data.entitlements] : [], input, context, "billfn.entitlements.list");
|
|
161
|
+
},
|
|
162
|
+
async getEntitlement(input, context) {
|
|
163
|
+
const data = unwrap(await options.billfn.getEntitlements(await options.subject(context)));
|
|
164
|
+
return data.entitlements?.id === input.id ? item(data.entitlements) : notFound("Entitlement");
|
|
165
|
+
},
|
|
166
|
+
async listUsage(input, context) {
|
|
167
|
+
const data = unwrap(await options.billfn.getUsage(await options.subject(context), optionalString(input.filter?.resource, "filter.resource")));
|
|
168
|
+
return list(data.usage.map((entry) => ({ ...entry, id: entry.resource })), input, context, "billfn.usage.list");
|
|
169
|
+
},
|
|
170
|
+
async getUsage(input, context) {
|
|
171
|
+
const data = unwrap(await options.billfn.getUsage(await options.subject(context), input.id));
|
|
172
|
+
const value = data.usage.find((entry) => entry.resource === input.id);
|
|
173
|
+
return value ? item({ ...value, id: value.resource }) : notFound("Usage meter");
|
|
174
|
+
},
|
|
175
|
+
async changeSubscription(input, context) {
|
|
176
|
+
return accepted(unwrap(await options.billfn.changeSubscription({
|
|
177
|
+
subject: await options.subject(context),
|
|
178
|
+
subscriptionId: input.id,
|
|
179
|
+
targetPriceId: input.payload.targetPriceId,
|
|
180
|
+
effectiveAt: input.payload.effectiveAt,
|
|
181
|
+
prorationBehavior: input.payload.prorationBehavior,
|
|
182
|
+
reason: input.reason,
|
|
183
|
+
})));
|
|
184
|
+
},
|
|
185
|
+
async cancelSubscription(input, context) {
|
|
186
|
+
return accepted(unwrap(await options.billfn.cancelSubscription({
|
|
187
|
+
subject: await options.subject(context),
|
|
188
|
+
subscriptionId: input.id,
|
|
189
|
+
reason: input.reason,
|
|
190
|
+
})));
|
|
191
|
+
},
|
|
192
|
+
async refundPayment(input, context) {
|
|
193
|
+
return accepted(unwrap(await options.billfn.refundCharge({
|
|
194
|
+
subject: await options.subject(context),
|
|
195
|
+
providerChargeId: input.id,
|
|
196
|
+
subscriptionId: input.payload?.subscriptionId,
|
|
197
|
+
mode: input.payload?.mode,
|
|
198
|
+
amount: input.payload?.amount,
|
|
199
|
+
reason: input.reason,
|
|
200
|
+
})));
|
|
201
|
+
},
|
|
202
|
+
async reconcileProvider(input, context) {
|
|
203
|
+
const subject = await options.subject(context);
|
|
204
|
+
const scoped = unwrap(await options.billfn.getEntitlements(subject));
|
|
205
|
+
if (input.payload.billingAccountId !== undefined && input.payload.billingAccountId !== scoped.billingAccount.id) {
|
|
206
|
+
throw new AdminError("forbidden", "The reconciliation billing account is outside the active BillFn subject.");
|
|
207
|
+
}
|
|
208
|
+
if (input.payload.kind !== "account-scan" && input.payload.kind !== "subscription-sync") {
|
|
209
|
+
throw new AdminError("forbidden", "Provider-wide reconciliation jobs cannot be scheduled from a subject-scoped admin operation.");
|
|
210
|
+
}
|
|
211
|
+
const subscriptionId = input.payload.kind === "subscription-sync"
|
|
212
|
+
? scoped.subscription?.id
|
|
213
|
+
: undefined;
|
|
214
|
+
if (input.payload.kind === "subscription-sync" && !subscriptionId) {
|
|
215
|
+
throw new AdminError("precondition_failed", "The active BillFn subject has no subscription to reconcile.");
|
|
216
|
+
}
|
|
217
|
+
if (input.payload.subscriptionId !== undefined && input.payload.subscriptionId !== subscriptionId) {
|
|
218
|
+
throw new AdminError("forbidden", "The reconciliation subscription is outside the active BillFn subject.");
|
|
219
|
+
}
|
|
220
|
+
return accepted(unwrap(await options.billfn.enqueueReconciliationJob({
|
|
221
|
+
kind: input.payload.kind,
|
|
222
|
+
provider: billingProvider(input.payload.provider),
|
|
223
|
+
billingAccountId: scoped.billingAccount.id,
|
|
224
|
+
subscriptionId,
|
|
225
|
+
})));
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=domain-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-service.js","sourceRoot":"","sources":["../src/domain-service.ts"],"names":[],"mappings":"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"}
|