Repository: nestjs/swagger
Pull request #2514 (2023-07-06 09:07:47)

fix: support defining `properties` for query-arguments of type objects
## 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)
- [x] ~Docs have been added / updated (for bug fixes / features)~ _N/A_


## PR Type
What kind of change does this PR introduce?

<!-- Please check the one that applies to this PR using "x". -->
- [x] Bugfix


## What is the current behavior?

When setting an object with a pre-defined list of properties as a Query-argument, the generated OpenAPI schema will have the `properties` key outside of the `schema` definition. This violates the OpenAPI spec.

https://github.com/addono/swagger/blob/038a366548beac5ffd392508e43225722d2184c6/e2e/api-spec.json#L362-L369

<img width="518" alt="image" src="https://github.com/nestjs/swagger/assets/15435678/259088f7-0d6f-40d9-9f59-d6eaa1397ac8">

<img width="750" alt="image" src="https://github.com/nestjs/swagger/assets/15435678/18a3a047-6758-4392-a7a1-db1975985377">

Issue Number: N/A


## What is the new behavior?

The `properties`-field is kept as a child of the `schema`-key.

https://github.com/Addono/swagger/blob/1e9a3386228e0bcb229027901e415b476dda7272/e2e/api-spec.json#L362-L373

<img width="514" alt="image" src="https://github.com/nestjs/swagger/assets/15435678/448ad0be-240f-401e-b1a9-36cd84361235">

<img width="521" alt="image" src="https://github.com/nestjs/swagger/assets/15435678/b3a1aa52-9295-455d-90fa-b5a79d68c757">


## Does this PR introduce a breaking change?
- [x] No

<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->


## Other information

This PR contains two commits:
 - First commit adds an example to the E2E tests which show how the generated spec is failing. For this commit, the E2E tests fail. This commit is there to allow reproducing the old behaviour.
 - Second commit fixes the behaviour and updates the expected spec in the E2E tests accordingly.

When merging, use squash-merge to avoid having a commit in the history for which the tests are known to fail.


Patch:
diff --git a/lib/services/swagger-types-mapper.ts b/lib/services/swagger-types-mapper.ts
index 110569b8..41abb12e 100644
--- a/lib/services/swagger-types-mapper.ts
+++ b/lib/services/swagger-types-mapper.ts
@@ -139,6 +139,7 @@ export class SwaggerTypesMapper {
 
   private getSchemaOptionsKeys(): Array<keyof SchemaObject> {
     return [
+      'properties',
       'patternProperties',
       'additionalProperties',
       'minimum',


Test patch:
diff --git a/e2e/api-spec.json b/e2e/api-spec.json
index 5cf27e9b..27b41ca7 100644
--- a/e2e/api-spec.json
+++ b/e2e/api-spec.json
@@ -360,6 +360,14 @@
             "required": true,
             "in": "query",
             "schema": {
+              "properties": {
+                "name": {
+                  "type": "string"
+                },
+                "age": {
+                  "type": "number"
+                }
+              },
               "additionalProperties": true,
               "type": "object"
             }
@@ -549,6 +557,14 @@
             "in": "query",
             "required": true,
             "schema": {
+              "properties": {
+                "name": {
+                  "type": "string"
+                },
+                "age": {
+                  "type": "number"
+                }
+              },
               "additionalProperties": true,
               "type": "object"
             }
diff --git a/e2e/src/cats/dto/pagination-query.dto.ts b/e2e/src/cats/dto/pagination-query.dto.ts
index 1572e871..a837af95 100644
--- a/e2e/src/cats/dto/pagination-query.dto.ts
+++ b/e2e/src/cats/dto/pagination-query.dto.ts
@@ -52,6 +52,14 @@ export class PaginationQuery {
 
   @ApiProperty({
     type: 'object',
+    properties: {
+      name: {
+        type: 'string'
+      },
+      age: {
+        type: 'number',
+      }
+    },
     additionalProperties: true
   })
   filter: Record<string, any>;