@bymax-one/nest-queue 1.0.8 → 1.0.10

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
@@ -7,6 +7,60 @@ versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.0.10] — 2026-08-06
11
+
12
+ **Documentation and tooling only.** `dist/` is byte-identical to `1.0.9`; no source file
13
+ changed.
14
+
15
+ ### Fixed
16
+
17
+ - The quality bullet claimed "no suppression comments" while the source carries five
18
+ `// Stryker disable` comments. The claim was about type suppressions and read as false to
19
+ anyone who grepped for it; it now says what is true — no `@ts-ignore` and no
20
+ `eslint-disable`.
21
+
22
+ ### Security
23
+
24
+ - **The OSV scan was passing because it had nothing to read.** The workflow ran
25
+ `osv-scanner` with no `actions/checkout` step, so it walked an empty workspace and
26
+ reported "No package sources found" and "No lockfiles found" before exiting 0. A green
27
+ check meant the scanner found no files, which is indistinguishable from finding no
28
+ vulnerabilities. With the checkout in place it scans the lockfile, which is how the next
29
+ item was found.
30
+ - **`js-yaml` is patched to the fixed release** (GHSA-5p4m-2wfm-xmqj, CVSS 7.5). The
31
+ override floors here already scoped it per major but admitted `3.15.0` and `4.3.0`, both
32
+ covered by the advisory; they are raised to `^3.15.1` and `^4.3.1`. It reaches this repo
33
+ only through `jest` -> `babel-plugin-istanbul` -> `@istanbuljs/load-nyc-config`, and
34
+ `dependencies` is empty, so nothing here ships it and no consumer was exposed. `dist/` is
35
+ unaffected.
36
+
37
+ ### Added
38
+
39
+ - `check:mutants` gate (`scripts/check-mutation-directives.mjs`) — validates every
40
+ `// Stryker` comment against the grammar Stryker's own parser accepts, rejecting a reason
41
+ written after `--` instead of a colon (silently dropped, and the report then shows
42
+ `Ignored using a comment`), a reason wrapped onto a second comment line (the report keeps
43
+ only the first fragment), and a mutator name Stryker does not know, which matches nothing
44
+ and so silences nothing. Wired into CI and `prepublishOnly`.
45
+ - `docs/mutation_testing_plan.md` carries the suppression policy now shared, word for word,
46
+ across the `@bymax-one/nest-*` libraries.
47
+
48
+ ## [1.0.9] — 2026-08-06
49
+
50
+ **Published-artifact change, not a behavioural one.** `dist/` differs from `1.0.8` — this
51
+ bundler preserves comments and the source gained mutation-suppression notes — but no runtime
52
+ path changed. Measured by building both revisions and diffing the output.
53
+
54
+ ### Documentation
55
+
56
+ - The mutation badge and README said **99.06%**; the measured score is **99.68%**.
57
+
58
+ ### Tests
59
+
60
+ - The withheld Redis connection now has the shape of its guarantee asserted: that the property is
61
+ non-enumerable, that redefining it throws, and that the URL's password stays out of both
62
+ `JSON.stringify` and `inspect({ showHidden: true })`.
63
+
10
64
  ## [1.0.8] — 2026-08-04
11
65
 
12
66
  **Runtime change.** `dist/` differs from `1.0.7`.
@@ -389,6 +443,8 @@ v6 peer range.
389
443
 
390
444
  ---
391
445
 
446
+ [1.0.10]: https://github.com/bymaxone/nest-queue/compare/v1.0.9...v1.0.10
447
+ [1.0.9]: https://github.com/bymaxone/nest-queue/compare/v1.0.8...v1.0.9
392
448
  [1.0.8]: https://github.com/bymaxone/nest-queue/compare/v1.0.7...v1.0.8
393
449
  [1.0.7]: https://github.com/bymaxone/nest-queue/compare/v1.0.6...v1.0.7
394
450
  [1.0.6]: https://github.com/bymaxone/nest-queue/releases/tag/v1.0.6
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
  <a href="https://www.npmjs.com/package/@bymax-one/nest-queue"><img src="https://img.shields.io/npm/dm/@bymax-one/nest-queue?style=flat-square&colorA=000000&colorB=000000" alt="npm downloads" /></a>
15
15
  <a href="https://github.com/bymaxone/nest-queue/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/bymaxone/nest-queue/ci.yml?branch=main&style=flat-square&colorA=000000&label=CI" alt="CI status" /></a>
16
16
  <a href="https://github.com/bymaxone/nest-queue/actions/workflows/ci.yml"><img src="https://img.shields.io/badge/coverage-100%25-brightgreen?style=flat-square&colorA=000000" alt="coverage" /></a>
17
- <a href="https://github.com/bymaxone/nest-queue/blob/main/docs/mutation_testing_results.md"><img src="https://img.shields.io/badge/mutation-99.06%25-brightgreen?style=flat-square&colorA=000000" alt="mutation score" /></a>
17
+ <a href="https://github.com/bymaxone/nest-queue/blob/main/docs/mutation_testing_results.md"><img src="https://img.shields.io/badge/mutation-99.68%25-brightgreen?style=flat-square&colorA=000000" alt="mutation score" /></a>
18
18
  <a href="https://scorecard.dev/viewer/?uri=github.com/bymaxone/nest-queue"><img src="https://api.scorecard.dev/projects/github.com/bymaxone/nest-queue/badge?style=flat-square" alt="OpenSSF Scorecard" /></a>
19
19
  <a href="https://github.com/bymaxone/nest-queue/blob/main/LICENSE"><img src="https://img.shields.io/github/license/bymaxone/nest-queue?style=flat-square&colorA=000000&colorB=000000" alt="license" /></a>
20
20
  <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-strict-3178C6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" /></a>
@@ -87,7 +87,7 @@ peer dependencies, so you control exact versions and the supply-chain surface st
87
87
  - ✅ **Stable error catalog** — namespaced codes exported from both subpaths, so a frontend maps a `code` without importing the server
88
88
  - ✅ **Dual-format output** — ESM + CJS with declarations for each format, verified against the packed tarball on every PR
89
89
  - ✅ **Opt-in observability** — OpenTelemetry passthrough via `bullmq-otel`, plus a `MetricsService` with a configurable TTL cache
90
- - ✅ **Typed end to end** — TypeScript `strict` with `exactOptionalPropertyTypes` and `noUncheckedIndexedAccess`; zero `any`, no suppression comments
90
+ - ✅ **Typed end to end** — TypeScript `strict` with `exactOptionalPropertyTypes` and `noUncheckedIndexedAccess`; zero `any`, no `@ts-ignore` and no `eslint-disable`
91
91
 
92
92
  ---
93
93
 
@@ -796,7 +796,7 @@ key will do it twice at some point.
796
796
  ## 🧪 Testing & Quality
797
797
 
798
798
  - **100% line/branch coverage** on every implemented file (hard CI gate).
799
- - **Mutation score 99.06%** (Stryker `break 95`) — see [`docs/mutation_testing_results.md`](docs/mutation_testing_results.md).
799
+ - **Mutation score 99.68%** (Stryker `break 95`) — see [`docs/mutation_testing_results.md`](docs/mutation_testing_results.md).
800
800
  - **Real-Redis E2E** via Testcontainers (workers, flows, schedulers, deduplication, retries,
801
801
  DLQ, graceful shutdown).
802
802
  - **Type-level API tests** (`pnpm test:types`) pin the published signatures, so a refactor
@@ -141,6 +141,7 @@ function applyDefaults(opts) {
141
141
  Object.defineProperty(base, "connection", {
142
142
  get: () => connection,
143
143
  enumerable: false,
144
+ // Stryker disable next-line BooleanLiteral: equivalent HERE — this object is `Object.freeze`d on the way out, and freezing makes every property non-configurable regardless. The flag stays because it states the guarantee at the point the accessor is defined, and because the sibling packages that withhold secrets the same way are NOT frozen, where it is load-bearing
144
145
  configurable: false
145
146
  });
146
147
  return Object.freeze(base);
@@ -1333,10 +1334,15 @@ QueueLifecycle = __decorateClass([
1333
1334
  ], QueueLifecycle);
1334
1335
 
1335
1336
  // src/server/bymax-queue.module.ts
1336
- var { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = new common.ConfigurableModuleBuilder({ moduleName: "BymaxQueue" }).setClassMethodName("forRoot").setFactoryMethodName("createQueueOptions").setExtras({ isGlobal: true }, (definition, extras) => ({
1337
- ...definition,
1338
- global: extras.isGlobal
1339
- })).build();
1337
+ var { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = (
1338
+ // The `moduleName` shapes the generated token's description only — a label read in Nest's DI
1339
+ // error output, never compared against anything. Mutation testing reports it as surviving for
1340
+ // that reason; no Stryker directive attaches inside this builder chain, so the note lives here.
1341
+ new common.ConfigurableModuleBuilder({ moduleName: "BymaxQueue" }).setClassMethodName("forRoot").setFactoryMethodName("createQueueOptions").setExtras({ isGlobal: true }, (definition, extras) => ({
1342
+ ...definition,
1343
+ global: extras.isGlobal
1344
+ })).build()
1345
+ );
1340
1346
  exports.BymaxQueueModule = class BymaxQueueModule extends ConfigurableModuleClass {
1341
1347
  /**
1342
1348
  * Synchronous registration. Validates options, resolves defaults, and wires the
@@ -139,6 +139,7 @@ function applyDefaults(opts) {
139
139
  Object.defineProperty(base, "connection", {
140
140
  get: () => connection,
141
141
  enumerable: false,
142
+ // Stryker disable next-line BooleanLiteral: equivalent HERE — this object is `Object.freeze`d on the way out, and freezing makes every property non-configurable regardless. The flag stays because it states the guarantee at the point the accessor is defined, and because the sibling packages that withhold secrets the same way are NOT frozen, where it is load-bearing
142
143
  configurable: false
143
144
  });
144
145
  return Object.freeze(base);
@@ -1331,10 +1332,15 @@ QueueLifecycle = __decorateClass([
1331
1332
  ], QueueLifecycle);
1332
1333
 
1333
1334
  // src/server/bymax-queue.module.ts
1334
- var { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = new ConfigurableModuleBuilder({ moduleName: "BymaxQueue" }).setClassMethodName("forRoot").setFactoryMethodName("createQueueOptions").setExtras({ isGlobal: true }, (definition, extras) => ({
1335
- ...definition,
1336
- global: extras.isGlobal
1337
- })).build();
1335
+ var { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = (
1336
+ // The `moduleName` shapes the generated token's description only — a label read in Nest's DI
1337
+ // error output, never compared against anything. Mutation testing reports it as surviving for
1338
+ // that reason; no Stryker directive attaches inside this builder chain, so the note lives here.
1339
+ new ConfigurableModuleBuilder({ moduleName: "BymaxQueue" }).setClassMethodName("forRoot").setFactoryMethodName("createQueueOptions").setExtras({ isGlobal: true }, (definition, extras) => ({
1340
+ ...definition,
1341
+ global: extras.isGlobal
1342
+ })).build()
1343
+ );
1338
1344
  var BymaxQueueModule = class extends ConfigurableModuleClass {
1339
1345
  /**
1340
1346
  * Synchronous registration. Validates options, resolves defaults, and wires the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-queue",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "NestJS dynamic module wrapping BullMQ — typed jobs, flows, job schedulers, deduplication, OpenTelemetry, graceful shutdown",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",
@@ -56,6 +56,7 @@
56
56
  "scripts": {
57
57
  "build": "pnpm clean && tsup",
58
58
  "check:exports": "attw --pack .",
59
+ "check:mutants": "node scripts/check-mutation-directives.mjs",
59
60
  "check:published": "node scripts/check-published-surface.mjs",
60
61
  "clean": "rm -rf dist coverage",
61
62
  "lint": "eslint src scripts test",
@@ -64,7 +65,7 @@
64
65
  "mutation:dry-run": "stryker run --dryRunOnly",
65
66
  "mutation:incremental": "stryker run --incremental",
66
67
  "prepare": "husky",
67
- "prepublishOnly": "pnpm clean && pnpm typecheck && pnpm test:types && pnpm lint && pnpm test:cov:all && pnpm build && pnpm check:published",
68
+ "prepublishOnly": "pnpm clean && pnpm typecheck && pnpm test:types && pnpm lint && pnpm check:mutants && pnpm test:cov:all && pnpm build && pnpm check:published",
68
69
  "release": "npm publish --provenance --access public",
69
70
  "size": "node scripts/check-size.mjs",
70
71
  "smoke": "node scripts/dogfood-smoke-test.mjs",
@@ -146,7 +147,7 @@
146
147
  "prettier --write"
147
148
  ]
148
149
  },
149
- "packageManager": "pnpm@11.0.0",
150
+ "packageManager": "pnpm@11.20.0",
150
151
  "engines": {
151
152
  "node": ">=24.0.0"
152
153
  },