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