@automattic/vip 3.9.0 → 3.9.2

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.
@@ -34,7 +34,7 @@ async function appDeployValidateCmd(arg = [], opts = {}) {
34
34
  await track('deploy_validate_app_command_execute');
35
35
  const ext = (0, _path.extname)(fileName);
36
36
  if (ext === '.zip') {
37
- (0, _customDeploy2.validateZipFile)(fileName);
37
+ await (0, _customDeploy2.validateZipFile)(fileName);
38
38
  } else {
39
39
  await (0, _customDeploy2.validateTarFile)(fileName);
40
40
  }
@@ -34,16 +34,6 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
34
34
 
35
35
  // Clone the read-only response object so we can modify it
36
36
  const clonedResponse = Object.assign({}, res);
37
- const header = [{
38
- key: 'id',
39
- value: res.id
40
- }, {
41
- key: 'name',
42
- value: res.name
43
- }, {
44
- key: 'repo',
45
- value: res.repo
46
- }];
47
37
  clonedResponse.environments = clonedResponse.environments.map(env => {
48
38
  const clonedEnv = Object.assign({}, env);
49
39
  clonedEnv.name = (0, _command.getEnvIdentifier)(env);
@@ -63,8 +53,5 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
63
53
  delete clonedEnv.deploymentStrategy;
64
54
  return clonedEnv;
65
55
  });
66
- return {
67
- header,
68
- data: clonedResponse.environments
69
- };
56
+ return clonedResponse.environments;
70
57
  });
@@ -220,7 +220,7 @@ const appQuery = exports.appQuery = `
220
220
  module: 'logs'
221
221
  }).option('type', 'Specify the type of Runtime Logs to retrieve. Accepts "batch" (only valid for WordPress environments).', 'app')
222
222
  // The default limit is set manually in the validateInputs function to address validation issues, avoiding incorrect replacement of the default value.
223
- .option('limit', `The maximum number of entries to return. Accepts an integer value between 1 and 5000 (defaults to ${LIMIT_DEFAULT}).`).option('follow', 'Output new entries as they are generated.').option('format', 'Render output in a particular format. Accepts “csv”, “json”, and “text”.', 'table').examples([{
223
+ .option('limit', `The maximum number of entries to return. Accepts an integer value between 1 and 5000 (defaults to ${LIMIT_DEFAULT}).`).option('follow', 'Output new entries as they are generated.').option('format', 'Render output in a particular format. Accepts “table“ (default), “csv“, “json“, and “text”.').examples([{
224
224
  usage: 'vip @example-app.production logs',
225
225
  description: 'Retrieve up to 500 of the most recent entries of application Runtime Logs from web containers.'
226
226
  }, {
@@ -169,10 +169,10 @@ void (0, _command.default)({
169
169
  appContext: true,
170
170
  appQuery,
171
171
  envContext: true,
172
- format: false,
172
+ format: true,
173
173
  module: 'slowlogs',
174
174
  usage: baseUsage
175
- }).option('limit', 'Set the maximum number of log entries. Accepts an integer value between 1 and 500.', 500).option('format', 'Render output in a particular format. Accepts “csv”, and “json”.', 'table').examples([{
175
+ }).option('limit', 'Set the maximum number of log entries. Accepts an integer value between 1 and 500.', 500).examples([{
176
176
  description: 'Retrieve up to 500 of the most recent entries from the MySQL slow query logs in the default format.',
177
177
  usage: exampleUsage
178
178
  }, {
@@ -92,7 +92,7 @@ async function getBuildConfiguration(application, environment) {
92
92
  return result.data.app.environments[0].buildConfiguration;
93
93
  } catch (error) {
94
94
  if (error.graphQLErrors && error.graphQLErrors.find(gqlError => gqlError.message === 'Unauthorized')) {
95
- 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/manage-user-access/vip-dashboard/'));
95
+ 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/'));
96
96
  await (0, _tracker.trackEvent)('validate_preflight_command_error', {
97
97
  env_id: environment.id,
98
98
  app_id: environment.appId,
@@ -162,7 +162,7 @@ async function vipValidatePreflightCommand(arg, opt) {
162
162
  ...baseTrackingParams,
163
163
  error: 'missing-package-json'
164
164
  });
165
- return exit.withError(`Could not find a 'package.json' in the current folder (${opt.path}).`);
165
+ return exit.withError(`Could not find a 'package.json' in the current directory (${opt.path}).`);
166
166
  }
167
167
  const customEnvVars = {};
168
168
  if (opt.env?.environmentVariables?.nodes.length > 0) {
@@ -350,23 +350,23 @@ async function handleResults(harmonia, results) {
350
350
 
351
351
  // If there is a Aborted test result
352
352
  if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
353
- 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.');
353
+ 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.');
354
354
  process.exit(1);
355
355
  }
356
356
 
357
357
  // If there is only a partial success, but no failures
358
358
  if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess] && !resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
359
- logToConsole(`${_chalk.default.bold.bgYellow(' PASS ')} The application has passed the required tests, but it does not follow all the recommendations.`);
359
+ logToConsole(`${_chalk.default.bold.bgYellow(' PASS ')} The application has passed the required tests, but it does not follow all of the recommendations.`);
360
360
  logToConsole('Please review the results.');
361
361
  process.exit(0);
362
362
  }
363
363
 
364
364
  // If there is a failure
365
365
  if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
366
- 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.');
366
+ 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.');
367
367
  process.exit(1);
368
368
  }
369
- logToConsole(`${_chalk.default.bold.bgGreen(' PASS ')} Congratulations. The application passes all the tests.`);
369
+ logToConsole(`${_chalk.default.bold.bgGreen(' PASS ')} Congratulations! The application passes all of the tests.`);
370
370
  process.exit(0);
371
371
  }
372
372
  async function validateArgs(opt) {
@@ -444,7 +444,8 @@ function sanitizeArgsForTracking(args) {
444
444
  return sanitizedArgs;
445
445
  }
446
446
  let commandOpts = {
447
- module: 'harmonia'
447
+ module: 'harmonia',
448
+ format: true
448
449
  };
449
450
 
450
451
  // The @app.env selector is optional, so we need to check if it was passed
@@ -457,12 +458,25 @@ if (parsedAlias.app) {
457
458
  appContext: true
458
459
  };
459
460
  } 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 defined.');
461
+ 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
  }
462
- (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 (${ALLOWED_NODEJS_VERSIONS.join(', ')})`).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('format', 'Output the log lines in CSV or JSON format', 'table').option(['P', 'path'], 'Path to the app to be tested', process.cwd()).examples([{
463
- usage: 'vip @mysite.production validate preflight',
464
- description: 'Runs the preflight tests to validate if your application is ready to be deployed to VIP Go'
463
+ const usage = 'vip validate preflight';
464
+ (0, _command.default)({
465
+ commandOpts,
466
+ usage
467
+ }).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([{
468
+ usage: 'vip validate preflight',
469
+ description: 'Run the validate command from within the root of the local Node.js codebase directory.'
465
470
  }, {
466
- usage: 'vip @mysite.production validate preflight --format json > results.json',
467
- description: 'Runs the preflight tests, but output the results in JSON format, and redirect the output to a file'
471
+ usage: 'vip validate preflight --path=/Users/example/Desktop/example-node-repo',
472
+ description: 'Run the validate command against a Node.js application directory at a specific local path.'
473
+ }, {
474
+ usage: 'vip @example-node-app.production validate preflight --node-version=20',
475
+ description: 'Run the validation tests with a specific version of Node.js.'
476
+ }, {
477
+ usage: 'vip validate preflight --format=json > results.json',
478
+ description: 'Output the results of the validation tests to a local file in JSON format.'
479
+ }, {
480
+ usage: 'vip @example-node-app.production validate preflight',
481
+ description: 'Run the validation tests with settings based on a targeted VIP Platform environment.'
468
482
  }]).argv(process.argv, vipValidatePreflightCommand);
@@ -6,6 +6,6 @@ var _tracker = require("../lib/tracker");
6
6
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
7
  (0, _command.default)({
8
8
  requiredArgs: 0
9
- }).command('preflight', 'Runs preflight tests to validate if your application is ready to be deployed').argv(process.argv, async () => {
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
10
  await (0, _tracker.trackEvent)('vip_validate_command_execute');
11
11
  });
package/dist/bin/vip.js CHANGED
@@ -22,7 +22,7 @@ const tokenURL = 'https://dashboard.wpvip.com/me/cli/token';
22
22
  const customDeployToken = process.env.WPVIP_DEPLOY_TOKEN;
23
23
  const runCmd = async function () {
24
24
  const cmd = (0, _command.default)();
25
- cmd.command('logout', 'Log out the current authenticated VIP-CLI user.').command('app', 'Interact with applications that the current authenticated VIP-CLI user has permission to access.').command('backup', 'Generate a backup of an environment.').command('cache', 'Manage page cache for an environment.').command('config', 'Manage environment configurations.').command('dev-env', 'Create and manage VIP Local Development Environments.').command('export', 'Export a copy of data associated with an environment.').command('import', 'Import media or SQL database files to an environment.').command('logs', 'Retrieve Runtime Logs from an environment.').command('search-replace', 'Search for a string in a local SQL file and replace it with a new string.').command('slowlogs', 'Retrieve MySQL slow query logs from an environment.').command('db', "Access an environment's database.").command('sync', 'Sync the database from production to a non-production environment.').command('whoami', 'Retrieve details about the current authenticated VIP-CLI user.').command('validate', 'Validate your VIP application and environment').command('wp', 'Execute a WP-CLI command against an environment.');
25
+ cmd.command('logout', 'Log out the current authenticated VIP-CLI user.').command('app', 'Interact with applications that the current authenticated VIP-CLI user has permission to access.').command('backup', 'Generate a backup of an environment.').command('cache', 'Manage page cache for an environment.').command('config', 'Manage environment configurations.').command('dev-env', 'Create and manage VIP Local Development Environments.').command('export', 'Export a copy of data associated with an environment.').command('import', 'Import media or SQL database files to an environment.').command('logs', 'Retrieve Runtime Logs from an environment.').command('search-replace', 'Search for a string in a local SQL file and replace it with a new string.').command('slowlogs', 'Retrieve MySQL slow query logs from an environment.').command('db', "Access an environment's database.").command('sync', 'Sync the database from production to a non-production environment.').command('whoami', 'Retrieve details about the current authenticated VIP-CLI user.').command('validate', 'Scan a Node.js codebase for issues that could prevent building or deploying.').command('wp', 'Execute a WP-CLI command against an environment.');
26
26
  cmd.argv(process.argv);
27
27
  };
28
28
 
@@ -25,11 +25,13 @@ const BACKUP_AND_JOB_STATUS_QUERY = (0, _graphqlTag.default)`
25
25
  id
26
26
  environments(id: $envId) {
27
27
  id
28
+ backupsSqlDumpTool
28
29
  latestBackup {
29
30
  id
30
31
  type
31
32
  size
32
33
  filename
34
+ sqlDumpTool
33
35
  createdAt
34
36
  }
35
37
  jobs(jobTypes: [db_backup_copy]) {
@@ -95,11 +97,13 @@ async function fetchLatestBackupAndJobStatusBase(appId, envId) {
95
97
  fetchPolicy: 'network-only'
96
98
  });
97
99
  const environments = response.data.app?.environments;
100
+ const envSqlDumpTool = environments?.[0]?.backupsSqlDumpTool;
98
101
  const latestBackup = environments?.[0]?.latestBackup;
99
102
  const jobs = environments?.[0]?.jobs || [];
100
103
  return {
101
104
  latestBackup,
102
- jobs
105
+ jobs,
106
+ envSqlDumpTool
103
107
  };
104
108
  }
105
109
  async function fetchLatestBackupAndJobStatus(appId, envId) {
@@ -358,7 +362,8 @@ class ExportSQLCommand {
358
362
  await this.runBackupJob();
359
363
  }
360
364
  const {
361
- latestBackup
365
+ latestBackup,
366
+ envSqlDumpTool
362
367
  } = await fetchLatestBackupAndJobStatus(this.app.id, this.env.id);
363
368
  if (!latestBackup) {
364
369
  await this.track('error', {
@@ -372,6 +377,10 @@ class ExportSQLCommand {
372
377
  } else {
373
378
  console.log(`${(0, _format.getGlyphForStatus)('success')} Backup created with timestamp ${latestBackup.createdAt}`);
374
379
  }
380
+ const showMyDumperWarning = (latestBackup.sqlDumpTool ?? envSqlDumpTool) === 'mydumper';
381
+ if (showMyDumperWarning) {
382
+ console.warn(_chalk.default.yellow.bold('WARNING:'), _chalk.default.yellow('This is a large or complex database. The backup file for this database is generated with MyDumper. ' + 'The file can only be loaded with MyLoader. ' + 'For more information: https://github.com/mydumper/mydumper'));
383
+ }
375
384
  if (await this.getExportJob()) {
376
385
  console.log(`Attaching to an existing export for the backup with timestamp ${latestBackup.createdAt}`);
377
386
  } else {
package/dist/lib/api.js CHANGED
@@ -43,7 +43,7 @@ function API({
43
43
  if (networkError && 'statusCode' in networkError && networkError.statusCode === 401) {
44
44
  let message = 'You are not authorized to perform this request; please logout with `vip logout`, then try again.';
45
45
  if (isServerError(networkError) && networkError.result?.code === 'token-disabled-inactivity') {
46
- message = 'Your token has been disabled due to inactivity; please log out with `vip logout`, then try again.';
46
+ message = 'Your token has expired due to inactivity; please log out with `vip logout`, then try again.';
47
47
  }
48
48
  console.error(_chalk.default.red('Unauthorized:'), message);
49
49
  process.exit(1);
@@ -68,6 +68,9 @@ _args.default.argv = async function (argv, cb) {
68
68
  version: false,
69
69
  debug: false
70
70
  });
71
+ if (_opts.format && !options.format) {
72
+ options.format = 'table';
73
+ }
71
74
  if (options.h || options.help) {
72
75
  this.showHelp();
73
76
  }
@@ -534,7 +537,7 @@ function _default(opts) {
534
537
  _args.default.option('force', 'Skip confirmation.', false);
535
538
  }
536
539
  if (_opts.format) {
537
- _args.default.option('format', 'Render output in a particular format. Accepts “csv”, and “json”.', 'table');
540
+ _args.default.option('format', 'Render output in a particular format. Accepts “table“ (default), “csv“, and “json“.');
538
541
  }
539
542
 
540
543
  // Add help and version to all subcommands
@@ -6,7 +6,7 @@ exports.validateFilename = validateFilename;
6
6
  exports.validateName = validateName;
7
7
  exports.validateTarFile = validateTarFile;
8
8
  exports.validateZipFile = validateZipFile;
9
- var _admZip = _interopRequireDefault(require("adm-zip"));
9
+ var _nodeStreamZip = _interopRequireDefault(require("node-stream-zip"));
10
10
  var _nodeFs = require("node:fs");
11
11
  var _path = _interopRequireDefault(require("path"));
12
12
  var tar = _interopRequireWildcard(require("tar"));
@@ -72,13 +72,13 @@ function validateName(name, isDirectory) {
72
72
  /**
73
73
  * Validate the existence of a symlink in a zip file. Ignores symlinks in node_modules/.bin/
74
74
  *
75
- * @param {IZipEntry} entry The zip entry to validate
75
+ * @param {ZipEntry} entry The zip entry to validate
76
76
  */
77
77
  function validateZipSymlink(entry) {
78
- if (symlinkIgnorePattern.test(entry.entryName)) {
78
+ if (symlinkIgnorePattern.test(entry.name)) {
79
79
  return;
80
80
  }
81
- const madeBy = entry.header.made >> 8; // eslint-disable-line no-bitwise
81
+ const madeBy = entry.verMade >> 8; // eslint-disable-line no-bitwise
82
82
  const errorMsg = errorMessages.symlink + entry.name;
83
83
 
84
84
  // DOS
@@ -98,23 +98,29 @@ function validateZipSymlink(entry) {
98
98
  * Validate a zip entry for disallowed characters and symlinks.
99
99
  * Ignores __MACOSX directories.
100
100
  *
101
- * @param {IZipEntry} entry The zip entry to validate
101
+ * @param {ZipEntry} entry The zip entry to validate
102
102
  */
103
103
  function validateZipEntry(entry) {
104
- if (entry.entryName.startsWith(macosxDir)) {
104
+ if (entry.name.startsWith(macosxDir)) {
105
105
  return;
106
106
  }
107
- validateName(entry.isDirectory ? entry.entryName : entry.name, entry.isDirectory);
107
+ validateName(entry.isDirectory ? entry.name : _path.default.basename(entry.name), entry.isDirectory);
108
108
  validateZipSymlink(entry);
109
109
  }
110
110
 
111
111
  /**
112
112
  * Validate the existence of a themes directory in the root folder.
113
113
  *
114
- * @param {IZipEntry[]} zipEntries The zip entries to validate
114
+ * @param rootFolder The root folder of the zip file
115
+ * @param {ZipEntry[]} zipEntries The zip entries to validate
115
116
  */
116
117
  function validateZipThemes(rootFolder, zipEntries) {
117
- const hasThemesDir = zipEntries.some(entry => entry.isDirectory && entry.entryName.startsWith(_path.default.join(rootFolder, 'themes/')));
118
+ const hasThemesDir = zipEntries.some(entry => {
119
+ // Convert win32 path separators to posix path separators
120
+ const posixPath = entry.name.replace(/\\/g, '/');
121
+ const requiredPosixPath = _path.default.join(rootFolder, 'themes/').replace(/\\/g, '/');
122
+ return entry.isDirectory && posixPath.startsWith(requiredPosixPath);
123
+ });
118
124
  if (!hasThemesDir) {
119
125
  exit.withError(errorMessages.missingThemes);
120
126
  }
@@ -125,17 +131,19 @@ function validateZipThemes(rootFolder, zipEntries) {
125
131
  *
126
132
  * @param {string} filePath The path to the zip file
127
133
  */
128
- function validateZipFile(filePath) {
134
+ async function validateZipFile(filePath) {
129
135
  try {
130
- const zipFile = new _admZip.default(filePath);
131
- const zipEntries = zipFile.getEntries();
132
- const rootDirs = zipEntries.filter(entry => entry.isDirectory && !entry.entryName.startsWith(macosxDir) && (entry.entryName.match(/\//g) || []).length === 1);
136
+ const zipFile = new _nodeStreamZip.default.async({
137
+ file: filePath
138
+ });
139
+ const zipEntries = await zipFile.entries();
140
+ const rootDirs = Object.values(zipEntries).filter(entry => entry.isDirectory && !entry.name.startsWith(macosxDir) && (entry.name.match(/\//g) || []).length === 1);
133
141
  if (rootDirs.length !== 1) {
134
142
  exit.withError(errorMessages.singleRootDir);
135
143
  }
136
- const rootFolder = rootDirs[0].entryName;
137
- validateZipThemes(rootFolder, zipEntries);
138
- zipEntries.forEach(entry => validateZipEntry(entry));
144
+ const rootFolder = rootDirs[0].name;
145
+ validateZipThemes(rootFolder, Object.values(zipEntries));
146
+ Object.values(zipEntries).forEach(entry => validateZipEntry(entry));
139
147
  } catch (error) {
140
148
  const err = error;
141
149
  exit.withError(`Error reading file: ${err.message}`);
package/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  ## Changelog
2
2
 
3
+ ### 3.9.2
4
+
5
+ * Fix `vip app`
6
+
7
+ **Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.9.1...3.9.2
8
+
9
+ ### 3.9.1
10
+
11
+ * Fix custom deploy zip file size limitation
12
+ * build(deps-dev): bump @types/node from 22.10.0 to 22.10.1
13
+ * build(deps-dev): bump @types/adm-zip from 0.5.6 to 0.5.7
14
+ * Update the `vip validate` command group to follow the VIP-CLI style guide
15
+ * fix: make the help text for the `format` option consistent for all commands
16
+ * Add a warning on `vip export` when exporting a MyDumper SQL dump
17
+
18
+ **Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.9.1...3.9.1
19
+
3
20
  ### 3.9.0
4
21
 
5
22
  * feat(dev-env): add support for PHP 8.4
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "3.9.0",
3
+ "version": "3.9.2",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@automattic/vip",
9
- "version": "3.9.0",
9
+ "version": "3.9.2",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
@@ -14,7 +14,6 @@
14
14
  "@automattic/vip-go-preflight-checks": "^2.0.16",
15
15
  "@automattic/vip-search-replace": "^1.1.1",
16
16
  "@json2csv/plainjs": "^7.0.3",
17
- "adm-zip": "^0.5.14",
18
17
  "args": "5.0.3",
19
18
  "chalk": "4.1.2",
20
19
  "check-disk-space": "3.4.0",
@@ -34,6 +33,7 @@
34
33
  "jwt-decode": "4.0.0",
35
34
  "lando": "github:automattic/lando-cli.git#6ca2668",
36
35
  "node-fetch": "^2.6.1",
36
+ "node-stream-zip": "1.15.0",
37
37
  "open": "^10.0.0",
38
38
  "proxy-from-env": "^1.1.0",
39
39
  "semver": "7.6.3",
@@ -115,7 +115,6 @@
115
115
  "@babel/preset-typescript": "7.26.0",
116
116
  "@jest/globals": "^29.7.0",
117
117
  "@jest/test-sequencer": "^29.7.0",
118
- "@types/adm-zip": "^0.5.5",
119
118
  "@types/args": "^5.0.3",
120
119
  "@types/cli-table": "^0.3.4",
121
120
  "@types/configstore": "5.0.1",
@@ -3428,15 +3427,6 @@
3428
3427
  "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.20.tgz",
3429
3428
  "integrity": "sha512-VqAAkydywPpkw63WQhPVKCD3SdwXuihCUVZbbiY3SfSTGQyHmwRoq27y4dmJdZuJwd5JIlQoMPyGvMbUPY0RKQ=="
3430
3429
  },
3431
- "node_modules/@types/adm-zip": {
3432
- "version": "0.5.6",
3433
- "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.6.tgz",
3434
- "integrity": "sha512-lRlcSLg5Yoo7C2H2AUiAoYlvifWoCx/se7iUNiCBTfEVVYFVn+Tr9ZGed4K73tYgLe9O4PjdJvbxlkdAOx/qiw==",
3435
- "dev": true,
3436
- "dependencies": {
3437
- "@types/node": "*"
3438
- }
3439
- },
3440
3430
  "node_modules/@types/args": {
3441
3431
  "version": "5.0.3",
3442
3432
  "resolved": "https://registry.npmjs.org/@types/args/-/args-5.0.3.tgz",
@@ -3618,9 +3608,9 @@
3618
3608
  "dev": true
3619
3609
  },
3620
3610
  "node_modules/@types/node": {
3621
- "version": "22.10.0",
3622
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz",
3623
- "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==",
3611
+ "version": "22.10.1",
3612
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz",
3613
+ "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==",
3624
3614
  "dependencies": {
3625
3615
  "undici-types": "~6.20.0"
3626
3616
  }
@@ -4024,14 +4014,6 @@
4024
4014
  "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
4025
4015
  }
4026
4016
  },
4027
- "node_modules/adm-zip": {
4028
- "version": "0.5.16",
4029
- "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz",
4030
- "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
4031
- "engines": {
4032
- "node": ">=12.0"
4033
- }
4034
- },
4035
4017
  "node_modules/agent-base": {
4036
4018
  "version": "6.0.2",
4037
4019
  "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -10182,6 +10164,18 @@
10182
10164
  "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
10183
10165
  "dev": true
10184
10166
  },
10167
+ "node_modules/node-stream-zip": {
10168
+ "version": "1.15.0",
10169
+ "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz",
10170
+ "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==",
10171
+ "engines": {
10172
+ "node": ">=0.12.0"
10173
+ },
10174
+ "funding": {
10175
+ "type": "github",
10176
+ "url": "https://github.com/sponsors/antelle"
10177
+ }
10178
+ },
10185
10179
  "node_modules/normalize-path": {
10186
10180
  "version": "3.0.0",
10187
10181
  "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -15688,15 +15682,6 @@
15688
15682
  "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.20.tgz",
15689
15683
  "integrity": "sha512-VqAAkydywPpkw63WQhPVKCD3SdwXuihCUVZbbiY3SfSTGQyHmwRoq27y4dmJdZuJwd5JIlQoMPyGvMbUPY0RKQ=="
15690
15684
  },
15691
- "@types/adm-zip": {
15692
- "version": "0.5.6",
15693
- "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.6.tgz",
15694
- "integrity": "sha512-lRlcSLg5Yoo7C2H2AUiAoYlvifWoCx/se7iUNiCBTfEVVYFVn+Tr9ZGed4K73tYgLe9O4PjdJvbxlkdAOx/qiw==",
15695
- "dev": true,
15696
- "requires": {
15697
- "@types/node": "*"
15698
- }
15699
- },
15700
15685
  "@types/args": {
15701
15686
  "version": "5.0.3",
15702
15687
  "resolved": "https://registry.npmjs.org/@types/args/-/args-5.0.3.tgz",
@@ -15878,9 +15863,9 @@
15878
15863
  "dev": true
15879
15864
  },
15880
15865
  "@types/node": {
15881
- "version": "22.10.0",
15882
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz",
15883
- "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==",
15866
+ "version": "22.10.1",
15867
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz",
15868
+ "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==",
15884
15869
  "requires": {
15885
15870
  "undici-types": "~6.20.0"
15886
15871
  }
@@ -16179,11 +16164,6 @@
16179
16164
  "dev": true,
16180
16165
  "requires": {}
16181
16166
  },
16182
- "adm-zip": {
16183
- "version": "0.5.16",
16184
- "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz",
16185
- "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ=="
16186
- },
16187
16167
  "agent-base": {
16188
16168
  "version": "6.0.2",
16189
16169
  "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -20661,6 +20641,11 @@
20661
20641
  "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
20662
20642
  "dev": true
20663
20643
  },
20644
+ "node-stream-zip": {
20645
+ "version": "1.15.0",
20646
+ "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz",
20647
+ "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw=="
20648
+ },
20664
20649
  "normalize-path": {
20665
20650
  "version": "3.0.0",
20666
20651
  "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "3.9.0",
3
+ "version": "3.9.2",
4
4
  "description": "The VIP Javascript library & CLI",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -114,7 +114,6 @@
114
114
  "@babel/preset-typescript": "7.26.0",
115
115
  "@jest/globals": "^29.7.0",
116
116
  "@jest/test-sequencer": "^29.7.0",
117
- "@types/adm-zip": "^0.5.5",
118
117
  "@types/args": "^5.0.3",
119
118
  "@types/cli-table": "^0.3.4",
120
119
  "@types/configstore": "5.0.1",
@@ -145,7 +144,6 @@
145
144
  "@automattic/vip-go-preflight-checks": "^2.0.16",
146
145
  "@automattic/vip-search-replace": "^1.1.1",
147
146
  "@json2csv/plainjs": "^7.0.3",
148
- "adm-zip": "^0.5.14",
149
147
  "args": "5.0.3",
150
148
  "chalk": "4.1.2",
151
149
  "check-disk-space": "3.4.0",
@@ -165,6 +163,7 @@
165
163
  "jwt-decode": "4.0.0",
166
164
  "lando": "github:automattic/lando-cli.git#6ca2668",
167
165
  "node-fetch": "^2.6.1",
166
+ "node-stream-zip": "1.15.0",
168
167
  "open": "^10.0.0",
169
168
  "proxy-from-env": "^1.1.0",
170
169
  "semver": "7.6.3",