@automattic/vip 2.30.0 → 2.31.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/CHANGELOG.md +25 -0
- package/assets/dev-env.lando.template.yml.ejs +14 -0
- package/assets/dev-env.nginx.template.conf.ejs +23 -2
- package/dist/bin/vip-dev-env-shell.js +2 -1
- package/dist/bin/vip-dev-env-sync-sql.js +15 -19
- package/dist/bin/vip-dev-env-sync.js +0 -0
- package/dist/bin/vip-dev-env-update.js +1 -0
- package/dist/bin/vip-export-sql.js +12 -11
- package/dist/bin/vip-import-sql.js +2 -2
- package/dist/bin/vip-whoami.js +7 -10
- package/dist/commands/dev-env-sync-sql.js +53 -20
- package/dist/commands/export-sql.js +13 -4
- package/dist/lib/analytics/clients/pendo.js +11 -20
- package/dist/lib/analytics/clients/tracks.js +12 -12
- package/dist/lib/analytics/index.js +9 -12
- package/dist/lib/api/app.js +10 -13
- package/dist/lib/api/cache-purge.js +3 -10
- package/dist/lib/api/feature-flags.js +4 -2
- package/dist/lib/api/http.js +10 -18
- package/dist/lib/api/user.js +3 -8
- package/dist/lib/api.js +11 -14
- package/dist/lib/app-logs/app-logs.js +3 -6
- package/dist/lib/cli/apiConfig.js +10 -7
- package/dist/lib/cli/config.js +2 -3
- package/dist/lib/cli/envAlias.js +11 -9
- package/dist/lib/cli/exit.js +4 -7
- package/dist/lib/cli/format.js +25 -26
- package/dist/lib/cli/progress.js +7 -3
- package/dist/lib/cli/prompt.js +3 -2
- package/dist/lib/client-file-uploader.js +86 -87
- package/dist/lib/config/software.js +18 -12
- package/dist/lib/dev-environment/dev-environment-cli.js +6 -4
- package/dist/lib/dev-environment/dev-environment-configuration-file.js +4 -2
- package/dist/lib/dev-environment/dev-environment-core.js +3 -0
- package/dist/lib/env.js +16 -13
- package/dist/lib/envvar/api-delete.js +2 -0
- package/dist/lib/envvar/api-get-all.js +4 -1
- package/dist/lib/envvar/api-get.js +3 -1
- package/dist/lib/envvar/api-list.js +8 -3
- package/dist/lib/envvar/api-set.js +2 -0
- package/dist/lib/envvar/api.js +2 -5
- package/dist/lib/envvar/input.js +7 -8
- package/dist/lib/envvar/read-file.js +4 -7
- package/dist/lib/http/proxy-agent.js +5 -4
- package/dist/lib/read-file.js +13 -14
- package/dist/lib/search-and-replace.js +17 -26
- package/dist/lib/tracker.js +12 -12
- package/dist/lib/user-error.js +6 -5
- package/dist/lib/utils.js +18 -22
- package/dist/lib/vip-import-validate-files.js +23 -22
- package/npm-shrinkwrap.json +9 -1043
- package/package.json +3 -6
- package/tsconfig.json +4 -2
- package/dist/lib/analytics/clients/stub.js +0 -16
- package/dist/lib/cli/repo.js +0 -61
- package/noImplictAnyImportBypass.d.ts +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
+
### 2.31.0
|
|
4
|
+
|
|
5
|
+
- #1397 feature(dev-env): Add ability to sync multisites
|
|
6
|
+
- #1399 chore(dev-deps): Remove stub type definitions
|
|
7
|
+
- #1394 FORNO-1609: Combine all error events into one error event
|
|
8
|
+
- #1345 feat(dev-env): Add Photon
|
|
9
|
+
- #1398 Fix coverage generation
|
|
10
|
+
- #1395 Add types for the other ways of using enquirer
|
|
11
|
+
- #1388 Typescript: refactor `vip-whoami`
|
|
12
|
+
- #1393 refactor: Convert `lib/{app-logs,envvar}` to TypeScript
|
|
13
|
+
- #1392 refactor: Convert `lib/config` to TypeScript
|
|
14
|
+
- #1391 refactor: Convert lib to TypeScript
|
|
15
|
+
- #1390 chore(deps): Update @automattic/vip-search-replace to 1.1.1
|
|
16
|
+
- #1389 Replace 'site' by 'environment' in error msg
|
|
17
|
+
- #1385 refactor: Convert lib/api to TypeScript
|
|
18
|
+
- #1387 chore(deps): Update @automattic/vip-search-replace to 1.1.0
|
|
19
|
+
- #1386 fix: Fix `getAbsolutePath()` and convert `utils.js` to TypeScript
|
|
20
|
+
- #1383 fix(dev-env): Pull uniqueLabel field from backend
|
|
21
|
+
- #1382 test: Reduce noise from tests
|
|
22
|
+
- #1384 fix: Add return type to parseEnvAliasFromArgv()
|
|
23
|
+
- #1381 refactor: Convert lib/cli and dependencies to TypeScript
|
|
24
|
+
- #1377 chore: Configure linting for TS files
|
|
25
|
+
- #1380 chore(dev-deps): Remove jest-environment-jsdom
|
|
26
|
+
- #1378 refactor: Convert analytics and dependencies to TypeScript
|
|
27
|
+
|
|
3
28
|
### 2.30.0
|
|
4
29
|
|
|
5
30
|
- #1264 feature(dev-env): Add dev-env-sync-sql command
|
|
@@ -222,6 +222,20 @@ services:
|
|
|
222
222
|
LANDO_NEEDS_EXEC: 1
|
|
223
223
|
<% } %>
|
|
224
224
|
|
|
225
|
+
<% if ( photon ) { %>
|
|
226
|
+
photon:
|
|
227
|
+
type: compose
|
|
228
|
+
services:
|
|
229
|
+
image: ghcr.io/automattic/vip-container-images/photon:latest
|
|
230
|
+
command: /usr/sbin/php-fpm
|
|
231
|
+
environment:
|
|
232
|
+
LANDO_NO_USER_PERMS: 1
|
|
233
|
+
LANDO_NO_SCRIPTS: 1
|
|
234
|
+
LANDO_NEEDS_EXEC: 1
|
|
235
|
+
volumes:
|
|
236
|
+
- ./uploads:/usr/share/webapps/photon/uploads:ro
|
|
237
|
+
<% } %>
|
|
238
|
+
|
|
225
239
|
tooling:
|
|
226
240
|
wp:
|
|
227
241
|
service: php
|
|
@@ -1,6 +1,27 @@
|
|
|
1
|
+
<% if ( photon ) { %>
|
|
2
|
+
|
|
3
|
+
location ^~ /wp-content/uploads/ {
|
|
4
|
+
expires max;
|
|
5
|
+
log_not_found off;
|
|
1
6
|
<% if ( mediaRedirectDomain ) { %>
|
|
7
|
+
if (!-f $request_filename) {
|
|
8
|
+
rewrite ^/(.*)$ <%= mediaRedirectDomain %>/$1 redirect;
|
|
9
|
+
}
|
|
10
|
+
<% } %>
|
|
11
|
+
|
|
12
|
+
include fastcgi_params;
|
|
13
|
+
fastcgi_param DOCUMENT_ROOT /usr/share/webapps/photon;
|
|
14
|
+
fastcgi_param SCRIPT_FILENAME /usr/share/webapps/photon/index.php;
|
|
15
|
+
fastcgi_param SCRIPT_NAME /index.php;
|
|
16
|
+
|
|
17
|
+
if ($request_uri ~* \.(gif|jpe?g|png)\?) {
|
|
18
|
+
fastcgi_pass photon:9000;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
<% } else if ( mediaRedirectDomain ) { %>
|
|
2
23
|
|
|
3
|
-
location
|
|
24
|
+
location ^~ /wp-content/uploads {
|
|
4
25
|
expires max;
|
|
5
26
|
log_not_found off;
|
|
6
27
|
try_files $uri @prod_site;
|
|
@@ -10,4 +31,4 @@ location @prod_site {
|
|
|
10
31
|
rewrite ^/(.*)$ <%= mediaRedirectDomain %>/$1 redirect;
|
|
11
32
|
}
|
|
12
33
|
|
|
13
|
-
<% } %>
|
|
34
|
+
<% } %>
|
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
/**
|
|
9
9
|
* External dependencies
|
|
10
10
|
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
11
15
|
"use strict";
|
|
12
16
|
|
|
13
|
-
var _chalk = _interopRequireDefault(require("chalk"));
|
|
14
17
|
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
15
18
|
var _devEnvironmentCore = require("../lib/dev-environment/dev-environment-core");
|
|
16
19
|
var _devEnvironmentLando = require("../lib/dev-environment/dev-environment-lando");
|
|
@@ -19,9 +22,6 @@ var _devEnvSyncSql = require("../commands/dev-env-sync-sql");
|
|
|
19
22
|
var _devEnvironment = require("../lib/constants/dev-environment");
|
|
20
23
|
var _tracker = require("../lib/tracker");
|
|
21
24
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
22
|
-
/**
|
|
23
|
-
* Internal dependencies
|
|
24
|
-
*/
|
|
25
25
|
const examples = [{
|
|
26
26
|
usage: `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} sync sql @my-test.develop --slug=my_site`,
|
|
27
27
|
description: 'Syncs with the `my-test` site\'s `develop` environment database into `my_site`'
|
|
@@ -39,6 +39,13 @@ const appQuery = `
|
|
|
39
39
|
primaryDomain { name }
|
|
40
40
|
uniqueLabel
|
|
41
41
|
isMultisite
|
|
42
|
+
wpSitesSDS(first:500) {
|
|
43
|
+
nodes {
|
|
44
|
+
id
|
|
45
|
+
blogId
|
|
46
|
+
homeUrl
|
|
47
|
+
}
|
|
48
|
+
}
|
|
42
49
|
}
|
|
43
50
|
`;
|
|
44
51
|
(0, _command.default)({
|
|
@@ -55,23 +62,10 @@ const appQuery = `
|
|
|
55
62
|
const trackerFn = (0, _tracker.makeCommandTracker)('dev_env_sync_sql', {
|
|
56
63
|
app: app.id,
|
|
57
64
|
env: env.uniqueLabel,
|
|
58
|
-
slug
|
|
65
|
+
slug,
|
|
66
|
+
multisite: env.isMultisite
|
|
59
67
|
});
|
|
60
68
|
await trackerFn('execute');
|
|
61
|
-
if (env.isMultisite) {
|
|
62
|
-
console.log(_chalk.default.yellow('You seem to be trying to sync a SQL database for a network site.'));
|
|
63
|
-
console.log(_chalk.default.yellow('Unfortunately, the current version of our tool does not yet support syncing network sites.\n'));
|
|
64
|
-
console.log(_chalk.default.yellow('However, you can manually export the database using the following command:'));
|
|
65
|
-
console.log(_chalk.default.yellow(_chalk.default.bold(`vip export sql @${app.id}.${env.uniqueLabel} --output=${app.id}-${env.uniqueLabel}-exported.sql.gz\n`)));
|
|
66
|
-
console.log(_chalk.default.yellow('After exporting the database, you\'ll need to perform the necessary search and replace operations on the exported file to update any relevant data or configurations.'));
|
|
67
|
-
console.log(_chalk.default.yellow('See: https://docs.wpvip.com/how-tos/dev-env-add-content/#h-3-import-the-sql-file\n'));
|
|
68
|
-
console.log(_chalk.default.yellow('Once you\'ve made the required changes, you can import the modified SQL file into your development environment using the following command:'));
|
|
69
|
-
console.log(_chalk.default.yellow(_chalk.default.bold(`vip dev-env import sql ${app.id}-${env.uniqueLabel}-exported.sql.gz --slug=${slug}`)));
|
|
70
|
-
await trackerFn('aborted', {
|
|
71
|
-
error_type: 'multisite_not_supported'
|
|
72
|
-
});
|
|
73
|
-
process.exit(0);
|
|
74
|
-
}
|
|
75
69
|
const lando = await (0, _devEnvironmentLando.bootstrapLando)();
|
|
76
70
|
const envPath = (0, _devEnvironmentCore.getEnvironmentPath)(slug);
|
|
77
71
|
if (!(await (0, _devEnvironmentLando.isEnvUp)(lando, envPath))) {
|
|
@@ -81,6 +75,8 @@ const appQuery = `
|
|
|
81
75
|
throw new _userError.default('Environment needs to be started first');
|
|
82
76
|
}
|
|
83
77
|
const cmd = new _devEnvSyncSql.DevEnvSyncSQLCommand(app, env, slug, trackerFn);
|
|
78
|
+
// TODO: There's a function called handleCLIException for dev-env that handles exceptions but DevEnvSyncSQLCommand has its own implementation.
|
|
79
|
+
// We should probably use handleCLIException instead?
|
|
84
80
|
await cmd.run();
|
|
85
81
|
await trackerFn('success');
|
|
86
82
|
});
|
|
File without changes
|
|
@@ -64,6 +64,7 @@ cmd.argv(process.argv, async (arg, opt) => {
|
|
|
64
64
|
phpmyadmin: currentInstanceData.phpmyadmin,
|
|
65
65
|
xdebug: currentInstanceData.xdebug,
|
|
66
66
|
mailpit: (_currentInstanceData$ = currentInstanceData.mailpit) !== null && _currentInstanceData$ !== void 0 ? _currentInstanceData$ : currentInstanceData.mailhog,
|
|
67
|
+
photon: currentInstanceData.photon,
|
|
67
68
|
mediaRedirectDomain: currentInstanceData.mediaRedirectDomain,
|
|
68
69
|
multisite: false,
|
|
69
70
|
title: ''
|
|
@@ -26,17 +26,18 @@ const examples = [{
|
|
|
26
26
|
description: 'The output file can be specified with the --output flag'
|
|
27
27
|
}];
|
|
28
28
|
const appQuery = `
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
id,
|
|
30
|
+
name,
|
|
31
|
+
type,
|
|
32
|
+
organization { id, name },
|
|
33
|
+
environments{
|
|
34
|
+
id
|
|
35
|
+
appId
|
|
36
|
+
type
|
|
37
|
+
name
|
|
38
|
+
primaryDomain { name }
|
|
39
|
+
uniqueLabel
|
|
40
|
+
}
|
|
40
41
|
`;
|
|
41
42
|
(0, _command.default)({
|
|
42
43
|
appContext: true,
|
|
@@ -317,7 +317,7 @@ const displayPlaybook = ({
|
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
|
-
(0, _command.default)({
|
|
320
|
+
void (0, _command.default)({
|
|
321
321
|
appContext: true,
|
|
322
322
|
appQuery,
|
|
323
323
|
envContext: true,
|
|
@@ -498,7 +498,7 @@ Processing the SQL import for your environment...
|
|
|
498
498
|
} catch (uploadError) {
|
|
499
499
|
await track('import_sql_command_error', {
|
|
500
500
|
error_type: 'upload_failed',
|
|
501
|
-
upload_error: uploadError
|
|
501
|
+
upload_error: uploadError.message
|
|
502
502
|
});
|
|
503
503
|
progressTracker.stepFailed('upload');
|
|
504
504
|
return failWithError(uploadError);
|
package/dist/bin/vip-whoami.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* @format
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
3
|
/**
|
|
9
4
|
* External dependencies
|
|
10
5
|
*/
|
|
@@ -26,28 +21,30 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
|
|
|
26
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; }
|
|
27
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
28
23
|
async function whoamiCommand() {
|
|
24
|
+
var _currentUser$displayN, _currentUser$id;
|
|
29
25
|
const trackingParams = {
|
|
30
26
|
command: 'vip whoami'
|
|
31
27
|
};
|
|
32
28
|
await (0, _tracker.trackEvent)('whoami_command_execute', trackingParams);
|
|
33
|
-
let currentUser
|
|
29
|
+
let currentUser;
|
|
34
30
|
try {
|
|
35
31
|
currentUser = await (0, _user.getCurrentUserInfo)();
|
|
36
32
|
} catch (err) {
|
|
33
|
+
const error = err instanceof Error ? err : new Error('Unknown error');
|
|
37
34
|
await (0, _tracker.trackEvent)('whoami_command_error', {
|
|
38
35
|
...trackingParams,
|
|
39
|
-
error:
|
|
36
|
+
error: error.message
|
|
40
37
|
});
|
|
41
|
-
exit.withError(`Failed to fetch information about the currently logged-in user error: ${
|
|
38
|
+
exit.withError(`Failed to fetch information about the currently logged-in user error: ${error.message}`);
|
|
42
39
|
}
|
|
43
40
|
await (0, _tracker.trackEvent)('whoami_command_success', trackingParams);
|
|
44
|
-
const output = [`- Howdy ${currentUser.displayName}!`, `- Your user ID is ${currentUser.id}`];
|
|
41
|
+
const output = [`- Howdy ${(_currentUser$displayN = currentUser.displayName) !== null && _currentUser$displayN !== void 0 ? _currentUser$displayN : 'user'}!`, `- Your user ID is ${(_currentUser$id = currentUser.id) !== null && _currentUser$id !== void 0 ? _currentUser$id : ' not found'}`];
|
|
45
42
|
if (currentUser.isVIP) {
|
|
46
43
|
output.push('- Your account has VIP Staff permissions');
|
|
47
44
|
}
|
|
48
45
|
console.log(output.join('\n'));
|
|
49
46
|
}
|
|
50
|
-
(0, _command.default)({
|
|
47
|
+
void (0, _command.default)({
|
|
51
48
|
usage: 'vip whoami'
|
|
52
49
|
}).examples([{
|
|
53
50
|
usage: 'vip whoami',
|
|
@@ -37,13 +37,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
37
37
|
* @return {string} Site home url. null if not found
|
|
38
38
|
*/
|
|
39
39
|
function findSiteHomeUrl(sql) {
|
|
40
|
+
var _sql$match;
|
|
40
41
|
const regex = "'(siteurl|home)',\\s?'(.*?)'";
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
const url = results[2];
|
|
44
|
-
return _url.default.parse(url).hostname;
|
|
45
|
-
}
|
|
46
|
-
return null;
|
|
42
|
+
const url = ((_sql$match = sql.match(regex)) === null || _sql$match === void 0 ? void 0 : _sql$match[2]) || '';
|
|
43
|
+
return _url.default.parse(url).hostname || null;
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
/**
|
|
@@ -60,11 +57,12 @@ async function extractSiteUrls(sqlFile) {
|
|
|
60
57
|
readInterface.on('line', line => {
|
|
61
58
|
const domain = findSiteHomeUrl(line);
|
|
62
59
|
if (domain) {
|
|
63
|
-
domains.add(
|
|
60
|
+
domains.add(domain);
|
|
64
61
|
}
|
|
65
62
|
});
|
|
66
63
|
readInterface.on('close', () => {
|
|
67
|
-
|
|
64
|
+
// Soring by length so that longest domains are replaced first
|
|
65
|
+
resolve(Array.from(domains).sort((dom1, dom2) => dom2.length - dom1.length));
|
|
68
66
|
});
|
|
69
67
|
readInterface.on('error', reject);
|
|
70
68
|
});
|
|
@@ -86,7 +84,7 @@ class DevEnvSyncSQLCommand {
|
|
|
86
84
|
this.tmpDir = (0, _utils.makeTempDir)();
|
|
87
85
|
}
|
|
88
86
|
get landoDomain() {
|
|
89
|
-
return
|
|
87
|
+
return `${this.slug}.vipdev.lndo.site`;
|
|
90
88
|
}
|
|
91
89
|
get sqlFile() {
|
|
92
90
|
return `${this.tmpDir}/sql-export.sql`;
|
|
@@ -114,7 +112,7 @@ class DevEnvSyncSQLCommand {
|
|
|
114
112
|
* @throws {Error} If there is an error reading the file
|
|
115
113
|
*/
|
|
116
114
|
async runSearchReplace() {
|
|
117
|
-
const replacements = this.
|
|
115
|
+
const replacements = Object.entries(this.searchReplaceMap).flat();
|
|
118
116
|
const readStream = _fs.default.createReadStream(this.sqlFile);
|
|
119
117
|
const replacedStream = await (0, _vipSearchReplace.replace)(readStream, replacements);
|
|
120
118
|
const outputFile = `${this.tmpDir}/sql-export-sr.sql`;
|
|
@@ -127,6 +125,20 @@ class DevEnvSyncSQLCommand {
|
|
|
127
125
|
replacedStream.on('error', reject);
|
|
128
126
|
});
|
|
129
127
|
}
|
|
128
|
+
generateSearchReplaceMap() {
|
|
129
|
+
this.searchReplaceMap = {};
|
|
130
|
+
for (const url of this.siteUrls) {
|
|
131
|
+
this.searchReplaceMap[url] = this.landoDomain;
|
|
132
|
+
}
|
|
133
|
+
const networkSites = this.env.wpSitesSDS.nodes;
|
|
134
|
+
if (!networkSites) return;
|
|
135
|
+
for (const site of networkSites) {
|
|
136
|
+
if (!site.blogId || site.blogId === 1) continue;
|
|
137
|
+
const url = site.homeUrl.replace(/https?:\/\//, '');
|
|
138
|
+
if (!this.searchReplaceMap[url]) continue;
|
|
139
|
+
this.searchReplaceMap[url] = `${site.blogId}.${this.landoDomain}`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
130
142
|
|
|
131
143
|
/**
|
|
132
144
|
* Runs the SQL import command to import the SQL file
|
|
@@ -153,6 +165,14 @@ class DevEnvSyncSQLCommand {
|
|
|
153
165
|
try {
|
|
154
166
|
await this.generateExport();
|
|
155
167
|
} catch (err) {
|
|
168
|
+
// this.generateExport probably catches all exceptions, track the event and runs exit.withError() but if things go really wrong
|
|
169
|
+
// and we have no tracking data, we would at least have it logged here.
|
|
170
|
+
// the following will not get executed if this.generateExport() calls exit.withError() on all exception
|
|
171
|
+
await this.track('error', {
|
|
172
|
+
error_type: 'export_sql_backup',
|
|
173
|
+
error_message: err === null || err === void 0 ? void 0 : err.message,
|
|
174
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
175
|
+
});
|
|
156
176
|
exit.withError(`Error exporting SQL backup: ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
157
177
|
}
|
|
158
178
|
try {
|
|
@@ -160,27 +180,38 @@ class DevEnvSyncSQLCommand {
|
|
|
160
180
|
await (0, _clientFileUploader.unzipFile)(this.gzFile, this.sqlFile);
|
|
161
181
|
console.log(`${_chalk.default.green('✓')} Extracted to ${this.sqlFile}`);
|
|
162
182
|
} catch (err) {
|
|
163
|
-
await this.track('
|
|
164
|
-
|
|
183
|
+
await this.track('error', {
|
|
184
|
+
error_type: 'archive_extraction',
|
|
185
|
+
error_message: err === null || err === void 0 ? void 0 : err.message,
|
|
186
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
165
187
|
});
|
|
166
|
-
exit.withError(`Error extracting the SQL export: ${err
|
|
188
|
+
exit.withError(`Error extracting the SQL export: ${err.message}`);
|
|
167
189
|
}
|
|
168
190
|
try {
|
|
169
191
|
console.log('Extracting site urls from the SQL file...');
|
|
170
192
|
this.siteUrls = await extractSiteUrls(this.sqlFile);
|
|
171
193
|
} catch (err) {
|
|
194
|
+
await this.track('error', {
|
|
195
|
+
error_type: 'extract_site_urls',
|
|
196
|
+
error_message: err === null || err === void 0 ? void 0 : err.message,
|
|
197
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
198
|
+
});
|
|
172
199
|
exit.withError(`Error extracting site URLs: ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
173
200
|
}
|
|
201
|
+
console.log('Generating search-replace configuration...');
|
|
202
|
+
this.generateSearchReplaceMap();
|
|
174
203
|
try {
|
|
175
204
|
console.log('Running the following search-replace operations on the SQL file:');
|
|
176
|
-
|
|
177
|
-
console.log(` ${domain} -> ${
|
|
178
|
-
}
|
|
205
|
+
for (const [domain, landoDomain] of Object.entries(this.searchReplaceMap)) {
|
|
206
|
+
console.log(` ${domain} -> ${landoDomain}`);
|
|
207
|
+
}
|
|
179
208
|
await this.runSearchReplace();
|
|
180
209
|
console.log(`${_chalk.default.green('✓')} Search-replace operation is complete`);
|
|
181
210
|
} catch (err) {
|
|
182
|
-
await this.track('
|
|
183
|
-
|
|
211
|
+
await this.track('error', {
|
|
212
|
+
error_type: 'search_replace',
|
|
213
|
+
error_message: err === null || err === void 0 ? void 0 : err.message,
|
|
214
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
184
215
|
});
|
|
185
216
|
exit.withError(`Error replacing domains: ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
186
217
|
}
|
|
@@ -189,8 +220,10 @@ class DevEnvSyncSQLCommand {
|
|
|
189
220
|
await this.runImport();
|
|
190
221
|
console.log(`${_chalk.default.green('✓')} SQL file imported`);
|
|
191
222
|
} catch (err) {
|
|
192
|
-
await this.track('
|
|
193
|
-
|
|
223
|
+
await this.track('error', {
|
|
224
|
+
error_type: 'import_sql_file',
|
|
225
|
+
error_message: err === null || err === void 0 ? void 0 : err.message,
|
|
226
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
194
227
|
});
|
|
195
228
|
exit.withError(`Error importing SQL file: ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
196
229
|
}
|
|
@@ -322,7 +322,8 @@ class ExportSQLCommand {
|
|
|
322
322
|
} catch (err) {
|
|
323
323
|
await this.track('error', {
|
|
324
324
|
error_type: 'cannot_write_to_path',
|
|
325
|
-
error_message: `Cannot write to the specified path: ${err === null || err === void 0 ? void 0 : err.message}
|
|
325
|
+
error_message: `Cannot write to the specified path: ${err === null || err === void 0 ? void 0 : err.message}`,
|
|
326
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
326
327
|
});
|
|
327
328
|
exit.withError(`Cannot write to the specified path: ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
328
329
|
}
|
|
@@ -351,9 +352,16 @@ class ExportSQLCommand {
|
|
|
351
352
|
if (err !== null && err !== void 0 && err.message.includes('Backup Copy already in progress')) {
|
|
352
353
|
await this.track('error', {
|
|
353
354
|
error_type: 'job_already_running',
|
|
354
|
-
error_message: err === null || err === void 0 ? void 0 : err.message
|
|
355
|
+
error_message: err === null || err === void 0 ? void 0 : err.message,
|
|
356
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
357
|
+
});
|
|
358
|
+
exit.withError('There is an export job already running for this environment: ' + `https://dashboard.wpvip.com/apps/${this.app.id}/${this.env.uniqueLabel}/data/database/backups\n` + 'Currently, we allow only one export job at a time, per site. Please try again later.');
|
|
359
|
+
} else {
|
|
360
|
+
await this.track('error', {
|
|
361
|
+
error_type: 'create_export_job',
|
|
362
|
+
error_message: err === null || err === void 0 ? void 0 : err.message,
|
|
363
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
355
364
|
});
|
|
356
|
-
exit.withError('There is an export job already running for this site: ' + `https://dashboard.wpvip.com/apps/${this.app.id}/${this.env.uniqueLabel}/data/database/backups\n` + 'Currently, we allow only one export job at a time, per site. Please try again later.');
|
|
357
365
|
}
|
|
358
366
|
exit.withError(`Error creating export job: ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
359
367
|
}
|
|
@@ -378,7 +386,8 @@ class ExportSQLCommand {
|
|
|
378
386
|
this.stopProgressTracker();
|
|
379
387
|
await this.track('error', {
|
|
380
388
|
error_type: 'download_failed',
|
|
381
|
-
error_message: err === null || err === void 0 ? void 0 : err.message
|
|
389
|
+
error_message: err === null || err === void 0 ? void 0 : err.message,
|
|
390
|
+
stack: err === null || err === void 0 ? void 0 : err.stack
|
|
382
391
|
});
|
|
383
392
|
exit.withError(`Error downloading exported file: ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
384
393
|
}
|
|
@@ -4,36 +4,29 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
7
8
|
var _http = _interopRequireDefault(require("../../../lib/api/http"));
|
|
8
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
10
|
/**
|
|
10
11
|
* External dependencies
|
|
11
12
|
*/
|
|
12
|
-
const debug = require('debug')('@automattic/vip:analytics:clients:pendo');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Internal dependencies
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
const debug = (0, _debug.default)('@automattic/vip:analytics:clients:pendo');
|
|
18
19
|
/**
|
|
19
20
|
* Pendo analytics client.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
22
|
class Pendo {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
userId,
|
|
29
|
-
eventPrefix,
|
|
30
|
-
env
|
|
31
|
-
}) {
|
|
32
|
-
this.eventPrefix = eventPrefix;
|
|
33
|
-
this.userAgent = env.userAgent;
|
|
34
|
-
this.userId = userId;
|
|
23
|
+
static ENDPOINT = '/pendo';
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.eventPrefix = options.eventPrefix;
|
|
26
|
+
this.userAgent = options.env.userAgent;
|
|
27
|
+
this.userId = options.userId;
|
|
35
28
|
this.context = {
|
|
36
|
-
...env
|
|
29
|
+
...options.env
|
|
37
30
|
};
|
|
38
31
|
}
|
|
39
32
|
async trackEvent(eventName, eventProps = {}) {
|
|
@@ -52,10 +45,8 @@ class Pendo {
|
|
|
52
45
|
return await this.send(eventName, eventProps);
|
|
53
46
|
} catch (error) {
|
|
54
47
|
debug(error);
|
|
48
|
+
return Promise.resolve(false);
|
|
55
49
|
}
|
|
56
|
-
|
|
57
|
-
// Resolve to false instead of rejecting
|
|
58
|
-
return Promise.resolve(false);
|
|
59
50
|
}
|
|
60
51
|
async send(eventName, eventProps) {
|
|
61
52
|
const body = {
|
|
@@ -69,11 +60,11 @@ class Pendo {
|
|
|
69
60
|
debug('send()', body);
|
|
70
61
|
const response = await (0, _http.default)(Pendo.ENDPOINT, {
|
|
71
62
|
method: 'POST',
|
|
72
|
-
body
|
|
63
|
+
body: JSON.stringify(body)
|
|
73
64
|
});
|
|
74
65
|
const responseText = await response.text();
|
|
75
66
|
debug('response', responseText);
|
|
76
|
-
return
|
|
67
|
+
return response;
|
|
77
68
|
}
|
|
78
69
|
}
|
|
79
70
|
exports.default = Pendo;
|
|
@@ -6,19 +6,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
|
|
8
8
|
var _querystring = _interopRequireDefault(require("querystring"));
|
|
9
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
9
10
|
var _apiConfig = require("../../cli/apiConfig");
|
|
10
11
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
12
|
/**
|
|
12
13
|
* External dependencies
|
|
13
14
|
*/
|
|
14
|
-
const debug = require('debug')('@automattic/vip:analytics:clients:tracks');
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Internal dependencies
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
const debug = (0, _debug.default)('@automattic/vip:analytics:clients:tracks');
|
|
20
21
|
const validEventOrPropNamePattern = /^[a-z_][a-z0-9_]*$/;
|
|
21
|
-
|
|
22
22
|
/**
|
|
23
23
|
* Simple class for tracking using Automattic Tracks.
|
|
24
24
|
*
|
|
@@ -28,9 +28,7 @@ const validEventOrPropNamePattern = /^[a-z_][a-z0-9_]*$/;
|
|
|
28
28
|
// TODO: add batch support (can include multiples in `events` array)
|
|
29
29
|
|
|
30
30
|
class Tracks {
|
|
31
|
-
static
|
|
32
|
-
return 'https://public-api.wordpress.com/rest/v1.1/tracks/record';
|
|
33
|
-
}
|
|
31
|
+
static ENDPOINT = 'https://public-api.wordpress.com/rest/v1.1/tracks/record';
|
|
34
32
|
constructor(userId, userType, eventPrefix, env) {
|
|
35
33
|
this.eventPrefix = eventPrefix;
|
|
36
34
|
this.userAgent = env.userAgent;
|
|
@@ -54,9 +52,10 @@ class Tracks {
|
|
|
54
52
|
});
|
|
55
53
|
eventProps.is_vip = await (0, _apiConfig.checkIfUserIsVip)(); // Add `is_vip` flag to every Tracks event recorded
|
|
56
54
|
|
|
57
|
-
const event =
|
|
58
|
-
_en: name
|
|
59
|
-
|
|
55
|
+
const event = {
|
|
56
|
+
_en: name,
|
|
57
|
+
...eventProps
|
|
58
|
+
};
|
|
60
59
|
|
|
61
60
|
// For when we want to support batched events
|
|
62
61
|
const events = [event];
|
|
@@ -89,10 +88,13 @@ class Tracks {
|
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
// Resolve to false instead of rejecting
|
|
92
|
-
return
|
|
91
|
+
return false;
|
|
93
92
|
}
|
|
94
93
|
send(extraParams) {
|
|
95
|
-
const params =
|
|
94
|
+
const params = {
|
|
95
|
+
...this.baseParams,
|
|
96
|
+
...extraParams
|
|
97
|
+
};
|
|
96
98
|
const method = 'POST';
|
|
97
99
|
const body = _querystring.default.stringify(params);
|
|
98
100
|
const headers = {
|
|
@@ -100,8 +102,6 @@ class Tracks {
|
|
|
100
102
|
'User-Agent': this.userAgent
|
|
101
103
|
};
|
|
102
104
|
debug('send()', body);
|
|
103
|
-
|
|
104
|
-
// eslint-disable-next-line no-undef
|
|
105
105
|
return (0, _nodeFetch.default)(Tracks.ENDPOINT, {
|
|
106
106
|
method,
|
|
107
107
|
body,
|
|
@@ -5,15 +5,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _debug = _interopRequireDefault(require("debug"));
|
|
8
|
-
var _stub = _interopRequireDefault(require("./clients/stub"));
|
|
9
8
|
var _env = _interopRequireDefault(require("../env"));
|
|
10
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
10
|
/**
|
|
12
11
|
* External dependencies
|
|
13
12
|
*/
|
|
13
|
+
|
|
14
14
|
/**
|
|
15
15
|
* Internal dependencies
|
|
16
16
|
*/
|
|
17
|
+
|
|
17
18
|
const debug = (0, _debug.default)('@automattic/vip:analytics');
|
|
18
19
|
|
|
19
20
|
/* eslint-disable camelcase */
|
|
@@ -26,23 +27,19 @@ const client_info = {
|
|
|
26
27
|
/* eslint-enable camelcase */
|
|
27
28
|
|
|
28
29
|
class Analytics {
|
|
29
|
-
constructor({
|
|
30
|
-
clients = new _stub.default()
|
|
31
|
-
}) {
|
|
30
|
+
constructor(clients) {
|
|
32
31
|
this.clients = clients;
|
|
33
32
|
}
|
|
34
33
|
async trackEvent(name, props = {}) {
|
|
35
34
|
if (process.env.DO_NOT_TRACK) {
|
|
36
35
|
debug(`trackEvent() for ${name} => skipping per DO_NOT_TRACK variable`);
|
|
37
|
-
return
|
|
36
|
+
return [];
|
|
38
37
|
}
|
|
39
|
-
return Promise.all(this.clients.map(client => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
45
|
-
}));
|
|
38
|
+
return Promise.all(this.clients.map(client => client.trackEvent(name, {
|
|
39
|
+
// eslint-disable-next-line camelcase
|
|
40
|
+
...client_info,
|
|
41
|
+
...props
|
|
42
|
+
})));
|
|
46
43
|
}
|
|
47
44
|
}
|
|
48
45
|
exports.default = Analytics;
|