@farm.js/autumn 0.1.0-beta.8 → 0.1.0-beta.80
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 +63 -7
- 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 ?? [])]
|
|
@@ -738,9 +782,7 @@ export function autumn(input) {
|
|
|
738
782
|
subscriptionId: active.subscription?.id ?? null,
|
|
739
783
|
currentPeriodStart: currentPeriodStart(active.subscription),
|
|
740
784
|
currentPeriodEnd: currentPeriodEnd(active.subscription),
|
|
741
|
-
cancelAtPeriodEnd: active.subscription
|
|
742
|
-
(active.subscription.canceledAt == null ||
|
|
743
|
-
active.subscription.canceledAt > Date.now()),
|
|
785
|
+
cancelAtPeriodEnd: isAutumnCancelAtPeriodEnd(active.subscription),
|
|
744
786
|
trialEndsAt: trialEndsAt(active.subscription),
|
|
745
787
|
features: plan.features ?? {},
|
|
746
788
|
limits: plan.limits ?? {},
|
|
@@ -1069,6 +1111,11 @@ export function autumn(input) {
|
|
|
1069
1111
|
if (typeof body.quantity !== "number" || !Number.isFinite(body.quantity)) {
|
|
1070
1112
|
return new Response("A numeric quantity is required.", { status: 400 });
|
|
1071
1113
|
}
|
|
1114
|
+
if (!body.idempotencyKey) {
|
|
1115
|
+
return new Response("An idempotencyKey is required for Autumn usage reporting.", {
|
|
1116
|
+
status: 400,
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1072
1119
|
const meter = billing.meters?.[body.key];
|
|
1073
1120
|
if (!meter) {
|
|
1074
1121
|
return new Response(`Unknown Autumn meter "${body.key}".`, { status: 404 });
|
|
@@ -1080,6 +1127,13 @@ export function autumn(input) {
|
|
|
1080
1127
|
});
|
|
1081
1128
|
}
|
|
1082
1129
|
const resolved = await requireOwner(ctx, billing, sdk);
|
|
1130
|
+
// A retried report with the same key replays the original result
|
|
1131
|
+
// instead of applying the usage a second time.
|
|
1132
|
+
const idempotencyCacheKey = `${resolved.externalCustomerId}:${featureId}:${body.idempotencyKey}`;
|
|
1133
|
+
const replayed = getReportedUsageEvent(idempotencyCacheKey);
|
|
1134
|
+
if (replayed) {
|
|
1135
|
+
return Response.json(replayed);
|
|
1136
|
+
}
|
|
1083
1137
|
const active = resolveActiveProduct(resolved.customer, products);
|
|
1084
1138
|
const planId = active.product?.planId ?? "free";
|
|
1085
1139
|
const plan = plans[planId] ?? {};
|
|
@@ -1166,7 +1220,7 @@ export function autumn(input) {
|
|
|
1166
1220
|
customerId: resolved.customer.id,
|
|
1167
1221
|
projectedCurrentPeriodUsed: nextUsed,
|
|
1168
1222
|
}, resolved.tools);
|
|
1169
|
-
|
|
1223
|
+
const result = {
|
|
1170
1224
|
key: body.key,
|
|
1171
1225
|
quantity: body.quantity,
|
|
1172
1226
|
customerId: resolved.customer.id,
|
|
@@ -1187,7 +1241,9 @@ export function autumn(input) {
|
|
|
1187
1241
|
: typeof softLimit === "number" && nextUsed >= softLimit
|
|
1188
1242
|
? "Included usage has been exhausted. Additional usage is billable."
|
|
1189
1243
|
: null,
|
|
1190
|
-
}
|
|
1244
|
+
};
|
|
1245
|
+
setReportedUsageEvent(idempotencyCacheKey, result);
|
|
1246
|
+
return Response.json(result);
|
|
1191
1247
|
},
|
|
1192
1248
|
}),
|
|
1193
1249
|
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.80",
|
|
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.80",
|
|
35
|
+
"@farm.js/integration-utils": "0.1.0-beta.80"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc",
|