@automattic/vip 2.22.0 → 2.24.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 (110) hide show
  1. package/CHANGELOG.md +38 -13
  2. package/assets/dev-env.lando.template.yml.ejs +6 -1
  3. package/dist/bin/vip-app-list.js +0 -12
  4. package/dist/bin/vip-app.js +6 -13
  5. package/dist/bin/vip-cache-purge-url.js +4 -19
  6. package/dist/bin/vip-cache.js +0 -2
  7. package/dist/bin/vip-config-envvar-delete.js +4 -19
  8. package/dist/bin/vip-config-envvar-get-all.js +6 -19
  9. package/dist/bin/vip-config-envvar-get.js +4 -15
  10. package/dist/bin/vip-config-envvar-list.js +8 -20
  11. package/dist/bin/vip-config-envvar-set.js +4 -23
  12. package/dist/bin/vip-config-envvar.js +0 -2
  13. package/dist/bin/vip-config-software-get.js +0 -17
  14. package/dist/bin/vip-config-software-update.js +6 -22
  15. package/dist/bin/vip-config-software.js +0 -2
  16. package/dist/bin/vip-config.js +0 -2
  17. package/dist/bin/vip-dev-env-create.js +8 -21
  18. package/dist/bin/vip-dev-env-destroy.js +4 -11
  19. package/dist/bin/vip-dev-env-exec.js +4 -14
  20. package/dist/bin/vip-dev-env-import-media.js +3 -8
  21. package/dist/bin/vip-dev-env-import-sql.js +10 -23
  22. package/dist/bin/vip-dev-env-import.js +0 -3
  23. package/dist/bin/vip-dev-env-info.js +5 -13
  24. package/dist/bin/vip-dev-env-list.js +4 -9
  25. package/dist/bin/vip-dev-env-start.js +9 -17
  26. package/dist/bin/vip-dev-env-stop.js +4 -11
  27. package/dist/bin/vip-dev-env-update.js +4 -12
  28. package/dist/bin/vip-dev-env.js +0 -2
  29. package/dist/bin/vip-import-media-abort.js +0 -18
  30. package/dist/bin/vip-import-media-status.js +0 -12
  31. package/dist/bin/vip-import-media.js +6 -23
  32. package/dist/bin/vip-import-sql-status.js +0 -12
  33. package/dist/bin/vip-import-sql.js +33 -99
  34. package/dist/bin/vip-import-validate-files.js +21 -42
  35. package/dist/bin/vip-import-validate-sql.js +0 -8
  36. package/dist/bin/vip-import.js +0 -3
  37. package/dist/bin/vip-logs.js +20 -50
  38. package/dist/bin/vip-search-replace.js +8 -14
  39. package/dist/bin/vip-sync.js +2 -25
  40. package/dist/bin/vip-validate-preflight.js +467 -0
  41. package/dist/bin/vip-validate.js +19 -0
  42. package/dist/bin/vip-whoami.js +2 -14
  43. package/dist/bin/vip-wp.js +39 -89
  44. package/dist/bin/vip.js +14 -40
  45. package/dist/lib/analytics/clients/pendo.js +9 -18
  46. package/dist/lib/analytics/clients/stub.js +1 -3
  47. package/dist/lib/analytics/clients/tracks.js +11 -20
  48. package/dist/lib/analytics/index.js +4 -11
  49. package/dist/lib/api/app.js +1 -11
  50. package/dist/lib/api/cache-purge.js +4 -7
  51. package/dist/lib/api/feature-flags.js +1 -4
  52. package/dist/lib/api/http.js +9 -15
  53. package/dist/lib/api/user.js +1 -7
  54. package/dist/lib/api.js +7 -18
  55. package/dist/lib/app-logs/app-logs.js +2 -9
  56. package/dist/lib/app.js +2 -5
  57. package/dist/lib/cli/apiConfig.js +4 -19
  58. package/dist/lib/cli/command.js +43 -133
  59. package/dist/lib/cli/config.js +1 -5
  60. package/dist/lib/cli/envAlias.js +14 -15
  61. package/dist/lib/cli/exit.js +4 -6
  62. package/dist/lib/cli/format.js +8 -50
  63. package/dist/lib/cli/progress.js +13 -42
  64. package/dist/lib/cli/prompt.js +1 -5
  65. package/dist/lib/cli/repo.js +7 -20
  66. package/dist/lib/client-file-uploader.js +44 -97
  67. package/dist/lib/config/software.js +2 -52
  68. package/dist/lib/constants/dev-environment.js +1 -2
  69. package/dist/lib/constants/file-size.js +1 -1
  70. package/dist/lib/constants/vipgo.js +1 -1
  71. package/dist/lib/dev-environment/dev-environment-cli.js +140 -195
  72. package/dist/lib/dev-environment/dev-environment-core.js +91 -186
  73. package/dist/lib/dev-environment/dev-environment-lando.js +32 -96
  74. package/dist/lib/env.js +1 -4
  75. package/dist/lib/envvar/api-delete.js +1 -4
  76. package/dist/lib/envvar/api-get-all.js +1 -4
  77. package/dist/lib/envvar/api-get.js +1 -2
  78. package/dist/lib/envvar/api-list.js +3 -4
  79. package/dist/lib/envvar/api-set.js +1 -4
  80. package/dist/lib/envvar/api.js +5 -16
  81. package/dist/lib/envvar/input.js +1 -8
  82. package/dist/lib/envvar/logging.js +2 -6
  83. package/dist/lib/envvar/read-file.js +1 -3
  84. package/dist/lib/http/proxy-agent.js +17 -22
  85. package/dist/lib/keychain/browser.js +1 -4
  86. package/dist/lib/keychain/insecure.js +1 -10
  87. package/dist/lib/keychain/secure.js +1 -8
  88. package/dist/lib/keychain.js +4 -8
  89. package/dist/lib/logout.js +0 -6
  90. package/dist/lib/media-import/media-file-import.js +3 -7
  91. package/dist/lib/media-import/progress.js +6 -17
  92. package/dist/lib/media-import/status.js +14 -65
  93. package/dist/lib/read-file.js +1 -6
  94. package/dist/lib/rollbar.js +1 -7
  95. package/dist/lib/search-and-replace.js +9 -41
  96. package/dist/lib/site-import/db-file-import.js +3 -9
  97. package/dist/lib/site-import/status.js +17 -74
  98. package/dist/lib/token.js +1 -33
  99. package/dist/lib/tracker.js +4 -20
  100. package/dist/lib/user-error.js +0 -2
  101. package/dist/lib/validations/is-multi-site-sql-dump.js +4 -12
  102. package/dist/lib/validations/is-multi-site.js +5 -21
  103. package/dist/lib/validations/is-multisite-domain-mapped.js +5 -31
  104. package/dist/lib/validations/line-by-line.js +4 -16
  105. package/dist/lib/validations/site-type.js +10 -19
  106. package/dist/lib/validations/sql.js +11 -76
  107. package/dist/lib/validations/utils.js +1 -6
  108. package/dist/lib/vip-import-validate-files.js +82 -109
  109. package/npm-shrinkwrap.json +894 -357
  110. package/package.json +5 -2
@@ -0,0 +1,467 @@
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 _enquirer = require("enquirer");
20
+ var _command = _interopRequireDefault(require("../lib/cli/command"));
21
+ var _envAlias = require("../lib/cli/envAlias");
22
+ var exit = _interopRequireWildcard(require("../lib/cli/exit"));
23
+ var _api = _interopRequireWildcard(require("../lib/api"));
24
+ var _tracker = require("../lib/tracker");
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); }
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; }
27
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28
+ /**
29
+ * Internal dependencies
30
+ */
31
+ const ALLOWED_NODEJS_VERSIONS = ['14', '16', '18'];
32
+ const appQuery = `
33
+ id
34
+ name
35
+ repo
36
+ environments {
37
+ id
38
+ appId
39
+ name
40
+ type
41
+ environmentVariables {
42
+ nodes {
43
+ name,
44
+ value
45
+ }
46
+ }
47
+ }
48
+ organization {
49
+ id
50
+ name
51
+ }
52
+ `;
53
+ exports.appQuery = appQuery;
54
+ let suppressOutput = false;
55
+ let outputJson = false;
56
+ let harmoniaArgs = [];
57
+ function logToConsole(...messages) {
58
+ if (suppressOutput) {
59
+ return;
60
+ }
61
+ if (messages.length === 0) {
62
+ messages = [''];
63
+ }
64
+ messages.forEach(message => console.log(message));
65
+ }
66
+ async function getBuildConfiguration(application, environment) {
67
+ const api = await (0, _api.default)();
68
+
69
+ // Disable the global GraphQL error handling, so we can catch Unauthorized errors and recommend next steps.
70
+ (0, _api.disableGlobalGraphQLErrorHandling)();
71
+ const buildConfigQuery = (0, _graphqlTag.default)`
72
+ query BuildConfig( $appId: Int, $envId: Int ) {
73
+ app(id: $appId) {
74
+ environments(id: $envId) {
75
+ id,
76
+ buildConfiguration {
77
+ buildType
78
+ nodeBuildDockerEnv,
79
+ nodeJSVersion,
80
+ npmToken,
81
+ }
82
+ }
83
+ }
84
+ }`;
85
+ try {
86
+ const result = await api.query({
87
+ query: buildConfigQuery,
88
+ fetchPolicy: 'network-only',
89
+ variables: {
90
+ appId: environment.appId,
91
+ envId: environment.id
92
+ }
93
+ });
94
+
95
+ // Reenable GraphQL error handling
96
+ (0, _api.enableGlobalGraphQLErrorHandling)();
97
+ return result.data.app.environments[0].buildConfiguration;
98
+ } catch (error) {
99
+ if (error.graphQLErrors && error.graphQLErrors.find(gqlError => gqlError.message === 'Unauthorized')) {
100
+ 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/'));
101
+ await (0, _tracker.trackEvent)('validate_preflight_command_error', {
102
+ env_id: environment.id,
103
+ app_id: environment.appId,
104
+ error: 'unauthorized'
105
+ });
106
+ process.exit(1);
107
+ } else {
108
+ // Handle it elsewhere
109
+ throw error;
110
+ }
111
+ }
112
+ }
113
+ async function vipValidatePreflightCommand(arg, opt) {
114
+ var _opt$env$appId, _opt$env, _opt$env$id, _opt$env2, _opt$app$repo, _opt$app, _opt$env3, _opt$env3$environment;
115
+ harmoniaArgs = await validateArgs(opt);
116
+ const appId = (_opt$env$appId = (_opt$env = opt.env) === null || _opt$env === void 0 ? void 0 : _opt$env.appId) !== null && _opt$env$appId !== void 0 ? _opt$env$appId : 0;
117
+ const envId = (_opt$env$id = (_opt$env2 = opt.env) === null || _opt$env2 === void 0 ? void 0 : _opt$env2.id) !== null && _opt$env$id !== void 0 ? _opt$env$id : 0;
118
+ const baseTrackingParams = {
119
+ env_id: envId,
120
+ app_id: appId,
121
+ command: 'vip validate preflight',
122
+ ...sanitizeArgsForTracking(harmoniaArgs)
123
+ };
124
+ await (0, _tracker.trackEvent)('validate_preflight_command_execute', baseTrackingParams);
125
+ logToConsole(' /\\ /\\__ _ _ __ _ __ ___ ___ _ __ (_) __ _ ');
126
+ logToConsole(' / /_/ / _` | \'__| \'_ ` _ \\ / _ \\| \'_ \\| |/ _` |');
127
+ logToConsole('/ __ / (_| | | | | | | | | (_) | | | | | (_| |');
128
+ logToConsole('\\/ /_/ \\__,_|_| |_| |_| |_|\\___/|_| |_|_|\\__,_|');
129
+ logToConsole('VIP Harmonia - Application testing made easy\n');
130
+ const harmonia = new _vipGoPreflightChecks.Harmonia();
131
+ harmonia.setSource('vip-cli');
132
+ if (harmoniaArgs.buildType !== 'nodejs') {
133
+ await (0, _tracker.trackEvent)('validate_preflight_command_error', {
134
+ ...baseTrackingParams,
135
+ error: 'not-nodejs'
136
+ });
137
+ exit.withError('Currently, only Node.js applications are supported.');
138
+ }
139
+
140
+ // Register the default tests.
141
+ harmonia.registerDefaultTests();
142
+
143
+ // Create the Site Config objects
144
+ const siteOptions = new _vipGoPreflightChecks.SiteConfig({
145
+ siteID: envId,
146
+ nodejsVersion: harmoniaArgs.nodejsVersion,
147
+ repository: (_opt$app$repo = (_opt$app = opt.app) === null || _opt$app === void 0 ? void 0 : _opt$app.repo) !== null && _opt$app$repo !== void 0 ? _opt$app$repo : 'no-repo',
148
+ baseURL: 'http://localhost:' + harmoniaArgs.port,
149
+ dockerBuildEnvs: harmoniaArgs.nodeBuildDockerEnv,
150
+ topRequests: [],
151
+ // TODO: get top 10 of most requested URLs
152
+ wait: harmoniaArgs.wait
153
+ });
154
+
155
+ // Get package.json
156
+ const packageJSONfile = _path.default.resolve(opt.path, 'package.json');
157
+ let packageJSON;
158
+ try {
159
+ packageJSON = require(packageJSONfile);
160
+ siteOptions.setPackageJSON(packageJSON);
161
+ } catch (error) {
162
+ await (0, _tracker.trackEvent)('validate_preflight_command_error', {
163
+ ...baseTrackingParams,
164
+ error: 'missing-package-json'
165
+ });
166
+ return exit.withError(`Could not find a 'package.json' in the current folder (${opt.path}).`);
167
+ }
168
+ const customEnvVars = {};
169
+ if (((_opt$env3 = opt.env) === null || _opt$env3 === void 0 ? void 0 : (_opt$env3$environment = _opt$env3.environmentVariables) === null || _opt$env3$environment === void 0 ? void 0 : _opt$env3$environment.nodes.length) > 0) {
170
+ opt.env.environmentVariables.nodes.forEach(envVar => {
171
+ customEnvVars[envVar.name] = envVar.value;
172
+ });
173
+ }
174
+
175
+ // Create the EnviornmentVariables object
176
+ const envVars = new _vipGoPreflightChecks.EnvironmentVariables({
177
+ PORT: harmoniaArgs.port,
178
+ ...customEnvVars
179
+ });
180
+
181
+ // Add NPM_TOKEN environment variable, if present
182
+ if (harmoniaArgs.npmToken) {
183
+ envVars.set('NPM_TOKEN', harmoniaArgs.npmToken);
184
+ }
185
+
186
+ // Get from .env, if exists
187
+ let dotenvOptions = {};
188
+ try {
189
+ const dotenvPath = _path.default.resolve(opt.path, '.env');
190
+ const dotenvContent = (0, _fs.readFileSync)(dotenvPath);
191
+ dotenvOptions = _ini.default.parse(dotenvContent);
192
+ } catch (error) {
193
+ // nothing
194
+ }
195
+
196
+ // Save dotenv in the site config
197
+ siteOptions.set('dotenv', dotenvOptions);
198
+
199
+ // Bootstrap
200
+ try {
201
+ harmonia.bootstrap(siteOptions, envVars);
202
+ } catch (error) {
203
+ await (0, _tracker.trackEvent)('validate_preflight_command_error', {
204
+ ...baseTrackingParams,
205
+ error: error.message
206
+ });
207
+ return exit.withError(error.message);
208
+ }
209
+ setupEvents(harmonia);
210
+ runHarmonia(harmonia);
211
+ }
212
+ function setupEvents(harmonia) {
213
+ // Register some events handlers
214
+ harmonia.on('ready', () => {
215
+ logToConsole('Harmonia is ready! ');
216
+ });
217
+
218
+ // Register the event handlers to output some information during the execution
219
+ harmonia.on('beforeTestSuite', suite => {
220
+ const description = suite.description ? `- ${_chalk.default.italic(suite.description)}` : '';
221
+ logToConsole(` >> Running test suite ${_chalk.default.bold(suite.name)} ${description} `);
222
+ logToConsole();
223
+ });
224
+ harmonia.on('beforeTest', test => {
225
+ logToConsole(` [ ${_chalk.default.bold(test.name)} ] - ${test.description}`);
226
+ });
227
+ harmonia.on('afterTest', (test, result) => {
228
+ switch (result.getType()) {
229
+ case _vipGoPreflightChecks.TestResultType.Success:
230
+ logToConsole(` ✅ ${_chalk.default.bgGreen(' Test passed with no errors. ')}`);
231
+ break;
232
+ case _vipGoPreflightChecks.TestResultType.Failed:
233
+ logToConsole(` ❌ ${_chalk.default.bgRed(` Test failed with ${result.getErrors().length} errors. `)}`);
234
+ break;
235
+ case _vipGoPreflightChecks.TestResultType.PartialSuccess:
236
+ logToConsole(` ✅ ${_chalk.default.bgYellow(' Test partially succeeded. ')}`);
237
+ break;
238
+ case _vipGoPreflightChecks.TestResultType.Aborted:
239
+ logToConsole(` ❌ ${_chalk.default.bgRedBright.underline(' Test aborted! ')} - There was a critical error that makes`, 'the application incompatible with the VIP Platform.');
240
+ break;
241
+ case _vipGoPreflightChecks.TestResultType.Skipped:
242
+ logToConsole(` ${_chalk.default.bgGrey.bold(' Skipped ')}\t${result.getLastNotice().message}`);
243
+ }
244
+ logToConsole();
245
+ });
246
+ harmonia.on('afterTestSuite', (test, result) => {
247
+ // Create a badge
248
+ let badge;
249
+ switch (result.getType()) {
250
+ case _vipGoPreflightChecks.TestResultType.Failed:
251
+ badge = _chalk.default.bgRed.bold(' FAILED ');
252
+ break;
253
+ case _vipGoPreflightChecks.TestResultType.Aborted:
254
+ badge = _chalk.default.bgRedBright.underline.bold(' ABORTED ');
255
+ break;
256
+ case _vipGoPreflightChecks.TestResultType.PartialSuccess:
257
+ badge = _chalk.default.bgYellow.bold(' PASS ');
258
+ break;
259
+ default:
260
+ badge = _chalk.default.bgGreen.bold(' PASS ');
261
+ break;
262
+ }
263
+ logToConsole(` >> ${badge} Finished running ${_chalk.default.bold(test.name)} suite`);
264
+ logToConsole();
265
+ });
266
+ harmonia.on('issue', issue => {
267
+ let issueTypeString = issue.getTypeString();
268
+ switch (issue.type) {
269
+ case _vipGoPreflightChecks.IssueType.Blocker:
270
+ issueTypeString = _chalk.default.bgRedBright.underline.bold(issueTypeString);
271
+ break;
272
+ case _vipGoPreflightChecks.IssueType.Error:
273
+ issueTypeString = _chalk.default.bgRed.bold(issueTypeString);
274
+ break;
275
+ case _vipGoPreflightChecks.IssueType.Warning:
276
+ issueTypeString = _chalk.default.bgYellow.bold(issueTypeString);
277
+ break;
278
+ case _vipGoPreflightChecks.IssueType.Notice:
279
+ issueTypeString = _chalk.default.bgGray.bold(issueTypeString);
280
+ break;
281
+ }
282
+ const documentation = issue.documentation ? `(${issue.documentation})` : '';
283
+
284
+ // Replace \n with \n\t\t to keep new lines aligned
285
+ const message = issue.message.replace(/\n/g, '\n\t\t');
286
+ logToConsole(` ${issueTypeString} \t${message} ${documentation}`);
287
+
288
+ // If it's a Blocker or Error, and the issue includes a stdout, print it out.
289
+ const issueData = issue.getData();
290
+ if (issueData && [_vipGoPreflightChecks.IssueType.Blocker, _vipGoPreflightChecks.IssueType.Error].includes(issue.type)) {
291
+ if (issueData.all) {
292
+ logToConsole(issueData.all);
293
+ logToConsole();
294
+ } else if (typeof issueData === 'string') {
295
+ logToConsole(issueData);
296
+ logToConsole();
297
+ }
298
+ }
299
+ });
300
+ }
301
+ function runHarmonia(harmonia) {
302
+ harmonia.run().then(async results => await handleResults(harmonia, results));
303
+ }
304
+ async function handleResults(harmonia, results) {
305
+ // Calculate the results
306
+ const resultCounter = harmonia.countResults(false);
307
+ const testSuiteResults = results.filter(result => result instanceof _vipGoPreflightChecks.TestSuiteResult);
308
+
309
+ // Send success event
310
+ await (0, _tracker.trackEvent)('validate_preflight_command_success', {
311
+ command: 'vip validate preflight',
312
+ ...sanitizeArgsForTracking(harmoniaArgs),
313
+ skipped: resultCounter[_vipGoPreflightChecks.TestResultType.Skipped],
314
+ success: resultCounter[_vipGoPreflightChecks.TestResultType.Success],
315
+ partial_success: resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess],
316
+ failed: resultCounter[_vipGoPreflightChecks.TestResultType.Failed],
317
+ aborted: resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]
318
+ });
319
+
320
+ // If the output is JSON, reenable the logToConsole output and print-out the json format.
321
+ if (outputJson) {
322
+ suppressOutput = false;
323
+ logToConsole(harmonia.resultsJSON());
324
+ process.exit(0);
325
+ }
326
+
327
+ // Print the results
328
+ logToConsole('\n' + _chalk.default.bgGray(' HARMONIA RESULTS \n'));
329
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Skipped]) {
330
+ logToConsole(` ${_chalk.default.bold.bgGrey(' SKIPPED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Skipped])} tests`);
331
+ }
332
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Success]) {
333
+ logToConsole(` ${_chalk.default.bold.bgGreen(' PASSED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Success])} tests`);
334
+ }
335
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess]) {
336
+ logToConsole(` ${_chalk.default.bold.bgYellow(' PARTIAL SUCCESS ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess])} tests`);
337
+ }
338
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
339
+ logToConsole(` ${_chalk.default.bold.bgRed(' FAILED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Failed])} tests`);
340
+ }
341
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
342
+ logToConsole(` ${_chalk.default.bold.bgRedBright(' ABORTED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Aborted])} tests`);
343
+ }
344
+ logToConsole();
345
+ logToConsole(` > Total of ${_chalk.default.bold(results.length - testSuiteResults.length)} tests have been executed.`);
346
+ logToConsole();
347
+
348
+ // If there is a Aborted test result
349
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
350
+ 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.');
351
+ process.exit(1);
352
+ }
353
+
354
+ // If there is only a partial success, but no failures
355
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess] && !resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
356
+ logToConsole(`${_chalk.default.bold.bgYellow(' PASS ')} The application has passed the required tests, but it does not follow all the recommendations.`);
357
+ logToConsole('Please review the results.');
358
+ process.exit(0);
359
+ }
360
+
361
+ // If there is a failure
362
+ if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
363
+ 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.');
364
+ process.exit(1);
365
+ }
366
+ logToConsole(`${_chalk.default.bold.bgGreen(' PASS ')} Congratulations. The application passes all the tests.`);
367
+ process.exit(0);
368
+ }
369
+ async function validateArgs(opt) {
370
+ var _opt$wait, _opt$port;
371
+ const args = {};
372
+
373
+ // Verbose
374
+ if (opt.verbose) {
375
+ _vipGoPreflightChecks.Harmonia.setVerbosity(true);
376
+ }
377
+
378
+ // Set path
379
+ if (opt.path) {
380
+ _vipGoPreflightChecks.Harmonia.setCwd(opt.path);
381
+ }
382
+
383
+ // If the JSON option is enabled, all the stdout should be suppressed to prevent polluting the output.
384
+ if (opt.json) {
385
+ suppressOutput = true;
386
+ outputJson = true;
387
+ }
388
+ if (opt.app) {
389
+ var _opt$nodeVersion;
390
+ // Get build information from API and store it in the env object
391
+ const buildConfig = await getBuildConfiguration(opt.app, opt.env);
392
+ args.app_id = opt.app.id;
393
+ args.env_id = opt.env.id;
394
+ args.nodejsVersion = (_opt$nodeVersion = opt.nodeVersion) !== null && _opt$nodeVersion !== void 0 ? _opt$nodeVersion : buildConfig.nodeJSVersion;
395
+ args.buildType = buildConfig.buildType;
396
+ args.npmToken = buildConfig.npmToken;
397
+ args.nodeBuildDockerEnv = buildConfig.nodeBuildDockerEnv;
398
+ } else {
399
+ args.app_id = 0;
400
+ args.env_id = 0;
401
+ args.buildType = 'nodejs';
402
+
403
+ // If no node.js version is specified, prompt the user to select one
404
+ if (!opt.nodeVersion) {
405
+ // Ask for a node.js version
406
+ try {
407
+ const selection = await (0, _enquirer.prompt)({
408
+ type: 'select',
409
+ name: 'nodejsVersion',
410
+ message: 'Which Node.js version do you want to use?',
411
+ choices: ALLOWED_NODEJS_VERSIONS
412
+ });
413
+ args.nodejsVersion = selection.nodejsVersion;
414
+ } catch (err) {
415
+ exit.withError('No Node.js version selected. Aborting.');
416
+ }
417
+ } else {
418
+ args.nodejsVersion = opt.nodeVersion;
419
+ }
420
+ }
421
+ args.wait = (_opt$wait = opt.wait) !== null && _opt$wait !== void 0 ? _opt$wait : 3000;
422
+ 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
423
+
424
+ return args;
425
+ }
426
+
427
+ /**
428
+ * Remove sensitive information from the tracked events and snake_case the keys.
429
+ *
430
+ * @param {object} args The arguments passed to the command.
431
+ * @returns {object} Copy of the arguments without sensitive information.
432
+ */
433
+ function sanitizeArgsForTracking(args) {
434
+ const protectedKeys = ['npmToken', 'nodeBuildDockerEnv'];
435
+ const sanitizedArgs = {};
436
+ Object.entries(args).forEach(([key, value]) => {
437
+ if (protectedKeys.includes(key)) {
438
+ return;
439
+ }
440
+ // snake_case the key, as required by Tracks
441
+ sanitizedArgs[key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)] = value;
442
+ });
443
+ return sanitizedArgs;
444
+ }
445
+ let commandOpts = {
446
+ module: 'harmonia'
447
+ };
448
+
449
+ // The @app.env selector is optional, so we need to check if it was passed
450
+ const parsedAlias = (0, _envAlias.parseEnvAliasFromArgv)(process.argv);
451
+ if (parsedAlias.app) {
452
+ commandOpts = {
453
+ ...commandOpts,
454
+ appQuery,
455
+ envContext: true,
456
+ appContext: true
457
+ };
458
+ } else {
459
+ logToConsole(_chalk.default.bold.yellow('Warning: ') + 'The preflight tests are running without a provided application and/or environment.\n' + 'Some app-dependent configurations, such as environment variables, might not defined.');
460
+ }
461
+ (0, _command.default)(commandOpts).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([{
462
+ usage: 'vip @mysite.production validate preflight',
463
+ description: 'Runs the preflight tests to validate if your application is ready to be deployed to VIP Go'
464
+ }, {
465
+ usage: 'vip @mysite.production validate preflight --json > results.json',
466
+ description: 'Runs the preflight tests, but output the results in JSON format, and redirect the output to a file'
467
+ }]).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([{