UNPKG

9.52 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.InitCommand = void 0;
4const cli_framework_1 = require("@ionic/cli-framework");
5const string_1 = require("@ionic/cli-framework/utils/string");
6const utils_terminal_1 = require("@ionic/utils-terminal");
7const path = require("path");
8const constants_1 = require("../constants");
9const color_1 = require("../lib/color");
10const command_1 = require("../lib/command");
11const errors_1 = require("../lib/errors");
12const project_1 = require("../lib/project");
13class 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: `
20This 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
24If 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" /* 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" /* ADVANCED */],
68 hint: color_1.weak('[multi-app]'),
69 },
70 ],
71 groups: ["beta" /* 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 // TODO: check for existing project config in multi-app
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); // TODO validate --project-id
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}
196exports.InitCommand = InitCommand;