partial-uploader 0.0.7 → 0.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/index.d.ts +4 -1
- package/dist/index.js +19 -3
- package/dist/index.test.js +44 -28
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,10 @@ type RefreshResult = {
|
|
|
5
5
|
type UnauthorizedCallback = (error: Response) => Promise<RefreshResult | null>;
|
|
6
6
|
declare const uploadWithPartialFile: (url: string, file: any, headers?: any, chunkSize?: number, delay_number?: number, concurrency?: number, onUnauthorized?: UnauthorizedCallback) => Promise<{
|
|
7
7
|
success: boolean;
|
|
8
|
-
id: string;
|
|
9
8
|
message: string;
|
|
9
|
+
statusCode: number;
|
|
10
|
+
data?: {
|
|
11
|
+
id: string;
|
|
12
|
+
};
|
|
10
13
|
}>;
|
|
11
14
|
export { uploadWithPartialFile };
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,7 @@ var uploadWithPartialFile = function (url, file, headers, chunkSize, delay_numbe
|
|
|
54
54
|
if (delay_number === void 0) { delay_number = 50; }
|
|
55
55
|
if (concurrency === void 0) { concurrency = 1; }
|
|
56
56
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
57
|
-
var sharedContext, id, fileName, totalSize, totalChunks, uploadChunk, queue_1, workers, e_1;
|
|
57
|
+
var sharedContext, id, fileName, totalSize, totalChunks, lastStatusCode, uploadChunk, queue_1, workers, e_1;
|
|
58
58
|
return __generator(this, function (_a) {
|
|
59
59
|
switch (_a.label) {
|
|
60
60
|
case 0:
|
|
@@ -69,6 +69,7 @@ var uploadWithPartialFile = function (url, file, headers, chunkSize, delay_numbe
|
|
|
69
69
|
fileName = file.name || 'file';
|
|
70
70
|
totalSize = file.size;
|
|
71
71
|
totalChunks = Math.ceil(totalSize / chunkSize) || 1;
|
|
72
|
+
lastStatusCode = 200;
|
|
72
73
|
uploadChunk = function (index) { return __awaiter(void 0, void 0, void 0, function () {
|
|
73
74
|
var start, end, chunk, retry, formData, res, refreshData, e_2;
|
|
74
75
|
return __generator(this, function (_a) {
|
|
@@ -99,6 +100,7 @@ var uploadWithPartialFile = function (url, file, headers, chunkSize, delay_numbe
|
|
|
99
100
|
})];
|
|
100
101
|
case 3:
|
|
101
102
|
res = _a.sent();
|
|
103
|
+
lastStatusCode = res.status;
|
|
102
104
|
if (!(res.status === 401 && onUnauthorized)) return [3 /*break*/, 5];
|
|
103
105
|
return [4 /*yield*/, onUnauthorized(res)];
|
|
104
106
|
case 4:
|
|
@@ -168,10 +170,24 @@ var uploadWithPartialFile = function (url, file, headers, chunkSize, delay_numbe
|
|
|
168
170
|
return [4 /*yield*/, Promise.all(workers)];
|
|
169
171
|
case 3:
|
|
170
172
|
_a.sent();
|
|
171
|
-
return [2 /*return*/, {
|
|
173
|
+
return [2 /*return*/, {
|
|
174
|
+
success: true,
|
|
175
|
+
message: "file uploaded successfully",
|
|
176
|
+
statusCode: lastStatusCode,
|
|
177
|
+
data: {
|
|
178
|
+
id: id
|
|
179
|
+
}
|
|
180
|
+
}];
|
|
172
181
|
case 4:
|
|
173
182
|
e_1 = _a.sent();
|
|
174
|
-
return [2 /*return*/, {
|
|
183
|
+
return [2 /*return*/, {
|
|
184
|
+
success: false,
|
|
185
|
+
message: e_1.message || "file could not be loaded",
|
|
186
|
+
statusCode: lastStatusCode,
|
|
187
|
+
data: {
|
|
188
|
+
id: id
|
|
189
|
+
}
|
|
190
|
+
}];
|
|
175
191
|
case 5: return [2 /*return*/];
|
|
176
192
|
}
|
|
177
193
|
});
|
package/dist/index.test.js
CHANGED
|
@@ -48,9 +48,9 @@ var index_1 = require("./index");
|
|
|
48
48
|
});
|
|
49
49
|
(0, vitest_1.it)('should upload a small file in a single chunk successfully', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
50
50
|
var resultPromise, result, formData;
|
|
51
|
-
var _a;
|
|
52
|
-
return __generator(this, function (
|
|
53
|
-
switch (
|
|
51
|
+
var _a, _b;
|
|
52
|
+
return __generator(this, function (_c) {
|
|
53
|
+
switch (_c.label) {
|
|
54
54
|
case 0:
|
|
55
55
|
fetch.mockResolvedValue({
|
|
56
56
|
ok: true,
|
|
@@ -61,13 +61,15 @@ var index_1 = require("./index");
|
|
|
61
61
|
return [4 /*yield*/, vitest_1.vi.runAllTimersAsync()];
|
|
62
62
|
case 1:
|
|
63
63
|
// Fast-forward any delays
|
|
64
|
-
|
|
64
|
+
_c.sent();
|
|
65
65
|
return [4 /*yield*/, resultPromise];
|
|
66
66
|
case 2:
|
|
67
|
-
result =
|
|
67
|
+
result = _c.sent();
|
|
68
68
|
(0, vitest_1.expect)(result.success).toBe(true);
|
|
69
|
+
(0, vitest_1.expect)(result.statusCode).toBe(200);
|
|
70
|
+
(0, vitest_1.expect)((_a = result.data) === null || _a === void 0 ? void 0 : _a.id).toBeDefined();
|
|
69
71
|
(0, vitest_1.expect)(fetch).toHaveBeenCalledTimes(1);
|
|
70
|
-
formData = (
|
|
72
|
+
formData = (_b = vitest_1.vi.mocked(fetch).mock.calls[0][1]) === null || _b === void 0 ? void 0 : _b.body;
|
|
71
73
|
(0, vitest_1.expect)(formData.get('isDone')).toBe('true');
|
|
72
74
|
(0, vitest_1.expect)(formData.get('totalChunks')).toBe('1');
|
|
73
75
|
return [2 /*return*/];
|
|
@@ -76,8 +78,9 @@ var index_1 = require("./index");
|
|
|
76
78
|
}); });
|
|
77
79
|
(0, vitest_1.it)('should upload a large file in multiple chunks', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
78
80
|
var largeFile, resultPromise, result;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
var _a;
|
|
82
|
+
return __generator(this, function (_b) {
|
|
83
|
+
switch (_b.label) {
|
|
81
84
|
case 0:
|
|
82
85
|
fetch.mockResolvedValue({
|
|
83
86
|
ok: true,
|
|
@@ -87,11 +90,13 @@ var index_1 = require("./index");
|
|
|
87
90
|
resultPromise = (0, index_1.uploadWithPartialFile)(mockUrl, largeFile, {}, 5, 0, 1);
|
|
88
91
|
return [4 /*yield*/, vitest_1.vi.runAllTimersAsync()];
|
|
89
92
|
case 1:
|
|
90
|
-
|
|
93
|
+
_b.sent();
|
|
91
94
|
return [4 /*yield*/, resultPromise];
|
|
92
95
|
case 2:
|
|
93
|
-
result =
|
|
96
|
+
result = _b.sent();
|
|
94
97
|
(0, vitest_1.expect)(result.success).toBe(true);
|
|
98
|
+
(0, vitest_1.expect)(result.statusCode).toBe(200);
|
|
99
|
+
(0, vitest_1.expect)((_a = result.data) === null || _a === void 0 ? void 0 : _a.id).toBeDefined();
|
|
95
100
|
(0, vitest_1.expect)(fetch).toHaveBeenCalledTimes(3);
|
|
96
101
|
return [2 /*return*/];
|
|
97
102
|
}
|
|
@@ -99,8 +104,9 @@ var index_1 = require("./index");
|
|
|
99
104
|
}); });
|
|
100
105
|
(0, vitest_1.it)('should retry on network error and succeed', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
101
106
|
var resultPromise, result;
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
var _a;
|
|
108
|
+
return __generator(this, function (_b) {
|
|
109
|
+
switch (_b.label) {
|
|
104
110
|
case 0:
|
|
105
111
|
fetch
|
|
106
112
|
.mockRejectedValueOnce(new Error('Network error'))
|
|
@@ -110,11 +116,13 @@ var index_1 = require("./index");
|
|
|
110
116
|
return [4 /*yield*/, vitest_1.vi.runAllTimersAsync()];
|
|
111
117
|
case 1:
|
|
112
118
|
// First attempt fails, wait for delay
|
|
113
|
-
|
|
119
|
+
_b.sent();
|
|
114
120
|
return [4 /*yield*/, resultPromise];
|
|
115
121
|
case 2:
|
|
116
|
-
result =
|
|
122
|
+
result = _b.sent();
|
|
117
123
|
(0, vitest_1.expect)(result.success).toBe(true);
|
|
124
|
+
(0, vitest_1.expect)(result.statusCode).toBe(200);
|
|
125
|
+
(0, vitest_1.expect)((_a = result.data) === null || _a === void 0 ? void 0 : _a.id).toBeDefined();
|
|
118
126
|
(0, vitest_1.expect)(fetch).toHaveBeenCalledTimes(2);
|
|
119
127
|
return [2 /*return*/];
|
|
120
128
|
}
|
|
@@ -122,9 +130,9 @@ var index_1 = require("./index");
|
|
|
122
130
|
}); });
|
|
123
131
|
(0, vitest_1.it)('should refresh token on 401 and retry successfully', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
124
132
|
var onUnauthorized, resultPromise, result, secondCallHeaders;
|
|
125
|
-
var _a;
|
|
126
|
-
return __generator(this, function (
|
|
127
|
-
switch (
|
|
133
|
+
var _a, _b;
|
|
134
|
+
return __generator(this, function (_c) {
|
|
135
|
+
switch (_c.label) {
|
|
128
136
|
case 0:
|
|
129
137
|
fetch
|
|
130
138
|
.mockResolvedValueOnce({ ok: false, status: 401 }) // First attempt: 401
|
|
@@ -135,14 +143,16 @@ var index_1 = require("./index");
|
|
|
135
143
|
resultPromise = (0, index_1.uploadWithPartialFile)(mockUrl, mockFile, { 'Authorization': 'Bearer old' }, 1024, 0, 1, onUnauthorized);
|
|
136
144
|
return [4 /*yield*/, vitest_1.vi.runAllTimersAsync()];
|
|
137
145
|
case 1:
|
|
138
|
-
|
|
146
|
+
_c.sent();
|
|
139
147
|
return [4 /*yield*/, resultPromise];
|
|
140
148
|
case 2:
|
|
141
|
-
result =
|
|
149
|
+
result = _c.sent();
|
|
142
150
|
(0, vitest_1.expect)(onUnauthorized).toHaveBeenCalled();
|
|
143
151
|
(0, vitest_1.expect)(result.success).toBe(true);
|
|
152
|
+
(0, vitest_1.expect)(result.statusCode).toBe(200);
|
|
153
|
+
(0, vitest_1.expect)((_a = result.data) === null || _a === void 0 ? void 0 : _a.id).toBeDefined();
|
|
144
154
|
(0, vitest_1.expect)(fetch).toHaveBeenCalledTimes(2);
|
|
145
|
-
secondCallHeaders = (
|
|
155
|
+
secondCallHeaders = (_b = vitest_1.vi.mocked(fetch).mock.calls[1][1]) === null || _b === void 0 ? void 0 : _b.headers;
|
|
146
156
|
(0, vitest_1.expect)(secondCallHeaders['Authorization']).toBe('Bearer new-token');
|
|
147
157
|
return [2 /*return*/];
|
|
148
158
|
}
|
|
@@ -150,18 +160,21 @@ var index_1 = require("./index");
|
|
|
150
160
|
}); });
|
|
151
161
|
(0, vitest_1.it)('should fail after maximum retries', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
152
162
|
var resultPromise, result;
|
|
153
|
-
|
|
154
|
-
|
|
163
|
+
var _a;
|
|
164
|
+
return __generator(this, function (_b) {
|
|
165
|
+
switch (_b.label) {
|
|
155
166
|
case 0:
|
|
156
167
|
fetch.mockRejectedValue(new Error('Persistent error'));
|
|
157
168
|
resultPromise = (0, index_1.uploadWithPartialFile)(mockUrl, mockFile, {}, 1024, 0);
|
|
158
169
|
return [4 /*yield*/, vitest_1.vi.runAllTimersAsync()];
|
|
159
170
|
case 1:
|
|
160
|
-
|
|
171
|
+
_b.sent();
|
|
161
172
|
return [4 /*yield*/, resultPromise];
|
|
162
173
|
case 2:
|
|
163
|
-
result =
|
|
174
|
+
result = _b.sent();
|
|
164
175
|
(0, vitest_1.expect)(result.success).toBe(false);
|
|
176
|
+
(0, vitest_1.expect)(result.statusCode).toBe(200); // defaults to 200 if fetch throws before any response
|
|
177
|
+
(0, vitest_1.expect)((_a = result.data) === null || _a === void 0 ? void 0 : _a.id).toBeDefined();
|
|
165
178
|
(0, vitest_1.expect)(fetch).toHaveBeenCalledTimes(3); // Retry limit is 3 in code
|
|
166
179
|
return [2 /*return*/];
|
|
167
180
|
}
|
|
@@ -169,19 +182,22 @@ var index_1 = require("./index");
|
|
|
169
182
|
}); });
|
|
170
183
|
(0, vitest_1.it)('should handle concurrency correctly', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
171
184
|
var largeFile, resultPromise, result;
|
|
172
|
-
|
|
173
|
-
|
|
185
|
+
var _a;
|
|
186
|
+
return __generator(this, function (_b) {
|
|
187
|
+
switch (_b.label) {
|
|
174
188
|
case 0:
|
|
175
189
|
fetch.mockResolvedValue({ ok: true, status: 200 });
|
|
176
190
|
largeFile = new File(['a'.repeat(100)], 'concurrency.txt');
|
|
177
191
|
resultPromise = (0, index_1.uploadWithPartialFile)(mockUrl, largeFile, {}, 10, 0, 5);
|
|
178
192
|
return [4 /*yield*/, vitest_1.vi.runAllTimersAsync()];
|
|
179
193
|
case 1:
|
|
180
|
-
|
|
194
|
+
_b.sent();
|
|
181
195
|
return [4 /*yield*/, resultPromise];
|
|
182
196
|
case 2:
|
|
183
|
-
result =
|
|
197
|
+
result = _b.sent();
|
|
184
198
|
(0, vitest_1.expect)(result.success).toBe(true);
|
|
199
|
+
(0, vitest_1.expect)(result.statusCode).toBe(200);
|
|
200
|
+
(0, vitest_1.expect)((_a = result.data) === null || _a === void 0 ? void 0 : _a.id).toBeDefined();
|
|
185
201
|
(0, vitest_1.expect)(fetch).toHaveBeenCalledTimes(10);
|
|
186
202
|
return [2 /*return*/];
|
|
187
203
|
}
|