nest-profiler-routes
Inspect the application routing table in Symfony-Routing-style Discover views, one per transport.
@eleven-labs/nest-profiler-routes
@eleven-labs/nest-profiler-routes adds the Discover views to the profiler home page — a Symfony-Routing-style view of the application's routing table, with one sidebar view per transport (Discover / HTTP, Discover / GraphQL, Discover / Commands, Discover / RabbitMQ) so each transport's table is a subject of its own. Every registered route is listed with its HTTP method, full path and controller/handler; a lock marks routes protected by a guard. Expanding a route reveals its description, guards, path params, query params, request headers, and the body DTO (class name, decorated properties, TypeScript types and, when class-validator is installed, the validation rules). Non-HTTP sources describe their inputs with their own labels — CLI commands list Arguments and Options with each option's description, GraphQL fields list Arguments.
A transport that discovered nothing gets no view at all, so the sidebar only ever lists what the application actually registered.

Installation
pnpm add -D @eleven-labs/nest-profiler-routesPeer dependencies: @eleven-labs/nest-profiler. class-validator is an optional peer — install it to surface DTO properties and validation rules; without it, a body DTO shows only its class name.
Setup
import { Module } from '@nestjs/common';
import { ProfilerModule } from '@eleven-labs/nest-profiler';
import { RoutesCollectorModule } from '@eleven-labs/nest-profiler-routes';
@Module({
imports: [ProfilerModule.forRoot({ isGlobal: true }), RoutesCollectorModule.forRoot()],
})
export class ProfilingModule {}
ProfilingModuleis the dev-only bundle loaded bymain-dev.ts— see Enabling and disabling the profiler. If the profiler is installed as a production dependency behind the runtime gate, wrap the same call inConditionalModule.registerWhen(..., isProfilerEnabled).
What it collects
At application startup, every registered route is discovered and grouped by transport, and each group becomes its own Discover view — keyed discover-<transport> in the ?view= parameter, so it can never collide with the same-protocol profile list (?view=graphql stays the GraphQL list, ?view=discover-graphql its routing table). The core ships a built-in HTTP source; other transport packages contribute their own — GraphQL resolvers (@eleven-labs/nest-profiler-graphql), RabbitMQ subscribers (@eleven-labs/nest-profiler-rabbitmq) and CLI commands (@eleven-labs/nest-profiler-commander) — by registering a ProfilerDiscoverSource with the core, so they appear automatically when installed.
Each REST route is introspected from its decorator metadata:
- Guards — the guard classes from
@UseGuards()on the controller and/or handler (e.g. an authentication guard); guarded routes show a lock. Only route-level guards are visible — a globalAPP_GUARDis not attached per handler. - Path params — from the route path (
/users/:id→id). - Query params — from
@Query('name')and whole-object@Query()DTOs. - Headers — from
@Headers('name'). - Body DTO — from
@Body(): the DTO class name, its top-level decorated properties with their TypeScript types, and (withclass-validator) the validation rules per property.
Introspection is top-level only: a property that is itself a DTO surfaces as its class name rather than being expanded.
Sources whose inputs are not HTTP-shaped use DiscoverInputs.groups instead — a list of { label, items } sections, each item being a { name, description?, required?, defaultValue? }. That is how the CLI source lists Arguments and Options, and the GraphQL source its field Arguments, without borrowing an HTTP label. A route may also carry a description, rendered above its inputs.
Contributing a custom route source
Any package can add its own Discover view by registering a ProfilerDiscoverSource with the core (mirroring how entrypoint types are registered). Each DiscoverGroup it returns becomes one view; set itemLabel when its entries are not routes, so the count reads 3 commands rather than 3 routes:
import { ModuleRef } from '@nestjs/core';
import { ProfilerCoreService } from '@eleven-labs/nest-profiler';
import type { ProfilerDiscoverSource } from '@eleven-labs/nest-profiler';
// in a module lifecycle hook:
const core = this.moduleRef.get(ProfilerCoreService, { strict: false });
core.registerDiscoverSource(mySource satisfies ProfilerDiscoverSource);License
MIT © Eleven Labs