2023-09-28 13:50:15 +08:00
|
|
|
import { createDir, error, firstUpperCase, readFile, toCamel } from "../utils";
|
|
|
|
import { join } from "path";
|
|
|
|
import { Entity, DistPath } from "./config";
|
|
|
|
import axios from "axios";
|
2023-11-23 21:54:00 +08:00
|
|
|
import { isArray, isEmpty, last, merge, unionBy } from "lodash";
|
2023-09-28 13:50:15 +08:00
|
|
|
import { createWriteStream } from "fs";
|
|
|
|
import prettier from "prettier";
|
|
|
|
import { proxy } from "../../../src/config/proxy";
|
2023-10-13 17:24:28 +08:00
|
|
|
import type { Eps } from "../types";
|
2023-09-28 13:50:15 +08:00
|
|
|
|
|
|
|
// 获取方法名
|
|
|
|
function getNames(v: any) {
|
|
|
|
return Object.keys(v).filter((e) => !["namespace", "permission"].includes(e));
|
|
|
|
}
|
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
// 数据
|
|
|
|
let service = {};
|
|
|
|
let list: Eps.Entity[] = [];
|
2023-09-28 13:50:15 +08:00
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
// 获取数据
|
|
|
|
async function getData(temps?: Eps.Entity[]) {
|
2023-09-28 13:50:15 +08:00
|
|
|
// 本地文件
|
|
|
|
try {
|
2023-10-13 17:24:28 +08:00
|
|
|
list = JSON.parse(readFile(join(DistPath, "eps.json")) || "[]");
|
2023-10-14 13:42:40 +08:00
|
|
|
} catch (err: any) {
|
2023-09-28 13:50:15 +08:00
|
|
|
error(`[eps] ${join(DistPath, "eps.json")} 文件异常, ${err.message}`);
|
|
|
|
}
|
|
|
|
|
2023-09-28 17:22:29 +08:00
|
|
|
// 远程地址
|
2023-09-28 13:50:15 +08:00
|
|
|
const url = proxy["/dev/"].target + "/admin/base/open/eps";
|
|
|
|
|
2023-09-28 17:22:29 +08:00
|
|
|
// 请求数据
|
2023-09-28 13:50:15 +08:00
|
|
|
await axios
|
|
|
|
.get(url, {
|
|
|
|
timeout: 5000
|
|
|
|
})
|
|
|
|
.then((res) => {
|
2023-11-24 15:08:24 +08:00
|
|
|
const { code, data } = res.data;
|
2023-09-28 13:50:15 +08:00
|
|
|
|
|
|
|
if (code === 1000) {
|
|
|
|
if (!isEmpty(data) && data) {
|
2023-10-30 18:34:30 +08:00
|
|
|
merge(list, Object.values(data).flat() as Eps.Entity[]);
|
2023-09-28 13:50:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(() => {
|
2023-11-24 15:08:24 +08:00
|
|
|
error(`[eps] 服务未启动 ➜ ${url}`);
|
2023-09-28 13:50:15 +08:00
|
|
|
});
|
|
|
|
|
2023-10-30 18:34:30 +08:00
|
|
|
// 合并其他数据
|
2023-09-28 17:22:29 +08:00
|
|
|
if (isArray(temps)) {
|
|
|
|
temps.forEach((e) => {
|
2023-11-24 15:08:24 +08:00
|
|
|
e.isLocal = true;
|
|
|
|
|
2023-09-28 17:22:29 +08:00
|
|
|
const d = list.find((a) => e.prefix === a.prefix);
|
|
|
|
|
2023-10-07 22:43:37 +08:00
|
|
|
if (d) {
|
2023-10-13 10:50:06 +08:00
|
|
|
merge(d, e);
|
2023-10-07 22:43:37 +08:00
|
|
|
} else {
|
2023-09-28 17:22:29 +08:00
|
|
|
list.push(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2023-11-23 21:54:00 +08:00
|
|
|
|
|
|
|
list = unionBy(list, "prefix");
|
2023-09-28 13:50:15 +08:00
|
|
|
}
|
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
// 创建 json 文件
|
|
|
|
function createJson() {
|
2023-11-24 15:08:24 +08:00
|
|
|
const d = list
|
|
|
|
.filter((e) => !e.isLocal)
|
|
|
|
.map((e) => {
|
|
|
|
return {
|
|
|
|
prefix: e.prefix,
|
|
|
|
name: e.name || "",
|
|
|
|
api: e.api.map((e) => {
|
|
|
|
return {
|
|
|
|
name: e.name,
|
|
|
|
method: e.method,
|
|
|
|
path: e.path
|
|
|
|
};
|
|
|
|
})
|
|
|
|
};
|
|
|
|
});
|
2023-10-13 17:24:28 +08:00
|
|
|
|
|
|
|
createWriteStream(join(DistPath, "eps.json"), {
|
|
|
|
flags: "w"
|
|
|
|
}).write(JSON.stringify(d));
|
2023-09-28 13:50:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 创建描述文件
|
2023-10-13 17:24:28 +08:00
|
|
|
async function createDescribe({ list, service }: { list: Eps.Entity[]; service: any }) {
|
2023-09-28 13:50:15 +08:00
|
|
|
// 获取类型
|
2023-10-14 13:42:40 +08:00
|
|
|
function getType({ propertyName, type }: any) {
|
2023-09-28 13:50:15 +08:00
|
|
|
for (const map of Entity.mapping) {
|
|
|
|
if (map.custom) {
|
|
|
|
const resType = map.custom({ propertyName, type });
|
|
|
|
if (resType) return resType;
|
|
|
|
}
|
|
|
|
if (map.test) {
|
|
|
|
if (map.test.includes(type)) return map.type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 创建 Entity
|
|
|
|
function createEntity() {
|
|
|
|
const t0: string[][] = [];
|
|
|
|
|
|
|
|
for (const item of list) {
|
|
|
|
if (!item.name) continue;
|
|
|
|
const t = [`interface ${item.name} {`];
|
2023-11-23 21:54:00 +08:00
|
|
|
|
2023-09-28 13:50:15 +08:00
|
|
|
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({
|
|
|
|
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 createDts() {
|
|
|
|
const t0: string[][] = [];
|
|
|
|
|
|
|
|
const t1 = [
|
|
|
|
`
|
|
|
|
type json = any;
|
|
|
|
|
|
|
|
type Service = {
|
|
|
|
request(options?: {
|
|
|
|
url: string;
|
|
|
|
method?: "POST" | "GET" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
|
|
|
|
data?: any;
|
|
|
|
params?: any;
|
|
|
|
headers?: {
|
|
|
|
[key: string]: any;
|
|
|
|
},
|
|
|
|
timeout?: number;
|
|
|
|
proxy?: boolean;
|
|
|
|
[key: string]: any;
|
|
|
|
}): Promise<any>;
|
|
|
|
`
|
|
|
|
];
|
|
|
|
|
|
|
|
// 处理数据
|
|
|
|
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) => {
|
|
|
|
// 方法名
|
2023-11-10 18:15:44 +08:00
|
|
|
const n = (a.name || last(a.path.split("/")) || "").replace(
|
|
|
|
/[:\/]/g,
|
2023-09-28 13:50:15 +08:00
|
|
|
""
|
|
|
|
);
|
|
|
|
|
|
|
|
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"}`;
|
|
|
|
|
2023-11-10 18:15:44 +08:00
|
|
|
q.push(`"${a}": ${b},`);
|
2023-09-28 13:50:15 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
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; [key: string]: any };
|
|
|
|
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(
|
2023-11-10 18:15:44 +08:00
|
|
|
`"${n}"(data${q.length == 1 ? "?" : ""}: ${q.join(
|
2023-09-28 13:50:15 +08:00
|
|
|
""
|
|
|
|
)}): Promise<${res}>;`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
permission.push(n);
|
|
|
|
});
|
|
|
|
|
|
|
|
// 权限标识
|
|
|
|
t.push("\n");
|
|
|
|
t.push("/**\n");
|
|
|
|
t.push(" * 权限标识\n");
|
|
|
|
t.push(" */\n");
|
|
|
|
t.push(
|
|
|
|
`permission: { ${permission
|
2023-11-10 18:15:44 +08:00
|
|
|
.map((e) => `"${e}": string;`)
|
2023-09-28 13:50:15 +08:00
|
|
|
.join("\n")} };`
|
|
|
|
);
|
|
|
|
|
|
|
|
// 权限状态
|
|
|
|
t.push("\n");
|
|
|
|
t.push("/**\n");
|
|
|
|
t.push(" * 权限状态\n");
|
|
|
|
t.push(" */\n");
|
|
|
|
t.push(
|
|
|
|
`_permission: { ${permission
|
2023-11-10 18:15:44 +08:00
|
|
|
.map((e) => `"${e}": boolean;`)
|
2023-09-28 13:50:15 +08:00
|
|
|
.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");
|
|
|
|
}
|
|
|
|
|
|
|
|
// 文件内容
|
|
|
|
const text = `
|
|
|
|
declare namespace Eps {
|
|
|
|
${createEntity()}
|
|
|
|
${createDts()}
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
// 文本内容
|
2023-10-13 17:24:28 +08:00
|
|
|
const content = prettier.format(text, {
|
2023-09-28 13:50:15 +08:00
|
|
|
parser: "typescript",
|
|
|
|
useTabs: true,
|
|
|
|
tabWidth: 4,
|
|
|
|
endOfLine: "lf",
|
|
|
|
semi: true,
|
|
|
|
singleQuote: false,
|
|
|
|
printWidth: 100,
|
|
|
|
trailingComma: "none"
|
|
|
|
});
|
|
|
|
|
|
|
|
// 创建 eps 描述文件
|
|
|
|
createWriteStream(join(DistPath, "eps.d.ts"), {
|
|
|
|
flags: "w"
|
|
|
|
}).write(content);
|
|
|
|
}
|
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
// 创建 service
|
|
|
|
function createService() {
|
|
|
|
list.forEach((e) => {
|
|
|
|
// 分隔路径
|
|
|
|
const arr = e.prefix
|
|
|
|
.replace(/\//, "")
|
|
|
|
.replace("admin", "")
|
|
|
|
.split("/")
|
|
|
|
.filter(Boolean)
|
|
|
|
.map(toCamel);
|
|
|
|
|
|
|
|
// 遍历
|
|
|
|
function deep(d: any, i: number) {
|
|
|
|
const k = arr[i];
|
|
|
|
|
|
|
|
if (k) {
|
|
|
|
// 是否最后一个
|
|
|
|
if (arr[i + 1]) {
|
|
|
|
if (!d[k]) {
|
|
|
|
d[k] = {};
|
|
|
|
}
|
2023-09-28 13:50:15 +08:00
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
deep(d[k], i + 1);
|
|
|
|
} else {
|
|
|
|
// 不存在则创建
|
|
|
|
if (!d[k]) {
|
|
|
|
d[k] = {
|
|
|
|
namespace: e.prefix.substring(1, e.prefix.length),
|
|
|
|
permission: {}
|
|
|
|
};
|
|
|
|
}
|
2023-09-28 13:50:15 +08:00
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
// 创建方法
|
|
|
|
e.api.forEach((a) => {
|
|
|
|
// 方法名
|
2023-11-02 17:03:10 +08:00
|
|
|
let n = a.path.replace("/", "");
|
2023-09-28 13:50:15 +08:00
|
|
|
|
2023-11-02 17:03:10 +08:00
|
|
|
if (n) {
|
|
|
|
// 示例 /info/:id
|
|
|
|
if (n.includes("/:")) {
|
|
|
|
a.path = a.path.split("/:")[0];
|
|
|
|
n = n.split("/:")[0];
|
|
|
|
}
|
|
|
|
|
2023-11-10 18:15:44 +08:00
|
|
|
d[k][n] = a;
|
2023-09-28 13:50:15 +08:00
|
|
|
}
|
2023-10-13 17:24:28 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
// 创建权限
|
|
|
|
getNames(d[k]).forEach((e) => {
|
|
|
|
d[k].permission[e] = `${d[k].namespace.replace("admin/", "")}/${e}`.replace(
|
|
|
|
/\//g,
|
|
|
|
":"
|
|
|
|
);
|
|
|
|
});
|
2023-09-28 13:50:15 +08:00
|
|
|
}
|
2023-10-13 17:24:28 +08:00
|
|
|
}
|
2023-09-28 13:50:15 +08:00
|
|
|
}
|
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
deep(service, 0);
|
|
|
|
});
|
2023-09-28 13:50:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 创建 eps
|
|
|
|
export async function createEps(query?: { list: any[] }) {
|
|
|
|
// 获取数据
|
2023-10-13 17:24:28 +08:00
|
|
|
await getData(query?.list || []);
|
2023-09-28 13:50:15 +08:00
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
// 创建 service
|
|
|
|
createService();
|
2023-09-28 13:50:15 +08:00
|
|
|
|
|
|
|
// 创建临时目录
|
|
|
|
createDir(DistPath);
|
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
// 创建 json 文件
|
|
|
|
createJson();
|
2023-09-28 13:50:15 +08:00
|
|
|
|
|
|
|
// 创建描述文件
|
|
|
|
createDescribe({ service, list });
|
|
|
|
|
2023-10-13 17:24:28 +08:00
|
|
|
return {
|
|
|
|
service,
|
|
|
|
list
|
|
|
|
};
|
2023-09-28 13:50:15 +08:00
|
|
|
}
|