docfy patch-spec

Applica una patch a un documento OpenAPI già costruito, interamente tramite analisi statica (ts-morph), senza alcun require() di file docs.

Perché esiste

Questo è un modo manuale, guidato dalla CI, per aggirare l'unica cosa che la pipeline a runtime di DocfyModule non può strutturalmente fare: funzionare sotto la modalità build webpack: true della NestJS CLI (vedi Il plugin CLI per l'alternativa automatica consigliata, che calcola la stessa analisi a ogni build invece che come step separato). patch-spec aggira il muro di webpack facendo il match su path + metodo HTTP, calcolato nello stesso modo in cui già fanno check/coverage/lint, invece di aver bisogno del riferimento live alla classe controller.

Utilizzo

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

Opzioni

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>tsFormato del file docs da cercare: ts o js
--quietfalseSuppress all output except errors

Cosa viene unito

Match su path + metodo HTTP contro il documento base:

  • ApiTags → unito in tags (non elimina mai i tag già presenti nel documento base)
  • ApiOperation({ summary, description, deprecated }) → sovrascrive quei campi
  • ApiResponse({ status, description, schema, example, examples }) → unito per codice di stato (gli altri codici restano intoccati); quando non viene indicato schema/type, ricade sul tipo di ritorno risolto del metodo, la stessa inferenza DTO/class-validator/interface che generate già fa, incluso un oneOf di $ref quando il tipo di ritorno è una union di ≥2 DTO/entità nominate (es. Promise<UserDto | AdminDto>)
  • ApiBody({ schema, examples }) → imposta requestBody, con lo stesso fallback in stile tipo-di-ritorno sul tipo risolto del parametro @Body(), incluso lo stesso trattamento union → oneOf (example non viene letto qui di proposito, dato che il vero tipo ApiBodyOptions di @nestjs/swagger ha solo examples, a differenza di ApiResponse, che supporta entrambi)
  • ApiBearerAuth() → aggiunto a security
  • ApiParam / ApiQuery / ApiHeader → uniti in parameters per nome + posizione: un parametro genuinamente nuovo viene aggiunto, ma uno già esistente (ad es. @nestjs/swagger genera automaticamente per pura reflection una voce required: true nuda per ogni argomento decorato con @Query()/@Param()) viene sovrapposto nei suoi campi, non scartato. enum viene letto da un array letterale (enum: ['a', 'b']) o da un riferimento a un enum TS, incluso uno importato da un altro file (enum: Role), e il type dello schema viene inferito come number quando ogni valore risolto è numerico, string altrimenti

What this does not do

Ambito intenzionalmente limitato

Questo comando ha un ambito intenzionalmente limitato, non è una reimplementazione completa della semantica dei decorator di @nestjs/swagger: anyOf (nessun costrutto TS mappa su "any of" nel modo in cui un union type mappa naturalmente su oneOf), links/callbacks (@nestjs/swagger stesso non ha un'opzione decorator per nessuno dei due), e qualsiasi argomento di decorator che non sia un letterale (una variabile, una chiamata di funzione, uno spread) vengono lasciati intoccati invece di essere indovinati. È meglio lasciare un campo com'era già nel documento base che applicare una patch sbagliata. Un tipo di ritorno union o un payload @Body() diventa un oneOf solo quando ogni ramo risolve a un DTO/entità nominata. Le rotte che un file docs documenta ma che non esistono in --spec vengono riportate come avvisi, non scartate né trattate come errore in silenzio.