根据swagger自动生成接口请求代码

377 阅读1分钟

已经更新 npm 包到仓库,地址如下:

npm i isoftstone-swagger-to-ts -D

增加了 地址及生成请求和类型配置,参考 npm 主页 README 文档 www.npmjs.com/package/iso…

import http from "http";
import fs from "fs";
import path from "path";

const fromurl = "http://10.0.11.89:8080/v3/api-docs"; // 接口文档地址
const tourl = "./src/api/schemaTypes.ts"; // 生成类型文件地址,必须和 toapi 在一个文件夹下
const toapi = "./src/api/schemaAPI.ts"; //  生成调用接口文件,和tourl 在一个文件夹下
const servicePath = "@/utils/request"; // axios 地址,会被重命名为 service

const env = process.env;
const __dirname = path.dirname(import.meta.url);
const createType = (value) => {
  if (value["items"] && value["items"]["$ref"]) {
    return value["items"]["$ref"].split("/").pop();
  }
  return "any";
};
const createObj = (data) => {
  let typeObj = "";

  Object.entries(data).forEach((item) => {
    const [key, value] = item;
    let typestr = "any";
    switch (value.type) {
      case "string":
        typestr = "string";
        break;
      case "integer":
        typestr = "number";
        break;
      case "array":
        typestr = `Array<${createType(value)}>`;
        break;
      case "object":
        typestr = `${createType(value)}`;
        break;
    }
    typeObj += `
      ${key.replace(/[«,»]/gi, "")}: ${typestr};
    `;
  });
  return typeObj;
};
const createReqType = (item) => {
  let typestr = "any";
  let typeObj = "";
  switch (item.schema.type) {
    case "string":
      typestr = "string";
      break;
    case "integer":
      typestr = "number";
      break;
  }
  typeObj += `${item.name.replace(/[«,»]/gi, "")}${
    item.required ? "" : "?"
  }: ${typestr};`;
  return typeObj;
};
const createReq = (parameters) => {
  console.log(parameters);
  let txt = `query:{ ${parameters
    .map((item) => {
      return createReqType(item);
    })
    .join("")}}`;
  console.log(txt);
  return txt;
};

const createSchema = (schemas) => {
  let typeString = "";
  Object.entries(schemas).forEach(([key, value]) => {
    typeString += `export type ${key.replace(
      /[«,»]/gi,
      "",
    )} = Partial<{ ${createObj(value.properties)}}>
    `;
  });
  console.log(typeString);
  return typeString;
};
// 生成类型
const createSchemaInput = (jsonData) => {
  console.log(jsonData);
  const text = createSchema(jsonData.components.schemas);
  fs.writeFileSync(tourl, text, {
    flag: "w",
    encoding: "utf-8",
  });
  // console.log(text);
  console.log("生成完成");
};
// 生成请求
const createParmas = (data) => {
  const { parameters, requestBody } =
    data["post"] || data["get"] || data["put"] || data["delete"];
  let query = "";
  let req = "";
  if (parameters) {
    query = createReq(parameters);
    // console.log(query);
  }
  if (requestBody) {
    const refs = Object.values(requestBody.content);
    if (refs && refs[0]) {
      req = `req:${(refs[0]["schema"] || { $ref: "" }).$ref.split("/").pop()}`;
    }
  }

  return [query, req];
};
const createRequest = (data) => {
  let text = "";
  let importType = new Set();
  Object.entries(data.paths).forEach(([key, value]) => {
    let [query, req] = createParmas(value);
    let method = Object.keys(value)[0];
    let methodData =
      value["get"] || value["post"] || value["put"] || value["delete"];
    let reqType = "any";
    let content = Object.values(methodData.responses["200"].content);

    if (content && content[0]["schema"]["$ref"]) {
      reqType = content[0]["schema"]["$ref"].split("/").pop();
    }
    reqType = reqType.replace(/[«,»]/gi, "");

    const createPath = () => {
      //   "/system/dict/data/list?" + new URLSearchParams(req),
      return `"${key}"${query ? "+'?'+new URLSearchParams(query as any)" : ""}`;
    };
    //${[query, req].filter((item) => item).join(",")}
    // 类型倒入
    if (reqType) {
      importType.add(reqType);
    }
    if (req) {
      importType.add(req.split(":")[1]);
    }

    text += `
        // README:接口路径 ${key}
        export const ${methodData.operationId} = (${[query, req]
          .filter((item) => item)
          .join(",")})=>{
          let path = ${createPath()};
          // 替换路径参数
          ${
            query
              ? `if(path.includes("{")){
              path.match(/\{.*?\}/ig)?.forEach?.(item=>{
                   let keys = item.replace(/[{}]/ig,"");
                   if(query&&(query as any)[keys]){
                      path = path.replace("{"+keys+"}",(query as any)[keys]);
                   }
              })
            }`
              : ""
          }
          
          return service.${method}<${reqType}>(path${req ? ",req" : ""});
        }
      `;
    console.log(text);
  });

  // 引用
  const tsFile = `
  import service from "${servicePath}";
  import {${[...importType].join(",")}} from  "./${tourl
    .split("/")
    .pop()
    .replace(".ts", "")}"
    ${text}
  `;

  fs.writeFileSync(toapi, tsFile, {
    flag: "w",
    encoding: "utf-8",
  });
};
const req = http.request(fromurl, (res) => {
  let data = "";
  res.on("data", (chunk) => {
    data += chunk;
  });
  res.on("end", () => {
    try {
      // Parse the received data as JSON.

      const jsonData = JSON.parse(data);
      createSchemaInput(jsonData); // 生成类型
      createRequest(jsonData); // 生成请求
    } catch (error) {
      console.error(`Error parsing JSON: ${error.message}`);
    }
  });
});
// Handle errors.
req.on("error", (error) => {
  console.error(`Error: ${error.message}`);
});

// End the request.
req.end();