@bymax-one/nest-ai-tokens 1.0.2 → 1.0.3

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/CHANGELOG.md CHANGED
@@ -8,6 +8,35 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [1.0.3] - 2026-08-06
12
+
13
+ ### Fixed
14
+
15
+ - **Every suppression reason was dropped from the mutation report.** All 249 `// Stryker
16
+ disable` directives in the source wrote their justification after `--`. Stryker reads a
17
+ directive with one regular expression, `/^\s?Stryker (disable|restore)(?: (next-line))?
18
+ ([a-zA-Z, ]+)(?::(.+)?)?/`, whose mutator list accepts letters, commas and spaces only
19
+ and which captures the reason exclusively after a colon. A `-` therefore closed the
20
+ mutator list and left the reason unmatched, so each directive still silenced its mutant
21
+ but the report recorded Stryker's fallback text, `Ignored using a comment`. The README
22
+ claimed the opposite — that every suppression carries its reason — and documented the
23
+ broken separator as the convention. The directives now use `<Mutator>: <reason>`, which
24
+ is the grammar the parser accepts, and the reasons reach the report.
25
+
26
+ ### Added
27
+
28
+ - `check:mutants` gate (`scripts/check-mutation-directives.mjs`) — validates every
29
+ `// Stryker` comment against the parser's own regular expression, rejecting a reason
30
+ written after `--`, a reason wrapped onto a second comment line (the report keeps only
31
+ the first fragment), and a mutator name Stryker does not know, which would silence
32
+ nothing at all. Wired into CI and `prepublishOnly`. Stryker warns about the last case,
33
+ but only during a mutation run, which on this repo happens post-merge.
34
+
35
+ ### Changed
36
+
37
+ - No runtime behaviour changed. `dist/` differs only in the text of those comments; the
38
+ server bundle moved from 38,096 to 38,145 B brotli, well inside its 40,000 B budget.
39
+
11
40
  ## [1.0.2] - 2026-08-05
12
41
 
13
42
  ### Fixed
@@ -164,4 +193,5 @@ have regressed from. They are kept because the reasoning is worth having.
164
193
  [1.0.0]: https://github.com/bymaxone/nest-ai-tokens/releases/tag/v1.0.0
165
194
  [1.0.1]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.0...v1.0.1
166
195
  [1.0.2]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.1...v1.0.2
167
- [Unreleased]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.2...HEAD
196
+ [1.0.3]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.2...v1.0.3
197
+ [Unreleased]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.3...HEAD
package/README.md CHANGED
@@ -742,9 +742,11 @@ tests pass".
742
742
  system does, `check:runtime` loads every subpath from the packed tarball in ESM and
743
743
  CommonJS, and `check:published` compiles this README's snippets against `dist/`
744
744
  - ✅ **Every suppression carries its reason** — no coverage directives anywhere; each
745
- `// Stryker disable` in the production source states, after `--`, why the mutant it
746
- silences is unobservable from a unit test (an internal error context, a provider id
747
- reached only through integration)
745
+ `// Stryker disable` in the production source states, after the `:` Stryker reads it
746
+ from, why the mutant it silences is unobservable from a unit test (an internal error
747
+ context, a provider id reached only through integration). `check:mutants` proves the
748
+ reasons parse, so they reach the mutation report instead of being replaced by
749
+ Stryker's `Ignored using a comment` fallback
748
750
 
749
751
  ```bash
750
752
  pnpm test # unit tests
@@ -276,7 +276,7 @@ function computePayloadHash(record) {
276
276
  // src/server/utils/hash-chain.ts
277
277
  function chainHash(prevHash, record) {
278
278
  return deriveIdempotencyKey({
279
- // Stryker disable next-line StringLiteral -- empty-string fallback for null prevHash; tests only verify hash determinism and inequality, not the specific hash value for a genesis block
279
+ // Stryker disable next-line StringLiteral: empty-string fallback for null prevHash; tests only verify hash determinism and inequality, not the specific hash value for a genesis block
280
280
  prevHash: prevHash ?? "",
281
281
  id: record.id,
282
282
  content: computePayloadHash(record)
@@ -274,7 +274,7 @@ function computePayloadHash(record) {
274
274
  // src/server/utils/hash-chain.ts
275
275
  function chainHash(prevHash, record) {
276
276
  return deriveIdempotencyKey({
277
- // Stryker disable next-line StringLiteral -- empty-string fallback for null prevHash; tests only verify hash determinism and inequality, not the specific hash value for a genesis block
277
+ // Stryker disable next-line StringLiteral: empty-string fallback for null prevHash; tests only verify hash determinism and inequality, not the specific hash value for a genesis block
278
278
  prevHash: prevHash ?? "",
279
279
  id: record.id,
280
280
  content: computePayloadHash(record)
@@ -362,9 +362,9 @@ function normalizeMistralUsage(raw) {
362
362
  provider: "mistral",
363
363
  model: str(response.model) ?? "",
364
364
  operation: "chat",
365
- // Stryker disable next-line StringLiteral -- provider and field names in error messages are internal diagnostics
365
+ // Stryker disable next-line StringLiteral: provider and field names in error messages are internal diagnostics
366
366
  inputTokens: requireNum(usage.prompt_tokens, "mistral", "usage.prompt_tokens"),
367
- // Stryker disable next-line StringLiteral -- provider and field names in error messages are internal diagnostics
367
+ // Stryker disable next-line StringLiteral: provider and field names in error messages are internal diagnostics
368
368
  outputTokens: requireNum(usage.completion_tokens, "mistral", "usage.completion_tokens"),
369
369
  raw: usage
370
370
  });
@@ -808,7 +808,7 @@ function validatePricing(options) {
808
808
  if (cacheTtlMs === void 0) return;
809
809
  if (!Number.isInteger(cacheTtlMs) || cacheTtlMs <= 0) {
810
810
  throw invalidConfig(
811
- // Stryker disable next-line StringLiteral -- error reason template is internal diagnostics
811
+ // Stryker disable next-line StringLiteral: error reason template is internal diagnostics
812
812
  `pricing.cacheTtlMs must be a positive integer number of milliseconds, received ${String(cacheTtlMs)}`
813
813
  );
814
814
  }
@@ -1128,7 +1128,7 @@ exports.BudgetGuard = class BudgetGuard {
1128
1128
  this.reflector = reflector;
1129
1129
  if (options.scopeResolver === void 0) {
1130
1130
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
1131
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
1131
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
1132
1132
  reason: "BudgetGuard requires options.scopeResolver to resolve the caller scope"
1133
1133
  });
1134
1134
  }
@@ -1359,7 +1359,7 @@ function computePayloadHash(record) {
1359
1359
  // src/server/utils/hash-chain.ts
1360
1360
  function chainHash(prevHash, record) {
1361
1361
  return deriveIdempotencyKey({
1362
- // Stryker disable next-line StringLiteral -- empty-string fallback for null prevHash; tests only verify hash determinism and inequality, not the specific hash value for a genesis block
1362
+ // Stryker disable next-line StringLiteral: empty-string fallback for null prevHash; tests only verify hash determinism and inequality, not the specific hash value for a genesis block
1363
1363
  prevHash: prevHash ?? "",
1364
1364
  id: record.id,
1365
1365
  content: computePayloadHash(record)
@@ -1560,7 +1560,7 @@ exports.LedgerService = class LedgerService {
1560
1560
  const original = await this.store.findById(recordId);
1561
1561
  if (original?.status !== "posted") {
1562
1562
  throw new AiTokensException("AI_TOKENS_IDEMPOTENCY_CONFLICT", void 0, {
1563
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
1563
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
1564
1564
  reason: original === null ? "record not found" : `cannot reverse a ${original.status} record`,
1565
1565
  recordId,
1566
1566
  requestedReason: reason
@@ -1581,7 +1581,7 @@ exports.LedgerService = class LedgerService {
1581
1581
  assertLegalTransition(from2, to, patch) {
1582
1582
  if (!isLegalLedgerTransition(from2, to)) {
1583
1583
  throw new AiTokensException("AI_TOKENS_IDEMPOTENCY_CONFLICT", void 0, {
1584
- // Stryker disable next-line StringLiteral -- error reason template is internal diagnostics
1584
+ // Stryker disable next-line StringLiteral: error reason template is internal diagnostics
1585
1585
  reason: `illegal transition ${from2} \u2192 ${to}`
1586
1586
  });
1587
1587
  }
@@ -1589,7 +1589,7 @@ exports.LedgerService = class LedgerService {
1589
1589
  for (const key of Object.keys(patch)) {
1590
1590
  if (!isLegalTransitionPatchKey(from2, to, key)) {
1591
1591
  throw new AiTokensException("AI_TOKENS_IDEMPOTENCY_CONFLICT", void 0, {
1592
- // Stryker disable next-line StringLiteral -- error reason template is internal diagnostics
1592
+ // Stryker disable next-line StringLiteral: error reason template is internal diagnostics
1593
1593
  reason: `${from2} \u2192 ${to} may not patch "${key}"`
1594
1594
  });
1595
1595
  }
@@ -1608,13 +1608,13 @@ function buildCompensatingRecord(original) {
1608
1608
  return {
1609
1609
  tenantId: original.tenantId,
1610
1610
  scope: original.scope,
1611
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { beneficiary: undefined } is equivalent to {} because downstream consumers check !== undefined
1611
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { beneficiary: undefined } is equivalent to {} because downstream consumers check !== undefined
1612
1612
  ...original.beneficiary !== void 0 ? { beneficiary: original.beneficiary } : {},
1613
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestedBy: undefined } is equivalent to {}
1613
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestedBy: undefined } is equivalent to {}
1614
1614
  ...original.requestedBy !== void 0 ? { requestedBy: original.requestedBy } : {},
1615
1615
  provider: original.provider,
1616
1616
  model: original.model,
1617
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestedModel: undefined } is equivalent to {}
1617
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestedModel: undefined } is equivalent to {}
1618
1618
  ...original.requestedModel !== void 0 ? { requestedModel: original.requestedModel } : {},
1619
1619
  operation: original.operation,
1620
1620
  serviceTier: original.serviceTier,
@@ -1630,7 +1630,7 @@ function buildCompensatingRecord(original) {
1630
1630
  audioOutTokens: -original.audioOutTokens,
1631
1631
  imageInTokens: -original.imageInTokens,
1632
1632
  imageOutTokens: -original.imageOutTokens,
1633
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { extraUnits: undefined } is equivalent to {} because consumers check !== undefined
1633
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { extraUnits: undefined } is equivalent to {} because consumers check !== undefined
1634
1634
  ...original.extraUnits !== void 0 ? { extraUnits: negateUnits(original.extraUnits) } : {},
1635
1635
  priceVersionId: original.priceVersionId,
1636
1636
  rawCostNanoUsd: -original.rawCostNanoUsd,
@@ -1641,12 +1641,12 @@ function buildCompensatingRecord(original) {
1641
1641
  priceMissing: original.priceMissing,
1642
1642
  status: "posted",
1643
1643
  reversesRecordId: original.id,
1644
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { correlationId: undefined } is equivalent to {}
1644
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { correlationId: undefined } is equivalent to {}
1645
1645
  ...original.correlationId !== void 0 ? { correlationId: original.correlationId } : {},
1646
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestId: undefined } is equivalent to {}
1646
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestId: undefined } is equivalent to {}
1647
1647
  ...original.requestId !== void 0 ? { requestId: original.requestId } : {},
1648
1648
  isSystemCost: original.isSystemCost,
1649
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { systemCostCategory: undefined } is equivalent to {}
1649
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { systemCostCategory: undefined } is equivalent to {}
1650
1650
  ...original.systemCostCategory !== void 0 ? { systemCostCategory: original.systemCostCategory } : {},
1651
1651
  enforced: original.enforced,
1652
1652
  occurredAt: original.occurredAt
@@ -1683,7 +1683,7 @@ var MarkupResolver = class {
1683
1683
  return await policy.resolve(context);
1684
1684
  } catch {
1685
1685
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
1686
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
1686
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
1687
1687
  reason: "markup policy failed to resolve a multiplier"
1688
1688
  });
1689
1689
  }
@@ -1694,7 +1694,7 @@ var MarkupResolver = class {
1694
1694
  return resolveMultiplier4dp(raw);
1695
1695
  } catch {
1696
1696
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
1697
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
1697
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
1698
1698
  reason: "markup policy returned an invalid multiplier",
1699
1699
  value: raw
1700
1700
  });
@@ -2163,7 +2163,7 @@ async function resolveHoldEstimate(pricing, context, estimate, at) {
2163
2163
  operation: estimate.operation,
2164
2164
  serviceTier: tier,
2165
2165
  at,
2166
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { baseModel: undefined } is equivalent to {} because resolveRate reads input.baseModel (undefined either way) — same cache key and same `baseModel !== undefined` resolution branch
2166
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { baseModel: undefined } is equivalent to {} because resolveRate reads input.baseModel (undefined either way) — same cache key and same `baseModel !== undefined` resolution branch
2167
2167
  ...context.baseModel !== void 0 ? { baseModel: context.baseModel } : {}
2168
2168
  });
2169
2169
  const rawEstimateNanoUsd = rate === null ? 0n : computeCostNanoUsd(usage, rate).totalNanoUsd;
@@ -2187,7 +2187,7 @@ async function resolveHoldEstimate(pricing, context, estimate, at) {
2187
2187
  async function resolveTokenEstimate(pricing, context, tokens, serviceTier, at) {
2188
2188
  if (context.preset === void 0) {
2189
2189
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
2190
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
2190
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
2191
2191
  reason: "a { tokens } hold estimate requires context.preset to identify the provider"
2192
2192
  });
2193
2193
  }
@@ -2212,7 +2212,7 @@ function normalizeCaptureUsage(usage, normalizer) {
2212
2212
  }
2213
2213
  }
2214
2214
  throw new AiTokensException("AI_TOKENS_USAGE_MALFORMED", void 0, {
2215
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
2215
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
2216
2216
  reason: "capture requires an already-normalized usage or a preset normalizer"
2217
2217
  });
2218
2218
  }
@@ -2241,7 +2241,7 @@ function buildAppendInput(args) {
2241
2241
  audioOutTokens: normalized.audioOutTokens,
2242
2242
  imageInTokens: normalized.imageInTokens,
2243
2243
  imageOutTokens: normalized.imageOutTokens,
2244
- // Stryker disable next-line ConditionalExpression,EqualityOperator -- CE/EQ: when ratedUnits is empty, spreading { extraUnits: {} } vs omitting the key; downstream consumers check record.extraUnits !== undefined (absent vs present {}); unit tests don't use server tool use, so ratedUnits={} always → no observable difference
2244
+ // Stryker disable next-line ConditionalExpression,EqualityOperator: CE/EQ: when ratedUnits is empty, spreading { extraUnits: {} } vs omitting the key; downstream consumers check record.extraUnits !== undefined (absent vs present {}); unit tests don't use server tool use, so ratedUnits={} always → no observable difference
2245
2245
  ...Object.keys(ratedUnits).length > 0 ? { extraUnits: ratedUnits } : {},
2246
2246
  priceVersionId: rating.priceVersionId,
2247
2247
  rawCostNanoUsd: rating.rawCostNanoUsd,
@@ -2252,7 +2252,7 @@ function buildAppendInput(args) {
2252
2252
  priceMissing: rating.priceMissing,
2253
2253
  status: "posted",
2254
2254
  isSystemCost: context.isSystemCost ?? false,
2255
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { systemCostCategory: undefined } is equivalent to {} because JS property access treats absent and undefined the same
2255
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { systemCostCategory: undefined } is equivalent to {} because JS property access treats absent and undefined the same
2256
2256
  ...context.systemCostCategory !== void 0 ? { systemCostCategory: context.systemCostCategory } : {},
2257
2257
  enforced,
2258
2258
  occurredAt
@@ -2262,19 +2262,19 @@ function baseColumns(usage, context, serviceTier) {
2262
2262
  return {
2263
2263
  tenantId: context.tenantId,
2264
2264
  scope: context.scope,
2265
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { beneficiary: undefined } is equivalent to {} for property access and truthiness-based filters
2265
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { beneficiary: undefined } is equivalent to {} for property access and truthiness-based filters
2266
2266
  ...context.beneficiary !== void 0 ? { beneficiary: context.beneficiary } : {},
2267
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestedBy: undefined } is equivalent to {}
2267
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestedBy: undefined } is equivalent to {}
2268
2268
  ...context.requestedBy !== void 0 ? { requestedBy: context.requestedBy } : {},
2269
2269
  provider: usage.provider,
2270
2270
  model: usage.model,
2271
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestedModel: undefined } is equivalent to {} for downstream consumers
2271
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestedModel: undefined } is equivalent to {} for downstream consumers
2272
2272
  ...context.baseModel !== void 0 ? { requestedModel: context.baseModel } : {},
2273
2273
  operation: usage.operation,
2274
2274
  serviceTier,
2275
2275
  feature: context.feature,
2276
2276
  tags: context.tags ?? [],
2277
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { correlationId: undefined } is equivalent to {} because it's only read via record.correlationId
2277
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { correlationId: undefined } is equivalent to {} because it's only read via record.correlationId
2278
2278
  ...context.correlationId !== void 0 ? { correlationId: context.correlationId } : {}
2279
2279
  };
2280
2280
  }
@@ -2336,7 +2336,7 @@ exports.MeteringService = class MeteringService {
2336
2336
  const enforcing = context.enforce === true;
2337
2337
  if (enforcing && this.wallets === void 0 && this.budgets === void 0) {
2338
2338
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
2339
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
2339
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
2340
2340
  reason: "enforce requires the wallets or budgets feature to be enabled"
2341
2341
  });
2342
2342
  }
@@ -2391,7 +2391,7 @@ exports.MeteringService = class MeteringService {
2391
2391
  model: input.model,
2392
2392
  operation: input.operation,
2393
2393
  serviceTier,
2394
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { feature: undefined } is equivalent to {} because markup.resolve treats absent and undefined feature the same
2394
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { feature: undefined } is equivalent to {} because markup.resolve treats absent and undefined feature the same
2395
2395
  ...input.feature !== void 0 ? { feature: input.feature } : {}
2396
2396
  });
2397
2397
  return { rawCostNanoUsd, billedCostNanoUsd: markup.apply(rawCostNanoUsd) };
@@ -2593,7 +2593,7 @@ exports.MeteringService = class MeteringService {
2593
2593
  priceMissing: false,
2594
2594
  status: "pending",
2595
2595
  isSystemCost,
2596
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { systemCostCategory: undefined } is equivalent to {}
2596
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { systemCostCategory: undefined } is equivalent to {}
2597
2597
  ...context.systemCostCategory !== void 0 ? { systemCostCategory: context.systemCostCategory } : {},
2598
2598
  enforced: !isSystemCost,
2599
2599
  occurredAt
@@ -2691,7 +2691,7 @@ exports.MeteringService = class MeteringService {
2691
2691
  if (normalizer !== void 0) return this.normalize(normalizer, input.usage);
2692
2692
  if (isNormalizedUsage(input.usage)) return input.usage;
2693
2693
  throw new AiTokensException("AI_TOKENS_UNKNOWN_PROVIDER", void 0, {
2694
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
2694
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
2695
2695
  reason: "raw usage requires a preset or normalizer, or an already-normalized usage"
2696
2696
  });
2697
2697
  }
@@ -2794,7 +2794,7 @@ exports.WalletService = class WalletService {
2794
2794
  amountNanoUsd: input.amountNanoUsd,
2795
2795
  priority: input.priority ?? 0,
2796
2796
  effectiveAt: input.effectiveAt ?? /* @__PURE__ */ new Date(),
2797
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { expiresAt: undefined } is equivalent to {} because InMemoryWalletStore and consumers check expiresAt !== undefined
2797
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { expiresAt: undefined } is equivalent to {} because InMemoryWalletStore and consumers check expiresAt !== undefined
2798
2798
  ...input.expiresAt !== void 0 ? { expiresAt: input.expiresAt } : {},
2799
2799
  idempotencyKey: input.idempotencyKey,
2800
2800
  reason: input.reason
@@ -2803,7 +2803,7 @@ exports.WalletService = class WalletService {
2803
2803
  walletId: entry.walletId,
2804
2804
  entryId: entry.id,
2805
2805
  amountNanoUsd: entry.amountNanoUsd,
2806
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { expiresAt: undefined } is equivalent to {} because event consumers check expiresAt !== undefined
2806
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { expiresAt: undefined } is equivalent to {} because event consumers check expiresAt !== undefined
2807
2807
  ...entry.expiresAt !== void 0 ? { expiresAt: entry.expiresAt } : {}
2808
2808
  };
2809
2809
  await this.events.granted(ref, granted);
@@ -2834,16 +2834,16 @@ exports.WalletService = class WalletService {
2834
2834
  throw this.invalid("a debit without a usageRecordId must carry a reason");
2835
2835
  }
2836
2836
  const entry = {
2837
- // Stryker disable next-line StringLiteral -- placeholder walletId; the store's insert always assigns the real wallet id and never reads this sentinel, so any string here is equivalent
2837
+ // Stryker disable next-line StringLiteral: placeholder walletId; the store's insert always assigns the real wallet id and never reads this sentinel, so any string here is equivalent
2838
2838
  walletId: "",
2839
2839
  type: "debit",
2840
2840
  amountNanoUsd: -input.amountNanoUsd,
2841
2841
  priority: 0,
2842
2842
  effectiveAt: /* @__PURE__ */ new Date(),
2843
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2843
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2844
2844
  ...input.usageRecordId !== void 0 ? { usageRecordId: input.usageRecordId } : {},
2845
2845
  idempotencyKey: input.idempotencyKey,
2846
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { reason: undefined } is equivalent to {} because store and consumers check reason !== undefined
2846
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { reason: undefined } is equivalent to {} because store and consumers check reason !== undefined
2847
2847
  ...input.reason !== void 0 ? { reason: input.reason } : {}
2848
2848
  };
2849
2849
  const debited = await this.conditionalDebit(ref, entry, input.amountNanoUsd);
@@ -2870,7 +2870,7 @@ exports.WalletService = class WalletService {
2870
2870
  amountNanoUsd: input.amountNanoUsd,
2871
2871
  priority: 0,
2872
2872
  effectiveAt: /* @__PURE__ */ new Date(),
2873
- // Stryker disable next-line ConditionalExpression,ObjectLiteral -- CE true / OL {}: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2873
+ // Stryker disable next-line ConditionalExpression,ObjectLiteral: CE true / OL {}: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2874
2874
  ...input.usageRecordId !== void 0 ? { usageRecordId: input.usageRecordId } : {},
2875
2875
  idempotencyKey: input.idempotencyKey,
2876
2876
  reason: input.reason
@@ -2927,8 +2927,8 @@ exports.WalletService = class WalletService {
2927
2927
  amountNanoUsd: input.amountNanoUsd,
2928
2928
  priority: 0,
2929
2929
  effectiveAt: /* @__PURE__ */ new Date(),
2930
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2931
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2930
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2931
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2932
2932
  ...input.usageRecordId !== void 0 ? { usageRecordId: input.usageRecordId } : {},
2933
2933
  idempotencyKey: input.idempotencyKey,
2934
2934
  reason: input.reason
@@ -3560,11 +3560,11 @@ function featureMatches3(features, feature) {
3560
3560
  }
3561
3561
  function limitsOf(budget) {
3562
3562
  return {
3563
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { nanoUsd: undefined } is equivalent to {} because all consumers check limits.nanoUsd !== undefined
3563
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { nanoUsd: undefined } is equivalent to {} because all consumers check limits.nanoUsd !== undefined
3564
3564
  ...budget.limitNanoUsd !== void 0 ? { nanoUsd: budget.limitNanoUsd } : {},
3565
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { tokens: undefined } is equivalent to {} because all consumers check limits.tokens !== undefined
3565
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { tokens: undefined } is equivalent to {} because all consumers check limits.tokens !== undefined
3566
3566
  ...budget.limitTokens !== void 0 ? { tokens: budget.limitTokens } : {},
3567
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { count: undefined } is equivalent to {} because all consumers check limits.count !== undefined
3567
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { count: undefined } is equivalent to {} because all consumers check limits.count !== undefined
3568
3568
  ...budget.limitCount !== void 0 ? { count: budget.limitCount } : {}
3569
3569
  };
3570
3570
  }
@@ -3604,11 +3604,11 @@ function ratio(spent, limit) {
3604
3604
  }
3605
3605
  function limitSnapshot(limits) {
3606
3606
  return {
3607
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { nanoUsd: undefined } is equivalent to {} for event consumers who check field !== undefined
3607
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { nanoUsd: undefined } is equivalent to {} for event consumers who check field !== undefined
3608
3608
  ...limits.nanoUsd !== void 0 ? { nanoUsd: limits.nanoUsd } : {},
3609
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { tokens: undefined } is equivalent to {} for event consumers who check field !== undefined
3609
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { tokens: undefined } is equivalent to {} for event consumers who check field !== undefined
3610
3610
  ...limits.tokens !== void 0 ? { tokens: limits.tokens } : {},
3611
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { count: undefined } is equivalent to {} for event consumers who check field !== undefined
3611
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { count: undefined } is equivalent to {} for event consumers who check field !== undefined
3612
3612
  ...limits.count !== void 0 ? { count: limits.count } : {}
3613
3613
  };
3614
3614
  }
@@ -3617,11 +3617,11 @@ function spendSnapshot(spend) {
3617
3617
  }
3618
3618
  function remainingSnapshot(limits, spend) {
3619
3619
  return {
3620
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { nanoUsd: undefined } is equivalent to {} for event consumers who check field !== undefined
3620
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { nanoUsd: undefined } is equivalent to {} for event consumers who check field !== undefined
3621
3621
  ...limits.nanoUsd !== void 0 ? { nanoUsd: max0(limits.nanoUsd - spend.spentNanoUsd) } : {},
3622
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { tokens: undefined } is equivalent to {} for event consumers who check field !== undefined
3622
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { tokens: undefined } is equivalent to {} for event consumers who check field !== undefined
3623
3623
  ...limits.tokens !== void 0 ? { tokens: Math.max(0, limits.tokens - spend.spentTokens) } : {},
3624
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { count: undefined } is equivalent to {} for event consumers who check field !== undefined
3624
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { count: undefined } is equivalent to {} for event consumers who check field !== undefined
3625
3625
  ...limits.count !== void 0 ? { count: Math.max(0, limits.count - spend.spentCount) } : {}
3626
3626
  };
3627
3627
  }
@@ -3629,7 +3629,7 @@ function buildStatus(budget, windowStart, resetsAt, spend) {
3629
3629
  const limits = limitsOf(budget);
3630
3630
  return {
3631
3631
  budgetId: budget.id,
3632
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { features: undefined } is equivalent to {} because status consumers check features !== undefined
3632
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { features: undefined } is equivalent to {} because status consumers check features !== undefined
3633
3633
  ...budget.features !== void 0 ? { features: budget.features } : {},
3634
3634
  window: budget.window,
3635
3635
  windowStart,
@@ -3796,29 +3796,29 @@ exports.UsageReportService = __decorateClass([
3796
3796
  function toLedgerFilter(filter, limit) {
3797
3797
  return {
3798
3798
  tenantId: filter.tenantId,
3799
- // Stryker disable next-line ConditionalExpression -- spreading { scope: undefined } is equivalent to {} because InMemoryLedgerStore uses truthiness; the 'false' variant is covered by the scope isolation test
3799
+ // Stryker disable next-line ConditionalExpression: spreading { scope: undefined } is equivalent to {} because InMemoryLedgerStore uses truthiness; the 'false' variant is covered by the scope isolation test
3800
3800
  ...filter.scope !== void 0 ? { scope: filter.scope } : {},
3801
- // Stryker disable next-line ConditionalExpression -- spreading { beneficiary: undefined } is equivalent to {} for the same reason
3801
+ // Stryker disable next-line ConditionalExpression: spreading { beneficiary: undefined } is equivalent to {} for the same reason
3802
3802
  ...filter.beneficiary !== void 0 ? { beneficiary: filter.beneficiary } : {},
3803
- // Stryker disable next-line ConditionalExpression -- spreading { feature: undefined } does not change the !== undefined check in matches()
3803
+ // Stryker disable next-line ConditionalExpression: spreading { feature: undefined } does not change the !== undefined check in matches()
3804
3804
  ...filter.feature !== void 0 ? { feature: filter.feature } : {},
3805
- // Stryker disable next-line ConditionalExpression -- spreading { features: undefined } does not change the truthiness check in matches()
3805
+ // Stryker disable next-line ConditionalExpression: spreading { features: undefined } does not change the truthiness check in matches()
3806
3806
  ...filter.features !== void 0 ? { features: filter.features } : {},
3807
- // Stryker disable next-line ConditionalExpression -- spreading { provider: undefined } does not change the !== undefined check in matches()
3807
+ // Stryker disable next-line ConditionalExpression: spreading { provider: undefined } does not change the !== undefined check in matches()
3808
3808
  ...filter.provider !== void 0 ? { provider: filter.provider } : {},
3809
- // Stryker disable next-line ConditionalExpression -- spreading { model: undefined } does not change the !== undefined check in matches()
3809
+ // Stryker disable next-line ConditionalExpression: spreading { model: undefined } does not change the !== undefined check in matches()
3810
3810
  ...filter.model !== void 0 ? { model: filter.model } : {},
3811
- // Stryker disable next-line ConditionalExpression -- spreading { operation: undefined } does not change the !== undefined check in matches()
3811
+ // Stryker disable next-line ConditionalExpression: spreading { operation: undefined } does not change the !== undefined check in matches()
3812
3812
  ...filter.operation !== void 0 ? { operation: filter.operation } : {},
3813
- // Stryker disable next-line ConditionalExpression -- spreading { serviceTier: undefined } does not change the !== undefined check in matches()
3813
+ // Stryker disable next-line ConditionalExpression: spreading { serviceTier: undefined } does not change the !== undefined check in matches()
3814
3814
  ...filter.serviceTier !== void 0 ? { serviceTier: filter.serviceTier } : {},
3815
- // Stryker disable next-line ConditionalExpression -- spreading { tags: undefined } does not change the truthiness check in matches()
3815
+ // Stryker disable next-line ConditionalExpression: spreading { tags: undefined } does not change the truthiness check in matches()
3816
3816
  ...filter.tags !== void 0 ? { tags: filter.tags } : {},
3817
- // Stryker disable next-line ConditionalExpression -- spreading { isSystemCost: undefined } does not change the !== undefined check in matches()
3817
+ // Stryker disable next-line ConditionalExpression: spreading { isSystemCost: undefined } does not change the !== undefined check in matches()
3818
3818
  ...filter.isSystemCost !== void 0 ? { isSystemCost: filter.isSystemCost } : {},
3819
- // Stryker disable next-line ConditionalExpression -- spreading { systemCostCategory: undefined } does not change the !== undefined check in matches()
3819
+ // Stryker disable next-line ConditionalExpression: spreading { systemCostCategory: undefined } does not change the !== undefined check in matches()
3820
3820
  ...filter.systemCostCategory !== void 0 ? { systemCostCategory: filter.systemCostCategory } : {},
3821
- // Stryker disable next-line ConditionalExpression -- spreading { enforcedOnly: undefined } does not change the === true check in matches()
3821
+ // Stryker disable next-line ConditionalExpression: spreading { enforcedOnly: undefined } does not change the === true check in matches()
3822
3822
  ...filter.enforcedOnly !== void 0 ? { enforcedOnly: filter.enforcedOnly } : {},
3823
3823
  status: filter.status ?? [...BALANCE_STATUSES2],
3824
3824
  from: filter.from,
@@ -4004,9 +4004,9 @@ exports.MeteringInterceptor = class MeteringInterceptor {
4004
4004
  const context = await this.resolveContext(executionContext, config, enrichment);
4005
4005
  return this.metering.record({
4006
4006
  usage,
4007
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { preset: undefined } is equivalent to {} because MeteringService checks preset !== undefined
4007
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { preset: undefined } is equivalent to {} because MeteringService checks preset !== undefined
4008
4008
  ...config.preset !== void 0 ? { preset: config.preset } : {},
4009
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { tags: undefined } is equivalent to {} because MeteringService checks tags !== undefined
4009
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { tags: undefined } is equivalent to {} because MeteringService checks tags !== undefined
4010
4010
  context: { ...context, enforce: true, isSystemCost: config.isSystemCost ?? false, ...config.tags !== void 0 ? { tags: config.tags } : {} }
4011
4011
  });
4012
4012
  }
@@ -4334,24 +4334,24 @@ function preset(provider, normalizer, ratingMode) {
4334
4334
  return { provider, normalizer, ratingMode };
4335
4335
  }
4336
4336
  var providerPresets = {
4337
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests that exercise the full preset→MeteringService→UsageRecord path
4337
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests that exercise the full preset→MeteringService→UsageRecord path
4338
4338
  openaiChat: preset("openai", normalizeOpenAiChatUsage, "rate-table"),
4339
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4339
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4340
4340
  openaiResponses: preset("openai", normalizeOpenAiResponsesUsage, "rate-table"),
4341
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4341
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4342
4342
  azureOpenai: preset("azure-openai", normalizeOpenAiChatUsage, "rate-table"),
4343
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4343
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4344
4344
  anthropic: preset("anthropic", normalizeAnthropicUsage, "rate-table"),
4345
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4345
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4346
4346
  gemini: preset("gemini", normalizeGeminiUsage, "rate-table"),
4347
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4347
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4348
4348
  vertex: preset("vertex", normalizeGeminiUsage, "rate-table"),
4349
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4349
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4350
4350
  bedrock: preset("bedrock", normalizeBedrockConverseUsage, "rate-table"),
4351
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4351
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4352
4352
  mistral: preset("mistral", normalizeMistralUsage, "rate-table"),
4353
4353
  vercelAiSdk: preset("openai", normalizeVercelAiSdkUsage, "rate-table"),
4354
- // Stryker disable next-line StringLiteral -- provider ID and rating mode; only observable via integration tests
4354
+ // Stryker disable next-line StringLiteral: provider ID and rating mode; only observable via integration tests
4355
4355
  openrouter: preset("openrouter", normalizeOpenRouterUsage, "provider-reported"),
4356
4356
  /** A custom OpenAI-compatible provider (DeepSeek, xAI, Groq, …). */
4357
4357
  openaiCompatible: (id) => preset(id, normalizeOpenAiCompatibleUsage, "rate-table")
@@ -360,9 +360,9 @@ function normalizeMistralUsage(raw) {
360
360
  provider: "mistral",
361
361
  model: str(response.model) ?? "",
362
362
  operation: "chat",
363
- // Stryker disable next-line StringLiteral -- provider and field names in error messages are internal diagnostics
363
+ // Stryker disable next-line StringLiteral: provider and field names in error messages are internal diagnostics
364
364
  inputTokens: requireNum(usage.prompt_tokens, "mistral", "usage.prompt_tokens"),
365
- // Stryker disable next-line StringLiteral -- provider and field names in error messages are internal diagnostics
365
+ // Stryker disable next-line StringLiteral: provider and field names in error messages are internal diagnostics
366
366
  outputTokens: requireNum(usage.completion_tokens, "mistral", "usage.completion_tokens"),
367
367
  raw: usage
368
368
  });
@@ -806,7 +806,7 @@ function validatePricing(options) {
806
806
  if (cacheTtlMs === void 0) return;
807
807
  if (!Number.isInteger(cacheTtlMs) || cacheTtlMs <= 0) {
808
808
  throw invalidConfig(
809
- // Stryker disable next-line StringLiteral -- error reason template is internal diagnostics
809
+ // Stryker disable next-line StringLiteral: error reason template is internal diagnostics
810
810
  `pricing.cacheTtlMs must be a positive integer number of milliseconds, received ${String(cacheTtlMs)}`
811
811
  );
812
812
  }
@@ -1126,7 +1126,7 @@ var BudgetGuard = class {
1126
1126
  this.reflector = reflector;
1127
1127
  if (options.scopeResolver === void 0) {
1128
1128
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
1129
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
1129
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
1130
1130
  reason: "BudgetGuard requires options.scopeResolver to resolve the caller scope"
1131
1131
  });
1132
1132
  }
@@ -1357,7 +1357,7 @@ function computePayloadHash(record) {
1357
1357
  // src/server/utils/hash-chain.ts
1358
1358
  function chainHash(prevHash, record) {
1359
1359
  return deriveIdempotencyKey({
1360
- // Stryker disable next-line StringLiteral -- empty-string fallback for null prevHash; tests only verify hash determinism and inequality, not the specific hash value for a genesis block
1360
+ // Stryker disable next-line StringLiteral: empty-string fallback for null prevHash; tests only verify hash determinism and inequality, not the specific hash value for a genesis block
1361
1361
  prevHash: prevHash ?? "",
1362
1362
  id: record.id,
1363
1363
  content: computePayloadHash(record)
@@ -1558,7 +1558,7 @@ var LedgerService = class {
1558
1558
  const original = await this.store.findById(recordId);
1559
1559
  if (original?.status !== "posted") {
1560
1560
  throw new AiTokensException("AI_TOKENS_IDEMPOTENCY_CONFLICT", void 0, {
1561
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
1561
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
1562
1562
  reason: original === null ? "record not found" : `cannot reverse a ${original.status} record`,
1563
1563
  recordId,
1564
1564
  requestedReason: reason
@@ -1579,7 +1579,7 @@ var LedgerService = class {
1579
1579
  assertLegalTransition(from2, to, patch) {
1580
1580
  if (!isLegalLedgerTransition(from2, to)) {
1581
1581
  throw new AiTokensException("AI_TOKENS_IDEMPOTENCY_CONFLICT", void 0, {
1582
- // Stryker disable next-line StringLiteral -- error reason template is internal diagnostics
1582
+ // Stryker disable next-line StringLiteral: error reason template is internal diagnostics
1583
1583
  reason: `illegal transition ${from2} \u2192 ${to}`
1584
1584
  });
1585
1585
  }
@@ -1587,7 +1587,7 @@ var LedgerService = class {
1587
1587
  for (const key of Object.keys(patch)) {
1588
1588
  if (!isLegalTransitionPatchKey(from2, to, key)) {
1589
1589
  throw new AiTokensException("AI_TOKENS_IDEMPOTENCY_CONFLICT", void 0, {
1590
- // Stryker disable next-line StringLiteral -- error reason template is internal diagnostics
1590
+ // Stryker disable next-line StringLiteral: error reason template is internal diagnostics
1591
1591
  reason: `${from2} \u2192 ${to} may not patch "${key}"`
1592
1592
  });
1593
1593
  }
@@ -1606,13 +1606,13 @@ function buildCompensatingRecord(original) {
1606
1606
  return {
1607
1607
  tenantId: original.tenantId,
1608
1608
  scope: original.scope,
1609
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { beneficiary: undefined } is equivalent to {} because downstream consumers check !== undefined
1609
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { beneficiary: undefined } is equivalent to {} because downstream consumers check !== undefined
1610
1610
  ...original.beneficiary !== void 0 ? { beneficiary: original.beneficiary } : {},
1611
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestedBy: undefined } is equivalent to {}
1611
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestedBy: undefined } is equivalent to {}
1612
1612
  ...original.requestedBy !== void 0 ? { requestedBy: original.requestedBy } : {},
1613
1613
  provider: original.provider,
1614
1614
  model: original.model,
1615
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestedModel: undefined } is equivalent to {}
1615
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestedModel: undefined } is equivalent to {}
1616
1616
  ...original.requestedModel !== void 0 ? { requestedModel: original.requestedModel } : {},
1617
1617
  operation: original.operation,
1618
1618
  serviceTier: original.serviceTier,
@@ -1628,7 +1628,7 @@ function buildCompensatingRecord(original) {
1628
1628
  audioOutTokens: -original.audioOutTokens,
1629
1629
  imageInTokens: -original.imageInTokens,
1630
1630
  imageOutTokens: -original.imageOutTokens,
1631
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { extraUnits: undefined } is equivalent to {} because consumers check !== undefined
1631
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { extraUnits: undefined } is equivalent to {} because consumers check !== undefined
1632
1632
  ...original.extraUnits !== void 0 ? { extraUnits: negateUnits(original.extraUnits) } : {},
1633
1633
  priceVersionId: original.priceVersionId,
1634
1634
  rawCostNanoUsd: -original.rawCostNanoUsd,
@@ -1639,12 +1639,12 @@ function buildCompensatingRecord(original) {
1639
1639
  priceMissing: original.priceMissing,
1640
1640
  status: "posted",
1641
1641
  reversesRecordId: original.id,
1642
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { correlationId: undefined } is equivalent to {}
1642
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { correlationId: undefined } is equivalent to {}
1643
1643
  ...original.correlationId !== void 0 ? { correlationId: original.correlationId } : {},
1644
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestId: undefined } is equivalent to {}
1644
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestId: undefined } is equivalent to {}
1645
1645
  ...original.requestId !== void 0 ? { requestId: original.requestId } : {},
1646
1646
  isSystemCost: original.isSystemCost,
1647
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { systemCostCategory: undefined } is equivalent to {}
1647
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { systemCostCategory: undefined } is equivalent to {}
1648
1648
  ...original.systemCostCategory !== void 0 ? { systemCostCategory: original.systemCostCategory } : {},
1649
1649
  enforced: original.enforced,
1650
1650
  occurredAt: original.occurredAt
@@ -1681,7 +1681,7 @@ var MarkupResolver = class {
1681
1681
  return await policy.resolve(context);
1682
1682
  } catch {
1683
1683
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
1684
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
1684
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
1685
1685
  reason: "markup policy failed to resolve a multiplier"
1686
1686
  });
1687
1687
  }
@@ -1692,7 +1692,7 @@ var MarkupResolver = class {
1692
1692
  return resolveMultiplier4dp(raw);
1693
1693
  } catch {
1694
1694
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
1695
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
1695
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
1696
1696
  reason: "markup policy returned an invalid multiplier",
1697
1697
  value: raw
1698
1698
  });
@@ -2161,7 +2161,7 @@ async function resolveHoldEstimate(pricing, context, estimate, at) {
2161
2161
  operation: estimate.operation,
2162
2162
  serviceTier: tier,
2163
2163
  at,
2164
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { baseModel: undefined } is equivalent to {} because resolveRate reads input.baseModel (undefined either way) — same cache key and same `baseModel !== undefined` resolution branch
2164
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { baseModel: undefined } is equivalent to {} because resolveRate reads input.baseModel (undefined either way) — same cache key and same `baseModel !== undefined` resolution branch
2165
2165
  ...context.baseModel !== void 0 ? { baseModel: context.baseModel } : {}
2166
2166
  });
2167
2167
  const rawEstimateNanoUsd = rate === null ? 0n : computeCostNanoUsd(usage, rate).totalNanoUsd;
@@ -2185,7 +2185,7 @@ async function resolveHoldEstimate(pricing, context, estimate, at) {
2185
2185
  async function resolveTokenEstimate(pricing, context, tokens, serviceTier, at) {
2186
2186
  if (context.preset === void 0) {
2187
2187
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
2188
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
2188
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
2189
2189
  reason: "a { tokens } hold estimate requires context.preset to identify the provider"
2190
2190
  });
2191
2191
  }
@@ -2210,7 +2210,7 @@ function normalizeCaptureUsage(usage, normalizer) {
2210
2210
  }
2211
2211
  }
2212
2212
  throw new AiTokensException("AI_TOKENS_USAGE_MALFORMED", void 0, {
2213
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
2213
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
2214
2214
  reason: "capture requires an already-normalized usage or a preset normalizer"
2215
2215
  });
2216
2216
  }
@@ -2239,7 +2239,7 @@ function buildAppendInput(args) {
2239
2239
  audioOutTokens: normalized.audioOutTokens,
2240
2240
  imageInTokens: normalized.imageInTokens,
2241
2241
  imageOutTokens: normalized.imageOutTokens,
2242
- // Stryker disable next-line ConditionalExpression,EqualityOperator -- CE/EQ: when ratedUnits is empty, spreading { extraUnits: {} } vs omitting the key; downstream consumers check record.extraUnits !== undefined (absent vs present {}); unit tests don't use server tool use, so ratedUnits={} always → no observable difference
2242
+ // Stryker disable next-line ConditionalExpression,EqualityOperator: CE/EQ: when ratedUnits is empty, spreading { extraUnits: {} } vs omitting the key; downstream consumers check record.extraUnits !== undefined (absent vs present {}); unit tests don't use server tool use, so ratedUnits={} always → no observable difference
2243
2243
  ...Object.keys(ratedUnits).length > 0 ? { extraUnits: ratedUnits } : {},
2244
2244
  priceVersionId: rating.priceVersionId,
2245
2245
  rawCostNanoUsd: rating.rawCostNanoUsd,
@@ -2250,7 +2250,7 @@ function buildAppendInput(args) {
2250
2250
  priceMissing: rating.priceMissing,
2251
2251
  status: "posted",
2252
2252
  isSystemCost: context.isSystemCost ?? false,
2253
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { systemCostCategory: undefined } is equivalent to {} because JS property access treats absent and undefined the same
2253
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { systemCostCategory: undefined } is equivalent to {} because JS property access treats absent and undefined the same
2254
2254
  ...context.systemCostCategory !== void 0 ? { systemCostCategory: context.systemCostCategory } : {},
2255
2255
  enforced,
2256
2256
  occurredAt
@@ -2260,19 +2260,19 @@ function baseColumns(usage, context, serviceTier) {
2260
2260
  return {
2261
2261
  tenantId: context.tenantId,
2262
2262
  scope: context.scope,
2263
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { beneficiary: undefined } is equivalent to {} for property access and truthiness-based filters
2263
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { beneficiary: undefined } is equivalent to {} for property access and truthiness-based filters
2264
2264
  ...context.beneficiary !== void 0 ? { beneficiary: context.beneficiary } : {},
2265
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestedBy: undefined } is equivalent to {}
2265
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestedBy: undefined } is equivalent to {}
2266
2266
  ...context.requestedBy !== void 0 ? { requestedBy: context.requestedBy } : {},
2267
2267
  provider: usage.provider,
2268
2268
  model: usage.model,
2269
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { requestedModel: undefined } is equivalent to {} for downstream consumers
2269
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { requestedModel: undefined } is equivalent to {} for downstream consumers
2270
2270
  ...context.baseModel !== void 0 ? { requestedModel: context.baseModel } : {},
2271
2271
  operation: usage.operation,
2272
2272
  serviceTier,
2273
2273
  feature: context.feature,
2274
2274
  tags: context.tags ?? [],
2275
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { correlationId: undefined } is equivalent to {} because it's only read via record.correlationId
2275
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { correlationId: undefined } is equivalent to {} because it's only read via record.correlationId
2276
2276
  ...context.correlationId !== void 0 ? { correlationId: context.correlationId } : {}
2277
2277
  };
2278
2278
  }
@@ -2334,7 +2334,7 @@ var MeteringService = class {
2334
2334
  const enforcing = context.enforce === true;
2335
2335
  if (enforcing && this.wallets === void 0 && this.budgets === void 0) {
2336
2336
  throw new AiTokensException("AI_TOKENS_INVALID_CONFIG", void 0, {
2337
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
2337
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
2338
2338
  reason: "enforce requires the wallets or budgets feature to be enabled"
2339
2339
  });
2340
2340
  }
@@ -2389,7 +2389,7 @@ var MeteringService = class {
2389
2389
  model: input.model,
2390
2390
  operation: input.operation,
2391
2391
  serviceTier,
2392
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { feature: undefined } is equivalent to {} because markup.resolve treats absent and undefined feature the same
2392
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { feature: undefined } is equivalent to {} because markup.resolve treats absent and undefined feature the same
2393
2393
  ...input.feature !== void 0 ? { feature: input.feature } : {}
2394
2394
  });
2395
2395
  return { rawCostNanoUsd, billedCostNanoUsd: markup.apply(rawCostNanoUsd) };
@@ -2591,7 +2591,7 @@ var MeteringService = class {
2591
2591
  priceMissing: false,
2592
2592
  status: "pending",
2593
2593
  isSystemCost,
2594
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { systemCostCategory: undefined } is equivalent to {}
2594
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { systemCostCategory: undefined } is equivalent to {}
2595
2595
  ...context.systemCostCategory !== void 0 ? { systemCostCategory: context.systemCostCategory } : {},
2596
2596
  enforced: !isSystemCost,
2597
2597
  occurredAt
@@ -2689,7 +2689,7 @@ var MeteringService = class {
2689
2689
  if (normalizer !== void 0) return this.normalize(normalizer, input.usage);
2690
2690
  if (isNormalizedUsage(input.usage)) return input.usage;
2691
2691
  throw new AiTokensException("AI_TOKENS_UNKNOWN_PROVIDER", void 0, {
2692
- // Stryker disable next-line StringLiteral -- error reason text is internal diagnostics
2692
+ // Stryker disable next-line StringLiteral: error reason text is internal diagnostics
2693
2693
  reason: "raw usage requires a preset or normalizer, or an already-normalized usage"
2694
2694
  });
2695
2695
  }
@@ -2792,7 +2792,7 @@ var WalletService = class {
2792
2792
  amountNanoUsd: input.amountNanoUsd,
2793
2793
  priority: input.priority ?? 0,
2794
2794
  effectiveAt: input.effectiveAt ?? /* @__PURE__ */ new Date(),
2795
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { expiresAt: undefined } is equivalent to {} because InMemoryWalletStore and consumers check expiresAt !== undefined
2795
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { expiresAt: undefined } is equivalent to {} because InMemoryWalletStore and consumers check expiresAt !== undefined
2796
2796
  ...input.expiresAt !== void 0 ? { expiresAt: input.expiresAt } : {},
2797
2797
  idempotencyKey: input.idempotencyKey,
2798
2798
  reason: input.reason
@@ -2801,7 +2801,7 @@ var WalletService = class {
2801
2801
  walletId: entry.walletId,
2802
2802
  entryId: entry.id,
2803
2803
  amountNanoUsd: entry.amountNanoUsd,
2804
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { expiresAt: undefined } is equivalent to {} because event consumers check expiresAt !== undefined
2804
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { expiresAt: undefined } is equivalent to {} because event consumers check expiresAt !== undefined
2805
2805
  ...entry.expiresAt !== void 0 ? { expiresAt: entry.expiresAt } : {}
2806
2806
  };
2807
2807
  await this.events.granted(ref, granted);
@@ -2832,16 +2832,16 @@ var WalletService = class {
2832
2832
  throw this.invalid("a debit without a usageRecordId must carry a reason");
2833
2833
  }
2834
2834
  const entry = {
2835
- // Stryker disable next-line StringLiteral -- placeholder walletId; the store's insert always assigns the real wallet id and never reads this sentinel, so any string here is equivalent
2835
+ // Stryker disable next-line StringLiteral: placeholder walletId; the store's insert always assigns the real wallet id and never reads this sentinel, so any string here is equivalent
2836
2836
  walletId: "",
2837
2837
  type: "debit",
2838
2838
  amountNanoUsd: -input.amountNanoUsd,
2839
2839
  priority: 0,
2840
2840
  effectiveAt: /* @__PURE__ */ new Date(),
2841
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2841
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2842
2842
  ...input.usageRecordId !== void 0 ? { usageRecordId: input.usageRecordId } : {},
2843
2843
  idempotencyKey: input.idempotencyKey,
2844
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { reason: undefined } is equivalent to {} because store and consumers check reason !== undefined
2844
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { reason: undefined } is equivalent to {} because store and consumers check reason !== undefined
2845
2845
  ...input.reason !== void 0 ? { reason: input.reason } : {}
2846
2846
  };
2847
2847
  const debited = await this.conditionalDebit(ref, entry, input.amountNanoUsd);
@@ -2868,7 +2868,7 @@ var WalletService = class {
2868
2868
  amountNanoUsd: input.amountNanoUsd,
2869
2869
  priority: 0,
2870
2870
  effectiveAt: /* @__PURE__ */ new Date(),
2871
- // Stryker disable next-line ConditionalExpression,ObjectLiteral -- CE true / OL {}: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2871
+ // Stryker disable next-line ConditionalExpression,ObjectLiteral: CE true / OL {}: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2872
2872
  ...input.usageRecordId !== void 0 ? { usageRecordId: input.usageRecordId } : {},
2873
2873
  idempotencyKey: input.idempotencyKey,
2874
2874
  reason: input.reason
@@ -2925,8 +2925,8 @@ var WalletService = class {
2925
2925
  amountNanoUsd: input.amountNanoUsd,
2926
2926
  priority: 0,
2927
2927
  effectiveAt: /* @__PURE__ */ new Date(),
2928
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2929
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2928
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2929
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { usageRecordId: undefined } is equivalent to {} because store and consumers check usageRecordId !== undefined
2930
2930
  ...input.usageRecordId !== void 0 ? { usageRecordId: input.usageRecordId } : {},
2931
2931
  idempotencyKey: input.idempotencyKey,
2932
2932
  reason: input.reason
@@ -3558,11 +3558,11 @@ function featureMatches3(features, feature) {
3558
3558
  }
3559
3559
  function limitsOf(budget) {
3560
3560
  return {
3561
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { nanoUsd: undefined } is equivalent to {} because all consumers check limits.nanoUsd !== undefined
3561
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { nanoUsd: undefined } is equivalent to {} because all consumers check limits.nanoUsd !== undefined
3562
3562
  ...budget.limitNanoUsd !== void 0 ? { nanoUsd: budget.limitNanoUsd } : {},
3563
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { tokens: undefined } is equivalent to {} because all consumers check limits.tokens !== undefined
3563
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { tokens: undefined } is equivalent to {} because all consumers check limits.tokens !== undefined
3564
3564
  ...budget.limitTokens !== void 0 ? { tokens: budget.limitTokens } : {},
3565
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { count: undefined } is equivalent to {} because all consumers check limits.count !== undefined
3565
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { count: undefined } is equivalent to {} because all consumers check limits.count !== undefined
3566
3566
  ...budget.limitCount !== void 0 ? { count: budget.limitCount } : {}
3567
3567
  };
3568
3568
  }
@@ -3602,11 +3602,11 @@ function ratio(spent, limit) {
3602
3602
  }
3603
3603
  function limitSnapshot(limits) {
3604
3604
  return {
3605
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { nanoUsd: undefined } is equivalent to {} for event consumers who check field !== undefined
3605
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { nanoUsd: undefined } is equivalent to {} for event consumers who check field !== undefined
3606
3606
  ...limits.nanoUsd !== void 0 ? { nanoUsd: limits.nanoUsd } : {},
3607
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { tokens: undefined } is equivalent to {} for event consumers who check field !== undefined
3607
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { tokens: undefined } is equivalent to {} for event consumers who check field !== undefined
3608
3608
  ...limits.tokens !== void 0 ? { tokens: limits.tokens } : {},
3609
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { count: undefined } is equivalent to {} for event consumers who check field !== undefined
3609
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { count: undefined } is equivalent to {} for event consumers who check field !== undefined
3610
3610
  ...limits.count !== void 0 ? { count: limits.count } : {}
3611
3611
  };
3612
3612
  }
@@ -3615,11 +3615,11 @@ function spendSnapshot(spend) {
3615
3615
  }
3616
3616
  function remainingSnapshot(limits, spend) {
3617
3617
  return {
3618
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { nanoUsd: undefined } is equivalent to {} for event consumers who check field !== undefined
3618
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { nanoUsd: undefined } is equivalent to {} for event consumers who check field !== undefined
3619
3619
  ...limits.nanoUsd !== void 0 ? { nanoUsd: max0(limits.nanoUsd - spend.spentNanoUsd) } : {},
3620
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { tokens: undefined } is equivalent to {} for event consumers who check field !== undefined
3620
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { tokens: undefined } is equivalent to {} for event consumers who check field !== undefined
3621
3621
  ...limits.tokens !== void 0 ? { tokens: Math.max(0, limits.tokens - spend.spentTokens) } : {},
3622
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { count: undefined } is equivalent to {} for event consumers who check field !== undefined
3622
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { count: undefined } is equivalent to {} for event consumers who check field !== undefined
3623
3623
  ...limits.count !== void 0 ? { count: Math.max(0, limits.count - spend.spentCount) } : {}
3624
3624
  };
3625
3625
  }
@@ -3627,7 +3627,7 @@ function buildStatus(budget, windowStart, resetsAt, spend) {
3627
3627
  const limits = limitsOf(budget);
3628
3628
  return {
3629
3629
  budgetId: budget.id,
3630
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { features: undefined } is equivalent to {} because status consumers check features !== undefined
3630
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { features: undefined } is equivalent to {} because status consumers check features !== undefined
3631
3631
  ...budget.features !== void 0 ? { features: budget.features } : {},
3632
3632
  window: budget.window,
3633
3633
  windowStart,
@@ -3794,29 +3794,29 @@ UsageReportService = __decorateClass([
3794
3794
  function toLedgerFilter(filter, limit) {
3795
3795
  return {
3796
3796
  tenantId: filter.tenantId,
3797
- // Stryker disable next-line ConditionalExpression -- spreading { scope: undefined } is equivalent to {} because InMemoryLedgerStore uses truthiness; the 'false' variant is covered by the scope isolation test
3797
+ // Stryker disable next-line ConditionalExpression: spreading { scope: undefined } is equivalent to {} because InMemoryLedgerStore uses truthiness; the 'false' variant is covered by the scope isolation test
3798
3798
  ...filter.scope !== void 0 ? { scope: filter.scope } : {},
3799
- // Stryker disable next-line ConditionalExpression -- spreading { beneficiary: undefined } is equivalent to {} for the same reason
3799
+ // Stryker disable next-line ConditionalExpression: spreading { beneficiary: undefined } is equivalent to {} for the same reason
3800
3800
  ...filter.beneficiary !== void 0 ? { beneficiary: filter.beneficiary } : {},
3801
- // Stryker disable next-line ConditionalExpression -- spreading { feature: undefined } does not change the !== undefined check in matches()
3801
+ // Stryker disable next-line ConditionalExpression: spreading { feature: undefined } does not change the !== undefined check in matches()
3802
3802
  ...filter.feature !== void 0 ? { feature: filter.feature } : {},
3803
- // Stryker disable next-line ConditionalExpression -- spreading { features: undefined } does not change the truthiness check in matches()
3803
+ // Stryker disable next-line ConditionalExpression: spreading { features: undefined } does not change the truthiness check in matches()
3804
3804
  ...filter.features !== void 0 ? { features: filter.features } : {},
3805
- // Stryker disable next-line ConditionalExpression -- spreading { provider: undefined } does not change the !== undefined check in matches()
3805
+ // Stryker disable next-line ConditionalExpression: spreading { provider: undefined } does not change the !== undefined check in matches()
3806
3806
  ...filter.provider !== void 0 ? { provider: filter.provider } : {},
3807
- // Stryker disable next-line ConditionalExpression -- spreading { model: undefined } does not change the !== undefined check in matches()
3807
+ // Stryker disable next-line ConditionalExpression: spreading { model: undefined } does not change the !== undefined check in matches()
3808
3808
  ...filter.model !== void 0 ? { model: filter.model } : {},
3809
- // Stryker disable next-line ConditionalExpression -- spreading { operation: undefined } does not change the !== undefined check in matches()
3809
+ // Stryker disable next-line ConditionalExpression: spreading { operation: undefined } does not change the !== undefined check in matches()
3810
3810
  ...filter.operation !== void 0 ? { operation: filter.operation } : {},
3811
- // Stryker disable next-line ConditionalExpression -- spreading { serviceTier: undefined } does not change the !== undefined check in matches()
3811
+ // Stryker disable next-line ConditionalExpression: spreading { serviceTier: undefined } does not change the !== undefined check in matches()
3812
3812
  ...filter.serviceTier !== void 0 ? { serviceTier: filter.serviceTier } : {},
3813
- // Stryker disable next-line ConditionalExpression -- spreading { tags: undefined } does not change the truthiness check in matches()
3813
+ // Stryker disable next-line ConditionalExpression: spreading { tags: undefined } does not change the truthiness check in matches()
3814
3814
  ...filter.tags !== void 0 ? { tags: filter.tags } : {},
3815
- // Stryker disable next-line ConditionalExpression -- spreading { isSystemCost: undefined } does not change the !== undefined check in matches()
3815
+ // Stryker disable next-line ConditionalExpression: spreading { isSystemCost: undefined } does not change the !== undefined check in matches()
3816
3816
  ...filter.isSystemCost !== void 0 ? { isSystemCost: filter.isSystemCost } : {},
3817
- // Stryker disable next-line ConditionalExpression -- spreading { systemCostCategory: undefined } does not change the !== undefined check in matches()
3817
+ // Stryker disable next-line ConditionalExpression: spreading { systemCostCategory: undefined } does not change the !== undefined check in matches()
3818
3818
  ...filter.systemCostCategory !== void 0 ? { systemCostCategory: filter.systemCostCategory } : {},
3819
- // Stryker disable next-line ConditionalExpression -- spreading { enforcedOnly: undefined } does not change the === true check in matches()
3819
+ // Stryker disable next-line ConditionalExpression: spreading { enforcedOnly: undefined } does not change the === true check in matches()
3820
3820
  ...filter.enforcedOnly !== void 0 ? { enforcedOnly: filter.enforcedOnly } : {},
3821
3821
  status: filter.status ?? [...BALANCE_STATUSES2],
3822
3822
  from: filter.from,
@@ -4002,9 +4002,9 @@ var MeteringInterceptor = class {
4002
4002
  const context = await this.resolveContext(executionContext, config, enrichment);
4003
4003
  return this.metering.record({
4004
4004
  usage,
4005
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { preset: undefined } is equivalent to {} because MeteringService checks preset !== undefined
4005
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { preset: undefined } is equivalent to {} because MeteringService checks preset !== undefined
4006
4006
  ...config.preset !== void 0 ? { preset: config.preset } : {},
4007
- // Stryker disable next-line ConditionalExpression -- CE true: spreading { tags: undefined } is equivalent to {} because MeteringService checks tags !== undefined
4007
+ // Stryker disable next-line ConditionalExpression: CE true: spreading { tags: undefined } is equivalent to {} because MeteringService checks tags !== undefined
4008
4008
  context: { ...context, enforce: true, isSystemCost: config.isSystemCost ?? false, ...config.tags !== void 0 ? { tags: config.tags } : {} }
4009
4009
  });
4010
4010
  }
@@ -4332,24 +4332,24 @@ function preset(provider, normalizer, ratingMode) {
4332
4332
  return { provider, normalizer, ratingMode };
4333
4333
  }
4334
4334
  var providerPresets = {
4335
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests that exercise the full preset→MeteringService→UsageRecord path
4335
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests that exercise the full preset→MeteringService→UsageRecord path
4336
4336
  openaiChat: preset("openai", normalizeOpenAiChatUsage, "rate-table"),
4337
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4337
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4338
4338
  openaiResponses: preset("openai", normalizeOpenAiResponsesUsage, "rate-table"),
4339
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4339
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4340
4340
  azureOpenai: preset("azure-openai", normalizeOpenAiChatUsage, "rate-table"),
4341
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4341
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4342
4342
  anthropic: preset("anthropic", normalizeAnthropicUsage, "rate-table"),
4343
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4343
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4344
4344
  gemini: preset("gemini", normalizeGeminiUsage, "rate-table"),
4345
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4345
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4346
4346
  vertex: preset("vertex", normalizeGeminiUsage, "rate-table"),
4347
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4347
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4348
4348
  bedrock: preset("bedrock", normalizeBedrockConverseUsage, "rate-table"),
4349
- // Stryker disable next-line StringLiteral -- provider ID; only observable via integration tests
4349
+ // Stryker disable next-line StringLiteral: provider ID; only observable via integration tests
4350
4350
  mistral: preset("mistral", normalizeMistralUsage, "rate-table"),
4351
4351
  vercelAiSdk: preset("openai", normalizeVercelAiSdkUsage, "rate-table"),
4352
- // Stryker disable next-line StringLiteral -- provider ID and rating mode; only observable via integration tests
4352
+ // Stryker disable next-line StringLiteral: provider ID and rating mode; only observable via integration tests
4353
4353
  openrouter: preset("openrouter", normalizeOpenRouterUsage, "provider-reported"),
4354
4354
  /** A custom OpenAI-compatible provider (DeepSeek, xAI, Groq, …). */
4355
4355
  openaiCompatible: (id) => preset(id, normalizeOpenAiCompatibleUsage, "rate-table")
@@ -332,9 +332,9 @@ function normalizeMistralUsage(raw) {
332
332
  provider: "mistral",
333
333
  model: str(response.model) ?? "",
334
334
  operation: "chat",
335
- // Stryker disable next-line StringLiteral -- provider and field names in error messages are internal diagnostics
335
+ // Stryker disable next-line StringLiteral: provider and field names in error messages are internal diagnostics
336
336
  inputTokens: requireNum(usage.prompt_tokens, "mistral", "usage.prompt_tokens"),
337
- // Stryker disable next-line StringLiteral -- provider and field names in error messages are internal diagnostics
337
+ // Stryker disable next-line StringLiteral: provider and field names in error messages are internal diagnostics
338
338
  outputTokens: requireNum(usage.completion_tokens, "mistral", "usage.completion_tokens"),
339
339
  raw: usage
340
340
  });
@@ -330,9 +330,9 @@ function normalizeMistralUsage(raw) {
330
330
  provider: "mistral",
331
331
  model: str(response.model) ?? "",
332
332
  operation: "chat",
333
- // Stryker disable next-line StringLiteral -- provider and field names in error messages are internal diagnostics
333
+ // Stryker disable next-line StringLiteral: provider and field names in error messages are internal diagnostics
334
334
  inputTokens: requireNum(usage.prompt_tokens, "mistral", "usage.prompt_tokens"),
335
- // Stryker disable next-line StringLiteral -- provider and field names in error messages are internal diagnostics
335
+ // Stryker disable next-line StringLiteral: provider and field names in error messages are internal diagnostics
336
336
  outputTokens: requireNum(usage.completion_tokens, "mistral", "usage.completion_tokens"),
337
337
  raw: usage
338
338
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-ai-tokens",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "AI token metering & usage-based billing for NestJS 11: provider usage normalizer (×9), versioned effective-dated pricing, immutable append-only ledger, prepaid wallets, multi-dimension budgets, and markup/margin. Zero runtime dependencies.",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",
@@ -76,6 +76,7 @@
76
76
  "scripts": {
77
77
  "build": "pnpm clean && tsup",
78
78
  "check:exports": "attw --pack . --profile strict",
79
+ "check:mutants": "node scripts/check-mutation-directives.mjs",
79
80
  "check:published": "node scripts/check-published-surface.mjs",
80
81
  "check:runtime": "node scripts/check-consumer-runtime.mjs",
81
82
  "clean": "node -e \"const {rmSync}=require('node:fs');for(const d of ['dist','coverage'])rmSync(d,{recursive:true,force:true})\"",
@@ -87,7 +88,7 @@
87
88
  "mutation:dry-run": "stryker run --dryRunOnly",
88
89
  "mutation:incremental": "stryker run --incremental",
89
90
  "prepare": "prisma generate",
90
- "prepublishOnly": "pnpm clean && pnpm typecheck && pnpm lint && pnpm test:cov:all && pnpm build && pnpm size && pnpm check:published",
91
+ "prepublishOnly": "pnpm clean && pnpm typecheck && pnpm lint && pnpm check:mutants && pnpm test:cov:all && pnpm build && pnpm size && pnpm check:published",
91
92
  "release": "npm publish --provenance --access public",
92
93
  "size": "node scripts/check-size.mjs",
93
94
  "test": "jest",