"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.injectEntry = void 0;
const tslib_1 = require("tslib");
const webpack_1 = tslib_1.__importDefault(require("webpack"));
/**
 * inject entry to webpack config
 * @param options webpack config
 * @param entryName specific which entry will inject new files, will inject to all entries if not specific
 * @param prepends prepends those files to the head of original entry
 * @param appends appends those files to the end of original entry
 */
const injectEntry = (compiler, entryName, prepends = [], appends = []) => {
    const currentWebpack = compiler.webpack || webpack_1.default;
    const { options } = compiler;
    if (!currentWebpack.version || currentWebpack.version.startsWith('4')) {
        injectEntryWebpack4(options, entryName, prepends, appends);
    }
    else {
        injectEntryWebpack5(options, entryName, prepends, appends);
    }
    compiler.hooks.entryOption.call(compiler.options.context, compiler.options.entry);
};
exports.injectEntry = injectEntry;
function injectEntryWebpack5(options, entryName, prepends = [], appends = []) {
    const entry = typeof options.entry === 'function' ? options.entry() : Promise.resolve(options.entry);
    options.entry = () => entry.then((entryObj) => {
        function injectOneEntry(entryName) {
            const injectEntry = entryObj[entryName];
            if (!(injectEntry === null || injectEntry === void 0 ? void 0 : injectEntry.import)) {
                throw new Error(`Could not find an entry named '${entryName}'. See https://webpack.js.org/concepts/entry-points/ for an overview of webpack entries.`);
            }
            prepends.forEach((prepend) => {
                if (!injectEntry.import.includes(prepend))
                    injectEntry.import.unshift(prepend);
            });
            appends.forEach((append) => {
                if (!injectEntry.import.includes(append))
                    injectEntry.import.push(append);
            });
            return entryObj;
        }
        if (entryName) {
            injectOneEntry(entryName);
        }
        else {
            Object.keys(entryObj).forEach((entryName) => {
                injectOneEntry(entryName);
            });
        }
        return entryObj;
    });
}
function injectEntryWebpack4(options, entryName, prepends = [], appends = []) {
    function injectEntry(entry) {
        switch (typeof entry) {
            case 'undefined': {
                throw new Error(`Could not find an entry named '${entryName}'. See https://webpack.js.org/concepts/entry-points/ for an overview of webpack entries.`);
            }
            case 'string': {
                return [...prepends, entry, ...appends];
            }
            case 'object': {
                if (Array.isArray(entry)) {
                    prepends.forEach((file) => {
                        if (!entry.includes(file))
                            entry.unshift(file);
                    });
                    appends.forEach((file) => {
                        if (!entry.includes(file))
                            entry.push(file);
                    });
                    return entry;
                }
                if (entryName) {
                    return {
                        ...entry,
                        [entryName]: injectEntry(entry[entryName]),
                    };
                }
                Object.keys(entry).forEach((key) => {
                    entry[key] = injectEntry(entry[key]);
                });
                return entry;
            }
            default: {
                const _exhaust = entry;
                return _exhaust;
            }
        }
    }
    const { entry } = options;
    typeof entry === 'function'
        ? (options.entry = () => Promise.resolve(entry()).then(injectEntry))
        : (options.entry = () => injectEntry(entry));
}
