@uploadista/client-core 0.0.3

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.
Files changed (235) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/LICENSE +21 -0
  3. package/README.md +100 -0
  4. package/dist/auth/auth-http-client.d.ts +50 -0
  5. package/dist/auth/auth-http-client.d.ts.map +1 -0
  6. package/dist/auth/auth-http-client.js +110 -0
  7. package/dist/auth/direct-auth.d.ts +38 -0
  8. package/dist/auth/direct-auth.d.ts.map +1 -0
  9. package/dist/auth/direct-auth.js +95 -0
  10. package/dist/auth/index.d.ts +6 -0
  11. package/dist/auth/index.d.ts.map +1 -0
  12. package/dist/auth/index.js +5 -0
  13. package/dist/auth/no-auth.d.ts +26 -0
  14. package/dist/auth/no-auth.d.ts.map +1 -0
  15. package/dist/auth/no-auth.js +33 -0
  16. package/dist/auth/saas-auth.d.ts +80 -0
  17. package/dist/auth/saas-auth.d.ts.map +1 -0
  18. package/dist/auth/saas-auth.js +167 -0
  19. package/dist/auth/types.d.ts +101 -0
  20. package/dist/auth/types.d.ts.map +1 -0
  21. package/dist/auth/types.js +8 -0
  22. package/dist/chunk-buffer.d.ts +209 -0
  23. package/dist/chunk-buffer.d.ts.map +1 -0
  24. package/dist/chunk-buffer.js +236 -0
  25. package/dist/client/create-uploadista-client.d.ts +369 -0
  26. package/dist/client/create-uploadista-client.d.ts.map +1 -0
  27. package/dist/client/create-uploadista-client.js +518 -0
  28. package/dist/client/index.d.ts +4 -0
  29. package/dist/client/index.d.ts.map +1 -0
  30. package/dist/client/index.js +3 -0
  31. package/dist/client/uploadista-api.d.ts +284 -0
  32. package/dist/client/uploadista-api.d.ts.map +1 -0
  33. package/dist/client/uploadista-api.js +444 -0
  34. package/dist/client/uploadista-websocket-manager.d.ts +110 -0
  35. package/dist/client/uploadista-websocket-manager.d.ts.map +1 -0
  36. package/dist/client/uploadista-websocket-manager.js +207 -0
  37. package/dist/error.d.ts +106 -0
  38. package/dist/error.d.ts.map +1 -0
  39. package/dist/error.js +69 -0
  40. package/dist/index.d.ts +9 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +12 -0
  43. package/dist/logger.d.ts +70 -0
  44. package/dist/logger.d.ts.map +1 -0
  45. package/dist/logger.js +59 -0
  46. package/dist/mock-data-store.d.ts +30 -0
  47. package/dist/mock-data-store.d.ts.map +1 -0
  48. package/dist/mock-data-store.js +88 -0
  49. package/dist/network-monitor.d.ts +262 -0
  50. package/dist/network-monitor.d.ts.map +1 -0
  51. package/dist/network-monitor.js +291 -0
  52. package/dist/services/abort-controller-service.d.ts +19 -0
  53. package/dist/services/abort-controller-service.d.ts.map +1 -0
  54. package/dist/services/abort-controller-service.js +4 -0
  55. package/dist/services/checksum-service.d.ts +4 -0
  56. package/dist/services/checksum-service.d.ts.map +1 -0
  57. package/dist/services/checksum-service.js +1 -0
  58. package/dist/services/file-reader-service.d.ts +38 -0
  59. package/dist/services/file-reader-service.d.ts.map +1 -0
  60. package/dist/services/file-reader-service.js +4 -0
  61. package/dist/services/fingerprint-service.d.ts +4 -0
  62. package/dist/services/fingerprint-service.d.ts.map +1 -0
  63. package/dist/services/fingerprint-service.js +1 -0
  64. package/dist/services/http-client.d.ts +182 -0
  65. package/dist/services/http-client.d.ts.map +1 -0
  66. package/dist/services/http-client.js +1 -0
  67. package/dist/services/id-generation-service.d.ts +10 -0
  68. package/dist/services/id-generation-service.d.ts.map +1 -0
  69. package/dist/services/id-generation-service.js +1 -0
  70. package/dist/services/index.d.ts +11 -0
  71. package/dist/services/index.d.ts.map +1 -0
  72. package/dist/services/index.js +10 -0
  73. package/dist/services/platform-service.d.ts +48 -0
  74. package/dist/services/platform-service.d.ts.map +1 -0
  75. package/dist/services/platform-service.js +10 -0
  76. package/dist/services/service-container.d.ts +25 -0
  77. package/dist/services/service-container.d.ts.map +1 -0
  78. package/dist/services/service-container.js +1 -0
  79. package/dist/services/storage-service.d.ts +26 -0
  80. package/dist/services/storage-service.d.ts.map +1 -0
  81. package/dist/services/storage-service.js +1 -0
  82. package/dist/services/websocket-service.d.ts +36 -0
  83. package/dist/services/websocket-service.d.ts.map +1 -0
  84. package/dist/services/websocket-service.js +4 -0
  85. package/dist/smart-chunker.d.ts +72 -0
  86. package/dist/smart-chunker.d.ts.map +1 -0
  87. package/dist/smart-chunker.js +317 -0
  88. package/dist/storage/client-storage.d.ts +148 -0
  89. package/dist/storage/client-storage.d.ts.map +1 -0
  90. package/dist/storage/client-storage.js +62 -0
  91. package/dist/storage/in-memory-storage-service.d.ts +7 -0
  92. package/dist/storage/in-memory-storage-service.d.ts.map +1 -0
  93. package/dist/storage/in-memory-storage-service.js +24 -0
  94. package/dist/storage/index.d.ts +3 -0
  95. package/dist/storage/index.d.ts.map +1 -0
  96. package/dist/storage/index.js +2 -0
  97. package/dist/types/buffered-chunk.d.ts +6 -0
  98. package/dist/types/buffered-chunk.d.ts.map +1 -0
  99. package/dist/types/buffered-chunk.js +1 -0
  100. package/dist/types/chunk-metrics.d.ts +12 -0
  101. package/dist/types/chunk-metrics.d.ts.map +1 -0
  102. package/dist/types/chunk-metrics.js +1 -0
  103. package/dist/types/flow-result.d.ts +11 -0
  104. package/dist/types/flow-result.d.ts.map +1 -0
  105. package/dist/types/flow-result.js +1 -0
  106. package/dist/types/flow-upload-config.d.ts +54 -0
  107. package/dist/types/flow-upload-config.d.ts.map +1 -0
  108. package/dist/types/flow-upload-config.js +1 -0
  109. package/dist/types/flow-upload-item.d.ts +16 -0
  110. package/dist/types/flow-upload-item.d.ts.map +1 -0
  111. package/dist/types/flow-upload-item.js +1 -0
  112. package/dist/types/flow-upload-options.d.ts +41 -0
  113. package/dist/types/flow-upload-options.d.ts.map +1 -0
  114. package/dist/types/flow-upload-options.js +1 -0
  115. package/dist/types/index.d.ts +14 -0
  116. package/dist/types/index.d.ts.map +1 -0
  117. package/dist/types/index.js +13 -0
  118. package/dist/types/multi-flow-upload-options.d.ts +33 -0
  119. package/dist/types/multi-flow-upload-options.d.ts.map +1 -0
  120. package/dist/types/multi-flow-upload-options.js +1 -0
  121. package/dist/types/multi-flow-upload-state.d.ts +9 -0
  122. package/dist/types/multi-flow-upload-state.d.ts.map +1 -0
  123. package/dist/types/multi-flow-upload-state.js +1 -0
  124. package/dist/types/performance-insights.d.ts +11 -0
  125. package/dist/types/performance-insights.d.ts.map +1 -0
  126. package/dist/types/performance-insights.js +1 -0
  127. package/dist/types/previous-upload.d.ts +20 -0
  128. package/dist/types/previous-upload.d.ts.map +1 -0
  129. package/dist/types/previous-upload.js +9 -0
  130. package/dist/types/upload-options.d.ts +40 -0
  131. package/dist/types/upload-options.d.ts.map +1 -0
  132. package/dist/types/upload-options.js +1 -0
  133. package/dist/types/upload-response.d.ts +6 -0
  134. package/dist/types/upload-response.d.ts.map +1 -0
  135. package/dist/types/upload-response.js +1 -0
  136. package/dist/types/upload-result.d.ts +57 -0
  137. package/dist/types/upload-result.d.ts.map +1 -0
  138. package/dist/types/upload-result.js +1 -0
  139. package/dist/types/upload-session-metrics.d.ts +16 -0
  140. package/dist/types/upload-session-metrics.d.ts.map +1 -0
  141. package/dist/types/upload-session-metrics.js +1 -0
  142. package/dist/upload/chunk-upload.d.ts +40 -0
  143. package/dist/upload/chunk-upload.d.ts.map +1 -0
  144. package/dist/upload/chunk-upload.js +82 -0
  145. package/dist/upload/flow-upload.d.ts +48 -0
  146. package/dist/upload/flow-upload.d.ts.map +1 -0
  147. package/dist/upload/flow-upload.js +240 -0
  148. package/dist/upload/index.d.ts +3 -0
  149. package/dist/upload/index.d.ts.map +1 -0
  150. package/dist/upload/index.js +2 -0
  151. package/dist/upload/parallel-upload.d.ts +65 -0
  152. package/dist/upload/parallel-upload.d.ts.map +1 -0
  153. package/dist/upload/parallel-upload.js +231 -0
  154. package/dist/upload/single-upload.d.ts +118 -0
  155. package/dist/upload/single-upload.d.ts.map +1 -0
  156. package/dist/upload/single-upload.js +332 -0
  157. package/dist/upload/upload-manager.d.ts +30 -0
  158. package/dist/upload/upload-manager.d.ts.map +1 -0
  159. package/dist/upload/upload-manager.js +57 -0
  160. package/dist/upload/upload-metrics.d.ts +37 -0
  161. package/dist/upload/upload-metrics.d.ts.map +1 -0
  162. package/dist/upload/upload-metrics.js +236 -0
  163. package/dist/upload/upload-storage.d.ts +32 -0
  164. package/dist/upload/upload-storage.d.ts.map +1 -0
  165. package/dist/upload/upload-storage.js +46 -0
  166. package/dist/upload/upload-strategy.d.ts +66 -0
  167. package/dist/upload/upload-strategy.d.ts.map +1 -0
  168. package/dist/upload/upload-strategy.js +171 -0
  169. package/dist/upload/upload-utils.d.ts +26 -0
  170. package/dist/upload/upload-utils.d.ts.map +1 -0
  171. package/dist/upload/upload-utils.js +80 -0
  172. package/package.json +29 -0
  173. package/src/__tests__/smart-chunking.test.ts +399 -0
  174. package/src/auth/__tests__/auth-http-client.test.ts +327 -0
  175. package/src/auth/__tests__/direct-auth.test.ts +135 -0
  176. package/src/auth/__tests__/no-auth.test.ts +40 -0
  177. package/src/auth/__tests__/saas-auth.test.ts +337 -0
  178. package/src/auth/auth-http-client.ts +150 -0
  179. package/src/auth/direct-auth.ts +121 -0
  180. package/src/auth/index.ts +5 -0
  181. package/src/auth/no-auth.ts +39 -0
  182. package/src/auth/saas-auth.ts +218 -0
  183. package/src/auth/types.ts +105 -0
  184. package/src/chunk-buffer.ts +287 -0
  185. package/src/client/create-uploadista-client.ts +901 -0
  186. package/src/client/index.ts +3 -0
  187. package/src/client/uploadista-api.ts +857 -0
  188. package/src/client/uploadista-websocket-manager.ts +275 -0
  189. package/src/error.ts +149 -0
  190. package/src/index.ts +13 -0
  191. package/src/logger.ts +104 -0
  192. package/src/mock-data-store.ts +97 -0
  193. package/src/network-monitor.ts +445 -0
  194. package/src/services/abort-controller-service.ts +21 -0
  195. package/src/services/checksum-service.ts +3 -0
  196. package/src/services/file-reader-service.ts +44 -0
  197. package/src/services/fingerprint-service.ts +6 -0
  198. package/src/services/http-client.ts +229 -0
  199. package/src/services/id-generation-service.ts +9 -0
  200. package/src/services/index.ts +10 -0
  201. package/src/services/platform-service.ts +65 -0
  202. package/src/services/service-container.ts +24 -0
  203. package/src/services/storage-service.ts +29 -0
  204. package/src/services/websocket-service.ts +33 -0
  205. package/src/smart-chunker.ts +451 -0
  206. package/src/storage/client-storage.ts +186 -0
  207. package/src/storage/in-memory-storage-service.ts +33 -0
  208. package/src/storage/index.ts +2 -0
  209. package/src/types/buffered-chunk.ts +5 -0
  210. package/src/types/chunk-metrics.ts +11 -0
  211. package/src/types/flow-result.ts +14 -0
  212. package/src/types/flow-upload-config.ts +56 -0
  213. package/src/types/flow-upload-item.ts +16 -0
  214. package/src/types/flow-upload-options.ts +56 -0
  215. package/src/types/index.ts +13 -0
  216. package/src/types/multi-flow-upload-options.ts +39 -0
  217. package/src/types/multi-flow-upload-state.ts +9 -0
  218. package/src/types/performance-insights.ts +7 -0
  219. package/src/types/previous-upload.ts +22 -0
  220. package/src/types/upload-options.ts +56 -0
  221. package/src/types/upload-response.ts +6 -0
  222. package/src/types/upload-result.ts +60 -0
  223. package/src/types/upload-session-metrics.ts +15 -0
  224. package/src/upload/chunk-upload.ts +151 -0
  225. package/src/upload/flow-upload.ts +367 -0
  226. package/src/upload/index.ts +2 -0
  227. package/src/upload/parallel-upload.ts +387 -0
  228. package/src/upload/single-upload.ts +554 -0
  229. package/src/upload/upload-manager.ts +106 -0
  230. package/src/upload/upload-metrics.ts +340 -0
  231. package/src/upload/upload-storage.ts +87 -0
  232. package/src/upload/upload-strategy.ts +296 -0
  233. package/src/upload/upload-utils.ts +114 -0
  234. package/tsconfig.json +23 -0
  235. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,296 @@
1
+ import type { DataStoreCapabilities } from "@uploadista/core/types";
2
+ import {
3
+ type NegotiatedStrategy,
4
+ UploadStrategyNegotiator,
5
+ type UploadStrategyOptions,
6
+ } from "@uploadista/core/upload";
7
+ import { UploadistaError } from "../error";
8
+ import type { Logger } from "../logger";
9
+ import {
10
+ defaultClientCapabilities,
11
+ MockClientDataStore,
12
+ } from "../mock-data-store";
13
+ import type { HttpClient } from "../services/http-client";
14
+
15
+ export type UploadStrategyConfig = {
16
+ preferredStrategy?: "single" | "parallel" | "auto";
17
+ minFileSizeForParallel?: number;
18
+ enableCapabilityNegotiation?: boolean;
19
+ onStrategySelected?: (strategy: {
20
+ chosen: "single" | "parallel";
21
+ chunkSize: number;
22
+ parallelUploads: number;
23
+ reasoning: string[];
24
+ warnings: string[];
25
+ }) => void;
26
+ };
27
+
28
+ export type UploadClientOptions = {
29
+ baseUrl: string;
30
+ uploadBasePath?: string;
31
+ storageId: string;
32
+ retryDelays?: number[];
33
+ chunkSize: number;
34
+ parallelUploads?: number;
35
+ parallelChunkSize?: number;
36
+ uploadStrategy?: UploadStrategyConfig;
37
+ };
38
+
39
+ export function createUploadStrategyNegotiator(
40
+ dataStore: MockClientDataStore,
41
+ ): UploadStrategyNegotiator {
42
+ return new UploadStrategyNegotiator(dataStore.getCapabilities(), (strategy) =>
43
+ dataStore.validateUploadStrategy(strategy),
44
+ );
45
+ }
46
+
47
+ /**
48
+ * Fetch capabilities from server
49
+ */
50
+ export async function fetchServerCapabilities(
51
+ baseUrl: string,
52
+ uploadBasePath: string,
53
+ storageId: string,
54
+ httpClient: HttpClient,
55
+ ): Promise<DataStoreCapabilities> {
56
+ const capabilitiesUrl = `${baseUrl}/${uploadBasePath}/capabilities?storageId=${encodeURIComponent(storageId)}`;
57
+
58
+ try {
59
+ const response = await httpClient.request(capabilitiesUrl, {
60
+ method: "GET",
61
+ headers: {
62
+ "Content-Type": "application/json",
63
+ },
64
+ });
65
+
66
+ if (!response.ok) {
67
+ throw new Error(
68
+ `Failed to fetch capabilities: ${response.status} ${response.statusText}`,
69
+ );
70
+ }
71
+
72
+ const data = await response.json();
73
+ return (data as { capabilities: DataStoreCapabilities }).capabilities;
74
+ } catch (_error) {
75
+ // Fall back to default capabilities if server fetch fails
76
+ return defaultClientCapabilities;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Negotiate upload strategy based on capabilities and options
82
+ */
83
+ export function negotiateUploadStrategy({
84
+ capabilities,
85
+ fileSize,
86
+ chunkSize,
87
+ parallelUploads,
88
+ uploadLengthDeferred,
89
+ strategyConfig,
90
+ logger,
91
+ }: {
92
+ capabilities: DataStoreCapabilities;
93
+ fileSize: number | null;
94
+ chunkSize: number;
95
+ parallelUploads: number;
96
+ uploadLengthDeferred?: boolean;
97
+ strategyConfig?: UploadStrategyConfig;
98
+ logger: Logger;
99
+ }): NegotiatedStrategy {
100
+ if (strategyConfig?.enableCapabilityNegotiation !== false) {
101
+ // Use capability negotiation with server-fetched capabilities
102
+ const mockDataStore = new MockClientDataStore(capabilities);
103
+ const negotiator = createUploadStrategyNegotiator(mockDataStore);
104
+
105
+ const negotiationOptions: UploadStrategyOptions = {
106
+ fileSize: fileSize || 0,
107
+ preferredStrategy:
108
+ strategyConfig?.preferredStrategy === "auto"
109
+ ? undefined
110
+ : strategyConfig?.preferredStrategy,
111
+ preferredChunkSize: chunkSize,
112
+ parallelUploads,
113
+ minChunkSizeForParallel:
114
+ strategyConfig?.minFileSizeForParallel || 10 * 1024 * 1024,
115
+ };
116
+
117
+ const negotiatedStrategy = negotiator.negotiateStrategy(negotiationOptions);
118
+
119
+ // Log negotiation results
120
+ logger.log(`Upload strategy negotiated: ${negotiatedStrategy.strategy}`);
121
+ for (const reason of negotiatedStrategy.reasoning) {
122
+ logger.log(` - ${reason}`);
123
+ }
124
+ for (const warning of negotiatedStrategy.warnings) {
125
+ logger.log(` Warning: ${warning}`);
126
+ }
127
+
128
+ // Notify client of strategy selection if callback provided
129
+ strategyConfig?.onStrategySelected?.({
130
+ chosen: negotiatedStrategy.strategy,
131
+ chunkSize: negotiatedStrategy.chunkSize,
132
+ parallelUploads: negotiatedStrategy.parallelUploads,
133
+ reasoning: negotiatedStrategy.reasoning,
134
+ warnings: negotiatedStrategy.warnings,
135
+ });
136
+
137
+ return negotiatedStrategy;
138
+ } else {
139
+ // Fallback to legacy logic
140
+ const shouldUseParallelUpload =
141
+ parallelUploads > 1 &&
142
+ fileSize &&
143
+ fileSize > (strategyConfig?.minFileSizeForParallel || 10 * 1024 * 1024) &&
144
+ !uploadLengthDeferred;
145
+
146
+ return {
147
+ strategy: shouldUseParallelUpload ? "parallel" : "single",
148
+ chunkSize,
149
+ parallelUploads: shouldUseParallelUpload ? parallelUploads : 1,
150
+ reasoning: [
151
+ `Legacy strategy selection: ${shouldUseParallelUpload ? "parallel" : "single"}`,
152
+ ],
153
+ warnings: [],
154
+ };
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Validate upload client configuration against data store capabilities
160
+ */
161
+ export function validateConfiguration(
162
+ options: UploadClientOptions,
163
+ capabilities: DataStoreCapabilities = defaultClientCapabilities,
164
+ logger: Logger,
165
+ ): {
166
+ valid: boolean;
167
+ errors: string[];
168
+ warnings: string[];
169
+ } {
170
+ const errors: string[] = [];
171
+ const warnings: string[] = [];
172
+
173
+ // Validate against capabilities
174
+ const mockDataStore = new MockClientDataStore(capabilities);
175
+ const negotiator = createUploadStrategyNegotiator(mockDataStore);
176
+
177
+ const validation = negotiator.validateConfiguration({
178
+ fileSize: 0, // Placeholder for validation
179
+ preferredStrategy:
180
+ options.uploadStrategy?.preferredStrategy === "auto"
181
+ ? undefined
182
+ : options.uploadStrategy?.preferredStrategy,
183
+ preferredChunkSize: options.chunkSize,
184
+ parallelUploads: options.parallelUploads,
185
+ });
186
+
187
+ if (!validation.valid) {
188
+ errors.push(...validation.errors);
189
+ }
190
+
191
+ // Additional client-specific validations
192
+ if (options.parallelUploads && options.parallelUploads < 1) {
193
+ errors.push("parallelUploads must be at least 1");
194
+ }
195
+
196
+ if (options.chunkSize && options.chunkSize < 1024) {
197
+ warnings.push("Chunk size below 1KB may impact performance");
198
+ }
199
+
200
+ if (
201
+ options.uploadStrategy?.preferredStrategy === "parallel" &&
202
+ !options.parallelUploads
203
+ ) {
204
+ warnings.push(
205
+ "Parallel strategy requested but parallelUploads not configured",
206
+ );
207
+ }
208
+
209
+ // Log validation results
210
+ if (errors.length > 0) {
211
+ logger.log("Configuration validation errors:");
212
+ for (const error of errors) {
213
+ logger.log(` Error: ${error}`);
214
+ }
215
+ }
216
+
217
+ if (warnings.length > 0) {
218
+ logger.log("Configuration validation warnings:");
219
+ for (const warning of warnings) {
220
+ logger.log(` Warning: ${warning}`);
221
+ }
222
+ }
223
+
224
+ return {
225
+ valid: errors.length === 0,
226
+ errors,
227
+ warnings,
228
+ };
229
+ }
230
+
231
+ /**
232
+ * Async configuration validation with server capabilities
233
+ */
234
+ export async function validateConfigurationAsync(
235
+ options: UploadClientOptions,
236
+ httpClient: HttpClient,
237
+ logger: Logger,
238
+ ): Promise<{
239
+ valid: boolean;
240
+ errors: string[];
241
+ warnings: string[];
242
+ capabilities: DataStoreCapabilities;
243
+ }> {
244
+ const errors: string[] = [];
245
+ const warnings: string[] = [];
246
+
247
+ let capabilities: DataStoreCapabilities;
248
+ try {
249
+ capabilities = await fetchServerCapabilities(
250
+ options.baseUrl,
251
+ options.uploadBasePath || "api/upload",
252
+ options.storageId,
253
+ httpClient,
254
+ );
255
+ } catch (error) {
256
+ logger.log(`Failed to fetch server capabilities for validation: ${error}`);
257
+ capabilities = defaultClientCapabilities;
258
+ warnings.push(
259
+ "Using default capabilities for validation - server unavailable",
260
+ );
261
+ }
262
+
263
+ const validation = validateConfiguration(options, capabilities, logger);
264
+ errors.push(...validation.errors);
265
+ warnings.push(...validation.warnings);
266
+
267
+ return {
268
+ valid: errors.length === 0,
269
+ errors,
270
+ warnings,
271
+ capabilities,
272
+ };
273
+ }
274
+
275
+ /**
276
+ * Validate options and throw if invalid
277
+ */
278
+ export function validateAndThrow(
279
+ options: UploadClientOptions,
280
+ logger: Logger,
281
+ ): void {
282
+ const validationResult = validateConfiguration(
283
+ options,
284
+ defaultClientCapabilities,
285
+ logger,
286
+ );
287
+
288
+ if (!validationResult.valid) {
289
+ const errorMessage = `Upload client configuration validation failed: ${validationResult.errors.join(", ")}`;
290
+ logger.log(errorMessage);
291
+ throw new UploadistaError({
292
+ name: "UPLOAD_SIZE_NOT_SPECIFIED", // Reusing existing error type
293
+ message: errorMessage,
294
+ });
295
+ }
296
+ }
@@ -0,0 +1,114 @@
1
+ import { Base64 } from "js-base64";
2
+ import { UploadistaError } from "../error";
3
+
4
+ /**
5
+ * Encodes metadata for upload headers
6
+ */
7
+ export function encodeMetadata(
8
+ metadata: Record<string, string | null>,
9
+ ): string {
10
+ return Object.entries(metadata)
11
+ .map(([key, value]) => `${key} ${Base64.encode(String(value))}`)
12
+ .join(",");
13
+ }
14
+
15
+ /**
16
+ * Checks whether a given status is in the range of the expected category.
17
+ * For example, only a status between 200 and 299 will satisfy the category 200.
18
+ */
19
+ export function inStatusCategory(
20
+ status: number,
21
+ category: 100 | 200 | 300 | 400 | 500,
22
+ ): boolean {
23
+ return status >= category && status < category + 100;
24
+ }
25
+
26
+ export type CalculateFileSizeOptions = {
27
+ uploadLengthDeferred?: boolean;
28
+ uploadSize?: number;
29
+ };
30
+
31
+ /**
32
+ * Calculate the final file size for upload based on options
33
+ */
34
+ export function calculateFileSize(
35
+ originalSize: number | null,
36
+ { uploadLengthDeferred, uploadSize }: CalculateFileSizeOptions,
37
+ ): number | null {
38
+ // First, we look at the uploadLengthDeferred option.
39
+ // Next, we check if the caller has supplied a manual upload size.
40
+ // Finally, we try to use the calculated size from the source object.
41
+ if (uploadLengthDeferred) {
42
+ return null;
43
+ }
44
+
45
+ if (uploadSize != null) {
46
+ return uploadSize;
47
+ }
48
+
49
+ const size = originalSize;
50
+ if (size == null) {
51
+ throw new UploadistaError({
52
+ name: "UPLOAD_SIZE_NOT_SPECIFIED",
53
+ message:
54
+ "cannot automatically derive upload's size from input. Specify it manually using the `uploadSize` option or use the `uploadLengthDeferred` option",
55
+ });
56
+ }
57
+
58
+ return size;
59
+ }
60
+
61
+ /**
62
+ * Calculate segments for parallel upload
63
+ */
64
+ export function calculateSegments(
65
+ fileSize: number,
66
+ parallelUploads: number,
67
+ parallelChunkSize?: number,
68
+ ): { startByte: number; endByte: number; segmentIndex: number }[] {
69
+ if (parallelUploads <= 1) {
70
+ return [{ startByte: 0, endByte: fileSize, segmentIndex: 0 }];
71
+ }
72
+
73
+ // Use parallelChunkSize if provided, otherwise divide file equally
74
+ const segments: {
75
+ startByte: number;
76
+ endByte: number;
77
+ segmentIndex: number;
78
+ }[] = [];
79
+
80
+ if (parallelChunkSize) {
81
+ // Fixed segment size approach
82
+ let currentByte = 0;
83
+ let segmentIndex = 0;
84
+
85
+ while (currentByte < fileSize) {
86
+ const endByte = Math.min(currentByte + parallelChunkSize, fileSize);
87
+ segments.push({
88
+ startByte: currentByte,
89
+ endByte,
90
+ segmentIndex,
91
+ });
92
+ currentByte = endByte;
93
+ segmentIndex++;
94
+ }
95
+ } else {
96
+ // Equal division approach
97
+ const segmentSize = Math.ceil(fileSize / parallelUploads);
98
+
99
+ for (let i = 0; i < parallelUploads; i++) {
100
+ const startByte = i * segmentSize;
101
+ const endByte = Math.min(startByte + segmentSize, fileSize);
102
+
103
+ if (startByte < fileSize) {
104
+ segments.push({
105
+ startByte,
106
+ endByte,
107
+ segmentIndex: i,
108
+ });
109
+ }
110
+ }
111
+ }
112
+
113
+ return segments;
114
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "extends": "@uploadista/typescript-config/base.json",
3
+ "compilerOptions": {
4
+ "baseUrl": "./",
5
+ "paths": {
6
+ "@/*": ["./src/*"]
7
+ },
8
+ "lib": ["ES2020"],
9
+ "target": "ES2020",
10
+ "typeRoots": ["../../node_modules/@types"],
11
+ "types": [],
12
+ "outDir": "./dist",
13
+ "rootDir": "./src"
14
+ },
15
+ "include": ["src/**/*.ts"],
16
+ "exclude": [
17
+ "node_modules",
18
+ "dist",
19
+ "**/__tests__/**",
20
+ "**/*.test.ts",
21
+ "**/*.spec.ts"
22
+ ]
23
+ }
@@ -0,0 +1 @@
1
+ {"root":["./src/chunk-buffer.ts","./src/error.ts","./src/index.ts","./src/logger.ts","./src/mock-data-store.ts","./src/network-monitor.ts","./src/smart-chunker.ts","./src/auth/auth-http-client.ts","./src/auth/direct-auth.ts","./src/auth/index.ts","./src/auth/no-auth.ts","./src/auth/saas-auth.ts","./src/auth/types.ts","./src/client/create-uploadista-client.ts","./src/client/index.ts","./src/client/uploadista-api.ts","./src/client/uploadista-websocket-manager.ts","./src/services/abort-controller-service.ts","./src/services/checksum-service.ts","./src/services/file-reader-service.ts","./src/services/fingerprint-service.ts","./src/services/http-client.ts","./src/services/id-generation-service.ts","./src/services/index.ts","./src/services/platform-service.ts","./src/services/service-container.ts","./src/services/storage-service.ts","./src/services/websocket-service.ts","./src/storage/client-storage.ts","./src/storage/in-memory-storage-service.ts","./src/storage/index.ts","./src/types/buffered-chunk.ts","./src/types/chunk-metrics.ts","./src/types/flow-result.ts","./src/types/flow-upload-config.ts","./src/types/flow-upload-item.ts","./src/types/flow-upload-options.ts","./src/types/index.ts","./src/types/multi-flow-upload-options.ts","./src/types/multi-flow-upload-state.ts","./src/types/performance-insights.ts","./src/types/previous-upload.ts","./src/types/upload-options.ts","./src/types/upload-response.ts","./src/types/upload-result.ts","./src/types/upload-session-metrics.ts","./src/upload/chunk-upload.ts","./src/upload/flow-upload.ts","./src/upload/index.ts","./src/upload/parallel-upload.ts","./src/upload/single-upload.ts","./src/upload/upload-manager.ts","./src/upload/upload-metrics.ts","./src/upload/upload-storage.ts","./src/upload/upload-strategy.ts","./src/upload/upload-utils.ts"],"version":"5.9.3"}