chore: move openapi validation and dereferencing to a worker (#4789)
This commit is contained in:
parent
c7a7ec3bb2
commit
3563e1eb16
3 changed files with 102 additions and 6 deletions
|
|
@ -27,13 +27,19 @@ import * as S from "fp-ts/string"
|
|||
import * as O from "fp-ts/Option"
|
||||
import * as TE from "fp-ts/TaskEither"
|
||||
import * as RA from "fp-ts/ReadonlyArray"
|
||||
import * as E from "fp-ts/Either"
|
||||
import { IMPORTER_INVALID_FILE_FORMAT } from "."
|
||||
import { cloneDeep, isNumber } from "lodash-es"
|
||||
import { getStatusCodeReasonPhrase } from "~/helpers/utils/statusCodes"
|
||||
|
||||
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))
|
||||
|
||||
|
|
@ -927,10 +933,7 @@ export const hoppOpenAPIImporter = (fileContents: string[]) =>
|
|||
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,
|
||||
})
|
||||
const validatedDoc = await validateDocs(docObj)
|
||||
|
||||
resultDoc.push(validatedDoc)
|
||||
} catch (err) {
|
||||
|
|
@ -969,7 +972,8 @@ export const hoppOpenAPIImporter = (fileContents: string[]) =>
|
|||
const resultDoc = []
|
||||
|
||||
for (const docObj of docArr) {
|
||||
const validatedDoc = await SwaggerParser.dereference(docObj)
|
||||
const validatedDoc = await dereferenceDocs(docObj)
|
||||
|
||||
resultDoc.push(validatedDoc)
|
||||
}
|
||||
|
||||
|
|
@ -981,3 +985,41 @@ export const hoppOpenAPIImporter = (fileContents: string[]) =>
|
|||
),
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
@ -27,6 +27,7 @@ export default defineConfig({
|
|||
define: {
|
||||
// For 'util' polyfill required by dep of '@apidevtools/swagger-parser'
|
||||
"process.env": {},
|
||||
"process.platform": '"browser"',
|
||||
},
|
||||
server: {
|
||||
port: 3000,
|
||||
|
|
|
|||
Loading…
Reference in a new issue