Project Detection
Source: src/engine/project-detector.ts
What
Detects whether the target is a monorepo or single project, and extracts project metadata (NestJS version, ORM, HTTP framework).
Why
- Monorepo detection happens early so the pipeline knows whether to loop over sub-projects or scan once.
- Project metadata is displayed in the report and used by ORM-specific rules like
no-orm-in-controllersandno-raw-entity-in-response.
Monorepo Detection
Input
targetPath: string // root directory to check
Output
interface MonorepoInfo {
projects: Map<string, string> // project name → relative root path
}
// Returns null if not a monorepo
Five detection strategies are tried in priority order. The first match wins.
Strategy 1: nest-cli.json
Reads nest-cli.json and checks for:
monorepo: true- A
projectsmap with at least one entry
{
"monorepo": true,
"projects": {
"api": { "root": "apps/api" },
"admin": { "root": "apps/admin" }
}
}
Strategy 2: pnpm-workspace.yaml
Reads pnpm-workspace.yaml and:
- Parses the
packages:patterns (block-style and inline arrays are both supported) - Globs for
package.jsonfiles matching those patterns - Filters to packages that have
@nestjs/coreor@nestjs/commonindependencies,devDependencies, orpeerDependencies
packages:
- "apps/*"
- "packages/*"
Strategy 3: package.json workspaces (npm / Yarn)
If no pnpm-workspace.yaml exists, reads the workspaces field from the root package.json. Both array and object (Yarn classic) formats are supported:
{
"workspaces": ["apps/*", "packages/*"]
}
{
"workspaces": {
"packages": ["apps/*", "packages/*"]
}
}
Resolves workspace globs the same way as strategy 2 — filters to packages with @nestjs/core or @nestjs/common. Skipped when pnpm-workspace.yaml exists to avoid duplicate detection (pnpm repos may have both).
Strategy 4: nx.json (Nx)
Detects the presence of nx.json, then scans for project.json files throughout the repo (excluding node_modules and the root-level project.json). For each project directory with a project.json, reads the sibling package.json and includes the project only if it depends on @nestjs/core or @nestjs/common.
Strategy 5: lerna.json (standalone Lerna)
Reads lerna.json and uses its packages globs (defaults to ["packages/*"] when not specified). Only activates when useWorkspaces is not set — if useWorkspaces: true, Lerna delegates to npm/Yarn workspaces and strategy 3 handles detection instead.
{
"packages": ["packages/*"]
}
Non-NestJS packages are always filtered out automatically across all strategies.
Fallback warning
If none of the strategies find NestJS packages but the directory looks like a monorepo (contains lerna.json, turbo.json, nx.json, pnpm-workspace.yaml, or a workspaces field in package.json), nestjs-doctor emits a warning and falls back to single-project mode.
If detected by any strategy, the pipeline runs stages 2-9 independently for each sub-project, then aggregates results into a combined score.
Single Project Detection
Input
targetPath: string // project root directory
Output
interface ProjectInfo {
name: string // from package.json name, or "unknown"
nestVersion: string | null // e.g. "10.0.0" (semver operators stripped)
orm: string | null // detected ORM
framework: "express" | "fastify" | null
moduleCount: number // 0 initially, updated by scanner
fileCount: number // 0 initially, updated by scanner
}
How It Works
Reads package.json and inspects dependencies + devDependencies:
ORM detection (first match takes precedence):
@prisma/client→"prisma"typeorm→"typeorm"@mikro-orm/core→"mikro-orm"sequelize→"sequelize"mongoose→"mongoose"drizzle-orm→"drizzle"
Framework detection:
@nestjs/platform-fastify→"fastify"@nestjs/platform-expressor@nestjs/core→"express"
NestJS version is extracted from @nestjs/core with semver operators (^, ~, >=) stripped.
Debugging Tips
- If the ORM shows as
null, check that the ORM package is independenciesordevDependenciesin the project'spackage.json. - Monorepo detection tries five strategies in order:
nest-cli.json,pnpm-workspace.yaml,package.jsonworkspaces (npm/Yarn),nx.json(Nx), andlerna.json(standalone Lerna). Only packages with@nestjs/coreor@nestjs/commonare included.