hydrousdb 2.0.1 → 3.0.0
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 +911 -515
- package/dist/index.cjs +1647 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1540 -0
- package/dist/index.d.ts +1339 -510
- package/dist/index.js +1427 -1100
- package/dist/index.js.map +1 -1
- package/package.json +31 -14
- package/dist/index.d.mts +0 -711
- package/dist/index.mjs +0 -1291
- package/dist/index.mjs.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/errors.ts","../src/utils/http.ts","../src/auth/client.ts","../src/utils/query.ts","../src/records/client.ts","../src/analytics/client.ts","../src/storage/client.ts","../src/client.ts","../src/index.ts"],"names":["_a","_b"],"mappings":"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","file":"index.js","sourcesContent":["import type { HydrousError } from '../types/index.js';\n\nexport class HydrousSDKError extends Error {\n readonly code: string;\n readonly status: number | undefined;\n\n constructor(message: string, code = 'SDK_ERROR', status?: number) {\n super(message);\n this.name = 'HydrousSDKError';\n this.code = code;\n this.status = status;\n }\n}\n\nexport function toHydrousError(err: unknown): HydrousError {\n if (err instanceof HydrousSDKError) {\n return { message: err.message, code: err.code, status: err.status };\n }\n if (err instanceof Error) {\n return { message: err.message, code: 'UNKNOWN_ERROR' };\n }\n return { message: String(err), code: 'UNKNOWN_ERROR' };\n}\n\nexport function isHydrousError(err: unknown): err is HydrousSDKError {\n return err instanceof HydrousSDKError;\n}\n","import { HydrousSDKError } from './errors.js';\n\nexport interface RequestOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n body?: BodyInit | null;\n headers?: Record<string, string>;\n timeout?: number;\n}\n\n/** Parse a JSON response, throwing HydrousSDKError on HTTP errors */\nexport async function parseResponse<T>(res: Response): Promise<T> {\n let body: unknown;\n try {\n body = await res.json();\n } catch {\n if (!res.ok) {\n throw new HydrousSDKError(`HTTP ${res.status}`, 'HTTP_ERROR', res.status);\n }\n return undefined as T;\n }\n\n if (!res.ok) {\n const err = body as { error?: string; message?: string; code?: string };\n throw new HydrousSDKError(\n err.error || err.message || `HTTP ${res.status}`,\n err.code || 'HTTP_ERROR',\n res.status,\n );\n }\n\n return body as T;\n}\n\n/** Build full URL from base + path + optional query params */\nexport function buildUrl(\n base: string,\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n): string {\n const url = new URL(path, base.endsWith('/') ? base : base + '/');\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null) {\n url.searchParams.set(k, String(v));\n }\n }\n }\n return url.toString();\n}\n\n/** Merge default headers with per-request headers */\nexport function mergeHeaders(\n defaults: Record<string, string>,\n overrides?: Record<string, string>,\n): Record<string, string> {\n return { ...defaults, ...overrides };\n}\n\n/**\n * Parse a Server-Sent Events stream and invoke `onEvent` for every\n * complete event block. Returns a promise that resolves when the\n * stream ends (or the connection is closed).\n *\n * @param response - A streaming fetch Response (`res.body` must be non-null)\n * @param onEvent - Called once per complete SSE event with (eventType, parsedData)\n */\nexport async function readSSEStream(\n response: Response,\n onEvent: (eventType: string, data: unknown) => void,\n): Promise<void> {\n if (!response.body) return;\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buf = '';\n\n const flush = (chunk: string) => {\n buf += chunk;\n const blocks = buf.split('\\n\\n');\n buf = blocks.pop() ?? '';\n\n for (const block of blocks) {\n if (!block.trim()) continue;\n let eventType = 'message';\n let dataLine: string | null = null;\n\n for (const line of block.split('\\n')) {\n if (line.startsWith('event:')) eventType = line.slice(6).trim();\n if (line.startsWith('data:')) dataLine = line.slice(5).trim();\n }\n\n if (dataLine === null) continue;\n\n try {\n onEvent(eventType, JSON.parse(dataLine));\n } catch {\n // skip heartbeats and malformed lines\n }\n }\n };\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n flush(decoder.decode(value, { stream: true }));\n }\n\n if (buf.trim()) flush('');\n}\n\n/**\n * XHR-based upload that fires real browser-side upload progress events.\n * Returns the raw response text (which may be an SSE stream body).\n *\n * Use this instead of fetch() for uploads — fetch() buffers the entire\n * request body before sending, giving you 0%→100% with no ticks in between.\n */\nexport function xhrUpload(\n url: string,\n body: FormData | Blob | BufferSource,\n headers: Record<string, string>,\n onXhrProgress?: (loaded: number, total: number) => void,\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('POST', url);\n\n for (const [key, val] of Object.entries(headers)) {\n xhr.setRequestHeader(key, val);\n }\n\n xhr.responseType = 'text';\n\n if (onXhrProgress) {\n xhr.upload.onprogress = (e) => {\n if (e.lengthComputable) onXhrProgress(e.loaded, e.total);\n };\n }\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(xhr.responseText);\n } else {\n try {\n const d = JSON.parse(xhr.responseText) as { error?: string };\n reject(new HydrousSDKError(d.error ?? `HTTP ${xhr.status}`, 'HTTP_ERROR', xhr.status));\n } catch {\n reject(new HydrousSDKError(`HTTP ${xhr.status}`, 'HTTP_ERROR', xhr.status));\n }\n }\n };\n\n xhr.onerror = () => reject(new HydrousSDKError('Network error', 'NETWORK_ERROR'));\n xhr.onabort = () => reject(new HydrousSDKError('Upload aborted', 'UPLOAD_ABORTED'));\n xhr.ontimeout = () => reject(new HydrousSDKError('Upload timed out', 'UPLOAD_TIMEOUT'));\n\n xhr.send(body);\n });\n}\n\n/** Parse a text body that contains SSE blocks */\nexport function parseSSEText(\n text: string,\n onEvent: (eventType: string, data: unknown) => void,\n): void {\n const blocks = text.split('\\n\\n');\n for (const block of blocks) {\n if (!block.trim()) continue;\n let eventType = 'message';\n let dataLine: string | null = null;\n for (const line of block.split('\\n')) {\n if (line.startsWith('event:')) eventType = line.slice(6).trim();\n if (line.startsWith('data:')) dataLine = line.slice(5).trim();\n }\n if (dataLine === null) continue;\n try { onEvent(eventType, JSON.parse(dataLine)); } catch { /* skip */ }\n }\n}\n","import type {\n HydrousConfig,\n AuthSession,\n AuthUser,\n SignUpOptions,\n SignInOptions,\n HydrousResponse,\n} from '../types/index.js';\nimport { toHydrousError } from '../utils/errors.js';\nimport { buildUrl, mergeHeaders, parseResponse } from '../utils/http.js';\n\nexport class AuthClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private session: AuthSession | null = null;\n\n constructor(config: HydrousConfig) {\n this.baseUrl = config.url;\n this.headers = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n };\n }\n\n // ─── SIGN UP ───────────────────────────────────────────────────────────────\n\n /**\n * Create a new user account and return a session.\n *\n * @example\n * const { data, error } = await hydrous.auth.signUp({\n * email: 'user@example.com',\n * password: 'supersecret',\n * });\n */\n async signUp(options: SignUpOptions): Promise<HydrousResponse<AuthSession>> {\n try {\n const url = buildUrl(this.baseUrl, 'auth/signup');\n const res = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(options),\n });\n const json = await parseResponse<{ data: AuthSession }>(res);\n this.session = json.data;\n return { data: json.data, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ─── SIGN IN ───────────────────────────────────────────────────────────────\n\n /**\n * Sign in with email and password.\n *\n * @example\n * const { data, error } = await hydrous.auth.signIn({\n * email: 'user@example.com',\n * password: 'supersecret',\n * });\n * if (data) console.log('Signed in as', data.user.email);\n */\n async signIn(options: SignInOptions): Promise<HydrousResponse<AuthSession>> {\n try {\n const url = buildUrl(this.baseUrl, 'auth/signin');\n const res = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(options),\n });\n const json = await parseResponse<{ data: AuthSession }>(res);\n this.session = json.data;\n return { data: json.data, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ─── SIGN OUT ──────────────────────────────────────────────────────────────\n\n /**\n * Sign out the current user and invalidate their session.\n */\n async signOut(): Promise<HydrousResponse<void>> {\n try {\n const url = buildUrl(this.baseUrl, 'auth/signout');\n const res = await fetch(url, {\n method: 'POST',\n headers: mergeHeaders(this.headers, this._sessionHeader()),\n });\n await parseResponse<void>(res);\n this.session = null;\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ─── GET USER ──────────────────────────────────────────────────────────────\n\n /** Return the currently authenticated user, or null if not signed in. */\n async getUser(): Promise<HydrousResponse<AuthUser>> {\n try {\n const url = buildUrl(this.baseUrl, 'auth/user');\n const res = await fetch(url, {\n headers: mergeHeaders(this.headers, this._sessionHeader()),\n });\n const json = await parseResponse<{ data: AuthUser }>(res);\n return { data: json.data, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ─── REFRESH TOKEN ────────────────────────────────────────────────────────\n\n /**\n * Refresh the access token using the stored refresh token.\n * Called automatically by the SDK when a 401 is received.\n */\n async refreshSession(): Promise<HydrousResponse<AuthSession>> {\n if (!this.session?.refreshToken) {\n return { data: null, error: { message: 'No session', code: 'NO_SESSION' } };\n }\n try {\n const url = buildUrl(this.baseUrl, 'auth/refresh');\n const res = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({ refreshToken: this.session.refreshToken }),\n });\n const json = await parseResponse<{ data: AuthSession }>(res);\n this.session = json.data;\n return { data: json.data, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n /** Return the current in-memory session (may be null). */\n getSession(): AuthSession | null {\n return this.session;\n }\n\n private _sessionHeader(): Record<string, string> {\n return this.session?.accessToken\n ? { 'X-Session-Token': this.session.accessToken }\n : {};\n }\n}\n","import type { Filter, FilterOperator, QueryOptions } from '../types/index.js';\n\n/**\n * Serialise a QueryOptions object into URL search-parameter-safe strings\n * for transmission to the Hydrous REST API.\n */\nexport function serialiseQuery(\n opts: QueryOptions = {},\n): Record<string, string> {\n const params: Record<string, string> = {};\n\n if (opts.limit !== undefined) params['limit'] = String(opts.limit);\n if (opts.offset !== undefined) params['offset'] = String(opts.offset);\n if (opts.select && opts.select.length > 0) {\n params['select'] = opts.select.join(',');\n }\n\n if (opts.orderBy) {\n params['orderBy'] = opts.orderBy.field;\n params['direction'] = opts.orderBy.direction ?? 'asc';\n }\n\n const filters = opts.where\n ? Array.isArray(opts.where) ? opts.where : [opts.where]\n : [];\n\n if (filters.length > 0) {\n params['where'] = JSON.stringify(filters);\n }\n\n return params;\n}\n\n/** Shorthand helper: creates a simple equality filter */\nexport function eq(field: string, value: unknown): Filter {\n return { field, operator: 'eq' as FilterOperator, value };\n}\n\n/** Shorthand helper: creates a \"not equal\" filter */\nexport function neq(field: string, value: unknown): Filter {\n return { field, operator: 'neq' as FilterOperator, value };\n}\n\n/** Shorthand helper: creates a \"greater than\" filter */\nexport function gt(field: string, value: unknown): Filter {\n return { field, operator: 'gt' as FilterOperator, value };\n}\n\n/** Shorthand helper: creates a \"less than\" filter */\nexport function lt(field: string, value: unknown): Filter {\n return { field, operator: 'lt' as FilterOperator, value };\n}\n\n/** Shorthand helper: creates an \"in array\" filter */\nexport function inArray(field: string, value: unknown[]): Filter {\n return { field, operator: 'in' as FilterOperator, value };\n}\n","import type {\n HydrousConfig,\n QueryOptions,\n RecordResponse,\n SingleRecordResponse,\n} from '../types/index.js';\nimport { HydrousSDKError, toHydrousError } from '../utils/errors.js';\nimport { buildUrl, mergeHeaders, parseResponse } from '../utils/http.js';\nimport { serialiseQuery } from '../utils/query.js';\n\nexport class RecordsClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n\n constructor(config: HydrousConfig) {\n this.baseUrl = config.url;\n this.headers = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n };\n }\n\n // ─── SELECT ────────────────────────────────────────────────────────────────\n\n /**\n * Query records from a collection.\n *\n * @param collection - Collection name (e.g. \"users\")\n * @param options - Filters, ordering, pagination\n *\n * @example\n * const { data, error } = await hydrous.records.select('users', {\n * where: { field: 'role', operator: 'eq', value: 'admin' },\n * orderBy: { field: 'createdAt', direction: 'desc' },\n * limit: 20,\n * });\n */\n async select<T = Record<string, unknown>>(\n collection: string,\n options: QueryOptions = {},\n ): Promise<RecordResponse<T>> {\n try {\n const params = serialiseQuery(options);\n const url = buildUrl(this.baseUrl, `records/${collection}`, params);\n const res = await fetch(url, { headers: this.headers });\n const json = await parseResponse<{ data: T[]; count: number }>(res);\n return { data: json.data, count: json.count, error: null };\n } catch (err) {\n return { data: [], count: 0, error: toHydrousError(err) };\n }\n }\n\n // ─── GET ONE ───────────────────────────────────────────────────────────────\n\n /**\n * Fetch a single record by its ID.\n *\n * @example\n * const { data, error } = await hydrous.records.get('users', 'user_abc123');\n */\n async get<T = Record<string, unknown>>(\n collection: string,\n id: string,\n ): Promise<SingleRecordResponse<T>> {\n try {\n const url = buildUrl(this.baseUrl, `records/${collection}/${id}`);\n const res = await fetch(url, { headers: this.headers });\n const json = await parseResponse<{ data: T }>(res);\n return { data: json.data, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ─── INSERT ────────────────────────────────────────────────────────────────\n\n /**\n * Insert one or more records into a collection.\n *\n * @param collection - Collection name\n * @param payload - A single record object or an array of record objects\n *\n * @example\n * // Single insert\n * const { data, error } = await hydrous.records.insert('users', {\n * name: 'Alice', email: 'alice@example.com'\n * });\n *\n * // Bulk insert\n * const { data, error } = await hydrous.records.insert('users', [\n * { name: 'Alice' }, { name: 'Bob' }\n * ]);\n */\n async insert<T = Record<string, unknown>>(\n collection: string,\n payload: Partial<T> | Partial<T>[],\n ): Promise<RecordResponse<T>> {\n try {\n const url = buildUrl(this.baseUrl, `records/${collection}`);\n const res = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(payload),\n });\n const json = await parseResponse<{ data: T[]; count: number }>(res);\n return { data: json.data, count: json.count, error: null };\n } catch (err) {\n return { data: [], count: 0, error: toHydrousError(err) };\n }\n }\n\n // ─── UPDATE ────────────────────────────────────────────────────────────────\n\n /**\n * Update a record by ID.\n *\n * @example\n * const { data, error } = await hydrous.records.update('users', 'user_abc123', {\n * name: 'Alice Smith'\n * });\n */\n async update<T = Record<string, unknown>>(\n collection: string,\n id: string,\n payload: Partial<T>,\n ): Promise<SingleRecordResponse<T>> {\n try {\n const url = buildUrl(this.baseUrl, `records/${collection}/${id}`);\n const res = await fetch(url, {\n method: 'PATCH',\n headers: this.headers,\n body: JSON.stringify(payload),\n });\n const json = await parseResponse<{ data: T }>(res);\n return { data: json.data, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ─── DELETE ────────────────────────────────────────────────────────────────\n\n /**\n * Delete a record by ID.\n *\n * @example\n * const { error } = await hydrous.records.delete('users', 'user_abc123');\n */\n async delete(\n collection: string,\n id: string,\n ): Promise<SingleRecordResponse<void>> {\n try {\n const url = buildUrl(this.baseUrl, `records/${collection}/${id}`);\n const res = await fetch(url, { method: 'DELETE', headers: this.headers });\n await parseResponse<void>(res);\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n}\n","import type {\n HydrousConfig,\n TrackEventOptions,\n AnalyticsQueryOptions,\n AnalyticsEvent,\n HydrousResponse,\n RecordResponse,\n} from '../types/index.js';\nimport { toHydrousError } from '../utils/errors.js';\nimport { buildUrl, mergeHeaders, parseResponse } from '../utils/http.js';\n\nexport class AnalyticsClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n\n constructor(config: HydrousConfig) {\n this.baseUrl = config.url;\n this.headers = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n };\n }\n\n // ─── TRACK ────────────────────────────────────────────────────────────────\n\n /**\n * Track an analytics event.\n *\n * @example\n * await hydrous.analytics.track({\n * event: 'page_view',\n * properties: { page: '/home', referrer: 'google.com' },\n * userId: 'user_abc123',\n * });\n */\n async track(options: TrackEventOptions): Promise<HydrousResponse<void>> {\n try {\n const url = buildUrl(this.baseUrl, 'analytics/track');\n const res = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({\n ...options,\n timestamp: options.timestamp ?? Date.now(),\n }),\n });\n await parseResponse<void>(res);\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ─── QUERY ────────────────────────────────────────────────────────────────\n\n /**\n * Query recorded analytics events.\n *\n * @example\n * const { data } = await hydrous.analytics.query({\n * event: 'page_view',\n * from: '2024-01-01',\n * to: '2024-01-31',\n * limit: 100,\n * });\n */\n async query(\n options: AnalyticsQueryOptions = {},\n ): Promise<RecordResponse<AnalyticsEvent>> {\n try {\n const params: Record<string, string> = {};\n if (options.event) params['event'] = options.event;\n if (options.from) params['from'] = options.from;\n if (options.to) params['to'] = options.to;\n if (options.limit) params['limit'] = String(options.limit);\n if (options.groupBy) params['groupBy'] = options.groupBy;\n\n const url = buildUrl(this.baseUrl, 'analytics/events', params);\n const res = await fetch(url, { headers: this.headers });\n const json = await parseResponse<{ data: AnalyticsEvent[]; count: number }>(res);\n return { data: json.data, count: json.count, error: null };\n } catch (err) {\n return { data: [], count: 0, error: toHydrousError(err) };\n }\n }\n\n // ─── BATCH TRACK ─────────────────────────────────────────────────────────\n\n /**\n * Track multiple events in a single request (more efficient than\n * calling `track` in a loop).\n *\n * @example\n * await hydrous.analytics.trackBatch([\n * { event: 'signup', userId: 'u1' },\n * { event: 'onboarded', userId: 'u1' },\n * ]);\n */\n async trackBatch(\n events: TrackEventOptions[],\n ): Promise<HydrousResponse<void>> {\n try {\n const url = buildUrl(this.baseUrl, 'analytics/track/batch');\n const stamped = events.map((e) => ({\n ...e,\n timestamp: e.timestamp ?? Date.now(),\n }));\n const res = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({ events: stamped }),\n });\n await parseResponse<void>(res);\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n}\n","import type {\n HydrousConfig,\n BucketKey,\n UploadOptions,\n BatchUploadOptions,\n BatchDownloadOptions,\n ListOptions,\n SignedUrlOptions,\n UploadProgress,\n UploadResult,\n BatchUploadResult,\n BatchDownloadFile,\n FileMetadata,\n ListResult,\n SignedUrlResult,\n StorageStats,\n HydrousResponse,\n DownloadProgress,\n} from '../types/index.js';\nimport { HydrousSDKError, toHydrousError } from '../utils/errors.js';\nimport { buildUrl, parseResponse, readSSEStream, parseSSEText, xhrUpload } from '../utils/http.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internal helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** True when running inside a browser (not Node/Edge/Deno) */\nconst isBrowser = typeof window !== 'undefined' && typeof XMLHttpRequest !== 'undefined';\n\n/** Extract the bucket name segment from an ssk_ key */\nfunction bucketFromKey(key: BucketKey): string {\n // Keys are in the form: ssk_<bucketName>_<secret>\n // The route uses /:bucket/ so we pass the whole key and let the server parse it.\n // For URL construction we use the key directly as the bucket identifier.\n return encodeURIComponent(key);\n}\n\n/** Build the base storage URL for a given bucket key */\nfunction storageUrl(base: string, bucketKey: BucketKey, path: string): string {\n const bucket = bucketFromKey(bucketKey);\n return `${base.replace(/\\/$/, '')}/storage/${bucket}/${path.replace(/^\\//, '')}`;\n}\n\n/** Shared storage request headers (no Content-Type — caller sets it) */\nfunction storageHeaders(bucketKey: BucketKey): Record<string, string> {\n return { 'X-Storage-Key': bucketKey };\n}\n\n/**\n * Collect all SSE progress events emitted by the Hydrous upload endpoint\n * from a text body that was already fully received (XHR flow).\n */\nfunction drainSSEProgress(\n rawText: string,\n onProgress: ((p: UploadProgress) => void) | undefined,\n): { results: UploadResult[]; errors: Array<{ path: string; error: string; code: string }> } {\n const results: UploadResult[] = [];\n const errors: Array<{ path: string; error: string; code: string }> = [];\n\n parseSSEText(rawText, (eventType, data) => {\n const d = data as Record<string, unknown>;\n if (eventType === 'progress' && onProgress) {\n onProgress({\n index: (d['index'] as number) ?? 0,\n total: (d['total'] as number) ?? 1,\n path: (d['path'] as string) ?? '',\n stage: (d['stage'] as UploadProgress['stage']) ?? 'uploading',\n bytesUploaded: (d['bytesUploaded'] as number) ?? 0,\n totalBytes: (d['totalBytes'] as number) ?? 0,\n percent: (d['percent'] as number) ?? 0,\n bytesPerSecond: (d['bytesPerSecond'] as number | null) ?? null,\n eta: (d['eta'] as number | null) ?? null,\n result: d['result'] as UploadResult | undefined,\n error: d['error'] as string | undefined,\n code: d['code'] as string | undefined,\n });\n }\n if (eventType === 'done') {\n if (d['path']) {\n // single-file done\n results.push(d as unknown as UploadResult);\n } else if (Array.isArray(d['errors'])) {\n // batch done — collect\n const succeeded = (d['succeeded'] as UploadResult[]) ?? [];\n const errs = d['errors'] as Array<{ path: string; error: string; code: string }>;\n results.push(...succeeded);\n errors.push(...errs);\n }\n }\n if (eventType === 'error') {\n errors.push({\n path: '',\n error: (d['error'] as string) ?? 'Unknown error',\n code: (d['code'] as string) ?? 'UNKNOWN',\n });\n }\n });\n\n return { results, errors };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// StorageClient\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class StorageClient {\n private readonly baseUrl: string;\n\n constructor(config: HydrousConfig) {\n this.baseUrl = config.url;\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // UPLOAD\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Upload a single file to a bucket.\n *\n * The bucket key **always comes first**.\n * Supply an `onProgress` callback to receive live upload progress including\n * bytes transferred, speed (bytes/sec), ETA, and lifecycle stage.\n *\n * ### Stages fired via `onProgress`\n * | Stage | Meaning |\n * |-------------|------------------------------------------|\n * | `pending` | Queued, not yet started |\n * | `compressing` | Server is compressing the file |\n * | `uploading` | Bytes flowing to cloud storage |\n * | `done` | Confirmed written to cloud storage |\n * | `error` | Something went wrong |\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param file A `File`, `Blob`, or `Buffer` (Node)\n * @param options Path, overwrite flag, progress callback\n *\n * @example\n * const { data, error } = await hydrous.storage.upload(\n * 'ssk_my_bucket_key',\n * file,\n * {\n * path: 'avatars/alice.jpg',\n * overwrite: true,\n * onProgress: (p) => {\n * console.log(`${p.stage} — ${p.percent}% ${p.bytesPerSecond} B/s ETA ${p.eta}s`);\n * },\n * }\n * );\n */\n async upload(\n bucketKey: BucketKey,\n file: File | Blob | Uint8Array | ArrayBuffer,\n options: UploadOptions = {},\n ): Promise<HydrousResponse<UploadResult>> {\n const { path, overwrite = false, onProgress } = options;\n\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'upload');\n const form = new FormData();\n\n if (file instanceof Uint8Array) {\n form.append('file', new Blob([file.buffer as ArrayBuffer]), path ?? 'file');\n } else if (file instanceof ArrayBuffer) {\n form.append('file', new Blob([file]), path ?? 'file');\n } else {\n form.append('file', file, path ?? (file instanceof File ? file.name : 'file'));\n }\n\n if (path) form.append('path', path);\n if (overwrite) form.append('overwrite', 'true');\n\n const headers = storageHeaders(bucketKey);\n\n // ── Browser path: XHR for real upload-progress ticks ─────────────────\n if (isBrowser) {\n const totalBytes = file instanceof Blob\n ? file.size\n : file instanceof Uint8Array\n ? file.byteLength\n : (file as ArrayBuffer).byteLength;\n\n // Phase 1 — XHR upload with byte-level progress\n const rawBody = await xhrUpload(url, form, headers, (loaded, total) => {\n if (onProgress) {\n onProgress({\n index: 0,\n total: 1,\n path: path ?? '',\n stage: 'uploading',\n bytesUploaded: loaded,\n totalBytes: total || totalBytes,\n percent: Math.min(99, Math.round((loaded / (total || totalBytes)) * 100)),\n bytesPerSecond: null,\n eta: null,\n });\n }\n });\n\n // Phase 2 — parse SSE response for stage transitions + final 100%\n const { results, errors } = drainSSEProgress(rawBody, onProgress);\n\n if (errors.length > 0 && results.length === 0) {\n return { data: null, error: { message: errors[0].error, code: errors[0].code } };\n }\n\n const result = results[0] ?? null;\n if (result && onProgress) {\n onProgress({ index: 0, total: 1, path: result.path, stage: 'done',\n bytesUploaded: totalBytes, totalBytes, percent: 100,\n bytesPerSecond: null, eta: 0, result });\n }\n\n return { data: result, error: null };\n }\n\n // ── Node path: fetch + SSE stream ──────────────────────────────────────\n const res = await fetch(url, { method: 'POST', headers, body: form });\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as { error?: string };\n throw new HydrousSDKError(err.error ?? `HTTP ${res.status}`, 'HTTP_ERROR', res.status);\n }\n\n let finalResult: UploadResult | null = null;\n await readSSEStream(res, (eventType, data) => {\n const d = data as Record<string, unknown>;\n if (eventType === 'progress' && onProgress) {\n onProgress({\n index: (d['index'] as number) ?? 0,\n total: (d['total'] as number) ?? 1,\n path: (d['path'] as string) ?? path ?? '',\n stage: (d['stage'] as UploadProgress['stage']) ?? 'uploading',\n bytesUploaded: (d['bytesUploaded'] as number) ?? 0,\n totalBytes: (d['totalBytes'] as number) ?? 0,\n percent: (d['percent'] as number) ?? 0,\n bytesPerSecond: (d['bytesPerSecond'] as number | null) ?? null,\n eta: (d['eta'] as number | null) ?? null,\n result: d['result'] as UploadResult | undefined,\n error: d['error'] as string | undefined,\n });\n }\n if (eventType === 'done') finalResult = data as UploadResult;\n if (eventType === 'error') {\n throw new HydrousSDKError(\n (d['error'] as string) ?? 'Upload failed',\n (d['code'] as string) ?? 'UPLOAD_ERROR',\n );\n }\n });\n\n return { data: finalResult, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // UPLOAD RAW (text / JSON / binary from string)\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Upload raw text or JSON content directly — no `File` object needed.\n * Great for saving generated content, config files, or JSON records.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param path Destination path (e.g. `\"configs/settings.json\"`)\n * @param content String content to store\n * @param options `mimeType`, `overwrite`, `onProgress`\n *\n * @example\n * await hydrous.storage.uploadText(\n * 'ssk_my_bucket_key',\n * 'reports/summary.txt',\n * 'Hello from Hydrous!',\n * { mimeType: 'text/plain' }\n * );\n */\n async uploadText(\n bucketKey: BucketKey,\n path: string,\n content: string,\n options: { mimeType?: string; overwrite?: boolean; onProgress?: UploadOptions['onProgress'] } = {},\n ): Promise<HydrousResponse<UploadResult>> {\n const { mimeType = 'text/plain', overwrite = false, onProgress } = options;\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'upload-raw');\n const headers = { ...storageHeaders(bucketKey), 'Content-Type': 'application/json' };\n const res = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ path, content, mimeType, overwrite }),\n });\n\n if (!res.ok) {\n const e = await res.json().catch(() => ({})) as { error?: string };\n throw new HydrousSDKError(e.error ?? `HTTP ${res.status}`, 'HTTP_ERROR', res.status);\n }\n\n let finalResult: UploadResult | null = null;\n await readSSEStream(res, (eventType, data) => {\n const d = data as Record<string, unknown>;\n if (eventType === 'progress' && onProgress) {\n onProgress({\n index: 0, total: 1, path,\n stage: (d['stage'] as UploadProgress['stage']) ?? 'uploading',\n bytesUploaded: (d['bytesUploaded'] as number) ?? 0,\n totalBytes: (d['totalBytes'] as number) ?? 0,\n percent: (d['percent'] as number) ?? 0,\n bytesPerSecond: (d['bytesPerSecond'] as number | null) ?? null,\n eta: (d['eta'] as number | null) ?? null,\n });\n }\n if (eventType === 'done') finalResult = data as UploadResult;\n });\n\n return { data: finalResult, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // BATCH UPLOAD\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Upload multiple files in one request.\n *\n * `onProgress` fires for **every file individually** — the `index` field\n * tells you which file the event belongs to (0-based, same order as `files`).\n * All files receive a `pending` event upfront before any uploads start,\n * so you can render all progress bars immediately.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param files Array of `File` objects (browser) or `{ name, data }` objects (Node)\n * @param options Prefix, per-file paths, overwrite, concurrency, onProgress\n *\n * @example\n * await hydrous.storage.batchUpload(\n * 'ssk_my_bucket_key',\n * fileArray,\n * {\n * prefix: 'uploads/2024/',\n * onProgress: (p) => {\n * console.log(`File ${p.index}: ${p.stage} ${p.percent}%`);\n * },\n * }\n * );\n */\n async batchUpload(\n bucketKey: BucketKey,\n files: File[],\n options: BatchUploadOptions = {},\n ): Promise<HydrousResponse<BatchUploadResult>> {\n const { prefix = '', paths, overwrite = false, onProgress } = options;\n\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'batch-upload');\n const form = new FormData();\n\n const resolvedPaths = files.map((f, i) =>\n paths?.[i] ?? `${prefix}${f.name}`,\n );\n\n files.forEach((f) => form.append('files', f, f.name));\n form.append('paths', JSON.stringify(resolvedPaths));\n if (overwrite) form.append('overwrite', 'true');\n\n const headers = storageHeaders(bucketKey);\n\n if (isBrowser) {\n const totalBytes = files.reduce((s, f) => s + f.size, 0);\n\n const rawBody = await xhrUpload(url, form, headers, (loaded, total) => {\n if (onProgress) {\n // Distribute overall XHR progress proportionally across files by size\n let cursor = 0;\n for (let i = 0; i < files.length; i++) {\n const share = files[i].size / (totalBytes || 1);\n const myStart = cursor;\n const myEnd = cursor + share;\n const fileLoaded = Math.max(0, Math.min(\n files[i].size,\n ((loaded / (total || totalBytes)) - myStart) / share * files[i].size,\n ));\n onProgress({\n index: i, total: files.length, path: resolvedPaths[i],\n stage: 'uploading',\n bytesUploaded: Math.round(fileLoaded),\n totalBytes: files[i].size,\n percent: Math.min(99, Math.round((fileLoaded / files[i].size) * 100)),\n bytesPerSecond: null,\n eta: null,\n });\n cursor = myEnd;\n }\n }\n });\n\n const { results, errors } = drainSSEProgress(rawBody, onProgress);\n return {\n data: {\n succeeded: results,\n failed: errors,\n },\n error: null,\n };\n }\n\n // Node\n const res = await fetch(url, { method: 'POST', headers, body: form });\n if (!res.ok) {\n const e = await res.json().catch(() => ({})) as { error?: string };\n throw new HydrousSDKError(e.error ?? `HTTP ${res.status}`, 'HTTP_ERROR', res.status);\n }\n\n const succeeded: UploadResult[] = [];\n const failed: Array<{ path: string; error: string; code: string }> = [];\n\n await readSSEStream(res, (eventType, data) => {\n const d = data as Record<string, unknown>;\n if (eventType === 'progress' && onProgress) {\n onProgress({\n index: (d['index'] as number) ?? 0,\n total: (d['total'] as number) ?? files.length,\n path: (d['path'] as string) ?? '',\n stage: (d['stage'] as UploadProgress['stage']) ?? 'uploading',\n bytesUploaded: (d['bytesUploaded'] as number) ?? 0,\n totalBytes: (d['totalBytes'] as number) ?? 0,\n percent: (d['percent'] as number) ?? 0,\n bytesPerSecond: (d['bytesPerSecond'] as number | null) ?? null,\n eta: (d['eta'] as number | null) ?? null,\n result: d['result'] as UploadResult | undefined,\n error: d['error'] as string | undefined,\n code: d['code'] as string | undefined,\n });\n }\n if (eventType === 'done' && d['succeeded']) {\n succeeded.push(...(d['succeeded'] as UploadResult[]));\n failed.push(...(d['errors'] as Array<{ path: string; error: string; code: string }> ?? []));\n }\n });\n\n return { data: { succeeded, failed }, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // DOWNLOAD\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Download a single file and return its content as an `ArrayBuffer`.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param filePath Path of the file within your bucket\n *\n * @example\n * const { data, error } = await hydrous.storage.download(\n * 'ssk_my_bucket_key',\n * 'avatars/alice.jpg'\n * );\n * if (data) {\n * const blob = new Blob([data]);\n * const url = URL.createObjectURL(blob);\n * }\n */\n async download(\n bucketKey: BucketKey,\n filePath: string,\n ): Promise<HydrousResponse<ArrayBuffer>> {\n try {\n const url = storageUrl(this.baseUrl, bucketKey, `download/${filePath}`);\n const res = await fetch(url, { headers: storageHeaders(bucketKey) });\n if (!res.ok) {\n const e = await res.json().catch(() => ({})) as { error?: string };\n throw new HydrousSDKError(e.error ?? `HTTP ${res.status}`, 'HTTP_ERROR', res.status);\n }\n const buffer = await res.arrayBuffer();\n return { data: buffer, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // BATCH DOWNLOAD\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Download multiple files in one request.\n *\n * When `autoSave: true` (browser only) each file is automatically saved\n * to the user's Downloads folder as it arrives.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param filePaths Array of file paths within your bucket\n * @param options Concurrency, onProgress, autoSave\n *\n * @example\n * const { data } = await hydrous.storage.batchDownload(\n * 'ssk_my_bucket_key',\n * ['reports/jan.pdf', 'reports/feb.pdf'],\n * {\n * onProgress: (p) => console.log(p.path, p.status),\n * autoSave: true, // triggers browser file-save dialog per file\n * }\n * );\n */\n async batchDownload(\n bucketKey: BucketKey,\n filePaths: string[],\n options: BatchDownloadOptions = {},\n ): Promise<HydrousResponse<BatchDownloadFile[]>> {\n const { concurrency = 5, onProgress, autoSave = false } = options;\n\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'batch-download');\n const res = await fetch(url, {\n method: 'POST',\n headers: { ...storageHeaders(bucketKey), 'Content-Type': 'application/json' },\n body: JSON.stringify({ paths: filePaths, concurrency }),\n });\n\n if (!res.ok) {\n const e = await res.json().catch(() => ({})) as { error?: string };\n throw new HydrousSDKError(e.error ?? `HTTP ${res.status}`, 'HTTP_ERROR', res.status);\n }\n\n const downloadedFiles: BatchDownloadFile[] = [];\n\n await readSSEStream(res, (eventType, data) => {\n const d = data as Record<string, unknown>;\n\n if (eventType === 'file') {\n const base64 = d['content'] as string;\n const mimeType = (d['mimeType'] as string) ?? 'application/octet-stream';\n const path = (d['path'] as string) ?? '';\n const size = (d['size'] as number) ?? 0;\n const index = (d['index'] as number) ?? 0;\n\n // Decode base64 → ArrayBuffer\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n const content = bytes.buffer;\n\n downloadedFiles.push({ path, content, mimeType, size });\n\n if (onProgress) {\n onProgress({\n index,\n total: filePaths.length,\n path,\n status: 'success',\n size,\n mimeType,\n });\n }\n\n // Auto-save in browser\n if (autoSave && isBrowser) {\n const blob = new Blob([content], { type: mimeType });\n const blobUrl = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = blobUrl;\n a.download = path.split('/').pop() ?? 'download';\n a.click();\n setTimeout(() => URL.revokeObjectURL(blobUrl), 5000);\n }\n }\n\n if (eventType === 'error' && onProgress) {\n const index = (d['index'] as number) ?? 0;\n onProgress({\n index,\n total: filePaths.length,\n path: filePaths[index] ?? '',\n status: 'error',\n error: (d['error'] as string) ?? 'Download failed',\n });\n }\n });\n\n return { data: downloadedFiles, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // LIST\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * List files and folders inside a bucket (or a folder within it).\n *\n * Results are paginated — use `pagination.nextCursor` to fetch the next page.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param options `prefix`, `limit`, `cursor`\n *\n * @example\n * const { data } = await hydrous.storage.list('ssk_my_bucket_key', {\n * prefix: 'avatars/',\n * limit: 50,\n * });\n * for (const item of data.items) {\n * console.log(item.type, item.path);\n * }\n */\n async list(\n bucketKey: BucketKey,\n options: ListOptions = {},\n ): Promise<HydrousResponse<ListResult>> {\n const { prefix = '', limit = 50, cursor } = options;\n try {\n const params: Record<string, string | number | boolean | undefined> = {\n prefix: prefix || undefined,\n limit,\n cursor: cursor || undefined,\n };\n const url = buildUrl(\n this.baseUrl,\n `storage/${bucketFromKey(bucketKey)}/list`,\n params,\n );\n const res = await fetch(url, { headers: storageHeaders(bucketKey) });\n const json = await parseResponse<ListResult>(res);\n return { data: json, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // METADATA\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Get metadata for a specific file (size, MIME type, compression info, etc.)\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param filePath Path of the file within your bucket\n *\n * @example\n * const { data } = await hydrous.storage.metadata(\n * 'ssk_my_bucket_key',\n * 'avatars/alice.jpg'\n * );\n * console.log(data.size, data.mimeType);\n */\n async metadata(\n bucketKey: BucketKey,\n filePath: string,\n ): Promise<HydrousResponse<FileMetadata>> {\n try {\n const url = storageUrl(this.baseUrl, bucketKey, `metadata/${filePath}`);\n const res = await fetch(url, { headers: storageHeaders(bucketKey) });\n const json = await parseResponse<{ data: FileMetadata }>(res);\n return { data: json.data, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // DELETE FILE\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Delete a single file.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param filePath Path of the file to delete\n *\n * @example\n * await hydrous.storage.deleteFile('ssk_my_bucket_key', 'avatars/old.jpg');\n */\n async deleteFile(\n bucketKey: BucketKey,\n filePath: string,\n ): Promise<HydrousResponse<void>> {\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'file');\n const res = await fetch(url, {\n method: 'DELETE',\n headers: { ...storageHeaders(bucketKey), 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: filePath }),\n });\n await parseResponse<void>(res);\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // DELETE FOLDER\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Recursively delete a folder and all of its contents.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param folderPath Folder path to delete (e.g. `\"old-uploads/\"`)\n *\n * @example\n * await hydrous.storage.deleteFolder('ssk_my_bucket_key', 'temp/');\n */\n async deleteFolder(\n bucketKey: BucketKey,\n folderPath: string,\n ): Promise<HydrousResponse<void>> {\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'folder');\n const res = await fetch(url, {\n method: 'DELETE',\n headers: { ...storageHeaders(bucketKey), 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: folderPath }),\n });\n await parseResponse<void>(res);\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // CREATE FOLDER\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Create an empty folder.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param folderPath Path for the new folder (e.g. `\"avatars/2024/\"`)\n *\n * @example\n * await hydrous.storage.createFolder('ssk_my_bucket_key', 'avatars/2024/');\n */\n async createFolder(\n bucketKey: BucketKey,\n folderPath: string,\n ): Promise<HydrousResponse<void>> {\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'folder');\n const res = await fetch(url, {\n method: 'POST',\n headers: { ...storageHeaders(bucketKey), 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: folderPath }),\n });\n await parseResponse<void>(res);\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // MOVE\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Move (rename) a file to a new path.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param fromPath Current path of the file\n * @param toPath New path for the file\n *\n * @example\n * await hydrous.storage.move(\n * 'ssk_my_bucket_key',\n * 'drafts/report.pdf',\n * 'published/report.pdf'\n * );\n */\n async move(\n bucketKey: BucketKey,\n fromPath: string,\n toPath: string,\n ): Promise<HydrousResponse<void>> {\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'move');\n const res = await fetch(url, {\n method: 'POST',\n headers: { ...storageHeaders(bucketKey), 'Content-Type': 'application/json' },\n body: JSON.stringify({ from: fromPath, to: toPath }),\n });\n await parseResponse<void>(res);\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // COPY\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Copy a file to a new path (original is kept).\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param fromPath Source path\n * @param toPath Destination path\n *\n * @example\n * await hydrous.storage.copy(\n * 'ssk_my_bucket_key',\n * 'templates/invoice.pdf',\n * 'invoices/invoice-001.pdf'\n * );\n */\n async copy(\n bucketKey: BucketKey,\n fromPath: string,\n toPath: string,\n ): Promise<HydrousResponse<void>> {\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'copy');\n const res = await fetch(url, {\n method: 'POST',\n headers: { ...storageHeaders(bucketKey), 'Content-Type': 'application/json' },\n body: JSON.stringify({ from: fromPath, to: toPath }),\n });\n await parseResponse<void>(res);\n return { data: undefined, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // SIGNED URL\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Generate a time-limited public URL for a private file.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n * @param filePath Path of the file\n * @param options `expiresIn` seconds (default: 3600)\n *\n * @example\n * const { data } = await hydrous.storage.signedUrl(\n * 'ssk_my_bucket_key',\n * 'private/contract.pdf',\n * { expiresIn: 300 } // 5 minutes\n * );\n * console.log(data.signedUrl); // share this URL\n */\n async signedUrl(\n bucketKey: BucketKey,\n filePath: string,\n options: SignedUrlOptions = {},\n ): Promise<HydrousResponse<SignedUrlResult>> {\n const { expiresIn = 3600 } = options;\n try {\n const url = storageUrl(this.baseUrl, bucketKey, 'signed-url');\n const res = await fetch(url, {\n method: 'POST',\n headers: { ...storageHeaders(bucketKey), 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: filePath, expiresInSeconds: expiresIn }),\n });\n const json = await parseResponse<SignedUrlResult>(res);\n return { data: json, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // STATS\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Get usage and billing statistics for this bucket key.\n *\n * @param bucketKey Your storage bucket key (`ssk_…`)\n *\n * @example\n * const { data } = await hydrous.storage.stats('ssk_my_bucket_key');\n * console.log(`${data.totalFiles} files, ${data.totalSizeBytes} bytes stored`);\n */\n async stats(\n bucketKey: BucketKey,\n ): Promise<HydrousResponse<StorageStats>> {\n try {\n const url = buildUrl(this.baseUrl, `storage/${bucketFromKey(bucketKey)}/stats`);\n const res = await fetch(url, { headers: storageHeaders(bucketKey) });\n const json = await parseResponse<{ data: StorageStats }>(res);\n return { data: json.data, error: null };\n } catch (err) {\n return { data: null, error: toHydrousError(err) };\n }\n }\n}\n","import type { HydrousConfig } from './types/index.js';\nimport { AuthClient } from './auth/client.js';\nimport { RecordsClient } from './records/client.js';\nimport { AnalyticsClient } from './analytics/client.js';\nimport { StorageClient } from './storage/client.js';\n\n/**\n * The root Hydrous client.\n *\n * Instantiate once and reuse throughout your app.\n *\n * @example\n * import { HydrousClient } from 'hydrous';\n *\n * const hydrous = new HydrousClient({\n * url: 'https://api.myapp.hydrous.app',\n * apiKey: 'hk_live_…',\n * });\n */\nexport class HydrousClient {\n /** Authentication — sign up, sign in, sign out, session management */\n public readonly auth: AuthClient;\n /** Records — insert, select, update, delete structured data */\n public readonly records: RecordsClient;\n /** Analytics — track events, query event history */\n public readonly analytics: AnalyticsClient;\n /**\n * Storage — upload, download, list, move, delete files.\n *\n * Every method takes a **bucket key** (`ssk_…`) as its **first argument**.\n */\n public readonly storage: StorageClient;\n\n constructor(config: HydrousConfig) {\n if (!config.url) throw new Error('[Hydrous] config.url is required');\n if (!config.apiKey) throw new Error('[Hydrous] config.apiKey is required');\n\n this.auth = new AuthClient(config);\n this.records = new RecordsClient(config);\n this.analytics = new AnalyticsClient(config);\n this.storage = new StorageClient(config);\n }\n}\n","// ─── Main client ─────────────────────────────────────────────────────────────\nexport { HydrousClient } from './client.js';\n\n// ─── Sub-clients (for direct instantiation or testing) ───────────────────────\nexport { AuthClient } from './auth/index.js';\nexport { RecordsClient } from './records/index.js';\nexport { AnalyticsClient } from './analytics/index.js';\nexport { StorageClient } from './storage/index.js';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\nexport type {\n // Core\n HydrousConfig,\n HydrousResponse,\n HydrousError,\n // Records\n Filter,\n FilterOperator,\n QueryOptions,\n RecordResponse,\n SingleRecordResponse,\n // Auth\n AuthUser,\n AuthSession,\n SignUpOptions,\n SignInOptions,\n // Analytics\n TrackEventOptions,\n AnalyticsQueryOptions,\n AnalyticsEvent,\n // Storage\n BucketKey,\n UploadStage,\n UploadProgress,\n DownloadProgress,\n UploadResult,\n UploadOptions,\n BatchUploadOptions,\n BatchUploadResult,\n BatchDownloadFile,\n BatchDownloadOptions,\n FileMetadata,\n StorageItem,\n ListResult,\n ListOptions,\n SignedUrlResult,\n SignedUrlOptions,\n StorageStats,\n} from './types/index.js';\n\n// ─── Query helpers ────────────────────────────────────────────────────────────\nexport { eq, neq, gt, lt, inArray } from './utils/query.js';\n\n// ─── Error utilities ─────────────────────────────────────────────────────────\nexport { HydrousSDKError, isHydrousError } from './utils/errors.js';\n\n// ─── Convenience factory ─────────────────────────────────────────────────────\nimport { HydrousClient } from './client.js';\nimport type { HydrousConfig } from './types/index.js';\n\n/**\n * Create and return a `HydrousClient` instance.\n *\n * @example\n * import { createClient } from 'hydrous';\n *\n * const hydrous = createClient({\n * url: 'https://api.myapp.hydrous.app',\n * apiKey: 'hk_live_…',\n * });\n */\nexport function createClient(config: HydrousConfig): HydrousClient {\n return new HydrousClient(config);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/errors.ts","../src/utils/http.ts","../src/auth/client.ts","../src/utils/query.ts","../src/records/client.ts","../src/analytics/client.ts","../src/storage/manager.ts","../src/storage/scoped.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export class HydrousError extends Error {\n readonly code: string;\n readonly status?: number;\n readonly requestId?: string;\n readonly details?: string[];\n\n constructor(\n message: string,\n code: string,\n status?: number,\n requestId?: string,\n details?: string[],\n ) {\n super(message);\n this.name = 'HydrousError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n this.details = details;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toString(): string {\n return `HydrousError [${this.code}]: ${this.message}`;\n }\n}\n\nexport class AuthError extends HydrousError {\n constructor(message: string, code: string, status?: number, requestId?: string, details?: string[]) {\n super(message, code, status, requestId, details);\n this.name = 'AuthError';\n }\n}\n\nexport class RecordError extends HydrousError {\n constructor(message: string, code: string, status?: number, requestId?: string, details?: string[]) {\n super(message, code, status, requestId, details);\n this.name = 'RecordError';\n }\n}\n\nexport class StorageError extends HydrousError {\n constructor(message: string, code: string, status?: number, requestId?: string) {\n super(message, code, status, requestId);\n this.name = 'StorageError';\n }\n}\n\nexport class AnalyticsError extends HydrousError {\n constructor(message: string, code: string, status?: number, requestId?: string) {\n super(message, code, status, requestId);\n this.name = 'AnalyticsError';\n }\n}\n\nexport class ValidationError extends HydrousError {\n constructor(message: string, details?: string[]) {\n super(message, 'VALIDATION_ERROR', 400, undefined, details);\n this.name = 'ValidationError';\n }\n}\n\nexport class NetworkError extends HydrousError {\n readonly cause?: unknown;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'NETWORK_ERROR');\n this.name = 'NetworkError';\n this.cause = cause;\n }\n}","import { HydrousError, NetworkError } from './errors.js';\n\nexport const DEFAULT_BASE_URL = 'https://db-api-82687684612.us-central1.run.app';\n\nexport interface RequestOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n body?: unknown;\n headers?: Record<string, string>;\n rawBody?: string | FormData | Uint8Array<ArrayBuffer>;\n contentType?: string;\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly securityKey: string;\n\n constructor(baseUrl: string, securityKey: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n this.securityKey = securityKey;\n }\n\n async request<T = unknown>(path: string, opts: RequestOptions = {}): Promise<T> {\n const {\n method = 'GET',\n body,\n headers = {},\n rawBody,\n contentType = 'application/json',\n } = opts;\n\n const url = `${this.baseUrl}${path}`;\n\n const reqHeaders: Record<string, string> = {\n 'X-Api-Key': this.securityKey,\n ...headers,\n };\n\n let reqBody: string | FormData | Uint8Array<ArrayBuffer> | null = null;\n\n if (rawBody !== undefined) {\n reqBody = rawBody;\n if (contentType) reqHeaders['Content-Type'] = contentType;\n } else if (body !== undefined) {\n reqBody = JSON.stringify(body);\n reqHeaders['Content-Type'] = 'application/json';\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: reqBody,\n });\n } catch (err) {\n throw new NetworkError(\n `Network request failed: ${err instanceof Error ? err.message : String(err)}`,\n err,\n );\n }\n\n const ct = response.headers.get('content-type') ?? '';\n\n if (!ct.includes('application/json')) {\n if (!response.ok) {\n throw new HydrousError(\n `Request failed with status ${response.status}`,\n `HTTP_${response.status}`,\n response.status,\n );\n }\n const buffer = await response.arrayBuffer();\n return buffer as T;\n }\n\n let responseData: unknown;\n try {\n responseData = await response.json() as unknown;\n } catch {\n throw new HydrousError(\n 'Failed to parse server response as JSON',\n 'PARSE_ERROR',\n response.status,\n );\n }\n\n if (!response.ok) {\n const errData = responseData as Record<string, unknown>;\n throw new HydrousError(\n (errData['error'] as string | undefined) ?? `Request failed with status ${response.status}`,\n (errData['code'] as string | undefined) ?? `HTTP_${response.status}`,\n response.status,\n errData['requestId'] as string | undefined,\n errData['details'] as string[] | undefined,\n );\n }\n\n return responseData as T;\n }\n\n get<T = unknown>(path: string, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'GET', headers });\n }\n\n post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'POST', body, headers });\n }\n\n put<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'PUT', body, headers });\n }\n\n patch<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'PATCH', body, headers });\n }\n\n delete<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'DELETE', body, headers });\n }\n\n async putToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array<ArrayBuffer> | ArrayBuffer,\n mimeType: string,\n onProgress?: (percent: number) => void,\n ): Promise<void> {\n if (typeof XMLHttpRequest !== 'undefined' && onProgress) {\n return new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = (e: ProgressEvent<EventTarget>) => {\n if (e.lengthComputable) {\n onProgress(Math.round((e.loaded / e.total) * 100));\n }\n };\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve();\n } else {\n reject(new Error(`Upload failed: ${xhr.status}`));\n }\n };\n\n xhr.onerror = () => reject(new Error('Upload network error'));\n xhr.open('PUT', signedUrl);\n xhr.setRequestHeader('Content-Type', mimeType);\n\n const payload: Blob = data instanceof Blob\n ? data\n : new Blob([data as ArrayBuffer], { type: mimeType });\n\n xhr.send(payload);\n });\n }\n\n const fetchBody: Blob = data instanceof Blob\n ? data\n : new Blob([data as ArrayBuffer], { type: mimeType });\n\n const response = await fetch(signedUrl, {\n method: 'PUT',\n headers: { 'Content-Type': mimeType },\n body: fetchBody,\n });\n\n if (!response.ok) {\n throw new NetworkError(`Signed URL upload failed with status ${response.status}`);\n }\n }\n}","import type { HttpClient } from '../utils/http.js';\nimport { AuthError } from '../utils/errors.js';\nimport type {\n SignupOptions,\n LoginOptions,\n AuthResult,\n UserRecord,\n UpdateUserOptions,\n ChangePasswordOptions,\n ListUsersOptions,\n ListUsersResult,\n Session,\n} from '../types/index.js';\n\ninterface ApiAuthResult {\n success: boolean;\n user: UserRecord;\n session: Session;\n requestId?: string;\n}\n\ninterface ApiUserResult {\n success: boolean;\n user: UserRecord;\n requestId?: string;\n}\n\ninterface ApiSessionResult {\n success: boolean;\n session: Session;\n requestId?: string;\n}\n\ninterface ApiMessageResult {\n success: boolean;\n message: string;\n meta?: Record<string, unknown>;\n requestId?: string;\n}\n\n/**\n * AuthClient — full user authentication for a single bucket.\n *\n * Every method maps directly to a route in the server's `auth.js` router.\n * The bucket key is the name of your user bucket (e.g. \"users\" or \"customers\").\n *\n * @example\n * ```ts\n * const db = createClient({ securityKey: 'sk_...' });\n * const auth = db.auth('my-app-users');\n *\n * const { user, session } = await auth.signup({\n * email: 'alice@example.com',\n * password: 'hunter2',\n * fullName: 'Alice',\n * });\n * ```\n */\nexport class AuthClient {\n private readonly http: HttpClient;\n private readonly bucketKey: string;\n private readonly basePath: string;\n\n constructor(http: HttpClient, bucketKey: string) {\n this.http = http;\n this.bucketKey = bucketKey;\n this.basePath = `/auth/${bucketKey}`;\n }\n\n // ─── Registration & Login ─────────────────────────────────────────────────\n\n /**\n * Register a new user in this bucket.\n *\n * @example\n * ```ts\n * const { user, session } = await auth.signup({\n * email: 'alice@example.com',\n * password: 'hunter2',\n * fullName: 'Alice Wonderland',\n * // Any extra fields are stored on the user record:\n * plan: 'pro',\n * });\n * ```\n */\n async signup(options: SignupOptions): Promise<AuthResult> {\n const result = await this.http.post<ApiAuthResult>(`${this.basePath}/signup`, options);\n return { user: result.user, session: result.session };\n }\n\n /**\n * Authenticate an existing user and create a session.\n * Sessions are valid for 24 hours; use `refreshSession` to extend.\n *\n * @example\n * ```ts\n * const { user, session } = await auth.login({\n * email: 'alice@example.com',\n * password: 'hunter2',\n * });\n * // Store session.sessionId safely — you'll need it for other calls.\n * ```\n */\n async login(options: LoginOptions): Promise<AuthResult> {\n const result = await this.http.post<ApiAuthResult>(`${this.basePath}/login`, options);\n return { user: result.user, session: result.session };\n }\n\n /**\n * Invalidate a session (sign out).\n *\n * @example\n * ```ts\n * await auth.logout({ sessionId: session.sessionId });\n * ```\n */\n async logout({ sessionId }: { sessionId: string }): Promise<void> {\n await this.http.post<ApiMessageResult>(`${this.basePath}/logout`, { sessionId });\n }\n\n /**\n * Extend a session using its refresh token.\n * Returns a new session object.\n *\n * @example\n * ```ts\n * const newSession = await auth.refreshSession({ refreshToken: session.refreshToken });\n * ```\n */\n async refreshSession({ refreshToken }: { refreshToken: string }): Promise<Session> {\n const result = await this.http.post<ApiSessionResult>(\n `${this.basePath}/session/refresh`,\n { refreshToken },\n );\n return result.session;\n }\n\n // ─── User Profile ─────────────────────────────────────────────────────────\n\n /**\n * Fetch a user by their ID.\n *\n * @example\n * ```ts\n * const user = await auth.getUser({ userId: 'usr_abc123' });\n * ```\n */\n async getUser({ userId }: { userId: string }): Promise<UserRecord> {\n const result = await this.http.get<ApiUserResult>(`${this.basePath}/user/${userId}`);\n return result.user;\n }\n\n /**\n * Update fields on a user record. Requires a valid session.\n *\n * @example\n * ```ts\n * const updated = await auth.updateUser({\n * sessionId: session.sessionId,\n * userId: user.id,\n * data: { fullName: 'Alice Smith', plan: 'enterprise' },\n * });\n * ```\n */\n async updateUser(options: UpdateUserOptions): Promise<UserRecord> {\n const { sessionId, userId, data } = options;\n const result = await this.http.patch<ApiUserResult>(\n `${this.basePath}/user`,\n { sessionId, userId, ...data },\n );\n return result.user;\n }\n\n /**\n * Soft-delete a user. The record is marked deleted but not removed from storage.\n * Requires a valid session (the user can delete themselves, or an admin can delete any user).\n *\n * @example\n * ```ts\n * await auth.deleteUser({ sessionId: session.sessionId, userId: user.id });\n * ```\n */\n async deleteUser({ sessionId, userId }: { sessionId: string; userId: string }): Promise<void> {\n await this.http.delete<ApiMessageResult>(`${this.basePath}/user`, { sessionId, userId });\n }\n\n // ─── Admin Operations ─────────────────────────────────────────────────────\n\n /**\n * List all users in the bucket. **Admin session required.**\n *\n * @example\n * ```ts\n * const { users, total } = await auth.listUsers({\n * sessionId: adminSession.sessionId,\n * limit: 50,\n * offset: 0,\n * });\n * ```\n */\n async listUsers(options: ListUsersOptions): Promise<ListUsersResult> {\n const { sessionId, limit = 50, offset = 0 } = options;\n const result = await this.http.post<{ success: boolean } & ListUsersResult>(\n `${this.basePath}/users/list`,\n { sessionId, limit, offset },\n );\n return { users: result.users, total: result.total, limit: result.limit, offset: result.offset };\n }\n\n /**\n * Permanently hard-delete a user and all their data. **Admin session required.**\n * This action is irreversible.\n *\n * @example\n * ```ts\n * await auth.hardDeleteUser({ sessionId: adminSession.sessionId, userId: user.id });\n * ```\n */\n async hardDeleteUser({ sessionId, userId }: { sessionId: string; userId: string }): Promise<void> {\n await this.http.delete<ApiMessageResult>(`${this.basePath}/user/hard`, { sessionId, userId });\n }\n\n /**\n * Bulk delete multiple users. **Admin session required.**\n *\n * @example\n * ```ts\n * const result = await auth.bulkDeleteUsers({\n * sessionId: adminSession.sessionId,\n * userIds: ['usr_a', 'usr_b'],\n * });\n * ```\n */\n async bulkDeleteUsers({\n sessionId,\n userIds,\n }: {\n sessionId: string;\n userIds: string[];\n }): Promise<{ deleted: number; failed: string[] }> {\n const result = await this.http.post<{ success: boolean; deleted: number; failed: string[] }>(\n `${this.basePath}/users/bulk-delete`,\n { sessionId, userIds },\n );\n return { deleted: result.deleted, failed: result.failed };\n }\n\n /**\n * Lock a user account, preventing login. **Admin session required.**\n *\n * @param options.duration Lock duration in milliseconds. Defaults to 15 minutes.\n *\n * @example\n * ```ts\n * await auth.lockAccount({\n * sessionId: adminSession.sessionId,\n * userId: user.id,\n * duration: 60 * 60 * 1000, // 1 hour\n * });\n * ```\n */\n async lockAccount({\n sessionId,\n userId,\n duration,\n }: {\n sessionId: string;\n userId: string;\n duration?: number;\n }): Promise<{ lockedUntil: number; unlockTime: string }> {\n const result = await this.http.post<{\n success: boolean;\n data: { lockedUntil: number; unlockTime: string };\n }>(`${this.basePath}/account/lock`, { sessionId, userId, duration });\n return result.data;\n }\n\n /**\n * Unlock a previously locked user account. **Admin session required.**\n *\n * @example\n * ```ts\n * await auth.unlockAccount({ sessionId: adminSession.sessionId, userId: user.id });\n * ```\n */\n async unlockAccount({\n sessionId,\n userId,\n }: {\n sessionId: string;\n userId: string;\n }): Promise<void> {\n await this.http.post<ApiMessageResult>(`${this.basePath}/account/unlock`, { sessionId, userId });\n }\n\n // ─── Password Management ──────────────────────────────────────────────────\n\n /**\n * Change a user's password. The user must supply their current password.\n *\n * @example\n * ```ts\n * await auth.changePassword({\n * sessionId: session.sessionId,\n * userId: user.id,\n * currentPassword: 'hunter2',\n * newPassword: 'correcthorsebatterystaple',\n * });\n * ```\n */\n async changePassword(options: ChangePasswordOptions): Promise<void> {\n await this.http.post<ApiMessageResult>(`${this.basePath}/password/change`, options);\n }\n\n /**\n * Request a password reset email for a user.\n * Always returns success to prevent user enumeration.\n *\n * @example\n * ```ts\n * await auth.requestPasswordReset({ email: 'alice@example.com' });\n * ```\n */\n async requestPasswordReset({ email }: { email: string }): Promise<void> {\n await this.http.post<ApiMessageResult>(`${this.basePath}/password/reset/request`, { email });\n }\n\n /**\n * Complete a password reset using the token from the reset email.\n *\n * @example\n * ```ts\n * await auth.confirmPasswordReset({\n * resetToken: 'tok_from_email',\n * newPassword: 'correcthorsebatterystaple',\n * });\n * ```\n */\n async confirmPasswordReset({\n resetToken,\n newPassword,\n }: {\n resetToken: string;\n newPassword: string;\n }): Promise<void> {\n await this.http.post<ApiMessageResult>(`${this.basePath}/password/reset/confirm`, {\n resetToken,\n newPassword,\n });\n }\n\n // ─── Email Verification ───────────────────────────────────────────────────\n\n /**\n * Send (or resend) an email verification message to a user.\n *\n * @example\n * ```ts\n * await auth.requestEmailVerification({ userId: user.id });\n * ```\n */\n async requestEmailVerification({ userId }: { userId: string }): Promise<void> {\n await this.http.post<ApiMessageResult>(`${this.basePath}/email/verify/request`, { userId });\n }\n\n /**\n * Confirm an email address using the token from the verification email.\n *\n * @example\n * ```ts\n * await auth.confirmEmailVerification({ verifyToken: 'tok_from_email' });\n * ```\n */\n async confirmEmailVerification({ verifyToken }: { verifyToken: string }): Promise<void> {\n await this.http.post<ApiMessageResult>(`${this.basePath}/email/verify/confirm`, { verifyToken });\n }\n}\n","import type { QueryFilter, QueryOptions } from '../types/index.js';\n\n/**\n * Build query string parameters for GET /records/:bucket requests.\n */\nexport function buildQueryParams(options: QueryOptions = {}): string {\n const params = new URLSearchParams();\n\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n if (options.offset !== undefined) params.set('offset', String(options.offset));\n if (options.orderBy !== undefined) params.set('orderBy', options.orderBy);\n if (options.order !== undefined) params.set('order', options.order);\n if (options.fields !== undefined) params.set('fields', options.fields);\n if (options.startAfter !== undefined) params.set('startAfter', options.startAfter);\n if (options.startAt !== undefined) params.set('startAt', options.startAt);\n if (options.endAt !== undefined) params.set('endAt', options.endAt);\n\n if (options.dateRange?.start !== undefined)\n params.set('startDate', new Date(options.dateRange.start).toISOString().split('T')[0]!);\n if (options.dateRange?.end !== undefined)\n params.set('endDate', new Date(options.dateRange.end).toISOString().split('T')[0]!);\n\n if (options.filters && options.filters.length > 0) {\n params.set('filters', JSON.stringify(options.filters));\n }\n\n const str = params.toString();\n return str ? `?${str}` : '';\n}\n\n/**\n * Normalise a filter shorthand into the standard { field, op, value } shape.\n * Accepts either a QueryFilter object or a 3-tuple [field, op, value].\n */\nexport function normaliseFilter(\n filter: QueryFilter | [string, QueryFilter['op'], QueryFilter['value']],\n): QueryFilter {\n if (Array.isArray(filter)) {\n const [field, op, value] = filter;\n return { field, op, value };\n }\n return filter;\n}\n\n/**\n * Detect a likely MIME type from a file extension.\n * Used when mimeType is not explicitly provided.\n */\nexport function guessMimeType(filename: string): string {\n const ext = filename.split('.').pop()?.toLowerCase();\n const map: Record<string, string> = {\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n webp: 'image/webp',\n svg: 'image/svg+xml',\n pdf: 'application/pdf',\n mp4: 'video/mp4',\n webm: 'video/webm',\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n txt: 'text/plain',\n html: 'text/html',\n css: 'text/css',\n js: 'application/javascript',\n json: 'application/json',\n xml: 'application/xml',\n zip: 'application/zip',\n csv: 'text/csv',\n };\n return map[ext ?? ''] ?? 'application/octet-stream';\n}\n\n/**\n * Validate that a name contains only safe characters.\n * Bucket keys allow hyphens; field names should not contain spaces or special chars.\n */\nexport function assertSafeName(name: string, label = 'name'): void {\n if (!/^[a-zA-Z_][a-zA-Z0-9_.\\-]{0,200}$/.test(name)) {\n throw new Error(\n `Invalid ${label} \"${name}\". Must start with a letter or underscore and contain only letters, numbers, underscores, dots, or hyphens.`,\n );\n }\n}","import type { HttpClient } from '../utils/http.js';\nimport { buildQueryParams, assertSafeName } from '../utils/query.js';\nimport type {\n RecordData,\n RecordResult,\n QueryOptions,\n QueryResult,\n PatchRecordOptions,\n RecordHistoryEntry,\n} from '../types/index.js';\n\ninterface ApiRecordResult<T> {\n success: boolean;\n record?: T & RecordResult;\n data?: T & RecordResult;\n}\n\ninterface ApiQueryResult<T> {\n success: boolean;\n records: (T & RecordResult)[];\n total?: number;\n hasMore?: boolean;\n nextCursor?: string;\n}\n\ninterface ApiDeleteResult {\n success: boolean;\n deleted: boolean;\n id: string;\n}\n\ninterface ApiHistoryResult {\n success: boolean;\n history: RecordHistoryEntry[];\n}\n\n/**\n * RecordsClient — create, read, update, delete, and query records in a bucket.\n *\n * A bucket is simply a named collection of JSON records. You create buckets\n * from your HydrousDB dashboard. Each record is a JSON object with any fields\n * you want; HydrousDB automatically adds `id`, `createdAt`, and `updatedAt`.\n *\n * @example\n * ```ts\n * const db = createClient({ securityKey: 'sk_...' });\n * const posts = db.records('blog-posts');\n *\n * // Create a record\n * const post = await posts.create({ title: 'Hello World', status: 'draft' });\n *\n * // Query records\n * const { records } = await posts.query({\n * filters: [{ field: 'status', op: '==', value: 'published' }],\n * limit: 20,\n * });\n * ```\n */\nexport class RecordsClient<T extends RecordData = RecordData> {\n private readonly http: HttpClient;\n private readonly bucketKey: string;\n private readonly basePath: string;\n\n constructor(http: HttpClient, bucketKey: string) {\n assertSafeName(bucketKey, 'bucketKey');\n this.http = http;\n this.bucketKey = bucketKey;\n this.basePath = `/records/${bucketKey}`;\n }\n\n // ─── Single Record Operations ─────────────────────────────────────────────\n\n /**\n * Create a new record.\n *\n * @example\n * ```ts\n * const user = await records.create({\n * name: 'Alice',\n * email: 'alice@example.com',\n * score: 100,\n * });\n * console.log(user.id); // \"rec_xxxxxxxx\"\n * ```\n */\n async create(data: T): Promise<T & RecordResult> {\n const result = await this.http.post<ApiRecordResult<T>>(this.basePath, data);\n return (result.record ?? result.data)!;\n }\n\n /**\n * Fetch a single record by ID.\n *\n * @example\n * ```ts\n * const post = await records.get('rec_abc123');\n * ```\n */\n async get(id: string): Promise<T & RecordResult> {\n const result = await this.http.get<ApiRecordResult<T>>(`${this.basePath}/${id}`);\n return (result.record ?? result.data)!;\n }\n\n /**\n * Overwrite a record entirely (full replace).\n *\n * @example\n * ```ts\n * const updated = await records.set('rec_abc123', {\n * name: 'Alice Updated',\n * email: 'alice2@example.com',\n * });\n * ```\n */\n async set(id: string, data: T): Promise<T & RecordResult> {\n const result = await this.http.put<ApiRecordResult<T>>(`${this.basePath}/${id}`, data);\n return (result.record ?? result.data)!;\n }\n\n /**\n * Partially update a record (merge by default).\n *\n * @example\n * ```ts\n * // Merge: only the provided fields are updated\n * const updated = await records.patch('rec_abc123', { score: 200 });\n *\n * // Replace: equivalent to set()\n * const replaced = await records.patch('rec_abc123', { score: 200 }, { merge: false });\n * ```\n */\n async patch(\n id: string,\n data: Partial<T>,\n options: PatchRecordOptions = {},\n ): Promise<T & RecordResult> {\n const { merge = true } = options;\n const result = await this.http.patch<ApiRecordResult<T>>(\n `${this.basePath}/${id}`,\n { ...data, _merge: merge },\n );\n return (result.record ?? result.data)!;\n }\n\n /**\n * Delete a record permanently.\n *\n * @example\n * ```ts\n * await records.delete('rec_abc123');\n * ```\n */\n async delete(id: string): Promise<void> {\n await this.http.delete<ApiDeleteResult>(`${this.basePath}/${id}`);\n }\n\n // ─── Batch Operations ─────────────────────────────────────────────────────\n\n /**\n * Create multiple records in one request.\n *\n * @example\n * ```ts\n * const created = await records.batchCreate([\n * { name: 'Alice', score: 100 },\n * { name: 'Bob', score: 200 },\n * ]);\n * ```\n */\n async batchCreate(items: T[]): Promise<(T & RecordResult)[]> {\n const result = await this.http.post<{ success: boolean; records: (T & RecordResult)[] }>(\n `${this.basePath}/batch`,\n { records: items },\n );\n return result.records;\n }\n\n /**\n * Delete multiple records by ID in one request.\n *\n * @example\n * ```ts\n * await records.batchDelete(['rec_a', 'rec_b', 'rec_c']);\n * ```\n */\n async batchDelete(ids: string[]): Promise<{ deleted: number; failed: string[] }> {\n const result = await this.http.post<{\n success: boolean;\n deleted: number;\n failed: string[];\n }>(`${this.basePath}/batch/delete`, { ids });\n return { deleted: result.deleted, failed: result.failed };\n }\n\n // ─── Querying ─────────────────────────────────────────────────────────────\n\n /**\n * Query records with optional filters, sorting, and pagination.\n *\n * @example\n * ```ts\n * // Simple query\n * const { records } = await posts.query({ limit: 10 });\n *\n * // Filtered query with cursor pagination\n * const page1 = await posts.query({\n * filters: [\n * { field: 'status', op: '==', value: 'published' },\n * { field: 'views', op: '>', value: 1000 },\n * ],\n * orderBy: 'createdAt',\n * order: 'desc',\n * limit: 20,\n * });\n *\n * const page2 = await posts.query({\n * filters: [{ field: 'status', op: '==', value: 'published' }],\n * limit: 20,\n * startAfter: page1.nextCursor,\n * });\n * ```\n */\n async query(options: QueryOptions = {}): Promise<QueryResult<T>> {\n const qs = buildQueryParams(options);\n const result = await this.http.get<ApiQueryResult<T>>(`${this.basePath}${qs}`);\n return {\n records: result.records,\n total: result.total,\n hasMore: result.hasMore,\n nextCursor: result.nextCursor,\n };\n }\n\n /**\n * Convenience alias: get all records up to `limit` (default 100).\n *\n * @example\n * ```ts\n * const allPosts = await posts.getAll({ limit: 500 });\n * ```\n */\n async getAll(options: Omit<QueryOptions, 'filters'> = {}): Promise<(T & RecordResult)[]> {\n const { records } = await this.query(options);\n return records;\n }\n\n /**\n * Count records matching optional filters.\n *\n * @example\n * ```ts\n * const total = await posts.count([{ field: 'status', op: '==', value: 'published' }]);\n * ```\n */\n async count(filters: QueryOptions['filters'] = []): Promise<number> {\n const result = await this.http.post<{ success: boolean; count: number }>(\n `${this.basePath}/count`,\n { filters },\n );\n return result.count;\n }\n\n // ─── Version History ──────────────────────────────────────────────────────\n\n /**\n * Retrieve the full version history of a record.\n * Each write creates a new version stored in GCS.\n *\n * @example\n * ```ts\n * const history = await records.getHistory('rec_abc123');\n * console.log(history[0].data); // latest version\n * ```\n */\n async getHistory(id: string): Promise<RecordHistoryEntry[]> {\n const result = await this.http.get<ApiHistoryResult>(`${this.basePath}/${id}/history`);\n return result.history;\n }\n\n /**\n * Restore a record to a specific historical version.\n *\n * @example\n * ```ts\n * const history = await records.getHistory('rec_abc123');\n * const restored = await records.restoreVersion('rec_abc123', history[2].version);\n * ```\n */\n async restoreVersion(id: string, version: number): Promise<T & RecordResult> {\n const result = await this.http.post<ApiRecordResult<T>>(\n `${this.basePath}/${id}/restore`,\n { version },\n );\n return (result.record ?? result.data)!;\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport { assertSafeName } from '../utils/query.js';\nimport type {\n AnalyticsQuery,\n AnalyticsResult,\n Aggregation,\n Granularity,\n SortOrder,\n DateRange,\n AnalyticsFilter,\n MetricDefinition,\n CountResult,\n DistributionRow,\n SumRow,\n TimeSeriesRow,\n FieldTimeSeriesRow,\n TopNRow,\n FieldStats,\n MultiMetricResult,\n StorageStatsResult,\n CrossBucketRow,\n RecordData,\n RecordResult,\n} from '../types/index.js';\n\ninterface ApiAnalyticsResult<T> {\n success: boolean;\n queryType: string;\n data: T;\n}\n\n/**\n * AnalyticsClient — run powerful aggregation and time-series queries against\n * your bucket data using BigQuery under the hood.\n *\n * All query types accept an optional `dateRange` to filter by time.\n * The security key is sent automatically — you never pass it manually.\n *\n * @example\n * ```ts\n * const db = createClient({ securityKey: 'sk_...' });\n * const analytics = db.analytics('orders');\n *\n * // How many orders in the last 30 days?\n * const { count } = await analytics.count({\n * dateRange: { start: Date.now() - 30 * 24 * 60 * 60 * 1000, end: Date.now() },\n * });\n * ```\n */\nexport class AnalyticsClient {\n private readonly http: HttpClient;\n private readonly bucketKey: string;\n private readonly basePath: string;\n\n constructor(http: HttpClient, bucketKey: string) {\n assertSafeName(bucketKey, 'bucketKey');\n this.http = http;\n this.bucketKey = bucketKey;\n this.basePath = `/analytics/${bucketKey}`;\n }\n\n /** Internal dispatcher — all queries POST to the same endpoint. */\n private async run<T>(query: AnalyticsQuery): Promise<T> {\n const result = await this.http.post<ApiAnalyticsResult<T>>(this.basePath, query);\n return result.data;\n }\n\n // ─── Count ────────────────────────────────────────────────────────────────\n\n /**\n * Count the total number of records in the bucket, with optional date filter.\n *\n * @example\n * ```ts\n * const { count } = await analytics.count();\n * // → { count: 4821 }\n *\n * // Count only this month's records\n * const { count } = await analytics.count({\n * dateRange: { start: new Date('2025-01-01').getTime(), end: Date.now() },\n * });\n * ```\n */\n async count(opts: { dateRange?: DateRange } = {}): Promise<CountResult> {\n return this.run<CountResult>({ queryType: 'count', ...opts });\n }\n\n // ─── Distribution ─────────────────────────────────────────────────────────\n\n /**\n * Count how many records have each unique value for a given field.\n * Great for pie charts and bar charts.\n *\n * @example\n * ```ts\n * const rows = await analytics.distribution({\n * field: 'status',\n * limit: 10,\n * order: 'desc',\n * });\n * // → [{ value: 'completed', count: 312 }, { value: 'pending', count: 88 }, ...]\n * ```\n */\n async distribution(opts: {\n field: string;\n limit?: number;\n order?: SortOrder;\n dateRange?: DateRange;\n }): Promise<DistributionRow[]> {\n assertSafeName(opts.field, 'field');\n return this.run<DistributionRow[]>({ queryType: 'distribution', ...opts });\n }\n\n // ─── Sum ──────────────────────────────────────────────────────────────────\n\n /**\n * Sum a numeric field, optionally grouped by another field.\n *\n * @example\n * ```ts\n * // Total revenue\n * const rows = await analytics.sum({ field: 'amount' });\n * // → [{ sum: 198432.50 }]\n *\n * // Revenue by country\n * const rows = await analytics.sum({ field: 'amount', groupBy: 'country', limit: 10 });\n * // → [{ group: 'US', sum: 120000 }, { group: 'UK', sum: 45000 }, ...]\n * ```\n */\n async sum(opts: {\n field: string;\n groupBy?: string;\n limit?: number;\n dateRange?: DateRange;\n }): Promise<SumRow[]> {\n assertSafeName(opts.field, 'field');\n if (opts.groupBy) assertSafeName(opts.groupBy, 'groupBy');\n return this.run<SumRow[]>({ queryType: 'sum', ...opts });\n }\n\n // ─── Time Series ──────────────────────────────────────────────────────────\n\n /**\n * Count records created over time, grouped by a time granularity.\n * Perfect for line charts and activity graphs.\n *\n * @example\n * ```ts\n * const rows = await analytics.timeSeries({\n * granularity: 'day',\n * dateRange: { start: Date.now() - 7 * 86400000, end: Date.now() },\n * });\n * // → [{ date: '2025-06-01', count: 42 }, { date: '2025-06-02', count: 67 }, ...]\n * ```\n */\n async timeSeries(opts: {\n granularity?: Granularity;\n dateRange?: DateRange;\n } = {}): Promise<TimeSeriesRow[]> {\n return this.run<TimeSeriesRow[]>({ queryType: 'timeSeries', granularity: 'day', ...opts });\n }\n\n // ─── Field Time Series ────────────────────────────────────────────────────\n\n /**\n * Aggregate a numeric field over time (e.g. daily revenue, hourly signups).\n *\n * @example\n * ```ts\n * const rows = await analytics.fieldTimeSeries({\n * field: 'amount',\n * aggregation: 'sum',\n * granularity: 'week',\n * });\n * // → [{ date: '2025-W22', value: 14230.50 }, ...]\n * ```\n */\n async fieldTimeSeries(opts: {\n field: string;\n aggregation?: Aggregation;\n granularity?: Granularity;\n dateRange?: DateRange;\n }): Promise<FieldTimeSeriesRow[]> {\n assertSafeName(opts.field, 'field');\n return this.run<FieldTimeSeriesRow[]>({\n queryType: 'fieldTimeSeries',\n aggregation: 'sum',\n granularity: 'day',\n ...opts,\n });\n }\n\n // ─── Top N ────────────────────────────────────────────────────────────────\n\n /**\n * Get the top N values by frequency for a field.\n * Optionally pair with a `labelField` for human-readable labels.\n *\n * @example\n * ```ts\n * // Top 5 most purchased products\n * const rows = await analytics.topN({\n * field: 'productId',\n * labelField: 'productName',\n * n: 5,\n * });\n * // → [{ value: 'prod_123', label: 'Widget Pro', count: 892 }, ...]\n * ```\n */\n async topN(opts: {\n field: string;\n n?: number;\n labelField?: string;\n order?: SortOrder;\n dateRange?: DateRange;\n }): Promise<TopNRow[]> {\n assertSafeName(opts.field, 'field');\n if (opts.labelField) assertSafeName(opts.labelField, 'labelField');\n return this.run<TopNRow[]>({ queryType: 'topN', n: 10, order: 'desc', ...opts });\n }\n\n // ─── Field Stats ──────────────────────────────────────────────────────────\n\n /**\n * Get statistical summary (min, max, avg, sum, count, stddev) for a numeric field.\n *\n * @example\n * ```ts\n * const stats = await analytics.stats({ field: 'orderValue' });\n * // → { min: 4.99, max: 9999.99, avg: 87.23, sum: 420948.27, count: 4823, stddev: 143.2 }\n * ```\n */\n async stats(opts: {\n field: string;\n dateRange?: DateRange;\n }): Promise<FieldStats> {\n assertSafeName(opts.field, 'field');\n return this.run<FieldStats>({ queryType: 'stats', ...opts });\n }\n\n // ─── Filtered Records ─────────────────────────────────────────────────────\n\n /**\n * Query raw records with filters, field selection, and pagination.\n * This is the analytics version of `records.query()` but powered by BigQuery.\n *\n * @example\n * ```ts\n * const { records } = await analytics.records({\n * filters: [{ field: 'status', op: '==', value: 'refunded' }],\n * selectFields: ['orderId', 'amount', 'createdAt'],\n * limit: 50,\n * orderBy: 'amount',\n * order: 'desc',\n * });\n * ```\n */\n async records<T extends RecordData = RecordData>(opts: {\n filters?: AnalyticsFilter[];\n selectFields?: string[];\n limit?: number;\n offset?: number;\n orderBy?: string;\n order?: SortOrder;\n dateRange?: DateRange;\n } = {}): Promise<(T & RecordResult)[]> {\n if (opts.orderBy) assertSafeName(opts.orderBy, 'orderBy');\n if (opts.selectFields) opts.selectFields.forEach(f => assertSafeName(f, 'selectField'));\n return this.run<(T & RecordResult)[]>({ queryType: 'records', limit: 100, order: 'desc', ...opts });\n }\n\n // ─── Multi Metric ─────────────────────────────────────────────────────────\n\n /**\n * Calculate multiple aggregations in a single query.\n * Ideal for dashboards that need several numbers at once.\n *\n * @example\n * ```ts\n * const result = await analytics.multiMetric({\n * metrics: [\n * { field: 'amount', name: 'totalRevenue', aggregation: 'sum' },\n * { field: 'amount', name: 'avgOrderValue', aggregation: 'avg' },\n * { field: 'userId', name: 'uniqueCustomers', aggregation: 'count' },\n * ],\n * });\n * // → { totalRevenue: 198432.50, avgOrderValue: 87.23, uniqueCustomers: 2275 }\n * ```\n */\n async multiMetric(opts: {\n metrics: MetricDefinition[];\n dateRange?: DateRange;\n }): Promise<MultiMetricResult> {\n opts.metrics.forEach(m => {\n assertSafeName(m.field, 'metric.field');\n assertSafeName(m.name, 'metric.name');\n });\n return this.run<MultiMetricResult>({ queryType: 'multiMetric', ...opts });\n }\n\n // ─── Storage Stats ────────────────────────────────────────────────────────\n\n /**\n * Get storage statistics for this bucket: record counts, byte sizes.\n *\n * @example\n * ```ts\n * const stats = await analytics.storageStats();\n * // → { totalRecords: 4821, totalBytes: 48293820, avgBytes: 10015, ... }\n * ```\n */\n async storageStats(opts: { dateRange?: DateRange } = {}): Promise<StorageStatsResult> {\n return this.run<StorageStatsResult>({ queryType: 'storageStats', ...opts });\n }\n\n // ─── Cross-Bucket Comparison ──────────────────────────────────────────────\n\n /**\n * Compare the same field aggregation across multiple buckets in one query.\n * Your security key must have read access to ALL listed buckets.\n *\n * @example\n * ```ts\n * const rows = await analytics.crossBucket({\n * bucketKeys: ['orders-us', 'orders-eu', 'orders-apac'],\n * field: 'amount',\n * aggregation: 'sum',\n * });\n * // → [\n * // { bucket: 'orders-us', value: 120000 },\n * // { bucket: 'orders-eu', value: 45000 },\n * // { bucket: 'orders-apac', value: 33000 },\n * // ]\n * ```\n */\n async crossBucket(opts: {\n bucketKeys: string[];\n field: string;\n aggregation?: Aggregation;\n dateRange?: DateRange;\n }): Promise<CrossBucketRow[]> {\n assertSafeName(opts.field, 'field');\n opts.bucketKeys.forEach(k => assertSafeName(k, 'bucketKey'));\n return this.run<CrossBucketRow[]>({ queryType: 'crossBucket', aggregation: 'sum', ...opts });\n }\n\n // ─── Raw Query ────────────────────────────────────────────────────────────\n\n /**\n * Send a raw analytics query object. Use this when you need full control\n * over the query shape or want to use a queryType not covered by the helpers.\n *\n * @example\n * ```ts\n * const result = await analytics.query({\n * queryType: 'topN',\n * field: 'category',\n * n: 3,\n * order: 'asc',\n * });\n * ```\n */\n async query<T = unknown>(query: AnalyticsQuery): Promise<AnalyticsResult<T>> {\n const data = await this.run<T>(query);\n return { queryType: query.queryType, data };\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport { guessMimeType } from '../utils/query.js';\nimport { StorageError } from '../utils/errors.js';\nimport type {\n UploadOptions,\n UploadResult,\n UploadUrlResult,\n ListOptions,\n ListResult,\n FileEntry,\n FileMetadata,\n SignedUrlResult,\n StorageStats,\n BatchUploadItem,\n BatchUploadUrlResult,\n} from '../types/index.js';\n\ninterface ApiUploadUrlResult {\n uploadUrl: string;\n path: string;\n mimeType: string;\n expiresAt: string;\n expiresIn: number;\n}\n\ninterface ApiConfirmResult {\n success: boolean;\n path: string;\n mimeType: string;\n size: number;\n isPublic: boolean;\n publicUrl: string | null;\n downloadUrl: string | null;\n}\n\ninterface ApiListResult {\n success: boolean;\n files: FileEntry[];\n folders: string[];\n hasMore: boolean;\n nextCursor?: string;\n}\n\ninterface ApiMetadataResult {\n success: boolean;\n path: string;\n size: number;\n mimeType: string;\n isPublic: boolean;\n publicUrl: string | null;\n downloadUrl: string | null;\n createdAt?: string;\n updatedAt?: string;\n}\n\ninterface ApiSignedUrlResult {\n success: boolean;\n signedUrl: string;\n expiresAt: string;\n expiresIn: number;\n path: string;\n}\n\ninterface ApiVisibilityResult {\n success: boolean;\n path: string;\n isPublic: boolean;\n publicUrl: string | null;\n downloadUrl: string | null;\n}\n\ninterface ApiStatsResult {\n success: boolean;\n stats: StorageStats;\n}\n\n/**\n * StorageManager — upload, download, list, move, copy, and delete files.\n *\n * Authentication is handled automatically via the X-Storage-Key header.\n * Files are scoped to your owner ID — you can never access another owner's files.\n *\n * **Recommended upload flow** (for progress tracking and large files):\n * 1. Call `getUploadUrl()` to get a signed PUT URL.\n * 2. Upload directly to GCS using XHR (supports progress events).\n * 3. Call `confirmUpload()` to finalize metadata.\n *\n * **Simple upload** (small files, no progress needed):\n * - Call `upload()` — it handles everything in one call.\n *\n * @example\n * ```ts\n * const db = createClient({ securityKey: 'sk_...' });\n *\n * // Simple upload\n * const file = await db.storage.upload(fileBlob, 'avatars/alice.jpg', { isPublic: true });\n * console.log(file.publicUrl); // CDN URL, usable anywhere\n * ```\n */\nexport class StorageManager {\n private readonly http: HttpClient;\n private readonly storageKey: string;\n private readonly basePath = '/storage';\n\n constructor(http: HttpClient, storageKey: string) {\n this.http = http;\n this.storageKey = storageKey;\n }\n\n /** Headers for all storage requests — uses X-Storage-Key, not X-Api-Key. */\n private get authHeaders(): Record<string, string> {\n return { 'X-Storage-Key': this.storageKey };\n }\n\n // ─── Upload: Simple (server-buffered) ────────────────────────────────────\n\n /**\n * Upload a file to storage in one step (server-buffered, up to 500 MB).\n * For files >10 MB or when you need upload progress, use `getUploadUrl()` instead.\n *\n * @param data File data as a Blob, Buffer, Uint8Array, or ArrayBuffer.\n * @param path Destination path in your storage (e.g. `\"avatars/alice.jpg\"`).\n * @param options Upload options: isPublic, overwrite, mimeType.\n *\n * @example\n * ```ts\n * // Upload a public avatar\n * const result = await storage.upload(file, 'avatars/alice.jpg', { isPublic: true });\n * console.log(result.publicUrl); // → https://...\n *\n * // Upload a private document\n * const result = await storage.upload(pdfBuffer, 'docs/contract.pdf');\n * console.log(result.downloadUrl); // → /storage/download/docs/contract.pdf\n * ```\n */\n async upload(\n data: Blob | Uint8Array<ArrayBuffer> | ArrayBuffer | Buffer,\n path: string,\n options: UploadOptions = {},\n ): Promise<UploadResult> {\n const { isPublic = false, overwrite = false, mimeType } = options;\n const mime = mimeType ?? guessMimeType(path);\n\n const formData = new FormData();\n const blob = data instanceof Blob\n ? data\n : new Blob([data as ArrayBuffer], { type: mime });\n\n formData.append('file', blob, path.split('/').pop() ?? 'file');\n formData.append('path', path);\n formData.append('mimeType', mime);\n formData.append('isPublic', String(isPublic));\n formData.append('overwrite', String(overwrite));\n\n const result = await this.http.request<ApiConfirmResult>(`${this.basePath}/upload`, {\n method: 'POST',\n rawBody: formData,\n headers: this.authHeaders,\n });\n\n return {\n path: result.path,\n mimeType: result.mimeType,\n size: result.size,\n isPublic: result.isPublic,\n publicUrl: result.publicUrl,\n downloadUrl: result.downloadUrl,\n };\n }\n\n /**\n * Upload raw JSON or plain text data as a file.\n *\n * @example\n * ```ts\n * const result = await storage.uploadRaw(\n * { config: { theme: 'dark' } },\n * 'settings/user-config.json',\n * { isPublic: false },\n * );\n * ```\n */\n async uploadRaw(\n data: unknown,\n path: string,\n options: UploadOptions = {},\n ): Promise<UploadResult> {\n const { isPublic = false, overwrite = false, mimeType = 'application/json' } = options;\n const body = typeof data === 'string' ? data : JSON.stringify(data);\n\n const result = await this.http.request<ApiConfirmResult>(`${this.basePath}/upload-raw`, {\n method: 'POST',\n body: { path, data: body, mimeType, isPublic, overwrite },\n headers: this.authHeaders,\n });\n\n return {\n path: result.path,\n mimeType: result.mimeType,\n size: result.size,\n isPublic: result.isPublic,\n publicUrl: result.publicUrl,\n downloadUrl: result.downloadUrl,\n };\n }\n\n // ─── Upload: Direct-to-GCS (recommended for large files) ─────────────────\n\n /**\n * Step 1 of the recommended upload flow.\n * Get a signed URL to upload directly to GCS from the client (supports progress).\n *\n * @example\n * ```ts\n * const { uploadUrl, path: confirmedPath } = await storage.getUploadUrl({\n * path: 'videos/intro.mp4',\n * mimeType: 'video/mp4',\n * size: file.size,\n * isPublic: true,\n * });\n *\n * // Upload using XHR for progress tracking\n * await storage.uploadToSignedUrl(uploadUrl, file, 'video/mp4', (pct) => {\n * console.log(`${pct}% uploaded`);\n * });\n *\n * // Step 3: confirm\n * const result = await storage.confirmUpload({ path: confirmedPath, mimeType: 'video/mp4', isPublic: true });\n * ```\n */\n async getUploadUrl(opts: {\n path: string;\n mimeType: string;\n size: number;\n isPublic?: boolean;\n overwrite?: boolean;\n expiresInSeconds?: number;\n }): Promise<UploadUrlResult> {\n const result = await this.http.request<ApiUploadUrlResult>(`${this.basePath}/upload-url`, {\n method: 'POST',\n body: { isPublic: false, overwrite: false, expiresInSeconds: 900, ...opts },\n headers: this.authHeaders,\n });\n return result;\n }\n\n /**\n * Upload data directly to a signed GCS URL (no auth headers needed).\n * Optionally tracks progress via a callback.\n *\n * @param signedUrl The URL returned by `getUploadUrl()`.\n * @param data File data.\n * @param mimeType Must match what was used in `getUploadUrl()`.\n * @param onProgress Optional callback called with 0–100 progress percentage.\n */\n async uploadToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array<ArrayBuffer> | ArrayBuffer,\n mimeType: string,\n onProgress?: (percent: number) => void,\n ): Promise<void> {\n await this.http.putToSignedUrl(signedUrl, data, mimeType, onProgress);\n }\n\n /**\n * Step 3 of the recommended upload flow.\n * Confirm a direct upload and register metadata on the server.\n *\n * @example\n * ```ts\n * const result = await storage.confirmUpload({\n * path: 'videos/intro.mp4',\n * mimeType: 'video/mp4',\n * isPublic: true,\n * });\n * console.log(result.publicUrl);\n * ```\n */\n async confirmUpload(opts: {\n path: string;\n mimeType: string;\n isPublic?: boolean;\n }): Promise<UploadResult> {\n const result = await this.http.request<ApiConfirmResult>(`${this.basePath}/confirm`, {\n method: 'POST',\n body: { isPublic: false, ...opts },\n headers: this.authHeaders,\n });\n return {\n path: result.path,\n mimeType: result.mimeType,\n size: result.size,\n isPublic: result.isPublic,\n publicUrl: result.publicUrl,\n downloadUrl: result.downloadUrl,\n };\n }\n\n // ─── Batch Upload ─────────────────────────────────────────────────────────\n\n /**\n * Get signed upload URLs for multiple files at once.\n *\n * @example\n * ```ts\n * const { files } = await storage.getBatchUploadUrls([\n * { path: 'images/photo1.jpg', mimeType: 'image/jpeg', size: 204800 },\n * { path: 'images/photo2.jpg', mimeType: 'image/jpeg', size: 153600 },\n * ]);\n *\n * // Upload each file and confirm\n * for (const f of files) {\n * await storage.uploadToSignedUrl(f.uploadUrl, blobs[f.index], f.mimeType);\n * await storage.confirmUpload({ path: f.path, mimeType: f.mimeType });\n * }\n * ```\n */\n async getBatchUploadUrls(files: BatchUploadItem[]): Promise<BatchUploadUrlResult> {\n const result = await this.http.request<{ success: boolean; files: BatchUploadUrlResult['files'] }>(\n `${this.basePath}/batch-upload-urls`,\n { method: 'POST', body: { files }, headers: this.authHeaders },\n );\n return { files: result.files };\n }\n\n /**\n * Confirm multiple direct uploads at once.\n */\n async batchConfirmUploads(\n items: Array<{ path: string; mimeType: string; isPublic?: boolean }>,\n ): Promise<UploadResult[]> {\n const result = await this.http.request<{ success: boolean; files: ApiConfirmResult[] }>(\n `${this.basePath}/batch-confirm`,\n { method: 'POST', body: { files: items }, headers: this.authHeaders },\n );\n return result.files.map(r => ({\n path: r.path,\n mimeType: r.mimeType,\n size: r.size,\n isPublic: r.isPublic,\n publicUrl: r.publicUrl,\n downloadUrl: r.downloadUrl,\n }));\n }\n\n // ─── Download ─────────────────────────────────────────────────────────────\n\n /**\n * Download a private file as an ArrayBuffer.\n * For public files, use the `publicUrl` directly — no SDK needed.\n *\n * @example\n * ```ts\n * const buffer = await storage.download('docs/contract.pdf');\n * const blob = new Blob([buffer], { type: 'application/pdf' });\n * // Open in browser:\n * window.open(URL.createObjectURL(blob));\n * ```\n */\n async download(path: string): Promise<ArrayBuffer> {\n const encoded = path.split('/').map(encodeURIComponent).join('/');\n return this.http.request<ArrayBuffer>(`${this.basePath}/download/${encoded}`, {\n method: 'GET',\n headers: this.authHeaders,\n });\n }\n\n /**\n * Download multiple files at once, returned as a JSON map of `{ path: base64 }`.\n *\n * @example\n * ```ts\n * const files = await storage.batchDownload(['docs/a.pdf', 'docs/b.pdf']);\n * ```\n */\n async batchDownload(paths: string[]): Promise<Record<string, string>> {\n const result = await this.http.request<{ success: boolean; files: Record<string, string> }>(\n `${this.basePath}/batch-download`,\n { method: 'POST', body: { paths }, headers: this.authHeaders },\n );\n return result.files;\n }\n\n // ─── List ─────────────────────────────────────────────────────────────────\n\n /**\n * List files and folders at a given path prefix.\n *\n * @example\n * ```ts\n * // List everything in the root\n * const { files, folders } = await storage.list();\n *\n * // List a specific folder\n * const { files, folders, hasMore, nextCursor } = await storage.list({\n * prefix: 'avatars/',\n * limit: 20,\n * });\n *\n * // Next page\n * const page2 = await storage.list({ prefix: 'avatars/', cursor: nextCursor });\n * ```\n */\n async list(opts: ListOptions = {}): Promise<ListResult> {\n const params = new URLSearchParams();\n if (opts.prefix) params.set('prefix', opts.prefix);\n if (opts.limit) params.set('limit', String(opts.limit));\n if (opts.cursor) params.set('cursor', opts.cursor);\n if (opts.recursive) params.set('recursive', 'true');\n const qs = params.toString() ? `?${params}` : '';\n\n const result = await this.http.request<ApiListResult>(`${this.basePath}/list${qs}`, {\n method: 'GET',\n headers: this.authHeaders,\n });\n return {\n files: result.files,\n folders: result.folders,\n hasMore: result.hasMore,\n nextCursor: result.nextCursor,\n };\n }\n\n // ─── Metadata ─────────────────────────────────────────────────────────────\n\n /**\n * Get metadata for a file (size, MIME type, visibility, URLs).\n *\n * @example\n * ```ts\n * const meta = await storage.getMetadata('avatars/alice.jpg');\n * console.log(meta.size, meta.isPublic, meta.publicUrl);\n * ```\n */\n async getMetadata(path: string): Promise<FileMetadata> {\n const encoded = path.split('/').map(encodeURIComponent).join('/');\n const result = await this.http.request<ApiMetadataResult>(\n `${this.basePath}/metadata/${encoded}`,\n { method: 'GET', headers: this.authHeaders },\n );\n return {\n path: result.path,\n size: result.size,\n mimeType: result.mimeType,\n isPublic: result.isPublic,\n publicUrl: result.publicUrl,\n downloadUrl: result.downloadUrl,\n createdAt: result.createdAt,\n updatedAt: result.updatedAt,\n };\n }\n\n // ─── Signed URL (time-limited share) ─────────────────────────────────────\n\n /**\n * Generate a time-limited download URL for a private file.\n * The URL can be shared externally without requiring an `X-Storage-Key`.\n *\n * > **Note:** Downloads via signed URLs bypass the server, so download stats\n * > are NOT tracked. Use `downloadUrl` for tracked downloads.\n *\n * @param path Path to the file.\n * @param expiresIn URL lifetime in seconds (default 3600 = 1 hour).\n *\n * @example\n * ```ts\n * const { signedUrl, expiresAt } = await storage.getSignedUrl('docs/invoice.pdf', 1800);\n * // Share signedUrl with the recipient — it expires in 30 minutes.\n * ```\n */\n async getSignedUrl(path: string, expiresIn = 3600): Promise<SignedUrlResult> {\n const result = await this.http.request<ApiSignedUrlResult>(`${this.basePath}/signed-url`, {\n method: 'POST',\n body: { path, expiresIn },\n headers: this.authHeaders,\n });\n return {\n signedUrl: result.signedUrl,\n expiresAt: result.expiresAt,\n expiresIn: result.expiresIn,\n path: result.path,\n };\n }\n\n // ─── Visibility ───────────────────────────────────────────────────────────\n\n /**\n * Change a file's visibility between public and private after upload.\n *\n * @example\n * ```ts\n * // Make a file public\n * const result = await storage.setVisibility('avatars/alice.jpg', true);\n * console.log(result.publicUrl); // CDN URL\n *\n * // Make a file private\n * const result = await storage.setVisibility('avatars/alice.jpg', false);\n * console.log(result.downloadUrl); // Auth-required URL\n * ```\n */\n async setVisibility(\n path: string,\n isPublic: boolean,\n ): Promise<{ path: string; isPublic: boolean; publicUrl: string | null; downloadUrl: string | null }> {\n const result = await this.http.request<ApiVisibilityResult>(`${this.basePath}/visibility`, {\n method: 'PATCH',\n body: { path, isPublic },\n headers: this.authHeaders,\n });\n return {\n path: result.path,\n isPublic: result.isPublic,\n publicUrl: result.publicUrl,\n downloadUrl: result.downloadUrl,\n };\n }\n\n // ─── Folder Operations ────────────────────────────────────────────────────\n\n /**\n * Create a folder (a GCS prefix placeholder).\n *\n * @example\n * ```ts\n * await storage.createFolder('uploads/2025/');\n * ```\n */\n async createFolder(path: string): Promise<{ path: string }> {\n const result = await this.http.request<{ success: boolean; path: string }>(\n `${this.basePath}/folder`,\n { method: 'POST', body: { path }, headers: this.authHeaders },\n );\n return { path: result.path };\n }\n\n // ─── File Operations ──────────────────────────────────────────────────────\n\n /**\n * Delete a single file.\n *\n * @example\n * ```ts\n * await storage.deleteFile('avatars/old-avatar.jpg');\n * ```\n */\n async deleteFile(path: string): Promise<void> {\n await this.http.request<{ success: boolean }>(`${this.basePath}/file`, {\n method: 'DELETE',\n body: { path },\n headers: this.authHeaders,\n });\n }\n\n /**\n * Delete a folder and all its contents recursively.\n *\n * @example\n * ```ts\n * await storage.deleteFolder('temp/');\n * ```\n */\n async deleteFolder(path: string): Promise<void> {\n await this.http.request<{ success: boolean }>(`${this.basePath}/folder`, {\n method: 'DELETE',\n body: { path },\n headers: this.authHeaders,\n });\n }\n\n /**\n * Move or rename a file.\n *\n * @example\n * ```ts\n * // Rename\n * await storage.move('docs/draft.pdf', 'docs/final.pdf');\n * // Move to a different folder\n * await storage.move('inbox/report.xlsx', 'archive/2025/report.xlsx');\n * ```\n */\n async move(from: string, to: string): Promise<{ from: string; to: string }> {\n const result = await this.http.request<{ success: boolean; from: string; to: string }>(\n `${this.basePath}/move`,\n { method: 'POST', body: { from, to }, headers: this.authHeaders },\n );\n return { from: result.from, to: result.to };\n }\n\n /**\n * Copy a file to a new path.\n *\n * @example\n * ```ts\n * await storage.copy('templates/base.html', 'sites/my-site/index.html');\n * ```\n */\n async copy(from: string, to: string): Promise<{ from: string; to: string }> {\n const result = await this.http.request<{ success: boolean; from: string; to: string }>(\n `${this.basePath}/copy`,\n { method: 'POST', body: { from, to }, headers: this.authHeaders },\n );\n return { from: result.from, to: result.to };\n }\n\n // ─── Stats ────────────────────────────────────────────────────────────────\n\n /**\n * Get storage statistics for your key: total files, bytes, operation counts.\n *\n * @example\n * ```ts\n * const stats = await storage.getStats();\n * console.log(`${stats.totalFiles} files, ${(stats.totalBytes / 1e6).toFixed(1)} MB`);\n * ```\n */\n async getStats(): Promise<StorageStats> {\n const result = await this.http.request<ApiStatsResult>(`${this.basePath}/stats`, {\n method: 'GET',\n headers: this.authHeaders,\n });\n return result.stats;\n }\n\n // ─── Info (no auth) ───────────────────────────────────────────────────────\n\n /**\n * Ping the storage service. No authentication required.\n *\n * @example\n * ```ts\n * const info = await storage.info();\n * // → { ok: true, storageRoot: 'hydrous-storage' }\n * ```\n */\n async info(): Promise<{ ok: boolean; storageRoot: string }> {\n return this.http.get<{ ok: boolean; storageRoot: string }>(`${this.basePath}/info`);\n }\n}","import type { StorageManager } from './manager.js';\nimport type {\n UploadOptions,\n UploadResult,\n UploadUrlResult,\n ListOptions,\n ListResult,\n FileMetadata,\n SignedUrlResult,\n} from '../types/index.js';\n\n/** Accepted data types for file uploads. */\ntype UploadData = Blob | Uint8Array<ArrayBuffer> | ArrayBuffer | Buffer;\n\n/**\n * ScopedStorage — a StorageManager pre-scoped to a specific folder prefix.\n *\n * All paths are automatically prepended with the scope, so you never\n * have to repeat the folder name.\n *\n * @example\n * ```ts\n * const db = createClient({ securityKey: 'sk_...' });\n *\n * // All operations in the \"avatars/\" folder\n * const avatars = db.storage.scope('avatars');\n *\n * await avatars.upload(file, 'alice.jpg'); // → \"avatars/alice.jpg\"\n * const list = await avatars.list(); // → files under \"avatars/\"\n * await avatars.deleteFile('alice.jpg'); // → deletes \"avatars/alice.jpg\"\n * ```\n */\nexport class ScopedStorage {\n private readonly manager: StorageManager;\n private readonly prefix: string;\n\n constructor(manager: StorageManager, prefix: string) {\n this.manager = manager;\n this.prefix = prefix.replace(/\\/+$/, '') + '/';\n }\n\n private scopedPath(userPath: string): string {\n return `${this.prefix}${userPath.replace(/^\\/+/, '')}`;\n }\n\n /** Upload a file within the scoped folder. */\n upload(data: UploadData, path: string, options?: UploadOptions): Promise<UploadResult> {\n return this.manager.upload(data, this.scopedPath(path), options);\n }\n\n /** Upload raw JSON or text within the scoped folder. */\n uploadRaw(data: unknown, path: string, options?: UploadOptions): Promise<UploadResult> {\n return this.manager.uploadRaw(data, this.scopedPath(path), options);\n }\n\n /** Get a signed upload URL for a file within the scoped folder. */\n getUploadUrl(opts: {\n path: string;\n mimeType: string;\n size: number;\n isPublic?: boolean;\n overwrite?: boolean;\n }): Promise<UploadUrlResult> {\n return this.manager.getUploadUrl({ ...opts, path: this.scopedPath(opts.path) });\n }\n\n /** Upload data directly to a signed GCS URL with optional progress tracking. */\n uploadToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array<ArrayBuffer> | ArrayBuffer,\n mimeType: string,\n onProgress?: (percent: number) => void,\n ): Promise<void> {\n return this.manager.uploadToSignedUrl(signedUrl, data, mimeType, onProgress);\n }\n\n /** Confirm a direct upload within the scoped folder. */\n confirmUpload(opts: {\n path: string;\n mimeType: string;\n isPublic?: boolean;\n }): Promise<UploadResult> {\n return this.manager.confirmUpload({ ...opts, path: this.scopedPath(opts.path) });\n }\n\n /** Download a file within the scoped folder. */\n download(path: string): Promise<ArrayBuffer> {\n return this.manager.download(this.scopedPath(path));\n }\n\n /** List files within the scoped folder. */\n list(opts: ListOptions = {}): Promise<ListResult> {\n return this.manager.list({ ...opts, prefix: this.scopedPath(opts.prefix ?? '') });\n }\n\n /** Get metadata for a file within the scoped folder. */\n getMetadata(path: string): Promise<FileMetadata> {\n return this.manager.getMetadata(this.scopedPath(path));\n }\n\n /** Get a time-limited signed URL for a file within the scoped folder. */\n getSignedUrl(path: string, expiresIn?: number): Promise<SignedUrlResult> {\n return this.manager.getSignedUrl(this.scopedPath(path), expiresIn);\n }\n\n /** Change visibility of a file within the scoped folder. */\n setVisibility(\n path: string,\n isPublic: boolean,\n ): Promise<{ path: string; isPublic: boolean; publicUrl: string | null; downloadUrl: string | null }> {\n return this.manager.setVisibility(this.scopedPath(path), isPublic);\n }\n\n /** Delete a file within the scoped folder. */\n deleteFile(path: string): Promise<void> {\n return this.manager.deleteFile(this.scopedPath(path));\n }\n\n /** Delete a sub-folder within the scoped folder. */\n deleteFolder(path: string): Promise<void> {\n return this.manager.deleteFolder(this.scopedPath(path));\n }\n\n /** Move a file within the scoped folder. */\n move(from: string, to: string): Promise<{ from: string; to: string }> {\n return this.manager.move(this.scopedPath(from), this.scopedPath(to));\n }\n\n /** Copy a file within the scoped folder. */\n copy(from: string, to: string): Promise<{ from: string; to: string }> {\n return this.manager.copy(this.scopedPath(from), this.scopedPath(to));\n }\n\n /** Create a sub-folder within the scoped folder. */\n createFolder(path: string): Promise<{ path: string }> {\n return this.manager.createFolder(this.scopedPath(path));\n }\n\n /**\n * Create a further-scoped instance nested within this scope.\n *\n * @example\n * ```ts\n * const uploads = db.storage.scope('user-uploads');\n * const images = uploads.scope('images'); // → \"user-uploads/images/\"\n * ```\n */\n scope(subPrefix: string): ScopedStorage {\n return new ScopedStorage(this.manager, this.scopedPath(subPrefix));\n }\n}","import { HttpClient, DEFAULT_BASE_URL } from './utils/http.js';\nimport { AuthClient } from './auth/client.js';\nimport { RecordsClient } from './records/client.js';\nimport { AnalyticsClient } from './analytics/client.js';\nimport { StorageManager } from './storage/manager.js';\nimport { ScopedStorage } from './storage/scoped.js';\nimport type { HydrousConfig, RecordData } from './types/index.js';\n\n/**\n * HydrousClient — the main entry point for the HydrousDB SDK.\n *\n * Create one instance per application (it is safe to share globally).\n * Every sub-client (`auth`, `records`, `analytics`, `storage`) is lazily\n * instantiated and cached on first access.\n *\n * @example\n * ```ts\n * import { createClient } from 'hydrousdb';\n *\n * const db = createClient({ securityKey: 'sk_live_...' });\n *\n * // Records\n * const posts = db.records('blog-posts');\n * const users = db.records('app-users');\n *\n * // Auth\n * const auth = db.auth('app-users');\n *\n * // Analytics\n * const stats = db.analytics('orders');\n *\n * // Storage (flat)\n * const storage = db.storage; // StorageManager\n *\n * // Storage (scoped to a folder)\n * const avatars = db.storage.scope('avatars');\n * ```\n */\nexport class HydrousClient {\n private readonly http: HttpClient;\n private readonly _storageKey: string;\n private _storage: StorageManager | null = null;\n private readonly _recordsCache = new Map<string, RecordsClient<RecordData>>();\n private readonly _authCache = new Map<string, AuthClient>();\n private readonly _analyticsCache = new Map<string, AnalyticsClient>();\n\n constructor(config: HydrousConfig) {\n if (!config.securityKey) {\n throw new Error(\n '[HydrousDB] securityKey is required. ' +\n 'Get yours from https://hydrousdb.com/dashboard.',\n );\n }\n\n const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;\n this.http = new HttpClient(baseUrl, config.securityKey);\n // Storage uses the same key (it's the only key type in this SDK).\n this._storageKey = config.securityKey;\n }\n\n // ─── Records ─────────────────────────────────────────────────────────────\n\n /**\n * Get a typed records client for the given bucket.\n *\n * The generic type parameter `T` describes the shape of records in this\n * bucket. Leave it unset for a generic `Record<string, unknown>` shape.\n *\n * @param bucketKey The name of your bucket (must match what you created in the dashboard).\n *\n * @example\n * ```ts\n * interface Post { title: string; body: string; published: boolean }\n * const posts = db.records<Post>('blog-posts');\n *\n * const post = await posts.create({ title: 'Hello', body: '...', published: false });\n * // post.id, post.createdAt, post.updatedAt are added automatically\n * ```\n */\n records<T extends RecordData = RecordData>(bucketKey: string): RecordsClient<T> {\n if (!this._recordsCache.has(bucketKey)) {\n this._recordsCache.set(bucketKey, new RecordsClient<T>(this.http, bucketKey) as RecordsClient<RecordData>);\n }\n return this._recordsCache.get(bucketKey) as RecordsClient<T>;\n }\n\n // ─── Auth ─────────────────────────────────────────────────────────────────\n\n /**\n * Get an auth client for the given user bucket.\n *\n * @param bucketKey The name of your user bucket (e.g. `\"app-users\"`).\n *\n * @example\n * ```ts\n * const auth = db.auth('app-users');\n * const { user, session } = await auth.login({ email: '...', password: '...' });\n * ```\n */\n auth(bucketKey: string): AuthClient {\n if (!this._authCache.has(bucketKey)) {\n this._authCache.set(bucketKey, new AuthClient(this.http, bucketKey));\n }\n return this._authCache.get(bucketKey)!;\n }\n\n // ─── Analytics ────────────────────────────────────────────────────────────\n\n /**\n * Get an analytics client for the given bucket.\n *\n * @param bucketKey The name of the bucket to analyse.\n *\n * @example\n * ```ts\n * const analytics = db.analytics('orders');\n * const { count } = await analytics.count();\n * ```\n */\n analytics(bucketKey: string): AnalyticsClient {\n if (!this._analyticsCache.has(bucketKey)) {\n this._analyticsCache.set(bucketKey, new AnalyticsClient(this.http, bucketKey));\n }\n return this._analyticsCache.get(bucketKey)!;\n }\n\n // ─── Storage ──────────────────────────────────────────────────────────────\n\n /**\n * The storage manager for uploading, downloading, listing, and managing files.\n *\n * Scoped to your project — you can never access another project's files.\n *\n * @example\n * ```ts\n * // Upload a file\n * const result = await db.storage.upload(file, 'images/photo.jpg', { isPublic: true });\n *\n * // Scope to a folder\n * const avatars = db.storage.scope('user-avatars');\n * await avatars.upload(blob, `${userId}.jpg`, { isPublic: true });\n * ```\n */\n get storage(): StorageManager & { scope: (prefix: string) => ScopedStorage } {\n if (!this._storage) {\n this._storage = new StorageManager(this.http, this._storageKey);\n }\n const mgr = this._storage;\n\n // Attach .scope() as a convenience method directly on the storage instance\n const extended = mgr as StorageManager & { scope: (prefix: string) => ScopedStorage };\n if (!extended.scope) {\n extended.scope = (prefix: string) => new ScopedStorage(mgr, prefix);\n }\n return extended;\n }\n}\n\n// ─── Factory function ─────────────────────────────────────────────────────────\n\n/**\n * Create a new HydrousDB client.\n *\n * This is the **only** export you need to get started.\n * The API URL is pre-configured — you only need your Security Key.\n *\n * @param config.securityKey Your project's Security Key from https://hydrousdb.com/dashboard\n * @param config.baseUrl (Optional) Override the API base URL.\n *\n * @example\n * ```ts\n * import { createClient } from 'hydrousdb';\n *\n * const db = createClient({\n * securityKey: process.env.HYDROUS_SECURITY_KEY!,\n * });\n * ```\n */\nexport function createClient(config: HydrousConfig): HydrousClient {\n return new HydrousClient(config);\n}\n"]}
|