@automattic/vip 3.19.0 → 3.19.1

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.
@@ -43,9 +43,13 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
43
43
  await (0, _tracker.trackEvent)('app_command_success');
44
44
 
45
45
  // Clone the read-only response object so we can modify it
46
- const clonedResponse = Object.assign({}, res);
46
+ const clonedResponse = {
47
+ ...res
48
+ };
47
49
  clonedResponse.environments = clonedResponse.environments.map(env => {
48
- const clonedEnv = Object.assign({}, env);
50
+ const clonedEnv = {
51
+ ...env
52
+ };
49
53
  clonedEnv.name = (0, _command.getEnvIdentifier)(env);
50
54
 
51
55
  // Use the short version of git commit hash
@@ -103,8 +103,8 @@ function isValidMd5(md5) {
103
103
  }
104
104
 
105
105
  /**
106
- * @param {AppForImport} app
107
- * @param {EnvForImport} env
106
+ * @param {import('../lib/site-import/db-file-import').AppForImport} app
107
+ * @param {import('../lib/site-import/db-file-import').EnvForImport} env
108
108
  * @param {string} fileNameOrURL
109
109
  * @param {boolean} isUrl
110
110
  * @param {string|null} md5
@@ -367,7 +367,7 @@ const displayPlaybook = ({
367
367
  }
368
368
  }
369
369
  };
370
- void (0, _command.default)({
370
+ (0, _command.default)({
371
371
  appContext: true,
372
372
  appQuery,
373
373
  envContext: true,
@@ -8,7 +8,6 @@
8
8
  exports.__esModule = true;
9
9
  exports.vipImportValidateFilesCmd = vipImportValidateFilesCmd;
10
10
  var _chalk = _interopRequireDefault(require("chalk"));
11
- var _url = _interopRequireDefault(require("url"));
12
11
  var _command = _interopRequireDefault(require("../lib/cli/command"));
13
12
  var _config = require("../lib/media-import/config");
14
13
  var _tracker = require("../lib/tracker");
@@ -24,9 +23,7 @@ async function vipImportValidateFilesCmd(arg = []) {
24
23
  *
25
24
  * Manipulating the file path/name to extract the folder name
26
25
  */
27
- const folder = arg.join(); // File comes in as an array as part of the args- turn it into a string
28
- arg = _url.default.parse(folder); // Then parse the file to its URL parts
29
- const filePath = arg.path; // Extract the path of the file
26
+ const filePath = arg.join(); // File comes in as an array as part of the args- turn it into a string
30
27
 
31
28
  if (!(await (0, _vipImportValidateFiles.isDirectory)(filePath))) {
32
29
  console.error(_chalk.default.red('✕ Error:'), 'The given path is not a directory. Provide a valid directory path.');
@@ -103,7 +103,6 @@ const bindStreamEvents = ({
103
103
  if (!isSubShell) {
104
104
  subShellRl.close();
105
105
  process.exit();
106
- return;
107
106
  }
108
107
  subShellRl.resume();
109
108
  subShellRl.prompt();
@@ -131,6 +130,14 @@ const getTokenForCommand = async (appId, envId, command) => {
131
130
  }
132
131
  });
133
132
  };
133
+
134
+ /**
135
+ * Returns the error so it can be caught by the `socket.on('error')`.
136
+ *
137
+ * @param {Error} err
138
+ * @returns {Error}
139
+ */
140
+ const onSocketError = err => err;
134
141
  const launchCommandAndGetStreams = async ({
135
142
  socket,
136
143
  guid,
@@ -162,10 +169,7 @@ const launchCommandAndGetStreams = async ({
162
169
  socket.close();
163
170
  exit.withError(`Cancel received from server: ${message}`);
164
171
  });
165
- (0, _socket2.default)(socket).on('error', err => {
166
- // This returns the error so it can be catched by the socket.on('error')
167
- return err;
168
- });
172
+ (0, _socket2.default)(socket).off('error', onSocketError).on('error', onSocketError);
169
173
  socket.on('error', err => {
170
174
  if (err === 'Rate limit exceeded') {
171
175
  console.log(_chalk.default.red('\nError:'), 'Rate limit exceeded: Please wait a moment and try again.');
@@ -262,10 +266,17 @@ const bindReconnectEvents = ({
262
266
 
263
267
  // create a new input stream so that we can still catch things like SIGINT while reconnecting
264
268
  if (currentJob.stdinStream) {
265
- process.stdin.unpipe(currentJob.stdinStream);
269
+ unpipeStreamsFromProcess({
270
+ stdin: currentJob.stdinStream,
271
+ stdout: currentJob.stdoutStream
272
+ });
266
273
  }
267
- process.stdin.pipe(_socket2.default.createStream());
274
+ currentJob.stdinStream = _socket2.default.createStream();
268
275
  currentJob.stdoutStream = _socket2.default.createStream();
276
+ pipeStreamsToProcess({
277
+ stdin: currentJob.stdinStream,
278
+ stdout: currentJob.stdoutStream
279
+ });
269
280
  bindStreamEvents({
270
281
  subShellRl,
271
282
  isSubShell,
@@ -138,12 +138,12 @@ class PhpMyAdminCommand {
138
138
  const {
139
139
  default: open
140
140
  } = await import('open');
141
- void open(url, {
141
+ return open(url, {
142
142
  wait: false
143
143
  });
144
144
  }
145
145
  async getStatus() {
146
- return await getPhpMyAdminStatus(this.app.id, this.env.id);
146
+ return getPhpMyAdminStatus(this.app.id, this.env.id);
147
147
  }
148
148
  async maybeEnablePhpMyAdmin() {
149
149
  const status = await this.getStatus();
@@ -29,8 +29,6 @@ var _default = async (path, options = {}) => {
29
29
  url = `${_api.API_HOST}${path}`;
30
30
  }
31
31
  const authToken = await _token.default.get();
32
-
33
- // TODO: remove this cast once the typings are fixed
34
32
  const proxyAgent = (0, _proxyAgent.createProxyAgent)(url);
35
33
  debug('running fetch', url);
36
34
  return (0, _nodeFetch.default)(url, {
@@ -316,21 +316,19 @@ _args.default.argv = async function (argv, cb) {
316
316
  }
317
317
 
318
318
  // Negotiate flag values
319
- switch (_opts.module) {
320
- case 'import-media':
321
- if ([true, 'true', 'yes'].includes(options.saveErrorLog)) {
322
- options.saveErrorLog = 'true';
323
- } else if ([false, 'false', 'no'].includes(options.saveErrorLog)) {
324
- options.saveErrorLog = 'false';
325
- } else {
326
- options.saveErrorLog = 'prompt';
327
- }
328
- break;
319
+ if (_opts.module === 'import-media') {
320
+ if ([true, 'true', 'yes'].includes(options.saveErrorLog)) {
321
+ options.saveErrorLog = 'true';
322
+ } else if ([false, 'false', 'no'].includes(options.saveErrorLog)) {
323
+ options.saveErrorLog = 'false';
324
+ } else {
325
+ options.saveErrorLog = 'prompt';
326
+ }
329
327
  }
330
328
 
331
329
  // Prompt for confirmation if necessary
332
330
  if (_opts.requireConfirm && !options.force) {
333
- /** @type {Tuple[]} */
331
+ /** @type {import('./format').Tuple[]} */
334
332
  const info = [];
335
333
  if (options.app) {
336
334
  info.push({
@@ -2,19 +2,38 @@
2
2
 
3
3
  exports.__esModule = true;
4
4
  exports.default = void 0;
5
+ exports.loadConfigFile = loadConfigFile;
5
6
  var _debug = _interopRequireDefault(require("debug"));
7
+ var _nodeFs = require("node:fs");
8
+ var _nodePath = _interopRequireDefault(require("node:path"));
6
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ // I don't like using synchronous versions, but until we migrate to ESM, we have to.
11
+
7
12
  const debug = (0, _debug.default)('@automattic/vip:lib:cli:config');
8
- let configFromFile;
9
- try {
13
+ function loadConfigFile() {
14
+ const paths = [
10
15
  // Get `local` config first; this will only exist in dev as it's npmignore-d.
11
- // eslint-disable-next-line @typescript-eslint/no-var-requires
12
- configFromFile = require('../../../config/config.local.json');
13
- debug('Loaded config data from config.local.json');
14
- } catch {
15
- // Fall back to `publish` config file.
16
- // eslint-disable-next-line @typescript-eslint/no-var-requires
17
- configFromFile = require('../../../config/config.publish.json');
18
- debug('Loaded config data from config.publish.json');
16
+ _nodePath.default.join(__dirname, '../../../config/config.local.json'), _nodePath.default.join(__dirname, '../../../config/config.publish.json')];
17
+ for (const filePath of paths) {
18
+ try {
19
+ const data = (0, _nodeFs.readFileSync)(filePath, 'utf-8');
20
+ debug(`Found config file at ${filePath}`);
21
+ return JSON.parse(data);
22
+ } catch (err) {
23
+ if (!(err instanceof Error) || !('code' in err) || err.code !== 'ENOENT') {
24
+ debug(`Error reading config file at ${filePath}:`, err);
25
+ }
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+ const configFromFile = loadConfigFile();
31
+ if (null === configFromFile) {
32
+ // This should not happen because `config/config.publish.json` is always present.
33
+ console.error('FATAL ERROR: Could not find a valid configuration file');
34
+ process.exit(1);
19
35
  }
20
- var _default = exports.default = configFromFile;
36
+
37
+ // Without this, TypeScript will export `configFromFile` as `Config | null`
38
+ const exportedConfig = configFromFile;
39
+ var _default = exports.default = exportedConfig;
@@ -91,14 +91,10 @@ function keyValue(values) {
91
91
  value
92
92
  } of values) {
93
93
  let formattedValue;
94
- switch (key.toLowerCase() // NOSONAR
95
- ) {
96
- case 'environment':
97
- formattedValue = formatEnvironment(value);
98
- break;
99
- default:
100
- formattedValue = value;
101
- break;
94
+ if (key.toLowerCase() === 'environment') {
95
+ formattedValue = formatEnvironment(value);
96
+ } else {
97
+ formattedValue = value;
102
98
  }
103
99
  lines.push(`+ ${key}: ${formattedValue}`);
104
100
  }
@@ -315,7 +315,8 @@ const formatSoftwareSettings = (softwareSetting, includes, format) => {
315
315
  if (includes.includes('available_versions')) {
316
316
  result.available_versions = _optionsForVersion(softwareSetting).filter(option => !option.deprecated).map(option => option.value);
317
317
  if (format !== 'json') {
318
- result.available_versions = result.available_versions.sort().join(',');
318
+ result.available_versions.sort((lhs, rhs) => lhs.localeCompare(rhs));
319
+ result.available_versions = result.available_versions.join(',');
319
320
  }
320
321
  }
321
322
  return result;
@@ -155,8 +155,6 @@ function preProcessInstanceData(instanceData) {
155
155
  // We need to make sure the redirect is an absolute path
156
156
  newInstanceData.mediaRedirectDomain = `https://${instanceData.mediaRedirectDomain}`;
157
157
  }
158
-
159
- // isNaN supports only number in TypeScript, actually, because isNaN('123') returns false despite being a string
160
158
  if (isNaN(instanceData.wordpress.tag)) {
161
159
  newInstanceData.wordpress.tag = 'trunk';
162
160
  }
@@ -692,7 +690,6 @@ async function maybeUpdateVersion(lando, slug) {
692
690
  */
693
691
  function fetchVersionList() {
694
692
  const url = `https://${_devEnvironment.DEV_ENVIRONMENT_RAW_GITHUB_HOST}${_devEnvironment.DEV_ENVIRONMENT_WORDPRESS_VERSIONS_URI}`;
695
- // TODO: remove this cast once the typings are fixed
696
693
  const proxyAgent = (0, _proxyAgent.createProxyAgent)(url);
697
694
  return (0, _nodeFetch.default)(url, {
698
695
  agent: proxyAgent ?? undefined
@@ -5,17 +5,18 @@ exports.default = void 0;
5
5
  var _debug = _interopRequireDefault(require("debug"));
6
6
  var _insecure = _interopRequireDefault(require("./keychain/insecure"));
7
7
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
- let exportValue;
8
+ let keychain;
9
9
  const debug = (0, _debug.default)('@automattic/vip:keychain');
10
10
  try {
11
11
  // Try using Secure keychain ("keytar") first
12
12
  // eslint-disable-next-line @typescript-eslint/no-var-requires
13
13
  const Secure = require('./keychain/secure');
14
- exportValue = new Secure();
14
+ keychain = new Secure();
15
15
  } catch (error) {
16
16
  debug('Cannot use Secure keychain; falling back to Insecure keychain (Details: %o)', error);
17
17
 
18
18
  // Fallback to Insecure keychain if we can't
19
- exportValue = new _insecure.default('vip-go-cli');
19
+ keychain = new _insecure.default('vip-go-cli');
20
20
  }
21
- var _default = exports.default = exportValue;
21
+ const exportedKeychain = keychain;
22
+ var _default = exports.default = exportedKeychain;
@@ -44,7 +44,7 @@ async function fileLineValidations(appId, envId, fileName, validations, searchRe
44
44
  await new Promise(resolve => readInterface.on('close', resolve));
45
45
  readInterface.close();
46
46
  return Promise.all(validations.map(validation => {
47
- if (Object.prototype.hasOwnProperty.call(validation, 'postLineExecutionProcessing') && typeof validation.postLineExecutionProcessing === 'function') {
47
+ if (Object.hasOwn(validation, 'postLineExecutionProcessing') && typeof validation.postLineExecutionProcessing === 'function') {
48
48
  return validation.postLineExecutionProcessing({
49
49
  fileName,
50
50
  isImport,