@telestack/storage 1.2.1 → 1.3.1
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/README.md +83 -84
- package/dist/index.d.mts +595 -116
- package/dist/index.d.ts +595 -116
- package/dist/index.global.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +5 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
declare class HttpClient {
|
|
2
|
-
|
|
2
|
+
readonly baseUrl: string;
|
|
3
3
|
private tenantId;
|
|
4
4
|
private headers;
|
|
5
|
+
readonly defaultUploadOptions?: Partial<UploadOptions>;
|
|
5
6
|
constructor(config: TelestackConfig);
|
|
6
7
|
private _fetchWithRetry;
|
|
7
8
|
get<T>(path: string, params?: Record<string, string | undefined>): Promise<T>;
|
|
@@ -13,44 +14,92 @@ declare class HttpClient {
|
|
|
13
14
|
uploadToPresignedUrl(url: string, data: Blob | ArrayBuffer, contentType: string, onProgress?: (p: number) => void): Promise<void>;
|
|
14
15
|
private _handle;
|
|
15
16
|
}
|
|
16
|
-
declare class TelestackError extends Error {
|
|
17
|
-
readonly status: number;
|
|
18
|
-
readonly code?: string | undefined;
|
|
19
|
-
constructor(message: string, status: number, code?: string | undefined);
|
|
20
|
-
}
|
|
21
17
|
|
|
22
18
|
/**
|
|
23
|
-
* A cancellable,
|
|
24
|
-
*
|
|
19
|
+
* A cancellable, pausable, and observable upload task.
|
|
20
|
+
* Modelled after Firebase Storage UploadTask — familiar API, powered by Telestack.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const task = storage.ref('photos/sunset.jpg').put(file, { userId: 'u_123' });
|
|
25
|
+
*
|
|
26
|
+
* task.on('state_changed',
|
|
27
|
+
* snap => console.log(`${Math.round(snap.bytesTransferred / snap.totalBytes * 100)}%`),
|
|
28
|
+
* err => console.error('Upload failed:', err),
|
|
29
|
+
* () => console.log('Upload complete!')
|
|
30
|
+
* );
|
|
31
|
+
*
|
|
32
|
+
* // Pause / Resume
|
|
33
|
+
* task.pause();
|
|
34
|
+
* setTimeout(() => task.resume(), 2000);
|
|
35
|
+
*
|
|
36
|
+
* // Await as a promise
|
|
37
|
+
* const result = await task;
|
|
38
|
+
* console.log('File ID:', result.file_id);
|
|
39
|
+
* ```
|
|
25
40
|
*/
|
|
26
41
|
declare class UploadTask implements Promise<UploadResult> {
|
|
27
42
|
private readonly client;
|
|
28
43
|
private readonly path;
|
|
44
|
+
/** Filename */
|
|
29
45
|
private readonly name;
|
|
30
46
|
private readonly contentType;
|
|
31
47
|
private readonly options;
|
|
48
|
+
/** Tenant ID, inherited from SDK config */
|
|
49
|
+
private readonly tenantId;
|
|
50
|
+
/** Current upload lifecycle state. */
|
|
32
51
|
private _state;
|
|
52
|
+
/** Bytes confirmed as uploaded so far. */
|
|
33
53
|
private _bytesTransferred;
|
|
54
|
+
/** Final payload size after optional compression/encryption. */
|
|
34
55
|
private _totalBytes;
|
|
56
|
+
/** Mutable upload payload (can change after preprocessing). */
|
|
35
57
|
private _data;
|
|
58
|
+
/** Observer registry for `state_changed` notifications. */
|
|
36
59
|
private _observers;
|
|
60
|
+
/** Promise facade for `await task`. */
|
|
37
61
|
private _promise;
|
|
62
|
+
/** Internal promise resolve hook. */
|
|
38
63
|
private _resolve;
|
|
64
|
+
/** Internal promise reject hook. */
|
|
39
65
|
private _reject;
|
|
66
|
+
/** Multipart session id returned by the worker. */
|
|
40
67
|
private _uploadId?;
|
|
68
|
+
/** File record id in metadata DB. */
|
|
69
|
+
private _fileId?;
|
|
70
|
+
/** Current version id in metadata DB (simple uploads). */
|
|
71
|
+
private _versionId?;
|
|
72
|
+
/** Object-store key generated by worker. */
|
|
73
|
+
private _storageKey?;
|
|
74
|
+
/** Uploaded multipart part list used for complete call. */
|
|
41
75
|
private _parts;
|
|
76
|
+
/** Zero-based multipart part index currently being uploaded. */
|
|
42
77
|
private _currentPartIndex;
|
|
78
|
+
/** True when payload uses multipart flow. */
|
|
79
|
+
private _isMultipart;
|
|
80
|
+
/** Provider tier returned by control plane. */
|
|
81
|
+
private _tier?;
|
|
82
|
+
/** Active XMLHttpRequest handle for cancellation/pause semantics. */
|
|
43
83
|
private _activeXhr?;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/**
|
|
84
|
+
constructor(client: HttpClient, path: string, data: Blob,
|
|
85
|
+
/** Filename */
|
|
86
|
+
name: string, contentType: string, options: UploadOptions,
|
|
87
|
+
/** Tenant ID, inherited from SDK config */
|
|
88
|
+
tenantId: string);
|
|
89
|
+
/**
|
|
90
|
+
* Register observers for upload lifecycle events.
|
|
91
|
+
* @param event Only `'state_changed'` is supported.
|
|
92
|
+
* @param nextOrObserver Progress callback or observer object.
|
|
93
|
+
* @param error Error callback.
|
|
94
|
+
* @param complete Completion callback.
|
|
95
|
+
* @returns Unsubscribe function.
|
|
96
|
+
*/
|
|
48
97
|
on(event: 'state_changed', nextOrObserver?: Observer<UploadTaskSnapshot> | ((snap: UploadTaskSnapshot) => void), error?: (err: Error) => void, complete?: () => void): () => void;
|
|
49
|
-
/**
|
|
98
|
+
/** Pause the upload. Works natively for multipart; simple uploads will restart on resume. */
|
|
50
99
|
pause(): boolean;
|
|
51
|
-
/** Resume a paused upload. */
|
|
100
|
+
/** Resume a paused upload from where it left off (multipart) or restart (simple). */
|
|
52
101
|
resume(): boolean;
|
|
53
|
-
/** Permanently cancel the upload, cleaning up
|
|
102
|
+
/** Permanently cancel the upload, cleaning up any in-progress server state. */
|
|
54
103
|
cancel(): boolean;
|
|
55
104
|
get snapshot(): UploadTaskSnapshot;
|
|
56
105
|
then<TResult1 = UploadResult, TResult2 = never>(onfulfilled?: ((value: UploadResult) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
@@ -58,85 +107,271 @@ declare class UploadTask implements Promise<UploadResult> {
|
|
|
58
107
|
finally(onfinally?: (() => void) | null): Promise<UploadResult>;
|
|
59
108
|
readonly [Symbol.toStringTag] = "UploadTask";
|
|
60
109
|
private _start;
|
|
110
|
+
/**
|
|
111
|
+
* Simple upload path (< 50 MB):
|
|
112
|
+
* 1. Obtain a presigned upload URL from the control plane
|
|
113
|
+
* 2. PUT directly to MinIO/S3 from the browser
|
|
114
|
+
* 3. Confirm via control plane (updates metadata, triggers quota + audit)
|
|
115
|
+
*/
|
|
61
116
|
private _startSimple;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Multipart upload path (>= 50 MB) via Tier 1 (S3):
|
|
119
|
+
* 1. Initiate multipart session on control plane
|
|
120
|
+
* 2. Upload each chunk to a separate presigned URL
|
|
121
|
+
* 3. Complete the session (S3 assembles the object)
|
|
122
|
+
*/
|
|
123
|
+
private _startMultipart;
|
|
124
|
+
private _continueMultipart;
|
|
125
|
+
private _putToPresignedUrl;
|
|
126
|
+
private _uploadChunkXhr;
|
|
127
|
+
/** Pushes a fresh snapshot to all registered observers. */
|
|
65
128
|
private _notifyObservers;
|
|
129
|
+
/** Centralized terminal error handler for all upload flows. */
|
|
66
130
|
private _handleError;
|
|
67
131
|
}
|
|
68
132
|
|
|
133
|
+
/** SDK initialization config */
|
|
69
134
|
interface TelestackConfig {
|
|
135
|
+
/** Full URL to your TelestackStorage worker, e.g. https://storage.example.com */
|
|
70
136
|
baseUrl: string;
|
|
137
|
+
/** Tenant ID — scopes all operations to a specific tenant's bucket */
|
|
138
|
+
tenantId: string;
|
|
139
|
+
/** Optional project context used by internal/admin operations */
|
|
140
|
+
projectId?: string;
|
|
141
|
+
/** Optional organization context used by internal/admin operations */
|
|
142
|
+
orgId?: string;
|
|
143
|
+
/** API Key for server-to-server or developer access */
|
|
71
144
|
apiKey?: string;
|
|
145
|
+
/** JWT Bearer token for end-user auth (from your auth provider) */
|
|
72
146
|
token?: string;
|
|
73
|
-
|
|
147
|
+
/** Default upload options applied to all uploads */
|
|
74
148
|
defaultUploadOptions?: Partial<UploadOptions>;
|
|
75
149
|
}
|
|
150
|
+
/** Represents a file stored in TelestackStorage */
|
|
76
151
|
interface FileMetadata {
|
|
77
|
-
|
|
152
|
+
/** Internal document ID */
|
|
153
|
+
$id: string;
|
|
154
|
+
/** Tenant/project id owning this file. */
|
|
78
155
|
tenant_id: string;
|
|
79
|
-
|
|
156
|
+
/** Parent directory id (`root` for root-level files). */
|
|
157
|
+
directory_id: string;
|
|
158
|
+
/** File display name. */
|
|
80
159
|
name: string;
|
|
160
|
+
/** Canonical hashed path used for lookups. */
|
|
161
|
+
path_hash: string;
|
|
162
|
+
/** Current active version id. */
|
|
163
|
+
current_version_id: string;
|
|
164
|
+
/** Cached file size in bytes. */
|
|
165
|
+
cached_size: number;
|
|
166
|
+
/** Lifecycle status in metadata DB. */
|
|
167
|
+
status: 'pending' | 'active' | 'deleted';
|
|
168
|
+
/** ISO timestamp when metadata row was created. */
|
|
169
|
+
created_at: string;
|
|
170
|
+
/** ISO timestamp when metadata row was last updated. */
|
|
171
|
+
updated_at: string;
|
|
172
|
+
}
|
|
173
|
+
/** Represents a specific version of a stored file */
|
|
174
|
+
interface FileVersionMetadata {
|
|
175
|
+
/** Version row id. */
|
|
176
|
+
$id: string;
|
|
177
|
+
/** Parent file id. */
|
|
178
|
+
file_id: string;
|
|
179
|
+
/** Object storage key for this specific version. */
|
|
180
|
+
storage_key: string;
|
|
181
|
+
/** 'tier1' = S3-compatible (MinIO/R2/S3) */
|
|
182
|
+
provider: 'tier1';
|
|
183
|
+
/** Version size in bytes. */
|
|
81
184
|
size: number;
|
|
185
|
+
/** MIME type recorded for this version. */
|
|
82
186
|
content_type: string;
|
|
187
|
+
/** Provider ETag if available. */
|
|
188
|
+
etag?: string;
|
|
189
|
+
/** ISO timestamp when the version row was created. */
|
|
190
|
+
created_at: string;
|
|
191
|
+
}
|
|
192
|
+
/** A bucket record corresponding to a tenant's storage configuration */
|
|
193
|
+
interface BucketMetadata {
|
|
194
|
+
/** Bucket row id. */
|
|
195
|
+
$id: string;
|
|
196
|
+
/** Tenant/project id owning the bucket. */
|
|
197
|
+
tenant_id: string;
|
|
198
|
+
/** Organization/owner id associated with the bucket. */
|
|
83
199
|
owner_id: string;
|
|
84
|
-
|
|
85
|
-
|
|
200
|
+
/** Bucket-level public-read toggle. */
|
|
201
|
+
is_public: boolean;
|
|
202
|
+
/** Physical storage tier. */
|
|
203
|
+
tier: 'tier1';
|
|
204
|
+
/** Commercial plan for this bucket. */
|
|
205
|
+
plan: 'free' | 'paid';
|
|
206
|
+
/** Operational status for access control. */
|
|
207
|
+
status: 'active' | 'suspended';
|
|
208
|
+
/** Quota limit in bytes. */
|
|
209
|
+
storage_limit: number;
|
|
210
|
+
/** ISO timestamp when bucket row was created. */
|
|
86
211
|
created_at: string;
|
|
212
|
+
/** ISO timestamp when bucket row was last updated. */
|
|
87
213
|
updated_at: string;
|
|
88
214
|
}
|
|
215
|
+
/** Options for upload operations */
|
|
89
216
|
interface UploadOptions {
|
|
90
|
-
|
|
91
|
-
userId
|
|
92
|
-
|
|
217
|
+
/** User ID to associate with the upload */
|
|
218
|
+
userId?: string;
|
|
219
|
+
/** Directory ID to place the file into (defaults to root) */
|
|
220
|
+
directoryId?: string;
|
|
221
|
+
/** Size of each multipart chunk in bytes (default: 10MB) */
|
|
93
222
|
chunkSize?: number;
|
|
223
|
+
/** Base64 AES-GCM key for client-side E2EE before upload */
|
|
94
224
|
encryptionKey?: string;
|
|
225
|
+
/** Image compression settings applied before upload */
|
|
95
226
|
compressImage?: {
|
|
96
227
|
maxWidth?: number;
|
|
97
228
|
maxHeight?: number;
|
|
229
|
+
/** 0.0 (worst) to 1.0 (best), default 0.85 */
|
|
98
230
|
quality?: number;
|
|
99
231
|
};
|
|
100
232
|
}
|
|
233
|
+
/** Options for download operations */
|
|
101
234
|
interface DownloadOptions {
|
|
235
|
+
/** Retrieve a specific version by its ID */
|
|
102
236
|
versionId?: string;
|
|
237
|
+
/** Expiry in seconds for the presigned URL (default: 3600) */
|
|
238
|
+
expiresIn?: number;
|
|
239
|
+
/** Download mode for content disposition handling */
|
|
240
|
+
mode?: 'download' | 'inline';
|
|
103
241
|
}
|
|
242
|
+
/** Options for listing files */
|
|
104
243
|
interface ListOptions {
|
|
105
|
-
|
|
244
|
+
/** Parent directory id, or `null` for root. */
|
|
245
|
+
directoryId?: string | null;
|
|
246
|
+
/** Max records to return. */
|
|
106
247
|
limit?: number;
|
|
248
|
+
/** Pagination offset. */
|
|
249
|
+
offset?: number;
|
|
107
250
|
}
|
|
251
|
+
/** Options for searching files */
|
|
108
252
|
interface SearchOptions {
|
|
253
|
+
/** Name prefix or substring filter */
|
|
109
254
|
query?: string;
|
|
110
|
-
|
|
255
|
+
/** Filter by file extension, e.g. 'pdf' */
|
|
256
|
+
extension?: string;
|
|
257
|
+
/** Filter by minimum file size in bytes */
|
|
258
|
+
minSize?: number;
|
|
111
259
|
limit?: number;
|
|
260
|
+
offset?: number;
|
|
112
261
|
}
|
|
262
|
+
/** Result of a search query */
|
|
113
263
|
interface SearchResult {
|
|
264
|
+
/** True on successful query execution. */
|
|
114
265
|
success: boolean;
|
|
266
|
+
/** Matched files after filtering. */
|
|
115
267
|
files: FileMetadata[];
|
|
268
|
+
/** Total records returned by the current query. */
|
|
269
|
+
total: number;
|
|
116
270
|
}
|
|
271
|
+
/** Result of a completed upload */
|
|
117
272
|
interface UploadResult {
|
|
118
|
-
|
|
273
|
+
/** True when upload/confirm flow completed successfully. */
|
|
274
|
+
success: boolean;
|
|
275
|
+
/** File metadata id. */
|
|
276
|
+
file_id: string;
|
|
277
|
+
/** Active version id. */
|
|
278
|
+
version_id: string;
|
|
279
|
+
/** Whether multipart S3 upload was used */
|
|
119
280
|
resumable: boolean;
|
|
120
281
|
}
|
|
282
|
+
/** Result of a batch delete */
|
|
121
283
|
interface BatchDeleteResult {
|
|
284
|
+
/** True when batch request is accepted/completed. */
|
|
122
285
|
success: boolean;
|
|
123
|
-
|
|
124
|
-
|
|
286
|
+
/** Status message (queued or completed). */
|
|
287
|
+
message: string;
|
|
125
288
|
}
|
|
126
|
-
|
|
289
|
+
/** Result of a batch copy/move */
|
|
290
|
+
interface BatchMutationResult {
|
|
291
|
+
/** True when batch request succeeds. */
|
|
127
292
|
success: boolean;
|
|
293
|
+
/** Provider result payloads per item. */
|
|
128
294
|
results: any[];
|
|
129
295
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
296
|
+
/** Public path visibility rule for selective anonymous access. */
|
|
297
|
+
interface PublicPathRule {
|
|
298
|
+
/** Rule row id. */
|
|
299
|
+
$id: string;
|
|
300
|
+
/** Tenant/project id owning the rule. */
|
|
301
|
+
tenant_id: string;
|
|
302
|
+
/** Public prefix (no trailing wildcard in DB). */
|
|
303
|
+
path_prefix: string;
|
|
304
|
+
/** Public-read toggle for this prefix. */
|
|
305
|
+
is_public: boolean;
|
|
306
|
+
/** ISO timestamp when rule was created. */
|
|
307
|
+
created_at: string;
|
|
308
|
+
}
|
|
309
|
+
/** Response payload for API key generation. */
|
|
310
|
+
interface GeneratedApiKeyResponse {
|
|
311
|
+
/** True when key creation succeeds. */
|
|
312
|
+
success: boolean;
|
|
313
|
+
/** Plaintext API key. Returned once and must be stored client-side securely. */
|
|
314
|
+
apiKey: string;
|
|
315
|
+
key: {
|
|
316
|
+
/** API key row id. */
|
|
317
|
+
id: string;
|
|
318
|
+
/** Display name assigned to the key. */
|
|
319
|
+
name: string;
|
|
320
|
+
/** Tenant/project id associated with the key. */
|
|
321
|
+
tenant_id: string;
|
|
322
|
+
/** ISO timestamp when the key was created. */
|
|
323
|
+
created_at: string;
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
/** Storage usage analytics for a tenant */
|
|
327
|
+
interface TenantUsageStats {
|
|
328
|
+
/** Aggregated stored bytes. */
|
|
329
|
+
total_bytes: number;
|
|
330
|
+
/** Aggregated active file count. */
|
|
331
|
+
total_files: number;
|
|
332
|
+
/** ISO timestamp of last aggregation sync. */
|
|
333
|
+
last_aggregated_at: string;
|
|
133
334
|
}
|
|
134
|
-
/**
|
|
335
|
+
/** Time-series analytics data point */
|
|
336
|
+
interface UsageAnalytics {
|
|
337
|
+
/** Read operation count. */
|
|
338
|
+
reads: number;
|
|
339
|
+
/** Write operation count. */
|
|
340
|
+
writes: number;
|
|
341
|
+
/** Bandwidth usage in bytes. */
|
|
342
|
+
bandwidth: number;
|
|
343
|
+
/** Aggregation period in days. */
|
|
344
|
+
period_days: number;
|
|
345
|
+
}
|
|
346
|
+
/** A real-time event emitted from the SSE stream */
|
|
347
|
+
interface StorageEvent {
|
|
348
|
+
/** Event row id. */
|
|
349
|
+
$id: string;
|
|
350
|
+
/** Tenant/project id for the event. */
|
|
351
|
+
tenant_id: string;
|
|
352
|
+
/** Event type key (e.g. `file.upload.confirmed`). */
|
|
353
|
+
event_type: string;
|
|
354
|
+
/** Logical resource type affected by the event. */
|
|
355
|
+
resource_type: string;
|
|
356
|
+
/** Resource id affected by the event. */
|
|
357
|
+
resource_id: string;
|
|
358
|
+
/** JSON payload string for event-specific context. */
|
|
359
|
+
payload: string;
|
|
360
|
+
/** Monotonic sequence for event stream ordering. */
|
|
361
|
+
sequence_number: string;
|
|
362
|
+
/** ISO timestamp when event was written. */
|
|
363
|
+
created_at: string;
|
|
364
|
+
}
|
|
365
|
+
/** Upload state, matching Firebase Storage semantics */
|
|
135
366
|
type UploadState = 'processing' | 'running' | 'paused' | 'success' | 'error' | 'canceled';
|
|
136
367
|
interface UploadTaskSnapshot {
|
|
368
|
+
/** Uploaded bytes at this observation point. */
|
|
137
369
|
bytesTransferred: number;
|
|
370
|
+
/** Total bytes for this upload task. */
|
|
138
371
|
totalBytes: number;
|
|
372
|
+
/** Current upload lifecycle state. */
|
|
139
373
|
state: UploadState;
|
|
374
|
+
/** Reference to the associated UploadTask instance. */
|
|
140
375
|
task: UploadTask;
|
|
141
376
|
}
|
|
142
377
|
type Observer<T> = {
|
|
@@ -146,158 +381,402 @@ type Observer<T> = {
|
|
|
146
381
|
};
|
|
147
382
|
|
|
148
383
|
/**
|
|
149
|
-
* Base
|
|
384
|
+
* Base class for Telestack path references.
|
|
150
385
|
*/
|
|
151
386
|
declare abstract class StorageRef {
|
|
152
387
|
protected readonly client: HttpClient;
|
|
153
388
|
readonly path: string;
|
|
154
389
|
readonly tenantId: string;
|
|
155
390
|
constructor(client: HttpClient, path: string, tenantId: string);
|
|
156
|
-
/**
|
|
391
|
+
/**
|
|
392
|
+
* Navigate to a child path. Returns a FileRef or DirRef based on whether
|
|
393
|
+
* the resulting path ends with a `/`.
|
|
394
|
+
*/
|
|
157
395
|
child(childPath: string): StorageRef;
|
|
158
396
|
}
|
|
159
397
|
/**
|
|
160
|
-
* Reference
|
|
398
|
+
* Reference to a directory (folder) in Telestack Storage.
|
|
161
399
|
*/
|
|
162
400
|
declare class DirRef extends StorageRef {
|
|
163
|
-
/**
|
|
164
|
-
|
|
401
|
+
/**
|
|
402
|
+
* List all files in this directory.
|
|
403
|
+
*/
|
|
404
|
+
listAll(options?: ListOptions): Promise<{
|
|
405
|
+
files: FileMetadata[];
|
|
406
|
+
directories: any[];
|
|
407
|
+
}>;
|
|
408
|
+
/**
|
|
409
|
+
* Create this directory and get back the directory document.
|
|
410
|
+
*/
|
|
411
|
+
create(parentId?: string): Promise<any>;
|
|
412
|
+
/**
|
|
413
|
+
* Delete this directory and all its contents asynchronously (background queue).
|
|
414
|
+
*/
|
|
415
|
+
delete(directoryId: string): Promise<{
|
|
416
|
+
success: boolean;
|
|
417
|
+
message: string;
|
|
418
|
+
}>;
|
|
419
|
+
/**
|
|
420
|
+
* Search within this directory's prefix.
|
|
421
|
+
*/
|
|
422
|
+
search(options: SearchOptions): Promise<SearchResult>;
|
|
165
423
|
}
|
|
166
424
|
/**
|
|
167
|
-
* Reference
|
|
425
|
+
* Reference to a specific file in Telestack Storage.
|
|
426
|
+
*
|
|
427
|
+
* @example
|
|
428
|
+
* ```ts
|
|
429
|
+
* const fileRef = storage.ref('documents/report.pdf');
|
|
430
|
+
*
|
|
431
|
+
* // Upload with progress tracking
|
|
432
|
+
* const task = fileRef.put(pdfBlob, { userId: 'u_abc' });
|
|
433
|
+
* task.on('state_changed', snap => console.log(snap.bytesTransferred));
|
|
434
|
+
*
|
|
435
|
+
* // Download URL
|
|
436
|
+
* const url = await fileRef.getDownloadUrl();
|
|
437
|
+
* ```
|
|
168
438
|
*/
|
|
169
439
|
declare class FileRef extends StorageRef {
|
|
440
|
+
private resolveFileRecord;
|
|
170
441
|
/**
|
|
171
|
-
* Upload a File
|
|
172
|
-
*
|
|
442
|
+
* Upload a File or Blob. Returns an UploadTask you can observe, pause,
|
|
443
|
+
* resume, and cancel — just like Firebase Storage.
|
|
173
444
|
*/
|
|
174
|
-
put(data: File | Blob, options
|
|
445
|
+
put(data: File | Blob, options?: UploadOptions): UploadTask;
|
|
175
446
|
/**
|
|
176
|
-
* Upload raw bytes
|
|
447
|
+
* Upload raw bytes.
|
|
177
448
|
*/
|
|
178
|
-
putBytes(data: ArrayBuffer, contentType: string, options
|
|
179
|
-
/** Get a time-limited presigned download URL. */
|
|
180
|
-
getDownloadUrl(options?: DownloadOptions): Promise<string>;
|
|
449
|
+
putBytes(data: ArrayBuffer, contentType: string, options?: UploadOptions): UploadTask;
|
|
181
450
|
/**
|
|
182
|
-
*
|
|
183
|
-
* Requires the exact Base64 AES-GCM key used during `put()`.
|
|
451
|
+
* Get a time-limited presigned download URL (302 redirect to CDN/S3).
|
|
184
452
|
*/
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
453
|
+
getDownloadUrl(fileId?: string, options?: DownloadOptions): Promise<string>;
|
|
454
|
+
/**
|
|
455
|
+
* Access this file via the public CDN URL (only works if bucket is_public = true).
|
|
456
|
+
* Returns the redirect URL directly.
|
|
457
|
+
*/
|
|
458
|
+
getCdnUrl(path: string): string;
|
|
459
|
+
/**
|
|
460
|
+
* Download and decrypt an E2EE-encrypted file entirely in the browser.
|
|
461
|
+
* Requires the same Base64 AES-GCM key used during upload.
|
|
462
|
+
*/
|
|
463
|
+
getDecryptedBlob(encryptionKey: string, originalMimeType: string, fileId?: string): Promise<Blob>;
|
|
464
|
+
/**
|
|
465
|
+
* Get the file's metadata record from the database.
|
|
466
|
+
*/
|
|
467
|
+
getMetadata(fileId?: string): Promise<FileMetadata>;
|
|
468
|
+
/**
|
|
469
|
+
* Get all versions of this file.
|
|
470
|
+
*/
|
|
471
|
+
getVersions(fileId?: string): Promise<FileVersionMetadata[]>;
|
|
472
|
+
/**
|
|
473
|
+
* Soft-delete a file (marks as deleted, preserves versions).
|
|
474
|
+
*/
|
|
475
|
+
delete(fileId?: string): Promise<void>;
|
|
200
476
|
}
|
|
201
477
|
|
|
202
478
|
/**
|
|
203
479
|
* Fluent builder for batch file operations.
|
|
204
|
-
*
|
|
480
|
+
* Each operation compiles to a single API request, handled by the background queue
|
|
481
|
+
* for large datasets to keep the API responsive.
|
|
205
482
|
*
|
|
206
483
|
* @example
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* await storage.batch().
|
|
484
|
+
* ```ts
|
|
485
|
+
* // Delete multiple files
|
|
486
|
+
* await storage.batch().delete(['fileId1', 'fileId2']).run();
|
|
487
|
+
*
|
|
488
|
+
* // Copy files to a new directory
|
|
489
|
+
* await storage.batch().copy([{ sourceId: 'id1', destDirId: 'dir2', destName: 'copy.pdf', destPath: 'docs/copy.pdf' }]).run();
|
|
490
|
+
* ```
|
|
210
491
|
*/
|
|
211
492
|
declare class BatchBuilder {
|
|
212
493
|
private readonly client;
|
|
494
|
+
private readonly tenantId;
|
|
213
495
|
private _op;
|
|
214
|
-
private
|
|
215
|
-
private
|
|
216
|
-
constructor(client: HttpClient);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
496
|
+
private _fileIds;
|
|
497
|
+
private _mappings;
|
|
498
|
+
constructor(client: HttpClient, tenantId: string);
|
|
499
|
+
/**
|
|
500
|
+
* Queue file IDs for batch deletion. Runs in background queue.
|
|
501
|
+
*/
|
|
502
|
+
delete(fileIds: string[]): this;
|
|
503
|
+
/**
|
|
504
|
+
* Queue copy operations (file ID → new directory).
|
|
505
|
+
*/
|
|
506
|
+
copy(mappings: {
|
|
507
|
+
sourceId: string;
|
|
508
|
+
destDirId: string;
|
|
509
|
+
destName: string;
|
|
510
|
+
destPath: string;
|
|
511
|
+
}[]): this;
|
|
512
|
+
/**
|
|
513
|
+
* Queue move operations (file ID → new directory/name).
|
|
514
|
+
*/
|
|
515
|
+
move(mappings: {
|
|
516
|
+
fileId: string;
|
|
517
|
+
destDirId: string;
|
|
518
|
+
destName: string;
|
|
519
|
+
destPath: string;
|
|
520
|
+
}[]): this;
|
|
521
|
+
/**
|
|
522
|
+
* Execute the queued batch operation.
|
|
523
|
+
*/
|
|
524
|
+
run(): Promise<BatchDeleteResult | BatchMutationResult>;
|
|
221
525
|
}
|
|
222
526
|
|
|
223
527
|
/**
|
|
224
528
|
* Fluent builder for searching files via Metadata or Full-Text queries.
|
|
225
529
|
*
|
|
226
530
|
* @example
|
|
531
|
+
* ```ts
|
|
227
532
|
* const files = await storage.query()
|
|
228
|
-
* .
|
|
229
|
-
* .
|
|
533
|
+
* .search('report')
|
|
534
|
+
* .withExtension('pdf')
|
|
535
|
+
* .minSize(1024)
|
|
230
536
|
* .limit(10)
|
|
231
537
|
* .get();
|
|
538
|
+
* ```
|
|
232
539
|
*/
|
|
233
540
|
declare class QueryBuilder {
|
|
234
541
|
private readonly client;
|
|
542
|
+
private readonly tenantId;
|
|
235
543
|
private _query;
|
|
236
|
-
private
|
|
544
|
+
private _extension;
|
|
545
|
+
private _minSize;
|
|
237
546
|
private _limit;
|
|
238
|
-
|
|
239
|
-
|
|
547
|
+
private _offset;
|
|
548
|
+
constructor(client: HttpClient, tenantId: string);
|
|
549
|
+
/** Find files whose names match this text */
|
|
240
550
|
search(text: string): this;
|
|
241
|
-
|
|
551
|
+
/** Filter by file extension (e.g., 'pdf', 'png') */
|
|
552
|
+
withExtension(ext: string): this;
|
|
553
|
+
/** Filter by minimum file size in bytes */
|
|
554
|
+
minSize(bytes: number): this;
|
|
555
|
+
/** Set the maximum number of results (default 20, max 100) */
|
|
242
556
|
limit(n: number): this;
|
|
557
|
+
/** Set the number of results to skip (for pagination) */
|
|
558
|
+
offset(n: number): this;
|
|
559
|
+
/** Execute the search and return the list of matching files */
|
|
243
560
|
get(): Promise<FileMetadata[]>;
|
|
561
|
+
/** Alias for get() */
|
|
244
562
|
run(): Promise<FileMetadata[]>;
|
|
245
563
|
}
|
|
246
564
|
|
|
247
565
|
/**
|
|
248
|
-
* TelestackStorage
|
|
249
|
-
*
|
|
566
|
+
* @class TelestackStorage
|
|
567
|
+
* The main entry point for the Telestack Storage Web SDK.
|
|
568
|
+
*
|
|
569
|
+
* Mirrors Firebase Storage's fluent `.ref()` API while adding enterprise-grade
|
|
570
|
+
* features: tiered storage (Internal + S3), realtime SSE, analytics, search,
|
|
571
|
+
* and batch operations.
|
|
250
572
|
*
|
|
251
573
|
* @example
|
|
252
574
|
* ```ts
|
|
575
|
+
* import { TelestackStorage } from '@telestack/storage-web';
|
|
576
|
+
*
|
|
253
577
|
* const storage = new TelestackStorage({
|
|
254
578
|
* baseUrl: 'https://storage.yourdomain.com',
|
|
255
|
-
* tenantId: '
|
|
256
|
-
* apiKey: '
|
|
579
|
+
* tenantId: 'tenant_abc',
|
|
580
|
+
* apiKey: 'tk_live_xxx',
|
|
257
581
|
* });
|
|
258
582
|
*
|
|
259
|
-
* // Upload
|
|
260
|
-
* const task = storage.ref('
|
|
261
|
-
* task.on('state_changed',
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
* );
|
|
583
|
+
* // Upload a file
|
|
584
|
+
* const task = storage.ref('photos/avatar.png').put(file);
|
|
585
|
+
* task.on('state_changed', snap => {
|
|
586
|
+
* const pct = (snap.bytesTransferred / snap.totalBytes * 100).toFixed(0);
|
|
587
|
+
* console.log(`${pct}% uploaded`);
|
|
588
|
+
* }, console.error, () => console.log('Done!'));
|
|
266
589
|
*
|
|
267
|
-
* //
|
|
268
|
-
*
|
|
269
|
-
*
|
|
590
|
+
* // Search files
|
|
591
|
+
* const results = await storage.search({ query: 'report', extension: 'pdf' });
|
|
592
|
+
*
|
|
593
|
+
* // Usage analytics
|
|
594
|
+
* const stats = await storage.getUsageStats(7);
|
|
270
595
|
* ```
|
|
271
596
|
*/
|
|
272
597
|
declare class TelestackStorage {
|
|
273
598
|
private readonly config;
|
|
274
|
-
|
|
599
|
+
/** @internal */
|
|
600
|
+
readonly http: HttpClient;
|
|
275
601
|
readonly tenantId: string;
|
|
276
602
|
constructor(config: TelestackConfig);
|
|
277
|
-
/**
|
|
603
|
+
/**
|
|
604
|
+
* Create a cloned client with updated tenant/project/org defaults.
|
|
605
|
+
* Helpful in multi-tenant consoles where context changes often.
|
|
606
|
+
*/
|
|
607
|
+
withContext(context: {
|
|
608
|
+
tenantId?: string;
|
|
609
|
+
projectId?: string;
|
|
610
|
+
orgId?: string;
|
|
611
|
+
}): TelestackStorage;
|
|
612
|
+
/**
|
|
613
|
+
* Create a cloned client with updated auth credentials.
|
|
614
|
+
* Passing `null` explicitly clears an existing credential.
|
|
615
|
+
*/
|
|
616
|
+
withAuth(auth: {
|
|
617
|
+
apiKey?: string | null;
|
|
618
|
+
token?: string | null;
|
|
619
|
+
}): TelestackStorage;
|
|
620
|
+
/**
|
|
621
|
+
* Get a fluent reference to a specific file path.
|
|
622
|
+
* Use this as the starting point for uploads, downloads, and file metadata.
|
|
623
|
+
*
|
|
624
|
+
* @param path - Full path within the tenant bucket, e.g. `'documents/report.pdf'`
|
|
625
|
+
*/
|
|
278
626
|
ref(path: string): FileRef;
|
|
279
|
-
/**
|
|
627
|
+
/**
|
|
628
|
+
* Get a fluent reference to a directory (prefix).
|
|
629
|
+
*
|
|
630
|
+
* @param path - Directory path, e.g. `'documents/'` or `'images'`
|
|
631
|
+
*/
|
|
280
632
|
dir(path: string): DirRef;
|
|
281
|
-
/**
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
633
|
+
/**
|
|
634
|
+
* Get this tenant's bucket configuration.
|
|
635
|
+
*/
|
|
636
|
+
getBucket(): Promise<BucketMetadata>;
|
|
637
|
+
/**
|
|
638
|
+
* List files in a directory. Pass `null` for the root.
|
|
639
|
+
*/
|
|
640
|
+
list(options?: ListOptions): Promise<{
|
|
641
|
+
files: FileMetadata[];
|
|
642
|
+
directories: any[];
|
|
287
643
|
}>;
|
|
288
|
-
/**
|
|
289
|
-
|
|
290
|
-
|
|
644
|
+
/**
|
|
645
|
+
* Search files by name, extension, or minimum size.
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* ```ts
|
|
649
|
+
* const { files, total } = await storage.search({ query: 'invoice', extension: 'pdf' });
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
search(options: SearchOptions): Promise<SearchResult>;
|
|
653
|
+
/**
|
|
654
|
+
* Get a fluent query builder for advanced searching.
|
|
655
|
+
*
|
|
656
|
+
* @example
|
|
657
|
+
* ```ts
|
|
658
|
+
* const files = await storage.query().search('invoice').get();
|
|
659
|
+
* ```
|
|
660
|
+
*/
|
|
291
661
|
query(): QueryBuilder;
|
|
292
|
-
/**
|
|
293
|
-
|
|
294
|
-
|
|
662
|
+
/**
|
|
663
|
+
* Get a fluent batch operation builder.
|
|
664
|
+
*
|
|
665
|
+
* @example
|
|
666
|
+
* ```ts
|
|
667
|
+
* await storage.batch()
|
|
668
|
+
* .delete(['id1', 'id2', 'id3'])
|
|
669
|
+
* .commit();
|
|
670
|
+
* ```
|
|
671
|
+
*/
|
|
672
|
+
batch(): BatchBuilder;
|
|
673
|
+
/**
|
|
674
|
+
* Bulk delete files by their IDs. Queued in background for large lists.
|
|
675
|
+
*/
|
|
676
|
+
batchDelete(fileIds: string[]): Promise<BatchDeleteResult>;
|
|
677
|
+
/**
|
|
678
|
+
* Copy multiple files to new directories simultaneously.
|
|
679
|
+
*/
|
|
680
|
+
batchCopy(mappings: {
|
|
681
|
+
sourceId: string;
|
|
682
|
+
destDirId: string;
|
|
683
|
+
destName: string;
|
|
684
|
+
destPath: string;
|
|
685
|
+
}[]): Promise<BatchMutationResult>;
|
|
686
|
+
/**
|
|
687
|
+
* Move multiple files to new directories/names simultaneously.
|
|
688
|
+
*/
|
|
689
|
+
batchMove(mappings: {
|
|
690
|
+
fileId: string;
|
|
691
|
+
destDirId: string;
|
|
692
|
+
destName: string;
|
|
693
|
+
destPath: string;
|
|
694
|
+
}[]): Promise<BatchMutationResult>;
|
|
695
|
+
/**
|
|
696
|
+
* Get aggregated storage usage for the tenant.
|
|
697
|
+
*
|
|
698
|
+
* @param days - Number of days to include in the time window (default: 7)
|
|
699
|
+
*/
|
|
700
|
+
getUsageStats(days?: number): Promise<UsageAnalytics>;
|
|
701
|
+
/**
|
|
702
|
+
* Subscribe to real-time storage events for this tenant via SSE.
|
|
703
|
+
* Events include file uploads, deletions, and system changes.
|
|
704
|
+
*
|
|
705
|
+
* @returns An `unsubscribe` function — call it to close the connection.
|
|
706
|
+
*
|
|
707
|
+
* @example
|
|
708
|
+
* ```ts
|
|
709
|
+
* const unsubscribe = storage.onEvent((event) => {
|
|
710
|
+
* console.log(event.event_type, event.resource_id);
|
|
711
|
+
* });
|
|
712
|
+
*
|
|
713
|
+
* // Later
|
|
714
|
+
* unsubscribe();
|
|
715
|
+
* ```
|
|
716
|
+
*/
|
|
717
|
+
onEvent(callback: (event: StorageEvent) => void): () => void;
|
|
718
|
+
/**
|
|
719
|
+
* Initialize the internal database schema (admin only — run once on bootstrap).
|
|
720
|
+
*/
|
|
721
|
+
initDatabase(): Promise<{
|
|
722
|
+
success: boolean;
|
|
295
723
|
message: string;
|
|
296
724
|
}>;
|
|
297
|
-
/**
|
|
725
|
+
/**
|
|
726
|
+
* Generate a new API key (admin only). The raw key is returned once — store it securely.
|
|
727
|
+
*
|
|
728
|
+
* @example
|
|
729
|
+
* ```ts
|
|
730
|
+
* const { apiKey } = await storage.generateApiKey('my-backend-service');
|
|
731
|
+
* ```
|
|
732
|
+
*/
|
|
733
|
+
generateApiKey(name?: string): Promise<GeneratedApiKeyResponse>;
|
|
734
|
+
/**
|
|
735
|
+
* Revoke an existing API key by its database ID.
|
|
736
|
+
*/
|
|
298
737
|
revokeApiKey(keyId: string): Promise<void>;
|
|
299
|
-
/**
|
|
300
|
-
|
|
738
|
+
/**
|
|
739
|
+
* Read analytics from internal admin API for the configured tenant.
|
|
740
|
+
*/
|
|
741
|
+
getInternalAnalytics(tenantId?: string): Promise<Array<{
|
|
742
|
+
date: string;
|
|
743
|
+
reads: number;
|
|
744
|
+
writes: number;
|
|
745
|
+
bandwidth: number;
|
|
746
|
+
}>>;
|
|
747
|
+
/**
|
|
748
|
+
* Fetch internal bucket information including effective quota.
|
|
749
|
+
*/
|
|
750
|
+
getInternalBucketInfo(tenantId?: string): Promise<{
|
|
751
|
+
tier: string;
|
|
752
|
+
quotaLimit: number;
|
|
753
|
+
bucket: BucketMetadata;
|
|
754
|
+
}>;
|
|
755
|
+
/**
|
|
756
|
+
* Toggle bucket visibility from internal admin API.
|
|
757
|
+
*/
|
|
758
|
+
updateBucketVisibility(isPublic: boolean, tenantId?: string): Promise<{
|
|
759
|
+
success: boolean;
|
|
760
|
+
bucket: BucketMetadata;
|
|
761
|
+
}>;
|
|
762
|
+
/**
|
|
763
|
+
* List granular public path rules.
|
|
764
|
+
*/
|
|
765
|
+
listPublicPathRules(tenantId?: string): Promise<PublicPathRule[]>;
|
|
766
|
+
/**
|
|
767
|
+
* Add a granular public path rule.
|
|
768
|
+
*/
|
|
769
|
+
addPublicPathRule(pathPrefix: string, tenantId?: string): Promise<PublicPathRule>;
|
|
770
|
+
/**
|
|
771
|
+
* Delete a granular public path rule by id.
|
|
772
|
+
*/
|
|
773
|
+
deletePublicPathRule(ruleId: string, tenantId?: string): Promise<void>;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
declare class TelestackError extends Error {
|
|
777
|
+
readonly status: number;
|
|
778
|
+
readonly code?: string | undefined;
|
|
779
|
+
constructor(message: string, status: number, code?: string | undefined);
|
|
301
780
|
}
|
|
302
781
|
|
|
303
782
|
declare class CryptoHelper {
|
|
@@ -333,4 +812,4 @@ declare class ImageHelper {
|
|
|
333
812
|
}): Promise<Blob>;
|
|
334
813
|
}
|
|
335
814
|
|
|
336
|
-
export { BatchBuilder, type
|
|
815
|
+
export { BatchBuilder, type BatchDeleteResult, type BatchMutationResult, type BucketMetadata, CryptoHelper, DirRef, type DownloadOptions, type FileMetadata, FileRef, type FileVersionMetadata, type GeneratedApiKeyResponse, HttpClient, ImageHelper, type ListOptions, type Observer, type PublicPathRule, QueryBuilder, type SearchOptions, type SearchResult, type StorageEvent, StorageRef, type TelestackConfig, TelestackError, TelestackStorage, type TenantUsageStats, type UploadOptions, type UploadResult, type UploadState, UploadTask, type UploadTaskSnapshot, type UsageAnalytics };
|