UNPKG

@alova/wormhole

Version:

More modern openAPI generating solution for alova.js

152 lines (151 loc) 5.48 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPlatformOpenApiData = getPlatformOpenApiData; exports.getOpenApiData = getOpenApiData; const promises_1 = __importDefault(require("node:fs/promises")); const node_path_1 = __importDefault(require("node:path")); const import_fresh_1 = __importDefault(require("import-fresh")); const js_yaml_1 = __importDefault(require("js-yaml")); const swagger2openapi_1 = __importDefault(require("swagger2openapi")); const helper_1 = require("../../../helper"); const utils_1 = require("../../../utils"); const supportedExtname = ['json', 'yaml']; const supportedPlatformType = ['swagger']; function isSwagger2(data) { return !!data?.swagger; } // Parse local openapi files async function parseLocalFile(url, projectPath = process.cwd()) { const [, extname] = /\.([^.]+)$/.exec(url) ?? []; if (!supportedExtname.includes(extname)) { throw helper_1.logger.throwError(`Unsupported file type: ${extname}`, { url, projectPath, }); } switch (extname) { case 'yaml': { const file = await promises_1.default.readFile(node_path_1.default.resolve(projectPath, url), 'utf-8'); const data = js_yaml_1.default.load(file); return data; } // Json default: { const data = (0, import_fresh_1.default)(node_path_1.default.resolve(projectPath, url)); return data; } } } // Parse remote openapi files async function parseRemoteFile(url, platformType) { // no extension and platform types if (platformType) { return getPlatformOpenApiData(url, platformType); } const dataText = (await (0, utils_1.fetchData)(url)) ?? ''; let data; try { // 尝试解析为 JSON 格式 data = JSON.parse(dataText); } catch (jsonError) { try { // 若 JSON 解析失败,尝试解析为 YAML 格式 data = js_yaml_1.default.load(dataText); } catch (yamlError) { throw helper_1.logger.throwError(`Only JSON and YAML formats are supported. Parsing failed: ${jsonError instanceof Error ? jsonError.message : String(jsonError)} ${yamlError instanceof Error ? yamlError.message : String(yamlError)}`, { url, }); } } // Validate if the data is valid (prevent server from returning error responses) if (!isValidOpenApiData(data)) { throw new Error(`Data retrieved from URL ${url} is not a valid OpenAPI document`); } return data; } // Parse platform openapi files function isValidOpenApiData(data) { if (!data || typeof data !== 'object') { return false; } // Check if it's an error response format (e.g., {"code": -1, "msg": "URL does not exist", "data": null}) if (data.code !== undefined && data.msg !== undefined) { return false; } // Check if it contains required OpenAPI/Swagger structure return !!(data.openapi || data.swagger || data.info || data.paths); } async function getPlatformOpenApiData(url, platformType) { if (!supportedPlatformType.includes(platformType)) { throw helper_1.logger.throwError(`Platform type ${platformType} is not supported.`, { url, platformType, }); } switch (platformType) { case 'swagger': { const urlsToTry = [url, `${url}/openapi.json`, `${url}/v2/swagger.json`]; for (const tryUrl of urlsToTry) { try { const dataText = await (0, utils_1.fetchData)(tryUrl); if (!dataText) continue; const data = JSON.parse(dataText); if (isValidOpenApiData(data)) { return data; } // If data is invalid, continue to next URL } catch { // If request or parsing fails, continue to next URL continue; } } // If all URLs fail or return invalid data, throw error throw helper_1.logger.throwError(`Unable to retrieve valid OpenAPI document from any URL: ${urlsToTry.join(', ')}`); } default: break; } } // Parse openapi files async function getOpenApiData(url, projectPath, platformType) { let data = null; try { if (!/^https?:\/\//.test(url)) { // local file data = await parseLocalFile(url, projectPath); } else { // remote file data = await parseRemoteFile(url, platformType); } // If it is a swagger2 file if (isSwagger2(data)) { data = (await swagger2openapi_1.default.convertObj(data, { warnOnly: true })).openapi; } } catch (error) { throw helper_1.logger.throwError(`Cannot read file from ${url}`, { error: error.message, projectPath, url, platformType, }); } if (!data) { throw helper_1.logger.throwError(`Cannot read file from ${url}`, { projectPath, url, platformType, }); } return data; }