@automattic/vip 4.0.6 → 4.0.8
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/dist/lib/client-file-uploader.js +52 -10
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -43,6 +43,45 @@ function parseEtagHeader(etag) {
|
|
|
43
43
|
}
|
|
44
44
|
return normalizedEtag.replace(/^"(.*)"$/u, '$1');
|
|
45
45
|
}
|
|
46
|
+
const isStreamBody = body => typeof body?.pipe === 'function';
|
|
47
|
+
function createProgressTransform(onChunk) {
|
|
48
|
+
return new _stream.Transform({
|
|
49
|
+
transform(chunk, _encoding, callback) {
|
|
50
|
+
onChunk(chunk);
|
|
51
|
+
callback(null, chunk);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function omitUnsupportedFetchHeaders(init) {
|
|
56
|
+
if (!init.headers) {
|
|
57
|
+
return init;
|
|
58
|
+
}
|
|
59
|
+
const headers = new _undici.Headers(init.headers);
|
|
60
|
+
headers.delete('expect');
|
|
61
|
+
return {
|
|
62
|
+
...init,
|
|
63
|
+
headers
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function withCauseMessage(err) {
|
|
67
|
+
if (!(err instanceof Error)) {
|
|
68
|
+
return err;
|
|
69
|
+
}
|
|
70
|
+
const cause = err.cause;
|
|
71
|
+
let causeMessage;
|
|
72
|
+
if (cause instanceof Error) {
|
|
73
|
+
causeMessage = cause.message;
|
|
74
|
+
} else if (typeof cause === 'string') {
|
|
75
|
+
causeMessage = cause;
|
|
76
|
+
}
|
|
77
|
+
if (!causeMessage || err.message.includes(causeMessage)) {
|
|
78
|
+
return err;
|
|
79
|
+
}
|
|
80
|
+
return new Error(`${err.message}: ${causeMessage}`, {
|
|
81
|
+
cause: err
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
46
85
|
/**
|
|
47
86
|
* Wraps `fetch` with exponential-backoff retries.
|
|
48
87
|
*
|
|
@@ -58,20 +97,25 @@ function parseEtagHeader(etag) {
|
|
|
58
97
|
* once so the underlying error surfaces instead of the misleading undici one.
|
|
59
98
|
*/
|
|
60
99
|
async function fetchWithRetry(input, init = {}, retries = 3, createBody) {
|
|
61
|
-
const bodyIsStream =
|
|
100
|
+
const bodyIsStream = isStreamBody(init.body);
|
|
62
101
|
// Only retry when we can hand `fetch` a fresh, replayable body each attempt.
|
|
63
102
|
const maxAttempts = createBody || !bodyIsStream ? retries : 0;
|
|
64
103
|
for (let attempt = 0; attempt <= maxAttempts; attempt++) {
|
|
65
104
|
const requestInit = createBody ? {
|
|
66
105
|
...init,
|
|
67
106
|
body: createBody()
|
|
68
|
-
} :
|
|
107
|
+
} : {
|
|
108
|
+
...init
|
|
109
|
+
};
|
|
110
|
+
if (isStreamBody(requestInit.body) && !requestInit.duplex) {
|
|
111
|
+
requestInit.duplex = 'half';
|
|
112
|
+
}
|
|
69
113
|
try {
|
|
70
114
|
// eslint-disable-next-line no-await-in-loop
|
|
71
|
-
return await (0, _undici.fetch)(input, requestInit);
|
|
115
|
+
return await (0, _undici.fetch)(input, omitUnsupportedFetchHeaders(requestInit));
|
|
72
116
|
} catch (err) {
|
|
73
117
|
if (attempt === maxAttempts) {
|
|
74
|
-
throw err;
|
|
118
|
+
throw withCauseMessage(err);
|
|
75
119
|
}
|
|
76
120
|
// eslint-disable-next-line no-await-in-loop
|
|
77
121
|
await (0, _promises3.setTimeout)(Math.pow(2, attempt) * 1000); // 1000, 2000, 4000
|
|
@@ -253,8 +297,7 @@ async function uploadUsingPutObject({
|
|
|
253
297
|
return fileContent;
|
|
254
298
|
}
|
|
255
299
|
let readBytes = 0;
|
|
256
|
-
const
|
|
257
|
-
progressPassThrough.on('data', data => {
|
|
300
|
+
const progressTransform = createProgressTransform(data => {
|
|
258
301
|
readBytes += data.length;
|
|
259
302
|
const percentage = `${Math.floor(100 * readBytes / fileSize)}%`;
|
|
260
303
|
debug(percentage);
|
|
@@ -262,7 +305,7 @@ async function uploadUsingPutObject({
|
|
|
262
305
|
progressCallback(percentage);
|
|
263
306
|
}
|
|
264
307
|
});
|
|
265
|
-
return (0, _fs.createReadStream)(fileName).pipe(
|
|
308
|
+
return (0, _fs.createReadStream)(fileName).pipe(progressTransform);
|
|
266
309
|
};
|
|
267
310
|
const response = await fetchWithRetry(presignedRequest.url, fetchOptions, 3, createBody);
|
|
268
311
|
if (response.status === 200) {
|
|
@@ -500,15 +543,14 @@ async function uploadParts({
|
|
|
500
543
|
const createBody = () => {
|
|
501
544
|
partBytesRead[index] = 0;
|
|
502
545
|
partPercentages[index] = 0;
|
|
503
|
-
const
|
|
504
|
-
progressPassThrough.on('data', data => {
|
|
546
|
+
const progressTransform = createProgressTransform(data => {
|
|
505
547
|
partBytesRead[index] += data.length;
|
|
506
548
|
partPercentages[index] = Math.floor(100 * partBytesRead[index] / partSize);
|
|
507
549
|
});
|
|
508
550
|
return (0, _fs.createReadStream)(fileMeta.fileName, {
|
|
509
551
|
start,
|
|
510
552
|
end
|
|
511
|
-
}).pipe(
|
|
553
|
+
}).pipe(progressTransform);
|
|
512
554
|
};
|
|
513
555
|
await readyForPartUpload();
|
|
514
556
|
const uploadResult = await uploadPart({
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.8",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@automattic/vip",
|
|
9
|
-
"version": "4.0.
|
|
9
|
+
"version": "4.0.8",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|