@farm.js/autumn 0.1.0-beta.10 → 0.1.0-beta.101
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.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +69 -10
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Autumn as AutumnSDK } from "autumn-js";
|
|
2
|
+
import type { Customer } from "autumn-js";
|
|
2
3
|
import { type FarmIntegration, type FarmIntegrationHandlerContext, type FarmIntegrationLogger } from "@farm.js/core";
|
|
3
4
|
import type { FarmWebhookConfig, FarmWebhookEvent } from "@farm.js/integration-utils/webhooks";
|
|
4
|
-
import { type AutumnBillingProductKind, type AutumnClientAPI, type AutumnClientPathOptions, type AutumnDefaultClientAPI } from "./client.js";
|
|
5
|
+
import { type AutumnBillingProductKind, type AutumnBillingStatus, type AutumnClientAPI, type AutumnClientPathOptions, type AutumnDefaultClientAPI } from "./client.js";
|
|
5
6
|
export type { AutumnBillingCheckInput, AutumnBillingCheckResult, AutumnBillingCurrentChargeLine, AutumnBillingCurrentChargesResult, AutumnBillingFeaturesResult, AutumnBillingInvoice, AutumnBillingInvoicesResult, AutumnBillingLimitsResult, AutumnBillingMeterState, AutumnBillingMeterUsageInput, AutumnBillingMeterUsageResult, AutumnBillingReportUsageInput, AutumnBillingReportUsageResult, AutumnBillingStatusResult, AutumnBillingUsageInput, AutumnBillingUsageProperties, AutumnBillingUsageResult, AutumnCatalogMeterPrice, AutumnCatalogProduct, AutumnCheckoutInput, AutumnCheckoutResult, AutumnClientAPI, AutumnDefaultClientAPI, AutumnPortalInput, AutumnPortalResult, } from "./client.js";
|
|
6
7
|
export { autumnClient } from "./client.js";
|
|
7
8
|
type AutumnWebhookPayload = {
|
|
@@ -132,8 +133,9 @@ export interface AutumnBillingOptions {
|
|
|
132
133
|
meters?: Record<string, AutumnBillingMeter>;
|
|
133
134
|
hooks?: AutumnBillingHooks;
|
|
134
135
|
}
|
|
136
|
+
export type AutumnIntegrationInstance = AutumnSDK;
|
|
135
137
|
export interface AutumnIntegrationInput extends AutumnClientPathOptions {
|
|
136
|
-
instance?:
|
|
138
|
+
instance?: AutumnIntegrationInstance;
|
|
137
139
|
secretKey?: string;
|
|
138
140
|
serverURL?: string;
|
|
139
141
|
appBaseUrl?: string;
|
|
@@ -173,6 +175,14 @@ type AutumnDefaultPathInput = {
|
|
|
173
175
|
type AutumnIntegrationResult<TApi> = Omit<FarmIntegration, "api"> & {
|
|
174
176
|
api: TApi;
|
|
175
177
|
};
|
|
178
|
+
export declare function normalizeAutumnStatus(customer: Customer | null, subscription: Customer["subscriptions"][number] | null): AutumnBillingStatus;
|
|
179
|
+
/**
|
|
180
|
+
* Whether the subscription is scheduled to cancel but has not yet ended: a
|
|
181
|
+
* cancellation exists (`canceledAt`) and access continues until a future
|
|
182
|
+
* `expiresAt`. This is the "cancels on <date>" state, distinct from a fully
|
|
183
|
+
* ended subscription.
|
|
184
|
+
*/
|
|
185
|
+
export declare function isAutumnCancelAtPeriodEnd(subscription: Customer["subscriptions"][number] | null | undefined): boolean;
|
|
176
186
|
export declare function autumn<const TInput extends AutumnIntegrationInput & AutumnDefaultPathInput>(input: TInput): AutumnIntegrationResult<AutumnDefaultClientAPI>;
|
|
177
187
|
export declare function autumn<const TInput extends AutumnIntegrationInput>(input: TInput): AutumnIntegrationResult<AutumnClientAPI<AutumnResolvedApiInput<TInput>>>;
|
|
178
188
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,34 @@ import { integrationConfig, normalizeWebhookConfig, resolveAppPath, toAbsoluteUr
|
|
|
5
5
|
import { createAutumnClientApi, } from "./client.js";
|
|
6
6
|
export { autumnClient } from "./client.js";
|
|
7
7
|
const pendingAutumnMeterProjection = new Map();
|
|
8
|
+
// Replay cache for /billing/report-usage idempotency. autumn-js 1.2.7 has no
|
|
9
|
+
// provider-side event dedupe, so a retried report with the same key must be
|
|
10
|
+
// answered from here instead of re-applying the usage. Per-instance, like the
|
|
11
|
+
// projection map above; multi-instance deployments still need provider-side
|
|
12
|
+
// dedupe once the SDK supports it.
|
|
13
|
+
const REPORTED_USAGE_EVENT_TTL_MS = 24 * 60 * 60 * 1000;
|
|
14
|
+
const REPORTED_USAGE_EVENT_LIMIT = 10_000;
|
|
15
|
+
const reportedUsageEvents = new Map();
|
|
16
|
+
function getReportedUsageEvent(key) {
|
|
17
|
+
const entry = reportedUsageEvents.get(key);
|
|
18
|
+
if (!entry) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
if (Date.now() - entry.at > REPORTED_USAGE_EVENT_TTL_MS) {
|
|
22
|
+
reportedUsageEvents.delete(key);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
return entry.result;
|
|
26
|
+
}
|
|
27
|
+
function setReportedUsageEvent(key, result) {
|
|
28
|
+
reportedUsageEvents.set(key, { at: Date.now(), result });
|
|
29
|
+
if (reportedUsageEvents.size > REPORTED_USAGE_EVENT_LIMIT) {
|
|
30
|
+
const oldest = reportedUsageEvents.keys().next().value;
|
|
31
|
+
if (oldest !== undefined) {
|
|
32
|
+
reportedUsageEvents.delete(oldest);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
8
36
|
function createAutumnApi(input) {
|
|
9
37
|
return createAutumnClientApi(input);
|
|
10
38
|
}
|
|
@@ -342,14 +370,19 @@ function getProjectedUsage(input) {
|
|
|
342
370
|
function setProjectedUsage(input) {
|
|
343
371
|
pendingAutumnMeterProjection.set(projectionKey(input), input.projectedUsage);
|
|
344
372
|
}
|
|
345
|
-
function normalizeAutumnStatus(customer, subscription) {
|
|
373
|
+
export function normalizeAutumnStatus(customer, subscription) {
|
|
346
374
|
if (!customer || !subscription) {
|
|
347
375
|
return "free";
|
|
348
376
|
}
|
|
349
377
|
if (subscription.pastDue) {
|
|
350
378
|
return "past_due";
|
|
351
379
|
}
|
|
352
|
-
|
|
380
|
+
// A subscription scheduled to cancel at period end has `canceledAt` set but
|
|
381
|
+
// remains usable until `expiresAt`. Only report the terminal "canceled"
|
|
382
|
+
// status once access has actually ended; until then it stays active/trialing
|
|
383
|
+
// and the cancellation is surfaced via `cancelAtPeriodEnd`.
|
|
384
|
+
if (subscription.canceledAt != null &&
|
|
385
|
+
(subscription.expiresAt == null || subscription.expiresAt <= Date.now())) {
|
|
353
386
|
return "canceled";
|
|
354
387
|
}
|
|
355
388
|
if (subscription.trialEndsAt != null && subscription.trialEndsAt > Date.now()) {
|
|
@@ -360,6 +393,17 @@ function normalizeAutumnStatus(customer, subscription) {
|
|
|
360
393
|
}
|
|
361
394
|
return "active";
|
|
362
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* Whether the subscription is scheduled to cancel but has not yet ended: a
|
|
398
|
+
* cancellation exists (`canceledAt`) and access continues until a future
|
|
399
|
+
* `expiresAt`. This is the "cancels on <date>" state, distinct from a fully
|
|
400
|
+
* ended subscription.
|
|
401
|
+
*/
|
|
402
|
+
export function isAutumnCancelAtPeriodEnd(subscription) {
|
|
403
|
+
return (subscription?.canceledAt != null &&
|
|
404
|
+
subscription.expiresAt != null &&
|
|
405
|
+
subscription.expiresAt > Date.now());
|
|
406
|
+
}
|
|
363
407
|
function resolveActiveProduct(customer, products) {
|
|
364
408
|
const byPlanId = new Map(products.map((product) => [product.autumnPlanId, product]));
|
|
365
409
|
const matchedSubscription = [...(customer?.subscriptions ?? [])]
|
|
@@ -373,15 +417,18 @@ function resolveActiveProduct(customer, products) {
|
|
|
373
417
|
status: normalizeAutumnStatus(customer, matchedSubscription),
|
|
374
418
|
};
|
|
375
419
|
}
|
|
376
|
-
const
|
|
420
|
+
const matchingPurchases = [...(customer?.purchases ?? [])]
|
|
377
421
|
.filter((entry) => byPlanId.has(entry.planId))
|
|
378
|
-
.sort((left, right) => right.startedAt - left.startedAt)
|
|
422
|
+
.sort((left, right) => right.startedAt - left.startedAt);
|
|
423
|
+
const now = Date.now();
|
|
424
|
+
const activePurchase = matchingPurchases.find((entry) => entry.expiresAt == null || entry.expiresAt > now);
|
|
425
|
+
const matchedPurchase = activePurchase ?? matchingPurchases[0];
|
|
379
426
|
if (matchedPurchase) {
|
|
380
427
|
return {
|
|
381
428
|
product: byPlanId.get(matchedPurchase.planId) ?? null,
|
|
382
429
|
subscription: null,
|
|
383
430
|
purchase: matchedPurchase,
|
|
384
|
-
status: "active",
|
|
431
|
+
status: activePurchase ? "active" : "canceled",
|
|
385
432
|
};
|
|
386
433
|
}
|
|
387
434
|
return {
|
|
@@ -738,9 +785,7 @@ export function autumn(input) {
|
|
|
738
785
|
subscriptionId: active.subscription?.id ?? null,
|
|
739
786
|
currentPeriodStart: currentPeriodStart(active.subscription),
|
|
740
787
|
currentPeriodEnd: currentPeriodEnd(active.subscription),
|
|
741
|
-
cancelAtPeriodEnd: active.subscription
|
|
742
|
-
(active.subscription.canceledAt == null ||
|
|
743
|
-
active.subscription.canceledAt > Date.now()),
|
|
788
|
+
cancelAtPeriodEnd: isAutumnCancelAtPeriodEnd(active.subscription),
|
|
744
789
|
trialEndsAt: trialEndsAt(active.subscription),
|
|
745
790
|
features: plan.features ?? {},
|
|
746
791
|
limits: plan.limits ?? {},
|
|
@@ -1069,6 +1114,11 @@ export function autumn(input) {
|
|
|
1069
1114
|
if (typeof body.quantity !== "number" || !Number.isFinite(body.quantity)) {
|
|
1070
1115
|
return new Response("A numeric quantity is required.", { status: 400 });
|
|
1071
1116
|
}
|
|
1117
|
+
if (!body.idempotencyKey) {
|
|
1118
|
+
return new Response("An idempotencyKey is required for Autumn usage reporting.", {
|
|
1119
|
+
status: 400,
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1072
1122
|
const meter = billing.meters?.[body.key];
|
|
1073
1123
|
if (!meter) {
|
|
1074
1124
|
return new Response(`Unknown Autumn meter "${body.key}".`, { status: 404 });
|
|
@@ -1080,6 +1130,13 @@ export function autumn(input) {
|
|
|
1080
1130
|
});
|
|
1081
1131
|
}
|
|
1082
1132
|
const resolved = await requireOwner(ctx, billing, sdk);
|
|
1133
|
+
// A retried report with the same key replays the original result
|
|
1134
|
+
// instead of applying the usage a second time.
|
|
1135
|
+
const idempotencyCacheKey = `${resolved.externalCustomerId}:${featureId}:${body.idempotencyKey}`;
|
|
1136
|
+
const replayed = getReportedUsageEvent(idempotencyCacheKey);
|
|
1137
|
+
if (replayed) {
|
|
1138
|
+
return Response.json(replayed);
|
|
1139
|
+
}
|
|
1083
1140
|
const active = resolveActiveProduct(resolved.customer, products);
|
|
1084
1141
|
const planId = active.product?.planId ?? "free";
|
|
1085
1142
|
const plan = plans[planId] ?? {};
|
|
@@ -1166,7 +1223,7 @@ export function autumn(input) {
|
|
|
1166
1223
|
customerId: resolved.customer.id,
|
|
1167
1224
|
projectedCurrentPeriodUsed: nextUsed,
|
|
1168
1225
|
}, resolved.tools);
|
|
1169
|
-
|
|
1226
|
+
const result = {
|
|
1170
1227
|
key: body.key,
|
|
1171
1228
|
quantity: body.quantity,
|
|
1172
1229
|
customerId: resolved.customer.id,
|
|
@@ -1187,7 +1244,9 @@ export function autumn(input) {
|
|
|
1187
1244
|
: typeof softLimit === "number" && nextUsed >= softLimit
|
|
1188
1245
|
? "Included usage has been exhausted. Additional usage is billable."
|
|
1189
1246
|
: null,
|
|
1190
|
-
}
|
|
1247
|
+
};
|
|
1248
|
+
setReportedUsageEvent(idempotencyCacheKey, result);
|
|
1249
|
+
return Response.json(result);
|
|
1191
1250
|
},
|
|
1192
1251
|
}),
|
|
1193
1252
|
integrationRoute.post(checkPath, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farm.js/autumn",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.101",
|
|
4
4
|
"description": "Autumn billing integration for Farm.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"autumn-js": "^1.2.7",
|
|
33
33
|
"standardwebhooks": "^1.0.0",
|
|
34
|
-
"@farm.js/
|
|
35
|
-
"@farm.js/
|
|
34
|
+
"@farm.js/core": "0.1.0-beta.101",
|
|
35
|
+
"@farm.js/integration-utils": "0.1.0-beta.101"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc",
|