@automattic/vip 3.17.1 → 3.19.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 (46) hide show
  1. package/assets/dev-env.lando.template.yml.ejs +1 -1
  2. package/dist/bin/vip-config-envvar-delete.js +1 -0
  3. package/dist/bin/vip-config-envvar-get-all.js +2 -1
  4. package/dist/bin/vip-config-envvar-get.js +1 -0
  5. package/dist/bin/vip-config-envvar-list.js +2 -1
  6. package/dist/bin/vip-config-envvar-set.js +1 -0
  7. package/dist/bin/vip-dev-env-envvar-delete.js +55 -0
  8. package/dist/bin/vip-dev-env-envvar-get-all.js +51 -0
  9. package/dist/bin/vip-dev-env-envvar-get.js +43 -0
  10. package/dist/bin/vip-dev-env-envvar-list.js +46 -0
  11. package/dist/bin/vip-dev-env-envvar-set.js +78 -0
  12. package/dist/bin/vip-dev-env-envvar.js +27 -0
  13. package/dist/bin/vip-dev-env.js +1 -1
  14. package/dist/bin/vip-import-media.js +1 -1
  15. package/dist/bin/vip-import-sql.js +5 -20
  16. package/dist/bin/vip-logs.js +1 -0
  17. package/dist/bin/vip-slowlogs.js +1 -0
  18. package/dist/bin/vip.js +1 -1
  19. package/dist/commands/backup-db.js +2 -5
  20. package/dist/commands/dev-env-sync-sql.js +13 -4
  21. package/dist/commands/phpmyadmin.js +2 -5
  22. package/dist/commands/wp-ssh.js +3 -5
  23. package/dist/lib/analytics/clients/pendo.js +3 -1
  24. package/dist/lib/analytics/clients/tracks.js +0 -1
  25. package/dist/lib/analytics/index.js +0 -1
  26. package/dist/lib/api/http.js +2 -0
  27. package/dist/lib/api/user.js +1 -0
  28. package/dist/lib/backup-storage-availability/backup-storage-availability.js +0 -1
  29. package/dist/lib/cli/format.js +1 -22
  30. package/dist/lib/custom-deploy/custom-deploy.js +2 -2
  31. package/dist/lib/database.js +6 -6
  32. package/dist/lib/dev-environment/dev-environment-cli.js +7 -5
  33. package/dist/lib/dev-environment/dev-environment-core.js +9 -4
  34. package/dist/lib/dev-environment/dev-environment-database.js +4 -0
  35. package/dist/lib/dev-environment/dev-environment-lando.js +37 -17
  36. package/dist/lib/dev-environment/env-vars.js +75 -0
  37. package/dist/lib/keychain/insecure.js +0 -1
  38. package/dist/lib/media-import/config.js +1 -1
  39. package/dist/lib/site-import/status.js +2 -7
  40. package/dist/lib/validations/is-multisite-domain-mapped.js +3 -2
  41. package/dist/lib/validations/line-by-line.js +1 -1
  42. package/docs/CHANGELOG.md +55 -0
  43. package/npm-shrinkwrap.json +3623 -3854
  44. package/package.json +18 -15
  45. package/dist/bin/vip-validate-preflight.js +0 -481
  46. package/dist/bin/vip-validate.js +0 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "3.17.1",
3
+ "version": "3.19.0",
4
4
  "description": "The VIP Javascript library & CLI",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -29,6 +29,12 @@
29
29
  "vip-dev-env-create": "dist/bin/vip-dev-env-create.js",
30
30
  "vip-dev-env-update": "dist/bin/vip-dev-env-update.js",
31
31
  "vip-dev-env-destroy": "dist/bin/vip-dev-env-destroy.js",
32
+ "vip-dev-env-envvar": "dist/bin/vip-dev-env-envvar.js",
33
+ "vip-dev-env-envvar-delete": "dist/bin/vip-dev-env-envvar-delete.js",
34
+ "vip-dev-env-envvar-get": "dist/bin/vip-dev-env-envvar-get.js",
35
+ "vip-dev-env-envvar-get-all": "dist/bin/vip-dev-env-envvar-get-all.js",
36
+ "vip-dev-env-envvar-list": "dist/bin/vip-dev-env-envvar-list.js",
37
+ "vip-dev-env-envvar-set": "dist/bin/vip-dev-env-envvar-set.js",
32
38
  "vip-dev-env-exec": "dist/bin/vip-dev-env-exec.js",
33
39
  "vip-dev-env-import": "dist/bin/vip-dev-env-import.js",
34
40
  "vip-dev-env-import-media": "dist/bin/vip-dev-env-import-media.js",
@@ -56,8 +62,6 @@
56
62
  "vip-search-replace": "dist/bin/vip-search-replace.js",
57
63
  "vip-slowlogs": "dist/bin/vip-slowlogs.js",
58
64
  "vip-sync": "dist/bin/vip-sync.js",
59
- "vip-validate": "dist/bin/vip-validate.js",
60
- "vip-validate-preflight": "dist/bin/vip-validate-preflight.js",
61
65
  "vip-whoami": "dist/bin/vip-whoami.js",
62
66
  "vip-wp": "dist/bin/vip-wp.js",
63
67
  "vip-logout": "dist/bin/vip-logout.js"
@@ -108,21 +112,21 @@
108
112
  "homepage": "https://github.com/Automattic/vip#readme",
109
113
  "devDependencies": {
110
114
  "@automattic/eslint-plugin-wpvip": "0.13.1",
111
- "@babel/cli": "7.27.2",
112
- "@babel/core": "7.27.4",
113
- "@babel/preset-env": "7.27.2",
115
+ "@babel/cli": "7.28.0",
116
+ "@babel/core": "7.28.0",
117
+ "@babel/preset-env": "7.28.0",
114
118
  "@babel/preset-typescript": "7.27.1",
115
- "@jest/globals": "^29.7.0",
116
- "@jest/test-sequencer": "^29.7.0",
119
+ "@jest/globals": "^30.0.0",
120
+ "@jest/test-sequencer": "^30.0.0",
117
121
  "@types/args": "^5.0.3",
118
122
  "@types/cli-table": "^0.3.4",
119
123
  "@types/configstore": "5.0.1",
120
124
  "@types/debug": "^4.1.12",
121
125
  "@types/dockerode": "^3.3.23",
122
126
  "@types/ejs": "^3.1.5",
123
- "@types/jest": "^29.5.8",
127
+ "@types/jest": "^30.0.0",
124
128
  "@types/js-yaml": "^4.0.9",
125
- "@types/node": "^22.5.5",
129
+ "@types/node": "^24.0.0",
126
130
  "@types/node-fetch": "^2.6.9",
127
131
  "@types/proxy-from-env": "^1.0.4",
128
132
  "@types/semver": "^7.5.5",
@@ -133,7 +137,7 @@
133
137
  "@types/xml2js": "^0.4.14",
134
138
  "dockerode": "^4.0.0",
135
139
  "eslint": "^8.35.0",
136
- "jest": "^29.7.0",
140
+ "jest": "^30.0.0",
137
141
  "nock": "13.5.6",
138
142
  "prettier": "npm:wp-prettier@2.8.5",
139
143
  "rimraf": "6.0.1",
@@ -141,7 +145,6 @@
141
145
  },
142
146
  "dependencies": {
143
147
  "@apollo/client": "3.3.6",
144
- "@automattic/vip-go-preflight-checks": "^2.0.16",
145
148
  "@automattic/vip-search-replace": "^1.1.1",
146
149
  "@json2csv/plainjs": "^7.0.3",
147
150
  "@wwa/single-line-log": "^1.1.4",
@@ -157,11 +160,11 @@
157
160
  "fetch-retry": "^6.0.0",
158
161
  "graphql": "15.5.1",
159
162
  "graphql-tag": "2.12.6",
160
- "https-proxy-agent": "^5.0.1",
163
+ "https-proxy-agent": "^7.0.6",
161
164
  "ini": "5.0.0",
162
165
  "js-yaml": "^4.1.0",
163
166
  "jwt-decode": "4.0.0",
164
- "lando": "github:automattic/lando-cli#1d3e8c01f5f7e7f5b51b29aba145f3bddd2ca32e",
167
+ "lando": "github:automattic/lando-cli#25136fb80684743276239e2ee155080f3056790c",
165
168
  "node-fetch": "^2.6.1",
166
169
  "node-stream-zip": "1.15.0",
167
170
  "open": "^10.0.0",
@@ -170,7 +173,7 @@
170
173
  "shelljs": "^0.10.0",
171
174
  "socket.io-client": "^4.5.3",
172
175
  "socket.io-stream": "npm:@wearemothership/socket.io-stream@^0.9.1",
173
- "socks-proxy-agent": "^5.0.1",
176
+ "socks-proxy-agent": "^8.0.5",
174
177
  "ssh2": "1.16.0",
175
178
  "tar": "^7.4.0",
176
179
  "update-notifier": "7.3.1",
@@ -1,481 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- exports.__esModule = true;
5
- exports.appQuery = void 0;
6
- exports.vipValidatePreflightCommand = vipValidatePreflightCommand;
7
- var _vipGoPreflightChecks = require("@automattic/vip-go-preflight-checks");
8
- var _chalk = _interopRequireDefault(require("chalk"));
9
- var _enquirer = require("enquirer");
10
- var _fs = require("fs");
11
- var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
12
- var _ini = _interopRequireDefault(require("ini"));
13
- var _path = _interopRequireDefault(require("path"));
14
- var _api = _interopRequireWildcard(require("../lib/api"));
15
- var _command = _interopRequireDefault(require("../lib/cli/command"));
16
- var _envAlias = require("../lib/cli/envAlias");
17
- var exit = _interopRequireWildcard(require("../lib/cli/exit"));
18
- var _tracker = require("../lib/tracker");
19
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
20
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
- const ALLOWED_NODEJS_VERSIONS = ['18', '20', '22'];
22
- const appQuery = exports.appQuery = `
23
- id
24
- name
25
- repo
26
- environments {
27
- id
28
- appId
29
- name
30
- type
31
- environmentVariables {
32
- nodes {
33
- name,
34
- value
35
- }
36
- }
37
- }
38
- organization {
39
- id
40
- name
41
- }
42
- `;
43
- let suppressOutput = false;
44
- let outputFormat = 'table';
45
- let harmoniaArgs = [];
46
-
47
- /**
48
- * @param {string[]} messages
49
- */
50
- function logToConsole(...messages) {
51
- if (suppressOutput) {
52
- return;
53
- }
54
- if (messages.length === 0) {
55
- messages = [''];
56
- }
57
- messages.forEach(message => console.log(message));
58
- }
59
- async function getBuildConfiguration(application, environment) {
60
- const api = (0, _api.default)();
61
-
62
- // Disable the global GraphQL error handling, so we can catch Unauthorized errors and recommend next steps.
63
- (0, _api.disableGlobalGraphQLErrorHandling)();
64
- const buildConfigQuery = (0, _graphqlTag.default)`
65
- query BuildConfig($appId: Int, $envId: Int) {
66
- app(id: $appId) {
67
- environments(id: $envId) {
68
- id
69
- buildConfiguration {
70
- buildType
71
- nodeBuildDockerEnv
72
- nodeJSVersion
73
- npmToken
74
- }
75
- }
76
- }
77
- }
78
- `;
79
- try {
80
- const result = await api.query({
81
- query: buildConfigQuery,
82
- fetchPolicy: 'network-only',
83
- variables: {
84
- appId: environment.appId,
85
- envId: environment.id
86
- }
87
- });
88
-
89
- // Reenable GraphQL error handling
90
- (0, _api.enableGlobalGraphQLErrorHandling)();
91
- return result.data.app.environments[0].buildConfiguration;
92
- } catch (error) {
93
- if (error.graphQLErrors && error.graphQLErrors.find(gqlError => gqlError.message === 'Unauthorized')) {
94
- console.log(`${_chalk.default.red('Error:')} You do not have sufficient 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` + 'Read more about organization and application roles in our documentation:\n' + _chalk.default.underline('https://docs.wpvip.com/manage-user-access/vip-dashboard/'));
95
- await (0, _tracker.trackEvent)('validate_preflight_command_error', {
96
- env_id: environment.id,
97
- app_id: environment.appId,
98
- error: 'unauthorized'
99
- });
100
- process.exit(1);
101
- } else {
102
- // Handle it elsewhere
103
- throw error;
104
- }
105
- }
106
- }
107
-
108
- /**
109
- * @param {string} argv
110
- */
111
- async function vipValidatePreflightCommand(arg, opt) {
112
- harmoniaArgs = await validateArgs(opt);
113
- const appId = opt.env?.appId ?? 0;
114
- const envId = opt.env?.id ?? 0;
115
- const baseTrackingParams = {
116
- env_id: envId,
117
- app_id: appId,
118
- command: 'vip validate preflight',
119
- ...sanitizeArgsForTracking(harmoniaArgs)
120
- };
121
- await (0, _tracker.trackEvent)('validate_preflight_command_execute', baseTrackingParams);
122
- logToConsole(' /\\ /\\__ _ _ __ _ __ ___ ___ _ __ (_) __ _ ');
123
- logToConsole(" / /_/ / _` | '__| '_ ` _ \\ / _ \\| '_ \\| |/ _` |");
124
- logToConsole('/ __ / (_| | | | | | | | | (_) | | | | | (_| |');
125
- logToConsole('\\/ /_/ \\__,_|_| |_| |_| |_|\\___/|_| |_|_|\\__,_|');
126
- logToConsole('VIP Harmonia - Application testing made easy\n');
127
- const harmonia = new _vipGoPreflightChecks.Harmonia();
128
- harmonia.setSource('vip-cli');
129
- if (harmoniaArgs.buildType !== 'nodejs') {
130
- await (0, _tracker.trackEvent)('validate_preflight_command_error', {
131
- ...baseTrackingParams,
132
- error: 'not-nodejs'
133
- });
134
- exit.withError('Currently, only Node.js applications are supported.');
135
- }
136
-
137
- // Register the default tests.
138
- harmonia.registerDefaultTests();
139
-
140
- // Create the Site Config objects
141
- const siteOptions = new _vipGoPreflightChecks.SiteConfig({
142
- siteID: envId,
143
- nodejsVersion: harmoniaArgs.nodejsVersion,
144
- repository: opt.app?.repo ?? 'no-repo',
145
- baseURL: 'http://localhost:' + harmoniaArgs.port,
146
- dockerBuildEnvs: harmoniaArgs.nodeBuildDockerEnv,
147
- topRequests: [],
148
- // TODO: get top 10 of most requested URLs
149
- wait: harmoniaArgs.wait
150
- });
151
-
152
- // Get package.json
153
- const packageJSONfile = _path.default.resolve(opt.path, 'package.json');
154
- let packageJSON;
155
- try {
156
- // eslint-disable-next-line security/detect-non-literal-require
157
- packageJSON = require(packageJSONfile);
158
- siteOptions.setPackageJSON(packageJSON);
159
- } catch (error) {
160
- await (0, _tracker.trackEvent)('validate_preflight_command_error', {
161
- ...baseTrackingParams,
162
- error: 'missing-package-json'
163
- });
164
- return exit.withError(`Could not find a 'package.json' in the current directory (${opt.path}).`);
165
- }
166
- const customEnvVars = {};
167
- if (opt.env?.environmentVariables?.nodes.length > 0) {
168
- opt.env.environmentVariables.nodes.forEach(envVar => {
169
- customEnvVars[envVar.name] = envVar.value;
170
- });
171
- }
172
-
173
- // Create the EnviornmentVariables object
174
- const envVars = new _vipGoPreflightChecks.EnvironmentVariables({
175
- PORT: harmoniaArgs.port,
176
- ...customEnvVars
177
- });
178
-
179
- // Add NPM_TOKEN environment variable, if present
180
- if (harmoniaArgs.npmToken) {
181
- envVars.set('NPM_TOKEN', harmoniaArgs.npmToken);
182
- }
183
-
184
- // Get from .env, if exists
185
- let dotenvOptions = {};
186
- try {
187
- const dotenvPath = _path.default.resolve(opt.path, '.env');
188
- const dotenvContent = (0, _fs.readFileSync)(dotenvPath);
189
- dotenvOptions = _ini.default.parse(dotenvContent);
190
- } catch (error) {
191
- // nothing
192
- }
193
-
194
- // Save dotenv in the site config
195
- siteOptions.set('dotenv', dotenvOptions);
196
-
197
- // Bootstrap
198
- try {
199
- harmonia.bootstrap(siteOptions, envVars);
200
- } catch (error) {
201
- await (0, _tracker.trackEvent)('validate_preflight_command_error', {
202
- ...baseTrackingParams,
203
- error: error.message
204
- });
205
- return exit.withError(error.message);
206
- }
207
- setupEvents(harmonia);
208
- runHarmonia(harmonia);
209
- }
210
-
211
- /**
212
- * @param {Harmonia} harmonia
213
- */
214
- function setupEvents(harmonia) {
215
- // Register some events handlers
216
- harmonia.on('ready', () => {
217
- logToConsole('Harmonia is ready! ');
218
- });
219
-
220
- // Register the event handlers to output some information during the execution
221
- harmonia.on('beforeTestSuite', suite => {
222
- const description = suite.description ? `- ${_chalk.default.italic(suite.description)}` : '';
223
- logToConsole(` >> Running test suite ${_chalk.default.bold(suite.name)} ${description} `);
224
- logToConsole();
225
- });
226
- harmonia.on('beforeTest', test => {
227
- logToConsole(` [ ${_chalk.default.bold(test.name)} ] - ${test.description}`);
228
- });
229
- harmonia.on('afterTest', (test, result) => {
230
- switch (result.getType()) {
231
- case _vipGoPreflightChecks.TestResultType.Success:
232
- logToConsole(` ✅ ${_chalk.default.bgGreen(' Test passed with no errors. ')}`);
233
- break;
234
- case _vipGoPreflightChecks.TestResultType.Failed:
235
- logToConsole(` ❌ ${_chalk.default.bgRed(` Test failed with ${result.getErrors().length} errors. `)}`);
236
- break;
237
- case _vipGoPreflightChecks.TestResultType.PartialSuccess:
238
- logToConsole(` ✅ ${_chalk.default.bgYellow(' Test partially succeeded. ')}`);
239
- break;
240
- case _vipGoPreflightChecks.TestResultType.Aborted:
241
- logToConsole(` ❌ ${_chalk.default.bgRedBright.underline(' Test aborted! ')} - There was a critical error that makes`, 'the application incompatible with the VIP Platform.');
242
- break;
243
- case _vipGoPreflightChecks.TestResultType.Skipped:
244
- logToConsole(` ${_chalk.default.bgGrey.bold(' Skipped ')}\t${result.getLastNotice().message}`);
245
- }
246
- logToConsole();
247
- });
248
- harmonia.on('afterTestSuite', (test, result) => {
249
- // Create a badge
250
- let badge;
251
- switch (result.getType()) {
252
- case _vipGoPreflightChecks.TestResultType.Failed:
253
- badge = _chalk.default.bgRed.bold(' FAILED ');
254
- break;
255
- case _vipGoPreflightChecks.TestResultType.Aborted:
256
- badge = _chalk.default.bgRedBright.underline.bold(' ABORTED ');
257
- break;
258
- case _vipGoPreflightChecks.TestResultType.PartialSuccess:
259
- badge = _chalk.default.bgYellow.bold(' PASS ');
260
- break;
261
- default:
262
- badge = _chalk.default.bgGreen.bold(' PASS ');
263
- break;
264
- }
265
- logToConsole(` >> ${badge} Finished running ${_chalk.default.bold(test.name)} suite`);
266
- logToConsole();
267
- });
268
- harmonia.on('issue', issue => {
269
- let issueTypeString = issue.getTypeString();
270
- switch (issue.type) {
271
- case _vipGoPreflightChecks.IssueType.Blocker:
272
- issueTypeString = _chalk.default.bgRedBright.underline.bold(issueTypeString);
273
- break;
274
- case _vipGoPreflightChecks.IssueType.Error:
275
- issueTypeString = _chalk.default.bgRed.bold(issueTypeString);
276
- break;
277
- case _vipGoPreflightChecks.IssueType.Warning:
278
- issueTypeString = _chalk.default.bgYellow.bold(issueTypeString);
279
- break;
280
- case _vipGoPreflightChecks.IssueType.Notice:
281
- issueTypeString = _chalk.default.bgGray.bold(issueTypeString);
282
- break;
283
- }
284
- const documentation = issue.documentation ? `(${issue.documentation})` : '';
285
-
286
- // Replace \n with \n\t\t to keep new lines aligned
287
- const message = issue.message.replace(/\n/g, '\n\t\t');
288
- logToConsole(` ${issueTypeString} \t${message} ${documentation}`);
289
-
290
- // If it's a Blocker or Error, and the issue includes a stdout, print it out.
291
- const issueData = issue.getData();
292
- if (issueData && [_vipGoPreflightChecks.IssueType.Blocker, _vipGoPreflightChecks.IssueType.Error].includes(issue.type)) {
293
- if (issueData.all) {
294
- logToConsole(issueData.all);
295
- logToConsole();
296
- } else if (typeof issueData === 'string') {
297
- logToConsole(issueData);
298
- logToConsole();
299
- }
300
- }
301
- });
302
- }
303
- function runHarmonia(harmonia) {
304
- harmonia.run().then(async results => await handleResults(harmonia, results));
305
- }
306
- async function handleResults(harmonia, results) {
307
- // Calculate the results
308
- const resultCounter = harmonia.countResults(false);
309
- const testSuiteResults = results.filter(result => result instanceof _vipGoPreflightChecks.TestSuiteResult);
310
-
311
- // Send success event
312
- await (0, _tracker.trackEvent)('validate_preflight_command_success', {
313
- command: 'vip validate preflight',
314
- ...sanitizeArgsForTracking(harmoniaArgs),
315
- skipped: resultCounter[_vipGoPreflightChecks.TestResultType.Skipped],
316
- success: resultCounter[_vipGoPreflightChecks.TestResultType.Success],
317
- partial_success: resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess],
318
- failed: resultCounter[_vipGoPreflightChecks.TestResultType.Failed],
319
- aborted: resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]
320
- });
321
-
322
- // If the output is JSON, reenable the logToConsole output and print-out the json format.
323
- if (outputFormat === 'json') {
324
- suppressOutput = false;
325
- logToConsole(harmonia.resultsJSON());
326
- process.exit(0);
327
- }
328
-
329
- // Print the results
330
- logToConsole('\n' + _chalk.default.bgGray(' HARMONIA RESULTS \n'));
331
- if (resultCounter[_vipGoPreflightChecks.TestResultType.Skipped]) {
332
- logToConsole(` ${_chalk.default.bold.bgGrey(' SKIPPED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Skipped])} tests`);
333
- }
334
- if (resultCounter[_vipGoPreflightChecks.TestResultType.Success]) {
335
- logToConsole(` ${_chalk.default.bold.bgGreen(' PASSED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Success])} tests`);
336
- }
337
- if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess]) {
338
- logToConsole(` ${_chalk.default.bold.bgYellow(' PARTIAL SUCCESS ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess])} tests`);
339
- }
340
- if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
341
- logToConsole(` ${_chalk.default.bold.bgRed(' FAILED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Failed])} tests`);
342
- }
343
- if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
344
- logToConsole(` ${_chalk.default.bold.bgRedBright(' ABORTED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Aborted])} tests`);
345
- }
346
- logToConsole();
347
- logToConsole(` > Total of ${_chalk.default.bold(results.length - testSuiteResults.length)} tests have been executed.`);
348
- logToConsole();
349
-
350
- // If there is a Aborted test result
351
- if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
352
- logToConsole(`${_chalk.default.bold.bgRedBright(' NOT PASS ')} There was a critical failure that makes the application ` + 'incompatible with the VIP Platform. Please review the results and re-run the tests.');
353
- process.exit(1);
354
- }
355
-
356
- // If there is only a partial success, but no failures
357
- if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess] && !resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
358
- logToConsole(`${_chalk.default.bold.bgYellow(' PASS ')} The application has passed the required tests, but it does not follow all of the recommendations.`);
359
- logToConsole('Please review the results.');
360
- process.exit(0);
361
- }
362
-
363
- // If there is a failure
364
- if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
365
- logToConsole(`${_chalk.default.bold.bgRed(' NOT PASS ')} The application has failed some tests, and will very likely have problems on a production ` + 'environment. Please review all of the errors found in the results.');
366
- process.exit(1);
367
- }
368
- logToConsole(`${_chalk.default.bold.bgGreen(' PASS ')} Congratulations! The application passes all of the tests.`);
369
- process.exit(0);
370
- }
371
- async function validateArgs(opt) {
372
- const args = {};
373
-
374
- // Verbose
375
- if (opt.verbose) {
376
- _vipGoPreflightChecks.Harmonia.setVerbosity(true);
377
- }
378
-
379
- // Set path
380
- if (opt.path) {
381
- _vipGoPreflightChecks.Harmonia.setCwd(opt.path);
382
- }
383
-
384
- // If the JSON option is enabled, all the stdout should be suppressed to prevent polluting the output.
385
- if (opt.format === 'json') {
386
- suppressOutput = true;
387
- outputFormat = 'json';
388
- }
389
- if (opt.app) {
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 ?? 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 ?? 3000;
422
- args.port = 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
- * @return {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
- format: true
448
- };
449
-
450
- // The @app.env selector is optional, so we need to check if it was passed
451
- const parsedAlias = (0, _envAlias.parseEnvAliasFromArgv)(process.argv);
452
- if (parsedAlias.app) {
453
- commandOpts = {
454
- ...commandOpts,
455
- appQuery,
456
- envContext: true,
457
- appContext: true
458
- };
459
- } else {
460
- 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 be defined.');
461
- }
462
- const usage = 'vip validate preflight';
463
- (0, _command.default)({
464
- commandOpts,
465
- usage
466
- }).option('verbose', 'Increase logging level to include app build and server boot up messages.', false).option('node-version', `Set a version of Node.js for the tests. Accepts semver format (MAJOR.MINOR.PATCH) or a MAJOR (${ALLOWED_NODEJS_VERSIONS.join(', ')}).`).option('wait', 'Set the number of milliseconds to delay the start of the tests. Only necessary if an application requires a greater amount of time to start.', 3000).option(['p', 'port'], 'Set a port for the application. (Defaults to a random value between 3001 and 3999)').option(['P', 'path'], 'Path to the app to be tested', process.cwd()).examples([{
467
- usage: 'vip validate preflight',
468
- description: 'Run the validate command from within the root of the local Node.js codebase directory.'
469
- }, {
470
- usage: 'vip validate preflight --path=/Users/example/Desktop/example-node-repo',
471
- description: 'Run the validate command against a Node.js application directory at a specific local path.'
472
- }, {
473
- usage: 'vip @example-node-app.production validate preflight --node-version=20',
474
- description: 'Run the validation tests with a specific version of Node.js.'
475
- }, {
476
- usage: 'vip validate preflight --format=json > results.json',
477
- description: 'Output the results of the validation tests to a local file in JSON format.'
478
- }, {
479
- usage: 'vip @example-node-app.production validate preflight',
480
- description: 'Run the validation tests with settings based on a targeted VIP Platform environment.'
481
- }]).argv(process.argv, vipValidatePreflightCommand);
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- var _command = _interopRequireDefault(require("../lib/cli/command"));
5
- var _tracker = require("../lib/tracker");
6
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
- (0, _command.default)({
8
- requiredArgs: 0
9
- }).command('preflight', 'Run a full suite of validation tests against a local Node.js codebase to identify potential issues that could prevent successful building or deploying.').argv(process.argv, async () => {
10
- await (0, _tracker.trackEvent)('vip_validate_command_execute');
11
- });