@ohmyts/vite
Version:
Proxy request to get response data and transform to TypeScript code.
102 lines (96 loc) • 3.12 kB
JavaScript
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 };