@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
@@ -0,0 +1,427 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ "use strict";
7
+
8
+ Object.defineProperty(exports, "__esModule", {
9
+ value: true
10
+ });
11
+ exports.appQuery = void 0;
12
+ exports.vipValidatePreflightCommand = vipValidatePreflightCommand;
13
+ var _vipGoPreflightChecks = require("@automattic/vip-go-preflight-checks");
14
+ var _path = _interopRequireDefault(require("path"));
15
+ var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
16
+ var _fs = require("fs");
17
+ var _ini = _interopRequireDefault(require("ini"));
18
+ var _chalk = _interopRequireDefault(require("chalk"));
19
+ var _command = _interopRequireDefault(require("../lib/cli/command"));
20
+ var exit = _interopRequireWildcard(require("../lib/cli/exit"));
21
+ var _api = _interopRequireWildcard(require("../lib/api"));
22
+ var _tracker = require("../lib/tracker");
23
+ 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); }
24
+ 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; }
25
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
+ /**
27
+ * Internal dependencies
28
+ */
29
+ const appQuery = `
30
+ id
31
+ name
32
+ repo
33
+ environments {
34
+ id
35
+ appId
36
+ name
37
+ type
38
+ environmentVariables {
39
+ nodes {
40
+ name,
41
+ value
42
+ }
43
+ }
44
+ }
45
+ organization {
46
+ id
47
+ name
48
+ }
49
+ `;
50
+ exports.appQuery = appQuery;
51
+ let suppressOutput = false;
52
+ let outputJson = false;
53
+ let harmoniaArgs = [];
54
+ function logToConsole(...messages) {
55
+ if (suppressOutput) {
56
+ return;
57
+ }
58
+ if (messages.length === 0) {
59
+ messages = [''];
60
+ }
61
+ messages.forEach(message => console.log(message));
62
+ }
63
+ async function getBuildConfiguration(application, environment) {
64
+ const api = await (0, _api.default)();
65
+
66
+ // Disable the global GraphQL error handling, so we can catch Unauthorized errors and recommend next steps.
67
+ (0, _api.disableGlobalGraphQLErrorHandling)();
68
+ const buildConfigQuery = (0, _graphqlTag.default)`
69
+ query BuildConfig( $appId: Int, $envId: Int ) {
70
+ app(id: $appId) {
71
+ environments(id: $envId) {
72
+ id,
73
+ buildConfiguration {
74
+ buildType
75
+ nodeBuildDockerEnv,
76
+ nodeJSVersion,
77
+ npmToken,
78
+ }
79
+ }
80
+ }
81
+ }`;
82
+ try {
83
+ const result = await api.query({
84
+ query: buildConfigQuery,
85
+ fetchPolicy: 'network-only',
86
+ variables: {
87
+ appId: environment.appId,
88
+ envId: environment.id
89
+ }
90
+ });
91
+
92
+ // Reenable GraphQL error handling
93
+ (0, _api.enableGlobalGraphQLErrorHandling)();
94
+ return result.data.app.environments[0].buildConfiguration;
95
+ } catch (error) {
96
+ if (error.graphQLErrors && error.graphQLErrors.find(gqlError => gqlError.message === 'Unauthorized')) {
97
+ console.log(`${_chalk.default.red('Error:')} You don't have the required permissions to run validations for this environment.\n` + `You must be either be an admin of the ${_chalk.default.bold.underline(application.organization.name)} organization, or, alternatively,\n` + `a guest of that organization and an admin of the ${_chalk.default.bold.underline(application.name)} application.\n\n` + 'You can read more about organization and application roles on our documentation:\n' + _chalk.default.underline('https://docs.wpvip.com/technical-references/enterprise-authentication/'));
98
+ await (0, _tracker.trackEvent)('validate_preflight_command_error', {
99
+ env_id: environment.id,
100
+ app_id: environment.appId,
101
+ error: 'unauthorized'
102
+ });
103
+ process.exit(1);
104
+ } else {
105
+ // Handle it elsewhere
106
+ throw error;
107
+ }
108
+ }
109
+ }
110
+ async function vipValidatePreflightCommand(arg, opt) {
111
+ var _opt$env$environmentV;
112
+ harmoniaArgs = await validateArgs(opt);
113
+ const baseTrackingParams = {
114
+ env_id: opt.env.id,
115
+ app_id: opt.env.appId,
116
+ command: 'vip validate preflight',
117
+ ...sanitizeArgsForTracking(harmoniaArgs)
118
+ };
119
+ await (0, _tracker.trackEvent)('validate_preflight_command_execute', baseTrackingParams);
120
+ logToConsole(' /\\ /\\__ _ _ __ _ __ ___ ___ _ __ (_) __ _ ');
121
+ logToConsole(' / /_/ / _` | \'__| \'_ ` _ \\ / _ \\| \'_ \\| |/ _` |');
122
+ logToConsole('/ __ / (_| | | | | | | | | (_) | | | | | (_| |');
123
+ logToConsole('\\/ /_/ \\__,_|_| |_| |_| |_|\\___/|_| |_|_|\\__,_|');
124
+ logToConsole('VIP Harmonia - Application testing made easy\n');
125
+ const harmonia = new _vipGoPreflightChecks.Harmonia();
126
+ harmonia.setSource('vip-cli');
127
+ if (harmoniaArgs.buildType !== 'nodejs') {
128
+ await (0, _tracker.trackEvent)('validate_preflight_command_error', {
129
+ ...baseTrackingParams,
130
+ error: 'not-nodejs'
131
+ });
132
+ exit.withError('Currently, only Node.js applications are supported.');
133
+ }
134
+
135
+ // Register the default tests.
136
+ harmonia.registerDefaultTests();
137
+
138
+ // Create the Site Config objects
139
+ const siteOptions = new _vipGoPreflightChecks.SiteConfig({
140
+ siteID: opt.app.id,
141
+ nodejsVersion: harmoniaArgs.nodejsVersion,
142
+ repository: opt.app.repo,
143
+ baseURL: 'http://localhost:' + harmoniaArgs.port,
144
+ dockerBuildEnvs: harmoniaArgs.nodeBuildDockerEnv,
145
+ topRequests: [],
146
+ // TODO: get top 10 of most requested URLs
147
+ wait: harmoniaArgs.wait
148
+ });
149
+
150
+ // Get package.json
151
+ const packageJSONfile = _path.default.resolve(opt.path, 'package.json');
152
+ let packageJSON;
153
+ try {
154
+ packageJSON = require(packageJSONfile);
155
+ siteOptions.setPackageJSON(packageJSON);
156
+ } catch (error) {
157
+ await (0, _tracker.trackEvent)('validate_preflight_command_error', {
158
+ ...baseTrackingParams,
159
+ error: 'missing-package-json'
160
+ });
161
+ return exit.withError(`Could not find a 'package.json' in the current folder (${opt.path}).`);
162
+ }
163
+ const customEnvVars = {};
164
+ if (((_opt$env$environmentV = opt.env.environmentVariables) === null || _opt$env$environmentV === void 0 ? void 0 : _opt$env$environmentV.nodes.length) > 0) {
165
+ opt.env.environmentVariables.nodes.forEach(envVar => {
166
+ customEnvVars[envVar.name] = envVar.value;
167
+ });
168
+ }
169
+
170
+ // Create the EnviornmentVariables object
171
+ const envVars = new _vipGoPreflightChecks.EnvironmentVariables({
172
+ PORT: harmoniaArgs.port,
173
+ ...customEnvVars
174
+ });
175
+
176
+ // Add NPM_TOKEN environment variable, if present
177
+ if (harmoniaArgs.npmToken) {
178
+ envVars.set('NPM_TOKEN', harmoniaArgs.npmToken);
179
+ }
180
+
181
+ // Get from .env, if exists
182
+ let dotenvOptions = {};
183
+ try {
184
+ const dotenvPath = _path.default.resolve(opt.path, '.env');
185
+ const dotenvContent = (0, _fs.readFileSync)(dotenvPath);
186
+ dotenvOptions = _ini.default.parse(dotenvContent);
187
+ } catch (error) {
188
+ // nothing
189
+ }
190
+
191
+ // Save dotenv in the site config
192
+ siteOptions.set('dotenv', dotenvOptions);
193
+
194
+ // Bootstrap
195
+ try {
196
+ harmonia.bootstrap(siteOptions, envVars);
197
+ } catch (error) {
198
+ await (0, _tracker.trackEvent)('validate_preflight_command_error', {
199
+ ...baseTrackingParams,
200
+ error: error.message
201
+ });
202
+ return exit.withError(error.message);
203
+ }
204
+ setupEvents(harmonia);
205
+ runHarmonia(harmonia);
206
+ }
207
+ function setupEvents(harmonia) {
208
+ // Register some events handlers
209
+ harmonia.on('ready', () => {
210
+ logToConsole('Harmonia is ready! ');
211
+ });
212
+
213
+ // Register the event handlers to output some information during the execution
214
+ harmonia.on('beforeTestSuite', suite => {
215
+ const description = suite.description ? `- ${_chalk.default.italic(suite.description)}` : '';
216
+ logToConsole(` >> Running test suite ${_chalk.default.bold(suite.name)} ${description} `);
217
+ logToConsole();
218
+ });
219
+ harmonia.on('beforeTest', test => {
220
+ logToConsole(` [ ${_chalk.default.bold(test.name)} ] - ${test.description}`);
221
+ });
222
+ harmonia.on('afterTest', (test, result) => {
223
+ switch (result.getType()) {
224
+ case _vipGoPreflightChecks.TestResultType.Success:
225
+ logToConsole(` ✅ ${_chalk.default.bgGreen(' Test passed with no errors. ')}`);
226
+ break;
227
+ case _vipGoPreflightChecks.TestResultType.Failed:
228
+ logToConsole(` ❌ ${_chalk.default.bgRed(` Test failed with ${result.getErrors().length} errors. `)}`);
229
+ break;
230
+ case _vipGoPreflightChecks.TestResultType.PartialSuccess:
231
+ logToConsole(` ✅ ${_chalk.default.bgYellow(' Test partially succeeded. ')}`);
232
+ break;
233
+ case _vipGoPreflightChecks.TestResultType.Aborted:
234
+ logToConsole(` ❌ ${_chalk.default.bgRedBright.underline(' Test aborted! ')} - There was a critical error that makes`, 'the application incompatible with the VIP Platform.');
235
+ break;
236
+ case _vipGoPreflightChecks.TestResultType.Skipped:
237
+ logToConsole(` ${_chalk.default.bgGrey.bold(' Skipped ')}\t${result.getLastNotice().message}`);
238
+ }
239
+ logToConsole();
240
+ });
241
+ harmonia.on('afterTestSuite', (test, result) => {
242
+ // Create a badge
243
+ let badge;
244
+ switch (result.getType()) {
245
+ case _vipGoPreflightChecks.TestResultType.Failed:
246
+ badge = _chalk.default.bgRed.bold(' FAILED ');
247
+ break;
248
+ case _vipGoPreflightChecks.TestResultType.Aborted:
249
+ badge = _chalk.default.bgRedBright.underline.bold(' ABORTED ');
250
+ break;
251
+ case _vipGoPreflightChecks.TestResultType.PartialSuccess:
252
+ badge = _chalk.default.bgYellow.bold(' PASS ');
253
+ break;
254
+ default:
255
+ badge = _chalk.default.bgGreen.bold(' PASS ');
256
+ break;
257
+ }
258
+ logToConsole(` >> ${badge} Finished running ${_chalk.default.bold(test.name)} suite`);
259
+ logToConsole();
260
+ });
261
+ harmonia.on('issue', issue => {
262
+ let issueTypeString = issue.getTypeString();
263
+ switch (issue.type) {
264
+ case _vipGoPreflightChecks.IssueType.Blocker:
265
+ issueTypeString = _chalk.default.bgRedBright.underline.bold(issueTypeString);
266
+ break;
267
+ case _vipGoPreflightChecks.IssueType.Error:
268
+ issueTypeString = _chalk.default.bgRed.bold(issueTypeString);
269
+ break;
270
+ case _vipGoPreflightChecks.IssueType.Warning:
271
+ issueTypeString = _chalk.default.bgYellow.bold(issueTypeString);
272
+ break;
273
+ case _vipGoPreflightChecks.IssueType.Notice:
274
+ issueTypeString = _chalk.default.bgGray.bold(issueTypeString);
275
+ break;
276
+ }
277
+ const documentation = issue.documentation ? `(${issue.documentation})` : '';
278
+
279
+ // Replace \n with \n\t\t to keep new lines aligned
280
+ const message = issue.message.replace(/\n/g, '\n\t\t');
281
+ logToConsole(` ${issueTypeString} \t${message} ${documentation}`);
282
+
283
+ // If it's a Blocker or Error, and the issue includes a stdout, print it out.
284
+ const issueData = issue.getData();
285
+ if (issueData && [_vipGoPreflightChecks.IssueType.Blocker, _vipGoPreflightChecks.IssueType.Error].includes(issue.type)) {
286
+ if (issueData.all) {
287
+ logToConsole(issueData.all);
288
+ logToConsole();
289
+ } else if (typeof issueData === 'string') {
290
+ logToConsole(issueData);
291
+ logToConsole();
292
+ }
293
+ }
294
+ });
295
+ }
296
+ function runHarmonia(harmonia) {
297
+ harmonia.run().then(async results => await handleResults(harmonia, results));
298
+ }
299
+ async function handleResults(harmonia, results) {
300
+ // Calculate the results
301
+ const resultCounter = harmonia.countResults(false);
302
+ const testSuiteResults = results.filter(result => result instanceof _vipGoPreflightChecks.TestSuiteResult);
303
+
304
+ // Send success event
305
+ await (0, _tracker.trackEvent)('validate_preflight_command_success', {
306
+ command: 'vip validate preflight',
307
+ ...sanitizeArgsForTracking(harmoniaArgs),
308
+ skipped: resultCounter[_vipGoPreflightChecks.TestResultType.Skipped],
309
+ success: resultCounter[_vipGoPreflightChecks.TestResultType.Success],
310
+ partial_success: resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess],
311
+ failed: resultCounter[_vipGoPreflightChecks.TestResultType.Failed],
312
+ aborted: resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]
313
+ });
314
+
315
+ // If the output is JSON, reenable the logToConsole output and print-out the json format.
316
+ if (outputJson) {
317
+ suppressOutput = false;
318
+ logToConsole(harmonia.resultsJSON());
319
+ process.exit(0);
320
+ }
321
+
322
+ // Print the results
323
+ logToConsole('\n' + _chalk.default.bgGray(' HARMONIA RESULTS \n'));
324
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Skipped]) {
325
+ logToConsole(` ${_chalk.default.bold.bgGrey(' SKIPPED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Skipped])} tests`);
326
+ }
327
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Success]) {
328
+ logToConsole(` ${_chalk.default.bold.bgGreen(' PASSED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Success])} tests`);
329
+ }
330
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess]) {
331
+ logToConsole(` ${_chalk.default.bold.bgYellow(' PARTIAL SUCCESS ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess])} tests`);
332
+ }
333
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
334
+ logToConsole(` ${_chalk.default.bold.bgRed(' FAILED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Failed])} tests`);
335
+ }
336
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
337
+ logToConsole(` ${_chalk.default.bold.bgRedBright(' ABORTED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Aborted])} tests`);
338
+ }
339
+ logToConsole();
340
+ logToConsole(` > Total of ${_chalk.default.bold(results.length - testSuiteResults.length)} tests have been executed.`);
341
+ logToConsole();
342
+
343
+ // If there is a Aborted test result
344
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
345
+ logToConsole(`${_chalk.default.bold.bgRedBright(' NOT PASS ')} There was a critical failure that makes the application ` + 'incompatible with VIP Go. Please review the results and re-run the tests.');
346
+ process.exit(1);
347
+ }
348
+
349
+ // If there is only a partial success, but no failures
350
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess] && !resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
351
+ logToConsole(`${_chalk.default.bold.bgYellow(' PASS ')} The application has passed the required tests, but it does not follow all the recommendations.`);
352
+ logToConsole('Please review the results.');
353
+ process.exit(0);
354
+ }
355
+
356
+ // If there is a failure
357
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
358
+ logToConsole(`${_chalk.default.bold.bgRed(' NOT PASS ')} The application has failed some tests, and will very likely have problems in a production ` + 'environment. Please review all the errors found in the results.');
359
+ process.exit(1);
360
+ }
361
+ logToConsole(`${_chalk.default.bold.bgGreen(' PASS ')} Congratulations. The application passes all the tests.`);
362
+ process.exit(0);
363
+ }
364
+ async function validateArgs(opt) {
365
+ var _opt$nodeVersion, _opt$wait, _opt$port;
366
+ const args = {};
367
+
368
+ // Verbose
369
+ if (opt.verbose) {
370
+ _vipGoPreflightChecks.Harmonia.setVerbosity(true);
371
+ }
372
+
373
+ // Set path
374
+ if (opt.path) {
375
+ _vipGoPreflightChecks.Harmonia.setCwd(opt.path);
376
+ }
377
+
378
+ // If the JSON option is enabled, all the stdout should be suppressed to prevent polluting the output.
379
+ if (opt.json) {
380
+ suppressOutput = true;
381
+ outputJson = true;
382
+ }
383
+
384
+ // Get build information from API and store it in the env object
385
+ const buildConfig = await getBuildConfiguration(opt.app, opt.env);
386
+ args.app_id = opt.app.id;
387
+ args.env_id = opt.env.id;
388
+ args.nodejsVersion = (_opt$nodeVersion = opt.nodeVersion) !== null && _opt$nodeVersion !== void 0 ? _opt$nodeVersion : buildConfig.nodeJSVersion;
389
+ args.buildType = buildConfig.buildType;
390
+ args.npmToken = buildConfig.npmToken;
391
+ args.nodeBuildDockerEnv = buildConfig.nodeBuildDockerEnv;
392
+ args.wait = (_opt$wait = opt.wait) !== null && _opt$wait !== void 0 ? _opt$wait : 3000;
393
+ args.port = (_opt$port = opt.port) !== null && _opt$port !== void 0 ? _opt$port : Math.floor(Math.random() * 1000) + 3001; // Get a PORT from 3001 and 3999
394
+
395
+ return args;
396
+ }
397
+
398
+ /**
399
+ * Remove sensitive information from the tracked events and snake_case the keys.
400
+ *
401
+ * @param {object} args The arguments passed to the command.
402
+ * @returns {object} Copy of the arguments without sensitive information.
403
+ */
404
+ function sanitizeArgsForTracking(args) {
405
+ const protectedKeys = ['npmToken', 'nodeBuildDockerEnv'];
406
+ const sanitizedArgs = {};
407
+ Object.entries(args).forEach(([key, value]) => {
408
+ if (protectedKeys.includes(key)) {
409
+ return;
410
+ }
411
+ // snake_case the key, as required by Tracks
412
+ sanitizedArgs[key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)] = value;
413
+ });
414
+ return sanitizedArgs;
415
+ }
416
+ (0, _command.default)({
417
+ appContext: true,
418
+ appQuery,
419
+ envContext: true,
420
+ module: 'harmonia'
421
+ }).option('verbose', 'Increase logging level to include app build and server boot up messages', false).option('node-version', 'Select a specific target Node.JS version in semver format (MAJOR.MINOR.PATCH) or a MAJOR').option('wait', 'Configure the time to wait in ms for the app to boot up. Do not change unless you have issues', 3000).option(['p', 'port'], 'Configure the port to use for the app (defaults to a random port between 3001 and 3999)').option('json', 'Output the results as JSON', false).option(['P', 'path'], 'Path to the app to be tested', process.cwd()).examples([{
422
+ usage: 'vip @mysite.production validate preflight',
423
+ description: 'Runs the preflight tests to validate if your application is ready to be deployed to VIP Go'
424
+ }, {
425
+ usage: 'vip @mysite.production validate preflight --json > results.json',
426
+ description: 'Runs the preflight tests, but output the results in JSON format, and redirect the output to a file'
427
+ }]).argv(process.argv, vipValidatePreflightCommand);
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ "use strict";
11
+
12
+ var _command = _interopRequireDefault(require("../lib/cli/command"));
13
+ var _tracker = require("../lib/tracker");
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ (0, _command.default)({
16
+ requiredArgs: 1
17
+ }).command('preflight', 'Runs preflight tests to validate if your application is ready to be deployed').argv(process.argv, async () => {
18
+ await (0, _tracker.trackEvent)('vip_validate_command_execute');
19
+ });
@@ -18,47 +18,35 @@ Object.defineProperty(exports, "__esModule", {
18
18
  value: true
19
19
  });
20
20
  exports.whoamiCommand = whoamiCommand;
21
-
22
21
  var _user = require("../lib/api/user");
23
-
24
22
  var _command = _interopRequireDefault(require("../lib/cli/command"));
25
-
26
23
  var _tracker = require("../lib/tracker");
27
-
28
24
  var exit = _interopRequireWildcard(require("../lib/cli/exit"));
29
-
30
25
  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); }
31
-
32
26
  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; }
33
-
34
27
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
-
36
28
  async function whoamiCommand() {
37
29
  const trackingParams = {
38
30
  command: 'vip whoami'
39
31
  };
40
32
  await (0, _tracker.trackEvent)('whoami_command_execute', trackingParams);
41
33
  let currentUser = {};
42
-
43
34
  try {
44
35
  currentUser = await (0, _user.getCurrentUserInfo)();
45
36
  } catch (err) {
46
- await (0, _tracker.trackEvent)('whoami_command_error', { ...trackingParams,
37
+ await (0, _tracker.trackEvent)('whoami_command_error', {
38
+ ...trackingParams,
47
39
  error: err.message
48
40
  });
49
41
  exit.withError(`Failed to fetch information about the currently logged-in user error: ${err.message}`);
50
42
  }
51
-
52
43
  await (0, _tracker.trackEvent)('whoami_command_success', trackingParams);
53
44
  const output = [`- Howdy ${currentUser.displayName}!`, `- Your user ID is ${currentUser.id}`];
54
-
55
45
  if (currentUser.isVIP) {
56
46
  output.push('- Your account has VIP Staff permissions');
57
47
  }
58
-
59
48
  console.log(output.join('\n'));
60
49
  }
61
-
62
50
  (0, _command.default)({
63
51
  usage: 'vip whoami'
64
52
  }).examples([{