@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
|
@@ -5,42 +5,31 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.MULTIPART_THRESHOLD = exports.COMPRESS_THRESHOLD = void 0;
|
|
7
7
|
exports.checkFileAccess = checkFileAccess;
|
|
8
|
-
exports.completeMultipartUpload = completeMultipartUpload;
|
|
9
8
|
exports.detectCompressedMimeType = detectCompressedMimeType;
|
|
10
9
|
exports.getFileMD5Hash = void 0;
|
|
11
10
|
exports.getFileMeta = getFileMeta;
|
|
12
11
|
exports.getFileSize = getFileSize;
|
|
13
|
-
exports.getFileStats = getFileStats;
|
|
14
12
|
exports.getPartBoundaries = getPartBoundaries;
|
|
15
|
-
exports.getSignedUploadRequestData = getSignedUploadRequestData;
|
|
16
|
-
exports.gzipFile = exports.getWorkingTempDir = void 0;
|
|
17
13
|
exports.isFile = isFile;
|
|
18
14
|
exports.unzipFile = void 0;
|
|
19
15
|
exports.uploadImportSqlFileToS3 = uploadImportSqlFileToS3;
|
|
20
|
-
exports.uploadPart = uploadPart;
|
|
21
16
|
exports.uploadParts = uploadParts;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
var _fs = _interopRequireWildcard(require("fs"));
|
|
17
|
+
var _fs = require("fs");
|
|
18
|
+
var _promises = require("node:fs/promises");
|
|
25
19
|
var _os = _interopRequireDefault(require("os"));
|
|
26
20
|
var _path = _interopRequireDefault(require("path"));
|
|
27
21
|
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
|
|
28
22
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
29
23
|
var _zlib = require("zlib");
|
|
30
24
|
var _crypto = require("crypto");
|
|
31
|
-
var
|
|
25
|
+
var _promises2 = require("node:stream/promises");
|
|
32
26
|
var _stream = require("stream");
|
|
33
27
|
var _xml2js = require("xml2js");
|
|
34
28
|
var _debug = _interopRequireDefault(require("debug"));
|
|
35
29
|
var _http = _interopRequireDefault(require("../lib/api/http"));
|
|
36
30
|
var _fileSize = require("../lib/constants/file-size");
|
|
37
31
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
38
|
-
|
|
39
|
-
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; }
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
* @format
|
|
43
|
-
*/
|
|
32
|
+
// @format
|
|
44
33
|
|
|
45
34
|
/**
|
|
46
35
|
* External dependencies
|
|
@@ -65,20 +54,28 @@ const UPLOAD_PART_SIZE = 16 * _fileSize.MB_IN_BYTES;
|
|
|
65
54
|
|
|
66
55
|
// How many parts will upload at the same time
|
|
67
56
|
const MAX_CONCURRENT_PART_UPLOADS = 5;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
57
|
+
|
|
58
|
+
// TODO: Replace with a proper definitions once we convert lib/cli/command.js to TypeScript
|
|
59
|
+
|
|
60
|
+
const getWorkingTempDir = () => (0, _promises.mkdtemp)(_path.default.join(_os.default.tmpdir(), 'vip-client-file-uploader'));
|
|
61
|
+
const getFileMD5Hash = async fileName => {
|
|
62
|
+
const src = (0, _fs.createReadStream)(fileName);
|
|
63
|
+
const dst = (0, _crypto.createHash)('md5');
|
|
64
|
+
try {
|
|
65
|
+
await (0, _promises2.pipeline)(src, dst);
|
|
66
|
+
return dst.digest().toString('hex');
|
|
67
|
+
} catch (err) {
|
|
68
|
+
throw new Error(`could not generate file hash: ${err.message}`);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
80
71
|
exports.getFileMD5Hash = getFileMD5Hash;
|
|
81
|
-
const gzipFile = async (uncompressedFileName, compressedFileName) =>
|
|
72
|
+
const gzipFile = async (uncompressedFileName, compressedFileName) => {
|
|
73
|
+
try {
|
|
74
|
+
await (0, _promises2.pipeline)((0, _fs.createReadStream)(uncompressedFileName), (0, _zlib.createGzip)(), (0, _fs.createWriteStream)(compressedFileName));
|
|
75
|
+
} catch (err) {
|
|
76
|
+
throw new Error(`could not compress file: ${err.message}`);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
82
79
|
|
|
83
80
|
/**
|
|
84
81
|
* Extract a .gz file and save it to a specified location
|
|
@@ -87,11 +84,10 @@ const gzipFile = async (uncompressedFileName, compressedFileName) => new Promise
|
|
|
87
84
|
* @param {string} outputFilename The file where the unzipped data will be written
|
|
88
85
|
* @return {Promise} A promise that resolves when the file is unzipped
|
|
89
86
|
*/
|
|
90
|
-
exports.gzipFile = gzipFile;
|
|
91
87
|
const unzipFile = async (inputFilename, outputFilename) => {
|
|
92
|
-
const source = _fs.
|
|
93
|
-
const destination = _fs.
|
|
94
|
-
await (0,
|
|
88
|
+
const source = (0, _fs.createReadStream)(inputFilename);
|
|
89
|
+
const destination = (0, _fs.createWriteStream)(outputFilename);
|
|
90
|
+
await (0, _promises2.pipeline)(source, (0, _zlib.createGunzip)(), destination);
|
|
95
91
|
};
|
|
96
92
|
exports.unzipFile = unzipFile;
|
|
97
93
|
async function getFileMeta(fileName) {
|
|
@@ -120,7 +116,7 @@ async function uploadImportSqlFileToS3({
|
|
|
120
116
|
try {
|
|
121
117
|
tmpDir = await getWorkingTempDir();
|
|
122
118
|
} catch (err) {
|
|
123
|
-
throw `Unable to create temporary working directory: ${err}
|
|
119
|
+
throw new Error(`Unable to create temporary working directory: ${err.message}`);
|
|
124
120
|
}
|
|
125
121
|
debug(`File ${_chalk.default.cyan(fileMeta.basename)} is ~ ${Math.floor(fileMeta.fileSize / _fileSize.MB_IN_BYTES)} MB\n`);
|
|
126
122
|
|
|
@@ -162,6 +158,11 @@ async function uploadImportSqlFileToS3({
|
|
|
162
158
|
result
|
|
163
159
|
};
|
|
164
160
|
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html#API_CompleteMultipartUpload_Example_3
|
|
164
|
+
*/
|
|
165
|
+
|
|
165
166
|
async function uploadUsingPutObject({
|
|
166
167
|
app,
|
|
167
168
|
env,
|
|
@@ -190,7 +191,7 @@ async function uploadUsingPutObject({
|
|
|
190
191
|
const progressPassThrough = new _stream.PassThrough();
|
|
191
192
|
progressPassThrough.on('data', data => {
|
|
192
193
|
readBytes += data.length;
|
|
193
|
-
const percentage = Math.floor(100 * readBytes / fileSize)
|
|
194
|
+
const percentage = `${Math.floor(100 * readBytes / fileSize)}%`;
|
|
194
195
|
debug(percentage);
|
|
195
196
|
if (typeof progressCallback === 'function') {
|
|
196
197
|
progressCallback(percentage);
|
|
@@ -198,7 +199,7 @@ async function uploadUsingPutObject({
|
|
|
198
199
|
});
|
|
199
200
|
const response = await (0, _nodeFetch.default)(presignedRequest.url, {
|
|
200
201
|
...fetchOptions,
|
|
201
|
-
body: fileContent ? fileContent : _fs.
|
|
202
|
+
body: fileContent ? fileContent : (0, _fs.createReadStream)(fileName).pipe(progressPassThrough)
|
|
202
203
|
});
|
|
203
204
|
if (response.status === 200) {
|
|
204
205
|
return 'ok';
|
|
@@ -214,17 +215,22 @@ async function uploadUsingPutObject({
|
|
|
214
215
|
try {
|
|
215
216
|
parsedResponse = await parser.parseStringPromise(result);
|
|
216
217
|
} catch (err) {
|
|
217
|
-
throw `Invalid response from cloud service. ${err}
|
|
218
|
+
throw new Error(`Invalid response from cloud service. ${err.message}`);
|
|
218
219
|
}
|
|
219
220
|
const {
|
|
220
221
|
Code,
|
|
221
222
|
Message
|
|
222
|
-
} = parsedResponse.Error
|
|
223
|
-
throw `Unable to upload to cloud storage. ${JSON.stringify({
|
|
223
|
+
} = parsedResponse.Error;
|
|
224
|
+
throw new Error(`Unable to upload to cloud storage. ${JSON.stringify({
|
|
224
225
|
Code,
|
|
225
226
|
Message
|
|
226
|
-
})}
|
|
227
|
+
})}`);
|
|
227
228
|
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html#API_CreateMultipartUpload_ResponseSyntax
|
|
232
|
+
*/
|
|
233
|
+
|
|
228
234
|
async function uploadUsingMultipart({
|
|
229
235
|
app,
|
|
230
236
|
env,
|
|
@@ -250,18 +256,18 @@ async function uploadUsingMultipart({
|
|
|
250
256
|
ignoreAttrs: true
|
|
251
257
|
});
|
|
252
258
|
const parsedResponse = await parser.parseStringPromise(multipartUploadResult);
|
|
253
|
-
if (parsedResponse
|
|
259
|
+
if ('Error' in parsedResponse) {
|
|
254
260
|
const {
|
|
255
261
|
Code,
|
|
256
262
|
Message
|
|
257
263
|
} = parsedResponse.Error;
|
|
258
|
-
throw `Unable to create cloud storage object. Error: ${JSON.stringify({
|
|
264
|
+
throw new Error(`Unable to create cloud storage object. Error: ${JSON.stringify({
|
|
259
265
|
Code,
|
|
260
266
|
Message
|
|
261
|
-
})}
|
|
267
|
+
})}`);
|
|
262
268
|
}
|
|
263
|
-
if (!
|
|
264
|
-
throw `Unable to get Upload ID from cloud storage. Error: ${multipartUploadResult}
|
|
269
|
+
if (!('InitiateMultipartUploadResult' in parsedResponse) || !parsedResponse.InitiateMultipartUploadResult.UploadId) {
|
|
270
|
+
throw new Error(`Unable to get Upload ID from cloud storage. Error: ${multipartUploadResult}`);
|
|
265
271
|
}
|
|
266
272
|
const uploadId = parsedResponse.InitiateMultipartUploadResult.UploadId;
|
|
267
273
|
debug({
|
|
@@ -309,54 +315,45 @@ async function getSignedUploadRequestData({
|
|
|
309
315
|
}
|
|
310
316
|
});
|
|
311
317
|
if (response.status !== 200) {
|
|
312
|
-
throw (await response.text()) || response.statusText;
|
|
318
|
+
throw new Error((await response.text()) || response.statusText);
|
|
313
319
|
}
|
|
314
320
|
return response.json();
|
|
315
321
|
}
|
|
316
322
|
async function checkFileAccess(fileName) {
|
|
317
|
-
return
|
|
318
|
-
}
|
|
319
|
-
async function getFileStats(fileName) {
|
|
320
|
-
return _fs.default.promises.stat(fileName);
|
|
323
|
+
return (0, _promises.access)(fileName, _fs.constants.R_OK);
|
|
321
324
|
}
|
|
322
325
|
async function isFile(fileName) {
|
|
323
326
|
try {
|
|
324
|
-
const stats = await
|
|
327
|
+
const stats = await (0, _promises.stat)(fileName);
|
|
325
328
|
return stats.isFile();
|
|
326
329
|
} catch (err) {
|
|
327
|
-
debug(`isFile error: ${err}`);
|
|
330
|
+
debug(`isFile error: ${err.message}`);
|
|
328
331
|
return false;
|
|
329
332
|
}
|
|
330
333
|
}
|
|
331
334
|
async function getFileSize(fileName) {
|
|
332
|
-
const stats = await
|
|
335
|
+
const stats = await (0, _promises.stat)(fileName);
|
|
333
336
|
return stats.size;
|
|
334
337
|
}
|
|
335
338
|
async function detectCompressedMimeType(fileName) {
|
|
336
339
|
const ZIP_MAGIC_NUMBER = '504b0304';
|
|
337
340
|
const GZ_MAGIC_NUMBER = '1f8b';
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
if (GZ_MAGIC_NUMBER === fileHeader.slice(0, GZ_MAGIC_NUMBER.length)) {
|
|
351
|
-
return resolve('application/gzip');
|
|
352
|
-
}
|
|
353
|
-
resolve();
|
|
354
|
-
});
|
|
355
|
-
});
|
|
341
|
+
const file = await (0, _promises.open)(fileName, 'r');
|
|
342
|
+
const {
|
|
343
|
+
buffer
|
|
344
|
+
} = await file.read(Buffer.alloc(4), 0, 4, 0);
|
|
345
|
+
const fileHeader = buffer.toString('hex');
|
|
346
|
+
if (ZIP_MAGIC_NUMBER === fileHeader.slice(0, ZIP_MAGIC_NUMBER.length)) {
|
|
347
|
+
return 'application/zip';
|
|
348
|
+
}
|
|
349
|
+
if (GZ_MAGIC_NUMBER === fileHeader.slice(0, GZ_MAGIC_NUMBER.length)) {
|
|
350
|
+
return 'application/gzip';
|
|
351
|
+
}
|
|
352
|
+
return '';
|
|
356
353
|
}
|
|
357
354
|
function getPartBoundaries(fileSize) {
|
|
358
355
|
if (fileSize < 1) {
|
|
359
|
-
throw 'fileSize must be greater than zero';
|
|
356
|
+
throw new Error('fileSize must be greater than zero');
|
|
360
357
|
}
|
|
361
358
|
const numParts = Math.ceil(fileSize / UPLOAD_PART_SIZE);
|
|
362
359
|
return new Array(numParts).fill(undefined).map((_numPart, index) => {
|
|
@@ -393,7 +390,7 @@ async function uploadParts({
|
|
|
393
390
|
}, 300);
|
|
394
391
|
});
|
|
395
392
|
const updateProgress = () => {
|
|
396
|
-
const percentage = Math.floor(100 * totalBytesRead / fileMeta.fileSize)
|
|
393
|
+
const percentage = `${Math.floor(100 * totalBytesRead / fileMeta.fileSize)}%`;
|
|
397
394
|
if (typeof progressCallback === 'function') {
|
|
398
395
|
progressCallback(percentage);
|
|
399
396
|
}
|
|
@@ -475,7 +472,7 @@ async function uploadPart({
|
|
|
475
472
|
*/
|
|
476
473
|
};
|
|
477
474
|
|
|
478
|
-
fetchOptions.body = _fs.
|
|
475
|
+
fetchOptions.body = (0, _fs.createReadStream)(fileName, {
|
|
479
476
|
start,
|
|
480
477
|
end
|
|
481
478
|
}).pipe(progressPassThrough);
|
|
@@ -493,23 +490,25 @@ async function uploadPart({
|
|
|
493
490
|
ignoreAttrs: true
|
|
494
491
|
});
|
|
495
492
|
const parsed = await parser.parseStringPromise(result);
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
})}`;
|
|
505
|
-
}
|
|
506
|
-
return parsed;
|
|
493
|
+
const {
|
|
494
|
+
Code,
|
|
495
|
+
Message
|
|
496
|
+
} = parsed.Error;
|
|
497
|
+
throw new Error(`Unable to upload file part. Error: ${JSON.stringify({
|
|
498
|
+
Code,
|
|
499
|
+
Message
|
|
500
|
+
})}`);
|
|
507
501
|
};
|
|
508
502
|
return {
|
|
509
503
|
ETag: await doUpload(),
|
|
510
504
|
PartNumber: s3PartNumber
|
|
511
505
|
};
|
|
512
506
|
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html#API_CompleteMultipartUpload_ResponseSyntax
|
|
510
|
+
*/
|
|
511
|
+
|
|
513
512
|
async function completeMultipartUpload({
|
|
514
513
|
app,
|
|
515
514
|
env,
|
|
@@ -546,15 +545,15 @@ async function completeMultipartUpload({
|
|
|
546
545
|
ignoreAttrs: true
|
|
547
546
|
});
|
|
548
547
|
const parsed = await parser.parseStringPromise(result);
|
|
549
|
-
if (parsed
|
|
548
|
+
if ('Error' in parsed) {
|
|
550
549
|
const {
|
|
551
550
|
Code,
|
|
552
551
|
Message
|
|
553
552
|
} = parsed.Error;
|
|
554
|
-
throw `Unable to complete the upload. Error: ${JSON.stringify({
|
|
553
|
+
throw new Error(`Unable to complete the upload. Error: ${JSON.stringify({
|
|
555
554
|
Code,
|
|
556
555
|
Message
|
|
557
|
-
})}
|
|
556
|
+
})}`);
|
|
558
557
|
}
|
|
559
558
|
return parsed;
|
|
560
559
|
}
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.triggerUpdate = exports.promptForUpdate = exports.getUpdateResult = exports.formatSoftwareSettings = exports.appQueryFragments = exports.appQuery = void 0;
|
|
7
|
+
var _promises = require("node:timers/promises");
|
|
7
8
|
var _enquirer = require("enquirer");
|
|
8
9
|
var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
|
|
9
10
|
var _debug = _interopRequireDefault(require("debug"));
|
|
@@ -14,9 +15,11 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
14
15
|
/**
|
|
15
16
|
* External dependencies
|
|
16
17
|
*/
|
|
18
|
+
|
|
17
19
|
/**
|
|
18
20
|
* Internal dependencies
|
|
19
21
|
*/
|
|
22
|
+
|
|
20
23
|
const UPDATE_PROGRESS_POLL_INTERVAL = 5;
|
|
21
24
|
const debug = (0, _debug.default)('@automattic/vip:bin:config-software');
|
|
22
25
|
const appQuery = `
|
|
@@ -182,7 +185,7 @@ const _optionsForVersion = softwareSettings => {
|
|
|
182
185
|
return option;
|
|
183
186
|
});
|
|
184
187
|
};
|
|
185
|
-
const _processComponent =
|
|
188
|
+
const _processComponent = (appTypeId, userProvidedComponent) => {
|
|
186
189
|
const validComponents = [];
|
|
187
190
|
if ((0, _app.isAppWordPress)(appTypeId)) {
|
|
188
191
|
validComponents.push('wordpress', 'php', 'muplugins');
|
|
@@ -193,13 +196,13 @@ const _processComponent = async (appTypeId, userProvidedComponent) => {
|
|
|
193
196
|
if (!validComponents.includes(userProvidedComponent)) {
|
|
194
197
|
throw new _userError.default(`Component ${userProvidedComponent} is not supported. Use one of: ${validComponents.join(',')}`);
|
|
195
198
|
}
|
|
196
|
-
return userProvidedComponent;
|
|
199
|
+
return Promise.resolve(userProvidedComponent);
|
|
197
200
|
}
|
|
198
201
|
if (validComponents.length === 0) {
|
|
199
202
|
throw new _userError.default('No components are supported for this application');
|
|
200
203
|
}
|
|
201
204
|
if (validComponents.length === 1) {
|
|
202
|
-
return validComponents[0];
|
|
205
|
+
return Promise.resolve(validComponents[0]);
|
|
203
206
|
}
|
|
204
207
|
const choices = validComponents.map(item => ({
|
|
205
208
|
message: COMPONENT_NAMES[item],
|
|
@@ -213,14 +216,14 @@ const _processComponent = async (appTypeId, userProvidedComponent) => {
|
|
|
213
216
|
throw new _userError.default('Command cancelled by user.');
|
|
214
217
|
});
|
|
215
218
|
};
|
|
216
|
-
const _processComponentVersion =
|
|
219
|
+
const _processComponentVersion = (softwareSettings, component, userProvidedVersion) => {
|
|
217
220
|
const versionChoices = _optionsForVersion(softwareSettings[component]);
|
|
218
221
|
if (userProvidedVersion) {
|
|
219
222
|
const validValues = versionChoices.map(item => item.value);
|
|
220
223
|
if (!validValues.includes(userProvidedVersion)) {
|
|
221
224
|
throw new _userError.default(`Version ${userProvidedVersion} is not supported for ${COMPONENT_NAMES[component]}. Use one of: ${validValues.join(',')}`);
|
|
222
225
|
}
|
|
223
|
-
return userProvidedVersion;
|
|
226
|
+
return Promise.resolve(userProvidedVersion);
|
|
224
227
|
}
|
|
225
228
|
const versionSelect = new _enquirer.Select({
|
|
226
229
|
message: `Version for ${COMPONENT_NAMES[component]} to upgrade to`,
|
|
@@ -233,7 +236,10 @@ const _processComponentVersion = async (softwareSettings, component, userProvide
|
|
|
233
236
|
const promptForUpdate = async (appTypeId, opts, softwareSettings) => {
|
|
234
237
|
const component = await _processComponent(appTypeId, opts.component);
|
|
235
238
|
const version = await _processComponentVersion(softwareSettings, component, opts.version);
|
|
239
|
+
|
|
240
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
236
241
|
const confirm = opts.force || (await new _enquirer.Confirm({
|
|
242
|
+
// NOSONAR
|
|
237
243
|
message: `Are you sure you want to upgrade ${COMPONENT_NAMES[component]} to ${version}?`
|
|
238
244
|
}).run().catch(() => {
|
|
239
245
|
throw new _userError.default('Command cancelled by user.');
|
|
@@ -257,7 +263,7 @@ const triggerUpdate = async variables => {
|
|
|
257
263
|
};
|
|
258
264
|
exports.triggerUpdate = triggerUpdate;
|
|
259
265
|
const _getLatestJob = async (appId, envId) => {
|
|
260
|
-
var _result$data, _result$data$app;
|
|
266
|
+
var _result$data$app$envi, _result$data$app, _result$data$app$envi2, _result$data$app$envi3;
|
|
261
267
|
const api = await (0, _api.default)();
|
|
262
268
|
const result = await api.query({
|
|
263
269
|
query: updateJobQuery,
|
|
@@ -267,20 +273,20 @@ const _getLatestJob = async (appId, envId) => {
|
|
|
267
273
|
},
|
|
268
274
|
fetchPolicy: 'network-only'
|
|
269
275
|
});
|
|
270
|
-
const jobs = (result === null ||
|
|
276
|
+
const jobs = (_result$data$app$envi = (_result$data$app = result.data.app) === null || _result$data$app === void 0 ? void 0 : (_result$data$app$envi2 = _result$data$app.environments) === null || _result$data$app$envi2 === void 0 ? void 0 : (_result$data$app$envi3 = _result$data$app$envi2[0]) === null || _result$data$app$envi3 === void 0 ? void 0 : _result$data$app$envi3.jobs) !== null && _result$data$app$envi !== void 0 ? _result$data$app$envi : [];
|
|
271
277
|
if (jobs.length) {
|
|
272
|
-
return jobs.reduce((prev, current) => prev.createdAt > current.createdAt ? prev : current);
|
|
278
|
+
return jobs.reduce((prev, current) => ((prev === null || prev === void 0 ? void 0 : prev.createdAt) || '') > ((current === null || current === void 0 ? void 0 : current.createdAt) || '') ? prev : current);
|
|
273
279
|
}
|
|
274
280
|
return null;
|
|
275
281
|
};
|
|
276
282
|
const _getCompletedJob = async (appId, envId) => {
|
|
277
283
|
const latestJob = await _getLatestJob(appId, envId);
|
|
278
284
|
debug('Latest job result:', latestJob);
|
|
279
|
-
if (!latestJob
|
|
285
|
+
if (!(latestJob !== null && latestJob !== void 0 && latestJob.inProgressLock)) {
|
|
280
286
|
return latestJob;
|
|
281
287
|
}
|
|
282
288
|
debug(`Sleep for ${UPDATE_PROGRESS_POLL_INTERVAL} seconds`);
|
|
283
|
-
await
|
|
289
|
+
await (0, _promises.setTimeout)(UPDATE_PROGRESS_POLL_INTERVAL * 1000);
|
|
284
290
|
return _getCompletedJob(appId, envId);
|
|
285
291
|
};
|
|
286
292
|
const getUpdateResult = async (appId, envId) => {
|
|
@@ -290,13 +296,13 @@ const getUpdateResult = async (appId, envId) => {
|
|
|
290
296
|
envId
|
|
291
297
|
});
|
|
292
298
|
const completedJob = await _getCompletedJob(appId, envId);
|
|
293
|
-
const success = !completedJob || (
|
|
299
|
+
const success = !completedJob || ((_completedJob$progres = completedJob.progress) === null || _completedJob$progres === void 0 ? void 0 : _completedJob$progres.status) === 'success';
|
|
294
300
|
if (success) {
|
|
295
301
|
return {
|
|
296
302
|
ok: true
|
|
297
303
|
};
|
|
298
304
|
}
|
|
299
|
-
const failedStep =
|
|
305
|
+
const failedStep = (_completedJob$progres2 = completedJob.progress) === null || _completedJob$progres2 === void 0 ? void 0 : (_completedJob$progres3 = _completedJob$progres2.steps) === null || _completedJob$progres3 === void 0 ? void 0 : _completedJob$progres3.find(step => (step === null || step === void 0 ? void 0 : step.status) === 'failed');
|
|
300
306
|
const error = failedStep ? `Failed during step: ${failedStep.name}` : 'Software update failed';
|
|
301
307
|
return {
|
|
302
308
|
ok: false,
|
|
@@ -307,12 +307,14 @@ async function promptForArguments(preselectedOptions, defaultOptions, suppressPr
|
|
|
307
307
|
xdebug: false,
|
|
308
308
|
xdebugConfig: preselectedOptions.xdebugConfig,
|
|
309
309
|
siteSlug: '',
|
|
310
|
-
mailpit: false
|
|
310
|
+
mailpit: false,
|
|
311
|
+
photon: false
|
|
311
312
|
};
|
|
312
313
|
const promptLabels = {
|
|
313
314
|
xdebug: 'XDebug',
|
|
314
315
|
phpmyadmin: 'phpMyAdmin',
|
|
315
|
-
mailpit: 'Mailpit'
|
|
316
|
+
mailpit: 'Mailpit',
|
|
317
|
+
photon: 'Photon'
|
|
316
318
|
};
|
|
317
319
|
if (!instanceData.mediaRedirectDomain && defaultOptions.mediaRedirectDomain) {
|
|
318
320
|
const mediaRedirectPromptText = `Would you like to redirect to ${defaultOptions.mediaRedirectDomain} for missing media files?`;
|
|
@@ -340,7 +342,7 @@ async function promptForArguments(preselectedOptions, defaultOptions, suppressPr
|
|
|
340
342
|
} else {
|
|
341
343
|
instanceData.elasticsearch = await promptForBoolean('Enable Elasticsearch (needed by Enterprise Search)?', !!defaultOptions.elasticsearch);
|
|
342
344
|
}
|
|
343
|
-
for (const service of ['phpmyadmin', 'xdebug', 'mailpit']) {
|
|
345
|
+
for (const service of ['phpmyadmin', 'xdebug', 'mailpit', 'photon']) {
|
|
344
346
|
if (service in instanceData) {
|
|
345
347
|
if (service in preselectedOptions) {
|
|
346
348
|
instanceData[service] = preselectedOptions[service];
|
|
@@ -636,7 +638,7 @@ function processVersionOption(value) {
|
|
|
636
638
|
}
|
|
637
639
|
function addDevEnvConfigurationOptions(command) {
|
|
638
640
|
// We leave the third parameter to undefined on some because the defaults are handled in preProcessInstanceData()
|
|
639
|
-
return command.option('wordpress', 'Use a specific WordPress version', undefined, processVersionOption).option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('app-code', 'Use the application code from a local directory or use "demo" for VIP skeleton code').option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, processBooleanOption).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, processBooleanOption).option('xdebug_config', 'Extra configuration to pass to xdebug via XDEBUG_CONFIG environment variable').option('elasticsearch', 'Enable Elasticsearch (needed by Enterprise Search)', undefined, processBooleanOption).option(['r', 'media-redirect-domain'], 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.').option('php', 'Explicitly choose PHP version to use', undefined, processVersionOption).option(['G', 'mailhog'], 'Enable Mailpit. By default it is disabled (deprecated option, please use --mailpit instead)', undefined, processBooleanOption).option(['A', 'mailpit'], 'Enable Mailpit. By default it is disabled', undefined, processBooleanOption);
|
|
641
|
+
return command.option('wordpress', 'Use a specific WordPress version', undefined, processVersionOption).option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('app-code', 'Use the application code from a local directory or use "demo" for VIP skeleton code').option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, processBooleanOption).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, processBooleanOption).option('xdebug_config', 'Extra configuration to pass to xdebug via XDEBUG_CONFIG environment variable').option('elasticsearch', 'Enable Elasticsearch (needed by Enterprise Search)', undefined, processBooleanOption).option(['r', 'media-redirect-domain'], 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.').option('php', 'Explicitly choose PHP version to use', undefined, processVersionOption).option(['G', 'mailhog'], 'Enable Mailpit. By default it is disabled (deprecated option, please use --mailpit instead)', undefined, processBooleanOption).option(['A', 'mailpit'], 'Enable Mailpit. By default it is disabled', undefined, processBooleanOption).option(['H', 'photon'], 'Enable Photon. By default it is disabled', undefined, processBooleanOption);
|
|
640
642
|
}
|
|
641
643
|
|
|
642
644
|
/**
|
|
@@ -94,7 +94,8 @@ async function sanitizeConfiguration(configuration) {
|
|
|
94
94
|
phpmyadmin: stringToBooleanIfDefined(configuration.phpmyadmin),
|
|
95
95
|
xdebug: stringToBooleanIfDefined(configuration.xdebug),
|
|
96
96
|
mailpit: stringToBooleanIfDefined((_configuration$mailpi = configuration.mailpit) !== null && _configuration$mailpi !== void 0 ? _configuration$mailpi : configuration.mailhog),
|
|
97
|
-
'media-redirect-domain': configuration['media-redirect-domain']
|
|
97
|
+
'media-redirect-domain': configuration['media-redirect-domain'],
|
|
98
|
+
photon: stringToBooleanIfDefined(configuration.photon)
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
// Remove undefined values
|
|
@@ -119,7 +120,8 @@ function mergeConfigurationFileOptions(preselectedOptions, configurationFileOpti
|
|
|
119
120
|
xdebug: configurationFileOptions.xdebug,
|
|
120
121
|
xdebugConfig: configurationFileOptions['xdebug-config'],
|
|
121
122
|
mailpit: (_configurationFileOpt = configurationFileOptions.mailpit) !== null && _configurationFileOpt !== void 0 ? _configurationFileOpt : configurationFileOptions.mailhog,
|
|
122
|
-
mediaRedirectDomain: configurationFileOptions['media-redirect-domain']
|
|
123
|
+
mediaRedirectDomain: configurationFileOptions['media-redirect-domain'],
|
|
124
|
+
photon: configurationFileOptions.photon
|
|
123
125
|
};
|
|
124
126
|
const mergedOptions = {};
|
|
125
127
|
Object.keys(configurationFileInstanceOptions).forEach(key => {
|
|
@@ -146,6 +146,9 @@ function preProcessInstanceData(instanceData) {
|
|
|
146
146
|
if (!newInstanceData.phpmyadmin) {
|
|
147
147
|
newInstanceData.phpmyadmin = false;
|
|
148
148
|
}
|
|
149
|
+
if (!newInstanceData.photon) {
|
|
150
|
+
newInstanceData.photon = false;
|
|
151
|
+
}
|
|
149
152
|
|
|
150
153
|
// Mailpit migration
|
|
151
154
|
if (!newInstanceData.mailpit) {
|
package/dist/lib/env.js
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
var
|
|
7
|
+
var _nodeOs = require("node:os");
|
|
8
8
|
var _package = _interopRequireDefault(require("../../package.json"));
|
|
9
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
10
|
/**
|
|
@@ -15,19 +15,22 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
15
15
|
* Internal dependencies
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
const app = {
|
|
19
|
+
name: _package.default.name,
|
|
20
|
+
version: _package.default.version
|
|
21
|
+
};
|
|
22
|
+
const os = {
|
|
23
|
+
name: (0, _nodeOs.platform)(),
|
|
24
|
+
version: (0, _nodeOs.release)()
|
|
25
|
+
};
|
|
26
|
+
const node = {
|
|
27
|
+
version: process.version
|
|
28
|
+
};
|
|
18
29
|
const env = {
|
|
19
|
-
app
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
os: {
|
|
24
|
-
name: _os.default.platform(),
|
|
25
|
-
version: _os.default.release()
|
|
26
|
-
},
|
|
27
|
-
node: {
|
|
28
|
-
version: process.version
|
|
29
|
-
}
|
|
30
|
+
app,
|
|
31
|
+
os,
|
|
32
|
+
node,
|
|
33
|
+
userAgent: `vip-cli/${app.version} (node/${node.version}; ${os.name}/${os.version}; +https://wpvip.com)`
|
|
30
34
|
};
|
|
31
|
-
env.userAgent = `vip-cli/${_package.default.version} (node/${env.node.version}; ${env.os.name}/${env.os.version}; +https://wpvip.com)`;
|
|
32
35
|
var _default = env;
|
|
33
36
|
exports.default = _default;
|
|
@@ -10,9 +10,11 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
10
10
|
/**
|
|
11
11
|
* External dependencies
|
|
12
12
|
*/
|
|
13
|
+
|
|
13
14
|
/**
|
|
14
15
|
* Internal dependencies
|
|
15
16
|
*/
|
|
17
|
+
|
|
16
18
|
const mutation = (0, _graphqlTag.default)`
|
|
17
19
|
mutation DeleteEnvironmentVariable(
|
|
18
20
|
$appId: Int!
|
|
@@ -10,9 +10,11 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
10
10
|
/**
|
|
11
11
|
* External dependencies
|
|
12
12
|
*/
|
|
13
|
+
|
|
13
14
|
/**
|
|
14
15
|
* Internal dependencies
|
|
15
16
|
*/
|
|
17
|
+
|
|
16
18
|
const query = (0, _graphqlTag.default)`
|
|
17
19
|
query GetEnvironmentVariablesWithValues(
|
|
18
20
|
$appId: Int!
|
|
@@ -38,6 +40,7 @@ const query = (0, _graphqlTag.default)`
|
|
|
38
40
|
}
|
|
39
41
|
`;
|
|
40
42
|
async function getEnvVars(appId, envId) {
|
|
43
|
+
var _ref, _data$app, _data$app$environment, _data$app$environment2, _data$app$environment3;
|
|
41
44
|
const api = await (0, _api.default)();
|
|
42
45
|
const variables = {
|
|
43
46
|
appId,
|
|
@@ -49,5 +52,5 @@ async function getEnvVars(appId, envId) {
|
|
|
49
52
|
query,
|
|
50
53
|
variables
|
|
51
54
|
});
|
|
52
|
-
return data.app.environments[0].environmentVariables.nodes;
|
|
55
|
+
return (_ref = (_data$app = data.app) === null || _data$app === void 0 ? void 0 : (_data$app$environment = _data$app.environments) === null || _data$app$environment === void 0 ? void 0 : (_data$app$environment2 = _data$app$environment[0]) === null || _data$app$environment2 === void 0 ? void 0 : (_data$app$environment3 = _data$app$environment2.environmentVariables) === null || _data$app$environment3 === void 0 ? void 0 : _data$app$environment3.nodes) !== null && _ref !== void 0 ? _ref : null;
|
|
53
56
|
}
|
|
@@ -9,12 +9,14 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
9
9
|
/**
|
|
10
10
|
* External dependencies
|
|
11
11
|
*/
|
|
12
|
+
|
|
12
13
|
/**
|
|
13
14
|
* Internal dependencies
|
|
14
15
|
*/
|
|
16
|
+
|
|
15
17
|
async function getEnvVar(appId, envId, name) {
|
|
16
18
|
const envvars = await (0, _apiGetAll.default)(appId, envId);
|
|
17
|
-
return envvars.find(({
|
|
19
|
+
return envvars === null || envvars === void 0 ? void 0 : envvars.find(({
|
|
18
20
|
name: foundName
|
|
19
21
|
}) => name === foundName);
|
|
20
22
|
}
|