@nehorai/credits 2.1.0 → 3.0.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/LICENSE +21 -0
- package/dist/adapters/index.cjs +3 -2
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +2 -2
- package/dist/adapters/index.d.ts +2 -2
- package/dist/adapters/index.js +3 -2
- package/dist/adapters/index.js.map +1 -1
- package/dist/core/index.cjs +218 -2
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +183 -5
- package/dist/core/index.d.ts +183 -5
- package/dist/core/index.js +199 -2
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +477 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +456 -59
- package/dist/index.js.map +1 -1
- package/dist/repository/index.cjs +394 -44
- package/dist/repository/index.cjs.map +1 -1
- package/dist/repository/index.d.cts +36 -7
- package/dist/repository/index.d.ts +36 -7
- package/dist/repository/index.js +391 -43
- package/dist/repository/index.js.map +1 -1
- package/dist/sdk/index.cjs +1 -0
- package/dist/sdk/index.cjs.map +1 -1
- package/dist/sdk/index.d.cts +2 -2
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/index.js +1 -0
- package/dist/sdk/index.js.map +1 -1
- package/dist/service/index.cjs +33 -20
- package/dist/service/index.cjs.map +1 -1
- package/dist/service/index.d.cts +2 -2
- package/dist/service/index.d.ts +2 -2
- package/dist/service/index.js +33 -20
- package/dist/service/index.js.map +1 -1
- package/dist/{types-Dzc443vy.d.cts → types-C3sxDvNb.d.cts} +43 -2
- package/dist/{types-Dzc443vy.d.ts → types-C3sxDvNb.d.ts} +43 -2
- package/dist/{types-BhCdep_t.d.ts → types-CY-oHIMA.d.ts} +55 -4
- package/dist/{types-wtksMa4n.d.cts → types-DOjguhEX.d.cts} +55 -4
- package/package.json +70 -71
|
@@ -93,11 +93,42 @@ interface PortableUserCredits {
|
|
|
93
93
|
monthlyResetAt: string;
|
|
94
94
|
/** Subscription expiry (null/undefined for free tier) - ISO 8601 or null */
|
|
95
95
|
subscriptionExpiresAt?: string | null;
|
|
96
|
+
/**
|
|
97
|
+
* The part of `balance` a balance-lowering write kept only to back outstanding
|
|
98
|
+
* holds. A commit consumes it; a release or expiry removes it from `balance`.
|
|
99
|
+
* Absent means 0. See `planBalanceCap`.
|
|
100
|
+
*/
|
|
101
|
+
expiredHoldBacking?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Where those credits end among the open holds, so a hold's share needs no write
|
|
104
|
+
* to the hold. Internal to the repositories: `toClientUserCredits` drops it.
|
|
105
|
+
*/
|
|
106
|
+
expiredBackingFrontier?: ExpiredBackingFrontier | null;
|
|
107
|
+
/**
|
|
108
|
+
* Set when the account was created with a signup-grant claim: the amount
|
|
109
|
+
* granted, 0 when the claim was already taken. Absent on any other account.
|
|
110
|
+
*/
|
|
111
|
+
signupGrant?: number;
|
|
96
112
|
/** Creation timestamp - ISO 8601 */
|
|
97
113
|
createdAt: string;
|
|
98
114
|
/** Last update timestamp - ISO 8601 */
|
|
99
115
|
updatedAt: string;
|
|
100
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The newest open hold carrying marked credits (`expiredHoldBacking`).
|
|
119
|
+
*
|
|
120
|
+
* Credits are marked oldest hold first, so a single point describes every share:
|
|
121
|
+
* a hold older than this carries its full amount, this hold carries `share`, and a
|
|
122
|
+
* newer one carries nothing. A marked credit leaves the balance when its hold closes,
|
|
123
|
+
* however it closes. See `allocateExpiredBacking` and `holdExpiredBacking`.
|
|
124
|
+
*/
|
|
125
|
+
interface ExpiredBackingFrontier {
|
|
126
|
+
/** The hold's `holdPlacedAt`. */
|
|
127
|
+
holdPlacedAt: string;
|
|
128
|
+
/** The hold's id, which orders holds placed in the same millisecond. */
|
|
129
|
+
id: string;
|
|
130
|
+
share: number;
|
|
131
|
+
}
|
|
101
132
|
/**
|
|
102
133
|
* Credit reservation status for two-phase commit
|
|
103
134
|
*/
|
|
@@ -136,6 +167,11 @@ interface PortableReservation {
|
|
|
136
167
|
* See `assertHoldPlaced` in `core/reservation-integrity.ts`.
|
|
137
168
|
*/
|
|
138
169
|
holdPlacedAt?: string;
|
|
170
|
+
/**
|
|
171
|
+
* This hold's share of the marked credits, stored by 2.2.0. A hold placed since carries
|
|
172
|
+
* none and takes its share from the account's frontier. See `holdExpiredBacking`.
|
|
173
|
+
*/
|
|
174
|
+
expiredBacking?: number;
|
|
139
175
|
}
|
|
140
176
|
/**
|
|
141
177
|
* Result of a credit check operation
|
|
@@ -250,8 +286,13 @@ interface PortableJournalEntry {
|
|
|
250
286
|
entryType: "debit" | "credit";
|
|
251
287
|
/** Amount of credits involved */
|
|
252
288
|
amount: number;
|
|
253
|
-
/**
|
|
289
|
+
/** `balance + bonusCredits` after this entry */
|
|
254
290
|
balanceAfter: number;
|
|
291
|
+
/**
|
|
292
|
+
* `balance + bonusCredits` before this entry, read in the same atomic step.
|
|
293
|
+
* Absent on entries written before 3.0.0.
|
|
294
|
+
*/
|
|
295
|
+
balanceBefore?: number;
|
|
255
296
|
/** Source of the credit change */
|
|
256
297
|
source: CreditSource;
|
|
257
298
|
/** Reference ID (e.g., reservationId, transactionId) */
|
|
@@ -350,4 +391,4 @@ interface WithCreditsOptions {
|
|
|
350
391
|
resourceType?: ResourceType;
|
|
351
392
|
}
|
|
352
393
|
|
|
353
|
-
export { type AIProviderType as A, type BuiltinTier as B, type CreditOperationType as C, type DeductCreditsResult as D, type JournalReferenceType as J, type MonthlyResetResult as M, type PortableTransaction as P, type ReservationStatus as R, type SubscriptionTier as S, type TierConfig as T, type UsageHistoryEntry as U, type WithCreditsOptions as W, type PortableReservation as a, type CreditSource as b, type PortableUserCredits as c, type PortableUsageLog as d, type SubscriptionExpiryResult as e, type PortableJournalEntry as f, type CreditCheckResult as g, type ResourceType as h, type TransactionType as i, type UsageHistoryResponse as j, calculateAvailableCredits as k, toPortableTimestamp as l, toDate as t };
|
|
394
|
+
export { type AIProviderType as A, type BuiltinTier as B, type CreditOperationType as C, type DeductCreditsResult as D, type ExpiredBackingFrontier as E, type JournalReferenceType as J, type MonthlyResetResult as M, type PortableTransaction as P, type ReservationStatus as R, type SubscriptionTier as S, type TierConfig as T, type UsageHistoryEntry as U, type WithCreditsOptions as W, type PortableReservation as a, type CreditSource as b, type PortableUserCredits as c, type PortableUsageLog as d, type SubscriptionExpiryResult as e, type PortableJournalEntry as f, type CreditCheckResult as g, type ResourceType as h, type TransactionType as i, type UsageHistoryResponse as j, calculateAvailableCredits as k, toPortableTimestamp as l, toDate as t };
|
|
@@ -93,11 +93,42 @@ interface PortableUserCredits {
|
|
|
93
93
|
monthlyResetAt: string;
|
|
94
94
|
/** Subscription expiry (null/undefined for free tier) - ISO 8601 or null */
|
|
95
95
|
subscriptionExpiresAt?: string | null;
|
|
96
|
+
/**
|
|
97
|
+
* The part of `balance` a balance-lowering write kept only to back outstanding
|
|
98
|
+
* holds. A commit consumes it; a release or expiry removes it from `balance`.
|
|
99
|
+
* Absent means 0. See `planBalanceCap`.
|
|
100
|
+
*/
|
|
101
|
+
expiredHoldBacking?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Where those credits end among the open holds, so a hold's share needs no write
|
|
104
|
+
* to the hold. Internal to the repositories: `toClientUserCredits` drops it.
|
|
105
|
+
*/
|
|
106
|
+
expiredBackingFrontier?: ExpiredBackingFrontier | null;
|
|
107
|
+
/**
|
|
108
|
+
* Set when the account was created with a signup-grant claim: the amount
|
|
109
|
+
* granted, 0 when the claim was already taken. Absent on any other account.
|
|
110
|
+
*/
|
|
111
|
+
signupGrant?: number;
|
|
96
112
|
/** Creation timestamp - ISO 8601 */
|
|
97
113
|
createdAt: string;
|
|
98
114
|
/** Last update timestamp - ISO 8601 */
|
|
99
115
|
updatedAt: string;
|
|
100
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The newest open hold carrying marked credits (`expiredHoldBacking`).
|
|
119
|
+
*
|
|
120
|
+
* Credits are marked oldest hold first, so a single point describes every share:
|
|
121
|
+
* a hold older than this carries its full amount, this hold carries `share`, and a
|
|
122
|
+
* newer one carries nothing. A marked credit leaves the balance when its hold closes,
|
|
123
|
+
* however it closes. See `allocateExpiredBacking` and `holdExpiredBacking`.
|
|
124
|
+
*/
|
|
125
|
+
interface ExpiredBackingFrontier {
|
|
126
|
+
/** The hold's `holdPlacedAt`. */
|
|
127
|
+
holdPlacedAt: string;
|
|
128
|
+
/** The hold's id, which orders holds placed in the same millisecond. */
|
|
129
|
+
id: string;
|
|
130
|
+
share: number;
|
|
131
|
+
}
|
|
101
132
|
/**
|
|
102
133
|
* Credit reservation status for two-phase commit
|
|
103
134
|
*/
|
|
@@ -136,6 +167,11 @@ interface PortableReservation {
|
|
|
136
167
|
* See `assertHoldPlaced` in `core/reservation-integrity.ts`.
|
|
137
168
|
*/
|
|
138
169
|
holdPlacedAt?: string;
|
|
170
|
+
/**
|
|
171
|
+
* This hold's share of the marked credits, stored by 2.2.0. A hold placed since carries
|
|
172
|
+
* none and takes its share from the account's frontier. See `holdExpiredBacking`.
|
|
173
|
+
*/
|
|
174
|
+
expiredBacking?: number;
|
|
139
175
|
}
|
|
140
176
|
/**
|
|
141
177
|
* Result of a credit check operation
|
|
@@ -250,8 +286,13 @@ interface PortableJournalEntry {
|
|
|
250
286
|
entryType: "debit" | "credit";
|
|
251
287
|
/** Amount of credits involved */
|
|
252
288
|
amount: number;
|
|
253
|
-
/**
|
|
289
|
+
/** `balance + bonusCredits` after this entry */
|
|
254
290
|
balanceAfter: number;
|
|
291
|
+
/**
|
|
292
|
+
* `balance + bonusCredits` before this entry, read in the same atomic step.
|
|
293
|
+
* Absent on entries written before 3.0.0.
|
|
294
|
+
*/
|
|
295
|
+
balanceBefore?: number;
|
|
255
296
|
/** Source of the credit change */
|
|
256
297
|
source: CreditSource;
|
|
257
298
|
/** Reference ID (e.g., reservationId, transactionId) */
|
|
@@ -350,4 +391,4 @@ interface WithCreditsOptions {
|
|
|
350
391
|
resourceType?: ResourceType;
|
|
351
392
|
}
|
|
352
393
|
|
|
353
|
-
export { type AIProviderType as A, type BuiltinTier as B, type CreditOperationType as C, type DeductCreditsResult as D, type JournalReferenceType as J, type MonthlyResetResult as M, type PortableTransaction as P, type ReservationStatus as R, type SubscriptionTier as S, type TierConfig as T, type UsageHistoryEntry as U, type WithCreditsOptions as W, type PortableReservation as a, type CreditSource as b, type PortableUserCredits as c, type PortableUsageLog as d, type SubscriptionExpiryResult as e, type PortableJournalEntry as f, type CreditCheckResult as g, type ResourceType as h, type TransactionType as i, type UsageHistoryResponse as j, calculateAvailableCredits as k, toPortableTimestamp as l, toDate as t };
|
|
394
|
+
export { type AIProviderType as A, type BuiltinTier as B, type CreditOperationType as C, type DeductCreditsResult as D, type ExpiredBackingFrontier as E, type JournalReferenceType as J, type MonthlyResetResult as M, type PortableTransaction as P, type ReservationStatus as R, type SubscriptionTier as S, type TierConfig as T, type UsageHistoryEntry as U, type WithCreditsOptions as W, type PortableReservation as a, type CreditSource as b, type PortableUserCredits as c, type PortableUsageLog as d, type SubscriptionExpiryResult as e, type PortableJournalEntry as f, type CreditCheckResult as g, type ResourceType as h, type TransactionType as i, type UsageHistoryResponse as j, calculateAvailableCredits as k, toPortableTimestamp as l, toDate as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as PortableTransaction, a as PortableReservation, R as ReservationStatus, C as CreditOperationType, b as CreditSource, J as JournalReferenceType, A as AIProviderType, S as SubscriptionTier, c as PortableUserCredits, d as PortableUsageLog, M as MonthlyResetResult, e as SubscriptionExpiryResult, f as PortableJournalEntry } from './types-
|
|
1
|
+
import { P as PortableTransaction, a as PortableReservation, R as ReservationStatus, C as CreditOperationType, b as CreditSource, J as JournalReferenceType, A as AIProviderType, S as SubscriptionTier, c as PortableUserCredits, d as PortableUsageLog, M as MonthlyResetResult, e as SubscriptionExpiryResult, f as PortableJournalEntry } from './types-C3sxDvNb.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Typed outcomes for the V2 reservation boundary.
|
|
@@ -326,7 +326,10 @@ interface CreateJournalEntryInput {
|
|
|
326
326
|
userId: string;
|
|
327
327
|
entryType: "debit" | "credit";
|
|
328
328
|
amount: number;
|
|
329
|
+
/** `balance + bonusCredits` after this entry. */
|
|
329
330
|
balanceAfter: number;
|
|
331
|
+
/** `balance + bonusCredits` before this entry. */
|
|
332
|
+
balanceBefore?: number;
|
|
330
333
|
source: CreditSource;
|
|
331
334
|
referenceId: string;
|
|
332
335
|
referenceType: JournalReferenceType;
|
|
@@ -335,6 +338,18 @@ interface CreateJournalEntryInput {
|
|
|
335
338
|
/** Deterministic key making this entry unique per user (V2, optional). */
|
|
336
339
|
idempotencyKey?: string;
|
|
337
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* The journal entry of a one-shot deduct, written in the deduct's own atomic step.
|
|
343
|
+
*/
|
|
344
|
+
interface DeductJournalInput {
|
|
345
|
+
referenceId: string;
|
|
346
|
+
description: string;
|
|
347
|
+
/** Defaults to `"operation_commit"`. */
|
|
348
|
+
source?: CreditSource;
|
|
349
|
+
/** Defaults to `"adjustment"`. */
|
|
350
|
+
referenceType?: JournalReferenceType;
|
|
351
|
+
metadata?: Record<string, unknown>;
|
|
352
|
+
}
|
|
338
353
|
/**
|
|
339
354
|
* Query options for journal entries
|
|
340
355
|
*/
|
|
@@ -375,9 +390,43 @@ interface TierUpdateInput {
|
|
|
375
390
|
tier: SubscriptionTier;
|
|
376
391
|
monthlyLimit: number;
|
|
377
392
|
balance?: number;
|
|
393
|
+
/**
|
|
394
|
+
* Atomically lowers balance to at most this, only when the account's current tier is not free.
|
|
395
|
+
* Ignored for an account already free. Cannot be combined with `balance`.
|
|
396
|
+
* Like every balance reduction, it stops at the credits backing outstanding holds.
|
|
397
|
+
*/
|
|
398
|
+
balanceCap?: number;
|
|
378
399
|
monthlyUsed?: number;
|
|
379
400
|
subscriptionExpiresAt?: Date | string | null;
|
|
380
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* Free-tier policy an application hands to a repository, for the decisions that
|
|
404
|
+
* have to be made inside the write, from the account's current state.
|
|
405
|
+
*/
|
|
406
|
+
interface CreditPolicyOptions {
|
|
407
|
+
/**
|
|
408
|
+
* Decides a due monthly reset, inside the reset transaction, from the account's current state.
|
|
409
|
+
* null: no reset and no write (wasReset false, monthlyResetAt unchanged).
|
|
410
|
+
* Takes precedence over getMonthlyLimit. monthlyLimit is written only when returned.
|
|
411
|
+
* A throw aborts the transaction.
|
|
412
|
+
*
|
|
413
|
+
* Must be synchronous and free of side effects: a contended transaction runs it again.
|
|
414
|
+
* The balance is validated, and floored at the credits backing outstanding holds.
|
|
415
|
+
*/
|
|
416
|
+
resolveMonthlyReset?: (credits: {
|
|
417
|
+
tier: SubscriptionTier;
|
|
418
|
+
balance: number;
|
|
419
|
+
}) => {
|
|
420
|
+
balance: number;
|
|
421
|
+
monthlyLimit?: number;
|
|
422
|
+
} | null;
|
|
423
|
+
/**
|
|
424
|
+
* Balance cap and monthlyLimit on a subscription-expiry downgrade.
|
|
425
|
+
* Default: DEFAULT_FREE_CREDITS in the Firestore adapter, the default tier's
|
|
426
|
+
* configured limit in the in-memory adapter.
|
|
427
|
+
*/
|
|
428
|
+
getDowngradeBalanceCap?: () => number;
|
|
429
|
+
}
|
|
381
430
|
/**
|
|
382
431
|
* Optional journal customization for `addCreditsAtomic`.
|
|
383
432
|
*
|
|
@@ -522,9 +571,10 @@ interface ICreditRepository extends Partial<ICreditRepositoryV2>, Partial<ICredi
|
|
|
522
571
|
* @returns Combined totals (balance + bonusCredits) before and after.
|
|
523
572
|
* @throws If user has no credits doc or insufficient credits
|
|
524
573
|
*/
|
|
525
|
-
deductCreditsAtomic(userId: string, amount: number): Promise<{
|
|
574
|
+
deductCreditsAtomic(userId: string, amount: number, journal?: DeductJournalInput): Promise<{
|
|
526
575
|
previousBalance: number;
|
|
527
576
|
newBalance: number;
|
|
577
|
+
journalEntryId?: string;
|
|
528
578
|
}>;
|
|
529
579
|
/**
|
|
530
580
|
* Create a credit transaction *record* — no balance moves.
|
|
@@ -582,7 +632,8 @@ interface ICreditRepository extends Partial<ICreditRepositoryV2>, Partial<ICredi
|
|
|
582
632
|
* Uses optimistic locking to prevent race conditions
|
|
583
633
|
*
|
|
584
634
|
* @param userId - User ID
|
|
585
|
-
* @param tier -
|
|
635
|
+
* @param tier - The tier the caller last read. Not trusted: it may be stale by the
|
|
636
|
+
* time the write runs, so implementations must use the tier stored on the account.
|
|
586
637
|
* @param expectedResetAt - The expected monthlyResetAt value (for optimistic locking)
|
|
587
638
|
* @returns Result indicating whether reset was performed and updated credits
|
|
588
639
|
*/
|
|
@@ -643,4 +694,4 @@ declare function supportsIdempotentCredit(repository: ICreditRepository): reposi
|
|
|
643
694
|
*/
|
|
644
695
|
declare function toClientUserCredits(credits: PortableUserCredits): PortableUserCredits;
|
|
645
696
|
|
|
646
|
-
export { type AddCreditsAtomicOptions as A, type CommitOutcome as C, type ExpireOutcome as E, type ICreditRepository as I, type JournalEntryQuery as J, type ReleaseOutcome as R, type TerminalReservationStatus as T, type UsageLogQuery as U, type AddCreditsOutcome as a, type AddCreditsV2Input as b, type CreateJournalEntryInput as c, type CreateReservationInput as d, type CreateTransactionInput as e, type CreateUsageLogInput as f, type CreditBalanceUpdate as g, type
|
|
697
|
+
export { type AddCreditsAtomicOptions as A, type CommitOutcome as C, type DeductJournalInput as D, type ExpireOutcome as E, type ICreditRepository as I, type JournalEntryQuery as J, type ReleaseOutcome as R, type TerminalReservationStatus as T, type UsageLogQuery as U, type AddCreditsOutcome as a, type AddCreditsV2Input as b, type CreateJournalEntryInput as c, type CreateReservationInput as d, type CreateTransactionInput as e, type CreateUsageLogInput as f, type CreditBalanceUpdate as g, type CreditPolicyOptions as h, type CreditRepositoryFactory as i, type ExpireReservationV2Options as j, type ICreditRepositoryCreditsV2 as k, type ICreditRepositoryV2 as l, type ReservationTransitionOptions as m, type ReserveCreditsV2Input as n, type ReserveOutcome as o, type TierUpdateInput as p, isCreditedOutcome as q, isReservedOutcome as r, isWinningOutcome as s, reservationJournalKey as t, supportsCreditsV2 as u, supportsIdempotentCredit as v, toClientUserCredits as w };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as PortableTransaction, a as PortableReservation, R as ReservationStatus, C as CreditOperationType, b as CreditSource, J as JournalReferenceType, A as AIProviderType, S as SubscriptionTier, c as PortableUserCredits, d as PortableUsageLog, M as MonthlyResetResult, e as SubscriptionExpiryResult, f as PortableJournalEntry } from './types-
|
|
1
|
+
import { P as PortableTransaction, a as PortableReservation, R as ReservationStatus, C as CreditOperationType, b as CreditSource, J as JournalReferenceType, A as AIProviderType, S as SubscriptionTier, c as PortableUserCredits, d as PortableUsageLog, M as MonthlyResetResult, e as SubscriptionExpiryResult, f as PortableJournalEntry } from './types-C3sxDvNb.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Typed outcomes for the V2 reservation boundary.
|
|
@@ -326,7 +326,10 @@ interface CreateJournalEntryInput {
|
|
|
326
326
|
userId: string;
|
|
327
327
|
entryType: "debit" | "credit";
|
|
328
328
|
amount: number;
|
|
329
|
+
/** `balance + bonusCredits` after this entry. */
|
|
329
330
|
balanceAfter: number;
|
|
331
|
+
/** `balance + bonusCredits` before this entry. */
|
|
332
|
+
balanceBefore?: number;
|
|
330
333
|
source: CreditSource;
|
|
331
334
|
referenceId: string;
|
|
332
335
|
referenceType: JournalReferenceType;
|
|
@@ -335,6 +338,18 @@ interface CreateJournalEntryInput {
|
|
|
335
338
|
/** Deterministic key making this entry unique per user (V2, optional). */
|
|
336
339
|
idempotencyKey?: string;
|
|
337
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* The journal entry of a one-shot deduct, written in the deduct's own atomic step.
|
|
343
|
+
*/
|
|
344
|
+
interface DeductJournalInput {
|
|
345
|
+
referenceId: string;
|
|
346
|
+
description: string;
|
|
347
|
+
/** Defaults to `"operation_commit"`. */
|
|
348
|
+
source?: CreditSource;
|
|
349
|
+
/** Defaults to `"adjustment"`. */
|
|
350
|
+
referenceType?: JournalReferenceType;
|
|
351
|
+
metadata?: Record<string, unknown>;
|
|
352
|
+
}
|
|
338
353
|
/**
|
|
339
354
|
* Query options for journal entries
|
|
340
355
|
*/
|
|
@@ -375,9 +390,43 @@ interface TierUpdateInput {
|
|
|
375
390
|
tier: SubscriptionTier;
|
|
376
391
|
monthlyLimit: number;
|
|
377
392
|
balance?: number;
|
|
393
|
+
/**
|
|
394
|
+
* Atomically lowers balance to at most this, only when the account's current tier is not free.
|
|
395
|
+
* Ignored for an account already free. Cannot be combined with `balance`.
|
|
396
|
+
* Like every balance reduction, it stops at the credits backing outstanding holds.
|
|
397
|
+
*/
|
|
398
|
+
balanceCap?: number;
|
|
378
399
|
monthlyUsed?: number;
|
|
379
400
|
subscriptionExpiresAt?: Date | string | null;
|
|
380
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* Free-tier policy an application hands to a repository, for the decisions that
|
|
404
|
+
* have to be made inside the write, from the account's current state.
|
|
405
|
+
*/
|
|
406
|
+
interface CreditPolicyOptions {
|
|
407
|
+
/**
|
|
408
|
+
* Decides a due monthly reset, inside the reset transaction, from the account's current state.
|
|
409
|
+
* null: no reset and no write (wasReset false, monthlyResetAt unchanged).
|
|
410
|
+
* Takes precedence over getMonthlyLimit. monthlyLimit is written only when returned.
|
|
411
|
+
* A throw aborts the transaction.
|
|
412
|
+
*
|
|
413
|
+
* Must be synchronous and free of side effects: a contended transaction runs it again.
|
|
414
|
+
* The balance is validated, and floored at the credits backing outstanding holds.
|
|
415
|
+
*/
|
|
416
|
+
resolveMonthlyReset?: (credits: {
|
|
417
|
+
tier: SubscriptionTier;
|
|
418
|
+
balance: number;
|
|
419
|
+
}) => {
|
|
420
|
+
balance: number;
|
|
421
|
+
monthlyLimit?: number;
|
|
422
|
+
} | null;
|
|
423
|
+
/**
|
|
424
|
+
* Balance cap and monthlyLimit on a subscription-expiry downgrade.
|
|
425
|
+
* Default: DEFAULT_FREE_CREDITS in the Firestore adapter, the default tier's
|
|
426
|
+
* configured limit in the in-memory adapter.
|
|
427
|
+
*/
|
|
428
|
+
getDowngradeBalanceCap?: () => number;
|
|
429
|
+
}
|
|
381
430
|
/**
|
|
382
431
|
* Optional journal customization for `addCreditsAtomic`.
|
|
383
432
|
*
|
|
@@ -522,9 +571,10 @@ interface ICreditRepository extends Partial<ICreditRepositoryV2>, Partial<ICredi
|
|
|
522
571
|
* @returns Combined totals (balance + bonusCredits) before and after.
|
|
523
572
|
* @throws If user has no credits doc or insufficient credits
|
|
524
573
|
*/
|
|
525
|
-
deductCreditsAtomic(userId: string, amount: number): Promise<{
|
|
574
|
+
deductCreditsAtomic(userId: string, amount: number, journal?: DeductJournalInput): Promise<{
|
|
526
575
|
previousBalance: number;
|
|
527
576
|
newBalance: number;
|
|
577
|
+
journalEntryId?: string;
|
|
528
578
|
}>;
|
|
529
579
|
/**
|
|
530
580
|
* Create a credit transaction *record* — no balance moves.
|
|
@@ -582,7 +632,8 @@ interface ICreditRepository extends Partial<ICreditRepositoryV2>, Partial<ICredi
|
|
|
582
632
|
* Uses optimistic locking to prevent race conditions
|
|
583
633
|
*
|
|
584
634
|
* @param userId - User ID
|
|
585
|
-
* @param tier -
|
|
635
|
+
* @param tier - The tier the caller last read. Not trusted: it may be stale by the
|
|
636
|
+
* time the write runs, so implementations must use the tier stored on the account.
|
|
586
637
|
* @param expectedResetAt - The expected monthlyResetAt value (for optimistic locking)
|
|
587
638
|
* @returns Result indicating whether reset was performed and updated credits
|
|
588
639
|
*/
|
|
@@ -643,4 +694,4 @@ declare function supportsIdempotentCredit(repository: ICreditRepository): reposi
|
|
|
643
694
|
*/
|
|
644
695
|
declare function toClientUserCredits(credits: PortableUserCredits): PortableUserCredits;
|
|
645
696
|
|
|
646
|
-
export { type AddCreditsAtomicOptions as A, type CommitOutcome as C, type ExpireOutcome as E, type ICreditRepository as I, type JournalEntryQuery as J, type ReleaseOutcome as R, type TerminalReservationStatus as T, type UsageLogQuery as U, type AddCreditsOutcome as a, type AddCreditsV2Input as b, type CreateJournalEntryInput as c, type CreateReservationInput as d, type CreateTransactionInput as e, type CreateUsageLogInput as f, type CreditBalanceUpdate as g, type
|
|
697
|
+
export { type AddCreditsAtomicOptions as A, type CommitOutcome as C, type DeductJournalInput as D, type ExpireOutcome as E, type ICreditRepository as I, type JournalEntryQuery as J, type ReleaseOutcome as R, type TerminalReservationStatus as T, type UsageLogQuery as U, type AddCreditsOutcome as a, type AddCreditsV2Input as b, type CreateJournalEntryInput as c, type CreateReservationInput as d, type CreateTransactionInput as e, type CreateUsageLogInput as f, type CreditBalanceUpdate as g, type CreditPolicyOptions as h, type CreditRepositoryFactory as i, type ExpireReservationV2Options as j, type ICreditRepositoryCreditsV2 as k, type ICreditRepositoryV2 as l, type ReservationTransitionOptions as m, type ReserveCreditsV2Input as n, type ReserveOutcome as o, type TierUpdateInput as p, isCreditedOutcome as q, isReservedOutcome as r, isWinningOutcome as s, reservationJournalKey as t, supportsCreditsV2 as u, supportsIdempotentCredit as v, toClientUserCredits as w };
|
package/package.json
CHANGED
|
@@ -1,71 +1,70 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@nehorai/credits",
|
|
3
|
-
"version": "
|
|
4
|
-
"type": "module",
|
|
5
|
-
"main": "./dist/index.cjs",
|
|
6
|
-
"module": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./dist/index.d.ts",
|
|
11
|
-
"import": "./dist/index.js",
|
|
12
|
-
"require": "./dist/index.cjs"
|
|
13
|
-
},
|
|
14
|
-
"./core": {
|
|
15
|
-
"types": "./dist/core/index.d.ts",
|
|
16
|
-
"import": "./dist/core/index.js",
|
|
17
|
-
"require": "./dist/core/index.cjs"
|
|
18
|
-
},
|
|
19
|
-
"./repository": {
|
|
20
|
-
"types": "./dist/repository/index.d.ts",
|
|
21
|
-
"import": "./dist/repository/index.js",
|
|
22
|
-
"require": "./dist/repository/index.cjs"
|
|
23
|
-
},
|
|
24
|
-
"./auth": {
|
|
25
|
-
"types": "./dist/auth/index.d.ts",
|
|
26
|
-
"import": "./dist/auth/index.js",
|
|
27
|
-
"require": "./dist/auth/index.cjs"
|
|
28
|
-
},
|
|
29
|
-
"./service": {
|
|
30
|
-
"types": "./dist/service/index.d.ts",
|
|
31
|
-
"import": "./dist/service/index.js",
|
|
32
|
-
"require": "./dist/service/index.cjs"
|
|
33
|
-
},
|
|
34
|
-
"./adapters": {
|
|
35
|
-
"types": "./dist/adapters/index.d.ts",
|
|
36
|
-
"import": "./dist/adapters/index.js",
|
|
37
|
-
"require": "./dist/adapters/index.cjs"
|
|
38
|
-
},
|
|
39
|
-
"./sdk": {
|
|
40
|
-
"types": "./dist/sdk/index.d.ts",
|
|
41
|
-
"import": "./dist/sdk/index.js",
|
|
42
|
-
"require": "./dist/sdk/index.cjs"
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
"files": [
|
|
46
|
-
"dist"
|
|
47
|
-
],
|
|
48
|
-
"license": "MIT",
|
|
49
|
-
"author": "Nehorai Hadad",
|
|
50
|
-
"repository": {
|
|
51
|
-
"type": "git",
|
|
52
|
-
"url": "https://github.com/NehoraiHadad/nehorai-plugins",
|
|
53
|
-
"directory": "packages/credits"
|
|
54
|
-
},
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
},
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@nehorai/credits",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
},
|
|
14
|
+
"./core": {
|
|
15
|
+
"types": "./dist/core/index.d.ts",
|
|
16
|
+
"import": "./dist/core/index.js",
|
|
17
|
+
"require": "./dist/core/index.cjs"
|
|
18
|
+
},
|
|
19
|
+
"./repository": {
|
|
20
|
+
"types": "./dist/repository/index.d.ts",
|
|
21
|
+
"import": "./dist/repository/index.js",
|
|
22
|
+
"require": "./dist/repository/index.cjs"
|
|
23
|
+
},
|
|
24
|
+
"./auth": {
|
|
25
|
+
"types": "./dist/auth/index.d.ts",
|
|
26
|
+
"import": "./dist/auth/index.js",
|
|
27
|
+
"require": "./dist/auth/index.cjs"
|
|
28
|
+
},
|
|
29
|
+
"./service": {
|
|
30
|
+
"types": "./dist/service/index.d.ts",
|
|
31
|
+
"import": "./dist/service/index.js",
|
|
32
|
+
"require": "./dist/service/index.cjs"
|
|
33
|
+
},
|
|
34
|
+
"./adapters": {
|
|
35
|
+
"types": "./dist/adapters/index.d.ts",
|
|
36
|
+
"import": "./dist/adapters/index.js",
|
|
37
|
+
"require": "./dist/adapters/index.cjs"
|
|
38
|
+
},
|
|
39
|
+
"./sdk": {
|
|
40
|
+
"types": "./dist/sdk/index.d.ts",
|
|
41
|
+
"import": "./dist/sdk/index.js",
|
|
42
|
+
"require": "./dist/sdk/index.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"dist"
|
|
47
|
+
],
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"author": "Nehorai Hadad",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/NehoraiHadad/nehorai-plugins",
|
|
53
|
+
"directory": "packages/credits"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"zod": "^3.24.2"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"typescript": "^5.7.3",
|
|
60
|
+
"vitest": "^3.0.5",
|
|
61
|
+
"@types/node": "^22.13.4"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsup",
|
|
65
|
+
"dev": "tsup --watch",
|
|
66
|
+
"typecheck": "tsc --noEmit",
|
|
67
|
+
"test": "vitest run",
|
|
68
|
+
"test:watch": "vitest"
|
|
69
|
+
}
|
|
70
|
+
}
|