1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const cli_framework_1 = require("@ionic/cli-framework");
|
4 | const format_1 = require("@ionic/cli-framework/utils/format");
|
5 | const string_1 = require("@ionic/cli-framework/utils/string");
|
6 | const path = require("path");
|
7 | const constants_1 = require("../constants");
|
8 | const color_1 = require("../lib/color");
|
9 | const command_1 = require("../lib/command");
|
10 | const errors_1 = require("../lib/errors");
|
11 | const project_1 = require("../lib/project");
|
12 | class InitCommand extends command_1.Command {
|
13 | async getMetadata() {
|
14 | return {
|
15 | name: 'init',
|
16 | type: 'global',
|
17 | summary: 'Initialize existing projects with Ionic',
|
18 | description: `
|
19 | This command will initialize an Ionic app within the current directory. Usually, this means an ${color_1.input(constants_1.PROJECT_FILE)} file is created. If used within a multi-app project, the app is initialized in the root ${color_1.input(constants_1.PROJECT_FILE)}.
|
20 |
|
21 | ${color_1.input('ionic init')} will prompt for a project name and then proceed to determine the type of your project. You can specify the ${color_1.input('name')} argument and ${color_1.input('--type')} option to provide these values via command-line.
|
22 |
|
23 | If the ${color_1.input('--multi-app')} flag is specified, this command will initialize your project as a multi-app project, allowing for apps within monorepos and unconventional repository structures. See the multi-app docs[^multi-app-docs] for details. Once a multi-app project is initialized, you can run ${color_1.input('ionic init')} again within apps in your project to initialize them.
|
24 | `,
|
25 | exampleCommands: [
|
26 | '',
|
27 | '"My App"',
|
28 | '"My App" --type=angular',
|
29 | '--multi-app',
|
30 | ],
|
31 | inputs: [
|
32 | {
|
33 | name: 'name',
|
34 | summary: `The name of your project (e.g. ${color_1.input('myApp')}, ${color_1.input('"My App"')})`,
|
35 | },
|
36 | ],
|
37 | options: [
|
38 | {
|
39 | name: 'type',
|
40 | summary: `Type of project (e.g. ${constants_1.MODERN_PROJECT_TYPES.map(type => color_1.input(type)).join(', ')})`,
|
41 | },
|
42 | {
|
43 | name: 'force',
|
44 | summary: 'Initialize even if a project already exists',
|
45 | type: Boolean,
|
46 | aliases: ['f'],
|
47 | default: false,
|
48 | },
|
49 | {
|
50 | name: 'multi-app',
|
51 | summary: 'Initialize a multi-app project',
|
52 | type: Boolean,
|
53 | default: false,
|
54 | },
|
55 | {
|
56 | name: 'project-id',
|
57 | summary: 'Specify a slug for your app',
|
58 | groups: ["advanced" ],
|
59 | spec: { value: 'slug' },
|
60 | hint: color_1.weak('[multi-app]'),
|
61 | },
|
62 | {
|
63 | name: 'default',
|
64 | summary: 'Mark the initialized app as the default project',
|
65 | type: Boolean,
|
66 | groups: ["advanced" ],
|
67 | hint: color_1.weak('[multi-app]'),
|
68 | },
|
69 | ],
|
70 | groups: ["beta" ],
|
71 | footnotes: [
|
72 | {
|
73 | id: 'multi-app-docs',
|
74 | url: 'https://ionicframework.com/docs/cli/configuration#multi-app-projects',
|
75 | shortUrl: 'https://ion.link/multi-app-docs',
|
76 | },
|
77 | ],
|
78 | };
|
79 | }
|
80 | async preRun(inputs, options) {
|
81 | const force = options['force'] ? true : false;
|
82 | if (this.project && !force) {
|
83 |
|
84 | if (this.project.details.context === 'app' || (this.project.details.context === 'multiapp' && options['multi-app'])) {
|
85 | throw new errors_1.FatalException(`Existing Ionic project file found: ${color_1.strong(format_1.prettyPath(this.project.filePath))}\n` +
|
86 | `You can re-initialize your project using the ${color_1.input('--force')} option.`);
|
87 | }
|
88 | }
|
89 | if (!options['multi-app']) {
|
90 | if (!inputs[0]) {
|
91 | const name = await this.env.prompt({
|
92 | type: 'input',
|
93 | name: 'name',
|
94 | message: 'Project name:',
|
95 | validate: v => cli_framework_1.validators.required(v),
|
96 | });
|
97 | inputs[0] = name;
|
98 | }
|
99 | if (!options['type']) {
|
100 | const details = new project_1.ProjectDetails({ rootDirectory: this.env.ctx.execPath, e: this.env });
|
101 | options['type'] = await details.getTypeFromDetection();
|
102 | }
|
103 | if (!options['type']) {
|
104 | if (this.env.flags.interactive) {
|
105 | this.env.log.warn(`Could not determine project type.\n` +
|
106 | `Please choose a project type from the list.`);
|
107 | this.env.log.nl();
|
108 | }
|
109 | const type = await this.env.prompt({
|
110 | type: 'list',
|
111 | name: 'type',
|
112 | message: 'Project type:',
|
113 | choices: constants_1.MODERN_PROJECT_TYPES.map(t => ({
|
114 | name: `${project_1.prettyProjectName(t)} (${color_1.input(t)})`,
|
115 | value: t,
|
116 | })),
|
117 | });
|
118 | options['type'] = type;
|
119 | }
|
120 | }
|
121 | }
|
122 | async run(inputs, options) {
|
123 | if (options['multi-app']) {
|
124 | await this.initializeMultiProject(inputs, options);
|
125 | }
|
126 | else {
|
127 | await this.initializeApp(inputs, options);
|
128 | }
|
129 | this.env.log.ok('Your Ionic project has been initialized!');
|
130 | }
|
131 | async initializeMultiProject(inputs, options) {
|
132 | const configPath = this.getProjectFilePath();
|
133 | const config = new project_1.MultiProjectConfig(configPath);
|
134 | config.c = { projects: {} };
|
135 | }
|
136 | async initializeApp(inputs, options) {
|
137 | const name = inputs[0] ? inputs[0].trim() : '';
|
138 | const type = options['type'] ? String(options['type']) : undefined;
|
139 | const projectId = options['project-id'] ? String(options['project-id']) : string_1.slugify(name);
|
140 | if (!name) {
|
141 | throw new errors_1.FatalException(`Project name not specified.\n` +
|
142 | `Please specify ${color_1.input('name')}, the first argument of ${color_1.input('ionic init')}. See ${color_1.input('ionic init --help')} for details.`);
|
143 | }
|
144 | if (!type) {
|
145 | throw new errors_1.FatalException(`Could not determine project type.\n` +
|
146 | `Please specify ${color_1.input('--type')}. See ${color_1.input('ionic init --help')} for details.`);
|
147 | }
|
148 | let project;
|
149 | if (this.project && this.project.details.context === 'multiapp') {
|
150 | const configPath = path.resolve(this.project.rootDirectory, constants_1.PROJECT_FILE);
|
151 | const projectRoot = path.relative(this.project.rootDirectory, this.env.ctx.execPath);
|
152 | const config = new project_1.MultiProjectConfig(configPath);
|
153 | if (!projectRoot) {
|
154 | if (this.env.flags.interactive) {
|
155 | this.env.log.warn(`About to initialize app in the root directory of your multi-app project.\n` +
|
156 | `Please confirm that you want your app initialized in the root of your multi-app project. If this wasn't intended, please ${color_1.input('cd')} into the appropriate directory and run ${color_1.input('ionic init')} again.\n`);
|
157 | }
|
158 | const confirm = await this.env.prompt({
|
159 | type: 'confirm',
|
160 | message: 'Continue?',
|
161 | default: false,
|
162 | });
|
163 | if (!confirm) {
|
164 | throw new errors_1.FatalException(`Not initializing app in root directory.`);
|
165 | }
|
166 | }
|
167 | const defaultProject = config.get('defaultProject');
|
168 | if (!defaultProject && typeof options['default'] !== 'boolean') {
|
169 | const confirm = await this.env.prompt({
|
170 | type: 'confirm',
|
171 | message: `Would you like to make this app the default project?`,
|
172 | default: true,
|
173 | });
|
174 | if (confirm) {
|
175 | options['default'] = true;
|
176 | }
|
177 | }
|
178 | if (options['default']) {
|
179 | config.set('defaultProject', projectId);
|
180 | }
|
181 | project = await project_1.createProjectFromDetails({ context: 'multiapp', configPath, id: projectId, type, errors: [] }, this.env);
|
182 | project.config.set('root', projectRoot);
|
183 | }
|
184 | else {
|
185 | const configPath = this.getProjectFilePath();
|
186 | project = await project_1.createProjectFromDetails({ context: 'app', configPath, type, errors: [] }, this.env);
|
187 | }
|
188 | project.config.set('name', name);
|
189 | project.config.set('type', type);
|
190 | }
|
191 | getProjectFilePath() {
|
192 | return path.resolve(this.env.ctx.execPath, constants_1.PROJECT_FILE);
|
193 | }
|
194 | }
|
195 | exports.InitCommand = InitCommand;
|