@nehorai/credits 3.0.0 → 3.1.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.
@@ -1,5 +1,5 @@
1
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-C3sxDvNb.cjs';
2
- import { I as ICreditRepository, o as ReserveOutcome, m as ReservationTransitionOptions, C as CommitOutcome, R as ReleaseOutcome, A as AddCreditsAtomicOptions, a as AddCreditsOutcome, J as JournalEntryQuery } from '../types-DOjguhEX.cjs';
2
+ import { I as ICreditRepository, o as ReserveOutcome, m as ReservationTransitionOptions, C as CommitOutcome, R as ReleaseOutcome, A as AddCreditsAtomicOptions, a as AddCreditsOutcome, J as JournalEntryQuery } from '../types-YLAB8bFk.cjs';
3
3
 
4
4
  /**
5
5
  * Notification callback type for low balance notifications
@@ -1,5 +1,5 @@
1
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-C3sxDvNb.js';
2
- import { I as ICreditRepository, o as ReserveOutcome, m as ReservationTransitionOptions, C as CommitOutcome, R as ReleaseOutcome, A as AddCreditsAtomicOptions, a as AddCreditsOutcome, J as JournalEntryQuery } from '../types-CY-oHIMA.js';
2
+ import { I as ICreditRepository, o as ReserveOutcome, m as ReservationTransitionOptions, C as CommitOutcome, R as ReleaseOutcome, A as AddCreditsAtomicOptions, a as AddCreditsOutcome, J as JournalEntryQuery } from '../types-BL3YqxUD.js';
3
3
 
4
4
  /**
5
5
  * Notification callback type for low balance notifications
@@ -159,6 +159,11 @@ function creditAmountReason(value) {
159
159
  }
160
160
  return `Credit amount ${value} is not exact to ${CREDIT_AMOUNT_SCALE} decimal places`;
161
161
  }
162
+ function isRepresentableAmount(value) {
163
+ if (typeof value !== "number") return false;
164
+ const cents = toCents(value);
165
+ return cents !== null && Math.abs(cents) <= MAX_CENTS;
166
+ }
162
167
  function storedMonthlyLimit(limit) {
163
168
  return Number.isFinite(limit) ? limit : CREDIT_AMOUNT_MAX;
164
169
  }
@@ -336,17 +341,25 @@ var DEFAULT_CONFIG = {
336
341
  }
337
342
  };
338
343
  var currentConfig = DEFAULT_CONFIG;
344
+ function isOperationCostMap(value) {
345
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
346
+ return Object.values(value).every((cost) => isRepresentableAmount(cost) && cost >= 0);
347
+ }
339
348
  function loadConfigFromEnv() {
340
349
  const envConfig = {};
341
350
  const operationCostsEnv = process.env.CREDITS_OPERATION_COSTS;
342
351
  if (operationCostsEnv) {
343
352
  try {
344
353
  const parsed = JSON.parse(operationCostsEnv);
345
- if (typeof parsed === "object" && parsed !== null) {
354
+ if (isOperationCostMap(parsed)) {
346
355
  envConfig.operationCosts = {
347
356
  ...DEFAULT_CONFIG.operationCosts,
348
357
  ...parsed
349
358
  };
359
+ } else {
360
+ console.warn(
361
+ "[Credits Config] Ignoring CREDITS_OPERATION_COSTS: it must be a JSON object whose costs are numbers >= 0, exact to the cent"
362
+ );
350
363
  }
351
364
  } catch {
352
365
  console.warn("[Credits Config] Failed to parse CREDITS_OPERATION_COSTS env var as JSON");
@@ -697,7 +710,7 @@ var CreditsService = class {
697
710
  userId,
698
711
  entryType: "debit",
699
712
  amount: 0,
700
- // No credits deducted, just tier change
713
+ // 0, however far the cap lowered the balance: the totals record the move
701
714
  balanceBefore: sumAmounts(data.balance, data.bonusCredits),
702
715
  // The ledger balance, matching every other journal writer: the V2
703
716
  // transitions and add/deduct all record `balance + bonusCredits`, so
@@ -1089,7 +1102,8 @@ var CreditsService = class {
1089
1102
  ]);
1090
1103
  const historyEntries = entries.map((entry) => {
1091
1104
  const type = this.mapSourceToHistoryType(entry.source);
1092
- const creditsChange = entry.entryType === "credit" ? entry.amount : -entry.amount;
1105
+ const signedAmount = entry.entryType === "credit" ? entry.amount : -entry.amount;
1106
+ const creditsChange = entry.balanceBefore !== void 0 ? sumAmounts(entry.balanceAfter, -entry.balanceBefore) : signedAmount;
1093
1107
  return {
1094
1108
  id: entry.id,
1095
1109
  type,