import prettier from "prettier"; import { isEmpty, last } from "lodash"; import { createDir, firstUpperCase, readFile, toCamel } from "../../utils"; import { createWriteStream } from "fs"; import { join } from "path"; import config from "./config"; interface Options { list: { prefix: string; name: string; columns: any[]; api: { name: string; method: string; path: string; summary: string; dts: { parameters: { description: string; schema: { type: string; }; name: string; required: boolean; }[]; }; }[]; }[]; service: { [key: string]: any; }; } // 临时目录路径 const tempPath = join(__dirname, "../../temp"); // 获取类型 function getType({ entityName, propertyName, type }) { for (const map of config.entity.mapping) { if (map.custom) { const resType = map.custom({ entityName, propertyName, type }); if (resType) return resType; } if (map.test) { if (map.test.includes(type)) return map.type; } } return type; } // 创建 Entity function createEntity({ list }: Options) { const t0: any[] = []; for (const item of list) { if (!item.name) continue; const t = [`interface ${item.name} {`]; for (const col of item.columns || []) { // 描述 t.push("\n"); t.push("/**\n"); t.push(` * ${col.comment}\n`); t.push(" */\n"); t.push( `${col.propertyName}?: ${getType({ entityName: item.name, propertyName: col.propertyName, type: col.type })};` ); } t.push("\n"); t.push("/**\n"); t.push(` * 任意键值\n`); t.push(" */\n"); t.push(`[key: string]: any;`); t.push("}"); t0.push(t); } return t0.map((e) => e.join("")).join("\n\n"); } // 创建 Service function createService({ list, service }: Options) { const t0: any[] = []; const t1 = [ `type Service = { request(options?: { url: string; method?: 'POST' | 'GET' | string; data?: any; params?: any; proxy?: boolean; [key: string]: any; }): Promise; ` ]; // 处理数据 function deep(d: any, k?: string) { if (!k) k = ""; for (const i in d) { const name = k + toCamel(firstUpperCase(i.replace(/[:]/g, ""))); if (d[i].namespace) { // 查找配置 const item = list.find((e) => (e.prefix || "").includes(d[i].namespace)); if (item) { const t = [`interface ${name} {`]; t1.push(`${i}: ${name};`); // 插入方法 if (item.api) { // 权限列表 const permission: string[] = []; item.api.forEach((a) => { // 方法名 const n = toCamel(a.name || last(a.path.split("/")) || "").replace( /[:\/-]/g, "" ); if (n) { // 参数类型 let q: string[] = []; // 参数列表 const { parameters = [] } = a.dts || {}; parameters.forEach((p) => { if (p.description) { q.push(`\n/** ${p.description} */\n`); } if (p.name.includes(":")) { return false; } const a = `${p.name}${p.required ? "" : "?"}`; const b = `${p.schema.type || "string"}`; q.push(`${a}: ${b},`); }); if (isEmpty(q)) { q = ["any"]; } else { q.unshift("{"); q.push("}"); } // 返回类型 let res = ""; // 实体名 const en = item.name || "any"; switch (a.path) { case "/page": res = ` { pagination: { size: number; page: number; total: number }; list: ${en} []; [key: string]: any; } `; break; case "/list": res = `${en} []`; break; case "/info": res = en; break; default: res = "any"; break; } // 描述 t.push("\n"); t.push("/**\n"); t.push(` * ${a.summary || n}\n`); t.push(" */\n"); t.push( `${n}(data${q.length == 1 ? "?" : ""}: ${q.join( "" )}): Promise<${res}>;` ); } permission.push(n); }); // 权限标识 t.push("\n"); t.push("/**\n"); t.push(" * 权限标识\n"); t.push(" */\n"); t.push( `permission: { ${permission.map((e) => `${e}: string;`).join("\n")} };` ); // 权限状态 t.push("\n"); t.push("/**\n"); t.push(" * 权限状态\n"); t.push(" */\n"); t.push( `_permission: { ${permission .map((e) => `${e}: boolean;`) .join("\n")} };` ); // 请求 t.push("\n"); t.push("/**\n"); t.push(" * 请求\n"); t.push(" */\n"); t.push(`request: Service['request']`); } t.push("}"); t0.push(t); } } else { t1.push(`${i}: {`); deep(d[i], name); t1.push(`},`); } } } // 深度 deep(service); // 结束 t1.push("}"); // 追加 t0.push(t1); return t0.map((e) => e.join("")).join("\n\n"); } // 创建描述文件 export async function createEps(options: Options) { // 文件内容 const text = ` declare namespace Eps { ${createEntity(options)} ${createService(options)} } `; // 文本内容 const content = prettier.format(text, { parser: "typescript", useTabs: true, tabWidth: 4, endOfLine: "lf", semi: true, singleQuote: false, printWidth: 100, trailingComma: "none" }); // 创建 temp 目录 createDir(tempPath); // 创建 eps 描述文件 createWriteStream(join(tempPath, "eps.d.ts"), { flags: "w" }).write(content); // 创建 eps 数据文件 createWriteStream(join(tempPath, "eps.json"), { flags: "w" }).write( JSON.stringify( (options.list || []).map((e) => { const req = e.api.map((a) => { const arr = [a.name ? `/${a.name}` : a.path]; if (a.method) { arr.push(a.method); } return arr; }); return [e.prefix, e.name || "", req]; }) ) ); } // 获取描述 export function getEps() { return JSON.stringify(readFile(join(tempPath, "eps.json"))); }