nestjs-doctorGitHub

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-controllers and no-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 projects map 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:

  1. Parses the packages: patterns (block-style and inline arrays are both supported)
  2. Globs for package.json files matching those patterns
  3. Filters to packages that have @nestjs/core or @nestjs/common in dependencies, devDependencies, or peerDependencies
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):

  1. @prisma/client"prisma"
  2. typeorm"typeorm"
  3. @mikro-orm/core"mikro-orm"
  4. sequelize"sequelize"
  5. mongoose"mongoose"
  6. drizzle-orm"drizzle"

Framework detection:

  • @nestjs/platform-fastify"fastify"
  • @nestjs/platform-express or @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 in dependencies or devDependencies in the project's package.json.
  • Monorepo detection tries five strategies in order: nest-cli.json, pnpm-workspace.yaml, package.json workspaces (npm/Yarn), nx.json (Nx), and lerna.json (standalone Lerna). Only packages with @nestjs/core or @nestjs/common are included.