@lunora/payment 1.0.0-alpha.3 → 1.0.0-alpha.30

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.
Files changed (43) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +5 -2
  3. package/dist/index.d.mts +266 -523
  4. package/dist/index.d.ts +266 -523
  5. package/dist/index.mjs +11 -13
  6. package/dist/packem_shared/{LunoraPaymentError-B3hEzXSs.mjs → LunoraPaymentError-BeQlhkZj.mjs} +4 -7
  7. package/dist/packem_shared/adapter.d-CMjjkTGB.d.mts +427 -0
  8. package/dist/packem_shared/adapter.d-CMjjkTGB.d.ts +427 -0
  9. package/dist/packem_shared/{addMoney-bCcs1nyw.mjs → addMoney-jSh_7TfF.mjs} +1 -1
  10. package/dist/packem_shared/{applyWebhookAction-DpAqf3Lw.mjs → applyWebhookAction-CLAx4svt.mjs} +1 -1
  11. package/dist/packem_shared/{constantTimeEqual-CfY0jYcL.mjs → constantTimeEqual-BQjoW85H.mjs} +14 -38
  12. package/dist/packem_shared/{createAdapterRegistry-BuDHFCBc.mjs → createAdapterRegistry-Ds7bx_TK.mjs} +1 -1
  13. package/dist/packem_shared/{createDatabasePaymentStore-bYB_HUE6.mjs → createDatabasePaymentStore-C0NUCj1H.mjs} +1 -1
  14. package/dist/packem_shared/{createPayment-BccfPGyw.mjs → createPayment-CKQAznOL.mjs} +26 -16
  15. package/dist/packem_shared/idempotencyKey-BzaHGdHD.mjs +9 -0
  16. package/dist/packem_shared/json-D0Cb5aMv.mjs +29 -0
  17. package/dist/packem_shared/{lunoraDatabaseToPaymentDatabase-RlKX3Kcd.mjs → lunoraDatabaseToPaymentDatabase-DTsgPvfO.mjs} +2 -2
  18. package/dist/packem_shared/not-supported-C0onRyia.mjs +7 -0
  19. package/dist/packem_shared/paymentTables-D4TbhaIk.mjs +59 -0
  20. package/dist/packem_shared/{reconcile-CI1ukJF9.mjs → reconcile-qE3ERi3D.mjs} +14 -2
  21. package/dist/packem_shared/subscription-event-CwEsWRCK.mjs +17 -0
  22. package/dist/providers/autumn-features.d.mts +129 -0
  23. package/dist/providers/autumn-features.d.ts +129 -0
  24. package/dist/providers/autumn-features.mjs +95 -0
  25. package/dist/providers/autumn.d.mts +28 -0
  26. package/dist/providers/autumn.d.ts +28 -0
  27. package/dist/providers/autumn.mjs +275 -0
  28. package/dist/providers/creem.d.mts +26 -0
  29. package/dist/providers/creem.d.ts +26 -0
  30. package/dist/providers/creem.mjs +236 -0
  31. package/dist/providers/dodopayments.d.mts +30 -0
  32. package/dist/providers/dodopayments.d.ts +30 -0
  33. package/dist/providers/dodopayments.mjs +259 -0
  34. package/dist/providers/polar.d.mts +31 -0
  35. package/dist/providers/polar.d.ts +31 -0
  36. package/dist/{packem_shared/createPolarAdapter-BJtVGSlF.mjs → providers/polar.mjs} +63 -49
  37. package/dist/providers/stripe.d.mts +32 -0
  38. package/dist/providers/stripe.d.ts +32 -0
  39. package/dist/{packem_shared/createStripeAdapter-D40MVBXg.mjs → providers/stripe.mjs} +56 -55
  40. package/package.json +46 -5
  41. package/dist/packem_shared/idempotencyKey-BFzDCA7g.mjs +0 -3
  42. package/dist/packem_shared/json-Db337f36.mjs +0 -6
  43. package/dist/packem_shared/paymentTables-DccHwWr_.mjs +0 -127
@@ -0,0 +1,59 @@
1
+ import { defineTable } from '@lunora/server';
2
+ import { v } from '@lunora/values';
3
+
4
+ const customers = defineTable({
5
+ createdAt: v.number(),
6
+ email: v.optional(v.string()),
7
+ provider: v.string(),
8
+ providerCustomerId: v.string(),
9
+ referenceId: v.string()
10
+ }).index("by_provider_customer", ["provider", "providerCustomerId"], { unique: true }).index("by_reference", ["referenceId"]);
11
+ const subscriptions = defineTable({
12
+ cancelAtPeriodEnd: v.boolean(),
13
+ createdAt: v.number(),
14
+ currentPeriodEnd: v.optional(v.number()),
15
+ currentPeriodStart: v.optional(v.number()),
16
+ priceId: v.string(),
17
+ provider: v.string(),
18
+ providerSubscriptionId: v.string(),
19
+ quantity: v.number(),
20
+ referenceId: v.string(),
21
+ state: v.string(),
22
+ updatedAt: v.number()
23
+ }).index("by_provider_subscription", ["provider", "providerSubscriptionId"], { unique: true }).index("by_reference", ["referenceId"]);
24
+ const paymentSessions = defineTable({
25
+ amountMinor: v.bigint(),
26
+ capturedMinor: v.bigint(),
27
+ createdAt: v.number(),
28
+ currency: v.string(),
29
+ provider: v.string(),
30
+ providerSessionId: v.string(),
31
+ referenceId: v.string(),
32
+ refundedMinor: v.bigint(),
33
+ state: v.string(),
34
+ updatedAt: v.number()
35
+ }).index("by_provider_session", ["provider", "providerSessionId"], { unique: true }).index("by_reference", ["referenceId"]);
36
+ const events = defineTable({
37
+ processedAt: v.number(),
38
+ provider: v.string(),
39
+ providerEventId: v.string(),
40
+ type: v.string()
41
+ }).index("by_provider_event", ["provider", "providerEventId"], { unique: true });
42
+ const usageEvents = defineTable({
43
+ createdAt: v.number(),
44
+ featureId: v.string(),
45
+ idempotencyKey: v.string(),
46
+ provider: v.string(),
47
+ quantity: v.number(),
48
+ referenceId: v.string(),
49
+ reportedToProvider: v.boolean()
50
+ }).index("by_idempotency", ["provider", "idempotencyKey"], { unique: true }).index("by_reference_feature", ["referenceId", "featureId"]);
51
+ const paymentTables = {
52
+ customers,
53
+ events,
54
+ paymentSessions,
55
+ subscriptions,
56
+ usageEvents
57
+ };
58
+
59
+ export { paymentTables as default };
@@ -1,9 +1,20 @@
1
- import { compareMoney } from './addMoney-bCcs1nyw.mjs';
1
+ import { compareMoney } from './addMoney-jSh_7TfF.mjs';
2
2
  import { n as notifyObserver } from './observability-CvhJ205g.mjs';
3
3
 
4
4
  const sameCurrencyAmount = (a, b) => a.currency === b.currency && compareMoney(a, b) === 0;
5
5
  const subscriptionDrifted = (existing, current) => existing?.state !== current.state || existing.cancelAtPeriodEnd !== current.cancelAtPeriodEnd || existing.currentPeriodEnd !== current.currentPeriodEnd || existing.priceId !== current.priceId || existing.quantity !== current.quantity;
6
6
  const paymentDrifted = (existing, current) => existing?.state !== current.state || !sameCurrencyAmount(existing.capturedAmount, current.capturedAmount) || !sameCurrencyAmount(existing.refundedAmount, current.refundedAmount);
7
+ const REFUND_STATES = /* @__PURE__ */ new Set(["partially_refunded", "refunded"]);
8
+ const mergePaymentTruth = (existing, current) => {
9
+ if (!existing) {
10
+ return current;
11
+ }
12
+ const sameRefundCurrency = existing.refundedAmount.currency === current.refundedAmount.currency;
13
+ const refundedAmount = sameRefundCurrency && compareMoney(existing.refundedAmount, current.refundedAmount) > 0 ? existing.refundedAmount : current.refundedAmount;
14
+ const state = current.state === "captured" && REFUND_STATES.has(existing.state) ? existing.state : current.state;
15
+ const referenceId = current.referenceId === "" ? existing.referenceId : current.referenceId;
16
+ return { ...current, referenceId, refundedAmount, state };
17
+ };
7
18
  const reconcileSubscription = async (adapter, store, id, observer) => {
8
19
  const current = await adapter.getSubscriptionStatus(id);
9
20
  const existing = await store.getSubscription(adapter.identifier, id);
@@ -15,8 +26,9 @@ const reconcileSubscription = async (adapter, store, id, observer) => {
15
26
  return true;
16
27
  };
17
28
  const reconcilePayment = async (adapter, store, id, observer) => {
18
- const current = await adapter.getPaymentStatus(id);
29
+ const providerTruth = await adapter.getPaymentStatus(id);
19
30
  const existing = await store.getPaymentSession(adapter.identifier, id);
31
+ const current = mergePaymentTruth(existing, providerTruth);
20
32
  if (!paymentDrifted(existing, current)) {
21
33
  return false;
22
34
  }
@@ -0,0 +1,17 @@
1
+ const stateToEventType = (state) => {
2
+ if (state === "canceled") {
3
+ return "subscription.canceled";
4
+ }
5
+ if (state === "past_due") {
6
+ return "subscription.past_due";
7
+ }
8
+ if (state === "paused") {
9
+ return "subscription.paused";
10
+ }
11
+ if (state === "active" || state === "trialing") {
12
+ return "subscription.active";
13
+ }
14
+ return "subscription.updated";
15
+ };
16
+
17
+ export { stateToEventType as s };
@@ -0,0 +1,129 @@
1
+ /**
2
+ * A per-seat / per-workspace sub-customer with its own feature balances.
3
+ * @experimental
4
+ */
5
+ interface AutumnEntity {
6
+ readonly featureId?: string;
7
+ readonly id: string;
8
+ readonly name?: string;
9
+ /** The raw provider record, for fields this facade does not normalize. */
10
+ readonly raw: Record<string, unknown>;
11
+ }
12
+ /**
13
+ * `CreateEntityInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
14
+ * @experimental
15
+ */
16
+ interface CreateEntityInput {
17
+ /** The feature the entity consumes a seat/allowance of (e.g. `"seats"`). */
18
+ readonly featureId: string;
19
+ /** Caller-chosen stable id — Autumn requires an entity id on create. */
20
+ readonly id: string;
21
+ readonly name?: string;
22
+ }
23
+ /**
24
+ * One point in a usage-events aggregation.
25
+ * @experimental
26
+ */
27
+ interface UsageEventPoint {
28
+ readonly count: number;
29
+ readonly period?: string;
30
+ readonly raw: Record<string, unknown>;
31
+ }
32
+ /**
33
+ * `EventsListInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
34
+ * @experimental
35
+ */
36
+ interface EventsListInput {
37
+ /** Feature(s) to report on. */
38
+ readonly featureId: ReadonlyArray<string> | string;
39
+ }
40
+ /**
41
+ * `EventsAggregateInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
42
+ * @experimental
43
+ */
44
+ interface EventsAggregateInput extends EventsListInput {
45
+ /** Time window to aggregate over (aggregate only — `list` ignores it, so it isn't accepted there). */
46
+ readonly range?: "7d" | "24h" | "30d" | "90d" | "last_cycle";
47
+ }
48
+ /**
49
+ * A prepaid feature quantity purchased at checkout (e.g. buy 5 seats up front).
50
+ * @experimental
51
+ */
52
+ interface PrepaidOption {
53
+ readonly featureId: string;
54
+ readonly quantity: number;
55
+ }
56
+ /**
57
+ * Autumn-native checkout — richer than the generic `createCheckout` (trials, prepaid, entities, rewards).
58
+ * @experimental
59
+ */
60
+ interface AutumnCheckoutInput {
61
+ /** Scope the checkout to a specific entity (seat/workspace) rather than the top-level customer. */
62
+ readonly entityId?: string;
63
+ /**
64
+ * Autumn applies a plan's configured free trial automatically. Pass `false` to opt out of that
65
+ * trial for this checkout; leave unset (or `true`) to keep the plan default.
66
+ */
67
+ readonly freeTrial?: boolean;
68
+ /** Prepaid feature quantities to purchase up front. */
69
+ readonly options?: ReadonlyArray<PrepaidOption>;
70
+ /** The plan to attach (Autumn's plan id — the successor to the classic "product" id). */
71
+ readonly planId: string;
72
+ /** An Autumn reward id to apply as a discount. */
73
+ readonly reward?: string;
74
+ readonly successUrl?: string;
75
+ }
76
+ /**
77
+ * The subset of the Autumn SDK surface the native facade calls. A real `Autumn` instance satisfies it.
78
+ * @experimental
79
+ */
80
+ interface AutumnFeaturesClientLike {
81
+ readonly billing: unknown;
82
+ readonly entities: unknown;
83
+ readonly events: unknown;
84
+ readonly plans: unknown;
85
+ readonly referrals: unknown;
86
+ }
87
+ /**
88
+ * `AutumnFeaturesOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
89
+ * @experimental
90
+ */
91
+ interface AutumnFeaturesOptions {
92
+ readonly client: AutumnFeaturesClientLike;
93
+ }
94
+ /**
95
+ * The Autumn-native feature facade returned by {@link createAutumnFeatures}.
96
+ * @experimental
97
+ */
98
+ interface AutumnFeatures {
99
+ readonly checkout: (referenceId: string, input: AutumnCheckoutInput) => Promise<{
100
+ raw: Record<string, unknown>;
101
+ url: string;
102
+ }>;
103
+ readonly entities: {
104
+ readonly create: (referenceId: string, input: CreateEntityInput) => Promise<AutumnEntity>;
105
+ readonly delete: (referenceId: string, entityId: string) => Promise<void>;
106
+ readonly get: (referenceId: string, entityId: string) => Promise<AutumnEntity>;
107
+ };
108
+ readonly events: {
109
+ readonly aggregate: (referenceId: string, input: EventsAggregateInput) => Promise<UsageEventPoint[]>;
110
+ readonly list: (referenceId: string, input: EventsListInput) => Promise<UsageEventPoint[]>;
111
+ };
112
+ readonly plans: {
113
+ readonly list: () => Promise<Record<string, unknown>[]>;
114
+ };
115
+ readonly referrals: {
116
+ readonly createCode: (referenceId: string, programId: string) => Promise<{
117
+ code: string;
118
+ raw: Record<string, unknown>;
119
+ }>;
120
+ readonly redeemCode: (referenceId: string, code: string) => Promise<Record<string, unknown>>;
121
+ };
122
+ }
123
+ /**
124
+ * Build the Autumn-native feature facade over an injected client. Companion to `createAutumnAdapter`;
125
+ * share the same underlying `autumn-js` `Autumn` client between them.
126
+ * @experimental
127
+ */
128
+ declare const createAutumnFeatures: (options: AutumnFeaturesOptions) => AutumnFeatures;
129
+ export { type AutumnCheckoutInput, type AutumnEntity, type AutumnFeatures, type AutumnFeaturesClientLike, type AutumnFeaturesOptions, type CreateEntityInput, type EventsAggregateInput, type EventsListInput, type PrepaidOption, type UsageEventPoint, createAutumnFeatures };
@@ -0,0 +1,129 @@
1
+ /**
2
+ * A per-seat / per-workspace sub-customer with its own feature balances.
3
+ * @experimental
4
+ */
5
+ interface AutumnEntity {
6
+ readonly featureId?: string;
7
+ readonly id: string;
8
+ readonly name?: string;
9
+ /** The raw provider record, for fields this facade does not normalize. */
10
+ readonly raw: Record<string, unknown>;
11
+ }
12
+ /**
13
+ * `CreateEntityInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
14
+ * @experimental
15
+ */
16
+ interface CreateEntityInput {
17
+ /** The feature the entity consumes a seat/allowance of (e.g. `"seats"`). */
18
+ readonly featureId: string;
19
+ /** Caller-chosen stable id — Autumn requires an entity id on create. */
20
+ readonly id: string;
21
+ readonly name?: string;
22
+ }
23
+ /**
24
+ * One point in a usage-events aggregation.
25
+ * @experimental
26
+ */
27
+ interface UsageEventPoint {
28
+ readonly count: number;
29
+ readonly period?: string;
30
+ readonly raw: Record<string, unknown>;
31
+ }
32
+ /**
33
+ * `EventsListInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
34
+ * @experimental
35
+ */
36
+ interface EventsListInput {
37
+ /** Feature(s) to report on. */
38
+ readonly featureId: ReadonlyArray<string> | string;
39
+ }
40
+ /**
41
+ * `EventsAggregateInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
42
+ * @experimental
43
+ */
44
+ interface EventsAggregateInput extends EventsListInput {
45
+ /** Time window to aggregate over (aggregate only — `list` ignores it, so it isn't accepted there). */
46
+ readonly range?: "7d" | "24h" | "30d" | "90d" | "last_cycle";
47
+ }
48
+ /**
49
+ * A prepaid feature quantity purchased at checkout (e.g. buy 5 seats up front).
50
+ * @experimental
51
+ */
52
+ interface PrepaidOption {
53
+ readonly featureId: string;
54
+ readonly quantity: number;
55
+ }
56
+ /**
57
+ * Autumn-native checkout — richer than the generic `createCheckout` (trials, prepaid, entities, rewards).
58
+ * @experimental
59
+ */
60
+ interface AutumnCheckoutInput {
61
+ /** Scope the checkout to a specific entity (seat/workspace) rather than the top-level customer. */
62
+ readonly entityId?: string;
63
+ /**
64
+ * Autumn applies a plan's configured free trial automatically. Pass `false` to opt out of that
65
+ * trial for this checkout; leave unset (or `true`) to keep the plan default.
66
+ */
67
+ readonly freeTrial?: boolean;
68
+ /** Prepaid feature quantities to purchase up front. */
69
+ readonly options?: ReadonlyArray<PrepaidOption>;
70
+ /** The plan to attach (Autumn's plan id — the successor to the classic "product" id). */
71
+ readonly planId: string;
72
+ /** An Autumn reward id to apply as a discount. */
73
+ readonly reward?: string;
74
+ readonly successUrl?: string;
75
+ }
76
+ /**
77
+ * The subset of the Autumn SDK surface the native facade calls. A real `Autumn` instance satisfies it.
78
+ * @experimental
79
+ */
80
+ interface AutumnFeaturesClientLike {
81
+ readonly billing: unknown;
82
+ readonly entities: unknown;
83
+ readonly events: unknown;
84
+ readonly plans: unknown;
85
+ readonly referrals: unknown;
86
+ }
87
+ /**
88
+ * `AutumnFeaturesOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
89
+ * @experimental
90
+ */
91
+ interface AutumnFeaturesOptions {
92
+ readonly client: AutumnFeaturesClientLike;
93
+ }
94
+ /**
95
+ * The Autumn-native feature facade returned by {@link createAutumnFeatures}.
96
+ * @experimental
97
+ */
98
+ interface AutumnFeatures {
99
+ readonly checkout: (referenceId: string, input: AutumnCheckoutInput) => Promise<{
100
+ raw: Record<string, unknown>;
101
+ url: string;
102
+ }>;
103
+ readonly entities: {
104
+ readonly create: (referenceId: string, input: CreateEntityInput) => Promise<AutumnEntity>;
105
+ readonly delete: (referenceId: string, entityId: string) => Promise<void>;
106
+ readonly get: (referenceId: string, entityId: string) => Promise<AutumnEntity>;
107
+ };
108
+ readonly events: {
109
+ readonly aggregate: (referenceId: string, input: EventsAggregateInput) => Promise<UsageEventPoint[]>;
110
+ readonly list: (referenceId: string, input: EventsListInput) => Promise<UsageEventPoint[]>;
111
+ };
112
+ readonly plans: {
113
+ readonly list: () => Promise<Record<string, unknown>[]>;
114
+ };
115
+ readonly referrals: {
116
+ readonly createCode: (referenceId: string, programId: string) => Promise<{
117
+ code: string;
118
+ raw: Record<string, unknown>;
119
+ }>;
120
+ readonly redeemCode: (referenceId: string, code: string) => Promise<Record<string, unknown>>;
121
+ };
122
+ }
123
+ /**
124
+ * Build the Autumn-native feature facade over an injected client. Companion to `createAutumnAdapter`;
125
+ * share the same underlying `autumn-js` `Autumn` client between them.
126
+ * @experimental
127
+ */
128
+ declare const createAutumnFeatures: (options: AutumnFeaturesOptions) => AutumnFeatures;
129
+ export { type AutumnCheckoutInput, type AutumnEntity, type AutumnFeatures, type AutumnFeaturesClientLike, type AutumnFeaturesOptions, type CreateEntityInput, type EventsAggregateInput, type EventsListInput, type PrepaidOption, type UsageEventPoint, createAutumnFeatures };
@@ -0,0 +1,95 @@
1
+ import { a as asRecord, r as readString, b as readNumber } from '../packem_shared/json-D0Cb5aMv.mjs';
2
+
3
+ const toFeatureId = (featureId) => typeof featureId === "string" ? featureId : [...featureId];
4
+ const entityFrom = (record) => {
5
+ return {
6
+ featureId: readString(record, "featureId") ?? readString(record, "feature_id"),
7
+ id: readString(record, "id") ?? "",
8
+ name: readString(record, "name"),
9
+ raw: record
10
+ };
11
+ };
12
+ const pointsFrom = (result) => {
13
+ const list = result.list ?? result.data ?? result.events;
14
+ const rows = Array.isArray(list) ? list : [];
15
+ return rows.map((entry) => {
16
+ const record = asRecord(entry);
17
+ return { count: readNumber(record, "count") ?? readNumber(record, "value") ?? 0, period: readString(record, "period"), raw: record };
18
+ });
19
+ };
20
+ const createAutumnFeatures = (options) => {
21
+ const client = options.client;
22
+ return {
23
+ /**
24
+ * Native Autumn checkout — supports opting out of a plan's free trial, prepaid feature
25
+ * quantities, entity scoping, and reward codes. Returns the hosted checkout URL (empty when
26
+ * Autumn applied the change directly without a payment step).
27
+ */
28
+ checkout: async (referenceId, input) => {
29
+ const result = asRecord(
30
+ await client.billing.attach({
31
+ customerId: referenceId,
32
+ // Autumn applies the plan's configured trial by default; `null` opts this checkout out.
33
+ // eslint-disable-next-line unicorn/no-null -- the SDK's customize.freeTrial requires null (not undefined) to disable
34
+ ...input.freeTrial === false ? { customize: { freeTrial: null } } : {},
35
+ discounts: input.reward ? [{ rewardId: input.reward }] : void 0,
36
+ entityId: input.entityId,
37
+ featureQuantities: input.options?.map((option) => {
38
+ return { featureId: option.featureId, quantity: option.quantity };
39
+ }),
40
+ planId: input.planId,
41
+ successUrl: input.successUrl
42
+ })
43
+ );
44
+ const url = readString(result, "paymentUrl") ?? readString(result, "checkoutUrl") ?? readString(result, "url") ?? "";
45
+ return { raw: result, url };
46
+ },
47
+ entities: {
48
+ /** Create a per-seat / per-workspace sub-customer under a reference. */
49
+ create: async (referenceId, input) => {
50
+ const created = await client.entities.create({ customerId: referenceId, entityId: input.id, featureId: input.featureId, name: input.name });
51
+ return entityFrom(asRecord(created));
52
+ },
53
+ /** Remove an entity — frees its seat/allowance. */
54
+ delete: async (referenceId, entityId) => {
55
+ await client.entities.delete({ customerId: referenceId, entityId });
56
+ },
57
+ /** Fetch one entity and its balances. */
58
+ get: async (referenceId, entityId) => {
59
+ const entity = await client.entities.get({ customerId: referenceId, entityId });
60
+ return entityFrom(asRecord(entity));
61
+ }
62
+ },
63
+ events: {
64
+ /** Bucketed usage aggregation for a reference's feature(s) over a range. */
65
+ aggregate: async (referenceId, input) => {
66
+ const result = await client.events.aggregate({ customerId: referenceId, featureId: toFeatureId(input.featureId), range: input.range });
67
+ return pointsFrom(asRecord(result));
68
+ },
69
+ /** Raw usage events for a reference's feature(s). */
70
+ list: async (referenceId, input) => {
71
+ const result = await client.events.list({ customerId: referenceId, featureId: toFeatureId(input.featureId) });
72
+ return pointsFrom(asRecord(result));
73
+ }
74
+ },
75
+ plans: {
76
+ /** The configured plan catalog. */
77
+ list: async () => {
78
+ const result = asRecord(await client.plans.list());
79
+ const list = result.list ?? result.data ?? result.plans;
80
+ return Array.isArray(list) ? list.map((entry) => asRecord(entry)) : [];
81
+ }
82
+ },
83
+ referrals: {
84
+ /** Mint (or fetch) a referral code for a reference in a referral program. */
85
+ createCode: async (referenceId, programId) => {
86
+ const result = asRecord(await client.referrals.createCode({ customerId: referenceId, programId }));
87
+ return { code: readString(result, "code") ?? "", raw: result };
88
+ },
89
+ /** Redeem a referral code on behalf of a reference. */
90
+ redeemCode: async (referenceId, code) => asRecord(await client.referrals.redeemCode({ code, customerId: referenceId }))
91
+ }
92
+ };
93
+ };
94
+
95
+ export { createAutumnFeatures };
@@ -0,0 +1,28 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.mjs";
2
+ /**
3
+ * The `autumn-js` SDK surface the adapter uses, as a structural type — a real `Autumn` instance
4
+ * satisfies it without a cast. Resources/methods are `unknown` (the adapter re-types the client as
5
+ * the real `Autumn` internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface AutumnClientLike {
9
+ readonly billing: unknown;
10
+ readonly check: unknown;
11
+ readonly customers: unknown;
12
+ readonly track: unknown;
13
+ }
14
+ /**
15
+ * `AutumnAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
16
+ * @experimental
17
+ */
18
+ interface AutumnAdapterOptions {
19
+ readonly client: AutumnClientLike;
20
+ readonly webhookSecret: string;
21
+ readonly webhookToleranceSeconds?: number;
22
+ }
23
+ /**
24
+ * `createAutumnAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
25
+ * @experimental
26
+ */
27
+ declare const createAutumnAdapter: (options: AutumnAdapterOptions) => PaymentAdapter;
28
+ export { type AutumnAdapterOptions, type AutumnClientLike, createAutumnAdapter };
@@ -0,0 +1,28 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.js";
2
+ /**
3
+ * The `autumn-js` SDK surface the adapter uses, as a structural type — a real `Autumn` instance
4
+ * satisfies it without a cast. Resources/methods are `unknown` (the adapter re-types the client as
5
+ * the real `Autumn` internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface AutumnClientLike {
9
+ readonly billing: unknown;
10
+ readonly check: unknown;
11
+ readonly customers: unknown;
12
+ readonly track: unknown;
13
+ }
14
+ /**
15
+ * `AutumnAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
16
+ * @experimental
17
+ */
18
+ interface AutumnAdapterOptions {
19
+ readonly client: AutumnClientLike;
20
+ readonly webhookSecret: string;
21
+ readonly webhookToleranceSeconds?: number;
22
+ }
23
+ /**
24
+ * `createAutumnAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
25
+ * @experimental
26
+ */
27
+ declare const createAutumnAdapter: (options: AutumnAdapterOptions) => PaymentAdapter;
28
+ export { type AutumnAdapterOptions, type AutumnClientLike, createAutumnAdapter };