@bymax-one/nest-config 1.2.4 → 1.2.5
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 +31 -1
- package/README.md +2 -1
- package/dist/internal/index.cjs +0 -126
- package/dist/internal/index.mjs +0 -126
- package/dist/testing/index.cjs +14 -2
- package/dist/testing/index.mjs +14 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,35 @@ as the GitHub Release body, so each released version needs a matching
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [1.2.5] - 2026-11-01
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **A test override that is not a plain object is one issue.** A namespace given `null` threw a raw
|
|
19
|
+
`TypeError`, an array produced one issue per index, a `Map` or a `Date` applied
|
|
20
|
+
nothing and said nothing, and a class instance had its own fields read as overrides. `createTestConfig` and `configTestingModule` now report each of them once,
|
|
21
|
+
by name, as "the override for `x` must be an object", in the same `BymaxConfigValidationError` as any
|
|
22
|
+
unmatched path. The overrides argument itself is held to the same rule and reported as "the overrides
|
|
23
|
+
must be an object"; `undefined` and `null` still mean no overrides.
|
|
24
|
+
|
|
25
|
+
#### Apply to a derived backend
|
|
26
|
+
|
|
27
|
+
Run the test suites. A test that expected a `TypeError` for a `null` namespace now receives a
|
|
28
|
+
`BymaxConfigValidationError`. A namespace override given as a class instance was applied field by
|
|
29
|
+
field; it is now refused, so pass a plain object. A `Map` or a `Date` as a namespace override was
|
|
30
|
+
ignored; it is now refused too.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- **The shipped bundles no longer carry comments.** The build runs `scripts/strip-bundle-comments.mjs`
|
|
35
|
+
after `tsup`: every comment is removed from `index.mjs` and `index.cjs` except the legal,
|
|
36
|
+
bundler-annotation and region-marker ones the script keeps, and the script proves with the
|
|
37
|
+
TypeScript parser that it changed no code. The documentation people read
|
|
38
|
+
comes from the `.d.ts` files, which are untouched. The internal bundle goes from 22,079 to 16,652
|
|
39
|
+
bytes and the package from 68.3 to 65.5 kB. Nothing to apply in a derived backend.
|
|
40
|
+
- **The internal bundle has a size budget.** `scripts/check-size.mjs` gates `dist/internal/index.mjs`,
|
|
41
|
+
which carries nearly all of the code, at 4.6 KiB brotli. Tooling only.
|
|
42
|
+
|
|
14
43
|
## [1.2.4] - 2026-11-01
|
|
15
44
|
|
|
16
45
|
### Fixed
|
|
@@ -556,4 +585,5 @@ have regressed from. They are kept because the reasoning is worth having.
|
|
|
556
585
|
[1.2.2]: https://github.com/bymaxone/nest-config/compare/v1.2.1...v1.2.2
|
|
557
586
|
[1.2.3]: https://github.com/bymaxone/nest-config/compare/v1.2.2...v1.2.3
|
|
558
587
|
[1.2.4]: https://github.com/bymaxone/nest-config/compare/v1.2.3...v1.2.4
|
|
559
|
-
[
|
|
588
|
+
[1.2.5]: https://github.com/bymaxone/nest-config/compare/v1.2.4...v1.2.5
|
|
589
|
+
[Unreleased]: https://github.com/bymaxone/nest-config/compare/v1.2.5...HEAD
|
package/README.md
CHANGED
|
@@ -913,7 +913,8 @@ Overrides mirror the `namespace.leaf` shape with every key optional and typed fr
|
|
|
913
913
|
a leaf what its environment variable would hold; an object becomes `'[object Object]'`, and an override
|
|
914
914
|
of `undefined` is ignored, so a defaulted leaf cannot be unset. An override whose path matches no leaf
|
|
915
915
|
of the schema throws, listing every such path, even when its value is `undefined`; a namespace given
|
|
916
|
-
something other than
|
|
916
|
+
something other than a plain object is reported once, by name, and so is an overrides argument that is
|
|
917
|
+
not a plain object; passing `undefined` or `null` for the whole argument means no overrides. Neither helper takes `strict`, a
|
|
917
918
|
custom `source`, a hook or `isGlobal`: `configTestingModule` registers the module globally, and a
|
|
918
919
|
failure case (a missing variable, a strict violation) is built with
|
|
919
920
|
`BymaxConfigModule.forRoot({ schema, source, strict: true })` and a source you write.
|
package/dist/internal/index.cjs
CHANGED
|
@@ -81,22 +81,12 @@ function formatIssueReport(issues) {
|
|
|
81
81
|
|
|
82
82
|
// src/errors.ts
|
|
83
83
|
var ConfigErrorCode = Object.freeze({
|
|
84
|
-
/** Top-level error code: one or more schema violations were collected. */
|
|
85
84
|
VALIDATION: "BYMAX_CONFIG_VALIDATION",
|
|
86
|
-
/** Issue code: a required variable is absent from the source. */
|
|
87
85
|
MISSING: "BYMAX_CONFIG_MISSING",
|
|
88
|
-
/** Issue code: a variable is present but violates its constraint. */
|
|
89
86
|
INVALID: "BYMAX_CONFIG_INVALID",
|
|
90
|
-
/** Issue code: strict mode found a source variable matching no declared leaf. */
|
|
91
87
|
UNKNOWN_KEY: "BYMAX_CONFIG_UNKNOWN_KEY"
|
|
92
88
|
});
|
|
93
89
|
var BymaxConfigValidationError = class _BymaxConfigValidationError extends Error {
|
|
94
|
-
/**
|
|
95
|
-
* Build the aggregated error from the collected issues.
|
|
96
|
-
*
|
|
97
|
-
* @param issues - Every collected violation; copied and frozen so neither the
|
|
98
|
-
* caller nor consumer code can mutate the reported list.
|
|
99
|
-
*/
|
|
100
90
|
constructor(issues) {
|
|
101
91
|
const normalized = issues.map(
|
|
102
92
|
(issue) => Object.freeze({
|
|
@@ -107,7 +97,6 @@ var BymaxConfigValidationError = class _BymaxConfigValidationError extends Error
|
|
|
107
97
|
})
|
|
108
98
|
);
|
|
109
99
|
super(formatIssueReport(normalized));
|
|
110
|
-
/** The stable top-level error code. */
|
|
111
100
|
this.code = ConfigErrorCode.VALIDATION;
|
|
112
101
|
Object.defineProperty(this, "name", {
|
|
113
102
|
value: "BymaxConfigValidationError",
|
|
@@ -404,35 +393,8 @@ var bymaxConfigProvider = {
|
|
|
404
393
|
};
|
|
405
394
|
var _config, _leaves;
|
|
406
395
|
exports.ConfigService = class ConfigService {
|
|
407
|
-
/**
|
|
408
|
-
* Bind the accessor to the frozen configuration object.
|
|
409
|
-
*
|
|
410
|
-
* Builds a flat `namespace.leaf` lookup once so `get`/`has` are constant-time
|
|
411
|
-
* and never rebuild a map per call. Iteration over entries (rather than dynamic
|
|
412
|
-
* bracket indexing) avoids introducing a non-literal property sink.
|
|
413
|
-
*
|
|
414
|
-
* @param config - The validated, deep-frozen config injected via {@link BYMAX_CONFIG}.
|
|
415
|
-
*/
|
|
416
396
|
constructor(config) {
|
|
417
|
-
/**
|
|
418
|
-
* The frozen configuration root.
|
|
419
|
-
*
|
|
420
|
-
* Held in an ECMAScript private field rather than a TypeScript `private`
|
|
421
|
-
* property: `private` is erased at runtime, leaving an enumerable own
|
|
422
|
-
* property that `JSON.stringify`, `Object.entries`, object spread and
|
|
423
|
-
* `util.inspect` all walk into. This object aggregates every secret the
|
|
424
|
-
* application declared, so any code that incidentally serializes the
|
|
425
|
-
* injected service — a logger that renders its arguments, an observability
|
|
426
|
-
* SDK capturing the scope of a thrown error, a stray `console.log` — would
|
|
427
|
-
* emit them in plaintext. A `#` field is unreachable to all of those.
|
|
428
|
-
*/
|
|
429
397
|
__privateAdd(this, _config);
|
|
430
|
-
/**
|
|
431
|
-
* Precomputed `namespace.leaf` to value lookup, built once at construction.
|
|
432
|
-
*
|
|
433
|
-
* An ECMAScript private field for the same reason as the config root: it
|
|
434
|
-
* holds the same values, flattened.
|
|
435
|
-
*/
|
|
436
398
|
__privateAdd(this, _leaves);
|
|
437
399
|
__privateSet(this, _config, config);
|
|
438
400
|
const leaves = /* @__PURE__ */ new Map();
|
|
@@ -443,86 +405,21 @@ exports.ConfigService = class ConfigService {
|
|
|
443
405
|
}
|
|
444
406
|
__privateSet(this, _leaves, leaves);
|
|
445
407
|
}
|
|
446
|
-
/**
|
|
447
|
-
* Describe the service for serialization without disclosing any value.
|
|
448
|
-
*
|
|
449
|
-
* `JSON.stringify` on an instance would otherwise yield `{}`, which reads as
|
|
450
|
-
* a bug rather than as a deliberate omission. Returning the namespace names
|
|
451
|
-
* keeps the output useful for debugging while the values stay unreachable.
|
|
452
|
-
*
|
|
453
|
-
* @returns The declared namespace names, never their contents.
|
|
454
|
-
* @example
|
|
455
|
-
* ```typescript
|
|
456
|
-
* JSON.stringify(config); // {"service":"ConfigService","namespaces":["server","database"]}
|
|
457
|
-
* ```
|
|
458
|
-
*/
|
|
459
408
|
toJSON() {
|
|
460
409
|
return {
|
|
461
410
|
service: "ConfigService",
|
|
462
411
|
namespaces: Object.keys(__privateGet(this, _config))
|
|
463
412
|
};
|
|
464
413
|
}
|
|
465
|
-
/**
|
|
466
|
-
* Read a leaf value by its `namespace.leaf` dot-path.
|
|
467
|
-
*
|
|
468
|
-
* The return type is inferred from the path, so `get('server.port')` is typed
|
|
469
|
-
* `number` with no cast. Never throws for a declared path: validation ran once
|
|
470
|
-
* at bootstrap. An optional leaf without a default may still resolve to
|
|
471
|
-
* `undefined` when its type includes it.
|
|
472
|
-
*
|
|
473
|
-
* @typeParam TPath - A declared path drawn from {@link Path}<TConfig>.
|
|
474
|
-
* @param path - The two-level dot-path to resolve.
|
|
475
|
-
* @returns The leaf value, typed as {@link PathValue}<TConfig, TPath>.
|
|
476
|
-
* @example
|
|
477
|
-
* ```typescript
|
|
478
|
-
* const port = config.get('server.port'); // number
|
|
479
|
-
* ```
|
|
480
|
-
*/
|
|
481
414
|
get(path) {
|
|
482
415
|
return this.resolve(path);
|
|
483
416
|
}
|
|
484
|
-
/**
|
|
485
|
-
* Return the whole validated configuration as its deep-frozen root.
|
|
486
|
-
*
|
|
487
|
-
* Yields the same frozen reference the module registered, fully typed for
|
|
488
|
-
* arbitrary depth, which is the escape hatch for nesting deeper than the
|
|
489
|
-
* two-level dot-path inference covers.
|
|
490
|
-
*
|
|
491
|
-
* @returns The frozen configuration root.
|
|
492
|
-
* @example
|
|
493
|
-
* ```typescript
|
|
494
|
-
* const everything = config.getAll(); // Readonly<AppConfig>
|
|
495
|
-
* ```
|
|
496
|
-
*/
|
|
497
417
|
getAll() {
|
|
498
418
|
return __privateGet(this, _config);
|
|
499
419
|
}
|
|
500
|
-
/**
|
|
501
|
-
* Report whether a declared path resolves to a defined value.
|
|
502
|
-
*
|
|
503
|
-
* Returns `false` when the leaf resolved to `undefined` (an optional leaf
|
|
504
|
-
* without a default), distinguishing "declared but unset" from "declared and
|
|
505
|
-
* set" without a truthiness pitfall on falsy values such as `0` or `''`.
|
|
506
|
-
*
|
|
507
|
-
* @param path - The two-level dot-path to check.
|
|
508
|
-
* @returns True when the resolved value is not `undefined`.
|
|
509
|
-
* @example
|
|
510
|
-
* ```typescript
|
|
511
|
-
* if (config.has('redis.url')) connectRedis(config.get('redis.url'));
|
|
512
|
-
* ```
|
|
513
|
-
*/
|
|
514
420
|
has(path) {
|
|
515
421
|
return this.resolve(path) !== void 0;
|
|
516
422
|
}
|
|
517
|
-
/**
|
|
518
|
-
* Resolve a two-level dot-path to its raw leaf value.
|
|
519
|
-
*
|
|
520
|
-
* Looks the path up in the precomputed `namespace.leaf` map, so an unset leaf
|
|
521
|
-
* (or, defensively, an unexpected path) yields `undefined` instead of throwing.
|
|
522
|
-
*
|
|
523
|
-
* @param path - The declared two-level dot-path.
|
|
524
|
-
* @returns The leaf value as `unknown`, or `undefined` when the leaf is unset.
|
|
525
|
-
*/
|
|
526
423
|
resolve(path) {
|
|
527
424
|
return __privateGet(this, _leaves).get(String(path));
|
|
528
425
|
}
|
|
@@ -539,35 +436,12 @@ function appendTo(list, ...items) {
|
|
|
539
436
|
return list === void 0 ? [...items] : [...list, ...items];
|
|
540
437
|
}
|
|
541
438
|
exports.BymaxConfigModule = class BymaxConfigModule extends ConfigurableModuleClass {
|
|
542
|
-
/**
|
|
543
|
-
* Register the module synchronously from a static schema.
|
|
544
|
-
*
|
|
545
|
-
* @param options - The module options plus the optional `isGlobal` extra.
|
|
546
|
-
* @returns The dynamic module augmented with the frozen config provider.
|
|
547
|
-
*/
|
|
548
439
|
static forRoot(options) {
|
|
549
440
|
return exports.BymaxConfigModule.withConfigProvider(super.forRoot(options));
|
|
550
441
|
}
|
|
551
|
-
/**
|
|
552
|
-
* Register the module asynchronously, resolving options through a factory.
|
|
553
|
-
*
|
|
554
|
-
* @param options - The async options with `useFactory` and explicit `inject`.
|
|
555
|
-
* @returns The dynamic module augmented with the frozen config provider.
|
|
556
|
-
*/
|
|
557
442
|
static forRootAsync(options) {
|
|
558
443
|
return exports.BymaxConfigModule.withConfigProvider(super.forRootAsync(options));
|
|
559
444
|
}
|
|
560
|
-
/**
|
|
561
|
-
* Append the config provider and typed accessor to a generated definition.
|
|
562
|
-
*
|
|
563
|
-
* Registers the frozen {@link BYMAX_CONFIG} provider and the {@link ConfigService}
|
|
564
|
-
* accessor (which injects that token), then exports both so consumers can
|
|
565
|
-
* inject either the raw frozen object or the typed service.
|
|
566
|
-
*
|
|
567
|
-
* @param definition - The dynamic module produced by the builder base class.
|
|
568
|
-
* @returns A definition that provides and exports {@link BYMAX_CONFIG} and
|
|
569
|
-
* {@link ConfigService}.
|
|
570
|
-
*/
|
|
571
445
|
static withConfigProvider(definition) {
|
|
572
446
|
return {
|
|
573
447
|
...definition,
|
package/dist/internal/index.mjs
CHANGED
|
@@ -79,22 +79,12 @@ function formatIssueReport(issues) {
|
|
|
79
79
|
|
|
80
80
|
// src/errors.ts
|
|
81
81
|
var ConfigErrorCode = Object.freeze({
|
|
82
|
-
/** Top-level error code: one or more schema violations were collected. */
|
|
83
82
|
VALIDATION: "BYMAX_CONFIG_VALIDATION",
|
|
84
|
-
/** Issue code: a required variable is absent from the source. */
|
|
85
83
|
MISSING: "BYMAX_CONFIG_MISSING",
|
|
86
|
-
/** Issue code: a variable is present but violates its constraint. */
|
|
87
84
|
INVALID: "BYMAX_CONFIG_INVALID",
|
|
88
|
-
/** Issue code: strict mode found a source variable matching no declared leaf. */
|
|
89
85
|
UNKNOWN_KEY: "BYMAX_CONFIG_UNKNOWN_KEY"
|
|
90
86
|
});
|
|
91
87
|
var BymaxConfigValidationError = class _BymaxConfigValidationError extends Error {
|
|
92
|
-
/**
|
|
93
|
-
* Build the aggregated error from the collected issues.
|
|
94
|
-
*
|
|
95
|
-
* @param issues - Every collected violation; copied and frozen so neither the
|
|
96
|
-
* caller nor consumer code can mutate the reported list.
|
|
97
|
-
*/
|
|
98
88
|
constructor(issues) {
|
|
99
89
|
const normalized = issues.map(
|
|
100
90
|
(issue) => Object.freeze({
|
|
@@ -105,7 +95,6 @@ var BymaxConfigValidationError = class _BymaxConfigValidationError extends Error
|
|
|
105
95
|
})
|
|
106
96
|
);
|
|
107
97
|
super(formatIssueReport(normalized));
|
|
108
|
-
/** The stable top-level error code. */
|
|
109
98
|
this.code = ConfigErrorCode.VALIDATION;
|
|
110
99
|
Object.defineProperty(this, "name", {
|
|
111
100
|
value: "BymaxConfigValidationError",
|
|
@@ -402,35 +391,8 @@ var bymaxConfigProvider = {
|
|
|
402
391
|
};
|
|
403
392
|
var _config, _leaves;
|
|
404
393
|
var ConfigService = class {
|
|
405
|
-
/**
|
|
406
|
-
* Bind the accessor to the frozen configuration object.
|
|
407
|
-
*
|
|
408
|
-
* Builds a flat `namespace.leaf` lookup once so `get`/`has` are constant-time
|
|
409
|
-
* and never rebuild a map per call. Iteration over entries (rather than dynamic
|
|
410
|
-
* bracket indexing) avoids introducing a non-literal property sink.
|
|
411
|
-
*
|
|
412
|
-
* @param config - The validated, deep-frozen config injected via {@link BYMAX_CONFIG}.
|
|
413
|
-
*/
|
|
414
394
|
constructor(config) {
|
|
415
|
-
/**
|
|
416
|
-
* The frozen configuration root.
|
|
417
|
-
*
|
|
418
|
-
* Held in an ECMAScript private field rather than a TypeScript `private`
|
|
419
|
-
* property: `private` is erased at runtime, leaving an enumerable own
|
|
420
|
-
* property that `JSON.stringify`, `Object.entries`, object spread and
|
|
421
|
-
* `util.inspect` all walk into. This object aggregates every secret the
|
|
422
|
-
* application declared, so any code that incidentally serializes the
|
|
423
|
-
* injected service — a logger that renders its arguments, an observability
|
|
424
|
-
* SDK capturing the scope of a thrown error, a stray `console.log` — would
|
|
425
|
-
* emit them in plaintext. A `#` field is unreachable to all of those.
|
|
426
|
-
*/
|
|
427
395
|
__privateAdd(this, _config);
|
|
428
|
-
/**
|
|
429
|
-
* Precomputed `namespace.leaf` to value lookup, built once at construction.
|
|
430
|
-
*
|
|
431
|
-
* An ECMAScript private field for the same reason as the config root: it
|
|
432
|
-
* holds the same values, flattened.
|
|
433
|
-
*/
|
|
434
396
|
__privateAdd(this, _leaves);
|
|
435
397
|
__privateSet(this, _config, config);
|
|
436
398
|
const leaves = /* @__PURE__ */ new Map();
|
|
@@ -441,86 +403,21 @@ var ConfigService = class {
|
|
|
441
403
|
}
|
|
442
404
|
__privateSet(this, _leaves, leaves);
|
|
443
405
|
}
|
|
444
|
-
/**
|
|
445
|
-
* Describe the service for serialization without disclosing any value.
|
|
446
|
-
*
|
|
447
|
-
* `JSON.stringify` on an instance would otherwise yield `{}`, which reads as
|
|
448
|
-
* a bug rather than as a deliberate omission. Returning the namespace names
|
|
449
|
-
* keeps the output useful for debugging while the values stay unreachable.
|
|
450
|
-
*
|
|
451
|
-
* @returns The declared namespace names, never their contents.
|
|
452
|
-
* @example
|
|
453
|
-
* ```typescript
|
|
454
|
-
* JSON.stringify(config); // {"service":"ConfigService","namespaces":["server","database"]}
|
|
455
|
-
* ```
|
|
456
|
-
*/
|
|
457
406
|
toJSON() {
|
|
458
407
|
return {
|
|
459
408
|
service: "ConfigService",
|
|
460
409
|
namespaces: Object.keys(__privateGet(this, _config))
|
|
461
410
|
};
|
|
462
411
|
}
|
|
463
|
-
/**
|
|
464
|
-
* Read a leaf value by its `namespace.leaf` dot-path.
|
|
465
|
-
*
|
|
466
|
-
* The return type is inferred from the path, so `get('server.port')` is typed
|
|
467
|
-
* `number` with no cast. Never throws for a declared path: validation ran once
|
|
468
|
-
* at bootstrap. An optional leaf without a default may still resolve to
|
|
469
|
-
* `undefined` when its type includes it.
|
|
470
|
-
*
|
|
471
|
-
* @typeParam TPath - A declared path drawn from {@link Path}<TConfig>.
|
|
472
|
-
* @param path - The two-level dot-path to resolve.
|
|
473
|
-
* @returns The leaf value, typed as {@link PathValue}<TConfig, TPath>.
|
|
474
|
-
* @example
|
|
475
|
-
* ```typescript
|
|
476
|
-
* const port = config.get('server.port'); // number
|
|
477
|
-
* ```
|
|
478
|
-
*/
|
|
479
412
|
get(path) {
|
|
480
413
|
return this.resolve(path);
|
|
481
414
|
}
|
|
482
|
-
/**
|
|
483
|
-
* Return the whole validated configuration as its deep-frozen root.
|
|
484
|
-
*
|
|
485
|
-
* Yields the same frozen reference the module registered, fully typed for
|
|
486
|
-
* arbitrary depth, which is the escape hatch for nesting deeper than the
|
|
487
|
-
* two-level dot-path inference covers.
|
|
488
|
-
*
|
|
489
|
-
* @returns The frozen configuration root.
|
|
490
|
-
* @example
|
|
491
|
-
* ```typescript
|
|
492
|
-
* const everything = config.getAll(); // Readonly<AppConfig>
|
|
493
|
-
* ```
|
|
494
|
-
*/
|
|
495
415
|
getAll() {
|
|
496
416
|
return __privateGet(this, _config);
|
|
497
417
|
}
|
|
498
|
-
/**
|
|
499
|
-
* Report whether a declared path resolves to a defined value.
|
|
500
|
-
*
|
|
501
|
-
* Returns `false` when the leaf resolved to `undefined` (an optional leaf
|
|
502
|
-
* without a default), distinguishing "declared but unset" from "declared and
|
|
503
|
-
* set" without a truthiness pitfall on falsy values such as `0` or `''`.
|
|
504
|
-
*
|
|
505
|
-
* @param path - The two-level dot-path to check.
|
|
506
|
-
* @returns True when the resolved value is not `undefined`.
|
|
507
|
-
* @example
|
|
508
|
-
* ```typescript
|
|
509
|
-
* if (config.has('redis.url')) connectRedis(config.get('redis.url'));
|
|
510
|
-
* ```
|
|
511
|
-
*/
|
|
512
418
|
has(path) {
|
|
513
419
|
return this.resolve(path) !== void 0;
|
|
514
420
|
}
|
|
515
|
-
/**
|
|
516
|
-
* Resolve a two-level dot-path to its raw leaf value.
|
|
517
|
-
*
|
|
518
|
-
* Looks the path up in the precomputed `namespace.leaf` map, so an unset leaf
|
|
519
|
-
* (or, defensively, an unexpected path) yields `undefined` instead of throwing.
|
|
520
|
-
*
|
|
521
|
-
* @param path - The declared two-level dot-path.
|
|
522
|
-
* @returns The leaf value as `unknown`, or `undefined` when the leaf is unset.
|
|
523
|
-
*/
|
|
524
421
|
resolve(path) {
|
|
525
422
|
return __privateGet(this, _leaves).get(String(path));
|
|
526
423
|
}
|
|
@@ -537,35 +434,12 @@ function appendTo(list, ...items) {
|
|
|
537
434
|
return list === void 0 ? [...items] : [...list, ...items];
|
|
538
435
|
}
|
|
539
436
|
var BymaxConfigModule = class extends ConfigurableModuleClass {
|
|
540
|
-
/**
|
|
541
|
-
* Register the module synchronously from a static schema.
|
|
542
|
-
*
|
|
543
|
-
* @param options - The module options plus the optional `isGlobal` extra.
|
|
544
|
-
* @returns The dynamic module augmented with the frozen config provider.
|
|
545
|
-
*/
|
|
546
437
|
static forRoot(options) {
|
|
547
438
|
return BymaxConfigModule.withConfigProvider(super.forRoot(options));
|
|
548
439
|
}
|
|
549
|
-
/**
|
|
550
|
-
* Register the module asynchronously, resolving options through a factory.
|
|
551
|
-
*
|
|
552
|
-
* @param options - The async options with `useFactory` and explicit `inject`.
|
|
553
|
-
* @returns The dynamic module augmented with the frozen config provider.
|
|
554
|
-
*/
|
|
555
440
|
static forRootAsync(options) {
|
|
556
441
|
return BymaxConfigModule.withConfigProvider(super.forRootAsync(options));
|
|
557
442
|
}
|
|
558
|
-
/**
|
|
559
|
-
* Append the config provider and typed accessor to a generated definition.
|
|
560
|
-
*
|
|
561
|
-
* Registers the frozen {@link BYMAX_CONFIG} provider and the {@link ConfigService}
|
|
562
|
-
* accessor (which injects that token), then exports both so consumers can
|
|
563
|
-
* inject either the raw frozen object or the typed service.
|
|
564
|
-
*
|
|
565
|
-
* @param definition - The dynamic module produced by the builder base class.
|
|
566
|
-
* @returns A definition that provides and exports {@link BYMAX_CONFIG} and
|
|
567
|
-
* {@link ConfigService}.
|
|
568
|
-
*/
|
|
569
443
|
static withConfigProvider(definition) {
|
|
570
444
|
return {
|
|
571
445
|
...definition,
|
package/dist/testing/index.cjs
CHANGED
|
@@ -167,14 +167,26 @@ function synthesizePlaceholderSource(schema) {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
// src/testing/create-test-config.ts
|
|
170
|
+
function isPlainObject(value) {
|
|
171
|
+
if (typeof value !== "object" || value === null) return false;
|
|
172
|
+
const prototype = Object.getPrototypeOf(value);
|
|
173
|
+
return prototype === Object.prototype || prototype === null;
|
|
174
|
+
}
|
|
170
175
|
function unplacedIssue(path, code, message) {
|
|
171
176
|
return { path, variable: "", code, message };
|
|
172
177
|
}
|
|
173
178
|
function flattenOverrides(overrides, declared) {
|
|
174
179
|
const flat = /* @__PURE__ */ new Map();
|
|
175
180
|
const unplaced = [];
|
|
181
|
+
if (overrides === void 0 || overrides === null) return { flat, unplaced };
|
|
182
|
+
if (!isPlainObject(overrides)) {
|
|
183
|
+
unplaced.push(
|
|
184
|
+
unplacedIssue("(overrides)", internal.ConfigErrorCode.INVALID, "the overrides must be an object")
|
|
185
|
+
);
|
|
186
|
+
return { flat, unplaced };
|
|
187
|
+
}
|
|
176
188
|
for (const [namespace, leaves] of Object.entries(overrides)) {
|
|
177
|
-
if (
|
|
189
|
+
if (!isPlainObject(leaves)) {
|
|
178
190
|
unplaced.push(
|
|
179
191
|
unplacedIssue(
|
|
180
192
|
namespace,
|
|
@@ -204,7 +216,7 @@ function flattenOverrides(overrides, declared) {
|
|
|
204
216
|
function applyOverrides(schema, base, overrides, overridden) {
|
|
205
217
|
const bindings = internal.resolveSourceNames(schema);
|
|
206
218
|
const { flat, unplaced } = flattenOverrides(
|
|
207
|
-
overrides
|
|
219
|
+
overrides,
|
|
208
220
|
new Set(bindings.map((binding) => binding.path))
|
|
209
221
|
);
|
|
210
222
|
if (unplaced.length > 0) throw new internal.BymaxConfigValidationError(unplaced);
|
package/dist/testing/index.mjs
CHANGED
|
@@ -165,14 +165,26 @@ function synthesizePlaceholderSource(schema) {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
// src/testing/create-test-config.ts
|
|
168
|
+
function isPlainObject(value) {
|
|
169
|
+
if (typeof value !== "object" || value === null) return false;
|
|
170
|
+
const prototype = Object.getPrototypeOf(value);
|
|
171
|
+
return prototype === Object.prototype || prototype === null;
|
|
172
|
+
}
|
|
168
173
|
function unplacedIssue(path, code, message) {
|
|
169
174
|
return { path, variable: "", code, message };
|
|
170
175
|
}
|
|
171
176
|
function flattenOverrides(overrides, declared) {
|
|
172
177
|
const flat = /* @__PURE__ */ new Map();
|
|
173
178
|
const unplaced = [];
|
|
179
|
+
if (overrides === void 0 || overrides === null) return { flat, unplaced };
|
|
180
|
+
if (!isPlainObject(overrides)) {
|
|
181
|
+
unplaced.push(
|
|
182
|
+
unplacedIssue("(overrides)", ConfigErrorCode.INVALID, "the overrides must be an object")
|
|
183
|
+
);
|
|
184
|
+
return { flat, unplaced };
|
|
185
|
+
}
|
|
174
186
|
for (const [namespace, leaves] of Object.entries(overrides)) {
|
|
175
|
-
if (
|
|
187
|
+
if (!isPlainObject(leaves)) {
|
|
176
188
|
unplaced.push(
|
|
177
189
|
unplacedIssue(
|
|
178
190
|
namespace,
|
|
@@ -202,7 +214,7 @@ function flattenOverrides(overrides, declared) {
|
|
|
202
214
|
function applyOverrides(schema, base, overrides, overridden) {
|
|
203
215
|
const bindings = resolveSourceNames(schema);
|
|
204
216
|
const { flat, unplaced } = flattenOverrides(
|
|
205
|
-
overrides
|
|
217
|
+
overrides,
|
|
206
218
|
new Set(bindings.map((binding) => binding.path))
|
|
207
219
|
);
|
|
208
220
|
if (unplaced.length > 0) throw new BymaxConfigValidationError(unplaced);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bymax-one/nest-config",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
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",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"./package.json": "./package.json"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
|
-
"build": "pnpm clean && tsup",
|
|
57
|
+
"build": "pnpm clean && tsup && node scripts/strip-bundle-comments.mjs",
|
|
58
58
|
"check:api": "node scripts/check-api-surface.mjs",
|
|
59
59
|
"check:exports": "attw --pack . --profile strict",
|
|
60
60
|
"check:lint-graph": "node scripts/check-lint-graph-rules.mjs",
|