@dudousxd/nestjs-diagnostics 0.7.1 → 0.8.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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # @dudousxd/nestjs-diagnostics
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#71](https://github.com/DavideCarvalho/nestjs-diagnostics/pull/71) [`f4c910b`](https://github.com/DavideCarvalho/nestjs-diagnostics/commit/f4c910b0651ee9419aa452268f23646533d10306) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Add `subscribeOfficial(lib, types | 'all', fn)`, which subscribes to the first-party `nestjs:<lib>:<type>` channels (`@nestjs/resilience`, `workflows`, `authentication`, `authorization`, `mail`) and wraps each raw payload in the Aviary envelope, with `traceId` from the context accessor and `source: 'nestjs'`. The channel lists are exported per lib (`NESTJS_*_CHANNELS`, `OFFICIAL_CHANNELS`), pinned to `OFFICIAL_PACKAGE_VERSIONS`, and guarded by a drift test. Aviary never publishes on `nestjs:*`.
8
+
9
+ ## 0.7.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [`db48c6e`](https://github.com/DavideCarvalho/nestjs-diagnostics/commit/db48c6e5484bbccbb8ed34a633816ad1ed252c47) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Document the capability token trio in English, and correct two claims
14
+
15
+ Comment-only change to `capability.ts`, `inject-capability.ts` and
16
+ `conformance.ts`, the only three source files whose doc comments were written in
17
+ Portuguese. Two statements were also wrong and are fixed: `capability()` is not
18
+ the single source of the `@dudousxd/nestjs-<lib>:<name>` naming (`CONTEXT_ACCESSOR`
19
+ spells the same token by hand, as `capability.spec.ts` pins), and
20
+ `assertCapabilityNaming` checks the token's name, not that `capability()` minted
21
+ it. `InjectCapability`'s dangling pointer to an out-of-repo plan is replaced with
22
+ the in-repo `CapabilityOf` type and the reason it is exported from the `/nestjs`
23
+ subpath only. No runtime behavior changes.
24
+
3
25
  ## 0.7.1
4
26
 
5
27
  ### Patch Changes
package/README.md CHANGED
@@ -94,6 +94,45 @@ const off = onChannelRegistered(subscribe);
94
94
  This is exactly how `@dudousxd/nestjs-diagnostics-telescope`'s single generic
95
95
  watcher records every diagnostic event in the Telescope dashboard.
96
96
 
97
+ ## First-party `nestjs:*` channels
98
+
99
+ The official NestJS packages publish their own events on
100
+ `diagnostics_channel` with the convention `nestjs:<lib>:<type>`: a raw
101
+ payload, with no envelope and no traceId (see
102
+ [docs.nestjs.com](https://docs.nestjs.com)). **`nestjs:*` is the first-party
103
+ convention, and Aviary never publishes on it.** `aviary:*` is only for what the
104
+ official packages don't emit.
105
+
106
+ `subscribeOfficial` lets one consumer record both. It wraps each official
107
+ payload in the Aviary envelope, with `traceId` taken from the context accessor
108
+ and `source: 'nestjs'`:
109
+
110
+ ```ts
111
+ import { subscribeOfficial } from '@dudousxd/nestjs-diagnostics';
112
+
113
+ const off = subscribeOfficial('resilience', ['retry', 'circuit-open'], (event, channel) => {
114
+ // event: { v, ts, lib: 'resilience', event: 'retry', traceId, payload, source: 'nestjs' }
115
+ });
116
+ subscribeOfficial('authentication', 'all', record);
117
+ off();
118
+ ```
119
+
120
+ The channel lists are exported per lib in one file, pinned to the official
121
+ versions they were verified against (`OFFICIAL_PACKAGE_VERSIONS`). A test
122
+ re-reads the installed packages and fails if a channel is added or renamed.
123
+
124
+ | Lib | Constant | Channels |
125
+ | --- | --- | --- |
126
+ | `@nestjs/resilience` 0.0.3 | `NESTJS_RESILIENCE_CHANNELS` | 9 |
127
+ | `@nestjs/workflows` 0.0.5 | `NESTJS_WORKFLOWS_CHANNELS` | 19 |
128
+ | `@nestjs/authentication` 0.1.5 | `NESTJS_AUTHENTICATION_CHANNELS` | 13 |
129
+ | `@nestjs/authorization` 0.1.3 | `NESTJS_AUTHORIZATION_CHANNELS` | 1 (`denied`) |
130
+ | `@nestjs/mail` 0.0.2 | `NESTJS_MAIL_CHANNELS` | 2 (`sent`, `failed`) |
131
+
132
+ These channels are not added to the `aviary:*` registry
133
+ (`registeredChannels`/`onChannelRegistered`). Their lists are fixed, so subscribe
134
+ to them explicitly.
135
+
97
136
  ## API
98
137
 
99
138
  | Export | Description |
@@ -106,7 +145,9 @@ watcher records every diagnostic event in the Telescope dashboard.
106
145
  | `onChannelRegistered(cb)` | Notified once per future channel registration; returns an unsubscribe. |
107
146
  | `setContextAccessor(accessor \| null)` | Register the accessor `emit` reads `traceId` from. |
108
147
  | `CONTEXT_ACCESSOR` | Shared DI token for the optional context accessor. |
109
- | `DiagnosticEvent`, `EmitOptions`, `ContextAccessor` | Types. |
148
+ | `subscribeOfficial(lib, types \| 'all', fn)` | Subscribe to first-party `nestjs:<lib>:<type>` channels, each payload wrapped in the envelope (+ `source: 'nestjs'`). Returns an unsubscribe. |
149
+ | `OFFICIAL_CHANNELS`, `NESTJS_*_CHANNELS`, `OFFICIAL_PACKAGE_VERSIONS`, `officialChannelNames()` | The pinned first-party channel lists. |
150
+ | `DiagnosticEvent`, `EmitOptions`, `ContextAccessor`, `OfficialDiagnosticEvent` | Types. |
110
151
 
111
152
  ## Reacting to events in NestJS — `@OnDiagnostic`
112
153
 
@@ -1,15 +1,20 @@
1
1
  /**
2
- * O token de DI estável para a capability `<lib>:<name>`. Fonte única do naming
3
- * `@dudousxd/nestjs-<lib>:<name>`. Como usa o registry global de símbolos
4
- * (`Symbol.for`), produtor e consumidor em libs diferentes — sem se importarem —
5
- * resolvem o MESMO símbolo. Espelha o `channelName(lib, event)` do transporte de
6
- * eventos, do outro lado do mesmo protocolo.
2
+ * The stable DI token for the capability `<lib>:<name>`, built from the canonical
3
+ * `@dudousxd/nestjs-<lib>:<name>` name. Because it goes through the global symbol
4
+ * registry (`Symbol.for`), a producer and a consumer living in different libs —
5
+ * neither importing the other — resolve the SAME symbol. Mirrors the event
6
+ * transport's `channelName(lib, event)`, on the other side of the same protocol.
7
+ *
8
+ * The naming is a convention, not an exclusive factory: a token spelled by hand
9
+ * with the same string IS the same symbol, which is what lets a lib adopt this
10
+ * without a breaking change. `CONTEXT_ACCESSOR` in `context-accessor.ts` is
11
+ * exactly that case — `capability('context', 'accessor')` resolves to it.
7
12
  */
8
13
  export declare function capability(lib: string, name: string): symbol;
9
14
  /**
10
- * Registry tipado de capabilities, augmentado pelas libs via declaration merging
11
- * — espelho exato do `ChannelRegistry` do transporte de eventos. Vazio por
12
- * padrão; o caminho não-tipado (`unknown`) está sempre disponível.
15
+ * Typed capability registry, augmented by libs through declaration merging — the
16
+ * exact mirror of the event transport's `ChannelRegistry`. Empty by default; the
17
+ * untyped (`unknown`) path is always available.
13
18
  *
14
19
  * ```ts
15
20
  * declare module '@dudousxd/nestjs-diagnostics' {
@@ -22,9 +27,9 @@ export declare function capability(lib: string, name: string): symbol;
22
27
  export interface CapabilityRegistry {
23
28
  }
24
29
  /**
25
- * O tipo declarado para `(TLib, TName)` no {@link CapabilityRegistry}, ou
26
- * `unknown` quando o par não está registrado. Espelha `PayloadOf` do
27
- * transporte de eventos.
30
+ * The type declared for `(TLib, TName)` in the {@link CapabilityRegistry}, or
31
+ * `unknown` when the pair is not registered. Mirrors `PayloadOf` from the event
32
+ * transport.
28
33
  */
29
34
  export type CapabilityOf<TLib extends string, TName extends string> = TLib extends keyof CapabilityRegistry ? TName extends keyof CapabilityRegistry[TLib] ? CapabilityRegistry[TLib][TName] : unknown : unknown;
30
35
  //# sourceMappingURL=capability.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,kBAAkB;CAAG;AAEtC;;;;GAIG;AACH,MAAM,MAAM,YAAY,CACtB,IAAI,SAAS,MAAM,EACnB,KAAK,SAAS,MAAM,IAClB,IAAI,SAAS,MAAM,kBAAkB,GACrC,KAAK,SAAS,MAAM,kBAAkB,CAAC,IAAI,CAAC,GAC1C,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAC/B,OAAO,GACT,OAAO,CAAC"}
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,kBAAkB;CAAG;AAEtC;;;;GAIG;AACH,MAAM,MAAM,YAAY,CACtB,IAAI,SAAS,MAAM,EACnB,KAAK,SAAS,MAAM,IAClB,IAAI,SAAS,MAAM,kBAAkB,GACrC,KAAK,SAAS,MAAM,kBAAkB,CAAC,IAAI,CAAC,GAC1C,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAC/B,OAAO,GACT,OAAO,CAAC"}
@@ -1,9 +1,14 @@
1
1
  /**
2
- * O token de DI estável para a capability `<lib>:<name>`. Fonte única do naming
3
- * `@dudousxd/nestjs-<lib>:<name>`. Como usa o registry global de símbolos
4
- * (`Symbol.for`), produtor e consumidor em libs diferentes — sem se importarem —
5
- * resolvem o MESMO símbolo. Espelha o `channelName(lib, event)` do transporte de
6
- * eventos, do outro lado do mesmo protocolo.
2
+ * The stable DI token for the capability `<lib>:<name>`, built from the canonical
3
+ * `@dudousxd/nestjs-<lib>:<name>` name. Because it goes through the global symbol
4
+ * registry (`Symbol.for`), a producer and a consumer living in different libs —
5
+ * neither importing the other — resolve the SAME symbol. Mirrors the event
6
+ * transport's `channelName(lib, event)`, on the other side of the same protocol.
7
+ *
8
+ * The naming is a convention, not an exclusive factory: a token spelled by hand
9
+ * with the same string IS the same symbol, which is what lets a lib adopt this
10
+ * without a breaking change. `CONTEXT_ACCESSOR` in `context-accessor.ts` is
11
+ * exactly that case — `capability('context', 'accessor')` resolves to it.
7
12
  */
8
13
  export function capability(lib, name) {
9
14
  return Symbol.for(`@dudousxd/nestjs-${lib}:${name}`);
@@ -1 +1 @@
1
- {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY;IAClD,OAAO,MAAM,CAAC,GAAG,CAAC,oBAAoB,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY;IAClD,OAAO,MAAM,CAAC,GAAG,CAAC,oBAAoB,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC"}
@@ -1,9 +1,13 @@
1
1
  /**
2
- * Trava anti-drift para contract tests: assere que TODO token exportado por uma
3
- * lib segue o naming canônico `@dudousxd/nestjs-<lib>:<name>` (i.e. foi criado
4
- * por `capability(lib, ...)`). `Symbol.for(k).description === k`, então basta
5
- * checar o prefixo da `description` — não é preciso comparar identidade.
6
- * Lança um erro que NOMEIA o export ofensor, virando o drift em teste vermelho.
2
+ * Anti-drift latch for contract tests: asserts that EVERY token a lib exports
3
+ * follows the canonical `@dudousxd/nestjs-<lib>:<name>` naming. Because
4
+ * `Symbol.for(k).description === k`, checking the `description` prefix is enough —
5
+ * no identity comparison needed. Throws an error that NAMES the offending export,
6
+ * turning drift into a red test.
7
+ *
8
+ * It checks the NAME, not the provenance: a symbol spelled by hand with the right
9
+ * prefix passes exactly like one built by `capability(lib, ...)`. That is the
10
+ * point — the canonical name is the contract, not the factory call.
7
11
  */
8
12
  export declare function assertCapabilityNaming(lib: string, tokens: Record<string, symbol>): void;
9
13
  //# sourceMappingURL=conformance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAWxF"}
1
+ {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAWxF"}
@@ -1,9 +1,13 @@
1
1
  /**
2
- * Trava anti-drift para contract tests: assere que TODO token exportado por uma
3
- * lib segue o naming canônico `@dudousxd/nestjs-<lib>:<name>` (i.e. foi criado
4
- * por `capability(lib, ...)`). `Symbol.for(k).description === k`, então basta
5
- * checar o prefixo da `description` — não é preciso comparar identidade.
6
- * Lança um erro que NOMEIA o export ofensor, virando o drift em teste vermelho.
2
+ * Anti-drift latch for contract tests: asserts that EVERY token a lib exports
3
+ * follows the canonical `@dudousxd/nestjs-<lib>:<name>` naming. Because
4
+ * `Symbol.for(k).description === k`, checking the `description` prefix is enough —
5
+ * no identity comparison needed. Throws an error that NAMES the offending export,
6
+ * turning drift into a red test.
7
+ *
8
+ * It checks the NAME, not the provenance: a symbol spelled by hand with the right
9
+ * prefix passes exactly like one built by `capability(lib, ...)`. That is the
10
+ * point — the canonical name is the contract, not the factory call.
7
11
  */
8
12
  export function assertCapabilityNaming(lib, tokens) {
9
13
  const prefix = `@dudousxd/nestjs-${lib}:`;
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAW,EAAE,MAA8B;IAChF,MAAM,MAAM,GAAG,oBAAoB,GAAG,GAAG,CAAC;IAC1C,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC;QAC/B,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CACb,qBAAqB,UAAU,qBAAqB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI;gBAC1E,2BAA2B,MAAM,sBAAsB,GAAG,aAAa,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAW,EAAE,MAA8B;IAChF,MAAM,MAAM,GAAG,oBAAoB,GAAG,GAAG,CAAC;IAC1C,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC;QAC/B,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CACb,qBAAqB,UAAU,qBAAqB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI;gBAC1E,2BAA2B,MAAM,sBAAsB,GAAG,aAAa,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { CHANNEL_PREFIX, channelName, emit, getChannel, SCHEMA_VERSION } from '.
4
4
  export { claimDiagnostics, isDiagnosticClaimed } from './claims.js';
5
5
  export { assertCapabilityNaming } from './conformance.js';
6
6
  export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, getContextAccessor, resolveTraceId, setContextAccessor, type UserRef, } from './context-accessor.js';
7
+ export { NESTJS_AUTHENTICATION_CHANNELS, NESTJS_AUTHORIZATION_CHANNELS, NESTJS_MAIL_CHANNELS, NESTJS_RESILIENCE_CHANNELS, NESTJS_WORKFLOWS_CHANNELS, OFFICIAL_CHANNEL_PREFIX, OFFICIAL_CHANNELS, OFFICIAL_PACKAGE_VERSIONS, type OfficialChannelName, type OfficialDiagnosticEvent, type OfficialLib, type OfficialListener, type OfficialType, officialChannelNames, subscribeOfficial, } from './official.js';
7
8
  export { onChannelRegistered, registerChannel, registeredChannels, resetRegistry, } from './registry.js';
8
9
  export { SPAN_SCHEMA_VERSION, trace, type TraceChannelNames, traceChannelNames, type TracingChannel, tracingChannel, } from './trace.js';
9
10
  export type { ChannelRegistry, DiagnosticEvent, EmitOptions, EventOf, LibOf, PayloadOf, SpanEvent, SpanPhase, TraceOptions, } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EACL,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,KAAK,OAAO,GACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,KAAK,EACL,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,KAAK,cAAc,EACnB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,eAAe,EACf,eAAe,EACf,WAAW,EACX,OAAO,EACP,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,GACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EACL,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,KAAK,OAAO,GACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,EAC7B,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,KAAK,EACL,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,KAAK,cAAc,EACnB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,eAAe,EACf,eAAe,EACf,WAAW,EACX,OAAO,EACP,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,GACb,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export { CHANNEL_PREFIX, channelName, emit, getChannel, SCHEMA_VERSION } from '.
3
3
  export { claimDiagnostics, isDiagnosticClaimed } from './claims.js';
4
4
  export { assertCapabilityNaming } from './conformance.js';
5
5
  export { CONTEXT_ACCESSOR, getContextAccessor, resolveTraceId, setContextAccessor, } from './context-accessor.js';
6
+ export { NESTJS_AUTHENTICATION_CHANNELS, NESTJS_AUTHORIZATION_CHANNELS, NESTJS_MAIL_CHANNELS, NESTJS_RESILIENCE_CHANNELS, NESTJS_WORKFLOWS_CHANNELS, OFFICIAL_CHANNEL_PREFIX, OFFICIAL_CHANNELS, OFFICIAL_PACKAGE_VERSIONS, officialChannelNames, subscribeOfficial, } from './official.js';
6
7
  export { onChannelRegistered, registerChannel, registeredChannels, resetRegistry, } from './registry.js';
7
8
  export { SPAN_SCHEMA_VERSION, trace, traceChannelNames, tracingChannel, } from './trace.js';
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EACL,gBAAgB,EAGhB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,GAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,KAAK,EAEL,iBAAiB,EAEjB,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EACL,gBAAgB,EAGhB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,GAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,EAC7B,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,yBAAyB,EAMzB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,KAAK,EAEL,iBAAiB,EAEjB,cAAc,GACf,MAAM,YAAY,CAAC"}
@@ -1,9 +1,14 @@
1
1
  /**
2
- * Injeta a capability de um peer `<lib>:<name>` OPCIONALMENTE — equivale a
3
- * `@Optional() @Inject(capability(lib, name))`, sem a string mágica copiada à
4
- * mão. Quando o produtor (a outra lib) está ausente, o parâmetro recebe
5
- * `undefined` em vez de quebrar a injeção. O tipo do parâmetro é anotado pelo
6
- * consumidor (ver nota no plano sobre declaration merging cross-repo).
2
+ * Injects a peer lib's `<lib>:<name>` capability OPTIONALLY — equivalent to
3
+ * `@Optional() @Inject(capability(lib, name))`, without the magic string copied by
4
+ * hand. When the producer lib is absent, the parameter receives `undefined`
5
+ * instead of breaking injection.
6
+ *
7
+ * The decorator carries no type of its own: annotate the parameter on the consumer
8
+ * side, e.g. with {@link import('./capability.js').CapabilityOf CapabilityOf}.
9
+ *
10
+ * Exported from the `/nestjs` subpath only, never from the main barrel: this file
11
+ * imports `@nestjs/common`, and the root entry point stays Nest-free.
7
12
  */
8
13
  export declare function InjectCapability(lib: string, name: string): ParameterDecorator;
9
14
  //# sourceMappingURL=inject-capability.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inject-capability.d.ts","sourceRoot":"","sources":["../src/inject-capability.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAM9E"}
1
+ {"version":3,"file":"inject-capability.d.ts","sourceRoot":"","sources":["../src/inject-capability.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAM9E"}
@@ -1,11 +1,16 @@
1
1
  import { Inject, Optional } from '@nestjs/common';
2
2
  import { capability } from './capability.js';
3
3
  /**
4
- * Injeta a capability de um peer `<lib>:<name>` OPCIONALMENTE — equivale a
5
- * `@Optional() @Inject(capability(lib, name))`, sem a string mágica copiada à
6
- * mão. Quando o produtor (a outra lib) está ausente, o parâmetro recebe
7
- * `undefined` em vez de quebrar a injeção. O tipo do parâmetro é anotado pelo
8
- * consumidor (ver nota no plano sobre declaration merging cross-repo).
4
+ * Injects a peer lib's `<lib>:<name>` capability OPTIONALLY — equivalent to
5
+ * `@Optional() @Inject(capability(lib, name))`, without the magic string copied by
6
+ * hand. When the producer lib is absent, the parameter receives `undefined`
7
+ * instead of breaking injection.
8
+ *
9
+ * The decorator carries no type of its own: annotate the parameter on the consumer
10
+ * side, e.g. with {@link import('./capability.js').CapabilityOf CapabilityOf}.
11
+ *
12
+ * Exported from the `/nestjs` subpath only, never from the main barrel: this file
13
+ * imports `@nestjs/common`, and the root entry point stays Nest-free.
9
14
  */
10
15
  export function InjectCapability(lib, name) {
11
16
  const token = capability(lib, name);
@@ -1 +1 @@
1
- {"version":3,"file":"inject-capability.js","sourceRoot":"","sources":["../src/inject-capability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,IAAY;IACxD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE;QAC7C,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IACrD,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"inject-capability.js","sourceRoot":"","sources":["../src/inject-capability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,IAAY;IACxD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE;QAC7C,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IACrD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,83 @@
1
+ import type { DiagnosticEvent } from './types.js';
2
+ /**
3
+ * The first-party NestJS packages publish raw events on `node:diagnostics_channel`
4
+ * under the fixed convention `nestjs:<lib>:<type>`: no envelope, no traceId. This
5
+ * file is the ONE place their channel lists live. Each list was read from the
6
+ * published tarball of the version in {@link OFFICIAL_PACKAGE_VERSIONS}, and
7
+ * `test/official.spec.ts` re-reads the installed (pinned) packages and fails when
8
+ * a channel is added, renamed or removed.
9
+ *
10
+ * Aviary never publishes on `nestjs:*`. It only subscribes, through
11
+ * {@link subscribeOfficial}. `aviary:*` is for what the official packages don't emit.
12
+ */
13
+ export declare const OFFICIAL_CHANNEL_PREFIX = "nestjs";
14
+ /** `nestjs:<lib>:<type>`, the first-party channel name. */
15
+ export type OfficialChannelName<L extends string, T extends string> = `nestjs:${L}:${T}`;
16
+ type ChannelMap<L extends string, T extends readonly string[]> = {
17
+ readonly [K in T[number]]: OfficialChannelName<L, K>;
18
+ };
19
+ /** `@nestjs/resilience`: the 9 fixed channels of `events/resilience.channels.js`. */
20
+ export declare const NESTJS_RESILIENCE_CHANNELS: ChannelMap<"resilience", readonly ["retry", "timeout", "circuit-open", "circuit-half-open", "circuit-closed", "circuit-rejected", "bulkhead-rejected", "rate-limited", "fallback"]>;
21
+ /** `@nestjs/workflows`: `channelFor(event.type)` over the 19 `WorkflowEvent` types. */
22
+ export declare const NESTJS_WORKFLOWS_CHANNELS: ChannelMap<"workflows", readonly ["workflow-started", "workflow-resumed", "workflow-suspended", "workflow-compensating", "workflow-completed", "workflow-failed", "workflow-cancelled", "workflow-compensation-failed", "step-completed", "step-failed", "step-compensated", "child-started", "signal-received", "signal-timed-out", "journal-large", "custom-status", "workflow-retried", "workflow-deleted", "schedule-skipped"]>;
23
+ /** `@nestjs/authentication`: `channelFor(event.type)` over the 13 `AuthenticationEvent` types. */
24
+ export declare const NESTJS_AUTHENTICATION_CHANNELS: ChannelMap<"authentication", readonly ["sign-in", "sign-out", "mfa-verified", "mfa-failed", "mfa-enabled", "mfa-disabled", "recovery-codes-generated", "refresh-token-reused", "password-reset-requested", "password-reset", "email-verified", "magic-link-refused", "session-touch-failed"]>;
25
+ /** `@nestjs/authorization`: the single `deniedChannel`. */
26
+ export declare const NESTJS_AUTHORIZATION_CHANNELS: ChannelMap<"authorization", readonly ["denied"]>;
27
+ /** `@nestjs/mail`: `channels.sent` and `channels.failed`. */
28
+ export declare const NESTJS_MAIL_CHANNELS: ChannelMap<"mail", readonly ["sent", "failed"]>;
29
+ /** Every known first-party lib → its `type → channel name` map. */
30
+ export declare const OFFICIAL_CHANNELS: Readonly<{
31
+ resilience: ChannelMap<"resilience", readonly ["retry", "timeout", "circuit-open", "circuit-half-open", "circuit-closed", "circuit-rejected", "bulkhead-rejected", "rate-limited", "fallback"]>;
32
+ workflows: ChannelMap<"workflows", readonly ["workflow-started", "workflow-resumed", "workflow-suspended", "workflow-compensating", "workflow-completed", "workflow-failed", "workflow-cancelled", "workflow-compensation-failed", "step-completed", "step-failed", "step-compensated", "child-started", "signal-received", "signal-timed-out", "journal-large", "custom-status", "workflow-retried", "workflow-deleted", "schedule-skipped"]>;
33
+ authentication: ChannelMap<"authentication", readonly ["sign-in", "sign-out", "mfa-verified", "mfa-failed", "mfa-enabled", "mfa-disabled", "recovery-codes-generated", "refresh-token-reused", "password-reset-requested", "password-reset", "email-verified", "magic-link-refused", "session-touch-failed"]>;
34
+ authorization: ChannelMap<"authorization", readonly ["denied"]>;
35
+ mail: ChannelMap<"mail", readonly ["sent", "failed"]>;
36
+ }>;
37
+ /** The official package version each list above was verified against. */
38
+ export declare const OFFICIAL_PACKAGE_VERSIONS: Readonly<{
39
+ resilience: string;
40
+ workflows: string;
41
+ authentication: string;
42
+ authorization: string;
43
+ mail: string;
44
+ }>;
45
+ /** A first-party lib whose channels are listed here. */
46
+ export type OfficialLib = keyof typeof OFFICIAL_CHANNELS;
47
+ /** The event types `L` publishes, e.g. `'retry' | 'timeout' | …` for `'resilience'`. */
48
+ export type OfficialType<L extends OfficialLib> = keyof (typeof OFFICIAL_CHANNELS)[L] & string;
49
+ /** Every first-party channel name, flattened. */
50
+ export declare function officialChannelNames(): string[];
51
+ /**
52
+ * The Aviary envelope wrapped around an official payload: the usual
53
+ * {@link DiagnosticEvent} plus `source: 'nestjs'`, so an observer that records
54
+ * both kinds (Telescope's `DiagnosticWatcher`) can tell them apart. Aviary's own
55
+ * `emit()` envelopes carry no `source`.
56
+ */
57
+ export interface OfficialDiagnosticEvent<TPayload = unknown> extends DiagnosticEvent<TPayload> {
58
+ source: 'nestjs';
59
+ }
60
+ /** Receives each wrapped official event and the `nestjs:*` channel it came from. */
61
+ export type OfficialListener = (event: OfficialDiagnosticEvent, channel: string) => void;
62
+ /**
63
+ * Subscribe to first-party `nestjs:<lib>:<type>` channels and receive each raw
64
+ * payload wrapped in the Aviary envelope `{ v, ts, lib, event, traceId, payload,
65
+ * source: 'nestjs' }`:
66
+ *
67
+ * - `traceId` comes from the registered context accessor. Official publishers run
68
+ * subscribers synchronously in the caller's async context, so it is the
69
+ * request's traceId;
70
+ * - `durationMs` is copied from the payload when it carries a numeric one
71
+ * (e.g. workflows' `step-completed`).
72
+ *
73
+ * Returns an unsubscribe function. A throwing `fn` never reaches the official
74
+ * publisher. Subscribing only reads `nestjs:*`; Aviary never publishes there.
75
+ *
76
+ * ```ts
77
+ * const off = subscribeOfficial('resilience', ['retry', 'circuit-open'], (e) => log(e));
78
+ * subscribeOfficial('authentication', 'all', record);
79
+ * ```
80
+ */
81
+ export declare function subscribeOfficial<L extends OfficialLib>(lib: L, types: readonly OfficialType<L>[] | 'all', fn: OfficialListener): () => void;
82
+ export {};
83
+ //# sourceMappingURL=official.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"official.d.ts","sourceRoot":"","sources":["../src/official.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAEhD,2DAA2D;AAC3D,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;AAEzF,KAAK,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,SAAS,MAAM,EAAE,IAAI;IAC/D,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC;CACrD,CAAC;AAWF,qFAAqF;AACrF,eAAO,MAAM,0BAA0B,qLAUrC,CAAC;AAEH,uFAAuF;AACvF,eAAO,MAAM,yBAAyB,qaAoBpC,CAAC;AAEH,kGAAkG;AAClG,eAAO,MAAM,8BAA8B,+RAczC,CAAC;AAEH,2DAA2D;AAC3D,eAAO,MAAM,6BAA6B,kDAA0C,CAAC;AAErF,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB,iDAAyC,CAAC;AAE3E,mEAAmE;AACnE,eAAO,MAAM,iBAAiB;;;;;;EAM5B,CAAC;AAEH,yEAAyE;AACzE,eAAO,MAAM,yBAAyB;;;;;;EAME,CAAC;AAEzC,wDAAwD;AACxD,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAEzD,wFAAwF;AACxF,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,WAAW,IAAI,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AAE/F,iDAAiD;AACjD,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB,CAAC,QAAQ,GAAG,OAAO,CAAE,SAAQ,eAAe,CAAC,QAAQ,CAAC;IAC5F,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,oFAAoF;AACpF,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,EACrD,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EACzC,EAAE,EAAE,gBAAgB,GACnB,MAAM,IAAI,CA8CZ"}
@@ -0,0 +1,159 @@
1
+ import diagnostics_channel from 'node:diagnostics_channel';
2
+ import { SCHEMA_VERSION } from './channel.js';
3
+ import { resolveTraceId } from './context-accessor.js';
4
+ /**
5
+ * The first-party NestJS packages publish raw events on `node:diagnostics_channel`
6
+ * under the fixed convention `nestjs:<lib>:<type>`: no envelope, no traceId. This
7
+ * file is the ONE place their channel lists live. Each list was read from the
8
+ * published tarball of the version in {@link OFFICIAL_PACKAGE_VERSIONS}, and
9
+ * `test/official.spec.ts` re-reads the installed (pinned) packages and fails when
10
+ * a channel is added, renamed or removed.
11
+ *
12
+ * Aviary never publishes on `nestjs:*`. It only subscribes, through
13
+ * {@link subscribeOfficial}. `aviary:*` is for what the official packages don't emit.
14
+ */
15
+ export const OFFICIAL_CHANNEL_PREFIX = 'nestjs';
16
+ function channelsOf(lib, types) {
17
+ return Object.freeze(Object.fromEntries(types.map((type) => [type, `${OFFICIAL_CHANNEL_PREFIX}:${lib}:${type}`])));
18
+ }
19
+ /** `@nestjs/resilience`: the 9 fixed channels of `events/resilience.channels.js`. */
20
+ export const NESTJS_RESILIENCE_CHANNELS = channelsOf('resilience', [
21
+ 'retry',
22
+ 'timeout',
23
+ 'circuit-open',
24
+ 'circuit-half-open',
25
+ 'circuit-closed',
26
+ 'circuit-rejected',
27
+ 'bulkhead-rejected',
28
+ 'rate-limited',
29
+ 'fallback',
30
+ ]);
31
+ /** `@nestjs/workflows`: `channelFor(event.type)` over the 19 `WorkflowEvent` types. */
32
+ export const NESTJS_WORKFLOWS_CHANNELS = channelsOf('workflows', [
33
+ 'workflow-started',
34
+ 'workflow-resumed',
35
+ 'workflow-suspended',
36
+ 'workflow-compensating',
37
+ 'workflow-completed',
38
+ 'workflow-failed',
39
+ 'workflow-cancelled',
40
+ 'workflow-compensation-failed',
41
+ 'step-completed',
42
+ 'step-failed',
43
+ 'step-compensated',
44
+ 'child-started',
45
+ 'signal-received',
46
+ 'signal-timed-out',
47
+ 'journal-large',
48
+ 'custom-status',
49
+ 'workflow-retried',
50
+ 'workflow-deleted',
51
+ 'schedule-skipped',
52
+ ]);
53
+ /** `@nestjs/authentication`: `channelFor(event.type)` over the 13 `AuthenticationEvent` types. */
54
+ export const NESTJS_AUTHENTICATION_CHANNELS = channelsOf('authentication', [
55
+ 'sign-in',
56
+ 'sign-out',
57
+ 'mfa-verified',
58
+ 'mfa-failed',
59
+ 'mfa-enabled',
60
+ 'mfa-disabled',
61
+ 'recovery-codes-generated',
62
+ 'refresh-token-reused',
63
+ 'password-reset-requested',
64
+ 'password-reset',
65
+ 'email-verified',
66
+ 'magic-link-refused',
67
+ 'session-touch-failed',
68
+ ]);
69
+ /** `@nestjs/authorization`: the single `deniedChannel`. */
70
+ export const NESTJS_AUTHORIZATION_CHANNELS = channelsOf('authorization', ['denied']);
71
+ /** `@nestjs/mail`: `channels.sent` and `channels.failed`. */
72
+ export const NESTJS_MAIL_CHANNELS = channelsOf('mail', ['sent', 'failed']);
73
+ /** Every known first-party lib → its `type → channel name` map. */
74
+ export const OFFICIAL_CHANNELS = Object.freeze({
75
+ resilience: NESTJS_RESILIENCE_CHANNELS,
76
+ workflows: NESTJS_WORKFLOWS_CHANNELS,
77
+ authentication: NESTJS_AUTHENTICATION_CHANNELS,
78
+ authorization: NESTJS_AUTHORIZATION_CHANNELS,
79
+ mail: NESTJS_MAIL_CHANNELS,
80
+ });
81
+ /** The official package version each list above was verified against. */
82
+ export const OFFICIAL_PACKAGE_VERSIONS = Object.freeze({
83
+ resilience: '0.0.3',
84
+ workflows: '0.0.5',
85
+ authentication: '0.1.5',
86
+ authorization: '0.1.3',
87
+ mail: '0.0.2',
88
+ });
89
+ /** Every first-party channel name, flattened. */
90
+ export function officialChannelNames() {
91
+ return Object.values(OFFICIAL_CHANNELS).flatMap((map) => Object.values(map));
92
+ }
93
+ /**
94
+ * Subscribe to first-party `nestjs:<lib>:<type>` channels and receive each raw
95
+ * payload wrapped in the Aviary envelope `{ v, ts, lib, event, traceId, payload,
96
+ * source: 'nestjs' }`:
97
+ *
98
+ * - `traceId` comes from the registered context accessor. Official publishers run
99
+ * subscribers synchronously in the caller's async context, so it is the
100
+ * request's traceId;
101
+ * - `durationMs` is copied from the payload when it carries a numeric one
102
+ * (e.g. workflows' `step-completed`).
103
+ *
104
+ * Returns an unsubscribe function. A throwing `fn` never reaches the official
105
+ * publisher. Subscribing only reads `nestjs:*`; Aviary never publishes there.
106
+ *
107
+ * ```ts
108
+ * const off = subscribeOfficial('resilience', ['retry', 'circuit-open'], (e) => log(e));
109
+ * subscribeOfficial('authentication', 'all', record);
110
+ * ```
111
+ */
112
+ export function subscribeOfficial(lib, types, fn) {
113
+ const map = OFFICIAL_CHANNELS[lib];
114
+ if (!map) {
115
+ throw new TypeError(`subscribeOfficial: unknown first-party lib '${String(lib)}'`);
116
+ }
117
+ const selected = types === 'all' ? Object.keys(map) : [...new Set(types)];
118
+ if (selected.length === 0) {
119
+ throw new TypeError(`subscribeOfficial: no '${lib}' channel selected; pass one or more types, or 'all'`);
120
+ }
121
+ const subscriptions = [];
122
+ for (const type of selected) {
123
+ const name = map[type];
124
+ if (name === undefined) {
125
+ throw new TypeError(`subscribeOfficial: '${lib}' publishes no '${type}' channel`);
126
+ }
127
+ const listener = (message) => {
128
+ try {
129
+ const duration = message?.durationMs;
130
+ const event = {
131
+ v: SCHEMA_VERSION,
132
+ ts: Date.now(),
133
+ lib,
134
+ event: type,
135
+ traceId: resolveTraceId(),
136
+ payload: message,
137
+ source: 'nestjs',
138
+ ...(typeof duration === 'number' && { durationMs: duration }),
139
+ };
140
+ fn(event, name);
141
+ }
142
+ catch {
143
+ // An observer must never change the outcome of the call it observes.
144
+ }
145
+ };
146
+ diagnostics_channel.subscribe(name, listener);
147
+ subscriptions.push([name, listener]);
148
+ }
149
+ let active = true;
150
+ return () => {
151
+ if (!active)
152
+ return;
153
+ active = false;
154
+ for (const [name, listener] of subscriptions) {
155
+ diagnostics_channel.unsubscribe(name, listener);
156
+ }
157
+ };
158
+ }
159
+ //# sourceMappingURL=official.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"official.js","sourceRoot":"","sources":["../src/official.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,QAAQ,CAAC;AAShD,SAAS,UAAU,CACjB,GAAM,EACN,KAAQ;IAER,OAAO,MAAM,CAAC,MAAM,CAClB,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,uBAAuB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CACzE,CAAC;AACxB,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,MAAM,0BAA0B,GAAG,UAAU,CAAC,YAAY,EAAE;IACjE,OAAO;IACP,SAAS;IACT,cAAc;IACd,mBAAmB;IACnB,gBAAgB;IAChB,kBAAkB;IAClB,mBAAmB;IACnB,cAAc;IACd,UAAU;CACX,CAAC,CAAC;AAEH,uFAAuF;AACvF,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAAC,WAAW,EAAE;IAC/D,kBAAkB;IAClB,kBAAkB;IAClB,oBAAoB;IACpB,uBAAuB;IACvB,oBAAoB;IACpB,iBAAiB;IACjB,oBAAoB;IACpB,8BAA8B;IAC9B,gBAAgB;IAChB,aAAa;IACb,kBAAkB;IAClB,eAAe;IACf,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,eAAe;IACf,kBAAkB;IAClB,kBAAkB;IAClB,kBAAkB;CACnB,CAAC,CAAC;AAEH,kGAAkG;AAClG,MAAM,CAAC,MAAM,8BAA8B,GAAG,UAAU,CAAC,gBAAgB,EAAE;IACzE,SAAS;IACT,UAAU;IACV,cAAc;IACd,YAAY;IACZ,aAAa;IACb,cAAc;IACd,0BAA0B;IAC1B,sBAAsB;IACtB,0BAA0B;IAC1B,gBAAgB;IAChB,gBAAgB;IAChB,oBAAoB;IACpB,sBAAsB;CACvB,CAAC,CAAC;AAEH,2DAA2D;AAC3D,MAAM,CAAC,MAAM,6BAA6B,GAAG,UAAU,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAErF,6DAA6D;AAC7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE3E,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7C,UAAU,EAAE,0BAA0B;IACtC,SAAS,EAAE,yBAAyB;IACpC,cAAc,EAAE,8BAA8B;IAC9C,aAAa,EAAE,6BAA6B;IAC5C,IAAI,EAAE,oBAAoB;CAC3B,CAAC,CAAC;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrD,UAAU,EAAE,OAAO;IACnB,SAAS,EAAE,OAAO;IAClB,cAAc,EAAE,OAAO;IACvB,aAAa,EAAE,OAAO;IACtB,IAAI,EAAE,OAAO;CACwB,CAAC,CAAC;AAQzC,iDAAiD;AACjD,MAAM,UAAU,oBAAoB;IAClC,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAa,CAAC,CAAC;AAC3F,CAAC;AAeD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAM,EACN,KAAyC,EACzC,EAAoB;IAEpB,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,CAAiD,CAAC;IACnF,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,SAAS,CAAC,+CAA+C,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,SAAS,CACjB,0BAA0B,GAAG,sDAAsD,CACpF,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAgD,EAAE,CAAC;IACtE,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,IAAI,SAAS,CAAC,uBAAuB,GAAG,mBAAmB,IAAI,WAAW,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC,OAAgB,EAAQ,EAAE;YAC1C,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAI,OAA2C,EAAE,UAAU,CAAC;gBAC1E,MAAM,KAAK,GAA4B;oBACrC,CAAC,EAAE,cAAc;oBACjB,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;oBACd,GAAG;oBACH,KAAK,EAAE,IAAI;oBACX,OAAO,EAAE,cAAc,EAAE;oBACzB,OAAO,EAAE,OAAO;oBAChB,MAAM,EAAE,QAAQ;oBAChB,GAAG,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;iBAC9D,CAAC;gBACF,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,qEAAqE;YACvE,CAAC;QACH,CAAC,CAAC;QACF,mBAAmB,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC9C,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,GAAG,KAAK,CAAC;QACf,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC;YAC7C,mBAAmB,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-diagnostics",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "A standard convention for @dudousxd/nestjs-* libs to emit observability events over node:diagnostics_channel.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -8,6 +8,19 @@
8
8
  "url": "git+https://github.com/DavideCarvalho/nestjs-diagnostics.git",
9
9
  "directory": "packages/core"
10
10
  },
11
+ "homepage": "https://davidecarvalho.github.io/aviary/docs/diagnostics",
12
+ "bugs": {
13
+ "url": "https://github.com/DavideCarvalho/nestjs-diagnostics/issues"
14
+ },
15
+ "keywords": [
16
+ "nestjs",
17
+ "diagnostics",
18
+ "diagnostics-channel",
19
+ "observability",
20
+ "telemetry",
21
+ "events",
22
+ "tanstack-intent"
23
+ ],
11
24
  "author": "Davi Carvalho <davi@goflip.ai>",
12
25
  "type": "module",
13
26
  "main": "./dist/index.js",
@@ -58,27 +71,23 @@
58
71
  "**/trace.ts"
59
72
  ],
60
73
  "devDependencies": {
61
- "@nestjs/common": "^12",
62
- "@nestjs/core": "^12",
63
- "@nestjs/testing": "^12",
64
- "@types/node": "^20.0.0",
65
- "reflect-metadata": "^0.2",
66
- "typescript": "^5.4.0",
67
- "unplugin-swc": "^1.5.1",
68
- "vitest": "^3.0.0"
74
+ "@nestjs/authentication": "0.1.5",
75
+ "@nestjs/authorization": "0.1.3",
76
+ "@nestjs/common": "12.0.4",
77
+ "@nestjs/core": "12.0.4",
78
+ "@nestjs/mail": "0.0.2",
79
+ "@nestjs/resilience": "0.0.3",
80
+ "@nestjs/testing": "12.0.4",
81
+ "@nestjs/workflows": "0.0.5",
82
+ "@types/node": "20.19.43",
83
+ "reflect-metadata": "0.2.2",
84
+ "typescript": "5.9.3",
85
+ "unplugin-swc": "1.6.0",
86
+ "vitest": "3.2.7"
69
87
  },
70
88
  "engines": {
71
89
  "node": ">=20"
72
90
  },
73
- "keywords": [
74
- "nestjs",
75
- "diagnostics",
76
- "diagnostics-channel",
77
- "observability",
78
- "telemetry",
79
- "events",
80
- "tanstack-intent"
81
- ],
82
91
  "scripts": {
83
92
  "build": "tsc -p tsconfig.json",
84
93
  "test": "vitest run --passWithNoTests",
@@ -162,3 +162,12 @@ The core swallows errors in `emit`/`registerChannel`, but a listener you attach
162
162
  directly runs inside the synchronous `publish` — guard it yourself, as the
163
163
  Telescope watcher's `safeRecord` does.
164
164
  Source: `packages/telescope/src/diagnostic.watcher.ts` (`safeRecord`).
165
+
166
+ ## First-party `nestjs:*` channels
167
+
168
+ The official NestJS packages (`@nestjs/resilience`, `workflows`,
169
+ `authentication`, `authorization`, `mail`) publish raw payloads on
170
+ `nestjs:<lib>:<type>`. These channels are not in the registry. Use
171
+ `subscribeOfficial(lib, types | 'all', fn)`, which wraps each payload in the
172
+ envelope with `traceId` and `source: 'nestjs'`. Never publish on `nestjs:*`
173
+ yourself. Lists: `OFFICIAL_CHANNELS` / `NESTJS_*_CHANNELS`.