"use strict";
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHtmlMinifier = getHtmlMinifier;
const html_minifier_terser_1 = require("html-minifier-terser");
const importFaster_1 = require("./importFaster");
// Historical env variable
const SkipHtmlMinification = process.env.SKIP_HTML_MINIFICATION === 'true';
const NoopMinifier = {
    minify: async (html) => ({ code: html, warnings: [] }),
};
async function getHtmlMinifier({ type, }) {
    if (SkipHtmlMinification) {
        return NoopMinifier;
    }
    if (type === 'swc') {
        return getSwcMinifier();
    }
    else {
        return getTerserMinifier();
    }
}
// Minify html with https://github.com/DanielRuf/html-minifier-terser
async function getTerserMinifier() {
    return {
        minify: async function minifyHtmlWithTerser(html) {
            try {
                const code = await (0, html_minifier_terser_1.minify)(html, {
                    // When enabled => React hydration errors
                    removeComments: false,
                    removeRedundantAttributes: false,
                    removeEmptyAttributes: false,
                    sortAttributes: false,
                    sortClassName: false,
                    removeScriptTypeAttributes: true,
                    removeStyleLinkTypeAttributes: true,
                    useShortDoctype: true,
                    minifyJS: true,
                });
                return { code, warnings: [] };
            }
            catch (err) {
                throw new Error(`HTML minification failed (Terser)`, {
                    cause: err,
                });
            }
        },
    };
}
// Minify html with @swc/html
// Not well-documented but fast!
// See https://github.com/swc-project/swc/discussions/9616
async function getSwcMinifier() {
    const swcHtmlMinifier = await (0, importFaster_1.importSwcHtmlMinifier)();
    return {
        minify: async function minifyHtmlWithSwc(html) {
            try {
                const result = await swcHtmlMinifier(Buffer.from(html), {
                    // Removing comments can lead to React hydration errors
                    // See https://x.com/sebastienlorber/status/1841966927440478577
                    removeComments: false,
                    // TODO maybe it's fine to only keep <!-- --> React comments?
                    preserveComments: [],
                    // Keep <head> tag: important for social image crawlers like LinkedIn
                    // See https://github.com/swc-project/swc/issues/10994
                    tagOmission: 'keep-head-and-body',
                    // Sorting these attributes (class) can lead to React hydration errors
                    sortSpaceSeparatedAttributeValues: false,
                    sortAttributes: false,
                    // When enabled => hydration error for className={"yt-lite "}
                    normalizeAttributes: false,
                    // When enabled => hydration error for className=""
                    removeEmptyAttributes: false,
                    // When enabled => hydration error for <a target="_self">
                    removeRedundantAttributes: 'none',
                    minifyJs: true,
                    minifyJson: true,
                    minifyCss: true,
                });
                const warnings = (result.errors ?? []).map((diagnostic) => {
                    return `[HTML minifier diagnostic - ${diagnostic.level}] ${diagnostic.message} - ${JSON.stringify(diagnostic.span)}`;
                });
                return {
                    code: result.code,
                    warnings,
                };
            }
            catch (err) {
                throw new Error(`HTML minification failed (SWC)`, {
                    cause: err,
                });
            }
        },
    };
}
//# sourceMappingURL=minifyHtml.js.map