chore: move openapi validation and dereferencing to a worker (#4789)

This commit is contained in:
Akash K 2025-02-26 19:04:15 +05:30 committed by GitHub
parent c7a7ec3bb2
commit 3563e1eb16
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 102 additions and 6 deletions

View file

@ -27,13 +27,19 @@ import * as S from "fp-ts/string"
import * as O from "fp-ts/Option" import * as O from "fp-ts/Option"
import * as TE from "fp-ts/TaskEither" import * as TE from "fp-ts/TaskEither"
import * as RA from "fp-ts/ReadonlyArray" import * as RA from "fp-ts/ReadonlyArray"
import * as E from "fp-ts/Either"
import { IMPORTER_INVALID_FILE_FORMAT } from "." import { IMPORTER_INVALID_FILE_FORMAT } from "."
import { cloneDeep, isNumber } from "lodash-es" import { cloneDeep, isNumber } from "lodash-es"
import { getStatusCodeReasonPhrase } from "~/helpers/utils/statusCodes" import { getStatusCodeReasonPhrase } from "~/helpers/utils/statusCodes"
export const OPENAPI_DEREF_ERROR = "openapi/deref_error" as const export const OPENAPI_DEREF_ERROR = "openapi/deref_error" as const
// TODO: URL Import Support const worker = new Worker(
new URL("./workers/openapi-import-worker.ts", import.meta.url),
{
type: "module",
}
)
const safeParseJSON = (str: string) => O.tryCatch(() => JSON.parse(str)) const safeParseJSON = (str: string) => O.tryCatch(() => JSON.parse(str))
@ -927,10 +933,7 @@ export const hoppOpenAPIImporter = (fileContents: string[]) =>
throw new Error("INVALID_OPENAPI_SPEC") throw new Error("INVALID_OPENAPI_SPEC")
} }
const validatedDoc = await SwaggerParser.validate(docObj, { const validatedDoc = await validateDocs(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) { } catch (err) {
@ -969,7 +972,8 @@ export const hoppOpenAPIImporter = (fileContents: string[]) =>
const resultDoc = [] const resultDoc = []
for (const docObj of docArr) { for (const docObj of docArr) {
const validatedDoc = await SwaggerParser.dereference(docObj) const validatedDoc = await dereferenceDocs(docObj)
resultDoc.push(validatedDoc) resultDoc.push(validatedDoc)
} }
@ -981,3 +985,41 @@ export const hoppOpenAPIImporter = (fileContents: string[]) =>
), ),
TE.chainW(convertOpenApiDocsToHopp) TE.chainW(convertOpenApiDocsToHopp)
) )
const validateDocs = (docs: any): Promise<OpenAPI.Document> => {
return new Promise((resolve, reject) => {
worker.postMessage({
type: "validate",
docs,
})
worker.onmessage = (event) => {
if (event.data.type === "VALIDATION_RESULT") {
if (E.isLeft(event.data.data)) {
reject("COULD_NOT_VALIDATE")
} else {
resolve(event.data.data.right as OpenAPI.Document)
}
}
}
})
}
const dereferenceDocs = (docs: any): Promise<OpenAPI.Document> => {
return new Promise((resolve, reject) => {
worker.postMessage({
type: "dereference",
docs,
})
worker.onmessage = (event) => {
if (event.data.type === "DEREFERENCE_RESULT") {
if (E.isLeft(event.data.data)) {
reject("COULD_NOT_DEREFERENCE")
} else {
resolve(event.data.data.right as OpenAPI.Document)
}
}
}
})
}

View file

@ -0,0 +1,53 @@
import { Buffer } from "buffer"
import process from "process"
// Set up global shims for the swagger-parser library
self.Buffer = Buffer
self.global = self
self.process = process
import SwaggerParser from "@apidevtools/swagger-parser"
import * as E from "fp-ts/Either"
const validateDocs = async (docs: any) => {
try {
const res = await SwaggerParser.validate(docs, {
// @ts-expect-error - this is a valid option, but seems like the types are not updated
continueOnError: true,
})
return E.right(res)
} catch (error) {
return E.left("COULD_NOT_VALIDATE" as const)
}
}
const dereferenceDocs = async (docs: any) => {
try {
const res = await SwaggerParser.dereference(docs)
return E.right(res)
} catch (error) {
return E.left("COULD_NOT_DEREFERENCE" as const)
}
}
self.addEventListener("message", async (event) => {
if (event.data.type === "validate") {
const res = await validateDocs(event.data.docs)
self.postMessage({
type: "VALIDATION_RESULT",
data: res,
})
}
if (event.data.type === "dereference") {
const res = await dereferenceDocs(event.data.docs)
self.postMessage({
type: "DEREFERENCE_RESULT",
data: res,
})
}
})

View file

@ -27,6 +27,7 @@ export default defineConfig({
define: { define: {
// For 'util' polyfill required by dep of '@apidevtools/swagger-parser' // For 'util' polyfill required by dep of '@apidevtools/swagger-parser'
"process.env": {}, "process.env": {},
"process.platform": '"browser"',
}, },
server: { server: {
port: 3000, port: 3000,