"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,
  chainToConfig: () => chainToConfig,
  formatPublicPath: () => formatPublicPath,
  getBundlerChain: () => getBundlerChain,
  getPublicPathFromChain: () => getPublicPathFromChain,
  modifyBundlerChain: () => modifyBundlerChain,
  modifySwcLoaderOptions: () => modifySwcLoaderOptions
});
module.exports = __toCommonJS(chain_exports);
var import_node_path = require("node: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.modifyBundlerChain.call(
    bundlerChain,
    utils
  );
  if (context.config.tools?.bundlerChain) {
    for (const item of (0, import_utils2.castArray)(context.config.tools.bundlerChain)) {
      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-asset-url",
    SVG_ASSET: "svg-asset",
    SVG_REACT: "svg-react",
    SVG_INLINE: "svg-asset-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",
    /** swc-loader */
    SWC: "swc",
    /** svgr */
    SVGR: "svgr",
    /** plugin-image-compress svgo-loader */
    SVGO: "svgo",
    /** yaml-loader */
    YAML: "yaml",
    /** toml-loader */
    TOML: "toml",
    /** node-loader */
    NODE: "node",
    /** babel-loader */
    BABEL: "babel",
    /** style-loader */
    STYLE: "style-loader",
    /** svelte-loader */
    SVELTE: "svelte",
    /** esbuild-loader */
    ESBUILD: "esbuild",
    /** postcss-loader */
    POSTCSS: "postcss",
    /** lightningcss-loader */
    LIGHTNINGCSS: "lightningcss",
    /** 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: "resolve-url-loader",
    /** plugin-image-compress.loader */
    IMAGE_COMPRESS: "image-compress"
  },
  /** Predefined plugins */
  PLUGIN: {
    /** HotModuleReplacementPlugin */
    HMR: "hmr",
    /** CopyWebpackPlugin */
    COPY: "copy",
    /** HtmlWebpackPlugin */
    HTML: "html",
    /** ESLintWebpackPlugin */
    ESLINT: "eslint",
    /** DefinePlugin */
    DEFINE: "define",
    /** ProgressPlugin */
    PROGRESS: "progress",
    /** AppIconPlugin */
    APP_ICON: "app-icon",
    /** WebpackManifestPlugin */
    MANIFEST: "webpack-manifest",
    /** ForkTsCheckerWebpackPlugin */
    TS_CHECKER: "ts-checker",
    /** InlineChunkHtmlPlugin */
    INLINE_HTML: "inline-html",
    /** WebpackBundleAnalyzer */
    BUNDLE_ANALYZER: "bundle-analyze",
    /** ModuleFederationPlugin */
    MODULE_FEDERATION: "module-federation",
    /** HtmlBasicPlugin */
    HTML_BASIC: "html-basic-plugin",
    /** HtmlNoncePlugin */
    HTML_NONCE: "html-nonce-plugin",
    /** HtmlCrossOriginPlugin */
    HTML_CROSS_ORIGIN: "html-cross-origin-plugin",
    /** 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",
    /** AssetsRetryPlugin */
    ASSETS_RETRY: "assets-retry",
    /** AutoSetRootFontSizePlugin */
    AUTO_SET_ROOT_SIZE: "auto-set-root-size"
  },
  /** Predefined minimizers */
  MINIMIZER: {
    /** SwcJsMinimizerRspackPlugin */
    JS: "js",
    /** SwcCssMinimizerRspackPlugin */
    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);
  for (const condition of [...includes, ...config.source.include || []]) {
    rule.include.add(condition);
  }
  for (const condition of [...excludes, ...config.source.exclude || []]) {
    rule.exclude.add(condition);
  }
}
const formatPublicPath = (publicPath, withSlash = true) => {
  if (publicPath === "auto") {
    return publicPath;
  }
  return withSlash ? (0, import_utils.addTrailingSlash)(publicPath) : (0, import_utils.removeTailingSlash)(publicPath);
};
const getPublicPathFromChain = (chain, withSlash = true) => {
  const publicPath = chain.output.get("publicPath");
  if (typeof publicPath === "string") {
    return formatPublicPath(publicPath, withSlash);
  }
  return formatPublicPath(import_constants.DEFAULT_ASSET_PREFIX, withSlash);
};
function getPublicPath({
  config,
  isProd,
  context
}) {
  const { dev, output } = config;
  let publicPath = import_constants.DEFAULT_ASSET_PREFIX;
  if (isProd) {
    if (typeof output.assetPrefix === "string") {
      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 formatPublicPath(publicPath);
}
function applyOutputPlugin(api) {
  api.modifyBundlerChain(
    async (chain, { isProd, isServer, isServiceWorker }) => {
      const config = api.getNormalizedConfig();
      const publicPath = getPublicPath({
        config,
        isProd,
        context: api.context
      });
      const jsPath = (0, import_fs.getDistPath)(config, "js");
      const jsAsyncPath = (0, import_fs.getDistPath)(config, "jsAsync");
      const jsFilename = (0, import_fs.getFilename)(config, "js", isProd);
      chain.output.path(api.context.distPath).filename(import_node_path.posix.join(jsPath, jsFilename)).chunkFilename(import_node_path.posix.join(jsAsyncPath, jsFilename)).publicPath(publicPath).pathinfo(false).hashFunction("xxhash64");
      if (isServer) {
        const serverPath = (0, import_fs.getDistPath)(config, "server");
        chain.output.path(import_node_path.posix.join(api.context.distPath, serverPath)).filename("[name].js").chunkFilename("[name].js").libraryTarget("commonjs2");
      }
      if (isServiceWorker) {
        const workerPath = (0, import_fs.getDistPath)(config, "worker");
        const filename = import_node_path.posix.join(workerPath, "[name].js");
        chain.output.filename(filename).chunkFilename(filename);
      }
    }
  );
}
function applyResolvePlugin(api) {
  api.modifyBundlerChain({
    order: "pre",
    handler: (chain, { target, CHAIN_ID: CHAIN_ID2 }) => {
      const config = api.getNormalizedConfig();
      applyExtensions({ chain });
      applyAlias({
        chain,
        target,
        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);
}
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,
  target,
  config,
  rootPath
}) {
  const { alias } = config.source;
  if (!alias) {
    return;
  }
  const mergedAlias = (0, import_mergeChainedOptions.mergeChainedOptions)({
    defaults: {},
    options: alias,
    utils: { target }
  });
  for (const name of Object.keys(mergedAlias)) {
    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
    );
  }
}
function chainToConfig(chain) {
  const config = chain.toConfig();
  const { entry } = config;
  if (!(0, import_utils.isPlainObject)(entry)) {
    return config;
  }
  const formattedEntry = {};
  for (const [entryName, entryValue] of Object.entries(entry)) {
    const entryImport = [];
    let entryDescription = null;
    for (const item of (0, import_utils2.castArray)(entryValue)) {
      if (typeof item === "string") {
        entryImport.push(item);
        continue;
      }
      if (item.import) {
        entryImport.push(...(0, import_utils2.castArray)(item.import));
      }
      if (entryDescription) {
        Object.assign(entryDescription, item);
      } else {
        entryDescription = item;
      }
    }
    formattedEntry[entryName] = entryDescription ? {
      ...entryDescription,
      import: entryImport
    } : entryImport;
  }
  config.entry = formattedEntry;
  return config;
}
const modifySwcLoaderOptions = ({
  chain,
  modifier
}) => {
  const ruleIds = [CHAIN_ID.RULE.JS, CHAIN_ID.RULE.JS_DATA_URI];
  for (const ruleId of ruleIds) {
    if (chain.module.rules.has(ruleId)) {
      const rule = chain.module.rule(ruleId);
      if (rule.uses.has(CHAIN_ID.USE.SWC)) {
        rule.use(CHAIN_ID.USE.SWC).tap(modifier);
      }
    }
  }
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  CHAIN_ID,
  applyOutputPlugin,
  applyResolvePlugin,
  applyScriptCondition,
  chainToConfig,
  formatPublicPath,
  getBundlerChain,
  getPublicPathFromChain,
  modifyBundlerChain,
  modifySwcLoaderOptions
});
