404

[ Avaa Bypassed ]




Upload:

Command:

botdev@3.15.1.45: ~ $
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StartCommand = void 0;
const cli_framework_1 = require("@ionic/cli-framework");
const string_1 = require("@ionic/cli-framework/utils/string");
const utils_fs_1 = require("@ionic/utils-fs");
const utils_terminal_1 = require("@ionic/utils-terminal");
const chalk = require("chalk");
const Debug = require("debug");
const path = require("path");
const constants_1 = require("../constants");
const color_1 = require("../lib/color");
const command_1 = require("../lib/command");
const errors_1 = require("../lib/errors");
const executor_1 = require("../lib/executor");
const project_1 = require("../lib/project");
const session_1 = require("../lib/session");
const shell_1 = require("../lib/shell");
const start_1 = require("../lib/start");
const emoji_1 = require("../lib/utils/emoji");
const http_1 = require("../lib/utils/http");
const debug = Debug('ionic:commands:start');
class StartCommand extends command_1.Command {
    constructor() {
        super(...arguments);
        this.canRemoveExisting = false;
    }
    async getMetadata() {
        return {
            name: 'start',
            type: 'global',
            summary: 'Create a new project',
            description: `
This command creates a working Ionic app. It installs dependencies for you and sets up your project.

Running ${color_1.input('ionic start')} without any arguments will prompt you for information about your new project.

The first argument is your app's ${color_1.input('name')}. Don't worry--you can always change this later. The ${color_1.input('--project-id')} is generated from ${color_1.input('name')} unless explicitly specified.

The second argument is the ${color_1.input('template')} from which to generate your app. You can list all templates with the ${color_1.input('--list')} option. You can also specify a git repository URL for ${color_1.input('template')}, in which case the existing project will be cloned.

Use the ${color_1.input('--type')} option to start projects using older versions of Ionic. For example, you can start an Ionic 3 project with ${color_1.input('--type=ionic-angular')}. Use ${color_1.input('--list')} to see all project types and templates.
      `,
            exampleCommands: [
                '',
                '--list',
                'myApp',
                'myApp blank',
                'myApp tabs --cordova',
                'myApp tabs --capacitor',
                'myApp super --type=ionic-angular',
                'myApp blank --type=ionic1',
                'cordovaApp tabs --cordova',
                '"My App" blank',
                '"Conference App" https://github.com/ionic-team/ionic-conference-app',
            ],
            inputs: [
                {
                    name: 'name',
                    summary: `The name of your new project (e.g. ${color_1.input('myApp')}, ${color_1.input('"My App"')})`,
                    validators: [cli_framework_1.validators.required],
                },
                {
                    name: 'template',
                    summary: `The starter template to use (e.g. ${['blank', 'tabs'].map(t => color_1.input(t)).join(', ')}; use ${color_1.input('--list')} to see all)`,
                    validators: [cli_framework_1.validators.required],
                },
            ],
            options: [
                {
                    name: 'list',
                    summary: 'List available starter templates',
                    type: Boolean,
                    aliases: ['l'],
                },
                {
                    name: 'type',
                    summary: `Type of project to start (e.g. ${start_1.getStarterProjectTypes().map(type => color_1.input(type)).join(', ')})`,
                    type: String,
                },
                {
                    name: 'cordova',
                    summary: 'Include Cordova integration',
                    type: Boolean,
                },
                {
                    name: 'capacitor',
                    summary: 'Include Capacitor integration',
                    type: Boolean,
                    groups: ["experimental" /* EXPERIMENTAL */],
                },
                {
                    name: 'deps',
                    summary: 'Do not install npm/yarn dependencies',
                    type: Boolean,
                    default: true,
                    groups: ["advanced" /* ADVANCED */],
                },
                {
                    name: 'git',
                    summary: 'Do not initialize a git repo',
                    type: Boolean,
                    default: true,
                    groups: ["advanced" /* ADVANCED */],
                },
                {
                    name: 'link',
                    summary: 'Connect your new app to Ionic',
                    type: Boolean,
                    groups: ["advanced" /* ADVANCED */],
                },
                {
                    name: 'id',
                    summary: 'Specify an Ionic App ID to link',
                },
                {
                    name: 'project-id',
                    summary: 'Specify a slug for your app (used for the directory name and package name)',
                    groups: ["advanced" /* ADVANCED */],
                    spec: { value: 'slug' },
                },
                {
                    name: 'package-id',
                    summary: 'Specify the bundle ID/application ID for your app (reverse-DNS notation)',
                    groups: ["advanced" /* ADVANCED */],
                    spec: { value: 'id' },
                },
                {
                    name: 'start-id',
                    summary: 'Used by the Ionic app start experience to generate an associated app locally',
                    groups: ["hidden" /* HIDDEN */],
                    spec: { value: 'id' },
                },
                {
                    name: 'tag',
                    summary: `Specify a tag to use for the starters (e.g. ${['latest', 'testing', 'next'].map(t => color_1.input(t)).join(', ')})`,
                    default: 'latest',
                    groups: ["hidden" /* HIDDEN */],
                },
            ],
        };
    }
    async startIdStart(inputs, options) {
        const startId = options['start-id'];
        const wizardApiUrl = process.env.START_WIZARD_URL_BASE || `https://ionicframework.com`;
        const { req } = await http_1.createRequest('GET', `${wizardApiUrl}/api/v1/wizard/app/${startId}`, this.env.config.getHTTPConfig());
        const error = (e) => {
            this.env.log.error(`No such app ${chalk.bold(startId)}. This app configuration may have expired. Please retry at https://ionicframework.com/start`);
            if (e) {
                throw e;
            }
        };
        let data;
        try {
            const ret = await req;
            if (ret.status !== 200) {
                return error();
            }
            data = (await req).body;
            if (!data) {
                return error();
            }
        }
        catch (e) {
            return error(e);
        }
        let projectDir = string_1.slugify(data.name);
        if (inputs.length === 1) {
            projectDir = inputs[0];
        }
        await this.checkForExisting(projectDir);
        inputs.push(data.name);
        inputs.push(data.template);
        await this.startIdConvert(startId);
        const appIconBuffer = data.appIcon ?
            Buffer.from(data.appIcon.replace(/^data:image\/\w+;base64,/, ''), 'base64') :
            undefined;
        const splashBuffer = data.appSplash ?
            Buffer.from(data.appSplash.replace(/^data:image\/\w+;base64,/, ''), 'base64') :
            undefined;
        this.schema = {
            cloned: false,
            name: data.name,
            type: data.type,
            template: data.template,
            projectId: string_1.slugify(data.name),
            projectDir,
            packageId: data['package-id'],
            appflowId: undefined,
            appIcon: appIconBuffer,
            splash: splashBuffer,
            themeColor: data.theme,
        };
    }
    async startIdConvert(id) {
        const wizardApiUrl = process.env.START_WIZARD_URL_BASE || `https://ionicframework.com`;
        if (!wizardApiUrl) {
            return;
        }
        const { req } = await http_1.createRequest('POST', `${wizardApiUrl}/api/v1/wizard/app/${id}/start`, this.env.config.getHTTPConfig());
        try {
            await req;
        }
        catch (e) {
            this.env.log.warn(`Unable to set app flag on server: ${e.message}`);
        }
    }
    async preRun(inputs, options) {
        const { promptToLogin } = await Promise.resolve().then(() => require('../lib/session'));
        start_1.verifyOptions(options, this.env);
        const appflowId = options['id'] ? String(options['id']) : undefined;
        if (appflowId) {
            if (!this.env.session.isLoggedIn()) {
                await promptToLogin(this.env);
            }
        }
        // The start wizard pre-populates all arguments for the CLI
        if (options['start-id']) {
            await this.startIdStart(inputs, options);
            return;
        }
        const projectType = string_1.isValidURL(inputs[1]) ? 'custom' : options['type'] ? String(options['type']) : await this.getProjectType();
        if (options['cordova']) {
            const { checkForUnsupportedProject } = await Promise.resolve().then(() => require('../lib/integrations/cordova/utils'));
            try {
                await checkForUnsupportedProject(projectType);
            }
            catch (e) {
                this.env.log.error(e.message);
                options['cordova'] = false;
            }
        }
        if (!inputs[0]) {
            if (appflowId) {
                const { AppClient } = await Promise.resolve().then(() => require('../lib/app'));
                const token = await this.env.session.getUserToken();
                const appClient = new AppClient(token, this.env);
                const tasks = this.createTaskChain();
                tasks.next(`Looking up app ${color_1.input(appflowId)}`);
                const app = await appClient.load(appflowId);
                // TODO: can ask to clone via repo_url
                tasks.end();
                this.env.log.info(`Using ${color_1.strong(app.name)} for ${color_1.input('name')} and ${color_1.strong(app.slug)} for ${color_1.input('--project-id')}.`);
                inputs[0] = app.name;
                options['project-id'] = app.slug;
            }
            else {
                if (this.env.flags.interactive) {
                    this.env.log.nl();
                    this.env.log.msg(`${color_1.strong(`Every great app needs a name! ${emoji_1.emoji('😍', '')}`)}\n` +
                        `Please enter the full name of your app. You can change this at any time. To bypass this prompt next time, supply ${color_1.input('name')}, the first argument to ${color_1.input('ionic start')}.\n\n`);
                }
                const name = await this.env.prompt({
                    type: 'input',
                    name: 'name',
                    message: 'Project name:',
                    validate: v => cli_framework_1.validators.required(v),
                });
                inputs[0] = name;
            }
        }
        if (!inputs[1]) {
            if (this.env.flags.interactive) {
                this.env.log.nl();
                this.env.log.msg(`${color_1.strong(`Let's pick the perfect starter template! ${emoji_1.emoji('💪', '')}`)}\n` +
                    `Starter templates are ready-to-go Ionic apps that come packed with everything you need to build your app. To bypass this prompt next time, supply ${color_1.input('template')}, the second argument to ${color_1.input('ionic start')}.\n\n`);
            }
            const template = await this.env.prompt({
                type: 'list',
                name: 'template',
                message: 'Starter template:',
                choices: () => {
                    const starterTemplateList = start_1.STARTER_TEMPLATES.filter(st => st.projectType === projectType);
                    const cols = utils_terminal_1.columnar(starterTemplateList.map(({ name, description }) => [color_1.input(name), description || '']), constants_1.COLUMNAR_OPTIONS).split('\n');
                    if (starterTemplateList.length === 0) {
                        throw new errors_1.FatalException(`No starter templates found for project type: ${color_1.input(projectType)}.`);
                    }
                    return starterTemplateList.map((starter, i) => {
                        return {
                            name: cols[i],
                            short: starter.name,
                            value: starter.name,
                        };
                    });
                },
            });
            inputs[1] = template;
        }
        const starterTemplate = start_1.STARTER_TEMPLATES.find(t => t.name === inputs[1] && t.projectType === projectType);
        if (starterTemplate && starterTemplate.type === 'repo') {
            inputs[1] = starterTemplate.repo;
        }
        const cloned = string_1.isValidURL(inputs[1]);
        if (this.project && this.project.details.context === 'app') {
            const confirm = await this.env.prompt({
                type: 'confirm',
                name: 'confirm',
                message: 'You are already in an Ionic project directory. Do you really want to start another project here?',
                default: false,
            });
            if (!confirm) {
                this.env.log.info('Not starting project within existing project.');
                throw new errors_1.FatalException();
            }
        }
        await this.validateProjectType(projectType);
        if (cloned) {
            if (!options['git']) {
                this.env.log.warn(`The ${color_1.input('--no-git')} option has no effect when cloning apps. Git must be used.`);
            }
            options['git'] = true;
        }
        if (options['v1'] || options['v2']) {
            throw new errors_1.FatalException(`The ${color_1.input('--v1')} and ${color_1.input('--v2')} flags have been removed.\n` +
                `Use the ${color_1.input('--type')} option. (see ${color_1.input('ionic start --help')})`);
        }
        if (options['app-name']) {
            this.env.log.warn(`The ${color_1.input('--app-name')} option has been removed. Use the ${color_1.input('name')} argument with double quotes: e.g. ${color_1.input('ionic start "My App"')}`);
        }
        if (options['display-name']) {
            this.env.log.warn(`The ${color_1.input('--display-name')} option has been removed. Use the ${color_1.input('name')} argument with double quotes: e.g. ${color_1.input('ionic start "My App"')}`);
        }
        if (options['bundle-id']) {
            this.env.log.warn(`The ${color_1.input('--bundle-id')} option has been deprecated. Please use ${color_1.input('--package-id')}.`);
            options['package-id'] = options['bundle-id'];
        }
        let projectId = options['project-id'] ? String(options['project-id']) : undefined;
        if (projectId) {
            await this.validateProjectId(projectId);
        }
        else {
            projectId = options['project-id'] = project_1.isValidProjectId(inputs[0]) ? inputs[0] : string_1.slugify(inputs[0]);
        }
        const projectDir = path.resolve(projectId);
        const packageId = options['package-id'] ? String(options['package-id']) : undefined;
        if (projectId) {
            await this.checkForExisting(projectDir);
        }
        if (cloned) {
            this.schema = {
                cloned: true,
                url: inputs[1],
                projectId,
                projectDir,
            };
        }
        else {
            this.schema = {
                cloned: false,
                name: inputs[0],
                type: projectType,
                template: inputs[1],
                projectId,
                projectDir,
                packageId,
                appflowId,
                themeColor: undefined,
            };
        }
    }
    async getProjectType() {
        if (this.env.flags.interactive) {
            this.env.log.nl();
            this.env.log.msg(`${color_1.strong(`Pick a framework! ${emoji_1.emoji('😁', '')}`)}\n\n` +
                `Please select the JavaScript framework to use for your new app. To bypass this prompt next time, supply a value for the ${color_1.input('--type')} option.\n\n`);
        }
        const frameworkChoice = await this.env.prompt({
            type: 'list',
            name: 'frameworks',
            message: 'Framework:',
            default: 'angular',
            choices: () => {
                const cols = utils_terminal_1.columnar(start_1.SUPPORTED_FRAMEWORKS.map(({ name, description }) => [color_1.input(name), description]), constants_1.COLUMNAR_OPTIONS).split('\n');
                return start_1.SUPPORTED_FRAMEWORKS.map((starterTemplate, i) => {
                    return {
                        name: cols[i],
                        short: starterTemplate.name,
                        value: starterTemplate.type,
                    };
                });
            },
        });
        return frameworkChoice;
    }
    async run(inputs, options, runinfo) {
        const { pkgManagerArgs } = await Promise.resolve().then(() => require('../lib/utils/npm'));
        const { getTopLevel, isGitInstalled } = await Promise.resolve().then(() => require('../lib/git'));
        if (!this.schema) {
            throw new errors_1.FatalException(`Invalid start schema: cannot start app.`);
        }
        const { projectId, projectDir, packageId, appflowId } = this.schema;
        const tag = options['tag'] ? String(options['tag']) : 'latest';
        let linkConfirmed = typeof appflowId === 'string';
        const gitDesired = options['git'] ? true : false;
        const gitInstalled = await isGitInstalled(this.env);
        const gitTopLevel = await getTopLevel(this.env);
        let gitIntegration = gitDesired && gitInstalled && !gitTopLevel ? true : false;
        if (!gitInstalled) {
            const installationDocs = `See installation docs for git: ${color_1.strong('https://git-scm.com/book/en/v2/Getting-Started-Installing-Git')}`;
            if (appflowId) {
                throw new errors_1.FatalException(`Git CLI not found on your PATH.\n` +
                    `Git must be installed to connect this app to Ionic. ${installationDocs}`);
            }
            if (this.schema.cloned) {
                throw new errors_1.FatalException(`Git CLI not found on your PATH.\n` +
                    `Git must be installed to clone apps with ${color_1.input('ionic start')}. ${installationDocs}`);
            }
        }
        if (gitTopLevel && !this.schema.cloned) {
            this.env.log.info(`Existing git project found (${color_1.strong(gitTopLevel)}). Git operations are disabled.`);
        }
        const tasks = this.createTaskChain();
        tasks.next(`Preparing directory ${color_1.input(utils_terminal_1.prettyPath(projectDir))}`);
        if (this.canRemoveExisting) {
            await utils_fs_1.remove(projectDir);
        }
        await utils_fs_1.mkdir(projectDir);
        tasks.end();
        if (this.schema.cloned) {
            await this.env.shell.run('git', ['clone', this.schema.url, projectDir, '--progress'], { stdio: 'inherit' });
        }
        else {
            const starterTemplate = await this.findStarterTemplate(this.schema.template, this.schema.type, tag);
            await this.downloadStarterTemplate(projectDir, starterTemplate);
        }
        let project;
        if (this.project && this.project.details.context === 'multiapp' && !this.schema.cloned) {
            // We're in a multi-app setup, so the new config file isn't wanted.
            await utils_fs_1.unlink(path.resolve(projectDir, constants_1.PROJECT_FILE));
            project = await project_1.createProjectFromDetails({ context: 'multiapp', configPath: path.resolve(this.project.rootDirectory, constants_1.PROJECT_FILE), id: projectId, type: this.schema.type, errors: [] }, this.env);
            project.config.set('type', this.schema.type);
            project.config.set('root', path.relative(this.project.rootDirectory, projectDir));
        }
        else {
            project = await project_1.createProjectFromDirectory(projectDir, { _: [] }, this.env, { logErrors: false });
        }
        // start is weird, once the project directory is created, it becomes a
        // "project" command and so we replace the `Project` instance that was
        // autogenerated when the CLI booted up. This has worked thus far?
        this.namespace.root.project = project;
        if (!this.project) {
            throw new errors_1.FatalException('Error while loading project.');
        }
        this.env.shell.alterPath = p => shell_1.prependNodeModulesBinToPath(projectDir, p);
        if (!this.schema.cloned) {
            if (this.schema.type === 'react') {
                options['capacitor'] = true;
            }
            if (options['cordova']) {
                const { confirmCordovaUsage } = await Promise.resolve().then(() => require('../lib/integrations/cordova/utils'));
                const confirm = await confirmCordovaUsage(this.env);
                if (confirm) {
                    await executor_1.runCommand(runinfo, ['integrations', 'enable', 'cordova', '--quiet']);
                }
                else {
                    options['cordova'] = false;
                }
            }
            if (options['capacitor'] === null && !options['cordova']) {
                const confirm = await this.env.prompt({
                    type: 'confirm',
                    name: 'confirm',
                    message: 'Integrate your new app with Capacitor to target native iOS and Android?',
                    default: false,
                });
                if (confirm) {
                    options['capacitor'] = true;
                }
            }
            if (options['capacitor']) {
                await executor_1.runCommand(runinfo, ['integrations', 'enable', 'capacitor', '--quiet', '--', this.schema.name, packageId ? packageId : 'io.ionic.starter']);
            }
            await this.project.personalize({
                name: this.schema.name,
                projectId,
                packageId,
                appIcon: this.schema.appIcon,
                splash: this.schema.splash,
                themeColor: this.schema.themeColor,
            });
            this.env.log.nl();
        }
        const shellOptions = { cwd: projectDir, stdio: 'inherit' };
        if (options['deps']) {
            this.env.log.msg('Installing dependencies may take several minutes.');
            this.env.log.rawmsg(start_1.getAdvertisement());
            const [installer, ...installerArgs] = await pkgManagerArgs(this.env.config.get('npmClient'), { command: 'install' });
            await this.env.shell.run(installer, installerArgs, shellOptions);
        }
        if (!this.schema.cloned) {
            if (gitIntegration) {
                try {
                    await this.env.shell.run('git', ['init'], shellOptions); // TODO: use initializeRepo()?
                }
                catch (e) {
                    this.env.log.warn('Error encountered during repo initialization. Disabling further git operations.');
                    gitIntegration = false;
                }
            }
            // Prompt to create account
            if (!this.env.session.isLoggedIn()) {
                await session_1.promptToSignup(this.env);
            }
            if (options['link']) {
                const cmdArgs = ['link'];
                if (appflowId) {
                    cmdArgs.push(appflowId);
                }
                cmdArgs.push('--name', this.schema.name);
                await executor_1.runCommand(runinfo, cmdArgs);
                linkConfirmed = true;
            }
            const manifestPath = path.resolve(projectDir, 'ionic.starter.json');
            const manifest = await this.loadManifest(manifestPath);
            if (manifest) {
                await utils_fs_1.unlink(manifestPath);
            }
            if (gitIntegration) {
                try {
                    await this.env.shell.run('git', ['add', '-A'], shellOptions);
                    await this.env.shell.run('git', ['commit', '-m', 'Initial commit', '--no-gpg-sign'], shellOptions);
                }
                catch (e) {
                    this.env.log.warn('Error encountered during commit. Disabling further git operations.');
                    gitIntegration = false;
                }
            }
            if (manifest) {
                await this.performManifestOps(manifest);
            }
        }
        this.env.log.nl();
        await this.showNextSteps(projectDir, this.schema.cloned, linkConfirmed, !options['cordova']);
    }
    async checkForExisting(projectDir) {
        const projectExists = await utils_fs_1.pathExists(projectDir);
        if (projectExists) {
            const confirm = await this.env.prompt({
                type: 'confirm',
                name: 'confirm',
                message: `${color_1.input(utils_terminal_1.prettyPath(projectDir))} exists. ${color_1.failure('Overwrite?')}`,
                default: false,
            });
            if (!confirm) {
                this.env.log.msg(`Not erasing existing project in ${color_1.input(utils_terminal_1.prettyPath(projectDir))}.`);
                throw new errors_1.FatalException();
            }
            this.canRemoveExisting = confirm;
        }
    }
    async findStarterTemplate(template, type, tag) {
        const starterTemplate = start_1.STARTER_TEMPLATES.find(t => t.projectType === type && t.name === template);
        if (starterTemplate && starterTemplate.type === 'managed') {
            return {
                ...starterTemplate,
                archive: `${start_1.STARTER_BASE_URL}/${tag === 'latest' ? '' : `${tag}/`}${starterTemplate.id}.tar.gz`,
            };
        }
        const tasks = this.createTaskChain();
        tasks.next('Looking up starter');
        const starterList = await start_1.getStarterList(this.env.config, tag);
        const starter = starterList.starters.find(t => t.type === type && t.name === template);
        if (starter) {
            tasks.end();
            return {
                name: starter.name,
                projectType: starter.type,
                archive: `${start_1.STARTER_BASE_URL}/${tag === 'latest' ? '' : `${tag}/`}${starter.id}.tar.gz`,
            };
        }
        else {
            throw new errors_1.FatalException(`Unable to find starter template for ${color_1.input(template)}\n` +
                `If this is not a typo, please make sure it is a valid starter template within the starters repo: ${color_1.strong('https://github.com/ionic-team/starters')}`);
        }
    }
    async validateProjectType(type) {
        const projectTypes = start_1.getStarterProjectTypes();
        if (!['custom', ...projectTypes].includes(type)) {
            throw new errors_1.FatalException(`${color_1.input(type)} is not a valid project type.\n` +
                `Please choose a different ${color_1.input('--type')}. Use ${color_1.input('ionic start --list')} to list all available starter templates.`);
        }
    }
    async validateProjectId(projectId) {
        if (!project_1.isValidProjectId(projectId)) {
            throw new errors_1.FatalException(`${color_1.input(projectId)} is not a valid package or directory name.\n` +
                `Please choose a different ${color_1.input('--project-id')}. Alphanumeric characters are always safe.`);
        }
    }
    async loadManifest(manifestPath) {
        try {
            return await start_1.readStarterManifest(manifestPath);
        }
        catch (e) {
            debug(`Error with manifest file ${color_1.strong(utils_terminal_1.prettyPath(manifestPath))}: ${e}`);
        }
    }
    async performManifestOps(manifest) {
        if (manifest.welcome) {
            this.env.log.nl();
            this.env.log.msg(`${color_1.strong('Starter Welcome')}:`);
            this.env.log.msg(manifest.welcome);
        }
    }
    async downloadStarterTemplate(projectDir, starterTemplate) {
        const { createRequest, download } = await Promise.resolve().then(() => require('../lib/utils/http'));
        const { tar } = await Promise.resolve().then(() => require('../lib/utils/archive'));
        const tasks = this.createTaskChain();
        const task = tasks.next(`Downloading and extracting ${color_1.input(starterTemplate.name.toString())} starter`);
        debug('Tar extraction created for %s', projectDir);
        const ws = tar.extract({ cwd: projectDir });
        const { req } = await createRequest('GET', starterTemplate.archive, this.env.config.getHTTPConfig());
        await download(req, ws, { progress: (loaded, total) => task.progress(loaded, total) });
        tasks.end();
    }
    async showNextSteps(projectDir, cloned, linkConfirmed, isCapacitor) {
        const cordovaResCommand = isCapacitor ? 'cordova-res --skip-config --copy' : 'cordova-res';
        const steps = [
            `Go to your ${cloned ? 'cloned' : 'new'} project: ${color_1.input(`cd ${utils_terminal_1.prettyPath(projectDir)}`)}`,
            `Run ${color_1.input('ionic serve')} within the app directory to see your app in the browser`,
            isCapacitor ?
                `Run ${color_1.input('ionic capacitor add')} to add a native iOS or Android project using Capacitor` :
                `Run ${color_1.input('ionic cordova platform add')} to add a native iOS or Android project using Cordova`,
            `Generate your app icon and splash screens using ${color_1.input(cordovaResCommand)}`,
            `Explore the Ionic docs for components, tutorials, and more: ${color_1.strong('https://ion.link/docs')}`,
            `Building an enterprise app? Ionic has Enterprise Support and Features: ${color_1.strong('https://ion.link/enterprise-edition')}`,
        ];
        if (linkConfirmed) {
            steps.push(`Push your code to Ionic Appflow to perform real-time updates, and more: ${color_1.input('git push ionic master')}`);
        }
        this.env.log.msg(`${color_1.strong('Your Ionic app is ready! Follow these next steps')}:\n${steps.map(s => ` - ${s}`).join('\n')}`);
    }
}
exports.StartCommand = StartCommand;

Filemanager

Name Type Size Permission Actions
capacitor Folder 0755
config Folder 0755
cordova Folder 0755
deploy Folder 0755
doctor Folder 0755
enterprise Folder 0755
git Folder 0755
integrations Folder 0755
monitoring Folder 0755
package Folder 0755
ssh Folder 0755
ssl Folder 0755
build.d.ts File 484 B 0644
build.js File 2.58 KB 0644
completion.d.ts File 315 B 0644
completion.js File 2 KB 0644
docs.d.ts File 309 B 0644
docs.js File 1.77 KB 0644
generate.d.ts File 436 B 0644
generate.js File 2.29 KB 0644
help.d.ts File 309 B 0644
help.js File 2.42 KB 0644
index.d.ts File 763 B 0644
index.js File 6.07 KB 0644
info.d.ts File 309 B 0644
info.js File 2.84 KB 0644
init.d.ts File 615 B 0644
init.js File 9.29 KB 0644
ionitron.d.ts File 313 B 0644
ionitron.js File 1.07 KB 0644
link.d.ts File 1.23 KB 0644
link.js File 22.04 KB 0644
login.d.ts File 507 B 0644
login.js File 7.78 KB 0644
logout.d.ts File 311 B 0644
logout.js File 922 B 0644
repair.d.ts File 544 B 0644
repair.js File 5.12 KB 0644
serve.d.ts File 621 B 0644
serve.js File 6.1 KB 0644
share.d.ts File 217 B 0644
share.js File 780 B 0644
signup.d.ts File 311 B 0644
signup.js File 977 B 0644
start.d.ts File 1.36 KB 0644
start.js File 30.26 KB 0644
state.d.ts File 217 B 0644
state.js File 1.93 KB 0644
telemetry.d.ts File 314 B 0644
telemetry.js File 1.17 KB 0644
version.d.ts File 312 B 0644
version.js File 648 B 0644