UNPKG

@scalar/api-reference

Version:

Generate beautiful API references from OpenAPI documents

119 lines (118 loc) 3.25 kB
import { isDereferenced } from "@scalar/openapi-types/helpers"; import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref"; function formatProperty(key, obj) { let output = key; const isRequired = obj.required?.includes(key); output += isRequired ? " REQUIRED " : " optional "; const property = getResolvedRef(obj.properties?.[key]); if (property) { output += property.type; if (property.description) { output += " " + property.description; } } return output; } function recursiveLogger(obj) { const results = ["Body"]; const schema = getResolvedRef(obj?.schema); const properties = schema?.properties; if (properties) { Object.keys(properties).forEach((key) => { if (!obj.schema) { return; } results.push(formatProperty(key, schema)); const property = getResolvedRef(properties[key]); const isNestedObject = property.type === "object" && Boolean(property.properties); if (isNestedObject && property.properties) { Object.keys(property.properties).forEach((subKey) => { results.push(`${subKey} ${getResolvedRef(property.properties?.[subKey])?.type}`); }); } }); } return results; } function extractRequestBody(operation) { try { const media = getResolvedRef(operation?.requestBody)?.content?.["application/json"]; if (!media) { throw new Error("Body not found"); } return recursiveLogger(media); } catch (_error) { return false; } } function deepMerge(source, target) { for (const [key, val] of Object.entries(source)) { if (val !== null && typeof val === "object") { target[key] ??= new val.__proto__.constructor(); deepMerge(val, target[key]); } else if (typeof val !== "undefined") { target[key] = val; } } return target; } function createEmptySpecification(partialSpecification) { return deepMerge(partialSpecification ?? {}, { info: { title: "", description: "", termsOfService: "", version: "", license: { name: "", url: "" }, contact: { email: "" } }, servers: [], tags: [] }); } function createParameterMap(operation) { const map = { path: [], query: [], header: [], cookie: [], body: [], formData: [] }; const parameters = operation.parameters ?? []; if (parameters) { parameters.forEach((parameter) => { if (!isDereferenced(parameter)) { return; } if (typeof parameter === "object" && parameter !== null && "$ref" in parameter) { return; } if (parameter.in === "path") { map.path.push(parameter); } else if (parameter.in === "query") { map.query.push(parameter); } else if (parameter.in === "header") { map.header.push(parameter); } else if (parameter.in === "cookie") { map.cookie.push(parameter); } else if (parameter.in === "body") { map.body.push(parameter); } else if (parameter.in === "formData") { map.formData.push(parameter); } }); } return map; } export { createEmptySpecification, createParameterMap, deepMerge, extractRequestBody };