2025-07-23 15:58:42 +08:00

111 lines
3.3 KiB
TypeScript

import { firstUpperCase } from "../utils";
/**
* 解析结果的接口定义
* @interface ParseResult
*/
interface ParseResult {
/** 解析出的键名 */
key: string;
/** 解析出的内容 */
content: string;
/** 层级 */
level: number;
}
/**
* 将模板字符串扁平化处理,转换为 Service 类型定义
* @param template - 包含 Service 类型定义的模板字符串
* @returns 处理后的 Service 类型定义字符串
* @throws {Error} 当模板中找不到 Service 类型定义时抛出错误
*/
export function flatten(template: string): string {
// 查找 Service 类型定义的起始位置
const startIndex = template.indexOf("export type Service = {");
// 保留 Service 类型定义前的内容
let header = template.substring(0, startIndex);
// 获取 Service 类型定义及其内容,去除换行和制表符
const serviceContent = template.substring(startIndex).replace(/\n|\t/g, "");
let interfaces = "";
let serviceFields = "";
// 解析内容并生成接口定义
parse(serviceContent).forEach(({ key, content, level }) => {
interfaces += `\nexport interface ${firstUpperCase(key)}Interface {${content}}\n`;
serviceFields += `${key}: ${firstUpperCase(key)}Interface;`;
});
return `${header}${interfaces}\nexport type Service = {${serviceFields}}`;
}
/**
* 查找匹配的右花括号位置
* @param str - 要搜索的字符串
* @param startIndex - 开始搜索的位置
* @returns 匹配的右花括号位置
* @throws {Error} 当找不到匹配的右花括号时抛出错误
*/
function findClosingBrace(str: string, startIndex: number): number {
let braceCount = 1;
let currentIndex = startIndex;
while (currentIndex < str.length && braceCount > 0) {
if (str[currentIndex] === "{") braceCount++;
if (str[currentIndex] === "}") braceCount--;
currentIndex++;
}
if (braceCount !== 0) {
throw new Error("Unmatched braces in the template");
}
return currentIndex - 1;
}
/**
* 解析内容中的嵌套结构
* @param content - 要解析的内容字符串
* @returns 解析结果数组,包含解析出的键值对
*/
function parse(content: string, level: number = 0): ParseResult[] {
// 匹配形如 xxx: { ... } 的结构
const interfacePattern = /(\w+)\s*:\s*\{/g;
const result: ParseResult[] = [];
let match: RegExpExecArray | null;
while ((match = interfacePattern.exec(content)) !== null) {
const startIndex = match.index + match[0].length;
const endIndex = findClosingBrace(content, startIndex);
if (endIndex > startIndex) {
let parsedContent = content.substring(startIndex, endIndex).trim();
// 处理嵌套结构
if (parsedContent.includes("{") && parsedContent.includes("}")) {
const nestedInterfaces = parse(parsedContent, level + 1);
// 替换嵌套的内容为接口引用
if (nestedInterfaces.length > 0) {
nestedInterfaces.forEach((nestedInterface) => {
const pattern = `${nestedInterface.key}: {${nestedInterface.content}};`;
const replacement = `${nestedInterface.key}: ${firstUpperCase(nestedInterface.key)}Interface`;
parsedContent = parsedContent.replace(pattern, replacement);
});
}
}
// 将解析结果添加到数组开头
result.unshift({
key: match[1],
level,
content: parsedContent,
});
}
}
return result;
}