@automattic/vip 3.4.1 → 3.5.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.
- package/assets/dev-env.lando.template.yml.ejs +21 -4
- package/dist/bin/vip-app-deploy-validate.js +7 -5
- package/dist/bin/vip-app-deploy.js +10 -8
- package/dist/bin/vip-app-list.js +17 -12
- package/dist/bin/vip-app.js +1 -1
- package/dist/bin/vip-config-envvar-delete.js +1 -1
- package/dist/bin/vip-config-envvar-set.js +1 -1
- package/dist/bin/vip.js +1 -1
- package/dist/commands/export-sql.js +9 -1
- package/dist/lib/constants/dev-environment.js +1 -1
- package/dist/lib/dev-environment/dev-environment-cli.js +6 -4
- package/dist/lib/dev-environment/dev-environment-configuration-file.js +4 -1
- package/dist/lib/dev-environment/dev-environment-core.js +3 -0
- package/dist/lib/dev-environment/dev-environment-lando.js +12 -9
- package/dist/lib/retry.js +153 -0
- package/dist/lib/validations/custom-deploy.js +2 -2
- package/dist/lib/validations/sql.js +8 -2
- package/docs/CHANGELOG.md +22 -0
- package/npm-shrinkwrap.json +28 -28
- package/package.json +3 -3
|
@@ -58,6 +58,9 @@ services:
|
|
|
58
58
|
<% } %>
|
|
59
59
|
<% if ( autologinKey ) { %>
|
|
60
60
|
VIP_DEV_AUTOLOGIN_KEY: "<%= autologinKey %>"
|
|
61
|
+
<% } %>
|
|
62
|
+
<% if ( cron ) { %>
|
|
63
|
+
ENABLE_CRON: 1
|
|
61
64
|
<% } %>
|
|
62
65
|
LANDO_NO_USER_PERMS: 'enable'
|
|
63
66
|
LANDO_NEEDS_EXEC: 1
|
|
@@ -83,6 +86,7 @@ services:
|
|
|
83
86
|
--domain "http://<%= siteSlug %>.<%= domain %>/"
|
|
84
87
|
--title "<%= wpTitle %>"
|
|
85
88
|
<% if ( multisite ) { %>--ms-domain "<%= siteSlug %>.<%= domain %>" <% if ( multisite === true || multisite === 'subdomain' ) { %>--subdomain <% } %> <% } %>
|
|
89
|
+
|
|
86
90
|
database:
|
|
87
91
|
type: compose
|
|
88
92
|
services:
|
|
@@ -120,12 +124,25 @@ services:
|
|
|
120
124
|
|
|
121
125
|
<% if ( phpmyadmin ) { %>
|
|
122
126
|
phpmyadmin:
|
|
123
|
-
type:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
type: compose
|
|
128
|
+
services:
|
|
129
|
+
image: phpmyadmin:5
|
|
130
|
+
command: /docker-entrypoint.sh apache2-foreground
|
|
127
131
|
environment:
|
|
132
|
+
MYSQL_ROOT_PASSWORD: ''
|
|
133
|
+
PMA_HOSTS: database
|
|
134
|
+
PMA_PORT: 3306
|
|
135
|
+
PMA_USER: root
|
|
136
|
+
PMA_PASSWORD: ''
|
|
128
137
|
UPLOAD_LIMIT: 4G
|
|
138
|
+
LANDO_NO_USER_PERMS: 1
|
|
139
|
+
LANDO_NEEDS_EXEC: 1
|
|
140
|
+
ports:
|
|
141
|
+
- 127.0.0.1::80
|
|
142
|
+
volumes:
|
|
143
|
+
- pma_www:/var/www/html
|
|
144
|
+
volumes:
|
|
145
|
+
pma_www:
|
|
129
146
|
<% } %>
|
|
130
147
|
|
|
131
148
|
<% if ( elasticsearch ) { %>
|
|
@@ -20,6 +20,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
20
20
|
* Internal dependencies
|
|
21
21
|
*/
|
|
22
22
|
const debug = (0, _debug.default)('@automattic/vip:bin:vip-app-deploy-validate');
|
|
23
|
+
const baseUsage = 'vip app deploy validate';
|
|
23
24
|
async function appDeployValidateCmd(arg = [], opts = {}) {
|
|
24
25
|
const app = opts.app;
|
|
25
26
|
const env = opts.env;
|
|
@@ -37,14 +38,15 @@ async function appDeployValidateCmd(arg = [], opts = {}) {
|
|
|
37
38
|
} else {
|
|
38
39
|
await (0, _customDeploy2.validateTarFile)(fileName);
|
|
39
40
|
}
|
|
40
|
-
console.log(_chalk.default.green('✓ Compressed file has been successfully validated with no errors
|
|
41
|
+
console.log(_chalk.default.green('✓ Compressed file has been successfully validated with no errors.'));
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
// Command examples for the `vip app deploy validate` help prompt
|
|
44
45
|
const examples = [{
|
|
45
|
-
usage: 'vip app
|
|
46
|
-
description: 'Validate the
|
|
46
|
+
usage: 'vip app deploy validate file.tar.gz',
|
|
47
|
+
description: 'Validate the directory structure of the local archived file named "file.tar.gz".'
|
|
47
48
|
}];
|
|
48
49
|
void (0, _command.default)({
|
|
49
|
-
requiredArgs: 1
|
|
50
|
-
|
|
50
|
+
requiredArgs: 1,
|
|
51
|
+
usage: baseUsage
|
|
52
|
+
}).examples(examples).argv(process.argv, appDeployValidateCmd);
|
|
@@ -35,6 +35,7 @@ const START_DEPLOY_MUTATION = (0, _graphqlTag.default)`
|
|
|
35
35
|
}
|
|
36
36
|
`;
|
|
37
37
|
const debug = (0, _debug.default)('@automattic/vip:bin:vip-app-deploy');
|
|
38
|
+
const baseUsage = 'vip app deploy';
|
|
38
39
|
const DEPLOY_PREFLIGHT_PROGRESS_STEPS = [{
|
|
39
40
|
id: 'upload',
|
|
40
41
|
name: 'Uploading file'
|
|
@@ -221,15 +222,16 @@ Processing the file for deployment to your environment...
|
|
|
221
222
|
const examples = [
|
|
222
223
|
// `app` subcommand
|
|
223
224
|
{
|
|
224
|
-
usage: 'vip app
|
|
225
|
-
description: 'Deploy
|
|
225
|
+
usage: 'WPVIP_DEPLOY_TOKEN=1234 vip @example-app.develop app deploy file.zip',
|
|
226
|
+
description: 'Deploy a local archived file named "file.zip" that contains application code to a VIP Platform environment that has Custom Deployment enabled.'
|
|
226
227
|
}, {
|
|
227
|
-
usage: 'vip app
|
|
228
|
-
description: '
|
|
228
|
+
usage: 'WPVIP_DEPLOY_TOKEN=1234 vip @example-app.develop app deploy file.tgz --message="A description for this deploy"',
|
|
229
|
+
description: 'Add a descriptive message for the Custom Deployment of the archived file named "file.tgz".'
|
|
229
230
|
}, {
|
|
230
|
-
usage: 'vip app
|
|
231
|
-
description: '
|
|
231
|
+
usage: 'WPVIP_DEPLOY_TOKEN=1234 vip @example-app.develop app deploy file.tar.gz --skip-confirmation',
|
|
232
|
+
description: 'Skip the confirmation prompt for the Custom Deployment of the archived file named "file.tar.gz" to the environment.'
|
|
232
233
|
}];
|
|
233
234
|
void (0, _command.default)({
|
|
234
|
-
requiredArgs: 1
|
|
235
|
-
|
|
235
|
+
requiredArgs: 1,
|
|
236
|
+
usage: baseUsage
|
|
237
|
+
}).command('validate', 'Validate the directory structure of an archived file.').examples(examples).option('message', 'Add a description of a deployment.').option('skip-confirmation', 'Skip the confirmation prompt.').option('force', 'Skip confirmation prompt (deprecated)').option('app', 'Target an application. Accepts a string value for the application name or an integer for the application ID.').option('env', 'Target an environment. Accepts a string value for the environment type.').argv(process.argv, appDeployCmd);
|
package/dist/bin/vip-app-list.js
CHANGED
|
@@ -6,27 +6,32 @@ var _api = _interopRequireDefault(require("../lib/api"));
|
|
|
6
6
|
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
7
7
|
var _tracker = require("../lib/tracker");
|
|
8
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const baseUsage = 'vip app list';
|
|
9
10
|
(0, _command.default)({
|
|
10
|
-
format: true
|
|
11
|
-
|
|
11
|
+
format: true,
|
|
12
|
+
usage: baseUsage
|
|
13
|
+
}).examples([{
|
|
14
|
+
usage: baseUsage + '\n' + ' - ┌──────┬─────────────────┬─────────────────────────────────┐\n' + ' - │ id │ name │ repo │\n' + ' - ┌──────┬─────────────────┬─────────────────────────────────┐\n' + ' - │ 8886 │ example-app │ wpcomvip/my-org-example-app │\n' + ' - ┌──────┬─────────────────┬─────────────────────────────────┐\n' + ' - │ 4325 │ mytestmultisite │ wpcomvip/my-org-mytestmultisite │\n' + ' - └──────┴─────────────────┴─────────────────────────────────┘\n',
|
|
15
|
+
description: 'Retrieve a list of applications that can be accessed by the current authenticated VIP-CLI user.'
|
|
16
|
+
}]).argv(process.argv, async () => {
|
|
12
17
|
const api = (0, _api.default)();
|
|
13
18
|
await (0, _tracker.trackEvent)('app_list_command_execute');
|
|
14
19
|
let response;
|
|
15
20
|
try {
|
|
16
21
|
response = await api.query({
|
|
17
22
|
query: (0, _graphqlTag.default)`
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
query Apps($first: Int, $after: String) {
|
|
24
|
+
apps(first: $first, after: $after) {
|
|
25
|
+
total
|
|
26
|
+
nextCursor
|
|
27
|
+
edges {
|
|
28
|
+
id
|
|
29
|
+
name
|
|
30
|
+
repo
|
|
31
|
+
}
|
|
26
32
|
}
|
|
27
33
|
}
|
|
28
|
-
|
|
29
|
-
`,
|
|
34
|
+
`,
|
|
30
35
|
variables: {
|
|
31
36
|
first: 100,
|
|
32
37
|
after: null // TODO make dynamic
|
package/dist/bin/vip-app.js
CHANGED
|
@@ -11,7 +11,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
11
11
|
(0, _command.default)({
|
|
12
12
|
requiredArgs: 1,
|
|
13
13
|
format: true
|
|
14
|
-
}).example('vip app
|
|
14
|
+
}).example('vip app list', 'Retrieve a list of applications that can be accessed by the current authenticated VIP-CLI user.').example('vip app example-app', 'Retrieve information about the application named "example-app" and its environments.').example('WPVIP_DEPLOY_TOKEN=1234 vip @example-app.develop app deploy file.zip', 'Deploy a local archived file named "file.zip" that contains application code to a VIP Platform environment that has Custom Deployment enabled.').command('list', 'Retrieve a list of applications that can be accessed by the current authenticated VIP-CLI user.').command('deploy', 'Deploy an archived file of application code to an environment that has Custom Deployment enabled.').argv(process.argv, async arg => {
|
|
15
15
|
await (0, _tracker.trackEvent)('app_command_execute');
|
|
16
16
|
let res;
|
|
17
17
|
try {
|
|
@@ -46,7 +46,7 @@ async function deleteEnvVarCommand(arg, opt) {
|
|
|
46
46
|
await (0, _tracker.trackEvent)('envvar_delete_user_cancelled_input', trackingParams);
|
|
47
47
|
(0, _input.cancel)();
|
|
48
48
|
});
|
|
49
|
-
if (!(await (0, _input.confirm)(`Are you sure? ${_chalk.default.bold.red('Deletion is permanent')}
|
|
49
|
+
if (!(await (0, _input.confirm)(`Are you sure? ${_chalk.default.bold.red('Deletion is permanent')}`))) {
|
|
50
50
|
await (0, _tracker.trackEvent)('envvar_delete_user_cancelled_confirmation', trackingParams);
|
|
51
51
|
(0, _input.cancel)();
|
|
52
52
|
}
|
|
@@ -65,7 +65,7 @@ async function setEnvVarCommand(arg, opt) {
|
|
|
65
65
|
console.log('===== Received value printed above =====');
|
|
66
66
|
console.log();
|
|
67
67
|
}
|
|
68
|
-
if (!(await (0, _input.confirm)(`Please ${_chalk.default.bold('confirm')} the input value above
|
|
68
|
+
if (!(await (0, _input.confirm)(`Please ${_chalk.default.bold('confirm')} the input value above`))) {
|
|
69
69
|
await (0, _tracker.trackEvent)('envvar_set_user_cancelled_confirmation', trackingParams);
|
|
70
70
|
(0, _input.cancel)();
|
|
71
71
|
}
|
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', '
|
|
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 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', 'Retrieve MySQL slow query logs from an environment.').command('db', "Access an environment's database.").command('sync', 'Sync production to a development environment').command('whoami', 'Retrieve details about the current authenticated VIP-CLI user.').command('validate', 'Validate your VIP application and environment').command('wp', 'Run WP CLI commands against an environment');
|
|
26
26
|
cmd.argv(process.argv);
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -13,6 +13,7 @@ var _backupStorageAvailability = require("../lib/backup-storage-availability/bac
|
|
|
13
13
|
var exit = _interopRequireWildcard(require("../lib/cli/exit"));
|
|
14
14
|
var _format = require("../lib/cli/format");
|
|
15
15
|
var _progress = require("../lib/cli/progress");
|
|
16
|
+
var _retry = require("../lib/retry");
|
|
16
17
|
var _utils = require("../lib/utils");
|
|
17
18
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
18
19
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
@@ -83,7 +84,7 @@ const CREATE_EXPORT_JOB_MUTATION = exports.CREATE_EXPORT_JOB_MUTATION = (0, _gra
|
|
|
83
84
|
* @param {number} envId Environment ID
|
|
84
85
|
* @return {Promise} A promise which resolves to the latest backup and job status
|
|
85
86
|
*/
|
|
86
|
-
async function
|
|
87
|
+
async function fetchLatestBackupAndJobStatusBase(appId, envId) {
|
|
87
88
|
const api = (0, _api.default)();
|
|
88
89
|
const response = await api.query({
|
|
89
90
|
query: BACKUP_AND_JOB_STATUS_QUERY,
|
|
@@ -107,6 +108,13 @@ async function fetchLatestBackupAndJobStatus(appId, envId) {
|
|
|
107
108
|
jobs
|
|
108
109
|
};
|
|
109
110
|
}
|
|
111
|
+
async function fetchLatestBackupAndJobStatus(appId, envId) {
|
|
112
|
+
return await (0, _retry.retry)({
|
|
113
|
+
retryOnlyIf: options => {
|
|
114
|
+
return (options.error.message || '').indexOf('Unexpected token < in JSON at position 0') !== -1;
|
|
115
|
+
}
|
|
116
|
+
}, () => fetchLatestBackupAndJobStatusBase(appId, envId));
|
|
117
|
+
}
|
|
110
118
|
|
|
111
119
|
/**
|
|
112
120
|
* Generates a download link for a backup
|
|
@@ -32,4 +32,4 @@ const DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_DEFAULTS = {
|
|
|
32
32
|
multisite: false,
|
|
33
33
|
phpVersion: Object.keys(DEV_ENVIRONMENT_PHP_VERSIONS)[0]
|
|
34
34
|
};
|
|
35
|
-
const DEV_ENVIRONMENT_VERSION = exports.DEV_ENVIRONMENT_VERSION = '2.0
|
|
35
|
+
const DEV_ENVIRONMENT_VERSION = exports.DEV_ENVIRONMENT_VERSION = '2.1.0';
|
|
@@ -250,13 +250,15 @@ async function promptForArguments(preselectedOptions, defaultOptions, suppressPr
|
|
|
250
250
|
xdebugConfig: preselectedOptions.xdebugConfig,
|
|
251
251
|
siteSlug: '',
|
|
252
252
|
mailpit: false,
|
|
253
|
-
photon: false
|
|
253
|
+
photon: false,
|
|
254
|
+
cron: false
|
|
254
255
|
};
|
|
255
256
|
const promptLabels = {
|
|
256
257
|
xdebug: 'XDebug',
|
|
257
258
|
phpmyadmin: 'phpMyAdmin',
|
|
258
259
|
mailpit: 'Mailpit',
|
|
259
|
-
photon: 'Photon'
|
|
260
|
+
photon: 'Photon',
|
|
261
|
+
cron: 'Cron'
|
|
260
262
|
};
|
|
261
263
|
if (create && !instanceData.mediaRedirectDomain && defaultOptions.mediaRedirectDomain) {
|
|
262
264
|
const mediaRedirectPromptText = `Would you like to redirect to ${defaultOptions.mediaRedirectDomain} for missing media files?`;
|
|
@@ -280,7 +282,7 @@ async function promptForArguments(preselectedOptions, defaultOptions, suppressPr
|
|
|
280
282
|
} else {
|
|
281
283
|
instanceData.elasticsearch = await promptForBoolean('Enable Elasticsearch (needed by Enterprise Search)?', Boolean(defaultOptions.elasticsearch));
|
|
282
284
|
}
|
|
283
|
-
const services = ['phpmyadmin', 'xdebug', 'mailpit', 'photon'];
|
|
285
|
+
const services = ['phpmyadmin', 'xdebug', 'mailpit', 'photon', 'cron'];
|
|
284
286
|
for (const service of services) {
|
|
285
287
|
if (service in instanceData) {
|
|
286
288
|
const preselected = preselectedOptions[service];
|
|
@@ -626,7 +628,7 @@ function processVersionOption(value) {
|
|
|
626
628
|
const phpVersionsSupported = Object.keys(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS).join(', ');
|
|
627
629
|
function addDevEnvConfigurationOptions(command) {
|
|
628
630
|
// We leave the third parameter to undefined on some because the defaults are handled in preProcessInstanceData()
|
|
629
|
-
return command.option('wordpress', 'Manage the version of WordPress. Accepts a string value for major versions (6.x). Defaults to the most recent version of WordPress.', undefined, processVersionOption).option(['u', 'mu-plugins'], 'Manage the source for VIP MU plugins. Accepts "demo" (default) for a read-only image of the staging branch, or a path to a built copy of VIP MU plugins on the local machine.').option('app-code', 'Manage the source for application code. Accepts "demo" (default) for a read-only image of WordPress VIP skeleton application code, or a path to a VIP formatted application repo on the local machine.').option('phpmyadmin', 'Enable or disable phpMyAdmin, disabled by default. Accepts "y" (default value) to enable or "n" to disable. When enabled, refer to the value of "PHPMYADMIN URLS" in the information output for a local environment for the URL to access phpMyAdmin.', undefined, processBooleanOption).option('xdebug', 'Enable or disable XDebug, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option('xdebug_config', 'Override some default configuration settings for Xdebug. Accepts a string value that is assigned to the XDEBUG_CONFIG environment variable.').option('elasticsearch', 'Enable or disable Elasticsearch (required by Enterprise Search), disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option(['r', 'media-redirect-domain'], 'Configure media files to be proxied from a VIP Platform environment. Accepts a string value for the primary domain of the VIP Platform environment or "n" to disable the media proxy.', undefined, processMediaRedirectDomainOption).option('php', `Manage the version of PHP. Accepts a string value for minor versions: ${phpVersionsSupported}`, undefined, processVersionOption).option(['A', 'mailpit'], 'Enable or disable Mailpit, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option(['H', 'photon'], 'Enable or disable Photon, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption);
|
|
631
|
+
return command.option('wordpress', 'Manage the version of WordPress. Accepts a string value for major versions (6.x). Defaults to the most recent version of WordPress.', undefined, processVersionOption).option(['u', 'mu-plugins'], 'Manage the source for VIP MU plugins. Accepts "demo" (default) for a read-only image of the staging branch, or a path to a built copy of VIP MU plugins on the local machine.').option('app-code', 'Manage the source for application code. Accepts "demo" (default) for a read-only image of WordPress VIP skeleton application code, or a path to a VIP formatted application repo on the local machine.').option('phpmyadmin', 'Enable or disable phpMyAdmin, disabled by default. Accepts "y" (default value) to enable or "n" to disable. When enabled, refer to the value of "PHPMYADMIN URLS" in the information output for a local environment for the URL to access phpMyAdmin.', undefined, processBooleanOption).option('xdebug', 'Enable or disable XDebug, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option('xdebug_config', 'Override some default configuration settings for Xdebug. Accepts a string value that is assigned to the XDEBUG_CONFIG environment variable.').option('elasticsearch', 'Enable or disable Elasticsearch (required by Enterprise Search), disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option(['r', 'media-redirect-domain'], 'Configure media files to be proxied from a VIP Platform environment. Accepts a string value for the primary domain of the VIP Platform environment or "n" to disable the media proxy.', undefined, processMediaRedirectDomainOption).option('php', `Manage the version of PHP. Accepts a string value for minor versions: ${phpVersionsSupported}`, undefined, processVersionOption).option('cron', 'Enable or disable cron, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option(['A', 'mailpit'], 'Enable or disable Mailpit, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option(['H', 'photon'], 'Enable or disable Photon, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption);
|
|
630
632
|
}
|
|
631
633
|
|
|
632
634
|
/**
|
|
@@ -84,6 +84,7 @@ function sanitizeConfiguration(configuration, configurationFilePath) {
|
|
|
84
84
|
mailpit: stringToBooleanIfDefined(configuration.mailpit),
|
|
85
85
|
'media-redirect-domain': configuration['media-redirect-domain']?.toString(),
|
|
86
86
|
photon: stringToBooleanIfDefined(configuration.photon),
|
|
87
|
+
cron: stringToBooleanIfDefined(configuration.cron),
|
|
87
88
|
meta: configurationMeta
|
|
88
89
|
};
|
|
89
90
|
|
|
@@ -121,7 +122,8 @@ function mergeConfigurationFileOptions(preselectedOptions, configurationFileOpti
|
|
|
121
122
|
xdebugConfig: configurationFileOptions['xdebug-config'],
|
|
122
123
|
mailpit: configurationFileOptions.mailpit,
|
|
123
124
|
mediaRedirectDomain: configurationFileOptions['media-redirect-domain'],
|
|
124
|
-
photon: configurationFileOptions.photon
|
|
125
|
+
photon: configurationFileOptions.photon,
|
|
126
|
+
cron: configurationFileOptions.cron
|
|
125
127
|
};
|
|
126
128
|
const mergedOptions = {};
|
|
127
129
|
Object.keys(configurationFileInstanceOptions).forEach(key => {
|
|
@@ -179,5 +181,6 @@ elasticsearch: false
|
|
|
179
181
|
xdebug: false
|
|
180
182
|
mailpit: false
|
|
181
183
|
photon: false
|
|
184
|
+
cron: false
|
|
182
185
|
`;
|
|
183
186
|
}
|
|
@@ -148,6 +148,9 @@ function preProcessInstanceData(instanceData) {
|
|
|
148
148
|
if (!newInstanceData.photon) {
|
|
149
149
|
newInstanceData.photon = false;
|
|
150
150
|
}
|
|
151
|
+
if (!newInstanceData.cron) {
|
|
152
|
+
newInstanceData.cron = false;
|
|
153
|
+
}
|
|
151
154
|
|
|
152
155
|
// Mailpit migration
|
|
153
156
|
newInstanceData.mailpit ??= false;
|
|
@@ -80,7 +80,7 @@ async function getLandoConfig() {
|
|
|
80
80
|
subdir: '.',
|
|
81
81
|
namespace: '@lando'
|
|
82
82
|
}],
|
|
83
|
-
disablePlugins: ['@lando/argv', '@lando/mailhog'],
|
|
83
|
+
disablePlugins: ['@lando/argv', '@lando/mailhog', '@lando/phpmyadmin'],
|
|
84
84
|
proxyName: 'vip-dev-env-proxy',
|
|
85
85
|
userConfRoot: landoDir,
|
|
86
86
|
home: fakeHomeDir,
|
|
@@ -373,16 +373,19 @@ async function getExtraServicesConnections(lando, app) {
|
|
|
373
373
|
// eslint-disable-next-line no-await-in-loop
|
|
374
374
|
const containerScan = service.id ? await lando.engine.docker.scan(service.id) : null;
|
|
375
375
|
if (containerScan?.NetworkSettings.Ports) {
|
|
376
|
-
const mappings = Object.
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
} = mappings[0][0];
|
|
376
|
+
const mappings = Object.values(containerScan.NetworkSettings.Ports).filter(externalMapping => externalMapping?.length);
|
|
377
|
+
mappings[0]?.forEach(({
|
|
378
|
+
HostIp: host,
|
|
379
|
+
HostPort: port
|
|
380
|
+
}) => {
|
|
382
381
|
const label = displayConfiguration.label ?? service.service;
|
|
383
382
|
const value = (displayConfiguration.protocol ? `${displayConfiguration.protocol}://` : '') + `${host}:${port}`;
|
|
384
|
-
extraServices[label]
|
|
385
|
-
|
|
383
|
+
if (extraServices[label]) {
|
|
384
|
+
extraServices[label] += `, ${value}`;
|
|
385
|
+
} else {
|
|
386
|
+
extraServices[label] = value;
|
|
387
|
+
}
|
|
388
|
+
});
|
|
386
389
|
}
|
|
387
390
|
}
|
|
388
391
|
return extraServices;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.EXPONENTIAL_BACKOFF_STARTING_IN_50_MS = exports.EXPONENTIAL_BACKOFF_STARTING_IN_200_MS = exports.EXPONENTIAL_BACKOFF_STARTING_IN_100_MS = void 0;
|
|
5
|
+
exports.exponentialBackoff = exponentialBackoff;
|
|
6
|
+
exports.retry = retry;
|
|
7
|
+
// copied over from our internal lib
|
|
8
|
+
|
|
9
|
+
const EXPONENTIAL_BACKOFF_STARTING_IN_50_MS = exports.EXPONENTIAL_BACKOFF_STARTING_IN_50_MS = exponentialBackoff(50);
|
|
10
|
+
const EXPONENTIAL_BACKOFF_STARTING_IN_100_MS = exports.EXPONENTIAL_BACKOFF_STARTING_IN_100_MS = exponentialBackoff(100);
|
|
11
|
+
const EXPONENTIAL_BACKOFF_STARTING_IN_200_MS = exports.EXPONENTIAL_BACKOFF_STARTING_IN_200_MS = exponentialBackoff(200);
|
|
12
|
+
const MAX_INTERVAL_BETWEEN_ATTEMPTS = 600000; // 10 minutes
|
|
13
|
+
|
|
14
|
+
const NOOP = async () => {};
|
|
15
|
+
const DEFAULT_OPTIONS = {
|
|
16
|
+
maxRetries: 4,
|
|
17
|
+
interval: EXPONENTIAL_BACKOFF_STARTING_IN_100_MS,
|
|
18
|
+
retryOnlyIf: () => Promise.resolve(true),
|
|
19
|
+
onRetry: NOOP,
|
|
20
|
+
onFailedAttempt: NOOP
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* We don't need a strict Error instance, which can help in cases (probably
|
|
24
|
+
* just tests) where code throws an object instead of an Error instance. We
|
|
25
|
+
* really just need to check for an object with a message property.
|
|
26
|
+
*/
|
|
27
|
+
function isErrorLike(value) {
|
|
28
|
+
return value instanceof Error || null !== value && 'object' === typeof value && 'message' in value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Execute a <task> and retries <options.maxRetries> times while it fails.
|
|
33
|
+
* @param {Object} [options] - The options.
|
|
34
|
+
* @param {number} [options.maxRetries] - The max number of retry attempts to be executed.
|
|
35
|
+
* @param {function|number} [options.interval] - The time to wait between retries in milliseconds.
|
|
36
|
+
* It can be either a number or a function.
|
|
37
|
+
* Function arguments: retryAttemptNumber.
|
|
38
|
+
* Expected return: a number representing the time in milliseconds.
|
|
39
|
+
* @param {function} [options.retryOnlyIf] - A function used to determine if a retry should be attempted.
|
|
40
|
+
* Arguments: Object<{ error, attemptNumber }>.
|
|
41
|
+
* Expected return: boolean|Promise<boolean>.
|
|
42
|
+
* @param {function} [options.onRetry] - A callback function executed right before a retry attempt.
|
|
43
|
+
* Arguments: Object<{ retryNumber: attemptNumber }>.
|
|
44
|
+
* Expected return: void|Promise<void>.
|
|
45
|
+
* @param {function} [options.onFailedAttempt] - A callback function executed right after a failed attempt.
|
|
46
|
+
* Arguments: Object<{ error, attemptNumber, attemptDuration }>.
|
|
47
|
+
* Expected return: void|Promise<void>.
|
|
48
|
+
* @param {function} task - The task to be executed.
|
|
49
|
+
* @return {any} - The value returned by the provided <task> function when it is successfully executed
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
async function retry(optionsOrTask, task) {
|
|
53
|
+
let options = optionsOrTask;
|
|
54
|
+
if (arguments.length < 3 && typeof optionsOrTask === 'function') {
|
|
55
|
+
task = optionsOrTask;
|
|
56
|
+
options = {};
|
|
57
|
+
}
|
|
58
|
+
const finalOptions = {
|
|
59
|
+
...DEFAULT_OPTIONS,
|
|
60
|
+
...options
|
|
61
|
+
};
|
|
62
|
+
const {
|
|
63
|
+
maxRetries,
|
|
64
|
+
interval,
|
|
65
|
+
retryOnlyIf,
|
|
66
|
+
onRetry,
|
|
67
|
+
onFailedAttempt
|
|
68
|
+
} = finalOptions;
|
|
69
|
+
validateTask(task);
|
|
70
|
+
validateOptions(finalOptions);
|
|
71
|
+
const maxAttempts = maxRetries + 1;
|
|
72
|
+
for (let attemptNumber = 1; attemptNumber <= maxAttempts; attemptNumber++) {
|
|
73
|
+
/* eslint-disable no-await-in-loop */
|
|
74
|
+
const attemptStart = Date.now();
|
|
75
|
+
try {
|
|
76
|
+
return await task();
|
|
77
|
+
} catch (caughtError) {
|
|
78
|
+
const attemptEnd = Date.now();
|
|
79
|
+
const attemptDuration = attemptEnd - attemptStart;
|
|
80
|
+
const attemptStartTime = new Date(attemptStart);
|
|
81
|
+
const attemptEndTime = new Date(attemptEnd);
|
|
82
|
+
const error = isErrorLike(caughtError) ? caughtError : new Error(String(caughtError));
|
|
83
|
+
await onFailedAttempt({
|
|
84
|
+
error,
|
|
85
|
+
attemptNumber,
|
|
86
|
+
attemptDuration,
|
|
87
|
+
attemptStartTime,
|
|
88
|
+
attemptEndTime
|
|
89
|
+
});
|
|
90
|
+
const shouldRetry = await retryOnlyIf({
|
|
91
|
+
error,
|
|
92
|
+
attemptNumber
|
|
93
|
+
});
|
|
94
|
+
if (attemptNumber === maxAttempts || shouldRetry !== true) {
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
await awaitInterval(interval, attemptNumber);
|
|
98
|
+
await onRetry({
|
|
99
|
+
retryNumber: attemptNumber
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
throw new Error('Error, wrong retry options set');
|
|
104
|
+
}
|
|
105
|
+
function isValidInterval(interval) {
|
|
106
|
+
if ('function' === typeof interval) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
return typeof interval === 'number' && Number.isInteger(interval) && interval >= 0 && interval <= MAX_INTERVAL_BETWEEN_ATTEMPTS;
|
|
110
|
+
}
|
|
111
|
+
async function awaitInterval(interval, attemptNumber) {
|
|
112
|
+
let newInterval;
|
|
113
|
+
if (typeof interval === 'function') {
|
|
114
|
+
newInterval = interval(attemptNumber);
|
|
115
|
+
if (!isValidInterval(newInterval)) {
|
|
116
|
+
throw new Error(`Invalid calculated interval for retry attempt ${attemptNumber}: "${newInterval}" (type: ${typeof newInterval})`);
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
newInterval = interval;
|
|
120
|
+
}
|
|
121
|
+
return new Promise(resolve => setTimeout(resolve, newInterval));
|
|
122
|
+
}
|
|
123
|
+
function validateTask(task) {
|
|
124
|
+
if (typeof task !== 'function') {
|
|
125
|
+
throw new Error('Invalid task: it should be a function');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function validateOptions({
|
|
129
|
+
maxRetries,
|
|
130
|
+
interval,
|
|
131
|
+
onFailedAttempt,
|
|
132
|
+
retryOnlyIf
|
|
133
|
+
}) {
|
|
134
|
+
if (!Number.isInteger(maxRetries) || maxRetries < 0) {
|
|
135
|
+
throw new Error('Invalid option "maxRetries": it should be an integer number >= 0');
|
|
136
|
+
}
|
|
137
|
+
if (!isValidInterval(interval)) {
|
|
138
|
+
const definition = `an integer number between 0 and ${MAX_INTERVAL_BETWEEN_ATTEMPTS}`;
|
|
139
|
+
throw new Error(`Invalid option "interval": it should be either ${definition}, or a synchronous function which returns ${definition}`);
|
|
140
|
+
}
|
|
141
|
+
if (!isValidInterval(interval)) {
|
|
142
|
+
throw new Error('Invalid option "interval": it should be either an integer number >= 0, or a synchronous function which returns an integer number >= 0');
|
|
143
|
+
}
|
|
144
|
+
if (typeof onFailedAttempt !== 'function') {
|
|
145
|
+
throw new Error('Invalid option "onFailedAttempt": it should be a function');
|
|
146
|
+
}
|
|
147
|
+
if (typeof retryOnlyIf !== 'function') {
|
|
148
|
+
throw new Error('Invalid option "retryOnlyIf": it should be a function');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function exponentialBackoff(startMilliseconds) {
|
|
152
|
+
return retryAttemptNumber => Math.pow(2, retryAttemptNumber - 1) * startMilliseconds;
|
|
153
|
+
}
|
|
@@ -15,9 +15,9 @@ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return
|
|
|
15
15
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
16
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
17
|
const errorMessages = {
|
|
18
|
-
missingThemes: 'Missing `themes` directory from root folder
|
|
18
|
+
missingThemes: 'Missing `themes` directory from root folder.',
|
|
19
19
|
symlink: 'Symlink detected: ',
|
|
20
|
-
singleRootDir: 'The compressed file must contain a single root directory
|
|
20
|
+
singleRootDir: 'The compressed file must contain a single root directory.',
|
|
21
21
|
invalidExt: 'Invalid file extension. Please provide a .zip, .tar.gz, or a .tgz file.',
|
|
22
22
|
invalidChars: (filename, invalidChars) => `Filename ${filename} contains disallowed characters: ${invalidChars}`
|
|
23
23
|
};
|
|
@@ -271,9 +271,15 @@ const checks = {
|
|
|
271
271
|
recommendation: ''
|
|
272
272
|
},
|
|
273
273
|
siteHomeUrlLando: {
|
|
274
|
-
matcher: "'(siteurl|home)',\\s?'(
|
|
274
|
+
matcher: "'(siteurl|home)',\\s?'([^']+)'",
|
|
275
275
|
matchHandler: (lineNumber, results, expectedDomain) => {
|
|
276
|
-
|
|
276
|
+
let foundDomain = results[2];
|
|
277
|
+
if (!/^https?:\/\//i.test(foundDomain)) {
|
|
278
|
+
return {
|
|
279
|
+
falsePositive: true
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
foundDomain = foundDomain.replace(/^https?:\/\//, '');
|
|
277
283
|
if (!foundDomain.trim()) {
|
|
278
284
|
return {
|
|
279
285
|
falsePositive: true
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
+
### 3.5.0
|
|
4
|
+
|
|
5
|
+
* feat(dev-env): add support for cron
|
|
6
|
+
* build(deps-dev): bump @automattic/eslint-plugin-wpvip from 0.11.0 to 0.12.0
|
|
7
|
+
* fix(dev-env): display all port mappings
|
|
8
|
+
* refactor(dev-env): migrate from `@lando/phpmyadmin` to `phpmyadmin` Docker image
|
|
9
|
+
|
|
10
|
+
**Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.4.2...3.5.0
|
|
11
|
+
|
|
12
|
+
### 3.4.2
|
|
13
|
+
|
|
14
|
+
* build(deps-dev): bump @types/node from 18.19.37 to 18.19.38
|
|
15
|
+
* build(deps-dev): bump typescript from 5.4.5 to 5.5.2
|
|
16
|
+
* build(deps-dev): bump @types/uuid from 9.0.8 to 10.0.0
|
|
17
|
+
* build(deps-dev): bump @types/node from 18.19.38 to 18.19.39
|
|
18
|
+
* fix(dev-env): ensure that URLs suggested for replacement start with `http(s)://`
|
|
19
|
+
* Remove unnecessary y/N choice for confirmations
|
|
20
|
+
* Update the vip app command to follow the VIP-CLI style guide
|
|
21
|
+
* Add retries to the fetching of jobs data
|
|
22
|
+
|
|
23
|
+
**Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.4.1...3.4.2
|
|
24
|
+
|
|
3
25
|
### 3.4.1
|
|
4
26
|
|
|
5
27
|
* Updating vip cache commands descriptions and examples to follow the VIP-CLI style guide
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@automattic/vip",
|
|
9
|
-
"version": "3.
|
|
9
|
+
"version": "3.5.0",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"vip-wp": "dist/bin/vip-wp.js"
|
|
109
109
|
},
|
|
110
110
|
"devDependencies": {
|
|
111
|
-
"@automattic/eslint-plugin-wpvip": "0.
|
|
111
|
+
"@automattic/eslint-plugin-wpvip": "0.12.0",
|
|
112
112
|
"@babel/cli": "7.24.7",
|
|
113
113
|
"@babel/core": "7.24.7",
|
|
114
114
|
"@babel/preset-env": "7.24.7",
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"@types/single-line-log": "1.1.2",
|
|
133
133
|
"@types/tar": "^6.1.13",
|
|
134
134
|
"@types/update-notifier": "^6.0.8",
|
|
135
|
-
"@types/uuid": "^
|
|
135
|
+
"@types/uuid": "^10.0.0",
|
|
136
136
|
"@types/xml2js": "^0.4.14",
|
|
137
137
|
"dockerode": "^4.0.0",
|
|
138
138
|
"eslint": "^8.35.0",
|
|
@@ -206,9 +206,9 @@
|
|
|
206
206
|
}
|
|
207
207
|
},
|
|
208
208
|
"node_modules/@automattic/eslint-plugin-wpvip": {
|
|
209
|
-
"version": "0.
|
|
210
|
-
"resolved": "https://registry.npmjs.org/@automattic/eslint-plugin-wpvip/-/eslint-plugin-wpvip-0.
|
|
211
|
-
"integrity": "sha512-
|
|
209
|
+
"version": "0.12.0",
|
|
210
|
+
"resolved": "https://registry.npmjs.org/@automattic/eslint-plugin-wpvip/-/eslint-plugin-wpvip-0.12.0.tgz",
|
|
211
|
+
"integrity": "sha512-ARF+Nj0HBHeaTPoWDA+BynaEergBrtHKDoYqIHtLWJEe7xMNRedB3Q4+lo1OuTZGA3ggBwMmOy5OU0izQwPpog==",
|
|
212
212
|
"dev": true,
|
|
213
213
|
"dependencies": {
|
|
214
214
|
"@babel/eslint-parser": "7.24.5",
|
|
@@ -3884,9 +3884,9 @@
|
|
|
3884
3884
|
"dev": true
|
|
3885
3885
|
},
|
|
3886
3886
|
"node_modules/@types/node": {
|
|
3887
|
-
"version": "18.19.
|
|
3888
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.
|
|
3889
|
-
"integrity": "sha512-
|
|
3887
|
+
"version": "18.19.39",
|
|
3888
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz",
|
|
3889
|
+
"integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==",
|
|
3890
3890
|
"dependencies": {
|
|
3891
3891
|
"undici-types": "~5.26.4"
|
|
3892
3892
|
}
|
|
@@ -3992,9 +3992,9 @@
|
|
|
3992
3992
|
}
|
|
3993
3993
|
},
|
|
3994
3994
|
"node_modules/@types/uuid": {
|
|
3995
|
-
"version": "
|
|
3996
|
-
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-
|
|
3997
|
-
"integrity": "sha512-
|
|
3995
|
+
"version": "10.0.0",
|
|
3996
|
+
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
|
|
3997
|
+
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
|
|
3998
3998
|
"dev": true
|
|
3999
3999
|
},
|
|
4000
4000
|
"node_modules/@types/xml2js": {
|
|
@@ -12643,9 +12643,9 @@
|
|
|
12643
12643
|
}
|
|
12644
12644
|
},
|
|
12645
12645
|
"node_modules/typescript": {
|
|
12646
|
-
"version": "5.
|
|
12647
|
-
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.
|
|
12648
|
-
"integrity": "sha512-
|
|
12646
|
+
"version": "5.5.2",
|
|
12647
|
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
|
|
12648
|
+
"integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
|
|
12649
12649
|
"dev": true,
|
|
12650
12650
|
"bin": {
|
|
12651
12651
|
"tsc": "bin/tsc",
|
|
@@ -13585,9 +13585,9 @@
|
|
|
13585
13585
|
}
|
|
13586
13586
|
},
|
|
13587
13587
|
"@automattic/eslint-plugin-wpvip": {
|
|
13588
|
-
"version": "0.
|
|
13589
|
-
"resolved": "https://registry.npmjs.org/@automattic/eslint-plugin-wpvip/-/eslint-plugin-wpvip-0.
|
|
13590
|
-
"integrity": "sha512-
|
|
13588
|
+
"version": "0.12.0",
|
|
13589
|
+
"resolved": "https://registry.npmjs.org/@automattic/eslint-plugin-wpvip/-/eslint-plugin-wpvip-0.12.0.tgz",
|
|
13590
|
+
"integrity": "sha512-ARF+Nj0HBHeaTPoWDA+BynaEergBrtHKDoYqIHtLWJEe7xMNRedB3Q4+lo1OuTZGA3ggBwMmOy5OU0izQwPpog==",
|
|
13591
13591
|
"dev": true,
|
|
13592
13592
|
"requires": {
|
|
13593
13593
|
"@babel/eslint-parser": "7.24.5",
|
|
@@ -16306,9 +16306,9 @@
|
|
|
16306
16306
|
"dev": true
|
|
16307
16307
|
},
|
|
16308
16308
|
"@types/node": {
|
|
16309
|
-
"version": "18.19.
|
|
16310
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.
|
|
16311
|
-
"integrity": "sha512-
|
|
16309
|
+
"version": "18.19.39",
|
|
16310
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz",
|
|
16311
|
+
"integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==",
|
|
16312
16312
|
"requires": {
|
|
16313
16313
|
"undici-types": "~5.26.4"
|
|
16314
16314
|
}
|
|
@@ -16415,9 +16415,9 @@
|
|
|
16415
16415
|
}
|
|
16416
16416
|
},
|
|
16417
16417
|
"@types/uuid": {
|
|
16418
|
-
"version": "
|
|
16419
|
-
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-
|
|
16420
|
-
"integrity": "sha512-
|
|
16418
|
+
"version": "10.0.0",
|
|
16419
|
+
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
|
|
16420
|
+
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
|
|
16421
16421
|
"dev": true
|
|
16422
16422
|
},
|
|
16423
16423
|
"@types/xml2js": {
|
|
@@ -22653,9 +22653,9 @@
|
|
|
22653
22653
|
}
|
|
22654
22654
|
},
|
|
22655
22655
|
"typescript": {
|
|
22656
|
-
"version": "5.
|
|
22657
|
-
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.
|
|
22658
|
-
"integrity": "sha512-
|
|
22656
|
+
"version": "5.5.2",
|
|
22657
|
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
|
|
22658
|
+
"integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
|
|
22659
22659
|
"dev": true
|
|
22660
22660
|
},
|
|
22661
22661
|
"typical": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "The VIP Javascript library & CLI",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
},
|
|
108
108
|
"homepage": "https://github.com/Automattic/vip#readme",
|
|
109
109
|
"devDependencies": {
|
|
110
|
-
"@automattic/eslint-plugin-wpvip": "0.
|
|
110
|
+
"@automattic/eslint-plugin-wpvip": "0.12.0",
|
|
111
111
|
"@babel/cli": "7.24.7",
|
|
112
112
|
"@babel/core": "7.24.7",
|
|
113
113
|
"@babel/preset-env": "7.24.7",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"@types/single-line-log": "1.1.2",
|
|
132
132
|
"@types/tar": "^6.1.13",
|
|
133
133
|
"@types/update-notifier": "^6.0.8",
|
|
134
|
-
"@types/uuid": "^
|
|
134
|
+
"@types/uuid": "^10.0.0",
|
|
135
135
|
"@types/xml2js": "^0.4.14",
|
|
136
136
|
"dockerode": "^4.0.0",
|
|
137
137
|
"eslint": "^8.35.0",
|