refactor: 悦码项目重构

This commit is contained in:
wangxuefeng
2025-02-19 13:42:56 +08:00
parent c8c9406fd5
commit eab709f94f
494 changed files with 50986 additions and 27639 deletions

View File

@@ -0,0 +1,21 @@
{
"name": "@sy/vite-plugin-http2-proxy",
"version": "0.0.2",
"type": "module",
"description": "",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": "./dist/index.js",
"scripts": {
"build": "tsc",
"clean:lock": "rimraf pnpm-lock.yaml && rimraf package.lock.json",
"clean:lib": "rimraf node_modules"
},
"license": "MIT",
"dependencies": {
"http2-proxy": "^5.0.53"
},
"devDependencies": {
"vite": "6.1.0"
}
}

View File

@@ -0,0 +1,138 @@
import http2Proxy from "http2-proxy";
import type { Plugin, PluginOption, ProxyOptions } from "vite";
const error = (message: string): never => {
throw new Error(message);
};
export default (options?: Record<string, ProxyOptions>): PluginOption => {
let routes: Record<string, ProxyOptions>;
const configure: Plugin["configureServer"] = ({
middlewares,
httpServer,
}) => {
const proxyOptions = options || routes;
for (const [regexp, serverOptions] of Object.entries(proxyOptions)) {
const {
target,
rewrite,
headers,
ws,
secure = true,
timeout = 30_000,
} = serverOptions;
if (!target) {
continue;
}
const re = new RegExp(regexp);
const urlObj = new URL(target.toString());
if (!urlObj.pathname.endsWith("/")) {
urlObj.pathname += "/";
}
const protocol = /^(http|ws)s?:$/.test(urlObj.protocol)
? (urlObj.protocol as "https" | "http")
: error(`Invalid protocol: ${urlObj.href}`);
const port =
urlObj.port === ""
? { https: 443, http: 80 }[protocol]
: /^\d+$/.test(urlObj.port)
? Number(urlObj.port)
: error(`Invalid port: ${urlObj.href}`);
// TODO unfinished
if (ws && httpServer) {
httpServer?.on("upgrade", (req, socket, head) => {
if (req.url && re.test(req.url)) {
const url = (rewrite?.(req.url) ?? req.url).replace(/^\/+/, "");
const { pathname, search } = new URL(url, urlObj);
http2Proxy.ws(
req,
socket,
head,
{
port: 443,
path: pathname + search,
proxyTimeout: timeout,
hostname: urlObj.hostname,
["rejectUnauthorized" as never]: secure,
...serverOptions,
},
(err) => {
if (err) {
console.error("proxy error", err);
socket.destroy();
}
}
);
}
});
} else {
middlewares.use((req, res, next) => {
if (req.url && re.test(req.url)) {
const url = (rewrite?.(req.url) ?? req.url).replace(/^\/+/, "");
const { pathname, search } = new URL(url, urlObj);
http2Proxy.web(
req,
res,
{
protocol,
port,
hostname: urlObj.hostname,
path: pathname + search,
proxyTimeout: timeout,
onReq: async (_, options) => {
options.headers = {
...options.headers,
...headers,
};
},
["rejectUnauthorized" as never]: secure,
...serverOptions,
},
(err) => err && next(err)
);
} else {
next();
}
});
}
}
};
// @ts-ignore
return {
name: "@sy/vite-plugin-http2-proxy",
config: (config) => {
const { server } = config;
routes = Object.entries(server?.proxy ?? {}).reduce(
(prev, [key, value]) => {
if (typeof value === "string") {
prev[key] = {
target: value,
};
} else {
prev[key] = value;
}
return prev;
},
{} as Record<string, ProxyOptions>
);
if (server) {
// https://cn.vitejs.dev/config/server-options#server-https
Reflect.deleteProperty(server, "proxy");
}
return config;
},
configureServer: configure,
// @ts-ignore
configurePreviewServer: configure,
};
};

View File

@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "ESNext",
"moduleResolution": "Node",
"module": "ESNext",
"outDir": "dist",
"declaration": true,
"strict": true,
"skipLibCheck": true,
"useUnknownInCatchVariables": false,
"allowSyntheticDefaultImports": true
}
}