typeorm: 0.3.20 regression with NestJS, TypeORM and Swagger

Issue description

Upgrading to 0.3.20 broke NestJS + Swagger integration, downgrading to 0.3.19 fixes the issue

Expected Behavior

not regression

Actual Behavior

regression

Steps to reproduce

https://github.com/OSA413/nestjs-bug-swagger-api-property

My Environment

Dependency Version
Operating System Windows 10
Node.js version 18.17.1
Typescript version not applicable i think
TypeORM version 0.3.20

Additional Context

Reposted from NestJS’ Discord So, I recently updated packages and Swagger started to throw errors related to @ApiProperty (Optional) and circular dependency though a week ago it was just fine. I’ve managed to make an MRE from the whole project, here it is: https://github.com/OSA413/nestjs-bug-swagger-api-property

The DTO looks like this:

export class Testttttttttt {
    @ApiProperty()
    public id: string;
}

It’s very interesting, because 1) it doesn’t specify any type in the annotation, 2) it’s a scalar type

Some other investigations:

  1. The bug goes away if I remove TypeORM import from the AppModule
  2. The bug may disappear if I leave only one controller by combining two of them
  3. The bug may disappear if I move DTO into the same file as controller

For easier reproduction of the example I provided you’ll need a Docker (because you need to connect to DB)

Package versions are listed in the repository, package.lock is provided

Here’s the log

[14:50:50] Starting compilation in watch mode...

[14:50:52] Found 0 errors. Watching for file changes.

[Nest] 12856  - 31.01.2024, 14:50:53     LOG [NestFactory] Starting Nest application...
[Nest] 12856  - 31.01.2024, 14:50:53     LOG [InstanceLoader] TypeOrmModule dependencies initialized +46ms
[Nest] 12856  - 31.01.2024, 14:50:53     LOG [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 12856  - 31.01.2024, 14:50:53     LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +22ms

C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:187
            throw new Error(`A circular dependency has been detected (property key: "${key}"). Please, make sure that each side of a bidirectional relationships are using lazy resolvers ("type: () => ClassType").`);
                  ^
Error: A circular dependency has been detected (property key: "id"). Please, make sure that each side of a bidirectional relationships are using lazy resolvers ("type: () => ClassType").
    at SchemaObjectFactory.createNotBuiltInTypeReference (C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:187:19)
    at SchemaObjectFactory.createSchemaMetadata (C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:297:25)
    at SchemaObjectFactory.mergePropertyWithMetadata (C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:131:21)
    at C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:82:35
    at Array.map (<anonymous>)
    at SchemaObjectFactory.extractPropertiesFromType (C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:81:52)
    at SchemaObjectFactory.exploreModelSchema (C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:103:41)
    at C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:36:36
    at Array.map (<anonymous>)
    at SchemaObjectFactory.createFromModel (C:\Users\Oleg.Sokolov\Documents\GitHub\nestjs-bug-swagger-api-property\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:20:45)

After investigation I figured out that downgrading typeorm from 0.3.20 to 0.3.19 fixes the issue.

Relevant Database Driver(s)

  • aurora-mysql
  • aurora-postgres
  • better-sqlite3
  • cockroachdb
  • cordova
  • expo
  • mongodb
  • mysql
  • nativescript
  • oracle
  • postgres
  • react-native
  • sap
  • spanner
  • sqlite
  • sqlite-abstract
  • sqljs
  • sqlserver

Are you willing to resolve this issue by submitting a Pull Request?

No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.

About this issue

  • Original URL
  • State: open
  • Created 5 months ago
  • Reactions: 5
  • Comments: 22 (10 by maintainers)

Most upvoted comments

@OSA413 just a quick note that after walking through changes introduced in the latest version of reflect-metadata I believe typeorm should consider setting reflect-metadata as a peer dependency (otherwise similar issues might keep occurring in the future)

For example, this issue could be solved without affecting any projects using TypeORM in combination with any other libs that rely on reflect-metadata by setting reflect-metadata as a peer dependency with "^0.1.14 || ^0.2.0" constraint and removing it from deps array

I’m not clear on the issue the latest update to reflect-metadata caused, and I’d like to address it if possible. In the recent changes to reflect-metadata I was trying to make it so that the package is more reliable when different versions are installed by having them share a central metadata store. If that is breaking, I’d love to get more details as to why and a suitable repro so that I can try to address it.

Here’s a pretty basic reproduction repository with instructions in the README file https://github.com/phuffer/controller-broken-example/

This should be fixed in reflect-metadata@0.2.2 and it now should be able to load side-by-side with reflect-metadata@0.1.x

Both npm and yarn automatically install peer dependencies now

the way peer deps work changed so many times that I’m not really sure how they currently work.

Technically the only thing that would change is that now package managers, be it npm or yarn, would know that reflect-metadata should be automatically “hoisted” as it’s supposed to be shared between packages that also rely on reflect-metadata. Currently, it’s installed as an internal dependency and hoisted only in case installed versions match (deduped)

If nothing will be broken and it’s that much of the issue right now, I can apply suggested changes.

I’ll wait for somebody to create a PR.

I can confirm that this is fixed after version update (and clean package install)

"@nestjs/common": "^10.3.2",
"@nestjs/core": "^10.3.2",

Source: https://github.com/nestjs/swagger/issues/2821#issuecomment-1931766882

Thank you @rbuckton. I just did a quick test and it seems to work as expected now (needs confirmation though).

In this case, upgrading the reflect-metadata dependency to the latest version in typeorm may be sufficient to fix this issue (without even moving it from deps to peer deps) @pleerock