@automattic/vip 2.21.0 → 2.23.0

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 (111) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/assets/dev-env.lando.template.yml.ejs +1 -1
  3. package/automattic-vip-2.23.0.tgz +0 -0
  4. package/dist/bin/vip-app-list.js +0 -12
  5. package/dist/bin/vip-app.js +6 -13
  6. package/dist/bin/vip-cache-purge-url.js +4 -19
  7. package/dist/bin/vip-cache.js +0 -2
  8. package/dist/bin/vip-config-envvar-delete.js +4 -19
  9. package/dist/bin/vip-config-envvar-get-all.js +6 -19
  10. package/dist/bin/vip-config-envvar-get.js +4 -15
  11. package/dist/bin/vip-config-envvar-list.js +8 -20
  12. package/dist/bin/vip-config-envvar-set.js +4 -23
  13. package/dist/bin/vip-config-envvar.js +0 -2
  14. package/dist/bin/vip-config-software-get.js +0 -17
  15. package/dist/bin/vip-config-software-update.js +6 -22
  16. package/dist/bin/vip-config-software.js +0 -2
  17. package/dist/bin/vip-config.js +0 -2
  18. package/dist/bin/vip-dev-env-create.js +0 -18
  19. package/dist/bin/vip-dev-env-destroy.js +0 -9
  20. package/dist/bin/vip-dev-env-exec.js +0 -12
  21. package/dist/bin/vip-dev-env-import-media.js +0 -7
  22. package/dist/bin/vip-dev-env-import-sql.js +2 -17
  23. package/dist/bin/vip-dev-env-import.js +0 -3
  24. package/dist/bin/vip-dev-env-info.js +0 -10
  25. package/dist/bin/vip-dev-env-list.js +0 -7
  26. package/dist/bin/vip-dev-env-start.js +4 -14
  27. package/dist/bin/vip-dev-env-stop.js +0 -9
  28. package/dist/bin/vip-dev-env-update.js +0 -11
  29. package/dist/bin/vip-dev-env.js +0 -2
  30. package/dist/bin/vip-import-media-abort.js +0 -18
  31. package/dist/bin/vip-import-media-status.js +0 -12
  32. package/dist/bin/vip-import-media.js +6 -23
  33. package/dist/bin/vip-import-sql-status.js +0 -12
  34. package/dist/bin/vip-import-sql.js +40 -103
  35. package/dist/bin/vip-import-validate-files.js +21 -42
  36. package/dist/bin/vip-import-validate-sql.js +0 -8
  37. package/dist/bin/vip-import.js +0 -3
  38. package/dist/bin/vip-logs.js +20 -50
  39. package/dist/bin/vip-search-replace.js +8 -14
  40. package/dist/bin/vip-sync.js +2 -25
  41. package/dist/bin/vip-validate-preflight.js +427 -0
  42. package/dist/bin/vip-validate.js +19 -0
  43. package/dist/bin/vip-whoami.js +2 -14
  44. package/dist/bin/vip-wp.js +39 -89
  45. package/dist/bin/vip.js +5 -35
  46. package/dist/lib/analytics/clients/pendo.js +9 -18
  47. package/dist/lib/analytics/clients/stub.js +1 -3
  48. package/dist/lib/analytics/clients/tracks.js +11 -20
  49. package/dist/lib/analytics/index.js +4 -11
  50. package/dist/lib/api/app.js +1 -11
  51. package/dist/lib/api/cache-purge.js +4 -7
  52. package/dist/lib/api/feature-flags.js +1 -4
  53. package/dist/lib/api/http.js +9 -15
  54. package/dist/lib/api/user.js +1 -7
  55. package/dist/lib/api.js +17 -19
  56. package/dist/lib/app-logs/app-logs.js +2 -9
  57. package/dist/lib/app.js +2 -5
  58. package/dist/lib/cli/apiConfig.js +4 -19
  59. package/dist/lib/cli/command.js +43 -133
  60. package/dist/lib/cli/config.js +1 -5
  61. package/dist/lib/cli/envAlias.js +14 -15
  62. package/dist/lib/cli/exit.js +4 -6
  63. package/dist/lib/cli/format.js +8 -50
  64. package/dist/lib/cli/progress.js +13 -42
  65. package/dist/lib/cli/prompt.js +1 -5
  66. package/dist/lib/cli/repo.js +7 -20
  67. package/dist/lib/client-file-uploader.js +44 -97
  68. package/dist/lib/config/software.js +2 -52
  69. package/dist/lib/constants/dev-environment.js +1 -2
  70. package/dist/lib/constants/file-size.js +1 -1
  71. package/dist/lib/constants/vipgo.js +1 -1
  72. package/dist/lib/dev-environment/dev-environment-cli.js +68 -155
  73. package/dist/lib/dev-environment/dev-environment-core.js +73 -194
  74. package/dist/lib/dev-environment/dev-environment-lando.js +16 -71
  75. package/dist/lib/env.js +1 -4
  76. package/dist/lib/envvar/api-delete.js +1 -4
  77. package/dist/lib/envvar/api-get-all.js +1 -4
  78. package/dist/lib/envvar/api-get.js +1 -2
  79. package/dist/lib/envvar/api-list.js +3 -4
  80. package/dist/lib/envvar/api-set.js +1 -4
  81. package/dist/lib/envvar/api.js +5 -16
  82. package/dist/lib/envvar/input.js +1 -8
  83. package/dist/lib/envvar/logging.js +2 -6
  84. package/dist/lib/envvar/read-file.js +1 -3
  85. package/dist/lib/http/proxy-agent.js +17 -22
  86. package/dist/lib/keychain/browser.js +1 -4
  87. package/dist/lib/keychain/insecure.js +1 -10
  88. package/dist/lib/keychain/secure.js +1 -8
  89. package/dist/lib/keychain.js +4 -8
  90. package/dist/lib/logout.js +0 -6
  91. package/dist/lib/media-import/media-file-import.js +3 -7
  92. package/dist/lib/media-import/progress.js +6 -17
  93. package/dist/lib/media-import/status.js +14 -65
  94. package/dist/lib/read-file.js +1 -6
  95. package/dist/lib/rollbar.js +1 -7
  96. package/dist/lib/search-and-replace.js +9 -41
  97. package/dist/lib/site-import/db-file-import.js +3 -9
  98. package/dist/lib/site-import/status.js +17 -74
  99. package/dist/lib/token.js +1 -33
  100. package/dist/lib/tracker.js +4 -20
  101. package/dist/lib/user-error.js +0 -2
  102. package/dist/lib/validations/is-multi-site-sql-dump.js +4 -12
  103. package/dist/lib/validations/is-multi-site.js +5 -21
  104. package/dist/lib/validations/is-multisite-domain-mapped.js +5 -31
  105. package/dist/lib/validations/line-by-line.js +4 -16
  106. package/dist/lib/validations/site-type.js +10 -19
  107. package/dist/lib/validations/sql.js +11 -76
  108. package/dist/lib/validations/utils.js +1 -6
  109. package/dist/lib/vip-import-validate-files.js +82 -109
  110. package/npm-shrinkwrap.json +2407 -1800
  111. package/package.json +18 -15
@@ -15,53 +15,29 @@ Object.defineProperty(exports, "__esModule", {
15
15
  });
16
16
  exports.gates = gates;
17
17
  exports.validateAndGetTableNames = validateAndGetTableNames;
18
-
19
18
  var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
20
-
21
19
  var _cliColumns = _interopRequireDefault(require("cli-columns"));
22
-
23
20
  var _chalk = _interopRequireDefault(require("chalk"));
24
-
25
21
  var _debug = _interopRequireDefault(require("debug"));
26
-
27
22
  var _enquirer = require("enquirer");
28
-
29
23
  var _command = _interopRequireDefault(require("../lib/cli/command"));
30
-
31
24
  var _dbFileImport = require("../lib/site-import/db-file-import");
32
-
33
25
  var _status = require("../lib/site-import/status");
34
-
35
26
  var _clientFileUploader = require("../lib/client-file-uploader");
36
-
37
27
  var _tracker = require("../lib/tracker");
38
-
39
28
  var _sql = require("../lib/validations/sql");
40
-
41
29
  var _siteType = require("../lib/validations/site-type");
42
-
43
30
  var _searchAndReplace = require("../lib/search-and-replace");
44
-
45
31
  var _api = _interopRequireDefault(require("../lib/api"));
46
-
47
32
  var exit = _interopRequireWildcard(require("../lib/cli/exit"));
48
-
49
33
  var _lineByLine = require("../lib/validations/line-by-line");
50
-
51
34
  var _format = require("../lib/cli/format");
52
-
53
35
  var _progress = require("../lib/cli/progress");
54
-
55
36
  var _isMultiSite = require("../lib/validations/is-multi-site");
56
-
57
37
  var _rollbar = require("../lib/rollbar");
58
-
59
38
  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); }
60
-
61
39
  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; }
62
-
63
40
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
64
-
65
41
  /**
66
42
  * Internal dependencies
67
43
  */
@@ -114,29 +90,24 @@ const SQL_IMPORT_PREFLIGHT_PROGRESS_STEPS = [{
114
90
  id: 'queue_import',
115
91
  name: 'Queueing Import'
116
92
  }];
117
-
118
93
  async function gates(app, env, fileName) {
119
94
  const {
120
95
  id: envId,
121
96
  appId
122
97
  } = env;
123
-
124
98
  const track = _tracker.trackEventWithEnv.bind(null, appId, envId);
125
-
126
99
  if (!(0, _dbFileImport.currentUserCanImportForApp)(app)) {
127
100
  await track('import_sql_command_error', {
128
101
  error_type: 'unauthorized'
129
102
  });
130
103
  exit.withError('The currently authenticated account does not have permission to perform a SQL import.');
131
104
  }
132
-
133
105
  if (!(0, _dbFileImport.isSupportedApp)(app)) {
134
106
  await track('import_sql_command_error', {
135
107
  error_type: 'unsupported-app'
136
108
  });
137
109
  exit.withError('The type of application you specified does not currently support SQL imports.');
138
110
  }
139
-
140
111
  try {
141
112
  await (0, _clientFileUploader.checkFileAccess)(fileName);
142
113
  } catch (err) {
@@ -145,25 +116,20 @@ async function gates(app, env, fileName) {
145
116
  });
146
117
  exit.withError(`File '${fileName}' does not exist or is not readable.`);
147
118
  }
148
-
149
119
  if (!(await (0, _clientFileUploader.isFile)(fileName))) {
150
120
  await track('import_sql_command_error', {
151
121
  error_type: 'sqlfile-notfile'
152
122
  });
153
123
  exit.withError(`Path '${fileName}' is not a file.`);
154
124
  }
155
-
156
125
  const fileSize = await (0, _clientFileUploader.getFileSize)(fileName);
157
-
158
126
  if (!fileSize) {
159
127
  await track('import_sql_command_error', {
160
128
  error_type: 'sqlfile-empty'
161
129
  });
162
130
  exit.withError(`File '${fileName}' is empty.`);
163
131
  }
164
-
165
132
  const maxFileSize = env !== null && env !== void 0 && env.launched ? _dbFileImport.SQL_IMPORT_FILE_SIZE_LIMIT_LAUNCHED : _dbFileImport.SQL_IMPORT_FILE_SIZE_LIMIT;
166
-
167
133
  if (fileSize > maxFileSize) {
168
134
  await track('import_sql_command_error', {
169
135
  error_type: 'sqlfile-toobig',
@@ -172,59 +138,59 @@ async function gates(app, env, fileName) {
172
138
  });
173
139
  exit.withError(`The sql import file size (${fileSize} bytes) exceeds the limit (${maxFileSize} bytes).` + (env.launched ? ' Note: This limit is lower for launched environments to maintain site stability.' : '') + '\n\nPlease split it into multiple files or contact support for assistance.');
174
140
  }
175
-
176
141
  if (!(env !== null && env !== void 0 && env.importStatus)) {
177
142
  await track('import_sql_command_error', {
178
143
  error_type: 'empty-import-status'
179
144
  });
180
145
  exit.withError('Could not determine the import status for this environment. Check the app/environment and if the problem persists, contact support for assistance');
181
146
  }
182
-
183
147
  const {
184
148
  importStatus: {
185
149
  dbOperationInProgress,
186
150
  importInProgress
187
151
  }
188
152
  } = env;
189
-
190
153
  if (importInProgress) {
191
154
  await track('import_sql_command_error', {
192
155
  error_type: 'existing-import'
193
156
  });
194
157
  exit.withError('There is already an import in progress.\n\nYou can view the status with command:\n vip import sql status');
195
158
  }
196
-
197
159
  if (dbOperationInProgress) {
198
160
  await track('import_sql_command_error', {
199
161
  error_type: 'existing-dbop'
200
162
  });
201
163
  exit.withError('There is already a database operation in progress. Please try again later.');
202
164
  }
203
- } // Command examples for the `vip import sql` help prompt
204
-
165
+ }
205
166
 
206
- const examples = [// `sql` subcommand
167
+ // Command examples for the `vip import sql` help prompt
168
+ const examples = [
169
+ // `sql` subcommand
207
170
  {
208
171
  usage: 'vip import sql @mysite.develop <file.sql>',
209
172
  description: 'Import the given SQL file to your site'
210
- }, // `search-replace` flag
173
+ },
174
+ // `search-replace` flag
211
175
  {
212
176
  usage: 'vip import sql @mysite.develop <file.sql> --search-replace="from,to"',
213
177
  description: 'Perform a Search and Replace, then import the replaced file to your site.\n' + ' * Ensure there are no spaces between your search-replace parameters'
214
- }, // `in-place` flag
178
+ },
179
+ // `in-place` flag
215
180
  {
216
181
  usage: 'vip import sql @mysite.develop <file.sql> --search-replace="from,to" --in-place',
217
182
  description: 'Search and Replace on the input <file.sql>, then import the replaced file to your site'
218
- }, // `output` flag
183
+ },
184
+ // `output` flag
219
185
  {
220
186
  usage: 'vip import sql @mysite.develop <file.sql> --search-replace="from,to" --output="<output.sql>"',
221
187
  description: 'Output the performed Search and Replace to the specified output file, then import the replaced file to your site\n' + ' * Has no effect when the `in-place` flag is used'
222
- }, // `sql status` subcommand
188
+ },
189
+ // `sql status` subcommand
223
190
  {
224
191
  usage: 'vip import sql status @mysite.develop',
225
192
  description: 'Check the status of the most recent import. If an import is running, this will poll until it is complete.'
226
193
  }];
227
-
228
194
  const promptToContinue = async ({
229
195
  launched,
230
196
  formattedEnvironment,
@@ -238,13 +204,11 @@ const promptToContinue = async ({
238
204
  name: 'confirmedDomain',
239
205
  message: `You are about to import the above tables into a ${launched ? 'launched' : 'un-launched'} ${formattedEnvironment} site ${_chalk.default.yellow(domain)}.\nType '${_chalk.default.yellow(promptToMatch)}' (without the quotes) to continue:\n`
240
206
  });
241
-
242
207
  if (promptResponse.confirmedDomain !== promptToMatch) {
243
208
  await track('import_sql_unexpected_tables');
244
209
  exit.withError('The input did not match the expected environment label. Import aborted.');
245
210
  }
246
211
  };
247
-
248
212
  async function validateAndGetTableNames({
249
213
  skipValidate,
250
214
  appId,
@@ -253,12 +217,10 @@ async function validateAndGetTableNames({
253
217
  searchReplace
254
218
  }) {
255
219
  const validations = [_sql.staticSqlValidations, _siteType.siteTypeValidations];
256
-
257
220
  if (skipValidate) {
258
221
  console.log('Skipping SQL file validation.');
259
222
  return [];
260
223
  }
261
-
262
224
  try {
263
225
  await (0, _lineByLine.fileLineValidations)(appId, envId, fileNameToUpload, validations, searchReplace);
264
226
  } catch (validateErr) {
@@ -266,12 +228,10 @@ async function validateAndGetTableNames({
266
228
  exit.withError(`${validateErr.message}\n
267
229
  If you are confident the file does not contain unsupported statements, you can retry the command with the ${_chalk.default.yellow('--skip-validate')} option.
268
230
  `);
269
- } // this can only be called after static validation of the SQL file
270
-
271
-
231
+ }
232
+ // this can only be called after static validation of the SQL file
272
233
  return (0, _sql.getTableNames)();
273
234
  }
274
-
275
235
  const displayPlaybook = ({
276
236
  launched,
277
237
  tableNames,
@@ -279,6 +239,7 @@ const displayPlaybook = ({
279
239
  fileName,
280
240
  domain,
281
241
  formattedEnvironment,
242
+ unformattedEnvironment,
282
243
  isMultiSite,
283
244
  app
284
245
  }) => {
@@ -286,38 +247,31 @@ const displayPlaybook = ({
286
247
  console.log(` importing: ${_chalk.default.blueBright(fileName)}`);
287
248
  console.log(` to: ${_chalk.default.cyan(domain)}`);
288
249
  console.log(` site: ${app.name} (${formattedEnvironment})`);
289
-
290
250
  if (searchReplace !== null && searchReplace !== void 0 && searchReplace.length) {
291
251
  const output = (from, to) => {
292
252
  const message = ` s-r: ${_chalk.default.blue(from)} -> ${_chalk.default.blue(to)}`;
293
253
  console.log(message);
294
254
  };
295
-
296
255
  (0, _format.formatSearchReplaceValues)(searchReplace, output);
297
256
  }
298
-
299
257
  let siteArray = [];
300
-
301
258
  if (isMultiSite) {
302
- var _app$environments$, _app$environments$$wp;
303
-
259
+ var _app$environments, _selectedEnvironmentO;
304
260
  // eslint-disable-next-line no-multi-spaces
305
261
  console.log(` multisite: ${isMultiSite.toString()}`);
306
- siteArray = app === null || app === void 0 ? void 0 : (_app$environments$ = app.environments[0]) === null || _app$environments$ === void 0 ? void 0 : (_app$environments$$wp = _app$environments$.wpSites) === null || _app$environments$$wp === void 0 ? void 0 : _app$environments$$wp.nodes;
262
+ const selectedEnvironmentObj = app === null || app === void 0 ? void 0 : (_app$environments = app.environments) === null || _app$environments === void 0 ? void 0 : _app$environments.find(env => unformattedEnvironment === env.type);
263
+ siteArray = selectedEnvironmentObj === null || selectedEnvironmentObj === void 0 ? void 0 : (_selectedEnvironmentO = selectedEnvironmentObj.wpSites) === null || _selectedEnvironmentO === void 0 ? void 0 : _selectedEnvironmentO.nodes;
307
264
  }
308
-
309
265
  if (!tableNames.length) {
310
266
  debug('Validation was skipped, no playbook information will be displayed');
311
267
  } else {
312
268
  // output the table names
313
269
  console.log();
314
-
315
270
  if (!isMultiSite) {
316
271
  console.log('Below are a list of Tables that will be imported by this process:');
317
272
  console.log((0, _cliColumns.default)(tableNames));
318
273
  } else {
319
274
  var _siteArray;
320
-
321
275
  // we have siteArray from the API, use it and the table names together
322
276
  if (siteArray === 'undefined' || !siteArray) {
323
277
  console.log(_chalk.default.yellowBright('Unable to determine the subsites affected by this import, please proceed only if you are confident on the contents in the import file.'));
@@ -325,16 +279,13 @@ const displayPlaybook = ({
325
279
  } else if (!((_siteArray = siteArray) !== null && _siteArray !== void 0 && _siteArray.length)) {
326
280
  throw new Error('There were no sites in your multisite installation');
327
281
  }
328
-
329
282
  const multiSiteBreakdown = siteArray.map(wpSite => {
330
283
  let siteRegex;
331
-
332
284
  if (wpSite.id === 1) {
333
- siteRegex = /wp_[a-z]+/i;
285
+ siteRegex = /^wp_[a-z]+/i;
334
286
  } else {
335
- siteRegex = new RegExp(`wp_${wpSite.id}_[a-z]+`, 'i');
287
+ siteRegex = new RegExp(`^wp_${wpSite.id}_[a-z]+`, 'i');
336
288
  }
337
-
338
289
  const tableNamesInGroup = tableNames.filter(name => siteRegex.test(name));
339
290
  return {
340
291
  id: wpSite.id,
@@ -342,11 +293,9 @@ const displayPlaybook = ({
342
293
  tables: tableNamesInGroup
343
294
  };
344
295
  });
345
-
346
296
  if (launched) {
347
297
  console.log(_chalk.default.yellowBright('You are updating tables in a launched multi site installation. Sites in the same network may have their performance impacted by this operation.'));
348
298
  }
349
-
350
299
  console.log(_chalk.default.yellow('The following sites will be affected by the import:'));
351
300
  multiSiteBreakdown.map(siteObject => {
352
301
  console.log();
@@ -356,7 +305,6 @@ const displayPlaybook = ({
356
305
  }
357
306
  }
358
307
  };
359
-
360
308
  (0, _command.default)({
361
309
  appContext: true,
362
310
  appQuery,
@@ -365,7 +313,6 @@ const displayPlaybook = ({
365
313
  module: 'import-sql'
366
314
  }).command('status', 'Check the status of the current running import').option('skip-validate', 'Do not perform pre-upload file validation. If unsupported entries are present, the import is likely to fail').option('search-replace', 'Perform Search and Replace on the specified SQL file').option('in-place', 'Search and Replace explicitly on the given input file').option('output', 'Specify the replacement output file for Search and Replace', 'process.stdout').examples(examples).argv(process.argv, async (arg, opts) => {
367
315
  var _env$primaryDomain;
368
-
369
316
  const {
370
317
  app,
371
318
  env
@@ -381,35 +328,35 @@ const displayPlaybook = ({
381
328
  const [fileName] = arg;
382
329
  const isMultiSite = await (0, _isMultiSite.isMultiSiteInSiteMeta)(appId, envId);
383
330
  let fileMeta = await (0, _clientFileUploader.getFileMeta)(fileName);
384
-
385
331
  if (fileMeta.isCompressed) {
386
332
  console.log(_chalk.default.yellowBright('You are importing a compressed file. Validation and search-replace operation will be skipped.'));
387
333
  skipValidate = true;
388
334
  searchReplace = undefined;
389
335
  }
390
-
391
336
  debug('Options: ', opts);
392
337
  debug('Args: ', arg);
393
-
394
338
  const track = _tracker.trackEventWithEnv.bind(null, appId, envId);
339
+ await track('import_sql_command_execute');
395
340
 
396
- await track('import_sql_command_execute'); // // halt operation of the import based on some rules
397
-
398
- await gates(app, env, fileName); // Log summary of import details
341
+ // // halt operation of the import based on some rules
342
+ await gates(app, env, fileName);
399
343
 
344
+ // Log summary of import details
400
345
  const domain = env !== null && env !== void 0 && (_env$primaryDomain = env.primaryDomain) !== null && _env$primaryDomain !== void 0 && _env$primaryDomain.name ? env.primaryDomain.name : `#${env.id}`;
401
346
  const formattedEnvironment = (0, _format.formatEnvironment)(opts.env.type);
402
347
  const launched = opts.env.launched;
403
- let fileNameToUpload = fileName; // SQL file validations
348
+ let fileNameToUpload = fileName;
404
349
 
350
+ // SQL file validations
405
351
  const tableNames = await validateAndGetTableNames({
406
352
  skipValidate,
407
353
  appId,
408
354
  envId,
409
355
  fileNameToUpload,
410
356
  searchReplace
411
- }); // display playbook of what will happen during execution
357
+ });
412
358
 
359
+ // display playbook of what will happen during execution
413
360
  displayPlaybook({
414
361
  launched,
415
362
  tableNames,
@@ -417,16 +364,19 @@ const displayPlaybook = ({
417
364
  fileName,
418
365
  domain,
419
366
  formattedEnvironment,
367
+ unformattedEnvironment: opts.env.type,
420
368
  isMultiSite,
421
369
  app
422
- }); // PROMPT TO PROCEED WITH THE IMPORT
370
+ });
423
371
 
372
+ // PROMPT TO PROCEED WITH THE IMPORT
424
373
  await promptToContinue({
425
374
  launched,
426
375
  formattedEnvironment,
427
376
  track,
428
377
  domain
429
378
  });
379
+
430
380
  /**
431
381
  * =========== WARNING =============
432
382
  *
@@ -436,10 +386,8 @@ const displayPlaybook = ({
436
386
  *
437
387
  * =========== WARNING =============
438
388
  */
439
-
440
389
  const progressTracker = new _progress.ProgressTracker(SQL_IMPORT_PREFLIGHT_PROGRESS_STEPS);
441
390
  let status = 'running';
442
-
443
391
  const setProgressTrackerPrefixAndSuffix = () => {
444
392
  progressTracker.prefix = `
445
393
  =============================================================
@@ -455,14 +403,12 @@ Processing the SQL import for your environment...
455
403
  progressTracker.print({
456
404
  clearAfter: true
457
405
  });
458
-
459
406
  _rollbar.rollbar.error(failureError);
460
-
461
407
  exit.withError(failureError);
462
408
  };
409
+ progressTracker.startPrinting(setProgressTrackerPrefixAndSuffix);
463
410
 
464
- progressTracker.startPrinting(setProgressTrackerPrefixAndSuffix); // Run Search and Replace if the --search-replace flag was provided
465
-
411
+ // Run Search and Replace if the --search-replace flag was provided
466
412
  if (searchReplace && searchReplace.length) {
467
413
  progressTracker.stepRunning('replace');
468
414
  const {
@@ -472,30 +418,25 @@ Processing the SQL import for your environment...
472
418
  inPlace: opts.inPlace,
473
419
  output: true
474
420
  });
475
-
476
421
  if (typeof outputFileName !== 'string') {
477
422
  progressTracker.stepFailed('replace');
478
423
  return failWithError('Unable to determine location of the intermediate search & replace file.');
479
424
  }
480
-
481
425
  fileNameToUpload = outputFileName;
482
426
  fileMeta = await (0, _clientFileUploader.getFileMeta)(fileNameToUpload);
483
427
  progressTracker.stepSuccess('replace');
484
428
  } else {
485
429
  progressTracker.stepSkipped('replace');
486
430
  }
431
+ progressTracker.stepRunning('upload');
487
432
 
488
- progressTracker.stepRunning('upload'); // Call the Public API
489
-
433
+ // Call the Public API
490
434
  const api = await (0, _api.default)();
491
435
  const startImportVariables = {};
492
-
493
436
  const progressCallback = percentage => {
494
437
  progressTracker.setUploadPercentage(percentage);
495
438
  };
496
-
497
439
  fileMeta.fileName = fileNameToUpload;
498
-
499
440
  try {
500
441
  const {
501
442
  fileMeta: {
@@ -516,15 +457,13 @@ Processing the SQL import for your environment...
516
457
  md5: md5,
517
458
  searchReplace: []
518
459
  };
519
-
520
460
  if (searchReplace) {
521
461
  let pairs = searchReplace;
522
-
523
462
  if (!Array.isArray(pairs)) {
524
463
  pairs = [searchReplace];
525
- } // determine all the replacements required
526
-
464
+ }
527
465
 
466
+ // determine all the replacements required
528
467
  const replacementsArr = pairs.map(pair => pair.split(',').map(str => str.trim()));
529
468
  startImportVariables.input.searchReplace = replacementsArr.map(arr => {
530
469
  return {
@@ -533,7 +472,6 @@ Processing the SQL import for your environment...
533
472
  };
534
473
  });
535
474
  }
536
-
537
475
  debug({
538
476
  basename,
539
477
  md5,
@@ -550,9 +488,9 @@ Processing the SQL import for your environment...
550
488
  });
551
489
  progressTracker.stepFailed('upload');
552
490
  return failWithError(uploadError);
553
- } // Start the import
554
-
491
+ }
555
492
 
493
+ // Start the import
556
494
  try {
557
495
  const startImportResults = await api.mutate({
558
496
  mutation: START_IMPORT_MUTATION,
@@ -570,7 +508,6 @@ Processing the SQL import for your environment...
570
508
  progressTracker.stepFailed('queue_import');
571
509
  return failWithError(`StartImport call failed: ${gqlErr}`);
572
510
  }
573
-
574
511
  progressTracker.stepSuccess('queue_import');
575
512
  await (0, _status.importSqlCheckStatus)({
576
513
  app,
@@ -6,23 +6,14 @@
6
6
  "use strict";
7
7
 
8
8
  var _url = _interopRequireDefault(require("url"));
9
-
10
9
  var _path = _interopRequireDefault(require("path"));
11
-
12
10
  var _chalk = _interopRequireDefault(require("chalk"));
13
-
14
11
  var _fs = _interopRequireDefault(require("fs"));
15
-
16
12
  var _util = require("util");
17
-
18
13
  var _command = _interopRequireDefault(require("../lib/cli/command"));
19
-
20
14
  var _vipImportValidateFiles = require("../lib/vip-import-validate-files");
21
-
22
15
  var _tracker = require("../lib/tracker");
23
-
24
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
-
26
17
  /**
27
18
  * Internal dependencies
28
19
  */
@@ -38,14 +29,12 @@ const stat = (0, _util.promisify)(_fs.default.stat);
38
29
  *
39
30
  * Manipulating the file path/name to extract the folder name
40
31
  */
41
-
42
32
  const folder = arg.join(); // File comes in as an array as part of the args- turn it into a string
43
-
44
33
  arg = _url.default.parse(folder); // Then parse the file to its URL parts
45
-
46
34
  const filePath = arg.path; // Extract the path of the file
47
35
 
48
36
  let folderValidation;
37
+
49
38
  /**
50
39
  * Folder structure validation
51
40
  *
@@ -53,19 +42,18 @@ const stat = (0, _util.promisify)(_fs.default.stat);
53
42
  *
54
43
  * Recommended structure: `uploads/year/month` (Single sites)
55
44
  */
56
-
57
45
  const nestedFiles = (0, _vipImportValidateFiles.findNestedDirectories)(filePath);
58
46
  const {
59
47
  files,
60
48
  folderStructureObj
61
49
  } = nestedFiles; // Destructure
62
- // Check if there are any nested directories within the given folder
63
50
 
51
+ // Check if there are any nested directories within the given folder
64
52
  const nestedDirectories = Object.keys(folderStructureObj);
65
-
66
53
  if (nestedDirectories && nestedDirectories.length > 0) {
67
54
  folderValidation = (0, _vipImportValidateFiles.folderStructureValidation)(nestedDirectories);
68
55
  }
56
+
69
57
  /**
70
58
  * Individual file validations
71
59
  *
@@ -73,56 +61,52 @@ const stat = (0, _util.promisify)(_fs.default.stat);
73
61
  * - Filename validation
74
62
  * - Intermediate image validation
75
63
  */
76
-
77
-
78
64
  if (!files || !files.length || files.length <= 0) {
79
65
  console.error(_chalk.default.red('✕ Error:'), 'Media files directory cannot be empty');
80
66
  }
67
+
81
68
  /**
82
69
  * Media file extension validation
83
70
  *
84
71
  * Ensure that prohibited media file types are not used
85
72
  */
86
- // Collect invalid files for error logging
87
-
88
73
 
74
+ // Collect invalid files for error logging
89
75
  let intermediateImagesTotal = 0;
90
76
  const errorFileTypes = [];
91
77
  const errorFileNames = [];
92
- const intermediateImages = {}; // Iterate through each file to isolate the extension name
78
+ const intermediateImages = {};
93
79
 
80
+ // Iterate through each file to isolate the extension name
94
81
  for (const file of files) {
95
82
  // Check if file is a directory
96
83
  const stats = await stat(file);
97
84
  const isFolder = stats.isDirectory();
98
-
99
85
  const extension = _path.default.extname(file); // Extract the extension of the file
100
-
101
-
102
86
  const ext = extension.substr(1); // We only want the ext name minus the period (e.g- .jpg -> jpg)
103
-
104
87
  const extLowerCase = ext.toLowerCase(); // Change any uppercase extensions to lowercase
88
+
105
89
  // Check for any invalid file extensions
106
90
  // Returns true if ext is valid; false if invalid
91
+ const validExtensions = _vipImportValidateFiles.acceptedExtensions.includes(extLowerCase);
107
92
 
108
- const validExtensions = _vipImportValidateFiles.acceptedExtensions.includes(extLowerCase); // Collect files that have no extension, have invalid extensions,
93
+ // Collect files that have no extension, have invalid extensions,
109
94
  // or are directories for error logging
110
-
111
-
112
95
  if (!extension || !validExtensions || isFolder) {
113
96
  errorFileTypes.push(file);
114
97
  }
98
+
115
99
  /**
116
100
  * Filename validation
117
101
  *
118
102
  * Ensure that filenames don't contain prohibited characters
119
103
  */
120
- // Collect files that have invalid file names for error logging
121
-
122
104
 
105
+ // Collect files that have invalid file names for error logging
123
106
  if ((0, _vipImportValidateFiles.isFileSanitized)(file)) {
124
107
  errorFileNames.push(file);
125
108
  }
109
+
126
110
  /**
127
111
  * Intermediate image validation
128
112
  *
@@ -131,14 +115,12 @@ const stat = (0, _util.promisify)(_fs.default.stat);
131
115
  * Intermediate images are copies of images that are resized, so you may have multiples of the same image.
132
116
  * You can resize an image directly on VIP so intermediate images are not necessary.
133
117
  */
118
+ const original = (0, _vipImportValidateFiles.doesImageHaveExistingSource)(file);
134
119
 
135
-
136
- const original = (0, _vipImportValidateFiles.doesImageHaveExistingSource)(file); // If an image is an intermediate image, increment the total number and
120
+ // If an image is an intermediate image, increment the total number and
137
121
  // populate key/value pairs of the original image and intermediate image(s)
138
-
139
122
  if (original) {
140
123
  intermediateImagesTotal++;
141
-
142
124
  if (intermediateImages[original]) {
143
125
  // Key: original image, value: intermediate image(s)
144
126
  intermediateImages[original] = `${intermediateImages[original]}, ${file}`;
@@ -147,24 +129,21 @@ const stat = (0, _util.promisify)(_fs.default.stat);
147
129
  }
148
130
  }
149
131
  }
132
+
150
133
  /**
151
134
  * Error logging
152
135
  */
153
-
154
-
155
136
  if (errorFileTypes.length > 0) {
156
137
  (0, _vipImportValidateFiles.logErrorsForInvalidFileTypes)(errorFileTypes);
157
138
  }
158
-
159
139
  if (errorFileNames.length > 0) {
160
140
  (0, _vipImportValidateFiles.logErrorsForInvalidFilenames)(errorFileNames);
161
141
  }
162
-
163
142
  if (Object.keys(intermediateImages).length > 0) {
164
143
  (0, _vipImportValidateFiles.logErrorsForIntermediateImages)(intermediateImages);
165
- } // Log a summary of all errors
166
-
144
+ }
167
145
 
146
+ // Log a summary of all errors
168
147
  (0, _vipImportValidateFiles.summaryLogs)({
169
148
  folderErrorsLength: folderValidation.length,
170
149
  intImagesErrorsLength: intermediateImagesTotal,
@@ -172,11 +151,11 @@ const stat = (0, _util.promisify)(_fs.default.stat);
172
151
  filenameErrorsLength: errorFileNames.length,
173
152
  totalFiles: files.length,
174
153
  totalFolders: nestedDirectories.length
175
- }); // Tracks events to track activity
176
- // Props (object keys) need to be in Snake case vs. camelCase
154
+ });
177
155
 
156
+ // Tracks events to track activity
157
+ // Props (object keys) need to be in Snake case vs. camelCase
178
158
  /* eslint-disable camelcase */
179
-
180
159
  const allErrors = {
181
160
  folder_errors_length: folderValidation.length,
182
161
  int_images_errors_length: intermediateImagesTotal,