NestJS Swagger Plugin when used with SWC references undeclared variable
Is there an existing issue for this?
- [X] I have searched the existing issues
Current behavior
When @nestjs/swagger CLI plugin is used alongside SWC, it generates output in the metadata.ts from the PluginMetadataGenerator that includes undeclared variables. These variables inside the metadata.ts trigger failures when type checking, also during runtime if the metadata is attempted to be used somewhere like loadPluginMetadata.
In my reproduction I have HelloClass and HelloClassSeperate demonstrating that this bug is only present when the class exists in the same file as the DTO.
✔ TSC Initializing type checker...
> TSC Found 0 issues. Generating metadata...
> SWC Running...
Successfully compiled: 8 files with swc (7.99ms)
[Nest] 3860 - 09/26/2023, 4:46:59 PM LOG [NestFactory] Starting Nest application...
[Nest] 3860 - 09/26/2023, 4:46:59 PM LOG [InstanceLoader] AppModule dependencies initialized +6ms
/Users/evanwhitten/Git/reproduce-cli-swagger-reference/dist/metadata.js:76
HelloClass
^
ReferenceError: HelloClass is not defined
at Object.type (/Users/evanwhitten/Git/reproduce-cli-swagger-reference/dist/metadata.js:76:41)
at SchemaObjectFactory.mergePropertyWithMetadata (/Users/evanwhitten/Git/reproduce-cli-swagger-reference/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:127:38)
at /Users/evanwhitten/Git/reproduce-cli-swagger-reference/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:82:35
at Array.map (<anonymous>)
at SchemaObjectFactory.extractPropertiesFromType (/Users/evanwhitten/Git/reproduce-cli-swagger-reference/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:81:52)
at SchemaObjectFactory.exploreModelSchema (/Users/evanwhitten/Git/reproduce-cli-swagger-reference/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:103:41)
at ResponseObjectFactory.create (/Users/evanwhitten/Git/reproduce-cli-swagger-reference/node_modules/@nestjs/swagger/dist/services/response-object-factory.js:46:47)
at /Users/evanwhitten/Git/reproduce-cli-swagger-reference/node_modules/@nestjs/swagger/dist/explorers/api-response.explorer.js:67:101
at /Users/evanwhitten/Git/reproduce-cli-swagger-reference/node_modules/lodash/lodash.js:13469:38
at /Users/evanwhitten/Git/reproduce-cli-swagger-reference/node_modules/lodash/lodash.js:4967:15
metadata.ts -> Problem area: { required: true, type: () => [HelloClass] }
export default async () => {
const t = {
["./seperate.dto"]: await import("./seperate.dto"),
["./app.dto"]: await import("./app.dto")
};
return { "@nestjs/swagger": { "models": [[import("./seperate.dto"), { "HelloClassSeperate": { name: { required: true, type: () => String } } }], [import("./app.dto"), { "GetHelloDto": { hello: { required: true, type: () => [HelloClass] } }, "GetHelloSeperateDto": { hello: { required: true, type: () => [t["./seperate.dto"].HelloClassSeperate] } } }]], "controllers": [[import("./app.controller"), { "AppController": { "getHello": { type: t["./app.dto"].GetHelloDto }, "getHelloSeperate": { type: t["./app.dto"].GetHelloSeperateDto } } }]] } };
};
Minimum reproduction code
https://github.com/evanwhitten/reproduce-cli-swagger-reference
Steps to reproduce
nest start -b swc --type-check-> view error from invalid metadata.ts generated
Expected behavior
Expected to have Swagger definitions generated the same as when running the app without SWC.
Without SWC
With SWC
Package
- [ ] I don't know. Or some 3rd-party package
- [ ]
@nestjs/common - [ ]
@nestjs/core - [ ]
@nestjs/microservices - [ ]
@nestjs/platform-express - [ ]
@nestjs/platform-fastify - [ ]
@nestjs/platform-socket.io - [ ]
@nestjs/platform-ws - [ ]
@nestjs/testing - [ ]
@nestjs/websockets - [X] Other (see below)
Other package
@nestjs/swagger
NestJS version
10.2.6
Packages versions
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/swagger": "^7.1.12",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@swc/cli": "^0.1.62",
"@swc/core": "^1.3.89",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/supertest": "^2.0.12",
"@typescript-eslint/eslint-plugin": "^5.59.11",
"@typescript-eslint/parser": "^5.59.11",
"eslint": "^8.42.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.5.0",
"prettier": "^2.8.8",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
},
Node.js version
v18.16.1
In which operating systems have you tested?
- [X] macOS
- [ ] Windows
- [ ] Linux
Other
No response
I believe I have narrowed this down to these lines, however it seems to be above my TS abilities to triage further.
https://github.com/nestjs/swagger/blob/master/lib/plugin/visitors/model-class.visitor.ts#L186-L193
@evanwhitten, I faced the same problem.
The problem occurs because the required dtos are not exported from the files.
Here's how to get a list of dto to export:
clear;yarn tsc --noEmit --pretty false | cut -d: -f '3' | sed -Ee "s/.*'(.*)'.*/\1/g" | sort | uniq
And here is a regular expression to add exports throughout the project (in parentheses you need to substitute your dto names without exports):
find ./ -type f -exec sed -i -Ee "/export /! s/(class DtoWithoutExportOne|class DtoWithoutExportTwo)/export \1/g" {} \;
I have same issue, any updates?
I have same issue, any updates?
As mentioned by @utrumo, you can workaround this by exporting the class.
In my example exporting this class , resolves the error.
@evanwhitten That does not solve the issue, dto classes are already being exported
Hello, I also encountered the same problem, but I used the method you provided and it did not solve the problem.
@evanwhitten That does not solve the issue, dto classes are already being exported这并不能解决问题,dto类已经被导出。