@uploadista/client-core 0.0.20 → 0.1.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/dist/index.d.mts +9 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/src/auth/__tests__/auth-http-client.test.ts +55 -8
- package/src/auth/__tests__/direct-auth.test.ts +50 -10
- package/src/auth/__tests__/uploadista-cloud-auth.test.ts +102 -19
- package/src/client/create-uploadista-client.ts +0 -1
- package/src/managers/__tests__/upload-manager.test.ts +1 -1
- package/src/types/previous-upload.ts +18 -5
- package/src/upload/flow-upload-orchestrator.ts +0 -3
- package/src/upload/single-upload.ts +1 -1
- package/src/upload/upload-storage.ts +2 -1
- package/src/utils/__tests__/flow-inputs-builder.test.ts +10 -7
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uploadista/client-core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"description": "Platform-agnostic core upload client logic for Uploadista",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Uploadista",
|
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"js-base64": "3.7.8",
|
|
36
|
-
"@uploadista/core": "0.0
|
|
36
|
+
"@uploadista/core": "0.1.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"zod": "^4.0.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"tsdown": "0.
|
|
43
|
-
"vitest": "4.0.
|
|
44
|
-
"zod": "4.
|
|
45
|
-
"@uploadista/typescript-config": "0.0
|
|
42
|
+
"tsdown": "0.19.0",
|
|
43
|
+
"vitest": "4.0.17",
|
|
44
|
+
"zod": "4.3.5",
|
|
45
|
+
"@uploadista/typescript-config": "0.1.0"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsc --noEmit && tsdown",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import
|
|
2
|
+
import { createLogger } from "../../logger";
|
|
3
|
+
import type { HttpClient, HttpResponse } from "../../services";
|
|
4
|
+
import { MockPlatformService } from "../../testing/mock-service-container";
|
|
3
5
|
import { AuthHttpClient } from "../auth-http-client";
|
|
4
6
|
import { DirectAuthManager } from "../direct-auth";
|
|
5
7
|
import { NoAuthManager } from "../no-auth";
|
|
@@ -83,6 +85,12 @@ describe("AuthHttpClient", () => {
|
|
|
83
85
|
});
|
|
84
86
|
|
|
85
87
|
describe("with DirectAuthManager", () => {
|
|
88
|
+
let mockPlatformService: MockPlatformService;
|
|
89
|
+
|
|
90
|
+
beforeEach(() => {
|
|
91
|
+
mockPlatformService = new MockPlatformService(false); // Node.js environment for tests
|
|
92
|
+
});
|
|
93
|
+
|
|
86
94
|
it("should attach credentials from DirectAuthManager", async () => {
|
|
87
95
|
const config: DirectAuthConfig = {
|
|
88
96
|
mode: "direct",
|
|
@@ -90,7 +98,12 @@ describe("AuthHttpClient", () => {
|
|
|
90
98
|
headers: { Authorization: "Bearer direct-token" },
|
|
91
99
|
}),
|
|
92
100
|
};
|
|
93
|
-
|
|
101
|
+
|
|
102
|
+
const authManager = new DirectAuthManager(
|
|
103
|
+
config,
|
|
104
|
+
mockPlatformService,
|
|
105
|
+
createLogger(true),
|
|
106
|
+
);
|
|
94
107
|
const authClient = new AuthHttpClient(mockHttpClient, authManager);
|
|
95
108
|
|
|
96
109
|
await authClient.request("https://api.example.com/upload", {
|
|
@@ -118,7 +131,11 @@ describe("AuthHttpClient", () => {
|
|
|
118
131
|
return { headers: { Authorization: "Bearer async-token" } };
|
|
119
132
|
},
|
|
120
133
|
};
|
|
121
|
-
const authManager = new DirectAuthManager(
|
|
134
|
+
const authManager = new DirectAuthManager(
|
|
135
|
+
config,
|
|
136
|
+
mockPlatformService,
|
|
137
|
+
createLogger(true),
|
|
138
|
+
);
|
|
122
139
|
const authClient = new AuthHttpClient(mockHttpClient, authManager);
|
|
123
140
|
|
|
124
141
|
await authClient.request("https://api.example.com/upload");
|
|
@@ -183,9 +200,14 @@ describe("AuthHttpClient", () => {
|
|
|
183
200
|
};
|
|
184
201
|
|
|
185
202
|
vi.mocked(uploadAuthMockHttpClient.request).mockResolvedValueOnce({
|
|
203
|
+
status: 200,
|
|
204
|
+
statusText: "OK",
|
|
205
|
+
headers: new Headers(),
|
|
186
206
|
ok: true,
|
|
187
207
|
json: async () => ({ token: "jwt-token-123" }),
|
|
188
|
-
|
|
208
|
+
text: async () => "",
|
|
209
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
210
|
+
} satisfies HttpResponse);
|
|
189
211
|
|
|
190
212
|
const authManager = new UploadistaCloudAuthManager(
|
|
191
213
|
config,
|
|
@@ -218,9 +240,14 @@ describe("AuthHttpClient", () => {
|
|
|
218
240
|
};
|
|
219
241
|
|
|
220
242
|
vi.mocked(uploadAuthMockHttpClient.request).mockResolvedValueOnce({
|
|
243
|
+
status: 200,
|
|
244
|
+
statusText: "OK",
|
|
245
|
+
headers: new Headers(),
|
|
221
246
|
ok: true,
|
|
222
247
|
json: async () => ({ token: "jwt-token-for-upload-123" }),
|
|
223
|
-
|
|
248
|
+
text: async () => "",
|
|
249
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
250
|
+
} satisfies HttpResponse);
|
|
224
251
|
|
|
225
252
|
const authManager = new UploadistaCloudAuthManager(
|
|
226
253
|
config,
|
|
@@ -246,9 +273,14 @@ describe("AuthHttpClient", () => {
|
|
|
246
273
|
};
|
|
247
274
|
|
|
248
275
|
vi.mocked(uploadAuthMockHttpClient.request).mockResolvedValueOnce({
|
|
276
|
+
status: 200,
|
|
277
|
+
statusText: "OK",
|
|
278
|
+
headers: new Headers(),
|
|
249
279
|
ok: true,
|
|
250
280
|
json: async () => ({ token: "jwt-token-for-flow-456" }),
|
|
251
|
-
|
|
281
|
+
text: async () => "",
|
|
282
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
283
|
+
} satisfies HttpResponse);
|
|
252
284
|
|
|
253
285
|
const authManager = new UploadistaCloudAuthManager(
|
|
254
286
|
config,
|
|
@@ -274,9 +306,14 @@ describe("AuthHttpClient", () => {
|
|
|
274
306
|
};
|
|
275
307
|
|
|
276
308
|
vi.mocked(uploadAuthMockHttpClient.request).mockResolvedValueOnce({
|
|
309
|
+
status: 200,
|
|
310
|
+
statusText: "OK",
|
|
311
|
+
headers: new Headers(),
|
|
277
312
|
ok: true,
|
|
278
313
|
json: async () => ({ token: "jwt-token-for-job-789" }),
|
|
279
|
-
|
|
314
|
+
text: async () => "",
|
|
315
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
316
|
+
} satisfies HttpResponse);
|
|
280
317
|
|
|
281
318
|
const authManager = new UploadistaCloudAuthManager(
|
|
282
319
|
config,
|
|
@@ -296,6 +333,12 @@ describe("AuthHttpClient", () => {
|
|
|
296
333
|
});
|
|
297
334
|
|
|
298
335
|
describe("error handling", () => {
|
|
336
|
+
let mockPlatformService: MockPlatformService;
|
|
337
|
+
|
|
338
|
+
beforeEach(() => {
|
|
339
|
+
mockPlatformService = new MockPlatformService(false); // Node.js environment for tests
|
|
340
|
+
});
|
|
341
|
+
|
|
299
342
|
it("should propagate auth errors", async () => {
|
|
300
343
|
const config: DirectAuthConfig = {
|
|
301
344
|
mode: "direct",
|
|
@@ -304,7 +347,11 @@ describe("AuthHttpClient", () => {
|
|
|
304
347
|
},
|
|
305
348
|
};
|
|
306
349
|
|
|
307
|
-
const authManager = new DirectAuthManager(
|
|
350
|
+
const authManager = new DirectAuthManager(
|
|
351
|
+
config,
|
|
352
|
+
mockPlatformService,
|
|
353
|
+
createLogger(true),
|
|
354
|
+
);
|
|
308
355
|
const authClient = new AuthHttpClient(mockHttpClient, authManager);
|
|
309
356
|
|
|
310
357
|
await expect(
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
1
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { createLogger } from "../../logger";
|
|
3
|
+
import { MockPlatformService } from "../../testing/mock-service-container";
|
|
2
4
|
import { DirectAuthManager } from "../direct-auth";
|
|
3
5
|
import type { DirectAuthConfig } from "../types";
|
|
4
6
|
|
|
5
7
|
describe("DirectAuthManager", () => {
|
|
8
|
+
let mockPlatformService: MockPlatformService;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
mockPlatformService = new MockPlatformService(false); // Node.js environment for tests
|
|
12
|
+
});
|
|
13
|
+
|
|
6
14
|
describe("attachCredentials", () => {
|
|
7
15
|
it("should attach headers from getCredentials", async () => {
|
|
8
16
|
const config: DirectAuthConfig = {
|
|
@@ -15,7 +23,11 @@ describe("DirectAuthManager", () => {
|
|
|
15
23
|
}),
|
|
16
24
|
};
|
|
17
25
|
|
|
18
|
-
const manager = new DirectAuthManager(
|
|
26
|
+
const manager = new DirectAuthManager(
|
|
27
|
+
config,
|
|
28
|
+
mockPlatformService,
|
|
29
|
+
createLogger(true),
|
|
30
|
+
);
|
|
19
31
|
const result = await manager.attachCredentials({
|
|
20
32
|
"Content-Type": "application/json",
|
|
21
33
|
});
|
|
@@ -41,7 +53,11 @@ describe("DirectAuthManager", () => {
|
|
|
41
53
|
},
|
|
42
54
|
};
|
|
43
55
|
|
|
44
|
-
const manager = new DirectAuthManager(
|
|
56
|
+
const manager = new DirectAuthManager(
|
|
57
|
+
config,
|
|
58
|
+
mockPlatformService,
|
|
59
|
+
createLogger(true),
|
|
60
|
+
);
|
|
45
61
|
const result = await manager.attachCredentials();
|
|
46
62
|
|
|
47
63
|
expect(result).toEqual({
|
|
@@ -55,7 +71,11 @@ describe("DirectAuthManager", () => {
|
|
|
55
71
|
getCredentials: () => ({}),
|
|
56
72
|
};
|
|
57
73
|
|
|
58
|
-
const manager = new DirectAuthManager(
|
|
74
|
+
const manager = new DirectAuthManager(
|
|
75
|
+
config,
|
|
76
|
+
mockPlatformService,
|
|
77
|
+
createLogger(true),
|
|
78
|
+
);
|
|
59
79
|
const result = await manager.attachCredentials({
|
|
60
80
|
"Content-Type": "application/json",
|
|
61
81
|
});
|
|
@@ -75,7 +95,11 @@ describe("DirectAuthManager", () => {
|
|
|
75
95
|
}),
|
|
76
96
|
};
|
|
77
97
|
|
|
78
|
-
const manager = new DirectAuthManager(
|
|
98
|
+
const manager = new DirectAuthManager(
|
|
99
|
+
config,
|
|
100
|
+
mockPlatformService,
|
|
101
|
+
createLogger(true),
|
|
102
|
+
);
|
|
79
103
|
const result = await manager.attachCredentials({
|
|
80
104
|
Authorization: "Bearer old-token",
|
|
81
105
|
"Content-Type": "application/json",
|
|
@@ -90,10 +114,18 @@ describe("DirectAuthManager", () => {
|
|
|
90
114
|
it("should throw error if getCredentials returns non-object", async () => {
|
|
91
115
|
const config: DirectAuthConfig = {
|
|
92
116
|
mode: "direct",
|
|
93
|
-
getCredentials: () =>
|
|
117
|
+
getCredentials: () =>
|
|
118
|
+
null as unknown as {
|
|
119
|
+
headers?: Record<string, string>;
|
|
120
|
+
cookies?: Record<string, string>;
|
|
121
|
+
},
|
|
94
122
|
};
|
|
95
123
|
|
|
96
|
-
const manager = new DirectAuthManager(
|
|
124
|
+
const manager = new DirectAuthManager(
|
|
125
|
+
config,
|
|
126
|
+
mockPlatformService,
|
|
127
|
+
createLogger(true),
|
|
128
|
+
);
|
|
97
129
|
|
|
98
130
|
await expect(manager.attachCredentials()).rejects.toThrow(
|
|
99
131
|
"Failed to attach auth credentials",
|
|
@@ -108,7 +140,11 @@ describe("DirectAuthManager", () => {
|
|
|
108
140
|
},
|
|
109
141
|
};
|
|
110
142
|
|
|
111
|
-
const manager = new DirectAuthManager(
|
|
143
|
+
const manager = new DirectAuthManager(
|
|
144
|
+
config,
|
|
145
|
+
mockPlatformService,
|
|
146
|
+
createLogger(true),
|
|
147
|
+
);
|
|
112
148
|
|
|
113
149
|
await expect(manager.attachCredentials()).rejects.toThrow(
|
|
114
150
|
"Failed to attach auth credentials: Token fetch failed",
|
|
@@ -120,12 +156,16 @@ describe("DirectAuthManager", () => {
|
|
|
120
156
|
mode: "direct",
|
|
121
157
|
getCredentials: () => ({
|
|
122
158
|
headers: {
|
|
123
|
-
Authorization: 123 as
|
|
159
|
+
Authorization: 123 as unknown as string, // Invalid: number instead of string
|
|
124
160
|
},
|
|
125
161
|
}),
|
|
126
162
|
};
|
|
127
163
|
|
|
128
|
-
const manager = new DirectAuthManager(
|
|
164
|
+
const manager = new DirectAuthManager(
|
|
165
|
+
config,
|
|
166
|
+
mockPlatformService,
|
|
167
|
+
createLogger(true),
|
|
168
|
+
);
|
|
129
169
|
|
|
130
170
|
await expect(manager.attachCredentials()).rejects.toThrow(
|
|
131
171
|
"Invalid header",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import type { HttpClient } from "../../services";
|
|
2
|
+
import type { HttpClient, HttpResponse } from "../../services";
|
|
3
3
|
import type { UploadistaCloudAuthConfig } from "../types";
|
|
4
4
|
import { UploadistaCloudAuthManager } from "../uploadista-cloud-auth";
|
|
5
5
|
|
|
@@ -57,12 +57,17 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
vi.mocked(mockHttpClient.request).mockResolvedValueOnce({
|
|
60
|
+
status: 200,
|
|
61
|
+
statusText: "OK",
|
|
62
|
+
headers: new Headers(),
|
|
60
63
|
ok: true,
|
|
61
64
|
json: async () => ({
|
|
62
65
|
token: "jwt-token-123",
|
|
63
66
|
expiresIn: 3600,
|
|
64
67
|
}),
|
|
65
|
-
|
|
68
|
+
text: async () => "",
|
|
69
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
70
|
+
} satisfies HttpResponse);
|
|
66
71
|
|
|
67
72
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
68
73
|
const result = await manager.fetchToken();
|
|
@@ -91,11 +96,14 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
91
96
|
};
|
|
92
97
|
|
|
93
98
|
vi.mocked(mockHttpClient.request).mockResolvedValueOnce({
|
|
94
|
-
ok: false,
|
|
95
99
|
status: 401,
|
|
96
100
|
statusText: "Unauthorized",
|
|
101
|
+
headers: new Headers(),
|
|
102
|
+
ok: false,
|
|
103
|
+
json: async () => ({ error: "Invalid credentials" }),
|
|
97
104
|
text: async () => JSON.stringify({ error: "Invalid credentials" }),
|
|
98
|
-
|
|
105
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
106
|
+
} satisfies HttpResponse);
|
|
99
107
|
|
|
100
108
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
101
109
|
|
|
@@ -130,9 +138,14 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
130
138
|
};
|
|
131
139
|
|
|
132
140
|
vi.mocked(mockHttpClient.request).mockResolvedValueOnce({
|
|
141
|
+
status: 200,
|
|
142
|
+
statusText: "OK",
|
|
143
|
+
headers: new Headers(),
|
|
133
144
|
ok: true,
|
|
134
145
|
json: async () => ({ noToken: "here" }), // Missing token field
|
|
135
|
-
|
|
146
|
+
text: async () => "",
|
|
147
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
148
|
+
} satisfies HttpResponse);
|
|
136
149
|
|
|
137
150
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
138
151
|
|
|
@@ -151,9 +164,14 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
151
164
|
};
|
|
152
165
|
|
|
153
166
|
vi.mocked(mockHttpClient.request).mockResolvedValueOnce({
|
|
167
|
+
status: 200,
|
|
168
|
+
statusText: "OK",
|
|
169
|
+
headers: new Headers(),
|
|
154
170
|
ok: true,
|
|
155
171
|
json: async () => ({ token: "jwt-token-123" }),
|
|
156
|
-
|
|
172
|
+
text: async () => "",
|
|
173
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
174
|
+
} satisfies HttpResponse);
|
|
157
175
|
|
|
158
176
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
159
177
|
const result = await manager.attachToken({
|
|
@@ -174,9 +192,14 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
174
192
|
};
|
|
175
193
|
|
|
176
194
|
vi.mocked(mockHttpClient.request).mockResolvedValueOnce({
|
|
195
|
+
status: 200,
|
|
196
|
+
statusText: "OK",
|
|
197
|
+
headers: new Headers(),
|
|
177
198
|
ok: true,
|
|
178
199
|
json: async () => ({ token: "jwt-token-123" }),
|
|
179
|
-
|
|
200
|
+
text: async () => "",
|
|
201
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
202
|
+
} satisfies HttpResponse);
|
|
180
203
|
|
|
181
204
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
182
205
|
|
|
@@ -198,13 +221,23 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
198
221
|
|
|
199
222
|
vi.mocked(mockHttpClient.request)
|
|
200
223
|
.mockResolvedValueOnce({
|
|
224
|
+
status: 200,
|
|
225
|
+
statusText: "OK",
|
|
226
|
+
headers: new Headers(),
|
|
201
227
|
ok: true,
|
|
202
228
|
json: async () => ({ token: "jwt-token-1" }),
|
|
203
|
-
|
|
229
|
+
text: async () => "",
|
|
230
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
231
|
+
} satisfies HttpResponse)
|
|
204
232
|
.mockResolvedValueOnce({
|
|
233
|
+
status: 200,
|
|
234
|
+
statusText: "OK",
|
|
235
|
+
headers: new Headers(),
|
|
205
236
|
ok: true,
|
|
206
237
|
json: async () => ({ token: "jwt-token-2" }),
|
|
207
|
-
|
|
238
|
+
text: async () => "",
|
|
239
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
240
|
+
} satisfies HttpResponse);
|
|
208
241
|
|
|
209
242
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
210
243
|
|
|
@@ -234,16 +267,26 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
234
267
|
// First token expires in 1 second
|
|
235
268
|
vi.mocked(mockHttpClient.request)
|
|
236
269
|
.mockResolvedValueOnce({
|
|
270
|
+
status: 200,
|
|
271
|
+
statusText: "OK",
|
|
272
|
+
headers: new Headers(),
|
|
237
273
|
ok: true,
|
|
238
274
|
json: async () => ({
|
|
239
275
|
token: "jwt-token-old",
|
|
240
276
|
expiresIn: 0.001, // Expires very soon
|
|
241
277
|
}),
|
|
242
|
-
|
|
278
|
+
text: async () => "",
|
|
279
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
280
|
+
} satisfies HttpResponse)
|
|
243
281
|
.mockResolvedValueOnce({
|
|
282
|
+
status: 200,
|
|
283
|
+
statusText: "OK",
|
|
284
|
+
headers: new Headers(),
|
|
244
285
|
ok: true,
|
|
245
286
|
json: async () => ({ token: "jwt-token-new" }),
|
|
246
|
-
|
|
287
|
+
text: async () => "",
|
|
288
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
289
|
+
} satisfies HttpResponse);
|
|
247
290
|
|
|
248
291
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
249
292
|
|
|
@@ -270,13 +313,23 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
270
313
|
|
|
271
314
|
vi.mocked(mockHttpClient.request)
|
|
272
315
|
.mockResolvedValueOnce({
|
|
316
|
+
status: 200,
|
|
317
|
+
statusText: "OK",
|
|
318
|
+
headers: new Headers(),
|
|
273
319
|
ok: true,
|
|
274
320
|
json: async () => ({ token: "jwt-token-1" }),
|
|
275
|
-
|
|
321
|
+
text: async () => "",
|
|
322
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
323
|
+
} satisfies HttpResponse)
|
|
276
324
|
.mockResolvedValueOnce({
|
|
325
|
+
status: 200,
|
|
326
|
+
statusText: "OK",
|
|
327
|
+
headers: new Headers(),
|
|
277
328
|
ok: true,
|
|
278
329
|
json: async () => ({ token: "jwt-token-2" }),
|
|
279
|
-
|
|
330
|
+
text: async () => "",
|
|
331
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
332
|
+
} satisfies HttpResponse);
|
|
280
333
|
|
|
281
334
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
282
335
|
|
|
@@ -303,17 +356,32 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
303
356
|
|
|
304
357
|
vi.mocked(mockHttpClient.request)
|
|
305
358
|
.mockResolvedValueOnce({
|
|
359
|
+
status: 200,
|
|
360
|
+
statusText: "OK",
|
|
361
|
+
headers: new Headers(),
|
|
306
362
|
ok: true,
|
|
307
363
|
json: async () => ({ token: "jwt-token-1" }),
|
|
308
|
-
|
|
364
|
+
text: async () => "",
|
|
365
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
366
|
+
} satisfies HttpResponse)
|
|
309
367
|
.mockResolvedValueOnce({
|
|
368
|
+
status: 200,
|
|
369
|
+
statusText: "OK",
|
|
370
|
+
headers: new Headers(),
|
|
310
371
|
ok: true,
|
|
311
372
|
json: async () => ({ token: "jwt-token-2" }),
|
|
312
|
-
|
|
373
|
+
text: async () => "",
|
|
374
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
375
|
+
} satisfies HttpResponse)
|
|
313
376
|
.mockResolvedValueOnce({
|
|
377
|
+
status: 200,
|
|
378
|
+
statusText: "OK",
|
|
379
|
+
headers: new Headers(),
|
|
314
380
|
ok: true,
|
|
315
381
|
json: async () => ({ token: "jwt-token-3" }),
|
|
316
|
-
|
|
382
|
+
text: async () => "",
|
|
383
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
384
|
+
} satisfies HttpResponse);
|
|
317
385
|
|
|
318
386
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
319
387
|
|
|
@@ -340,17 +408,32 @@ describe("UploadistaCloudAuthManager", () => {
|
|
|
340
408
|
|
|
341
409
|
vi.mocked(mockHttpClient.request)
|
|
342
410
|
.mockResolvedValueOnce({
|
|
411
|
+
status: 200,
|
|
412
|
+
statusText: "OK",
|
|
413
|
+
headers: new Headers(),
|
|
343
414
|
ok: true,
|
|
344
415
|
json: async () => ({ token: "jwt-token-1" }),
|
|
345
|
-
|
|
416
|
+
text: async () => "",
|
|
417
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
418
|
+
} satisfies HttpResponse)
|
|
346
419
|
.mockResolvedValueOnce({
|
|
420
|
+
status: 200,
|
|
421
|
+
statusText: "OK",
|
|
422
|
+
headers: new Headers(),
|
|
347
423
|
ok: true,
|
|
348
424
|
json: async () => ({ token: "jwt-token-2" }),
|
|
349
|
-
|
|
425
|
+
text: async () => "",
|
|
426
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
427
|
+
} satisfies HttpResponse)
|
|
350
428
|
.mockResolvedValueOnce({
|
|
429
|
+
status: 200,
|
|
430
|
+
statusText: "OK",
|
|
431
|
+
headers: new Headers(),
|
|
351
432
|
ok: true,
|
|
352
433
|
json: async () => ({ token: "jwt-token-3" }),
|
|
353
|
-
|
|
434
|
+
text: async () => "",
|
|
435
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
436
|
+
} satisfies HttpResponse);
|
|
354
437
|
|
|
355
438
|
const manager = new UploadistaCloudAuthManager(config, mockHttpClient);
|
|
356
439
|
|
|
@@ -573,7 +573,7 @@ describe("UploadManager", () => {
|
|
|
573
573
|
manager.abort();
|
|
574
574
|
|
|
575
575
|
// Now resolve
|
|
576
|
-
resolveUpload
|
|
576
|
+
resolveUpload?.(mockAbortController);
|
|
577
577
|
await upload;
|
|
578
578
|
|
|
579
579
|
// Abort should have been attempted (though controller wasn't available yet)
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
import type { JsonValue } from "@uploadista/core/types";
|
|
1
2
|
import z from "zod";
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* JSON value schema that allows any JSON-serializable data.
|
|
6
|
+
* This is used for metadata values which can be primitives, arrays, or objects.
|
|
7
|
+
*/
|
|
8
|
+
const jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>
|
|
9
|
+
z.union([
|
|
10
|
+
z.string(),
|
|
11
|
+
z.number(),
|
|
12
|
+
z.boolean(),
|
|
13
|
+
z.null(),
|
|
14
|
+
z.array(jsonValueSchema),
|
|
15
|
+
z.record(z.string(), jsonValueSchema),
|
|
16
|
+
]),
|
|
17
|
+
);
|
|
18
|
+
|
|
3
19
|
export type PreviousUpload = {
|
|
4
20
|
size: number | null;
|
|
5
|
-
metadata:
|
|
21
|
+
metadata: Record<string, JsonValue>;
|
|
6
22
|
creationTime: string;
|
|
7
23
|
uploadId?: string;
|
|
8
24
|
parallelUploadUrls?: string[];
|
|
@@ -11,10 +27,7 @@ export type PreviousUpload = {
|
|
|
11
27
|
|
|
12
28
|
export const previousUploadSchema = z.object({
|
|
13
29
|
size: z.number().nullable(),
|
|
14
|
-
metadata: z.record(
|
|
15
|
-
z.string(),
|
|
16
|
-
z.union([z.string(), z.number(), z.boolean()]),
|
|
17
|
-
),
|
|
30
|
+
metadata: z.record(z.string(), jsonValueSchema),
|
|
18
31
|
creationTime: z.string(),
|
|
19
32
|
uploadId: z.string().optional(),
|
|
20
33
|
parallelUploadUrls: z.array(z.string()).optional(),
|
|
@@ -10,7 +10,6 @@ import type { SmartChunker, SmartChunkerConfig } from "../smart-chunker";
|
|
|
10
10
|
import { shouldRetry } from "./chunk-upload";
|
|
11
11
|
import type { Callbacks } from "./single-upload";
|
|
12
12
|
import type { UploadMetrics } from "./upload-metrics";
|
|
13
|
-
import { inStatusCategory } from "./upload-utils";
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Result from initializing a flow input node
|
|
@@ -178,7 +177,6 @@ export async function uploadInputChunks(
|
|
|
178
177
|
): Promise<void> {
|
|
179
178
|
const {
|
|
180
179
|
nodeId,
|
|
181
|
-
jobId,
|
|
182
180
|
uploadFile,
|
|
183
181
|
source,
|
|
184
182
|
offset = 0,
|
|
@@ -289,7 +287,6 @@ export async function uploadInputChunks(
|
|
|
289
287
|
if (retryDelays != null) {
|
|
290
288
|
const shouldResetDelays = currentOffset > offsetBeforeRetry;
|
|
291
289
|
if (shouldResetDelays) {
|
|
292
|
-
// biome-ignore lint: mutation needed for retry logic
|
|
293
290
|
retryAttempt = 0;
|
|
294
291
|
}
|
|
295
292
|
|
|
@@ -288,7 +288,7 @@ export async function createUpload({
|
|
|
288
288
|
try {
|
|
289
289
|
logger.log("Computing file checksum...");
|
|
290
290
|
checksum = await checksumService.computeChecksum(
|
|
291
|
-
new Uint8Array(source.input as
|
|
291
|
+
new Uint8Array(source.input as unknown as ArrayBuffer),
|
|
292
292
|
);
|
|
293
293
|
logger.log(`Checksum computed: ${checksum}`);
|
|
294
294
|
} catch (error) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { JsonValue } from "@uploadista/core/types";
|
|
1
2
|
import type { IdGenerationService } from "../services/id-generation-service";
|
|
2
3
|
import type { ClientStorage } from "../storage/client-storage";
|
|
3
4
|
import type { PreviousUpload } from "../types/previous-upload";
|
|
@@ -42,7 +43,7 @@ export async function saveUploadInClientStorage({
|
|
|
42
43
|
clientStorage: ClientStorage;
|
|
43
44
|
fingerprint: string;
|
|
44
45
|
size: number;
|
|
45
|
-
metadata: Record<string,
|
|
46
|
+
metadata: Record<string, JsonValue>;
|
|
46
47
|
clientStorageKey: string | null;
|
|
47
48
|
storeFingerprintForResuming: boolean;
|
|
48
49
|
generateId: IdGenerationService;
|