@automattic/vip 2.9.5 → 2.11.2

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 (115) hide show
  1. package/CONTRIBUTING.md +2 -11
  2. package/README.md +26 -0
  3. package/dist/bin/vip-dev-env-create.js +9 -1
  4. package/dist/bin/vip-dev-env-destroy.js +7 -7
  5. package/dist/bin/vip-dev-env-exec.js +7 -1
  6. package/dist/bin/vip-dev-env-import-media.js +7 -1
  7. package/dist/bin/vip-dev-env-import-sql.js +7 -1
  8. package/dist/bin/vip-dev-env-info.js +10 -1
  9. package/dist/bin/vip-dev-env-list.js +10 -1
  10. package/dist/bin/vip-dev-env-start.js +14 -3
  11. package/dist/bin/vip-dev-env-stop.js +7 -1
  12. package/dist/bin/vip-dev-env-update.js +8 -2
  13. package/dist/bin/vip-import-sql.js +7 -1
  14. package/dist/lib/analytics/clients/pendo.js +92 -0
  15. package/dist/lib/analytics/index.js +8 -3
  16. package/dist/lib/dev-environment/dev-environment-cli.js +56 -1
  17. package/dist/lib/dev-environment/dev-environment-core.js +4 -2
  18. package/dist/lib/dev-environment/dev-environment-lando.js +35 -3
  19. package/dist/lib/tracker.js +15 -7
  20. package/npm-shrinkwrap.json +1 -1
  21. package/package/dist/bin/vip-app-list.js +73 -0
  22. package/package/dist/bin/vip-app.js +76 -0
  23. package/package/dist/bin/vip-config-envvar-delete.js +97 -0
  24. package/package/dist/bin/vip-config-envvar-get-all.js +94 -0
  25. package/package/dist/bin/vip-config-envvar-get.js +79 -0
  26. package/package/dist/bin/vip-config-envvar-list.js +91 -0
  27. package/package/dist/bin/vip-config-envvar-set.js +123 -0
  28. package/package/dist/bin/vip-config-envvar.js +23 -0
  29. package/package/dist/bin/vip-config.js +20 -0
  30. package/package/dist/bin/vip-dev-env-create.js +105 -0
  31. package/package/dist/bin/vip-dev-env-destroy.js +56 -0
  32. package/package/dist/bin/vip-dev-env-exec.js +67 -0
  33. package/package/dist/bin/vip-dev-env-import-media.js +51 -0
  34. package/package/dist/bin/vip-dev-env-import-sql.js +83 -0
  35. package/package/dist/bin/vip-dev-env-import.js +32 -0
  36. package/package/dist/bin/vip-dev-env-info.js +61 -0
  37. package/package/dist/bin/vip-dev-env-list.js +46 -0
  38. package/package/dist/bin/vip-dev-env-start.js +77 -0
  39. package/package/dist/bin/vip-dev-env-stop.js +52 -0
  40. package/package/dist/bin/vip-dev-env-update.js +89 -0
  41. package/package/dist/bin/vip-dev-env.js +23 -0
  42. package/package/dist/bin/vip-import-media-abort.js +132 -0
  43. package/package/dist/bin/vip-import-media-status.js +84 -0
  44. package/package/dist/bin/vip-import-media.js +168 -0
  45. package/package/dist/bin/vip-import-sql-status.js +83 -0
  46. package/package/dist/bin/vip-import-sql.js +580 -0
  47. package/package/dist/bin/vip-import-validate-files.js +191 -0
  48. package/package/dist/bin/vip-import-validate-sql.js +34 -0
  49. package/package/dist/bin/vip-import.js +20 -0
  50. package/package/dist/bin/vip-logs.js +232 -0
  51. package/package/dist/bin/vip-search-replace.js +71 -0
  52. package/package/dist/bin/vip-sync.js +191 -0
  53. package/package/dist/bin/vip-whoami.js +67 -0
  54. package/package/dist/bin/vip-wp.js +555 -0
  55. package/package/dist/bin/vip.js +149 -0
  56. package/package/dist/lib/analytics/clients/client.js +1 -0
  57. package/package/dist/lib/analytics/clients/pendo.js +92 -0
  58. package/package/dist/lib/analytics/clients/stub.js +19 -0
  59. package/package/dist/lib/analytics/clients/tracks.js +128 -0
  60. package/package/dist/lib/analytics/index.js +45 -0
  61. package/package/dist/lib/api/app.js +70 -0
  62. package/package/dist/lib/api/feature-flags.js +39 -0
  63. package/package/dist/lib/api/user.js +58 -0
  64. package/package/dist/lib/api.js +136 -0
  65. package/package/dist/lib/app-logs/app-logs.js +70 -0
  66. package/package/dist/lib/cli/apiConfig.js +90 -0
  67. package/package/dist/lib/cli/command.js +606 -0
  68. package/package/dist/lib/cli/envAlias.js +60 -0
  69. package/package/dist/lib/cli/exit.js +33 -0
  70. package/package/dist/lib/cli/format.js +213 -0
  71. package/package/dist/lib/cli/pager.js +52 -0
  72. package/package/dist/lib/cli/progress.js +208 -0
  73. package/package/dist/lib/cli/prompt.js +37 -0
  74. package/package/dist/lib/cli/repo.js +77 -0
  75. package/package/dist/lib/client-file-uploader.js +602 -0
  76. package/package/dist/lib/constants/dev-environment.js +42 -0
  77. package/package/dist/lib/constants/file-size.js +14 -0
  78. package/package/dist/lib/dev-environment/dev-environment-cli.js +508 -0
  79. package/package/dist/lib/dev-environment/dev-environment-core.js +620 -0
  80. package/package/dist/lib/dev-environment/dev-environment-lando.js +330 -0
  81. package/package/dist/lib/dev-environment/types.js +1 -0
  82. package/package/dist/lib/env.js +36 -0
  83. package/package/dist/lib/envvar/api-delete.js +56 -0
  84. package/package/dist/lib/envvar/api-get-all.js +59 -0
  85. package/package/dist/lib/envvar/api-get.js +24 -0
  86. package/package/dist/lib/envvar/api-list.js +60 -0
  87. package/package/dist/lib/envvar/api-set.js +58 -0
  88. package/package/dist/lib/envvar/api.js +104 -0
  89. package/package/dist/lib/envvar/input.js +55 -0
  90. package/package/dist/lib/envvar/logging.js +33 -0
  91. package/package/dist/lib/envvar/read-file.js +43 -0
  92. package/package/dist/lib/http/socks-proxy-agent.js +25 -0
  93. package/package/dist/lib/keychain/browser.js +35 -0
  94. package/package/dist/lib/keychain/insecure.js +63 -0
  95. package/package/dist/lib/keychain/keychain.js +1 -0
  96. package/package/dist/lib/keychain/secure.js +36 -0
  97. package/package/dist/lib/keychain.js +36 -0
  98. package/package/dist/lib/media-import/media-file-import.js +34 -0
  99. package/package/dist/lib/media-import/progress.js +86 -0
  100. package/package/dist/lib/media-import/status.js +335 -0
  101. package/package/dist/lib/rollbar.js +35 -0
  102. package/package/dist/lib/search-and-replace.js +203 -0
  103. package/package/dist/lib/site-import/db-file-import.js +46 -0
  104. package/package/dist/lib/site-import/status.js +444 -0
  105. package/package/dist/lib/token.js +132 -0
  106. package/package/dist/lib/tracker.js +96 -0
  107. package/package/dist/lib/validations/is-multi-site-sql-dump.js +59 -0
  108. package/package/dist/lib/validations/is-multi-site.js +99 -0
  109. package/package/dist/lib/validations/line-by-line.js +92 -0
  110. package/package/dist/lib/validations/site-type.js +66 -0
  111. package/package/dist/lib/validations/sql.js +371 -0
  112. package/package/dist/lib/vip-import-validate-files.js +548 -0
  113. package/package/vip.iml +11 -0
  114. package/package.json +1 -1
  115. package/vip.iml +11 -0
@@ -0,0 +1,508 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.handleCLIException = handleCLIException;
7
+ exports.getEnvironmentName = getEnvironmentName;
8
+ exports.getEnvironmentStartCommand = getEnvironmentStartCommand;
9
+ exports.printTable = printTable;
10
+ exports.processComponentOptionInput = processComponentOptionInput;
11
+ exports.getOptionsFromAppInfo = getOptionsFromAppInfo;
12
+ exports.promptForArguments = promptForArguments;
13
+ exports.resolvePath = resolvePath;
14
+ exports.promptForText = promptForText;
15
+ exports.promptForBoolean = promptForBoolean;
16
+ exports.promptForPhpVersion = promptForPhpVersion;
17
+ exports.promptForComponent = promptForComponent;
18
+ exports.addDevEnvConfigurationOptions = addDevEnvConfigurationOptions;
19
+ exports.getTagChoices = getTagChoices;
20
+ exports.getEnvTrackingInfo = getEnvTrackingInfo;
21
+ exports.validateDependencies = void 0;
22
+
23
+ var _chalk = _interopRequireDefault(require("chalk"));
24
+
25
+ var _formatters = _interopRequireDefault(require("lando/lib/formatters"));
26
+
27
+ var _enquirer = require("enquirer");
28
+
29
+ var _debug = _interopRequireDefault(require("debug"));
30
+
31
+ var _fs = _interopRequireDefault(require("fs"));
32
+
33
+ var _path = _interopRequireDefault(require("path"));
34
+
35
+ var _os = _interopRequireDefault(require("os"));
36
+
37
+ var exit = _interopRequireWildcard(require("../cli/exit"));
38
+
39
+ var _tracker = require("../tracker");
40
+
41
+ var _devEnvironment = require("../constants/dev-environment");
42
+
43
+ var _devEnvironmentCore = require("./dev-environment-core");
44
+
45
+ var _devEnvironmentLando = require("./dev-environment-lando");
46
+
47
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
48
+
49
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
50
+
51
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
52
+
53
+ /**
54
+ *
55
+ * @format
56
+ */
57
+
58
+ /**
59
+ * External dependencies
60
+ */
61
+
62
+ /**
63
+ * Internal dependencies
64
+ */
65
+ const debug = (0, _debug.default)('@automattic/vip:bin:dev-environment');
66
+ const DEFAULT_SLUG = 'vip-local';
67
+
68
+ async function handleCLIException(exception, trackKey, trackBaseInfo = {}) {
69
+ const errorPrefix = _chalk.default.red('Error:');
70
+
71
+ if (_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND === exception.message) {
72
+ const createCommand = _chalk.default.bold(_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND + ' create');
73
+
74
+ const message = `Environment doesn't exist.\n\n\nTo create a new environment run:\n\n${createCommand}\n`;
75
+ console.log(errorPrefix, message);
76
+ } else {
77
+ let message = exception.message; // if the message has already ERROR prefix we should drop it as we are adding our own cool red Error-prefix
78
+
79
+ message = message.replace('ERROR: ', '');
80
+ console.log(errorPrefix, message);
81
+
82
+ if (trackKey) {
83
+ try {
84
+ const errorTrackingInfo = { ...trackBaseInfo,
85
+ failure: message
86
+ };
87
+ await (0, _tracker.trackEvent)(trackKey, errorTrackingInfo);
88
+ } catch (trackException) {
89
+ console.log(errorPrefix, `Failed to record track event ${trackKey}`, trackException.message);
90
+ }
91
+ }
92
+
93
+ if (!process.env.DEBUG) {
94
+ console.log(`Please re-run the command with "--debug ${_chalk.default.bold('@automattic/vip:bin:dev-environment')}" appended to it and provide the stack trace on the support ticket.`);
95
+ console.log(_chalk.default.bold('\nExample:\n'));
96
+ console.log('vip dev-env create --debug @automattic/vip:bin:dev-environment \n');
97
+ }
98
+
99
+ debug(exception);
100
+ }
101
+ }
102
+
103
+ const validateDependencies = async () => {
104
+ try {
105
+ await (0, _devEnvironmentLando.validateDockerInstalled)();
106
+ } catch (exception) {
107
+ exit.withError(exception.message);
108
+ }
109
+ };
110
+
111
+ exports.validateDependencies = validateDependencies;
112
+
113
+ function getEnvironmentName(options) {
114
+ if (options.slug) {
115
+ return options.slug;
116
+ }
117
+
118
+ if (options.app) {
119
+ const envSuffix = options.env ? `-${options.env}` : '';
120
+ return options.app + envSuffix;
121
+ }
122
+
123
+ return DEFAULT_SLUG;
124
+ }
125
+
126
+ function getEnvironmentStartCommand(options) {
127
+ if (options.slug) {
128
+ return `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} start --slug ${options.slug}`;
129
+ }
130
+
131
+ if (options.app) {
132
+ let application = `@${options.app}`;
133
+
134
+ if (options.env) {
135
+ application += `.${options.env}`;
136
+ }
137
+
138
+ return `vip ${application} ${_devEnvironment.DEV_ENVIRONMENT_SUBCOMMAND} start`;
139
+ }
140
+
141
+ return `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} start`;
142
+ }
143
+
144
+ function printTable(data) {
145
+ const formattedData = _formatters.default.formatData(data, {
146
+ format: 'table'
147
+ }, {
148
+ border: false
149
+ });
150
+
151
+ console.log(formattedData);
152
+ }
153
+
154
+ function processComponentOptionInput(passedParam, allowLocal) {
155
+ // cast to string
156
+ const param = passedParam + '';
157
+
158
+ if (allowLocal && param.includes('/')) {
159
+ return {
160
+ mode: 'local',
161
+ dir: param
162
+ };
163
+ }
164
+
165
+ return {
166
+ mode: 'image',
167
+ tag: param
168
+ };
169
+ }
170
+
171
+ function getOptionsFromAppInfo(appInfo) {
172
+ var _appInfo$environment, _appInfo$environment2, _appInfo$environment3;
173
+
174
+ return {
175
+ title: ((_appInfo$environment = appInfo.environment) === null || _appInfo$environment === void 0 ? void 0 : _appInfo$environment.name) || appInfo.name || '',
176
+ multisite: !!(appInfo !== null && appInfo !== void 0 && (_appInfo$environment2 = appInfo.environment) !== null && _appInfo$environment2 !== void 0 && _appInfo$environment2.isMultisite),
177
+ mediaRedirectDomain: (_appInfo$environment3 = appInfo.environment) === null || _appInfo$environment3 === void 0 ? void 0 : _appInfo$environment3.primaryDomain
178
+ };
179
+ }
180
+ /**
181
+ * Prompt for arguments
182
+ * @param {InstanceOptions} preselectedOptions - options to be used without prompt
183
+ * @param {InstanceOptions} defaultOptions - options to be used as default values for prompt
184
+ * @returns {any} instance data
185
+ */
186
+
187
+
188
+ async function promptForArguments(preselectedOptions, defaultOptions) {
189
+ debug('Provided preselected', preselectedOptions, 'and default', defaultOptions);
190
+ console.log(_devEnvironment.DEV_ENVIRONMENT_PROMPT_INTRO);
191
+ let multisiteText = 'Multisite';
192
+ let multisiteDefault = _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.multisite;
193
+
194
+ if (defaultOptions.title) {
195
+ multisiteText += ` (${defaultOptions.title} ${defaultOptions.multisite ? 'IS' : 'is NOT'} multisite)`;
196
+ multisiteDefault = defaultOptions.multisite;
197
+ }
198
+
199
+ const instanceData = {
200
+ wpTitle: preselectedOptions.title || (await promptForText('WordPress site title', defaultOptions.title || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.title)),
201
+ multisite: 'multisite' in preselectedOptions ? preselectedOptions.multisite : await promptForBoolean(multisiteText, !!multisiteDefault),
202
+ elasticsearch: preselectedOptions.elasticsearch || defaultOptions.elasticsearch || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.elasticsearchVersion,
203
+ php: preselectedOptions.php ? resolvePhpVersion(preselectedOptions.php) : await promptForPhpVersion(resolvePhpVersion(defaultOptions.php || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.phpVersion)),
204
+ mariadb: preselectedOptions.mariadb || defaultOptions.mariadb || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.mariadbVersion,
205
+ mediaRedirectDomain: preselectedOptions.mediaRedirectDomain || '',
206
+ wordpress: {
207
+ mode: 'image'
208
+ },
209
+ muPlugins: {
210
+ mode: 'image'
211
+ },
212
+ clientCode: {
213
+ mode: 'image'
214
+ },
215
+ statsd: false,
216
+ phpmyadmin: false,
217
+ xdebug: false,
218
+ siteSlug: '',
219
+ enterpriseSearchEnabled: preselectedOptions.enterpriseSearchEnabled || defaultOptions.enterpriseSearchEnabled
220
+ };
221
+ const promptLabels = {
222
+ xdebug: 'XDebug',
223
+ phpmyadmin: 'phpMyAdmin'
224
+ };
225
+
226
+ if (!instanceData.mediaRedirectDomain && defaultOptions.mediaRedirectDomain) {
227
+ const mediaRedirectPromptText = `Would you like to redirect to ${defaultOptions.mediaRedirectDomain} for missing media files?`;
228
+ const setMediaRedirectDomain = await promptForBoolean(mediaRedirectPromptText, true);
229
+
230
+ if (setMediaRedirectDomain) {
231
+ var _defaultOptions$media;
232
+
233
+ instanceData.mediaRedirectDomain = (_defaultOptions$media = defaultOptions.mediaRedirectDomain) !== null && _defaultOptions$media !== void 0 ? _defaultOptions$media : '';
234
+ }
235
+ }
236
+
237
+ for (const component of _devEnvironment.DEV_ENVIRONMENT_COMPONENTS) {
238
+ var _preselectedOptions$c, _defaultOptions$compo;
239
+
240
+ const option = ((_preselectedOptions$c = preselectedOptions[component]) !== null && _preselectedOptions$c !== void 0 ? _preselectedOptions$c : '').toString();
241
+ const defaultValue = ((_defaultOptions$compo = defaultOptions[component]) !== null && _defaultOptions$compo !== void 0 ? _defaultOptions$compo : '').toString();
242
+ const result = await processComponent(component, option, defaultValue);
243
+
244
+ if (null === result) {
245
+ throw new Error('processComponent() returned null');
246
+ }
247
+
248
+ instanceData[component] = result;
249
+ }
250
+
251
+ instanceData.enterpriseSearchEnabled = await promptForBoolean('Enable Enterprise Search?', defaultOptions.enterpriseSearchEnabled);
252
+
253
+ if (instanceData.enterpriseSearchEnabled) {
254
+ instanceData.statsd = preselectedOptions.statsd || defaultOptions.statsd || false;
255
+ } else {
256
+ instanceData.statsd = false;
257
+ }
258
+
259
+ for (const service of ['phpmyadmin', 'xdebug']) {
260
+ if (service in instanceData) {
261
+ instanceData[service] = await promptForBoolean(`Enable ${promptLabels[service] || service}`, instanceData[service]);
262
+ }
263
+ }
264
+
265
+ debug('Instance data after prompts', instanceData);
266
+ return instanceData;
267
+ }
268
+
269
+ async function processComponent(component, preselectedValue, defaultValue) {
270
+ debug(`processing a component '${component}', with preselected/deafault - ${preselectedValue}/${defaultValue}`);
271
+ let result = null;
272
+ const allowLocal = component !== 'wordpress';
273
+ const defaultObject = defaultValue ? processComponentOptionInput(defaultValue, allowLocal) : null;
274
+
275
+ if (preselectedValue) {
276
+ result = processComponentOptionInput(preselectedValue, allowLocal);
277
+ } else {
278
+ result = await promptForComponent(component, allowLocal, defaultObject);
279
+ }
280
+
281
+ while ('local' === ((_result = result) === null || _result === void 0 ? void 0 : _result.mode)) {
282
+ var _result;
283
+
284
+ const resolvedPath = resolvePath(result.dir || '');
285
+ result.dir = resolvedPath;
286
+
287
+ const isDirectory = resolvedPath && _fs.default.existsSync(resolvedPath) && _fs.default.lstatSync(resolvedPath).isDirectory();
288
+
289
+ const isEmpty = isDirectory ? _fs.default.readdirSync(resolvedPath).length === 0 : true;
290
+
291
+ if (isDirectory && !isEmpty) {
292
+ break;
293
+ } else {
294
+ const message = `Provided path "${resolvedPath}" does not point to a valid or existing directory.`;
295
+ console.log(_chalk.default.yellow('Warning:'), message);
296
+ result = await promptForComponent(component, allowLocal, defaultObject);
297
+ }
298
+ }
299
+
300
+ return result;
301
+ }
302
+
303
+ function resolvePath(input) {
304
+ // Resolve does not do ~ reliably
305
+ const resolvedPath = input.replace(/^~/, _os.default.homedir()); // And resolve to handle relative paths
306
+
307
+ return _path.default.resolve(resolvedPath);
308
+ }
309
+
310
+ async function promptForText(message, initial) {
311
+ const nonEmptyValidator = value => {
312
+ if ((value || '').trim()) {
313
+ return true;
314
+ }
315
+
316
+ return 'value needs to be provided';
317
+ };
318
+
319
+ const result = await (0, _enquirer.prompt)({
320
+ type: 'input',
321
+ name: 'input',
322
+ message,
323
+ initial,
324
+ validate: nonEmptyValidator
325
+ });
326
+ return ((result === null || result === void 0 ? void 0 : result.input) || '').trim();
327
+ }
328
+
329
+ async function promptForBoolean(message, initial) {
330
+ const confirm = new _enquirer.Confirm({
331
+ message,
332
+ initial
333
+ });
334
+ return confirm.run();
335
+ }
336
+
337
+ function resolvePhpVersion(version) {
338
+ debug(`Resolving PHP version '${version}'`);
339
+ const versions = Object.keys(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS);
340
+ const images = Object.values(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS); // eslint-disable-next-line eqeqeq -- use loose comparison because commander resolves '8.0' to '8'
341
+
342
+ const index = versions.findIndex(value => value == version);
343
+
344
+ if (index === -1) {
345
+ const image = images.find(value => value === version);
346
+ return image !== null && image !== void 0 ? image : images[0];
347
+ }
348
+
349
+ return images[index];
350
+ }
351
+
352
+ async function promptForPhpVersion(initialValue) {
353
+ debug(`Prompting for PHP version, preselected option is ${initialValue}`);
354
+ const choices = Object.keys(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS);
355
+ const images = Object.values(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS);
356
+ const initial = images.findIndex(version => version === initialValue);
357
+ const select = new _enquirer.Select({
358
+ message: 'PHP version to use',
359
+ choices,
360
+ initial
361
+ });
362
+ const answer = await select.run();
363
+ return resolvePhpVersion(answer);
364
+ }
365
+
366
+ const componentDisplayNames = {
367
+ wordpress: 'WordPress',
368
+ muPlugins: 'vip-go-mu-plugins',
369
+ clientCode: 'site-code'
370
+ };
371
+
372
+ async function promptForComponent(component, allowLocal, defaultObject) {
373
+ debug(`Prompting for ${component} with default:`, defaultObject);
374
+ const componentDisplayName = componentDisplayNames[component] || component;
375
+ const modChoices = [];
376
+
377
+ if (allowLocal) {
378
+ modChoices.push({
379
+ message: `local folder - where you already have ${componentDisplayName} code`,
380
+ value: 'local'
381
+ });
382
+ }
383
+
384
+ modChoices.push({
385
+ message: 'image - that gets automatically fetched',
386
+ value: 'image'
387
+ });
388
+ let initialMode = 'image';
389
+
390
+ if ('clientCode' === component) {
391
+ initialMode = 'local';
392
+ }
393
+
394
+ if (defaultObject !== null && defaultObject !== void 0 && defaultObject.mode) {
395
+ initialMode = defaultObject.mode;
396
+ }
397
+
398
+ let modeResult = initialMode;
399
+ const selectMode = modChoices.length > 1;
400
+
401
+ if (selectMode) {
402
+ const initialModeIndex = modChoices.findIndex(choice => choice.value === initialMode);
403
+ const select = new _enquirer.Select({
404
+ message: `How would you like to source ${componentDisplayName}`,
405
+ choices: modChoices,
406
+ initial: initialModeIndex
407
+ });
408
+ modeResult = await select.run();
409
+ }
410
+
411
+ const messagePrefix = selectMode ? '\t' : `${componentDisplayName} - `;
412
+
413
+ if ('local' === modeResult) {
414
+ const directoryPath = await promptForText(`${messagePrefix}What is a path to your local ${componentDisplayName}`, (defaultObject === null || defaultObject === void 0 ? void 0 : defaultObject.dir) || '');
415
+ return {
416
+ mode: modeResult,
417
+ dir: directoryPath
418
+ };
419
+ } // image with selection
420
+
421
+
422
+ if (component === 'wordpress') {
423
+ const message = `${messagePrefix}Which version would you like`;
424
+ const tagChoices = await getTagChoices();
425
+ const selectTag = new _enquirer.Select({
426
+ message,
427
+ choices: tagChoices
428
+ });
429
+ const option = await selectTag.run();
430
+ return {
431
+ mode: modeResult,
432
+ tag: option
433
+ };
434
+ } // image
435
+
436
+
437
+ return {
438
+ mode: modeResult
439
+ };
440
+ }
441
+
442
+ function addDevEnvConfigurationOptions(command) {
443
+ return command.option('wordpress', 'Use a specific WordPress version').option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('client-code', 'Use the client code from a local directory or VIP skeleton').option('statsd', 'Enable statsd component. By default it is disabled', undefined, value => {
444
+ var _value$toLowerCase;
445
+
446
+ return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase = value.toLowerCase) === null || _value$toLowerCase === void 0 ? void 0 : _value$toLowerCase.call(value));
447
+ }).option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, value => {
448
+ var _value$toLowerCase2;
449
+
450
+ return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase2 = value.toLowerCase) === null || _value$toLowerCase2 === void 0 ? void 0 : _value$toLowerCase2.call(value));
451
+ }).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, value => {
452
+ var _value$toLowerCase3;
453
+
454
+ return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase3 = value.toLowerCase) === null || _value$toLowerCase3 === void 0 ? void 0 : _value$toLowerCase3.call(value));
455
+ }).option('elasticsearch', 'Explicitly choose Elasticsearch version to use').option('mariadb', 'Explicitly choose MariaDB version to use').option(['r', 'media-redirect-domain'], 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.').option('php', 'Explicitly choose PHP version to use');
456
+ }
457
+ /**
458
+ * Provides the list of tag choices for selection
459
+ */
460
+
461
+
462
+ async function getTagChoices() {
463
+ const versions = await (0, _devEnvironmentCore.getVersionList)();
464
+
465
+ if (versions.length < 1) {
466
+ return ['5.9', '5.8', '5.7', '5.6', '5.5'];
467
+ }
468
+
469
+ return versions.map(version => {
470
+ let mapping;
471
+ const tagFormatted = version.tag.padEnd(8 - version.tag.length);
472
+ const prerelease = version.prerelease ? '(Pre-Release)' : '';
473
+
474
+ if (version.tag !== version.ref) {
475
+ mapping = `→ ${prerelease} ${version.ref}`;
476
+ } else {
477
+ mapping = '';
478
+ }
479
+
480
+ return {
481
+ name: version.tag,
482
+ message: `${tagFormatted} ${mapping}`,
483
+ value: version.tag
484
+ };
485
+ });
486
+ }
487
+
488
+ function getEnvTrackingInfo(slug) {
489
+ try {
490
+ const envData = (0, _devEnvironmentCore.readEnvironmentData)(slug);
491
+ const result = {
492
+ slug
493
+ };
494
+
495
+ for (const key of Object.keys(envData)) {
496
+ // track doesnt like camelCase
497
+ const snakeCasedKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
498
+ const value = _devEnvironment.DEV_ENVIRONMENT_COMPONENTS.includes(key) ? JSON.stringify(envData[key]) : envData[key];
499
+ result[snakeCasedKey] = value;
500
+ }
501
+
502
+ return result;
503
+ } catch (err) {
504
+ return {
505
+ slug
506
+ };
507
+ }
508
+ }