@automattic/vip 2.32.2 → 2.32.3

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 (44) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/assets/dev-env.lando.template.yml.ejs +10 -2
  3. package/dist/bin/vip-dev-env-exec.js +1 -7
  4. package/dist/bin/vip-dev-env-shell.js +0 -4
  5. package/dist/bin/vip-dev-env-start.js +1 -1
  6. package/dist/bin/vip-dev-env-sync-sql.js +8 -6
  7. package/dist/bin/vip-dev-env-update.js +1 -2
  8. package/dist/bin/vip-import-sql.js +2 -2
  9. package/dist/bin/vip-logout.js +23 -0
  10. package/dist/bin/vip-slowlogs.js +192 -0
  11. package/dist/bin/vip-validate-preflight.js +8 -10
  12. package/dist/bin/vip-whoami.js +1 -2
  13. package/dist/bin/vip.js +1 -5
  14. package/dist/commands/backup-db.js +8 -9
  15. package/dist/lib/api/app.js +2 -2
  16. package/dist/lib/api/cache-purge.js +2 -2
  17. package/dist/lib/api/http.js +2 -3
  18. package/dist/lib/app-logs/app-logs.js +2 -2
  19. package/dist/lib/app-slowlogs/app-slowlogs.js +63 -0
  20. package/dist/lib/app-slowlogs/types.js +1 -0
  21. package/dist/lib/cli/apiConfig.js +1 -1
  22. package/dist/lib/client-file-uploader.js +19 -4
  23. package/dist/lib/config/software.js +4 -4
  24. package/dist/lib/constants/dev-environment.js +7 -3
  25. package/dist/lib/dev-environment/dev-environment-cli.js +110 -117
  26. package/dist/lib/dev-environment/dev-environment-configuration-file.js +34 -36
  27. package/dist/lib/dev-environment/dev-environment-core.js +36 -19
  28. package/dist/lib/dev-environment/dev-environment-lando.js +80 -72
  29. package/dist/lib/dev-environment/docker-utils.js +8 -9
  30. package/dist/lib/envvar/api-get-all.js +2 -2
  31. package/dist/lib/envvar/api-list.js +3 -6
  32. package/dist/lib/envvar/input.js +1 -2
  33. package/dist/lib/site-import/status.js +5 -5
  34. package/dist/lib/token.js +3 -6
  35. package/dist/lib/validations/is-multi-site-sql-dump.js +0 -1
  36. package/dist/lib/validations/is-multi-site.js +14 -12
  37. package/dist/lib/validations/is-multisite-domain-mapped.js +5 -10
  38. package/dist/lib/validations/line-by-line.js +9 -13
  39. package/dist/lib/validations/site-type.js +2 -7
  40. package/dist/lib/validations/sql.js +14 -19
  41. package/dist/lib/validations/utils.js +1 -1
  42. package/npm-shrinkwrap.json +913 -926
  43. package/package.json +12 -9
  44. package/tsconfig.json +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  ## Changelog
2
2
 
3
+ ### 2.32.3
4
+
5
+ - #1456 Fix DB engine validation regex
6
+ - #1455 Fix SQL import command
7
+ - #1454 chore(deps): update lando to 5efb9eb
8
+ - #1453 Refactor logout
9
+ - #1425 Add Slowlogs command
10
+ - #1341 feat(dev-env): Add a concept of init-only containers
11
+ - #1344 fix(dev-env): Do not run URL scan unless really need to
12
+ - #1414 [dev-env] Tweak error handling dev-env sync
13
+ - #1452 chore(dev-deps): update TypeScript-related packages
14
+ - #1420 feat(dev-env): Adds automigration logic to dev-env
15
+ - #1451 chore(dev-deps): update testing tools
16
+ - #1448 chore(dev-deps): update babel packages to 7.22.9
17
+ - #1421 refactor: Convert dev-environment to TypeScript
18
+ - #1450 refactor: convert `validations` to TS
19
+
3
20
  ### 2.32.2
4
21
 
5
22
  - #1443 On-demand Database Backup: Use a less error-prone way of detecting if we're rate limited
@@ -17,7 +17,7 @@ services:
17
17
  type: compose
18
18
  services:
19
19
  image: ghcr.io/automattic/vip-container-images/dev-tools:0.9
20
- command: sleep infinity
20
+ command: exit 0
21
21
  volumes:
22
22
  - devtools:/dev-tools
23
23
  - scripts:/scripts
@@ -28,6 +28,7 @@ services:
28
28
  volumes:
29
29
  devtools: {}
30
30
  scripts:
31
+ initOnly: true
31
32
 
32
33
  nginx:
33
34
  type: compose
@@ -154,6 +155,7 @@ services:
154
155
  type: compose
155
156
  services:
156
157
  image: ghcr.io/automattic/vip-container-images/wordpress:<%= wordpress.tag %>
158
+ # command: /usr/local/bin/entrypoint.sh
157
159
  command: sh -c "rsync -a --chown=www-data:www-data /wp/ /shared/; sleep infinity"
158
160
  volumes:
159
161
  - ./wordpress:/shared
@@ -162,6 +164,10 @@ services:
162
164
  target: /scripts
163
165
  volume:
164
166
  nocopy: true
167
+ # environment:
168
+ # LANDO_NO_SCRIPTS: 1
169
+ # LANDO_NEEDS_EXEC: 1
170
+ # initOnly: true
165
171
 
166
172
  <% if ( muPlugins.mode == 'image' ) { %>
167
173
  vip-mu-plugins:
@@ -181,6 +187,7 @@ services:
181
187
  LANDO_NEEDS_EXEC: 1
182
188
  volumes:
183
189
  mu-plugins: {}
190
+ initOnly: true
184
191
  <% } %>
185
192
 
186
193
  <% if ( appCode.mode == 'image' ) { %>
@@ -188,7 +195,7 @@ services:
188
195
  type: compose
189
196
  services:
190
197
  image: ghcr.io/automattic/vip-container-images/skeleton:latest
191
- command: sleep infinity
198
+ command: exit 0
192
199
  volumes:
193
200
  - clientcode_clientmuPlugins:/clientcode/client-mu-plugins
194
201
  - clientcode_images:/clientcode/images
@@ -205,6 +212,7 @@ services:
205
212
  clientcode_private: {}
206
213
  clientcode_themes: {}
207
214
  clientcode_vipconfig: {}
215
+ initOnly: true
208
216
  <% } %>
209
217
 
210
218
  <% if ( mailpit ) { %>
@@ -30,13 +30,7 @@ const examples = [{
30
30
  }];
31
31
  (0, _command.default)({
32
32
  wildcardCommand: true
33
- }).option('slug', 'Custom name of the dev environment').option('force', 'Disabling validations before task execution', undefined, value => {
34
- var _value$toLowerCase;
35
- return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase = value.toLowerCase) === null || _value$toLowerCase === void 0 ? void 0 : _value$toLowerCase.call(value));
36
- }).option('quiet', 'Suppress output', undefined, value => {
37
- var _value$toLowerCase2;
38
- return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase2 = value.toLowerCase) === null || _value$toLowerCase2 === void 0 ? void 0 : _value$toLowerCase2.call(value));
39
- }).examples(examples).argv(process.argv, async (unmatchedArgs, opt) => {
33
+ }).option('slug', 'Custom name of the dev environment').option('force', 'Disable validations before task execution', undefined, _devEnvironmentCli.processBooleanOption).option('quiet', 'Suppress output', undefined, _devEnvironmentCli.processBooleanOption).examples(examples).argv(process.argv, async (unmatchedArgs, opt) => {
40
34
  const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
41
35
  const lando = await (0, _devEnvironmentLando.bootstrapLando)();
42
36
  await (0, _devEnvironmentCli.validateDependencies)(lando, slug, opt.quiet);
@@ -18,14 +18,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
18
18
  */
19
19
  const debug = (0, _debug.default)('@automattic/vip:bin:dev-environment');
20
20
  const userMap = {
21
- devtools: 'www-data',
22
21
  nginx: 'www-data',
23
22
  php: 'www-data',
24
23
  database: 'mysql',
25
24
  memcached: 'memcache',
26
- wordpress: 'www-data',
27
- 'vip-mu-plugins': 'www-data',
28
- 'demo-app-code': 'www-data',
29
25
  elasticsearch: 'elasticsearch',
30
26
  phpmyadmin: 'www-data',
31
27
  mailhog: 'mailhog',
@@ -73,7 +73,7 @@ const examples = [{
73
73
  await (0, _devEnvironmentCli.handleCLIException)(error, 'dev_env_start_command_error', trackingInfo);
74
74
  process.exitCode = 1;
75
75
  }
76
- await (0, _devEnvironmentCli.postStart)(slug, {
76
+ (0, _devEnvironmentCli.postStart)(slug, {
77
77
  openVSCode: !!opt.vscode
78
78
  });
79
79
  });
@@ -21,6 +21,7 @@ var _userError = _interopRequireDefault(require("../lib/user-error"));
21
21
  var _devEnvSyncSql = require("../commands/dev-env-sync-sql");
22
22
  var _devEnvironment = require("../lib/constants/dev-environment");
23
23
  var _tracker = require("../lib/tracker");
24
+ var _devEnvironmentCli = require("../lib/dev-environment/dev-environment-cli");
24
25
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
26
  const examples = [{
26
27
  usage: `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} sync sql @my-test.develop --slug=my_site`,
@@ -54,11 +55,12 @@ const appQuery = `
54
55
  envContext: true,
55
56
  requiredArgs: 0,
56
57
  module: 'dev-env-sync-sql'
57
- }).option('slug', 'Custom name of the dev environment').examples(examples).argv(process.argv, async (arg, {
58
- app,
59
- env,
60
- slug
61
- }) => {
58
+ }).option('slug', 'Custom name of the dev environment').option('force', 'Disable validations before running sync', undefined, _devEnvironmentCli.processBooleanOption).examples(examples).argv(process.argv, async (arg, opt) => {
59
+ const {
60
+ app,
61
+ env
62
+ } = opt;
63
+ const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
62
64
  const trackerFn = (0, _tracker.makeCommandTracker)('dev_env_sync_sql', {
63
65
  app: app.id,
64
66
  env: env.uniqueLabel,
@@ -68,7 +70,7 @@ const appQuery = `
68
70
  await trackerFn('execute');
69
71
  const lando = await (0, _devEnvironmentLando.bootstrapLando)();
70
72
  const envPath = (0, _devEnvironmentCore.getEnvironmentPath)(slug);
71
- if (!(await (0, _devEnvironmentLando.isEnvUp)(lando, envPath))) {
73
+ if (!(await (0, _devEnvironmentLando.isEnvUp)(lando, envPath)) && !opt.force) {
72
74
  await trackerFn('env_not_running_error', {
73
75
  errorMessage: 'Environment was not running'
74
76
  });
@@ -39,7 +39,6 @@ cmd.argv(process.argv, async (arg, opt) => {
39
39
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
40
40
  await (0, _tracker.trackEvent)('dev_env_update_command_execute', trackingInfo);
41
41
  try {
42
- var _currentInstanceData$;
43
42
  const environmentAlreadyExists = await (0, _devEnvironmentCore.doesEnvironmentExist)((0, _devEnvironmentCore.getEnvironmentPath)(slug));
44
43
  if (!environmentAlreadyExists) {
45
44
  throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
@@ -63,7 +62,7 @@ cmd.argv(process.argv, async (arg, opt) => {
63
62
  mariadb: currentInstanceData.mariadb,
64
63
  phpmyadmin: currentInstanceData.phpmyadmin,
65
64
  xdebug: currentInstanceData.xdebug,
66
- mailpit: (_currentInstanceData$ = currentInstanceData.mailpit) !== null && _currentInstanceData$ !== void 0 ? _currentInstanceData$ : currentInstanceData.mailhog,
65
+ mailpit: currentInstanceData.mailpit ?? currentInstanceData.mailhog,
67
66
  photon: currentInstanceData.photon,
68
67
  mediaRedirectDomain: currentInstanceData.mediaRedirectDomain,
69
68
  multisite: false,
@@ -271,8 +271,8 @@ const displayPlaybook = ({
271
271
  var _app$environments, _selectedEnvironmentO;
272
272
  // eslint-disable-next-line no-multi-spaces
273
273
  console.log(` multisite: ${isMultiSite.toString()}`);
274
- 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);
275
- siteArray = selectedEnvironmentObj === null || selectedEnvironmentObj === void 0 ? void 0 : (_selectedEnvironmentO = selectedEnvironmentObj.wpSites) === null || _selectedEnvironmentO === void 0 ? void 0 : _selectedEnvironmentO.nodes;
274
+ const selectedEnvironmentObj = app === null || app === void 0 || (_app$environments = app.environments) === null || _app$environments === void 0 ? void 0 : _app$environments.find(env => unformattedEnvironment === env.type);
275
+ siteArray = selectedEnvironmentObj === null || selectedEnvironmentObj === void 0 || (_selectedEnvironmentO = selectedEnvironmentObj.wpSites) === null || _selectedEnvironmentO === void 0 ? void 0 : _selectedEnvironmentO.nodes;
276
276
  }
277
277
  if (!tableNames.length) {
278
278
  debug('Validation was skipped, no playbook information will be displayed');
@@ -0,0 +1,23 @@
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 _logout = _interopRequireDefault(require("../lib/logout"));
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ void (0, _command.default)({
16
+ usage: 'vip logout'
17
+ }).examples([{
18
+ usage: 'vip logout',
19
+ description: 'Logs out current user.'
20
+ }]).argv(process.argv, async () => {
21
+ await (0, _logout.default)();
22
+ console.log('You are successfully logged out.');
23
+ });
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * External dependencies
4
+ */
5
+ "use strict";
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports.appQuery = void 0;
11
+ exports.followLogs = followLogs;
12
+ exports.getSlowlogs = getSlowlogs;
13
+ exports.validateInputs = validateInputs;
14
+ var _chalk = _interopRequireDefault(require("chalk"));
15
+ var _promises = require("timers/promises");
16
+ var _command = _interopRequireDefault(require("../lib/cli/command"));
17
+ var _tracker = require("../lib/tracker");
18
+ var slowlogsLib = _interopRequireWildcard(require("../lib/app-slowlogs/app-slowlogs"));
19
+ var exit = _interopRequireWildcard(require("../lib/cli/exit"));
20
+ var _format = require("../lib/cli/format");
21
+ 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); }
22
+ 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; }
23
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
+ /**
25
+ * Internal dependencies
26
+ */
27
+ const LIMIT_MIN = 1;
28
+ const LIMIT_MAX = 500;
29
+ const ALLOWED_FORMATS = ['csv', 'json', 'text'];
30
+ const DEFAULT_POLLING_DELAY_IN_SECONDS = 30;
31
+ const MIN_POLLING_DELAY_IN_SECONDS = 5;
32
+ const MAX_POLLING_DELAY_IN_SECONDS = 300;
33
+ async function getSlowlogs(arg, opt) {
34
+ validateInputs(opt.limit, opt.format);
35
+ const trackingParams = getBaseTrackingParams(opt);
36
+ await (0, _tracker.trackEvent)('slowlogs_command_execute', trackingParams);
37
+ let slowlogs;
38
+ try {
39
+ slowlogs = await slowlogsLib.getRecentSlowlogs(opt.app.id, opt.env.id, opt.limit);
40
+ } catch (error) {
41
+ const err = error;
42
+ await (0, _tracker.trackEvent)('slowlogs_command_error', {
43
+ ...trackingParams,
44
+ error: err.message
45
+ });
46
+ return exit.withError(err.message);
47
+ }
48
+ await (0, _tracker.trackEvent)('slowlogs_command_success', {
49
+ ...trackingParams,
50
+ total: slowlogs.nodes.length
51
+ });
52
+ if (!slowlogs.nodes.length) {
53
+ console.error('No logs found');
54
+ return;
55
+ }
56
+ printSlowlogs(slowlogs.nodes, opt.format);
57
+ }
58
+ async function followLogs(opt) {
59
+ let after = null;
60
+ let isFirstRequest = true;
61
+ // How many times have we polled?
62
+ let requestNumber = 0;
63
+ const trackingParams = getBaseTrackingParams(opt);
64
+
65
+ // Set an initial default delay
66
+ let delay = DEFAULT_POLLING_DELAY_IN_SECONDS;
67
+
68
+ // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition
69
+ while (true) {
70
+ const limit = isFirstRequest ? opt.limit : LIMIT_MAX;
71
+ requestNumber++;
72
+ trackingParams.request_number = requestNumber;
73
+ trackingParams.request_delay = delay;
74
+ trackingParams.limit = limit;
75
+ let slowlogs;
76
+ try {
77
+ // eslint-disable-next-line no-await-in-loop
78
+ slowlogs = await slowlogsLib.getRecentSlowlogs(opt.app.id, opt.env.id, limit, after);
79
+
80
+ // eslint-disable-next-line no-await-in-loop
81
+ await (0, _tracker.trackEvent)('slowlogs_command_follow_success', {
82
+ ...trackingParams,
83
+ total: slowlogs.nodes.length
84
+ });
85
+ } catch (error) {
86
+ const err = error;
87
+ // eslint-disable-next-line no-await-in-loop
88
+ await (0, _tracker.trackEvent)('slowlogs_command_follow_error', {
89
+ ...trackingParams,
90
+ error: err.message
91
+ });
92
+
93
+ // If the first request fails we don't want to retry (it's probably not recoverable)
94
+ if (isFirstRequest) {
95
+ console.error(`${_chalk.default.red('Error:')} Failed to fetch slowlogs.`);
96
+ break;
97
+ }
98
+ // Increase the delay on errors to avoid overloading the server, up to a max of 5 minutes
99
+ delay += DEFAULT_POLLING_DELAY_IN_SECONDS;
100
+ delay = Math.min(delay, MAX_POLLING_DELAY_IN_SECONDS);
101
+ console.error(`${_chalk.default.red('Error:')} Failed to fetch slowlogs. Trying again in ${delay} seconds.`);
102
+ }
103
+ if (slowlogs) {
104
+ if (slowlogs.nodes.length) {
105
+ printSlowlogs(slowlogs.nodes, opt.format);
106
+ }
107
+ after = slowlogs.nextCursor;
108
+ isFirstRequest = false;
109
+
110
+ // Keep a sane lower limit of MIN_POLLING_DELAY_IN_SECONDS just in case something goes wrong in the server-side
111
+ delay = Math.max(slowlogs.pollingDelaySeconds || DEFAULT_POLLING_DELAY_IN_SECONDS, MIN_POLLING_DELAY_IN_SECONDS);
112
+ }
113
+
114
+ // eslint-disable-next-line no-await-in-loop
115
+ await (0, _promises.setTimeout)(delay * 1000);
116
+ }
117
+ }
118
+ function getBaseTrackingParams(opt) {
119
+ return {
120
+ command: 'vip slowlogs',
121
+ org_id: opt.app.organization.id,
122
+ app_id: opt.app.id,
123
+ env_id: opt.env.id,
124
+ limit: opt.limit,
125
+ follow: opt.follow ?? false,
126
+ format: opt.format
127
+ };
128
+ }
129
+ function printSlowlogs(slowlogs, format) {
130
+ // Strip out __typename
131
+ slowlogs = slowlogs.map(log => {
132
+ const {
133
+ timestamp,
134
+ rowsSent,
135
+ rowsExamined,
136
+ queryTime,
137
+ requestUri,
138
+ query
139
+ } = log;
140
+ return {
141
+ timestamp,
142
+ rowsSent,
143
+ rowsExamined,
144
+ queryTime,
145
+ requestUri,
146
+ query
147
+ };
148
+ });
149
+ console.log((0, _format.formatData)(slowlogs, format));
150
+ }
151
+ function validateInputs(limit, format) {
152
+ if (!ALLOWED_FORMATS.includes(format)) {
153
+ exit.withError(`Invalid format: ${format}. The supported formats are: ${ALLOWED_FORMATS.join(', ')}.`);
154
+ }
155
+ if (!Number.isInteger(limit) || limit < LIMIT_MIN || limit > slowlogsLib.LIMIT_MAX) {
156
+ exit.withError(`Invalid limit: ${limit}. It should be a number between ${LIMIT_MIN} and ${slowlogsLib.LIMIT_MAX}.`);
157
+ }
158
+ }
159
+ const appQuery = `
160
+ id
161
+ name
162
+ environments {
163
+ id
164
+ appId
165
+ name
166
+ type
167
+ }
168
+ organization {
169
+ id
170
+ name
171
+ }
172
+ `;
173
+ exports.appQuery = appQuery;
174
+ void (0, _command.default)({
175
+ appContext: true,
176
+ appQuery,
177
+ envContext: true,
178
+ format: true,
179
+ module: 'slowlogs'
180
+ }).option('limit', 'The maximum number of log lines', 500).option('format', 'Output the log lines in CSV or JSON format', 'text').examples([{
181
+ description: 'Get the most recent app slowlogs',
182
+ usage: 'vip @mysite.production slowlogs'
183
+ }, {
184
+ usage: 'vip @mysite.production slowlogs --limit 100',
185
+ description: 'Get the most recent 100 slowlog entries'
186
+ }, {
187
+ usage: 'vip @mysite.production slowlogs --limit 100 --format csv',
188
+ description: 'Get the most recent 100 slowlog entries formatted as comma-separated values (CSV)'
189
+ }, {
190
+ usage: 'vip @mysite.production slowlogs --limit 100 --format json',
191
+ description: 'Get the most recent 100 slowlog entries formatted as JSON'
192
+ }]).argv(process.argv, getSlowlogs);
@@ -111,10 +111,10 @@ async function getBuildConfiguration(application, environment) {
111
111
  }
112
112
  }
113
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;
114
+ var _opt$env, _opt$env2, _opt$app, _opt$env3;
115
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;
116
+ const appId = ((_opt$env = opt.env) === null || _opt$env === void 0 ? void 0 : _opt$env.appId) ?? 0;
117
+ const envId = ((_opt$env2 = opt.env) === null || _opt$env2 === void 0 ? void 0 : _opt$env2.id) ?? 0;
118
118
  const baseTrackingParams = {
119
119
  env_id: envId,
120
120
  app_id: appId,
@@ -144,7 +144,7 @@ async function vipValidatePreflightCommand(arg, opt) {
144
144
  const siteOptions = new _vipGoPreflightChecks.SiteConfig({
145
145
  siteID: envId,
146
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',
147
+ repository: ((_opt$app = opt.app) === null || _opt$app === void 0 ? void 0 : _opt$app.repo) ?? 'no-repo',
148
148
  baseURL: 'http://localhost:' + harmoniaArgs.port,
149
149
  dockerBuildEnvs: harmoniaArgs.nodeBuildDockerEnv,
150
150
  topRequests: [],
@@ -167,7 +167,7 @@ async function vipValidatePreflightCommand(arg, opt) {
167
167
  return exit.withError(`Could not find a 'package.json' in the current folder (${opt.path}).`);
168
168
  }
169
169
  const customEnvVars = {};
170
- 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
+ if (((_opt$env3 = opt.env) === null || _opt$env3 === void 0 || (_opt$env3 = _opt$env3.environmentVariables) === null || _opt$env3 === void 0 ? void 0 : _opt$env3.nodes.length) > 0) {
171
171
  opt.env.environmentVariables.nodes.forEach(envVar => {
172
172
  customEnvVars[envVar.name] = envVar.value;
173
173
  });
@@ -368,7 +368,6 @@ async function handleResults(harmonia, results) {
368
368
  process.exit(0);
369
369
  }
370
370
  async function validateArgs(opt) {
371
- var _opt$wait, _opt$port;
372
371
  const args = {};
373
372
 
374
373
  // Verbose
@@ -387,12 +386,11 @@ async function validateArgs(opt) {
387
386
  outputJson = true;
388
387
  }
389
388
  if (opt.app) {
390
- var _opt$nodeVersion;
391
389
  // Get build information from API and store it in the env object
392
390
  const buildConfig = await getBuildConfiguration(opt.app, opt.env);
393
391
  args.app_id = opt.app.id;
394
392
  args.env_id = opt.env.id;
395
- args.nodejsVersion = (_opt$nodeVersion = opt.nodeVersion) !== null && _opt$nodeVersion !== void 0 ? _opt$nodeVersion : buildConfig.nodeJSVersion;
393
+ args.nodejsVersion = opt.nodeVersion ?? buildConfig.nodeJSVersion;
396
394
  args.buildType = buildConfig.buildType;
397
395
  args.npmToken = buildConfig.npmToken;
398
396
  args.nodeBuildDockerEnv = buildConfig.nodeBuildDockerEnv;
@@ -419,8 +417,8 @@ async function validateArgs(opt) {
419
417
  args.nodejsVersion = opt.nodeVersion;
420
418
  }
421
419
  }
422
- args.wait = (_opt$wait = opt.wait) !== null && _opt$wait !== void 0 ? _opt$wait : 3000;
423
- 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
420
+ args.wait = opt.wait ?? 3000;
421
+ args.port = opt.port ?? Math.floor(Math.random() * 1000) + 3001; // Get a PORT from 3001 and 3999
424
422
 
425
423
  return args;
426
424
  }
@@ -21,7 +21,6 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
21
21
  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; }
22
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
23
  async function whoamiCommand() {
24
- var _currentUser$displayN, _currentUser$id;
25
24
  const trackingParams = {
26
25
  command: 'vip whoami'
27
26
  };
@@ -38,7 +37,7 @@ async function whoamiCommand() {
38
37
  exit.withError(`Failed to fetch information about the currently logged-in user error: ${error.message}`);
39
38
  }
40
39
  await (0, _tracker.trackEvent)('whoami_command_success', trackingParams);
41
- const output = [`- Howdy ${(_currentUser$displayN = currentUser.displayName) !== null && _currentUser$displayN !== void 0 ? _currentUser$displayN : 'user'}!`, `- Your user ID is ${(_currentUser$id = currentUser.id) !== null && _currentUser$id !== void 0 ? _currentUser$id : ' not found'}`];
40
+ const output = [`- Howdy ${currentUser.displayName ?? 'user'}!`, `- Your user ID is ${currentUser.id ?? ' not found'}`];
42
41
  if (currentUser.isVIP) {
43
42
  output.push('- Your account has VIP Staff permissions');
44
43
  }
package/dist/bin/vip.js CHANGED
@@ -12,7 +12,6 @@ var _config = _interopRequireDefault(require("../lib/cli/config"));
12
12
  var _command = _interopRequireWildcard(require("../lib/cli/command"));
13
13
  var _token2 = _interopRequireDefault(require("../lib/token"));
14
14
  var _tracker = require("../lib/tracker");
15
- var _logout = _interopRequireDefault(require("../lib/logout"));
16
15
  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); }
17
16
  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; }
18
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -29,10 +28,7 @@ if (_config.default && _config.default.environment !== 'production') {
29
28
  const tokenURL = 'https://dashboard.wpvip.com/me/cli/token';
30
29
  const runCmd = async function () {
31
30
  const cmd = (0, _command.default)();
32
- cmd.command('logout', 'Logout from your current session', async () => {
33
- await (0, _logout.default)();
34
- console.log('You are successfully logged out.');
35
- }).command('app', 'List and modify your VIP applications').command('cache', 'Manage page cache for your VIP applications').command('config', 'Set configuration for your VIP applications').command('dev-env', 'Use local dev-environment').command('export', 'Export data from your VIP application').command('import', 'Import media or SQL files into your VIP applications').command('logs', 'Get logs from your VIP applications').command('search-replace', 'Perform search and replace tasks on files').command('sync', 'Sync production to a development environment').command('whoami', 'Display details about the currently logged-in user').command('validate', 'Validate your VIP application and environment').command('wp', 'Run WP CLI commands against an environment');
31
+ cmd.command('logout', 'Logout from your current session').command('app', 'List and modify your VIP applications').command('cache', 'Manage page cache for your VIP applications').command('config', 'Set configuration for your VIP applications').command('dev-env', 'Use local dev-environment').command('export', 'Export data from your VIP application').command('import', 'Import media or SQL files into your VIP applications').command('logs', 'Get logs from your VIP applications').command('search-replace', 'Perform search and replace tasks on files').command('slowlogs', 'Get slowlogs from your VIP applications').command('sync', 'Sync production to a development environment').command('whoami', 'Display details about the currently logged-in user').command('validate', 'Validate your VIP application and environment').command('wp', 'Run WP CLI commands against an environment');
36
32
  cmd.argv(process.argv);
37
33
  };
38
34
  function doesArgvHaveAtLeastOneParam(argv, params) {
@@ -61,7 +61,7 @@ const DB_BACKUP_JOB_STATUS_QUERY = (0, _graphqlTag.default)`
61
61
  `;
62
62
  exports.DB_BACKUP_JOB_STATUS_QUERY = DB_BACKUP_JOB_STATUS_QUERY;
63
63
  async function getBackupJob(appId, envId) {
64
- var _app$environments, _app$environments$, _app$environments$$jo;
64
+ var _app$environments;
65
65
  const api = await (0, _api.default)();
66
66
  const response = await api.query({
67
67
  query: DB_BACKUP_JOB_STATUS_QUERY,
@@ -76,7 +76,7 @@ async function getBackupJob(appId, envId) {
76
76
  app
77
77
  }
78
78
  } = response;
79
- return app === null || app === void 0 ? void 0 : (_app$environments = app.environments) === null || _app$environments === void 0 ? void 0 : (_app$environments$ = _app$environments[0]) === null || _app$environments$ === void 0 ? void 0 : (_app$environments$$jo = _app$environments$.jobs) === null || _app$environments$$jo === void 0 ? void 0 : _app$environments$$jo[0];
79
+ return app === null || app === void 0 || (_app$environments = app.environments) === null || _app$environments === void 0 || (_app$environments = _app$environments[0]) === null || _app$environments === void 0 || (_app$environments = _app$environments.jobs) === null || _app$environments === void 0 ? void 0 : _app$environments[0];
80
80
  }
81
81
  async function createBackupJob(appId, envId) {
82
82
  // Disable global error handling so that we can handle errors ourselves
@@ -134,10 +134,10 @@ class BackupDBCommand {
134
134
  this.progressTracker.stopPrinting();
135
135
  }
136
136
  async loadBackupJob() {
137
- var _this$app$id, _this$env$id, _this$job$metadata$fi, _this$job, _this$job$metadata, _this$job$metadata$fi2, _this$job$progress$st, _this$job2, _this$job2$progress, _this$job3;
138
- this.job = await getBackupJob((_this$app$id = this.app.id) !== null && _this$app$id !== void 0 ? _this$app$id : 0, (_this$env$id = this.env.id) !== null && _this$env$id !== void 0 ? _this$env$id : 0);
139
- this.backupName = (_this$job$metadata$fi = (_this$job = this.job) === null || _this$job === void 0 ? void 0 : (_this$job$metadata = _this$job.metadata) === null || _this$job$metadata === void 0 ? void 0 : (_this$job$metadata$fi2 = _this$job$metadata.find(meta => (meta === null || meta === void 0 ? void 0 : meta.name) === 'backupName')) === null || _this$job$metadata$fi2 === void 0 ? void 0 : _this$job$metadata$fi2.value) !== null && _this$job$metadata$fi !== void 0 ? _this$job$metadata$fi : 'Unknown';
140
- this.jobStatus = (_this$job$progress$st = (_this$job2 = this.job) === null || _this$job2 === void 0 ? void 0 : (_this$job2$progress = _this$job2.progress) === null || _this$job2$progress === void 0 ? void 0 : _this$job2$progress.status) !== null && _this$job$progress$st !== void 0 ? _this$job$progress$st : undefined;
137
+ var _this$job, _this$job2, _this$job3;
138
+ this.job = await getBackupJob(this.app.id ?? 0, this.env.id ?? 0);
139
+ this.backupName = ((_this$job = this.job) === null || _this$job === void 0 || (_this$job = _this$job.metadata) === null || _this$job === void 0 || (_this$job = _this$job.find(meta => (meta === null || meta === void 0 ? void 0 : meta.name) === 'backupName')) === null || _this$job === void 0 ? void 0 : _this$job.value) ?? 'Unknown';
140
+ this.jobStatus = ((_this$job2 = this.job) === null || _this$job2 === void 0 || (_this$job2 = _this$job2.progress) === null || _this$job2 === void 0 ? void 0 : _this$job2.status) ?? undefined;
141
141
  if ((_this$job3 = this.job) !== null && _this$job3 !== void 0 && _this$job3.completedAt) {
142
142
  this.jobAge = (new Date().getTime() - new Date(this.job.completedAt).getTime()) / 1000 / 60;
143
143
  } else {
@@ -157,18 +157,17 @@ class BackupDBCommand {
157
157
  this.log('Database backup already in progress...');
158
158
  } else {
159
159
  try {
160
- var _this$app$id2, _this$env$id2;
161
160
  this.log('Generating a new database backup...');
162
161
  this.progressTracker.stepRunning(this.steps.PREPARE);
163
162
  this.progressTracker.startPrinting();
164
- await createBackupJob((_this$app$id2 = this.app.id) !== null && _this$app$id2 !== void 0 ? _this$app$id2 : 0, (_this$env$id2 = this.env.id) !== null && _this$env$id2 !== void 0 ? _this$env$id2 : 0);
163
+ await createBackupJob(this.app.id ?? 0, this.env.id ?? 0);
165
164
  } catch (err) {
166
165
  var _error$graphQLErrors, _graphQLError$extensi;
167
166
  const error = err;
168
167
  const graphQLError = (_error$graphQLErrors = error.graphQLErrors) === null || _error$graphQLErrors === void 0 ? void 0 : _error$graphQLErrors[0];
169
168
  this.progressTracker.stepFailed(this.steps.PREPARE);
170
169
  this.stopProgressTracker();
171
- if ((graphQLError === null || graphQLError === void 0 ? void 0 : (_graphQLError$extensi = graphQLError.extensions) === null || _graphQLError$extensi === void 0 ? void 0 : _graphQLError$extensi.errorHttpCode) === 429) {
170
+ if ((graphQLError === null || graphQLError === void 0 || (_graphQLError$extensi = graphQLError.extensions) === null || _graphQLError$extensi === void 0 ? void 0 : _graphQLError$extensi.errorHttpCode) === 429) {
172
171
  const retryAfter = graphQLError.extensions.retryAfter;
173
172
  await this.track('error', {
174
173
  error_type: 'rate_limit_exceeded',
@@ -18,7 +18,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
18
18
  async function _default(app, fields = 'id,name', fragments = '') {
19
19
  const api = await (0, _api.default)();
20
20
  if (isNaN(+app)) {
21
- var _res$data$apps, _res$data$apps$edges;
21
+ var _res$data$apps;
22
22
  const res = await api.query({
23
23
  query: (0, _graphqlTag.default)`query App( $name: String ) {
24
24
  apps( first: 1, name: $name ) {
@@ -34,7 +34,7 @@ async function _default(app, fields = 'id,name', fragments = '') {
34
34
  name: app
35
35
  }
36
36
  });
37
- if (!((_res$data$apps = res.data.apps) !== null && _res$data$apps !== void 0 && (_res$data$apps$edges = _res$data$apps.edges) !== null && _res$data$apps$edges !== void 0 && _res$data$apps$edges.length)) {
37
+ if (!((_res$data$apps = res.data.apps) !== null && _res$data$apps !== void 0 && (_res$data$apps = _res$data$apps.edges) !== null && _res$data$apps !== void 0 && _res$data$apps.length)) {
38
38
  return {};
39
39
  }
40
40
  return res.data.apps.edges[0];
@@ -43,7 +43,7 @@ const appQuery = `
43
43
  `;
44
44
  exports.appQuery = appQuery;
45
45
  async function purgeCache(appId, envId, urls) {
46
- var _response$data$purgeP, _response$data;
46
+ var _response$data;
47
47
  const api = await (0, _api.default)();
48
48
  const variables = {
49
49
  appId,
@@ -54,5 +54,5 @@ async function purgeCache(appId, envId, urls) {
54
54
  mutation,
55
55
  variables
56
56
  });
57
- return (_response$data$purgeP = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.purgePageCache) !== null && _response$data$purgeP !== void 0 ? _response$data$purgeP : null;
57
+ return ((_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.purgePageCache) ?? null;
58
58
  }
@@ -31,7 +31,6 @@ const debug = (0, _debug.default)('@automattic/vip:http');
31
31
  * @return {Promise} Return value of the `fetch` call
32
32
  */
33
33
  var _default = async (path, options = {}) => {
34
- var _options$headers;
35
34
  let url = path;
36
35
 
37
36
  // For convenience, we support just passing in the path to this function...
@@ -44,12 +43,12 @@ var _default = async (path, options = {}) => {
44
43
  debug('running fetch', url);
45
44
  return (0, _nodeFetch.default)(url, {
46
45
  ...options,
47
- agent: proxyAgent !== null && proxyAgent !== void 0 ? proxyAgent : undefined,
46
+ agent: proxyAgent ?? undefined,
48
47
  headers: {
49
48
  Authorization: `Bearer ${authToken.raw}`,
50
49
  'User-Agent': _env.default.userAgent,
51
50
  'Content-Type': 'application/json',
52
- ...((_options$headers = options.headers) !== null && _options$headers !== void 0 ? _options$headers : {})
51
+ ...(options.headers ?? {})
53
52
  },
54
53
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
55
54
  body: typeof options.body === 'object' ? JSON.stringify(options.body) : options.body
@@ -44,7 +44,7 @@ const QUERY_ENVIRONMENT_LOGS = (0, _graphqlTag.default)`
44
44
  }
45
45
  `;
46
46
  async function getRecentLogs(appId, envId, type, limit, after) {
47
- var _response$data$app, _response$data$app$en, _response$data$app$en2;
47
+ var _response$data$app;
48
48
  const api = await (0, _api.default)({
49
49
  exitOnError: false
50
50
  });
@@ -58,7 +58,7 @@ async function getRecentLogs(appId, envId, type, limit, after) {
58
58
  after
59
59
  }
60
60
  });
61
- const logs = (_response$data$app = response.data.app) === null || _response$data$app === void 0 ? void 0 : (_response$data$app$en = _response$data$app.environments) === null || _response$data$app$en === void 0 ? void 0 : (_response$data$app$en2 = _response$data$app$en[0]) === null || _response$data$app$en2 === void 0 ? void 0 : _response$data$app$en2.logs;
61
+ const logs = (_response$data$app = response.data.app) === null || _response$data$app === void 0 || (_response$data$app = _response$data$app.environments) === null || _response$data$app === void 0 || (_response$data$app = _response$data$app[0]) === null || _response$data$app === void 0 ? void 0 : _response$data$app.logs;
62
62
  if (!(logs !== null && logs !== void 0 && logs.nodes)) {
63
63
  throw new Error('Unable to query logs');
64
64
  }