text: "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.
   */
  var __rest = (this && this.__rest) || function (s, e) {
      var t = {};
      for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
          t[p] = s[p];
      if (s != null && typeof Object.getOwnPropertySymbols === "function")
          for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
              if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                  t[p[i]] = s[p[i]];
          }
      return t;
  };
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getFileLoaderUtils = exports.compile = exports.applyConfigureWebpack = exports.getBabelLoader = exports.getCacheLoader = exports.getStyleLoaders = void 0;
  const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
  const std_env_1 = __importDefault(require("std-env"));
  const webpack_merge_1 = __importDefault(require("webpack-merge"));
  const webpack_1 = __importDefault(require("webpack"));
  const package_json_1 = require("cache-loader/package.json");
  const constants_1 = require("../constants");
  // Utility method to get style loaders
  function getStyleLoaders(isServer, cssOptions = {}) {
      if (isServer) {
          return [
              cssOptions.modules
                  ? {
                      loader: require.resolve('css-loader'),
                      options: cssOptions,
                  }
                  : require.resolve('null-loader'),
          ];
      }
      const isProd = process.env.NODE_ENV === 'production';
      const loaders = [
          {
              loader: mini_css_extract_plugin_1.default.loader,
              options: {
                  hmr: !isProd,
              },
          },
          {
              loader: require.resolve('css-loader'),
              options: cssOptions,
          },
          {
              // Options for PostCSS as we reference these options twice
              // Adds vendor prefixing based on your specified browser support in
              // package.json
              loader: require.resolve('postcss-loader'),
              options: {
                  // Necessary for external CSS imports to work
                  // https://github.com/facebook/create-react-app/issues/2677
                  ident: 'postcss',
                  plugins: () => [
                      // eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
                      require('postcss-preset-env')({
                          autoprefixer: {
                              flexbox: 'no-2009',
                          },
                          stage: 3,
                      }),
                  ],
              },
          },
      ];
      return loaders;
  }
  exports.getStyleLoaders = getStyleLoaders;
  function getCacheLoader(isServer, cacheOptions) {
      if (std_env_1.default.ci || std_env_1.default.test) {
          return null;
      }
      return {
          loader: require.resolve('cache-loader'),
          options: Object.assign({ cacheIdentifier: `cache-loader:${package_json_1.version}${isServer}` }, cacheOptions),
      };
  }
  exports.getCacheLoader = getCacheLoader;
  function getBabelLoader(isServer, babelOptions) {
      let options;
      if (typeof babelOptions === 'string') {
          options = {
              babelrc: false,
              configFile: babelOptions,
              caller: { name: isServer ? 'server' : 'client' },
          };
      }
      else {
          options = Object.assign(babelOptions !== null && babelOptions !== void 0 ? babelOptions : { presets: [require.resolve('../babel/preset')] }, {
              babelrc: false,
              configFile: false,
              caller: { name: isServer ? 'server' : 'client' },
          });
      }
      return {
          loader: require.resolve('babel-loader'),
          options,
      };
  }
  exports.getBabelLoader = getBabelLoader;
  /**
   * Helper function to modify webpack config
   * @param configureWebpack a webpack config or a function to modify config
   * @param config initial webpack config
   * @param isServer indicates if this is a server webpack configuration
   * @returns final/ modified webpack config
   */
  function applyConfigureWebpack(configureWebpack, config, isServer) {
      // Export some utility functions
      const utils = {
          getStyleLoaders,
          getCacheLoader,
          getBabelLoader,
      };
      if (typeof configureWebpack === 'function') {
          const _a = configureWebpack(config, isServer, utils), { mergeStrategy } = _a, res = __rest(_a, ["mergeStrategy"]);
          if (res && typeof res === 'object') {
              return webpack_merge_1.default.strategy(mergeStrategy !== null && mergeStrategy !== void 0 ? mergeStrategy : {})(config, res);
          }
      }
      return config;
  }
  exports.applyConfigureWebpack = applyConfigureWebpack;
  function compile(config) {
      return new Promise((resolve, reject) => {
          const compiler = webpack_1.default(config);
          compiler.run((err, stats) => {
              var _a;
              if (err) {
                  reject(err);
              }
              if (stats.hasErrors()) {
                  stats.toJson('errors-only').errors.forEach((e) => {
                      console.error(e);
                  });
                  reject(new Error('Failed to compile with errors.'));
              }
              if (stats.hasWarnings()) {
                  // Custom filtering warnings (see https://github.com/webpack/webpack/issues/7841).
                  let { warnings } = stats.toJson('errors-warnings');
                  const warningsFilter = (((_a = config[0].stats) === null || _a === void 0 ? void 0 : _a.warningsFilter) || []);
                  if (Array.isArray(warningsFilter)) {
                      warnings = warnings.filter((warning) => warningsFilter.every((str) => !warning.includes(str)));
                  }
                  warnings.forEach((warning) => {
                      console.warn(warning);
                  });
              }
              resolve();
          });
      });
  }
  exports.compile = compile;
  // Inspired by https://github.com/gatsbyjs/gatsby/blob/8e6e021014da310b9cc7d02e58c9b3efe938c665/packages/gatsby/src/utils/webpack-utils.ts#L447
  function getFileLoaderUtils() {
      // files/images < 10kb will be inlined as base64 strings directly in the html
      const urlLoaderLimit = 10000;
      // defines the path/pattern of the assets handled by webpack
      const fileLoaderFileName = (folder) => `${constants_1.STATIC_ASSETS_DIR_NAME}/${folder}/[name]-[hash].[ext]`;
      const loaders = {
          file: (options) => {
              return {
                  loader: require.resolve(`file-loader`),
                  options: {
                      name: fileLoaderFileName(options.folder),
                  },
              };
          },
          url: (options) => {
              return {
                  loader: require.resolve(`url-loader`),
                  options: {
                      limit: urlLoaderLimit,
                      name: fileLoaderFileName(options.folder),
                      fallback: require.resolve(`file-loader`),
                  },
              };
          },
          // TODO find a better solution to avoid conflicts with the ideal-image plugin
          // TODO this may require a little breaking change for ideal-image users?
          // Maybe with the ideal image plugin, all md images should be "ideal"?
          // This is used to force url-loader+file-loader on markdown images
          // https://webpack.js.org/concepts/loaders/#inline
          inlineMarkdownImageFileLoader: `!url-loader?limit=${urlLoaderLimit}&name=${fileLoaderFileName('images')}&fallback=file-loader!`,
      };
      const rules = {
          /**
           * Loads image assets, inlines images via a data URI if they are below
           * the size threshold
           */
          images: () => {
              return {
                  use: [loaders.url({ folder: 'images' })],
                  test: /\.(ico|svg|jpg|jpeg|png|gif|webp)(\?.*)?$/,
              };
          },
          /**
           * Loads audio and video and inlines them via a data URI if they are below
           * the size threshold
           */
          media: () => {
              return {
                  use: [loaders.url({ folder: 'medias' })],
                  test: /\.(mp4|webm|ogv|wav|mp3|m4a|aac|oga|flac)$/,
              };
          },
          otherAssets: () => {
              return {
                  use: [loaders.file({ folder: 'files' })],
                  test: /\.(pdf|doc|docx|xls|xlsx|zip|rar)$/,
              };
          },
      };
      return { loaders, rules };
  }
  exports.getFileLoaderUtils = getFileLoaderUtils;
  