"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformMiddleware = void 0;
const css_1 = require("../../plugins/css");
const utils_1 = require("../../utils");
const send_1 = require("../send");
const transformRequest_1 = require("../transformRequest");
const html_1 = require("../../plugins/html");
const chalk_1 = __importDefault(require("chalk"));
const constants_1 = require("../../constants");
const debugCache = utils_1.createDebugger('vite:cache');
const isDebug = !!process.env.DEBUG;
const knownIgnoreList = new Set(['/', '/favicon.ico']);
function transformMiddleware(server) {
    const { config: { root, logger, assetsInclude }, moduleGraph } = server;
    return async (req, res, next) => {
        var _a, _b, _c, _d, _e, _f;
        if (req.method !== 'GET' || ((_a = req.headers.accept) === null || _a === void 0 ? void 0 : _a.includes('text/html')) ||
            knownIgnoreList.has(req.url)) {
            return next();
        }
        let url = decodeURI(utils_1.removeTimestampQuery(req.url));
        const withoutQuery = utils_1.cleanUrl(url);
        try {
            const isSourceMap = withoutQuery.endsWith('.map');
            // since we generate source map references, handle those requests here
            if (isSourceMap) {
                // #1323 - browser may remove // when fetching source maps
                if (url.startsWith(constants_1.FS_PREFIX)) {
                    url = constants_1.FS_PREFIX + url.split(constants_1.FS_PREFIX)[1].replace(/^\/?/, '/');
                }
                const originalUrl = url.replace(/\.map($|\?)/, '$1');
                const map = (_c = (_b = (await moduleGraph.getModuleByUrl(originalUrl))) === null || _b === void 0 ? void 0 : _b.transformResult) === null || _c === void 0 ? void 0 : _c.map;
                if (map) {
                    return send_1.send(req, res, JSON.stringify(map), 'json');
                }
                else {
                    res.statusCode = 404;
                    return res.end();
                }
            }
            // warn explicit /public/ paths
            if (url.startsWith('/public/')) {
                logger.warn(chalk_1.default.yellow(`files in the public directory are served at the root path.\n` +
                    `Instead of ${chalk_1.default.cyan(url)}, use ${chalk_1.default.cyan(url.replace(/^\/public\//, '/'))}.`));
            }
            if (utils_1.isJSRequest(url) ||
                utils_1.isImportRequest(url) ||
                css_1.isCSSRequest(url) ||
                html_1.isHTMLProxy(url) ||
                (req.headers.accept === '*/*' && !assetsInclude(withoutQuery))) {
                // strip ?import
                url = utils_1.removeImportQuery(url);
                // Strip valid id prefix. This is preprended to resolved Ids that are
                // not valid browser import specifiers by the importAnalysis plugin.
                if (url.startsWith(constants_1.VALID_ID_PREFIX)) {
                    url = url.slice(constants_1.VALID_ID_PREFIX.length);
                }
                // for CSS, we need to differentiate between normal CSS requests and
                // imports
                if (css_1.isCSSRequest(url) && ((_d = req.headers.accept) === null || _d === void 0 ? void 0 : _d.includes('text/css'))) {
                    url = utils_1.injectQuery(url, 'direct');
                }
                // check if we can return 304 early
                const ifNoneMatch = req.headers['if-none-match'];
                if (ifNoneMatch &&
                    ((_f = (_e = (await moduleGraph.getModuleByUrl(url))) === null || _e === void 0 ? void 0 : _e.transformResult) === null || _f === void 0 ? void 0 : _f.etag) ===
                        ifNoneMatch) {
                    isDebug && debugCache(`[304] ${utils_1.prettifyUrl(url, root)}`);
                    res.statusCode = 304;
                    return res.end();
                }
                // resolve, load and transform using the plugin container
                const result = await transformRequest_1.transformRequest(url, server);
                if (result) {
                    const type = css_1.isDirectCSSRequest(url) ? 'css' : 'js';
                    const isDep = constants_1.DEP_VERSION_RE.test(url) ||
                        url.includes(`node_modules/${constants_1.DEP_CACHE_DIR}`);
                    return send_1.send(req, res, result.code, type, result.etag, 
                    // allow browser to cache npm deps!
                    isDep ? 'max-age=31536000,immutable' : 'no-cache', result.map);
                }
            }
        }
        catch (e) {
            return next(e);
        }
        next();
    };
}
exports.transformMiddleware = transformMiddleware;
//# sourceMappingURL=transform.js.map