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/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 Hydrous project URL e.g. https://api.yourapp.hydrous.app */
15
+ /** Your HydrousDB project base URL */
3
16
  url: string;
4
- /** Your project API key */
5
- apiKey: string;
6
- /** Optional default request timeout in milliseconds (default: 30_000) */
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 this operation */
112
+ /** Total files in the operation */
95
113
  total: number;
96
- /** Destination path (relative to your bucket root) */
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 integer */
120
+ /** 0 100 */
105
121
  percent: number;
106
- /** Upload speed in bytes/second null before the first tick */
122
+ /** Upload speed in bytes/sec; null until the first tick */
107
123
  bytesPerSecond: number | null;
108
- /** Estimated seconds remaining null until speed is known */
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 while the file is being transferred.
214
- * Use this to drive progress bars, speed indicators, and ETAs.
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). @default 5 */
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
- * When true, automatically triggers browser download for each file as
248
- * it arrives. Only works in browser environments.
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 (e.g. "avatars/"). Empty string = root. */
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, in seconds. @default 3600 (1 hour) */
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
- /** Return the currently authenticated user, or null if not signed in. */
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
- declare class StorageClient {
410
- private readonly baseUrl;
411
- constructor(config: HydrousConfig);
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 to a bucket.
316
+ * Upload a single file.
414
317
  *
415
- * The bucket key **always comes first**.
416
- * Supply an `onProgress` callback to receive live upload progress including
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
- * ### Stages fired via `onProgress`
420
- * | Stage | Meaning |
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
- * @param bucketKey Your storage bucket key (`ssk_…`)
429
- * @param file A `File`, `Blob`, or `Buffer` (Node)
430
- * @param options Path, overwrite flag, progress callback
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 hydrous.storage.upload(
434
- * 'ssk_my_bucket_key',
435
- * file,
436
- * {
437
- * path: 'avatars/alice.jpg',
438
- * overwrite: true,
439
- * onProgress: (p) => {
440
- * console.log(`${p.stage} — ${p.percent}% ${p.bytesPerSecond} B/s ETA ${p.eta}s`);
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(bucketKey: BucketKey, file: File | Blob | Uint8Array | ArrayBuffer, options?: UploadOptions): Promise<HydrousResponse<UploadResult>>;
339
+ upload(file: File | Blob | Uint8Array | ArrayBuffer, options?: UploadOptions): Promise<HydrousResponse<UploadResult>>;
446
340
  /**
447
- * Upload raw text or JSON content directly — no `File` object needed.
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
- * await hydrous.storage.uploadText(
457
- * 'ssk_my_bucket_key',
458
- * 'reports/summary.txt',
459
- * 'Hello from Hydrous!',
460
- * { mimeType: 'text/plain' }
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(bucketKey: BucketKey, path: string, content: string, options?: {
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 for **every file individually** the `index` field
472
- * tells you which file the event belongs to (0-based, same order as `files`).
473
- * All files receive a `pending` event upfront before any uploads start,
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 hydrous.storage.batchUpload(
482
- * 'ssk_my_bucket_key',
483
- * fileArray,
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(bucketKey: BucketKey, files: File[], options?: BatchUploadOptions): Promise<HydrousResponse<BatchUploadResult>>;
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, error } = await hydrous.storage.download(
501
- * 'ssk_my_bucket_key',
502
- * 'avatars/alice.jpg'
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(bucketKey: BucketKey, filePath: string): Promise<HydrousResponse<ArrayBuffer>>;
378
+ download(filePath: string): Promise<HydrousResponse<ArrayBuffer>>;
510
379
  /**
511
380
  * Download multiple files in one request.
512
381
  *
513
- * When `autoSave: true` (browser only) each file is automatically saved
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 hydrous.storage.batchDownload(
522
- * 'ssk_my_bucket_key',
523
- * ['reports/jan.pdf', 'reports/feb.pdf'],
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(bucketKey: BucketKey, filePaths: string[], options?: BatchDownloadOptions): Promise<HydrousResponse<BatchDownloadFile[]>>;
390
+ batchDownload(filePaths: string[], options?: BatchDownloadOptions): Promise<HydrousResponse<BatchDownloadFile[]>>;
531
391
  /**
532
- * List files and folders inside a bucket (or a folder within it).
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 hydrous.storage.list('ssk_my_bucket_key', {
541
- * prefix: 'avatars/',
542
- * limit: 50,
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(bucketKey: BucketKey, options?: ListOptions): Promise<HydrousResponse<ListResult>>;
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
- * Copy a file to a new path (original is kept).
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 hydrous.storage.copy(
617
- * 'ssk_my_bucket_key',
618
- * 'templates/invoice.pdf',
619
- * 'invoices/invoice-001.pdf'
620
- * );
621
- */
622
- copy(bucketKey: BucketKey, fromPath: string, toPath: string): Promise<HydrousResponse<void>>;
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 hydrous.storage.signedUrl(
632
- * 'ssk_my_bucket_key',
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(bucketKey: BucketKey, filePath: string, options?: SignedUrlOptions): Promise<HydrousResponse<SignedUrlResult>>;
426
+ signedUrl(filePath: string, options?: SignedUrlOptions): Promise<HydrousResponse<SignedUrlResult>>;
639
427
  /**
640
- * Get usage and billing statistics for this bucket key.
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 hydrous.storage.stats('ssk_my_bucket_key');
646
- * console.log(`${data.totalFiles} files, ${data.totalSizeBytes} bytes stored`);
431
+ * const { data } = await db.storage('main').stats();
432
+ * console.log(data!.totalFiles, data!.totalSizeBytes);
647
433
  */
648
- stats(bucketKey: BucketKey): Promise<HydrousResponse<StorageStats>>;
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 Hydrous client.
446
+ * The HydrousDB root client.
653
447
  *
654
- * Instantiate once and reuse throughout your app.
448
+ * Create once and reuse across your app:
655
449
  *
656
- * @example
657
- * import { HydrousClient } from 'hydrous';
450
+ * ```ts
451
+ * import { createClient } from 'hydrousdb';
658
452
  *
659
- * const hydrous = new HydrousClient({
660
- * url: 'https://api.myapp.hydrous.app',
661
- * apiKey: 'hk_live_…',
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
- /** Authentication — sign up, sign in, sign out, session management */
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, query event history */
470
+ /** Analytics — track events and query history */
670
471
  readonly analytics: AnalyticsClient;
671
472
  /**
672
- * Storage — upload, download, list, move, delete files.
473
+ * Storage — call with the name of the key you want.
673
474
  *
674
- * Every method takes a **bucket key** (`ssk_…`) as its **first argument**.
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: StorageClient;
481
+ readonly storage: CallableStorage;
677
482
  constructor(config: HydrousConfig);
678
483
  }
679
484
 
680
- /** Shorthand helper: creates a simple equality filter */
681
- declare function eq(field: string, value: unknown): Filter;
682
- /** Shorthand helper: creates a "not equal" filter */
683
- declare function neq(field: string, value: unknown): Filter;
684
- /** Shorthand helper: creates a "greater than" filter */
685
- declare function gt(field: string, value: unknown): Filter;
686
- /** Shorthand helper: creates a "less than" filter */
687
- declare function lt(field: string, value: unknown): Filter;
688
- /** Shorthand helper: creates an "in array" filter */
689
- declare function inArray(field: string, value: unknown[]): Filter;
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 HydrousSDKError extends Error {
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 HydrousSDKError;
533
+ declare function isHydrousError(err: unknown): err is HydrousDBError;
697
534
 
698
535
  /**
699
- * Create and return a `HydrousClient` instance.
536
+ * Create a HydrousDB client.
700
537
  *
701
538
  * @example
702
- * import { createClient } from 'hydrous';
539
+ * import { createClient } from 'hydrousdb';
703
540
  *
704
- * const hydrous = createClient({
705
- * url: 'https://api.myapp.hydrous.app',
706
- * apiKey: 'hk_live_…',
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 BucketKey, type DownloadProgress, type FileMetadata, type Filter, type FilterOperator, HydrousClient, type HydrousConfig, type HydrousError, type HydrousResponse, HydrousSDKError, type ListOptions, type ListResult, type QueryOptions, type RecordResponse, RecordsClient, type SignInOptions, type SignUpOptions, type SignedUrlOptions, type SignedUrlResult, type SingleRecordResponse, StorageClient, type StorageItem, type StorageStats, type TrackEventOptions, type UploadOptions, type UploadProgress, type UploadResult, type UploadStage, createClient, eq, gt, inArray, isHydrousError, lt, neq };
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 };