Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NestJS Swagger Plugin when used with SWC references undeclared variable #2636

Open
3 of 15 tasks
evanwhitten opened this issue Sep 26, 2023 · 6 comments
Open
3 of 15 tasks

Comments

@evanwhitten
Copy link

evanwhitten commented Sep 26, 2023

Is there an existing issue for this?

  • 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

  1. 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
Screenshot 2023-09-26 at 4 36 46 PM

With SWC
Screenshot 2023-09-26 at 4 37 39 PM

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
  • 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?

  • macOS
  • Windows
  • Linux

Other

No response

@evanwhitten
Copy link
Author

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

@utrumo
Copy link

utrumo commented Oct 6, 2023

@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" {} \;

@m0x61h0x64i
Copy link

I have same issue, any updates?

@evanwhitten
Copy link
Author

evanwhitten commented Dec 14, 2023

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.

@m0x61h0x64i
Copy link

@evanwhitten That does not solve the issue, dto classes are already being exported

@czfadmin
Copy link

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类已经被导出。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants