'use strict';
var os = require('os');
var fs = require('fs-extra');
var path = require('path');
var chalk = require('chalk');
var inquirer = require('inquirer');
var camelCase = require('lodash/camelCase');
var upperFirst = require('lodash/upperFirst');
var index = require('./index-CCLafGQH.cjs.js');
var codeowners = require('./codeowners-BYrqMw1o.cjs.js');
var tasks = require('./tasks-mGXy8WjR.cjs.js');
var Lockfile = require('./Lockfile-C7rtIlD6.cjs.js');
require('minimatch');
require('@manypkg/get-packages');
require('./yarn-BDZCENk5.cjs.js');
require('./run-BcxUFacd.cjs.js');
var partition = require('lodash/partition');
var cliNode = require('@backstage/cli-node');
var errors = require('@backstage/errors');
require('commander');
require('semver');
require('@backstage/cli-common');
require('handlebars');
require('ora');
require('util');
require('recursive-readdir');
require('child_process');
require('@yarnpkg/parsers');
require('@yarnpkg/lockfile');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
var os__default = /*#__PURE__*/_interopDefaultCompat(os);
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
var inquirer__default = /*#__PURE__*/_interopDefaultCompat(inquirer);
var camelCase__default = /*#__PURE__*/_interopDefaultCompat(camelCase);
var upperFirst__default = /*#__PURE__*/_interopDefaultCompat(upperFirst);
var partition__default = /*#__PURE__*/_interopDefaultCompat(partition);
function createFactory(config) {
return config;
}
function pluginIdPrompt() {
return {
type: "input",
name: "id",
message: "Enter the ID of the plugin [required]",
validate: (value) => {
if (!value) {
return "Please enter the ID of the plugin";
} else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {
return "Plugin IDs must be lowercase and contain only letters, digits, and dashes.";
}
return true;
}
};
}
function moduleIdIdPrompt() {
return {
type: "input",
name: "moduleId",
message: "Enter the ID of the module [required]",
validate: (value) => {
if (!value) {
return "Please enter the ID of the module";
} else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {
return "Module IDs must be lowercase and contain only letters, digits, and dashes.";
}
return true;
}
};
}
function ownerPrompt() {
return {
type: "input",
name: "owner",
message: "Enter an owner to add to CODEOWNERS [optional]",
when: (opts) => Boolean(opts.codeOwnersPath),
validate: (value) => {
if (!value) {
return true;
}
const ownerIds = codeowners.parseOwnerIds(value);
if (!ownerIds) {
return "The owner must be a space separated list of team names (e.g. @org/team-name), usernames (e.g. @username), or the email addresses (e.g. user@example.com).";
}
return true;
}
};
}
async function executePluginPackageTemplate(ctx, options) {
const { targetDir } = options;
let lockfile;
try {
lockfile = await Lockfile.Lockfile.load(index.paths.resolveTargetRoot("yarn.lock"));
} catch {
}
tasks.Task.section("Checking Prerequisites");
const shortPluginDir = path.relative(index.paths.targetRoot, targetDir);
await tasks.Task.forItem("availability", shortPluginDir, async () => {
if (await fs__default.default.pathExists(targetDir)) {
throw new Error(
`A package with the same plugin ID already exists at ${chalk__default.default.cyan(
shortPluginDir
)}. Please try again with a different ID.`
);
}
});
const tempDir = await tasks.Task.forItem("creating", "temp dir", async () => {
return await ctx.createTemporaryDirectory("backstage-create");
});
tasks.Task.section("Executing Template");
await tasks.templatingTask(
index.paths.resolveOwn("templates", options.templateName),
tempDir,
options.values,
index.createPackageVersionProvider(lockfile),
ctx.isMonoRepo
);
const pkgJsonPath = path.resolve(tempDir, "package.json");
if (await fs__default.default.pathExists(pkgJsonPath)) {
const pkgJson = await fs__default.default.readJson(pkgJsonPath);
await fs__default.default.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
}
tasks.Task.section("Installing");
await tasks.Task.forItem("moving", shortPluginDir, async () => {
await fs__default.default.move(tempDir, targetDir).catch((error) => {
throw new Error(
`Failed to move package from ${tempDir} to ${targetDir}, ${error.message}`
);
});
});
ctx.markAsModified();
}
const resolvePackageName = (options) => {
const { baseName, scope, plugin } = options;
if (scope) {
if (plugin) {
const pluginName = scope.startsWith("backstage") ? "plugin" : "backstage-plugin";
return scope.includes("/") ? `@${scope}${pluginName}-${baseName}` : `@${scope}/${pluginName}-${baseName}`;
}
return scope.includes("/") ? `@${scope}${baseName}` : `@${scope}/${baseName}`;
}
return plugin ? `backstage-plugin-${baseName}` : baseName;
};
const frontendPlugin = createFactory({
name: "plugin",
description: "A new frontend plugin",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [pluginIdPrompt(), ownerPrompt()],
async create(options, ctx) {
const { id } = options;
const name = resolvePackageName({
baseName: id,
scope: ctx.scope,
plugin: true
});
const extensionName = `${upperFirst__default.default(camelCase__default.default(id))}Page`;
tasks.Task.log();
tasks.Task.log(`Creating frontend plugin ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("plugins", id) : index.paths.resolveTargetRoot(`backstage-plugin-${id}`);
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "default-plugin",
values: {
id,
name,
extensionName,
pluginVar: `${camelCase__default.default(id)}Plugin`,
pluginVersion: ctx.defaultVersion,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry
}
});
if (await fs__default.default.pathExists(index.paths.resolveTargetRoot("packages/app"))) {
await tasks.Task.forItem("app", "adding dependency", async () => {
await tasks.addPackageDependency(
index.paths.resolveTargetRoot("packages/app/package.json"),
{
dependencies: {
[name]: `^${ctx.defaultVersion}`
}
}
);
});
await tasks.Task.forItem("app", "adding import", async () => {
var _a;
const pluginsFilePath = index.paths.resolveTargetRoot(
"packages/app/src/App.tsx"
);
if (!await fs__default.default.pathExists(pluginsFilePath)) {
return;
}
const content = await fs__default.default.readFile(pluginsFilePath, "utf8");
const revLines = content.split("\n").reverse();
const lastImportIndex = revLines.findIndex(
(line) => line.match(/ from ("|').*("|')/)
);
const lastRouteIndex = revLines.findIndex(
(line) => line.match(/<\/FlatRoutes/)
);
if (lastImportIndex !== -1 && lastRouteIndex !== -1) {
const importLine = `import { ${extensionName} } from '${name}';`;
if (!content.includes(importLine)) {
revLines.splice(lastImportIndex, 0, importLine);
}
const componentLine = `} />`;
if (!content.includes(componentLine)) {
const [indentation] = (_a = revLines[lastRouteIndex + 1].match(/^\s*/)) != null ? _a : [];
revLines.splice(lastRouteIndex + 1, 0, indentation + componentLine);
}
const newContent = revLines.reverse().join("\n");
await fs__default.default.writeFile(pluginsFilePath, newContent, "utf8");
}
});
}
if (options.owner) {
await codeowners.addCodeownersEntry(`/plugins/${id}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
const backendPlugin = createFactory({
name: "backend-plugin",
description: "A new backend plugin",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [pluginIdPrompt(), ownerPrompt()],
async create(options, ctx) {
const { id } = options;
const pluginId = `${id}-backend`;
const name = resolvePackageName({
baseName: pluginId,
scope: ctx.scope,
plugin: true
});
tasks.Task.log();
tasks.Task.log(`Creating backend plugin ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("plugins", pluginId) : index.paths.resolveTargetRoot(`backstage-plugin-${pluginId}`);
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "default-backend-plugin",
values: {
id,
name,
pluginVar: `${camelCase__default.default(id)}Plugin`,
pluginVersion: ctx.defaultVersion,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry
}
});
if (await fs__default.default.pathExists(index.paths.resolveTargetRoot("packages/backend"))) {
await tasks.Task.forItem("backend", "adding dependency", async () => {
await tasks.addPackageDependency(
index.paths.resolveTargetRoot("packages/backend/package.json"),
{
dependencies: {
[name]: `^${ctx.defaultVersion}`
}
}
);
});
}
if (options.owner) {
await codeowners.addCodeownersEntry(`/plugins/${id}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
const backendModule = createFactory({
name: "backend-module",
description: "A new backend module that extends an existing backend plugin with additional features",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [pluginIdPrompt(), moduleIdIdPrompt(), ownerPrompt()],
async create(options, ctx) {
const { id: pluginId, moduleId } = options;
const dirName = `${pluginId}-backend-module-${moduleId}`;
const name = resolvePackageName({
baseName: dirName,
scope: ctx.scope,
plugin: true
});
tasks.Task.log();
tasks.Task.log(`Creating backend module ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("plugins", dirName) : index.paths.resolveTargetRoot(`backstage-plugin-${dirName}`);
const moduleCamelCase = camelCase__default.default(moduleId);
const modulePascalCase = moduleCamelCase[0].toUpperCase() + moduleCamelCase.slice(1);
const moduleVar = `${camelCase__default.default(pluginId)}Module${modulePascalCase}`;
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "default-backend-module",
values: {
pluginId,
moduleId,
name,
moduleVar,
packageVersion: ctx.defaultVersion,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry
}
});
if (await fs__default.default.pathExists(index.paths.resolveTargetRoot("packages/backend"))) {
await tasks.Task.forItem("backend", "adding dependency", async () => {
await tasks.addPackageDependency(
index.paths.resolveTargetRoot("packages/backend/package.json"),
{
dependencies: {
[name]: `^${ctx.defaultVersion}`
}
}
);
});
}
if (options.owner) {
await codeowners.addCodeownersEntry(`/plugins/${dirName}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
const nodeLibraryPackage = createFactory({
name: "node-library",
description: "A new node-library package, exporting shared functionality for backend plugins and modules",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [pluginIdPrompt(), ownerPrompt()],
async create(options, ctx) {
const { id } = options;
const name = resolvePackageName({
baseName: id,
scope: ctx.scope,
plugin: false
});
tasks.Task.log();
tasks.Task.log(`Creating node-library package ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("packages", id) : index.paths.resolveTargetRoot(`${id}`);
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "node-library-package",
values: {
id,
name,
pluginVersion: ctx.defaultVersion,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry
}
});
if (options.owner) {
await codeowners.addCodeownersEntry(`/packages/${id}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
const webLibraryPackage = createFactory({
name: "web-library",
description: "A new web-library package, exporting shared functionality for frontend plugins",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [pluginIdPrompt(), ownerPrompt()],
async create(options, ctx) {
const { id } = options;
const name = resolvePackageName({
baseName: id,
scope: ctx.scope,
plugin: false
});
tasks.Task.log();
tasks.Task.log(`Creating web-library package ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("packages", id) : index.paths.resolveTargetRoot(`${id}`);
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "web-library-package",
values: {
id,
name,
pluginVersion: ctx.defaultVersion,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry
}
});
if (options.owner) {
await codeowners.addCodeownersEntry(`/packages/${id}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
const pluginCommon = createFactory({
name: "plugin-common",
description: "A new isomorphic common plugin package",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [pluginIdPrompt(), ownerPrompt()],
async create(options, ctx) {
const { id } = options;
const suffix = `${id}-common`;
const name = resolvePackageName({
baseName: suffix,
scope: ctx.scope,
plugin: true
});
tasks.Task.log();
tasks.Task.log(`Creating backend plugin ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("plugins", suffix) : index.paths.resolveTargetRoot(`backstage-plugin-${suffix}`);
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "default-common-plugin-package",
values: {
id,
name,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry,
pluginVersion: ctx.defaultVersion
}
});
if (options.owner) {
await codeowners.addCodeownersEntry(`/plugins/${suffix}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
const pluginNode = createFactory({
name: "plugin-node",
description: "A new Node.js library plugin package",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [pluginIdPrompt(), ownerPrompt()],
async create(options, ctx) {
const { id } = options;
const suffix = `${id}-node`;
const name = resolvePackageName({
baseName: suffix,
scope: ctx.scope,
plugin: true
});
tasks.Task.log();
tasks.Task.log(`Creating Node.js plugin library ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("plugins", suffix) : index.paths.resolveTargetRoot(`backstage-plugin-${suffix}`);
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "default-node-plugin-package",
values: {
id,
name,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry,
pluginVersion: ctx.defaultVersion
}
});
if (options.owner) {
await codeowners.addCodeownersEntry(`/plugins/${suffix}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
const pluginWeb = createFactory({
name: "plugin-react",
description: "A new web library plugin package",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [pluginIdPrompt(), ownerPrompt()],
async create(options, ctx) {
const { id } = options;
const suffix = `${id}-react`;
const name = resolvePackageName({
baseName: suffix,
scope: ctx.scope,
plugin: true
});
tasks.Task.log();
tasks.Task.log(`Creating web plugin library ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("plugins", suffix) : index.paths.resolveTargetRoot(`backstage-plugin-${suffix}`);
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "default-react-plugin-package",
values: {
id,
name,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry,
pluginVersion: ctx.defaultVersion
}
});
if (options.owner) {
await codeowners.addCodeownersEntry(`/plugins/${suffix}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
const scaffolderModule = createFactory({
name: "scaffolder-module",
description: "An module exporting custom actions for @backstage/plugin-scaffolder-backend",
optionsDiscovery: async () => ({
codeOwnersPath: await codeowners.getCodeownersFilePath(index.paths.targetRoot)
}),
optionsPrompts: [
{
type: "input",
name: "id",
message: "Enter the name of the module [required]",
validate: (value) => {
if (!value) {
return "Please enter the name of the module";
} else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {
return "Module names must be lowercase and contain only letters, digits, and dashes.";
}
return true;
}
},
ownerPrompt()
],
async create(options, ctx) {
const { id } = options;
const slug = `scaffolder-backend-module-${id}`;
const name = resolvePackageName({
baseName: slug,
scope: ctx.scope,
plugin: true
});
tasks.Task.log();
tasks.Task.log(`Creating module ${chalk__default.default.cyan(name)}`);
const targetDir = ctx.isMonoRepo ? index.paths.resolveTargetRoot("plugins", slug) : index.paths.resolveTargetRoot(`backstage-plugin-${slug}`);
await executePluginPackageTemplate(ctx, {
targetDir,
templateName: "scaffolder-module",
values: {
id,
name,
privatePackage: ctx.private,
npmRegistry: ctx.npmRegistry,
pluginVersion: ctx.defaultVersion
}
});
if (options.owner) {
await codeowners.addCodeownersEntry(`/plugins/${slug}`, options.owner);
}
await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
await tasks.Task.forCommand("yarn lint --fix", {
cwd: targetDir,
optional: true
});
}
});
var factories = /*#__PURE__*/Object.freeze({
__proto__: null,
backendModule: backendModule,
backendPlugin: backendPlugin,
frontendPlugin: frontendPlugin,
nodeLibraryPackage: nodeLibraryPackage,
pluginCommon: pluginCommon,
pluginNode: pluginNode,
pluginWeb: pluginWeb,
scaffolderModule: scaffolderModule,
webLibraryPackage: webLibraryPackage
});
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
function applyPromptMessageTransforms(prompt, transforms) {
return {
...prompt,
message: prompt.message && (async (answers) => {
if (typeof prompt.message === "function") {
return transforms.message(await prompt.message(answers));
}
return transforms.message(await prompt.message);
}),
validate: prompt.validate && (async (...args) => {
const result = await prompt.validate(...args);
if (typeof result === "string") {
return transforms.error(result);
}
return result;
})
};
}
class FactoryRegistry {
static async interactiveSelect(preselected) {
let selected = preselected;
if (!selected) {
const answers = await inquirer__default.default.prompt([
{
type: "list",
name: "name",
message: "What do you want to create?",
choices: Array.from(this.factoryMap.values()).map((factory2) => ({
name: `${factory2.name} - ${factory2.description}`,
value: factory2.name
}))
}
]);
selected = answers.name;
}
const factory = this.factoryMap.get(selected);
if (!factory) {
throw new Error(`Unknown selection '${selected}'`);
}
return factory;
}
static async populateOptions(factory, provided) {
let currentOptions = provided;
if (factory.optionsDiscovery) {
const discoveredOptions = await factory.optionsDiscovery();
currentOptions = {
...currentOptions,
...discoveredOptions
};
}
if (factory.optionsPrompts) {
const [hasAnswers, needsAnswers] = partition__default.default(
factory.optionsPrompts,
(option) => option.name in currentOptions
);
for (const option of hasAnswers) {
const value = provided[option.name];
if (option.validate) {
const result = option.validate(value);
if (result !== true) {
throw new Error(`Invalid option '${option.name}'. ${result}`);
}
}
}
currentOptions = await inquirer__default.default.prompt(
needsAnswers.map(
(option) => applyPromptMessageTransforms(option, {
message: chalk__default.default.blue,
error: chalk__default.default.red
})
),
currentOptions
);
}
return currentOptions;
}
}
__publicField(FactoryRegistry, "factoryMap", new Map(
Object.values(factories).map((factory) => [factory.name, factory])
));
function parseOptions(optionStrings) {
const options = {};
for (const str of optionStrings) {
const [key] = str.split("=", 1);
const value = str.slice(key.length + 1);
if (!key || str[key.length] !== "=") {
throw new Error(
`Invalid option '${str}', must be of the format =`
);
}
options[key] = value;
}
return options;
}
var _new = async (opts) => {
var _a;
const factory = await FactoryRegistry.interactiveSelect(opts.select);
const providedOptions = parseOptions(opts.option);
const options = await FactoryRegistry.populateOptions(
factory,
providedOptions
);
let defaultVersion = "0.1.0";
if (opts.baseVersion) {
defaultVersion = opts.baseVersion;
} else {
const lernaVersion = await fs__default.default.readJson(index.paths.resolveTargetRoot("lerna.json")).then((pkg) => pkg.version).catch(() => void 0);
if (lernaVersion) {
defaultVersion = lernaVersion;
}
}
const tempDirs = new Array();
async function createTemporaryDirectory(name) {
const dir = await fs__default.default.mkdtemp(path.join(os__default.default.tmpdir(), name));
tempDirs.push(dir);
return dir;
}
let modified = false;
try {
await factory.create(options, {
isMonoRepo: await cliNode.isMonoRepo(),
defaultVersion,
scope: (_a = opts.scope) == null ? void 0 : _a.replace(/^@/, ""),
npmRegistry: opts.npmRegistry,
private: Boolean(opts.private),
createTemporaryDirectory,
markAsModified() {
modified = true;
}
});
tasks.Task.log();
tasks.Task.log(`\u{1F389} Successfully created ${factory.name}`);
tasks.Task.log();
} catch (error) {
errors.assertError(error);
tasks.Task.error(error.message);
if (modified) {
tasks.Task.log("It seems that something went wrong in the creation process \u{1F914}");
tasks.Task.log();
tasks.Task.log(
"We have left the changes that were made intact in case you want to"
);
tasks.Task.log(
"continue manually, but you can also revert the changes and try again."
);
tasks.Task.error(`\u{1F525} Failed to create ${factory.name}!`);
}
} finally {
for (const dir of tempDirs) {
try {
await fs__default.default.remove(dir);
} catch (error) {
console.error(
`Failed to remove temporary directory '${dir}', ${error}`
);
}
}
}
};
exports.default = _new;
//# sourceMappingURL=new-CfGQG6Qx.cjs.js.map