@dudousxd/nestjs-diagnostics 0.7.2 → 0.8.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.
- package/CHANGELOG.md +12 -0
- package/README.md +43 -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/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 +22 -13
- package/skills/observe-channels/SKILL.md +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @dudousxd/nestjs-diagnostics
|
|
2
2
|
|
|
3
|
+
## 0.8.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#77](https://github.com/DavideCarvalho/nestjs-diagnostics/pull/77) [`5730846`](https://github.com/DavideCarvalho/nestjs-diagnostics/commit/5730846a07b685effba58b344004722dc4d7f08c) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Docs: `OfficialDiagnosticEvent` TSDoc no longer says Telescope's `DiagnosticWatcher` records `nestjs:*`; READMEs note the removed-channel test and the Telescope peer range.
|
|
8
|
+
|
|
9
|
+
## 0.8.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#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:*`.
|
|
14
|
+
|
|
3
15
|
## 0.7.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -94,6 +94,46 @@ 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, renamed or
|
|
123
|
+
removed.
|
|
124
|
+
|
|
125
|
+
| Lib | Constant | Channels |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| `@nestjs/resilience` 0.0.3 | `NESTJS_RESILIENCE_CHANNELS` | 9 |
|
|
128
|
+
| `@nestjs/workflows` 0.0.5 | `NESTJS_WORKFLOWS_CHANNELS` | 19 |
|
|
129
|
+
| `@nestjs/authentication` 0.1.5 | `NESTJS_AUTHENTICATION_CHANNELS` | 13 |
|
|
130
|
+
| `@nestjs/authorization` 0.1.3 | `NESTJS_AUTHORIZATION_CHANNELS` | 1 (`denied`) |
|
|
131
|
+
| `@nestjs/mail` 0.0.2 | `NESTJS_MAIL_CHANNELS` | 2 (`sent`, `failed`) |
|
|
132
|
+
|
|
133
|
+
These channels are not added to the `aviary:*` registry
|
|
134
|
+
(`registeredChannels`/`onChannelRegistered`). Their lists are fixed, so subscribe
|
|
135
|
+
to them explicitly.
|
|
136
|
+
|
|
97
137
|
## API
|
|
98
138
|
|
|
99
139
|
| Export | Description |
|
|
@@ -106,7 +146,9 @@ watcher records every diagnostic event in the Telescope dashboard.
|
|
|
106
146
|
| `onChannelRegistered(cb)` | Notified once per future channel registration; returns an unsubscribe. |
|
|
107
147
|
| `setContextAccessor(accessor \| null)` | Register the accessor `emit` reads `traceId` from. |
|
|
108
148
|
| `CONTEXT_ACCESSOR` | Shared DI token for the optional context accessor. |
|
|
109
|
-
| `
|
|
149
|
+
| `subscribeOfficial(lib, types \| 'all', fn)` | Subscribe to first-party `nestjs:<lib>:<type>` channels, each payload wrapped in the envelope (+ `source: 'nestjs'`). Returns an unsubscribe. |
|
|
150
|
+
| `OFFICIAL_CHANNELS`, `NESTJS_*_CHANNELS`, `OFFICIAL_PACKAGE_VERSIONS`, `officialChannelNames()` | The pinned first-party channel lists. |
|
|
151
|
+
| `DiagnosticEvent`, `EmitOptions`, `ContextAccessor`, `OfficialDiagnosticEvent` | Types. |
|
|
110
152
|
|
|
111
153
|
## Reacting to events in NestJS — `@OnDiagnostic`
|
|
112
154
|
|
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"}
|
|
@@ -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 can tell them apart. Aviary's own `emit()` envelopes carry no
|
|
55
|
+
* `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.1",
|
|
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,9 +71,14 @@
|
|
|
58
71
|
"**/trace.ts"
|
|
59
72
|
],
|
|
60
73
|
"devDependencies": {
|
|
61
|
-
"@nestjs/
|
|
62
|
-
"@nestjs/
|
|
63
|
-
"@nestjs/
|
|
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",
|
|
64
82
|
"@types/node": "20.19.43",
|
|
65
83
|
"reflect-metadata": "0.2.2",
|
|
66
84
|
"typescript": "5.9.3",
|
|
@@ -70,15 +88,6 @@
|
|
|
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`.
|