@bymax-one/nest-config 1.0.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 ADDED
@@ -0,0 +1,106 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@bymax-one/nest-config` are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ The `release.yml` workflow extracts the section matching the pushed `vX.Y.Z` tag
9
+ as the GitHub Release body, so each released version needs a matching
10
+ `## [X.Y.Z]` heading here.
11
+
12
+ ## [Unreleased]
13
+
14
+ ## [1.0.0] - 2026-08-03
15
+
16
+ First published release. Everything below ships in it.
17
+
18
+ The `Fixed` and `Security` entries record defects found and corrected before
19
+ publication, not regressions any consumer saw — there is no earlier release to
20
+ have regressed from. They are kept because the reasoning is worth having.
21
+
22
+ ### Added
23
+
24
+ - `defineEnv`: a thin, typed factory over `z.object(...)` establishing the
25
+ two-level namespace convention, with deterministic `SCREAMING_SNAKE_CASE`
26
+ source-variable mapping and a `meta({ env })` override for legacy names.
27
+ - Validation pipeline: a single aggregated pass over the source that never
28
+ echoes raw values, exposed through `BymaxConfigValidationError`,
29
+ `ConfigIssue`, and the frozen `ConfigErrorCode` catalog
30
+ (`BYMAX_CONFIG_VALIDATION`, `BYMAX_CONFIG_MISSING`, `BYMAX_CONFIG_INVALID`,
31
+ `BYMAX_CONFIG_UNKNOWN_KEY`).
32
+ - `BymaxConfigModule`: a global NestJS dynamic module with `forRoot` and
33
+ `forRootAsync` registration, the `BYMAX_CONFIG` and `BYMAX_CONFIG_OPTIONS`
34
+ Symbol injection tokens, and deep-freezing of the validated configuration
35
+ before it enters the DI container.
36
+ - `ConfigService<TConfig>`: a typed accessor with compile-time dot-path
37
+ inference (`get`, `getAll`, `has`) limited to the two-level namespace
38
+ convention.
39
+ - `./testing` subpath: `createTestConfig` and `configTestingModule`,
40
+ synthesizing a complete, schema-compliant source with selective overrides
41
+ and running the exact production validation and freeze pipeline.
42
+ - Repository scaffold: package manifest with the two-subpath exports map,
43
+ build tooling, lint and test configuration, mutation testing configuration,
44
+ commit governance, and the open-source baseline files.
45
+
46
+ - **`pnpm check:exports`** runs `attw --pack . --profile strict` against the packed
47
+ tarball, which is what surfaced both resolution defects above.
48
+ - **`pnpm check:runtime`** packs the tarball, lays it out the way npm would, and
49
+ boots NestJS against it in ESM _and_ CommonJS, registering `configTestingModule`
50
+ and resolving the root's tokens through it. Every other gate reads the source or
51
+ the declarations, so a defect in how the entry points are bundled was invisible
52
+ to all of them. Both run in CI, as their own release steps — they pack a
53
+ tarball, and a pack nested inside a publish fails, so they cannot live in
54
+ `prepublishOnly`.
55
+ - **An end-to-end spec for the `./testing` subpath**, run against `dist`. The e2e
56
+ harness already resolved the built artifact but never exercised the two entry
57
+ points together, which is the gap the defect lived in.
58
+
59
+ ### Fixed
60
+
61
+ - **`configTestingModule()` provided tokens no consumer could inject.** Registering
62
+ it from `@bymax-one/nest-config/testing` and then resolving `ConfigService` or
63
+ `BYMAX_CONFIG` imported from the package root failed with
64
+ `UnknownElementException` — the flow `configTestingModule`'s own documentation
65
+ describes. `createTestConfig` rejected with a `BymaxConfigValidationError` that
66
+ did not satisfy `instanceof` against the class the root exports, so a consumer
67
+ narrowing on it silently reported an unexpected failure instead of a
68
+ configuration one.
69
+
70
+ Each entry point is a separate bundle, so `BymaxConfigModule`,
71
+ `BymaxConfigValidationError` and the validation helpers the testing subpath
72
+ reached by a relative path were copied into it. A copied class is a different
73
+ injection token and a different `instanceof` target. The shared runtime now
74
+ lives in one bundle, `./internal`, which both entry points import by package
75
+ specifier — one identity in CommonJS as well as ESM, which code splitting could
76
+ not give, since esbuild splits ESM only. The testing bundle drops from 20.7 KB
77
+ to 6.2 KB, the duplicate being all of the difference.
78
+
79
+ - **CommonJS consumers resolved ESM type declarations.** The `exports` map
80
+ declared a single `types` condition, so `require()` landed on `.d.ts` instead of
81
+ `.d.cts` — `attw` reports it as _Masquerading as ESM_ on both subpaths. Types
82
+ are now declared per condition.
83
+
84
+ - **`node10` type resolution failed outright** for both subpaths: the manifest
85
+ carried no `main`, `module` or `types`, and no `typesVersions`. All four are now
86
+ present.
87
+
88
+ ### Security
89
+
90
+ - **Peer floors raised to exclude known-vulnerable NestJS versions.** The declared
91
+ ranges were `@nestjs/common ^11.0.0` and `@nestjs/core ^11.0.0`, and both
92
+ admitted versions carrying published advisories:
93
+
94
+ | Peer | Advisory | Vulnerable | New floor |
95
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ---------- |
96
+ | `@nestjs/common` | [GHSA-cj7v-w2c7-cp7c](https://github.com/advisories/GHSA-cj7v-w2c7-cp7c) — remote code execution via the `Content-Type` header | `>= 11.0.0-next.1, < 11.0.16` | `^11.0.16` |
97
+ | `@nestjs/core` | [GHSA-36xv-jgw5-4q75](https://github.com/advisories/GHSA-36xv-jgw5-4q75) — improper neutralization of special elements in downstream output | `<= 11.1.17` | `^11.1.18` |
98
+
99
+ A peer range is a statement about which versions this library supports. A floor
100
+ below a published advisory tells a consumer that a vulnerable install is a
101
+ supported one, and nothing in their tooling contradicts it — the install resolves
102
+ cleanly and silently. Corrected before the first publish, so no released version
103
+ ever carried the permissive range. No runtime behaviour changed.
104
+
105
+ [1.0.0]: https://github.com/bymaxone/nest-config/releases/tag/v1.0.0
106
+ [Unreleased]: https://github.com/bymaxone/nest-config/compare/v1.0.0...HEAD
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bymax One
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.