@bymax-one/nest-config 1.1.3 → 1.2.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 +56 -1
- package/README.md +72 -7
- package/dist/internal/index.cjs +7 -2
- package/dist/internal/index.d.cts +11 -2
- package/dist/internal/index.d.ts +11 -2
- package/dist/internal/index.mjs +7 -2
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,60 @@ as the GitHub Release body, so each released version needs a matching
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [1.2.0] - 2026-09-04
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **A namespace can declare itself open, so `strict` is usable next to a library that
|
|
19
|
+
reads its own environment.** `strict` claims a declared namespace's entire variable
|
|
20
|
+
prefix: a namespace named `otel` rejects the OpenTelemetry SDK's own
|
|
21
|
+
`OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_TRACES_SAMPLER`, and one named `redis` rejects a
|
|
22
|
+
`REDIS_PORT` only a compose file reads. A prefix matching no declared namespace
|
|
23
|
+
(`POSTGRES_*` with no `postgres` namespace) is never inspected, so the failure lands
|
|
24
|
+
hardest exactly where a schema shares a prefix with another program — which is the common
|
|
25
|
+
case. `OTEL_` is an open standard; a consumer cannot rename around it.
|
|
26
|
+
|
|
27
|
+
`z.object({ ... }).meta({ open: true })` on the namespace waives unknown-key detection
|
|
28
|
+
for the remainder of that prefix. The waiver is narrow by construction: declared leaves
|
|
29
|
+
stay bound and validated (an open `otel` still reads and coerces `OTEL_ENABLED`), it
|
|
30
|
+
applies per namespace rather than per schema, and a more specific closed namespace still
|
|
31
|
+
claims its own variables (`otelExporter` beside an open `otel` still reports
|
|
32
|
+
`OTEL_EXPORTER_TYPO`). Only the literal `true` opens a namespace.
|
|
33
|
+
|
|
34
|
+
**The cost is stated rather than designed away:** an open namespace cannot distinguish a
|
|
35
|
+
foreign variable from a misspelled local one, so a typo of `OTEL_ENABLED` passes and the
|
|
36
|
+
leaf falls back to its default. The two cases are indistinguishable by name. Open the
|
|
37
|
+
namespaces whose prefix genuinely belongs to another program, and leave the rest closed.
|
|
38
|
+
|
|
39
|
+
Filtering the foreign names out of `source` is not an equivalent workaround and is worse
|
|
40
|
+
in a way that is easy to miss: removing `OTEL_*` from the source also unbinds the declared
|
|
41
|
+
`OTEL_ENABLED`, whose `.default()` then manufactures a plausible value while the variable
|
|
42
|
+
silently stops being read.
|
|
43
|
+
|
|
44
|
+
### Security
|
|
45
|
+
|
|
46
|
+
- **Development-only advisories cleared; the published package was never affected.** Eight
|
|
47
|
+
advisories landed against transitive development dependencies across this cycle:
|
|
48
|
+
`browserslist` (GHSA-73wf-gq98-2v4g, GHSA-c83g-rgw3-j3cx, CVSS 7.5 each), `fast-uri`
|
|
49
|
+
(GHSA-5jgf-p345-68v8, GHSA-jqff-g426-hqxp — host confusion; GHSA-f65p-4m7j-42xc,
|
|
50
|
+
GHSA-fph4-wmhf-6fwf — server-side request forgery; CVSS 7.5 each) and `qs`
|
|
51
|
+
(GHSA-4mjr-xmp4-gh2g, GHSA-x5fp-wj9c-mxmx, CVSS 6.3 each). All three are reached through
|
|
52
|
+
the mutation-testing and commit-tooling chains, none is a runtime dependency, and this
|
|
53
|
+
package ships `dist` alone — so no consumer resolved a vulnerable version through it.
|
|
54
|
+
|
|
55
|
+
Recorded here rather than omitted as internal because a consumer reading an advisory feed
|
|
56
|
+
needs to know whether a library in their tree pulled one in, and "it did not" is an answer
|
|
57
|
+
only the maintainer can give. The floors now sit above every affected range and the
|
|
58
|
+
lockfile resolves `browserslist@4.28.8`, `fast-uri@3.1.6` and `qs@6.16.0`.
|
|
59
|
+
|
|
60
|
+
### Documentation
|
|
61
|
+
|
|
62
|
+
- **`strict` now documents what it claims before you enable it.** The option read as an
|
|
63
|
+
unambiguous improvement and gave no warning that a declared namespace claims its whole
|
|
64
|
+
prefix — the behaviour was measured by a consumer only after enabling it broke a boot on
|
|
65
|
+
five correct variables. The API reference gains a `Strict mode and shared prefixes`
|
|
66
|
+
section covering the claim, the open-namespace opt-out, and its cost.
|
|
67
|
+
|
|
14
68
|
## [1.1.3] - 2026-08-18
|
|
15
69
|
|
|
16
70
|
**Documentation.** The runtime bundles are byte-identical to `1.1.2`. Five files differ: the
|
|
@@ -320,4 +374,5 @@ have regressed from. They are kept because the reasoning is worth having.
|
|
|
320
374
|
[1.1.1]: https://github.com/bymaxone/nest-config/compare/v1.1.0...v1.1.1
|
|
321
375
|
[1.1.2]: https://github.com/bymaxone/nest-config/compare/v1.1.1...v1.1.2
|
|
322
376
|
[1.1.3]: https://github.com/bymaxone/nest-config/compare/v1.1.2...v1.1.3
|
|
323
|
-
[
|
|
377
|
+
[1.2.0]: https://github.com/bymaxone/nest-config/compare/v1.1.3...v1.2.0
|
|
378
|
+
[Unreleased]: https://github.com/bymaxone/nest-config/compare/v1.2.0...HEAD
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<a href="https://www.npmjs.com/package/@bymax-one/nest-config"><img src="https://img.shields.io/npm/dm/@bymax-one/nest-config?style=flat-square&colorA=000000&colorB=000000" alt="npm downloads" /></a>
|
|
15
15
|
<a href="https://github.com/bymaxone/nest-config/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/bymaxone/nest-config/ci.yml?branch=main&style=flat-square&colorA=000000&label=CI" alt="CI status" /></a>
|
|
16
16
|
<a href="https://github.com/bymaxone/nest-config/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-config/blob/main/docs/mutation_testing_results.md"><img src="https://img.shields.io/badge/mutation-99.
|
|
17
|
+
<a href="https://github.com/bymaxone/nest-config/blob/main/docs/mutation_testing_results.md"><img src="https://img.shields.io/badge/mutation-99.62%25-brightgreen?style=flat-square&colorA=000000" alt="mutation score" /></a>
|
|
18
18
|
<a href="https://scorecard.dev/viewer/?uri=github.com/bymaxone/nest-config"><img src="https://api.scorecard.dev/projects/github.com/bymaxone/nest-config/badge?style=flat-square" alt="OpenSSF Scorecard" /></a>
|
|
19
19
|
<a href="https://github.com/bymaxone/nest-config/blob/main/LICENSE"><img src="https://img.shields.io/github/license/bymaxone/nest-config?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>
|
|
@@ -258,6 +258,20 @@ database: z.object({
|
|
|
258
258
|
})
|
|
259
259
|
```
|
|
260
260
|
|
|
261
|
+
A namespace can declare itself **open**, which waives strict unknown-key
|
|
262
|
+
detection for the rest of its prefix. Use it when the prefix is shared with
|
|
263
|
+
another program that reads its own variables — see
|
|
264
|
+
[Strict mode and shared prefixes](#strict-mode-and-shared-prefixes):
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
// OTEL_ENABLED is read and validated; every other OTEL_* variable belongs to
|
|
268
|
+
// the OpenTelemetry SDK, which reads it natively.
|
|
269
|
+
otel: z.object({ enabled: z.stringbool().default(false) }).meta({ open: true })
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Only the literal `true` opens a namespace. Any other value, and any metadata
|
|
273
|
+
without the key, leaves detection in force.
|
|
274
|
+
|
|
261
275
|
### `BymaxConfigModule`
|
|
262
276
|
|
|
263
277
|
| Method | Signature |
|
|
@@ -267,12 +281,12 @@ database: z.object({
|
|
|
267
281
|
|
|
268
282
|
`BymaxConfigModuleOptions`:
|
|
269
283
|
|
|
270
|
-
| Field | Type | Required | Notes
|
|
271
|
-
| ------------------- | ---------------------------------------------- | -------- |
|
|
272
|
-
| `schema` | `EnvSchema` | yes | Produced by `defineEnv`.
|
|
273
|
-
| `source` | `Record<string, string \| undefined>` | no | Defaults to `process.env` in the provider factory. Injectable for tests.
|
|
274
|
-
| `onValidationError` | `(issues: ReadonlyArray<ConfigIssue>) => void` | no | Observability hook invoked before the fail-fast throw. Cannot suppress the failure.
|
|
275
|
-
| `strict` | `boolean` | no | When true, source variables matching a namespace prefix but no declared leaf raise `BYMAX_CONFIG_UNKNOWN_KEY`. Defaults to `false`. |
|
|
284
|
+
| Field | Type | Required | Notes |
|
|
285
|
+
| ------------------- | ---------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
286
|
+
| `schema` | `EnvSchema` | yes | Produced by `defineEnv`. |
|
|
287
|
+
| `source` | `Record<string, string \| undefined>` | no | Defaults to `process.env` in the provider factory. Injectable for tests. |
|
|
288
|
+
| `onValidationError` | `(issues: ReadonlyArray<ConfigIssue>) => void` | no | Observability hook invoked before the fail-fast throw. Cannot suppress the failure. |
|
|
289
|
+
| `strict` | `boolean` | no | When true, source variables matching a namespace prefix but no declared leaf raise `BYMAX_CONFIG_UNKNOWN_KEY`. Defaults to `false`. Read [Strict mode and shared prefixes](#strict-mode-and-shared-prefixes) before enabling it. |
|
|
276
290
|
|
|
277
291
|
`forRootAsync` resolves the source through another provider, for example a
|
|
278
292
|
secrets-manager client composed with `process.env`:
|
|
@@ -293,6 +307,53 @@ BymaxConfigModule.forRootAsync({
|
|
|
293
307
|
`isGlobal` defaults to `true` and can be set to `false` through the standard
|
|
294
308
|
extras when an application intentionally scopes configuration to a submodule.
|
|
295
309
|
|
|
310
|
+
#### Strict mode and shared prefixes
|
|
311
|
+
|
|
312
|
+
**A declared namespace claims its entire variable prefix.** Under `strict`, any
|
|
313
|
+
source variable starting with that prefix and matching no declared leaf fails
|
|
314
|
+
the boot — including variables this application never reads because _another
|
|
315
|
+
program_ reads them. A namespace named `otel` claims `OTEL_*`, so the
|
|
316
|
+
OpenTelemetry SDK's own `OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_TRACES_SAMPLER`
|
|
317
|
+
are rejected; a namespace named `redis` claims `REDIS_*`, so a `REDIS_PORT` that
|
|
318
|
+
only a compose file reads is rejected too. A prefix matching no declared
|
|
319
|
+
namespace at all (`POSTGRES_*` with no `postgres` namespace) is never inspected,
|
|
320
|
+
which is why the failure lands hardest on schemas that share a prefix with a
|
|
321
|
+
library or a tool — the common case, not the edge one.
|
|
322
|
+
|
|
323
|
+
Declare such a namespace **open** to waive the check for the remainder of its
|
|
324
|
+
prefix:
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
export const envSchema = defineEnv({
|
|
328
|
+
// OTEL_ENABLED is declared, read and validated. Every other OTEL_* variable
|
|
329
|
+
// is the SDK's, and strict leaves it alone.
|
|
330
|
+
otel: z.object({ enabled: z.stringbool().default(false) }).meta({ open: true }),
|
|
331
|
+
database: z.object({ url: z.url() })
|
|
332
|
+
})
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
What the waiver does and does not do:
|
|
336
|
+
|
|
337
|
+
- **Declared leaves stay bound.** `OTEL_ENABLED` is still read, coerced and
|
|
338
|
+
validated. Opening a namespace waives unknown-key detection only; it never
|
|
339
|
+
weakens the validation the schema does perform.
|
|
340
|
+
- **The waiver is per namespace.** A stray `DATABASE_TYPO` is still reported
|
|
341
|
+
while `otel` is open. One open namespace does not disable strict mode.
|
|
342
|
+
- **The most specific namespace wins.** If a schema declares both `otel` (open)
|
|
343
|
+
and `otelExporter` (closed), `OTEL_EXPORTER_TYPO` belongs to `otelExporter`
|
|
344
|
+
and is still reported.
|
|
345
|
+
|
|
346
|
+
**The cost, stated plainly:** an open namespace cannot tell a foreign variable
|
|
347
|
+
from a misspelled local one. Under an open `otel`, a typo of `OTEL_ENABLED`
|
|
348
|
+
passes silently and the leaf falls back to its default. No design removes this —
|
|
349
|
+
the two cases are indistinguishable by name — so open the namespaces whose
|
|
350
|
+
prefix genuinely belongs to someone else, and leave the rest closed.
|
|
351
|
+
|
|
352
|
+
> Filtering the foreign names out of `source` instead is **not** equivalent, and
|
|
353
|
+
> is worse in a way that is easy to miss: removing `OTEL_*` from the source also
|
|
354
|
+
> unbinds the declared `OTEL_ENABLED`, whose `.default()` then manufactures a
|
|
355
|
+
> plausible value while the variable silently stops being read.
|
|
356
|
+
|
|
296
357
|
### `ConfigService<TConfig>`
|
|
297
358
|
|
|
298
359
|
The typed, injectable accessor over the frozen configuration object.
|
|
@@ -672,6 +733,10 @@ standard is Jest.
|
|
|
672
733
|
4. **No multi-source precedence.** One source record per module
|
|
673
734
|
registration. Precedence between layers (defaults, env, secrets) is the
|
|
674
735
|
caller's composition (`{ ...a, ...b }`), kept explicit on purpose.
|
|
736
|
+
5. **An open namespace cannot detect a typo in its own prefix.** A foreign
|
|
737
|
+
variable and a misspelled local one are indistinguishable by name, so
|
|
738
|
+
`meta({ open: true })` accepts both. See
|
|
739
|
+
[Strict mode and shared prefixes](#strict-mode-and-shared-prefixes).
|
|
675
740
|
|
|
676
741
|
## 🤝 Contributing
|
|
677
742
|
|
package/dist/internal/index.cjs
CHANGED
|
@@ -125,6 +125,9 @@ function readEnvOverride(leaf) {
|
|
|
125
125
|
const override = leaf.meta()?.env;
|
|
126
126
|
return typeof override === "string" && override.length > 0 ? override : void 0;
|
|
127
127
|
}
|
|
128
|
+
function readOpenFlag(namespace) {
|
|
129
|
+
return namespace.meta()?.open === true;
|
|
130
|
+
}
|
|
128
131
|
function deriveVariable(namespace, leafKey) {
|
|
129
132
|
return `${toScreamingSnake(namespace)}_${toScreamingSnake(leafKey)}`;
|
|
130
133
|
}
|
|
@@ -137,9 +140,10 @@ function resolveSourceNames(schema) {
|
|
|
137
140
|
);
|
|
138
141
|
}
|
|
139
142
|
function resolveNamespacePrefixes(schema) {
|
|
140
|
-
return Object.
|
|
143
|
+
return Object.entries(schema.shape).map(([namespace, namespaceSchema]) => ({
|
|
141
144
|
namespace,
|
|
142
|
-
prefix: `${toScreamingSnake(namespace)}_
|
|
145
|
+
prefix: `${toScreamingSnake(namespace)}_`,
|
|
146
|
+
open: readOpenFlag(namespaceSchema)
|
|
143
147
|
}));
|
|
144
148
|
}
|
|
145
149
|
|
|
@@ -240,6 +244,7 @@ function detectUnknownKeys(prefixes, bindings, source) {
|
|
|
240
244
|
if (source.get(key) === void 0) continue;
|
|
241
245
|
const match = longestMatchingPrefix(prefixes, key);
|
|
242
246
|
if (match === void 0) continue;
|
|
247
|
+
if (match.open) continue;
|
|
243
248
|
issues.push({
|
|
244
249
|
path: match.namespace,
|
|
245
250
|
variable: key,
|
|
@@ -240,6 +240,12 @@ interface BymaxConfigModuleOptions<TSchema extends EnvSchema = EnvSchema> {
|
|
|
240
240
|
/**
|
|
241
241
|
* When true, source variables that match a declared namespace prefix but no
|
|
242
242
|
* declared leaf produce `BYMAX_CONFIG_UNKNOWN_KEY` issues. Defaults to false.
|
|
243
|
+
*
|
|
244
|
+
* The prefix is claimed whole, so a namespace sharing its prefix with another
|
|
245
|
+
* program (`OTEL_` with an OpenTelemetry SDK, `REDIS_` with a compose file)
|
|
246
|
+
* would reject that program's variables. Declare such a namespace
|
|
247
|
+
* `meta({ open: true })` to waive the check for the rest of its prefix while
|
|
248
|
+
* its own leaves stay bound and validated.
|
|
243
249
|
*/
|
|
244
250
|
readonly strict?: boolean;
|
|
245
251
|
}
|
|
@@ -562,8 +568,11 @@ declare function createValidatedConfig<TShape extends EnvShape>(options: Omit<By
|
|
|
562
568
|
* @fileoverview Deterministic mapping between nested config paths and flat
|
|
563
569
|
* environment variable names. Each leaf resolves to exactly one variable:
|
|
564
570
|
* SCREAMING_SNAKE_CASE of the joined path (`database.url` reads `DATABASE_URL`),
|
|
565
|
-
* unless the leaf declares a `meta({ env })` override, which wins.
|
|
566
|
-
*
|
|
571
|
+
* unless the leaf declares a `meta({ env })` override, which wins. It also
|
|
572
|
+
* resolves the shared prefix of each namespace and whether that namespace
|
|
573
|
+
* declared `meta({ open: true })`, the two facts strict unknown-key detection
|
|
574
|
+
* runs on. This is an internal module consumed by the validator; it is not part
|
|
575
|
+
* of the public API.
|
|
567
576
|
* @layer Utility
|
|
568
577
|
*/
|
|
569
578
|
|
package/dist/internal/index.d.ts
CHANGED
|
@@ -240,6 +240,12 @@ interface BymaxConfigModuleOptions<TSchema extends EnvSchema = EnvSchema> {
|
|
|
240
240
|
/**
|
|
241
241
|
* When true, source variables that match a declared namespace prefix but no
|
|
242
242
|
* declared leaf produce `BYMAX_CONFIG_UNKNOWN_KEY` issues. Defaults to false.
|
|
243
|
+
*
|
|
244
|
+
* The prefix is claimed whole, so a namespace sharing its prefix with another
|
|
245
|
+
* program (`OTEL_` with an OpenTelemetry SDK, `REDIS_` with a compose file)
|
|
246
|
+
* would reject that program's variables. Declare such a namespace
|
|
247
|
+
* `meta({ open: true })` to waive the check for the rest of its prefix while
|
|
248
|
+
* its own leaves stay bound and validated.
|
|
243
249
|
*/
|
|
244
250
|
readonly strict?: boolean;
|
|
245
251
|
}
|
|
@@ -562,8 +568,11 @@ declare function createValidatedConfig<TShape extends EnvShape>(options: Omit<By
|
|
|
562
568
|
* @fileoverview Deterministic mapping between nested config paths and flat
|
|
563
569
|
* environment variable names. Each leaf resolves to exactly one variable:
|
|
564
570
|
* SCREAMING_SNAKE_CASE of the joined path (`database.url` reads `DATABASE_URL`),
|
|
565
|
-
* unless the leaf declares a `meta({ env })` override, which wins.
|
|
566
|
-
*
|
|
571
|
+
* unless the leaf declares a `meta({ env })` override, which wins. It also
|
|
572
|
+
* resolves the shared prefix of each namespace and whether that namespace
|
|
573
|
+
* declared `meta({ open: true })`, the two facts strict unknown-key detection
|
|
574
|
+
* runs on. This is an internal module consumed by the validator; it is not part
|
|
575
|
+
* of the public API.
|
|
567
576
|
* @layer Utility
|
|
568
577
|
*/
|
|
569
578
|
|
package/dist/internal/index.mjs
CHANGED
|
@@ -123,6 +123,9 @@ function readEnvOverride(leaf) {
|
|
|
123
123
|
const override = leaf.meta()?.env;
|
|
124
124
|
return typeof override === "string" && override.length > 0 ? override : void 0;
|
|
125
125
|
}
|
|
126
|
+
function readOpenFlag(namespace) {
|
|
127
|
+
return namespace.meta()?.open === true;
|
|
128
|
+
}
|
|
126
129
|
function deriveVariable(namespace, leafKey) {
|
|
127
130
|
return `${toScreamingSnake(namespace)}_${toScreamingSnake(leafKey)}`;
|
|
128
131
|
}
|
|
@@ -135,9 +138,10 @@ function resolveSourceNames(schema) {
|
|
|
135
138
|
);
|
|
136
139
|
}
|
|
137
140
|
function resolveNamespacePrefixes(schema) {
|
|
138
|
-
return Object.
|
|
141
|
+
return Object.entries(schema.shape).map(([namespace, namespaceSchema]) => ({
|
|
139
142
|
namespace,
|
|
140
|
-
prefix: `${toScreamingSnake(namespace)}_
|
|
143
|
+
prefix: `${toScreamingSnake(namespace)}_`,
|
|
144
|
+
open: readOpenFlag(namespaceSchema)
|
|
141
145
|
}));
|
|
142
146
|
}
|
|
143
147
|
|
|
@@ -238,6 +242,7 @@ function detectUnknownKeys(prefixes, bindings, source) {
|
|
|
238
242
|
if (source.get(key) === void 0) continue;
|
|
239
243
|
const match = longestMatchingPrefix(prefixes, key);
|
|
240
244
|
if (match === void 0) continue;
|
|
245
|
+
if (match.open) continue;
|
|
241
246
|
issues.push({
|
|
242
247
|
path: match.namespace,
|
|
243
248
|
variable: key,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bymax-one/nest-config",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Typed and validated environment configuration entry point for NestJS 11 applications, built on Zod v4.",
|
|
5
5
|
"author": "Bymax One <support@bymax.one>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -56,16 +56,17 @@
|
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "pnpm clean && tsup",
|
|
58
58
|
"check:exports": "attw --pack . --profile strict",
|
|
59
|
+
"check:lint-graph": "node scripts/check-lint-graph-rules.mjs",
|
|
59
60
|
"check:mutants": "node scripts/check-mutation-directives.mjs",
|
|
60
61
|
"check:published": "node scripts/check-published-surface.mjs",
|
|
61
62
|
"check:runtime": "node scripts/check-consumer-runtime.mjs",
|
|
62
63
|
"clean": "node -e \"const fs=require('node:fs');for(const d of ['dist','coverage'])fs.rmSync(d,{recursive:true,force:true})\"",
|
|
63
64
|
"dogfood": "node scripts/dogfood-smoke-test.mjs",
|
|
64
|
-
"lint": "eslint src",
|
|
65
|
-
"lint:fix": "eslint src --fix",
|
|
65
|
+
"lint": "eslint src scripts",
|
|
66
|
+
"lint:fix": "eslint src scripts --fix",
|
|
66
67
|
"mutation": "stryker run",
|
|
67
|
-
"mutation:full": "node -e \"require('node:fs').rmSync('reports/stryker-incremental.json',{force:true,recursive:true})\" && stryker run",
|
|
68
68
|
"mutation:dry-run": "stryker run --dryRunOnly",
|
|
69
|
+
"mutation:full": "node -e \"require('node:fs').rmSync('reports/stryker-incremental.json',{force:true,recursive:true})\" && stryker run",
|
|
69
70
|
"prepare": "husky",
|
|
70
71
|
"prepublishOnly": "pnpm typecheck && pnpm lint && pnpm check:mutants && pnpm test:cov:all && pnpm build && pnpm size && pnpm check:published",
|
|
71
72
|
"release": "npm publish --provenance --access public",
|
|
@@ -86,7 +87,6 @@
|
|
|
86
87
|
"prettier --write"
|
|
87
88
|
]
|
|
88
89
|
},
|
|
89
|
-
"dependencies": {},
|
|
90
90
|
"peerDependencies": {
|
|
91
91
|
"@nestjs/common": "^11.0.16",
|
|
92
92
|
"@nestjs/core": "^11.1.18",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
98
98
|
"@commitlint/cli": "^21.0.2",
|
|
99
99
|
"@commitlint/config-conventional": "^21.0.2",
|
|
100
|
-
"@eslint/js": "^
|
|
100
|
+
"@eslint/js": "^10.0.1",
|
|
101
101
|
"@nestjs/common": "^11.1.20",
|
|
102
102
|
"@nestjs/core": "^11.1.20",
|
|
103
103
|
"@nestjs/platform-express": "^11.1.20",
|
|
@@ -110,10 +110,10 @@
|
|
|
110
110
|
"@types/node": "^25",
|
|
111
111
|
"@typescript-eslint/eslint-plugin": "^8.59.3",
|
|
112
112
|
"@typescript-eslint/parser": "^8.59.3",
|
|
113
|
-
"eslint": "^9.
|
|
113
|
+
"eslint": "^10.9.1",
|
|
114
114
|
"eslint-config-prettier": "^10.1.8",
|
|
115
|
-
"eslint-import-resolver-typescript": "^4.4.
|
|
116
|
-
"eslint-plugin-import": "^
|
|
115
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
116
|
+
"eslint-plugin-import-x": "^4.17.1",
|
|
117
117
|
"eslint-plugin-prettier": "^5.5.5",
|
|
118
118
|
"eslint-plugin-security": "^4.0.0",
|
|
119
119
|
"globals": "^17.6.0",
|