UNPKG

docusaurus-plugin-openapi-docs

Version:

OpenAPI plugin for Docusaurus.

154 lines (153 loc) 5.67 kB
"use strict"; /* ============================================================================ * Copyright (c) Palo Alto Networks * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * ========================================================================== */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertSwagger2OpenAPI = convertSwagger2OpenAPI; exports.loadAndResolveSpec = loadAndResolveSpec; const json_schema_ref_parser_1 = __importDefault(require("@apidevtools/json-schema-ref-parser")); const openapi_core_1 = require("@redocly/openapi-core"); const chalk_1 = __importDefault(require("chalk")); // @ts-ignore const swagger2openapi_1 = require("swagger2openapi"); const OpenAPIParser_1 = require("./services/OpenAPIParser"); function serializer(replacer, cycleReplacer) { var stack = [], keys = []; if (cycleReplacer === undefined) cycleReplacer = function (key, value) { if (stack[0] === value) return "circular()"; return value.title ? `circular(${value.title})` : "circular()"; }; return function (key, value) { // Resolve discriminator ref pointers if ((value === null || value === void 0 ? void 0 : value.discriminator) !== undefined) { const parser = new OpenAPIParser_1.OpenAPIParser(stack[0]); if (value.discriminator.mapping && typeof value.discriminator.mapping === "object") { for (let [k, v] of Object.entries(value.discriminator.mapping)) { const discriminator = k; if (typeof v === "string" && v.charAt(0) === "#") { const ref = v; const resolvedRef = parser.byRef(ref); value.discriminator.mapping[discriminator] = resolvedRef; } } } } if (stack.length > 0) { // @ts-ignore var thisPos = stack.indexOf(this); // @ts-ignore ~thisPos ? stack.splice(thisPos + 1) : stack.push(this); ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key); // @ts-ignore if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value); } else stack.push(value); // @ts-ignore return replacer === undefined ? value : replacer.call(this, key, value); }; } function convertSwagger2OpenAPI(spec) { console.warn("[ReDoc Compatibility mode]: Converting OpenAPI 2.0 to OpenAPI 3.0"); return new Promise((resolve, reject) => (0, swagger2openapi_1.convertObj)(spec, { patch: true, warnOnly: true, text: "{}", anchors: true, resolveInternal: true, }, (err, res) => { // TODO: log any warnings if (err) { return reject(err); } resolve(res && res.openapi); })); } async function resolveJsonRefs(specUrlOrObject) { try { let schema = await json_schema_ref_parser_1.default.dereference(specUrlOrObject, { continueOnError: true, resolve: { file: true, external: true, http: { timeout: 15000, // 15 sec timeout }, }, dereference: { circular: true, }, }); return schema; } catch (err) { let errorMsg = ""; if (err.errors[0] !== undefined) { const error = err.errors[0]; errorMsg = `Error: [${error.message}] with footprint [${error.footprint}]`; } else { errorMsg = err; } console.error(chalk_1.default.yellow(errorMsg)); return; } } async function loadAndResolveSpec(specUrlOrObject) { const config = new openapi_core_1.Config({}); const bundleOpts = { config, base: process.cwd(), }; if (typeof specUrlOrObject === "object" && specUrlOrObject !== null) { bundleOpts["doc"] = { source: { absoluteRef: "" }, parsed: specUrlOrObject, }; } else { bundleOpts["ref"] = specUrlOrObject; } // Force dereference ? // bundleOpts["dereference"] = true; const { bundle: { parsed }, } = await (0, openapi_core_1.bundle)(bundleOpts); //Pre-processing before resolving JSON refs if (parsed.components) { for (let [component, type] of Object.entries(parsed.components)) { if (component === "schemas") { for (let [schemaKey, schemaValue] of Object.entries(type)) { const title = schemaValue["title"]; if (!title) { schemaValue.title = schemaKey; } } } } } const resolved = await resolveJsonRefs(parsed); // Force serialization and replace circular $ref pointers // @ts-ignore const serialized = JSON.stringify(resolved, serializer()); let decycled; try { decycled = JSON.parse(serialized); } catch (err) { console.error(chalk_1.default.yellow(err)); } return decycled !== undefined && typeof decycled === "object" ? decycled.swagger !== undefined ? convertSwagger2OpenAPI(decycled) : decycled : resolved; }