UNPKG

@alova/wormhole

Version:

More modern openAPI generating solution for alova.js

206 lines (205 loc) 6.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.rename = rename; const utils_1 = require("./utils"); function toCamelCase(str) { return str.replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : '')).replace(/^(.)/, c => c.toLowerCase()); } function toCase(str) { return str .replace(/([a-z\d])([A-Z])/g, '$1_$2') .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1_$2') .replace(/[-\s]+/g, '_') .toLowerCase(); } function toKebabCase(str) { return str .replace(/([a-z\d])([A-Z])/g, '$1-$2') .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1-$2') .replace(/[_\s]+/g, '-') .toLowerCase(); } function toPascalCase(str) { return str.replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : '')).replace(/^(.)/, c => c.toUpperCase()); } /** * Applies renaming rules to the specified value * @returns The renamed value, or original value if not matched */ function applyRenameRule(value, config, apiDescriptor) { if (!(0, utils_1.isMatch)(value, config.match)) { return value; } if (config.transform) { value = config.transform(apiDescriptor, value); } if (!config.style) { return value; } if (config.style === 'kebabCase' && config.scope === 'refName') { throw new Error(`Invalid rename style: ${config.style}${config.scope}`); } switch (config.style) { case 'camelCase': return toCamelCase(value); case 'snakeCase': return toCase(value); case 'kebabCase': return toKebabCase(value); case 'pascalCase': return toPascalCase(value); default: throw new Error(`Invalid rename style: ${config.style}`); } } /** * renames URL path by processing each segment individually * while keeping path parameter placeholders */ function renameUrl(url, config, apiDescriptor) { const segments = url.split('/'); return segments .map((segment) => { // Skip parameter placeholders and empty segments if ((segment.startsWith('{') && segment.endsWith('}')) || !segment) { return segment; } return applyRenameRule(segment, config, apiDescriptor); }) .join('/') .replace(/^\/{2,}/g, '/'); } /** * Transforms object properties using the renaming rules */ function transformProperties(obj, config, apiDescriptor) { if (!obj || typeof obj !== 'object' || !('properties' in obj)) { return obj; } const properties = { ...obj.properties }; const newProperties = {}; for (const key in properties) { const newKey = applyRenameRule(key, config, apiDescriptor); newProperties[newKey] = properties[key]; } return { ...obj, properties: newProperties, }; } /** * Transforms parameters of specific type using the renaming rules */ function transformParameters(parameters, type, config, apiDescriptor) { if (!parameters || !Array.isArray(parameters)) { return parameters; } return parameters.map((param) => { if (param.in === type) { return { ...param, name: applyRenameRule(param.name, config, apiDescriptor), }; } return param; }); } function transformRefNameMap(refNameMap, config, apiDescriptor) { if (!refNameMap || typeof refNameMap !== 'object') { return refNameMap; } const newRefNameMap = {}; for (const key in refNameMap) { const newValue = applyRenameRule(refNameMap[key], config, apiDescriptor); newRefNameMap[key] = newValue; } return newRefNameMap; } /** * Processes API descriptor based on renaming configuration * * Each scope targets different parts of the API descriptor: * - url: Renames URL path segments * - params: Renames query parameters * - pathParams: Renames path parameters and their placeholders in URL * - data: Renames request body properties * - response: Renames response body properties */ function renameApiDescriptor(apiDescriptor, config) { if (!apiDescriptor) return apiDescriptor; const newDescriptor = { ...apiDescriptor }; const scope = config.scope || 'url'; switch (scope) { case 'params': if (newDescriptor.parameters) { newDescriptor.parameters = transformParameters(newDescriptor.parameters, 'query', config, apiDescriptor); } break; case 'pathParams': if (newDescriptor.parameters) { newDescriptor.parameters = transformParameters(newDescriptor.parameters, 'path', config, apiDescriptor); } if (newDescriptor.url) { newDescriptor.url = newDescriptor.url.replace(/\{([^}]+)\}/g, (match, paramName) => { const newName = applyRenameRule(paramName, config, apiDescriptor); return `{${newName}}`; }); } break; case 'data': if (newDescriptor.requestBody) { newDescriptor.requestBody = transformProperties(newDescriptor.requestBody, config, apiDescriptor); } break; case 'response': if (newDescriptor.responses) { newDescriptor.responses = transformProperties(newDescriptor.responses, config, apiDescriptor); } break; case 'url': if (newDescriptor.url) { newDescriptor.url = renameUrl(newDescriptor.url, config, apiDescriptor); } break; case 'refName': if (newDescriptor.refNameMap) { newDescriptor.refNameMap = transformRefNameMap(newDescriptor.refNameMap, config, apiDescriptor); } break; default: // No action needed, keep original descriptor break; } return newDescriptor; } /** * Creates a rename plugin that transforms API descriptors * according to specified naming rules */ function rename(config) { const configs = Array.isArray(config) ? config : [config]; for (const conf of configs) { if (!conf.style && !conf.transform) { throw new Error('at least one of `style` or `transform` is required'); } } return { name: 'rename', config(config) { return (0, utils_1.extend)(config, { handleApi: (apiDescriptor) => { if (!apiDescriptor) return null; // Apply each configuration in sequence return configs.reduce((desc, conf) => { if (!desc) return null; return renameApiDescriptor(desc, conf); }, apiDescriptor); }, }); }, }; } exports.default = rename;