'use strict';

var packageDetection = require('./packageDetection-2556dd6d.cjs.js');
require('react-dev-utils/FileSizeReporter');
require('react-dev-utils/formatWebpackMessages');
var chalk = require('chalk');
var fs = require('fs-extra');
var webpack = require('webpack');
require('yn');
require('path');
var config = require('./config-fab10260.cjs.js');
require('chokidar');
var index = require('./index-79e50cf7.cjs.js');
var openBrowser = require('react-dev-utils/openBrowser');
var cliNode = require('@backstage/cli-node');
var uniq = require('lodash/uniq');
var WebpackDevServer = require('webpack-dev-server');
var Lockfile = require('./Lockfile-1c04a5bb.cjs.js');
require('react-dev-utils/ModuleScopePlugin');
require('@backstage/cli-common');
require('@manypkg/get-packages');
require('eslint-webpack-plugin');
require('fork-ts-checker-webpack-plugin');
require('html-webpack-plugin');
require('lodash/pickBy');
require('@backstage/errors');
require('child_process');
require('util');
require('@openshift/dynamic-plugin-sdk-webpack');
require('@pmmmwh/react-refresh-webpack-plugin');
require('mini-css-extract-plugin');
require('@backstage/config');
require('@backstage/config-loader');
require('commander');
require('semver');
require('@yarnpkg/lockfile');
require('@yarnpkg/parsers');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var webpack__default = /*#__PURE__*/_interopDefaultLegacy(webpack);
var openBrowser__default = /*#__PURE__*/_interopDefaultLegacy(openBrowser);
var uniq__default = /*#__PURE__*/_interopDefaultLegacy(uniq);
var WebpackDevServer__default = /*#__PURE__*/_interopDefaultLegacy(WebpackDevServer);

const INCLUDED = [/^@backstage\//];
const includedFilter = (name) => INCLUDED.some((pattern) => pattern.test(name));
const FORBID_DUPLICATES = [
  /^@backstage\/core-app-api$/,
  /^@backstage\/plugin-/
];
const ALLOW_DUPLICATES = [
  /^@backstage\/core-plugin-api$/,
  // Duplicates of libraries are OK
  // TODO(Rugvip): Check this using package role instead
  /^@backstage\/plugin-.*-react$/,
  /^@backstage\/plugin-.*-node$/,
  /^@backstage\/plugin-.*-common$/
];
const forbiddenDuplicatesFilter = (name) => FORBID_DUPLICATES.some((pattern) => pattern.test(name)) && !ALLOW_DUPLICATES.some((pattern) => pattern.test(name));

async function serveBundle(options) {
  var _a, _b, _c;
  const paths = config.resolveBundlingPaths(options);
  const targetPkg = await fs__default["default"].readJson(paths.targetPackageJson);
  if (options.verifyVersions) {
    const lockfile = await Lockfile.Lockfile.load(
      index.paths.resolveTargetRoot("yarn.lock")
    );
    const result = lockfile.analyze({
      filter: includedFilter,
      localPackages: cliNode.PackageGraph.fromPackages(
        await cliNode.PackageGraph.listTargetPackages()
      )
    });
    const problemPackages = [...result.newVersions, ...result.newRanges].map(({ name: name2 }) => name2).filter(forbiddenDuplicatesFilter);
    if (problemPackages.length > 1) {
      console.log(
        chalk__default["default"].yellow(
          `\u26A0\uFE0F   Some of the following packages may be outdated or have duplicate installations:

          ${uniq__default["default"](problemPackages).join(", ")}
        `
        )
      );
      console.log(
        chalk__default["default"].yellow(
          `\u26A0\uFE0F   This can be resolved using the following command:

          yarn backstage-cli versions:check --fix
      `
        )
      );
    }
  }
  checkReactVersion();
  const { name } = await fs__default["default"].readJson(index.paths.resolveTarget("package.json"));
  let server = void 0;
  let latestFrontendAppConfigs = [];
  const cliConfig = await config.loadCliConfig({
    args: options.configPaths,
    fromPackage: name,
    withFilteredKeys: true,
    watch(appConfigs) {
      latestFrontendAppConfigs = appConfigs;
      server == null ? void 0 : server.invalidate();
    }
  });
  latestFrontendAppConfigs = cliConfig.frontendAppConfigs;
  const appBaseUrl = cliConfig.frontendConfig.getString("app.baseUrl");
  const backendBaseUrl = cliConfig.frontendConfig.getString("backend.baseUrl");
  if (appBaseUrl === backendBaseUrl) {
    console.log(
      chalk__default["default"].yellow(
        `\u26A0\uFE0F   Conflict between app baseUrl and backend baseUrl:

    app.baseUrl:     ${appBaseUrl}
    backend.baseUrl: ${backendBaseUrl}

    Must have unique hostname and/or ports.

    This can be resolved by changing app.baseUrl and backend.baseUrl to point to their respective local development ports.
`
      )
    );
  }
  const { frontendConfig, fullConfig } = cliConfig;
  const url = config.resolveBaseUrl(frontendConfig);
  const host = frontendConfig.getOptionalString("app.listen.host") || url.hostname;
  const port = frontendConfig.getOptionalNumber("app.listen.port") || Number(url.port) || (url.protocol === "https:" ? 443 : 80);
  const detectedModulesEntryPoint = await packageDetection.createDetectedModulesEntryPoint({
    config: fullConfig,
    targetPath: paths.targetPath,
    watch() {
      server == null ? void 0 : server.invalidate();
    }
  });
  const config$1 = await config.createConfig(paths, {
    ...options,
    checksEnabled: options.checksEnabled,
    isDev: true,
    baseUrl: url,
    frontendConfig,
    getFrontendAppConfigs: () => {
      return latestFrontendAppConfigs;
    },
    additionalEntryPoints: detectedModulesEntryPoint
  });
  const compiler = webpack__default["default"](config$1);
  server = new WebpackDevServer__default["default"](
    {
      hot: !process.env.CI,
      devMiddleware: {
        publicPath: (_a = config$1.output) == null ? void 0 : _a.publicPath,
        stats: "errors-warnings"
      },
      static: paths.targetPublic ? {
        publicPath: (_b = config$1.output) == null ? void 0 : _b.publicPath,
        directory: paths.targetPublic
      } : void 0,
      historyApiFallback: {
        // Paths with dots should still use the history fallback.
        // See https://github.com/facebookincubator/create-react-app/issues/387.
        disableDotRule: true,
        // The index needs to be rewritten relative to the new public path, including subroutes.
        index: `${(_c = config$1.output) == null ? void 0 : _c.publicPath}index.html`
      },
      https: url.protocol === "https:" ? {
        cert: fullConfig.getString("app.https.certificate.cert"),
        key: fullConfig.getString("app.https.certificate.key")
      } : false,
      host,
      port,
      proxy: targetPkg.proxy,
      // When the dev server is behind a proxy, the host and public hostname differ
      allowedHosts: [url.hostname],
      client: {
        webSocketURL: "auto://0.0.0.0:0/ws"
      }
    },
    compiler
  );
  await new Promise((resolve, reject) => {
    server == null ? void 0 : server.startCallback((err) => {
      if (err) {
        reject(err);
        return;
      }
      openBrowser__default["default"](url.href);
      resolve();
    });
  });
  const waitForExit = async () => {
    for (const signal of ["SIGINT", "SIGTERM"]) {
      process.on(signal, () => {
        server == null ? void 0 : server.close();
        process.exit();
      });
    }
    return new Promise(() => {
    });
  };
  return waitForExit;
}
function checkReactVersion() {
  try {
    const reactPkgPath = require.resolve("react/package.json", {
      paths: [index.paths.targetRoot]
    });
    const reactPkg = require(reactPkgPath);
    if (reactPkg.version.startsWith("16.")) {
      console.log(
        chalk__default["default"].yellow(
          `
\u26A0\uFE0F                                                                           \u26A0\uFE0F
\u26A0\uFE0F You are using React version 16, which is deprecated for use in Backstage. \u26A0\uFE0F
\u26A0\uFE0F Please upgrade to React 17 by updating your packages/app dependencies.    \u26A0\uFE0F
\u26A0\uFE0F                                                                           \u26A0\uFE0F
`
        )
      );
    }
  } catch {
  }
}

async function startFrontend(options) {
  const waitForExit = await serveBundle({
    entry: options.entry,
    checksEnabled: options.checksEnabled,
    configPaths: options.configPaths,
    verifyVersions: options.verifyVersions
  });
  await waitForExit();
}

async function command(opts) {
  const role = await packageDetection.findRoleFromCommand(opts);
  const options = {
    configPaths: opts.config,
    checksEnabled: Boolean(opts.check),
    inspectEnabled: Boolean(opts.inspect),
    inspectBrkEnabled: Boolean(opts.inspectBrk)
  };
  switch (role) {
    case "frontend":
      return startFrontend({
        ...options,
        entry: "src/index",
        verifyVersions: true
      });
    case "web-library":
    case "frontend-plugin":
    case "frontend-plugin-module":
      return startFrontend({ entry: "dev/index", ...options });
    default:
      throw new Error(
        `Start command is not supported for package role '${role}'`
      );
  }
}

exports.command = command;
//# sourceMappingURL=index-2135e357.cjs.js.map
