Repository: nestjs/swagger
Pull request #1770 (2022-01-11 16:02:57)

feat: add plugin support for bigint
## PR Checklist
Please check if your PR fulfills the following requirements:

- [x] The commit message follows our guidelines: https://github.com/nestjs/nest/blob/master/CONTRIBUTING.md
- [x] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)


## PR Type
What kind of change does this PR introduce?

<!-- Please check the one that applies to this PR using "x". -->
- [ ] Bugfix
- [x] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Other... Please describe:

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->

Issue Number: #1768 


## What is the new behavior?
The CLI plugin will now automatically annotate bigint properties and will not throw a `Cicular dependency error` when stumbling upon a bigint property.

## Does this PR introduce a breaking change?
- [ ] Yes
- [x] No

<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->


## Other information



Patch:
diff --git a/lib/plugin/utils/ast-utils.ts b/lib/plugin/utils/ast-utils.ts
index 815e4aee..2f1299ac 100644
--- a/lib/plugin/utils/ast-utils.ts
+++ b/lib/plugin/utils/ast-utils.ts
@@ -50,6 +50,10 @@ export function isNumber(type: Type) {
   return hasFlag(type, TypeFlags.Number);
 }
 
+export function isBigInt(type: Type) {
+  return hasFlag(type, TypeFlags.BigInt);
+}
+
 export function isInterface(type: Type) {
   return hasObjectFlag(type, ObjectFlags.Interface);
 }
diff --git a/lib/plugin/utils/plugin-utils.ts b/lib/plugin/utils/plugin-utils.ts
index 51a157c7..ed224400 100644
--- a/lib/plugin/utils/plugin-utils.ts
+++ b/lib/plugin/utils/plugin-utils.ts
@@ -10,6 +10,7 @@ import {
   isEnum,
   isInterface,
   isNumber,
+  isBigInt,
   isString,
   isStringLiteral
 } from './ast-utils';
@@ -46,6 +47,9 @@ export function getTypeReferenceAsString(
   if (isNumber(type)) {
     return Number.name;
   }
+  if (isBigInt(type)) {
+    return BigInt.name;
+  }
   if (isString(type) || isStringLiteral(type)) {
     return String.name;
   }
diff --git a/lib/services/schema-object-factory.ts b/lib/services/schema-object-factory.ts
index 45d0a4ce..0a9d345d 100644
--- a/lib/services/schema-object-factory.ts
+++ b/lib/services/schema-object-factory.ts
@@ -500,6 +500,14 @@ export class SchemaObjectFactory {
         name: metadata.name || key
       };
     }
+    if (this.isBigInt(trueType as Function)) {
+      return {
+        format: 'int64',
+        ...metadata,
+        type: 'integer',
+        name: metadata.name || key
+      };
+    }
     if (!isBuiltInType(trueType as Function)) {
       return this.createNotBuiltInTypeReference(
         key,
@@ -569,6 +577,10 @@ export class SchemaObjectFactory {
     return Object.getPrototypeOf(obj) === objPrototype;
   }
 
+  private isBigInt(type: Function | Type<unknown> | string): boolean {
+    return type === BigInt;
+  }
+
   private extractPropertyModifiers(
     metadata: SchemaObjectMetadata
   ): [Partial<SchemaObjectMetadata>, string[]] {


Test patch:
diff --git a/test/plugin/fixtures/create-cat-alt.dto.ts b/test/plugin/fixtures/create-cat-alt.dto.ts
index 71c8fc77..488ecab9 100644
--- a/test/plugin/fixtures/create-cat-alt.dto.ts
+++ b/test/plugin/fixtures/create-cat-alt.dto.ts
@@ -41,6 +41,7 @@ export class CreateCatDto2 {
   prop: {
     [x: string]: string;
   }
+  amount: bigint;
 }
 `;
 
@@ -56,7 +57,7 @@ export class CreateCatDto2 {
         this.status = Status.ENABLED;
     }
     static _OPENAPI_METADATA_FACTORY() {
-        return { name: { required: true, type: () => String }, age: { required: true, type: () => Number, default: 3 }, tags: { required: true, type: () => [String] }, status: { required: true, default: Status.ENABLED, enum: Status }, breed: { required: false, type: () => String }, nodes: { required: true, type: () => [Object] }, alias: { required: true, type: () => Object }, numberAlias: { required: true, type: () => Number, description: "NumberAlias" }, union: { required: true, type: () => Object }, intersection: { required: true, type: () => Object }, nested: { required: true, type: () => ({ first: { required: true, type: () => String }, second: { required: true, type: () => Number }, status: { required: true, enum: Status }, tags: { required: true, type: () => [String] }, nodes: { required: true, type: () => [Object] }, alias: { required: true, type: () => Object }, numberAlias: { required: true, type: () => Number } }) } };
+        return { name: { required: true, type: () => String }, age: { required: true, type: () => Number, default: 3 }, tags: { required: true, type: () => [String] }, status: { required: true, default: Status.ENABLED, enum: Status }, breed: { required: false, type: () => String }, nodes: { required: true, type: () => [Object] }, alias: { required: true, type: () => Object }, numberAlias: { required: true, type: () => Number, description: "NumberAlias" }, union: { required: true, type: () => Object }, intersection: { required: true, type: () => Object }, nested: { required: true, type: () => ({ first: { required: true, type: () => String }, second: { required: true, type: () => Number }, status: { required: true, enum: Status }, tags: { required: true, type: () => [String] }, nodes: { required: true, type: () => [Object] }, alias: { required: true, type: () => Object }, numberAlias: { required: true, type: () => Number } }) }, amount: { required: true, type: () => BigInt } };
     }
 }
 __decorate([
diff --git a/test/services/fixtures/create-user.dto.ts b/test/services/fixtures/create-user.dto.ts
index 38a45a8a..53d7db16 100644
--- a/test/services/fixtures/create-user.dto.ts
+++ b/test/services/fixtures/create-user.dto.ts
@@ -93,6 +93,9 @@ export class CreateUserDto {
   @ApiProperty()
   createdAt: Date;
 
+  @ApiProperty()
+  amount: bigint;
+
   static _OPENAPI_METADATA_FACTORY() {
     return {
       tags: { type: () => [String] },
diff --git a/test/services/schema-object-factory.spec.ts b/test/services/schema-object-factory.spec.ts
index 3df7f5c5..6222b22a 100644
--- a/test/services/schema-object-factory.spec.ts
+++ b/test/services/schema-object-factory.spec.ts
@@ -113,6 +113,10 @@ describe('SchemaObjectFactory', () => {
             format: 'int64',
             example: 10
           },
+          amount: {
+            type: 'integer',
+            format: 'int64'
+          },
           createdAt: {
             format: 'date-time',
             type: 'string'
@@ -206,7 +210,8 @@ describe('SchemaObjectFactory', () => {
           'options',
           'allOf',
           'houses',
-          'createdAt'
+          'createdAt',
+          'amount'
         ]
       });
       expect(schemas['CreateProfileDto']).toEqual({