Last active
December 8, 2021 18:53
-
-
Save gioragutt/c29b35aaf805f7eb9de270f89f76f843 to your computer and use it in GitHub Desktop.
nestjs swagger helper for extracting inline schemas to the document schemas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable @typescript-eslint/no-explicit-any */ | |
import { getSchemaPath, OpenAPIObject } from '@nestjs/swagger'; | |
import _set from 'lodash.set'; | |
import _get from 'lodash.get'; | |
function flattenObject(theObject: any): Record<string, any> { | |
const toReturn: any = {}; | |
for (const objectKey in theObject) { | |
if (!Object.prototype.hasOwnProperty.call(theObject, objectKey)) { | |
continue; | |
} | |
if (typeof theObject[objectKey] == 'object') { | |
const flatObject = flattenObject(theObject[objectKey] as any); | |
for (const x in flatObject) { | |
if (!Object.prototype.hasOwnProperty.call(flatObject, x)) { | |
continue; | |
} | |
toReturn[objectKey + '.' + x] = flatObject[x]; | |
} | |
} else { | |
toReturn[objectKey] = theObject[objectKey]; | |
} | |
} | |
return toReturn; | |
} | |
/** | |
* # What is this? | |
* | |
* The plugin goes over endpoint definitions, looks for responses that are titles `PaginatedResponseOf(.*)`, | |
* And moves them to the global schemas section of the document, replacing the response scheme to reference them. | |
* | |
* # Why is it needed? | |
* | |
* 1. Without that, you don't get an accurate schema definition in the definitions section, | |
* Which is bad for user experience | |
* 2. And this is the bad one, openapi-generator-cli with the typescript-fetch template generates broken code, | |
* Because it does not take the `title` of the inline schema as the name of the schema. | |
* Example code: `PaginationResponseDTO & objectFromJson(value)` instead of `PaginatedResponseOfMyModelFromJson(value)` | |
*/ | |
export function extractPaginatedResponsesToDefinitions(document: OpenAPIObject): void { | |
const flattenedSwagger = flattenObject(document); | |
const keys = Object.keys(flattenedSwagger); | |
keys | |
.filter(k => k.endsWith('schema.title')) | |
.forEach(key => { | |
const title = flattenedSwagger[key]; | |
if (!title.startsWith('PaginatedResponseOf')) { | |
return; | |
} | |
const schemaKey = key.replace('.title', ''); | |
const schema = _get(document, schemaKey); | |
_set(document, schemaKey, { | |
$ref: getSchemaPath(title), | |
}); | |
document.components.schemas[title] = schema; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A workaround was found, so this is here for backup and documentation of hardships of the process