"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.proxyMiddleware = void 0;
const utils_1 = require("../../utils");
const http_proxy_1 = __importDefault(require("http-proxy"));
const ws_1 = require("../ws");
const debug = utils_1.createDebugger('vite:proxy');
function proxyMiddleware({ httpServer, config }) {
    const options = config.server.proxy;
    // lazy require only when proxy is used
    const proxies = {};
    Object.keys(options).forEach((context) => {
        let opts = options[context];
        if (typeof opts === 'string') {
            opts = { target: opts };
        }
        const proxy = http_proxy_1.default.createProxyServer(opts);
        if (opts.configure) {
            opts.configure(proxy, opts);
        }
        // clone before saving becaues http-proxy mutates the options
        proxies[context] = [proxy, { ...opts }];
    });
    httpServer.on('upgrade', (req, socket, head) => {
        var _a;
        const url = req.url;
        for (const context in proxies) {
            if (url.startsWith(context)) {
                const [proxy, opts] = proxies[context];
                if ((opts.ws || ((_a = opts.target) === null || _a === void 0 ? void 0 : _a.toString().startsWith('ws:'))) &&
                    req.headers['sec-websocket-protocol'] !== ws_1.HMR_HEADER) {
                    proxy.ws(req, socket, head);
                }
            }
        }
    });
    return (req, res, next) => {
        const url = req.url;
        for (const context in proxies) {
            if (url.startsWith(context)) {
                const [proxy, opts] = proxies[context];
                if (opts.bypass) {
                    const bypassResult = opts.bypass(req, res, opts);
                    if (typeof bypassResult === 'string') {
                        req.url = bypassResult;
                        debug(`bypass: ${req.url} -> ${bypassResult}`);
                        return next();
                    }
                    else if (bypassResult === false) {
                        debug(`bypass: ${req.url} -> 404`);
                        return res.end(404);
                    }
                }
                debug(`${req.url} -> ${opts.target || opts.forward}`);
                if (opts.rewrite) {
                    req.url = opts.rewrite(req.url);
                }
                proxy.web(req, res);
                return;
            }
        }
        next();
    };
}
exports.proxyMiddleware = proxyMiddleware;
//# sourceMappingURL=proxy.js.map