UNPKG

16.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const path = require("path");
5const chalk_1 = require("chalk");
6const utils_fs_1 = require("@ionic/utils-fs");
7const app_1 = require("../../app");
8const git_1 = require("../../git");
9const config_1 = require("../../integrations/cordova/config");
10const project_1 = require("../../integrations/cordova/project");
11const npm_1 = require("../../utils/npm");
12const base_1 = require("./base");
13tslib_1.__exportStar(require("./base"), exports);
14tslib_1.__exportStar(require("./utils"), exports);
15class NpmInstalledLocally extends base_1.Ailment {
16 constructor() {
17 super(...arguments);
18 this.id = 'npm-installed-locally';
19 this.treatable = true;
20 }
21 getMessage() {
22 return tslib_1.__awaiter(this, void 0, void 0, function* () {
23 return (`${chalk_1.default.bold('npm')} is installed locally.\n` +
24 `${chalk_1.default.bold('npm')} is typically installed globally and may cause some confusion about versions when other CLIs use it.\n`).trim();
25 });
26 }
27 detected() {
28 return tslib_1.__awaiter(this, void 0, void 0, function* () {
29 const pkg = yield this.getLocalPackageJson('npm');
30 return pkg !== undefined;
31 });
32 }
33 getTreatmentSteps() {
34 return tslib_1.__awaiter(this, void 0, void 0, function* () {
35 const [manager, ...managerArgs] = yield npm_1.pkgManagerArgs(this.config.get('npmClient'), { command: 'uninstall', pkg: 'npm' });
36 return [
37 {
38 message: `Run: ${chalk_1.default.green(manager + ' ' + managerArgs.join(' '))}`,
39 treat: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
40 yield this.shell.run(manager, managerArgs, {});
41 }),
42 },
43 ];
44 });
45 }
46}
47exports.NpmInstalledLocally = NpmInstalledLocally;
48class IonicCLIInstalledLocally extends base_1.Ailment {
49 constructor() {
50 super(...arguments);
51 this.id = 'ionic-installed-locally';
52 this.treatable = true;
53 }
54 getMessage() {
55 return tslib_1.__awaiter(this, void 0, void 0, function* () {
56 return (`The Ionic CLI is installed locally.\n` +
57 `While the CLI can run locally, there's no longer a reason to have it installed locally and it may cause some confusion over configuration and versions.\n`).trim();
58 });
59 }
60 detected() {
61 return tslib_1.__awaiter(this, void 0, void 0, function* () {
62 const pkg = yield this.getLocalPackageJson('ionic');
63 return pkg !== undefined;
64 });
65 }
66 getTreatmentSteps() {
67 return tslib_1.__awaiter(this, void 0, void 0, function* () {
68 const [manager, ...managerArgs] = yield npm_1.pkgManagerArgs(this.config.get('npmClient'), { command: 'uninstall', pkg: 'ionic' });
69 return [
70 {
71 message: `Run: ${chalk_1.default.green(manager + ' ' + managerArgs.join(' '))}`,
72 treat: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
73 yield this.shell.run(manager, managerArgs, {});
74 }),
75 },
76 ];
77 });
78 }
79}
80exports.IonicCLIInstalledLocally = IonicCLIInstalledLocally;
81class GitNotUsed extends base_1.Ailment {
82 constructor() {
83 super(...arguments);
84 this.id = 'git-not-used';
85 }
86 getMessage() {
87 return tslib_1.__awaiter(this, void 0, void 0, function* () {
88 return (`Git doesn't appear to be in use.\n` +
89 `We highly recommend using source control software such as git (${chalk_1.default.bold('https://git-scm.com')}) to track changes in your code throughout time.\n`).trim();
90 });
91 }
92 detected() {
93 return tslib_1.__awaiter(this, void 0, void 0, function* () {
94 if (!(yield git_1.isRepoInitialized(this.project.directory))) {
95 return true;
96 }
97 const cmdInstalled = yield this.shell.cmdinfo('git', ['--version']);
98 if (!cmdInstalled) {
99 return true;
100 }
101 const [revListCount, status] = yield Promise.all([
102 this.shell.output('git', ['rev-list', '--count', 'HEAD'], { fatalOnError: false, showCommand: false, showError: false }),
103 this.shell.output('git', ['status', '--porcelain'], { fatalOnError: false, showCommand: false, showError: false }),
104 ]);
105 this.debug('rev-list count: %s, status: %s', revListCount.trim(), status);
106 if (!revListCount) {
107 return true;
108 }
109 const commitCount = Number(revListCount);
110 const changes = Boolean(status);
111 return commitCount === 1 && changes;
112 });
113 }
114 getTreatmentSteps() {
115 return tslib_1.__awaiter(this, void 0, void 0, function* () {
116 return [
117 { message: `Download git if you don't have it installed: ${chalk_1.default.bold('https://git-scm.com/downloads')}` },
118 { message: `Learn the basics if you're unfamiliar with git: ${chalk_1.default.bold('https://try.github.io')}` },
119 { message: `Make your first commit and start tracking code changes! 😍` },
120 ];
121 });
122 }
123}
124exports.GitNotUsed = GitNotUsed;
125class GitConfigInvalid extends base_1.Ailment {
126 constructor() {
127 super(...arguments);
128 this.id = 'git-config-invalid';
129 }
130 getMessage() {
131 return tslib_1.__awaiter(this, void 0, void 0, function* () {
132 const proId = yield this.project.requireProId();
133 return (`App linked to ${chalk_1.default.bold(proId)} with invalid git configuration.\n` +
134 `This app is linked to an app on Ionic (${chalk_1.default.bold(proId)}), but the git configuration is not valid.\n`).trim();
135 });
136 }
137 detected() {
138 return tslib_1.__awaiter(this, void 0, void 0, function* () {
139 const isLoggedIn = this.session.isLoggedIn();
140 if (!isLoggedIn) {
141 return false;
142 }
143 const proId = this.project.config.get('pro_id');
144 if (!proId) {
145 return false;
146 }
147 if (!(yield git_1.isRepoInitialized(this.project.directory))) {
148 return false;
149 }
150 const remote = yield git_1.getIonicRemote({ shell: this.shell }, this.project.directory);
151 if (!remote) {
152 return true;
153 }
154 const token = this.session.getUserToken();
155 const appClient = new app_1.AppClient({ token, client: this.client });
156 const app = yield appClient.load(proId);
157 if (app.repo_url !== remote) {
158 return true;
159 }
160 return false;
161 });
162 }
163 getTreatmentSteps() {
164 return tslib_1.__awaiter(this, void 0, void 0, function* () {
165 return [
166 { message: `Run: ${chalk_1.default.green('ionic git remote')}` },
167 ];
168 });
169 }
170}
171exports.GitConfigInvalid = GitConfigInvalid;
172class IonicNativeOldVersionInstalled extends base_1.Ailment {
173 constructor() {
174 super(...arguments);
175 this.id = 'ionic-native-old-version-installed';
176 }
177 getMessage() {
178 return tslib_1.__awaiter(this, void 0, void 0, function* () {
179 return (`Old version of Ionic Native installed.\n` +
180 `Ionic Native ${chalk_1.default.bold('ionic-native')} has been restructured into individual packages under the ${chalk_1.default.bold('@ionic-native/')} namespace to allow for better bundling and faster apps.\n`).trim();
181 });
182 }
183 detected() {
184 return tslib_1.__awaiter(this, void 0, void 0, function* () {
185 const pkg = yield this.getLocalPackageJson('ionic-native');
186 return pkg !== undefined;
187 });
188 }
189 getTreatmentSteps() {
190 return tslib_1.__awaiter(this, void 0, void 0, function* () {
191 const args = yield npm_1.pkgManagerArgs(this.config.get('npmClient'), { command: 'uninstall', pkg: 'ionic-native' });
192 return [
193 { message: `Run ${chalk_1.default.green(args.join(' '))}` },
194 { message: `Refer to ${chalk_1.default.bold('https://ionicframework.com/docs/native')} for installation & usage instructions` },
195 ];
196 });
197 }
198}
199exports.IonicNativeOldVersionInstalled = IonicNativeOldVersionInstalled;
200class UnsavedCordovaPlatforms extends base_1.Ailment {
201 constructor() {
202 super(...arguments);
203 this.id = 'unsaved-cordova-platforms';
204 }
205 getMessage() {
206 return tslib_1.__awaiter(this, void 0, void 0, function* () {
207 return (`Cordova platforms unsaved.\n` +
208 `There are Cordova platforms installed that are not saved in ${chalk_1.default.bold('config.xml')} or ${chalk_1.default.bold('package.json')}. It is good practice to manage Cordova platforms and their versions. See the Cordova docs${chalk_1.default.cyan('[1]')} for more information.\n\n` +
209 `${chalk_1.default.cyan('[1]')}: ${chalk_1.default.bold('https://cordova.apache.org/docs/en/latest/platform_plugin_versioning_ref/')}\n`).trim();
210 });
211 }
212 detected() {
213 return tslib_1.__awaiter(this, void 0, void 0, function* () {
214 let cordova;
215 try {
216 cordova = yield this.project.getIntegration('cordova');
217 }
218 catch (e) {
219 return false;
220 }
221 const platforms = yield project_1.getPlatforms(cordova.root);
222 const conf = yield config_1.loadConfigXml({ project: this.project });
223 const engines = conf.getPlatformEngines();
224 const engineNames = new Set([...engines.map(e => e.name)]);
225 const configXmlDiff = platforms.filter(p => !engineNames.has(p));
226 return configXmlDiff.length > 0;
227 });
228 }
229 getTreatmentSteps() {
230 return tslib_1.__awaiter(this, void 0, void 0, function* () {
231 return [
232 { message: `Run: ${chalk_1.default.green('ionic cordova platform save')}` },
233 ];
234 });
235 }
236}
237exports.UnsavedCordovaPlatforms = UnsavedCordovaPlatforms;
238class DefaultCordovaBundleIdUsed extends base_1.Ailment {
239 constructor() {
240 super(...arguments);
241 this.id = 'default-cordova-bundle-id-used';
242 }
243 getMessage() {
244 return tslib_1.__awaiter(this, void 0, void 0, function* () {
245 return (`Package ID unchanged in ${chalk_1.default.bold('config.xml')}.\n` +
246 `The Package Identifier (AKA "Bundle ID" for iOS and "Application ID" for Android) is a unique ID (usually written in reverse DNS notation, such as ${chalk_1.default.bold('com.mycompany.MyApp')}) that Cordova uses when compiling the native build of your app. When your app is submitted to the App Store or Play Store, the Package ID can't be changed. This issue was detected because this app's Package ID is ${chalk_1.default.green('"io.ionic.starter"')}, which is the default Package ID provided after running ${chalk_1.default.green('ionic start')}.`).trim();
247 });
248 }
249 detected() {
250 return tslib_1.__awaiter(this, void 0, void 0, function* () {
251 if (!this.project.config.get('integrations').cordova) {
252 return false;
253 }
254 const conf = yield config_1.loadConfigXml({ project: this.project });
255 return conf.getBundleId() === 'io.ionic.starter';
256 });
257 }
258 getTreatmentSteps() {
259 return tslib_1.__awaiter(this, void 0, void 0, function* () {
260 return [
261 { message: `Change the ${chalk_1.default.bold('id')} attribute of ${chalk_1.default.bold('<widget>')} (root element) to something other than ${chalk_1.default.green('"io.ionic.starter"')}` },
262 ];
263 });
264 }
265}
266exports.DefaultCordovaBundleIdUsed = DefaultCordovaBundleIdUsed;
267class ViewportFitNotSet extends base_1.Ailment {
268 constructor() {
269 super(...arguments);
270 this.id = 'viewport-fit-not-set';
271 }
272 getMessage() {
273 return tslib_1.__awaiter(this, void 0, void 0, function* () {
274 return (`${chalk_1.default.bold('viewport-fit=cover')} not set in ${chalk_1.default.bold('index.html')}\n` +
275 `iOS 11 introduces new "safe regions" for webviews, which can throw off component sizing, squish the header into the status bar, letterbox the app on iPhone X, etc. Fixing this issue will ensure the webview takes up the full size of the screen. See ${chalk_1.default.bold('https://blog.ionicframework.com/ios-11-checklist')} for more information.`).trim();
276 });
277 }
278 detected() {
279 return tslib_1.__awaiter(this, void 0, void 0, function* () {
280 const indexHtml = yield utils_fs_1.readFile(path.resolve(yield this.project.getSourceDir(), 'index.html'), { encoding: 'utf8' });
281 const m = indexHtml.match(/\<meta.*viewport-fit=cover/);
282 return !Boolean(m);
283 });
284 }
285 getTreatmentSteps() {
286 return tslib_1.__awaiter(this, void 0, void 0, function* () {
287 return [
288 { message: `Add ${chalk_1.default.bold('viewport-fit=cover')} to the ${chalk_1.default.bold('<meta name="viewport">')} tag in your ${chalk_1.default.bold('index.html')} file` },
289 ];
290 });
291 }
292}
293exports.ViewportFitNotSet = ViewportFitNotSet;
294class CordovaPlatformsCommitted extends base_1.Ailment {
295 constructor() {
296 super(...arguments);
297 this.id = 'cordova-platforms-committed';
298 }
299 getMessage() {
300 return tslib_1.__awaiter(this, void 0, void 0, function* () {
301 return (`Cordova ${chalk_1.default.bold('platforms/')} directory is committed to git.\n` +
302 `Cordova considers ${chalk_1.default.bold('platforms/')} and ${chalk_1.default.bold('plugins/')} build artifacts${chalk_1.default.cyan('[1]')}, and routinely overwrites files.\n\n` +
303 `While committing these files might be necessary for some projects${chalk_1.default.cyan('[2]')}, generally platforms should be configured using ${chalk_1.default.bold('config.xml')} and Cordova hooks${chalk_1.default.cyan('[3]')} so that your project is more portable and SDK updates are easier.\n\n` +
304 `${chalk_1.default.cyan('[1]')}: ${chalk_1.default.bold('https://cordova.apache.org/docs/en/latest/reference/cordova-cli/#version-control')}\n` +
305 `${chalk_1.default.cyan('[2]')}: ${chalk_1.default.bold('https://cordova.apache.org/docs/en/latest/reference/cordova-cli/#platforms')}\n` +
306 `${chalk_1.default.cyan('[3]')}: ${chalk_1.default.bold('https://cordova.apache.org/docs/en/latest/guide/appdev/hooks/index.html')}\n\n` +
307 `${chalk_1.default.yellow(`${chalk_1.default.bold('WARNING')}: Attempting to fix this could be dangerous. Only proceed if you're sure you haven't made manual modifications to these files.`)}\n`).trim();
308 });
309 }
310 detected() {
311 return tslib_1.__awaiter(this, void 0, void 0, function* () {
312 if (!(yield git_1.isRepoInitialized(this.project.directory))) {
313 return false;
314 }
315 const cmdInstalled = yield this.shell.cmdinfo('git', ['--version']);
316 if (!cmdInstalled) {
317 return false;
318 }
319 const files = (yield this.shell.output('git', ['ls-tree', '--name-only', 'HEAD'], { fatalOnError: false, showCommand: false, showError: false })).split('\n');
320 return files.includes('platforms'); // TODO
321 });
322 }
323 getTreatmentSteps() {
324 return tslib_1.__awaiter(this, void 0, void 0, function* () {
325 return [
326 { message: `Remove ${chalk_1.default.bold('platforms/')} from source control: ${chalk_1.default.green('git rm -rf platforms/')} and ${chalk_1.default.green('git commit')}` },
327 { message: `Make sure the ${chalk_1.default.bold('platforms/')} directory has been removed: ${chalk_1.default.green('rm -rf platforms/')}` },
328 { message: `Allow Cordova to repopulate your platforms: ${chalk_1.default.green('ionic cordova prepare')}` },
329 ];
330 });
331 }
332}
333exports.CordovaPlatformsCommitted = CordovaPlatformsCommitted;