@automattic/vip 2.7.0 → 2.8.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.
- package/README.md +23 -0
- package/dist/bin/vip-config-envvar-set.js +8 -1
- package/dist/bin/vip-dev-env-list.js +37 -0
- package/dist/bin/vip-dev-env.js +1 -1
- package/dist/bin/vip-import-sql.js +20 -6
- package/dist/bin/vip-logs.js +101 -20
- package/dist/bin/vip-whoami.js +67 -0
- package/dist/bin/vip.js +1 -1
- package/dist/lib/api/user.js +58 -0
- package/dist/lib/api.js +7 -2
- package/dist/lib/app-logs/app-logs.js +16 -8
- package/dist/lib/client-file-uploader.js +6 -7
- package/dist/lib/dev-environment/dev-environment-cli.js +1 -1
- package/npm-shrinkwrap.json +14454 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -27,6 +27,29 @@ By default, we record information about the usage of this tool using an in-house
|
|
|
27
27
|
|
|
28
28
|
## Changelog
|
|
29
29
|
|
|
30
|
+
### 2.8.2 (27 January 2021)
|
|
31
|
+
- #961 Fixes md5 calculation failing when search-replace is used
|
|
32
|
+
- #959 Fixes md5 calculation for SQL Imports on VIPd
|
|
33
|
+
|
|
34
|
+
https://github.com/Automattic/vip/releases/tag/v2.8.2
|
|
35
|
+
|
|
36
|
+
### 2.8.0 (25 January 2021)
|
|
37
|
+
- #952 FORNO-1047: Fix SQL Import for compressed files
|
|
38
|
+
- #955 Add Error prefix for "Failed to fetch logs" msg
|
|
39
|
+
- #946 Add support for the site logs tailing feature
|
|
40
|
+
- #953 [dev-env] Updated list of available wordpress images for dev-env
|
|
41
|
+
- #933 Update dependency debug to v4.3.3
|
|
42
|
+
|
|
43
|
+
https://github.com/Automattic/vip/releases/tag/v2.8.0
|
|
44
|
+
|
|
45
|
+
### 2.7.1 (10 January 2021)
|
|
46
|
+
- #950 Switch to npm-shrinkwrap
|
|
47
|
+
- #947 [dev-env] List all dev env alias
|
|
48
|
+
- #944 Add `vip whoami` command
|
|
49
|
+
- #942 Envvar: Show message when there is an attempt to change the New Relic key.
|
|
50
|
+
|
|
51
|
+
https://github.com/Automattic/vip/releases/tag/v2.7.1
|
|
52
|
+
|
|
30
53
|
### 2.7.0 (07 December 2021)
|
|
31
54
|
- #941 [dev-env] Bump lando CLI dependency
|
|
32
55
|
- #938 Hide roll back message after SQL Import failure for launched sites
|
|
@@ -36,7 +36,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
36
36
|
/**
|
|
37
37
|
* Internal dependencies
|
|
38
38
|
*/
|
|
39
|
-
const baseUsage = 'vip config envvar set';
|
|
39
|
+
const baseUsage = 'vip config envvar set';
|
|
40
|
+
const NEW_RELIC_ENVVAR_KEY = 'NEW_RELIC_LICENSE_KEY'; // Command examples
|
|
40
41
|
|
|
41
42
|
const examples = [{
|
|
42
43
|
usage: `${baseUsage} MY_VARIABLE`,
|
|
@@ -63,6 +64,12 @@ async function setEnvVarCommand(arg, opt) {
|
|
|
63
64
|
process.exit(1);
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
if (NEW_RELIC_ENVVAR_KEY === name) {
|
|
68
|
+
await (0, _tracker.trackEvent)('envvar_set_newrelic_key', trackingParams);
|
|
69
|
+
console.log(_chalk.default.bold.red('Setting the New Relic key is not permitted.'), 'If you want to set your own New Relic key, please contact our support team through the usual channels.');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
66
73
|
let value;
|
|
67
74
|
|
|
68
75
|
if (opt.fromFile) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @format
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* External dependencies
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
"use strict";
|
|
16
|
+
|
|
17
|
+
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
18
|
+
|
|
19
|
+
var _devEnvironmentCore = require("../lib/dev-environment/dev-environment-core");
|
|
20
|
+
|
|
21
|
+
var _devEnvironmentCli = require("../lib/dev-environment/dev-environment-cli");
|
|
22
|
+
|
|
23
|
+
var _devEnvironment = require("../lib/constants/dev-environment");
|
|
24
|
+
|
|
25
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
26
|
+
|
|
27
|
+
const examples = [{
|
|
28
|
+
usage: `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} list`,
|
|
29
|
+
description: 'Return information about all local dev environments'
|
|
30
|
+
}];
|
|
31
|
+
(0, _command.default)().examples(examples).argv(process.argv, async () => {
|
|
32
|
+
try {
|
|
33
|
+
await (0, _devEnvironmentCore.printAllEnvironmentsInfo)();
|
|
34
|
+
} catch (error) {
|
|
35
|
+
(0, _devEnvironmentCli.handleCLIException)(error);
|
|
36
|
+
}
|
|
37
|
+
});
|
package/dist/bin/vip-dev-env.js
CHANGED
|
@@ -20,4 +20,4 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
20
20
|
|
|
21
21
|
(0, _command.default)({
|
|
22
22
|
requiredArgs: 1
|
|
23
|
-
}).command('create', 'Create a new local dev environment').command('update', 'Update an already created local dev environment').command('start', 'Start a local dev environment').command('stop', 'Stop a local dev environment').command('destroy', 'Remove containers, networks, volumes and configuration files of a local dev environment').command('info', 'Provides basic info about one or multiple local dev environments').command('exec', 'Execute an operation on a dev environment').command('import', 'Import data into a local WordPress environment').argv(process.argv);
|
|
23
|
+
}).command('create', 'Create a new local dev environment').command('update', 'Update an already created local dev environment').command('start', 'Start a local dev environment').command('stop', 'Stop a local dev environment').command('destroy', 'Remove containers, networks, volumes and configuration files of a local dev environment').command('info', 'Provides basic info about one or multiple local dev environments').command('list', 'Provides basic info about all local dev environments').command('exec', 'Execute an operation on a dev environment').command('import', 'Import data into a local WordPress environment').argv(process.argv);
|
|
@@ -54,6 +54,8 @@ var _progress = require("../lib/cli/progress");
|
|
|
54
54
|
|
|
55
55
|
var _isMultiSite = require("../lib/validations/is-multi-site");
|
|
56
56
|
|
|
57
|
+
var _path = _interopRequireDefault(require("path"));
|
|
58
|
+
|
|
57
59
|
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); }
|
|
58
60
|
|
|
59
61
|
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; }
|
|
@@ -367,9 +369,11 @@ const displayPlaybook = ({
|
|
|
367
369
|
|
|
368
370
|
const {
|
|
369
371
|
app,
|
|
370
|
-
env
|
|
371
|
-
|
|
372
|
-
|
|
372
|
+
env
|
|
373
|
+
} = opts;
|
|
374
|
+
let {
|
|
375
|
+
skipValidate,
|
|
376
|
+
searchReplace
|
|
373
377
|
} = opts;
|
|
374
378
|
const {
|
|
375
379
|
id: envId,
|
|
@@ -377,6 +381,14 @@ const displayPlaybook = ({
|
|
|
377
381
|
} = env;
|
|
378
382
|
const [fileName] = arg;
|
|
379
383
|
const isMultiSite = await (0, _isMultiSite.isMultiSiteInSiteMeta)(appId, envId);
|
|
384
|
+
const fileMeta = await (0, _clientFileUploader.getFileMeta)(fileName);
|
|
385
|
+
|
|
386
|
+
if (fileMeta.isCompressed) {
|
|
387
|
+
console.log(_chalk.default.yellowBright('You are importing a compressed file. Validation and search-replace operation will be skipped.'));
|
|
388
|
+
skipValidate = true;
|
|
389
|
+
searchReplace = undefined;
|
|
390
|
+
}
|
|
391
|
+
|
|
380
392
|
debug('Options: ', opts);
|
|
381
393
|
debug('Args: ', arg);
|
|
382
394
|
|
|
@@ -478,17 +490,19 @@ Processing the SQL import for your environment...
|
|
|
478
490
|
progressTracker.setUploadPercentage(percentage);
|
|
479
491
|
};
|
|
480
492
|
|
|
493
|
+
fileMeta.fileName = fileNameToUpload;
|
|
494
|
+
|
|
481
495
|
try {
|
|
482
496
|
const {
|
|
483
497
|
fileMeta: {
|
|
484
|
-
basename
|
|
485
|
-
md5
|
|
498
|
+
basename
|
|
486
499
|
},
|
|
500
|
+
md5,
|
|
487
501
|
result
|
|
488
502
|
} = await (0, _clientFileUploader.uploadImportSqlFileToS3)({
|
|
489
503
|
app,
|
|
490
504
|
env,
|
|
491
|
-
|
|
505
|
+
fileMeta,
|
|
492
506
|
progressCallback
|
|
493
507
|
});
|
|
494
508
|
startImportVariables.input = {
|
package/dist/bin/vip-logs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* External dependencies
|
|
5
5
|
*/
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
@@ -9,9 +9,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
9
9
|
value: true
|
|
10
10
|
});
|
|
11
11
|
exports.getLogs = getLogs;
|
|
12
|
+
exports.followLogs = followLogs;
|
|
12
13
|
exports.validateInputs = validateInputs;
|
|
13
14
|
exports.appQuery = void 0;
|
|
14
15
|
|
|
16
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
17
|
+
|
|
15
18
|
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
16
19
|
|
|
17
20
|
var _rollbar = require("../lib/rollbar");
|
|
@@ -30,26 +33,28 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
30
33
|
|
|
31
34
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Internal dependencies
|
|
38
|
+
*/
|
|
34
39
|
const LIMIT_MIN = 1;
|
|
40
|
+
const LIMIT_MAX = 5000;
|
|
35
41
|
const ALLOWED_TYPES = ['app', 'batch'];
|
|
36
42
|
const ALLOWED_FORMATS = ['csv', 'json', 'text'];
|
|
43
|
+
const DEFAULT_POLLING_DELAY_IN_SECONDS = 30;
|
|
44
|
+
const MIN_POLLING_DELAY_IN_SECONDS = 5;
|
|
45
|
+
const MAX_POLLING_DELAY_IN_SECONDS = 300;
|
|
37
46
|
|
|
38
47
|
async function getLogs(arg, opt) {
|
|
39
48
|
validateInputs(opt.type, opt.limit, opt.format);
|
|
40
|
-
const trackingParams =
|
|
41
|
-
command: 'vip logs',
|
|
42
|
-
org_id: opt.app.organization.id,
|
|
43
|
-
app_id: opt.app.id,
|
|
44
|
-
env_id: opt.env.id,
|
|
45
|
-
type: opt.type,
|
|
46
|
-
limit: opt.limit,
|
|
47
|
-
format: opt.format
|
|
48
|
-
};
|
|
49
|
+
const trackingParams = getBaseTrackingParams(opt);
|
|
49
50
|
await (0, _tracker.trackEvent)('logs_command_execute', trackingParams);
|
|
50
|
-
let logs
|
|
51
|
+
let logs;
|
|
51
52
|
|
|
52
53
|
try {
|
|
54
|
+
if (opt.follow) {
|
|
55
|
+
return await followLogs(opt);
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
logs = await logsLib.getRecentLogs(opt.app.id, opt.env.id, opt.type, opt.limit);
|
|
54
59
|
} catch (error) {
|
|
55
60
|
_rollbar.rollbar.error(error);
|
|
@@ -61,15 +66,91 @@ async function getLogs(arg, opt) {
|
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
await (0, _tracker.trackEvent)('logs_command_success', { ...trackingParams,
|
|
64
|
-
|
|
69
|
+
total: logs.nodes.length
|
|
65
70
|
});
|
|
66
71
|
|
|
67
|
-
if (!logs.length) {
|
|
72
|
+
if (!logs.nodes.length) {
|
|
68
73
|
console.error('No logs found');
|
|
69
74
|
return;
|
|
70
|
-
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
printLogs(logs.nodes, opt.format);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function followLogs(opt) {
|
|
81
|
+
let after = null;
|
|
82
|
+
let isFirstRequest = true; // How many times have we polled?
|
|
83
|
+
|
|
84
|
+
let requestNumber = 0;
|
|
85
|
+
const trackingParams = getBaseTrackingParams(opt); // Set an initial default delay
|
|
86
|
+
|
|
87
|
+
let delay = DEFAULT_POLLING_DELAY_IN_SECONDS;
|
|
88
|
+
|
|
89
|
+
while (true) {
|
|
90
|
+
const limit = isFirstRequest ? opt.limit : LIMIT_MAX;
|
|
91
|
+
requestNumber++;
|
|
92
|
+
trackingParams.request_number = requestNumber;
|
|
93
|
+
trackingParams.request_delay = delay;
|
|
94
|
+
trackingParams.limit = limit;
|
|
95
|
+
let logs;
|
|
71
96
|
|
|
97
|
+
try {
|
|
98
|
+
var _logs;
|
|
99
|
+
|
|
100
|
+
logs = await logsLib.getRecentLogs(opt.app.id, opt.env.id, opt.type, limit, after);
|
|
101
|
+
await (0, _tracker.trackEvent)('logs_command_follow_success', { ...trackingParams,
|
|
102
|
+
total: (_logs = logs) === null || _logs === void 0 ? void 0 : _logs.nodes.length
|
|
103
|
+
});
|
|
104
|
+
} catch (error) {
|
|
105
|
+
await (0, _tracker.trackEvent)('logs_command_follow_error', { ...trackingParams,
|
|
106
|
+
error: error.message
|
|
107
|
+
}); // If the first request fails we don't want to retry (it's probably not recoverable)
|
|
108
|
+
|
|
109
|
+
if (isFirstRequest) {
|
|
110
|
+
console.error(`${_chalk.default.red('Error:')} Failed to fetch logs.`);
|
|
111
|
+
break;
|
|
112
|
+
} // Increase the delay on errors to avoid overloading the server, up to a max of 5 minutes
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
delay += DEFAULT_POLLING_DELAY_IN_SECONDS;
|
|
116
|
+
delay = Math.min(delay, MAX_POLLING_DELAY_IN_SECONDS);
|
|
117
|
+
console.error(`${_chalk.default.red('Error:')} Failed to fetch logs. Trying again in ${delay} seconds.`);
|
|
118
|
+
|
|
119
|
+
_rollbar.rollbar.error(error);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (logs) {
|
|
123
|
+
var _logs2, _logs3, _logs4;
|
|
124
|
+
|
|
125
|
+
if ((_logs2 = logs) !== null && _logs2 !== void 0 && _logs2.nodes.length) {
|
|
126
|
+
printLogs(logs.nodes, opt.format);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
after = (_logs3 = logs) === null || _logs3 === void 0 ? void 0 : _logs3.nextCursor;
|
|
130
|
+
isFirstRequest = false; // Keep a sane lower limit of MIN_POLLING_DELAY_IN_SECONDS just in case something goes wrong in the server-side
|
|
131
|
+
|
|
132
|
+
delay = Math.max(((_logs4 = logs) === null || _logs4 === void 0 ? void 0 : _logs4.pollingDelaySeconds) || DEFAULT_POLLING_DELAY_IN_SECONDS, MIN_POLLING_DELAY_IN_SECONDS);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
await new Promise(resolve => setTimeout(resolve, delay * 1000));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function getBaseTrackingParams(opt) {
|
|
140
|
+
return {
|
|
141
|
+
command: 'vip logs',
|
|
142
|
+
org_id: opt.app.organization.id,
|
|
143
|
+
app_id: opt.app.id,
|
|
144
|
+
env_id: opt.env.id,
|
|
145
|
+
type: opt.type,
|
|
146
|
+
limit: opt.limit,
|
|
147
|
+
follow: opt.follow || false,
|
|
148
|
+
format: opt.format
|
|
149
|
+
};
|
|
150
|
+
}
|
|
72
151
|
|
|
152
|
+
function printLogs(logs, format) {
|
|
153
|
+
// Strip out __typename
|
|
73
154
|
logs = logs.map(log => {
|
|
74
155
|
const {
|
|
75
156
|
timestamp,
|
|
@@ -82,7 +163,7 @@ async function getLogs(arg, opt) {
|
|
|
82
163
|
});
|
|
83
164
|
let output = '';
|
|
84
165
|
|
|
85
|
-
if (
|
|
166
|
+
if (format && 'text' === format) {
|
|
86
167
|
const rows = [];
|
|
87
168
|
|
|
88
169
|
for (const {
|
|
@@ -93,7 +174,7 @@ async function getLogs(arg, opt) {
|
|
|
93
174
|
output = rows.join('\n');
|
|
94
175
|
}
|
|
95
176
|
} else {
|
|
96
|
-
output = (0, _format.formatData)(logs,
|
|
177
|
+
output = (0, _format.formatData)(logs, format);
|
|
97
178
|
}
|
|
98
179
|
|
|
99
180
|
console.log(output);
|
|
@@ -108,8 +189,8 @@ function validateInputs(type, limit, format) {
|
|
|
108
189
|
exit.withError(`Invalid format: ${format}. The supported formats are: ${ALLOWED_FORMATS.join(', ')}.`);
|
|
109
190
|
}
|
|
110
191
|
|
|
111
|
-
if (!Number.isInteger(limit) || limit < LIMIT_MIN || limit > LIMIT_MAX) {
|
|
112
|
-
exit.withError(`Invalid limit: ${limit}. It should be a number between ${LIMIT_MIN} and ${LIMIT_MAX}.`);
|
|
192
|
+
if (!Number.isInteger(limit) || limit < LIMIT_MIN || limit > logsLib.LIMIT_MAX) {
|
|
193
|
+
exit.withError(`Invalid limit: ${limit}. It should be a number between ${LIMIT_MIN} and ${logsLib.LIMIT_MAX}.`);
|
|
113
194
|
}
|
|
114
195
|
}
|
|
115
196
|
|
|
@@ -133,7 +214,7 @@ exports.appQuery = appQuery;
|
|
|
133
214
|
appQuery,
|
|
134
215
|
envContext: true,
|
|
135
216
|
module: 'logs'
|
|
136
|
-
}).option('type', 'The type of logs to be returned: "app" or "batch"', 'app').option('limit', 'The maximum number of log lines', 500).option('format', 'Output the log lines in CSV or JSON format', 'text').examples([{
|
|
217
|
+
}).option('type', 'The type of logs to be returned: "app" or "batch"', 'app').option('limit', 'The maximum number of log lines', 500).option('follow', 'Keep fetching new logs as they are generated').option('format', 'Output the log lines in CSV or JSON format', 'text').examples([{
|
|
137
218
|
usage: 'vip @mysite.production logs',
|
|
138
219
|
description: 'Get the most recent app logs'
|
|
139
220
|
}, {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @format
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* External dependencies
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
"use strict";
|
|
16
|
+
|
|
17
|
+
Object.defineProperty(exports, "__esModule", {
|
|
18
|
+
value: true
|
|
19
|
+
});
|
|
20
|
+
exports.whoamiCommand = whoamiCommand;
|
|
21
|
+
|
|
22
|
+
var _user = require("../lib/api/user");
|
|
23
|
+
|
|
24
|
+
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
25
|
+
|
|
26
|
+
var _tracker = require("../lib/tracker");
|
|
27
|
+
|
|
28
|
+
var exit = _interopRequireWildcard(require("../lib/cli/exit"));
|
|
29
|
+
|
|
30
|
+
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); }
|
|
31
|
+
|
|
32
|
+
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; }
|
|
33
|
+
|
|
34
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
|
+
|
|
36
|
+
async function whoamiCommand() {
|
|
37
|
+
const trackingParams = {
|
|
38
|
+
command: 'vip whoami'
|
|
39
|
+
};
|
|
40
|
+
await (0, _tracker.trackEvent)('whoami_command_execute', trackingParams);
|
|
41
|
+
let currentUser = {};
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
currentUser = await (0, _user.getCurrentUserInfo)();
|
|
45
|
+
} catch (err) {
|
|
46
|
+
await (0, _tracker.trackEvent)('whoami_command_error', { ...trackingParams,
|
|
47
|
+
error: err.message
|
|
48
|
+
});
|
|
49
|
+
exit.withError(`Failed to fetch information about the currently logged-in user error: ${err.message}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
await (0, _tracker.trackEvent)('whoami_command_success', trackingParams);
|
|
53
|
+
const output = [`- Howdy ${currentUser.displayName}!`, `- Your user ID is ${currentUser.id}`];
|
|
54
|
+
|
|
55
|
+
if (currentUser.isVIP) {
|
|
56
|
+
output.push('- Your account has VIP Staff permissions');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log(output.join('\n'));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
(0, _command.default)({
|
|
63
|
+
usage: 'vip whoami'
|
|
64
|
+
}).examples([{
|
|
65
|
+
usage: 'vip whoami',
|
|
66
|
+
description: 'Display details about the currently logged-in user.'
|
|
67
|
+
}]).argv(process.argv, whoamiCommand);
|
package/dist/bin/vip.js
CHANGED
|
@@ -48,7 +48,7 @@ const runCmd = async function () {
|
|
|
48
48
|
await _token.default.purge();
|
|
49
49
|
await (0, _tracker.trackEvent)('logout_command_execute');
|
|
50
50
|
console.log('You are successfully logged out.');
|
|
51
|
-
}).command('app', 'List and modify your VIP applications').command('config', 'Set configuration for your VIP applications').command('dev-env', 'Use local dev-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('sync', 'Sync production to a development environment').command('wp', 'Run WP CLI commands against an environment');
|
|
51
|
+
}).command('app', 'List and modify your VIP applications').command('config', 'Set configuration for your VIP applications').command('dev-env', 'Use local dev-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('sync', 'Sync production to a development environment').command('whoami', 'Display details about the currently logged-in user').command('wp', 'Run WP CLI commands against an environment');
|
|
52
52
|
cmd.argv(process.argv);
|
|
53
53
|
};
|
|
54
54
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getCurrentUserInfo = getCurrentUserInfo;
|
|
7
|
+
|
|
8
|
+
var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
|
|
9
|
+
|
|
10
|
+
var _api = _interopRequireDefault(require("../api"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @format
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* External dependencies
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Internal dependencies
|
|
25
|
+
*/
|
|
26
|
+
const QUERY_CURRENT_USER = (0, _graphqlTag.default)`
|
|
27
|
+
query Me {
|
|
28
|
+
me {
|
|
29
|
+
id
|
|
30
|
+
displayName
|
|
31
|
+
isVIP
|
|
32
|
+
organizationRoles {
|
|
33
|
+
nodes {
|
|
34
|
+
organizationId
|
|
35
|
+
roleId
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
async function getCurrentUserInfo() {
|
|
43
|
+
const api = await (0, _api.default)();
|
|
44
|
+
const response = await api.query({
|
|
45
|
+
query: QUERY_CURRENT_USER
|
|
46
|
+
});
|
|
47
|
+
const {
|
|
48
|
+
data: {
|
|
49
|
+
me
|
|
50
|
+
}
|
|
51
|
+
} = response;
|
|
52
|
+
|
|
53
|
+
if (!me) {
|
|
54
|
+
throw new Error('The API did not return any information about the user.');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return me;
|
|
58
|
+
}
|
package/dist/lib/api.js
CHANGED
|
@@ -52,7 +52,9 @@ function disableGlobalGraphQLErrorHandling() {
|
|
|
52
52
|
globalGraphQLErrorHandlingEnabled = false;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
async function API(
|
|
55
|
+
async function API({
|
|
56
|
+
exitOnError = true
|
|
57
|
+
} = {}) {
|
|
56
58
|
const authToken = await _token.default.get();
|
|
57
59
|
const headers = {
|
|
58
60
|
'User-Agent': _env.default.userAgent,
|
|
@@ -71,7 +73,10 @@ async function API() {
|
|
|
71
73
|
graphQLErrors.forEach(error => {
|
|
72
74
|
console.error(_chalk.default.red('Error:'), error.message);
|
|
73
75
|
});
|
|
74
|
-
|
|
76
|
+
|
|
77
|
+
if (exitOnError) {
|
|
78
|
+
process.exit();
|
|
79
|
+
}
|
|
75
80
|
}
|
|
76
81
|
});
|
|
77
82
|
const withToken = (0, _context.setContext)(async () => {
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getRecentLogs = getRecentLogs;
|
|
7
|
+
exports.LIMIT_MAX = void 0;
|
|
7
8
|
|
|
8
9
|
var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
|
|
9
10
|
|
|
@@ -23,38 +24,45 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
23
24
|
/**
|
|
24
25
|
* Internal dependencies
|
|
25
26
|
*/
|
|
27
|
+
const LIMIT_MAX = 5000;
|
|
28
|
+
exports.LIMIT_MAX = LIMIT_MAX;
|
|
26
29
|
const QUERY_ENVIRONMENT_LOGS = (0, _graphqlTag.default)`
|
|
27
|
-
query GetAppLogs( $appId: Int, $envId: Int, $type: AppEnvironmentLogType, $limit: Int ) {
|
|
30
|
+
query GetAppLogs( $appId: Int, $envId: Int, $type: AppEnvironmentLogType, $limit: Int, $after: String ) {
|
|
28
31
|
app( id: $appId ) {
|
|
29
32
|
environments( id: $envId ) {
|
|
30
33
|
id
|
|
31
|
-
logs( type: $type, limit: $limit ) {
|
|
34
|
+
logs( type: $type, limit: $limit, after: $after ) {
|
|
32
35
|
nodes {
|
|
33
36
|
timestamp
|
|
34
37
|
message
|
|
35
38
|
}
|
|
39
|
+
nextCursor
|
|
40
|
+
pollingDelaySeconds
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
`;
|
|
41
46
|
|
|
42
|
-
async function getRecentLogs(appId, envId, type, limit) {
|
|
43
|
-
var _response$data, _response$data$app, _response$data$app$en
|
|
47
|
+
async function getRecentLogs(appId, envId, type, limit, after) {
|
|
48
|
+
var _response$data, _response$data$app, _response$data$app$en;
|
|
44
49
|
|
|
45
|
-
const api = await (0, _api.default)(
|
|
50
|
+
const api = await (0, _api.default)({
|
|
51
|
+
exitOnError: false
|
|
52
|
+
});
|
|
46
53
|
const response = await api.query({
|
|
47
54
|
query: QUERY_ENVIRONMENT_LOGS,
|
|
48
55
|
variables: {
|
|
49
56
|
appId,
|
|
50
57
|
envId,
|
|
51
58
|
type,
|
|
52
|
-
limit
|
|
59
|
+
limit,
|
|
60
|
+
after
|
|
53
61
|
}
|
|
54
62
|
});
|
|
55
|
-
const logs = response === null || response === void 0 ? void 0 : (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$app = _response$data.app) === null || _response$data$app === void 0 ? void 0 : (_response$data$app$en = _response$data$app.environments[0]) === null || _response$data$app$en === void 0 ? void 0 :
|
|
63
|
+
const logs = response === null || response === void 0 ? void 0 : (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$app = _response$data.app) === null || _response$data$app === void 0 ? void 0 : (_response$data$app$en = _response$data$app.environments[0]) === null || _response$data$app$en === void 0 ? void 0 : _response$data$app$en.logs;
|
|
56
64
|
|
|
57
|
-
if (!logs) {
|
|
65
|
+
if (!(logs !== null && logs !== void 0 && logs.nodes)) {
|
|
58
66
|
throw new Error('Unable to query logs');
|
|
59
67
|
}
|
|
60
68
|
|
|
@@ -105,15 +105,11 @@ async function getFileMeta(fileName) {
|
|
|
105
105
|
const mimeType = await detectCompressedMimeType(fileName); // TODO Only allow a subset of Mime Types...?
|
|
106
106
|
|
|
107
107
|
const isCompressed = ['application/zip', 'application/gzip'].includes(mimeType);
|
|
108
|
-
debug('Calculating file md5 checksum...');
|
|
109
|
-
const md5 = await getFileMD5Hash(fileName);
|
|
110
|
-
debug(`Calculated file md5 checksum: ${md5}\n`);
|
|
111
108
|
resolve({
|
|
112
109
|
basename,
|
|
113
110
|
fileName,
|
|
114
111
|
fileSize,
|
|
115
|
-
isCompressed
|
|
116
|
-
md5
|
|
112
|
+
isCompressed
|
|
117
113
|
});
|
|
118
114
|
});
|
|
119
115
|
}
|
|
@@ -121,10 +117,9 @@ async function getFileMeta(fileName) {
|
|
|
121
117
|
async function uploadImportSqlFileToS3({
|
|
122
118
|
app,
|
|
123
119
|
env,
|
|
124
|
-
|
|
120
|
+
fileMeta,
|
|
125
121
|
progressCallback
|
|
126
122
|
}) {
|
|
127
|
-
const fileMeta = await getFileMeta(fileName);
|
|
128
123
|
let tmpDir;
|
|
129
124
|
|
|
130
125
|
try {
|
|
@@ -152,6 +147,9 @@ async function uploadImportSqlFileToS3({
|
|
|
152
147
|
debug(`** Compression resulted in a ${calculation} smaller file 📦 **\n`);
|
|
153
148
|
}
|
|
154
149
|
|
|
150
|
+
debug('Calculating file md5 checksum...');
|
|
151
|
+
const md5 = await getFileMD5Hash(fileMeta.fileName);
|
|
152
|
+
debug(`Calculated file md5 checksum: ${md5}\n`);
|
|
155
153
|
const result = fileMeta.fileSize < MULTIPART_THRESHOLD ? await uploadUsingPutObject({
|
|
156
154
|
app,
|
|
157
155
|
env,
|
|
@@ -165,6 +163,7 @@ async function uploadImportSqlFileToS3({
|
|
|
165
163
|
});
|
|
166
164
|
return {
|
|
167
165
|
fileMeta,
|
|
166
|
+
md5,
|
|
168
167
|
result
|
|
169
168
|
};
|
|
170
169
|
}
|