@bymax-one/nest-core 1.5.0 → 1.5.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +47 -1
  2. package/README.md +78 -8
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -11,6 +11,51 @@ heading here.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [1.5.1] - 2026-08-15
15
+
16
+ Documentation only; no source change. The 1.5.0 warning's known-limit note told
17
+ readers that no tool could catch the one shape the warning cannot report, and
18
+ that rendering the document twice was therefore the only check. That is true
19
+ only of something reading the rendered document alone — a consumer's own suite
20
+ knows the intent and can assert it on every commit — so the note was arguing
21
+ against the better practice.
22
+
23
+ **Apply to a derived backend:** nothing to change in code. Read the revised
24
+ "Documenting authentication" section and write the assertion it now shows; it
25
+ costs one test and replaces a manual step nobody remembers to run.
26
+
27
+ ### Documentation
28
+
29
+ - **The credential-free warning's known limit no longer argues against the
30
+ practice that covers it.** The README said no tool could distinguish a
31
+ document that lost its requirements from one that never had any, and that
32
+ rendering the document twice was therefore the only check. The first half is
33
+ true only of something reading the rendered document alone; a consumer's own
34
+ suite knows which of the two it is and can assert it on every commit. Saying
35
+ otherwise did not merely overstate a limit — it told readers that the standing
36
+ check they should write does not exist. The section now attributes the limit
37
+ correctly, states why the warning cannot fire on that shape (it follows from
38
+ the trigger, in every version), gives the assertion as the practice, and
39
+ leaves render-and-diff the narrower job it is genuinely good at: seeing what
40
+ moved when you change something, so you can turn it into an assertion.
41
+
42
+ - **A contributed scheme's presence is documented as part of the contributor's
43
+ configuration.** Which security schemes a library contributes can depend on
44
+ how that library is configured — the names are stable, their presence is not.
45
+ A document-level default must therefore be derived from the same configuration
46
+ the contributor reads. A literal is correct only for the configuration it was
47
+ written against: elsewhere it either resolves while describing one of two
48
+ credentials a route accepts (quietly incomplete) or names a scheme nobody
49
+ declares (a failed document build). Guarding on whether the scheme exists
50
+ clears the loud case and ships the quiet one.
51
+
52
+ - **What a document-level default does not let you say** is now stated. Its
53
+ entries are alternatives applied to every operation that says nothing, so a
54
+ backend with two credential families _can_ list both and nothing rejects it —
55
+ the result asserts that either credential works for every inheriting route,
56
+ which is false in the permissive direction. The minority family belongs in
57
+ `openapi.operationSecurity`, which outranks the default.
58
+
14
59
  ## [1.5.0] - 2026-08-15
15
60
 
16
61
  An OpenAPI document could stop requiring credentials without anything saying
@@ -690,4 +735,5 @@ have regressed from. They are kept because the reasoning is worth having.
690
735
  [1.2.0]: https://github.com/bymaxone/nest-core/compare/v1.1.1...v1.2.0
691
736
  [1.4.0]: https://github.com/bymaxone/nest-core/compare/v1.3.2...v1.4.0
692
737
  [1.5.0]: https://github.com/bymaxone/nest-core/compare/v1.4.0...v1.5.0
693
- [Unreleased]: https://github.com/bymaxone/nest-core/compare/v1.5.0...HEAD
738
+ [1.5.1]: https://github.com/bymaxone/nest-core/compare/v1.5.0...v1.5.1
739
+ [Unreleased]: https://github.com/bymaxone/nest-core/compare/v1.5.1...HEAD
package/README.md CHANGED
@@ -420,14 +420,84 @@ rather than by silencing output: `operationSecurity: { 'GET /examples': [] }`
420
420
  marks the operation public, and it stops being reported. A library can do the
421
421
  same for its own routes by contributing `security: []` in its fragment.
422
422
 
423
- **And there is one shape nothing can warn you about, so the diff is the only
424
- check that covers it.** If you remove _every_ requirement at once — no library
425
- describing anything, no decorator, no override, no document default what
426
- remains is indistinguishable from the document of an API that is public on
427
- purpose. Both are a set of operations that ask for nothing. No tool can separate
428
- the two without also shouting at every genuinely public API, which is how a
429
- warning earns the right to be ignored. Render the document twice and compare; it
430
- is the one step that does not depend on somebody having anticipated your case.
423
+ **There is one shape this warning cannot report.** If you remove _every_
424
+ requirement at once no library describing anything, no decorator, no override,
425
+ no document default the second condition above is never met: nothing states a
426
+ requirement, so there are no bare operations sitting _beside_ described ones.
427
+ That follows from the trigger and therefore holds in every version; it is not a
428
+ gap a later release closes, and a reader who expects one is exactly the reader
429
+ who stops checking.
430
+
431
+ The limit belongs to **anything reading only the rendered document**. Such a
432
+ document is indistinguishable from that of an API which is public on purpose —
433
+ both are a set of operations asking for nothing — and this package cannot tell
434
+ them apart without also warning at every genuinely public API, which is how a
435
+ warning earns the right to be ignored.
436
+
437
+ **Your own suite has no such handicap, because you know which one you are.**
438
+ Assert it, and the check runs on every commit rather than when somebody
439
+ remembers to look:
440
+
441
+ ```ts
442
+ it('still requires a credential everywhere it should', () => {
443
+ const document = buildYourDocument()
444
+
445
+ // Assert the default you expect, not merely that one exists. `[]` is a
446
+ // defined value that requires nothing, so a "toBeDefined" check passes for
447
+ // a default that degraded to empty — which is the regression this test is
448
+ // here to catch, wearing the shape of a pass.
449
+ expect(document.security).toEqual([{ cookieAuth: [] }])
450
+
451
+ // An explicit `[]` is how an operation says "public". The set of operations
452
+ // saying it should be the set you meant — no more, no fewer.
453
+ expect(publicOperationsOf(document)).toEqual(['POST /auth/login'])
454
+ })
455
+ ```
456
+
457
+ Render-and-diff keeps a narrower job, and it is a good one: when you are
458
+ _changing_ something — adopting a library that describes its own routes, moving
459
+ a default — render with and without the change and compare the operations you
460
+ mount. It shows you what moved without your having to predict it. Then turn what
461
+ it showed you into an assertion, so the next change is caught rather than
462
+ inspected.
463
+
464
+ #### A contributed scheme's presence is part of the contributor's configuration
465
+
466
+ A library contributes security schemes, and **which** ones it contributes can
467
+ depend on how you configured it. Any of them, gated on any of its inputs, and
468
+ often on more than one — the scheme you have in mind may be the absent one, and
469
+ the setting you are thinking of may not be the only gate. The names are stable;
470
+ their presence is not.
471
+
472
+ That has one consequence worth stating as a rule, because getting it wrong
473
+ produces a failure at either end of the loudness scale:
474
+
475
+ > Derive a document-level default from **the same configuration the contributor
476
+ > reads**, never from the scheme names, and never from what the document
477
+ > happened to contain before you adopted the library.
478
+
479
+ Writing the name as a literal is correct only for the configuration you wrote it
480
+ against. Under a configuration that declares that scheme plus another, the
481
+ default still resolves but describes one of two credentials the route accepts —
482
+ **quietly incomplete**. Under one that declares it not at all, the name resolves
483
+ to nothing and the document build **fails** with the undeclared-scheme error
484
+ above. Guarding on whether the scheme exists is the tempting fix and it is the
485
+ wrong one: it clears the case that already announced itself and ships the one
486
+ that does not.
487
+
488
+ Note what a document-level default does not let you _say_. Its entries are
489
+ **alternatives** — any one of them satisfies an operation — and they apply to
490
+ every operation that states nothing. So a backend whose routes sit behind **two
491
+ different credential families** can certainly list both, and nothing rejects it:
492
+ the result is a document asserting that _either_ credential works for _every_
493
+ inheriting route. That is not an incomplete document, it is a false one, and it
494
+ is false in the permissive direction — it tells a client that a credential the
495
+ route will reject is one the route accepts.
496
+
497
+ Give the majority family the default and the minority explicit
498
+ `operationSecurity` entries. Those outrank the default, and an operation
499
+ carrying one is never named by the warning above, because it states a
500
+ requirement.
431
501
 
432
502
  ## 🔑 DI Tokens
433
503
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-core",
3
- "version": "1.5.0",
3
+ "version": "1.5.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",