UNPKG

@alova/wormhole

Version:

More modern openAPI generating solution for alova.js

183 lines (182 loc) 6.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateDefaultValues = void 0; exports.removeComments = removeComments; exports.generateDefaultValuesFormat = generateDefaultValuesFormat; const utils_1 = require("../../../utils"); // Remove comments function removeComments(content) { // Remove single line comments content = content.replace(/\/\/.*$/gm, ''); // Remove multi-line comments and documentation comments content = content.replace(/\/\*[\s\S]*?\*\//g, ''); return content; } const LEFT_BRACKET = ['(', '<', '{', '[']; const RIGHT_BRACKET = [')', '>', '}', ']']; function parseTypeBody(typeBody) { const processedTypeBody = typeBody .replace(/:[\t\v\f\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*\n\s*\|/g, ':') // Handle union type after colon .replace(/:[\t\v\f\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*\n\s*&/g, ':') // Handle intersection type after colon .replace(/\n\s*\|/g, '|') // Handle union type line breaks .replace(/\n\s*&/g, '&'); // Handle intersection type line breaks const properties = []; let bracketCount = 0; let currentProperty = ''; for (let i = 0; i < processedTypeBody.length; i += 1) { const char = processedTypeBody[i]; if (LEFT_BRACKET.includes(char)) { bracketCount += 1; } else if (RIGHT_BRACKET.includes(char)) { bracketCount -= 1; } currentProperty += char; if (currentProperty.trim() && /\n/.test(char) && bracketCount === 0) { properties.push(currentProperty.trim()); currentProperty = ''; } } if (currentProperty.trim()) { properties.push(currentProperty.trim()); } const parsedProperties = properties .map((prop) => { const [keyOrigin, ...valueOrigin] = prop.split(':'); const key = keyOrigin.trim(); const value = valueOrigin.join(':').trim(); const isOptional = key.endsWith('?'); const defaultValue = getDefaultValue(value); return { key: key.replace('?', ''), value: defaultValue, isOptional }; }) .filter(prop => !prop.isOptional) .map(prop => `${prop.key}: ${prop.value}`) .join(',\n'); return `{\n${parsedProperties}\n}`; } function isSplitType(type, c) { if (!type.includes(c)) { return false; } let bracketCount = 0; for (let i = 0; i < type.length; i += 1) { const char = type[i]; if (LEFT_BRACKET.includes(char)) { bracketCount += 1; } else if (RIGHT_BRACKET.includes(char)) { bracketCount -= 1; } if (bracketCount === 0 && char === c) { return true; } } return false; } function splitTypes(typeStr, c) { const result = []; let bracketCount = 0; let currentType = ''; for (let i = 0; i < typeStr.length; i += 1) { const char = typeStr[i]; if (LEFT_BRACKET.includes(char)) { bracketCount += 1; } else if (RIGHT_BRACKET.includes(char)) { bracketCount -= 1; } if (char === c && bracketCount === 0) { result.push(currentType.trim()); currentType = ''; } else { currentType += char; } } if (currentType.trim()) { result.push(currentType.trim()); } return result; } function isIntersectionType(type) { return isSplitType(type, '&'); } function isUnionType(type) { return isSplitType(type, '|'); } function getDefaultValue(type) { // Remove trailing semicolon type = type.replace(/;$/, ''); if (isUnionType(type)) { const types = splitTypes(type, '|'); return getDefaultValue(types[0]); } if (isIntersectionType(type)) { const types = splitTypes(type, '&'); const mergedDefaults = types.map(t => getDefaultValue(t)); return mergedDefaults.reduce((acc, curr) => { if (curr.startsWith('{') && curr.endsWith('}')) { const currProperties = curr.slice(1, -1).trim(); if (acc === '{ }') { return `{\n ${currProperties} \n}`; } return `${acc.slice(0, -2)},\n ${currProperties} \n}`; } return acc; }, '{ }'); } if (type.startsWith('(') && type.endsWith(')')) { return getDefaultValue(type.slice(1, -1).trim()); } if (type.startsWith('{') && type.endsWith('}')) { return parseTypeBody(type.slice(1, -1).trim()); } if (type.endsWith(')[]') && type.startsWith('(')) { return '[]'; } if (type.endsWith('[]') || type.startsWith('Array<')) { return '[]'; } if (type.startsWith('[') && type.endsWith(']')) { return parseTuple(type); } if ((type.startsWith('\'') && type.endsWith('\'')) || (type.startsWith('"') && type.endsWith('"'))) { return type; } if (Number.parseInt(type, 10)) { return type; } switch (type) { case 'string': return '""'; case 'number': return '0'; case 'boolean': return 'false'; case 'null': case 'undefined': return type; default: return '{ }'; } } function parseTuple(tupleType) { const elements = tupleType .slice(1, -1) .split(',') .map(el => el.trim()); const parsedElements = elements.map(el => getDefaultValue(el)); return `[${parsedElements.join(', ')}]`; } const generateDefaultValues = (sourceCode) => getDefaultValue(removeComments(sourceCode).trim()); exports.generateDefaultValues = generateDefaultValues; /** * Generates default value objects for types and interfaces from the given TypeScript source code. * @param sourceCode -TypeScript source code string * @returns Object containing type and interface default values */ function generateDefaultValuesFormat(sourceCode) { return (0, utils_1.format)((0, exports.generateDefaultValues)(sourceCode), { parser: 'json', }); }