docfy patch-spec

Patcht ein bereits erstelltes OpenAPI-Dokument, ausschließlich über statische Analyse (ts-morph), ohne require() einer Docs-Datei.

Warum es das gibt

Das ist ein manueller, CI-gesteuerter Weg, um genau das eine zu umgehen, was die Runtime-Pipeline von DocfyModule strukturell nicht kann: unter dem webpack: true-Build-Modus der NestJS-CLI zu funktionieren (siehe Das CLI-Plugin für die automatische, empfohlene Alternative, die dieselbe Analyse bei jedem Build statt in einem separaten Schritt durchführt). patch-spec umgeht die Webpack-Mauer, indem es nach Pfad + HTTP-Methode matcht, genauso berechnet wie check/coverage/lint es bereits tun, statt die laufende Controller-Klassenreferenz zu benötigen.

Verwendung

bash
npx nestjs-docfy patch-spec --spec <path-or-url> [options]
bash
# Patch a running app's served document
npx nestjs-docfy patch-spec --spec http://localhost:3000/api-json --out openapi.json

# Patch a file already written to disk
npx nestjs-docfy patch-spec --spec dist/openapi.json --out dist/openapi.json

Optionen

OptionDefaultDescription
--spec <path|url>(required)A local openapi.json, or a URL (e.g. a running app's /api-json)
--out <path>stdoutWhere to write the patched document
--root <path>.Project root directory
--tsconfig <path>auto-detectedPath to tsconfig.json
--pattern <glob>**/*.controller.tsGlob pattern to find controllers
--format <format>tsZu suchendes Docs-Dateiformat: ts oder js
--quietfalseSuppress all output except errors

Was zusammengeführt wird

Gematcht nach path + HTTP-Methode gegen das Basisdokument:

  • ApiTags → wird in tags vereinigt (verwirft nie Tags, die das Basisdokument bereits hatte)
  • ApiOperation({ summary, description, deprecated }) → überschreibt diese Felder
  • ApiResponse({ status, description, schema, example, examples }) → wird pro Statuscode zusammengeführt (andere Statuscodes bleiben unberührt); wenn kein schema/type angegeben ist, fällt es auf den aufgelösten Rückgabetyp der Methode zurück – dieselbe DTO-/class-validator-/Interface-Ableitung, die generate bereits vornimmt, inklusive eines oneOf aus $refs, wenn der Rückgabetyp eine Union aus ≥2 benannten DTOs/Entities ist (z. B. Promise<UserDto | AdminDto>)
  • ApiBody({ schema, examples }) → setzt requestBody, mit demselben Fallback auf den aufgelösten Typ des @Body()-Parameters, inklusive derselben Union-→-oneOf-Behandlung (example wird hier bewusst nicht gelesen, da der echte ApiBodyOptions-Typ von @nestjs/swagger nur examples kennt, anders als ApiResponse, das beides unterstützt)
  • ApiBearerAuth() → wird an security angehängt
  • ApiParam / ApiQuery / ApiHeader → werden nach Name + Ort in parameters zusammengeführt: ein wirklich neuer Parameter wird angehängt, aber einer, der schon existiert (z. B. generiert @nestjs/swagger aus reiner Reflection allein einen bloßen required: true-Eintrag für jedes mit @Query()/@Param() dekorierte Argument), bekommt seine Felder überlagert statt verworfen. enum wird aus einem Array-Literal (enum: ['a', 'b']) oder einer Referenz auf ein TS-enum gelesen, auch wenn es aus einer anderen Datei importiert wird (enum: Role), und der type des Schemas wird als number abgeleitet, wenn jeder aufgelöste Wert numerisch ist, sonst als string

What this does not do

Bewusst eingegrenzt

Dieser Befehl ist bewusst eingegrenzt, keine vollständige Neuimplementierung der Decorator-Semantik von @nestjs/swagger: anyOf (es gibt keine TS-Konstruktion, die „any of“ so natürlich abbildet, wie ein Union-Typ auf oneOf abbildet), links/callbacks (@nestjs/swagger selbst hat für keins von beiden eine Decorator-Option) und jedes Decorator-Argument, das kein Literal ist (eine Variable, ein Funktionsaufruf, ein Spread), werden unangetastet gelassen statt geraten. Es ist besser, ein Feld so zu lassen, wie es das Basisdokument schon hatte, als etwas Falsches hineinzupatchen. Ein Union-Rückgabetyp oder @Body()-Payload wird nur dann zu einem oneOf, wenn jeder Zweig auf ein benanntes DTO/eine benannte Entity auflöst. Routen, die eine Docs-Datei dokumentiert, aber die in --spec nicht existieren, werden als Warnungen gemeldet, nicht stillschweigend verworfen oder als Fehler behandelt.