chore: continue openapi imports on error with a partial import (#4535)
This commit is contained in:
@@ -48,6 +48,42 @@ const objectHasProperty = <T extends string>(
|
|||||||
typeof obj === "object" &&
|
typeof obj === "object" &&
|
||||||
Object.prototype.hasOwnProperty.call(obj, propName)
|
Object.prototype.hasOwnProperty.call(obj, propName)
|
||||||
|
|
||||||
|
// basic validation for OpenAPI V2 Document
|
||||||
|
const isOpenAPIV2Document = (doc: unknown): doc is OpenAPIV2.Document => {
|
||||||
|
return (
|
||||||
|
objectHasProperty(doc, "swagger") &&
|
||||||
|
typeof doc.swagger === "string" &&
|
||||||
|
doc.swagger === "2.0"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic validation for OpenAPI V3 Document
|
||||||
|
const isOpenAPIV3Document = (
|
||||||
|
doc: unknown
|
||||||
|
): doc is OpenAPIV3.Document | OpenAPIV31.Document => {
|
||||||
|
return (
|
||||||
|
objectHasProperty(doc, "openapi") &&
|
||||||
|
typeof doc.openapi === "string" &&
|
||||||
|
doc.openapi.startsWith("3.")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasRequiredOpenAPIFields = (doc: unknown): boolean => {
|
||||||
|
return (
|
||||||
|
objectHasProperty(doc, "info") &&
|
||||||
|
objectHasProperty(doc.info, "title") &&
|
||||||
|
objectHasProperty(doc.info, "version") &&
|
||||||
|
objectHasProperty(doc, "paths")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isABasicOpenAPIDoc = (doc: unknown): boolean => {
|
||||||
|
return (
|
||||||
|
(isOpenAPIV2Document(doc) || isOpenAPIV3Document(doc)) &&
|
||||||
|
hasRequiredOpenAPIFields(doc)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
type OpenAPIPathInfoType =
|
type OpenAPIPathInfoType =
|
||||||
| OpenAPIV2.PathItemObject<Record<string, unknown>>
|
| OpenAPIV2.PathItemObject<Record<string, unknown>>
|
||||||
| OpenAPIV3.PathItemObject<Record<string, unknown>>
|
| OpenAPIV3.PathItemObject<Record<string, unknown>>
|
||||||
@@ -869,8 +905,39 @@ export const hoppOpenAPIImporter = (fileContents: string[]) =>
|
|||||||
const resultDoc = []
|
const resultDoc = []
|
||||||
|
|
||||||
for (const docObj of docArr) {
|
for (const docObj of docArr) {
|
||||||
const validatedDoc = await SwaggerParser.validate(docObj)
|
try {
|
||||||
|
const isValidOpenAPISpec = isABasicOpenAPIDoc(docObj)
|
||||||
|
|
||||||
|
if (!isValidOpenAPISpec) {
|
||||||
|
throw new Error("INVALID_OPENAPI_SPEC")
|
||||||
|
}
|
||||||
|
|
||||||
|
const validatedDoc = await SwaggerParser.validate(docObj, {
|
||||||
|
// @ts-expect-error - this is a valid option, but seems like the types are not updated
|
||||||
|
continueOnError: true,
|
||||||
|
})
|
||||||
|
|
||||||
resultDoc.push(validatedDoc)
|
resultDoc.push(validatedDoc)
|
||||||
|
} catch (err) {
|
||||||
|
if (
|
||||||
|
err instanceof Error &&
|
||||||
|
err.message === "INVALID_OPENAPI_SPEC"
|
||||||
|
) {
|
||||||
|
throw new Error("INVALID_OPENAPI_SPEC")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
// @ts-expect-error the type for err is not exported from the library
|
||||||
|
err.files &&
|
||||||
|
// @ts-expect-error the type for err is not exported from the library
|
||||||
|
err.files instanceof SwaggerParser &&
|
||||||
|
// @ts-expect-error the type for err is not exported from the library
|
||||||
|
err.files.schema
|
||||||
|
) {
|
||||||
|
// @ts-expect-error the type for err is not exported from the library
|
||||||
|
resultDoc.push(err.files.schema)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultDoc
|
return resultDoc
|
||||||
|
|||||||
Reference in New Issue
Block a user