@valentinkolb/filegate 2.4.0 → 2.5.2

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 (88) hide show
  1. package/dist/activity.d.ts +15 -0
  2. package/dist/activity.d.ts.map +1 -0
  3. package/dist/activity.js +21 -0
  4. package/dist/activity.js.map +1 -0
  5. package/dist/capabilities.d.ts +9 -0
  6. package/dist/capabilities.d.ts.map +1 -0
  7. package/dist/capabilities.js +11 -0
  8. package/dist/capabilities.js.map +1 -0
  9. package/dist/client.d.ts +37 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/client.js +77 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/core.d.ts +26 -0
  14. package/dist/core.d.ts.map +1 -0
  15. package/dist/core.js +58 -0
  16. package/dist/core.js.map +1 -0
  17. package/dist/downloads.d.ts +9 -0
  18. package/dist/downloads.d.ts.map +1 -0
  19. package/dist/downloads.js +11 -0
  20. package/dist/downloads.js.map +1 -0
  21. package/dist/errors.d.ts +18 -0
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/errors.js +42 -0
  24. package/dist/errors.js.map +1 -0
  25. package/dist/index-client.d.ts +17 -0
  26. package/dist/index-client.d.ts.map +1 -0
  27. package/dist/index-client.js +29 -0
  28. package/dist/index-client.js.map +1 -0
  29. package/dist/index.d.ts +14 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +7 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/nodes.d.ts +27 -0
  34. package/dist/nodes.d.ts.map +1 -0
  35. package/dist/nodes.js +71 -0
  36. package/dist/nodes.js.map +1 -0
  37. package/dist/paths.d.ts +45 -0
  38. package/dist/paths.d.ts.map +1 -0
  39. package/dist/paths.js +71 -0
  40. package/dist/paths.js.map +1 -0
  41. package/dist/search.d.ts +17 -0
  42. package/dist/search.d.ts.map +1 -0
  43. package/dist/search.js +25 -0
  44. package/dist/search.js.map +1 -0
  45. package/dist/stats.d.ts +9 -0
  46. package/dist/stats.d.ts.map +1 -0
  47. package/dist/stats.js +11 -0
  48. package/dist/stats.js.map +1 -0
  49. package/dist/transfers.d.ts +9 -0
  50. package/dist/transfers.d.ts.map +1 -0
  51. package/dist/transfers.js +14 -0
  52. package/dist/transfers.js.map +1 -0
  53. package/dist/types.d.ts +285 -0
  54. package/dist/types.d.ts.map +1 -0
  55. package/dist/types.js +2 -0
  56. package/dist/types.js.map +1 -0
  57. package/dist/uploads.d.ts +246 -0
  58. package/dist/uploads.d.ts.map +1 -0
  59. package/dist/uploads.js +580 -0
  60. package/dist/uploads.js.map +1 -0
  61. package/dist/utils.d.ts +25 -0
  62. package/dist/utils.d.ts.map +1 -0
  63. package/dist/utils.js +41 -0
  64. package/dist/utils.js.map +1 -0
  65. package/dist/versions.d.ts +76 -0
  66. package/dist/versions.d.ts.map +1 -0
  67. package/dist/versions.js +82 -0
  68. package/dist/versions.js.map +1 -0
  69. package/package.json +36 -41
  70. package/LICENSE +0 -21
  71. package/README.md +0 -569
  72. package/src/client.ts +0 -436
  73. package/src/config.ts +0 -41
  74. package/src/handlers/files.ts +0 -696
  75. package/src/handlers/indexHandler.ts +0 -107
  76. package/src/handlers/search.ts +0 -144
  77. package/src/handlers/thumbnail.ts +0 -174
  78. package/src/handlers/upload.ts +0 -401
  79. package/src/index.ts +0 -131
  80. package/src/lib/index.ts +0 -325
  81. package/src/lib/openapi.ts +0 -48
  82. package/src/lib/ownership.ts +0 -133
  83. package/src/lib/path.ts +0 -128
  84. package/src/lib/response.ts +0 -10
  85. package/src/lib/scanner.ts +0 -121
  86. package/src/lib/validator.ts +0 -21
  87. package/src/schemas.ts +0 -376
  88. package/src/utils.ts +0 -282
package/src/utils.ts DELETED
@@ -1,282 +0,0 @@
1
- // ============================================================================
2
- // Filegate Utils - Browser-compatible utilities for chunked uploads
3
- // ============================================================================
4
-
5
- // ============================================================================
6
- // Type Declarations
7
- // ============================================================================
8
-
9
- // Blob.slice() is standard but missing from TypeScript's lib.dom.d.ts
10
- declare global {
11
- interface Blob {
12
- slice(start?: number, end?: number, contentType?: string): Blob;
13
- }
14
- }
15
-
16
- // ============================================================================
17
- // Types
18
- // ============================================================================
19
-
20
- export interface ChunkInfo {
21
- index: number;
22
- data: Blob;
23
- total: number;
24
- }
25
-
26
- export interface UploadState {
27
- uploaded: number;
28
- total: number;
29
- percent: number;
30
- status: "pending" | "uploading" | "completed" | "error";
31
- }
32
-
33
- export type StateSubscriber = (state: UploadState) => void;
34
-
35
- export interface PrepareOptions {
36
- file: Blob | File;
37
- chunkSize?: number;
38
- }
39
-
40
- export interface SendOptions {
41
- index: number;
42
- retries?: number;
43
- fn: (chunk: { index: number; data: Blob }) => Promise<void>;
44
- }
45
-
46
- export interface SendAllOptions {
47
- skip?: number[];
48
- retries?: number;
49
- concurrency?: number;
50
- fn: (chunk: { index: number; data: Blob }) => Promise<void>;
51
- }
52
-
53
- // ============================================================================
54
- // ChunkedUpload Class
55
- // ============================================================================
56
-
57
- export class ChunkedUpload {
58
- readonly file: Blob | File;
59
- readonly fileSize: number;
60
- readonly chunkSize: number;
61
- readonly totalChunks: number;
62
- readonly checksum: string;
63
-
64
- private _state: UploadState;
65
- private _subscribers: Set<StateSubscriber> = new Set();
66
- private _completedChunks: Set<number> = new Set();
67
-
68
- constructor(opts: { file: Blob | File; fileSize: number; chunkSize: number; totalChunks: number; checksum: string }) {
69
- this.file = opts.file;
70
- this.fileSize = opts.fileSize;
71
- this.chunkSize = opts.chunkSize;
72
- this.totalChunks = opts.totalChunks;
73
- this.checksum = opts.checksum;
74
- this._state = {
75
- uploaded: 0,
76
- total: opts.totalChunks,
77
- percent: 0,
78
- status: "pending",
79
- };
80
- }
81
-
82
- // ==========================================================================
83
- // State Management
84
- // ==========================================================================
85
-
86
- get state(): UploadState {
87
- return { ...this._state };
88
- }
89
-
90
- subscribe(fn: StateSubscriber): () => void {
91
- this._subscribers.add(fn);
92
- // Emit current state immediately
93
- fn(this.state);
94
- return () => {
95
- this._subscribers.delete(fn);
96
- };
97
- }
98
-
99
- private _updateState(partial: Partial<UploadState>): void {
100
- this._state = { ...this._state, ...partial };
101
- for (const fn of this._subscribers) {
102
- fn(this.state);
103
- }
104
- }
105
-
106
- complete(opts: { index: number }): void {
107
- if (this._completedChunks.has(opts.index)) return;
108
-
109
- this._completedChunks.add(opts.index);
110
- const uploaded = this._completedChunks.size;
111
- const percent = Math.round((uploaded / this.totalChunks) * 100);
112
- const status = uploaded === this.totalChunks ? "completed" : "uploading";
113
-
114
- this._updateState({ uploaded, percent, status });
115
- }
116
-
117
- reset(): void {
118
- this._completedChunks.clear();
119
- this._updateState({
120
- uploaded: 0,
121
- percent: 0,
122
- status: "pending",
123
- });
124
- }
125
-
126
- // ==========================================================================
127
- // Chunk Access
128
- // ==========================================================================
129
-
130
- get(opts: { index: number }): Blob {
131
- const start = opts.index * this.chunkSize;
132
- const end = Math.min(start + this.chunkSize, this.fileSize);
133
- // Blob.prototype.slice is standard but TypeScript's lib.dom.d.ts doesn't include it
134
- // We use a type-safe wrapper that preserves the Blob type
135
- return (this.file as Blob).slice(start, end);
136
- }
137
-
138
- async hash(opts: { data: Blob | ArrayBuffer }): Promise<string> {
139
- const buffer = opts.data instanceof Blob ? await opts.data.arrayBuffer() : opts.data;
140
- const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
141
- const hashArray = new Uint8Array(hashBuffer);
142
- return `sha256:${Array.from(hashArray)
143
- .map((b) => b.toString(16).padStart(2, "0"))
144
- .join("")}`;
145
- }
146
-
147
- // ==========================================================================
148
- // Upload Helpers
149
- // ==========================================================================
150
-
151
- async send(opts: SendOptions): Promise<void> {
152
- const { index, retries = 0, fn } = opts;
153
- const data = this.get({ index });
154
-
155
- let lastError: Error | null = null;
156
- for (let attempt = 0; attempt <= retries; attempt++) {
157
- try {
158
- await fn({ index, data });
159
- this.complete({ index });
160
- return;
161
- } catch (err) {
162
- lastError = err instanceof Error ? err : new Error(String(err));
163
- if (attempt < retries) {
164
- // Exponential backoff: 100ms, 200ms, 400ms, ...
165
- await new Promise((r) => setTimeout(r, 100 * Math.pow(2, attempt)));
166
- }
167
- }
168
- }
169
-
170
- this._updateState({ status: "error" });
171
- throw lastError;
172
- }
173
-
174
- async sendAll(opts: SendAllOptions): Promise<void> {
175
- const { skip = [], retries = 0, concurrency = 1, fn } = opts;
176
- const skipSet = new Set(skip);
177
-
178
- // Mark skipped chunks as completed
179
- for (const index of skip) {
180
- this.complete({ index });
181
- }
182
-
183
- this._updateState({ status: "uploading" });
184
-
185
- // Get indices that need to be uploaded
186
- const toUpload: number[] = [];
187
- for (let i = 0; i < this.totalChunks; i++) {
188
- if (!skipSet.has(i) && !this._completedChunks.has(i)) {
189
- toUpload.push(i);
190
- }
191
- }
192
-
193
- if (concurrency === 1) {
194
- // Sequential upload
195
- for (const index of toUpload) {
196
- await this.send({ index, retries, fn });
197
- }
198
- } else {
199
- // Concurrent upload with limited parallelism
200
- const queue = [...toUpload];
201
- const inFlight: Promise<void>[] = [];
202
-
203
- while (queue.length > 0 || inFlight.length > 0) {
204
- // Start new uploads up to concurrency limit
205
- while (queue.length > 0 && inFlight.length < concurrency) {
206
- const index = queue.shift()!;
207
- const promise = this.send({ index, retries, fn }).then(() => {
208
- inFlight.splice(inFlight.indexOf(promise), 1);
209
- });
210
- inFlight.push(promise);
211
- }
212
-
213
- // Wait for at least one to complete
214
- if (inFlight.length > 0) {
215
- await Promise.race(inFlight);
216
- }
217
- }
218
- }
219
-
220
- this._updateState({ status: "completed" });
221
- }
222
-
223
- // ==========================================================================
224
- // Async Iterator
225
- // ==========================================================================
226
-
227
- async *[Symbol.asyncIterator](): AsyncGenerator<ChunkInfo> {
228
- for (let index = 0; index < this.totalChunks; index++) {
229
- yield {
230
- index,
231
- data: this.get({ index }),
232
- total: this.totalChunks,
233
- };
234
- }
235
- }
236
- }
237
-
238
- // ============================================================================
239
- // chunks namespace
240
- // ============================================================================
241
-
242
- async function prepare(opts: PrepareOptions): Promise<ChunkedUpload> {
243
- const { file, chunkSize = 5 * 1024 * 1024 } = opts;
244
- const fileSize = file.size;
245
- const totalChunks = Math.ceil(fileSize / chunkSize);
246
-
247
- // Calculate checksum using WebCrypto
248
- const buffer = await file.arrayBuffer();
249
- const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
250
- const hashArray = new Uint8Array(hashBuffer);
251
- const checksum = `sha256:${Array.from(hashArray)
252
- .map((b) => b.toString(16).padStart(2, "0"))
253
- .join("")}`;
254
-
255
- return new ChunkedUpload({
256
- file,
257
- fileSize,
258
- chunkSize,
259
- totalChunks,
260
- checksum,
261
- });
262
- }
263
-
264
- export const chunks = {
265
- prepare,
266
- };
267
-
268
- // ============================================================================
269
- // formatBytes
270
- // ============================================================================
271
-
272
- export function formatBytes(opts: { bytes: number; decimals?: number }): string {
273
- const { bytes, decimals = 2 } = opts;
274
-
275
- if (bytes === 0) return "0 Bytes";
276
-
277
- const k = 1024;
278
- const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
279
- const i = Math.floor(Math.log(bytes) / Math.log(k));
280
-
281
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimals))} ${sizes[i]}`;
282
- }