@nehorai/credits 1.4.0 → 1.6.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/dist/adapters/index.cjs +13 -3
- 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 +13 -3
- package/dist/adapters/index.js.map +1 -1
- package/dist/core/index.cjs +13 -3
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +3 -3
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +13 -3
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +155 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -16
- package/dist/index.d.ts +75 -16
- package/dist/index.js +146 -17
- package/dist/index.js.map +1 -1
- package/dist/repository/index.cjs +47 -11
- package/dist/repository/index.cjs.map +1 -1
- package/dist/repository/index.d.cts +3 -3
- package/dist/repository/index.d.ts +3 -3
- package/dist/repository/index.js +47 -11
- package/dist/repository/index.js.map +1 -1
- package/dist/sdk/index.d.cts +2 -2
- package/dist/sdk/index.d.ts +2 -2
- package/dist/service/index.cjs +130 -10
- package/dist/service/index.cjs.map +1 -1
- package/dist/service/index.d.cts +43 -3
- package/dist/service/index.d.ts +43 -3
- package/dist/service/index.js +130 -10
- package/dist/service/index.js.map +1 -1
- package/dist/{types-D1vdeBcA.d.cts → types-CZNv1U3e.d.cts} +1 -1
- package/dist/{types-BBxIWHK2.d.cts → types-CjLj3GW5.d.cts} +37 -3
- package/dist/{types-BBxIWHK2.d.ts → types-CjLj3GW5.d.ts} +37 -3
- package/dist/{types-aJsyv8df.d.ts → types-G4WK0rM-.d.ts} +1 -1
- package/package.json +10 -9
- package/LICENSE +0 -21
package/dist/index.d.cts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { S as SubscriptionTier, T as TierConfig, c as PortableReservation } from './types-
|
|
2
|
-
export { A as AIProviderType, g as CreditCheckResult, a as CreditOperationType, C as CreditSource, J as JournalReferenceType, M as MonthlyResetResult, f as PortableJournalEntry, P as PortableTransaction, d as PortableUsageLog, b as PortableUserCredits, R as ReservationStatus, h as ResourceType, g as SDKCreditCheckResult, e as SubscriptionExpiryResult, i as TransactionType, U as UsageHistoryEntry, j as UsageHistoryResponse, b as UserCredits, W as WithCreditsOptions, k as calculateAvailableCredits, t as toDate, l as toPortableTimestamp } from './types-
|
|
1
|
+
import { S as SubscriptionTier, T as TierConfig, c as PortableReservation } from './types-CjLj3GW5.cjs';
|
|
2
|
+
export { A as AIProviderType, B as BuiltinTier, g as CreditCheckResult, a as CreditOperationType, C as CreditSource, D as DeductCreditsResult, J as JournalReferenceType, M as MonthlyResetResult, f as PortableJournalEntry, P as PortableTransaction, d as PortableUsageLog, b as PortableUserCredits, R as ReservationStatus, h as ResourceType, g as SDKCreditCheckResult, e as SubscriptionExpiryResult, i as TransactionType, U as UsageHistoryEntry, j as UsageHistoryResponse, b as UserCredits, W as WithCreditsOptions, k as calculateAvailableCredits, t as toDate, l as toPortableTimestamp } from './types-CjLj3GW5.cjs';
|
|
3
3
|
export { CreditError, CreditErrorCode, CreditErrorCodeType, commitReservationWithJournal, createInsufficientCreditsError, createInvalidOperationTypeError, createReservationAlreadyProcessedError, createReservationExpiredError, createReservationNotFoundError, createUserNotFoundError, isCreditError, isInsufficientCreditsError, releaseReservationWithJournal, reserveCreditsForOperation } from './core/index.cjs';
|
|
4
4
|
export { D as DeferredExecutor, c as createDeferredExecutor, g as genericDeferred, n as noopDeferred, s as synchronousDeferred } from './deferred-C7rrRfkm.cjs';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
export { C as CreateJournalEntryInput, a as CreateReservationInput, b as CreateTransactionInput, c as CreateUsageLogInput, d as CreditBalanceUpdate, e as CreditRepositoryFactory, I as ICreditRepository, J as JournalEntryQuery, T as TierUpdateInput, U as UsageLogQuery, t as toClientUserCredits } from './types-
|
|
6
|
+
export { C as CreateJournalEntryInput, a as CreateReservationInput, b as CreateTransactionInput, c as CreateUsageLogInput, d as CreditBalanceUpdate, e as CreditRepositoryFactory, I as ICreditRepository, J as JournalEntryQuery, T as TierUpdateInput, U as UsageLogQuery, t as toClientUserCredits } from './types-CZNv1U3e.cjs';
|
|
7
7
|
export { InMemoryCreditRepository, createInMemoryCreditRepository, generateId, getNextMonthlyReset } from './repository/index.cjs';
|
|
8
8
|
export { C as CreditsAuthProviderFactory, a as CreditsUser, I as ICreditsAuthProvider } from './types-OZU3I5OM.cjs';
|
|
9
9
|
export { ApiKeyCreditsProvider, createApiKeyProvider, verifyAdminApiKey, verifyBearerToken } from './auth/index.cjs';
|
|
10
|
-
export { CreditsService, LowBalanceNotificationCallback, SubscriptionExpiredNotificationCallback, createCreditsService } from './service/index.cjs';
|
|
10
|
+
export { CreditsService, DeductCreditsOptions, LowBalanceNotificationCallback, ReserveCreditsOptions, SubscriptionExpiredNotificationCallback, createCreditsService } from './service/index.cjs';
|
|
11
11
|
export { ActionResult, CreditActionHandler, CreditsAdapter, CreditsAdapterConfig, createGenericAdapter } from './adapters/index.cjs';
|
|
12
12
|
export { AdminCreditsClient, AdminCreditsClientConfig, ApiResponse, AuthenticationError, AuthorizationError, CreditsClient, CreditsClientConfig, CreditsConfig, CreditsSDKError, ListUsersOptions, ListUsersResponse, NetworkError, PaginationOptions, ReservationResult, SDKErrorCode, SDKErrorCodeType, InsufficientCreditsError as SDKInsufficientCreditsError, ReservationExpiredError as SDKReservationExpiredError, ReservationNotFoundError as SDKReservationNotFoundError, UsageHistoryEntry as SDKUsageHistoryEntry, UsageHistoryResponse as SDKUsageHistoryResponse, ServerError, ValidationError, parseApiError } from './sdk/index.cjs';
|
|
13
13
|
|
|
@@ -29,21 +29,30 @@ declare const creditSystemConfigSchema: z.ZodObject<{
|
|
|
29
29
|
/**
|
|
30
30
|
* Tier configurations
|
|
31
31
|
*/
|
|
32
|
-
tierConfigs: z.ZodRecord<z.
|
|
33
|
-
tier: z.
|
|
32
|
+
tierConfigs: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
33
|
+
tier: z.ZodString;
|
|
34
34
|
monthlyCredits: z.ZodNumber;
|
|
35
35
|
priceUsd: z.ZodNumber;
|
|
36
36
|
features: z.ZodArray<z.ZodString, "many">;
|
|
37
|
+
isFree: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
39
|
+
isDefault: z.ZodOptional<z.ZodBoolean>;
|
|
37
40
|
}, "strip", z.ZodTypeAny, {
|
|
38
|
-
tier:
|
|
41
|
+
tier: string;
|
|
39
42
|
monthlyCredits: number;
|
|
40
43
|
priceUsd: number;
|
|
41
44
|
features: string[];
|
|
45
|
+
unlimited?: boolean | undefined;
|
|
46
|
+
isFree?: boolean | undefined;
|
|
47
|
+
isDefault?: boolean | undefined;
|
|
42
48
|
}, {
|
|
43
|
-
tier:
|
|
49
|
+
tier: string;
|
|
44
50
|
monthlyCredits: number;
|
|
45
51
|
priceUsd: number;
|
|
46
52
|
features: string[];
|
|
53
|
+
unlimited?: boolean | undefined;
|
|
54
|
+
isFree?: boolean | undefined;
|
|
55
|
+
isDefault?: boolean | undefined;
|
|
47
56
|
}>>;
|
|
48
57
|
/**
|
|
49
58
|
* Reservation expiry time in milliseconds
|
|
@@ -87,12 +96,15 @@ declare const creditSystemConfigSchema: z.ZodObject<{
|
|
|
87
96
|
}, "strip", z.ZodTypeAny, {
|
|
88
97
|
operationCosts: Record<string, number>;
|
|
89
98
|
operationLabels: Record<string, string>;
|
|
90
|
-
tierConfigs:
|
|
91
|
-
tier:
|
|
99
|
+
tierConfigs: Record<string, {
|
|
100
|
+
tier: string;
|
|
92
101
|
monthlyCredits: number;
|
|
93
102
|
priceUsd: number;
|
|
94
103
|
features: string[];
|
|
95
|
-
|
|
104
|
+
unlimited?: boolean | undefined;
|
|
105
|
+
isFree?: boolean | undefined;
|
|
106
|
+
isDefault?: boolean | undefined;
|
|
107
|
+
}>;
|
|
96
108
|
features: {
|
|
97
109
|
journalEntries: boolean;
|
|
98
110
|
notifications: boolean;
|
|
@@ -106,12 +118,15 @@ declare const creditSystemConfigSchema: z.ZodObject<{
|
|
|
106
118
|
lowBalanceNotificationCooldownHours: number;
|
|
107
119
|
}, {
|
|
108
120
|
operationCosts: Record<string, number>;
|
|
109
|
-
tierConfigs:
|
|
110
|
-
tier:
|
|
121
|
+
tierConfigs: Record<string, {
|
|
122
|
+
tier: string;
|
|
111
123
|
monthlyCredits: number;
|
|
112
124
|
priceUsd: number;
|
|
113
125
|
features: string[];
|
|
114
|
-
|
|
126
|
+
unlimited?: boolean | undefined;
|
|
127
|
+
isFree?: boolean | undefined;
|
|
128
|
+
isDefault?: boolean | undefined;
|
|
129
|
+
}>;
|
|
115
130
|
operationLabels?: Record<string, string> | undefined;
|
|
116
131
|
features?: {
|
|
117
132
|
journalEntries?: boolean | undefined;
|
|
@@ -165,7 +180,41 @@ declare function isValidOperationType(type: string): boolean;
|
|
|
165
180
|
*/
|
|
166
181
|
declare function getConfigOperationCost(operationType: string): number;
|
|
167
182
|
/**
|
|
168
|
-
* Get tier
|
|
183
|
+
* Get all valid tier ids from configuration
|
|
184
|
+
* Returns the keys of the tierConfigs object
|
|
185
|
+
*/
|
|
186
|
+
declare function getValidTiers(): string[];
|
|
187
|
+
/**
|
|
188
|
+
* Check if a tier id is valid (configured in the system)
|
|
189
|
+
*/
|
|
190
|
+
declare function isValidTier(tier: string): boolean;
|
|
191
|
+
/**
|
|
192
|
+
* Check if a tier is the free/default tier.
|
|
193
|
+
* Falls back to priceUsd === 0 when the isFree flag is not set.
|
|
194
|
+
*/
|
|
195
|
+
declare function isFreeTier(tier: SubscriptionTier): boolean;
|
|
196
|
+
/**
|
|
197
|
+
* Check if a tier is unlimited.
|
|
198
|
+
* Falls back to monthlyCredits === 0 when the unlimited flag is not set.
|
|
199
|
+
*/
|
|
200
|
+
declare function isUnlimitedTier(tier: SubscriptionTier): boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Get the tier assigned to brand-new users.
|
|
203
|
+
* Prefers the tier flagged isDefault, then the first isFree tier, then "free".
|
|
204
|
+
*/
|
|
205
|
+
declare function getDefaultTier(): SubscriptionTier;
|
|
206
|
+
/**
|
|
207
|
+
* Magic balance assigned to unlimited tiers on upgrade.
|
|
208
|
+
* Kept at 999999 for back-compat with stored/displayed balances.
|
|
209
|
+
*/
|
|
210
|
+
declare const UNLIMITED_BALANCE_SENTINEL = 999999;
|
|
211
|
+
/**
|
|
212
|
+
* Get the magic balance assigned to unlimited tiers on upgrade.
|
|
213
|
+
*/
|
|
214
|
+
declare function getUnlimitedSentinelBalance(): number;
|
|
215
|
+
/**
|
|
216
|
+
* Get tier configuration from configuration.
|
|
217
|
+
* Falls back to the default tier (with a warning) if the tier is unknown.
|
|
169
218
|
*/
|
|
170
219
|
declare function getConfigTierConfig(tier: SubscriptionTier): TierConfig;
|
|
171
220
|
/**
|
|
@@ -173,6 +222,16 @@ declare function getConfigTierConfig(tier: SubscriptionTier): TierConfig;
|
|
|
173
222
|
* Returns Infinity for unlimited tier
|
|
174
223
|
*/
|
|
175
224
|
declare function getConfigMonthlyLimit(tier: SubscriptionTier): number;
|
|
225
|
+
/**
|
|
226
|
+
* Runtime zod validator for tier ids. Validates against the LIVE config keys
|
|
227
|
+
* at parse time, so apps that add tiers via config get correct validation.
|
|
228
|
+
*/
|
|
229
|
+
declare const tierSchema: z.ZodType<SubscriptionTier>;
|
|
230
|
+
/**
|
|
231
|
+
* Parse/validate a tier id against the live config keys.
|
|
232
|
+
* @throws ZodError if the tier is not configured
|
|
233
|
+
*/
|
|
234
|
+
declare function parseTier(value: unknown): SubscriptionTier;
|
|
176
235
|
/**
|
|
177
236
|
* Check if a feature is enabled
|
|
178
237
|
*/
|
|
@@ -434,4 +493,4 @@ declare function isPreviewMode(data: unknown): boolean;
|
|
|
434
493
|
*/
|
|
435
494
|
declare function createDummyReservation(userId: string, operationType: string): PortableReservation;
|
|
436
495
|
|
|
437
|
-
export { ConsoleNotificationHandler, type CreditErrorInfo, type CreditNotificationEvent, PortableReservation as CreditReservation, type CreditSystemConfig, type ICreditConfigProvider, type ICreditNotificationHandler, type OperationCostInfo, PortableReservation, SubscriptionTier as SDKSubscriptionTier, SubscriptionTier, TierConfig, checkAndNotifyLowBalance, clearConfigProvider, clearCooldownState, clearNotificationHandlers, createDummyReservation, generateRequestId, getConfig, getConfigMonthlyLimit, getConfigOperationCost, getConfigProvider, getConfigTierConfig, getDefaultFreeCredits, getMonthlyLimit, getOperationCost, getOperationCosts, getOperationCostsWithLabels, getOperationLabel, getOperationLabels, getReservationExpiryMs, getTierConfig, getTotalCredits, getValidOperationTypes, initializeConfig, isCreditErrorMessage, isFeatureEnabled, isPreviewMode, isValidOperationType, loadConfigFromEnv, notifySubscriptionExpired, notifySubscriptionExpiring, parseCreditError, registerConfigProvider, registerNotificationHandler, resetConfig };
|
|
496
|
+
export { ConsoleNotificationHandler, type CreditErrorInfo, type CreditNotificationEvent, PortableReservation as CreditReservation, type CreditSystemConfig, type ICreditConfigProvider, type ICreditNotificationHandler, type OperationCostInfo, PortableReservation, SubscriptionTier as SDKSubscriptionTier, SubscriptionTier, TierConfig, UNLIMITED_BALANCE_SENTINEL, checkAndNotifyLowBalance, clearConfigProvider, clearCooldownState, clearNotificationHandlers, createDummyReservation, generateRequestId, getConfig, getConfigMonthlyLimit, getConfigOperationCost, getConfigProvider, getConfigTierConfig, getDefaultFreeCredits, getDefaultTier, getMonthlyLimit, getOperationCost, getOperationCosts, getOperationCostsWithLabels, getOperationLabel, getOperationLabels, getReservationExpiryMs, getTierConfig, getTotalCredits, getUnlimitedSentinelBalance, getValidOperationTypes, getValidTiers, initializeConfig, isCreditErrorMessage, isFeatureEnabled, isFreeTier, isPreviewMode, isUnlimitedTier, isValidOperationType, isValidTier, loadConfigFromEnv, notifySubscriptionExpired, notifySubscriptionExpiring, parseCreditError, parseTier, registerConfigProvider, registerNotificationHandler, resetConfig, tierSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { S as SubscriptionTier, T as TierConfig, c as PortableReservation } from './types-
|
|
2
|
-
export { A as AIProviderType, g as CreditCheckResult, a as CreditOperationType, C as CreditSource, J as JournalReferenceType, M as MonthlyResetResult, f as PortableJournalEntry, P as PortableTransaction, d as PortableUsageLog, b as PortableUserCredits, R as ReservationStatus, h as ResourceType, g as SDKCreditCheckResult, e as SubscriptionExpiryResult, i as TransactionType, U as UsageHistoryEntry, j as UsageHistoryResponse, b as UserCredits, W as WithCreditsOptions, k as calculateAvailableCredits, t as toDate, l as toPortableTimestamp } from './types-
|
|
1
|
+
import { S as SubscriptionTier, T as TierConfig, c as PortableReservation } from './types-CjLj3GW5.js';
|
|
2
|
+
export { A as AIProviderType, B as BuiltinTier, g as CreditCheckResult, a as CreditOperationType, C as CreditSource, D as DeductCreditsResult, J as JournalReferenceType, M as MonthlyResetResult, f as PortableJournalEntry, P as PortableTransaction, d as PortableUsageLog, b as PortableUserCredits, R as ReservationStatus, h as ResourceType, g as SDKCreditCheckResult, e as SubscriptionExpiryResult, i as TransactionType, U as UsageHistoryEntry, j as UsageHistoryResponse, b as UserCredits, W as WithCreditsOptions, k as calculateAvailableCredits, t as toDate, l as toPortableTimestamp } from './types-CjLj3GW5.js';
|
|
3
3
|
export { CreditError, CreditErrorCode, CreditErrorCodeType, commitReservationWithJournal, createInsufficientCreditsError, createInvalidOperationTypeError, createReservationAlreadyProcessedError, createReservationExpiredError, createReservationNotFoundError, createUserNotFoundError, isCreditError, isInsufficientCreditsError, releaseReservationWithJournal, reserveCreditsForOperation } from './core/index.js';
|
|
4
4
|
export { D as DeferredExecutor, c as createDeferredExecutor, g as genericDeferred, n as noopDeferred, s as synchronousDeferred } from './deferred-C7rrRfkm.js';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
export { C as CreateJournalEntryInput, a as CreateReservationInput, b as CreateTransactionInput, c as CreateUsageLogInput, d as CreditBalanceUpdate, e as CreditRepositoryFactory, I as ICreditRepository, J as JournalEntryQuery, T as TierUpdateInput, U as UsageLogQuery, t as toClientUserCredits } from './types-
|
|
6
|
+
export { C as CreateJournalEntryInput, a as CreateReservationInput, b as CreateTransactionInput, c as CreateUsageLogInput, d as CreditBalanceUpdate, e as CreditRepositoryFactory, I as ICreditRepository, J as JournalEntryQuery, T as TierUpdateInput, U as UsageLogQuery, t as toClientUserCredits } from './types-G4WK0rM-.js';
|
|
7
7
|
export { InMemoryCreditRepository, createInMemoryCreditRepository, generateId, getNextMonthlyReset } from './repository/index.js';
|
|
8
8
|
export { C as CreditsAuthProviderFactory, a as CreditsUser, I as ICreditsAuthProvider } from './types-OZU3I5OM.js';
|
|
9
9
|
export { ApiKeyCreditsProvider, createApiKeyProvider, verifyAdminApiKey, verifyBearerToken } from './auth/index.js';
|
|
10
|
-
export { CreditsService, LowBalanceNotificationCallback, SubscriptionExpiredNotificationCallback, createCreditsService } from './service/index.js';
|
|
10
|
+
export { CreditsService, DeductCreditsOptions, LowBalanceNotificationCallback, ReserveCreditsOptions, SubscriptionExpiredNotificationCallback, createCreditsService } from './service/index.js';
|
|
11
11
|
export { ActionResult, CreditActionHandler, CreditsAdapter, CreditsAdapterConfig, createGenericAdapter } from './adapters/index.js';
|
|
12
12
|
export { AdminCreditsClient, AdminCreditsClientConfig, ApiResponse, AuthenticationError, AuthorizationError, CreditsClient, CreditsClientConfig, CreditsConfig, CreditsSDKError, ListUsersOptions, ListUsersResponse, NetworkError, PaginationOptions, ReservationResult, SDKErrorCode, SDKErrorCodeType, InsufficientCreditsError as SDKInsufficientCreditsError, ReservationExpiredError as SDKReservationExpiredError, ReservationNotFoundError as SDKReservationNotFoundError, UsageHistoryEntry as SDKUsageHistoryEntry, UsageHistoryResponse as SDKUsageHistoryResponse, ServerError, ValidationError, parseApiError } from './sdk/index.js';
|
|
13
13
|
|
|
@@ -29,21 +29,30 @@ declare const creditSystemConfigSchema: z.ZodObject<{
|
|
|
29
29
|
/**
|
|
30
30
|
* Tier configurations
|
|
31
31
|
*/
|
|
32
|
-
tierConfigs: z.ZodRecord<z.
|
|
33
|
-
tier: z.
|
|
32
|
+
tierConfigs: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
33
|
+
tier: z.ZodString;
|
|
34
34
|
monthlyCredits: z.ZodNumber;
|
|
35
35
|
priceUsd: z.ZodNumber;
|
|
36
36
|
features: z.ZodArray<z.ZodString, "many">;
|
|
37
|
+
isFree: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
39
|
+
isDefault: z.ZodOptional<z.ZodBoolean>;
|
|
37
40
|
}, "strip", z.ZodTypeAny, {
|
|
38
|
-
tier:
|
|
41
|
+
tier: string;
|
|
39
42
|
monthlyCredits: number;
|
|
40
43
|
priceUsd: number;
|
|
41
44
|
features: string[];
|
|
45
|
+
unlimited?: boolean | undefined;
|
|
46
|
+
isFree?: boolean | undefined;
|
|
47
|
+
isDefault?: boolean | undefined;
|
|
42
48
|
}, {
|
|
43
|
-
tier:
|
|
49
|
+
tier: string;
|
|
44
50
|
monthlyCredits: number;
|
|
45
51
|
priceUsd: number;
|
|
46
52
|
features: string[];
|
|
53
|
+
unlimited?: boolean | undefined;
|
|
54
|
+
isFree?: boolean | undefined;
|
|
55
|
+
isDefault?: boolean | undefined;
|
|
47
56
|
}>>;
|
|
48
57
|
/**
|
|
49
58
|
* Reservation expiry time in milliseconds
|
|
@@ -87,12 +96,15 @@ declare const creditSystemConfigSchema: z.ZodObject<{
|
|
|
87
96
|
}, "strip", z.ZodTypeAny, {
|
|
88
97
|
operationCosts: Record<string, number>;
|
|
89
98
|
operationLabels: Record<string, string>;
|
|
90
|
-
tierConfigs:
|
|
91
|
-
tier:
|
|
99
|
+
tierConfigs: Record<string, {
|
|
100
|
+
tier: string;
|
|
92
101
|
monthlyCredits: number;
|
|
93
102
|
priceUsd: number;
|
|
94
103
|
features: string[];
|
|
95
|
-
|
|
104
|
+
unlimited?: boolean | undefined;
|
|
105
|
+
isFree?: boolean | undefined;
|
|
106
|
+
isDefault?: boolean | undefined;
|
|
107
|
+
}>;
|
|
96
108
|
features: {
|
|
97
109
|
journalEntries: boolean;
|
|
98
110
|
notifications: boolean;
|
|
@@ -106,12 +118,15 @@ declare const creditSystemConfigSchema: z.ZodObject<{
|
|
|
106
118
|
lowBalanceNotificationCooldownHours: number;
|
|
107
119
|
}, {
|
|
108
120
|
operationCosts: Record<string, number>;
|
|
109
|
-
tierConfigs:
|
|
110
|
-
tier:
|
|
121
|
+
tierConfigs: Record<string, {
|
|
122
|
+
tier: string;
|
|
111
123
|
monthlyCredits: number;
|
|
112
124
|
priceUsd: number;
|
|
113
125
|
features: string[];
|
|
114
|
-
|
|
126
|
+
unlimited?: boolean | undefined;
|
|
127
|
+
isFree?: boolean | undefined;
|
|
128
|
+
isDefault?: boolean | undefined;
|
|
129
|
+
}>;
|
|
115
130
|
operationLabels?: Record<string, string> | undefined;
|
|
116
131
|
features?: {
|
|
117
132
|
journalEntries?: boolean | undefined;
|
|
@@ -165,7 +180,41 @@ declare function isValidOperationType(type: string): boolean;
|
|
|
165
180
|
*/
|
|
166
181
|
declare function getConfigOperationCost(operationType: string): number;
|
|
167
182
|
/**
|
|
168
|
-
* Get tier
|
|
183
|
+
* Get all valid tier ids from configuration
|
|
184
|
+
* Returns the keys of the tierConfigs object
|
|
185
|
+
*/
|
|
186
|
+
declare function getValidTiers(): string[];
|
|
187
|
+
/**
|
|
188
|
+
* Check if a tier id is valid (configured in the system)
|
|
189
|
+
*/
|
|
190
|
+
declare function isValidTier(tier: string): boolean;
|
|
191
|
+
/**
|
|
192
|
+
* Check if a tier is the free/default tier.
|
|
193
|
+
* Falls back to priceUsd === 0 when the isFree flag is not set.
|
|
194
|
+
*/
|
|
195
|
+
declare function isFreeTier(tier: SubscriptionTier): boolean;
|
|
196
|
+
/**
|
|
197
|
+
* Check if a tier is unlimited.
|
|
198
|
+
* Falls back to monthlyCredits === 0 when the unlimited flag is not set.
|
|
199
|
+
*/
|
|
200
|
+
declare function isUnlimitedTier(tier: SubscriptionTier): boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Get the tier assigned to brand-new users.
|
|
203
|
+
* Prefers the tier flagged isDefault, then the first isFree tier, then "free".
|
|
204
|
+
*/
|
|
205
|
+
declare function getDefaultTier(): SubscriptionTier;
|
|
206
|
+
/**
|
|
207
|
+
* Magic balance assigned to unlimited tiers on upgrade.
|
|
208
|
+
* Kept at 999999 for back-compat with stored/displayed balances.
|
|
209
|
+
*/
|
|
210
|
+
declare const UNLIMITED_BALANCE_SENTINEL = 999999;
|
|
211
|
+
/**
|
|
212
|
+
* Get the magic balance assigned to unlimited tiers on upgrade.
|
|
213
|
+
*/
|
|
214
|
+
declare function getUnlimitedSentinelBalance(): number;
|
|
215
|
+
/**
|
|
216
|
+
* Get tier configuration from configuration.
|
|
217
|
+
* Falls back to the default tier (with a warning) if the tier is unknown.
|
|
169
218
|
*/
|
|
170
219
|
declare function getConfigTierConfig(tier: SubscriptionTier): TierConfig;
|
|
171
220
|
/**
|
|
@@ -173,6 +222,16 @@ declare function getConfigTierConfig(tier: SubscriptionTier): TierConfig;
|
|
|
173
222
|
* Returns Infinity for unlimited tier
|
|
174
223
|
*/
|
|
175
224
|
declare function getConfigMonthlyLimit(tier: SubscriptionTier): number;
|
|
225
|
+
/**
|
|
226
|
+
* Runtime zod validator for tier ids. Validates against the LIVE config keys
|
|
227
|
+
* at parse time, so apps that add tiers via config get correct validation.
|
|
228
|
+
*/
|
|
229
|
+
declare const tierSchema: z.ZodType<SubscriptionTier>;
|
|
230
|
+
/**
|
|
231
|
+
* Parse/validate a tier id against the live config keys.
|
|
232
|
+
* @throws ZodError if the tier is not configured
|
|
233
|
+
*/
|
|
234
|
+
declare function parseTier(value: unknown): SubscriptionTier;
|
|
176
235
|
/**
|
|
177
236
|
* Check if a feature is enabled
|
|
178
237
|
*/
|
|
@@ -434,4 +493,4 @@ declare function isPreviewMode(data: unknown): boolean;
|
|
|
434
493
|
*/
|
|
435
494
|
declare function createDummyReservation(userId: string, operationType: string): PortableReservation;
|
|
436
495
|
|
|
437
|
-
export { ConsoleNotificationHandler, type CreditErrorInfo, type CreditNotificationEvent, PortableReservation as CreditReservation, type CreditSystemConfig, type ICreditConfigProvider, type ICreditNotificationHandler, type OperationCostInfo, PortableReservation, SubscriptionTier as SDKSubscriptionTier, SubscriptionTier, TierConfig, checkAndNotifyLowBalance, clearConfigProvider, clearCooldownState, clearNotificationHandlers, createDummyReservation, generateRequestId, getConfig, getConfigMonthlyLimit, getConfigOperationCost, getConfigProvider, getConfigTierConfig, getDefaultFreeCredits, getMonthlyLimit, getOperationCost, getOperationCosts, getOperationCostsWithLabels, getOperationLabel, getOperationLabels, getReservationExpiryMs, getTierConfig, getTotalCredits, getValidOperationTypes, initializeConfig, isCreditErrorMessage, isFeatureEnabled, isPreviewMode, isValidOperationType, loadConfigFromEnv, notifySubscriptionExpired, notifySubscriptionExpiring, parseCreditError, registerConfigProvider, registerNotificationHandler, resetConfig };
|
|
496
|
+
export { ConsoleNotificationHandler, type CreditErrorInfo, type CreditNotificationEvent, PortableReservation as CreditReservation, type CreditSystemConfig, type ICreditConfigProvider, type ICreditNotificationHandler, type OperationCostInfo, PortableReservation, SubscriptionTier as SDKSubscriptionTier, SubscriptionTier, TierConfig, UNLIMITED_BALANCE_SENTINEL, checkAndNotifyLowBalance, clearConfigProvider, clearCooldownState, clearNotificationHandlers, createDummyReservation, generateRequestId, getConfig, getConfigMonthlyLimit, getConfigOperationCost, getConfigProvider, getConfigTierConfig, getDefaultFreeCredits, getDefaultTier, getMonthlyLimit, getOperationCost, getOperationCosts, getOperationCostsWithLabels, getOperationLabel, getOperationLabels, getReservationExpiryMs, getTierConfig, getTotalCredits, getUnlimitedSentinelBalance, getValidOperationTypes, getValidTiers, initializeConfig, isCreditErrorMessage, isFeatureEnabled, isFreeTier, isPreviewMode, isUnlimitedTier, isValidOperationType, isValidTier, loadConfigFromEnv, notifySubscriptionExpired, notifySubscriptionExpiring, parseCreditError, parseTier, registerConfigProvider, registerNotificationHandler, resetConfig, tierSchema };
|
package/dist/index.js
CHANGED
|
@@ -165,10 +165,13 @@ function clearConfigProvider() {
|
|
|
165
165
|
|
|
166
166
|
// src/config/index.ts
|
|
167
167
|
var tierConfigSchema = z.object({
|
|
168
|
-
tier: z.
|
|
168
|
+
tier: z.string().min(1),
|
|
169
169
|
monthlyCredits: z.number().min(0),
|
|
170
170
|
priceUsd: z.number().min(0),
|
|
171
|
-
features: z.array(z.string())
|
|
171
|
+
features: z.array(z.string()),
|
|
172
|
+
isFree: z.boolean().optional(),
|
|
173
|
+
unlimited: z.boolean().optional(),
|
|
174
|
+
isDefault: z.boolean().optional()
|
|
172
175
|
});
|
|
173
176
|
var creditSystemConfigSchema = z.object({
|
|
174
177
|
/**
|
|
@@ -192,7 +195,7 @@ var creditSystemConfigSchema = z.object({
|
|
|
192
195
|
* Tier configurations
|
|
193
196
|
*/
|
|
194
197
|
tierConfigs: z.record(
|
|
195
|
-
z.
|
|
198
|
+
z.string().min(1),
|
|
196
199
|
tierConfigSchema
|
|
197
200
|
),
|
|
198
201
|
/**
|
|
@@ -248,6 +251,8 @@ var DEFAULT_CONFIG = {
|
|
|
248
251
|
tier: "free",
|
|
249
252
|
monthlyCredits: 25,
|
|
250
253
|
priceUsd: 0,
|
|
254
|
+
isFree: true,
|
|
255
|
+
isDefault: true,
|
|
251
256
|
features: [
|
|
252
257
|
"25 credits per month",
|
|
253
258
|
"Basic story generation",
|
|
@@ -281,6 +286,7 @@ var DEFAULT_CONFIG = {
|
|
|
281
286
|
tier: "unlimited",
|
|
282
287
|
monthlyCredits: 0,
|
|
283
288
|
// 0 = unlimited
|
|
289
|
+
unlimited: true,
|
|
284
290
|
priceUsd: 49.99,
|
|
285
291
|
features: [
|
|
286
292
|
"Unlimited credits",
|
|
@@ -408,12 +414,46 @@ function getConfigOperationCost(operationType) {
|
|
|
408
414
|
}
|
|
409
415
|
return cost;
|
|
410
416
|
}
|
|
417
|
+
function getValidTiers() {
|
|
418
|
+
return Object.keys(getConfig().tierConfigs);
|
|
419
|
+
}
|
|
420
|
+
function isValidTier(tier) {
|
|
421
|
+
return tier in getConfig().tierConfigs;
|
|
422
|
+
}
|
|
423
|
+
function isFreeTier(tier) {
|
|
424
|
+
const c = getConfig().tierConfigs[tier];
|
|
425
|
+
if (!c) return false;
|
|
426
|
+
return c.isFree ?? c.priceUsd === 0;
|
|
427
|
+
}
|
|
428
|
+
function isUnlimitedTier(tier) {
|
|
429
|
+
const c = getConfig().tierConfigs[tier];
|
|
430
|
+
if (!c) return false;
|
|
431
|
+
return c.unlimited ?? c.monthlyCredits === 0;
|
|
432
|
+
}
|
|
433
|
+
function getDefaultTier() {
|
|
434
|
+
const entries = Object.entries(getConfig().tierConfigs);
|
|
435
|
+
const def = entries.find(([, c]) => c.isDefault)?.[0] ?? entries.find(([, c]) => c.isFree ?? c.priceUsd === 0)?.[0];
|
|
436
|
+
return def ?? "free";
|
|
437
|
+
}
|
|
438
|
+
var UNLIMITED_BALANCE_SENTINEL = 999999;
|
|
439
|
+
function getUnlimitedSentinelBalance() {
|
|
440
|
+
return UNLIMITED_BALANCE_SENTINEL;
|
|
441
|
+
}
|
|
411
442
|
function getConfigTierConfig(tier) {
|
|
412
|
-
|
|
443
|
+
const cfg = getConfig().tierConfigs[tier];
|
|
444
|
+
if (cfg) return cfg;
|
|
445
|
+
const fallback = getDefaultTier();
|
|
446
|
+
console.warn(
|
|
447
|
+
`[Credits Config] Unknown tier "${tier}". Falling back to "${fallback}". Valid: ${getValidTiers().join(", ")}`
|
|
448
|
+
);
|
|
449
|
+
return getConfig().tierConfigs[fallback];
|
|
413
450
|
}
|
|
414
451
|
function getConfigMonthlyLimit(tier) {
|
|
415
|
-
|
|
416
|
-
|
|
452
|
+
return isUnlimitedTier(tier) ? Infinity : getConfigTierConfig(tier).monthlyCredits;
|
|
453
|
+
}
|
|
454
|
+
var tierSchema = z.string().refine(isValidTier, { message: "Unknown subscription tier" });
|
|
455
|
+
function parseTier(value) {
|
|
456
|
+
return tierSchema.parse(value);
|
|
417
457
|
}
|
|
418
458
|
function isFeatureEnabled(feature) {
|
|
419
459
|
return getConfig().features[feature];
|
|
@@ -988,7 +1028,7 @@ var InMemoryCreditRepository = class {
|
|
|
988
1028
|
if (!credits) {
|
|
989
1029
|
throw new Error(`User ${userId} not found`);
|
|
990
1030
|
}
|
|
991
|
-
if (credits.tier
|
|
1031
|
+
if (isFreeTier(credits.tier) || !credits.subscriptionExpiresAt) {
|
|
992
1032
|
return {
|
|
993
1033
|
wasDowngraded: false,
|
|
994
1034
|
inGracePeriod: false,
|
|
@@ -1015,11 +1055,11 @@ var InMemoryCreditRepository = class {
|
|
|
1015
1055
|
credits
|
|
1016
1056
|
};
|
|
1017
1057
|
}
|
|
1018
|
-
const
|
|
1019
|
-
const
|
|
1020
|
-
credits.tier =
|
|
1021
|
-
credits.monthlyLimit =
|
|
1022
|
-
credits.balance = Math.min(credits.balance,
|
|
1058
|
+
const defaultTier = getDefaultTier();
|
|
1059
|
+
const defaultTierConfig = getConfigTierConfig(defaultTier);
|
|
1060
|
+
credits.tier = defaultTier;
|
|
1061
|
+
credits.monthlyLimit = defaultTierConfig.monthlyCredits;
|
|
1062
|
+
credits.balance = Math.min(credits.balance, defaultTierConfig.monthlyCredits);
|
|
1023
1063
|
credits.subscriptionExpiresAt = null;
|
|
1024
1064
|
credits.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1025
1065
|
this.users.set(userId, credits);
|
|
@@ -1159,7 +1199,7 @@ var CreditsService = class {
|
|
|
1159
1199
|
if (!data) {
|
|
1160
1200
|
return null;
|
|
1161
1201
|
}
|
|
1162
|
-
if (data.tier
|
|
1202
|
+
if (!isFreeTier(data.tier) && data.subscriptionExpiresAt) {
|
|
1163
1203
|
const expiryResult = await this.repository.checkAndHandleSubscriptionExpiry(
|
|
1164
1204
|
userId,
|
|
1165
1205
|
getConfig().subscriptionGracePeriodDays
|
|
@@ -1228,7 +1268,7 @@ var CreditsService = class {
|
|
|
1228
1268
|
async initializeUserCredits(userId) {
|
|
1229
1269
|
const credits = await this.repository.initializeUserCredits(
|
|
1230
1270
|
userId,
|
|
1231
|
-
|
|
1271
|
+
getDefaultTier(),
|
|
1232
1272
|
getConfig().defaultFreeCredits
|
|
1233
1273
|
);
|
|
1234
1274
|
return toClientUserCredits(credits);
|
|
@@ -1360,6 +1400,83 @@ var CreditsService = class {
|
|
|
1360
1400
|
async addCredits(userId, amount, description, paymentRef) {
|
|
1361
1401
|
return this.repository.addCreditsAtomic(userId, amount, description, paymentRef);
|
|
1362
1402
|
}
|
|
1403
|
+
/**
|
|
1404
|
+
* One-shot atomic "deduct-if-sufficient" credit charge.
|
|
1405
|
+
*
|
|
1406
|
+
* Unlike the reserve/commit/release two-phase flow, this performs a single
|
|
1407
|
+
* atomic check-and-deduct against the repository — suited for synchronous,
|
|
1408
|
+
* in-request operations that don't need a hold across an async job. Exactly
|
|
1409
|
+
* one call is made to `repository.deductCreditsAtomic`, which enforces
|
|
1410
|
+
* atomicity so concurrent callers can never both succeed against the same
|
|
1411
|
+
* limited balance.
|
|
1412
|
+
*
|
|
1413
|
+
* On success, creates a journal entry (same audit trail as `commitCredits`)
|
|
1414
|
+
* and, if `options.operationType` is provided, a usage log entry via the
|
|
1415
|
+
* same `logUsage` path.
|
|
1416
|
+
*
|
|
1417
|
+
* @param userId - User ID
|
|
1418
|
+
* @param amount - Credits to deduct (must be > 0)
|
|
1419
|
+
* @param options - Optional usage-log / journal metadata
|
|
1420
|
+
* @returns Typed result: `{ success: true, newBalance }` or
|
|
1421
|
+
* `{ success: false, reason: 'insufficient', available, required, shortfall }`
|
|
1422
|
+
* @throws Error if amount is not a positive number
|
|
1423
|
+
*/
|
|
1424
|
+
async deductCredits(userId, amount, options) {
|
|
1425
|
+
if (!(amount > 0)) {
|
|
1426
|
+
throw new Error(`deductCredits amount must be positive (got ${amount})`);
|
|
1427
|
+
}
|
|
1428
|
+
let deduction;
|
|
1429
|
+
try {
|
|
1430
|
+
deduction = await this.repository.deductCreditsAtomic(userId, amount);
|
|
1431
|
+
} catch (error) {
|
|
1432
|
+
const credits = await this.repository.getUserCredits(userId);
|
|
1433
|
+
const available = credits ? credits.balance + credits.bonusCredits - credits.reserved : 0;
|
|
1434
|
+
if (available >= amount) {
|
|
1435
|
+
throw error;
|
|
1436
|
+
}
|
|
1437
|
+
return {
|
|
1438
|
+
success: false,
|
|
1439
|
+
reason: "insufficient",
|
|
1440
|
+
available,
|
|
1441
|
+
required: amount,
|
|
1442
|
+
shortfall: amount - available
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
const operationType = options?.operationType;
|
|
1446
|
+
await this.repository.createJournalEntry({
|
|
1447
|
+
userId,
|
|
1448
|
+
entryType: "debit",
|
|
1449
|
+
amount,
|
|
1450
|
+
balanceAfter: deduction.newBalance,
|
|
1451
|
+
source: "operation_commit",
|
|
1452
|
+
referenceId: options?.requestId ?? `deduct-${Date.now()}`,
|
|
1453
|
+
referenceType: "adjustment",
|
|
1454
|
+
description: operationType ? `Deducted ${amount} credits for ${getOperationLabel(operationType)}` : `Deducted ${amount} credits`,
|
|
1455
|
+
metadata: {
|
|
1456
|
+
...operationType && { operationType },
|
|
1457
|
+
...options?.metadata
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1460
|
+
if (operationType) {
|
|
1461
|
+
await this.logUsage({
|
|
1462
|
+
userId,
|
|
1463
|
+
operationType,
|
|
1464
|
+
provider: "gemini",
|
|
1465
|
+
creditsUsed: amount,
|
|
1466
|
+
success: true,
|
|
1467
|
+
resourceId: options?.resourceId,
|
|
1468
|
+
resourceType: options?.resourceType,
|
|
1469
|
+
requestId: options?.requestId,
|
|
1470
|
+
metadata: options?.metadata
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
if (this.lowBalanceCallback) {
|
|
1474
|
+
this.lowBalanceCallback(userId, deduction.newBalance).catch((error) => {
|
|
1475
|
+
console.error("[Credits] Failed to send low balance notification:", error);
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
return { success: true, newBalance: deduction.newBalance };
|
|
1479
|
+
}
|
|
1363
1480
|
/**
|
|
1364
1481
|
* Update user subscription tier
|
|
1365
1482
|
* @param userId - User ID
|
|
@@ -1368,12 +1485,15 @@ var CreditsService = class {
|
|
|
1368
1485
|
*/
|
|
1369
1486
|
async updateTier(userId, tier, expiresAt) {
|
|
1370
1487
|
const monthlyLimit = getConfigMonthlyLimit(tier);
|
|
1488
|
+
const unlimited = isUnlimitedTier(tier);
|
|
1489
|
+
const free = isFreeTier(tier);
|
|
1371
1490
|
await this.repository.updateUserTier(userId, {
|
|
1372
1491
|
tier,
|
|
1373
|
-
|
|
1492
|
+
// Stored monthlyLimit uses the 0-means-unlimited convention.
|
|
1493
|
+
monthlyLimit: unlimited ? 0 : monthlyLimit,
|
|
1374
1494
|
// Reset balance to new tier limit if upgrading
|
|
1375
|
-
balance:
|
|
1376
|
-
monthlyUsed:
|
|
1495
|
+
balance: !free ? unlimited ? getUnlimitedSentinelBalance() : monthlyLimit : void 0,
|
|
1496
|
+
monthlyUsed: !free ? 0 : void 0,
|
|
1377
1497
|
subscriptionExpiresAt: expiresAt ? expiresAt.toISOString() : null
|
|
1378
1498
|
});
|
|
1379
1499
|
}
|
|
@@ -2341,6 +2461,7 @@ export {
|
|
|
2341
2461
|
ReservationExpiredError as SDKReservationExpiredError,
|
|
2342
2462
|
ReservationNotFoundError as SDKReservationNotFoundError,
|
|
2343
2463
|
ServerError,
|
|
2464
|
+
UNLIMITED_BALANCE_SENTINEL,
|
|
2344
2465
|
ValidationError,
|
|
2345
2466
|
calculateAvailableCredits,
|
|
2346
2467
|
checkAndNotifyLowBalance,
|
|
@@ -2369,6 +2490,7 @@ export {
|
|
|
2369
2490
|
getConfigProvider,
|
|
2370
2491
|
getConfigTierConfig,
|
|
2371
2492
|
getDefaultFreeCredits,
|
|
2493
|
+
getDefaultTier,
|
|
2372
2494
|
getMonthlyLimit,
|
|
2373
2495
|
getNextMonthlyReset,
|
|
2374
2496
|
getOperationCost,
|
|
@@ -2379,26 +2501,33 @@ export {
|
|
|
2379
2501
|
getReservationExpiryMs,
|
|
2380
2502
|
getTierConfig,
|
|
2381
2503
|
getTotalCredits,
|
|
2504
|
+
getUnlimitedSentinelBalance,
|
|
2382
2505
|
getValidOperationTypes,
|
|
2506
|
+
getValidTiers,
|
|
2383
2507
|
initializeConfig,
|
|
2384
2508
|
isCreditError,
|
|
2385
2509
|
isCreditErrorMessage,
|
|
2386
2510
|
isFeatureEnabled,
|
|
2511
|
+
isFreeTier,
|
|
2387
2512
|
isInsufficientCreditsError,
|
|
2388
2513
|
isPreviewMode2 as isPreviewMode,
|
|
2514
|
+
isUnlimitedTier,
|
|
2389
2515
|
isValidOperationType,
|
|
2516
|
+
isValidTier,
|
|
2390
2517
|
loadConfigFromEnv,
|
|
2391
2518
|
noopDeferred,
|
|
2392
2519
|
notifySubscriptionExpired,
|
|
2393
2520
|
notifySubscriptionExpiring,
|
|
2394
2521
|
parseApiError,
|
|
2395
2522
|
parseCreditError,
|
|
2523
|
+
parseTier,
|
|
2396
2524
|
registerConfigProvider,
|
|
2397
2525
|
registerNotificationHandler,
|
|
2398
2526
|
releaseReservationWithJournal,
|
|
2399
2527
|
reserveCreditsForOperation,
|
|
2400
2528
|
resetConfig,
|
|
2401
2529
|
synchronousDeferred,
|
|
2530
|
+
tierSchema,
|
|
2402
2531
|
toClientUserCredits,
|
|
2403
2532
|
toDate,
|
|
2404
2533
|
toPortableTimestamp,
|