@scandipwa/magento-scripts 1.14.1-alpha.10 → 1.14.1-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/lib/commands/logs.js +1 -0
  2. package/lib/commands/start.js +18 -5
  3. package/lib/config/dependencies-for-platforms.js +12 -2
  4. package/lib/config/docker.js +4 -3
  5. package/lib/config/get-port-config.js +2 -1
  6. package/lib/config/index.js +2 -1
  7. package/lib/config/php/extensions/libsodium.js +2 -1
  8. package/lib/config/scandipwa-versions.js +2 -2
  9. package/lib/config/system-config.js +34 -5
  10. package/lib/errors/known-error.js +15 -0
  11. package/lib/errors/unknown-error.js +15 -0
  12. package/lib/tasks/cli/create-bashrc-config.js +2 -1
  13. package/lib/tasks/composer/index.js +5 -3
  14. package/lib/tasks/composer/local-auth-json.js +4 -2
  15. package/lib/tasks/docker/network.js +2 -1
  16. package/lib/tasks/file-system/create-nginx-config.js +2 -1
  17. package/lib/tasks/file-system/create-php-config.js +2 -1
  18. package/lib/tasks/file-system/create-php-fpm-config.js +2 -1
  19. package/lib/tasks/file-system/create-php-storm-config.js +6 -5
  20. package/lib/tasks/file-system/create-ssl-terminator-config.js +5 -3
  21. package/lib/tasks/file-system/create-varnish-config.js +2 -23
  22. package/lib/tasks/file-system/create-vscode-config.js +3 -2
  23. package/lib/tasks/magento/enable-magento-composer-plugins.js +3 -2
  24. package/lib/tasks/magento/install-magento.js +7 -5
  25. package/lib/tasks/magento/setup-magento/flush-redis-config.js +2 -1
  26. package/lib/tasks/magento/setup-magento/index.js +3 -1
  27. package/lib/tasks/magento/setup-magento/install-magento.js +2 -1
  28. package/lib/tasks/magento/setup-magento/upgrade-magento.js +11 -1
  29. package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +41 -0
  30. package/lib/tasks/mysql/connect-to-mysql.js +2 -1
  31. package/lib/tasks/mysql/import-dump-to-mysql.js +4 -2
  32. package/lib/tasks/mysql/import-remote-db/index.js +2 -1
  33. package/lib/tasks/mysql/import-remote-db/ssh/index.js +2 -1
  34. package/lib/tasks/mysql/import-remote-db/ssh/regular-server.js +2 -1
  35. package/lib/tasks/php/bundled-extensions.js +28 -0
  36. package/lib/tasks/php/compile-options.js +18 -48
  37. package/lib/tasks/php/compile.js +4 -3
  38. package/lib/tasks/php/configure.js +7 -66
  39. package/lib/tasks/php/extensions/index.js +71 -0
  40. package/lib/tasks/php/index.js +7 -6
  41. package/lib/tasks/php/update-phpbrew.js +2 -1
  42. package/lib/tasks/php/validate-php.js +67 -0
  43. package/lib/tasks/php-fpm/start-php-fpm.js +2 -1
  44. package/lib/tasks/requirements/composer.js +5 -3
  45. package/lib/tasks/requirements/dependency/arch.js +2 -1
  46. package/lib/tasks/requirements/dependency/centos.js +2 -1
  47. package/lib/tasks/requirements/dependency/fedora.js +2 -1
  48. package/lib/tasks/requirements/docker/index.js +5 -4
  49. package/lib/tasks/requirements/docker/install.js +2 -1
  50. package/lib/tasks/requirements/docker/running-status.js +3 -2
  51. package/lib/tasks/requirements/docker/version.js +2 -1
  52. package/lib/tasks/requirements/node-version.js +2 -1
  53. package/lib/tasks/requirements/php-version.js +5 -3
  54. package/lib/tasks/requirements/phpbrew/index.js +2 -1
  55. package/lib/tasks/requirements/phpbrew/install.js +2 -1
  56. package/lib/tasks/requirements/phpbrew/version.js +2 -1
  57. package/lib/tasks/requirements/platform.js +3 -2
  58. package/lib/tasks/start.js +3 -1
  59. package/lib/tasks/theme/build-theme.js +2 -1
  60. package/lib/tasks/theme/install-theme.js +2 -1
  61. package/lib/tasks/theme/retrieve-theme-data.js +2 -1
  62. package/lib/tasks/theme/setup-persisted-query.js +2 -1
  63. package/lib/tasks/theme/setup-themes.js +2 -1
  64. package/lib/tasks/theme/symlink-theme.js +2 -1
  65. package/lib/util/analytics.js +337 -0
  66. package/lib/util/config-file-validator.js +2 -1
  67. package/lib/util/config-php-json.js +3 -2
  68. package/lib/util/env-php-json.js +3 -2
  69. package/lib/util/get-installed-magento-version.js +3 -2
  70. package/lib/util/get-jsonfile-data.js +2 -1
  71. package/lib/util/install-dependencies-task.js +4 -4
  72. package/lib/util/instance-metadata.js +2 -1
  73. package/lib/util/ip.js +45 -1
  74. package/lib/util/magento-task.js +20 -9
  75. package/lib/util/request.js +0 -0
  76. package/lib/util/resolve-configuration-with-overrides.js +2 -1
  77. package/lib/util/run-composer.js +3 -2
  78. package/lib/util/run-magento.js +3 -2
  79. package/lib/util/run-php.js +3 -2
  80. package/lib/util/wait-for-it.js +3 -2
  81. package/package.json +4 -3
@@ -0,0 +1,337 @@
1
+ const os = require('os');
2
+ const { request } = require('smol-request');
3
+ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
4
+ const generateUUID = require('@tilework/mosaic-dev-utils/uuid');
5
+ const { getSystemConfigSync } = require('../config/system-config');
6
+ const { getExternalIpAddress } = require('./ip');
7
+ const pkg = require('../../package.json');
8
+
9
+ const GA_TRACKING_ID = process.env.GA_TRACKING_ID || 'UA-127741417-8';
10
+ const UNKNOWN = 'unknown';
11
+
12
+ const anonymizeError = (text) => text.replace(new RegExp(`${os.homedir()}`, 'gi'), '/home/magento-scripts-user');
13
+
14
+ /**
15
+ * Google Analytics Parameters
16
+ * @typedef {Object} GAParameters
17
+ * @property {String} version
18
+ * @property {String} trackingID
19
+ * @property {String} [dataSource]
20
+ * @property {Object} [user]
21
+ * @property {String} [user.clientID]
22
+ * @property {String} [user.userID]
23
+ * @property {Object} [session]
24
+ * @property {String} [session.sessionControl]
25
+ * @property {String} [session.ipOverride]
26
+ * @property {String} [session.userAgentOverride]
27
+ * @property {Object} [systemInfo]
28
+ * @property {String} [systemInfo.userLanguage]
29
+ * @property {Object} [contentInformation]
30
+ * @property {String} [contentInformation.documentLocationUrl]
31
+ * @property {String} [contentInformation.documentPath]
32
+ * @property {String} [contentInformation.documentHostName]
33
+ * @property {Object} [timing]
34
+ * @property {String} [timing.userTimingCategory]
35
+ * @property {String} [timing.userTimingVariableName]
36
+ * @property {String} [timing.userTimingTime]
37
+ * @property {String} [timing.userTimingLabel]
38
+ * @property {Object} [hit]
39
+ * @property {String} [hit.type]
40
+ * @property {Object} [exception]
41
+ * @property {String} [exception.description]
42
+ * @property {Boolean} [exception.fatal]
43
+ * @property {Object} [event]
44
+ * @property {String} event.category
45
+ * @property {String} event.action
46
+ * @property {String} [event.label]
47
+ * @property {String} [event.value]
48
+ * @property {Object} [app]
49
+ * @property {String} [app.name]
50
+ * @property {String} [app.id]
51
+ * @property {String} [app.version]
52
+ * @property {String} [app.installedID]
53
+ * @property {Record<string, string>} [customDimension]
54
+ */
55
+
56
+ /**
57
+ * @type {GAParameters}
58
+ */
59
+ const gaParametersMapping = {
60
+ version: 'v',
61
+ trackingID: 'tid',
62
+ user: {
63
+ clientID: 'cid',
64
+ userID: 'uid'
65
+ },
66
+ session: {
67
+ sessionControl: 'sc',
68
+ ipOverride: 'uip',
69
+ userAgentOverride: 'ua'
70
+ },
71
+ systemInfo: {
72
+ userLanguage: 'ul'
73
+ },
74
+ contentInformation: {
75
+ documentLocationUrl: 'dl',
76
+ documentPath: 'dp',
77
+ documentHostName: 'dh'
78
+ },
79
+ timing: {
80
+ userTimingCategory: 'utc',
81
+ userTimingVariableName: 'utv',
82
+ userTimingTime: 'utt',
83
+ userTimingLabel: 'utl'
84
+ },
85
+ hit: {
86
+ type: 't'
87
+ },
88
+ exception: {
89
+ description: 'exd',
90
+ fatal: 'exf'
91
+ },
92
+ event: {
93
+ category: 'ec',
94
+ action: 'ea',
95
+ label: 'el',
96
+ value: 'ev'
97
+ },
98
+ app: {
99
+ name: 'an',
100
+ id: 'aid',
101
+ version: 'av',
102
+ installedID: 'aiid'
103
+ },
104
+ customDimension: Array.from({ length: 200 }, (_, i) => i + 1).reduce((acc, val) => ({
105
+ ...acc,
106
+ [`customDimension${val}`]: `cd${val}`
107
+ }), {})
108
+ };
109
+
110
+ const getAppData = () => ({
111
+ name: pkg.name,
112
+ version: pkg.version
113
+ });
114
+
115
+ /**
116
+ * @param {GAParameters} parameters
117
+ */
118
+ const collectAnalyticsParameters = (parameters) => {
119
+ const parsedParameters = {};
120
+
121
+ for (const [firstLevelKey, firstLevelValue] of Object.entries(gaParametersMapping)) {
122
+ if (typeof firstLevelValue === 'object' && firstLevelValue !== null) {
123
+ for (const [secondLevelKey, secondLevelValue] of Object.entries(firstLevelValue)) {
124
+ if (parameters[firstLevelKey] && parameters[firstLevelKey][secondLevelKey]) {
125
+ parsedParameters[secondLevelValue] = parameters[firstLevelKey][secondLevelKey];
126
+ }
127
+ }
128
+ } else if (parameters[firstLevelKey]) {
129
+ parsedParameters[firstLevelValue] = parameters[firstLevelKey];
130
+ }
131
+ }
132
+
133
+ return parsedParameters;
134
+ };
135
+
136
+ class Analytics {
137
+ constructor() {
138
+ this.isGaDisabled = this.getIsGaDisabled();
139
+ this.gaTrackingId = GA_TRACKING_ID;
140
+ this.clientIdentifier = UNKNOWN;
141
+ this.currentUrl = UNKNOWN;
142
+ this.lang = UNKNOWN;
143
+
144
+ try {
145
+ this.setClientIdentifier(
146
+ generateUUID()
147
+ );
148
+ } catch (e) {
149
+ this.setClientIdentifier(
150
+ Date.now()
151
+ );
152
+ }
153
+ }
154
+
155
+ setLang(lang) {
156
+ this.lang = lang;
157
+ }
158
+
159
+ setCurrentUrl(currentUrl) {
160
+ this.currentUrl = currentUrl;
161
+ }
162
+
163
+ setClientIdentifier(id) {
164
+ this.clientIdentifier = id;
165
+ }
166
+
167
+ setGaTrackingId(id) {
168
+ this.gaTrackingId = id;
169
+ }
170
+
171
+ getIsGaDisabled() {
172
+ const { analytics } = getSystemConfigSync({ validate: false });
173
+
174
+ return !analytics;
175
+ }
176
+
177
+ /**
178
+ * @param {GAParameters} data
179
+ */
180
+ async _collect(data) {
181
+ if (this.isGaDisabled) {
182
+ // skip GA
183
+ return;
184
+ }
185
+
186
+ /**
187
+ * @type {GAParameters}
188
+ */
189
+ const analyticsParameters = {
190
+ ...data,
191
+ version: '1',
192
+ trackingID: this.gaTrackingId,
193
+ user: {
194
+ clientID: this.clientIdentifier
195
+ },
196
+ app: getAppData()
197
+ };
198
+
199
+ try {
200
+ analyticsParameters.systemInfo = {
201
+ ipOverride: await getExternalIpAddress()
202
+ };
203
+ } catch (e) {
204
+ console.log(e);
205
+ // Do nothing
206
+ }
207
+
208
+ if (this.lang !== UNKNOWN) {
209
+ // get system language here
210
+ analyticsParameters.systemInfo = {
211
+ userLanguage: this.lang
212
+ };
213
+ }
214
+
215
+ if (this.currentUrl !== UNKNOWN) {
216
+ const {
217
+ hostname,
218
+ pathname
219
+ } = new URL(this.currentUrl);
220
+
221
+ analyticsParameters.contentInformation = {
222
+ documentLocationUrl: this.currentUrl,
223
+ documentPath: pathname,
224
+ documentHostName: hostname
225
+ };
226
+ }
227
+
228
+ const params = new URLSearchParams(collectAnalyticsParameters(analyticsParameters)).toString();
229
+
230
+ try {
231
+ if (!process.env.GA_DEBUG) {
232
+ await request(
233
+ `https://www.google-analytics.com/collect?${ params }`,
234
+ {
235
+ headers: { 'User-Agent': 'Google-Cloud-Functions' },
236
+ responseType: 'headers'
237
+ }
238
+ );
239
+
240
+ return;
241
+ }
242
+
243
+ const { data: jsonResponse } = await request(
244
+ `https://www.google-analytics.com/debug/collect?${ params }`,
245
+ {
246
+ headers: { 'User-Agent': 'Google-Cloud-Functions' },
247
+ responseType: 'json'
248
+ }
249
+ );
250
+
251
+ logger.log(analyticsParameters);
252
+ logger.log(JSON.stringify(jsonResponse, null, 2));
253
+
254
+ // eslint-disable-next-line no-empty
255
+ } catch (e) {
256
+ console.log('Failed to report telemetry data');
257
+ }
258
+ }
259
+
260
+ trackError(error, isFatal = true) {
261
+ // return; // nothing
262
+ return this._collect({
263
+ hit: {
264
+ type: 'exception'
265
+ },
266
+ exception: {
267
+ description: anonymizeError(typeof error === 'string' ? error : error.message),
268
+ fatal: isFatal
269
+ }
270
+ });
271
+ // return this._collect({
272
+ // t: 'exception',
273
+ // exd: anonymizeError(typeof error === 'string' ? error : error.message),
274
+ // exf: isFatal
275
+ // });
276
+ }
277
+
278
+ trackTiming(label, time, category = UNKNOWN) {
279
+ return this._collect({
280
+ hit: {
281
+ type: 'timing'
282
+ },
283
+ timing: {
284
+ userTimingCategory: category,
285
+ userTimingVariableName: label,
286
+ userTimingLabel: this.currentUrl,
287
+ userTimingTime: Math.round(time)
288
+ }
289
+ });
290
+ // return this._collect({
291
+ // t: 'timing',
292
+ // utc: category,
293
+ // utv: label,
294
+ // utl: this.currentUrl,
295
+ // utt: Math.round(time)
296
+ // });
297
+ }
298
+
299
+ trackPageView() {
300
+ return this._collect({
301
+ hit: {
302
+ type: 'pageview'
303
+ }
304
+ });
305
+ }
306
+
307
+ trackEvent(action, label, value, category = UNKNOWN) {
308
+ return this._collect({
309
+ hit: {
310
+ type: 'event'
311
+ },
312
+ event: {
313
+ category,
314
+ action,
315
+ label,
316
+ value
317
+ }
318
+ });
319
+ // return this._collect({
320
+ // t: 'event',
321
+ // ec: category,
322
+ // ea: action,
323
+ // el: label,
324
+ // ev: value
325
+ // });
326
+ }
327
+
328
+ printAboutAnalytics() {
329
+ if (!this.isGaDisabled) {
330
+ logger.log('We collect analytics data to make our products more stable and reliable!');
331
+ logger.log('If you want to know more go here https://docs.scandipwa.com/about/data-analytics');
332
+ logger.logN();
333
+ }
334
+ }
335
+ }
336
+
337
+ module.exports = new Analytics();
@@ -1,12 +1,13 @@
1
1
  const Joi = require('joi');
2
2
  const semver = require('semver');
3
+ const KnownError = require('../errors/known-error');
3
4
  const pathExistsSync = require('./path-exists-sync');
4
5
 
5
6
  const fileExistsValidator = (value) => {
6
7
  const fileExists = pathExistsSync(value);
7
8
 
8
9
  if (!fileExists) {
9
- throw new Error(`File "${value}" does not exists!`);
10
+ throw new KnownError(`File "${value}" does not exists!`);
10
11
  }
11
12
 
12
13
  return undefined;
@@ -1,4 +1,5 @@
1
1
  const path = require('path');
2
+ const UnknownError = require('../errors/unknown-error');
2
3
  const runPhpCode = require('./run-php');
3
4
 
4
5
  const configPhpToJson = async (projectPath = process.cwd(), { magentoVersion }) => {
@@ -7,12 +8,12 @@ const configPhpToJson = async (projectPath = process.cwd(), { magentoVersion })
7
8
  });
8
9
 
9
10
  if (code !== 0) {
10
- throw new Error(result);
11
+ throw new UnknownError(`Received non-zero code during converting app/etc/config.php to json:\n\n${result}`);
11
12
  }
12
13
  try {
13
14
  return JSON.parse(result);
14
15
  } catch (e) {
15
- throw new Error(`Ooops! Something went wrong when trying to parse app/etc/config.php file!\n\n${e}\n\nFile result: ${result}`);
16
+ throw new UnknownError(`Ooops! Something went wrong when trying to parse app/etc/config.php file!\n\n${e}\n\nFile result: ${result}`);
16
17
  }
17
18
  };
18
19
 
@@ -1,4 +1,5 @@
1
1
  const path = require('path');
2
+ const UnknownError = require('../errors/unknown-error');
2
3
  const runPhpCode = require('./run-php');
3
4
 
4
5
  const envPhpToJson = async (projectPath = process.cwd(), { magentoVersion }) => {
@@ -7,12 +8,12 @@ const envPhpToJson = async (projectPath = process.cwd(), { magentoVersion }) =>
7
8
  });
8
9
 
9
10
  if (code !== 0) {
10
- throw new Error(result);
11
+ throw new UnknownError(`Received non-zero code during converting app/etc/env.php to json:\n\n${result}`);
11
12
  }
12
13
  try {
13
14
  return JSON.parse(result);
14
15
  } catch (e) {
15
- throw new Error(`Ooops! Something went wrong when trying to parse app/etc/env.php file!\n\n${e}\n\nFile result: ${result}`);
16
+ throw new UnknownError(`Ooops! Something went wrong when trying to parse app/etc/env.php file!\n\n${e}\n\nFile result: ${result}`);
16
17
  }
17
18
  };
18
19
 
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const KnownError = require('../errors/known-error');
3
4
  const pathExists = require('./path-exists');
4
5
 
5
6
  const getComposerData = async (composerPath) => {
@@ -16,7 +17,7 @@ const getInstalledMagentoVersion = async (projectPath = process.cwd()) => {
16
17
  const composerData = await getComposerData(path.join(projectPath, 'composer.json'));
17
18
 
18
19
  if (!composerData) {
19
- throw new Error('composer.json not found');
20
+ throw new KnownError('composer.json not found');
20
21
  }
21
22
  const magentoDependency = [
22
23
  'magento/product-community-edition',
@@ -24,7 +25,7 @@ const getInstalledMagentoVersion = async (projectPath = process.cwd()) => {
24
25
  ].find((magentoEdition) => composerData.require[magentoEdition]);
25
26
 
26
27
  if (!magentoDependency) {
27
- throw new Error('No Magento dependency found in composer.json');
28
+ throw new KnownError('No Magento dependency found in composer.json');
28
29
  }
29
30
 
30
31
  return composerData.require[magentoDependency].replace(/\^/i, '');
@@ -1,4 +1,5 @@
1
1
  const fs = require('fs');
2
+ const UnknownError = require('../errors/unknown-error');
2
3
  const pathExists = require('./path-exists');
3
4
 
4
5
  const getJsonfileData = async (filePath) => {
@@ -11,7 +12,7 @@ const getJsonfileData = async (filePath) => {
11
12
  try {
12
13
  return JSON.parse(await fs.promises.readFile(filePath, 'utf-8'));
13
14
  } catch (e) {
14
- throw new Error(`Ooops! Something went wrong when trying to json parse ${filePath} file!\n\n${e}`);
15
+ throw new UnknownError(`Ooops! Something went wrong when trying to json parse ${filePath} file!\n\n${e}`);
15
16
  }
16
17
  };
17
18
 
@@ -3,6 +3,7 @@ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
3
3
  const sleep = require('./sleep');
4
4
  const { execCommandTask } = require('./exec-async-command');
5
5
  const dependenciesForPlatforms = require('../config/dependencies-for-platforms');
6
+ const KnownError = require('../errors/known-error');
6
7
 
7
8
  /**
8
9
  * Install dependencies
@@ -56,15 +57,14 @@ const installDependenciesTask = (options) => ({
56
57
  promptSkipper = true;
57
58
 
58
59
  if (installAnswer === 'timeout') {
59
- throw new Error(`Timeout!
60
+ throw new KnownError(`Timeout!
60
61
 
61
62
  To install missing ${ dependenciesWordFormatter } manually, run the following command: ${ installCommand }`);
62
63
  }
63
64
 
64
65
  if (installAnswer === 'not-install') {
65
- throw new Error(`Okay, skipping ${ dependenciesWordFormatter } installation for now.
66
-
67
- To install missing ${ dependenciesWordFormatter } manually, run the following command: ${ installCommand }`);
66
+ task.skip(`User chose to skip installation of ${ dependenciesWordFormatter }`);
67
+ return;
68
68
  }
69
69
 
70
70
  if (installAnswer === 'install') {
@@ -7,7 +7,8 @@ const WEB_ADMIN_CREDENTIALS_TITLE = 'Panel credentials';
7
7
 
8
8
  const mapDataStyle = ({ title, text }) => ({
9
9
  title,
10
- text: logger.style.link(text)
10
+ text: logger.style.link(text),
11
+ link: text
11
12
  });
12
13
 
13
14
  /**
package/lib/util/ip.js CHANGED
@@ -1,8 +1,52 @@
1
+ const { request } = require('smol-request');
2
+
1
3
  const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
2
4
 
3
5
  const isIpAddress = (text) => ipRegex.test(text);
4
6
 
7
+ const externalIpProviders = [
8
+ 'http://api.ipify.org/',
9
+ 'http://icanhazip.com/',
10
+ 'http://ifconfig.io/ip',
11
+ 'http://ip.appspot.com/',
12
+ 'http://ident.me/',
13
+ 'http://whatismyip.akamai.com/',
14
+ 'http://tnx.nl/ip',
15
+ 'http://myip.dnsomatic.com/',
16
+ 'http://ipecho.net/plain',
17
+ 'http://diagnostic.opendns.com/myip',
18
+ 'http://trackip.net/ip'
19
+ ];
20
+
21
+ /**
22
+ * Get an external IP address
23
+ * @returns {Promise<string>}
24
+ */
25
+ const getExternalIpAddress = async () => {
26
+ let ip;
27
+
28
+ for (const ipProvider of externalIpProviders) {
29
+ try {
30
+ const response = await request(ipProvider, {
31
+ responseType: 'text'
32
+ });
33
+
34
+ ip = response.data;
35
+ break;
36
+ } catch (e) {
37
+ //
38
+ }
39
+ }
40
+
41
+ if (!ip) {
42
+ throw new Error('External IP address is not available!');
43
+ }
44
+
45
+ return ip;
46
+ };
47
+
5
48
  module.exports = {
6
49
  ipRegex,
7
- isIpAddress
50
+ isIpAddress,
51
+ getExternalIpAddress
8
52
  };
@@ -1,17 +1,28 @@
1
1
  const runMagentoCommand = require('./run-magento');
2
2
 
3
3
  /**
4
- * @type {(command: string) => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
4
+ * @param {String} command
5
+ * @param {Object} [options]
6
+ * @param {(e: Error) => void} [options.onError]
7
+ * @returns {import('listr2').ListrTask<import('../../typings/context').ListrContext>}
5
8
  */
6
- const magentoTask = (command) => ({
9
+ const magentoTask = (command, options = {}) => ({
7
10
  title: `Running command 'magento ${command}'`,
8
- task: ({ magentoVersion, verbose }, task) => runMagentoCommand(command, {
9
- callback: !verbose ? undefined : (t) => {
10
- task.output = t;
11
- },
12
- magentoVersion,
13
- throwNonZeroCode: true
14
- }),
11
+ task: async ({ magentoVersion, verbose }, task) => {
12
+ try {
13
+ await runMagentoCommand(command, {
14
+ callback: !verbose ? undefined : (t) => {
15
+ task.output = t;
16
+ },
17
+ magentoVersion,
18
+ throwNonZeroCode: true
19
+ });
20
+ } catch (e) {
21
+ if (options.onError) {
22
+ options.onError(e);
23
+ }
24
+ }
25
+ },
15
26
  options: {
16
27
  bottomBar: 10
17
28
  }
File without changes
@@ -1,4 +1,5 @@
1
1
  const path = require('path');
2
+ const UnknownError = require('../errors/unknown-error');
2
3
  const { configFileSchema } = require('./config-file-validator');
3
4
  const { deepmerge } = require('./deepmerge');
4
5
  const pathExists = require('./path-exists');
@@ -11,7 +12,7 @@ const resolveConfigurationWithOverrides = async (configuration, baseConfig, proj
11
12
  try {
12
13
  await configFileSchema.validateAsync(userConfiguration);
13
14
  } catch (e) {
14
- throw new Error(`Configuration file validation error!\n\n${e.message}`);
15
+ throw new UnknownError(`Configuration file validation error!\n\n${e.message}`);
15
16
  }
16
17
 
17
18
  const overridenConfiguration = deepmerge(configuration, userConfiguration);
@@ -1,5 +1,6 @@
1
1
  const { execAsyncSpawn } = require('./exec-async-command');
2
2
  const { getConfigFromMagentoVersion, defaultConfiguration } = require('../config');
3
+ const UnknownError = require('../errors/unknown-error');
3
4
  /**
4
5
  * Execute composer command
5
6
  * @param {String} command composer command
@@ -24,8 +25,8 @@ const runComposerCommand = async (command, options = {}) => {
24
25
  });
25
26
 
26
27
  if (throwNonZeroCode && code !== 0) {
27
- throw new Error(`Code: ${code}
28
- Response: ${result}`);
28
+ throw new UnknownError(`Code: ${code}
29
+ Response: ${result}`);
29
30
  }
30
31
 
31
32
  return { code, result };
@@ -1,5 +1,6 @@
1
1
  const { execAsyncSpawn } = require('./exec-async-command');
2
2
  const { getConfigFromMagentoVersion, defaultConfiguration, magento } = require('../config');
3
+ const UnknownError = require('../errors/unknown-error');
3
4
  /**
4
5
  * Execute magento command
5
6
  * @param {String} command magento command
@@ -27,8 +28,8 @@ const runMagentoCommand = async (command, options = {}) => {
27
28
  });
28
29
 
29
30
  if (throwNonZeroCode && code !== 0) {
30
- throw new Error(`Code: ${code}
31
- Response: ${result}`);
31
+ throw new UnknownError(`Code: ${code}
32
+ Response: ${result}`);
32
33
  }
33
34
 
34
35
  return { code, result };
@@ -1,5 +1,6 @@
1
1
  const { execAsyncSpawn } = require('./exec-async-command');
2
2
  const { getConfigFromMagentoVersion, defaultConfiguration } = require('../config');
3
+ const UnknownError = require('../errors/unknown-error');
3
4
  /**
4
5
  * Execute PHP code
5
6
  * @param {String} command magento command
@@ -29,8 +30,8 @@ const runPhpCode = async (command, options = {}) => {
29
30
  });
30
31
 
31
32
  if (throwNonZeroCode && code !== 0) {
32
- throw new Error(`Code: ${code}
33
- Response: ${result}`);
33
+ throw new UnknownError(`Code: ${code}
34
+ Response: ${result}`);
34
35
  }
35
36
 
36
37
  return { code, result };
@@ -1,4 +1,5 @@
1
1
  const net = require('net');
2
+ const UnknownError = require('../errors/unknown-error');
2
3
  const sleep = require('./sleep');
3
4
 
4
5
  const connectToHostPort = ({ host, port }) => new Promise((resolve, reject) => {
@@ -14,7 +15,7 @@ const connectToHostPort = ({ host, port }) => new Promise((resolve, reject) => {
14
15
  });
15
16
  socket.on('timeout', () => {
16
17
  socket.end();
17
- reject(new Error('Connection timeout'));
18
+ reject(new UnknownError('Connection timeout'));
18
19
  });
19
20
  });
20
21
 
@@ -29,7 +30,7 @@ const waitForIt = async ({
29
30
  // eslint-disable-next-line no-await-in-loop
30
31
  await Promise.race([
31
32
  sleep(300).then(() => {
32
- throw new Error('Connection timeout');
33
+ throw new UnknownError('Connection timeout');
33
34
  }),
34
35
  connectToHostPort({ host, port })
35
36
  ]);