@bymax-one/nest-ai-tokens 1.0.4 → 1.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.
- package/CHANGELOG.md +18 -7
- package/README.md +3 -3
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,18 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## [
|
|
9
|
+
## [1.1.0] - 2026-08-11
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **BREAKING: `ioredis` peer moved to `^6.0.0`** (was `^5.0.0`; the ranges are disjoint, so an
|
|
14
|
+
ioredis 5 consumer no longer satisfies the contract). It aligns the `./redis` budget counter
|
|
15
|
+
with `@bymax-one/nest-queue@1.2.0`, so a backend that consumes both resolves one shared `ioredis`.
|
|
16
|
+
ioredis 6 defaults to RESP3 but keeps `replyMapping: "legacy"`, leaving reply shapes unchanged at
|
|
17
|
+
runtime; the store's URL-only `new Redis(url)` construction is untouched by the RESP3 options
|
|
18
|
+
typing break, so no source changed.
|
|
19
|
+
- **Mutation gate raised to a perfect score.** `stryker.config.json` now breaks below 100 (`break`,
|
|
20
|
+
`high` and `low` are all 100), so no surviving mutant can pass the gate.
|
|
10
21
|
|
|
11
22
|
## [1.0.4] - 2026-08-10
|
|
12
23
|
|
|
@@ -35,9 +46,9 @@ Remediation of a local audit's settlement findings (merged in #65). No API chang
|
|
|
35
46
|
### Fixed
|
|
36
47
|
|
|
37
48
|
- **Every suppression reason was dropped from the mutation report.** All 249 `// Stryker
|
|
38
|
-
|
|
49
|
+
disable` directives in the source wrote their justification after `--`. Stryker reads a
|
|
39
50
|
directive with one regular expression, `/^\s?Stryker (disable|restore)(?: (next-line))?
|
|
40
|
-
|
|
51
|
+
([a-zA-Z, ]+)(?::(.+)?)?/`, whose mutator list accepts letters, commas and spaces only
|
|
41
52
|
and which captures the reason exclusively after a colon. A `-` therefore closed the
|
|
42
53
|
mutator list and left the reason unmatched, so each directive still silenced its mutant
|
|
43
54
|
but the report recorded Stryker's fallback text, `Ignored using a comment`. The README
|
|
@@ -71,14 +82,14 @@ Remediation of a local audit's settlement findings (merged in #65). No API chang
|
|
|
71
82
|
implement `emitDecoratorMetadata` because it does not replicate TypeScript's type
|
|
72
83
|
system — so the second key was never there. The first two parameters had neither, and
|
|
73
84
|
the container threw `Nest can't resolve dependencies of the MeteringInterceptor
|
|
74
|
-
|
|
85
|
+
(?, +, Symbol(BYMAX_AI_TOKENS_OPTIONS))` before any provider was created. Both now
|
|
75
86
|
carry `@Inject`.
|
|
76
87
|
|
|
77
88
|
### Changed
|
|
78
89
|
|
|
79
90
|
- `emitDecoratorMetadata` is `false` in `tsconfig.json`. It was `true`, which was never
|
|
80
91
|
true of the artifact: tsup prints `You have emitDecoratorMetadata enabled but
|
|
81
|
-
|
|
92
|
+
@swc/core was not installed, skipping swc plugin` on every build, and that warning had
|
|
82
93
|
been printed on every build of this package. Turning it off makes the source compile
|
|
83
94
|
the way the bundle is built, so a parameter that depends on reflected types now fails
|
|
84
95
|
where it is cheap to see.
|
|
@@ -139,7 +150,6 @@ have regressed from. They are kept because the reasoning is worth having.
|
|
|
139
150
|
- **Zero runtime dependencies** — `"dependencies": {}`. All runtime functionality via peer dependencies.
|
|
140
151
|
- **100% unit test coverage** — 804 tests; 10-scenario Testcontainers e2e suite; Stryker mutation gate at 100.00% (0 surviving mutants, break 95).
|
|
141
152
|
|
|
142
|
-
|
|
143
153
|
- **Prisma 7 support, alongside Prisma 6.** The declared peer range has always
|
|
144
154
|
been `>=6.0.0`, but nothing verified the claim; the end-to-end suite now runs
|
|
145
155
|
against Prisma 7 and a real PostgreSQL, and it is what surfaced the conflict
|
|
@@ -155,7 +165,7 @@ have regressed from. They are kept because the reasoning is worth having.
|
|
|
155
165
|
- **`pnpm check:exports`** runs `attw --pack . --profile strict` against the packed
|
|
156
166
|
tarball, which is what surfaced both resolution defects above.
|
|
157
167
|
- **`pnpm check:runtime`** packs the tarball, lays it out the way npm would, and
|
|
158
|
-
asserts in ESM
|
|
168
|
+
asserts in ESM _and_ CommonJS that an error thrown by `PrismaAiTokensStore`
|
|
159
169
|
satisfies `instanceof AiTokensException` against the class the root exports. No
|
|
160
170
|
source-based suite can observe this: the unit tests map the subpath specifiers to
|
|
161
171
|
`src` and therefore see a single copy. Both gates run in CI.
|
|
@@ -215,6 +225,7 @@ have regressed from. They are kept because the reasoning is worth having.
|
|
|
215
225
|
[1.0.0]: https://github.com/bymaxone/nest-ai-tokens/releases/tag/v1.0.0
|
|
216
226
|
[1.0.1]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.0...v1.0.1
|
|
217
227
|
[1.0.2]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.1...v1.0.2
|
|
228
|
+
[1.1.0]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.4...v1.1.0
|
|
218
229
|
[1.0.4]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.3...v1.0.4
|
|
219
230
|
[1.0.3]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.2...v1.0.3
|
|
220
231
|
[Unreleased]: https://github.com/bymaxone/nest-ai-tokens/compare/v1.0.4...HEAD
|
package/README.md
CHANGED
|
@@ -715,7 +715,7 @@ that reads a tenant id from request input lets a caller bill someone else.
|
|
|
715
715
|
- **Runtime:** Node.js 24+
|
|
716
716
|
- **Framework:** NestJS 11 (guard + interceptor, `ConfigurableModuleBuilder`, `Symbol()` tokens)
|
|
717
717
|
- **Persistence:** `@prisma/client ^6 || ^7` (peer) over PostgreSQL — both majors supported
|
|
718
|
-
- **Budget acceleration:** `ioredis ^
|
|
718
|
+
- **Budget acceleration:** `ioredis ^6` (peer), optional
|
|
719
719
|
- **Events:** `@nestjs/event-emitter >=2` (peer), optional
|
|
720
720
|
- **Telemetry:** `@opentelemetry/api ^1.9` (peer), optional
|
|
721
721
|
- **Build:** tsup — ESM + CJS per subpath, with `.d.ts` _and_ `.d.cts` declarations
|
|
@@ -730,7 +730,7 @@ This library decides what a customer is charged, so the suite is held to a bar b
|
|
|
730
730
|
tests pass".
|
|
731
731
|
|
|
732
732
|
- ✅ **100% line coverage** — statements, branches, functions and lines, enforced as a gate
|
|
733
|
-
- ✅ **100% mutation score against a `break:
|
|
733
|
+
- ✅ **100% mutation score against a `break: 100` gate** — the gate is the floor a run must
|
|
734
734
|
clear; the score the suite actually reaches is 100%, verified with
|
|
735
735
|
[Stryker](https://stryker-mutator.io/) ([report](./docs/mutation_testing_results.md))
|
|
736
736
|
- ✅ **Real PostgreSQL in e2e** — Testcontainers, so the unique constraint that prevents a
|
|
@@ -752,7 +752,7 @@ tests pass".
|
|
|
752
752
|
pnpm test # unit tests
|
|
753
753
|
pnpm test:cov # unit tests with the 100% coverage gate
|
|
754
754
|
pnpm test:e2e # end-to-end against PostgreSQL (requires Docker)
|
|
755
|
-
pnpm mutation # Stryker mutation testing (break:
|
|
755
|
+
pnpm mutation # Stryker mutation testing (break: 100)
|
|
756
756
|
pnpm typecheck # tsc strict check
|
|
757
757
|
pnpm lint # ESLint
|
|
758
758
|
pnpm build && pnpm size # bundle-size budgets
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bymax-one/nest-ai-tokens",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
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",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"reflect-metadata": "^0.2.0",
|
|
107
107
|
"rxjs": "^7.8.0",
|
|
108
108
|
"@prisma/client": "^6.0.0 || ^7.0.0",
|
|
109
|
-
"ioredis": "^
|
|
109
|
+
"ioredis": "^6.0.0",
|
|
110
110
|
"@nestjs/event-emitter": ">=2.0.0",
|
|
111
111
|
"@opentelemetry/api": "^1.9.0"
|
|
112
112
|
},
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"eslint": "^9.39.5",
|
|
159
159
|
"eslint-config-prettier": "^10.1.8",
|
|
160
160
|
"fast-check": "^4.9.0",
|
|
161
|
-
"ioredis": "^
|
|
161
|
+
"ioredis": "^6.0.0",
|
|
162
162
|
"jest": "^30.4.2",
|
|
163
163
|
"prettier": "^3.9.6",
|
|
164
164
|
"prisma": "^7.9.1",
|