@automattic/vip 2.32.1 → 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.
- package/.prettierignore +0 -2
- package/CHANGELOG.md +26 -0
- package/CONTRIBUTING.md +41 -17
- package/assets/dev-env.lando.template.yml.ejs +10 -2
- package/dist/bin/vip-dev-env-exec.js +1 -7
- package/dist/bin/vip-dev-env-shell.js +0 -4
- package/dist/bin/vip-dev-env-start.js +1 -1
- package/dist/bin/vip-dev-env-sync-sql.js +8 -6
- package/dist/bin/vip-dev-env-update.js +1 -2
- package/dist/bin/vip-import-sql.js +2 -2
- package/dist/bin/vip-logout.js +23 -0
- package/dist/bin/vip-slowlogs.js +192 -0
- package/dist/bin/vip-validate-preflight.js +8 -10
- package/dist/bin/vip-whoami.js +1 -2
- package/dist/bin/vip.js +1 -5
- package/dist/commands/backup-db.js +29 -30
- package/dist/lib/api/app.js +2 -2
- package/dist/lib/api/cache-purge.js +2 -2
- package/dist/lib/api/http.js +3 -3
- package/dist/lib/app-logs/app-logs.js +2 -2
- package/dist/lib/app-slowlogs/app-slowlogs.js +63 -0
- package/dist/lib/app-slowlogs/types.js +1 -0
- package/dist/lib/cli/apiConfig.js +1 -1
- package/dist/lib/client-file-uploader.js +19 -4
- package/dist/lib/config/software.js +4 -4
- package/dist/lib/constants/dev-environment.js +7 -3
- package/dist/lib/dev-environment/dev-environment-cli.js +110 -117
- package/dist/lib/dev-environment/dev-environment-configuration-file.js +34 -36
- package/dist/lib/dev-environment/dev-environment-core.js +36 -19
- package/dist/lib/dev-environment/dev-environment-lando.js +80 -72
- package/dist/lib/dev-environment/docker-utils.js +8 -9
- package/dist/lib/envvar/api-get-all.js +2 -2
- package/dist/lib/envvar/api-list.js +3 -6
- package/dist/lib/envvar/input.js +1 -2
- package/dist/lib/site-import/status.js +5 -5
- package/dist/lib/token.js +3 -6
- package/dist/lib/types/graphql/rate-limit-exceeded-error.js +1 -0
- package/dist/lib/validations/is-multi-site-sql-dump.js +0 -1
- package/dist/lib/validations/is-multi-site.js +14 -12
- package/dist/lib/validations/is-multisite-domain-mapped.js +5 -10
- package/dist/lib/validations/line-by-line.js +9 -13
- package/dist/lib/validations/site-type.js +2 -7
- package/dist/lib/validations/sql.js +14 -19
- package/dist/lib/validations/utils.js +1 -1
- package/helpers/generate-docs.js +151 -0
- package/npm-shrinkwrap.json +920 -933
- package/package.json +15 -10
- package/tsconfig.json +16 -6
package/.prettierignore
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
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
|
+
|
|
20
|
+
### 2.32.2
|
|
21
|
+
|
|
22
|
+
- #1443 On-demand Database Backup: Use a less error-prone way of detecting if we're rate limited
|
|
23
|
+
- #1434 Add more clarifying steps for making a release
|
|
24
|
+
- #1435 Remove enums from GraphQL codegen and make sure that prettier actually runs
|
|
25
|
+
- #1433 Redeploy codegen for GraphQL queries
|
|
26
|
+
- #1432 Revert "Add codegen for GraphQL queries (#1429)"
|
|
27
|
+
- #1304 Generate docs
|
|
28
|
+
|
|
3
29
|
### 2.32.1
|
|
4
30
|
|
|
5
31
|
- #1445 chore(deps): update vulnerable dependencies to fix ReDoS in semver
|
package/CONTRIBUTING.md
CHANGED
|
@@ -97,26 +97,23 @@ We use a custom pre-publish [script](https://github.com/Automattic/vip/blob/trun
|
|
|
97
97
|
|
|
98
98
|
Further checks can be added to this flow as needed.
|
|
99
99
|
|
|
100
|
-
### Pre-publish Tasks
|
|
101
|
-
|
|
102
|
-
As part of the publish flow, we run the `prepareConfig:publish` task on `prepack`. This copies over "production" config values to your working copy to make sure the release includes those instead of development values.
|
|
103
|
-
|
|
104
|
-
We use `prepack` because:
|
|
105
|
-
|
|
106
|
-
- `prepareConfig:local` runs on `npm build` and we want to make sure those values are overriden.
|
|
107
|
-
- This is the latest npm event that we can run on before publishing. (Note: we tried `prepublishOnly` but files added during that step [don't get included in the build](https://github.com/Automattic/vip/commit/c7dabe1b0f73ec9e6e8c05ccff0c41281e4cd5e8)).
|
|
108
|
-
|
|
109
100
|
### New Releases
|
|
110
101
|
|
|
111
102
|
Prepare the release by making sure that:
|
|
112
103
|
|
|
113
104
|
1. All relevant PRs have been merged.
|
|
114
105
|
1. The release has been tested across macOS, Windows, and Linux.
|
|
115
|
-
1.
|
|
116
|
-
|
|
106
|
+
1. All tests pass and your working directory is clean (we have pre-publish checks to catch this,
|
|
107
|
+
just-in-case).
|
|
108
|
+
1. Make sure not to merge anymore changes into `develop` while all the release steps below are in
|
|
109
|
+
progress.
|
|
117
110
|
|
|
118
111
|
#### Changelog Generator Hint:
|
|
119
112
|
|
|
113
|
+
In the first step, you'll need to generate a changelog.
|
|
114
|
+
|
|
115
|
+
Run the following and copy the output somewhere.
|
|
116
|
+
|
|
120
117
|
```
|
|
121
118
|
export LAST_RELEASE_DATE=2021-08-25T13:40:00+02
|
|
122
119
|
gh pr list --search "is:merged sort:updated-desc closed:>$LAST_RELEASE_DATE" | sed -e 's/\s\+\S\+\tMERGED.*$//' -e 's/^/- #/'
|
|
@@ -124,15 +121,28 @@ gh pr list --search "is:merged sort:updated-desc closed:>$LAST_RELEASE_DATE" | s
|
|
|
124
121
|
|
|
125
122
|
Then, let's publish:
|
|
126
123
|
|
|
127
|
-
1.
|
|
124
|
+
1. Create a pull request that adds the next version's changelog into `develop`. Use the Changelog
|
|
125
|
+
Generate Hint above to generate the changelog, and refer to previous releases to ensure that your
|
|
126
|
+
format matches.
|
|
127
|
+
1. Create a pull request that merges `develop` to `trunk`.
|
|
128
|
+
1. Merge it after approval.
|
|
129
|
+
1. Make sure trunk branch is up-to-date `git pull`.
|
|
130
|
+
1. Make sure to clean all of your repositories of extra files. Run a dangerous, destructive
|
|
131
|
+
command `git clean -xfd` to do so.
|
|
132
|
+
1. Run `npm install`.
|
|
128
133
|
1. Set the version (via `npm version minor` or `npm version major` or `npm version patch`)
|
|
129
134
|
1. For most regular releases, this will be `npm version minor`.
|
|
130
135
|
1. Push the tag to GitHub (`git push --tags`)
|
|
131
136
|
1. Push the trunk branch `git push`
|
|
132
137
|
1. Make sure you're part of the Automattic organization in npm
|
|
133
|
-
1. Publish the release to npm (`npm publish --access public`) the script will do some extra checks (
|
|
134
|
-
|
|
135
|
-
|
|
138
|
+
1. Publish the release to npm (`npm publish --access public`) the script will do some extra checks (
|
|
139
|
+
node version, branch, etc) to ensure everything is correct. If all looks good, the new version
|
|
140
|
+
will be published and you can proceed.
|
|
141
|
+
1. Edit [the release on GitHub](https://github.com/Automattic/vip/releases) to include a description
|
|
142
|
+
of the changes and publish (this can just copy the details from the changelog).
|
|
143
|
+
1. Push `trunk` changes (mostly the version bump)
|
|
144
|
+
to `develop` (`git checkout develop && git merge trunk` ). There's no need to use a pull request
|
|
145
|
+
to do so.
|
|
136
146
|
|
|
137
147
|
Once released, it's worth running `npm i -g @automattic/vip` to install / upgrade the released version to make sure everything looks good.
|
|
138
148
|
|
|
@@ -161,6 +171,20 @@ Then, repeat for any additional versions that we need to patch.
|
|
|
161
171
|
|
|
162
172
|
### go-search-replace binaries
|
|
163
173
|
|
|
164
|
-
Some unit tests require some go-search-replace executable binary files to run. Binaries files for
|
|
174
|
+
Some unit tests require some go-search-replace executable binary files to run. Binaries files for
|
|
175
|
+
several OS architectures can be downloaded
|
|
176
|
+
from https://github.com/Automattic/go-search-replace/releases/
|
|
177
|
+
|
|
178
|
+
If, for some reason, you need to compile these binaries yourself, please follow instructions
|
|
179
|
+
at https://github.com/Automattic/go-search-replace
|
|
180
|
+
|
|
181
|
+
### Generating the types
|
|
182
|
+
|
|
183
|
+
If you're an employee of Automattic, you can follow these steps to regenerate the GraphQL types
|
|
184
|
+
used.
|
|
165
185
|
|
|
166
|
-
|
|
186
|
+
1. Get a hold of `schema.gql` and paste it in project root - this is the schema of the endpoint that
|
|
187
|
+
we communicate with.
|
|
188
|
+
2. Run `npm run typescript:codegen:install-dependencies` - this will install the codegen
|
|
189
|
+
dependencies without updating `package.json`
|
|
190
|
+
3. Run `npm run typescript:codegen:generate` - this will regenerate the types
|
|
@@ -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:
|
|
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:
|
|
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', '
|
|
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
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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:
|
|
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
|
|
275
|
-
siteArray = selectedEnvironmentObj === null || selectedEnvironmentObj === void 0
|
|
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
|
|
114
|
+
var _opt$env, _opt$env2, _opt$app, _opt$env3;
|
|
115
115
|
harmoniaArgs = await validateArgs(opt);
|
|
116
|
-
const appId = (
|
|
117
|
-
const envId = (
|
|
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: (
|
|
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
|
|
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 =
|
|
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 =
|
|
423
|
-
args.port =
|
|
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
|
}
|
package/dist/bin/vip-whoami.js
CHANGED
|
@@ -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 ${
|
|
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',
|
|
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) {
|