@angelitosystems/nest-devtools 1.0.2 → 1.0.3

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/dist/index.cjs CHANGED
@@ -650,6 +650,48 @@ function detectNestJsVersion() {
650
650
  // src/version.ts
651
651
  var SDK_VERSION = "0.1.0";
652
652
 
653
+ // src/banner.ts
654
+ var RESET = "\x1B[0m";
655
+ var DIM = "\x1B[2m";
656
+ var BOLD = "\x1B[1m";
657
+ var GREEN = "\x1B[32m";
658
+ var YELLOW = "\x1B[33m";
659
+ var CYAN = "\x1B[36m";
660
+ var GRAY = "\x1B[90m";
661
+ var WIDTH = 47;
662
+ function colorEnabled() {
663
+ if (process.env["NO_COLOR"]) return false;
664
+ return Boolean(process.stdout?.isTTY);
665
+ }
666
+ function paint(color, text) {
667
+ return colorEnabled() ? `${color}${text}${RESET}` : text;
668
+ }
669
+ function pad(label, value) {
670
+ const line = ` ${paint(GRAY, label.padEnd(9))} ${paint(CYAN, value)}`;
671
+ return line;
672
+ }
673
+ function printStartupBanner(info) {
674
+ const top = `${paint(GRAY, "\u250C" + "\u2500".repeat(WIDTH) + "\u2510")}`;
675
+ const bottom = `${paint(GRAY, "\u2514" + "\u2500".repeat(WIDTH) + "\u2518")}`;
676
+ const title = ` ${paint(BOLD + CYAN, "NestJS DevTools")} ${paint(GREEN, "\u25CF")} ${paint(DIM, `(${info.project})`)}`;
677
+ writeOriginalConsole("log", "");
678
+ writeOriginalConsole("log", top);
679
+ writeOriginalConsole("log", title);
680
+ writeOriginalConsole("log", pad("Endpoint", info.endpoint));
681
+ writeOriginalConsole("log", pad("Dashboard", info.dashboard));
682
+ writeOriginalConsole("log", `${paint(GRAY, " Estado")} ${paint(YELLOW, "\u25CC conectando\u2026")}`);
683
+ writeOriginalConsole("log", bottom);
684
+ }
685
+ function printConnectionStatus(state, dashboard) {
686
+ if (state === "open") {
687
+ writeOriginalConsole("log", ` ${paint(GREEN, "\u2713")} Conectado al dashboard ${paint(DIM, `(${dashboard})`)}`);
688
+ return;
689
+ }
690
+ writeOriginalConsole("log", ` ${paint(YELLOW, "\u26A0")} No se pudo conectar al dashboard todav\xEDa.`);
691
+ writeOriginalConsole("log", ` ${paint(DIM, "Lev\xE1ntalo en otra terminal con:")} ${paint(BOLD, "npx nest-devtools start")}`);
692
+ writeOriginalConsole("log", ` ${paint(DIM, "Reintentando en segundo plano \u2014 se conectar\xE1 solo cuando el dashboard est\xE9 arriba.")}`);
693
+ }
694
+
653
695
  // src/sdk.ts
654
696
  var NestDevTools = class {
655
697
  static cleanups = [];
@@ -681,7 +723,20 @@ var NestDevTools = class {
681
723
  nestjsVersion: detectNestJsVersion(),
682
724
  sdkVersion: SDK_VERSION
683
725
  };
684
- import_devtools_core7.devtools.initialize({ config, projectInfo, registerCleanup });
726
+ let hasWarnedOffline = false;
727
+ import_devtools_core7.devtools.initialize({
728
+ config,
729
+ projectInfo,
730
+ registerCleanup,
731
+ onStateChange: (state) => {
732
+ if (state === "open") {
733
+ printConnectionStatus("open", dashboardUrl(config.server));
734
+ } else if (state === "retrying" && !hasWarnedOffline) {
735
+ hasWarnedOffline = true;
736
+ printConnectionStatus("offline", dashboardUrl(config.server));
737
+ }
738
+ }
739
+ });
685
740
  const adapter = app.getHttpAdapter();
686
741
  const httpReady = Boolean(adapter && ["http", "express"].includes(adapter.getType()));
687
742
  const http = new HttpInstrumentation({ config, projectInfo });
@@ -697,9 +752,11 @@ var NestDevTools = class {
697
752
  if (config.capture.database) {
698
753
  registerCleanup(new DatabaseInstrumentation({ config, projectInfo }).attach());
699
754
  }
700
- writeOriginalConsole("log", "[NestJS DevTools] SDK started");
701
- writeOriginalConsole("log", ` SDK endpoint: ${config.server}`);
702
- writeOriginalConsole("log", ` Dashboard: ${dashboardUrl(config.server)}`);
755
+ printStartupBanner({
756
+ endpoint: config.server,
757
+ dashboard: dashboardUrl(config.server),
758
+ project: projectInfo.projectName
759
+ });
703
760
  return {
704
761
  enabled: true,
705
762
  projectId: config.projectId,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/sdk.ts","../src/instrumentation/http.ts","../src/emitter.ts","../src/instrumentation/timeline.ts","../src/instrumentation/console.ts","../src/instrumentation/nest-logger.ts","../src/instrumentation/exceptions.ts","../src/instrumentation/performance.ts","../src/instrumentation/app-explorer.ts","../src/instrumentation/websockets.ts","../src/instrumentation/database.ts","../src/detect.ts","../src/version.ts"],"sourcesContent":["/**\n * @angelitosystems/nest-devtools\n *\n * Drop-in real-time debugging and observability for NestJS.\n *\n * Usage:\n * import { NestDevTools } from '@angelitosystems/nest-devtools';\n * const app = await NestFactory.create(AppModule);\n * NestDevTools.init(app);\n */\nexport { NestDevTools, devtools } from './sdk';\nexport type { InitResult } from './sdk';\nexport { captureError } from './instrumentation/exceptions';\nexport type { DevToolsUserConfig } from '@angelitosystems/devtools-core';\nexport { requestContext } from '@angelitosystems/devtools-core';\nexport type { RequestContext } from '@angelitosystems/devtools-core';\n","import { hostname } from 'os';\nimport { devtools as coreDevtools, resolveConfig } from '@angelitosystems/devtools-core';\nimport type { DevToolsUserConfig } from '@angelitosystems/devtools-core';\nimport type { ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { HttpInstrumentation } from './instrumentation/http';\nimport { ConsoleInstrumentation, writeOriginalConsole } from './instrumentation/console';\nimport { LoggerInstrumentation } from './instrumentation/nest-logger';\nimport { ExceptionsInstrumentation, captureError } from './instrumentation/exceptions';\nimport { PerformanceInstrumentation } from './instrumentation/performance';\nimport { AppExplorer } from './instrumentation/app-explorer';\nimport { WebsocketInstrumentation } from './instrumentation/websockets';\nimport { DatabaseInstrumentation } from './instrumentation/database';\nimport { detectNestJsVersion } from './detect';\nimport { SDK_VERSION } from './version';\n\n/** Result of calling NestDevTools.init(). */\nexport interface InitResult {\n /** True when instrumentation is live. */\n enabled: boolean;\n /** Reason when partially or fully disabled. */\n reason?: 'disabled-by-config' | 'already-initialized' | 'no-http-adapter';\n projectId: string;\n projectName: string;\n server: string;\n}\n\n/**\n * Main entry point: `NestDevTools.init(app, config?)`.\n *\n * Never throws, never blocks startup, and disables itself in production\n * unless explicitly enabled.\n */\nexport class NestDevTools {\n private static readonly cleanups: Array<() => void> = [];\n private static initialized = false;\n\n /** Initialize DevTools for a NestJS application. One active instance per process. */\n static init(app: INestApplication, userConfig?: DevToolsUserConfig): InitResult {\n const config = resolveConfig(userConfig);\n const disabled: InitResult = {\n enabled: false,\n reason: 'disabled-by-config',\n projectId: config.projectId,\n projectName: config.project ?? config.projectId,\n server: config.server,\n };\n\n if (this.initialized) return { ...disabled, reason: 'already-initialized' };\n if (!config.enabled) return disabled; // zero side effects: no patching, no sockets, no timers\n\n this.initialized = true;\n const registerCleanup = (fn: () => void) => this.cleanups.push(fn);\n\n const projectInfo: ProjectInfo = {\n projectId: config.projectId,\n projectName: config.project ?? config.projectId,\n environment: config.environment,\n hostname: safeHostname(),\n port: null,\n pid: process.pid,\n runtime: detectRuntime(),\n runtimeVersion: detectRuntimeVersion(),\n nodeVersion: process.version,\n nestjsVersion: detectNestJsVersion(),\n sdkVersion: SDK_VERSION,\n };\n\n // transport is fully async: a missing server never affects startup\n coreDevtools.initialize({ config, projectInfo, registerCleanup });\n\n const adapter = app.getHttpAdapter();\n const httpReady = Boolean(adapter && ['http', 'express'].includes(adapter.getType()));\n\n // ---- HTTP instrumentation -------------------------------------------\n const http = new HttpInstrumentation({ config, projectInfo });\n registerCleanup(http.attach(app));\n\n // ---- console + NestJS Logger + global errors ------------------------\n registerCleanup(new ConsoleInstrumentation({ config, projectInfo }).attach());\n registerCleanup(new LoggerInstrumentation({ config, projectInfo }).attach());\n registerCleanup(ExceptionsInstrumentation.attach({ config, projectInfo }));\n\n // ---- performance sampling -------------------------------------------\n registerCleanup(new PerformanceInstrumentation({ config, projectInfo }).attach());\n\n // ---- application graph ----------------------------------------------\n registerCleanup(new AppExplorer({ config, projectInfo }).attach(app));\n\n // ---- websockets + database (best effort) ----------------------------\n if (config.capture.websockets) {\n registerCleanup(new WebsocketInstrumentation({ config, projectInfo }).attach());\n }\n if (config.capture.database) {\n registerCleanup(new DatabaseInstrumentation({ config, projectInfo }).attach());\n }\n\n writeOriginalConsole('log', '[NestJS DevTools] SDK started');\n writeOriginalConsole('log', ` SDK endpoint: ${config.server}`);\n writeOriginalConsole('log', ` Dashboard: ${dashboardUrl(config.server)}`);\n\n return {\n enabled: true,\n projectId: config.projectId,\n projectName: projectInfo.projectName,\n server: config.server,\n ...(httpReady ? {} : { reason: 'no-http-adapter' as const }),\n };\n }\n\n /** Teardown everything (mostly useful in tests). */\n static destroy(): void {\n for (const cleanup of this.cleanups.splice(0)) {\n try {\n cleanup();\n } catch {\n /* ignore */\n }\n }\n this.initialized = false;\n coreDevtools.shutdown();\n }\n\n /** Whether the SDK is currently active in this process. */\n static isActive(): boolean {\n return this.initialized;\n }\n}\n\n/** Convenience functional alias: devtools.init(app). */\nexport const devtools = {\n init: NestDevTools.init.bind(NestDevTools),\n destroy: NestDevTools.destroy.bind(NestDevTools),\n isActive: NestDevTools.isActive.bind(NestDevTools),\n};\n\nfunction safeHostname(): string {\n try {\n return hostname();\n } catch {\n return 'unknown';\n }\n}\n\nfunction detectRuntime(): string {\n const versions = process.versions as Record<string, string | undefined>;\n if (versions['bun']) return 'bun';\n if (versions['deno']) return 'deno';\n return 'node';\n}\n\nfunction detectRuntimeVersion(): string {\n const versions = process.versions as Record<string, string | undefined>;\n return versions['bun'] ?? versions['deno'] ?? process.version;\n}\n\nfunction dashboardUrl(server: string): string {\n try {\n const url = new URL(server);\n url.protocol = url.protocol === 'wss:' ? 'https:' : 'http:';\n const port = Number(url.port);\n url.port = String(Number.isFinite(port) && port > 0 ? port - 1 : 4317);\n url.pathname = '';\n url.search = '';\n url.hash = '';\n return url.toString().replace(/\\/$/, '');\n } catch {\n return 'http://localhost:4317';\n }\n}\n\nexport { captureError };\n","import type { IncomingMessage, ServerResponse, Server as HttpServer } from 'http';\nimport { Redactor, randomId } from '@angelitosystems/devtools-protocol';\nimport type {\n ProjectInfo,\n RequestCompletedPayload,\n RequestStartedPayload,\n TimelineSpan,\n} from '@angelitosystems/devtools-protocol';\nimport { requestContext } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { emit } from '../emitter';\nimport { trackSpans } from './timeline';\n\n/** Shared context every instrumentation module receives. */\nexport interface InstrumentationContext {\n config: DevToolsConfig;\n projectInfo: ProjectInfo;\n}\n\n/** Headers captured by default (denylist still applies). */\nconst INTERESTING_HEADERS = [\n 'content-type',\n 'content-length',\n 'accept',\n 'origin',\n 'referer',\n 'user-agent',\n 'x-forwarded-for',\n 'x-request-id',\n] as const;\n\ntype RequestListener = (req: IncomingMessage, res: ServerResponse) => void;\n\nconst WRAPPED = Symbol('nest-devtools.wrapped');\n\n/**\n * Instrument the HTTP server of a NestJS application.\n *\n * Covers both bootstrap orders without touching Node module internals:\n * - `NestDevTools.init(app)` after `app.listen()`: the server already exists\n * and is wrapped immediately.\n * - `NestDevTools.init(app)` before `app.listen()` (recommended): `app.listen`\n * is wrapped so the server is wrapped the moment it exists.\n */\nexport class HttpInstrumentation {\n private readonly redactor: Redactor;\n\n constructor(private readonly ctx: InstrumentationContext) {\n this.redactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n }\n\n /** Begin capturing HTTP requests. Returns a cleanup function. */\n attach(app: INestApplication): () => void {\n try {\n const adapter = app.getHttpAdapter();\n // 'http' = platform-default adapter, 'express' = @nestjs/platform-express\n if (!adapter || !['http', 'express'].includes(adapter.getType())) return () => {};\n\n const getServer = (): HttpServer | undefined =>\n (adapter as unknown as { getHttpServer?: () => HttpServer }).getHttpServer?.();\n\n // 1) server already exists (init called after listen)\n const existing = getServer();\n if (existing) {\n this.wrapServer(existing);\n return () => {};\n }\n\n // 2) init called before listen: wrap the server once listen() resolves\n const appLike = app as unknown as { listen: (...args: unknown[]) => unknown };\n const originalListen = appLike.listen.bind(app);\n const self = this;\n const patchedListen = (...args: unknown[]) => {\n const result = originalListen(...args);\n Promise.resolve(result)\n .then(() => {\n const server = getServer();\n if (server) self.wrapServer(server);\n })\n .catch(() => {\n /* listen failed — the app will surface its own error */\n });\n return result;\n };\n appLike.listen = patchedListen;\n\n return () => {\n appLike.listen = originalListen;\n };\n } catch {\n return () => {};\n }\n }\n\n /** Wrap the 'request' listeners of a server exactly once. */\n private wrapServer(server: HttpServer): void {\n const target = server as unknown as Record<symbol, unknown>;\n if (target[WRAPPED]) return;\n target[WRAPPED] = true;\n\n const self = this;\n const originalListeners = server.rawListeners('request') as RequestListener[];\n\n server.removeAllListeners('request');\n server.on('request', (req, res) => {\n self.instrumentRequest(req, res, () => {\n for (const listener of originalListeners) {\n listener.call(server, req, res);\n }\n });\n });\n }\n\n /** Wrap a single request lifecycle. */\n private instrumentRequest(req: IncomingMessage, res: ServerResponse, next: () => void): void {\n if (!this.ctx.config.capture.requests) {\n next();\n return;\n }\n\n const startedAt = Date.now();\n const requestId = randomId('req');\n const method = (req.method ?? 'GET').toUpperCase();\n const rawUrl = req.url ?? '/';\n const url = safeUrlPath(rawUrl);\n\n const spans: TimelineSpan[] = [];\n const unregister = trackSpans(requestId, spans);\n res.once('finish', unregister);\n\n const started: RequestStartedPayload = {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n method,\n url,\n headers: this.collectHeaders(req),\n query: parseQuery(rawUrl),\n ip: clientIp(req),\n userAgent: asString(req.headers['user-agent']) || undefined,\n startedAt,\n };\n\n const middlewareSpan: TimelineSpan = {\n layer: 'middleware',\n label: `${method} ${url}`,\n duration: 0,\n startedAt,\n status: 'ok',\n };\n spans.push(middlewareSpan);\n\n const onFinished = () => {\n const finishedAt = Date.now();\n middlewareSpan.duration = Math.max(0, finishedAt - middlewareSpan.startedAt);\n middlewareSpan.status = res.statusCode >= 500 ? 'error' : 'ok';\n\n const responseSpan: TimelineSpan = {\n layer: 'response',\n label: 'response',\n duration: 0,\n startedAt: finishedAt,\n status: 'ok',\n };\n spans.push(responseSpan);\n\n const errored = res.statusCode >= 500;\n\n const completed: RequestCompletedPayload = {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n method,\n url,\n statusCode: res.statusCode,\n duration: finishedAt - startedAt,\n startedAt,\n timeline: spans,\n query: parseQuery(rawUrl),\n errored,\n };\n\n emit('request.completed', completed);\n\n // NestJS exception filters turn controller errors into 5xx responses\n // without any process-level signal — surface them in the Error Explorer.\n if (errored) {\n emit('error.created', {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n name: 'HttpError',\n message: `${method} ${url} failed with status ${res.statusCode}`,\n fingerprint: httpErrorFingerprint(method, url, res.statusCode),\n request: { method, url, statusCode: res.statusCode },\n timestamp: finishedAt,\n });\n }\n };\n\n const context = requestContext();\n context.run({ requestId, method, url, startedAt }, () => {\n emit('request.started', started);\n res.once('finish', onFinished);\n next();\n });\n }\n\n private collectHeaders(req: IncomingMessage): Record<string, string> {\n const out: Record<string, string> = {};\n for (const key of INTERESTING_HEADERS) {\n const value = req.headers[key];\n if (value === undefined) continue;\n out[key] = this.redactor.isSensitive(key) ? '[REDACTED]' : asString(value).slice(0, 200);\n }\n return out;\n }\n}\n\nfunction asString(value: string | string[] | undefined): string {\n if (Array.isArray(value)) return value.join(', ');\n return value ?? '';\n}\n\n/** Stable fingerprint for framework-handled HTTP failures. */\nfunction httpErrorFingerprint(method: string, url: string, statusCode: number): string {\n const route = url.replace(/\\/\\d+(?=\\/|$)/g, '/:id'); // group /users/15 with /users/16\n const raw = `${method}::${route}::${statusCode}`;\n let hash = 0;\n for (let i = 0; i < raw.length; i++) {\n hash = (hash * 31 + raw.charCodeAt(i)) >>> 0;\n }\n return hash.toString(36).padStart(7, '0');\n}\n\nfunction safeUrlPath(raw: string): string {\n const index = raw.indexOf('?');\n return index === -1 ? raw : raw.slice(0, index);\n}\n\nfunction parseQuery(raw: string): Record<string, unknown> {\n const index = raw.indexOf('?');\n if (index === -1) return {};\n const out: Record<string, unknown> = {};\n for (const [key, value] of new URLSearchParams(raw.slice(index + 1))) {\n out[key] = value;\n }\n return out;\n}\n\nfunction clientIp(req: IncomingMessage): string | undefined {\n const forwarded = req.headers['x-forwarded-for'];\n if (typeof forwarded === 'string') return forwarded.split(',')[0]?.trim();\n return req.socket?.remoteAddress ?? undefined;\n}\n\nexport { safeUrlPath, parseQuery, clientIp };\n","import { devtools as coreDevtools } from '@angelitosystems/devtools-core';\nimport type { DevToolsEventMap, DevToolsEventName } from '@angelitosystems/devtools-protocol';\n\n/** Emit a typed protocol event to the DevTools server (fire-and-forget). */\nexport function emit<K extends DevToolsEventName>(event: K, payload: DevToolsEventMap[K]): void {\n try {\n coreDevtools.send(event, payload);\n } catch {\n /* instrumentation must never break the app */\n }\n}\n","import type { TimelineSpan } from '@angelitosystems/devtools-protocol';\n\n/** Create a started span inside a request's span list. */\nexport function startSpan(spans: TimelineSpan[], layer: string, label: string, detail?: string): TimelineSpan {\n const span: TimelineSpan = {\n layer,\n label,\n duration: 0,\n startedAt: Date.now(),\n status: 'ok',\n ...(detail !== undefined ? { detail } : {}),\n };\n spans.push(span);\n return span;\n}\n\n/** Finalize a span, computing its duration. */\nexport function endSpan(span: TimelineSpan, status?: 'ok' | 'error'): void {\n span.duration = Math.max(0, Date.now() - span.startedAt);\n if (status) span.status = status;\n}\n\n/**\n * Registry of active request timelines, keyed by requestId.\n * Lets deeper instrumentation (database, websockets) attach spans to the\n * request that caused them, using the AsyncLocalStorage request id.\n */\nconst recorders = new Map<string, TimelineSpan[]>();\n\n/** Register a request's span list. Returns an unregister callback. */\nexport function trackSpans(requestId: string, spans: TimelineSpan[]): () => void {\n recorders.set(requestId, spans);\n return () => recorders.delete(requestId);\n}\n\n/** Add an auto-ended span to a request if it is still active. */\nexport function recordSpan(requestId: string, layer: string, label: string, detail?: string, status?: 'ok' | 'error'): void {\n const spans = recorders.get(requestId);\n if (!spans) return;\n const span = startSpan(spans, layer, label, detail);\n endSpan(span, status);\n}\n","import { Console } from 'console';\nimport { Redactor } from '@angelitosystems/devtools-protocol';\nimport { resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { LogPayload, LogLevel, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport { requestContext } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\nconst METHODS = ['log', 'info', 'warn', 'error', 'debug'] as const;\ntype ConsoleMethod = (typeof METHODS)[number];\n\nconst LEVEL_BY_METHOD: Record<ConsoleMethod, LogLevel> = {\n log: 'info',\n info: 'info',\n warn: 'warn',\n error: 'error',\n debug: 'debug',\n};\n\n/** Original console bound directly to the process streams. */\nconst originalConsole = new Console({\n stdout: process.stdout,\n stderr: process.stderr,\n colorMode: 'auto',\n});\n\n/** Write through the untouched console (used by DevTools' own logging). */\nexport function writeOriginalConsole(method: ConsoleMethod, ...args: unknown[]): void {\n const fn = (originalConsole as unknown as Record<string, (...a: unknown[]) => void>)[method];\n if (fn) fn.apply(originalConsole, args);\n}\n\n/** Capture console output and mirror it to DevTools. */\nexport class ConsoleInstrumentation {\n private readonly redactor: Redactor;\n\n constructor(private readonly ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {\n this.redactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n }\n\n /** Patch console methods. Returns a restore function. */\n attach(): () => void {\n const self = this;\n const restores: Array<() => void> = [];\n\n for (const method of METHODS) {\n const original = (console as unknown as Record<string, unknown>)[method];\n if (typeof original !== 'function') continue;\n\n const patched = (...args: unknown[]) => {\n try {\n (original as (...a: unknown[]) => void).apply(console, args);\n } catch {\n /* never break host logging */\n }\n self.capture(method, args);\n };\n\n (console as unknown as Record<string, unknown>)[method] = patched;\n restores.push(() => {\n (console as unknown as Record<string, unknown>)[method] = original;\n });\n }\n\n return () => {\n for (const restore of restores.splice(0)) restore();\n };\n }\n\n private capture(method: ConsoleMethod, args: unknown[]): void {\n if (!this.ctx.config.capture.logs) return;\n try {\n const level = LEVEL_BY_METHOD[method];\n const payload: LogPayload = {\n projectId: this.ctx.projectInfo.projectId,\n level,\n message: formatMessage(args, this.redactor),\n arguments: args.length > 0 ? (this.redactor.redact(args) as unknown[]) : undefined,\n stack: method === 'error' ? captureStack() : undefined,\n source: resolveSourceLocation(captureStack() ?? '', { skip: 0 }),\n context: undefined,\n processId: process.pid,\n requestId: requestContext().requestId(),\n timestamp: Date.now(),\n };\n if (method === 'error') payload.level = 'error';\n emit('log.created', payload);\n } catch {\n /* never propagate */\n }\n }\n}\n\nfunction formatMessage(args: unknown[], redactor: Redactor): string {\n if (args.length === 0) return '';\n const first = args[0];\n if (typeof first === 'string') {\n return args.length === 1 ? redactor.redactString(first) : `${first} ${redactor.serialize(args.slice(1))}`;\n }\n return redactor.serialize(args);\n}\n\nfunction captureStack(): string | undefined {\n const err = new Error();\n const stack = err.stack;\n if (!stack) return undefined;\n // drop the frames created by this helper\n return stack.split('\\n').slice(3).join('\\n');\n}\n","import { Logger } from '@nestjs/common';\nimport { Redactor } from '@angelitosystems/devtools-protocol';\nimport type { LogPayload, LogLevel, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport { requestContext, resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\n/**\n * Captures NestJS framework logs (`new Logger('Ctx').log(...)` and the static\n * `Logger.log(...)` variants). Nest's Logger writes through process.stdout\n * internals, not console.*, so it needs its own hook.\n *\n * State is module-scoped on purpose: the patched methods are plain functions\n * and must never depend on class-instance `this` binding.\n */\nlet activeRedactor = new Redactor();\nlet activeConfig: DevToolsConfig | null = null;\nlet activeProjectId = '';\n\nfunction capture(level: LogLevel, message: unknown, context?: string, stack?: string): void {\n try {\n if (!activeConfig?.capture.logs) return;\n const text = typeof message === 'string' ? message : activeRedactor.serialize(message);\n const payload: LogPayload = {\n projectId: activeProjectId,\n level,\n message: activeRedactor.redactString(text),\n source: stack ? undefined : resolveSdkAwareLocation(),\n context,\n stack,\n processId: process.pid,\n requestId: requestContext().requestId(),\n timestamp: Date.now(),\n };\n emit('log.created', payload);\n } catch {\n /* never propagate */\n }\n}\n\n/** Captures NestJS Logger output and mirrors it to DevTools. */\nexport class LoggerInstrumentation {\n constructor(ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {\n activeRedactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n activeConfig = ctx.config;\n activeProjectId = ctx.projectInfo.projectId;\n }\n\n /** Patch Logger.prototype and the static Logger methods. Returns a restore function. */\n attach(): () => void {\n const restores: Array<() => void> = [];\n\n const patch = (owner: Record<string, unknown>, method: string, level: LogLevel, instance: boolean) => {\n const original = owner[method];\n if (typeof original !== 'function') return;\n\n owner[method] = function (this: unknown, message: unknown, ...rest: unknown[]) {\n const context = instance\n ? ((this as { context?: string } | undefined)?.context ?? (rest[0] as string | undefined))\n : (rest[0] as string | undefined);\n const stack = rest[1] as string | undefined;\n try {\n const result = (original as (...a: unknown[]) => unknown).apply(this, [message, ...rest]);\n capture(level, message, context, stack);\n return result;\n } catch (err) {\n capture(level, message, context, stack);\n throw err;\n }\n };\n\n restores.push(() => {\n owner[method] = original;\n });\n };\n\n // instance loggers: `new Logger('Ctx').log(...)` — the common case\n const proto = Logger.prototype as unknown as Record<string, unknown>;\n patch(proto, 'log', 'info', true);\n patch(proto, 'error', 'error', true);\n patch(proto, 'warn', 'warn', true);\n patch(proto, 'debug', 'debug', true);\n patch(proto, 'verbose', 'verbose', true);\n\n // static loggers: `Logger.log(...)`\n const statics = Logger as unknown as Record<string, unknown>;\n patch(statics, 'log', 'info', false);\n patch(statics, 'error', 'error', false);\n patch(statics, 'warn', 'warn', false);\n patch(statics, 'debug', 'debug', false);\n patch(statics, 'verbose', 'verbose', false);\n\n return () => {\n for (const restore of restores.splice(0)) restore();\n };\n }\n}\n\nfunction resolveSdkAwareLocation(): LogPayload['source'] {\n try {\n const err = new Error();\n const stack = err.stack?.split('\\n').slice(3).join('\\n');\n return resolveSourceLocation(stack ?? '', { skip: 0 });\n } catch {\n return undefined;\n }\n}\n","import { basename } from 'path';\nimport type { ErrorPayload, ProjectInfo, SourceLocation } from '@angelitosystems/devtools-protocol';\nimport { requestContext, safeStringify, resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\ntype InstrumentationCtx = {\n config: DevToolsConfig;\n projectInfo: ProjectInfo;\n};\n\n/**\n * Global error capture via process-level hooks. Errors handled by NestJS\n * filters surface through request.completed; unexpected errors land here.\n */\nexport class ExceptionsInstrumentation {\n /** Attach process-level hooks. Returns a detach function. */\n static attach(ctx: InstrumentationCtx): () => void {\n const onUncaught = (error: unknown): void => {\n reportError(error, ctx, { source: 'uncaughtException' });\n };\n const onRejection = (reason: unknown): void => {\n reportError(reason, ctx, { source: 'unhandledRejection' });\n };\n\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onRejection);\n\n return () => {\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onRejection);\n };\n }\n}\n\n/** Public helper: report an error manually from anywhere in the app. */\nexport function captureError(\n error: unknown,\n options?: { context?: string; controller?: string; service?: string },\n): void {\n reportError(error, undefined, options);\n}\n\nfunction reportError(\n error: unknown,\n ctx: InstrumentationCtx | undefined,\n options?: { context?: string; controller?: string; service?: string; source?: string },\n): void {\n try {\n if (ctx && !ctx.config.capture.errors) return;\n\n const normalized = normalizeError(error);\n const location = resolveSourceLocation(normalized.error ?? normalized.message, { skip: 1 });\n const projectId = ctx?.projectInfo.projectId ?? basename(process.cwd());\n\n const payload: ErrorPayload = {\n requestId: requestContext().requestId(),\n projectId,\n name: normalized.name,\n message: normalized.message,\n stack: normalized.error?.stack,\n source: location,\n fingerprint: fingerprint(normalized.name, normalized.message, location),\n context: options?.context ?? options?.source,\n request: currentRequestSummary(),\n controller: options?.controller,\n service: options?.service,\n timestamp: Date.now(),\n };\n\n emit('error.created', payload);\n } catch {\n /* never propagate */\n }\n}\n\nfunction normalizeError(error: unknown): { error: Error | undefined; name: string; message: string } {\n if (error instanceof Error) {\n return { error, name: error.name, message: error.message };\n }\n if (typeof error === 'string') {\n return { error: undefined, name: 'Unknown', message: error };\n }\n if (error !== null && typeof error === 'object' && 'message' in error) {\n const record = error as Record<string, unknown>;\n return {\n error: undefined,\n name: typeof record['name'] === 'string' ? record['name'] : 'Error',\n message: String(record['message']),\n };\n }\n return { error: undefined, name: 'Unknown', message: safeStringify(error) };\n}\n\nfunction fingerprint(name: string, message: string, location?: SourceLocation): string {\n const raw = name + '::' + message + '::' + (location?.file ?? '') + ':' + String(location?.line ?? '');\n let hash = 0;\n for (let i = 0; i < raw.length; i++) {\n hash = (hash * 31 + raw.charCodeAt(i)) >>> 0;\n }\n return hash.toString(36).padStart(7, '0');\n}\n\nfunction currentRequestSummary(): { method: string; url: string } | undefined {\n const context = requestContext().current();\n if (!context?.method || !context?.url) return undefined;\n return { method: context.method, url: context.url };\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * Performance instrumentation.\n *\n * Periodic CPU/memory/event-loop/latency sampling lives in core\n * (CoreDevtools.startPerformance) so it works even without an HTTP adapter.\n * This module exists as the capture-toggle boundary and future extension\n * point (gc hooks, histograms, cluster awareness).\n */\nexport class PerformanceInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op: sampling is owned by core. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import type { AppModuleNode, AppMemberNode, AppSnapshot, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { emit } from '../emitter';\n\ninterface ContainerNode {\n id: string;\n name?: string;\n metatype?: Function;\n instance?: object;\n subtype?: 'httpController' | 'gateway';\n}\n\n/**\n * Explore the Nest container to build the module graph (modules, controllers,\n * providers, guards, pipes...). Best effort: any failure keeps the app safe.\n */\nexport class AppExplorer {\n constructor(private readonly ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {}\n\n /** Walk the container and emit app.snapshot. Returns a no-op cleanup. */\n attach(app: INestApplication): () => void {\n try {\n const snapshot = this.buildSnapshot(app);\n emit('app.snapshot', snapshot);\n } catch {\n /* best effort */\n }\n return () => {};\n }\n\n private buildSnapshot(app: INestApplication): AppSnapshot {\n const internal = (app as unknown as { container?: unknown }).container as\n | { getModules?: () => Map<string, ContainerNode> }\n | undefined;\n\n const modules: AppModuleNode[] = [];\n const modulesMap = internal?.getModules?.();\n if (modulesMap) {\n for (const [id, node] of modulesMap) {\n const moduleName = node.metatype?.name ?? String(id);\n const members = this.extractMembers(node);\n modules.push({\n name: moduleName,\n imports: [],\n controllers: members.controllers,\n providers: members.providers,\n exports: [],\n });\n }\n }\n\n return {\n projectId: this.ctx.projectInfo.projectId,\n projectName: this.ctx.projectInfo.projectName,\n modules,\n nestjsVersion: this.ctx.projectInfo.nestjsVersion,\n capturedAt: Date.now(),\n };\n }\n\n private extractMembers(node: ContainerNode): { controllers: AppMemberNode[]; providers: AppMemberNode[] } {\n const controllers: AppMemberNode[] = [];\n const providers: AppMemberNode[] = [];\n\n const providersMap = (node as unknown as { providers?: Map<string, unknown> }).providers;\n if (providersMap instanceof Map) {\n for (const [id, wrapper] of providersMap) {\n const member = this.memberFromWrapper(id, wrapper);\n if (!member) continue;\n if (wrapper && (wrapper as { subtype?: string }).subtype === 'httpController') {\n controllers.push(member);\n } else {\n providers.push(member);\n }\n }\n }\n\n return { controllers, providers };\n }\n\n private memberFromWrapper(id: string, wrapper: unknown): AppMemberNode | null {\n const w = wrapper as { name?: string; metatype?: Function; subtype?: string; instance?: Record<string, unknown> } | null;\n const name = w?.metatype?.name ?? (typeof id === 'string' ? id.replace(/^[A-Z_0-9]+:/, '') : 'unknown');\n const type = classify(name, w?.instance);\n return { name, type };\n }\n}\n\n/** Heuristic classification of providers into guards/interceptors/pipes/filters. */\nfunction classify(name: string, instance?: Record<string, unknown>): AppMemberNode['type'] {\n if (name.endsWith('Gateway')) return 'gateway';\n if (name.endsWith('Guard')) return 'guard';\n if (name.endsWith('Interceptor')) return 'interceptor';\n if (name.endsWith('Pipe')) return 'pipe';\n if (name.endsWith('Filter')) return 'filter';\n if (instance && typeof instance.canActivate === 'function') return 'guard';\n if (instance && typeof instance.intercept === 'function') return 'interceptor';\n if (instance && typeof instance.transform === 'function') return 'pipe';\n if (instance && typeof instance.catch === 'function') return 'filter';\n return 'provider';\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * WebSocket gateway instrumentation (v0.3 roadmap).\n *\n * Will introspect @WebSocketGateway() classes via the Nest container and wrap\n * gateway handlers. The placeholder keeps the init() wiring stable and\n * guarantees zero interference with host sockets.\n */\nexport class WebsocketInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op for now. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * Database instrumentation (v0.3 roadmap).\n *\n * Provider strategies will live here:\n * - Prisma: $extends / $use hooks\n * - TypeORM: DataSource QueryListener via subscriber\n * - Sequelize: sequelize.addHook\n * - MikroORM: EntityManager event subscriber\n *\n * All strategies must attach spans to the active request via trackSpans/\n * recordSpan and emit query.executed with redacted parameters.\n */\nexport class DatabaseInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op for now. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'path';\n\nlet cached: string | null | undefined;\n\n/** Best-effort detection of the host app's @nestjs/core version. */\nexport function detectNestJsVersion(): string | null {\n if (cached !== undefined) return cached;\n cached = null;\n try {\n const candidates = [\n resolve(process.cwd(), 'node_modules/@nestjs/core/package.json'),\n // bun/pnpm layouts: walk up a couple of levels\n resolve(process.cwd(), '../../node_modules/@nestjs/core/package.json'),\n ];\n for (const path of candidates) {\n if (!existsSync(path)) continue;\n const pkg = JSON.parse(readFileSync(path, 'utf8')) as { version?: string };\n if (pkg.version) {\n cached = pkg.version;\n break;\n }\n }\n } catch {\n cached = null;\n }\n return cached;\n}\n","/** SDK version reported to the DevTools server. Keep in sync with package.json. */\nexport const SDK_VERSION = '0.1.0';\n"],"mappings":"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","names":["import_devtools_core","import_devtools_core","coreDevtools","import_devtools_protocol","import_devtools_core","import_devtools_protocol","import_devtools_core","import_devtools_core","import_path","coreDevtools","import_devtools_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/sdk.ts","../src/instrumentation/http.ts","../src/emitter.ts","../src/instrumentation/timeline.ts","../src/instrumentation/console.ts","../src/instrumentation/nest-logger.ts","../src/instrumentation/exceptions.ts","../src/instrumentation/performance.ts","../src/instrumentation/app-explorer.ts","../src/instrumentation/websockets.ts","../src/instrumentation/database.ts","../src/detect.ts","../src/version.ts","../src/banner.ts"],"sourcesContent":["/**\n * @angelitosystems/nest-devtools\n *\n * Drop-in real-time debugging and observability for NestJS.\n *\n * Usage:\n * import { NestDevTools } from '@angelitosystems/nest-devtools';\n * const app = await NestFactory.create(AppModule);\n * NestDevTools.init(app);\n */\nexport { NestDevTools, devtools } from './sdk';\nexport type { InitResult } from './sdk';\nexport { captureError } from './instrumentation/exceptions';\nexport type { DevToolsUserConfig } from '@angelitosystems/devtools-core';\nexport { requestContext } from '@angelitosystems/devtools-core';\nexport type { RequestContext } from '@angelitosystems/devtools-core';\n","import { hostname } from 'os';\nimport { devtools as coreDevtools, resolveConfig } from '@angelitosystems/devtools-core';\nimport type { DevToolsUserConfig } from '@angelitosystems/devtools-core';\nimport type { ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { HttpInstrumentation } from './instrumentation/http';\nimport { ConsoleInstrumentation } from './instrumentation/console';\nimport { LoggerInstrumentation } from './instrumentation/nest-logger';\nimport { ExceptionsInstrumentation, captureError } from './instrumentation/exceptions';\nimport { PerformanceInstrumentation } from './instrumentation/performance';\nimport { AppExplorer } from './instrumentation/app-explorer';\nimport { WebsocketInstrumentation } from './instrumentation/websockets';\nimport { DatabaseInstrumentation } from './instrumentation/database';\nimport { detectNestJsVersion } from './detect';\nimport { SDK_VERSION } from './version';\nimport { printStartupBanner, printConnectionStatus } from './banner';\n\n/** Result of calling NestDevTools.init(). */\nexport interface InitResult {\n /** True when instrumentation is live. */\n enabled: boolean;\n /** Reason when partially or fully disabled. */\n reason?: 'disabled-by-config' | 'already-initialized' | 'no-http-adapter';\n projectId: string;\n projectName: string;\n server: string;\n}\n\n/**\n * Main entry point: `NestDevTools.init(app, config?)`.\n *\n * Never throws, never blocks startup, and disables itself in production\n * unless explicitly enabled.\n */\nexport class NestDevTools {\n private static readonly cleanups: Array<() => void> = [];\n private static initialized = false;\n\n /** Initialize DevTools for a NestJS application. One active instance per process. */\n static init(app: INestApplication, userConfig?: DevToolsUserConfig): InitResult {\n const config = resolveConfig(userConfig);\n const disabled: InitResult = {\n enabled: false,\n reason: 'disabled-by-config',\n projectId: config.projectId,\n projectName: config.project ?? config.projectId,\n server: config.server,\n };\n\n if (this.initialized) return { ...disabled, reason: 'already-initialized' };\n if (!config.enabled) return disabled; // zero side effects: no patching, no sockets, no timers\n\n this.initialized = true;\n const registerCleanup = (fn: () => void) => this.cleanups.push(fn);\n\n const projectInfo: ProjectInfo = {\n projectId: config.projectId,\n projectName: config.project ?? config.projectId,\n environment: config.environment,\n hostname: safeHostname(),\n port: null,\n pid: process.pid,\n runtime: detectRuntime(),\n runtimeVersion: detectRuntimeVersion(),\n nodeVersion: process.version,\n nestjsVersion: detectNestJsVersion(),\n sdkVersion: SDK_VERSION,\n };\n\n // transport is fully async: a missing server never affects startup\n let hasWarnedOffline = false;\n coreDevtools.initialize({\n config,\n projectInfo,\n registerCleanup,\n onStateChange: (state) => {\n if (state === 'open') {\n printConnectionStatus('open', dashboardUrl(config.server));\n } else if (state === 'retrying' && !hasWarnedOffline) {\n hasWarnedOffline = true;\n printConnectionStatus('offline', dashboardUrl(config.server));\n }\n },\n });\n\n const adapter = app.getHttpAdapter();\n const httpReady = Boolean(adapter && ['http', 'express'].includes(adapter.getType()));\n\n // ---- HTTP instrumentation -------------------------------------------\n const http = new HttpInstrumentation({ config, projectInfo });\n registerCleanup(http.attach(app));\n\n // ---- console + NestJS Logger + global errors ------------------------\n registerCleanup(new ConsoleInstrumentation({ config, projectInfo }).attach());\n registerCleanup(new LoggerInstrumentation({ config, projectInfo }).attach());\n registerCleanup(ExceptionsInstrumentation.attach({ config, projectInfo }));\n\n // ---- performance sampling -------------------------------------------\n registerCleanup(new PerformanceInstrumentation({ config, projectInfo }).attach());\n\n // ---- application graph ----------------------------------------------\n registerCleanup(new AppExplorer({ config, projectInfo }).attach(app));\n\n // ---- websockets + database (best effort) ----------------------------\n if (config.capture.websockets) {\n registerCleanup(new WebsocketInstrumentation({ config, projectInfo }).attach());\n }\n if (config.capture.database) {\n registerCleanup(new DatabaseInstrumentation({ config, projectInfo }).attach());\n }\n\n printStartupBanner({\n endpoint: config.server,\n dashboard: dashboardUrl(config.server),\n project: projectInfo.projectName,\n });\n\n return {\n enabled: true,\n projectId: config.projectId,\n projectName: projectInfo.projectName,\n server: config.server,\n ...(httpReady ? {} : { reason: 'no-http-adapter' as const }),\n };\n }\n\n /** Teardown everything (mostly useful in tests). */\n static destroy(): void {\n for (const cleanup of this.cleanups.splice(0)) {\n try {\n cleanup();\n } catch {\n /* ignore */\n }\n }\n this.initialized = false;\n coreDevtools.shutdown();\n }\n\n /** Whether the SDK is currently active in this process. */\n static isActive(): boolean {\n return this.initialized;\n }\n}\n\n/** Convenience functional alias: devtools.init(app). */\nexport const devtools = {\n init: NestDevTools.init.bind(NestDevTools),\n destroy: NestDevTools.destroy.bind(NestDevTools),\n isActive: NestDevTools.isActive.bind(NestDevTools),\n};\n\nfunction safeHostname(): string {\n try {\n return hostname();\n } catch {\n return 'unknown';\n }\n}\n\nfunction detectRuntime(): string {\n const versions = process.versions as Record<string, string | undefined>;\n if (versions['bun']) return 'bun';\n if (versions['deno']) return 'deno';\n return 'node';\n}\n\nfunction detectRuntimeVersion(): string {\n const versions = process.versions as Record<string, string | undefined>;\n return versions['bun'] ?? versions['deno'] ?? process.version;\n}\n\nfunction dashboardUrl(server: string): string {\n try {\n const url = new URL(server);\n url.protocol = url.protocol === 'wss:' ? 'https:' : 'http:';\n const port = Number(url.port);\n url.port = String(Number.isFinite(port) && port > 0 ? port - 1 : 4317);\n url.pathname = '';\n url.search = '';\n url.hash = '';\n return url.toString().replace(/\\/$/, '');\n } catch {\n return 'http://localhost:4317';\n }\n}\n\nexport { captureError };","import type { IncomingMessage, ServerResponse, Server as HttpServer } from 'http';\nimport { Redactor, randomId } from '@angelitosystems/devtools-protocol';\nimport type {\n ProjectInfo,\n RequestCompletedPayload,\n RequestStartedPayload,\n TimelineSpan,\n} from '@angelitosystems/devtools-protocol';\nimport { requestContext } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { emit } from '../emitter';\nimport { trackSpans } from './timeline';\n\n/** Shared context every instrumentation module receives. */\nexport interface InstrumentationContext {\n config: DevToolsConfig;\n projectInfo: ProjectInfo;\n}\n\n/** Headers captured by default (denylist still applies). */\nconst INTERESTING_HEADERS = [\n 'content-type',\n 'content-length',\n 'accept',\n 'origin',\n 'referer',\n 'user-agent',\n 'x-forwarded-for',\n 'x-request-id',\n] as const;\n\ntype RequestListener = (req: IncomingMessage, res: ServerResponse) => void;\n\nconst WRAPPED = Symbol('nest-devtools.wrapped');\n\n/**\n * Instrument the HTTP server of a NestJS application.\n *\n * Covers both bootstrap orders without touching Node module internals:\n * - `NestDevTools.init(app)` after `app.listen()`: the server already exists\n * and is wrapped immediately.\n * - `NestDevTools.init(app)` before `app.listen()` (recommended): `app.listen`\n * is wrapped so the server is wrapped the moment it exists.\n */\nexport class HttpInstrumentation {\n private readonly redactor: Redactor;\n\n constructor(private readonly ctx: InstrumentationContext) {\n this.redactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n }\n\n /** Begin capturing HTTP requests. Returns a cleanup function. */\n attach(app: INestApplication): () => void {\n try {\n const adapter = app.getHttpAdapter();\n // 'http' = platform-default adapter, 'express' = @nestjs/platform-express\n if (!adapter || !['http', 'express'].includes(adapter.getType())) return () => {};\n\n const getServer = (): HttpServer | undefined =>\n (adapter as unknown as { getHttpServer?: () => HttpServer }).getHttpServer?.();\n\n // 1) server already exists (init called after listen)\n const existing = getServer();\n if (existing) {\n this.wrapServer(existing);\n return () => {};\n }\n\n // 2) init called before listen: wrap the server once listen() resolves\n const appLike = app as unknown as { listen: (...args: unknown[]) => unknown };\n const originalListen = appLike.listen.bind(app);\n const self = this;\n const patchedListen = (...args: unknown[]) => {\n const result = originalListen(...args);\n Promise.resolve(result)\n .then(() => {\n const server = getServer();\n if (server) self.wrapServer(server);\n })\n .catch(() => {\n /* listen failed — the app will surface its own error */\n });\n return result;\n };\n appLike.listen = patchedListen;\n\n return () => {\n appLike.listen = originalListen;\n };\n } catch {\n return () => {};\n }\n }\n\n /** Wrap the 'request' listeners of a server exactly once. */\n private wrapServer(server: HttpServer): void {\n const target = server as unknown as Record<symbol, unknown>;\n if (target[WRAPPED]) return;\n target[WRAPPED] = true;\n\n const self = this;\n const originalListeners = server.rawListeners('request') as RequestListener[];\n\n server.removeAllListeners('request');\n server.on('request', (req, res) => {\n self.instrumentRequest(req, res, () => {\n for (const listener of originalListeners) {\n listener.call(server, req, res);\n }\n });\n });\n }\n\n /** Wrap a single request lifecycle. */\n private instrumentRequest(req: IncomingMessage, res: ServerResponse, next: () => void): void {\n if (!this.ctx.config.capture.requests) {\n next();\n return;\n }\n\n const startedAt = Date.now();\n const requestId = randomId('req');\n const method = (req.method ?? 'GET').toUpperCase();\n const rawUrl = req.url ?? '/';\n const url = safeUrlPath(rawUrl);\n\n const spans: TimelineSpan[] = [];\n const unregister = trackSpans(requestId, spans);\n res.once('finish', unregister);\n\n const started: RequestStartedPayload = {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n method,\n url,\n headers: this.collectHeaders(req),\n query: parseQuery(rawUrl),\n ip: clientIp(req),\n userAgent: asString(req.headers['user-agent']) || undefined,\n startedAt,\n };\n\n const middlewareSpan: TimelineSpan = {\n layer: 'middleware',\n label: `${method} ${url}`,\n duration: 0,\n startedAt,\n status: 'ok',\n };\n spans.push(middlewareSpan);\n\n const onFinished = () => {\n const finishedAt = Date.now();\n middlewareSpan.duration = Math.max(0, finishedAt - middlewareSpan.startedAt);\n middlewareSpan.status = res.statusCode >= 500 ? 'error' : 'ok';\n\n const responseSpan: TimelineSpan = {\n layer: 'response',\n label: 'response',\n duration: 0,\n startedAt: finishedAt,\n status: 'ok',\n };\n spans.push(responseSpan);\n\n const errored = res.statusCode >= 500;\n\n const completed: RequestCompletedPayload = {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n method,\n url,\n statusCode: res.statusCode,\n duration: finishedAt - startedAt,\n startedAt,\n timeline: spans,\n query: parseQuery(rawUrl),\n errored,\n };\n\n emit('request.completed', completed);\n\n // NestJS exception filters turn controller errors into 5xx responses\n // without any process-level signal — surface them in the Error Explorer.\n if (errored) {\n emit('error.created', {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n name: 'HttpError',\n message: `${method} ${url} failed with status ${res.statusCode}`,\n fingerprint: httpErrorFingerprint(method, url, res.statusCode),\n request: { method, url, statusCode: res.statusCode },\n timestamp: finishedAt,\n });\n }\n };\n\n const context = requestContext();\n context.run({ requestId, method, url, startedAt }, () => {\n emit('request.started', started);\n res.once('finish', onFinished);\n next();\n });\n }\n\n private collectHeaders(req: IncomingMessage): Record<string, string> {\n const out: Record<string, string> = {};\n for (const key of INTERESTING_HEADERS) {\n const value = req.headers[key];\n if (value === undefined) continue;\n out[key] = this.redactor.isSensitive(key) ? '[REDACTED]' : asString(value).slice(0, 200);\n }\n return out;\n }\n}\n\nfunction asString(value: string | string[] | undefined): string {\n if (Array.isArray(value)) return value.join(', ');\n return value ?? '';\n}\n\n/** Stable fingerprint for framework-handled HTTP failures. */\nfunction httpErrorFingerprint(method: string, url: string, statusCode: number): string {\n const route = url.replace(/\\/\\d+(?=\\/|$)/g, '/:id'); // group /users/15 with /users/16\n const raw = `${method}::${route}::${statusCode}`;\n let hash = 0;\n for (let i = 0; i < raw.length; i++) {\n hash = (hash * 31 + raw.charCodeAt(i)) >>> 0;\n }\n return hash.toString(36).padStart(7, '0');\n}\n\nfunction safeUrlPath(raw: string): string {\n const index = raw.indexOf('?');\n return index === -1 ? raw : raw.slice(0, index);\n}\n\nfunction parseQuery(raw: string): Record<string, unknown> {\n const index = raw.indexOf('?');\n if (index === -1) return {};\n const out: Record<string, unknown> = {};\n for (const [key, value] of new URLSearchParams(raw.slice(index + 1))) {\n out[key] = value;\n }\n return out;\n}\n\nfunction clientIp(req: IncomingMessage): string | undefined {\n const forwarded = req.headers['x-forwarded-for'];\n if (typeof forwarded === 'string') return forwarded.split(',')[0]?.trim();\n return req.socket?.remoteAddress ?? undefined;\n}\n\nexport { safeUrlPath, parseQuery, clientIp };\n","import { devtools as coreDevtools } from '@angelitosystems/devtools-core';\nimport type { DevToolsEventMap, DevToolsEventName } from '@angelitosystems/devtools-protocol';\n\n/** Emit a typed protocol event to the DevTools server (fire-and-forget). */\nexport function emit<K extends DevToolsEventName>(event: K, payload: DevToolsEventMap[K]): void {\n try {\n coreDevtools.send(event, payload);\n } catch {\n /* instrumentation must never break the app */\n }\n}\n","import type { TimelineSpan } from '@angelitosystems/devtools-protocol';\n\n/** Create a started span inside a request's span list. */\nexport function startSpan(spans: TimelineSpan[], layer: string, label: string, detail?: string): TimelineSpan {\n const span: TimelineSpan = {\n layer,\n label,\n duration: 0,\n startedAt: Date.now(),\n status: 'ok',\n ...(detail !== undefined ? { detail } : {}),\n };\n spans.push(span);\n return span;\n}\n\n/** Finalize a span, computing its duration. */\nexport function endSpan(span: TimelineSpan, status?: 'ok' | 'error'): void {\n span.duration = Math.max(0, Date.now() - span.startedAt);\n if (status) span.status = status;\n}\n\n/**\n * Registry of active request timelines, keyed by requestId.\n * Lets deeper instrumentation (database, websockets) attach spans to the\n * request that caused them, using the AsyncLocalStorage request id.\n */\nconst recorders = new Map<string, TimelineSpan[]>();\n\n/** Register a request's span list. Returns an unregister callback. */\nexport function trackSpans(requestId: string, spans: TimelineSpan[]): () => void {\n recorders.set(requestId, spans);\n return () => recorders.delete(requestId);\n}\n\n/** Add an auto-ended span to a request if it is still active. */\nexport function recordSpan(requestId: string, layer: string, label: string, detail?: string, status?: 'ok' | 'error'): void {\n const spans = recorders.get(requestId);\n if (!spans) return;\n const span = startSpan(spans, layer, label, detail);\n endSpan(span, status);\n}\n","import { Console } from 'console';\nimport { Redactor } from '@angelitosystems/devtools-protocol';\nimport { resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { LogPayload, LogLevel, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport { requestContext } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\nconst METHODS = ['log', 'info', 'warn', 'error', 'debug'] as const;\ntype ConsoleMethod = (typeof METHODS)[number];\n\nconst LEVEL_BY_METHOD: Record<ConsoleMethod, LogLevel> = {\n log: 'info',\n info: 'info',\n warn: 'warn',\n error: 'error',\n debug: 'debug',\n};\n\n/** Original console bound directly to the process streams. */\nconst originalConsole = new Console({\n stdout: process.stdout,\n stderr: process.stderr,\n colorMode: 'auto',\n});\n\n/** Write through the untouched console (used by DevTools' own logging). */\nexport function writeOriginalConsole(method: ConsoleMethod, ...args: unknown[]): void {\n const fn = (originalConsole as unknown as Record<string, (...a: unknown[]) => void>)[method];\n if (fn) fn.apply(originalConsole, args);\n}\n\n/** Capture console output and mirror it to DevTools. */\nexport class ConsoleInstrumentation {\n private readonly redactor: Redactor;\n\n constructor(private readonly ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {\n this.redactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n }\n\n /** Patch console methods. Returns a restore function. */\n attach(): () => void {\n const self = this;\n const restores: Array<() => void> = [];\n\n for (const method of METHODS) {\n const original = (console as unknown as Record<string, unknown>)[method];\n if (typeof original !== 'function') continue;\n\n const patched = (...args: unknown[]) => {\n try {\n (original as (...a: unknown[]) => void).apply(console, args);\n } catch {\n /* never break host logging */\n }\n self.capture(method, args);\n };\n\n (console as unknown as Record<string, unknown>)[method] = patched;\n restores.push(() => {\n (console as unknown as Record<string, unknown>)[method] = original;\n });\n }\n\n return () => {\n for (const restore of restores.splice(0)) restore();\n };\n }\n\n private capture(method: ConsoleMethod, args: unknown[]): void {\n if (!this.ctx.config.capture.logs) return;\n try {\n const level = LEVEL_BY_METHOD[method];\n const payload: LogPayload = {\n projectId: this.ctx.projectInfo.projectId,\n level,\n message: formatMessage(args, this.redactor),\n arguments: args.length > 0 ? (this.redactor.redact(args) as unknown[]) : undefined,\n stack: method === 'error' ? captureStack() : undefined,\n source: resolveSourceLocation(captureStack() ?? '', { skip: 0 }),\n context: undefined,\n processId: process.pid,\n requestId: requestContext().requestId(),\n timestamp: Date.now(),\n };\n if (method === 'error') payload.level = 'error';\n emit('log.created', payload);\n } catch {\n /* never propagate */\n }\n }\n}\n\nfunction formatMessage(args: unknown[], redactor: Redactor): string {\n if (args.length === 0) return '';\n const first = args[0];\n if (typeof first === 'string') {\n return args.length === 1 ? redactor.redactString(first) : `${first} ${redactor.serialize(args.slice(1))}`;\n }\n return redactor.serialize(args);\n}\n\nfunction captureStack(): string | undefined {\n const err = new Error();\n const stack = err.stack;\n if (!stack) return undefined;\n // drop the frames created by this helper\n return stack.split('\\n').slice(3).join('\\n');\n}\n","import { Logger } from '@nestjs/common';\nimport { Redactor } from '@angelitosystems/devtools-protocol';\nimport type { LogPayload, LogLevel, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport { requestContext, resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\n/**\n * Captures NestJS framework logs (`new Logger('Ctx').log(...)` and the static\n * `Logger.log(...)` variants). Nest's Logger writes through process.stdout\n * internals, not console.*, so it needs its own hook.\n *\n * State is module-scoped on purpose: the patched methods are plain functions\n * and must never depend on class-instance `this` binding.\n */\nlet activeRedactor = new Redactor();\nlet activeConfig: DevToolsConfig | null = null;\nlet activeProjectId = '';\n\nfunction capture(level: LogLevel, message: unknown, context?: string, stack?: string): void {\n try {\n if (!activeConfig?.capture.logs) return;\n const text = typeof message === 'string' ? message : activeRedactor.serialize(message);\n const payload: LogPayload = {\n projectId: activeProjectId,\n level,\n message: activeRedactor.redactString(text),\n source: stack ? undefined : resolveSdkAwareLocation(),\n context,\n stack,\n processId: process.pid,\n requestId: requestContext().requestId(),\n timestamp: Date.now(),\n };\n emit('log.created', payload);\n } catch {\n /* never propagate */\n }\n}\n\n/** Captures NestJS Logger output and mirrors it to DevTools. */\nexport class LoggerInstrumentation {\n constructor(ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {\n activeRedactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n activeConfig = ctx.config;\n activeProjectId = ctx.projectInfo.projectId;\n }\n\n /** Patch Logger.prototype and the static Logger methods. Returns a restore function. */\n attach(): () => void {\n const restores: Array<() => void> = [];\n\n const patch = (owner: Record<string, unknown>, method: string, level: LogLevel, instance: boolean) => {\n const original = owner[method];\n if (typeof original !== 'function') return;\n\n owner[method] = function (this: unknown, message: unknown, ...rest: unknown[]) {\n const context = instance\n ? ((this as { context?: string } | undefined)?.context ?? (rest[0] as string | undefined))\n : (rest[0] as string | undefined);\n const stack = rest[1] as string | undefined;\n try {\n const result = (original as (...a: unknown[]) => unknown).apply(this, [message, ...rest]);\n capture(level, message, context, stack);\n return result;\n } catch (err) {\n capture(level, message, context, stack);\n throw err;\n }\n };\n\n restores.push(() => {\n owner[method] = original;\n });\n };\n\n // instance loggers: `new Logger('Ctx').log(...)` — the common case\n const proto = Logger.prototype as unknown as Record<string, unknown>;\n patch(proto, 'log', 'info', true);\n patch(proto, 'error', 'error', true);\n patch(proto, 'warn', 'warn', true);\n patch(proto, 'debug', 'debug', true);\n patch(proto, 'verbose', 'verbose', true);\n\n // static loggers: `Logger.log(...)`\n const statics = Logger as unknown as Record<string, unknown>;\n patch(statics, 'log', 'info', false);\n patch(statics, 'error', 'error', false);\n patch(statics, 'warn', 'warn', false);\n patch(statics, 'debug', 'debug', false);\n patch(statics, 'verbose', 'verbose', false);\n\n return () => {\n for (const restore of restores.splice(0)) restore();\n };\n }\n}\n\nfunction resolveSdkAwareLocation(): LogPayload['source'] {\n try {\n const err = new Error();\n const stack = err.stack?.split('\\n').slice(3).join('\\n');\n return resolveSourceLocation(stack ?? '', { skip: 0 });\n } catch {\n return undefined;\n }\n}\n","import { basename } from 'path';\nimport type { ErrorPayload, ProjectInfo, SourceLocation } from '@angelitosystems/devtools-protocol';\nimport { requestContext, safeStringify, resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\ntype InstrumentationCtx = {\n config: DevToolsConfig;\n projectInfo: ProjectInfo;\n};\n\n/**\n * Global error capture via process-level hooks. Errors handled by NestJS\n * filters surface through request.completed; unexpected errors land here.\n */\nexport class ExceptionsInstrumentation {\n /** Attach process-level hooks. Returns a detach function. */\n static attach(ctx: InstrumentationCtx): () => void {\n const onUncaught = (error: unknown): void => {\n reportError(error, ctx, { source: 'uncaughtException' });\n };\n const onRejection = (reason: unknown): void => {\n reportError(reason, ctx, { source: 'unhandledRejection' });\n };\n\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onRejection);\n\n return () => {\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onRejection);\n };\n }\n}\n\n/** Public helper: report an error manually from anywhere in the app. */\nexport function captureError(\n error: unknown,\n options?: { context?: string; controller?: string; service?: string },\n): void {\n reportError(error, undefined, options);\n}\n\nfunction reportError(\n error: unknown,\n ctx: InstrumentationCtx | undefined,\n options?: { context?: string; controller?: string; service?: string; source?: string },\n): void {\n try {\n if (ctx && !ctx.config.capture.errors) return;\n\n const normalized = normalizeError(error);\n const location = resolveSourceLocation(normalized.error ?? normalized.message, { skip: 1 });\n const projectId = ctx?.projectInfo.projectId ?? basename(process.cwd());\n\n const payload: ErrorPayload = {\n requestId: requestContext().requestId(),\n projectId,\n name: normalized.name,\n message: normalized.message,\n stack: normalized.error?.stack,\n source: location,\n fingerprint: fingerprint(normalized.name, normalized.message, location),\n context: options?.context ?? options?.source,\n request: currentRequestSummary(),\n controller: options?.controller,\n service: options?.service,\n timestamp: Date.now(),\n };\n\n emit('error.created', payload);\n } catch {\n /* never propagate */\n }\n}\n\nfunction normalizeError(error: unknown): { error: Error | undefined; name: string; message: string } {\n if (error instanceof Error) {\n return { error, name: error.name, message: error.message };\n }\n if (typeof error === 'string') {\n return { error: undefined, name: 'Unknown', message: error };\n }\n if (error !== null && typeof error === 'object' && 'message' in error) {\n const record = error as Record<string, unknown>;\n return {\n error: undefined,\n name: typeof record['name'] === 'string' ? record['name'] : 'Error',\n message: String(record['message']),\n };\n }\n return { error: undefined, name: 'Unknown', message: safeStringify(error) };\n}\n\nfunction fingerprint(name: string, message: string, location?: SourceLocation): string {\n const raw = name + '::' + message + '::' + (location?.file ?? '') + ':' + String(location?.line ?? '');\n let hash = 0;\n for (let i = 0; i < raw.length; i++) {\n hash = (hash * 31 + raw.charCodeAt(i)) >>> 0;\n }\n return hash.toString(36).padStart(7, '0');\n}\n\nfunction currentRequestSummary(): { method: string; url: string } | undefined {\n const context = requestContext().current();\n if (!context?.method || !context?.url) return undefined;\n return { method: context.method, url: context.url };\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * Performance instrumentation.\n *\n * Periodic CPU/memory/event-loop/latency sampling lives in core\n * (CoreDevtools.startPerformance) so it works even without an HTTP adapter.\n * This module exists as the capture-toggle boundary and future extension\n * point (gc hooks, histograms, cluster awareness).\n */\nexport class PerformanceInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op: sampling is owned by core. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import type { AppModuleNode, AppMemberNode, AppSnapshot, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { emit } from '../emitter';\n\ninterface ContainerNode {\n id: string;\n name?: string;\n metatype?: Function;\n instance?: object;\n subtype?: 'httpController' | 'gateway';\n}\n\n/**\n * Explore the Nest container to build the module graph (modules, controllers,\n * providers, guards, pipes...). Best effort: any failure keeps the app safe.\n */\nexport class AppExplorer {\n constructor(private readonly ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {}\n\n /** Walk the container and emit app.snapshot. Returns a no-op cleanup. */\n attach(app: INestApplication): () => void {\n try {\n const snapshot = this.buildSnapshot(app);\n emit('app.snapshot', snapshot);\n } catch {\n /* best effort */\n }\n return () => {};\n }\n\n private buildSnapshot(app: INestApplication): AppSnapshot {\n const internal = (app as unknown as { container?: unknown }).container as\n | { getModules?: () => Map<string, ContainerNode> }\n | undefined;\n\n const modules: AppModuleNode[] = [];\n const modulesMap = internal?.getModules?.();\n if (modulesMap) {\n for (const [id, node] of modulesMap) {\n const moduleName = node.metatype?.name ?? String(id);\n const members = this.extractMembers(node);\n modules.push({\n name: moduleName,\n imports: [],\n controllers: members.controllers,\n providers: members.providers,\n exports: [],\n });\n }\n }\n\n return {\n projectId: this.ctx.projectInfo.projectId,\n projectName: this.ctx.projectInfo.projectName,\n modules,\n nestjsVersion: this.ctx.projectInfo.nestjsVersion,\n capturedAt: Date.now(),\n };\n }\n\n private extractMembers(node: ContainerNode): { controllers: AppMemberNode[]; providers: AppMemberNode[] } {\n const controllers: AppMemberNode[] = [];\n const providers: AppMemberNode[] = [];\n\n const providersMap = (node as unknown as { providers?: Map<string, unknown> }).providers;\n if (providersMap instanceof Map) {\n for (const [id, wrapper] of providersMap) {\n const member = this.memberFromWrapper(id, wrapper);\n if (!member) continue;\n if (wrapper && (wrapper as { subtype?: string }).subtype === 'httpController') {\n controllers.push(member);\n } else {\n providers.push(member);\n }\n }\n }\n\n return { controllers, providers };\n }\n\n private memberFromWrapper(id: string, wrapper: unknown): AppMemberNode | null {\n const w = wrapper as { name?: string; metatype?: Function; subtype?: string; instance?: Record<string, unknown> } | null;\n const name = w?.metatype?.name ?? (typeof id === 'string' ? id.replace(/^[A-Z_0-9]+:/, '') : 'unknown');\n const type = classify(name, w?.instance);\n return { name, type };\n }\n}\n\n/** Heuristic classification of providers into guards/interceptors/pipes/filters. */\nfunction classify(name: string, instance?: Record<string, unknown>): AppMemberNode['type'] {\n if (name.endsWith('Gateway')) return 'gateway';\n if (name.endsWith('Guard')) return 'guard';\n if (name.endsWith('Interceptor')) return 'interceptor';\n if (name.endsWith('Pipe')) return 'pipe';\n if (name.endsWith('Filter')) return 'filter';\n if (instance && typeof instance.canActivate === 'function') return 'guard';\n if (instance && typeof instance.intercept === 'function') return 'interceptor';\n if (instance && typeof instance.transform === 'function') return 'pipe';\n if (instance && typeof instance.catch === 'function') return 'filter';\n return 'provider';\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * WebSocket gateway instrumentation (v0.3 roadmap).\n *\n * Will introspect @WebSocketGateway() classes via the Nest container and wrap\n * gateway handlers. The placeholder keeps the init() wiring stable and\n * guarantees zero interference with host sockets.\n */\nexport class WebsocketInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op for now. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * Database instrumentation (v0.3 roadmap).\n *\n * Provider strategies will live here:\n * - Prisma: $extends / $use hooks\n * - TypeORM: DataSource QueryListener via subscriber\n * - Sequelize: sequelize.addHook\n * - MikroORM: EntityManager event subscriber\n *\n * All strategies must attach spans to the active request via trackSpans/\n * recordSpan and emit query.executed with redacted parameters.\n */\nexport class DatabaseInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op for now. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'path';\n\nlet cached: string | null | undefined;\n\n/** Best-effort detection of the host app's @nestjs/core version. */\nexport function detectNestJsVersion(): string | null {\n if (cached !== undefined) return cached;\n cached = null;\n try {\n const candidates = [\n resolve(process.cwd(), 'node_modules/@nestjs/core/package.json'),\n // bun/pnpm layouts: walk up a couple of levels\n resolve(process.cwd(), '../../node_modules/@nestjs/core/package.json'),\n ];\n for (const path of candidates) {\n if (!existsSync(path)) continue;\n const pkg = JSON.parse(readFileSync(path, 'utf8')) as { version?: string };\n if (pkg.version) {\n cached = pkg.version;\n break;\n }\n }\n } catch {\n cached = null;\n }\n return cached;\n}\n","/** SDK version reported to the DevTools server. Keep in sync with package.json. */\nexport const SDK_VERSION = '0.1.0';\n","import { writeOriginalConsole } from './instrumentation/console';\n\n/** ANSI escape helpers (kept tiny and dependency-free, mirrors the CLI renderer). */\nconst RESET = '\\x1b[0m';\nconst DIM = '\\x1b[2m';\nconst BOLD = '\\x1b[1m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst CYAN = '\\x1b[36m';\nconst GRAY = '\\x1b[90m';\n\nconst WIDTH = 47;\n\nfunction colorEnabled(): boolean {\n // Respect NO_COLOR / non-TTY output the same way most CLIs do.\n if (process.env['NO_COLOR']) return false;\n return Boolean(process.stdout?.isTTY);\n}\n\nfunction paint(color: string, text: string): string {\n return colorEnabled() ? `${color}${text}${RESET}` : text;\n}\n\nfunction pad(label: string, value: string): string {\n const line = ` ${paint(GRAY, label.padEnd(9))} ${paint(CYAN, value)}`;\n return line;\n}\n\n/** Prints the boxed \"SDK started\" banner once, right after init(). */\nexport function printStartupBanner(info: { endpoint: string; dashboard: string; project: string }): void {\n const top = `${paint(GRAY, '┌' + '─'.repeat(WIDTH) + '┐')}`;\n const bottom = `${paint(GRAY, '└' + '─'.repeat(WIDTH) + '┘')}`;\n const title = ` ${paint(BOLD + CYAN, 'NestJS DevTools')} ${paint(GREEN, '●')} ${paint(DIM, `(${info.project})`)}`;\n\n writeOriginalConsole('log', '');\n writeOriginalConsole('log', top);\n writeOriginalConsole('log', title);\n writeOriginalConsole('log', pad('Endpoint', info.endpoint));\n writeOriginalConsole('log', pad('Dashboard', info.dashboard));\n writeOriginalConsole('log', `${paint(GRAY, ' Estado')} ${paint(YELLOW, '◌ conectando…')}`);\n writeOriginalConsole('log', bottom);\n}\n\n/** Prints a single status line once the transport's connection state is known. */\nexport function printConnectionStatus(state: 'open' | 'offline', dashboard: string): void {\n if (state === 'open') {\n writeOriginalConsole('log', ` ${paint(GREEN, '✓')} Conectado al dashboard ${paint(DIM, `(${dashboard})`)}`);\n return;\n }\n writeOriginalConsole('log', ` ${paint(YELLOW, '⚠')} No se pudo conectar al dashboard todavía.`);\n writeOriginalConsole('log', ` ${paint(DIM, 'Levántalo en otra terminal con:')} ${paint(BOLD, 'npx nest-devtools start')}`);\n writeOriginalConsole('log', ` ${paint(DIM, 'Reintentando en segundo plano — se conectará solo cuando el dashboard esté arriba.')}`);\n}"],"mappings":"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","names":["import_devtools_core","import_devtools_core","coreDevtools","import_devtools_protocol","import_devtools_core","import_devtools_protocol","import_devtools_core","import_devtools_core","import_path","coreDevtools","import_devtools_core"]}
package/dist/index.js CHANGED
@@ -621,6 +621,48 @@ function detectNestJsVersion() {
621
621
  // src/version.ts
622
622
  var SDK_VERSION = "0.1.0";
623
623
 
624
+ // src/banner.ts
625
+ var RESET = "\x1B[0m";
626
+ var DIM = "\x1B[2m";
627
+ var BOLD = "\x1B[1m";
628
+ var GREEN = "\x1B[32m";
629
+ var YELLOW = "\x1B[33m";
630
+ var CYAN = "\x1B[36m";
631
+ var GRAY = "\x1B[90m";
632
+ var WIDTH = 47;
633
+ function colorEnabled() {
634
+ if (process.env["NO_COLOR"]) return false;
635
+ return Boolean(process.stdout?.isTTY);
636
+ }
637
+ function paint(color, text) {
638
+ return colorEnabled() ? `${color}${text}${RESET}` : text;
639
+ }
640
+ function pad(label, value) {
641
+ const line = ` ${paint(GRAY, label.padEnd(9))} ${paint(CYAN, value)}`;
642
+ return line;
643
+ }
644
+ function printStartupBanner(info) {
645
+ const top = `${paint(GRAY, "\u250C" + "\u2500".repeat(WIDTH) + "\u2510")}`;
646
+ const bottom = `${paint(GRAY, "\u2514" + "\u2500".repeat(WIDTH) + "\u2518")}`;
647
+ const title = ` ${paint(BOLD + CYAN, "NestJS DevTools")} ${paint(GREEN, "\u25CF")} ${paint(DIM, `(${info.project})`)}`;
648
+ writeOriginalConsole("log", "");
649
+ writeOriginalConsole("log", top);
650
+ writeOriginalConsole("log", title);
651
+ writeOriginalConsole("log", pad("Endpoint", info.endpoint));
652
+ writeOriginalConsole("log", pad("Dashboard", info.dashboard));
653
+ writeOriginalConsole("log", `${paint(GRAY, " Estado")} ${paint(YELLOW, "\u25CC conectando\u2026")}`);
654
+ writeOriginalConsole("log", bottom);
655
+ }
656
+ function printConnectionStatus(state, dashboard) {
657
+ if (state === "open") {
658
+ writeOriginalConsole("log", ` ${paint(GREEN, "\u2713")} Conectado al dashboard ${paint(DIM, `(${dashboard})`)}`);
659
+ return;
660
+ }
661
+ writeOriginalConsole("log", ` ${paint(YELLOW, "\u26A0")} No se pudo conectar al dashboard todav\xEDa.`);
662
+ writeOriginalConsole("log", ` ${paint(DIM, "Lev\xE1ntalo en otra terminal con:")} ${paint(BOLD, "npx nest-devtools start")}`);
663
+ writeOriginalConsole("log", ` ${paint(DIM, "Reintentando en segundo plano \u2014 se conectar\xE1 solo cuando el dashboard est\xE9 arriba.")}`);
664
+ }
665
+
624
666
  // src/sdk.ts
625
667
  var NestDevTools = class {
626
668
  static cleanups = [];
@@ -652,7 +694,20 @@ var NestDevTools = class {
652
694
  nestjsVersion: detectNestJsVersion(),
653
695
  sdkVersion: SDK_VERSION
654
696
  };
655
- coreDevtools2.initialize({ config, projectInfo, registerCleanup });
697
+ let hasWarnedOffline = false;
698
+ coreDevtools2.initialize({
699
+ config,
700
+ projectInfo,
701
+ registerCleanup,
702
+ onStateChange: (state) => {
703
+ if (state === "open") {
704
+ printConnectionStatus("open", dashboardUrl(config.server));
705
+ } else if (state === "retrying" && !hasWarnedOffline) {
706
+ hasWarnedOffline = true;
707
+ printConnectionStatus("offline", dashboardUrl(config.server));
708
+ }
709
+ }
710
+ });
656
711
  const adapter = app.getHttpAdapter();
657
712
  const httpReady = Boolean(adapter && ["http", "express"].includes(adapter.getType()));
658
713
  const http = new HttpInstrumentation({ config, projectInfo });
@@ -668,9 +723,11 @@ var NestDevTools = class {
668
723
  if (config.capture.database) {
669
724
  registerCleanup(new DatabaseInstrumentation({ config, projectInfo }).attach());
670
725
  }
671
- writeOriginalConsole("log", "[NestJS DevTools] SDK started");
672
- writeOriginalConsole("log", ` SDK endpoint: ${config.server}`);
673
- writeOriginalConsole("log", ` Dashboard: ${dashboardUrl(config.server)}`);
726
+ printStartupBanner({
727
+ endpoint: config.server,
728
+ dashboard: dashboardUrl(config.server),
729
+ project: projectInfo.projectName
730
+ });
674
731
  return {
675
732
  enabled: true,
676
733
  projectId: config.projectId,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sdk.ts","../src/instrumentation/http.ts","../src/emitter.ts","../src/instrumentation/timeline.ts","../src/instrumentation/console.ts","../src/instrumentation/nest-logger.ts","../src/instrumentation/exceptions.ts","../src/instrumentation/performance.ts","../src/instrumentation/app-explorer.ts","../src/instrumentation/websockets.ts","../src/instrumentation/database.ts","../src/detect.ts","../src/version.ts","../src/index.ts"],"sourcesContent":["import { hostname } from 'os';\nimport { devtools as coreDevtools, resolveConfig } from '@angelitosystems/devtools-core';\nimport type { DevToolsUserConfig } from '@angelitosystems/devtools-core';\nimport type { ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { HttpInstrumentation } from './instrumentation/http';\nimport { ConsoleInstrumentation, writeOriginalConsole } from './instrumentation/console';\nimport { LoggerInstrumentation } from './instrumentation/nest-logger';\nimport { ExceptionsInstrumentation, captureError } from './instrumentation/exceptions';\nimport { PerformanceInstrumentation } from './instrumentation/performance';\nimport { AppExplorer } from './instrumentation/app-explorer';\nimport { WebsocketInstrumentation } from './instrumentation/websockets';\nimport { DatabaseInstrumentation } from './instrumentation/database';\nimport { detectNestJsVersion } from './detect';\nimport { SDK_VERSION } from './version';\n\n/** Result of calling NestDevTools.init(). */\nexport interface InitResult {\n /** True when instrumentation is live. */\n enabled: boolean;\n /** Reason when partially or fully disabled. */\n reason?: 'disabled-by-config' | 'already-initialized' | 'no-http-adapter';\n projectId: string;\n projectName: string;\n server: string;\n}\n\n/**\n * Main entry point: `NestDevTools.init(app, config?)`.\n *\n * Never throws, never blocks startup, and disables itself in production\n * unless explicitly enabled.\n */\nexport class NestDevTools {\n private static readonly cleanups: Array<() => void> = [];\n private static initialized = false;\n\n /** Initialize DevTools for a NestJS application. One active instance per process. */\n static init(app: INestApplication, userConfig?: DevToolsUserConfig): InitResult {\n const config = resolveConfig(userConfig);\n const disabled: InitResult = {\n enabled: false,\n reason: 'disabled-by-config',\n projectId: config.projectId,\n projectName: config.project ?? config.projectId,\n server: config.server,\n };\n\n if (this.initialized) return { ...disabled, reason: 'already-initialized' };\n if (!config.enabled) return disabled; // zero side effects: no patching, no sockets, no timers\n\n this.initialized = true;\n const registerCleanup = (fn: () => void) => this.cleanups.push(fn);\n\n const projectInfo: ProjectInfo = {\n projectId: config.projectId,\n projectName: config.project ?? config.projectId,\n environment: config.environment,\n hostname: safeHostname(),\n port: null,\n pid: process.pid,\n runtime: detectRuntime(),\n runtimeVersion: detectRuntimeVersion(),\n nodeVersion: process.version,\n nestjsVersion: detectNestJsVersion(),\n sdkVersion: SDK_VERSION,\n };\n\n // transport is fully async: a missing server never affects startup\n coreDevtools.initialize({ config, projectInfo, registerCleanup });\n\n const adapter = app.getHttpAdapter();\n const httpReady = Boolean(adapter && ['http', 'express'].includes(adapter.getType()));\n\n // ---- HTTP instrumentation -------------------------------------------\n const http = new HttpInstrumentation({ config, projectInfo });\n registerCleanup(http.attach(app));\n\n // ---- console + NestJS Logger + global errors ------------------------\n registerCleanup(new ConsoleInstrumentation({ config, projectInfo }).attach());\n registerCleanup(new LoggerInstrumentation({ config, projectInfo }).attach());\n registerCleanup(ExceptionsInstrumentation.attach({ config, projectInfo }));\n\n // ---- performance sampling -------------------------------------------\n registerCleanup(new PerformanceInstrumentation({ config, projectInfo }).attach());\n\n // ---- application graph ----------------------------------------------\n registerCleanup(new AppExplorer({ config, projectInfo }).attach(app));\n\n // ---- websockets + database (best effort) ----------------------------\n if (config.capture.websockets) {\n registerCleanup(new WebsocketInstrumentation({ config, projectInfo }).attach());\n }\n if (config.capture.database) {\n registerCleanup(new DatabaseInstrumentation({ config, projectInfo }).attach());\n }\n\n writeOriginalConsole('log', '[NestJS DevTools] SDK started');\n writeOriginalConsole('log', ` SDK endpoint: ${config.server}`);\n writeOriginalConsole('log', ` Dashboard: ${dashboardUrl(config.server)}`);\n\n return {\n enabled: true,\n projectId: config.projectId,\n projectName: projectInfo.projectName,\n server: config.server,\n ...(httpReady ? {} : { reason: 'no-http-adapter' as const }),\n };\n }\n\n /** Teardown everything (mostly useful in tests). */\n static destroy(): void {\n for (const cleanup of this.cleanups.splice(0)) {\n try {\n cleanup();\n } catch {\n /* ignore */\n }\n }\n this.initialized = false;\n coreDevtools.shutdown();\n }\n\n /** Whether the SDK is currently active in this process. */\n static isActive(): boolean {\n return this.initialized;\n }\n}\n\n/** Convenience functional alias: devtools.init(app). */\nexport const devtools = {\n init: NestDevTools.init.bind(NestDevTools),\n destroy: NestDevTools.destroy.bind(NestDevTools),\n isActive: NestDevTools.isActive.bind(NestDevTools),\n};\n\nfunction safeHostname(): string {\n try {\n return hostname();\n } catch {\n return 'unknown';\n }\n}\n\nfunction detectRuntime(): string {\n const versions = process.versions as Record<string, string | undefined>;\n if (versions['bun']) return 'bun';\n if (versions['deno']) return 'deno';\n return 'node';\n}\n\nfunction detectRuntimeVersion(): string {\n const versions = process.versions as Record<string, string | undefined>;\n return versions['bun'] ?? versions['deno'] ?? process.version;\n}\n\nfunction dashboardUrl(server: string): string {\n try {\n const url = new URL(server);\n url.protocol = url.protocol === 'wss:' ? 'https:' : 'http:';\n const port = Number(url.port);\n url.port = String(Number.isFinite(port) && port > 0 ? port - 1 : 4317);\n url.pathname = '';\n url.search = '';\n url.hash = '';\n return url.toString().replace(/\\/$/, '');\n } catch {\n return 'http://localhost:4317';\n }\n}\n\nexport { captureError };\n","import type { IncomingMessage, ServerResponse, Server as HttpServer } from 'http';\nimport { Redactor, randomId } from '@angelitosystems/devtools-protocol';\nimport type {\n ProjectInfo,\n RequestCompletedPayload,\n RequestStartedPayload,\n TimelineSpan,\n} from '@angelitosystems/devtools-protocol';\nimport { requestContext } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { emit } from '../emitter';\nimport { trackSpans } from './timeline';\n\n/** Shared context every instrumentation module receives. */\nexport interface InstrumentationContext {\n config: DevToolsConfig;\n projectInfo: ProjectInfo;\n}\n\n/** Headers captured by default (denylist still applies). */\nconst INTERESTING_HEADERS = [\n 'content-type',\n 'content-length',\n 'accept',\n 'origin',\n 'referer',\n 'user-agent',\n 'x-forwarded-for',\n 'x-request-id',\n] as const;\n\ntype RequestListener = (req: IncomingMessage, res: ServerResponse) => void;\n\nconst WRAPPED = Symbol('nest-devtools.wrapped');\n\n/**\n * Instrument the HTTP server of a NestJS application.\n *\n * Covers both bootstrap orders without touching Node module internals:\n * - `NestDevTools.init(app)` after `app.listen()`: the server already exists\n * and is wrapped immediately.\n * - `NestDevTools.init(app)` before `app.listen()` (recommended): `app.listen`\n * is wrapped so the server is wrapped the moment it exists.\n */\nexport class HttpInstrumentation {\n private readonly redactor: Redactor;\n\n constructor(private readonly ctx: InstrumentationContext) {\n this.redactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n }\n\n /** Begin capturing HTTP requests. Returns a cleanup function. */\n attach(app: INestApplication): () => void {\n try {\n const adapter = app.getHttpAdapter();\n // 'http' = platform-default adapter, 'express' = @nestjs/platform-express\n if (!adapter || !['http', 'express'].includes(adapter.getType())) return () => {};\n\n const getServer = (): HttpServer | undefined =>\n (adapter as unknown as { getHttpServer?: () => HttpServer }).getHttpServer?.();\n\n // 1) server already exists (init called after listen)\n const existing = getServer();\n if (existing) {\n this.wrapServer(existing);\n return () => {};\n }\n\n // 2) init called before listen: wrap the server once listen() resolves\n const appLike = app as unknown as { listen: (...args: unknown[]) => unknown };\n const originalListen = appLike.listen.bind(app);\n const self = this;\n const patchedListen = (...args: unknown[]) => {\n const result = originalListen(...args);\n Promise.resolve(result)\n .then(() => {\n const server = getServer();\n if (server) self.wrapServer(server);\n })\n .catch(() => {\n /* listen failed — the app will surface its own error */\n });\n return result;\n };\n appLike.listen = patchedListen;\n\n return () => {\n appLike.listen = originalListen;\n };\n } catch {\n return () => {};\n }\n }\n\n /** Wrap the 'request' listeners of a server exactly once. */\n private wrapServer(server: HttpServer): void {\n const target = server as unknown as Record<symbol, unknown>;\n if (target[WRAPPED]) return;\n target[WRAPPED] = true;\n\n const self = this;\n const originalListeners = server.rawListeners('request') as RequestListener[];\n\n server.removeAllListeners('request');\n server.on('request', (req, res) => {\n self.instrumentRequest(req, res, () => {\n for (const listener of originalListeners) {\n listener.call(server, req, res);\n }\n });\n });\n }\n\n /** Wrap a single request lifecycle. */\n private instrumentRequest(req: IncomingMessage, res: ServerResponse, next: () => void): void {\n if (!this.ctx.config.capture.requests) {\n next();\n return;\n }\n\n const startedAt = Date.now();\n const requestId = randomId('req');\n const method = (req.method ?? 'GET').toUpperCase();\n const rawUrl = req.url ?? '/';\n const url = safeUrlPath(rawUrl);\n\n const spans: TimelineSpan[] = [];\n const unregister = trackSpans(requestId, spans);\n res.once('finish', unregister);\n\n const started: RequestStartedPayload = {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n method,\n url,\n headers: this.collectHeaders(req),\n query: parseQuery(rawUrl),\n ip: clientIp(req),\n userAgent: asString(req.headers['user-agent']) || undefined,\n startedAt,\n };\n\n const middlewareSpan: TimelineSpan = {\n layer: 'middleware',\n label: `${method} ${url}`,\n duration: 0,\n startedAt,\n status: 'ok',\n };\n spans.push(middlewareSpan);\n\n const onFinished = () => {\n const finishedAt = Date.now();\n middlewareSpan.duration = Math.max(0, finishedAt - middlewareSpan.startedAt);\n middlewareSpan.status = res.statusCode >= 500 ? 'error' : 'ok';\n\n const responseSpan: TimelineSpan = {\n layer: 'response',\n label: 'response',\n duration: 0,\n startedAt: finishedAt,\n status: 'ok',\n };\n spans.push(responseSpan);\n\n const errored = res.statusCode >= 500;\n\n const completed: RequestCompletedPayload = {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n method,\n url,\n statusCode: res.statusCode,\n duration: finishedAt - startedAt,\n startedAt,\n timeline: spans,\n query: parseQuery(rawUrl),\n errored,\n };\n\n emit('request.completed', completed);\n\n // NestJS exception filters turn controller errors into 5xx responses\n // without any process-level signal — surface them in the Error Explorer.\n if (errored) {\n emit('error.created', {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n name: 'HttpError',\n message: `${method} ${url} failed with status ${res.statusCode}`,\n fingerprint: httpErrorFingerprint(method, url, res.statusCode),\n request: { method, url, statusCode: res.statusCode },\n timestamp: finishedAt,\n });\n }\n };\n\n const context = requestContext();\n context.run({ requestId, method, url, startedAt }, () => {\n emit('request.started', started);\n res.once('finish', onFinished);\n next();\n });\n }\n\n private collectHeaders(req: IncomingMessage): Record<string, string> {\n const out: Record<string, string> = {};\n for (const key of INTERESTING_HEADERS) {\n const value = req.headers[key];\n if (value === undefined) continue;\n out[key] = this.redactor.isSensitive(key) ? '[REDACTED]' : asString(value).slice(0, 200);\n }\n return out;\n }\n}\n\nfunction asString(value: string | string[] | undefined): string {\n if (Array.isArray(value)) return value.join(', ');\n return value ?? '';\n}\n\n/** Stable fingerprint for framework-handled HTTP failures. */\nfunction httpErrorFingerprint(method: string, url: string, statusCode: number): string {\n const route = url.replace(/\\/\\d+(?=\\/|$)/g, '/:id'); // group /users/15 with /users/16\n const raw = `${method}::${route}::${statusCode}`;\n let hash = 0;\n for (let i = 0; i < raw.length; i++) {\n hash = (hash * 31 + raw.charCodeAt(i)) >>> 0;\n }\n return hash.toString(36).padStart(7, '0');\n}\n\nfunction safeUrlPath(raw: string): string {\n const index = raw.indexOf('?');\n return index === -1 ? raw : raw.slice(0, index);\n}\n\nfunction parseQuery(raw: string): Record<string, unknown> {\n const index = raw.indexOf('?');\n if (index === -1) return {};\n const out: Record<string, unknown> = {};\n for (const [key, value] of new URLSearchParams(raw.slice(index + 1))) {\n out[key] = value;\n }\n return out;\n}\n\nfunction clientIp(req: IncomingMessage): string | undefined {\n const forwarded = req.headers['x-forwarded-for'];\n if (typeof forwarded === 'string') return forwarded.split(',')[0]?.trim();\n return req.socket?.remoteAddress ?? undefined;\n}\n\nexport { safeUrlPath, parseQuery, clientIp };\n","import { devtools as coreDevtools } from '@angelitosystems/devtools-core';\nimport type { DevToolsEventMap, DevToolsEventName } from '@angelitosystems/devtools-protocol';\n\n/** Emit a typed protocol event to the DevTools server (fire-and-forget). */\nexport function emit<K extends DevToolsEventName>(event: K, payload: DevToolsEventMap[K]): void {\n try {\n coreDevtools.send(event, payload);\n } catch {\n /* instrumentation must never break the app */\n }\n}\n","import type { TimelineSpan } from '@angelitosystems/devtools-protocol';\n\n/** Create a started span inside a request's span list. */\nexport function startSpan(spans: TimelineSpan[], layer: string, label: string, detail?: string): TimelineSpan {\n const span: TimelineSpan = {\n layer,\n label,\n duration: 0,\n startedAt: Date.now(),\n status: 'ok',\n ...(detail !== undefined ? { detail } : {}),\n };\n spans.push(span);\n return span;\n}\n\n/** Finalize a span, computing its duration. */\nexport function endSpan(span: TimelineSpan, status?: 'ok' | 'error'): void {\n span.duration = Math.max(0, Date.now() - span.startedAt);\n if (status) span.status = status;\n}\n\n/**\n * Registry of active request timelines, keyed by requestId.\n * Lets deeper instrumentation (database, websockets) attach spans to the\n * request that caused them, using the AsyncLocalStorage request id.\n */\nconst recorders = new Map<string, TimelineSpan[]>();\n\n/** Register a request's span list. Returns an unregister callback. */\nexport function trackSpans(requestId: string, spans: TimelineSpan[]): () => void {\n recorders.set(requestId, spans);\n return () => recorders.delete(requestId);\n}\n\n/** Add an auto-ended span to a request if it is still active. */\nexport function recordSpan(requestId: string, layer: string, label: string, detail?: string, status?: 'ok' | 'error'): void {\n const spans = recorders.get(requestId);\n if (!spans) return;\n const span = startSpan(spans, layer, label, detail);\n endSpan(span, status);\n}\n","import { Console } from 'console';\nimport { Redactor } from '@angelitosystems/devtools-protocol';\nimport { resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { LogPayload, LogLevel, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport { requestContext } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\nconst METHODS = ['log', 'info', 'warn', 'error', 'debug'] as const;\ntype ConsoleMethod = (typeof METHODS)[number];\n\nconst LEVEL_BY_METHOD: Record<ConsoleMethod, LogLevel> = {\n log: 'info',\n info: 'info',\n warn: 'warn',\n error: 'error',\n debug: 'debug',\n};\n\n/** Original console bound directly to the process streams. */\nconst originalConsole = new Console({\n stdout: process.stdout,\n stderr: process.stderr,\n colorMode: 'auto',\n});\n\n/** Write through the untouched console (used by DevTools' own logging). */\nexport function writeOriginalConsole(method: ConsoleMethod, ...args: unknown[]): void {\n const fn = (originalConsole as unknown as Record<string, (...a: unknown[]) => void>)[method];\n if (fn) fn.apply(originalConsole, args);\n}\n\n/** Capture console output and mirror it to DevTools. */\nexport class ConsoleInstrumentation {\n private readonly redactor: Redactor;\n\n constructor(private readonly ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {\n this.redactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n }\n\n /** Patch console methods. Returns a restore function. */\n attach(): () => void {\n const self = this;\n const restores: Array<() => void> = [];\n\n for (const method of METHODS) {\n const original = (console as unknown as Record<string, unknown>)[method];\n if (typeof original !== 'function') continue;\n\n const patched = (...args: unknown[]) => {\n try {\n (original as (...a: unknown[]) => void).apply(console, args);\n } catch {\n /* never break host logging */\n }\n self.capture(method, args);\n };\n\n (console as unknown as Record<string, unknown>)[method] = patched;\n restores.push(() => {\n (console as unknown as Record<string, unknown>)[method] = original;\n });\n }\n\n return () => {\n for (const restore of restores.splice(0)) restore();\n };\n }\n\n private capture(method: ConsoleMethod, args: unknown[]): void {\n if (!this.ctx.config.capture.logs) return;\n try {\n const level = LEVEL_BY_METHOD[method];\n const payload: LogPayload = {\n projectId: this.ctx.projectInfo.projectId,\n level,\n message: formatMessage(args, this.redactor),\n arguments: args.length > 0 ? (this.redactor.redact(args) as unknown[]) : undefined,\n stack: method === 'error' ? captureStack() : undefined,\n source: resolveSourceLocation(captureStack() ?? '', { skip: 0 }),\n context: undefined,\n processId: process.pid,\n requestId: requestContext().requestId(),\n timestamp: Date.now(),\n };\n if (method === 'error') payload.level = 'error';\n emit('log.created', payload);\n } catch {\n /* never propagate */\n }\n }\n}\n\nfunction formatMessage(args: unknown[], redactor: Redactor): string {\n if (args.length === 0) return '';\n const first = args[0];\n if (typeof first === 'string') {\n return args.length === 1 ? redactor.redactString(first) : `${first} ${redactor.serialize(args.slice(1))}`;\n }\n return redactor.serialize(args);\n}\n\nfunction captureStack(): string | undefined {\n const err = new Error();\n const stack = err.stack;\n if (!stack) return undefined;\n // drop the frames created by this helper\n return stack.split('\\n').slice(3).join('\\n');\n}\n","import { Logger } from '@nestjs/common';\nimport { Redactor } from '@angelitosystems/devtools-protocol';\nimport type { LogPayload, LogLevel, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport { requestContext, resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\n/**\n * Captures NestJS framework logs (`new Logger('Ctx').log(...)` and the static\n * `Logger.log(...)` variants). Nest's Logger writes through process.stdout\n * internals, not console.*, so it needs its own hook.\n *\n * State is module-scoped on purpose: the patched methods are plain functions\n * and must never depend on class-instance `this` binding.\n */\nlet activeRedactor = new Redactor();\nlet activeConfig: DevToolsConfig | null = null;\nlet activeProjectId = '';\n\nfunction capture(level: LogLevel, message: unknown, context?: string, stack?: string): void {\n try {\n if (!activeConfig?.capture.logs) return;\n const text = typeof message === 'string' ? message : activeRedactor.serialize(message);\n const payload: LogPayload = {\n projectId: activeProjectId,\n level,\n message: activeRedactor.redactString(text),\n source: stack ? undefined : resolveSdkAwareLocation(),\n context,\n stack,\n processId: process.pid,\n requestId: requestContext().requestId(),\n timestamp: Date.now(),\n };\n emit('log.created', payload);\n } catch {\n /* never propagate */\n }\n}\n\n/** Captures NestJS Logger output and mirrors it to DevTools. */\nexport class LoggerInstrumentation {\n constructor(ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {\n activeRedactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n activeConfig = ctx.config;\n activeProjectId = ctx.projectInfo.projectId;\n }\n\n /** Patch Logger.prototype and the static Logger methods. Returns a restore function. */\n attach(): () => void {\n const restores: Array<() => void> = [];\n\n const patch = (owner: Record<string, unknown>, method: string, level: LogLevel, instance: boolean) => {\n const original = owner[method];\n if (typeof original !== 'function') return;\n\n owner[method] = function (this: unknown, message: unknown, ...rest: unknown[]) {\n const context = instance\n ? ((this as { context?: string } | undefined)?.context ?? (rest[0] as string | undefined))\n : (rest[0] as string | undefined);\n const stack = rest[1] as string | undefined;\n try {\n const result = (original as (...a: unknown[]) => unknown).apply(this, [message, ...rest]);\n capture(level, message, context, stack);\n return result;\n } catch (err) {\n capture(level, message, context, stack);\n throw err;\n }\n };\n\n restores.push(() => {\n owner[method] = original;\n });\n };\n\n // instance loggers: `new Logger('Ctx').log(...)` — the common case\n const proto = Logger.prototype as unknown as Record<string, unknown>;\n patch(proto, 'log', 'info', true);\n patch(proto, 'error', 'error', true);\n patch(proto, 'warn', 'warn', true);\n patch(proto, 'debug', 'debug', true);\n patch(proto, 'verbose', 'verbose', true);\n\n // static loggers: `Logger.log(...)`\n const statics = Logger as unknown as Record<string, unknown>;\n patch(statics, 'log', 'info', false);\n patch(statics, 'error', 'error', false);\n patch(statics, 'warn', 'warn', false);\n patch(statics, 'debug', 'debug', false);\n patch(statics, 'verbose', 'verbose', false);\n\n return () => {\n for (const restore of restores.splice(0)) restore();\n };\n }\n}\n\nfunction resolveSdkAwareLocation(): LogPayload['source'] {\n try {\n const err = new Error();\n const stack = err.stack?.split('\\n').slice(3).join('\\n');\n return resolveSourceLocation(stack ?? '', { skip: 0 });\n } catch {\n return undefined;\n }\n}\n","import { basename } from 'path';\nimport type { ErrorPayload, ProjectInfo, SourceLocation } from '@angelitosystems/devtools-protocol';\nimport { requestContext, safeStringify, resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\ntype InstrumentationCtx = {\n config: DevToolsConfig;\n projectInfo: ProjectInfo;\n};\n\n/**\n * Global error capture via process-level hooks. Errors handled by NestJS\n * filters surface through request.completed; unexpected errors land here.\n */\nexport class ExceptionsInstrumentation {\n /** Attach process-level hooks. Returns a detach function. */\n static attach(ctx: InstrumentationCtx): () => void {\n const onUncaught = (error: unknown): void => {\n reportError(error, ctx, { source: 'uncaughtException' });\n };\n const onRejection = (reason: unknown): void => {\n reportError(reason, ctx, { source: 'unhandledRejection' });\n };\n\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onRejection);\n\n return () => {\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onRejection);\n };\n }\n}\n\n/** Public helper: report an error manually from anywhere in the app. */\nexport function captureError(\n error: unknown,\n options?: { context?: string; controller?: string; service?: string },\n): void {\n reportError(error, undefined, options);\n}\n\nfunction reportError(\n error: unknown,\n ctx: InstrumentationCtx | undefined,\n options?: { context?: string; controller?: string; service?: string; source?: string },\n): void {\n try {\n if (ctx && !ctx.config.capture.errors) return;\n\n const normalized = normalizeError(error);\n const location = resolveSourceLocation(normalized.error ?? normalized.message, { skip: 1 });\n const projectId = ctx?.projectInfo.projectId ?? basename(process.cwd());\n\n const payload: ErrorPayload = {\n requestId: requestContext().requestId(),\n projectId,\n name: normalized.name,\n message: normalized.message,\n stack: normalized.error?.stack,\n source: location,\n fingerprint: fingerprint(normalized.name, normalized.message, location),\n context: options?.context ?? options?.source,\n request: currentRequestSummary(),\n controller: options?.controller,\n service: options?.service,\n timestamp: Date.now(),\n };\n\n emit('error.created', payload);\n } catch {\n /* never propagate */\n }\n}\n\nfunction normalizeError(error: unknown): { error: Error | undefined; name: string; message: string } {\n if (error instanceof Error) {\n return { error, name: error.name, message: error.message };\n }\n if (typeof error === 'string') {\n return { error: undefined, name: 'Unknown', message: error };\n }\n if (error !== null && typeof error === 'object' && 'message' in error) {\n const record = error as Record<string, unknown>;\n return {\n error: undefined,\n name: typeof record['name'] === 'string' ? record['name'] : 'Error',\n message: String(record['message']),\n };\n }\n return { error: undefined, name: 'Unknown', message: safeStringify(error) };\n}\n\nfunction fingerprint(name: string, message: string, location?: SourceLocation): string {\n const raw = name + '::' + message + '::' + (location?.file ?? '') + ':' + String(location?.line ?? '');\n let hash = 0;\n for (let i = 0; i < raw.length; i++) {\n hash = (hash * 31 + raw.charCodeAt(i)) >>> 0;\n }\n return hash.toString(36).padStart(7, '0');\n}\n\nfunction currentRequestSummary(): { method: string; url: string } | undefined {\n const context = requestContext().current();\n if (!context?.method || !context?.url) return undefined;\n return { method: context.method, url: context.url };\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * Performance instrumentation.\n *\n * Periodic CPU/memory/event-loop/latency sampling lives in core\n * (CoreDevtools.startPerformance) so it works even without an HTTP adapter.\n * This module exists as the capture-toggle boundary and future extension\n * point (gc hooks, histograms, cluster awareness).\n */\nexport class PerformanceInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op: sampling is owned by core. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import type { AppModuleNode, AppMemberNode, AppSnapshot, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { emit } from '../emitter';\n\ninterface ContainerNode {\n id: string;\n name?: string;\n metatype?: Function;\n instance?: object;\n subtype?: 'httpController' | 'gateway';\n}\n\n/**\n * Explore the Nest container to build the module graph (modules, controllers,\n * providers, guards, pipes...). Best effort: any failure keeps the app safe.\n */\nexport class AppExplorer {\n constructor(private readonly ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {}\n\n /** Walk the container and emit app.snapshot. Returns a no-op cleanup. */\n attach(app: INestApplication): () => void {\n try {\n const snapshot = this.buildSnapshot(app);\n emit('app.snapshot', snapshot);\n } catch {\n /* best effort */\n }\n return () => {};\n }\n\n private buildSnapshot(app: INestApplication): AppSnapshot {\n const internal = (app as unknown as { container?: unknown }).container as\n | { getModules?: () => Map<string, ContainerNode> }\n | undefined;\n\n const modules: AppModuleNode[] = [];\n const modulesMap = internal?.getModules?.();\n if (modulesMap) {\n for (const [id, node] of modulesMap) {\n const moduleName = node.metatype?.name ?? String(id);\n const members = this.extractMembers(node);\n modules.push({\n name: moduleName,\n imports: [],\n controllers: members.controllers,\n providers: members.providers,\n exports: [],\n });\n }\n }\n\n return {\n projectId: this.ctx.projectInfo.projectId,\n projectName: this.ctx.projectInfo.projectName,\n modules,\n nestjsVersion: this.ctx.projectInfo.nestjsVersion,\n capturedAt: Date.now(),\n };\n }\n\n private extractMembers(node: ContainerNode): { controllers: AppMemberNode[]; providers: AppMemberNode[] } {\n const controllers: AppMemberNode[] = [];\n const providers: AppMemberNode[] = [];\n\n const providersMap = (node as unknown as { providers?: Map<string, unknown> }).providers;\n if (providersMap instanceof Map) {\n for (const [id, wrapper] of providersMap) {\n const member = this.memberFromWrapper(id, wrapper);\n if (!member) continue;\n if (wrapper && (wrapper as { subtype?: string }).subtype === 'httpController') {\n controllers.push(member);\n } else {\n providers.push(member);\n }\n }\n }\n\n return { controllers, providers };\n }\n\n private memberFromWrapper(id: string, wrapper: unknown): AppMemberNode | null {\n const w = wrapper as { name?: string; metatype?: Function; subtype?: string; instance?: Record<string, unknown> } | null;\n const name = w?.metatype?.name ?? (typeof id === 'string' ? id.replace(/^[A-Z_0-9]+:/, '') : 'unknown');\n const type = classify(name, w?.instance);\n return { name, type };\n }\n}\n\n/** Heuristic classification of providers into guards/interceptors/pipes/filters. */\nfunction classify(name: string, instance?: Record<string, unknown>): AppMemberNode['type'] {\n if (name.endsWith('Gateway')) return 'gateway';\n if (name.endsWith('Guard')) return 'guard';\n if (name.endsWith('Interceptor')) return 'interceptor';\n if (name.endsWith('Pipe')) return 'pipe';\n if (name.endsWith('Filter')) return 'filter';\n if (instance && typeof instance.canActivate === 'function') return 'guard';\n if (instance && typeof instance.intercept === 'function') return 'interceptor';\n if (instance && typeof instance.transform === 'function') return 'pipe';\n if (instance && typeof instance.catch === 'function') return 'filter';\n return 'provider';\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * WebSocket gateway instrumentation (v0.3 roadmap).\n *\n * Will introspect @WebSocketGateway() classes via the Nest container and wrap\n * gateway handlers. The placeholder keeps the init() wiring stable and\n * guarantees zero interference with host sockets.\n */\nexport class WebsocketInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op for now. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * Database instrumentation (v0.3 roadmap).\n *\n * Provider strategies will live here:\n * - Prisma: $extends / $use hooks\n * - TypeORM: DataSource QueryListener via subscriber\n * - Sequelize: sequelize.addHook\n * - MikroORM: EntityManager event subscriber\n *\n * All strategies must attach spans to the active request via trackSpans/\n * recordSpan and emit query.executed with redacted parameters.\n */\nexport class DatabaseInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op for now. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'path';\n\nlet cached: string | null | undefined;\n\n/** Best-effort detection of the host app's @nestjs/core version. */\nexport function detectNestJsVersion(): string | null {\n if (cached !== undefined) return cached;\n cached = null;\n try {\n const candidates = [\n resolve(process.cwd(), 'node_modules/@nestjs/core/package.json'),\n // bun/pnpm layouts: walk up a couple of levels\n resolve(process.cwd(), '../../node_modules/@nestjs/core/package.json'),\n ];\n for (const path of candidates) {\n if (!existsSync(path)) continue;\n const pkg = JSON.parse(readFileSync(path, 'utf8')) as { version?: string };\n if (pkg.version) {\n cached = pkg.version;\n break;\n }\n }\n } catch {\n cached = null;\n }\n return cached;\n}\n","/** SDK version reported to the DevTools server. Keep in sync with package.json. */\nexport const SDK_VERSION = '0.1.0';\n","/**\n * @angelitosystems/nest-devtools\n *\n * Drop-in real-time debugging and observability for NestJS.\n *\n * Usage:\n * import { NestDevTools } from '@angelitosystems/nest-devtools';\n * const app = await NestFactory.create(AppModule);\n * NestDevTools.init(app);\n */\nexport { NestDevTools, devtools } from './sdk';\nexport type { InitResult } from './sdk';\nexport { captureError } from './instrumentation/exceptions';\nexport type { DevToolsUserConfig } from '@angelitosystems/devtools-core';\nexport { requestContext } from '@angelitosystems/devtools-core';\nexport type { RequestContext } from '@angelitosystems/devtools-core';\n"],"mappings":"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","names":["coreDevtools","Redactor","requestContext","Redactor","requestContext","Redactor","requestContext","resolveSourceLocation","Redactor","requestContext","resolveSourceLocation","requestContext","resolveSourceLocation","resolveSourceLocation","requestContext","coreDevtools","requestContext"]}
1
+ {"version":3,"sources":["../src/sdk.ts","../src/instrumentation/http.ts","../src/emitter.ts","../src/instrumentation/timeline.ts","../src/instrumentation/console.ts","../src/instrumentation/nest-logger.ts","../src/instrumentation/exceptions.ts","../src/instrumentation/performance.ts","../src/instrumentation/app-explorer.ts","../src/instrumentation/websockets.ts","../src/instrumentation/database.ts","../src/detect.ts","../src/version.ts","../src/banner.ts","../src/index.ts"],"sourcesContent":["import { hostname } from 'os';\nimport { devtools as coreDevtools, resolveConfig } from '@angelitosystems/devtools-core';\nimport type { DevToolsUserConfig } from '@angelitosystems/devtools-core';\nimport type { ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { HttpInstrumentation } from './instrumentation/http';\nimport { ConsoleInstrumentation } from './instrumentation/console';\nimport { LoggerInstrumentation } from './instrumentation/nest-logger';\nimport { ExceptionsInstrumentation, captureError } from './instrumentation/exceptions';\nimport { PerformanceInstrumentation } from './instrumentation/performance';\nimport { AppExplorer } from './instrumentation/app-explorer';\nimport { WebsocketInstrumentation } from './instrumentation/websockets';\nimport { DatabaseInstrumentation } from './instrumentation/database';\nimport { detectNestJsVersion } from './detect';\nimport { SDK_VERSION } from './version';\nimport { printStartupBanner, printConnectionStatus } from './banner';\n\n/** Result of calling NestDevTools.init(). */\nexport interface InitResult {\n /** True when instrumentation is live. */\n enabled: boolean;\n /** Reason when partially or fully disabled. */\n reason?: 'disabled-by-config' | 'already-initialized' | 'no-http-adapter';\n projectId: string;\n projectName: string;\n server: string;\n}\n\n/**\n * Main entry point: `NestDevTools.init(app, config?)`.\n *\n * Never throws, never blocks startup, and disables itself in production\n * unless explicitly enabled.\n */\nexport class NestDevTools {\n private static readonly cleanups: Array<() => void> = [];\n private static initialized = false;\n\n /** Initialize DevTools for a NestJS application. One active instance per process. */\n static init(app: INestApplication, userConfig?: DevToolsUserConfig): InitResult {\n const config = resolveConfig(userConfig);\n const disabled: InitResult = {\n enabled: false,\n reason: 'disabled-by-config',\n projectId: config.projectId,\n projectName: config.project ?? config.projectId,\n server: config.server,\n };\n\n if (this.initialized) return { ...disabled, reason: 'already-initialized' };\n if (!config.enabled) return disabled; // zero side effects: no patching, no sockets, no timers\n\n this.initialized = true;\n const registerCleanup = (fn: () => void) => this.cleanups.push(fn);\n\n const projectInfo: ProjectInfo = {\n projectId: config.projectId,\n projectName: config.project ?? config.projectId,\n environment: config.environment,\n hostname: safeHostname(),\n port: null,\n pid: process.pid,\n runtime: detectRuntime(),\n runtimeVersion: detectRuntimeVersion(),\n nodeVersion: process.version,\n nestjsVersion: detectNestJsVersion(),\n sdkVersion: SDK_VERSION,\n };\n\n // transport is fully async: a missing server never affects startup\n let hasWarnedOffline = false;\n coreDevtools.initialize({\n config,\n projectInfo,\n registerCleanup,\n onStateChange: (state) => {\n if (state === 'open') {\n printConnectionStatus('open', dashboardUrl(config.server));\n } else if (state === 'retrying' && !hasWarnedOffline) {\n hasWarnedOffline = true;\n printConnectionStatus('offline', dashboardUrl(config.server));\n }\n },\n });\n\n const adapter = app.getHttpAdapter();\n const httpReady = Boolean(adapter && ['http', 'express'].includes(adapter.getType()));\n\n // ---- HTTP instrumentation -------------------------------------------\n const http = new HttpInstrumentation({ config, projectInfo });\n registerCleanup(http.attach(app));\n\n // ---- console + NestJS Logger + global errors ------------------------\n registerCleanup(new ConsoleInstrumentation({ config, projectInfo }).attach());\n registerCleanup(new LoggerInstrumentation({ config, projectInfo }).attach());\n registerCleanup(ExceptionsInstrumentation.attach({ config, projectInfo }));\n\n // ---- performance sampling -------------------------------------------\n registerCleanup(new PerformanceInstrumentation({ config, projectInfo }).attach());\n\n // ---- application graph ----------------------------------------------\n registerCleanup(new AppExplorer({ config, projectInfo }).attach(app));\n\n // ---- websockets + database (best effort) ----------------------------\n if (config.capture.websockets) {\n registerCleanup(new WebsocketInstrumentation({ config, projectInfo }).attach());\n }\n if (config.capture.database) {\n registerCleanup(new DatabaseInstrumentation({ config, projectInfo }).attach());\n }\n\n printStartupBanner({\n endpoint: config.server,\n dashboard: dashboardUrl(config.server),\n project: projectInfo.projectName,\n });\n\n return {\n enabled: true,\n projectId: config.projectId,\n projectName: projectInfo.projectName,\n server: config.server,\n ...(httpReady ? {} : { reason: 'no-http-adapter' as const }),\n };\n }\n\n /** Teardown everything (mostly useful in tests). */\n static destroy(): void {\n for (const cleanup of this.cleanups.splice(0)) {\n try {\n cleanup();\n } catch {\n /* ignore */\n }\n }\n this.initialized = false;\n coreDevtools.shutdown();\n }\n\n /** Whether the SDK is currently active in this process. */\n static isActive(): boolean {\n return this.initialized;\n }\n}\n\n/** Convenience functional alias: devtools.init(app). */\nexport const devtools = {\n init: NestDevTools.init.bind(NestDevTools),\n destroy: NestDevTools.destroy.bind(NestDevTools),\n isActive: NestDevTools.isActive.bind(NestDevTools),\n};\n\nfunction safeHostname(): string {\n try {\n return hostname();\n } catch {\n return 'unknown';\n }\n}\n\nfunction detectRuntime(): string {\n const versions = process.versions as Record<string, string | undefined>;\n if (versions['bun']) return 'bun';\n if (versions['deno']) return 'deno';\n return 'node';\n}\n\nfunction detectRuntimeVersion(): string {\n const versions = process.versions as Record<string, string | undefined>;\n return versions['bun'] ?? versions['deno'] ?? process.version;\n}\n\nfunction dashboardUrl(server: string): string {\n try {\n const url = new URL(server);\n url.protocol = url.protocol === 'wss:' ? 'https:' : 'http:';\n const port = Number(url.port);\n url.port = String(Number.isFinite(port) && port > 0 ? port - 1 : 4317);\n url.pathname = '';\n url.search = '';\n url.hash = '';\n return url.toString().replace(/\\/$/, '');\n } catch {\n return 'http://localhost:4317';\n }\n}\n\nexport { captureError };","import type { IncomingMessage, ServerResponse, Server as HttpServer } from 'http';\nimport { Redactor, randomId } from '@angelitosystems/devtools-protocol';\nimport type {\n ProjectInfo,\n RequestCompletedPayload,\n RequestStartedPayload,\n TimelineSpan,\n} from '@angelitosystems/devtools-protocol';\nimport { requestContext } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { emit } from '../emitter';\nimport { trackSpans } from './timeline';\n\n/** Shared context every instrumentation module receives. */\nexport interface InstrumentationContext {\n config: DevToolsConfig;\n projectInfo: ProjectInfo;\n}\n\n/** Headers captured by default (denylist still applies). */\nconst INTERESTING_HEADERS = [\n 'content-type',\n 'content-length',\n 'accept',\n 'origin',\n 'referer',\n 'user-agent',\n 'x-forwarded-for',\n 'x-request-id',\n] as const;\n\ntype RequestListener = (req: IncomingMessage, res: ServerResponse) => void;\n\nconst WRAPPED = Symbol('nest-devtools.wrapped');\n\n/**\n * Instrument the HTTP server of a NestJS application.\n *\n * Covers both bootstrap orders without touching Node module internals:\n * - `NestDevTools.init(app)` after `app.listen()`: the server already exists\n * and is wrapped immediately.\n * - `NestDevTools.init(app)` before `app.listen()` (recommended): `app.listen`\n * is wrapped so the server is wrapped the moment it exists.\n */\nexport class HttpInstrumentation {\n private readonly redactor: Redactor;\n\n constructor(private readonly ctx: InstrumentationContext) {\n this.redactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n }\n\n /** Begin capturing HTTP requests. Returns a cleanup function. */\n attach(app: INestApplication): () => void {\n try {\n const adapter = app.getHttpAdapter();\n // 'http' = platform-default adapter, 'express' = @nestjs/platform-express\n if (!adapter || !['http', 'express'].includes(adapter.getType())) return () => {};\n\n const getServer = (): HttpServer | undefined =>\n (adapter as unknown as { getHttpServer?: () => HttpServer }).getHttpServer?.();\n\n // 1) server already exists (init called after listen)\n const existing = getServer();\n if (existing) {\n this.wrapServer(existing);\n return () => {};\n }\n\n // 2) init called before listen: wrap the server once listen() resolves\n const appLike = app as unknown as { listen: (...args: unknown[]) => unknown };\n const originalListen = appLike.listen.bind(app);\n const self = this;\n const patchedListen = (...args: unknown[]) => {\n const result = originalListen(...args);\n Promise.resolve(result)\n .then(() => {\n const server = getServer();\n if (server) self.wrapServer(server);\n })\n .catch(() => {\n /* listen failed — the app will surface its own error */\n });\n return result;\n };\n appLike.listen = patchedListen;\n\n return () => {\n appLike.listen = originalListen;\n };\n } catch {\n return () => {};\n }\n }\n\n /** Wrap the 'request' listeners of a server exactly once. */\n private wrapServer(server: HttpServer): void {\n const target = server as unknown as Record<symbol, unknown>;\n if (target[WRAPPED]) return;\n target[WRAPPED] = true;\n\n const self = this;\n const originalListeners = server.rawListeners('request') as RequestListener[];\n\n server.removeAllListeners('request');\n server.on('request', (req, res) => {\n self.instrumentRequest(req, res, () => {\n for (const listener of originalListeners) {\n listener.call(server, req, res);\n }\n });\n });\n }\n\n /** Wrap a single request lifecycle. */\n private instrumentRequest(req: IncomingMessage, res: ServerResponse, next: () => void): void {\n if (!this.ctx.config.capture.requests) {\n next();\n return;\n }\n\n const startedAt = Date.now();\n const requestId = randomId('req');\n const method = (req.method ?? 'GET').toUpperCase();\n const rawUrl = req.url ?? '/';\n const url = safeUrlPath(rawUrl);\n\n const spans: TimelineSpan[] = [];\n const unregister = trackSpans(requestId, spans);\n res.once('finish', unregister);\n\n const started: RequestStartedPayload = {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n method,\n url,\n headers: this.collectHeaders(req),\n query: parseQuery(rawUrl),\n ip: clientIp(req),\n userAgent: asString(req.headers['user-agent']) || undefined,\n startedAt,\n };\n\n const middlewareSpan: TimelineSpan = {\n layer: 'middleware',\n label: `${method} ${url}`,\n duration: 0,\n startedAt,\n status: 'ok',\n };\n spans.push(middlewareSpan);\n\n const onFinished = () => {\n const finishedAt = Date.now();\n middlewareSpan.duration = Math.max(0, finishedAt - middlewareSpan.startedAt);\n middlewareSpan.status = res.statusCode >= 500 ? 'error' : 'ok';\n\n const responseSpan: TimelineSpan = {\n layer: 'response',\n label: 'response',\n duration: 0,\n startedAt: finishedAt,\n status: 'ok',\n };\n spans.push(responseSpan);\n\n const errored = res.statusCode >= 500;\n\n const completed: RequestCompletedPayload = {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n method,\n url,\n statusCode: res.statusCode,\n duration: finishedAt - startedAt,\n startedAt,\n timeline: spans,\n query: parseQuery(rawUrl),\n errored,\n };\n\n emit('request.completed', completed);\n\n // NestJS exception filters turn controller errors into 5xx responses\n // without any process-level signal — surface them in the Error Explorer.\n if (errored) {\n emit('error.created', {\n requestId,\n projectId: this.ctx.projectInfo.projectId,\n name: 'HttpError',\n message: `${method} ${url} failed with status ${res.statusCode}`,\n fingerprint: httpErrorFingerprint(method, url, res.statusCode),\n request: { method, url, statusCode: res.statusCode },\n timestamp: finishedAt,\n });\n }\n };\n\n const context = requestContext();\n context.run({ requestId, method, url, startedAt }, () => {\n emit('request.started', started);\n res.once('finish', onFinished);\n next();\n });\n }\n\n private collectHeaders(req: IncomingMessage): Record<string, string> {\n const out: Record<string, string> = {};\n for (const key of INTERESTING_HEADERS) {\n const value = req.headers[key];\n if (value === undefined) continue;\n out[key] = this.redactor.isSensitive(key) ? '[REDACTED]' : asString(value).slice(0, 200);\n }\n return out;\n }\n}\n\nfunction asString(value: string | string[] | undefined): string {\n if (Array.isArray(value)) return value.join(', ');\n return value ?? '';\n}\n\n/** Stable fingerprint for framework-handled HTTP failures. */\nfunction httpErrorFingerprint(method: string, url: string, statusCode: number): string {\n const route = url.replace(/\\/\\d+(?=\\/|$)/g, '/:id'); // group /users/15 with /users/16\n const raw = `${method}::${route}::${statusCode}`;\n let hash = 0;\n for (let i = 0; i < raw.length; i++) {\n hash = (hash * 31 + raw.charCodeAt(i)) >>> 0;\n }\n return hash.toString(36).padStart(7, '0');\n}\n\nfunction safeUrlPath(raw: string): string {\n const index = raw.indexOf('?');\n return index === -1 ? raw : raw.slice(0, index);\n}\n\nfunction parseQuery(raw: string): Record<string, unknown> {\n const index = raw.indexOf('?');\n if (index === -1) return {};\n const out: Record<string, unknown> = {};\n for (const [key, value] of new URLSearchParams(raw.slice(index + 1))) {\n out[key] = value;\n }\n return out;\n}\n\nfunction clientIp(req: IncomingMessage): string | undefined {\n const forwarded = req.headers['x-forwarded-for'];\n if (typeof forwarded === 'string') return forwarded.split(',')[0]?.trim();\n return req.socket?.remoteAddress ?? undefined;\n}\n\nexport { safeUrlPath, parseQuery, clientIp };\n","import { devtools as coreDevtools } from '@angelitosystems/devtools-core';\nimport type { DevToolsEventMap, DevToolsEventName } from '@angelitosystems/devtools-protocol';\n\n/** Emit a typed protocol event to the DevTools server (fire-and-forget). */\nexport function emit<K extends DevToolsEventName>(event: K, payload: DevToolsEventMap[K]): void {\n try {\n coreDevtools.send(event, payload);\n } catch {\n /* instrumentation must never break the app */\n }\n}\n","import type { TimelineSpan } from '@angelitosystems/devtools-protocol';\n\n/** Create a started span inside a request's span list. */\nexport function startSpan(spans: TimelineSpan[], layer: string, label: string, detail?: string): TimelineSpan {\n const span: TimelineSpan = {\n layer,\n label,\n duration: 0,\n startedAt: Date.now(),\n status: 'ok',\n ...(detail !== undefined ? { detail } : {}),\n };\n spans.push(span);\n return span;\n}\n\n/** Finalize a span, computing its duration. */\nexport function endSpan(span: TimelineSpan, status?: 'ok' | 'error'): void {\n span.duration = Math.max(0, Date.now() - span.startedAt);\n if (status) span.status = status;\n}\n\n/**\n * Registry of active request timelines, keyed by requestId.\n * Lets deeper instrumentation (database, websockets) attach spans to the\n * request that caused them, using the AsyncLocalStorage request id.\n */\nconst recorders = new Map<string, TimelineSpan[]>();\n\n/** Register a request's span list. Returns an unregister callback. */\nexport function trackSpans(requestId: string, spans: TimelineSpan[]): () => void {\n recorders.set(requestId, spans);\n return () => recorders.delete(requestId);\n}\n\n/** Add an auto-ended span to a request if it is still active. */\nexport function recordSpan(requestId: string, layer: string, label: string, detail?: string, status?: 'ok' | 'error'): void {\n const spans = recorders.get(requestId);\n if (!spans) return;\n const span = startSpan(spans, layer, label, detail);\n endSpan(span, status);\n}\n","import { Console } from 'console';\nimport { Redactor } from '@angelitosystems/devtools-protocol';\nimport { resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { LogPayload, LogLevel, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport { requestContext } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\nconst METHODS = ['log', 'info', 'warn', 'error', 'debug'] as const;\ntype ConsoleMethod = (typeof METHODS)[number];\n\nconst LEVEL_BY_METHOD: Record<ConsoleMethod, LogLevel> = {\n log: 'info',\n info: 'info',\n warn: 'warn',\n error: 'error',\n debug: 'debug',\n};\n\n/** Original console bound directly to the process streams. */\nconst originalConsole = new Console({\n stdout: process.stdout,\n stderr: process.stderr,\n colorMode: 'auto',\n});\n\n/** Write through the untouched console (used by DevTools' own logging). */\nexport function writeOriginalConsole(method: ConsoleMethod, ...args: unknown[]): void {\n const fn = (originalConsole as unknown as Record<string, (...a: unknown[]) => void>)[method];\n if (fn) fn.apply(originalConsole, args);\n}\n\n/** Capture console output and mirror it to DevTools. */\nexport class ConsoleInstrumentation {\n private readonly redactor: Redactor;\n\n constructor(private readonly ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {\n this.redactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n }\n\n /** Patch console methods. Returns a restore function. */\n attach(): () => void {\n const self = this;\n const restores: Array<() => void> = [];\n\n for (const method of METHODS) {\n const original = (console as unknown as Record<string, unknown>)[method];\n if (typeof original !== 'function') continue;\n\n const patched = (...args: unknown[]) => {\n try {\n (original as (...a: unknown[]) => void).apply(console, args);\n } catch {\n /* never break host logging */\n }\n self.capture(method, args);\n };\n\n (console as unknown as Record<string, unknown>)[method] = patched;\n restores.push(() => {\n (console as unknown as Record<string, unknown>)[method] = original;\n });\n }\n\n return () => {\n for (const restore of restores.splice(0)) restore();\n };\n }\n\n private capture(method: ConsoleMethod, args: unknown[]): void {\n if (!this.ctx.config.capture.logs) return;\n try {\n const level = LEVEL_BY_METHOD[method];\n const payload: LogPayload = {\n projectId: this.ctx.projectInfo.projectId,\n level,\n message: formatMessage(args, this.redactor),\n arguments: args.length > 0 ? (this.redactor.redact(args) as unknown[]) : undefined,\n stack: method === 'error' ? captureStack() : undefined,\n source: resolveSourceLocation(captureStack() ?? '', { skip: 0 }),\n context: undefined,\n processId: process.pid,\n requestId: requestContext().requestId(),\n timestamp: Date.now(),\n };\n if (method === 'error') payload.level = 'error';\n emit('log.created', payload);\n } catch {\n /* never propagate */\n }\n }\n}\n\nfunction formatMessage(args: unknown[], redactor: Redactor): string {\n if (args.length === 0) return '';\n const first = args[0];\n if (typeof first === 'string') {\n return args.length === 1 ? redactor.redactString(first) : `${first} ${redactor.serialize(args.slice(1))}`;\n }\n return redactor.serialize(args);\n}\n\nfunction captureStack(): string | undefined {\n const err = new Error();\n const stack = err.stack;\n if (!stack) return undefined;\n // drop the frames created by this helper\n return stack.split('\\n').slice(3).join('\\n');\n}\n","import { Logger } from '@nestjs/common';\nimport { Redactor } from '@angelitosystems/devtools-protocol';\nimport type { LogPayload, LogLevel, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport { requestContext, resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\n/**\n * Captures NestJS framework logs (`new Logger('Ctx').log(...)` and the static\n * `Logger.log(...)` variants). Nest's Logger writes through process.stdout\n * internals, not console.*, so it needs its own hook.\n *\n * State is module-scoped on purpose: the patched methods are plain functions\n * and must never depend on class-instance `this` binding.\n */\nlet activeRedactor = new Redactor();\nlet activeConfig: DevToolsConfig | null = null;\nlet activeProjectId = '';\n\nfunction capture(level: LogLevel, message: unknown, context?: string, stack?: string): void {\n try {\n if (!activeConfig?.capture.logs) return;\n const text = typeof message === 'string' ? message : activeRedactor.serialize(message);\n const payload: LogPayload = {\n projectId: activeProjectId,\n level,\n message: activeRedactor.redactString(text),\n source: stack ? undefined : resolveSdkAwareLocation(),\n context,\n stack,\n processId: process.pid,\n requestId: requestContext().requestId(),\n timestamp: Date.now(),\n };\n emit('log.created', payload);\n } catch {\n /* never propagate */\n }\n}\n\n/** Captures NestJS Logger output and mirrors it to DevTools. */\nexport class LoggerInstrumentation {\n constructor(ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {\n activeRedactor = new Redactor({\n redact: ctx.config.redact,\n allow: ctx.config.allow,\n maxBytes: ctx.config.maxPayloadBytes,\n });\n activeConfig = ctx.config;\n activeProjectId = ctx.projectInfo.projectId;\n }\n\n /** Patch Logger.prototype and the static Logger methods. Returns a restore function. */\n attach(): () => void {\n const restores: Array<() => void> = [];\n\n const patch = (owner: Record<string, unknown>, method: string, level: LogLevel, instance: boolean) => {\n const original = owner[method];\n if (typeof original !== 'function') return;\n\n owner[method] = function (this: unknown, message: unknown, ...rest: unknown[]) {\n const context = instance\n ? ((this as { context?: string } | undefined)?.context ?? (rest[0] as string | undefined))\n : (rest[0] as string | undefined);\n const stack = rest[1] as string | undefined;\n try {\n const result = (original as (...a: unknown[]) => unknown).apply(this, [message, ...rest]);\n capture(level, message, context, stack);\n return result;\n } catch (err) {\n capture(level, message, context, stack);\n throw err;\n }\n };\n\n restores.push(() => {\n owner[method] = original;\n });\n };\n\n // instance loggers: `new Logger('Ctx').log(...)` — the common case\n const proto = Logger.prototype as unknown as Record<string, unknown>;\n patch(proto, 'log', 'info', true);\n patch(proto, 'error', 'error', true);\n patch(proto, 'warn', 'warn', true);\n patch(proto, 'debug', 'debug', true);\n patch(proto, 'verbose', 'verbose', true);\n\n // static loggers: `Logger.log(...)`\n const statics = Logger as unknown as Record<string, unknown>;\n patch(statics, 'log', 'info', false);\n patch(statics, 'error', 'error', false);\n patch(statics, 'warn', 'warn', false);\n patch(statics, 'debug', 'debug', false);\n patch(statics, 'verbose', 'verbose', false);\n\n return () => {\n for (const restore of restores.splice(0)) restore();\n };\n }\n}\n\nfunction resolveSdkAwareLocation(): LogPayload['source'] {\n try {\n const err = new Error();\n const stack = err.stack?.split('\\n').slice(3).join('\\n');\n return resolveSourceLocation(stack ?? '', { skip: 0 });\n } catch {\n return undefined;\n }\n}\n","import { basename } from 'path';\nimport type { ErrorPayload, ProjectInfo, SourceLocation } from '@angelitosystems/devtools-protocol';\nimport { requestContext, safeStringify, resolveSourceLocation } from '@angelitosystems/devtools-core';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\n\nimport { emit } from '../emitter';\n\ntype InstrumentationCtx = {\n config: DevToolsConfig;\n projectInfo: ProjectInfo;\n};\n\n/**\n * Global error capture via process-level hooks. Errors handled by NestJS\n * filters surface through request.completed; unexpected errors land here.\n */\nexport class ExceptionsInstrumentation {\n /** Attach process-level hooks. Returns a detach function. */\n static attach(ctx: InstrumentationCtx): () => void {\n const onUncaught = (error: unknown): void => {\n reportError(error, ctx, { source: 'uncaughtException' });\n };\n const onRejection = (reason: unknown): void => {\n reportError(reason, ctx, { source: 'unhandledRejection' });\n };\n\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onRejection);\n\n return () => {\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onRejection);\n };\n }\n}\n\n/** Public helper: report an error manually from anywhere in the app. */\nexport function captureError(\n error: unknown,\n options?: { context?: string; controller?: string; service?: string },\n): void {\n reportError(error, undefined, options);\n}\n\nfunction reportError(\n error: unknown,\n ctx: InstrumentationCtx | undefined,\n options?: { context?: string; controller?: string; service?: string; source?: string },\n): void {\n try {\n if (ctx && !ctx.config.capture.errors) return;\n\n const normalized = normalizeError(error);\n const location = resolveSourceLocation(normalized.error ?? normalized.message, { skip: 1 });\n const projectId = ctx?.projectInfo.projectId ?? basename(process.cwd());\n\n const payload: ErrorPayload = {\n requestId: requestContext().requestId(),\n projectId,\n name: normalized.name,\n message: normalized.message,\n stack: normalized.error?.stack,\n source: location,\n fingerprint: fingerprint(normalized.name, normalized.message, location),\n context: options?.context ?? options?.source,\n request: currentRequestSummary(),\n controller: options?.controller,\n service: options?.service,\n timestamp: Date.now(),\n };\n\n emit('error.created', payload);\n } catch {\n /* never propagate */\n }\n}\n\nfunction normalizeError(error: unknown): { error: Error | undefined; name: string; message: string } {\n if (error instanceof Error) {\n return { error, name: error.name, message: error.message };\n }\n if (typeof error === 'string') {\n return { error: undefined, name: 'Unknown', message: error };\n }\n if (error !== null && typeof error === 'object' && 'message' in error) {\n const record = error as Record<string, unknown>;\n return {\n error: undefined,\n name: typeof record['name'] === 'string' ? record['name'] : 'Error',\n message: String(record['message']),\n };\n }\n return { error: undefined, name: 'Unknown', message: safeStringify(error) };\n}\n\nfunction fingerprint(name: string, message: string, location?: SourceLocation): string {\n const raw = name + '::' + message + '::' + (location?.file ?? '') + ':' + String(location?.line ?? '');\n let hash = 0;\n for (let i = 0; i < raw.length; i++) {\n hash = (hash * 31 + raw.charCodeAt(i)) >>> 0;\n }\n return hash.toString(36).padStart(7, '0');\n}\n\nfunction currentRequestSummary(): { method: string; url: string } | undefined {\n const context = requestContext().current();\n if (!context?.method || !context?.url) return undefined;\n return { method: context.method, url: context.url };\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * Performance instrumentation.\n *\n * Periodic CPU/memory/event-loop/latency sampling lives in core\n * (CoreDevtools.startPerformance) so it works even without an HTTP adapter.\n * This module exists as the capture-toggle boundary and future extension\n * point (gc hooks, histograms, cluster awareness).\n */\nexport class PerformanceInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op: sampling is owned by core. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import type { AppModuleNode, AppMemberNode, AppSnapshot, ProjectInfo } from '@angelitosystems/devtools-protocol';\nimport type { DevToolsConfig } from '@angelitosystems/devtools-core';\nimport type { INestApplication } from '@nestjs/common';\n\nimport { emit } from '../emitter';\n\ninterface ContainerNode {\n id: string;\n name?: string;\n metatype?: Function;\n instance?: object;\n subtype?: 'httpController' | 'gateway';\n}\n\n/**\n * Explore the Nest container to build the module graph (modules, controllers,\n * providers, guards, pipes...). Best effort: any failure keeps the app safe.\n */\nexport class AppExplorer {\n constructor(private readonly ctx: { config: DevToolsConfig; projectInfo: ProjectInfo }) {}\n\n /** Walk the container and emit app.snapshot. Returns a no-op cleanup. */\n attach(app: INestApplication): () => void {\n try {\n const snapshot = this.buildSnapshot(app);\n emit('app.snapshot', snapshot);\n } catch {\n /* best effort */\n }\n return () => {};\n }\n\n private buildSnapshot(app: INestApplication): AppSnapshot {\n const internal = (app as unknown as { container?: unknown }).container as\n | { getModules?: () => Map<string, ContainerNode> }\n | undefined;\n\n const modules: AppModuleNode[] = [];\n const modulesMap = internal?.getModules?.();\n if (modulesMap) {\n for (const [id, node] of modulesMap) {\n const moduleName = node.metatype?.name ?? String(id);\n const members = this.extractMembers(node);\n modules.push({\n name: moduleName,\n imports: [],\n controllers: members.controllers,\n providers: members.providers,\n exports: [],\n });\n }\n }\n\n return {\n projectId: this.ctx.projectInfo.projectId,\n projectName: this.ctx.projectInfo.projectName,\n modules,\n nestjsVersion: this.ctx.projectInfo.nestjsVersion,\n capturedAt: Date.now(),\n };\n }\n\n private extractMembers(node: ContainerNode): { controllers: AppMemberNode[]; providers: AppMemberNode[] } {\n const controllers: AppMemberNode[] = [];\n const providers: AppMemberNode[] = [];\n\n const providersMap = (node as unknown as { providers?: Map<string, unknown> }).providers;\n if (providersMap instanceof Map) {\n for (const [id, wrapper] of providersMap) {\n const member = this.memberFromWrapper(id, wrapper);\n if (!member) continue;\n if (wrapper && (wrapper as { subtype?: string }).subtype === 'httpController') {\n controllers.push(member);\n } else {\n providers.push(member);\n }\n }\n }\n\n return { controllers, providers };\n }\n\n private memberFromWrapper(id: string, wrapper: unknown): AppMemberNode | null {\n const w = wrapper as { name?: string; metatype?: Function; subtype?: string; instance?: Record<string, unknown> } | null;\n const name = w?.metatype?.name ?? (typeof id === 'string' ? id.replace(/^[A-Z_0-9]+:/, '') : 'unknown');\n const type = classify(name, w?.instance);\n return { name, type };\n }\n}\n\n/** Heuristic classification of providers into guards/interceptors/pipes/filters. */\nfunction classify(name: string, instance?: Record<string, unknown>): AppMemberNode['type'] {\n if (name.endsWith('Gateway')) return 'gateway';\n if (name.endsWith('Guard')) return 'guard';\n if (name.endsWith('Interceptor')) return 'interceptor';\n if (name.endsWith('Pipe')) return 'pipe';\n if (name.endsWith('Filter')) return 'filter';\n if (instance && typeof instance.canActivate === 'function') return 'guard';\n if (instance && typeof instance.intercept === 'function') return 'interceptor';\n if (instance && typeof instance.transform === 'function') return 'pipe';\n if (instance && typeof instance.catch === 'function') return 'filter';\n return 'provider';\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * WebSocket gateway instrumentation (v0.3 roadmap).\n *\n * Will introspect @WebSocketGateway() classes via the Nest container and wrap\n * gateway handlers. The placeholder keeps the init() wiring stable and\n * guarantees zero interference with host sockets.\n */\nexport class WebsocketInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op for now. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import type { InstrumentationContext } from './http';\n\n/**\n * Database instrumentation (v0.3 roadmap).\n *\n * Provider strategies will live here:\n * - Prisma: $extends / $use hooks\n * - TypeORM: DataSource QueryListener via subscriber\n * - Sequelize: sequelize.addHook\n * - MikroORM: EntityManager event subscriber\n *\n * All strategies must attach spans to the active request via trackSpans/\n * recordSpan and emit query.executed with redacted parameters.\n */\nexport class DatabaseInstrumentation {\n constructor(private readonly ctx: InstrumentationContext) {}\n\n /** No-op for now. Returns a no-op cleanup. */\n attach(): () => void {\n void this.ctx;\n return () => {};\n }\n}\n","import { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'path';\n\nlet cached: string | null | undefined;\n\n/** Best-effort detection of the host app's @nestjs/core version. */\nexport function detectNestJsVersion(): string | null {\n if (cached !== undefined) return cached;\n cached = null;\n try {\n const candidates = [\n resolve(process.cwd(), 'node_modules/@nestjs/core/package.json'),\n // bun/pnpm layouts: walk up a couple of levels\n resolve(process.cwd(), '../../node_modules/@nestjs/core/package.json'),\n ];\n for (const path of candidates) {\n if (!existsSync(path)) continue;\n const pkg = JSON.parse(readFileSync(path, 'utf8')) as { version?: string };\n if (pkg.version) {\n cached = pkg.version;\n break;\n }\n }\n } catch {\n cached = null;\n }\n return cached;\n}\n","/** SDK version reported to the DevTools server. Keep in sync with package.json. */\nexport const SDK_VERSION = '0.1.0';\n","import { writeOriginalConsole } from './instrumentation/console';\n\n/** ANSI escape helpers (kept tiny and dependency-free, mirrors the CLI renderer). */\nconst RESET = '\\x1b[0m';\nconst DIM = '\\x1b[2m';\nconst BOLD = '\\x1b[1m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst CYAN = '\\x1b[36m';\nconst GRAY = '\\x1b[90m';\n\nconst WIDTH = 47;\n\nfunction colorEnabled(): boolean {\n // Respect NO_COLOR / non-TTY output the same way most CLIs do.\n if (process.env['NO_COLOR']) return false;\n return Boolean(process.stdout?.isTTY);\n}\n\nfunction paint(color: string, text: string): string {\n return colorEnabled() ? `${color}${text}${RESET}` : text;\n}\n\nfunction pad(label: string, value: string): string {\n const line = ` ${paint(GRAY, label.padEnd(9))} ${paint(CYAN, value)}`;\n return line;\n}\n\n/** Prints the boxed \"SDK started\" banner once, right after init(). */\nexport function printStartupBanner(info: { endpoint: string; dashboard: string; project: string }): void {\n const top = `${paint(GRAY, '┌' + '─'.repeat(WIDTH) + '┐')}`;\n const bottom = `${paint(GRAY, '└' + '─'.repeat(WIDTH) + '┘')}`;\n const title = ` ${paint(BOLD + CYAN, 'NestJS DevTools')} ${paint(GREEN, '●')} ${paint(DIM, `(${info.project})`)}`;\n\n writeOriginalConsole('log', '');\n writeOriginalConsole('log', top);\n writeOriginalConsole('log', title);\n writeOriginalConsole('log', pad('Endpoint', info.endpoint));\n writeOriginalConsole('log', pad('Dashboard', info.dashboard));\n writeOriginalConsole('log', `${paint(GRAY, ' Estado')} ${paint(YELLOW, '◌ conectando…')}`);\n writeOriginalConsole('log', bottom);\n}\n\n/** Prints a single status line once the transport's connection state is known. */\nexport function printConnectionStatus(state: 'open' | 'offline', dashboard: string): void {\n if (state === 'open') {\n writeOriginalConsole('log', ` ${paint(GREEN, '✓')} Conectado al dashboard ${paint(DIM, `(${dashboard})`)}`);\n return;\n }\n writeOriginalConsole('log', ` ${paint(YELLOW, '⚠')} No se pudo conectar al dashboard todavía.`);\n writeOriginalConsole('log', ` ${paint(DIM, 'Levántalo en otra terminal con:')} ${paint(BOLD, 'npx nest-devtools start')}`);\n writeOriginalConsole('log', ` ${paint(DIM, 'Reintentando en segundo plano — se conectará solo cuando el dashboard esté arriba.')}`);\n}","/**\n * @angelitosystems/nest-devtools\n *\n * Drop-in real-time debugging and observability for NestJS.\n *\n * Usage:\n * import { NestDevTools } from '@angelitosystems/nest-devtools';\n * const app = await NestFactory.create(AppModule);\n * NestDevTools.init(app);\n */\nexport { NestDevTools, devtools } from './sdk';\nexport type { InitResult } from './sdk';\nexport { captureError } from './instrumentation/exceptions';\nexport type { DevToolsUserConfig } from '@angelitosystems/devtools-core';\nexport { requestContext } from '@angelitosystems/devtools-core';\nexport type { RequestContext } from '@angelitosystems/devtools-core';\n"],"mappings":"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","names":["coreDevtools","Redactor","requestContext","Redactor","requestContext","Redactor","requestContext","resolveSourceLocation","Redactor","requestContext","resolveSourceLocation","requestContext","resolveSourceLocation","resolveSourceLocation","requestContext","coreDevtools","requestContext"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angelitosystems/nest-devtools",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "One-line real-time debugging and observability for NestJS applications.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,8 +32,8 @@
32
32
  "websocket"
33
33
  ],
34
34
  "dependencies": {
35
- "@angelitosystems/devtools-core": "1.0.2",
36
- "@angelitosystems/devtools-protocol": "1.0.2"
35
+ "@angelitosystems/devtools-core": "1.0.3",
36
+ "@angelitosystems/devtools-protocol": "1.0.3"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@nestjs/common": "^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0",