From 453947609f33e921c41e58a0f2c5f9b8184cbd3d Mon Sep 17 00:00:00 2001 From: Freek van Rijt Date: Wed, 10 Apr 2024 12:59:58 +0200 Subject: [PATCH] refactor(open-api): resolve type safety issues and create util file for OpenAPI type guards INT-407 --- .../client/components/global/OpenApi.vue | 36 ++++++++++++------- .../client/components/global/OpenApiPath.vue | 11 +++--- .../components/global/OpenApiResponses.vue | 6 +--- .../components/global/OpenApiSchema.vue | 11 +----- .../theme/client/utils/openApiGuards.ts | 22 ++++++++++++ 5 files changed, 51 insertions(+), 35 deletions(-) create mode 100644 src/.vuepress/theme/client/utils/openApiGuards.ts diff --git a/src/.vuepress/theme/client/components/global/OpenApi.vue b/src/.vuepress/theme/client/components/global/OpenApi.vue index fed8f5a5..64d78f98 100644 --- a/src/.vuepress/theme/client/components/global/OpenApi.vue +++ b/src/.vuepress/theme/client/components/global/OpenApi.vue @@ -27,22 +27,32 @@ const props = defineProps<{ const resolvedDocument = computed(() => resolveRefs(props.document)); // Recursively loop through the entire document and replace any $ref keys with their corresponding values +type RecursiveType = { + [key: string]: unknown | RecursiveType | RecursiveType[]; +}; + function resolveRefs(document: OpenApiType.Document): OpenApiType.Document { const resolvedDocument = {...document}; - function resolveRefsRecursive(obj: object | (string | number | object)[]) { - for (const key in obj) { - if (key === '$ref') { - const lookup = (obj as {$ref: string})[key]; - // Lookup is a string that defines the path to the referenced object like '#/components/schemas/Example' - const path = lookup.split('/').slice(1); - // Find the referenced object in the document using lodash's get function - const referencedObject = get(resolvedDocument, path); - // Remove the $ref: '...' key from the object and replace it with the referenced object itself - obj = Object.assign(obj, referencedObject); - } else if (typeof obj[key] === 'object' || Array.isArray(obj[key])) { - // If the value is an object or an array, recursively call this function - resolveRefsRecursive(obj[key]); + function resolveRefsRecursive(obj: RecursiveType) { + if (Array.isArray(obj)) { + for (const item of obj) { + resolveRefsRecursive(item); + } + } else if (typeof obj === 'object') { + for (const key in obj) { + if (key === '$ref') { + // Lookup is a string that defines the path to the referenced object like '#/components/schemas/Example' + const path = key.split('/').slice(1); + // Find the referenced object in the document using lodash's get function + const referencedObject = get(resolvedDocument, path); + // Remove the $ref: '...' key from the object and replace it with the referenced object itself + obj = Object.assign(obj, referencedObject); + } else if (typeof obj[key] === 'object' || Array.isArray(obj[key])) { + const guarded = obj[key] as RecursiveType; + // If the value is an object or an array, recursively call this function + resolveRefsRecursive(guarded); + } } } } diff --git a/src/.vuepress/theme/client/components/global/OpenApiPath.vue b/src/.vuepress/theme/client/components/global/OpenApiPath.vue index d2c0c94b..4c1548a1 100644 --- a/src/.vuepress/theme/client/components/global/OpenApiPath.vue +++ b/src/.vuepress/theme/client/components/global/OpenApiPath.vue @@ -48,7 +48,9 @@ v-for="(content, key) in operation.requestBody.content" :key="key"> {{ key }} - + @@ -63,6 +65,7 @@ diff --git a/src/.vuepress/theme/client/components/global/OpenApiResponses.vue b/src/.vuepress/theme/client/components/global/OpenApiResponses.vue index a0bf47c0..d7efaa44 100644 --- a/src/.vuepress/theme/client/components/global/OpenApiResponses.vue +++ b/src/.vuepress/theme/client/components/global/OpenApiResponses.vue @@ -65,6 +65,7 @@