hydrousdb 2.0.1 → 2.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.
- package/LICENSE +1 -1
- package/README.md +976 -421
- package/dist/index.d.mts +226 -383
- package/dist/index.d.ts +226 -383
- package/dist/index.js +343 -593
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +339 -592
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -27
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Named storage keys.
|
|
3
|
+
* Create as many as you need in the HydrousDB dashboard and give each one a
|
|
4
|
+
* meaningful name — you'll reference it by name when calling storage methods.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* {
|
|
8
|
+
* main: 'ssk_main_…',
|
|
9
|
+
* avatars: 'ssk_avatars_…',
|
|
10
|
+
* documents: 'ssk_docs_…',
|
|
11
|
+
* }
|
|
12
|
+
*/
|
|
13
|
+
type StorageKeys = Record<string, string>;
|
|
1
14
|
interface HydrousConfig {
|
|
2
|
-
/** Your
|
|
15
|
+
/** Your HydrousDB project base URL */
|
|
3
16
|
url: string;
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
/**
|
|
17
|
+
/** Auth service key — used for all auth.* operations */
|
|
18
|
+
authKey: string;
|
|
19
|
+
/** Bucket security key — used for records.* and analytics.* operations */
|
|
20
|
+
bucketSecurityKey: string;
|
|
21
|
+
/**
|
|
22
|
+
* Storage keys object. Each property name is a label you choose; each
|
|
23
|
+
* value is a storage key (ssk_…) from your dashboard.
|
|
24
|
+
* You can have as many as you need.
|
|
25
|
+
*/
|
|
26
|
+
storageKeys: StorageKeys;
|
|
27
|
+
/** Optional global request timeout in milliseconds (default: 30 000) */
|
|
7
28
|
timeout?: number;
|
|
8
29
|
}
|
|
9
30
|
interface HydrousResponse<T = unknown> {
|
|
@@ -84,37 +105,28 @@ interface AnalyticsEvent {
|
|
|
84
105
|
sessionId?: string;
|
|
85
106
|
timestamp: number;
|
|
86
107
|
}
|
|
87
|
-
/** The bucket key (ssk_…) that authorizes access to a specific storage bucket */
|
|
88
|
-
type BucketKey = string;
|
|
89
108
|
type UploadStage = 'pending' | 'compressing' | 'uploading' | 'done' | 'error';
|
|
90
|
-
/** Fired for every progress tick during an upload */
|
|
91
109
|
interface UploadProgress {
|
|
92
|
-
/** 0-based index (always 0 for single uploads) */
|
|
110
|
+
/** 0-based file index (always 0 for single uploads) */
|
|
93
111
|
index: number;
|
|
94
|
-
/** Total files in
|
|
112
|
+
/** Total files in the operation */
|
|
95
113
|
total: number;
|
|
96
|
-
/** Destination path
|
|
114
|
+
/** Destination path in the bucket */
|
|
97
115
|
path: string;
|
|
98
116
|
/** Current lifecycle stage */
|
|
99
117
|
stage: UploadStage;
|
|
100
|
-
/** Bytes sent to the server so far */
|
|
101
118
|
bytesUploaded: number;
|
|
102
|
-
/** Total bytes to send */
|
|
103
119
|
totalBytes: number;
|
|
104
|
-
/** 0–100
|
|
120
|
+
/** 0 – 100 */
|
|
105
121
|
percent: number;
|
|
106
|
-
/** Upload speed in bytes/
|
|
122
|
+
/** Upload speed in bytes/sec; null until the first tick */
|
|
107
123
|
bytesPerSecond: number | null;
|
|
108
|
-
/** Estimated seconds remaining
|
|
124
|
+
/** Estimated seconds remaining; null until speed is known */
|
|
109
125
|
eta: number | null;
|
|
110
|
-
/** Set when stage === 'done' */
|
|
111
126
|
result?: UploadResult;
|
|
112
|
-
/** Set when stage === 'error' */
|
|
113
127
|
error?: string;
|
|
114
|
-
/** Set when stage === 'error' */
|
|
115
128
|
code?: string;
|
|
116
129
|
}
|
|
117
|
-
/** Per-file progress during a batch download */
|
|
118
130
|
interface DownloadProgress {
|
|
119
131
|
index: number;
|
|
120
132
|
total: number;
|
|
@@ -199,67 +211,44 @@ interface StorageStats {
|
|
|
199
211
|
compressionRatio: string;
|
|
200
212
|
}
|
|
201
213
|
interface UploadOptions {
|
|
202
|
-
/**
|
|
203
|
-
* Destination path within your bucket (e.g. "avatars/photo.jpg").
|
|
204
|
-
* Defaults to the file's original name.
|
|
205
|
-
*/
|
|
214
|
+
/** Destination path in the bucket (defaults to the file's original name) */
|
|
206
215
|
path?: string;
|
|
207
|
-
/**
|
|
208
|
-
* Replace the file if it already exists at the given path.
|
|
209
|
-
* @default false
|
|
210
|
-
*/
|
|
216
|
+
/** Replace the file if it already exists (default: false) */
|
|
211
217
|
overwrite?: boolean;
|
|
212
218
|
/**
|
|
213
|
-
* Called on every progress tick
|
|
214
|
-
* Use this to drive progress bars, speed
|
|
219
|
+
* Called on every progress tick.
|
|
220
|
+
* Use this to drive progress bars, speed displays, and ETAs.
|
|
215
221
|
*/
|
|
216
222
|
onProgress?: (progress: UploadProgress) => void;
|
|
217
223
|
}
|
|
218
224
|
interface BatchUploadOptions {
|
|
219
|
-
/**
|
|
220
|
-
* Folder prefix to prepend to all file names (e.g. "uploads/2024/").
|
|
221
|
-
* Individual path overrides take precedence if provided.
|
|
222
|
-
*/
|
|
225
|
+
/** Folder prefix prepended to every filename */
|
|
223
226
|
prefix?: string;
|
|
224
|
-
/**
|
|
225
|
-
* Per-file destination paths in the same order as the `files` array.
|
|
226
|
-
* If omitted, `prefix + file.name` is used.
|
|
227
|
-
*/
|
|
227
|
+
/** Per-file paths (same order as the `files` array; takes priority over prefix) */
|
|
228
228
|
paths?: string[];
|
|
229
|
-
/** @default false */
|
|
230
229
|
overwrite?: boolean;
|
|
231
|
-
/** Max simultaneous uploads (1–10
|
|
230
|
+
/** Max simultaneous server-side uploads (1–10, default 5) */
|
|
232
231
|
concurrency?: number;
|
|
233
|
-
/**
|
|
234
|
-
* Called on every progress tick for every file.
|
|
235
|
-
* The `index` field identifies which file the event belongs to.
|
|
236
|
-
*/
|
|
232
|
+
/** Called for every progress tick on every file */
|
|
237
233
|
onProgress?: (progress: UploadProgress) => void;
|
|
238
234
|
}
|
|
239
235
|
interface BatchDownloadOptions {
|
|
240
|
-
/** Max simultaneous downloads (1–10). @default 5 */
|
|
241
236
|
concurrency?: number;
|
|
242
|
-
/**
|
|
243
|
-
* Called when each file's download status changes.
|
|
244
|
-
*/
|
|
245
237
|
onProgress?: (progress: DownloadProgress) => void;
|
|
246
238
|
/**
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
* @default false
|
|
239
|
+
* Browser only — automatically triggers a Save dialog for each file as it
|
|
240
|
+
* arrives (default: false)
|
|
250
241
|
*/
|
|
251
242
|
autoSave?: boolean;
|
|
252
243
|
}
|
|
253
244
|
interface ListOptions {
|
|
254
|
-
/** Folder prefix to list (
|
|
245
|
+
/** Folder prefix to list (empty = bucket root) */
|
|
255
246
|
prefix?: string;
|
|
256
|
-
/** Max items per page (1–100). @default 50 */
|
|
257
247
|
limit?: number;
|
|
258
|
-
/** Pagination cursor returned from the previous call. */
|
|
259
248
|
cursor?: string;
|
|
260
249
|
}
|
|
261
250
|
interface SignedUrlOptions {
|
|
262
|
-
/** How long the URL stays valid
|
|
251
|
+
/** How long the URL stays valid in seconds (default: 3600) */
|
|
263
252
|
expiresIn?: number;
|
|
264
253
|
}
|
|
265
254
|
|
|
@@ -268,39 +257,17 @@ declare class AuthClient {
|
|
|
268
257
|
private readonly headers;
|
|
269
258
|
private session;
|
|
270
259
|
constructor(config: HydrousConfig);
|
|
271
|
-
/**
|
|
272
|
-
* Create a new user account and return a session.
|
|
273
|
-
*
|
|
274
|
-
* @example
|
|
275
|
-
* const { data, error } = await hydrous.auth.signUp({
|
|
276
|
-
* email: 'user@example.com',
|
|
277
|
-
* password: 'supersecret',
|
|
278
|
-
* });
|
|
279
|
-
*/
|
|
260
|
+
/** Create a new user account */
|
|
280
261
|
signUp(options: SignUpOptions): Promise<HydrousResponse<AuthSession>>;
|
|
281
|
-
/**
|
|
282
|
-
* Sign in with email and password.
|
|
283
|
-
*
|
|
284
|
-
* @example
|
|
285
|
-
* const { data, error } = await hydrous.auth.signIn({
|
|
286
|
-
* email: 'user@example.com',
|
|
287
|
-
* password: 'supersecret',
|
|
288
|
-
* });
|
|
289
|
-
* if (data) console.log('Signed in as', data.user.email);
|
|
290
|
-
*/
|
|
262
|
+
/** Sign in with email and password */
|
|
291
263
|
signIn(options: SignInOptions): Promise<HydrousResponse<AuthSession>>;
|
|
292
|
-
/**
|
|
293
|
-
* Sign out the current user and invalidate their session.
|
|
294
|
-
*/
|
|
264
|
+
/** Sign out and invalidate the current session */
|
|
295
265
|
signOut(): Promise<HydrousResponse<void>>;
|
|
296
|
-
/**
|
|
266
|
+
/** Get the currently authenticated user */
|
|
297
267
|
getUser(): Promise<HydrousResponse<AuthUser>>;
|
|
298
|
-
/**
|
|
299
|
-
* Refresh the access token using the stored refresh token.
|
|
300
|
-
* Called automatically by the SDK when a 401 is received.
|
|
301
|
-
*/
|
|
268
|
+
/** Refresh the access token using the stored refresh token */
|
|
302
269
|
refreshSession(): Promise<HydrousResponse<AuthSession>>;
|
|
303
|
-
/** Return the current in-memory session (may be null)
|
|
270
|
+
/** Return the current in-memory session (may be null) */
|
|
304
271
|
getSession(): AuthSession | null;
|
|
305
272
|
private _sessionHeader;
|
|
306
273
|
}
|
|
@@ -309,60 +276,15 @@ declare class RecordsClient {
|
|
|
309
276
|
private readonly baseUrl;
|
|
310
277
|
private readonly headers;
|
|
311
278
|
constructor(config: HydrousConfig);
|
|
312
|
-
/**
|
|
313
|
-
* Query records from a collection.
|
|
314
|
-
*
|
|
315
|
-
* @param collection - Collection name (e.g. "users")
|
|
316
|
-
* @param options - Filters, ordering, pagination
|
|
317
|
-
*
|
|
318
|
-
* @example
|
|
319
|
-
* const { data, error } = await hydrous.records.select('users', {
|
|
320
|
-
* where: { field: 'role', operator: 'eq', value: 'admin' },
|
|
321
|
-
* orderBy: { field: 'createdAt', direction: 'desc' },
|
|
322
|
-
* limit: 20,
|
|
323
|
-
* });
|
|
324
|
-
*/
|
|
279
|
+
/** Query records from a collection */
|
|
325
280
|
select<T = Record<string, unknown>>(collection: string, options?: QueryOptions): Promise<RecordResponse<T>>;
|
|
326
|
-
/**
|
|
327
|
-
* Fetch a single record by its ID.
|
|
328
|
-
*
|
|
329
|
-
* @example
|
|
330
|
-
* const { data, error } = await hydrous.records.get('users', 'user_abc123');
|
|
331
|
-
*/
|
|
281
|
+
/** Fetch a single record by ID */
|
|
332
282
|
get<T = Record<string, unknown>>(collection: string, id: string): Promise<SingleRecordResponse<T>>;
|
|
333
|
-
/**
|
|
334
|
-
* Insert one or more records into a collection.
|
|
335
|
-
*
|
|
336
|
-
* @param collection - Collection name
|
|
337
|
-
* @param payload - A single record object or an array of record objects
|
|
338
|
-
*
|
|
339
|
-
* @example
|
|
340
|
-
* // Single insert
|
|
341
|
-
* const { data, error } = await hydrous.records.insert('users', {
|
|
342
|
-
* name: 'Alice', email: 'alice@example.com'
|
|
343
|
-
* });
|
|
344
|
-
*
|
|
345
|
-
* // Bulk insert
|
|
346
|
-
* const { data, error } = await hydrous.records.insert('users', [
|
|
347
|
-
* { name: 'Alice' }, { name: 'Bob' }
|
|
348
|
-
* ]);
|
|
349
|
-
*/
|
|
283
|
+
/** Insert one or more records */
|
|
350
284
|
insert<T = Record<string, unknown>>(collection: string, payload: Partial<T> | Partial<T>[]): Promise<RecordResponse<T>>;
|
|
351
|
-
/**
|
|
352
|
-
* Update a record by ID.
|
|
353
|
-
*
|
|
354
|
-
* @example
|
|
355
|
-
* const { data, error } = await hydrous.records.update('users', 'user_abc123', {
|
|
356
|
-
* name: 'Alice Smith'
|
|
357
|
-
* });
|
|
358
|
-
*/
|
|
285
|
+
/** Update a record by ID */
|
|
359
286
|
update<T = Record<string, unknown>>(collection: string, id: string, payload: Partial<T>): Promise<SingleRecordResponse<T>>;
|
|
360
|
-
/**
|
|
361
|
-
* Delete a record by ID.
|
|
362
|
-
*
|
|
363
|
-
* @example
|
|
364
|
-
* const { error } = await hydrous.records.delete('users', 'user_abc123');
|
|
365
|
-
*/
|
|
287
|
+
/** Delete a record by ID */
|
|
366
288
|
delete(collection: string, id: string): Promise<SingleRecordResponse<void>>;
|
|
367
289
|
}
|
|
368
290
|
|
|
@@ -370,97 +292,63 @@ declare class AnalyticsClient {
|
|
|
370
292
|
private readonly baseUrl;
|
|
371
293
|
private readonly headers;
|
|
372
294
|
constructor(config: HydrousConfig);
|
|
373
|
-
/**
|
|
374
|
-
* Track an analytics event.
|
|
375
|
-
*
|
|
376
|
-
* @example
|
|
377
|
-
* await hydrous.analytics.track({
|
|
378
|
-
* event: 'page_view',
|
|
379
|
-
* properties: { page: '/home', referrer: 'google.com' },
|
|
380
|
-
* userId: 'user_abc123',
|
|
381
|
-
* });
|
|
382
|
-
*/
|
|
295
|
+
/** Track a single analytics event */
|
|
383
296
|
track(options: TrackEventOptions): Promise<HydrousResponse<void>>;
|
|
384
|
-
/**
|
|
385
|
-
* Query recorded analytics events.
|
|
386
|
-
*
|
|
387
|
-
* @example
|
|
388
|
-
* const { data } = await hydrous.analytics.query({
|
|
389
|
-
* event: 'page_view',
|
|
390
|
-
* from: '2024-01-01',
|
|
391
|
-
* to: '2024-01-31',
|
|
392
|
-
* limit: 100,
|
|
393
|
-
* });
|
|
394
|
-
*/
|
|
395
|
-
query(options?: AnalyticsQueryOptions): Promise<RecordResponse<AnalyticsEvent>>;
|
|
396
|
-
/**
|
|
397
|
-
* Track multiple events in a single request (more efficient than
|
|
398
|
-
* calling `track` in a loop).
|
|
399
|
-
*
|
|
400
|
-
* @example
|
|
401
|
-
* await hydrous.analytics.trackBatch([
|
|
402
|
-
* { event: 'signup', userId: 'u1' },
|
|
403
|
-
* { event: 'onboarded', userId: 'u1' },
|
|
404
|
-
* ]);
|
|
405
|
-
*/
|
|
297
|
+
/** Track many events in one request */
|
|
406
298
|
trackBatch(events: TrackEventOptions[]): Promise<HydrousResponse<void>>;
|
|
299
|
+
/** Query recorded analytics events */
|
|
300
|
+
query(options?: AnalyticsQueryOptions): Promise<RecordResponse<AnalyticsEvent>>;
|
|
407
301
|
}
|
|
408
302
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
303
|
+
/**
|
|
304
|
+
* A storage client that is already bound to a specific storage key.
|
|
305
|
+
* You get one of these by calling `db.storage('keyName')`.
|
|
306
|
+
*
|
|
307
|
+
* None of the methods on this class require you to pass a bucket key —
|
|
308
|
+
* it's already baked in.
|
|
309
|
+
*/
|
|
310
|
+
declare class ScopedStorageClient {
|
|
311
|
+
private readonly base;
|
|
312
|
+
private readonly key;
|
|
313
|
+
readonly keyName: string;
|
|
314
|
+
constructor(baseUrl: string, keyName: string, bucketKey: string);
|
|
412
315
|
/**
|
|
413
|
-
* Upload a single file
|
|
316
|
+
* Upload a single file.
|
|
414
317
|
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
* bytes transferred, speed (bytes/sec), ETA, and lifecycle stage.
|
|
318
|
+
* Supply `onProgress` to receive live upload ticks including bytes
|
|
319
|
+
* transferred, speed (bytes/sec), ETA, and lifecycle stage.
|
|
418
320
|
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
* |-------------|------------------------------------------|
|
|
422
|
-
* | `pending` | Queued, not yet started |
|
|
423
|
-
* | `compressing` | Server is compressing the file |
|
|
424
|
-
* | `uploading` | Bytes flowing to cloud storage |
|
|
425
|
-
* | `done` | Confirmed written to cloud storage |
|
|
426
|
-
* | `error` | Something went wrong |
|
|
321
|
+
* **Stage sequence:**
|
|
322
|
+
* `pending → compressing → uploading → done | error`
|
|
427
323
|
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
324
|
+
* In browsers the progress is tracked at the network level via XHR, so
|
|
325
|
+
* `percent` reflects actual bytes leaving the device. `done` only fires
|
|
326
|
+
* after the server confirms the write to cloud storage, so 100% is real.
|
|
431
327
|
*
|
|
432
328
|
* @example
|
|
433
|
-
* const { data, error } = await
|
|
434
|
-
* '
|
|
435
|
-
*
|
|
436
|
-
* {
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
* }
|
|
443
|
-
* );
|
|
329
|
+
* const { data, error } = await db.storage('avatars').upload(file, {
|
|
330
|
+
* path: 'users/alice.jpg',
|
|
331
|
+
* overwrite: true,
|
|
332
|
+
* onProgress: (p) => {
|
|
333
|
+
* setProgress(p.percent); // e.g. drive a <progress> bar
|
|
334
|
+
* setSpeed(`${p.bytesPerSecond} B/s`);
|
|
335
|
+
* setEta(`${p.eta}s remaining`);
|
|
336
|
+
* },
|
|
337
|
+
* });
|
|
444
338
|
*/
|
|
445
|
-
upload(
|
|
339
|
+
upload(file: File | Blob | Uint8Array | ArrayBuffer, options?: UploadOptions): Promise<HydrousResponse<UploadResult>>;
|
|
446
340
|
/**
|
|
447
|
-
* Upload raw text or JSON content directly — no
|
|
448
|
-
* Great for saving generated content, config files, or JSON records.
|
|
449
|
-
*
|
|
450
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
451
|
-
* @param path Destination path (e.g. `"configs/settings.json"`)
|
|
452
|
-
* @param content String content to store
|
|
453
|
-
* @param options `mimeType`, `overwrite`, `onProgress`
|
|
341
|
+
* Upload raw text or JSON content directly — no File object needed.
|
|
454
342
|
*
|
|
455
343
|
* @example
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
* '
|
|
459
|
-
*
|
|
460
|
-
* { mimeType: '
|
|
344
|
+
* // Save a JSON config
|
|
345
|
+
* await db.storage('configs').uploadText(
|
|
346
|
+
* 'settings/app.json',
|
|
347
|
+
* JSON.stringify({ theme: 'dark' }),
|
|
348
|
+
* { mimeType: 'application/json' }
|
|
461
349
|
* );
|
|
462
350
|
*/
|
|
463
|
-
uploadText(
|
|
351
|
+
uploadText(path: string, content: string, options?: {
|
|
464
352
|
mimeType?: string;
|
|
465
353
|
overwrite?: boolean;
|
|
466
354
|
onProgress?: UploadOptions['onProgress'];
|
|
@@ -468,244 +356,199 @@ declare class StorageClient {
|
|
|
468
356
|
/**
|
|
469
357
|
* Upload multiple files in one request.
|
|
470
358
|
*
|
|
471
|
-
* `onProgress` fires
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
* so you can render all progress bars immediately.
|
|
475
|
-
*
|
|
476
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
477
|
-
* @param files Array of `File` objects (browser) or `{ name, data }` objects (Node)
|
|
478
|
-
* @param options Prefix, per-file paths, overwrite, concurrency, onProgress
|
|
359
|
+
* `onProgress` fires per file — use `p.index` to identify which file.
|
|
360
|
+
* All files receive a `pending` event upfront so you can render progress
|
|
361
|
+
* bars immediately before any data is sent.
|
|
479
362
|
*
|
|
480
363
|
* @example
|
|
481
|
-
* await
|
|
482
|
-
* '
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
* prefix: 'uploads/2024/',
|
|
486
|
-
* onProgress: (p) => {
|
|
487
|
-
* console.log(`File ${p.index}: ${p.stage} ${p.percent}%`);
|
|
488
|
-
* },
|
|
489
|
-
* }
|
|
490
|
-
* );
|
|
364
|
+
* await db.storage('documents').batchUpload(files, {
|
|
365
|
+
* prefix: 'reports/2024/',
|
|
366
|
+
* onProgress: (p) => updateBar(p.index, p.percent),
|
|
367
|
+
* });
|
|
491
368
|
*/
|
|
492
|
-
batchUpload(
|
|
369
|
+
batchUpload(files: File[], options?: BatchUploadOptions): Promise<HydrousResponse<BatchUploadResult>>;
|
|
493
370
|
/**
|
|
494
371
|
* Download a single file and return its content as an `ArrayBuffer`.
|
|
495
372
|
*
|
|
496
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
497
|
-
* @param filePath Path of the file within your bucket
|
|
498
|
-
*
|
|
499
373
|
* @example
|
|
500
|
-
* const { data
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
* );
|
|
504
|
-
* if (data) {
|
|
505
|
-
* const blob = new Blob([data]);
|
|
506
|
-
* const url = URL.createObjectURL(blob);
|
|
507
|
-
* }
|
|
374
|
+
* const { data } = await db.storage('avatars').download('users/alice.jpg');
|
|
375
|
+
* const blob = new Blob([data!]);
|
|
376
|
+
* img.src = URL.createObjectURL(blob);
|
|
508
377
|
*/
|
|
509
|
-
download(
|
|
378
|
+
download(filePath: string): Promise<HydrousResponse<ArrayBuffer>>;
|
|
510
379
|
/**
|
|
511
380
|
* Download multiple files in one request.
|
|
512
381
|
*
|
|
513
|
-
*
|
|
514
|
-
* to the user's Downloads folder as it arrives.
|
|
515
|
-
*
|
|
516
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
517
|
-
* @param filePaths Array of file paths within your bucket
|
|
518
|
-
* @param options Concurrency, onProgress, autoSave
|
|
382
|
+
* Set `autoSave: true` (browser only) to trigger a Save dialog per file.
|
|
519
383
|
*
|
|
520
384
|
* @example
|
|
521
|
-
* const { data } = await
|
|
522
|
-
* '
|
|
523
|
-
*
|
|
524
|
-
* {
|
|
525
|
-
* onProgress: (p) => console.log(p.path, p.status),
|
|
526
|
-
* autoSave: true, // triggers browser file-save dialog per file
|
|
527
|
-
* }
|
|
385
|
+
* const { data } = await db.storage('reports').batchDownload(
|
|
386
|
+
* ['jan.pdf', 'feb.pdf'],
|
|
387
|
+
* { autoSave: true, onProgress: (p) => console.log(p.path, p.status) }
|
|
528
388
|
* );
|
|
529
389
|
*/
|
|
530
|
-
batchDownload(
|
|
390
|
+
batchDownload(filePaths: string[], options?: BatchDownloadOptions): Promise<HydrousResponse<BatchDownloadFile[]>>;
|
|
531
391
|
/**
|
|
532
|
-
* List files and folders
|
|
533
|
-
*
|
|
534
|
-
* Results are paginated — use `pagination.nextCursor` to fetch the next page.
|
|
535
|
-
*
|
|
536
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
537
|
-
* @param options `prefix`, `limit`, `cursor`
|
|
392
|
+
* List files and folders (paginated).
|
|
538
393
|
*
|
|
539
394
|
* @example
|
|
540
|
-
* const { data } = await
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
* });
|
|
544
|
-
* for (const item of data.items) {
|
|
545
|
-
* console.log(item.type, item.path);
|
|
395
|
+
* const { data } = await db.storage('avatars').list({ prefix: 'users/' });
|
|
396
|
+
* for (const item of data!.items) {
|
|
397
|
+
* console.log(item.type, item.path, item.size);
|
|
546
398
|
* }
|
|
547
399
|
*/
|
|
548
|
-
list(
|
|
549
|
-
/**
|
|
550
|
-
* Get metadata for a specific file (size, MIME type, compression info, etc.)
|
|
551
|
-
*
|
|
552
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
553
|
-
* @param filePath Path of the file within your bucket
|
|
554
|
-
*
|
|
555
|
-
* @example
|
|
556
|
-
* const { data } = await hydrous.storage.metadata(
|
|
557
|
-
* 'ssk_my_bucket_key',
|
|
558
|
-
* 'avatars/alice.jpg'
|
|
559
|
-
* );
|
|
560
|
-
* console.log(data.size, data.mimeType);
|
|
561
|
-
*/
|
|
562
|
-
metadata(bucketKey: BucketKey, filePath: string): Promise<HydrousResponse<FileMetadata>>;
|
|
563
|
-
/**
|
|
564
|
-
* Delete a single file.
|
|
565
|
-
*
|
|
566
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
567
|
-
* @param filePath Path of the file to delete
|
|
568
|
-
*
|
|
569
|
-
* @example
|
|
570
|
-
* await hydrous.storage.deleteFile('ssk_my_bucket_key', 'avatars/old.jpg');
|
|
571
|
-
*/
|
|
572
|
-
deleteFile(bucketKey: BucketKey, filePath: string): Promise<HydrousResponse<void>>;
|
|
573
|
-
/**
|
|
574
|
-
* Recursively delete a folder and all of its contents.
|
|
575
|
-
*
|
|
576
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
577
|
-
* @param folderPath Folder path to delete (e.g. `"old-uploads/"`)
|
|
578
|
-
*
|
|
579
|
-
* @example
|
|
580
|
-
* await hydrous.storage.deleteFolder('ssk_my_bucket_key', 'temp/');
|
|
581
|
-
*/
|
|
582
|
-
deleteFolder(bucketKey: BucketKey, folderPath: string): Promise<HydrousResponse<void>>;
|
|
583
|
-
/**
|
|
584
|
-
* Create an empty folder.
|
|
585
|
-
*
|
|
586
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
587
|
-
* @param folderPath Path for the new folder (e.g. `"avatars/2024/"`)
|
|
588
|
-
*
|
|
589
|
-
* @example
|
|
590
|
-
* await hydrous.storage.createFolder('ssk_my_bucket_key', 'avatars/2024/');
|
|
591
|
-
*/
|
|
592
|
-
createFolder(bucketKey: BucketKey, folderPath: string): Promise<HydrousResponse<void>>;
|
|
593
|
-
/**
|
|
594
|
-
* Move (rename) a file to a new path.
|
|
595
|
-
*
|
|
596
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
597
|
-
* @param fromPath Current path of the file
|
|
598
|
-
* @param toPath New path for the file
|
|
599
|
-
*
|
|
600
|
-
* @example
|
|
601
|
-
* await hydrous.storage.move(
|
|
602
|
-
* 'ssk_my_bucket_key',
|
|
603
|
-
* 'drafts/report.pdf',
|
|
604
|
-
* 'published/report.pdf'
|
|
605
|
-
* );
|
|
606
|
-
*/
|
|
607
|
-
move(bucketKey: BucketKey, fromPath: string, toPath: string): Promise<HydrousResponse<void>>;
|
|
400
|
+
list(options?: ListOptions): Promise<HydrousResponse<ListResult>>;
|
|
608
401
|
/**
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
612
|
-
* @param fromPath Source path
|
|
613
|
-
* @param toPath Destination path
|
|
402
|
+
* Get metadata for a file (size, MIME type, compression, etc.)
|
|
614
403
|
*
|
|
615
404
|
* @example
|
|
616
|
-
* await
|
|
617
|
-
*
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
405
|
+
* const { data: meta } = await db.storage('docs').metadata('report.pdf');
|
|
406
|
+
* console.log(meta!.size, meta!.mimeType, meta!.isCompressed);
|
|
407
|
+
*/
|
|
408
|
+
metadata(filePath: string): Promise<HydrousResponse<FileMetadata>>;
|
|
409
|
+
/** Delete a single file */
|
|
410
|
+
deleteFile(filePath: string): Promise<HydrousResponse<void>>;
|
|
411
|
+
/** Recursively delete a folder and all its contents */
|
|
412
|
+
deleteFolder(folderPath: string): Promise<HydrousResponse<void>>;
|
|
413
|
+
/** Create an empty folder */
|
|
414
|
+
createFolder(folderPath: string): Promise<HydrousResponse<void>>;
|
|
415
|
+
/** Move (rename) a file */
|
|
416
|
+
move(fromPath: string, toPath: string): Promise<HydrousResponse<void>>;
|
|
417
|
+
/** Copy a file (original is kept) */
|
|
418
|
+
copy(fromPath: string, toPath: string): Promise<HydrousResponse<void>>;
|
|
623
419
|
/**
|
|
624
420
|
* Generate a time-limited public URL for a private file.
|
|
625
421
|
*
|
|
626
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
627
|
-
* @param filePath Path of the file
|
|
628
|
-
* @param options `expiresIn` seconds (default: 3600)
|
|
629
|
-
*
|
|
630
422
|
* @example
|
|
631
|
-
* const { data } = await
|
|
632
|
-
*
|
|
633
|
-
* 'private/contract.pdf',
|
|
634
|
-
* { expiresIn: 300 } // 5 minutes
|
|
635
|
-
* );
|
|
636
|
-
* console.log(data.signedUrl); // share this URL
|
|
423
|
+
* const { data } = await db.storage('contracts').signedUrl('nda.pdf', { expiresIn: 300 });
|
|
424
|
+
* console.log(data!.signedUrl); // share this
|
|
637
425
|
*/
|
|
638
|
-
signedUrl(
|
|
426
|
+
signedUrl(filePath: string, options?: SignedUrlOptions): Promise<HydrousResponse<SignedUrlResult>>;
|
|
639
427
|
/**
|
|
640
|
-
* Get usage and billing
|
|
641
|
-
*
|
|
642
|
-
* @param bucketKey Your storage bucket key (`ssk_…`)
|
|
428
|
+
* Get usage and billing stats for this storage key.
|
|
643
429
|
*
|
|
644
430
|
* @example
|
|
645
|
-
* const { data } = await
|
|
646
|
-
* console.log(
|
|
431
|
+
* const { data } = await db.storage('main').stats();
|
|
432
|
+
* console.log(data!.totalFiles, data!.totalSizeBytes);
|
|
647
433
|
*/
|
|
648
|
-
stats(
|
|
434
|
+
stats(): Promise<HydrousResponse<StorageStats>>;
|
|
649
435
|
}
|
|
650
436
|
|
|
437
|
+
interface CallableStorage {
|
|
438
|
+
/** Get a scoped storage client by key name */
|
|
439
|
+
(keyName: string): ScopedStorageClient;
|
|
440
|
+
/** Same as calling db.storage(keyName) — more explicit */
|
|
441
|
+
use(keyName: string): ScopedStorageClient;
|
|
442
|
+
/** Return names of all configured storage keys */
|
|
443
|
+
keyNames(): string[];
|
|
444
|
+
}
|
|
651
445
|
/**
|
|
652
|
-
* The root
|
|
446
|
+
* The HydrousDB root client.
|
|
653
447
|
*
|
|
654
|
-
*
|
|
448
|
+
* Create once and reuse across your app:
|
|
655
449
|
*
|
|
656
|
-
*
|
|
657
|
-
* import {
|
|
450
|
+
* ```ts
|
|
451
|
+
* import { createClient } from 'hydrousdb';
|
|
658
452
|
*
|
|
659
|
-
* const
|
|
660
|
-
* url:
|
|
661
|
-
*
|
|
453
|
+
* const db = createClient({
|
|
454
|
+
* url: 'https://api.myapp.hydrous.app',
|
|
455
|
+
* authKey: 'hk_auth_…',
|
|
456
|
+
* bucketSecurityKey: 'hk_bucket_…',
|
|
457
|
+
* storageKeys: {
|
|
458
|
+
* main: 'ssk_main_…',
|
|
459
|
+
* avatars: 'ssk_avatars_…',
|
|
460
|
+
* documents: 'ssk_docs_…',
|
|
461
|
+
* },
|
|
662
462
|
* });
|
|
463
|
+
* ```
|
|
663
464
|
*/
|
|
664
465
|
declare class HydrousClient {
|
|
665
|
-
/**
|
|
466
|
+
/** Auth — sign up, sign in, sign out, session management */
|
|
666
467
|
readonly auth: AuthClient;
|
|
667
468
|
/** Records — insert, select, update, delete structured data */
|
|
668
469
|
readonly records: RecordsClient;
|
|
669
|
-
/** Analytics — track events
|
|
470
|
+
/** Analytics — track events and query history */
|
|
670
471
|
readonly analytics: AnalyticsClient;
|
|
671
472
|
/**
|
|
672
|
-
* Storage —
|
|
473
|
+
* Storage — call with the name of the key you want.
|
|
673
474
|
*
|
|
674
|
-
*
|
|
475
|
+
* ```ts
|
|
476
|
+
* db.storage('avatars').upload(file, { path: 'user.jpg' })
|
|
477
|
+
* db.storage('documents').list({ prefix: 'invoices/' })
|
|
478
|
+
* db.storage('main').stats()
|
|
479
|
+
* ```
|
|
675
480
|
*/
|
|
676
|
-
readonly storage:
|
|
481
|
+
readonly storage: CallableStorage;
|
|
677
482
|
constructor(config: HydrousConfig);
|
|
678
483
|
}
|
|
679
484
|
|
|
680
|
-
/**
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
485
|
+
/**
|
|
486
|
+
* StorageManager is the object exposed as `db.storage`.
|
|
487
|
+
*
|
|
488
|
+
* Call `.use(keyName)` — or use the shorthand `db.storage('keyName')` which
|
|
489
|
+
* the main HydrousClient wires up as a Proxy — to get a scoped storage client
|
|
490
|
+
* bound to that key.
|
|
491
|
+
*
|
|
492
|
+
* ```ts
|
|
493
|
+
* db.storage('main').upload(file)
|
|
494
|
+
* db.storage('avatars').list()
|
|
495
|
+
* db.storage('documents').download('report.pdf')
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
declare class StorageManager {
|
|
499
|
+
private readonly baseUrl;
|
|
500
|
+
private readonly _keys;
|
|
501
|
+
private readonly cache;
|
|
502
|
+
constructor(config: HydrousConfig);
|
|
503
|
+
/**
|
|
504
|
+
* Get a storage client scoped to a named key.
|
|
505
|
+
*
|
|
506
|
+
* @param keyName - Must match a property you declared in `storageKeys`
|
|
507
|
+
*
|
|
508
|
+
* @example
|
|
509
|
+
* const avatarStore = db.storage('avatars');
|
|
510
|
+
* const documentStore = db.storage('documents');
|
|
511
|
+
*
|
|
512
|
+
* await avatarStore.upload(file, { path: 'users/alice.jpg' });
|
|
513
|
+
* const list = await documentStore.list({ prefix: 'invoices/' });
|
|
514
|
+
*/
|
|
515
|
+
use(keyName: string): ScopedStorageClient;
|
|
516
|
+
/** Return the names of all configured storage keys */
|
|
517
|
+
keyNames(): string[];
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
declare const eq: (field: string, value: unknown) => Filter;
|
|
521
|
+
declare const neq: (field: string, value: unknown) => Filter;
|
|
522
|
+
declare const gt: (field: string, value: unknown) => Filter;
|
|
523
|
+
declare const lt: (field: string, value: unknown) => Filter;
|
|
524
|
+
declare const gte: (field: string, value: unknown) => Filter;
|
|
525
|
+
declare const lte: (field: string, value: unknown) => Filter;
|
|
526
|
+
declare const inArray: (field: string, value: unknown[]) => Filter;
|
|
690
527
|
|
|
691
|
-
declare class
|
|
528
|
+
declare class HydrousDBError extends Error {
|
|
692
529
|
readonly code: string;
|
|
693
530
|
readonly status: number | undefined;
|
|
694
531
|
constructor(message: string, code?: string, status?: number);
|
|
695
532
|
}
|
|
696
|
-
declare function isHydrousError(err: unknown): err is
|
|
533
|
+
declare function isHydrousError(err: unknown): err is HydrousDBError;
|
|
697
534
|
|
|
698
535
|
/**
|
|
699
|
-
* Create
|
|
536
|
+
* Create a HydrousDB client.
|
|
700
537
|
*
|
|
701
538
|
* @example
|
|
702
|
-
* import { createClient } from '
|
|
539
|
+
* import { createClient } from 'hydrousdb';
|
|
703
540
|
*
|
|
704
|
-
* const
|
|
705
|
-
* url:
|
|
706
|
-
*
|
|
541
|
+
* const db = createClient({
|
|
542
|
+
* url: 'https://api.myapp.hydrous.app',
|
|
543
|
+
* authKey: 'hk_auth_…',
|
|
544
|
+
* bucketSecurityKey: 'hk_bucket_…',
|
|
545
|
+
* storageKeys: {
|
|
546
|
+
* main: 'ssk_main_…',
|
|
547
|
+
* avatars: 'ssk_avatars_…',
|
|
548
|
+
* documents: 'ssk_docs_…',
|
|
549
|
+
* },
|
|
707
550
|
* });
|
|
708
551
|
*/
|
|
709
552
|
declare function createClient(config: HydrousConfig): HydrousClient;
|
|
710
553
|
|
|
711
|
-
export { AnalyticsClient, type AnalyticsEvent, type AnalyticsQueryOptions, AuthClient, type AuthSession, type AuthUser, type BatchDownloadFile, type BatchDownloadOptions, type BatchUploadOptions, type BatchUploadResult, type
|
|
554
|
+
export { AnalyticsClient, type AnalyticsEvent, type AnalyticsQueryOptions, AuthClient, type AuthSession, type AuthUser, type BatchDownloadFile, type BatchDownloadOptions, type BatchUploadOptions, type BatchUploadResult, type CallableStorage, type DownloadProgress, type FileMetadata, type Filter, type FilterOperator, HydrousClient, type HydrousConfig, HydrousDBError, type HydrousError, type HydrousResponse, type ListOptions, type ListResult, type QueryOptions, type RecordResponse, RecordsClient, ScopedStorageClient, type SignInOptions, type SignUpOptions, type SignedUrlOptions, type SignedUrlResult, type SingleRecordResponse, type StorageItem, type StorageKeys, StorageManager, type StorageStats, type TrackEventOptions, type UploadOptions, type UploadProgress, type UploadResult, type UploadStage, createClient, eq, gt, gte, inArray, isHydrousError, lt, lte, neq };
|