@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 +22 -0
- package/README.md +42 -1
- package/dist/capability.d.ts +16 -11
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js +10 -5
- package/dist/capability.js.map +1 -1
- package/dist/conformance.d.ts +9 -5
- package/dist/conformance.d.ts.map +1 -1
- package/dist/conformance.js +9 -5
- package/dist/conformance.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/inject-capability.d.ts +10 -5
- package/dist/inject-capability.d.ts.map +1 -1
- package/dist/inject-capability.js +10 -5
- package/dist/inject-capability.js.map +1 -1
- package/dist/official.d.ts +83 -0
- package/dist/official.d.ts.map +1 -0
- package/dist/official.js +159 -0
- package/dist/official.js.map +1 -0
- package/package.json +27 -18
- package/skills/observe-channels/SKILL.md +9 -0
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
|
-
| `
|
|
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
|
|
package/dist/capability.d.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* `@dudousxd/nestjs-<lib>:<name
|
|
4
|
-
* (`Symbol.for`),
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
-
*
|
|
26
|
-
* `unknown`
|
|
27
|
-
*
|
|
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
|
package/dist/capability.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
package/dist/capability.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* `@dudousxd/nestjs-<lib>:<name
|
|
4
|
-
* (`Symbol.for`),
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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}`);
|
package/dist/capability.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
package/dist/conformance.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
|
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"}
|
package/dist/conformance.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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}:`;
|
package/dist/conformance.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"AAAA
|
|
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';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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
|
-
*
|
|
3
|
-
* `@Optional() @Inject(capability(lib, name))`,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
|
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
|
-
*
|
|
5
|
-
* `@Optional() @Inject(capability(lib, name))`,
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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
|
|
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"}
|
package/dist/official.js
ADDED
|
@@ -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":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dudousxd/nestjs-diagnostics",
|
|
3
|
-
"version": "0.
|
|
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/
|
|
62
|
-
"@nestjs/
|
|
63
|
-
"@nestjs/
|
|
64
|
-
"@
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
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`.
|