@bymax-one/nest-core 1.2.2 → 1.3.1

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
@@ -11,6 +11,59 @@ heading here.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [1.3.1] - 2026-08-11
15
+
16
+ A patch fixing a defect that existed only in the published artifact: `applyBymaxOpenApi` threw on
17
+ every consumer boot, including consumers that never enabled the OpenAPI document. No API changed —
18
+ the type declarations are byte-identical to `1.3.0` apart from one added documentation comment.
19
+
20
+ **Apply to a derived backend:** `pnpm up @bymax-one/nest-core`. No code change on the consumer
21
+ side; the DI token identities are internal to the package.
22
+
23
+ ### Fixed
24
+
25
+ - **`applyBymaxOpenApi` resolves the options registered by `BymaxCoreModule` again.** The DI
26
+ tokens were minted with `Symbol()`. This package ships one bundle per published subpath with the
27
+ shared internals inlined into each, so `core.tokens` existed twice at runtime — once in
28
+ `dist/index.cjs`, once in `dist/openapi/index.cjs` — and `Symbol('X') !== Symbol('X')`. The
29
+ provider bound by the package root carried one identity and the `./openapi` helper looked up
30
+ another, so `app.get()` found nothing and the helper threw its "could not resolve
31
+ BYMAX_CORE_OPTIONS" error with `BymaxCoreModule` correctly registered. Under Nest's default
32
+ `abortOnError` that took down the process. The feature flag did not protect anyone: the helper
33
+ resolves the options before it reads `openapi.enabled`, so an application with the document
34
+ switched off failed exactly the same way. Every token is now minted with `Symbol.for` against the
35
+ runtime's global symbol registry, which is immune to bundle duplication by construction.
36
+ `./health`, `./metrics` and `./pagination` were audited and carry no DI token at all, so
37
+ `./openapi` was the only subpath where the defect could manifest; the remaining tokens are
38
+ converted anyway, so a future subpath that starts consuming one is safe before the fact.
39
+
40
+ ### Internal
41
+
42
+ - **The consumer load gate now boots a real application against the packed tarball.** It registers
43
+ `BymaxCoreModule.forRootAsync` from the package root, calls `applyBymaxOpenApi` from the
44
+ `./openapi` subpath, and asserts all three outcomes — disabled, mounted outside production, and
45
+ refused in production — in ESM and in CommonJS. The unit suite structurally could not catch this
46
+ class of defect: under ts-jest every module is loaded once, so tokens shared between two entries
47
+ are the same object however they were minted, and the bug only exists once the code is bundled.
48
+ The gate fails against the `1.3.0` artifact and passes against this one.
49
+ - The token specs assert that every exported token round-trips through `Symbol.for`, swept from the
50
+ module namespace rather than a hand-maintained list, so a token added later is covered without
51
+ anyone remembering to add it.
52
+
53
+ ## [1.3.0] - 2026-08-11
54
+
55
+ Coordinated ecosystem release aligning every `@bymax-one/*` package after the ioredis 6 /
56
+ bullmq 6 migration. **No source, runtime, or public-API change in this package** — the
57
+ published `dist/` is byte-identical to `1.2.2`; the changes below are development
58
+ and CI tooling only.
59
+
60
+ ### Changed
61
+
62
+ - Bumped the `dev-dependencies` group with 3 updates. None of these reaches the published bundle.
63
+ - Bumped the pinned `pnpm/action-setup` CI action from 6.0.9 to 6.0.10.
64
+ - Bumped the pinned `github/codeql-action/upload-sarif` CI action from 4.37.4 to 4.37.6 in the
65
+ codeql group.
66
+
14
67
  ## [1.2.2] - 2026-08-10
15
68
 
16
69
  Remediation of a local audit's metrics-auth and pagination-bound findings (merged in #62). No
@@ -341,7 +394,9 @@ have regressed from. They are kept because the reasoning is worth having.
341
394
  [1.0.1]: https://github.com/bymaxone/nest-core/compare/v1.0.0...v1.0.1
342
395
  [1.0.0]: https://github.com/bymaxone/nest-core/releases/tag/v1.0.0
343
396
  [1.1.1]: https://github.com/bymaxone/nest-core/compare/v1.1.0...v1.1.1
397
+ [1.3.1]: https://github.com/bymaxone/nest-core/compare/v1.3.0...v1.3.1
398
+ [1.3.0]: https://github.com/bymaxone/nest-core/compare/v1.2.2...v1.3.0
344
399
  [1.2.2]: https://github.com/bymaxone/nest-core/compare/v1.2.1...v1.2.2
345
400
  [1.2.1]: https://github.com/bymaxone/nest-core/compare/v1.2.0...v1.2.1
346
401
  [1.2.0]: https://github.com/bymaxone/nest-core/compare/v1.1.1...v1.2.0
347
- [Unreleased]: https://github.com/bymaxone/nest-core/compare/v1.2.2...HEAD
402
+ [Unreleased]: https://github.com/bymaxone/nest-core/compare/v1.3.1...HEAD
package/dist/index.cjs CHANGED
@@ -127,12 +127,18 @@ function normalizeCoreOptions(raw) {
127
127
  normalizeCoreOptions();
128
128
 
129
129
  // src/core.tokens.ts
130
- var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol("BYMAX_CORE_OPTIONS");
131
- var BYMAX_CORRELATION_PROVIDER = /* @__PURE__ */ Symbol("BYMAX_CORRELATION_PROVIDER");
132
- var BYMAX_TIMING_SINK = /* @__PURE__ */ Symbol("BYMAX_TIMING_SINK");
133
- var BYMAX_HEALTH_INDICATORS = /* @__PURE__ */ Symbol("BYMAX_HEALTH_INDICATORS");
134
- var BYMAX_METRICS_REGISTRY = /* @__PURE__ */ Symbol("BYMAX_METRICS_REGISTRY");
135
- var BYMAX_TRACE_CONTEXT = /* @__PURE__ */ Symbol("BYMAX_TRACE_CONTEXT");
130
+ var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:core-options");
131
+ var BYMAX_CORRELATION_PROVIDER = /* @__PURE__ */ Symbol.for(
132
+ "@bymax-one/nest-core:correlation-provider"
133
+ );
134
+ var BYMAX_TIMING_SINK = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:timing-sink");
135
+ var BYMAX_HEALTH_INDICATORS = /* @__PURE__ */ Symbol.for(
136
+ "@bymax-one/nest-core:health-indicators"
137
+ );
138
+ var BYMAX_METRICS_REGISTRY = /* @__PURE__ */ Symbol.for(
139
+ "@bymax-one/nest-core:metrics-registry"
140
+ );
141
+ var BYMAX_TRACE_CONTEXT = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:trace-context");
136
142
 
137
143
  // src/optional-peer.ts
138
144
  function isMissingModuleError(cause) {
@@ -201,7 +207,7 @@ async function resolveTraceContextProvider(options) {
201
207
  var DEFAULT_MONOTONIC_CLOCK = {
202
208
  now: () => performance.now()
203
209
  };
204
- var BYMAX_TIMING_CLOCK = /* @__PURE__ */ Symbol("BYMAX_TIMING_CLOCK");
210
+ var BYMAX_TIMING_CLOCK = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:timing-clock");
205
211
 
206
212
  // src/defaults.providers.ts
207
213
  var NoopCorrelationIdProvider = class {
package/dist/index.d.cts CHANGED
@@ -295,6 +295,43 @@ declare class BymaxCoreModule extends BymaxCoreModuleBase {
295
295
  * @fileoverview Dependency-injection tokens for `@bymax-one/nest-core`.
296
296
  * Every token is a `Symbol`, so the container never collides with a consumer's
297
297
  * string tokens and the public contracts stay explicit at every injection site.
298
+ *
299
+ * Every token is minted with `Symbol.for`, never `Symbol()`. This package ships
300
+ * one bundle per published subpath and the bundler inlines shared modules into
301
+ * each of them, so this file exists once per bundle at runtime: a `Symbol()`
302
+ * token would mint a *different* identity in `dist/index.cjs` than in
303
+ * `dist/openapi/index.cjs`, and a provider registered from the package root
304
+ * would be unreachable from a subpath that injects "the same" token. That is not
305
+ * hypothetical — it is the 1.3.0 defect that made `applyBymaxOpenApi` throw on
306
+ * every consumer boot. `Symbol.for` resolves through the runtime's global symbol
307
+ * registry, so all copies converge on one identity no matter how many bundles
308
+ * carry them. The same reasoning keeps the health marker's metadata key a
309
+ * literal; see `health/health.marker.ts`.
310
+ *
311
+ * The registry keys below are therefore part of the package's public contract,
312
+ * as binding as the export names: changing one is a breaking change even though
313
+ * no signature moves. They are namespaced with the full npm package name because
314
+ * the registry is process-global and shared with every other library in the
315
+ * application — the package name is the one string guaranteed not to collide.
316
+ *
317
+ * The keys carry no version, which is a deliberate choice with a consequence
318
+ * worth stating plainly. Every copy of this package loaded into one process
319
+ * shares these identities, whatever its version. Within a major that is exactly
320
+ * what is wanted: two resolved instances of the same major agree on what each
321
+ * token binds, so sharing one identity is what makes a duplicated install
322
+ * harmless rather than broken. Across majors it is a hazard: a consumer of one
323
+ * major would resolve, without complaint, a value registered by another against
324
+ * a contract it does not know, and fail later on an unexpected shape instead of
325
+ * immediately on an unresolvable token.
326
+ *
327
+ * That hazard is not specific to the options snapshot. Each token below binds
328
+ * its own contract — the correlation provider, the timing sink, the health
329
+ * indicator array, the metrics registry, the trace-context reader — and every
330
+ * one of them is now shared across majors by the same mechanism. So this belongs
331
+ * on the major-release checklist, not in a comment nobody reads at the right
332
+ * moment: **a major that changes the contract behind any token here must change
333
+ * that token's key in the same commit.** Changing a key is already a breaking
334
+ * change, which is precisely why a major is the only place it can happen.
298
335
  * @layer Constants
299
336
  */
300
337
  /**
package/dist/index.d.ts CHANGED
@@ -295,6 +295,43 @@ declare class BymaxCoreModule extends BymaxCoreModuleBase {
295
295
  * @fileoverview Dependency-injection tokens for `@bymax-one/nest-core`.
296
296
  * Every token is a `Symbol`, so the container never collides with a consumer's
297
297
  * string tokens and the public contracts stay explicit at every injection site.
298
+ *
299
+ * Every token is minted with `Symbol.for`, never `Symbol()`. This package ships
300
+ * one bundle per published subpath and the bundler inlines shared modules into
301
+ * each of them, so this file exists once per bundle at runtime: a `Symbol()`
302
+ * token would mint a *different* identity in `dist/index.cjs` than in
303
+ * `dist/openapi/index.cjs`, and a provider registered from the package root
304
+ * would be unreachable from a subpath that injects "the same" token. That is not
305
+ * hypothetical — it is the 1.3.0 defect that made `applyBymaxOpenApi` throw on
306
+ * every consumer boot. `Symbol.for` resolves through the runtime's global symbol
307
+ * registry, so all copies converge on one identity no matter how many bundles
308
+ * carry them. The same reasoning keeps the health marker's metadata key a
309
+ * literal; see `health/health.marker.ts`.
310
+ *
311
+ * The registry keys below are therefore part of the package's public contract,
312
+ * as binding as the export names: changing one is a breaking change even though
313
+ * no signature moves. They are namespaced with the full npm package name because
314
+ * the registry is process-global and shared with every other library in the
315
+ * application — the package name is the one string guaranteed not to collide.
316
+ *
317
+ * The keys carry no version, which is a deliberate choice with a consequence
318
+ * worth stating plainly. Every copy of this package loaded into one process
319
+ * shares these identities, whatever its version. Within a major that is exactly
320
+ * what is wanted: two resolved instances of the same major agree on what each
321
+ * token binds, so sharing one identity is what makes a duplicated install
322
+ * harmless rather than broken. Across majors it is a hazard: a consumer of one
323
+ * major would resolve, without complaint, a value registered by another against
324
+ * a contract it does not know, and fail later on an unexpected shape instead of
325
+ * immediately on an unresolvable token.
326
+ *
327
+ * That hazard is not specific to the options snapshot. Each token below binds
328
+ * its own contract — the correlation provider, the timing sink, the health
329
+ * indicator array, the metrics registry, the trace-context reader — and every
330
+ * one of them is now shared across majors by the same mechanism. So this belongs
331
+ * on the major-release checklist, not in a comment nobody reads at the right
332
+ * moment: **a major that changes the contract behind any token here must change
333
+ * that token's key in the same commit.** Changing a key is already a breaking
334
+ * change, which is precisely why a major is the only place it can happen.
298
335
  * @layer Constants
299
336
  */
300
337
  /**
package/dist/index.mjs CHANGED
@@ -125,12 +125,18 @@ function normalizeCoreOptions(raw) {
125
125
  normalizeCoreOptions();
126
126
 
127
127
  // src/core.tokens.ts
128
- var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol("BYMAX_CORE_OPTIONS");
129
- var BYMAX_CORRELATION_PROVIDER = /* @__PURE__ */ Symbol("BYMAX_CORRELATION_PROVIDER");
130
- var BYMAX_TIMING_SINK = /* @__PURE__ */ Symbol("BYMAX_TIMING_SINK");
131
- var BYMAX_HEALTH_INDICATORS = /* @__PURE__ */ Symbol("BYMAX_HEALTH_INDICATORS");
132
- var BYMAX_METRICS_REGISTRY = /* @__PURE__ */ Symbol("BYMAX_METRICS_REGISTRY");
133
- var BYMAX_TRACE_CONTEXT = /* @__PURE__ */ Symbol("BYMAX_TRACE_CONTEXT");
128
+ var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:core-options");
129
+ var BYMAX_CORRELATION_PROVIDER = /* @__PURE__ */ Symbol.for(
130
+ "@bymax-one/nest-core:correlation-provider"
131
+ );
132
+ var BYMAX_TIMING_SINK = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:timing-sink");
133
+ var BYMAX_HEALTH_INDICATORS = /* @__PURE__ */ Symbol.for(
134
+ "@bymax-one/nest-core:health-indicators"
135
+ );
136
+ var BYMAX_METRICS_REGISTRY = /* @__PURE__ */ Symbol.for(
137
+ "@bymax-one/nest-core:metrics-registry"
138
+ );
139
+ var BYMAX_TRACE_CONTEXT = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:trace-context");
134
140
 
135
141
  // src/optional-peer.ts
136
142
  function isMissingModuleError(cause) {
@@ -199,7 +205,7 @@ async function resolveTraceContextProvider(options) {
199
205
  var DEFAULT_MONOTONIC_CLOCK = {
200
206
  now: () => performance.now()
201
207
  };
202
- var BYMAX_TIMING_CLOCK = /* @__PURE__ */ Symbol("BYMAX_TIMING_CLOCK");
208
+ var BYMAX_TIMING_CLOCK = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:timing-clock");
203
209
 
204
210
  // src/defaults.providers.ts
205
211
  var NoopCorrelationIdProvider = class {
@@ -5,7 +5,7 @@ var common = require('@nestjs/common');
5
5
  // src/openapi/openapi.bootstrap.ts
6
6
 
7
7
  // src/core.tokens.ts
8
- var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol("BYMAX_CORE_OPTIONS");
8
+ var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:core-options");
9
9
 
10
10
  // src/runtime.environment.ts
11
11
  var NON_PRODUCTION_ENVIRONMENTS = /* @__PURE__ */ new Set(["development", "test"]);
@@ -3,7 +3,7 @@ import { Logger } from '@nestjs/common';
3
3
  // src/openapi/openapi.bootstrap.ts
4
4
 
5
5
  // src/core.tokens.ts
6
- var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol("BYMAX_CORE_OPTIONS");
6
+ var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:core-options");
7
7
 
8
8
  // src/runtime.environment.ts
9
9
  var NON_PRODUCTION_ENVIRONMENTS = /* @__PURE__ */ new Set(["development", "test"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-core",
3
- "version": "1.2.2",
3
+ "version": "1.3.1",
4
4
  "description": "Zero-dependency NestJS 11 application foundation kit: error-envelope exception filter, request-timing interceptor, pagination helpers, health endpoints with indicator discovery, an optional Prometheus metrics endpoint with a contribution contract, OpenAPI documents in development, and OpenTelemetry trace correlation.",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",