Files
jindengchen-ai-report/cool-admin-vue/packages/vite-plugin/src/uniapp-x/flatten.ts

130 lines
4.1 KiB
TypeScript
Raw Normal View History

import { firstUpperCase } from "../utils";
/**
* 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 serviceTemplateContent = template.substring(startIndex).replace(/\n|\t/g, "");
// 找到 Service 的内容部分
const serviceStartIndex = serviceTemplateContent.indexOf("{") + 1;
const serviceEndIndex = findClosingBrace(serviceTemplateContent, serviceStartIndex);
const serviceInnerContent = serviceTemplateContent
.substring(serviceStartIndex, serviceEndIndex)
.trim();
// 存储所有接口定义
const allInterfaces = new Map<string, string>();
// 处理 Service 内容,保持原有结构但替换嵌套对象为接口引用
const serviceContent = buildCurrentLevelContent(serviceInnerContent);
// 递归收集所有需要生成的接口
flattenContent(serviceInnerContent, allInterfaces, []);
// 生成所有接口定义
let interfaces = "";
allInterfaces.forEach((content, key) => {
interfaces += `\nexport interface ${firstUpperCase(key)}Interface { ${content} }\n`;
});
return `${header}${interfaces}\nexport type Service = { ${serviceContent} }`;
}
/**
*
* @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 -
* @param allInterfaces - Map
* @param parentFields - 使
*/
function flattenContent(
content: string,
allInterfaces: Map<string, string>,
parentFields: string[],
): void {
const interfacePattern = /(\w+)\s*:\s*\{/g;
let match: RegExpExecArray | null;
while ((match = interfacePattern.exec(content)) !== null) {
const key = match[1];
const startIndex = match.index + match[0].length;
const endIndex = findClosingBrace(content, startIndex);
if (endIndex > startIndex) {
const innerContent = content.substring(startIndex, endIndex).trim();
// 构建当前接口的内容,将嵌套对象替换为接口引用
const currentLevelContent = buildCurrentLevelContent(innerContent);
allInterfaces.set(key, currentLevelContent);
// 递归处理嵌套内容
flattenContent(innerContent, allInterfaces, []);
}
}
}
/**
*
* @param content -
* @returns
*/
function buildCurrentLevelContent(content: string): string {
const interfacePattern = /(\w+)\s*:\s*\{/g;
let result = content;
let match: RegExpExecArray | null;
// 重置正则表达式的 lastIndex
interfacePattern.lastIndex = 0;
while ((match = interfacePattern.exec(content)) !== null) {
const key = match[1];
const startIndex = match.index + match[0].length;
const endIndex = findClosingBrace(content, startIndex);
if (endIndex > startIndex) {
const fullMatch = content.substring(match.index, endIndex + 1);
const replacement = `${key}: ${firstUpperCase(key)}Interface;`;
result = result.replace(fullMatch, replacement);
}
}
// 清理多余的分号和空格
result = result.replace(/;+/g, ";").replace(/\s+/g, " ").trim();
return result;
}