'use strict';

var cliNode = require('@backstage/cli-node');
var fs = require('fs-extra');
var index = require('./index-79e50cf7.cjs.js');
var collect = require('./collect-c99ee3f5.cjs.js');
var config$1 = require('@backstage/config');
var configLoader = require('@backstage/config-loader');
var getPackages = require('@manypkg/get-packages');
var rollup = require('rollup');
var semver = require('semver');
var child_process = require('child_process');
var path = require('path');
var commonjs = require('@rollup/plugin-commonjs');
var json = require('@rollup/plugin-json');
var resolve = require('@rollup/plugin-node-resolve');
var yaml = require('@rollup/plugin-yaml');
var svgr = require('@svgr/rollup');
var chalk = require('chalk');
var dts = require('rollup-plugin-dts');
var esbuild = require('rollup-plugin-esbuild');
var postcss = require('rollup-plugin-postcss');
var config = require('./config-fab10260.cjs.js');
var rollupPluginutils = require('rollup-pluginutils');
var groupBy = require('lodash/groupBy');
var sortBy = require('lodash/sortBy');
var parallel = require('./parallel-0df0ea12.cjs.js');
var npmPackList = require('npm-packlist');
var tasks = require('./tasks-581252fb.cjs.js');
var FileSizeReporter = require('react-dev-utils/FileSizeReporter');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var webpack = require('webpack');
var yn = require('yn');
require('commander');
require('@backstage/errors');
require('@backstage/cli-common');
require('os');
require('react-dev-utils/ModuleScopePlugin');
require('eslint-webpack-plugin');
require('fork-ts-checker-webpack-plugin');
require('html-webpack-plugin');
require('lodash/pickBy');
require('util');
require('@openshift/dynamic-plugin-sdk-webpack');
require('@pmmmwh/react-refresh-webpack-plugin');
require('mini-css-extract-plugin');
require('worker_threads');
require('handlebars');
require('ora');
require('recursive-readdir');

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

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n["default"] = e;
  return Object.freeze(n);
}

var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var semver__namespace = /*#__PURE__*/_interopNamespace(semver);
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var commonjs__default = /*#__PURE__*/_interopDefaultLegacy(commonjs);
var json__default = /*#__PURE__*/_interopDefaultLegacy(json);
var resolve__default = /*#__PURE__*/_interopDefaultLegacy(resolve);
var yaml__default = /*#__PURE__*/_interopDefaultLegacy(yaml);
var svgr__default = /*#__PURE__*/_interopDefaultLegacy(svgr);
var chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
var dts__default = /*#__PURE__*/_interopDefaultLegacy(dts);
var esbuild__default = /*#__PURE__*/_interopDefaultLegacy(esbuild);
var postcss__default = /*#__PURE__*/_interopDefaultLegacy(postcss);
var groupBy__default = /*#__PURE__*/_interopDefaultLegacy(groupBy);
var sortBy__default = /*#__PURE__*/_interopDefaultLegacy(sortBy);
var npmPackList__default = /*#__PURE__*/_interopDefaultLegacy(npmPackList);
var formatWebpackMessages__default = /*#__PURE__*/_interopDefaultLegacy(formatWebpackMessages);
var webpack__default = /*#__PURE__*/_interopDefaultLegacy(webpack);
var yn__default = /*#__PURE__*/_interopDefaultLegacy(yn);

var Output = /* @__PURE__ */ ((Output2) => {
  Output2[Output2["esm"] = 0] = "esm";
  Output2[Output2["cjs"] = 1] = "cjs";
  Output2[Output2["types"] = 2] = "types";
  return Output2;
})(Output || {});

const defaultIndex = {
  mount: ".",
  path: "src/index.ts",
  name: "index",
  ext: ".ts"
};
function parseEntryPoint(mount, path$1) {
  let name = mount;
  if (name === ".") {
    name = "index";
  } else if (name.startsWith("./")) {
    name = name.slice(2);
  }
  if (name.includes("/")) {
    throw new Error(`Mount point '${mount}' may not contain multiple slashes`);
  }
  return { mount, path: path$1, name, ext: path.extname(path$1) };
}
function readEntryPoints(pkg) {
  const exp = pkg.exports;
  if (typeof exp === "string") {
    return [defaultIndex];
  } else if (exp && typeof exp === "object" && !Array.isArray(exp)) {
    const entryPoints = new Array();
    for (const mount of Object.keys(exp)) {
      const path = exp[mount];
      if (typeof path !== "string") {
        throw new Error(
          `Exports field value must be a string, got '${JSON.stringify(path)}'`
        );
      }
      entryPoints.push(parseEntryPoint(mount, path));
    }
    return entryPoints;
  }
  return [defaultIndex];
}

function forwardFileImports(options) {
  const filter = rollupPluginutils.createFilter(options.include, options.exclude);
  const exportedFiles = /* @__PURE__ */ new Set();
  const generatedFor = /* @__PURE__ */ new Set();
  return {
    name: "forward-file-imports",
    async generateBundle(outputOptions, bundle, isWrite) {
      if (!isWrite) {
        return;
      }
      const dir = outputOptions.dir || path.dirname(outputOptions.file);
      if (generatedFor.has(dir)) {
        return;
      }
      for (const output of Object.values(bundle)) {
        if (output.type !== "chunk") {
          continue;
        }
        const chunk = output;
        if (!chunk.facadeModuleId) {
          continue;
        }
        generatedFor.add(dir);
        const srcRoot = path.dirname(chunk.facadeModuleId);
        await Promise.all(
          Array.from(exportedFiles).map(async (exportedFile) => {
            const outputPath = path.relative(srcRoot, exportedFile);
            const targetFile = path.resolve(dir, outputPath);
            await fs__default["default"].ensureDir(path.dirname(targetFile));
            await fs__default["default"].copyFile(exportedFile, targetFile);
          })
        );
        return;
      }
    },
    options(inputOptions) {
      const origExternal = inputOptions.external;
      const external = (id, importer, isResolved) => {
        if (typeof origExternal === "function" && origExternal(id, importer, isResolved)) {
          return true;
        }
        if (Array.isArray(origExternal) && origExternal.includes(id)) {
          return true;
        }
        if (!filter(id)) {
          return false;
        }
        if (!importer) {
          throw new Error(`Unknown importer of file module ${id}`);
        }
        const fullId = isResolved ? id : path.resolve(path.dirname(importer), id);
        exportedFiles.add(fullId);
        return true;
      };
      return { ...inputOptions, external };
    }
  };
}

const SCRIPT_EXTS$1 = [".js", ".jsx", ".ts", ".tsx"];
function isFileImport(source) {
  if (source.startsWith(".")) {
    return true;
  }
  if (source.startsWith("/")) {
    return true;
  }
  if (source.match(/[a-z]:/i)) {
    return true;
  }
  return false;
}
async function makeRollupConfigs(options) {
  var _a;
  const configs = new Array();
  const targetDir = (_a = options.targetDir) != null ? _a : index.paths.targetDir;
  let targetPkg = options.packageJson;
  if (!targetPkg) {
    const packagePath = path.resolve(targetDir, "package.json");
    targetPkg = await fs__default["default"].readJson(packagePath);
  }
  const onwarn = ({ code, message }) => {
    if (code === "EMPTY_BUNDLE") {
      return;
    }
    if (options.logPrefix) {
      console.log(options.logPrefix + message);
    } else {
      console.log(message);
    }
  };
  const distDir = path.resolve(targetDir, "dist");
  const entryPoints = readEntryPoints(targetPkg);
  const scriptEntryPoints = entryPoints.filter(
    (e) => SCRIPT_EXTS$1.includes(e.ext)
  );
  if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) {
    const output = new Array();
    const mainFields = ["module", "main"];
    if (options.outputs.has(Output.cjs)) {
      output.push({
        dir: distDir,
        entryFileNames: `[name].cjs.js`,
        chunkFileNames: `cjs/[name]-[hash].cjs.js`,
        format: "commonjs",
        sourcemap: true,
        exports: "named"
      });
    }
    if (options.outputs.has(Output.esm)) {
      output.push({
        dir: distDir,
        entryFileNames: `[name].esm.js`,
        chunkFileNames: `esm/[name]-[hash].esm.js`,
        format: "module",
        sourcemap: true
      });
      mainFields.unshift("browser");
    }
    configs.push({
      input: Object.fromEntries(
        scriptEntryPoints.map((e) => [e.name, path.resolve(targetDir, e.path)])
      ),
      output,
      onwarn,
      preserveEntrySignatures: "strict",
      // All module imports are always marked as external
      external: (source, importer, isResolved) => Boolean(importer && !isResolved && !isFileImport(source)),
      plugins: [
        resolve__default["default"]({ mainFields }),
        commonjs__default["default"]({
          include: /node_modules/,
          exclude: [/\/[^/]+\.(?:stories|test)\.[^/]+$/]
        }),
        postcss__default["default"](),
        forwardFileImports({
          exclude: /\.icon\.svg$/,
          include: [
            /\.svg$/,
            /\.png$/,
            /\.gif$/,
            /\.jpg$/,
            /\.jpeg$/,
            /\.eot$/,
            /\.woff$/,
            /\.woff2$/,
            /\.ttf$/,
            /\.md$/
          ]
        }),
        json__default["default"](),
        yaml__default["default"](),
        svgr__default["default"]({
          include: /\.icon\.svg$/,
          template: config.svgrTemplate
        }),
        esbuild__default["default"]({
          target: "es2019",
          minify: options.minify
        })
      ]
    });
  }
  if (options.outputs.has(Output.types) && !options.useApiExtractor) {
    const input = Object.fromEntries(
      scriptEntryPoints.map((e) => [
        e.name,
        index.paths.resolveTargetRoot(
          "dist-types",
          path.relative(index.paths.targetRoot, targetDir),
          e.path.replace(/\.(?:ts|tsx)$/, ".d.ts")
        )
      ])
    );
    for (const path$1 of Object.values(input)) {
      const declarationsExist = await fs__default["default"].pathExists(path$1);
      if (!declarationsExist) {
        const declarationPath = path.relative(targetDir, path$1);
        throw new Error(
          `No declaration files found at ${declarationPath}, be sure to run ${chalk__default["default"].bgRed.white(
            "yarn tsc"
          )} to generate .d.ts files before packaging`
        );
      }
    }
    configs.push({
      input,
      output: {
        dir: distDir,
        entryFileNames: `[name].d.ts`,
        chunkFileNames: `types/[name]-[hash].d.ts`,
        format: "es"
      },
      external: [
        /\.css$/,
        /\.scss$/,
        /\.sass$/,
        /\.svg$/,
        /\.eot$/,
        /\.woff$/,
        /\.woff2$/,
        /\.ttf$/
      ],
      onwarn,
      plugins: [dts__default["default"]()]
    });
  }
  return configs;
}

function createStepDefinition(config) {
  return config;
}

class DependenciesStep {
  constructor(data) {
    this.data = data;
  }
  async run() {
    const { dependencies: dependencies2 } = this.data;
    const byTarget = groupBy__default["default"](dependencies2, "target");
    for (const [target, deps] of Object.entries(byTarget)) {
      const pkgPath = index.paths.resolveTargetRoot(target, "package.json");
      const pkgJson = await fs__default["default"].readJson(pkgPath);
      const depTypes = /* @__PURE__ */ new Set();
      for (const dep of deps) {
        depTypes.add(dep.type);
        pkgJson[dep.type][dep.name] = dep.query;
      }
      for (const depType of depTypes) {
        pkgJson[depType] = Object.fromEntries(
          sortBy__default["default"](Object.entries(pkgJson[depType]), ([key]) => key)
        );
      }
      await fs__default["default"].writeJson(pkgPath, pkgJson, { spaces: 2 });
    }
    console.log();
    console.log(
      `Running ${chalk__default["default"].blue("yarn install")} to install new versions`
    );
    console.log();
    await config.run("yarn", ["install"]);
  }
}
const dependencies = createStepDefinition({
  type: "dependencies",
  deserialize() {
    throw new Error("The dependency step may not be defined in JSON");
  },
  create(data) {
    return new DependenciesStep(data);
  }
});

function embedModules(options) {
  const filter = rollupPluginutils.createFilter(options.filter.include, options.filter.exclude, {
    resolve: false
  });
  const embedded = /* @__PURE__ */ new Set();
  return {
    name: "embed-modules",
    async buildEnd(err) {
      if (err !== void 0) {
        return;
      }
      for (const e of embedded) {
        const mod = await this.resolve(
          path__default["default"].join(e, "package.json"),
          void 0,
          { skipSelf: true }
        );
        if (mod === null) {
          continue;
        }
        const pkgContent = await fs__default["default"].readFile(mod.id, "utf8");
        const pkg = JSON.parse(pkgContent);
        if (dependencies === void 0) {
          continue;
        }
        for (const dep in pkg.dependencies) {
          if (!Object.prototype.hasOwnProperty.call(pkg.dependencies, dep)) {
            continue;
          }
          options.addDependency(e, dep, pkg.dependencies[dep]);
        }
      }
    },
    options(inputOptions) {
      const origExternal = inputOptions.external;
      const external = (id, importer, isResolved) => {
        const importedId = id.replace(/\/alpha$/, "");
        if (filter(importedId) && importer !== void 0) {
          if (!embedded.has(importedId)) {
            embedded.add(importedId);
            console.log(`Embedding module ${importedId}`);
          }
          return false;
        }
        if (typeof origExternal === "function") {
          return origExternal(id, importer, isResolved);
        }
        if (Array.isArray(origExternal)) {
          return origExternal.includes(id);
        }
        return true;
      };
      return { ...inputOptions, external };
    }
  };
}

async function buildTypeDefinitionsWorker(workerData, sendMessage) {
  try {
    require("@microsoft/api-extractor");
  } catch (error) {
    throw new Error(
      "Failed to resolve @microsoft/api-extractor, it must best installed as a dependency of your project in order to use experimental type builds"
    );
  }
  const { dirname } = require("path");
  const { entryPoints, workerConfigs, typescriptCompilerFolder } = workerData;
  const apiExtractor = require("@microsoft/api-extractor");
  const { Extractor, ExtractorConfig, CompilerState } = apiExtractor;
  const {
    PackageJsonLookup
    // eslint-disable-next-line @backstage/no-undeclared-imports
  } = require("@rushstack/node-core-library/lib/PackageJsonLookup");
  const old = PackageJsonLookup.prototype.tryGetPackageJsonFilePathFor;
  PackageJsonLookup.prototype.tryGetPackageJsonFilePathFor = function tryGetPackageJsonFilePathForPatch(path) {
    if (path.includes("@material-ui") && !dirname(path).endsWith("@material-ui")) {
      return void 0;
    }
    return old.call(this, path);
  };
  let compilerState;
  for (const { extractorOptions, targetTypesDir } of workerConfigs) {
    const extractorConfig = ExtractorConfig.prepare(extractorOptions);
    if (!compilerState) {
      compilerState = CompilerState.create(extractorConfig, {
        additionalEntryPoints: entryPoints
      });
    }
    const extractorResult = Extractor.invoke(extractorConfig, {
      compilerState,
      localBuild: false,
      typescriptCompilerFolder,
      showVerboseMessages: false,
      showDiagnostics: false,
      messageCallback: (message) => {
        message.handled = true;
        sendMessage({ message, targetTypesDir });
      }
    });
    if (!extractorResult.succeeded) {
      throw new Error(
        `Type definition build completed with ${extractorResult.errorCount} errors and ${extractorResult.warningCount} warnings`
      );
    }
  }
}

const ignoredMessages = /* @__PURE__ */ new Set(["tsdoc-undefined-tag", "ae-forgotten-export"]);
async function buildTypeDefinitions(targetDirs = [index.paths.targetDir]) {
  const packageDirs = targetDirs.map(
    (dir) => path.relative(index.paths.targetRoot, dir)
  );
  const entryPoints = await Promise.all(
    packageDirs.map(async (dir) => {
      const entryPoint = index.paths.resolveTargetRoot(
        "dist-types",
        dir,
        "src/index.d.ts"
      );
      const declarationsExist = await fs__default["default"].pathExists(entryPoint);
      if (!declarationsExist) {
        throw new Error(
          `No declaration files found at ${entryPoint}, be sure to run ${chalk__default["default"].bgRed.white(
            "yarn tsc"
          )} to generate .d.ts files before packaging`
        );
      }
      return entryPoint;
    })
  );
  const workerConfigs = packageDirs.map((packageDir) => {
    const targetDir = index.paths.resolveTargetRoot(packageDir);
    const targetTypesDir = index.paths.resolveTargetRoot("dist-types", packageDir);
    const extractorOptions = {
      configObject: {
        mainEntryPointFilePath: path.resolve(targetTypesDir, "src/index.d.ts"),
        bundledPackages: [],
        compiler: {
          skipLibCheck: true,
          tsconfigFilePath: index.paths.resolveTargetRoot("tsconfig.json")
        },
        dtsRollup: {
          enabled: true,
          untrimmedFilePath: path.resolve(targetDir, "dist/index.alpha.d.ts"),
          betaTrimmedFilePath: path.resolve(targetDir, "dist/index.beta.d.ts"),
          publicTrimmedFilePath: path.resolve(targetDir, "dist/index.d.ts")
        },
        newlineKind: "lf",
        projectFolder: targetDir
      },
      configObjectFullPath: targetDir,
      packageJsonFullPath: path.resolve(targetDir, "package.json")
    };
    return { extractorOptions, targetTypesDir };
  });
  const typescriptDir = index.paths.resolveTargetRoot("node_modules/typescript");
  const hasTypescript = await fs__default["default"].pathExists(typescriptDir);
  const typescriptCompilerFolder = hasTypescript ? typescriptDir : void 0;
  await parallel.runWorkerThreads({
    threadCount: 1,
    workerData: {
      entryPoints,
      workerConfigs,
      typescriptCompilerFolder
    },
    worker: buildTypeDefinitionsWorker,
    onMessage: ({
      message,
      targetTypesDir
    }) => {
      if (ignoredMessages.has(message.messageId)) {
        return;
      }
      let text = `${message.text} (${message.messageId})`;
      if (message.sourceFilePath) {
        text += " at ";
        text += path.relative(targetTypesDir, message.sourceFilePath);
        if (message.sourceFileLine) {
          text += `:${message.sourceFileLine}`;
          if (message.sourceFileColumn) {
            text += `:${message.sourceFileColumn}`;
          }
        }
      }
      if (message.logLevel === "error") {
        console.error(chalk__default["default"].red(`Error: ${text}`));
      } else if (message.logLevel === "warning" || message.category === "Extractor") {
        console.warn(`Warning: ${text}`);
      } else {
        console.log(text);
      }
    }
  });
}

function formatErrorMessage(error) {
  var _a;
  let msg = "";
  if (error.code === "PLUGIN_ERROR") {
    if (error.plugin === "esbuild") {
      msg += `${error.message}`;
      if ((_a = error.errors) == null ? void 0 : _a.length) {
        msg += `

`;
        for (const { text, location } of error.errors) {
          const { line, column } = location;
          const path$1 = path.relative(index.paths.targetDir, error.id);
          const loc = chalk__default["default"].cyan(`${path$1}:${line}:${column}`);
          if (text === 'Unexpected "<"' && error.id.endsWith(".js")) {
            msg += `${loc}: ${text}, JavaScript files with JSX should use a .jsx extension`;
          } else {
            msg += `${loc}: ${text}`;
          }
        }
      }
    } else {
      msg += `(plugin ${error.plugin}) ${error}
`;
    }
  } else {
    if (error.loc) {
      const file = `${index.paths.resolveTarget(error.loc.file || error.id)}`;
      const pos = `${error.loc.line}:${error.loc.column}`;
      msg += `${file} [${pos}]
`;
    } else if (error.id) {
      msg += `${index.paths.resolveTarget(error.id)}
`;
    }
    msg += `${error}
`;
    if (error.url) {
      msg += `${chalk__default["default"].cyan(error.url)}
`;
    }
    if (error.frame) {
      msg += `${chalk__default["default"].dim(error.frame)}
`;
    }
  }
  return msg;
}
async function rollupBuild(config) {
  try {
    const bundle = await rollup.rollup(config);
    if (config.output) {
      for (const output of [config.output].flat()) {
        await bundle.generate(output);
        await bundle.write(output);
      }
    }
  } catch (error) {
    throw new Error(formatErrorMessage(error));
  }
}
const buildPackage = async (options) => {
  try {
    const { resolutions } = await fs__default["default"].readJson(
      index.paths.resolveTargetRoot("package.json")
    );
    if (resolutions == null ? void 0 : resolutions.esbuild) {
      console.warn(
        chalk__default["default"].red(
          'Your root package.json contains a "resolutions" entry for "esbuild". This was included in older @backstage/create-app templates in order to work around build issues that have since been fixed. Please remove the entry and run `yarn install`'
        )
      );
    }
  } catch {
  }
  const rollupConfigs = await makeRollupConfigs(options);
  await fs__default["default"].remove(index.paths.resolveTarget("dist"));
  const buildTasks = rollupConfigs.map(rollupBuild);
  if (options.outputs.has(Output.types) && options.useApiExtractor) {
    buildTasks.push(buildTypeDefinitions());
  }
  await Promise.all(buildTasks);
};

const PKG_PATH = "package.json";
const PKG_BACKUP_PATH = "package.json-prepack";
const SKIPPED_KEYS = ["access", "registry", "tag", "alphaTypes", "betaTypes"];
const SCRIPT_EXTS = [".js", ".jsx", ".ts", ".tsx"];
async function productionPack(options) {
  var _a, _b, _c;
  const { packageDir, targetDir } = options;
  const pkgPath = path.resolve(packageDir, PKG_PATH);
  const pkgContent = await fs__default["default"].readFile(pkgPath, "utf8");
  const pkg = JSON.parse(pkgContent);
  if (!targetDir) {
    await fs__default["default"].writeFile(PKG_BACKUP_PATH, pkgContent);
  }
  const hasStageEntry = !!((_a = pkg.publishConfig) == null ? void 0 : _a.alphaTypes) || !!((_b = pkg.publishConfig) == null ? void 0 : _b.betaTypes);
  if (pkg.exports && hasStageEntry) {
    throw new Error(
      "Combining both exports and alpha/beta types is not supported"
    );
  }
  const writeCompatibilityEntryPoints = await prepareExportsEntryPoints(
    pkg,
    packageDir
  );
  const publishConfig = (_c = pkg.publishConfig) != null ? _c : {};
  for (const key of Object.keys(publishConfig)) {
    if (!SKIPPED_KEYS.includes(key)) {
      pkg[key] = publishConfig[key];
    }
  }
  delete pkg.typesVersions;
  if (pkg.bundled) {
    delete pkg.dependencies;
    delete pkg.devDependencies;
    delete pkg.peerDependencies;
    delete pkg.optionalDependencies;
  }
  if (options.customizeManifest !== void 0) {
    options.customizeManifest(pkg);
  }
  if (targetDir) {
    const filePaths = await npmPackList__default["default"]({
      path: packageDir,
      // This makes sure we use the updated package.json when listing files
      packageJsonCache: /* @__PURE__ */ new Map([
        [path.resolve(packageDir, PKG_PATH), pkg]
      ])
      // Seems like this parameter type is wrong,
    });
    await fs__default["default"].ensureDir(targetDir);
    for (const filePath of filePaths.sort()) {
      const target = path.resolve(targetDir, filePath);
      if (filePath === PKG_PATH) {
        await fs__default["default"].writeJson(target, pkg, { encoding: "utf8", spaces: 2 });
      } else {
        await fs__default["default"].copy(path.resolve(packageDir, filePath), target);
      }
    }
  } else {
    await fs__default["default"].writeJson(pkgPath, pkg, { encoding: "utf8", spaces: 2 });
  }
  if (publishConfig.alphaTypes) {
    await writeReleaseStageEntrypoint(pkg, "alpha", targetDir != null ? targetDir : packageDir);
  }
  if (publishConfig.betaTypes) {
    await writeReleaseStageEntrypoint(pkg, "beta", targetDir != null ? targetDir : packageDir);
  }
  if (writeCompatibilityEntryPoints) {
    await writeCompatibilityEntryPoints(targetDir != null ? targetDir : packageDir);
  }
}
function resolveEntrypoint(pkg, name) {
  const targetEntry = pkg.publishConfig[name] || pkg[name];
  return targetEntry && path.posix.join("..", targetEntry);
}
async function writeReleaseStageEntrypoint(pkg, stage, targetDir) {
  await fs__default["default"].ensureDir(path.resolve(targetDir, stage));
  await fs__default["default"].writeJson(
    path.resolve(targetDir, stage, PKG_PATH),
    {
      name: pkg.name,
      version: pkg.version,
      main: resolveEntrypoint(pkg, "main"),
      module: resolveEntrypoint(pkg, "module"),
      browser: resolveEntrypoint(pkg, "browser"),
      types: path.posix.join("..", pkg.publishConfig[`${stage}Types`])
    },
    { encoding: "utf8", spaces: 2 }
  );
}
const EXPORT_MAP = {
  import: ".esm.js",
  require: ".cjs.js",
  types: ".d.ts"
};
async function prepareExportsEntryPoints(pkg, packageDir) {
  var _a;
  const distPath = path.resolve(packageDir, "dist");
  if (!await fs__default["default"].pathExists(distPath)) {
    return void 0;
  }
  const distFiles = await fs__default["default"].readdir(distPath);
  const outputExports = {};
  const compatibilityWriters = new Array();
  const entryPoints = readEntryPoints(pkg);
  for (const entryPoint of entryPoints) {
    if (!SCRIPT_EXTS.includes(entryPoint.ext)) {
      outputExports[entryPoint.mount] = entryPoint.path;
      continue;
    }
    const exp = {};
    for (const [key, ext] of Object.entries(EXPORT_MAP)) {
      const name = `${entryPoint.name}${ext}`;
      if (distFiles.includes(name)) {
        exp[key] = `./${path.posix.join(`dist`, name)}`;
      }
    }
    exp.default = (_a = exp.require) != null ? _a : exp.import;
    if (entryPoint.mount === ".") {
      if (exp.default) {
        pkg.main = exp.default;
      }
      if (exp.import) {
        pkg.module = exp.import;
      }
      if (exp.types) {
        pkg.types = exp.types;
      }
    } else {
      compatibilityWriters.push(async (targetDir) => {
        const entryPointDir = path.resolve(targetDir, entryPoint.name);
        await fs__default["default"].ensureDir(entryPointDir);
        await fs__default["default"].writeJson(
          path.resolve(entryPointDir, PKG_PATH),
          {
            name: pkg.name,
            version: pkg.version,
            ...exp.default ? { main: path.posix.join("..", exp.default) } : {},
            ...exp.import ? { module: path.posix.join("..", exp.import) } : {},
            ...exp.types ? { types: path.posix.join("..", exp.types) } : {}
          },
          { encoding: "utf8", spaces: 2 }
        );
      });
      if (Array.isArray(pkg.files) && !pkg.files.includes(entryPoint.name)) {
        pkg.files.push(entryPoint.name);
      }
    }
    if (Object.keys(exp).length > 0) {
      outputExports[entryPoint.mount] = exp;
    }
  }
  if (pkg.exports) {
    pkg.exports = outputExports;
    pkg.exports["./package.json"] = "./package.json";
  }
  if (compatibilityWriters.length > 0) {
    return async (targetDir) => {
      await Promise.all(compatibilityWriters.map((writer) => writer(targetDir)));
    };
  }
  return void 0;
}

async function backend(roleInfo, opts) {
  var _a, _b;
  if (!fs__default["default"].existsSync(index.paths.resolveTarget("src", "dynamic"))) {
    console.warn(
      `Package doesn't seem to provide dynamic loading entrypoints. You might want to add dynamic loading entrypoints in a src/dynamic folder.`
    );
  }
  const outputs = /* @__PURE__ */ new Set();
  if (roleInfo.output.includes("cjs")) {
    outputs.add(Output.cjs);
  }
  if (roleInfo.output.includes("esm")) {
    outputs.add(Output.esm);
  }
  const pkgContent = await fs__default["default"].readFile(
    index.paths.resolveTarget("package.json"),
    "utf8"
  );
  const pkg = JSON.parse(pkgContent);
  if (pkg.bundled) {
    throw new Error(
      'Packages exported as dynamic backend plugins should not have the "bundled" field set to true'
    );
  }
  const target = path__default["default"].join(index.paths.targetDir, "dist-dynamic");
  const requiredFiles = ["dist-dynamic/*.*", "dist-dynamic/dist/**"];
  const entryPoints = readEntryPoints(pkg);
  if (entryPoints.find((e) => e.mount === "./alpha")) {
    requiredFiles.push("dist-dynamic/alpha/*");
  }
  if (requiredFiles.some((f) => {
    var _a2;
    return !((_a2 = pkg.files) == null ? void 0 : _a2.includes(f));
  })) {
    console.warn(
      `Package doesn't seem to fully support dynamic loading: its "files" property should include the following entries: [${requiredFiles.map((f) => `"${f}"`).join(", ")}].`
    );
  }
  const mergeWithOutput = [];
  const commonPackage = pkg.name.replace(/-backend$/, "-common");
  if (commonPackage !== pkg.name) {
    mergeWithOutput.push(commonPackage);
  }
  const nodePackage = pkg.name.replace(/-backend$/, "-node");
  if (nodePackage !== pkg.name) {
    mergeWithOutput.push(nodePackage);
  }
  if (opts.embedPackage !== void 0) {
    for (const pkgToEmbed of opts.embedPackage) {
      if (pkg.dependencies === void 0 || !(pkgToEmbed in pkg.dependencies)) {
        console.log(
          `Embeded package '${pkgToEmbed}' is not part of direct dependencies. Are you sure you want to embed it ?`
        );
      }
      mergeWithOutput.push(pkgToEmbed);
      const relatedCommonPackage = pkgToEmbed.replace(/-backend$/, "-common");
      if (relatedCommonPackage !== pkgToEmbed) {
        mergeWithOutput.push(relatedCommonPackage);
      }
      const relatedNodePackage = pkgToEmbed.replace(/-backend$/, "-node");
      if (relatedNodePackage !== pkgToEmbed) {
        mergeWithOutput.push(relatedNodePackage);
      }
    }
  }
  const filter = {
    include: mergeWithOutput,
    exclude: mergeWithOutput.length !== 0 ? void 0 : /.*/
  };
  const stringOrRegexp = (s) => s.startsWith("/") && s.endsWith("/") ? new RegExp(s.slice(1, -1)) : s;
  const moveToPeerDependencies = [
    /@backstage\//,
    ...(opts.sharedPackage || []).filter((p) => !p.startsWith("!")).map(stringOrRegexp)
  ];
  const dontMoveToPeerDependencies = (opts.sharedPackage || []).filter((p) => p.startsWith("!")).map((p) => p.slice(1)).map(stringOrRegexp);
  let interopForAll = void 0;
  const interopForPackage = {};
  for (const mode in opts.overrideInterop) {
    if (!Object.prototype.hasOwnProperty.call(opts.overrideInterop, mode)) {
      continue;
    }
    if (!((_a = opts.overrideInterop[mode]) == null ? void 0 : _a.length)) {
      interopForAll = mode;
    }
    for (const interopPkg of opts.overrideInterop[mode]) {
      interopForPackage[interopPkg] = mode;
    }
  }
  const rollupConfigs = await makeRollupConfigs({
    outputs,
    minify: Boolean(opts.minify),
    useApiExtractor: false
  });
  if (rollupConfigs.length === 0) {
    throw new Error("Rollup config is missing");
  }
  const dependenciesToAdd = {};
  const rollupConfig = rollupConfigs[0];
  (_b = rollupConfig.plugins) == null ? void 0 : _b.push(
    embedModules({
      filter,
      addDependency(embeddedModule, dependencyName, newDependencyVersion) {
        const existingDependencyVersion = dependenciesToAdd[dependencyName];
        if (existingDependencyVersion === void 0) {
          dependenciesToAdd[dependencyName] = newDependencyVersion;
          return;
        }
        if (existingDependencyVersion === newDependencyVersion) {
          return;
        }
        const existingDependencyMinVersion = semver__namespace.minVersion(
          existingDependencyVersion
        );
        if (existingDependencyMinVersion && semver__namespace.satisfies(existingDependencyMinVersion, newDependencyVersion)) {
          console.log(
            `Several compatible versions ('${existingDependencyVersion}', '${newDependencyVersion}') of the same transitive dependency ('${dependencyName}') for embedded module ('${embeddedModule}'): keeping '${existingDependencyVersion}'`
          );
          return;
        }
        const newDependencyMinVersion = semver__namespace.minVersion(newDependencyVersion);
        if (newDependencyMinVersion && semver__namespace.satisfies(newDependencyMinVersion, existingDependencyVersion)) {
          dependenciesToAdd[dependencyName] = newDependencyVersion;
          console.log(
            `Several compatible versions ('${existingDependencyVersion}', '${newDependencyVersion}') of the same transitive dependency ('${dependencyName}') for embedded module ('${embeddedModule}'): keeping '${newDependencyVersion}'`
          );
          return;
        }
        throw new Error(
          `Several incompatible versions ('${existingDependencyVersion}', '${newDependencyVersion}') of the same transitive dependency ('${dependencyName}') for embedded module ('${embeddedModule}')`
        );
      }
    })
  );
  if (Array.isArray(rollupConfig.output)) {
    rollupConfig.output.forEach((output) => {
      if (output.format === "commonjs") {
        if (interopForAll) {
          console.log(
            `Overriding Interop to '${interopForAll}' for all imports`
          );
        }
        output.interop = (id) => {
          if (id && interopForPackage[id]) {
            console.log(
              `Overriding Interop to '${interopForPackage[id]}' for '${id}'`
            );
            return interopForPackage[id];
          }
          return interopForAll || true;
        };
      }
    });
  }
  await fs__default["default"].remove(index.paths.resolveTarget("dist"));
  try {
    const bundle = await rollup.rollup(rollupConfig);
    if (rollupConfig.output) {
      for (const output of [rollupConfig.output].flat()) {
        await bundle.generate(output);
        await bundle.write(output);
      }
    }
  } catch (error) {
    throw new Error(formatErrorMessage(error));
  }
  if (opts.clean) {
    await fs__default["default"].remove(target);
  }
  const monoRepoPackages = await getPackages.getPackages(index.paths.targetDir);
  await productionPack({
    packageDir: "",
    targetDir: target,
    customizeManifest: (pkgToCustomize) => {
      var _a2;
      function test(str, expr) {
        if (typeof expr === "string") {
          return str === expr;
        }
        return expr.test(str);
      }
      pkgToCustomize.name = `${pkgToCustomize.name}-dynamic`;
      pkgToCustomize.bundleDependencies = true;
      pkgToCustomize.files = (_a2 = pkgToCustomize.files) == null ? void 0 : _a2.filter(
        (f) => !f.startsWith("dist-dynamic/")
      );
      for (const dep in dependenciesToAdd) {
        if (!Object.prototype.hasOwnProperty.call(dependenciesToAdd, dep)) {
          continue;
        }
        pkgToCustomize.dependencies || (pkgToCustomize.dependencies = {});
        const existingVersion = pkgToCustomize.dependencies[dep];
        if (existingVersion === void 0) {
          pkgToCustomize.dependencies[dep] = dependenciesToAdd[dep];
          continue;
        }
        if (existingVersion !== dependenciesToAdd[dep]) {
          const existingMinVersion = semver__namespace.minVersion(existingVersion);
          if (existingMinVersion && semver__namespace.satisfies(existingMinVersion, dependenciesToAdd[dep])) {
            console.log(
              `The version of a dependency ('${dep}') of an embedded module differs from the main module's dependencies: '${dependenciesToAdd[dep]}', '${existingVersion}': keeping it as it is compatible`
            );
          } else {
            throw new Error(
              `The version of a dependency ('${dep}') of an embedded module conflicts with main module dependencies: '${dependenciesToAdd[dep]}', '${existingVersion}': cannot proceed!`
            );
          }
        }
      }
      if (pkgToCustomize.dependencies) {
        for (const monoRepoPackage of monoRepoPackages.packages) {
          if (pkgToCustomize.dependencies[monoRepoPackage.packageJson.name]) {
            pkgToCustomize.dependencies[monoRepoPackage.packageJson.name] = `^${monoRepoPackage.packageJson.version}`;
          }
        }
        for (const dep in pkgToCustomize.dependencies) {
          if (!Object.prototype.hasOwnProperty.call(
            pkgToCustomize.dependencies,
            dep
          )) {
            continue;
          }
          if (mergeWithOutput.some((merge) => test(dep, merge))) {
            delete pkgToCustomize.dependencies[dep];
            continue;
          }
          if (dontMoveToPeerDependencies.some((dontMove) => test(dep, dontMove))) {
            continue;
          }
          if (moveToPeerDependencies.some((move) => test(dep, move))) {
            console.log(`Moving '${dep}' to peerDependencies`);
            pkgToCustomize.peerDependencies || (pkgToCustomize.peerDependencies = {});
            pkgToCustomize.peerDependencies[dep] = pkgToCustomize.dependencies[dep];
            delete pkgToCustomize.dependencies[dep];
          }
        }
      }
      pkgToCustomize.devDependencies = {};
      const overrides = pkgToCustomize.overrides || {};
      pkgToCustomize.overrides = {
        "@aws-sdk/util-utf8-browser": {
          "@smithy/util-utf8": "^2.0.0"
        },
        ...overrides
      };
      const resolutions = pkgToCustomize.resolutions || {};
      pkgToCustomize.resolutions = {
        "@aws-sdk/util-utf8-browser": "npm:@smithy/util-utf8@~2",
        ...resolutions
      };
    }
  });
  const yarnLock = path__default["default"].resolve(target, "yarn.lock");
  const yarnLockExists = fs__default["default"].existsSync(yarnLock);
  if (!yarnLockExists) {
    await fs__default["default"].ensureFile(yarnLock);
  }
  if (opts.install) {
    const version = child_process.execSync("yarn --version").toString().trim();
    const yarnInstall = version.startsWith("1.") ? `yarn install --production${yarnLockExists ? " --frozen-lockfile" : ""}` : `yarn install${yarnLockExists ? " --immutable" : ""}`;
    await tasks.Task.forCommand(yarnInstall, { cwd: target, optional: false });
    await fs__default["default"].remove(index.paths.resolveTarget("dist-dynamic", ".yarn"));
  }
  await fs__default["default"].remove(index.paths.resolveTarget("dist"));
  await buildPackage({
    outputs,
    minify: Boolean(opts.minify)
  });
  if (opts.dev) {
    const appConfigs = await configLoader.loadConfig({
      configRoot: index.paths.targetRoot,
      configTargets: []
    });
    const fullConfig = config$1.ConfigReader.fromConfigs(appConfigs.appConfigs);
    const dynamicPlugins = fullConfig.getOptional("dynamicPlugins");
    if (typeof dynamicPlugins === "object" && dynamicPlugins !== null && "rootDirectory" in dynamicPlugins && typeof dynamicPlugins.rootDirectory === "string") {
      await fs__default["default"].ensureSymlink(
        index.paths.resolveTarget("src"),
        path__default["default"].resolve(target, "src"),
        "dir"
      );
      const dynamicPluginsRootPath = path__default["default"].isAbsolute(
        dynamicPlugins.rootDirectory
      ) ? dynamicPlugins.rootDirectory : index.paths.resolveTargetRoot(dynamicPlugins.rootDirectory);
      await fs__default["default"].ensureSymlink(
        target,
        path__default["default"].resolve(dynamicPluginsRootPath, path.basename(index.paths.targetDir)),
        "dir"
      );
    } else {
      throw new Error(
        `'dynamicPlugins.rootDirectory' should be configured in the app config in order to use the --dev option.`
      );
    }
  }
}

const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
function applyContextToError(error, moduleName) {
  return `Failed to compile '${moduleName}':
  ${error}`;
}
async function buildScalprumBundle(options) {
  const paths = config.resolveBundlingPaths(options);
  const config$1 = await config.createScalprumConfig(paths, {
    ...options,
    checksEnabled: false,
    isDev: false,
    baseUrl: config.resolveBaseUrl(options.frontendConfig)
  });
  const isCi = yn__default["default"](process.env.CI, { default: false });
  const previousFileSizes = await FileSizeReporter.measureFileSizesBeforeBuild(
    paths.targetScalprumDist
  );
  await fs__default["default"].emptyDir(paths.targetScalprumDist);
  if (paths.targetPublic) {
    await fs__default["default"].copy(paths.targetPublic, paths.targetDist, {
      dereference: true,
      filter: (file) => file !== paths.targetHtml
    });
  }
  const { stats } = await build(config$1, isCi);
  if (!stats) {
    throw new Error("No stats returned");
  }
  FileSizeReporter.printFileSizesAfterBuild(
    stats,
    previousFileSizes,
    paths.targetScalprumDist,
    WARN_AFTER_BUNDLE_GZIP_SIZE,
    WARN_AFTER_CHUNK_GZIP_SIZE
  );
}
async function build(config, isCi) {
  var _a, _b, _c;
  const stats = await new Promise(
    (resolve, reject) => {
      webpack__default["default"](config, (err, buildStats) => {
        if (err) {
          if (err.message) {
            const { errors: errors2 } = formatWebpackMessages__default["default"]({
              errors: [err.message],
              warnings: new Array(),
              _showErrors: true,
              _showWarnings: true
            });
            throw new Error(errors2[0]);
          } else {
            reject(err);
          }
        } else {
          resolve(buildStats);
        }
      });
    }
  );
  if (!stats) {
    throw new Error("Failed to compile: No stats provided");
  }
  const serializedStats = stats.toJson({
    all: false,
    warnings: true,
    errors: true
  });
  const { errors, warnings } = formatWebpackMessages__default["default"]({
    errors: serializedStats.errors,
    warnings: serializedStats.warnings
  });
  if (errors.length) {
    const errorWithContext = applyContextToError(
      errors[0],
      (_c = (_b = (_a = serializedStats.errors) == null ? void 0 : _a[0]) == null ? void 0 : _b.moduleName) != null ? _c : ""
    );
    throw new Error(errorWithContext);
  }
  if (isCi && warnings.length) {
    const warningsWithContext = warnings.map((warning, i) => {
      var _a2, _b2, _c2;
      return applyContextToError(
        warning,
        (_c2 = (_b2 = (_a2 = serializedStats.warnings) == null ? void 0 : _a2[i]) == null ? void 0 : _b2.moduleName) != null ? _c2 : ""
      );
    });
    console.log(chalk__default["default"].yellow(warningsWithContext.join("\n\n")));
  }
  return { stats };
}

async function buildScalprumPlugin(options) {
  const { targetDir, pluginMetadata, fromPackage } = options;
  await buildScalprumBundle({
    targetDir,
    entry: "src/index",
    parallelism: parallel.getEnvironmentParallelism(),
    pluginMetadata,
    ...await config.loadCliConfig({
      args: [],
      fromPackage
    })
  });
}

async function frontend(_, __) {
  const {
    name,
    version,
    scalprum: scalprumExternal
  } = await fs__default["default"].readJson(index.paths.resolveTarget("package.json"));
  let scalprum = scalprumExternal;
  if (scalprum === void 0) {
    let scalprumName;
    if (name.includes("/")) {
      const fragments = name.split("/");
      scalprumName = `${fragments[0].replace("@", "")}.${fragments[1]}`;
    } else {
      scalprumName = name;
    }
    scalprum = {
      name: scalprumName,
      exposedModules: {
        PluginRoot: "./src/index.ts"
      }
    };
    console.log(`No scalprum config. Using default dynamic UI configuration:`);
    console.log(JSON.stringify(scalprum, null, 2));
    console.log(
      `If you wish to change the defaults, add "scalprum" configuration to plugin "package.json" file.`
    );
  }
  await fs__default["default"].remove(index.paths.resolveTarget("dist-scalprum"));
  await buildScalprumPlugin({
    writeStats: false,
    configPaths: [],
    targetDir: index.paths.targetDir,
    pluginMetadata: {
      ...scalprum,
      version
    },
    fromPackage: name
  });
}

const saveSchema = async (packageName, path) => {
  const configSchema = await collect.getConfigSchema(packageName);
  await fs__default["default"].writeJson(index.paths.resolveTarget(path), configSchema, {
    encoding: "utf8",
    spaces: 2
  });
};
async function command(opts) {
  const rawPkg = await fs__default["default"].readJson(index.paths.resolveTarget("package.json"));
  const role = cliNode.PackageRoles.getRoleFromPackage(rawPkg);
  if (!role) {
    throw new Error(`Target package must have 'backstage.role' set`);
  }
  const roleInfo = cliNode.PackageRoles.getRoleInfo(role);
  if (role === "backend-plugin" || role === "backend-plugin-module") {
    await backend(roleInfo, opts);
    await saveSchema(rawPkg.name, "dist-dynamic/dist/configSchema.json");
    return;
  }
  if (role === "frontend-plugin") {
    await frontend();
    await saveSchema(rawPkg.name, "dist-scalprum/configSchema.json");
    return;
  }
  throw new Error(
    'Only packages with the "backend-plugin", "backend-plugin-module" or "frontend-plugin" roles can be exported as dynamic backend plugins'
  );
}

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