@automattic/vip 2.9.5 → 2.11.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/CONTRIBUTING.md +2 -11
- package/README.md +26 -0
- package/dist/bin/vip-dev-env-create.js +9 -1
- package/dist/bin/vip-dev-env-destroy.js +7 -7
- package/dist/bin/vip-dev-env-exec.js +7 -1
- package/dist/bin/vip-dev-env-import-media.js +7 -1
- package/dist/bin/vip-dev-env-import-sql.js +7 -1
- package/dist/bin/vip-dev-env-info.js +10 -1
- package/dist/bin/vip-dev-env-list.js +10 -1
- package/dist/bin/vip-dev-env-start.js +14 -3
- package/dist/bin/vip-dev-env-stop.js +7 -1
- package/dist/bin/vip-dev-env-update.js +8 -2
- package/dist/bin/vip-import-sql.js +7 -1
- package/dist/lib/analytics/clients/pendo.js +92 -0
- package/dist/lib/analytics/index.js +8 -3
- package/dist/lib/dev-environment/dev-environment-cli.js +56 -1
- package/dist/lib/dev-environment/dev-environment-core.js +4 -2
- package/dist/lib/dev-environment/dev-environment-lando.js +35 -3
- package/dist/lib/tracker.js +15 -7
- package/npm-shrinkwrap.json +1 -1
- package/package/dist/bin/vip-app-list.js +73 -0
- package/package/dist/bin/vip-app.js +76 -0
- package/package/dist/bin/vip-config-envvar-delete.js +97 -0
- package/package/dist/bin/vip-config-envvar-get-all.js +94 -0
- package/package/dist/bin/vip-config-envvar-get.js +79 -0
- package/package/dist/bin/vip-config-envvar-list.js +91 -0
- package/package/dist/bin/vip-config-envvar-set.js +123 -0
- package/package/dist/bin/vip-config-envvar.js +23 -0
- package/package/dist/bin/vip-config.js +20 -0
- package/package/dist/bin/vip-dev-env-create.js +105 -0
- package/package/dist/bin/vip-dev-env-destroy.js +56 -0
- package/package/dist/bin/vip-dev-env-exec.js +67 -0
- package/package/dist/bin/vip-dev-env-import-media.js +51 -0
- package/package/dist/bin/vip-dev-env-import-sql.js +83 -0
- package/package/dist/bin/vip-dev-env-import.js +32 -0
- package/package/dist/bin/vip-dev-env-info.js +61 -0
- package/package/dist/bin/vip-dev-env-list.js +46 -0
- package/package/dist/bin/vip-dev-env-start.js +77 -0
- package/package/dist/bin/vip-dev-env-stop.js +52 -0
- package/package/dist/bin/vip-dev-env-update.js +89 -0
- package/package/dist/bin/vip-dev-env.js +23 -0
- package/package/dist/bin/vip-import-media-abort.js +132 -0
- package/package/dist/bin/vip-import-media-status.js +84 -0
- package/package/dist/bin/vip-import-media.js +168 -0
- package/package/dist/bin/vip-import-sql-status.js +83 -0
- package/package/dist/bin/vip-import-sql.js +580 -0
- package/package/dist/bin/vip-import-validate-files.js +191 -0
- package/package/dist/bin/vip-import-validate-sql.js +34 -0
- package/package/dist/bin/vip-import.js +20 -0
- package/package/dist/bin/vip-logs.js +232 -0
- package/package/dist/bin/vip-search-replace.js +71 -0
- package/package/dist/bin/vip-sync.js +191 -0
- package/package/dist/bin/vip-whoami.js +67 -0
- package/package/dist/bin/vip-wp.js +555 -0
- package/package/dist/bin/vip.js +149 -0
- package/package/dist/lib/analytics/clients/client.js +1 -0
- package/package/dist/lib/analytics/clients/pendo.js +92 -0
- package/package/dist/lib/analytics/clients/stub.js +19 -0
- package/package/dist/lib/analytics/clients/tracks.js +128 -0
- package/package/dist/lib/analytics/index.js +45 -0
- package/package/dist/lib/api/app.js +70 -0
- package/package/dist/lib/api/feature-flags.js +39 -0
- package/package/dist/lib/api/user.js +58 -0
- package/package/dist/lib/api.js +136 -0
- package/package/dist/lib/app-logs/app-logs.js +70 -0
- package/package/dist/lib/cli/apiConfig.js +90 -0
- package/package/dist/lib/cli/command.js +606 -0
- package/package/dist/lib/cli/envAlias.js +60 -0
- package/package/dist/lib/cli/exit.js +33 -0
- package/package/dist/lib/cli/format.js +213 -0
- package/package/dist/lib/cli/pager.js +52 -0
- package/package/dist/lib/cli/progress.js +208 -0
- package/package/dist/lib/cli/prompt.js +37 -0
- package/package/dist/lib/cli/repo.js +77 -0
- package/package/dist/lib/client-file-uploader.js +602 -0
- package/package/dist/lib/constants/dev-environment.js +42 -0
- package/package/dist/lib/constants/file-size.js +14 -0
- package/package/dist/lib/dev-environment/dev-environment-cli.js +508 -0
- package/package/dist/lib/dev-environment/dev-environment-core.js +620 -0
- package/package/dist/lib/dev-environment/dev-environment-lando.js +330 -0
- package/package/dist/lib/dev-environment/types.js +1 -0
- package/package/dist/lib/env.js +36 -0
- package/package/dist/lib/envvar/api-delete.js +56 -0
- package/package/dist/lib/envvar/api-get-all.js +59 -0
- package/package/dist/lib/envvar/api-get.js +24 -0
- package/package/dist/lib/envvar/api-list.js +60 -0
- package/package/dist/lib/envvar/api-set.js +58 -0
- package/package/dist/lib/envvar/api.js +104 -0
- package/package/dist/lib/envvar/input.js +55 -0
- package/package/dist/lib/envvar/logging.js +33 -0
- package/package/dist/lib/envvar/read-file.js +43 -0
- package/package/dist/lib/http/socks-proxy-agent.js +25 -0
- package/package/dist/lib/keychain/browser.js +35 -0
- package/package/dist/lib/keychain/insecure.js +63 -0
- package/package/dist/lib/keychain/keychain.js +1 -0
- package/package/dist/lib/keychain/secure.js +36 -0
- package/package/dist/lib/keychain.js +36 -0
- package/package/dist/lib/media-import/media-file-import.js +34 -0
- package/package/dist/lib/media-import/progress.js +86 -0
- package/package/dist/lib/media-import/status.js +335 -0
- package/package/dist/lib/rollbar.js +35 -0
- package/package/dist/lib/search-and-replace.js +203 -0
- package/package/dist/lib/site-import/db-file-import.js +46 -0
- package/package/dist/lib/site-import/status.js +444 -0
- package/package/dist/lib/token.js +132 -0
- package/package/dist/lib/tracker.js +96 -0
- package/package/dist/lib/validations/is-multi-site-sql-dump.js +59 -0
- package/package/dist/lib/validations/is-multi-site.js +99 -0
- package/package/dist/lib/validations/line-by-line.js +92 -0
- package/package/dist/lib/validations/site-type.js +66 -0
- package/package/dist/lib/validations/sql.js +371 -0
- package/package/dist/lib/vip-import-validate-files.js +548 -0
- package/package/vip.iml +11 -0
- package/package.json +1 -1
- package/vip.iml +11 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.importSqlCheckStatus = importSqlCheckStatus;
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
|
|
9
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
10
|
+
|
|
11
|
+
var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
|
|
12
|
+
|
|
13
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
14
|
+
|
|
15
|
+
var _api = _interopRequireDefault(require("../api"));
|
|
16
|
+
|
|
17
|
+
var _dbFileImport = require("./db-file-import");
|
|
18
|
+
|
|
19
|
+
var _progress = require("../cli/progress");
|
|
20
|
+
|
|
21
|
+
var exit = _interopRequireWildcard(require("../cli/exit"));
|
|
22
|
+
|
|
23
|
+
var _format = require("../cli/format");
|
|
24
|
+
|
|
25
|
+
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); }
|
|
26
|
+
|
|
27
|
+
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; }
|
|
28
|
+
|
|
29
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* @format
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* External dependencies
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Internal dependencies
|
|
42
|
+
*/
|
|
43
|
+
const debug = (0, _debug.default)('vip:lib/site-import/status');
|
|
44
|
+
const IMPORT_SQL_PROGRESS_POLL_INTERVAL = 5000;
|
|
45
|
+
const IMPORT_SQL_PROGRESS_QUERY = (0, _graphqlTag.default)`
|
|
46
|
+
query App($appId: Int, $envId: Int) {
|
|
47
|
+
app(id: $appId) {
|
|
48
|
+
environments(id: $envId) {
|
|
49
|
+
id
|
|
50
|
+
isK8sResident
|
|
51
|
+
launched
|
|
52
|
+
jobs(types: "sql_import") {
|
|
53
|
+
id
|
|
54
|
+
type
|
|
55
|
+
completedAt
|
|
56
|
+
createdAt
|
|
57
|
+
progress {
|
|
58
|
+
status
|
|
59
|
+
steps {
|
|
60
|
+
id
|
|
61
|
+
name
|
|
62
|
+
status
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
importStatus {
|
|
67
|
+
dbOperationInProgress
|
|
68
|
+
importInProgress
|
|
69
|
+
progress {
|
|
70
|
+
started_at
|
|
71
|
+
steps {
|
|
72
|
+
name
|
|
73
|
+
started_at
|
|
74
|
+
finished_at
|
|
75
|
+
result
|
|
76
|
+
output
|
|
77
|
+
}
|
|
78
|
+
finished_at
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
async function getStatus(api, appId, envId) {
|
|
87
|
+
const response = await api.query({
|
|
88
|
+
query: IMPORT_SQL_PROGRESS_QUERY,
|
|
89
|
+
variables: {
|
|
90
|
+
appId,
|
|
91
|
+
envId
|
|
92
|
+
},
|
|
93
|
+
fetchPolicy: 'network-only'
|
|
94
|
+
});
|
|
95
|
+
const {
|
|
96
|
+
data: {
|
|
97
|
+
app: {
|
|
98
|
+
environments
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} = response;
|
|
102
|
+
|
|
103
|
+
if (!(environments !== null && environments !== void 0 && environments.length)) {
|
|
104
|
+
throw new Error('Unable to determine import status from environment');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const [environment] = environments;
|
|
108
|
+
const {
|
|
109
|
+
importStatus,
|
|
110
|
+
jobs,
|
|
111
|
+
launched
|
|
112
|
+
} = environment;
|
|
113
|
+
|
|
114
|
+
if (!environment.isK8sResident && !(jobs !== null && jobs !== void 0 && jobs.length)) {
|
|
115
|
+
return {};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const [importJob] = jobs;
|
|
119
|
+
return {
|
|
120
|
+
importStatus,
|
|
121
|
+
importJob,
|
|
122
|
+
launched
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getErrorMessage(importFailed, launched = false) {
|
|
127
|
+
debug({
|
|
128
|
+
importFailed
|
|
129
|
+
});
|
|
130
|
+
const rollbackMessage = launched ? '' : `Your site is ${_chalk.default.blue('automatically being rolled back')} to the last backup prior to your import job.
|
|
131
|
+
`;
|
|
132
|
+
let message = importFailed.error;
|
|
133
|
+
|
|
134
|
+
if (importFailed.inImportProgress) {
|
|
135
|
+
switch (importFailed.stepName) {
|
|
136
|
+
case 'import_preflights':
|
|
137
|
+
message += `
|
|
138
|
+
This error occurred prior to the mysql batch script processing of your SQL file.
|
|
139
|
+
|
|
140
|
+
Your site content was not altered.
|
|
141
|
+
|
|
142
|
+
If this error persists, please contact support.
|
|
143
|
+
`;
|
|
144
|
+
break;
|
|
145
|
+
|
|
146
|
+
case 'importing_db':
|
|
147
|
+
message += `
|
|
148
|
+
This error occurred during the mysql batch script processing of your SQL file.
|
|
149
|
+
|
|
150
|
+
${rollbackMessage}`;
|
|
151
|
+
|
|
152
|
+
if (importFailed.commandOutput) {
|
|
153
|
+
const commandOutput = [].concat(importFailed.commandOutput).join(';');
|
|
154
|
+
message += `
|
|
155
|
+
Please inspect your input file and make the appropriate corrections before trying again.
|
|
156
|
+
The server said:
|
|
157
|
+
> ${_chalk.default.red(commandOutput)}
|
|
158
|
+
`;
|
|
159
|
+
} else {
|
|
160
|
+
message += 'Please contact support and include this message along with your sql file.';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
break;
|
|
164
|
+
|
|
165
|
+
case 'validating_db':
|
|
166
|
+
message += `\nThis error occurred during the post-import validation of the imported data.
|
|
167
|
+
|
|
168
|
+
${rollbackMessage}
|
|
169
|
+
`;
|
|
170
|
+
|
|
171
|
+
if (importFailed.commandOutput) {
|
|
172
|
+
const commandOutput = [].concat(importFailed.commandOutput).join(';');
|
|
173
|
+
message += `
|
|
174
|
+
Please inspect your input file and make the appropriate corrections before trying again.
|
|
175
|
+
The server said:
|
|
176
|
+
> ${_chalk.default.red(commandOutput)}
|
|
177
|
+
`;
|
|
178
|
+
} else {
|
|
179
|
+
message += 'Please contact support and include this message along with your sql file.';
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
break;
|
|
183
|
+
|
|
184
|
+
default:
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return message;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function importSqlCheckStatus({
|
|
192
|
+
app,
|
|
193
|
+
env,
|
|
194
|
+
progressTracker
|
|
195
|
+
}) {
|
|
196
|
+
// Stop printing so we can pass our callback
|
|
197
|
+
progressTracker.stopPrinting(); // NO `console.log` in this function (until results are final)! It will break the progress printing.
|
|
198
|
+
|
|
199
|
+
const api = await (0, _api.default)();
|
|
200
|
+
|
|
201
|
+
if (!(0, _dbFileImport.currentUserCanImportForApp)(app)) {
|
|
202
|
+
throw new Error('The currently authenticated account does not have permission to view SQL import status.');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
let createdAt;
|
|
206
|
+
let completedAt;
|
|
207
|
+
let overallStatus = 'Checking...';
|
|
208
|
+
|
|
209
|
+
const setProgressTrackerSuffix = () => {
|
|
210
|
+
const sprite = (0, _format.getGlyphForStatus)(overallStatus, progressTracker.runningSprite);
|
|
211
|
+
const formattedCreatedAt = createdAt ? `${new Date(createdAt).toLocaleString()} (${createdAt})` : 'TBD';
|
|
212
|
+
const formattedCompletedAt = createdAt && completedAt ? `${new Date(completedAt).toLocaleString()} (${completedAt})` : 'TBD';
|
|
213
|
+
const exitPrompt = '(Press ^C to hide progress. The import will continue in the background.)';
|
|
214
|
+
let statusMessage;
|
|
215
|
+
|
|
216
|
+
switch (overallStatus) {
|
|
217
|
+
case 'success':
|
|
218
|
+
statusMessage = `Success ${sprite} imported data should be visible on your site ${env.primaryDomain.name}.`;
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
case 'running':
|
|
222
|
+
if (progressTracker.allStepsSucceeded()) {
|
|
223
|
+
statusMessage = `Finishing up... ${sprite} `;
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Intentionally no break to get default case:
|
|
228
|
+
|
|
229
|
+
default:
|
|
230
|
+
statusMessage = `${(0, _format.capitalize)(overallStatus)} ${sprite}`;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const maybeExitPrompt = `${overallStatus === 'running' ? exitPrompt : ''}`;
|
|
234
|
+
const jobCreateCompleteTimestamps = `
|
|
235
|
+
SQL Import Started: ${formattedCreatedAt}
|
|
236
|
+
SQL Import Completed: ${formattedCompletedAt}`;
|
|
237
|
+
const maybeTimestamps = ['running', 'success', 'failed'].includes(overallStatus) ? jobCreateCompleteTimestamps : '';
|
|
238
|
+
const suffix = `
|
|
239
|
+
=============================================================
|
|
240
|
+
Status: ${statusMessage}
|
|
241
|
+
Site: ${app.name} (${(0, _format.formatEnvironment)(env.type)})${maybeTimestamps}
|
|
242
|
+
=============================================================
|
|
243
|
+
${maybeExitPrompt}
|
|
244
|
+
`;
|
|
245
|
+
progressTracker.suffix = suffix;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const setSuffixAndPrint = () => {
|
|
249
|
+
setProgressTrackerSuffix();
|
|
250
|
+
progressTracker.print();
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
progressTracker.startPrinting(setSuffixAndPrint);
|
|
254
|
+
|
|
255
|
+
const getResults = () => new Promise((resolve, reject) => {
|
|
256
|
+
const checkStatus = async () => {
|
|
257
|
+
var _importJob$progress$s, _importJob$progress, _importJob$progress$s2, _importJob$progress2;
|
|
258
|
+
|
|
259
|
+
let status;
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
status = await getStatus(api, app.id, env.id);
|
|
263
|
+
} catch (error) {
|
|
264
|
+
return reject({
|
|
265
|
+
error
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const {
|
|
270
|
+
importStatus,
|
|
271
|
+
launched
|
|
272
|
+
} = status;
|
|
273
|
+
let {
|
|
274
|
+
importJob
|
|
275
|
+
} = status;
|
|
276
|
+
let jobStatus,
|
|
277
|
+
jobSteps = [];
|
|
278
|
+
|
|
279
|
+
if (env.isK8sResident) {
|
|
280
|
+
// in the future the API may provide this in k8s jobs so account for that.
|
|
281
|
+
// Until then we need to create the importJob from the status object.
|
|
282
|
+
if (!importJob) {
|
|
283
|
+
var _importStatus$progres, _importStatus$progres2;
|
|
284
|
+
|
|
285
|
+
importJob = {};
|
|
286
|
+
const statusSteps = importStatus === null || importStatus === void 0 ? void 0 : (_importStatus$progres = importStatus.progress) === null || _importStatus$progres === void 0 ? void 0 : _importStatus$progres.steps; // if the progress meta isn't filled out yet, wait until it is.
|
|
287
|
+
|
|
288
|
+
if (!statusSteps) {
|
|
289
|
+
return setTimeout(checkStatus, IMPORT_SQL_PROGRESS_POLL_INTERVAL);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
jobSteps = statusSteps.map(step => {
|
|
293
|
+
return {
|
|
294
|
+
id: step.name,
|
|
295
|
+
name: (0, _format.capitalize)(step.name.replace(/_/g, ' ')),
|
|
296
|
+
status: step.result
|
|
297
|
+
};
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
if (statusSteps.some(({
|
|
301
|
+
result
|
|
302
|
+
}) => result === 'failed') && !statusSteps.find(({
|
|
303
|
+
name,
|
|
304
|
+
result
|
|
305
|
+
}) => name === 'restore_db' && !result)) {
|
|
306
|
+
jobStatus = 'error';
|
|
307
|
+
} else if (statusSteps.every(({
|
|
308
|
+
result
|
|
309
|
+
}) => result === 'success')) {
|
|
310
|
+
jobStatus = 'success';
|
|
311
|
+
importJob.completedAt = new Date(Math.max(...statusSteps.map(step => step.finished_at), 0) * 1000).toUTCString();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (importStatus !== null && importStatus !== void 0 && (_importStatus$progres2 = importStatus.progress) !== null && _importStatus$progres2 !== void 0 && _importStatus$progres2.started_at) {
|
|
315
|
+
importJob.createdAt = new Date(importStatus.progress.started_at * 1000).toUTCString();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
importJob.progress = {
|
|
319
|
+
status: jobStatus,
|
|
320
|
+
steps: jobSteps
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
} else if (!importJob) {
|
|
324
|
+
return resolve('No import job found');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
jobStatus = (_importJob$progress$s = (_importJob$progress = importJob.progress) === null || _importJob$progress === void 0 ? void 0 : _importJob$progress.status) !== null && _importJob$progress$s !== void 0 ? _importJob$progress$s : 'unknown';
|
|
328
|
+
jobSteps = (_importJob$progress$s2 = (_importJob$progress2 = importJob.progress) === null || _importJob$progress2 === void 0 ? void 0 : _importJob$progress2.steps) !== null && _importJob$progress$s2 !== void 0 ? _importJob$progress$s2 : [];
|
|
329
|
+
createdAt = importJob.createdAt;
|
|
330
|
+
completedAt = importJob.completedAt;
|
|
331
|
+
const {
|
|
332
|
+
dbOperationInProgress,
|
|
333
|
+
importInProgress,
|
|
334
|
+
progress: importStepProgress
|
|
335
|
+
} = importStatus;
|
|
336
|
+
debug({
|
|
337
|
+
jobStatus,
|
|
338
|
+
completedAt,
|
|
339
|
+
createdAt,
|
|
340
|
+
dbOperationInProgress,
|
|
341
|
+
importInProgress,
|
|
342
|
+
importStepProgress
|
|
343
|
+
});
|
|
344
|
+
let jobCreationTime;
|
|
345
|
+
|
|
346
|
+
try {
|
|
347
|
+
jobCreationTime = new Date(createdAt).getTime();
|
|
348
|
+
} catch (err) {
|
|
349
|
+
debug('Unable to parse createdAt to a Date');
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
let failedImportStep;
|
|
353
|
+
|
|
354
|
+
if (jobCreationTime && (importStepProgress === null || importStepProgress === void 0 ? void 0 : importStepProgress.started_at) * 1000 >= jobCreationTime) {
|
|
355
|
+
// The contents of the `import_progress` meta are pertinent to the most recent import job
|
|
356
|
+
failedImportStep = importStepProgress.steps.find(step => (step === null || step === void 0 ? void 0 : step.result) === 'failed' && 1000 * (step === null || step === void 0 ? void 0 : step.started_at) > new Date(createdAt).getTime());
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (!jobSteps.length) {
|
|
360
|
+
return reject({
|
|
361
|
+
error: 'Could not enumerate the import job steps',
|
|
362
|
+
launched
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (failedImportStep) {
|
|
367
|
+
// The server marks the step as a success as per the host action, demote it to 'failed'
|
|
368
|
+
const _jobSteps = [...jobSteps];
|
|
369
|
+
|
|
370
|
+
const failedJobStepIndex = _jobSteps.findIndex(({
|
|
371
|
+
id
|
|
372
|
+
}) => id === 'import');
|
|
373
|
+
|
|
374
|
+
_jobSteps[failedJobStepIndex] = { ..._jobSteps[failedJobStepIndex],
|
|
375
|
+
status: 'failed'
|
|
376
|
+
};
|
|
377
|
+
progressTracker.setStepsFromServer(_jobSteps);
|
|
378
|
+
overallStatus = 'failed';
|
|
379
|
+
setSuffixAndPrint();
|
|
380
|
+
return reject({
|
|
381
|
+
inImportProgress: true,
|
|
382
|
+
commandOutput: failedImportStep.output,
|
|
383
|
+
error: 'Import step failed',
|
|
384
|
+
stepName: failedImportStep.name,
|
|
385
|
+
errorText: failedImportStep.error,
|
|
386
|
+
launched
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
progressTracker.setStepsFromServer(jobSteps);
|
|
391
|
+
setSuffixAndPrint();
|
|
392
|
+
|
|
393
|
+
if (jobStatus === 'error') {
|
|
394
|
+
return reject({
|
|
395
|
+
error: 'Import job failed',
|
|
396
|
+
steps: jobSteps,
|
|
397
|
+
launched
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (jobStatus !== 'running' && completedAt) {
|
|
402
|
+
return resolve(importJob);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
overallStatus = 'running';
|
|
406
|
+
setTimeout(checkStatus, IMPORT_SQL_PROGRESS_POLL_INTERVAL);
|
|
407
|
+
}; // Kick off the check
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
checkStatus();
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
try {
|
|
414
|
+
const results = await getResults();
|
|
415
|
+
|
|
416
|
+
if (typeof results === 'string') {
|
|
417
|
+
overallStatus = results;
|
|
418
|
+
} else {
|
|
419
|
+
var _results$progress;
|
|
420
|
+
|
|
421
|
+
overallStatus = (results === null || results === void 0 ? void 0 : (_results$progress = results.progress) === null || _results$progress === void 0 ? void 0 : _results$progress.status) || 'unknown'; // This shouldn't be 'unknown'...what should we do here?
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
progressTracker.stopPrinting();
|
|
425
|
+
setProgressTrackerSuffix(); // Print one final time
|
|
426
|
+
|
|
427
|
+
progressTracker.print({
|
|
428
|
+
clearAfter: true
|
|
429
|
+
}); // This type of result is not an importing error. e.g. no import job was found
|
|
430
|
+
|
|
431
|
+
process.exit(0);
|
|
432
|
+
} catch (importFailed) {
|
|
433
|
+
progressTracker.stopPrinting();
|
|
434
|
+
progressTracker.print({
|
|
435
|
+
clearAfter: true
|
|
436
|
+
});
|
|
437
|
+
exit.withError(getErrorMessage(importFailed, importFailed.launched));
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
var _default = {
|
|
442
|
+
importSqlCheckStatus
|
|
443
|
+
};
|
|
444
|
+
exports.default = _default;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.SERVICE = void 0;
|
|
7
|
+
|
|
8
|
+
var _jwtDecode = _interopRequireDefault(require("jwt-decode"));
|
|
9
|
+
|
|
10
|
+
var _uuid2 = require("uuid");
|
|
11
|
+
|
|
12
|
+
var _keychain = _interopRequireDefault(require("./keychain"));
|
|
13
|
+
|
|
14
|
+
var _api = require("./api");
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* External dependencies
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Internal dependencies
|
|
24
|
+
*/
|
|
25
|
+
// Config
|
|
26
|
+
const SERVICE = 'vip-go-cli';
|
|
27
|
+
exports.SERVICE = SERVICE;
|
|
28
|
+
|
|
29
|
+
class Token {
|
|
30
|
+
constructor(token) {
|
|
31
|
+
if (!token) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
token = token.trim();
|
|
36
|
+
|
|
37
|
+
if (!token.length) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const decodedToken = (0, _jwtDecode.default)(token);
|
|
42
|
+
this.raw = token;
|
|
43
|
+
|
|
44
|
+
if (decodedToken.id) {
|
|
45
|
+
this.id = decodedToken.id;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (decodedToken.iat) {
|
|
49
|
+
this.iat = new Date(decodedToken.iat * 1000);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (decodedToken.exp) {
|
|
53
|
+
this.exp = new Date(decodedToken.exp * 1000);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
valid() {
|
|
58
|
+
if (!this.id) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!this.iat) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const now = new Date();
|
|
67
|
+
|
|
68
|
+
if (!this.exp) {
|
|
69
|
+
return now > this.iat;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return now > this.iat && now < this.exp;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
expired() {
|
|
76
|
+
if (!this.exp) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const now = new Date();
|
|
81
|
+
return now > this.exp;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static async uuid() {
|
|
85
|
+
const service = Token.getServiceName('-uuid');
|
|
86
|
+
|
|
87
|
+
let _uuid = await _keychain.default.getPassword(service);
|
|
88
|
+
|
|
89
|
+
if (!_uuid) {
|
|
90
|
+
_uuid = (0, _uuid2.v4)();
|
|
91
|
+
await _keychain.default.setPassword(service, _uuid);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return _uuid;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static async setUuid(_uuid) {
|
|
98
|
+
const service = Token.getServiceName('-uuid');
|
|
99
|
+
await _keychain.default.setPassword(service, _uuid);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static async set(token) {
|
|
103
|
+
const service = Token.getServiceName();
|
|
104
|
+
return _keychain.default.setPassword(service, token);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static async get() {
|
|
108
|
+
const service = Token.getServiceName();
|
|
109
|
+
const token = await _keychain.default.getPassword(service);
|
|
110
|
+
return new Token(token);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static async purge() {
|
|
114
|
+
const service = Token.getServiceName();
|
|
115
|
+
return _keychain.default.deletePassword(service);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static getServiceName(modifier = '') {
|
|
119
|
+
let service = SERVICE;
|
|
120
|
+
|
|
121
|
+
if (_api.PRODUCTION_API_HOST !== _api.API_HOST) {
|
|
122
|
+
const sanitized = _api.API_HOST.replace(/[^a-z0-9]/gi, '-');
|
|
123
|
+
|
|
124
|
+
service = `${SERVICE}:${sanitized}`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return `${service}${modifier}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
exports.default = Token;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.trackEvent = trackEvent;
|
|
7
|
+
exports.aliasUser = aliasUser;
|
|
8
|
+
exports.trackEventWithEnv = trackEventWithEnv;
|
|
9
|
+
|
|
10
|
+
var _index = _interopRequireDefault(require("./analytics/index"));
|
|
11
|
+
|
|
12
|
+
var _tracks = _interopRequireDefault(require("./analytics/clients/tracks"));
|
|
13
|
+
|
|
14
|
+
var _pendo = _interopRequireDefault(require("./analytics/clients/pendo"));
|
|
15
|
+
|
|
16
|
+
var _token = _interopRequireDefault(require("./token"));
|
|
17
|
+
|
|
18
|
+
var _config = _interopRequireDefault(require("../../config/config.json"));
|
|
19
|
+
|
|
20
|
+
var _env = _interopRequireDefault(require("./env"));
|
|
21
|
+
|
|
22
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* External dependencies
|
|
26
|
+
*/
|
|
27
|
+
const debug = require('debug')('@automattic/vip:analytics');
|
|
28
|
+
/**
|
|
29
|
+
* Internal dependencies
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
let analytics = null;
|
|
34
|
+
|
|
35
|
+
async function init() {
|
|
36
|
+
const uuid = await _token.default.uuid();
|
|
37
|
+
const clients = [];
|
|
38
|
+
const tracksUserType = _config.default.tracksUserType;
|
|
39
|
+
const tracksEventPrefix = _config.default.tracksEventPrefix;
|
|
40
|
+
|
|
41
|
+
if (tracksUserType && tracksEventPrefix) {
|
|
42
|
+
clients.push(new _tracks.default(uuid, tracksUserType, tracksEventPrefix, _env.default));
|
|
43
|
+
clients.push(new _pendo.default({
|
|
44
|
+
env: _env.default,
|
|
45
|
+
eventPrefix: tracksEventPrefix,
|
|
46
|
+
userId: uuid
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
analytics = new _index.default({
|
|
51
|
+
clients
|
|
52
|
+
});
|
|
53
|
+
return analytics;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function getInstance() {
|
|
57
|
+
if (analytics) {
|
|
58
|
+
return analytics;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
analytics = await init();
|
|
62
|
+
return analytics;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function trackEvent(...args) {
|
|
66
|
+
try {
|
|
67
|
+
await _token.default.uuid();
|
|
68
|
+
const client = await getInstance();
|
|
69
|
+
return await client.trackEvent(...args);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
debug('trackEvent() failed', err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function aliasUser(vipUserId) {
|
|
76
|
+
try {
|
|
77
|
+
if (vipUserId) {
|
|
78
|
+
await trackEvent('_alias_user', {
|
|
79
|
+
ui: vipUserId,
|
|
80
|
+
_ut: _config.default.tracksUserType,
|
|
81
|
+
anonid: _token.default.uuid()
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
_token.default.setUuid(vipUserId);
|
|
85
|
+
}
|
|
86
|
+
} catch (err) {
|
|
87
|
+
debug('aliasUser() failed', err);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function trackEventWithEnv(appId, envId, eventName, eventProps = {}) {
|
|
92
|
+
return trackEvent(eventName, { ...eventProps,
|
|
93
|
+
app_id: appId,
|
|
94
|
+
env_id: envId
|
|
95
|
+
});
|
|
96
|
+
}
|