@nehorai/credits 1.6.0 → 2.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/README.md +226 -2
- package/dist/adapters/index.cjs +298 -40
- 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 +298 -40
- package/dist/adapters/index.js.map +1 -1
- package/dist/core/index.cjs +696 -74
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +583 -5
- package/dist/core/index.d.ts +583 -5
- package/dist/core/index.js +648 -74
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +1779 -364
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -6
- package/dist/index.d.ts +41 -6
- package/dist/index.js +1723 -364
- package/dist/index.js.map +1 -1
- package/dist/repository/index.cjs +1413 -181
- package/dist/repository/index.cjs.map +1 -1
- package/dist/repository/index.d.cts +142 -16
- package/dist/repository/index.d.ts +142 -16
- package/dist/repository/index.js +1406 -181
- package/dist/repository/index.js.map +1 -1
- package/dist/sdk/index.cjs +23 -1
- 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 +23 -1
- package/dist/sdk/index.js.map +1 -1
- package/dist/service/index.cjs +483 -105
- package/dist/service/index.cjs.map +1 -1
- package/dist/service/index.d.cts +70 -10
- package/dist/service/index.d.ts +70 -10
- package/dist/service/index.js +483 -105
- package/dist/service/index.js.map +1 -1
- package/dist/types-BmG5Omzj.d.ts +646 -0
- package/dist/types-C8hZMe8a.d.cts +646 -0
- package/dist/{types-CjLj3GW5.d.cts → types-DJ8yqaVr.d.cts} +39 -1
- package/dist/{types-CjLj3GW5.d.ts → types-DJ8yqaVr.d.ts} +39 -1
- package/package.json +9 -10
- package/dist/types-CZNv1U3e.d.cts +0 -305
- package/dist/types-G4WK0rM-.d.ts +0 -305
package/dist/service/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { I as ICreditRepository, J as JournalEntryQuery } from '../types-
|
|
1
|
+
import { c as PortableUserCredits, g as CreditCheckResult, C as CreditOperationType, a as PortableReservation, d as PortableUsageLog, D as DeductCreditsResult, S as SubscriptionTier, j as UsageHistoryResponse, f as PortableJournalEntry } from '../types-DJ8yqaVr.cjs';
|
|
2
|
+
import { I as ICreditRepository, n as ReserveOutcome, l as ReservationTransitionOptions, C as CommitOutcome, R as ReleaseOutcome, A as AddCreditsAtomicOptions, a as AddCreditsOutcome, J as JournalEntryQuery } from '../types-C8hZMe8a.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Notification callback type for low balance notifications
|
|
@@ -22,6 +22,20 @@ interface ReserveCreditsOptions {
|
|
|
22
22
|
* legitimately in flight.
|
|
23
23
|
*/
|
|
24
24
|
ttlMs?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Caller-supplied idempotency key, unique per user.
|
|
27
|
+
*
|
|
28
|
+
* Retrying a reserve with the same key and the same amount/operation returns
|
|
29
|
+
* the original reservation instead of placing a second hold — the fix for a
|
|
30
|
+
* webhook or job runner delivering the same request twice. Reusing a key
|
|
31
|
+
* with a *different* amount or operation is a
|
|
32
|
+
* `CreditErrorCode.IDEMPOTENCY_CONFLICT`.
|
|
33
|
+
*
|
|
34
|
+
* Requires a repository implementing the V2 boundary (see
|
|
35
|
+
* `supportsCreditsV2`). A legacy adapter has no unique index to enforce the
|
|
36
|
+
* key, so it is ignored there rather than silently promised.
|
|
37
|
+
*/
|
|
38
|
+
idempotencyKey?: string;
|
|
25
39
|
}
|
|
26
40
|
/**
|
|
27
41
|
* Options for a one-shot atomic credit deduction via `deductCredits`.
|
|
@@ -103,16 +117,55 @@ declare class CreditsService {
|
|
|
103
117
|
*/
|
|
104
118
|
reserveCredits(userId: string, amount: number, operationType: CreditOperationType, options?: ReserveCreditsOptions): Promise<PortableReservation>;
|
|
105
119
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
120
|
+
* Reserve credits and get the typed outcome instead of an exception.
|
|
121
|
+
*
|
|
122
|
+
* Prefer this over {@link reserveCredits} in async callers: it distinguishes
|
|
123
|
+
* a fresh hold from an idempotent replay, and reports insufficient funds as
|
|
124
|
+
* a value rather than as control flow.
|
|
125
|
+
*/
|
|
126
|
+
reserveCreditsDetailed(userId: string, amount: number, operationType: CreditOperationType, options?: ReserveCreditsOptions): Promise<ReserveOutcome>;
|
|
127
|
+
/**
|
|
128
|
+
* Commit a reservation (phase 2 of two-phase commit - success).
|
|
129
|
+
*
|
|
130
|
+
* Idempotent: re-delivering a commit for an already-committed reservation is
|
|
131
|
+
* a no-op. Committing one that was released or expired throws, because the
|
|
132
|
+
* credits are no longer held and pretending otherwise would hide a real bug.
|
|
109
133
|
*/
|
|
110
|
-
commitCredits(userId: string, reservationId: string): Promise<void>;
|
|
134
|
+
commitCredits(userId: string, reservationId: string, options?: ReservationTransitionOptions): Promise<void>;
|
|
111
135
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
136
|
+
* Commit a reservation and get the typed outcome.
|
|
137
|
+
*
|
|
138
|
+
* Exactly one concurrent caller sees `committed`; that call moved the balance
|
|
139
|
+
* and wrote the single journal entry. On a V2 repository the journal is
|
|
140
|
+
* written inside the same transaction, so this method adds none of its own —
|
|
141
|
+
* the duplicate entry the previous implementation wrote is gone.
|
|
142
|
+
*
|
|
143
|
+
* The low-balance notification fires only for the winner, and only after the
|
|
144
|
+
* transaction has committed, so no callback runs inside a database
|
|
145
|
+
* transaction.
|
|
146
|
+
*/
|
|
147
|
+
commitCreditsDetailed(userId: string, reservationId: string, options?: ReservationTransitionOptions): Promise<CommitOutcome>;
|
|
148
|
+
/**
|
|
149
|
+
* Release a reservation (phase 2 of two-phase commit - failure).
|
|
150
|
+
*
|
|
151
|
+
* Throws `RESERVATION_NOT_FOUND` for an unknown reservation, matching the
|
|
152
|
+
* pre-V2 behaviour — a release naming a reservation that does not exist is a
|
|
153
|
+
* caller bug, and swallowing it hides the bug while the credits stay held.
|
|
154
|
+
*
|
|
155
|
+
* Releasing one that is already terminal — `released`, `expired`, or
|
|
156
|
+
* `committed` — is a no-op, which is the behaviour this method has always
|
|
157
|
+
* had. A release that loses a race to a concurrent commit is the common
|
|
158
|
+
* case in a retry-heavy caller, and callers written against the pre-V2
|
|
159
|
+
* contract handle it by not handling it.
|
|
160
|
+
*
|
|
161
|
+
* That does mean this method cannot tell you that the credits were spent
|
|
162
|
+
* rather than returned. Use {@link releaseCreditsDetailed}, which reports
|
|
163
|
+
* `already_terminal` with `terminalStatus: 'committed'`, when you need to
|
|
164
|
+
* branch on it.
|
|
114
165
|
*/
|
|
115
|
-
releaseCredits(userId: string, reservationId: string): Promise<void>;
|
|
166
|
+
releaseCredits(userId: string, reservationId: string, options?: ReservationTransitionOptions): Promise<void>;
|
|
167
|
+
/** Release a reservation and get the typed outcome. */
|
|
168
|
+
releaseCreditsDetailed(userId: string, reservationId: string, options?: ReservationTransitionOptions): Promise<ReleaseOutcome>;
|
|
116
169
|
/**
|
|
117
170
|
* Log usage for audit trail
|
|
118
171
|
* @param log - Usage log data
|
|
@@ -124,8 +177,15 @@ declare class CreditsService {
|
|
|
124
177
|
* @param amount - Credits to add
|
|
125
178
|
* @param description - Transaction description
|
|
126
179
|
* @param paymentRef - Optional payment reference
|
|
180
|
+
* @param options - Optional journal source / reference type / extra metadata
|
|
181
|
+
* for the credit journal entry (e.g. revenue-attribution fields).
|
|
182
|
+
* @returns Whether this delivery credited the account (`created`), repeated an
|
|
183
|
+
* earlier one (`replayed`), or reused the reference for a different credit
|
|
184
|
+
* event (`conflict`, which credited nothing). On a repository without
|
|
185
|
+
* `addCreditsV2` the result is always `created` and carries no
|
|
186
|
+
* deduplication guarantee — see {@link addCreditsThroughRepository}.
|
|
127
187
|
*/
|
|
128
|
-
addCredits(userId: string, amount: number, description: string, paymentRef?: string): Promise<
|
|
188
|
+
addCredits(userId: string, amount: number, description: string, paymentRef?: string, options?: AddCreditsAtomicOptions): Promise<AddCreditsOutcome>;
|
|
129
189
|
/**
|
|
130
190
|
* One-shot atomic "deduct-if-sufficient" credit charge.
|
|
131
191
|
*
|
package/dist/service/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { I as ICreditRepository, J as JournalEntryQuery } from '../types-
|
|
1
|
+
import { c as PortableUserCredits, g as CreditCheckResult, C as CreditOperationType, a as PortableReservation, d as PortableUsageLog, D as DeductCreditsResult, S as SubscriptionTier, j as UsageHistoryResponse, f as PortableJournalEntry } from '../types-DJ8yqaVr.js';
|
|
2
|
+
import { I as ICreditRepository, n as ReserveOutcome, l as ReservationTransitionOptions, C as CommitOutcome, R as ReleaseOutcome, A as AddCreditsAtomicOptions, a as AddCreditsOutcome, J as JournalEntryQuery } from '../types-BmG5Omzj.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Notification callback type for low balance notifications
|
|
@@ -22,6 +22,20 @@ interface ReserveCreditsOptions {
|
|
|
22
22
|
* legitimately in flight.
|
|
23
23
|
*/
|
|
24
24
|
ttlMs?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Caller-supplied idempotency key, unique per user.
|
|
27
|
+
*
|
|
28
|
+
* Retrying a reserve with the same key and the same amount/operation returns
|
|
29
|
+
* the original reservation instead of placing a second hold — the fix for a
|
|
30
|
+
* webhook or job runner delivering the same request twice. Reusing a key
|
|
31
|
+
* with a *different* amount or operation is a
|
|
32
|
+
* `CreditErrorCode.IDEMPOTENCY_CONFLICT`.
|
|
33
|
+
*
|
|
34
|
+
* Requires a repository implementing the V2 boundary (see
|
|
35
|
+
* `supportsCreditsV2`). A legacy adapter has no unique index to enforce the
|
|
36
|
+
* key, so it is ignored there rather than silently promised.
|
|
37
|
+
*/
|
|
38
|
+
idempotencyKey?: string;
|
|
25
39
|
}
|
|
26
40
|
/**
|
|
27
41
|
* Options for a one-shot atomic credit deduction via `deductCredits`.
|
|
@@ -103,16 +117,55 @@ declare class CreditsService {
|
|
|
103
117
|
*/
|
|
104
118
|
reserveCredits(userId: string, amount: number, operationType: CreditOperationType, options?: ReserveCreditsOptions): Promise<PortableReservation>;
|
|
105
119
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
120
|
+
* Reserve credits and get the typed outcome instead of an exception.
|
|
121
|
+
*
|
|
122
|
+
* Prefer this over {@link reserveCredits} in async callers: it distinguishes
|
|
123
|
+
* a fresh hold from an idempotent replay, and reports insufficient funds as
|
|
124
|
+
* a value rather than as control flow.
|
|
125
|
+
*/
|
|
126
|
+
reserveCreditsDetailed(userId: string, amount: number, operationType: CreditOperationType, options?: ReserveCreditsOptions): Promise<ReserveOutcome>;
|
|
127
|
+
/**
|
|
128
|
+
* Commit a reservation (phase 2 of two-phase commit - success).
|
|
129
|
+
*
|
|
130
|
+
* Idempotent: re-delivering a commit for an already-committed reservation is
|
|
131
|
+
* a no-op. Committing one that was released or expired throws, because the
|
|
132
|
+
* credits are no longer held and pretending otherwise would hide a real bug.
|
|
109
133
|
*/
|
|
110
|
-
commitCredits(userId: string, reservationId: string): Promise<void>;
|
|
134
|
+
commitCredits(userId: string, reservationId: string, options?: ReservationTransitionOptions): Promise<void>;
|
|
111
135
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
136
|
+
* Commit a reservation and get the typed outcome.
|
|
137
|
+
*
|
|
138
|
+
* Exactly one concurrent caller sees `committed`; that call moved the balance
|
|
139
|
+
* and wrote the single journal entry. On a V2 repository the journal is
|
|
140
|
+
* written inside the same transaction, so this method adds none of its own —
|
|
141
|
+
* the duplicate entry the previous implementation wrote is gone.
|
|
142
|
+
*
|
|
143
|
+
* The low-balance notification fires only for the winner, and only after the
|
|
144
|
+
* transaction has committed, so no callback runs inside a database
|
|
145
|
+
* transaction.
|
|
146
|
+
*/
|
|
147
|
+
commitCreditsDetailed(userId: string, reservationId: string, options?: ReservationTransitionOptions): Promise<CommitOutcome>;
|
|
148
|
+
/**
|
|
149
|
+
* Release a reservation (phase 2 of two-phase commit - failure).
|
|
150
|
+
*
|
|
151
|
+
* Throws `RESERVATION_NOT_FOUND` for an unknown reservation, matching the
|
|
152
|
+
* pre-V2 behaviour — a release naming a reservation that does not exist is a
|
|
153
|
+
* caller bug, and swallowing it hides the bug while the credits stay held.
|
|
154
|
+
*
|
|
155
|
+
* Releasing one that is already terminal — `released`, `expired`, or
|
|
156
|
+
* `committed` — is a no-op, which is the behaviour this method has always
|
|
157
|
+
* had. A release that loses a race to a concurrent commit is the common
|
|
158
|
+
* case in a retry-heavy caller, and callers written against the pre-V2
|
|
159
|
+
* contract handle it by not handling it.
|
|
160
|
+
*
|
|
161
|
+
* That does mean this method cannot tell you that the credits were spent
|
|
162
|
+
* rather than returned. Use {@link releaseCreditsDetailed}, which reports
|
|
163
|
+
* `already_terminal` with `terminalStatus: 'committed'`, when you need to
|
|
164
|
+
* branch on it.
|
|
114
165
|
*/
|
|
115
|
-
releaseCredits(userId: string, reservationId: string): Promise<void>;
|
|
166
|
+
releaseCredits(userId: string, reservationId: string, options?: ReservationTransitionOptions): Promise<void>;
|
|
167
|
+
/** Release a reservation and get the typed outcome. */
|
|
168
|
+
releaseCreditsDetailed(userId: string, reservationId: string, options?: ReservationTransitionOptions): Promise<ReleaseOutcome>;
|
|
116
169
|
/**
|
|
117
170
|
* Log usage for audit trail
|
|
118
171
|
* @param log - Usage log data
|
|
@@ -124,8 +177,15 @@ declare class CreditsService {
|
|
|
124
177
|
* @param amount - Credits to add
|
|
125
178
|
* @param description - Transaction description
|
|
126
179
|
* @param paymentRef - Optional payment reference
|
|
180
|
+
* @param options - Optional journal source / reference type / extra metadata
|
|
181
|
+
* for the credit journal entry (e.g. revenue-attribution fields).
|
|
182
|
+
* @returns Whether this delivery credited the account (`created`), repeated an
|
|
183
|
+
* earlier one (`replayed`), or reused the reference for a different credit
|
|
184
|
+
* event (`conflict`, which credited nothing). On a repository without
|
|
185
|
+
* `addCreditsV2` the result is always `created` and carries no
|
|
186
|
+
* deduplication guarantee — see {@link addCreditsThroughRepository}.
|
|
127
187
|
*/
|
|
128
|
-
addCredits(userId: string, amount: number, description: string, paymentRef?: string): Promise<
|
|
188
|
+
addCredits(userId: string, amount: number, description: string, paymentRef?: string, options?: AddCreditsAtomicOptions): Promise<AddCreditsOutcome>;
|
|
129
189
|
/**
|
|
130
190
|
* One-shot atomic "deduct-if-sufficient" credit charge.
|
|
131
191
|
*
|