"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var chain_exports = {};
__export(chain_exports, {
  CHAIN_ID: () => CHAIN_ID,
  applyOutputPlugin: () => applyOutputPlugin,
  applyResolvePlugin: () => applyResolvePlugin,
  applyScriptCondition: () => applyScriptCondition,
  getBundlerChain: () => getBundlerChain,
  modifyBundlerChain: () => modifyBundlerChain
});
module.exports = __toCommonJS(chain_exports);
var import_path = require("path");
var import_fs = require("./fs");
var import_utils = require("./utils");
var import_utils2 = require("./utils");
var import_logger = require("./logger");
var import_constants = require("./constants");
var import_mergeChainedOptions = require("./mergeChainedOptions");
async function getBundlerChain() {
  const { default: WebpackChain } = await Promise.resolve().then(() => __toESM(require("../compiled/webpack-chain")));
  const bundlerChain = new WebpackChain();
  return bundlerChain;
}
async function modifyBundlerChain(context, utils) {
  (0, import_logger.debug)("modify bundler chain");
  const bundlerChain = await getBundlerChain();
  const [modifiedBundlerChain] = await context.hooks.modifyBundlerChainHook.call(bundlerChain, utils);
  if (context.config.tools?.bundlerChain) {
    (0, import_utils2.castArray)(context.config.tools.bundlerChain).forEach((item) => {
      item(modifiedBundlerChain, utils);
    });
  }
  (0, import_logger.debug)("modify bundler chain done");
  return modifiedBundlerChain;
}
const CHAIN_ID = {
  /** Predefined rules */
  RULE: {
    /** Rule for .mjs */
    MJS: "mjs",
    /** Rule for fonts */
    FONT: "font",
    /** Rule for images */
    IMAGE: "image",
    /** Rule for media */
    MEDIA: "media",
    /** Rule for js */
    JS: "js",
    /** Rule for data uri encoded javascript */
    JS_DATA_URI: "js-data-uri",
    /** Rule for ts */
    TS: "ts",
    /** Rule for css */
    CSS: "css",
    /** Rule for less */
    LESS: "less",
    /** Rule for sass */
    SASS: "sass",
    /** Rule for stylus */
    STYLUS: "stylus",
    /** Rule for svg */
    SVG: "svg",
    /** Rule for pug */
    PUG: "pug",
    /** Rule for Vue */
    VUE: "vue",
    /** Rule for toml */
    TOML: "toml",
    /** Rule for yaml */
    YAML: "yaml",
    /** Rule for wasm */
    WASM: "wasm",
    /** Rule for node */
    NODE: "node",
    /** Rule for svelte */
    SVELTE: "svelte"
  },
  /** Predefined rule groups */
  ONE_OF: {
    SVG: "svg",
    SVG_URL: "svg-url",
    SVG_ASSET: "svg-asset",
    SVG_INLINE: "svg-inline"
  },
  /** Predefined loaders */
  USE: {
    /** ts-loader */
    TS: "ts",
    /** css-loader */
    CSS: "css",
    /** sass-loader */
    SASS: "sass",
    /** less-loader */
    LESS: "less",
    /** stylus-loader */
    STYLUS: "stylus",
    /** url-loader */
    URL: "url",
    /** pug-loader */
    PUG: "pug",
    /** vue-loader */
    VUE: "vue",
    /** @svgr/webpack */
    SVGR: "svgr",
    /** yaml-loader */
    YAML: "yaml",
    /** toml-loader */
    TOML: "toml",
    /** node-loader */
    NODE: "node",
    /** babel-loader */
    BABEL: "babel",
    /** esbuild-loader */
    ESBUILD: "esbuild",
    /** swc-loader */
    SWC: "swc",
    /** style-loader */
    STYLE: "style-loader",
    /** postcss-loader */
    POSTCSS: "postcss",
    /** ignore-css-loader */
    IGNORE_CSS: "ignore-css",
    /** css-modules-typescript-loader */
    CSS_MODULES_TS: "css-modules-typescript",
    /** mini-css-extract-plugin.loader */
    MINI_CSS_EXTRACT: "mini-css-extract",
    /** resolve-url-loader */
    RESOLVE_URL_LOADER_FOR_SASS: "resolve-url-loader",
    /** plugin-image-compress.loader */
    IMAGE_COMPRESS: "image-compress",
    /** plugin-image-compress svgo-loader */
    SVGO: "svgo",
    /** svelte-loader */
    SVELTE: "svelte"
  },
  /** Predefined plugins */
  PLUGIN: {
    /** HotModuleReplacementPlugin */
    HMR: "hmr",
    /** CopyWebpackPlugin */
    COPY: "copy",
    /** HtmlWebpackPlugin */
    HTML: "html",
    /** DefinePlugin */
    DEFINE: "define",
    /** IgnorePlugin */
    IGNORE: "ignore",
    /** BannerPlugin */
    BANNER: "banner",
    /** ProgressPlugin */
    PROGRESS: "progress",
    /** Inspector */
    INSPECTOR: "inspector",
    /** AppIconPlugin */
    APP_ICON: "app-icon",
    /** WebpackManifestPlugin */
    MANIFEST: "webpack-manifest",
    /** ForkTsCheckerWebpackPlugin */
    TS_CHECKER: "ts-checker",
    /** InlineChunkHtmlPlugin */
    INLINE_HTML: "inline-html",
    /** WebpackBundleAnalyzer */
    BUNDLE_ANALYZER: "bundle-analyze",
    /** HtmlTagsPlugin */
    HTML_TAGS: "html-tags",
    /** HtmlBasicPlugin */
    HTML_BASIC: "html-basic",
    /** HtmlNoncePlugin */
    HTML_NONCE: "html-nonce",
    /** HtmlCrossOriginPlugin */
    HTML_CROSS_ORIGIN: "html-cross-origin",
    /** htmlPreconnectPlugin */
    HTML_PRECONNECT: "html-preconnect-plugin",
    /** htmlDnsPrefetchPlugin */
    HTML_DNS_PREFETCH: "html-dns-prefetch-plugin",
    /** htmlPrefetchPlugin */
    HTML_PREFETCH: "html-prefetch-plugin",
    /** htmlPreloadPlugin */
    HTML_PRELOAD: "html-preload-plugin",
    /** MiniCssExtractPlugin */
    MINI_CSS_EXTRACT: "mini-css-extract",
    /** VueLoaderPlugin */
    VUE_LOADER_PLUGIN: "vue-loader-plugin",
    /** ReactFastRefreshPlugin */
    REACT_FAST_REFRESH: "react-fast-refresh",
    /** ProvidePlugin for node polyfill */
    NODE_POLYFILL_PROVIDE: "node-polyfill-provide",
    /** WebpackSRIPlugin */
    SUBRESOURCE_INTEGRITY: "subresource-integrity",
    /** WebpackAssetsRetryPlugin */
    ASSETS_RETRY: "assets-retry",
    /** AutoSetRootFontSizePlugin */
    AUTO_SET_ROOT_SIZE: "auto-set-root-size",
    /** HtmlAsyncChunkPlugin */
    HTML_ASYNC_CHUNK: "html-async-chunk"
  },
  /** Predefined minimizers */
  MINIMIZER: {
    /** TerserWebpackPlugin */
    JS: "js",
    /** CssMinimizerWebpackPlugin */
    CSS: "css",
    /** ESBuildPlugin */
    ESBUILD: "js-css",
    /** SWCPlugin */
    SWC: "swc"
  },
  /** Predefined resolve plugins */
  RESOLVE_PLUGIN: {
    /** ModuleScopePlugin */
    MODULE_SCOPE: "module-scope",
    /** TsConfigPathsPlugin */
    TS_CONFIG_PATHS: "ts-config-paths"
  }
};
function applyScriptCondition({
  rule,
  config,
  context,
  includes,
  excludes
}) {
  rule.include.add({
    and: [context.rootPath, { not: import_constants.NODE_MODULES_REGEX }]
  });
  rule.include.add(import_constants.TS_AND_JSX_REGEX);
  [...includes, ...config.source.include || []].forEach((condition) => {
    rule.include.add(condition);
  });
  [...excludes, ...config.source.exclude || []].forEach((condition) => {
    rule.exclude.add(condition);
  });
}
function applyOutputPlugin(api) {
  function getPublicPath({
    config,
    isProd,
    context
  }) {
    const { dev, output } = config;
    let publicPath = import_constants.DEFAULT_ASSET_PREFIX;
    if (isProd) {
      if (output.assetPrefix) {
        publicPath = output.assetPrefix;
      }
    } else if (typeof dev.assetPrefix === "string") {
      publicPath = dev.assetPrefix;
    } else if (dev.assetPrefix === true) {
      const protocol = context.devServer?.https ? "https" : "http";
      const hostname = context.devServer?.hostname || import_constants.DEFAULT_DEV_HOST;
      const port = context.devServer?.port || import_constants.DEFAULT_PORT;
      if (hostname === import_constants.DEFAULT_DEV_HOST) {
        const localHostname = `localhost`;
        publicPath = `${protocol}://${localHostname}:${port}/`;
      } else {
        publicPath = `${protocol}://${hostname}:${port}/`;
      }
    }
    return (0, import_utils.addTrailingSlash)(publicPath);
  }
  api.modifyBundlerChain(
    async (chain, { isProd, isServer, isServiceWorker }) => {
      const config = api.getNormalizedConfig();
      const jsPath = (0, import_fs.getDistPath)(config, "js");
      const publicPath = getPublicPath({
        config,
        isProd,
        context: api.context
      });
      const jsFilename = (0, import_fs.getFilename)(config, "js", isProd);
      chain.output.path(api.context.distPath).filename(import_path.posix.join(jsPath, jsFilename)).chunkFilename(import_path.posix.join(jsPath, `async/${jsFilename}`)).publicPath(publicPath).pathinfo(false).hashFunction("xxhash64");
      if (isServer) {
        const serverPath = (0, import_fs.getDistPath)(config, "server");
        const filename = import_path.posix.join(serverPath, `[name].js`);
        chain.output.filename(filename).chunkFilename(filename).libraryTarget("commonjs2");
      }
      if (isServiceWorker) {
        const workerPath = (0, import_fs.getDistPath)(config, "worker");
        const filename = import_path.posix.join(workerPath, `[name].js`);
        chain.output.filename(filename).chunkFilename(filename);
      }
    }
  );
}
function applyResolvePlugin(api) {
  api.modifyBundlerChain((chain, { CHAIN_ID: CHAIN_ID2 }) => {
    const config = api.getNormalizedConfig();
    applyExtensions({ chain });
    applyAlias({
      chain,
      config,
      rootPath: api.context.rootPath
    });
    applyFullySpecified({ chain, config, CHAIN_ID: CHAIN_ID2 });
  });
}
function applyFullySpecified({
  chain,
  CHAIN_ID: CHAIN_ID2
}) {
  chain.module.rule(CHAIN_ID2.RULE.MJS).test(/\.m?js/).resolve.set("fullySpecified", false);
  if (chain.module.rules.get(CHAIN_ID2.RULE.JS_DATA_URI)) {
    chain.module.rule(CHAIN_ID2.RULE.JS_DATA_URI).resolve.set("fullySpecified", false);
  }
}
function applyExtensions({ chain }) {
  const extensions = [
    // most projects are using TypeScript, resolve .ts(x) files first to reduce resolve time.
    ".ts",
    ".tsx",
    ".js",
    ".jsx",
    ".mjs",
    ".json"
  ];
  chain.resolve.extensions.merge(extensions);
}
function applyAlias({
  chain,
  config,
  rootPath
}) {
  const { alias } = config.source;
  if (!alias) {
    return;
  }
  const mergedAlias = (0, import_mergeChainedOptions.mergeChainedOptions)({
    defaults: {},
    options: alias
  });
  Object.keys(mergedAlias).forEach((name) => {
    const values = (0, import_utils2.castArray)(mergedAlias[name]);
    const formattedValues = values.map((value) => {
      if (typeof value === "string" && value.startsWith(".")) {
        return (0, import_utils2.ensureAbsolutePath)(rootPath, value);
      }
      return value;
    });
    chain.resolve.alias.set(
      name,
      formattedValues.length === 1 ? formattedValues[0] : formattedValues
    );
  });
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  CHAIN_ID,
  applyOutputPlugin,
  applyResolvePlugin,
  applyScriptCondition,
  getBundlerChain,
  modifyBundlerChain
});
