UNPKG

@ohmyts/vite

Version:

Proxy request to get response data and transform to TypeScript code.

102 lines (96 loc) 3.12 kB
import events from 'events'; import httpProxy from 'http-proxy'; import parse from 'url-parse'; import * as fs from 'fs'; import JsonToTS from 'json-to-ts'; import MagicString from 'magic-string'; function writeFileSyncRecursive(filename, content, charset = "utf-8") { let filepath = filename.replace(/\\/g, "/"); let root = ""; if (filepath[0] === "/") { root = "/"; filepath = filepath.slice(1); } else if (filepath[1] === ":") { root = filepath.slice(0, 3); filepath = filepath.slice(3); } const folders = filepath.split("/").slice(0, -1); folders.reduce( (acc, folder) => { const folderPath = `${acc + folder}/`; if (!fs.existsSync(folderPath)) fs.mkdirSync(folderPath); return folderPath; }, root ); fs.writeFileSync(root + filepath, content, charset); } const parseUrl = (req) => { const parsedUrl = parse(req.url).pathname.split("/").map((name) => `${(name[0] || "").toUpperCase()}${name.slice(1)}`).join(""); return `${req.method.toString().toUpperCase()}_${parsedUrl}.d.ts`; }; const transformJSONToTs = (req, chunks, options) => { const { suffix = "ResponseType", encoding = "utf-8", rootDir = "@types", overwrite = true, declare = true } = options; const name = parseUrl(req); let dir = rootDir; if (rootDir.endsWith("/")) { const splitDir = rootDir.split("/"); dir = splitDir.slice(0, splitDir.length - 1).join(""); } dir = `${dir}/${name}`; const isFileExist = fs.existsSync(dir); if (overwrite || !isFileExist) { try { const json = JSON.parse(Buffer.concat(chunks).toString(encoding)); const code = new MagicString(JsonToTS(json).toLocaleString().replaceAll("},interface", "}\ninterface")); const typename = name.split("_"); code.replace("interface RootObject", `${declare ? "declare" : "export"} interface I${typename[0]}${typename[1].replace(".d.ts", "")}${suffix}`); writeFileSyncRecursive(dir, code.toString()); } catch (err) { console.log(`[ohmyts Error] ${err}`); } } }; const ee = events.EventEmitter; function ohmytsVite(options) { return { name: "ohmyts", configureServer(server) { const proxy = httpProxy.createProxyServer(); const proxyWeb = (req, res, pathname, option) => { proxy.web(req, res, { changeOrigin: true, ...option.proxyOptions }); }; ee.setMaxListeners(0); return () => { if (!Array.isArray(options)) options = [options]; for (const option of options) { server.middlewares.use(option.target, (req, res) => { const pathname = parse(req.url).pathname; proxyWeb(req, res, pathname, option); proxy.on("proxyRes", (proxyRes) => { const chunks = []; proxyRes.on("data", (chunk) => { chunks.push(chunk); }); proxyRes.on("end", () => { transformJSONToTs(req, chunks, option); }); }); }); } }; } }; } export { ohmytsVite };