"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
var os_1 = require("os");
var react_native_1 = require("../tools/react-native");
var packager_1 = require("../tools/packager");
var pretty_1 = require("../tools/pretty");
var flag_1 = require("../tools/flag");
var cache_1 = require("../tools/cache");
var expoGoCompatibility_1 = require("../tools/expoGoCompatibility");
module.exports = {
    run: function (toolbox) { return __awaiter(void 0, void 0, void 0, function () {
        var print, filesystem, system, meta, parameters, strings, prompt, kebabCase, exists, path, removeAsync, copy, read, write, homedir, info, colors, warning, gray, cyan, yellow, white, red, underline, options, yname, noTimeout, useDefault, CMD_INDENT, p2, command, MAX_APP_CREATION_TIME, timeoutExit, debug, log, validateProjectName, projectName, projectNameKebab, bname, defaultBundleIdentifier, bundleIdentifier, bundleIdentifierResponse, validateBundleIdentifier, defaultTargetPath, targetPath, targetPathResponse, handleHomePrefix, defaultOverwrite, overwrite, overwriteResponse, alreadyExists, defaultWorkflow, workflow, workflowResponse, needsPrebuild, defaultGit, git, gitResponse, defaultRemoveDemo, removeDemo, removeDemoResponse, availablePackagers, defaultPackagerName, packagerName, validatePackagerName, initial_1, NOT_FOUND, packagerNameResponse, packagerOptions, isWindows, ignitePath, boilerplatePath, boilerplate, defaultInstallDeps, installDeps, installDepsResponse, newArch, experimentalFlags, defaultNewArch, experimentalNewArch, newArchResponse, perfStart, timeout, terminalWidth, logo, pkg, igniteVersion, msg, boilerplateIgnorePath, targetIgnorePath, gitIgnoreContents, cwd, packageJsonRaw, packageJson, npmrcPath, npmrcContents, boilerplatePackageJsonHash, cachePath, cacheExists, defaultUseCache, useCache, shouldUseCache, msg, renameSpinnerMsg, boilerplateBundleIdentifier, shouldFreshInstallDeps, unboxingMessage, msg, appJsonRaw, appJson, prebuildMessage, removeDemoPart, IGNITE, CMD, e_1, warnAboutEOL, templates, e_2, perfDuration, cliCommand, prettyCliCommand, isMac, e_3, IGNITE, doctorResults, e_4;
        var _a, _b, _c, _d;
        return __generator(this, function (_e) {
            switch (_e.label) {
                case 0:
                    print = toolbox.print, filesystem = toolbox.filesystem, system = toolbox.system, meta = toolbox.meta, parameters = toolbox.parameters, strings = toolbox.strings, prompt = toolbox.prompt;
                    kebabCase = strings.kebabCase;
                    exists = filesystem.exists, path = filesystem.path, removeAsync = filesystem.removeAsync, copy = filesystem.copy, read = filesystem.read, write = filesystem.write, homedir = filesystem.homedir;
                    info = print.info, colors = print.colors, warning = print.warning;
                    gray = colors.gray, cyan = colors.cyan, yellow = colors.yellow, white = colors.white, red = colors.red, underline = colors.underline;
                    options = parameters.options;
                    yname = (0, flag_1.boolFlag)(options.y) || (0, flag_1.boolFlag)(options.yes);
                    noTimeout = (_a = options.noTimeout) !== null && _a !== void 0 ? _a : false;
                    useDefault = function (option) { return yname && option === undefined; };
                    CMD_INDENT = "  ";
                    p2 = function (m) {
                        if (m === void 0) { m = ""; }
                        return (0, pretty_1.p)(" ".concat(m));
                    };
                    command = function (cmd) { return p2(white(CMD_INDENT + cmd)); };
                    MAX_APP_CREATION_TIME = 10 * 60 * 1000;
                    timeoutExit = function () {
                        (0, pretty_1.p)();
                        (0, pretty_1.p)(yellow("Error: App creation timed out."));
                        if (!debug)
                            (0, pretty_1.p)(gray("Run again with --debug to see what's going on."));
                        process.exit(1);
                    };
                    debug = (0, flag_1.boolFlag)(options.debug);
                    log = function (m) {
                        debug && info(" ".concat(m));
                        return m;
                    };
                    // log raw parameters for debugging
                    log("ignite command: ".concat(parameters.argv.join(" ")));
                    // #endregion
                    // #region Project Name
                    // retrieve project name from toolbox
                    (0, pretty_1.p)();
                    validateProjectName = require("../tools/validations").validateProjectName;
                    return [4 /*yield*/, validateProjectName(toolbox)];
                case 1:
                    projectName = _e.sent();
                    projectNameKebab = kebabCase(projectName);
                    bname = options.b || options.boilerplate;
                    if (bname) {
                        (0, pretty_1.p)();
                        (0, pretty_1.p)(yellow("Different boilerplates are no longer supported in Ignite v4+."));
                        (0, pretty_1.p)(gray("To use the old CLI to support different boilerplates, try:"));
                        (0, pretty_1.p)(cyan("npx ignite-cli@3 new ".concat(projectName, " --boilerplate ").concat(bname)));
                        process.exit(1);
                    }
                    defaultBundleIdentifier = "com.".concat(strings.pascalCase(projectName).toLowerCase());
                    bundleIdentifier = useDefault(options.bundle) ? defaultBundleIdentifier : options.bundle;
                    if (!(bundleIdentifier === undefined)) return [3 /*break*/, 3];
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "input",
                            name: "bundleIdentifier",
                            message: "What bundle identifier?",
                            initial: defaultBundleIdentifier,
                            prefix: pretty_1.prefix,
                        }); })];
                case 2:
                    bundleIdentifierResponse = _e.sent();
                    bundleIdentifier = bundleIdentifierResponse.bundleIdentifier;
                    _e.label = 3;
                case 3:
                    validateBundleIdentifier = require("../tools/validations").validateBundleIdentifier;
                    validateBundleIdentifier(toolbox, bundleIdentifier);
                    defaultTargetPath = path(projectName);
                    targetPath = useDefault(options.targetPath) ? defaultTargetPath : options.targetPath;
                    if (!(targetPath === undefined)) return [3 /*break*/, 5];
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "input",
                            name: "targetPath",
                            message: "Where do you want to start your project?",
                            initial: defaultTargetPath,
                            prefix: pretty_1.prefix,
                        }); })];
                case 4:
                    targetPathResponse = _e.sent();
                    targetPath = targetPathResponse.targetPath;
                    _e.label = 5;
                case 5:
                    handleHomePrefix = function (p) {
                        return (p === null || p === void 0 ? void 0 : p.startsWith("~")) ? p.replace("~", homedir()) : p;
                    };
                    targetPath = path(handleHomePrefix(targetPath));
                    defaultOverwrite = false;
                    overwrite = useDefault(options.overwrite) ? defaultOverwrite : (0, flag_1.boolFlag)(options.overwrite);
                    if (!(exists(targetPath) && overwrite === undefined)) return [3 /*break*/, 7];
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "confirm",
                            name: "overwrite",
                            message: "Directory ".concat(targetPath, " already exists. Do you want to overwrite it?"),
                            initial: defaultOverwrite,
                            format: pretty_1.prettyPrompt.format.boolean,
                            prefix: pretty_1.prefix,
                        }); })];
                case 6:
                    overwriteResponse = _e.sent();
                    overwrite = overwriteResponse.overwrite;
                    _e.label = 7;
                case 7:
                    if (exists(targetPath) && overwrite === false) {
                        alreadyExists = "Error: There's already a folder at ".concat(targetPath, ". To force overwriting that folder, run with --overwrite or say yes.");
                        (0, pretty_1.p)();
                        (0, pretty_1.p)(yellow(alreadyExists));
                        process.exit(1);
                    }
                    defaultWorkflow = "expo";
                    workflow = useDefault(options.workflow) ? defaultWorkflow : options.workflow;
                    if (!(workflow === undefined)) return [3 /*break*/, 9];
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "select",
                            name: "workflow",
                            message: "Choose a workflow:",
                            choices: [
                                {
                                    name: "Expo Go",
                                    message: "Expo Go         Choose this if: the only native modules you need are included in the Expo SDK",
                                    value: "expo",
                                },
                                {
                                    name: "Expo Prebuild",
                                    message: "Expo Prebuild   Choose this if: you need to add native modules or configuration using Expo config plugins",
                                    value: "prebuild",
                                },
                                {
                                    name: "DIY",
                                    message: "DIY             Choose this if: you want to manage native configuration/modules directly, without Expo config plugins",
                                    value: "manual",
                                },
                            ],
                            result: function (name) {
                                // Some magical enquirer map function here that returns an object of { [name]: value]}
                                // and we only need the value underneath (using name for the cli display to the user)
                                // @ts-expect-error
                                return this.map(name)[name];
                            },
                            initial: "expo",
                            prefix: pretty_1.prefix,
                        }); })];
                case 8:
                    workflowResponse = _e.sent();
                    workflow = workflowResponse.workflow;
                    _e.label = 9;
                case 9:
                    needsPrebuild = workflow === "prebuild" || workflow === "manual";
                    log("worflow: ".concat(workflow));
                    log("needs prebuild: ".concat(needsPrebuild));
                    defaultGit = true;
                    git = useDefault(options.git) ? defaultGit : (0, flag_1.boolFlag)(options.git);
                    if (!(git === undefined)) return [3 /*break*/, 11];
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "confirm",
                            name: "git",
                            message: "Do you want to initialize a git repository?",
                            initial: defaultGit,
                            format: pretty_1.prettyPrompt.format.boolean,
                            prefix: pretty_1.prefix,
                        }); })];
                case 10:
                    gitResponse = _e.sent();
                    git = gitResponse.git;
                    _e.label = 11;
                case 11:
                    defaultRemoveDemo = false;
                    removeDemo = useDefault(options.removeDemo)
                        ? defaultRemoveDemo
                        : (0, flag_1.boolFlag)(options.removeDemo);
                    if (!(removeDemo === undefined)) return [3 /*break*/, 13];
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "confirm",
                            name: "removeDemo",
                            message: "Remove demo code? We recommend leaving it in if it's your first time using Ignite",
                            initial: defaultRemoveDemo,
                            format: pretty_1.prettyPrompt.format.boolean,
                            prefix: pretty_1.prefix,
                        }); })];
                case 12:
                    removeDemoResponse = _e.sent();
                    removeDemo = removeDemoResponse.removeDemo;
                    _e.label = 13;
                case 13:
                    availablePackagers = packager_1.packager.availablePackagers();
                    log("availablePackagers: ".concat(availablePackagers));
                    defaultPackagerName = availablePackagers.includes("yarn") ? "yarn" : "npm";
                    packagerName = useDefault(options.packager) ? defaultPackagerName : options.packager;
                    validatePackagerName = function (input) {
                        return typeof input === "string" && ["npm", "yarn", "pnpm", "bun"].includes(input);
                    };
                    if (packagerName !== undefined && validatePackagerName(packagerName) === false) {
                        (0, pretty_1.p)();
                        (0, pretty_1.p)(yellow("Error: Invalid packager: \"".concat(packagerName, "\". Valid packagers are npm, yarn, pnpm, bun.")));
                        process.exit(1);
                    }
                    if (packagerName !== undefined && availablePackagers.includes(packagerName) === false) {
                        (0, pretty_1.p)();
                        (0, pretty_1.p)(yellow("Error: selected \"".concat(packagerName, "\" but packager was not available on system")));
                        process.exit(1);
                    }
                    if (!(packagerName === undefined)) return [3 /*break*/, 15];
                    initial_1 = availablePackagers.findIndex(function (p) { return p === defaultPackagerName; });
                    NOT_FOUND = -1;
                    if (initial_1 === NOT_FOUND) {
                        (0, pretty_1.p)();
                        (0, pretty_1.p)(yellow("Error: Default packager \"".concat(defaultPackagerName, "\" was not available on system")));
                        process.exit(1);
                    }
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "select",
                            name: "packagerName",
                            message: "Which package manager do you want to use?",
                            choices: availablePackagers,
                            initial: initial_1,
                            prefix: pretty_1.prefix,
                        }); })];
                case 14:
                    packagerNameResponse = _e.sent();
                    packagerName = packagerNameResponse.packagerName;
                    _e.label = 15;
                case 15:
                    packagerOptions = { packagerName: packagerName };
                    isWindows = process.platform === "win32";
                    ignitePath = path("".concat(meta.src), "..");
                    boilerplatePath = path(ignitePath, "boilerplate");
                    boilerplate = function () {
                        var pathParts = [];
                        for (var _i = 0; _i < arguments.length; _i++) {
                            pathParts[_i] = arguments[_i];
                        }
                        return path.apply(void 0, __spreadArray([boilerplatePath], pathParts, false));
                    };
                    log("ignitePath: ".concat(ignitePath));
                    log("boilerplatePath: ".concat(boilerplatePath));
                    defaultInstallDeps = true;
                    installDeps = useDefault(options.installDeps)
                        ? defaultInstallDeps
                        : (0, flag_1.boolFlag)(options.installDeps);
                    if (!(installDeps === undefined)) return [3 /*break*/, 17];
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "confirm",
                            name: "installDeps",
                            message: "Do you want to install dependencies?",
                            initial: defaultInstallDeps,
                            format: pretty_1.prettyPrompt.format.boolean,
                            prefix: pretty_1.prefix,
                        }); })];
                case 16:
                    installDepsResponse = _e.sent();
                    installDeps = installDepsResponse.installDeps;
                    _e.label = 17;
                case 17:
                    experimentalFlags = (_c = (_b = options.experimental) === null || _b === void 0 ? void 0 : _b.split(",")) !== null && _c !== void 0 ? _c : [];
                    log("experimentalFlags: ".concat(experimentalFlags));
                    experimentalFlags.forEach(function (flag) {
                        if (flag === "new-arch") {
                            newArch = true;
                        }
                    });
                    defaultNewArch = false;
                    experimentalNewArch = useDefault(newArch) ? defaultNewArch : (0, flag_1.boolFlag)(newArch);
                    if (!(experimentalNewArch === undefined && workflow !== "expo")) return [3 /*break*/, 19];
                    return [4 /*yield*/, prompt.ask(function () { return ({
                            type: "confirm",
                            name: "experimentalNewArch",
                            message: "❗EXPERIMENTAL❗Would you like to enable the New Architecture?",
                            initial: defaultNewArch,
                            format: pretty_1.prettyPrompt.format.boolean,
                            prefix: pretty_1.prefix,
                        }); })];
                case 18:
                    newArchResponse = _e.sent();
                    experimentalNewArch = newArchResponse.experimentalNewArch;
                    return [3 /*break*/, 20];
                case 19:
                    // Don't ask this for Expo Go flow since it isn't supported atm due to expo-updates
                    experimentalNewArch = false;
                    _e.label = 20;
                case 20:
                    perfStart = new Date().getTime();
                    timeout = noTimeout ? undefined : setTimeout(timeoutExit, MAX_APP_CREATION_TIME);
                    _e.label = 21;
                case 21:
                    _e.trys.push([21, 52, , 57]);
                    terminalWidth = (_d = process.stdout.columns) !== null && _d !== void 0 ? _d : 80;
                    logo = terminalWidth > 80 ? function () { return (0, pretty_1.ascii)("logo.ascii.txt"); } : function () { return (0, pretty_1.ascii)("logo-sm.ascii.txt"); };
                    (0, pretty_1.p)();
                    (0, pretty_1.p)();
                    (0, pretty_1.p)();
                    (0, pretty_1.p)();
                    logo();
                    (0, pretty_1.p)();
                    (0, pretty_1.p)();
                    pkg = (0, pretty_1.pkgColor)(packagerName);
                    igniteVersion = meta.version();
                    (0, pretty_1.p)(" \u2588 Creating ".concat((0, pretty_1.em)(projectName), " using ").concat((0, pretty_1.em)("Ignite ".concat(igniteVersion))));
                    (0, pretty_1.p)(" \u2588 Powered by ".concat((0, pretty_1.ir)(" ∞ Infinite Red "), " (").concat((0, pretty_1.link)("https://infinite.red"), ")"));
                    (0, pretty_1.p)(" \u2588 Package Manager: ".concat(pkg(print.colors.bold(packagerName))));
                    (0, pretty_1.p)(" \u2588 Bundle identifier: ".concat((0, pretty_1.em)(bundleIdentifier)));
                    (0, pretty_1.p)(" \u2588 Path: ".concat(underline(targetPath)));
                    (0, pretty_1.hr)();
                    (0, pretty_1.p)();
                    if (!(exists(targetPath) === "dir" && overwrite === true)) return [3 /*break*/, 23];
                    msg = " Tossing that old app like it's hot";
                    (0, pretty_1.startSpinner)(msg);
                    return [4 /*yield*/, removeAsync(targetPath)];
                case 22:
                    _e.sent();
                    (0, pretty_1.stopSpinner)(msg, "🗑️");
                    _e.label = 23;
                case 23:
                    // #endregion
                    // #region Copy Boilerplate Files
                    (0, pretty_1.startSpinner)(" 3D-printing a new React Native app");
                    return [4 /*yield*/, (0, react_native_1.copyBoilerplate)(toolbox, {
                            boilerplatePath: boilerplatePath,
                            targetPath: targetPath,
                            excluded: [".vscode", "node_modules", "yarn.lock", "bun.lockb", "package-lock.json"],
                            overwrite: overwrite,
                        })];
                case 24:
                    _e.sent();
                    (0, pretty_1.stopSpinner)(" 3D-printing a new React Native app", "🖨");
                    boilerplateIgnorePath = exists(boilerplate(".gitignore.template"))
                        ? boilerplate(".gitignore.template")
                        : boilerplate(".gitignore");
                    targetIgnorePath = log(path(targetPath, ".gitignore"));
                    copy(log(boilerplateIgnorePath), targetIgnorePath, { overwrite: true });
                    if (exists(targetIgnorePath) === false) {
                        warning("  Unable to copy ".concat(boilerplateIgnorePath, " to ").concat(targetIgnorePath));
                    }
                    else if (workflow === "expo" || workflow === "prebuild") {
                        gitIgnoreContents = read(targetIgnorePath);
                        gitIgnoreContents = gitIgnoreContents
                            .replace(/# android/g, "android")
                            .replace(/# ios/g, "ios");
                        write(targetIgnorePath, gitIgnoreContents);
                    }
                    cwd = log(process.cwd());
                    // jump into the project to do additional tasks
                    process.chdir(targetPath);
                    packageJsonRaw = read("package.json");
                    packageJsonRaw = packageJsonRaw
                        .replace(/HelloWorld/g, projectName)
                        .replace(/hello-world/g, projectNameKebab);
                    // - If we need native dirs, change up start scripts from Expo Go variation to expo run:platform.
                    if (needsPrebuild) {
                        packageJsonRaw = packageJsonRaw
                            .replace(/start --android/g, "run:android")
                            .replace(/start --ios/g, "run:ios");
                    }
                    else {
                        // Expo Go workflow, swap back to compatible Expo Go versions of modules
                        log("Changing some dependencies for Expo Go compatibility...");
                        log(JSON.stringify(expoGoCompatibility_1.expoGoCompatExpectedVersions));
                        packageJsonRaw = (0, expoGoCompatibility_1.findAndUpdateDependencyVersions)(packageJsonRaw, expoGoCompatibility_1.expoGoCompatExpectedVersions);
                    }
                    packageJson = JSON.parse(packageJsonRaw);
                    write("./package.json", packageJson);
                    // #endregion
                    // #region Run Packager Install
                    // pnpm/yarn/npm/bun install it
                    // fix .npmrc if using pnpm
                    if (packagerName === "pnpm") {
                        npmrcPath = path(targetPath, ".npmrc");
                        npmrcContents = read(npmrcPath);
                        write(npmrcPath, "".concat(npmrcContents).concat(os_1.EOL, "node-linker=hoisted").concat(os_1.EOL));
                    }
                    boilerplatePackageJsonHash = cache_1.cache.hash(read(path(boilerplatePath, "package.json")));
                    cachePath = path(cache_1.cache.rootdir(), boilerplatePackageJsonHash, packagerName);
                    cacheExists = exists(cachePath) === "dir";
                    log("".concat(!cacheExists ? "expected " : "", "cachePath: ").concat(cachePath));
                    log("cacheExists: ".concat(cacheExists));
                    defaultUseCache = false;
                    useCache = options.useCache === undefined ? defaultUseCache : (0, flag_1.boolFlag)(options.useCache);
                    shouldUseCache = installDeps && cacheExists && useCache;
                    if (!shouldUseCache) return [3 /*break*/, 26];
                    msg = "Grabbing those ".concat(packagerName, " dependencies from the back");
                    (0, pretty_1.startSpinner)(msg);
                    return [4 /*yield*/, cache_1.cache.copy({
                            fromRootDir: cachePath,
                            toRootDir: targetPath,
                            packagerName: packagerName,
                        })];
                case 25:
                    _e.sent();
                    (0, pretty_1.stopSpinner)(msg, "📦");
                    _e.label = 26;
                case 26:
                    renameSpinnerMsg = "Getting those last few details perfect";
                    (0, pretty_1.startSpinner)(renameSpinnerMsg);
                    boilerplateBundleIdentifier = "com.helloworld";
                    return [4 /*yield*/, (0, react_native_1.renameReactNativeApp)(toolbox, "HelloWorld", projectName, boilerplateBundleIdentifier, bundleIdentifier)];
                case 27:
                    _e.sent();
                    return [4 /*yield*/, (0, react_native_1.replaceMaestroBundleIds)(toolbox, boilerplateBundleIdentifier, bundleIdentifier)];
                case 28:
                    _e.sent();
                    (0, pretty_1.stopSpinner)(renameSpinnerMsg, "🎨");
                    shouldFreshInstallDeps = installDeps && shouldUseCache === false;
                    if (!shouldFreshInstallDeps) return [3 /*break*/, 30];
                    unboxingMessage = "Installing ".concat(packagerName, " dependencies (wow these are heavy)");
                    (0, pretty_1.startSpinner)(unboxingMessage);
                    return [4 /*yield*/, packager_1.packager.install(__assign(__assign({}, packagerOptions), { onProgress: log }))];
                case 29:
                    _e.sent();
                    (0, pretty_1.stopSpinner)(unboxingMessage, "🧶");
                    _e.label = 30;
                case 30: 
                // remove the gitignore template
                return [4 /*yield*/, removeAsync(".gitignore.template")
                    // #endregion
                    // #region Cache dependencies
                ];
                case 31:
                    // remove the gitignore template
                    _e.sent();
                    if (!(shouldFreshInstallDeps && cacheExists === false && useCache)) return [3 /*break*/, 33];
                    msg = "Saving ".concat(packagerName, " dependencies for next time");
                    (0, pretty_1.startSpinner)(msg);
                    log(targetPath);
                    return [4 /*yield*/, cache_1.cache.copy({
                            fromRootDir: targetPath,
                            toRootDir: cachePath,
                            packagerName: packagerName,
                        })];
                case 32:
                    _e.sent();
                    (0, pretty_1.stopSpinner)(msg, "📦");
                    _e.label = 33;
                case 33:
                    // #endregion
                    // #region Configure app.json
                    // Enable New Architecture if requested (must happen before prebuild)
                    (0, pretty_1.startSpinner)(" Configuring app.json");
                    try {
                        appJsonRaw = read("app.json");
                        appJson = JSON.parse(appJsonRaw);
                        // Inject ignite version to app.json
                        appJson.ignite.version = igniteVersion;
                        if (experimentalNewArch === true) {
                            appJson.expo.plugins[1][1].ios.newArchEnabled = true;
                            appJson.expo.plugins[1][1].android.newArchEnabled = true;
                            // Adding the "deploymentTarget" key is required for
                            // @react-native-async-storage/async-storage to work in the new architecture
                            appJson.expo.plugins[1][1].ios.deploymentTarget = "13.4";
                        }
                        write("./app.json", appJson);
                    }
                    catch (e) {
                        log(e);
                        (0, pretty_1.p)(yellow("Unable to configure app.json."));
                    }
                    (0, pretty_1.stopSpinner)(" Configuring app.json", "");
                    if (!(installDeps === true)) return [3 /*break*/, 37];
                    if (!needsPrebuild) return [3 /*break*/, 35];
                    prebuildMessage = " Generating native template via Expo Prebuild";
                    (0, pretty_1.startSpinner)(prebuildMessage);
                    return [4 /*yield*/, packager_1.packager.run("prebuild:clean", __assign(__assign({}, packagerOptions), { onProgress: log }))];
                case 34:
                    _e.sent();
                    (0, pretty_1.stopSpinner)(prebuildMessage, "🛠️");
                    _e.label = 35;
                case 35: 
                // Make sure all our modifications are formatted nicely
                return [4 /*yield*/, packager_1.packager.run("format", __assign(__assign({}, packagerOptions), { silent: !debug }))];
                case 36:
                    // Make sure all our modifications are formatted nicely
                    _e.sent();
                    _e.label = 37;
                case 37:
                    removeDemoPart = removeDemo === true ? "code" : "markup";
                    (0, pretty_1.startSpinner)(" Removing fancy demo ".concat(removeDemoPart));
                    _e.label = 38;
                case 38:
                    _e.trys.push([38, 40, , 41]);
                    IGNITE = "node " + filesystem.path(__dirname, "..", "..", "bin", "ignite");
                    CMD = removeDemo === true ? "remove-demo" : "remove-demo-markup";
                    log("Ignite bin path: ".concat(IGNITE));
                    return [4 /*yield*/, system.run("".concat(IGNITE, " ").concat(CMD, " \"").concat(targetPath, "\""), {
                            onProgress: log,
                        })];
                case 39:
                    _e.sent();
                    return [3 /*break*/, 41];
                case 40:
                    e_1 = _e.sent();
                    log(e_1);
                    (0, pretty_1.p)(yellow("Unable to remove demo ".concat(removeDemoPart, ".")));
                    return [3 /*break*/, 41];
                case 41:
                    (0, pretty_1.stopSpinner)(" Removing fancy demo ".concat(removeDemoPart), "🛠️");
                    warnAboutEOL = false;
                    if (isWindows) {
                        try {
                            templates = filesystem.find("".concat(targetPath, "/ignite/templates"), {
                                directories: false,
                                files: true,
                                matching: "*.ejs",
                            });
                            log("templates to change EOL: ".concat(templates));
                            templates.map(function (file) { return __awaiter(void 0, void 0, void 0, function () {
                                var template;
                                return __generator(this, function (_a) {
                                    log("Converting EOL for ".concat(file));
                                    template = read(file);
                                    template = template.replace(/\n/g, "\r\n");
                                    write(file, template);
                                    return [2 /*return*/];
                                });
                            }); });
                        }
                        catch (_f) {
                            warnAboutEOL = true;
                        }
                    }
                    if (!(git === true)) return [3 /*break*/, 51];
                    (0, pretty_1.startSpinner)(" Backing everything up in source control");
                    _e.label = 42;
                case 42:
                    _e.trys.push([42, 49, , 50]);
                    if (!isWindows) return [3 /*break*/, 46];
                    return [4 /*yield*/, system.run(log("git init"))];
                case 43:
                    _e.sent();
                    return [4 /*yield*/, system.run(log("git add -A"))];
                case 44:
                    _e.sent();
                    return [4 /*yield*/, system.run(log("git commit -m \"New Ignite ".concat(meta.version(), " app")))];
                case 45:
                    _e.sent();
                    return [3 /*break*/, 48];
                case 46: return [4 /*yield*/, system.run(log("\n              \\rm -rf ./.git\n              git init;\n              git add -A;\n              git commit -m \"New Ignite ".concat(meta.version(), " app\";\n            ")))];
                case 47:
                    _e.sent();
                    _e.label = 48;
                case 48: return [3 /*break*/, 50];
                case 49:
                    e_2 = _e.sent();
                    (0, pretty_1.p)(yellow("Unable to commit the initial changes. Please check your git username and email."));
                    return [3 /*break*/, 50];
                case 50:
                    (0, pretty_1.stopSpinner)(" Backing everything up in source control", "🗄");
                    _e.label = 51;
                case 51:
                    // back to the original directory
                    process.chdir(log(cwd));
                    // #endregion
                    // #region Print Finish
                    // clean up any spinners we forgot to clear
                    (0, pretty_1.p)();
                    (0, pretty_1.hr)();
                    (0, pretty_1.p)();
                    (0, pretty_1.clearSpinners)();
                    perfDuration = Math.round((new Date().getTime() - perfStart) / 10) / 100;
                    // no need to timeout, we're done!
                    clearTimeout(timeout);
                    p2("Ignited ".concat((0, pretty_1.em)("".concat(projectName)), " in ").concat(gray("".concat(perfDuration, "s")), "  \uD83D\uDE80 "));
                    p2();
                    cliCommand = buildCliCommand({
                        flags: {
                            b: bname,
                            boilerplate: bname,
                            bundle: bundleIdentifier,
                            debug: debug,
                            git: git,
                            installDeps: installDeps,
                            overwrite: overwrite,
                            packager: packagerName,
                            targetPath: targetPath,
                            removeDemo: removeDemo,
                            experimental: experimentalFlags.length > 0 ? experimentalFlags.join(",") : undefined,
                            workflow: workflow,
                            useCache: useCache,
                            y: yname,
                            yes: yname,
                            noTimeout: noTimeout,
                        },
                        projectName: projectName,
                        toolbox: toolbox,
                    });
                    p2("For next time: here are the Ignite options you picked!");
                    prettyCliCommand = cliCommand
                        .split(" ")
                        .map(function (c) { return (c === projectName || (c === null || c === void 0 ? void 0 : c.startsWith("--")) ? "".concat(c, " \\").concat(os_1.EOL) : c); }) // add a line break after the project name and each flag
                        .map(function (c, i, a) { return (i === a.length - 1 ? c.replace("\\".concat(os_1.EOL), "") : c); }) // remove the line break after the last flag
                        .map(function (c) { return (c.startsWith("--") ? pretty_1.INDENT + CMD_INDENT + CMD_INDENT + c : c); }) // add whitespace to the flags so it looks nice
                        .join(" ");
                    command("".concat(prettyCliCommand));
                    p2();
                    if (!(0, react_native_1.isAndroidInstalled)(toolbox)) {
                        (0, pretty_1.hr)();
                        p2();
                        p2("To run in Android, make sure you've followed the latest");
                        p2("react-native setup instructions. You reference them at:");
                        p2("".concat((0, pretty_1.link)("https://reactnative.dev/docs/environment-setup")));
                        p2();
                    }
                    if (warnAboutEOL) {
                        (0, pretty_1.hr)();
                        p2();
                        p2(yellow("Generator templates could not be converted to Windows EOL."));
                        p2(yellow("You may want to update these manually with your code editor, more info at:"));
                        p2("".concat((0, pretty_1.link)("https://github.com/infinitered/ignite/blob/master/docs/Generators.md")));
                        p2();
                    }
                    (0, pretty_1.hr)();
                    p2();
                    p2("Need additional help?");
                    p2();
                    p2("Join our Slack community at ".concat((0, pretty_1.link)("http://community.infinite.red.")));
                    p2();
                    (0, pretty_1.hr)();
                    p2();
                    p2("Now get cooking! 🍽");
                    command("cd ".concat(targetPath));
                    if (!installDeps)
                        command(packager_1.packager.installCmd({ packagerName: packagerName }));
                    isMac = process.platform === "darwin";
                    if (isMac) {
                        command("".concat(packager_1.packager.runCmd("ios", packagerOptions)));
                        p2("Or Android via");
                        command("".concat(packager_1.packager.runCmd("android", packagerOptions)));
                    }
                    else {
                        command("".concat(packager_1.packager.runCmd("android", packagerOptions)));
                    }
                    p2();
                    p2();
                    // #endregion
                    // this is a hack to prevent the process from hanging
                    // if there are any tasks left in the event loop
                    // like I/O operations to process.stdout and process.stderr
                    // see https://github.com/infinitered/ignite/issues/2084
                    process.exit(0);
                    return [3 /*break*/, 57];
                case 52:
                    e_3 = _e.sent();
                    (0, pretty_1.stopLastSpinner)("❌");
                    p2(red("\nThe following error occurred:"));
                    p2();
                    p2(red(e_3.toString()));
                    p2();
                    p2("Consider opening an issue with the following information at:");
                    p2("".concat((0, pretty_1.link)("https://github.com/infinitered/ignite/issues/new?template=bug_report.yml&labels=bug")));
                    p2();
                    (0, pretty_1.startSpinner)(" Gathering system and project details");
                    _e.label = 53;
                case 53:
                    _e.trys.push([53, 55, , 56]);
                    IGNITE = "node " + filesystem.path(__dirname, "..", "..", "bin", "ignite");
                    return [4 /*yield*/, system.run("".concat(IGNITE, " doctor"))];
                case 54:
                    doctorResults = _e.sent();
                    (0, pretty_1.p)("\n\n".concat(doctorResults));
                    return [3 /*break*/, 56];
                case 55:
                    e_4 = _e.sent();
                    (0, pretty_1.p)(yellow("Unable to gather system and project details."));
                    return [3 /*break*/, 56];
                case 56:
                    (0, pretty_1.clearSpinners)();
                    process.exit(1);
                    return [3 /*break*/, 57];
                case 57: return [2 /*return*/];
            }
        });
    }); },
};
function buildCliCommand(args) {
    var flags = args.flags, toolbox = args.toolbox, projectName = args.projectName;
    var strings = toolbox.strings;
    var kebabCase = strings.kebabCase;
    var privateFlags = ["b", "boilerplate", "debug", "useCache", "y", "yes"];
    var stringFlag = function (_a) {
        var key = _a[0], value = _a[1];
        return "--".concat(kebabCase(key), "=").concat(value);
    };
    var booleanFlag = function (_a) {
        var key = _a[0], value = _a[1];
        return value ? "--".concat(kebabCase(key)) : "--".concat(kebabCase(key), "=").concat(value);
    };
    var cliCommand = "npx ignite-cli new ".concat(projectName, " ").concat(Object.entries(flags)
        .filter(function (_a) {
        var key = _a[0];
        return privateFlags.includes(key) === false;
    })
        .filter(function (_a) {
        var value = _a[1];
        return value !== undefined;
    })
        .map(function (_a) {
        var key = _a[0], value = _a[1];
        return typeof value === "boolean" ? booleanFlag([key, value]) : stringFlag([key, value]);
    })
        .join(" "));
    return cliCommand;
}
//# sourceMappingURL=new.js.map