hydrousdb 3.5.1 → 3.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/errors.ts","../src/utils/http.ts","../src/routes.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.cjs","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 if (cause !== undefined) this.cause = cause;\n }\n}\n","import { HydrousError, NetworkError } from './errors.js';\n\n/**\n * The server base URL — no trailing slash, no /api suffix.\n * Routes in routes.ts already include /api, /api/analytics, /api/auth, /storage.\n */\nexport const DEFAULT_BASE_URL = 'https://db-api-82687684612.us-central1.run.app';\n\ninterface RequestOptions {\n method: string;\n body?: unknown;\n rawBody?: FormData | Uint8Array | ArrayBuffer;\n headers?: Record<string, string>;\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n\n constructor(baseUrl: string) {\n // Strip trailing slash; routes.ts paths start with /\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n }\n\n // ─── Core request ──────────────────────────────────────────────────────────\n\n async request<T>(path: string, options: RequestOptions): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = { ...options.headers };\n\n let body: BodyInit | undefined;\n\n if (options.rawBody !== undefined) {\n // FormData or binary — browser/Node sets Content-Type automatically\n body = options.rawBody as BodyInit;\n } else if (options.body !== undefined) {\n headers['Content-Type'] = 'application/json';\n body = JSON.stringify(options.body);\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: options.method,\n headers,\n body,\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 // Binary responses (downloads)\n const contentType = response.headers.get('content-type') ?? '';\n if (!contentType.includes('application/json')) {\n if (!response.ok) {\n throw new HydrousError(\n `Request failed with status ${response.status}`,\n 'REQUEST_FAILED',\n response.status,\n );\n }\n return response.arrayBuffer() as Promise<T>;\n }\n\n let data: Record<string, unknown>;\n try {\n data = await response.json() as Record<string, unknown>;\n } catch {\n throw new HydrousError('Failed to parse response JSON', 'PARSE_ERROR', response.status);\n }\n\n if (!response.ok) {\n throw new HydrousError(\n (data['error'] as string) || (data['message'] as string) || `Request failed with status ${response.status}`,\n (data['code'] as string) || 'REQUEST_FAILED',\n response.status,\n data['requestId'] as string | undefined,\n data['details'] as string[] | undefined,\n );\n }\n\n return data as T;\n }\n\n // ─── Convenience wrappers ─────────────────────────────────────────────────\n\n get<T>(path: string, apiKey?: string, extraHeaders?: Record<string, string>): Promise<T> {\n return this.request<T>(path, {\n method: 'GET',\n headers: apiKey\n ? { 'X-Api-Key': apiKey, ...extraHeaders }\n : { ...extraHeaders },\n });\n }\n\n post<T>(path: string, apiKey: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body,\n headers: { 'X-Api-Key': apiKey },\n });\n }\n\n put<T>(path: string, apiKey: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PUT',\n body,\n headers: { 'X-Api-Key': apiKey },\n });\n }\n\n patch<T>(path: string, apiKey: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PATCH',\n body,\n headers: { 'X-Api-Key': apiKey },\n });\n }\n\n delete<T>(path: string, apiKey: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'DELETE',\n body,\n headers: { 'X-Api-Key': apiKey },\n });\n }\n\n /**\n * PUT directly to a signed GCS URL.\n * Uses XHR in browsers for onprogress support; fetch in Node.\n */\n async putToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array | ArrayBuffer,\n mimeType: string,\n onProgress?: (percent: number) => void,\n ): Promise<void> {\n const body: Blob | ArrayBuffer =\n data instanceof Blob ? data :\n data instanceof Uint8Array ? data.buffer as ArrayBuffer :\n data;\n\n if (typeof XMLHttpRequest !== 'undefined' && typeof onProgress === 'function') {\n await new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.upload.onprogress = (e) => {\n if (e.lengthComputable) onProgress(Math.round((e.loaded / e.total) * 100));\n };\n xhr.onload = () => (xhr.status >= 200 && xhr.status < 300 ? resolve() : reject(new Error(`GCS upload failed: ${xhr.status}`)));\n xhr.onerror = () => reject(new Error('GCS upload network error'));\n xhr.open('PUT', signedUrl);\n xhr.setRequestHeader('Content-Type', mimeType);\n xhr.send(body);\n });\n } else {\n const res = await fetch(signedUrl, {\n method: 'PUT',\n headers: { 'Content-Type': mimeType },\n body,\n });\n if (!res.ok) {\n throw new HydrousError(`GCS upload failed: ${res.status}`, 'GCS_UPLOAD_FAILED', res.status);\n }\n }\n }\n}\n","/**\n * routes.ts — Single source of truth for every API path in the HydrousDB SDK.\n *\n * Base URL: https://db-api-82687684612.us-central1.run.app\n *\n * Mount points (from server.js):\n * /api → records router (X-Api-Key: bucketSecurityKey)\n * /api/analytics → analytics router (X-Api-Key: bucketSecurityKey)\n * /api/auth → auth router (X-Api-Key: authKey)\n * /storage → storage router (X-Storage-Key: ssk_…)\n *\n * ⚠️ Keys MUST be sent in headers — NEVER in URLs or query strings.\n * Records + Analytics: X-Api-Key (or Authorization: Bearer …)\n * Storage: X-Storage-Key (or Authorization: Bearer …)\n */\n\n// ─── Records (/api/:bucketKey) ────────────────────────────────────────────────\n// The server mounts the records router at /api, so paths are /api/:bucketKey\n\nexport const RECORDS = {\n /** GET|POST|PATCH|DELETE|HEAD /api/:bucketKey */\n bucket: (bucketKey: string) => `/api/${bucketKey}`,\n\n /** POST /api/:bucketKey/batch/insert */\n batchInsert: (bucketKey: string) => `/api/${bucketKey}/batch/insert`,\n\n /** POST /api/:bucketKey/batch/update */\n batchUpdate: (bucketKey: string) => `/api/${bucketKey}/batch/update`,\n\n /** POST /api/:bucketKey/batch/delete */\n batchDelete: (bucketKey: string) => `/api/${bucketKey}/batch/delete`,\n} as const;\n\n// ─── Analytics (/api/analytics/:bucketKey) ────────────────────────────────────\n// The server mounts analytics at /api/analytics — all queries are POST\n\nexport const ANALYTICS = {\n /** POST /api/analytics/:bucketKey */\n query: (bucketKey: string) => `/api/analytics/${bucketKey}`,\n} as const;\n\n// ─── Auth (/api/auth) ─────────────────────────────────────────────────────────\n// Auth routes do NOT include bucketKey in the URL path.\n// The bucketKey is resolved server-side from the API key itself.\n\nexport const AUTH = {\n /** POST /api/auth/signup body: { email, password, fullName?, ...extra } */\n signup: '/api/auth/signup',\n\n /** POST /api/auth/signin body: { email, password } */\n signin: '/api/auth/signin',\n\n /** POST /api/auth/signout body: { sessionId, allDevices? } */\n signout: '/api/auth/signout',\n\n /** POST /api/auth/session/validate body: { sessionId } */\n sessionValidate: '/api/auth/session/validate',\n\n /** POST /api/auth/session/refresh body: { refreshToken } */\n sessionRefresh: '/api/auth/session/refresh',\n\n /** GET /api/auth/user?userId=... */\n getUser: '/api/auth/user',\n\n /** GET /api/auth/users?limit=&cursor= */\n listUsers: '/api/auth/users',\n\n /** PATCH /api/auth/user body: { sessionId, userId, updates: {...} } */\n updateUser: '/api/auth/user',\n\n /** DELETE /api/auth/user?userId=... body: { sessionId } */\n deleteUser: '/api/auth/user',\n\n /** DELETE /api/auth/user/hard?userId=... body: { sessionId } */\n hardDeleteUser: '/api/auth/user/hard',\n\n /** DELETE /api/auth/users/bulk body: { userIds, hard?, sessionId } */\n bulkDeleteUsers: '/api/auth/users/bulk',\n\n /** POST /api/auth/password/change body: { sessionId, userId, oldPassword, newPassword } */\n passwordChange: '/api/auth/password/change',\n\n /** POST /api/auth/password/reset/request body: { email } */\n passwordResetRequest: '/api/auth/password/reset/request',\n\n /** POST /api/auth/password/reset/confirm body: { resetToken, newPassword } */\n passwordResetConfirm: '/api/auth/password/reset/confirm',\n\n /** POST /api/auth/email/verify/request body: { userId } */\n emailVerifyRequest: '/api/auth/email/verify/request',\n\n /** POST /api/auth/email/verify/confirm body: { verifyToken } */\n emailVerifyConfirm: '/api/auth/email/verify/confirm',\n\n /** POST /api/auth/account/lock body: { sessionId, userId, duration? } */\n accountLock: '/api/auth/account/lock',\n\n /** POST /api/auth/account/unlock body: { sessionId, userId } */\n accountUnlock: '/api/auth/account/unlock',\n} as const;\n\n// ─── Storage (/storage) ───────────────────────────────────────────────────────\n// Storage uses X-Storage-Key (ssk_…), NOT X-Api-Key.\n// These paths are relative to the server base — NOT under /api.\n\nexport const STORAGE = {\n /** GET /storage/info — no auth required */\n info: '/storage/info',\n\n /** GET /storage/public/:fullScopedPath — no auth required */\n publicFile: (fullScopedPath: string) => `/storage/public/${fullScopedPath}`,\n\n /** POST /storage/upload-url body: { path, mimeType, size, isPublic?, overwrite?, expiresIn? } */\n uploadUrl: '/storage/upload-url',\n\n /** POST /storage/batch-upload-urls body: { files: [...], expiresIn? } */\n batchUploadUrls: '/storage/batch-upload-urls',\n\n /** POST /storage/confirm body: { path, mimeType, isPublic? } */\n confirm: '/storage/confirm',\n\n /** POST /storage/batch-confirm body: { files: [...] } */\n batchConfirm: '/storage/batch-confirm',\n\n /** POST /storage/upload multipart/form-data: file, path, mimeType, isPublic, overwrite */\n upload: '/storage/upload',\n\n /** POST /storage/upload-raw body: { path, content, mimeType?, isPublic?, overwrite? } */\n uploadRaw: '/storage/upload-raw',\n\n /** GET /storage/list?prefix=&limit=&cursor= */\n list: '/storage/list',\n\n /** GET /storage/download/:path — requires X-Storage-Key */\n download: (filePath: string) => `/storage/download/${filePath}`,\n\n /** POST /storage/batch-download body: { paths: [...], concurrency? } */\n batchDownload: '/storage/batch-download',\n\n /** GET /storage/metadata/:path */\n metadata: (filePath: string) => `/storage/metadata/${filePath}`,\n\n /** POST /storage/signed-url body: { path, expiresIn? } */\n signedUrl: '/storage/signed-url',\n\n /** PATCH /storage/visibility body: { path, isPublic } */\n visibility: '/storage/visibility',\n\n /** POST /storage/folder body: { path } */\n folder: '/storage/folder',\n\n /** DELETE /storage/file body: { path } */\n file: '/storage/file',\n\n /** DELETE /storage/folder body: { path } */\n folderDelete: '/storage/folder',\n\n /** POST /storage/move body: { from, to } */\n move: '/storage/move',\n\n /** POST /storage/copy body: { from, to } */\n copy: '/storage/copy',\n\n /** GET /storage/stats */\n stats: '/storage/stats',\n} as const;\n","import type { HttpClient } from '../utils/http.js';\nimport { AUTH } from '../routes.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\n// ─── Internal response shapes ─────────────────────────────────────────────────\n\ninterface ApiAuthResponse {\n success: boolean;\n data?: UserRecord;\n session: { sessionId: string; refreshToken: string; expiresAt: number };\n requestId?: string;\n}\n\ninterface ApiUserResponse {\n success: boolean;\n data: UserRecord;\n requestId?: string;\n}\n\ninterface ApiSessionValidateResponse {\n success: boolean;\n data: UserRecord;\n session: { sessionId: string; expiresAt: number };\n requestId?: string;\n}\n\ninterface ApiSessionRefreshResponse {\n success: boolean;\n data?: UserRecord;\n session: { sessionId: string; refreshToken: string; expiresAt: number };\n requestId?: string;\n}\n\ninterface ApiMessageResponse {\n success: boolean;\n message: string;\n requestId?: string;\n}\n\ninterface ApiLockResponse {\n success: boolean;\n data: { lockedUntil: number; unlockTime: string };\n requestId?: string;\n}\n\ninterface ApiListUsersResponse {\n success: boolean;\n data?: UserRecord[];\n meta?: { hasMore: boolean; nextCursor: string | null };\n hasMore?: boolean;\n nextCursor?: string | null;\n requestId?: string;\n}\n\ninterface ApiBulkDeleteResponse {\n success: boolean;\n message: string;\n meta: { succeeded: number; failed: number };\n requestId?: string;\n}\n\n/**\n * AuthClient — user authentication for a project.\n *\n * All routes are under `/api/auth` (NOT `/api/auth/:bucketKey`).\n * The server resolves which user bucket to use from the API key itself.\n * Uses `X-Api-Key: <authKey>`.\n *\n * @example\n * ```ts\n * const auth = db.auth();\n * const { user, session } = await auth.signup({ email: 'alice@example.com', password: 'hunter2' });\n * ```\n */\nexport class AuthClient {\n private readonly http: HttpClient;\n private readonly authKey: string;\n\n constructor(http: HttpClient, authKey: string) {\n this.http = http;\n this.authKey = authKey;\n }\n\n private post<T>(path: string, body?: unknown): Promise<T> {\n return this.http.post<T>(path, this.authKey, body);\n }\n\n private get<T>(path: string, query?: Record<string, string>, extraHeaders?: Record<string, string>): Promise<T> {\n const qs = query && Object.keys(query).length\n ? '?' + new URLSearchParams(query).toString()\n : '';\n return this.http.get<T>(`${path}${qs}`, this.authKey, extraHeaders);\n }\n\n private patch<T>(path: string, body?: unknown): Promise<T> {\n return this.http.patch<T>(path, this.authKey, body);\n }\n\n // ─── Signup / Login / Logout ──────────────────────────────────────────────\n\n /**\n * Register a new user account.\n *\n * Server: POST /api/auth/signup\n * Body: { email, password, fullName?, ...extraData }\n */\n async signup(options: SignupOptions): Promise<AuthResult> {\n const result = await this.post<ApiAuthResponse>(AUTH.signup, options);\n const user = result.data!;\n return this._buildAuthResult(user, result.session);\n }\n\n /**\n * Sign in with email + password.\n *\n * Server: POST /api/auth/signin (NOT /login)\n * Body: { email, password }\n */\n async login(options: LoginOptions): Promise<AuthResult> {\n const result = await this.post<ApiAuthResponse>(AUTH.signin, options);\n const user = result.data!;\n return this._buildAuthResult(user, result.session);\n }\n\n /**\n * Sign out — revoke a session (or all sessions with `allDevices: true`).\n *\n * Server: POST /api/auth/signout\n * Body: { sessionId, allDevices? }\n */\n async logout(options: { sessionId: string; allDevices?: boolean }): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.signout, options);\n }\n\n // ─── Session Management ───────────────────────────────────────────────────\n\n /**\n * Validate an existing session and retrieve the current user.\n *\n * Server: POST /api/auth/session/validate\n * Body: { sessionId }\n */\n async validateSession(\n sessionId: string,\n ): Promise<{ user: UserRecord; session: { sessionId: string; expiresAt: number } }> {\n const result = await this.post<ApiSessionValidateResponse>(\n AUTH.sessionValidate,\n { sessionId },\n );\n return { user: result.data, session: result.session };\n }\n\n /**\n * Rotate a refresh token to get a new session.\n *\n * Server: POST /api/auth/session/refresh\n * Body: { refreshToken }\n */\n async refreshSession(refreshToken: string): Promise<Session> {\n const result = await this.post<ApiSessionRefreshResponse>(\n AUTH.sessionRefresh,\n { refreshToken },\n );\n const s = result.session;\n return {\n sessionId: s.sessionId,\n userId: result.data?.id ?? '',\n bucketId: '',\n createdAt: Date.now(),\n expiresAt: s.expiresAt,\n refreshToken: s.refreshToken,\n refreshExpiresAt: s.expiresAt,\n };\n }\n\n // ─── User Profile ─────────────────────────────────────────────────────────\n\n /**\n * Fetch a user by ID.\n *\n * Server: GET /api/auth/user?userId=:userId\n */\n async getUser(userId: string): Promise<UserRecord> {\n const result = await this.get<ApiUserResponse>(AUTH.getUser, { userId });\n return result.data;\n }\n\n /**\n * Update a user's profile fields.\n * Regular users can only update themselves; admins can update any user.\n *\n * Server: PATCH /api/auth/user\n * Body: { sessionId, userId, updates: { ...fields } }\n */\n async updateUser(options: UpdateUserOptions): Promise<UserRecord> {\n const { sessionId, userId, updates } = options;\n const result = await this.patch<ApiUserResponse>(\n AUTH.updateUser,\n { sessionId, userId, updates },\n );\n return result.data;\n }\n\n /**\n * Soft-delete a user account.\n * Regular users can only delete themselves; admins can delete any user.\n *\n * Server: DELETE /api/auth/user?userId=:userId\n * Body: { sessionId }\n */\n async deleteUser(sessionId: string, userId: string): Promise<void> {\n await this.http.request<ApiMessageResponse>(\n `${AUTH.deleteUser}?userId=${encodeURIComponent(userId)}`,\n {\n method: 'DELETE',\n body: { sessionId },\n headers: { 'X-Api-Key': this.authKey },\n },\n );\n }\n\n // ─── Admin Operations ─────────────────────────────────────────────────────\n\n /**\n * List all users (paginated). Admin only.\n *\n * Server: GET /api/auth/users?limit=&cursor=\n * The sessionId is passed via the X-Session-Id header (GET body is unreliable).\n */\n async listUsers(options: ListUsersOptions): Promise<ListUsersResult> {\n const { sessionId, limit = 50, cursor } = options;\n const params: Record<string, string> = { limit: String(limit) };\n if (cursor) params['cursor'] = cursor;\n\n const result = await this.http.request<ApiListUsersResponse>(\n `${AUTH.listUsers}?${new URLSearchParams(params)}`,\n {\n method: 'GET',\n headers: { 'X-Api-Key': this.authKey, 'X-Session-Id': sessionId },\n },\n );\n return {\n users: result.data ?? [],\n hasMore: result.meta?.hasMore ?? result.hasMore ?? false,\n nextCursor: result.meta?.nextCursor ?? result.nextCursor ?? null,\n };\n }\n\n /**\n * Permanently delete a user (hard delete — cannot be undone).\n * Admin only. Charged at 1 HC per deletion.\n *\n * Server: DELETE /api/auth/user/hard?userId=:userId\n * Body: { sessionId }\n */\n async hardDeleteUser(sessionId: string, userId: string): Promise<void> {\n await this.http.request<ApiMessageResponse>(\n `${AUTH.hardDeleteUser}?userId=${encodeURIComponent(userId)}`,\n {\n method: 'DELETE',\n body: { sessionId },\n headers: { 'X-Api-Key': this.authKey },\n },\n );\n }\n\n /**\n * Delete multiple users at once (soft or hard). Admin only.\n *\n * Server: DELETE /api/auth/users/bulk\n * Body: { userIds, hard?, sessionId }\n */\n async bulkDeleteUsers(options: {\n sessionId: string;\n userIds: string[];\n hard?: boolean;\n }): Promise<{ succeeded: number; failed: number }> {\n const result = await this.http.request<ApiBulkDeleteResponse>(\n AUTH.bulkDeleteUsers,\n {\n method: 'DELETE',\n body: {\n userIds: options.userIds,\n hard: options.hard ?? false,\n sessionId: options.sessionId,\n },\n headers: { 'X-Api-Key': this.authKey },\n },\n );\n return { succeeded: result.meta.succeeded, failed: result.meta.failed };\n }\n\n /**\n * Lock a user account for a specified duration. Admin only.\n *\n * Server: POST /api/auth/account/lock\n * Body: { sessionId, userId, duration? } — duration in ms, default 15 min\n */\n async lockAccount(options: {\n sessionId: string;\n userId: string;\n duration?: number;\n }): Promise<{ lockedUntil: number; unlockTime: string }> {\n const result = await this.post<ApiLockResponse>(AUTH.accountLock, options);\n return result.data;\n }\n\n /**\n * Unlock a locked user account. Admin only.\n *\n * Server: POST /api/auth/account/unlock\n * Body: { sessionId, userId }\n */\n async unlockAccount(sessionId: string, userId: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.accountUnlock, { sessionId, userId });\n }\n\n // ─── Password Management ──────────────────────────────────────────────────\n\n /**\n * Change a user's password. Requires both a valid session AND the old password.\n *\n * Server: POST /api/auth/password/change\n * Body: { sessionId, userId, oldPassword, newPassword }\n */\n async changePassword(options: ChangePasswordOptions): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.passwordChange, {\n sessionId: options.sessionId,\n userId: options.userId,\n oldPassword: options.currentPassword, // server field is `oldPassword`\n newPassword: options.newPassword,\n });\n }\n\n /**\n * Request a password reset email.\n * Always returns success regardless of whether the email exists (prevents enumeration).\n *\n * Server: POST /api/auth/password/reset/request\n * Body: { email }\n */\n async requestPasswordReset(email: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.passwordResetRequest, { email });\n }\n\n /**\n * Confirm a password reset using the token from the reset email.\n *\n * Server: POST /api/auth/password/reset/confirm\n * Body: { resetToken, newPassword }\n */\n async confirmPasswordReset(resetToken: string, newPassword: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.passwordResetConfirm, { resetToken, newPassword });\n }\n\n // ─── Email Verification ───────────────────────────────────────────────────\n\n /**\n * Request a verification email be sent to a user.\n *\n * Server: POST /api/auth/email/verify/request\n * Body: { userId }\n */\n async requestEmailVerification(userId: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.emailVerifyRequest, { userId });\n }\n\n /**\n * Confirm email ownership using the token from the verification email.\n *\n * Server: POST /api/auth/email/verify/confirm\n * Body: { verifyToken }\n */\n async confirmEmailVerification(verifyToken: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.emailVerifyConfirm, { verifyToken });\n }\n\n // ─── Private helpers ──────────────────────────────────────────────────────\n\n private _buildAuthResult(\n user: UserRecord,\n session: { sessionId: string; refreshToken: string; expiresAt: number },\n ): AuthResult {\n return {\n user,\n session: {\n sessionId: session.sessionId,\n userId: user.id,\n bucketId: '',\n createdAt: Date.now(),\n expiresAt: session.expiresAt,\n refreshToken: session.refreshToken,\n refreshExpiresAt: session.expiresAt,\n },\n };\n }\n}\n","import type { QueryFilter, QueryOptions } from '../types/index.js';\n\n/**\n * Build a query string from QueryOptions for GET /api/:bucket requests.\n *\n * The server reads filters from individual query params, NOT a JSON `filters` blob:\n * ?fieldName=value → field == value\n * ?fieldName[op]=value → field <op> value\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('sortBy', options.orderBy); // server param is sortBy\n if (options.order !== undefined) params.set('sortOrder', options.order); // server param is sortOrder\n if (options.fields !== undefined) params.set('fields', options.fields);\n\n // Pagination cursors\n if (options.startAfter !== undefined) params.set('cursor', options.startAfter);\n if (options.startAt !== undefined) params.set('cursor', options.startAt);\n\n // Time-scope shorthand — narrows results to a specific day, month, or year\n // using the record ID prefix convention (_day_YYMMDD | _month_YYMM | _year_YY).\n if (options.timeScope !== undefined) params.set('timeScope', options.timeScope);\n\n // Date range — server GET route doesn't accept dateRange directly;\n // only the analytics POST endpoint handles dateRange as timestamps.\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 // Filters — server GET uses ?field=value and ?field[op]=value syntax\n if (options.filters && options.filters.length > 0) {\n for (const f of options.filters) {\n const key = f.op === '==' ? f.field : `${f.field}[${f.op}]`;\n params.set(key, String(f.value));\n }\n }\n\n const str = params.toString();\n return str ? `?${str}` : '';\n}\n\n/**\n * Normalise a filter shorthand into { 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 * Guess a MIME type from a file extension.\n */\nexport function guessMimeType(filename: string): string {\n const ext = filename.split('.').pop()?.toLowerCase();\n const map: Record<string, string> = {\n jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png',\n gif: 'image/gif', webp: 'image/webp', svg: 'image/svg+xml',\n pdf: 'application/pdf', mp4: 'video/mp4', webm: 'video/webm',\n mp3: 'audio/mpeg', wav: 'audio/wav', txt: 'text/plain',\n html: 'text/html', css: 'text/css', js: 'application/javascript',\n ts: 'application/typescript',\n json: 'application/json', xml: 'application/xml',\n zip: 'application/zip', csv: 'text/csv',\n xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n };\n return map[ext ?? ''] ?? 'application/octet-stream';\n}\n\n/**\n * Assert that a name is safe for use in API paths.\n * Must start with a letter or underscore and contain only letters,\n * numbers, underscores, dots, or hyphens (max 200 chars after the first).\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 ` +\n `contain only letters, numbers, underscores, dots, or hyphens.`,\n );\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport { buildQueryParams, assertSafeName } from '../utils/query.js';\nimport { RECORDS } from '../routes.js';\nimport type {\n RecordData,\n RecordResult,\n QueryOptions,\n QueryResult,\n PatchRecordOptions,\n RecordHistoryEntry,\n CreateRecordOptions,\n BatchCreateOptions,\n} from '../types/index.js';\n\n// ─── Internal response shapes ─────────────────────────────────────────────────\n\ninterface ApiRecordResponse<T> {\n success: boolean;\n data?: T & RecordResult;\n upserted?: boolean;\n meta?: { id: string; custom?: boolean; updatedAt?: number };\n}\n\ninterface ApiQueryResponse<T> {\n success: boolean;\n data?: (T & RecordResult)[];\n meta?: { hasMore: boolean; nextCursor?: string | null; total?: number };\n hasMore?: boolean;\n nextCursor?: string | null;\n total?: number;\n}\n\ninterface ApiBatchCreateResponse<T> {\n success: boolean;\n data?: (T & RecordResult)[];\n meta?: { totalProcessed: number; successful: number; failed: number };\n errors?: unknown[];\n}\n\ninterface ApiBatchDeleteResponse {\n success: boolean;\n data?: { successful: number; failed: string[] };\n meta?: { count: number };\n}\n\ninterface ApiHistoryResponse {\n success: boolean;\n history?: RecordHistoryEntry[];\n}\n\ninterface ApiBatchUpdateResponse {\n success: boolean;\n data?: { successful: number; failed: string[] };\n meta?: { count: number };\n}\n\ninterface ApiExistsResponse {\n success: boolean;\n exists: boolean;\n}\n\n/**\n * RecordsClient — typed CRUD + batch + query for a single bucket.\n *\n * All requests use `X-Api-Key: <bucketSecurityKey>`.\n * Routes: GET|POST|PATCH|DELETE /api/:bucketKey\n *\n * @example\n * ```ts\n * interface Post { title: string; published: boolean }\n * const posts = db.records<Post>('blog-posts');\n * const post = await posts.create({ title: 'Hello', published: false });\n * ```\n */\nexport class RecordsClient<T extends RecordData = RecordData> {\n private readonly http: HttpClient;\n private readonly bucketKey: string;\n private readonly apiKey: string;\n\n constructor(http: HttpClient, bucketSecurityKey: string, bucketKey: string) {\n assertSafeName(bucketKey, 'bucketKey');\n this.http = http;\n this.bucketKey = bucketKey;\n this.apiKey = bucketSecurityKey;\n }\n\n // ─── Single Record Operations ─────────────────────────────────────────────\n\n /**\n * Create a new record (auto-generated ID) or upsert by `customRecordId`.\n *\n * Server: POST /api/:bucketKey\n * Body: { values, queryableFields?, userEmail?, customRecordId? }\n * Returns 201 for new records, 200 for upserts.\n *\n * @example\n * ```ts\n * const post = await posts.create(\n * { title: 'Hello', status: 'draft', authorId: 'u1' },\n * { queryableFields: ['status', 'authorId'], userEmail: 'alice@example.com' },\n * );\n * ```\n */\n async create(data: T, options: CreateRecordOptions = {}): Promise<T & RecordResult> {\n const { queryableFields, userEmail, customRecordId } = options;\n const body: Record<string, unknown> = { values: data };\n if (queryableFields?.length) body['queryableFields'] = queryableFields;\n if (userEmail) body['userEmail'] = userEmail;\n if (customRecordId) body['customRecordId'] = customRecordId;\n\n const result = await this.http.post<ApiRecordResponse<T>>(\n RECORDS.bucket(this.bucketKey),\n this.apiKey,\n body,\n );\n return result.data!;\n }\n\n /**\n * Get a single record by ID.\n *\n * Server: GET /api/:bucketKey?recordId=:id\n */\n async get(id: string): Promise<T & RecordResult> {\n const result = await this.http.get<ApiRecordResponse<T>>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}`,\n this.apiKey,\n );\n return result.data!;\n }\n\n /**\n * Partially update an existing record (PATCH semantics).\n * Supports write-filter sentinels: `{ __op: 'increment', delta: 1 }` etc.\n *\n * Server: PATCH /api/:bucketKey\n * Body: { recordId, values, userEmail?, track_record_history? }\n */\n async patch(\n id: string,\n data: Partial<T>,\n options: PatchRecordOptions & { userEmail?: string; trackHistory?: boolean } = {},\n ): Promise<{ id: string; updatedAt?: number }> {\n const { userEmail, trackHistory } = options;\n const body: Record<string, unknown> = { recordId: id, values: data };\n if (userEmail) body['userEmail'] = userEmail;\n if (trackHistory) body['track_record_history'] = true;\n\n const result = await this.http.patch<ApiRecordResponse<T>>(\n RECORDS.bucket(this.bucketKey),\n this.apiKey,\n body,\n );\n return { id: result.meta?.id ?? id, updatedAt: result.meta?.updatedAt };\n }\n\n /**\n * Delete a record permanently.\n *\n * Server: DELETE /api/:bucketKey?recordId=:id\n */\n async delete(id: string): Promise<void> {\n await this.http.delete<{ success: boolean }>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}`,\n this.apiKey,\n );\n }\n\n /**\n * Check whether a record exists (HEAD request — very lightweight).\n *\n * Server: HEAD /api/:bucketKey?recordId=:id\n * Returns true if the record exists, false if 404.\n */\n async exists(id: string): Promise<boolean> {\n try {\n await this.http.request<void>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}`,\n { method: 'HEAD', headers: { 'X-Api-Key': this.apiKey } },\n );\n return true;\n } catch (err: unknown) {\n if (err && typeof err === 'object' && 'status' in err && (err as { status: number }).status === 404) return false;\n throw err;\n }\n }\n\n /**\n * Get a historical snapshot of a record at a specific generation.\n *\n * Server: GET /api/:bucketKey?recordId=:id&generation=:gen\n */\n async getVersion(id: string, generation: string | number): Promise<T & RecordResult> {\n const result = await this.http.get<ApiRecordResponse<T>>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}&generation=${encodeURIComponent(String(generation))}`,\n this.apiKey,\n );\n return result.data!;\n }\n\n /**\n * Get the version history of a record.\n *\n * Server: GET /api/:bucketKey?recordId=:id&showHistory=true\n */\n async getHistory(id: string): Promise<RecordHistoryEntry[]> {\n const result = await this.http.get<ApiHistoryResponse>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}&showHistory=true`,\n this.apiKey,\n );\n return result.history ?? [];\n }\n\n // ─── Batch Operations ─────────────────────────────────────────────────────\n\n /**\n * Create up to 500 records in one request.\n * Each record may include `_customRecordId` for upsert behaviour.\n *\n * Server: POST /api/:bucketKey/batch/insert\n * Body: { records, queryableFields?, userEmail? }\n *\n * @example\n * ```ts\n * const results = await posts.batchCreate(\n * [{ title: 'A' }, { title: 'B' }],\n * { queryableFields: ['title'] },\n * );\n * ```\n */\n async batchCreate(\n items: T[],\n options: BatchCreateOptions = {},\n ): Promise<{ results: (T & RecordResult)[]; errors: unknown[]; successful: number; failed: number }> {\n const { queryableFields, userEmail } = options;\n const body: Record<string, unknown> = { records: items };\n if (queryableFields?.length) body['queryableFields'] = queryableFields;\n if (userEmail) body['userEmail'] = userEmail;\n\n const result = await this.http.post<ApiBatchCreateResponse<T>>(\n RECORDS.batchInsert(this.bucketKey),\n this.apiKey,\n body,\n );\n return {\n results: result.data ?? [],\n errors: result.errors ?? [],\n successful: result.meta?.successful ?? (result.data?.length ?? 0),\n failed: result.meta?.failed ?? 0,\n };\n }\n\n /**\n * Update up to 500 records in one request.\n *\n * Server: POST /api/:bucketKey/batch/update\n * Body: { updates: [{ recordId, values }], userEmail? }\n */\n async batchUpdate(\n updates: Array<{ recordId: string; values: Partial<T> }>,\n userEmail?: string,\n ): Promise<{ successful: number; failed: string[] }> {\n const body: Record<string, unknown> = { updates };\n if (userEmail) body['userEmail'] = userEmail;\n\n const result = await this.http.post<ApiBatchUpdateResponse>(\n RECORDS.batchUpdate(this.bucketKey),\n this.apiKey,\n body,\n );\n return {\n successful: result.data?.successful ?? result.meta?.count ?? 0,\n failed: result.data?.failed ?? [],\n };\n }\n\n /**\n * Delete up to 500 records in one request.\n *\n * Server: POST /api/:bucketKey/batch/delete\n * Body: { recordIds, userEmail? }\n */\n async batchDelete(\n ids: string[],\n userEmail?: string,\n ): Promise<{ successful: number; failed: string[] }> {\n const body: Record<string, unknown> = { recordIds: ids };\n if (userEmail) body['userEmail'] = userEmail;\n\n const result = await this.http.post<ApiBatchDeleteResponse>(\n RECORDS.batchDelete(this.bucketKey),\n this.apiKey,\n body,\n );\n return {\n successful: result.data?.successful ?? result.meta?.count ?? 0,\n failed: result.data?.failed ?? [],\n };\n }\n\n // ─── Querying ─────────────────────────────────────────────────────────────\n\n /**\n * Query records with filters, sorting, and cursor-based pagination.\n *\n * Server: GET /api/:bucketKey?field=value&field[op]=value&limit=&sortBy=&sortOrder=&cursor=\n *\n * @example\n * ```ts\n * const { records, hasMore, nextCursor } = await posts.query({\n * filters: [{ field: 'status', op: '==', value: 'published' }],\n * orderBy: 'createdAt',\n * order: 'desc',\n * limit: 20,\n * });\n * ```\n */\n async query(options: QueryOptions = {}): Promise<QueryResult<T>> {\n const qs = buildQueryParams(options);\n const result = await this.http.get<ApiQueryResponse<T>>(\n `${RECORDS.bucket(this.bucketKey)}${qs}`,\n this.apiKey,\n );\n return {\n records: result.data ?? [],\n total: result.meta?.total ?? result.total,\n hasMore: result.meta?.hasMore ?? result.hasMore ?? false,\n nextCursor: result.meta?.nextCursor ?? result.nextCursor ?? undefined,\n };\n }\n\n /**\n * Retrieve all records matching options (no filter support — use `query()` for filters).\n */\n async getAll(options: Omit<QueryOptions, 'filters'> = {}): Promise<(T & RecordResult)[]> {\n const { records } = await this.query(options);\n return records;\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport { assertSafeName } from '../utils/query.js';\nimport { ANALYTICS } from '../routes.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 — BigQuery-powered aggregations for a single bucket.\n *\n * All methods POST a `queryType` body to `POST /api/analytics/:bucketKey`.\n * The `dateRange` is passed as `{ start, end }` ms timestamps — the server\n * converts them to ISO date strings internally.\n * Uses `X-Api-Key: <bucketSecurityKey>`.\n *\n * @example\n * ```ts\n * const analytics = db.analytics('orders');\n * const { count } = await analytics.count();\n * const top5 = await analytics.topN({ field: 'country', n: 5 });\n * ```\n */\nexport class AnalyticsClient {\n private readonly http: HttpClient;\n private readonly bucketSecurityKey: string;\n private readonly bucketKey: string;\n\n constructor(http: HttpClient, bucketSecurityKey: string, bucketKey: string) {\n assertSafeName(bucketKey, 'bucketKey');\n this.http = http;\n this.bucketSecurityKey = bucketSecurityKey;\n this.bucketKey = bucketKey;\n }\n\n private async run<T>(query: AnalyticsQuery): Promise<T> {\n const result = await this.http.post<ApiAnalyticsResult<T>>(\n ANALYTICS.query(this.bucketKey),\n this.bucketSecurityKey,\n query,\n );\n return result.data;\n }\n\n // ─── Query methods ────────────────────────────────────────────────────────\n\n /** Count all records, optionally within a date range. */\n async count(opts: { dateRange?: DateRange } = {}): Promise<CountResult> {\n return this.run<CountResult>({ queryType: 'count', ...opts });\n }\n\n /**\n * Get value distribution for a field (e.g. records per status).\n * `order` maps to `sortBy` on the wire (the server param name).\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 a numeric field, optionally grouped by another field. */\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 /** Count of records over time, bucketed by granularity. */\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 /** Aggregate a numeric field over time. */\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 values for a field by count. */\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 /** Statistical summary (min, max, avg, sum, count, stddev) for a numeric field. */\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 /**\n * Fetch filtered records via the analytics engine (BigQuery).\n * Bypasses Firestore pagination — useful for large result sets.\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 /**\n * Compute multiple aggregations in a single request.\n * `metrics` must have valid `field` and `name` (used as BigQuery column aliases).\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 usage stats for the bucket (record count, bytes, avg/min/max size). */\n async storageStats(opts: { dateRange?: DateRange } = {}): Promise<StorageStatsResult> {\n return this.run<StorageStatsResult>({ queryType: 'storageStats', ...opts });\n }\n\n /**\n * Compare a metric across multiple buckets in one query.\n * The caller's key must have read access to EVERY bucket in `bucketKeys`.\n * System buckets (`users`, `_sys_*`) are blocked server-side.\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 /**\n * Raw query — escape hatch when the typed helpers don't cover your case.\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 { STORAGE } from '../routes.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 BatchDownloadResult,\n} from '../types/index.js';\n\n// ─── Internal response shapes ─────────────────────────────────────────────────\n\ninterface ApiUploadResult {\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 ApiUploadUrlResult {\n uploadUrl: string;\n path: string;\n mimeType: string;\n isPublic: boolean;\n size: number;\n expiresAt: string;\n expiresIn: number;\n}\n\ninterface ApiListResult {\n success: boolean;\n items?: FileEntry[];\n pagination?: { hasMore: boolean; nextCursor?: string | null };\n files?: FileEntry[];\n folders?: string[];\n hasMore?: boolean;\n nextCursor?: string | null;\n}\n\ninterface ApiMetadataResult {\n success: boolean;\n path: string;\n name: 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\ninterface ApiBatchUploadUrlResult {\n succeeded: Array<ApiUploadUrlResult & { index: number }>;\n failed: Array<{ index: number; path: string; error: string; code?: string }>;\n}\n\ninterface ApiBatchConfirmResult {\n success: boolean;\n succeeded: ApiUploadResult[];\n failed: Array<{ path: string; error: string; code?: string }>;\n}\n\ninterface ApiBatchDownloadResult {\n success: boolean;\n succeeded: Array<{\n index: number;\n path: string;\n mimeType: string;\n size: number;\n isPublic: boolean;\n content: string; // base64\n }>;\n failed: Array<{ index: number; path: string; error: string; code?: string }>;\n}\n\nfunction toUploadResult(r: ApiUploadResult): UploadResult {\n return {\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/**\n * StorageManager — upload, download, list, move, copy, and delete files.\n *\n * Uses `X-Storage-Key: <ssk_…>` header — separate from auth and bucket keys.\n * Files are scoped server-side to `hydrous-storage/{ownerId}/{userPath}`.\n * You only ever deal with your own `userPath` — the server handles scoping.\n *\n * Get a StorageManager via `db.storage('keyName')` where the name matches\n * one of the keys defined in `storageKeys` when calling `createClient`.\n *\n * @example\n * ```ts\n * const storage = db.storage('avatars');\n * const result = await storage.upload(file, 'alice.jpg', { isPublic: true });\n * console.log(result.publicUrl);\n * ```\n */\nexport class StorageManager {\n private readonly http: HttpClient;\n private readonly storageKey: string;\n\n constructor(http: HttpClient, storageKey: string) {\n this.http = http;\n this.storageKey = storageKey;\n }\n\n private get authHeaders(): Record<string, string> {\n return { 'X-Storage-Key': this.storageKey };\n }\n\n // ─── Upload: Server-buffered ──────────────────────────────────────────────\n\n /**\n * Upload a file in one step (server-buffered, up to 500 MB).\n * For files >10 MB or when upload progress tracking is needed, use the\n * signed URL flow: `getUploadUrl()` → `uploadToSignedUrl()` → `confirmUpload()`.\n *\n * Server: POST /storage/upload (multipart/form-data)\n *\n * @example\n * ```ts\n * const result = await storage.upload(file, 'avatars/alice.jpg', { isPublic: true });\n * console.log(result.publicUrl);\n * ```\n */\n async upload(\n data: Blob | Uint8Array | 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<ApiUploadResult>(STORAGE.upload, {\n method: 'POST',\n rawBody: formData,\n headers: this.authHeaders,\n });\n return toUploadResult(result);\n }\n\n /**\n * Upload raw string or JSON data directly as a file.\n *\n * Server: POST /storage/upload-raw\n * Body: { path, content, mimeType?, isPublic?, overwrite? }\n *\n * @example\n * ```ts\n * await storage.uploadRaw({ theme: 'dark' }, 'settings/config.json');\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 // Server field is `content`, not `data`\n const content = typeof data === 'string' ? data : JSON.stringify(data);\n\n const result = await this.http.request<ApiUploadResult>(STORAGE.uploadRaw, {\n method: 'POST',\n body: { path, content, mimeType, isPublic, overwrite },\n headers: this.authHeaders,\n });\n return toUploadResult(result);\n }\n\n // ─── Upload: Direct-to-GCS (recommended for large files / progress) ───────\n\n /**\n * Step 1 — get a signed GCS PUT URL for direct client-to-GCS upload.\n *\n * Server: POST /storage/upload-url\n * Body: { path, mimeType, size, isPublic?, overwrite?, expiresIn? }\n *\n * @example\n * ```ts\n * const { uploadUrl, path: p } = await storage.getUploadUrl({\n * path: 'videos/intro.mp4', mimeType: 'video/mp4', size: file.size,\n * });\n * await storage.uploadToSignedUrl(uploadUrl, file, 'video/mp4', pct => setProgress(pct));\n * const result = await storage.confirmUpload({ path: p, mimeType: 'video/mp4' });\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 { expiresInSeconds, ...rest } = opts;\n // Server reads `expiresIn` in seconds (not `expiresInSeconds`)\n const result = await this.http.request<ApiUploadUrlResult>(STORAGE.uploadUrl, {\n method: 'POST',\n body: { isPublic: false, overwrite: false, expiresIn: expiresInSeconds ?? 900, ...rest },\n headers: this.authHeaders,\n });\n return {\n uploadUrl: result.uploadUrl,\n path: result.path,\n mimeType: result.mimeType,\n expiresAt: result.expiresAt,\n expiresIn: result.expiresIn,\n };\n }\n\n /**\n * Step 2 — upload data directly to the signed GCS URL.\n * Supports progress tracking in browser environments via XHR.\n */\n async uploadToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array | 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 — confirm a direct upload and register metadata server-side.\n *\n * Server: POST /storage/confirm\n * Body: { path, mimeType, isPublic? }\n */\n async confirmUpload(opts: {\n path: string;\n mimeType: string;\n isPublic?: boolean;\n }): Promise<UploadResult> {\n const result = await this.http.request<ApiUploadResult>(STORAGE.confirm, {\n method: 'POST',\n body: { isPublic: false, ...opts },\n headers: this.authHeaders,\n });\n return toUploadResult(result);\n }\n\n // ─── Batch Upload ─────────────────────────────────────────────────────────\n\n /**\n * Get signed upload URLs for up to 50 files at once.\n *\n * Server: POST /storage/batch-upload-urls\n * Body: { files: [...], expiresIn? }\n */\n async getBatchUploadUrls(files: BatchUploadItem[]): Promise<BatchUploadUrlResult> {\n const result = await this.http.request<ApiBatchUploadUrlResult>(STORAGE.batchUploadUrls, {\n method: 'POST',\n body: { files },\n headers: this.authHeaders,\n });\n return {\n files: result.succeeded.map(f => ({\n index: f.index,\n uploadUrl: f.uploadUrl,\n path: f.path,\n mimeType: f.mimeType,\n expiresAt: f.expiresAt,\n expiresIn: f.expiresIn,\n })),\n };\n }\n\n /**\n * Confirm multiple direct uploads at once.\n *\n * Server: POST /storage/batch-confirm\n * Body: { files: [{ path, mimeType, isPublic? }] }\n */\n async batchConfirmUploads(\n items: Array<{ path: string; mimeType: string; isPublic?: boolean }>,\n ): Promise<{ succeeded: UploadResult[]; failed: Array<{ path: string; error: string }> }> {\n const result = await this.http.request<ApiBatchConfirmResult>(STORAGE.batchConfirm, {\n method: 'POST',\n body: { files: items },\n headers: this.authHeaders,\n });\n return {\n succeeded: result.succeeded.map(toUploadResult),\n failed: result.failed,\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 * Server: GET /storage/download/:path (requires X-Storage-Key)\n */\n async download(path: string): Promise<ArrayBuffer> {\n const encoded = path.split('/').map(encodeURIComponent).join('/');\n return this.http.request<ArrayBuffer>(STORAGE.download(encoded), {\n method: 'GET',\n headers: this.authHeaders,\n });\n }\n\n /**\n * Download up to 20 files at once. Returns base64-encoded content.\n *\n * Server: POST /storage/batch-download\n * Body: { paths, concurrency? }\n */\n async batchDownload(paths: string[], concurrency = 5): Promise<BatchDownloadResult> {\n const result = await this.http.request<ApiBatchDownloadResult>(STORAGE.batchDownload, {\n method: 'POST',\n body: { paths, concurrency },\n headers: this.authHeaders,\n });\n return {\n succeeded: result.succeeded.map(f => ({\n index: f.index,\n path: f.path,\n mimeType: f.mimeType,\n size: f.size,\n content: f.content,\n })),\n failed: result.failed.map(f => ({\n index: f.index,\n path: f.path,\n error: f.error,\n code: f.code,\n })),\n };\n }\n\n // ─── List ─────────────────────────────────────────────────────────────────\n\n /**\n * List files and folders at a given path prefix.\n *\n * Server: GET /storage/list?prefix=&limit=&cursor=\n *\n * @example\n * ```ts\n * const { files, folders, hasMore, nextCursor } = await storage.list({ prefix: 'avatars/', limit: 20 });\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 const qs = params.toString() ? `?${params}` : '';\n\n const result = await this.http.request<ApiListResult>(`${STORAGE.list}${qs}`, {\n method: 'GET',\n headers: this.authHeaders,\n });\n\n // Server returns { items: [...], pagination: { hasMore, nextCursor } }\n if (result.items !== undefined) {\n const files: FileEntry[] = [];\n const folders: string[] = [];\n for (const item of result.items) {\n if (item.type === 'folder') folders.push(item.path);\n else files.push(item);\n }\n return {\n files,\n folders,\n hasMore: result.pagination?.hasMore ?? false,\n nextCursor: result.pagination?.nextCursor ?? undefined,\n };\n }\n\n return {\n files: result.files ?? [],\n folders: result.folders ?? [],\n hasMore: result.hasMore ?? false,\n nextCursor: result.nextCursor ?? undefined,\n };\n }\n\n // ─── Metadata ─────────────────────────────────────────────────────────────\n\n /**\n * Get file metadata: size, MIME type, visibility, URLs.\n *\n * Server: GET /storage/metadata/:path\n */\n async getMetadata(path: string): Promise<FileMetadata> {\n const encoded = path.split('/').map(encodeURIComponent).join('/');\n const result = await this.http.request<ApiMetadataResult>(STORAGE.metadata(encoded), {\n method: 'GET',\n 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 ───────────────────────────────────────────────────────────\n\n /**\n * Generate a time-limited download URL for a private file.\n * Can be shared externally — no X-Storage-Key required to access.\n *\n * Note: Downloads via signed URLs bypass the server — stats are NOT tracked.\n *\n * Server: POST /storage/signed-url\n * Body: { path, expiresIn? }\n *\n * @param path File path.\n * @param expiresIn URL lifetime in seconds (default 3600 = 1 hour).\n */\n async getSignedUrl(path: string, expiresIn = 3600): Promise<SignedUrlResult> {\n const result = await this.http.request<ApiSignedUrlResult>(STORAGE.signedUrl, {\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.\n *\n * Server: PATCH /storage/visibility\n * Body: { path, isPublic }\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>(STORAGE.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 (empty GCS object used as a prefix marker).\n *\n * Server: POST /storage/folder\n * Body: { path }\n */\n async createFolder(path: string): Promise<{ path: string }> {\n const result = await this.http.request<{ success: boolean; path: string }>(STORAGE.folder, {\n method: 'POST',\n body: { path },\n headers: this.authHeaders,\n });\n return { path: result.path };\n }\n\n // ─── File Operations ──────────────────────────────────────────────────────\n\n /**\n * Permanently delete a file.\n *\n * Server: DELETE /storage/file\n * Body: { path }\n */\n async deleteFile(path: string): Promise<void> {\n await this.http.request<{ success: boolean }>(STORAGE.file, {\n method: 'DELETE',\n body: { path },\n headers: this.authHeaders,\n });\n }\n\n /**\n * Recursively delete a folder and all its contents.\n *\n * Server: DELETE /storage/folder\n * Body: { path }\n */\n async deleteFolder(path: string): Promise<void> {\n await this.http.request<{ success: boolean }>(STORAGE.folderDelete, {\n method: 'DELETE',\n body: { path },\n headers: this.authHeaders,\n });\n }\n\n /**\n * Move (rename) a file.\n *\n * Server: POST /storage/move\n * Body: { from, to }\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 }>(STORAGE.move, {\n method: 'POST',\n body: { from, to },\n 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 * Server: POST /storage/copy\n * Body: { from, to }\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 }>(STORAGE.copy, {\n method: 'POST',\n body: { from, to },\n headers: this.authHeaders,\n });\n return { from: result.from, to: result.to };\n }\n\n // ─── Stats ────────────────────────────────────────────────────────────────\n\n /**\n * Get usage statistics for this storage key.\n *\n * Server: GET /storage/stats\n */\n async getStats(): Promise<StorageStats> {\n const result = await this.http.request<ApiStatsResult>(STORAGE.stats, {\n method: 'GET',\n headers: this.authHeaders,\n });\n return result.stats;\n }\n\n /**\n * Get server info (no auth required).\n *\n * Server: GET /storage/info\n */\n async info(): Promise<{ ok: boolean; storageRoot: string }> {\n return this.http.request<{ ok: boolean; storageRoot: string }>(STORAGE.info, {\n method: 'GET',\n });\n }\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 StorageStats,\n BatchUploadItem,\n BatchUploadUrlResult,\n BatchDownloadResult,\n} from '../types/index.js';\n\n/**\n * ScopedStorage — a path-prefixed view over a StorageManager.\n *\n * Every path you pass is automatically prefixed with the scope.\n * Obtain via `db.storage('keyName').scope('prefix/')`.\n *\n * @example\n * ```ts\n * const userDocs = db.storage('documents').scope(`users/${userId}/`);\n *\n * // Uploads to: users/{userId}/contract.pdf\n * await userDocs.upload(pdfBuffer, 'contract.pdf');\n *\n * // Lists: users/{userId}/\n * const { files } = await userDocs.list();\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 // Ensure exactly one trailing slash\n this.prefix = prefix.endsWith('/') ? prefix : `${prefix}/`;\n }\n\n private p(path: string): string {\n return `${this.prefix}${path.replace(/^\\/+/, '')}`;\n }\n\n // ─── Upload ───────────────────────────────────────────────────────────────\n\n async upload(\n data: Blob | Uint8Array | ArrayBuffer | Buffer,\n path: string,\n options: UploadOptions = {},\n ): Promise<UploadResult> {\n return this.manager.upload(data, this.p(path), options);\n }\n\n async uploadRaw(\n data: unknown,\n path: string,\n options: UploadOptions = {},\n ): Promise<UploadResult> {\n return this.manager.uploadRaw(data, this.p(path), options);\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 return this.manager.getUploadUrl({ ...opts, path: this.p(opts.path) });\n }\n\n async uploadToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array | ArrayBuffer,\n mimeType: string,\n onProgress?: (percent: number) => void,\n ): Promise<void> {\n return this.manager.uploadToSignedUrl(signedUrl, data, mimeType, onProgress);\n }\n\n async confirmUpload(opts: {\n path: string;\n mimeType: string;\n isPublic?: boolean;\n }): Promise<UploadResult> {\n return this.manager.confirmUpload({ ...opts, path: this.p(opts.path) });\n }\n\n async getBatchUploadUrls(files: BatchUploadItem[]): Promise<BatchUploadUrlResult> {\n return this.manager.getBatchUploadUrls(\n files.map(f => ({ ...f, path: this.p(f.path) })),\n );\n }\n\n async batchConfirmUploads(\n items: Array<{ path: string; mimeType: string; isPublic?: boolean }>,\n ): Promise<{ succeeded: UploadResult[]; failed: Array<{ path: string; error: string }> }> {\n return this.manager.batchConfirmUploads(\n items.map(i => ({ ...i, path: this.p(i.path) })),\n );\n }\n\n // ─── Download ─────────────────────────────────────────────────────────────\n\n async download(path: string): Promise<ArrayBuffer> {\n return this.manager.download(this.p(path));\n }\n\n async batchDownload(paths: string[]): Promise<BatchDownloadResult> {\n return this.manager.batchDownload(paths.map(p => this.p(p)));\n }\n\n // ─── List ─────────────────────────────────────────────────────────────────\n\n /**\n * List files within this scope.\n * The `prefix` option is relative to the scope root.\n *\n * @example\n * ```ts\n * const userDocs = storage.scope('users/alice/');\n * // Lists users/alice/docs/\n * const { files } = await userDocs.list({ prefix: 'docs/' });\n * ```\n */\n async list(opts: ListOptions = {}): Promise<ListResult> {\n return this.manager.list({\n ...opts,\n prefix: this.p(opts.prefix ?? ''),\n });\n }\n\n // ─── Metadata & URLs ──────────────────────────────────────────────────────\n\n async getMetadata(path: string): Promise<FileMetadata> {\n return this.manager.getMetadata(this.p(path));\n }\n\n async getSignedUrl(path: string, expiresIn = 3600): Promise<SignedUrlResult> {\n return this.manager.getSignedUrl(this.p(path), expiresIn);\n }\n\n async 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.p(path), isPublic);\n }\n\n // ─── Folder Operations ────────────────────────────────────────────────────\n\n async createFolder(path: string): Promise<{ path: string }> {\n return this.manager.createFolder(this.p(path));\n }\n\n // ─── File Operations ──────────────────────────────────────────────────────\n\n async deleteFile(path: string): Promise<void> {\n return this.manager.deleteFile(this.p(path));\n }\n\n async deleteFolder(path: string): Promise<void> {\n return this.manager.deleteFolder(this.p(path));\n }\n\n async move(from: string, to: string): Promise<{ from: string; to: string }> {\n return this.manager.move(this.p(from), this.p(to));\n }\n\n async copy(from: string, to: string): Promise<{ from: string; to: string }> {\n return this.manager.copy(this.p(from), this.p(to));\n }\n\n // ─── Stats ────────────────────────────────────────────────────────────────\n\n async getStats(): Promise<StorageStats> {\n return this.manager.getStats();\n }\n\n // ─── Nesting ──────────────────────────────────────────────────────────────\n\n /**\n * Create a deeper scope within this one.\n *\n * @example\n * ```ts\n * const user = storage.scope('users/alice/');\n * const userDocs = user.scope('docs/');\n * // Effective prefix: users/alice/docs/\n * ```\n */\n scope(subPrefix: string): ScopedStorage {\n return new ScopedStorage(this.manager, this.p(subPrefix));\n }\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\nexport class HydrousClient {\n private readonly http: HttpClient;\n private readonly authKey_: string;\n private readonly bucketSecurityKey_: string;\n private readonly storageKeys_: Record<string, string>;\n\n private readonly _recordsCache = new Map<string, RecordsClient<RecordData>>();\n private readonly _analyticsCache = new Map<string, AnalyticsClient>();\n private readonly _storageCache = new Map<string, StorageManager>();\n private _authClient?: AuthClient;\n\n constructor(config: HydrousConfig) {\n if (!config.authKey) {\n throw new Error('[HydrousDB] authKey is required.');\n }\n if (!config.bucketSecurityKey) {\n throw new Error('[HydrousDB] bucketSecurityKey is required.');\n }\n if (!config.storageKeys || Object.keys(config.storageKeys).length === 0) {\n throw new Error('[HydrousDB] storageKeys must define at least one key.');\n }\n\n // The baseUrl should point to the server root (no /api suffix).\n // All route paths in routes.ts are fully qualified: /api/..., /storage/...\n this.http = new HttpClient(config.baseUrl ?? DEFAULT_BASE_URL);\n this.authKey_ = config.authKey;\n this.bucketSecurityKey_ = config.bucketSecurityKey;\n this.storageKeys_ = config.storageKeys;\n }\n\n // ─── Records ──────────────────────────────────────────────────────────────\n\n /**\n * Get a typed RecordsClient for a bucket.\n *\n * @example\n * ```ts\n * interface Post { title: string; published: boolean }\n * const posts = db.records<Post>('blog-posts');\n * const post = await posts.create({ title: 'Hello', published: false });\n * ```\n */\n records<T extends RecordData = RecordData>(bucketKey: string): RecordsClient<T> {\n if (!this._recordsCache.has(bucketKey)) {\n this._recordsCache.set(\n bucketKey,\n new RecordsClient<T>(this.http, this.bucketSecurityKey_, bucketKey) as RecordsClient<RecordData>,\n );\n }\n return this._recordsCache.get(bucketKey) as RecordsClient<T>;\n }\n\n // ─── Auth ─────────────────────────────────────────────────────────────────\n\n /**\n * Get the AuthClient.\n * Auth routes are NOT bucket-scoped in the URL — the bucket is determined\n * server-side from the API key itself.\n *\n * @example\n * ```ts\n * const { user, session } = await db.auth().signup({ email: 'alice@example.com', password: 'pw' });\n * ```\n */\n auth(): AuthClient {\n if (!this._authClient) {\n this._authClient = new AuthClient(this.http, this.authKey_);\n }\n return this._authClient;\n }\n\n // ─── Analytics ────────────────────────────────────────────────────────────\n\n /**\n * Get an AnalyticsClient for a bucket.\n *\n * @example\n * ```ts\n * const { count } = await db.analytics('orders').count();\n * ```\n */\n analytics(bucketKey: string): AnalyticsClient {\n if (!this._analyticsCache.has(bucketKey)) {\n this._analyticsCache.set(\n bucketKey,\n new AnalyticsClient(this.http, this.bucketSecurityKey_, bucketKey),\n );\n }\n return this._analyticsCache.get(bucketKey)!;\n }\n\n // ─── Storage ──────────────────────────────────────────────────────────────\n\n /**\n * Get a StorageManager for a named storage key.\n * The name must match a key in the `storageKeys` config object.\n *\n * Attach `.scope('prefix/')` to get a path-prefixed ScopedStorage.\n *\n * @example\n * ```ts\n * const avatars = db.storage('avatars');\n * const result = await avatars.upload(file, 'alice.jpg', { isPublic: true });\n *\n * // Scoped:\n * const userFiles = db.storage('documents').scope(`users/${userId}/`);\n * await userFiles.upload(pdf, 'contract.pdf');\n * ```\n */\n storage(keyName: string): StorageManager & { scope: (prefix: string) => ScopedStorage } {\n const ssk = this.storageKeys_[keyName];\n if (!ssk) {\n const available = Object.keys(this.storageKeys_).join(', ');\n throw new Error(\n `[HydrousDB] Unknown storage key name \"${keyName}\". ` +\n `Available keys: ${available}. ` +\n `Add it to storageKeys in your createClient() config.`,\n );\n }\n\n if (!this._storageCache.has(keyName)) {\n this._storageCache.set(keyName, new StorageManager(this.http, ssk));\n }\n\n const mgr = this._storageCache.get(keyName)!;\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 ──────────────────────────────────────────────────────────────────\n\n/**\n * Create a HydrousDB client.\n *\n * @example\n * ```ts\n * import { createClient } from 'hydrous-sdk';\n *\n * const db = createClient({\n * authKey: 'hk_auth_…',\n * bucketSecurityKey: 'hk_bucket_…',\n * storageKeys: { avatars: 'ssk_…' },\n * });\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/routes.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.cjs","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 if (cause !== undefined) this.cause = cause;\n }\n}\n","import { HydrousError, NetworkError } from './errors.js';\n\n/**\n * The server base URL — no trailing slash, no /api suffix.\n * Routes in routes.ts already include /api, /api/analytics, /api/auth, /storage.\n */\nexport const DEFAULT_BASE_URL = 'https://db-api-82687684612.us-central1.run.app';\n\ninterface RequestOptions {\n method: string;\n body?: unknown;\n rawBody?: FormData | Uint8Array | ArrayBuffer;\n headers?: Record<string, string>;\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n\n constructor(baseUrl: string) {\n // Strip trailing slash; routes.ts paths start with /\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n }\n\n // ─── Core request ──────────────────────────────────────────────────────────\n\n async request<T>(path: string, options: RequestOptions): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = { ...options.headers };\n\n let body: BodyInit | undefined;\n\n if (options.rawBody !== undefined) {\n // FormData or binary — browser/Node sets Content-Type automatically\n body = options.rawBody as BodyInit;\n } else if (options.body !== undefined) {\n headers['Content-Type'] = 'application/json';\n body = JSON.stringify(options.body);\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: options.method,\n headers,\n body,\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 // Binary responses (downloads)\n const contentType = response.headers.get('content-type') ?? '';\n if (!contentType.includes('application/json')) {\n if (!response.ok) {\n throw new HydrousError(\n `Request failed with status ${response.status}`,\n 'REQUEST_FAILED',\n response.status,\n );\n }\n return response.arrayBuffer() as Promise<T>;\n }\n\n let data: Record<string, unknown>;\n try {\n data = await response.json() as Record<string, unknown>;\n } catch {\n throw new HydrousError('Failed to parse response JSON', 'PARSE_ERROR', response.status);\n }\n\n if (!response.ok) {\n throw new HydrousError(\n (data['error'] as string) || (data['message'] as string) || `Request failed with status ${response.status}`,\n (data['code'] as string) || 'REQUEST_FAILED',\n response.status,\n data['requestId'] as string | undefined,\n data['details'] as string[] | undefined,\n );\n }\n\n return data as T;\n }\n\n // ─── Convenience wrappers ─────────────────────────────────────────────────\n\n get<T>(path: string, apiKey?: string, extraHeaders?: Record<string, string>): Promise<T> {\n return this.request<T>(path, {\n method: 'GET',\n headers: apiKey\n ? { 'X-Api-Key': apiKey, ...extraHeaders }\n : { ...extraHeaders },\n });\n }\n\n post<T>(path: string, apiKey: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body,\n headers: { 'X-Api-Key': apiKey },\n });\n }\n\n put<T>(path: string, apiKey: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PUT',\n body,\n headers: { 'X-Api-Key': apiKey },\n });\n }\n\n patch<T>(path: string, apiKey: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PATCH',\n body,\n headers: { 'X-Api-Key': apiKey },\n });\n }\n\n delete<T>(path: string, apiKey: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'DELETE',\n body,\n headers: { 'X-Api-Key': apiKey },\n });\n }\n\n /**\n * PUT directly to a signed GCS URL.\n * Uses XHR in browsers for onprogress support; fetch in Node.\n */\n async putToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array | ArrayBuffer,\n mimeType: string,\n onProgress?: (percent: number) => void,\n ): Promise<void> {\n const body: Blob | ArrayBuffer =\n data instanceof Blob ? data :\n data instanceof Uint8Array ? data.buffer as ArrayBuffer :\n data;\n\n if (typeof XMLHttpRequest !== 'undefined' && typeof onProgress === 'function') {\n await new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.upload.onprogress = (e) => {\n if (e.lengthComputable) onProgress(Math.round((e.loaded / e.total) * 100));\n };\n xhr.onload = () => (xhr.status >= 200 && xhr.status < 300 ? resolve() : reject(new Error(`GCS upload failed: ${xhr.status}`)));\n xhr.onerror = () => reject(new Error('GCS upload network error'));\n xhr.open('PUT', signedUrl);\n xhr.setRequestHeader('Content-Type', mimeType);\n xhr.send(body);\n });\n } else {\n const res = await fetch(signedUrl, {\n method: 'PUT',\n headers: { 'Content-Type': mimeType },\n body,\n });\n if (!res.ok) {\n throw new HydrousError(`GCS upload failed: ${res.status}`, 'GCS_UPLOAD_FAILED', res.status);\n }\n }\n }\n}\n","// ─── Route constants & builders ───────────────────────────────────────────────\n// All paths are fully qualified so they can be appended directly to baseUrl.\n// Never include a trailing slash.\n\n// ─── Records ──────────────────────────────────────────────────────────────────\nexport const RECORDS = {\n /** Base path for a bucket: GET|POST /api/:bucketKey */\n bucket: (bucketKey: string) => `/api/${bucketKey}`,\n /** Batch insert: POST /api/:bucketKey/batch/insert */\n batchInsert: (bucketKey: string) => `/api/${bucketKey}/batch/insert`,\n /** Batch update: POST /api/:bucketKey/batch/update */\n batchUpdate: (bucketKey: string) => `/api/${bucketKey}/batch/update`,\n /** Batch delete: POST /api/:bucketKey/batch/delete */\n batchDelete: (bucketKey: string) => `/api/${bucketKey}/batch/delete`,\n} as const;\n\n// ─── Analytics ────────────────────────────────────────────────────────────────\nexport const ANALYTICS = {\n /** Analytics query: POST /api/analytics/:bucketKey */\n query: (bucketKey: string) => `/api/analytics/${bucketKey}`,\n} as const;\n\n// ─── Auth ─────────────────────────────────────────────────────────────────────\n// All auth routes are under /api/auth.\n// The server resolves the user bucket from the API key — no bucketKey in the URL.\nexport const AUTH = {\n // ── Core ────────────────────────────────────────────────────────────────\n signup: '/api/auth/signup',\n signin: '/api/auth/signin',\n signout: '/api/auth/signout',\n\n // ── Google OAuth ─────────────────────────────────────────────────────────\n // POST /api/auth/google — sign in or create account via Google ID token\n // POST /api/auth/google/link — link Google to an existing email/password account\n // DELETE /api/auth/google/unlink — remove Google (only if a password is set)\n googleSignIn: '/api/auth/google',\n googleLink: '/api/auth/google/link',\n googleUnlink: '/api/auth/google/unlink',\n\n // ── Session ──────────────────────────────────────────────────────────────\n sessionValidate: '/api/auth/session/validate',\n sessionRefresh: '/api/auth/session/refresh',\n\n // ── User ─────────────────────────────────────────────────────────────────\n getUser: '/api/auth/user',\n updateUser: '/api/auth/user',\n deleteUser: '/api/auth/user',\n\n // ── Admin ─────────────────────────────────────────────────────────────────\n listUsers: '/api/auth/users',\n hardDeleteUser: '/api/auth/user/hard',\n bulkDeleteUsers: '/api/auth/users/bulk',\n\n // ── Account ───────────────────────────────────────────────────────────────\n accountLock: '/api/auth/account/lock',\n accountUnlock: '/api/auth/account/unlock',\n\n // ── Password ──────────────────────────────────────────────────────────────\n passwordChange: '/api/auth/password/change',\n passwordResetRequest: '/api/auth/password/reset/request',\n passwordResetConfirm: '/api/auth/password/reset/confirm',\n\n // ── Email Verification ────────────────────────────────────────────────────\n emailVerifyRequest: '/api/auth/email/verify/request',\n emailVerifyConfirm: '/api/auth/email/verify/confirm',\n} as const;\n\n// ─── Storage ──────────────────────────────────────────────────────────────────\n// All storage routes are under /storage.\n// Paths that include a file path use a function so the path can be encoded.\nexport const STORAGE = {\n base: '/storage',\n upload: '/storage/upload',\n uploadRaw: '/storage/upload/raw',\n uploadUrl: '/storage/upload/url',\n confirm: '/storage/upload/confirm',\n batchUploadUrls:'/storage/upload/batch/urls',\n batchConfirm: '/storage/upload/batch/confirm',\n download: (encodedPath: string) => `/storage/download/${encodedPath}`,\n batchDownload: '/storage/download/batch',\n list: '/storage/list',\n metadata: (encodedPath: string) => `/storage/metadata/${encodedPath}`,\n signedUrl: '/storage/signed-url',\n visibility: '/storage/visibility',\n folder: '/storage/folder',\n file: '/storage/file',\n folderDelete: '/storage/folder/delete',\n move: '/storage/move',\n copy: '/storage/copy',\n stats: '/storage/stats',\n info: '/storage/info',\n} as const;\n","import type { HttpClient } from '../utils/http.js';\nimport { AUTH } from '../routes.js';\nimport type {\n SignupOptions,\n LoginOptions,\n GoogleSignInOptions,\n GoogleLinkOptions,\n AuthResult,\n UserRecord,\n UpdateUserOptions,\n ChangePasswordOptions,\n ListUsersOptions,\n ListUsersResult,\n Session,\n} from '../types/index.js';\n\n// ─── Internal response shapes ─────────────────────────────────────────────────\n\ninterface ApiAuthResponse {\n success: boolean;\n data?: UserRecord;\n session: { sessionId: string; refreshToken: string; expiresAt: number };\n isNew?: boolean;\n requestId?: string;\n}\n\ninterface ApiUserResponse {\n success: boolean;\n data: UserRecord;\n requestId?: string;\n}\n\ninterface ApiSessionValidateResponse {\n success: boolean;\n data: UserRecord;\n session: { sessionId: string; expiresAt: number };\n requestId?: string;\n}\n\ninterface ApiSessionRefreshResponse {\n success: boolean;\n data?: UserRecord;\n session: { sessionId: string; refreshToken: string; expiresAt: number };\n requestId?: string;\n}\n\ninterface ApiMessageResponse {\n success: boolean;\n message: string;\n requestId?: string;\n}\n\ninterface ApiLockResponse {\n success: boolean;\n data: { lockedUntil: number; unlockTime: string };\n requestId?: string;\n}\n\ninterface ApiListUsersResponse {\n success: boolean;\n data?: UserRecord[];\n meta?: { hasMore: boolean; nextCursor: string | null };\n hasMore?: boolean;\n nextCursor?: string | null;\n requestId?: string;\n}\n\ninterface ApiBulkDeleteResponse {\n success: boolean;\n message: string;\n meta: { succeeded: number; failed: number };\n requestId?: string;\n}\n\n/**\n * AuthClient — user authentication for a project.\n *\n * All routes are under `/api/auth` (NOT `/api/auth/:bucketKey`).\n * The server resolves which user bucket to use from the API key itself.\n * Uses `X-Api-Key: <authKey>`.\n *\n * @example\n * ```ts\n * const auth = db.auth();\n * const { user, session } = await auth.signup({ email: 'alice@example.com', password: 'hunter2' });\n * ```\n */\nexport class AuthClient {\n private readonly http: HttpClient;\n private readonly authKey: string;\n\n constructor(http: HttpClient, authKey: string) {\n this.http = http;\n this.authKey = authKey;\n }\n\n private post<T>(path: string, body?: unknown): Promise<T> {\n return this.http.post<T>(path, this.authKey, body);\n }\n\n private get<T>(path: string, query?: Record<string, string>, extraHeaders?: Record<string, string>): Promise<T> {\n const qs = query && Object.keys(query).length\n ? '?' + new URLSearchParams(query).toString()\n : '';\n return this.http.get<T>(`${path}${qs}`, this.authKey, extraHeaders);\n }\n\n private patch<T>(path: string, body?: unknown): Promise<T> {\n return this.http.patch<T>(path, this.authKey, body);\n }\n\n // ─── Signup / Login / Logout ──────────────────────────────────────────────\n\n /**\n * Register a new user account.\n *\n * Server: POST /api/auth/signup\n * Body: { email, password, fullName?, ...extraData }\n */\n async signup(options: SignupOptions): Promise<AuthResult> {\n const result = await this.post<ApiAuthResponse>(AUTH.signup, options);\n return this._buildAuthResult(result.data!, result.session, result.isNew);\n }\n\n /**\n * Sign in with email + password.\n *\n * Server: POST /api/auth/signin (NOT /login)\n * Body: { email, password }\n */\n async login(options: LoginOptions): Promise<AuthResult> {\n const result = await this.post<ApiAuthResponse>(AUTH.signin, options);\n return this._buildAuthResult(result.data!, result.session, result.isNew);\n }\n\n /**\n * Sign out — revoke a session (or all sessions with `allDevices: true`).\n *\n * Server: POST /api/auth/signout\n * Body: { sessionId, allDevices? }\n */\n async logout(options: { sessionId: string; allDevices?: boolean }): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.signout, options);\n }\n\n // ─── Google Sign-In ───────────────────────────────────────────────────────\n\n /**\n * Sign in or create an account using a Google ID token.\n *\n * Pass the `idToken` from the Google Sign-In SDK. Your server verifies the\n * token against Google's public keys, then either creates a new account or\n * signs in the returning user. No password is ever set or required.\n *\n * The returned `AuthResult` is identical in shape to `login()` and `signup()`.\n * Sessions from Google sign-in work with `validateSession`, `refreshSession`,\n * and `logout` — nothing changes after the initial sign-in.\n *\n * Use `isNew` to drive onboarding flows.\n *\n * @example\n * ```ts\n * // Web — Google Identity Services\n * google.accounts.id.initialize({\n * client_id: 'YOUR_GOOGLE_CLIENT_ID',\n * callback: async ({ credential }) => {\n * const { user, session, isNew } = await db.auth().continueWithGoogle({\n * idToken: credential,\n * });\n * if (isNew) router.push('/onboarding');\n * else router.push('/dashboard');\n * },\n * });\n *\n * // React Native\n * const { idToken } = await GoogleSignin.signIn();\n * const { user, session, isNew } = await db.auth().continueWithGoogle({ idToken });\n * ```\n *\n * Server: POST /api/auth/google\n * Body: { idToken }\n */\n async continueWithGoogle(options: GoogleSignInOptions): Promise<AuthResult> {\n if (!options.idToken || typeof options.idToken !== 'string') {\n throw new Error('[HydrousDB] continueWithGoogle: idToken is required and must be a string.');\n }\n const result = await this.post<ApiAuthResponse>(AUTH.googleSignIn, {\n idToken: options.idToken,\n });\n return this._buildAuthResult(result.data!, result.session, result.isNew);\n }\n\n /**\n * Link a Google account to the currently signed-in user.\n *\n * After linking, the user can sign in with either their email + password\n * or with Google — both produce valid sessions.\n *\n * The server is idempotent — calling this when Google is already linked\n * returns the updated user without creating duplicate entries.\n *\n * @example\n * ```ts\n * // User is signed in with email. They click \"Connect Google\" in settings.\n * const { idToken } = await GoogleSignin.signIn();\n * const updatedUser = await db.auth().linkGoogle({\n * sessionId: currentSession.sessionId,\n * idToken,\n * });\n * ```\n *\n * Server: POST /api/auth/google/link\n * Body: { sessionId, idToken }\n */\n async linkGoogle(options: GoogleLinkOptions): Promise<UserRecord> {\n if (!options.sessionId) {\n throw new Error('[HydrousDB] linkGoogle: sessionId is required.');\n }\n if (!options.idToken || typeof options.idToken !== 'string') {\n throw new Error('[HydrousDB] linkGoogle: idToken is required and must be a string.');\n }\n const result = await this.post<ApiUserResponse>(AUTH.googleLink, {\n sessionId: options.sessionId,\n idToken: options.idToken,\n });\n return result.data;\n }\n\n /**\n * Unlink Google from the currently signed-in user's account.\n *\n * Only succeeds if the user has a password set — you cannot remove the only\n * sign-in method. If the account was created via Google and has no password,\n * call `changePassword` first.\n *\n * @example\n * ```ts\n * await db.auth().unlinkGoogle({ sessionId: currentSession.sessionId });\n * ```\n *\n * Server: DELETE /api/auth/google/unlink\n * Body: { sessionId }\n */\n async unlinkGoogle(options: { sessionId: string }): Promise<void> {\n if (!options.sessionId) {\n throw new Error('[HydrousDB] unlinkGoogle: sessionId is required.');\n }\n await this.http.request<ApiMessageResponse>(AUTH.googleUnlink, {\n method: 'DELETE',\n body: { sessionId: options.sessionId },\n headers: { 'X-Api-Key': this.authKey },\n });\n }\n\n // ─── Session Management ───────────────────────────────────────────────────\n\n /**\n * Validate an existing session and retrieve the current user.\n *\n * Server: POST /api/auth/session/validate\n * Body: { sessionId }\n */\n async validateSession(\n sessionId: string,\n ): Promise<{ user: UserRecord; session: { sessionId: string; expiresAt: number } }> {\n const result = await this.post<ApiSessionValidateResponse>(\n AUTH.sessionValidate,\n { sessionId },\n );\n return { user: result.data, session: result.session };\n }\n\n /**\n * Rotate a refresh token to get a new session.\n *\n * Server: POST /api/auth/session/refresh\n * Body: { refreshToken }\n */\n async refreshSession(refreshToken: string): Promise<Session> {\n const result = await this.post<ApiSessionRefreshResponse>(\n AUTH.sessionRefresh,\n { refreshToken },\n );\n const s = result.session;\n return {\n sessionId: s.sessionId,\n userId: result.data?.id ?? '',\n bucketId: '',\n createdAt: Date.now(),\n expiresAt: s.expiresAt,\n refreshToken: s.refreshToken,\n refreshExpiresAt: s.expiresAt,\n };\n }\n\n // ─── User Profile ─────────────────────────────────────────────────────────\n\n /**\n * Fetch a user by ID.\n *\n * Server: GET /api/auth/user?userId=:userId\n */\n async getUser(userId: string): Promise<UserRecord> {\n const result = await this.get<ApiUserResponse>(AUTH.getUser, { userId });\n return result.data;\n }\n\n /**\n * Update a user's profile fields.\n * Regular users can only update themselves; admins can update any user.\n *\n * Server: PATCH /api/auth/user\n * Body: { sessionId, userId, updates: { ...fields } }\n */\n async updateUser(options: UpdateUserOptions): Promise<UserRecord> {\n const { sessionId, userId, updates } = options;\n const result = await this.patch<ApiUserResponse>(\n AUTH.updateUser,\n { sessionId, userId, updates },\n );\n return result.data;\n }\n\n /**\n * Soft-delete a user account.\n * Regular users can only delete themselves; admins can delete any user.\n *\n * Server: DELETE /api/auth/user?userId=:userId\n * Body: { sessionId }\n */\n async deleteUser(sessionId: string, userId: string): Promise<void> {\n await this.http.request<ApiMessageResponse>(\n `${AUTH.deleteUser}?userId=${encodeURIComponent(userId)}`,\n {\n method: 'DELETE',\n body: { sessionId },\n headers: { 'X-Api-Key': this.authKey },\n },\n );\n }\n\n // ─── Admin Operations ─────────────────────────────────────────────────────\n\n /**\n * List all users (paginated). Admin only.\n *\n * Server: GET /api/auth/users?limit=&cursor=\n * The sessionId is passed via the X-Session-Id header (GET body is unreliable).\n */\n async listUsers(options: ListUsersOptions): Promise<ListUsersResult> {\n const { sessionId, limit = 50, cursor } = options;\n const params: Record<string, string> = { limit: String(limit) };\n if (cursor) params['cursor'] = cursor;\n\n const result = await this.http.request<ApiListUsersResponse>(\n `${AUTH.listUsers}?${new URLSearchParams(params)}`,\n {\n method: 'GET',\n headers: { 'X-Api-Key': this.authKey, 'X-Session-Id': sessionId },\n },\n );\n return {\n users: result.data ?? [],\n hasMore: result.meta?.hasMore ?? result.hasMore ?? false,\n nextCursor: result.meta?.nextCursor ?? result.nextCursor ?? null,\n };\n }\n\n /**\n * Permanently delete a user (hard delete — cannot be undone).\n * Admin only. Charged at 1 HC per deletion.\n *\n * Server: DELETE /api/auth/user/hard?userId=:userId\n * Body: { sessionId }\n */\n async hardDeleteUser(sessionId: string, userId: string): Promise<void> {\n await this.http.request<ApiMessageResponse>(\n `${AUTH.hardDeleteUser}?userId=${encodeURIComponent(userId)}`,\n {\n method: 'DELETE',\n body: { sessionId },\n headers: { 'X-Api-Key': this.authKey },\n },\n );\n }\n\n /**\n * Delete multiple users at once (soft or hard). Admin only.\n *\n * Server: DELETE /api/auth/users/bulk\n * Body: { userIds, hard?, sessionId }\n */\n async bulkDeleteUsers(options: {\n sessionId: string;\n userIds: string[];\n hard?: boolean;\n }): Promise<{ succeeded: number; failed: number }> {\n const result = await this.http.request<ApiBulkDeleteResponse>(\n AUTH.bulkDeleteUsers,\n {\n method: 'DELETE',\n body: {\n userIds: options.userIds,\n hard: options.hard ?? false,\n sessionId: options.sessionId,\n },\n headers: { 'X-Api-Key': this.authKey },\n },\n );\n return { succeeded: result.meta.succeeded, failed: result.meta.failed };\n }\n\n /**\n * Lock a user account for a specified duration. Admin only.\n *\n * Server: POST /api/auth/account/lock\n * Body: { sessionId, userId, duration? } — duration in ms, default 15 min\n */\n async lockAccount(options: {\n sessionId: string;\n userId: string;\n duration?: number;\n }): Promise<{ lockedUntil: number; unlockTime: string }> {\n const result = await this.post<ApiLockResponse>(AUTH.accountLock, options);\n return result.data;\n }\n\n /**\n * Unlock a locked user account. Admin only.\n *\n * Server: POST /api/auth/account/unlock\n * Body: { sessionId, userId }\n */\n async unlockAccount(sessionId: string, userId: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.accountUnlock, { sessionId, userId });\n }\n\n // ─── Password Management ──────────────────────────────────────────────────\n\n /**\n * Change a user's password. Requires both a valid session AND the old password.\n *\n * Server: POST /api/auth/password/change\n * Body: { sessionId, userId, oldPassword, newPassword }\n */\n async changePassword(options: ChangePasswordOptions): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.passwordChange, {\n sessionId: options.sessionId,\n userId: options.userId,\n oldPassword: options.currentPassword, // server field is `oldPassword`\n newPassword: options.newPassword,\n });\n }\n\n /**\n * Request a password reset email.\n * Always returns success regardless of whether the email exists (prevents enumeration).\n *\n * Server: POST /api/auth/password/reset/request\n * Body: { email }\n */\n async requestPasswordReset(email: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.passwordResetRequest, { email });\n }\n\n /**\n * Confirm a password reset using the token from the reset email.\n *\n * Server: POST /api/auth/password/reset/confirm\n * Body: { resetToken, newPassword }\n */\n async confirmPasswordReset(resetToken: string, newPassword: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.passwordResetConfirm, { resetToken, newPassword });\n }\n\n // ─── Email Verification ───────────────────────────────────────────────────\n\n /**\n * Request a verification email be sent to a user.\n *\n * Server: POST /api/auth/email/verify/request\n * Body: { userId }\n */\n async requestEmailVerification(userId: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.emailVerifyRequest, { userId });\n }\n\n /**\n * Confirm email ownership using the token from the verification email.\n *\n * Server: POST /api/auth/email/verify/confirm\n * Body: { verifyToken }\n */\n async confirmEmailVerification(verifyToken: string): Promise<void> {\n await this.post<ApiMessageResponse>(AUTH.emailVerifyConfirm, { verifyToken });\n }\n\n // ─── Private helpers ──────────────────────────────────────────────────────\n\n private _buildAuthResult(\n user: UserRecord,\n session: { sessionId: string; refreshToken: string; expiresAt: number },\n isNew?: boolean,\n ): AuthResult {\n return {\n user,\n session: {\n sessionId: session.sessionId,\n userId: user.id,\n bucketId: '',\n createdAt: Date.now(),\n expiresAt: session.expiresAt,\n refreshToken: session.refreshToken,\n refreshExpiresAt: session.expiresAt,\n },\n isNew: isNew ?? false,\n };\n }\n}\n","import type { QueryFilter, QueryOptions } from '../types/index.js';\n\n/**\n * Build a query string from QueryOptions for GET /api/:bucket requests.\n *\n * The server reads filters from individual query params, NOT a JSON `filters` blob:\n * ?fieldName=value → field == value\n * ?fieldName[op]=value → field <op> value\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.order !== undefined) params.set('sortOrder', options.order);\n if (options.fields !== undefined) params.set('fields', options.fields);\n\n // sortBy / orderBy — both map to ?sortBy= on the server.\n // sortBy takes precedence if both are set.\n if (options.orderBy !== undefined) params.set('sortBy', options.orderBy);\n if (options.sortBy !== undefined) params.set('sortBy', options.sortBy); // overrides orderBy\n\n // Pagination cursors\n if (options.startAfter !== undefined) params.set('cursor', options.startAfter);\n if (options.startAt !== undefined) params.set('cursor', options.startAt);\n if (options.endAt !== undefined) params.set('endAt', options.endAt);\n\n // Time-scope shorthand — narrows results to a specific day, month, or year\n // using the record ID prefix convention (_day_YYMMDD | _month_YYMM | _year_YY).\n if (options.timeScope !== undefined) params.set('timeScope', options.timeScope);\n\n // Explicit ISO date strings — GCS day-range walk\n if (options.startDate !== undefined) params.set('startDate', options.startDate);\n if (options.endDate !== undefined) params.set('endDate', options.endDate);\n\n // dateRange (timestamp ms) — converted to ISO date strings.\n // Only applied if the explicit startDate/endDate fields are not already set.\n if (options.dateRange?.start !== undefined && options.startDate === undefined)\n params.set('startDate', new Date(options.dateRange.start).toISOString().split('T')[0]!);\n if (options.dateRange?.end !== undefined && options.endDate === undefined)\n params.set('endDate', new Date(options.dateRange.end).toISOString().split('T')[0]!);\n\n // Year — restricts the monthly walk to a specific two-digit year e.g. '26'\n if (options.year !== undefined) params.set('year', options.year);\n\n // Filters — server GET uses ?field=value and ?field[op]=value syntax\n if (options.filters && options.filters.length > 0) {\n for (const f of options.filters) {\n const key = f.op === '==' ? f.field : `${f.field}[${f.op}]`;\n params.set(key, String(f.value));\n }\n }\n\n const str = params.toString();\n return str ? `?${str}` : '';\n}\n\n/**\n * Normalise a filter shorthand into { 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 * Guess a MIME type from a file extension.\n */\nexport function guessMimeType(filename: string): string {\n const ext = filename.split('.').pop()?.toLowerCase();\n const map: Record<string, string> = {\n jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png',\n gif: 'image/gif', webp: 'image/webp', svg: 'image/svg+xml',\n pdf: 'application/pdf', mp4: 'video/mp4', webm: 'video/webm',\n mp3: 'audio/mpeg', wav: 'audio/wav', txt: 'text/plain',\n html: 'text/html', css: 'text/css', js: 'application/javascript',\n ts: 'application/typescript',\n json: 'application/json', xml: 'application/xml',\n zip: 'application/zip', csv: 'text/csv',\n xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n };\n return map[ext ?? ''] ?? 'application/octet-stream';\n}\n\n/**\n * Assert that a name is safe for use in API paths.\n * Must start with a letter or underscore and contain only letters,\n * numbers, underscores, dots, or hyphens (max 200 chars after the first).\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 ` +\n `contain only letters, numbers, underscores, dots, or hyphens.`,\n );\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport { buildQueryParams, assertSafeName } from '../utils/query.js';\nimport { RECORDS } from '../routes.js';\nimport type {\n RecordData,\n RecordResult,\n QueryOptions,\n QueryResult,\n PatchRecordOptions,\n RecordHistoryEntry,\n CreateRecordOptions,\n BatchCreateOptions,\n} from '../types/index.js';\n\n// ─── Internal response shapes ─────────────────────────────────────────────────\n\ninterface ApiRecordResponse<T> {\n success: boolean;\n data?: T & RecordResult;\n upserted?: boolean;\n meta?: { id: string; custom?: boolean; updatedAt?: number };\n}\n\ninterface ApiQueryResponse<T> {\n success: boolean;\n data?: (T & RecordResult)[];\n meta?: { hasMore: boolean; nextCursor?: string | null; total?: number };\n hasMore?: boolean;\n nextCursor?: string | null;\n total?: number;\n}\n\ninterface ApiBatchCreateResponse<T> {\n success: boolean;\n data?: (T & RecordResult)[];\n meta?: { totalProcessed: number; successful: number; failed: number };\n errors?: unknown[];\n}\n\ninterface ApiBatchDeleteResponse {\n success: boolean;\n data?: { successful: number; failed: string[] };\n meta?: { count: number };\n}\n\ninterface ApiHistoryResponse {\n success: boolean;\n history?: RecordHistoryEntry[];\n}\n\ninterface ApiBatchUpdateResponse {\n success: boolean;\n data?: { successful: number; failed: string[] };\n meta?: { count: number };\n}\n\ninterface ApiExistsResponse {\n success: boolean;\n exists: boolean;\n}\n\n/**\n * RecordsClient — typed CRUD + batch + query for a single bucket.\n *\n * All requests use `X-Api-Key: <bucketSecurityKey>`.\n * Routes: GET|POST|PATCH|DELETE /api/:bucketKey\n *\n * @example\n * ```ts\n * interface Post { title: string; published: boolean }\n * const posts = db.records<Post>('blog-posts');\n * const post = await posts.create({ title: 'Hello', published: false });\n * ```\n */\nexport class RecordsClient<T extends RecordData = RecordData> {\n private readonly http: HttpClient;\n private readonly bucketKey: string;\n private readonly apiKey: string;\n\n constructor(http: HttpClient, bucketSecurityKey: string, bucketKey: string) {\n assertSafeName(bucketKey, 'bucketKey');\n this.http = http;\n this.bucketKey = bucketKey;\n this.apiKey = bucketSecurityKey;\n }\n\n // ─── Single Record Operations ─────────────────────────────────────────────\n\n /**\n * Create a new record (auto-generated ID) or upsert by `customRecordId`.\n *\n * Server: POST /api/:bucketKey\n * Body: { values, queryableFields?, userEmail?, customRecordId? }\n * Returns 201 for new records, 200 for upserts.\n *\n * @example\n * ```ts\n * const post = await posts.create(\n * { title: 'Hello', status: 'draft', authorId: 'u1' },\n * { queryableFields: ['status', 'authorId'], userEmail: 'alice@example.com' },\n * );\n * ```\n */\n async create(data: T, options: CreateRecordOptions = {}): Promise<T & RecordResult> {\n const { queryableFields, userEmail, customRecordId } = options;\n const body: Record<string, unknown> = { values: data };\n if (queryableFields?.length) body['queryableFields'] = queryableFields;\n if (userEmail) body['userEmail'] = userEmail;\n if (customRecordId) body['customRecordId'] = customRecordId;\n\n const result = await this.http.post<ApiRecordResponse<T>>(\n RECORDS.bucket(this.bucketKey),\n this.apiKey,\n body,\n );\n return result.data!;\n }\n\n /**\n * Get a single record by ID.\n *\n * Server: GET /api/:bucketKey?recordId=:id\n */\n async get(id: string): Promise<T & RecordResult> {\n const result = await this.http.get<ApiRecordResponse<T>>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}`,\n this.apiKey,\n );\n return result.data!;\n }\n\n /**\n * Partially update an existing record (PATCH semantics).\n * Supports write-filter sentinels: `{ __op: 'increment', delta: 1 }` etc.\n *\n * Server: PATCH /api/:bucketKey\n * Body: { recordId, values, userEmail?, track_record_history? }\n */\n async patch(\n id: string,\n data: Partial<T>,\n options: PatchRecordOptions & { userEmail?: string; trackHistory?: boolean } = {},\n ): Promise<{ id: string; updatedAt?: number }> {\n const { userEmail, trackHistory } = options;\n const body: Record<string, unknown> = { recordId: id, values: data };\n if (userEmail) body['userEmail'] = userEmail;\n if (trackHistory) body['track_record_history'] = true;\n\n const result = await this.http.patch<ApiRecordResponse<T>>(\n RECORDS.bucket(this.bucketKey),\n this.apiKey,\n body,\n );\n return { id: result.meta?.id ?? id, updatedAt: result.meta?.updatedAt };\n }\n\n /**\n * Delete a record permanently.\n *\n * Server: DELETE /api/:bucketKey?recordId=:id\n */\n async delete(id: string): Promise<void> {\n await this.http.delete<{ success: boolean }>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}`,\n this.apiKey,\n );\n }\n\n /**\n * Check whether a record exists (HEAD request — very lightweight).\n *\n * Server: HEAD /api/:bucketKey?recordId=:id\n * Returns true if the record exists, false if 404.\n */\n async exists(id: string): Promise<boolean> {\n try {\n await this.http.request<void>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}`,\n { method: 'HEAD', headers: { 'X-Api-Key': this.apiKey } },\n );\n return true;\n } catch (err: unknown) {\n if (err && typeof err === 'object' && 'status' in err && (err as { status: number }).status === 404) return false;\n throw err;\n }\n }\n\n /**\n * Get a historical snapshot of a record at a specific generation.\n *\n * Server: GET /api/:bucketKey?recordId=:id&generation=:gen\n */\n async getVersion(id: string, generation: string | number): Promise<T & RecordResult> {\n const result = await this.http.get<ApiRecordResponse<T>>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}&generation=${encodeURIComponent(String(generation))}`,\n this.apiKey,\n );\n return result.data!;\n }\n\n /**\n * Get the version history of a record.\n *\n * Server: GET /api/:bucketKey?recordId=:id&showHistory=true\n */\n async getHistory(id: string): Promise<RecordHistoryEntry[]> {\n const result = await this.http.get<ApiHistoryResponse>(\n `${RECORDS.bucket(this.bucketKey)}?recordId=${encodeURIComponent(id)}&showHistory=true`,\n this.apiKey,\n );\n return result.history ?? [];\n }\n\n // ─── Batch Operations ─────────────────────────────────────────────────────\n\n /**\n * Create up to 500 records in one request.\n * Each record may include `_customRecordId` for upsert behaviour.\n *\n * Server: POST /api/:bucketKey/batch/insert\n * Body: { records, queryableFields?, userEmail? }\n *\n * @example\n * ```ts\n * const results = await posts.batchCreate(\n * [{ title: 'A' }, { title: 'B' }],\n * { queryableFields: ['title'] },\n * );\n * ```\n */\n async batchCreate(\n items: T[],\n options: BatchCreateOptions = {},\n ): Promise<{ results: (T & RecordResult)[]; errors: unknown[]; successful: number; failed: number }> {\n const { queryableFields, userEmail } = options;\n const body: Record<string, unknown> = { records: items };\n if (queryableFields?.length) body['queryableFields'] = queryableFields;\n if (userEmail) body['userEmail'] = userEmail;\n\n const result = await this.http.post<ApiBatchCreateResponse<T>>(\n RECORDS.batchInsert(this.bucketKey),\n this.apiKey,\n body,\n );\n return {\n results: result.data ?? [],\n errors: result.errors ?? [],\n successful: result.meta?.successful ?? (result.data?.length ?? 0),\n failed: result.meta?.failed ?? 0,\n };\n }\n\n /**\n * Update up to 500 records in one request.\n *\n * Server: POST /api/:bucketKey/batch/update\n * Body: { updates: [{ recordId, values }], userEmail? }\n */\n async batchUpdate(\n updates: Array<{ recordId: string; values: Partial<T> }>,\n userEmail?: string,\n ): Promise<{ successful: number; failed: string[] }> {\n const body: Record<string, unknown> = { updates };\n if (userEmail) body['userEmail'] = userEmail;\n\n const result = await this.http.post<ApiBatchUpdateResponse>(\n RECORDS.batchUpdate(this.bucketKey),\n this.apiKey,\n body,\n );\n return {\n successful: result.data?.successful ?? result.meta?.count ?? 0,\n failed: result.data?.failed ?? [],\n };\n }\n\n /**\n * Delete up to 500 records in one request.\n *\n * Server: POST /api/:bucketKey/batch/delete\n * Body: { recordIds, userEmail? }\n */\n async batchDelete(\n ids: string[],\n userEmail?: string,\n ): Promise<{ successful: number; failed: string[] }> {\n const body: Record<string, unknown> = { recordIds: ids };\n if (userEmail) body['userEmail'] = userEmail;\n\n const result = await this.http.post<ApiBatchDeleteResponse>(\n RECORDS.batchDelete(this.bucketKey),\n this.apiKey,\n body,\n );\n return {\n successful: result.data?.successful ?? result.meta?.count ?? 0,\n failed: result.data?.failed ?? [],\n };\n }\n\n // ─── Querying ─────────────────────────────────────────────────────────────\n\n /**\n * Query records with filters, sorting, and cursor-based pagination.\n *\n * Server: GET /api/:bucketKey?field=value&field[op]=value&limit=&sortBy=&sortOrder=&cursor=\n *\n * @example\n * ```ts\n * const { records, hasMore, nextCursor } = await posts.query({\n * filters: [{ field: 'status', op: '==', value: 'published' }],\n * orderBy: 'createdAt',\n * order: 'desc',\n * limit: 20,\n * });\n * ```\n */\n async query(options: QueryOptions = {}): Promise<QueryResult<T>> {\n const qs = buildQueryParams(options);\n const result = await this.http.get<ApiQueryResponse<T>>(\n `${RECORDS.bucket(this.bucketKey)}${qs}`,\n this.apiKey,\n );\n return {\n records: result.data ?? [],\n total: result.meta?.total ?? result.total,\n hasMore: result.meta?.hasMore ?? result.hasMore ?? false,\n nextCursor: result.meta?.nextCursor ?? result.nextCursor ?? undefined,\n };\n }\n\n /**\n * Retrieve all records matching options (no filter support — use `query()` for filters).\n */\n async getAll(options: Omit<QueryOptions, 'filters'> = {}): Promise<(T & RecordResult)[]> {\n const { records } = await this.query(options);\n return records;\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport { assertSafeName } from '../utils/query.js';\nimport { ANALYTICS } from '../routes.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 — BigQuery-powered aggregations for a single bucket.\n *\n * All methods POST a `queryType` body to `POST /api/analytics/:bucketKey`.\n * The `dateRange` is passed as `{ start, end }` ms timestamps — the server\n * converts them to ISO date strings internally.\n * Uses `X-Api-Key: <bucketSecurityKey>`.\n *\n * @example\n * ```ts\n * const analytics = db.analytics('orders');\n * const { count } = await analytics.count();\n * const top5 = await analytics.topN({ field: 'country', n: 5 });\n * ```\n */\nexport class AnalyticsClient {\n private readonly http: HttpClient;\n private readonly bucketSecurityKey: string;\n private readonly bucketKey: string;\n\n constructor(http: HttpClient, bucketSecurityKey: string, bucketKey: string) {\n assertSafeName(bucketKey, 'bucketKey');\n this.http = http;\n this.bucketSecurityKey = bucketSecurityKey;\n this.bucketKey = bucketKey;\n }\n\n private async run<T>(query: AnalyticsQuery): Promise<T> {\n const result = await this.http.post<ApiAnalyticsResult<T>>(\n ANALYTICS.query(this.bucketKey),\n this.bucketSecurityKey,\n query,\n );\n return result.data;\n }\n\n // ─── Query methods ────────────────────────────────────────────────────────\n\n /** Count all records, optionally within a date range. */\n async count(opts: { dateRange?: DateRange } = {}): Promise<CountResult> {\n return this.run<CountResult>({ queryType: 'count', ...opts });\n }\n\n /**\n * Get value distribution for a field (e.g. records per status).\n * `order` maps to `sortBy` on the wire (the server param name).\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 a numeric field, optionally grouped by another field. */\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 /** Count of records over time, bucketed by granularity. */\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 /** Aggregate a numeric field over time. */\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 values for a field by count. */\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 /** Statistical summary (min, max, avg, sum, count, stddev) for a numeric field. */\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 /**\n * Fetch filtered records via the analytics engine (BigQuery).\n * Bypasses Firestore pagination — useful for large result sets.\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 /**\n * Compute multiple aggregations in a single request.\n * `metrics` must have valid `field` and `name` (used as BigQuery column aliases).\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 usage stats for the bucket (record count, bytes, avg/min/max size). */\n async storageStats(opts: { dateRange?: DateRange } = {}): Promise<StorageStatsResult> {\n return this.run<StorageStatsResult>({ queryType: 'storageStats', ...opts });\n }\n\n /**\n * Compare a metric across multiple buckets in one query.\n * The caller's key must have read access to EVERY bucket in `bucketKeys`.\n * System buckets (`users`, `_sys_*`) are blocked server-side.\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 /**\n * Raw query — escape hatch when the typed helpers don't cover your case.\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 { STORAGE } from '../routes.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 BatchDownloadResult,\n} from '../types/index.js';\n\n// ─── Internal response shapes ─────────────────────────────────────────────────\n\ninterface ApiUploadResult {\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 ApiUploadUrlResult {\n uploadUrl: string;\n path: string;\n mimeType: string;\n isPublic: boolean;\n size: number;\n expiresAt: string;\n expiresIn: number;\n}\n\ninterface ApiListResult {\n success: boolean;\n items?: FileEntry[];\n pagination?: { hasMore: boolean; nextCursor?: string | null };\n files?: FileEntry[];\n folders?: string[];\n hasMore?: boolean;\n nextCursor?: string | null;\n}\n\ninterface ApiMetadataResult {\n success: boolean;\n path: string;\n name: 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\ninterface ApiBatchUploadUrlResult {\n succeeded: Array<ApiUploadUrlResult & { index: number }>;\n failed: Array<{ index: number; path: string; error: string; code?: string }>;\n}\n\ninterface ApiBatchConfirmResult {\n success: boolean;\n succeeded: ApiUploadResult[];\n failed: Array<{ path: string; error: string; code?: string }>;\n}\n\ninterface ApiBatchDownloadResult {\n success: boolean;\n succeeded: Array<{\n index: number;\n path: string;\n mimeType: string;\n size: number;\n isPublic: boolean;\n content: string; // base64\n }>;\n failed: Array<{ index: number; path: string; error: string; code?: string }>;\n}\n\nfunction toUploadResult(r: ApiUploadResult): UploadResult {\n return {\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/**\n * StorageManager — upload, download, list, move, copy, and delete files.\n *\n * Uses `X-Storage-Key: <ssk_…>` header — separate from auth and bucket keys.\n * Files are scoped server-side to `hydrous-storage/{ownerId}/{userPath}`.\n * You only ever deal with your own `userPath` — the server handles scoping.\n *\n * Get a StorageManager via `db.storage('keyName')` where the name matches\n * one of the keys defined in `storageKeys` when calling `createClient`.\n *\n * @example\n * ```ts\n * const storage = db.storage('avatars');\n * const result = await storage.upload(file, 'alice.jpg', { isPublic: true });\n * console.log(result.publicUrl);\n * ```\n */\nexport class StorageManager {\n private readonly http: HttpClient;\n private readonly storageKey: string;\n\n constructor(http: HttpClient, storageKey: string) {\n this.http = http;\n this.storageKey = storageKey;\n }\n\n private get authHeaders(): Record<string, string> {\n return { 'X-Storage-Key': this.storageKey };\n }\n\n // ─── Upload: Server-buffered ──────────────────────────────────────────────\n\n /**\n * Upload a file in one step (server-buffered, up to 500 MB).\n * For files >10 MB or when upload progress tracking is needed, use the\n * signed URL flow: `getUploadUrl()` → `uploadToSignedUrl()` → `confirmUpload()`.\n *\n * Server: POST /storage/upload (multipart/form-data)\n *\n * @example\n * ```ts\n * const result = await storage.upload(file, 'avatars/alice.jpg', { isPublic: true });\n * console.log(result.publicUrl);\n * ```\n */\n async upload(\n data: Blob | Uint8Array | 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<ApiUploadResult>(STORAGE.upload, {\n method: 'POST',\n rawBody: formData,\n headers: this.authHeaders,\n });\n return toUploadResult(result);\n }\n\n /**\n * Upload raw string or JSON data directly as a file.\n *\n * Server: POST /storage/upload-raw\n * Body: { path, content, mimeType?, isPublic?, overwrite? }\n *\n * @example\n * ```ts\n * await storage.uploadRaw({ theme: 'dark' }, 'settings/config.json');\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 // Server field is `content`, not `data`\n const content = typeof data === 'string' ? data : JSON.stringify(data);\n\n const result = await this.http.request<ApiUploadResult>(STORAGE.uploadRaw, {\n method: 'POST',\n body: { path, content, mimeType, isPublic, overwrite },\n headers: this.authHeaders,\n });\n return toUploadResult(result);\n }\n\n // ─── Upload: Direct-to-GCS (recommended for large files / progress) ───────\n\n /**\n * Step 1 — get a signed GCS PUT URL for direct client-to-GCS upload.\n *\n * Server: POST /storage/upload-url\n * Body: { path, mimeType, size, isPublic?, overwrite?, expiresIn? }\n *\n * @example\n * ```ts\n * const { uploadUrl, path: p } = await storage.getUploadUrl({\n * path: 'videos/intro.mp4', mimeType: 'video/mp4', size: file.size,\n * });\n * await storage.uploadToSignedUrl(uploadUrl, file, 'video/mp4', pct => setProgress(pct));\n * const result = await storage.confirmUpload({ path: p, mimeType: 'video/mp4' });\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 { expiresInSeconds, ...rest } = opts;\n // Server reads `expiresIn` in seconds (not `expiresInSeconds`)\n const result = await this.http.request<ApiUploadUrlResult>(STORAGE.uploadUrl, {\n method: 'POST',\n body: { isPublic: false, overwrite: false, expiresIn: expiresInSeconds ?? 900, ...rest },\n headers: this.authHeaders,\n });\n return {\n uploadUrl: result.uploadUrl,\n path: result.path,\n mimeType: result.mimeType,\n expiresAt: result.expiresAt,\n expiresIn: result.expiresIn,\n };\n }\n\n /**\n * Step 2 — upload data directly to the signed GCS URL.\n * Supports progress tracking in browser environments via XHR.\n */\n async uploadToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array | 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 — confirm a direct upload and register metadata server-side.\n *\n * Server: POST /storage/confirm\n * Body: { path, mimeType, isPublic? }\n */\n async confirmUpload(opts: {\n path: string;\n mimeType: string;\n isPublic?: boolean;\n }): Promise<UploadResult> {\n const result = await this.http.request<ApiUploadResult>(STORAGE.confirm, {\n method: 'POST',\n body: { isPublic: false, ...opts },\n headers: this.authHeaders,\n });\n return toUploadResult(result);\n }\n\n // ─── Batch Upload ─────────────────────────────────────────────────────────\n\n /**\n * Get signed upload URLs for up to 50 files at once.\n *\n * Server: POST /storage/batch-upload-urls\n * Body: { files: [...], expiresIn? }\n */\n async getBatchUploadUrls(files: BatchUploadItem[]): Promise<BatchUploadUrlResult> {\n const result = await this.http.request<ApiBatchUploadUrlResult>(STORAGE.batchUploadUrls, {\n method: 'POST',\n body: { files },\n headers: this.authHeaders,\n });\n return {\n files: result.succeeded.map(f => ({\n index: f.index,\n uploadUrl: f.uploadUrl,\n path: f.path,\n mimeType: f.mimeType,\n expiresAt: f.expiresAt,\n expiresIn: f.expiresIn,\n })),\n };\n }\n\n /**\n * Confirm multiple direct uploads at once.\n *\n * Server: POST /storage/batch-confirm\n * Body: { files: [{ path, mimeType, isPublic? }] }\n */\n async batchConfirmUploads(\n items: Array<{ path: string; mimeType: string; isPublic?: boolean }>,\n ): Promise<{ succeeded: UploadResult[]; failed: Array<{ path: string; error: string }> }> {\n const result = await this.http.request<ApiBatchConfirmResult>(STORAGE.batchConfirm, {\n method: 'POST',\n body: { files: items },\n headers: this.authHeaders,\n });\n return {\n succeeded: result.succeeded.map(toUploadResult),\n failed: result.failed,\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 * Server: GET /storage/download/:path (requires X-Storage-Key)\n */\n async download(path: string): Promise<ArrayBuffer> {\n const encoded = path.split('/').map(encodeURIComponent).join('/');\n return this.http.request<ArrayBuffer>(STORAGE.download(encoded), {\n method: 'GET',\n headers: this.authHeaders,\n });\n }\n\n /**\n * Download up to 20 files at once. Returns base64-encoded content.\n *\n * Server: POST /storage/batch-download\n * Body: { paths, concurrency? }\n */\n async batchDownload(paths: string[], concurrency = 5): Promise<BatchDownloadResult> {\n const result = await this.http.request<ApiBatchDownloadResult>(STORAGE.batchDownload, {\n method: 'POST',\n body: { paths, concurrency },\n headers: this.authHeaders,\n });\n return {\n succeeded: result.succeeded.map(f => ({\n index: f.index,\n path: f.path,\n mimeType: f.mimeType,\n size: f.size,\n content: f.content,\n })),\n failed: result.failed.map(f => ({\n index: f.index,\n path: f.path,\n error: f.error,\n code: f.code,\n })),\n };\n }\n\n // ─── List ─────────────────────────────────────────────────────────────────\n\n /**\n * List files and folders at a given path prefix.\n *\n * Server: GET /storage/list?prefix=&limit=&cursor=\n *\n * @example\n * ```ts\n * const { files, folders, hasMore, nextCursor } = await storage.list({ prefix: 'avatars/', limit: 20 });\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 const qs = params.toString() ? `?${params}` : '';\n\n const result = await this.http.request<ApiListResult>(`${STORAGE.list}${qs}`, {\n method: 'GET',\n headers: this.authHeaders,\n });\n\n // Server returns { items: [...], pagination: { hasMore, nextCursor } }\n if (result.items !== undefined) {\n const files: FileEntry[] = [];\n const folders: string[] = [];\n for (const item of result.items) {\n if (item.type === 'folder') folders.push(item.path);\n else files.push(item);\n }\n return {\n files,\n folders,\n hasMore: result.pagination?.hasMore ?? false,\n nextCursor: result.pagination?.nextCursor ?? undefined,\n };\n }\n\n return {\n files: result.files ?? [],\n folders: result.folders ?? [],\n hasMore: result.hasMore ?? false,\n nextCursor: result.nextCursor ?? undefined,\n };\n }\n\n // ─── Metadata ─────────────────────────────────────────────────────────────\n\n /**\n * Get file metadata: size, MIME type, visibility, URLs.\n *\n * Server: GET /storage/metadata/:path\n */\n async getMetadata(path: string): Promise<FileMetadata> {\n const encoded = path.split('/').map(encodeURIComponent).join('/');\n const result = await this.http.request<ApiMetadataResult>(STORAGE.metadata(encoded), {\n method: 'GET',\n 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 ───────────────────────────────────────────────────────────\n\n /**\n * Generate a time-limited download URL for a private file.\n * Can be shared externally — no X-Storage-Key required to access.\n *\n * Note: Downloads via signed URLs bypass the server — stats are NOT tracked.\n *\n * Server: POST /storage/signed-url\n * Body: { path, expiresIn? }\n *\n * @param path File path.\n * @param expiresIn URL lifetime in seconds (default 3600 = 1 hour).\n */\n async getSignedUrl(path: string, expiresIn = 3600): Promise<SignedUrlResult> {\n const result = await this.http.request<ApiSignedUrlResult>(STORAGE.signedUrl, {\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.\n *\n * Server: PATCH /storage/visibility\n * Body: { path, isPublic }\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>(STORAGE.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 (empty GCS object used as a prefix marker).\n *\n * Server: POST /storage/folder\n * Body: { path }\n */\n async createFolder(path: string): Promise<{ path: string }> {\n const result = await this.http.request<{ success: boolean; path: string }>(STORAGE.folder, {\n method: 'POST',\n body: { path },\n headers: this.authHeaders,\n });\n return { path: result.path };\n }\n\n // ─── File Operations ──────────────────────────────────────────────────────\n\n /**\n * Permanently delete a file.\n *\n * Server: DELETE /storage/file\n * Body: { path }\n */\n async deleteFile(path: string): Promise<void> {\n await this.http.request<{ success: boolean }>(STORAGE.file, {\n method: 'DELETE',\n body: { path },\n headers: this.authHeaders,\n });\n }\n\n /**\n * Recursively delete a folder and all its contents.\n *\n * Server: DELETE /storage/folder\n * Body: { path }\n */\n async deleteFolder(path: string): Promise<void> {\n await this.http.request<{ success: boolean }>(STORAGE.folderDelete, {\n method: 'DELETE',\n body: { path },\n headers: this.authHeaders,\n });\n }\n\n /**\n * Move (rename) a file.\n *\n * Server: POST /storage/move\n * Body: { from, to }\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 }>(STORAGE.move, {\n method: 'POST',\n body: { from, to },\n 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 * Server: POST /storage/copy\n * Body: { from, to }\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 }>(STORAGE.copy, {\n method: 'POST',\n body: { from, to },\n headers: this.authHeaders,\n });\n return { from: result.from, to: result.to };\n }\n\n // ─── Stats ────────────────────────────────────────────────────────────────\n\n /**\n * Get usage statistics for this storage key.\n *\n * Server: GET /storage/stats\n */\n async getStats(): Promise<StorageStats> {\n const result = await this.http.request<ApiStatsResult>(STORAGE.stats, {\n method: 'GET',\n headers: this.authHeaders,\n });\n return result.stats;\n }\n\n /**\n * Get server info (no auth required).\n *\n * Server: GET /storage/info\n */\n async info(): Promise<{ ok: boolean; storageRoot: string }> {\n return this.http.request<{ ok: boolean; storageRoot: string }>(STORAGE.info, {\n method: 'GET',\n });\n }\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 StorageStats,\n BatchUploadItem,\n BatchUploadUrlResult,\n BatchDownloadResult,\n} from '../types/index.js';\n\n/**\n * ScopedStorage — a path-prefixed view over a StorageManager.\n *\n * Every path you pass is automatically prefixed with the scope.\n * Obtain via `db.storage('keyName').scope('prefix/')`.\n *\n * @example\n * ```ts\n * const userDocs = db.storage('documents').scope(`users/${userId}/`);\n *\n * // Uploads to: users/{userId}/contract.pdf\n * await userDocs.upload(pdfBuffer, 'contract.pdf');\n *\n * // Lists: users/{userId}/\n * const { files } = await userDocs.list();\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 // Ensure exactly one trailing slash\n this.prefix = prefix.endsWith('/') ? prefix : `${prefix}/`;\n }\n\n private p(path: string): string {\n return `${this.prefix}${path.replace(/^\\/+/, '')}`;\n }\n\n // ─── Upload ───────────────────────────────────────────────────────────────\n\n async upload(\n data: Blob | Uint8Array | ArrayBuffer | Buffer,\n path: string,\n options: UploadOptions = {},\n ): Promise<UploadResult> {\n return this.manager.upload(data, this.p(path), options);\n }\n\n async uploadRaw(\n data: unknown,\n path: string,\n options: UploadOptions = {},\n ): Promise<UploadResult> {\n return this.manager.uploadRaw(data, this.p(path), options);\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 return this.manager.getUploadUrl({ ...opts, path: this.p(opts.path) });\n }\n\n async uploadToSignedUrl(\n signedUrl: string,\n data: Blob | Uint8Array | ArrayBuffer,\n mimeType: string,\n onProgress?: (percent: number) => void,\n ): Promise<void> {\n return this.manager.uploadToSignedUrl(signedUrl, data, mimeType, onProgress);\n }\n\n async confirmUpload(opts: {\n path: string;\n mimeType: string;\n isPublic?: boolean;\n }): Promise<UploadResult> {\n return this.manager.confirmUpload({ ...opts, path: this.p(opts.path) });\n }\n\n async getBatchUploadUrls(files: BatchUploadItem[]): Promise<BatchUploadUrlResult> {\n return this.manager.getBatchUploadUrls(\n files.map(f => ({ ...f, path: this.p(f.path) })),\n );\n }\n\n async batchConfirmUploads(\n items: Array<{ path: string; mimeType: string; isPublic?: boolean }>,\n ): Promise<{ succeeded: UploadResult[]; failed: Array<{ path: string; error: string }> }> {\n return this.manager.batchConfirmUploads(\n items.map(i => ({ ...i, path: this.p(i.path) })),\n );\n }\n\n // ─── Download ─────────────────────────────────────────────────────────────\n\n async download(path: string): Promise<ArrayBuffer> {\n return this.manager.download(this.p(path));\n }\n\n async batchDownload(paths: string[]): Promise<BatchDownloadResult> {\n return this.manager.batchDownload(paths.map(p => this.p(p)));\n }\n\n // ─── List ─────────────────────────────────────────────────────────────────\n\n /**\n * List files within this scope.\n * The `prefix` option is relative to the scope root.\n *\n * @example\n * ```ts\n * const userDocs = storage.scope('users/alice/');\n * // Lists users/alice/docs/\n * const { files } = await userDocs.list({ prefix: 'docs/' });\n * ```\n */\n async list(opts: ListOptions = {}): Promise<ListResult> {\n return this.manager.list({\n ...opts,\n prefix: this.p(opts.prefix ?? ''),\n });\n }\n\n // ─── Metadata & URLs ──────────────────────────────────────────────────────\n\n async getMetadata(path: string): Promise<FileMetadata> {\n return this.manager.getMetadata(this.p(path));\n }\n\n async getSignedUrl(path: string, expiresIn = 3600): Promise<SignedUrlResult> {\n return this.manager.getSignedUrl(this.p(path), expiresIn);\n }\n\n async 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.p(path), isPublic);\n }\n\n // ─── Folder Operations ────────────────────────────────────────────────────\n\n async createFolder(path: string): Promise<{ path: string }> {\n return this.manager.createFolder(this.p(path));\n }\n\n // ─── File Operations ──────────────────────────────────────────────────────\n\n async deleteFile(path: string): Promise<void> {\n return this.manager.deleteFile(this.p(path));\n }\n\n async deleteFolder(path: string): Promise<void> {\n return this.manager.deleteFolder(this.p(path));\n }\n\n async move(from: string, to: string): Promise<{ from: string; to: string }> {\n return this.manager.move(this.p(from), this.p(to));\n }\n\n async copy(from: string, to: string): Promise<{ from: string; to: string }> {\n return this.manager.copy(this.p(from), this.p(to));\n }\n\n // ─── Stats ────────────────────────────────────────────────────────────────\n\n async getStats(): Promise<StorageStats> {\n return this.manager.getStats();\n }\n\n // ─── Nesting ──────────────────────────────────────────────────────────────\n\n /**\n * Create a deeper scope within this one.\n *\n * @example\n * ```ts\n * const user = storage.scope('users/alice/');\n * const userDocs = user.scope('docs/');\n * // Effective prefix: users/alice/docs/\n * ```\n */\n scope(subPrefix: string): ScopedStorage {\n return new ScopedStorage(this.manager, this.p(subPrefix));\n }\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\nexport class HydrousClient {\n private readonly http: HttpClient;\n private readonly authKey_: string;\n private readonly bucketSecurityKey_: string;\n private readonly storageKeys_: Record<string, string>;\n\n private readonly _recordsCache = new Map<string, RecordsClient<RecordData>>();\n private readonly _analyticsCache = new Map<string, AnalyticsClient>();\n private readonly _storageCache = new Map<string, StorageManager>();\n private _authClient?: AuthClient;\n\n constructor(config: HydrousConfig) {\n if (!config.authKey) {\n throw new Error('[HydrousDB] authKey is required.');\n }\n if (!config.bucketSecurityKey) {\n throw new Error('[HydrousDB] bucketSecurityKey is required.');\n }\n if (!config.storageKeys || Object.keys(config.storageKeys).length === 0) {\n throw new Error('[HydrousDB] storageKeys must define at least one key.');\n }\n\n // The baseUrl should point to the server root (no /api suffix).\n // All route paths in routes.ts are fully qualified: /api/..., /storage/...\n this.http = new HttpClient(config.baseUrl ?? DEFAULT_BASE_URL);\n this.authKey_ = config.authKey;\n this.bucketSecurityKey_ = config.bucketSecurityKey;\n this.storageKeys_ = config.storageKeys;\n }\n\n // ─── Records ──────────────────────────────────────────────────────────────\n\n /**\n * Get a typed RecordsClient for a bucket.\n *\n * @example\n * ```ts\n * interface Post { title: string; published: boolean }\n * const posts = db.records<Post>('blog-posts');\n * const post = await posts.create({ title: 'Hello', published: false });\n * ```\n */\n records<T extends RecordData = RecordData>(bucketKey: string): RecordsClient<T> {\n if (!this._recordsCache.has(bucketKey)) {\n this._recordsCache.set(\n bucketKey,\n new RecordsClient<T>(this.http, this.bucketSecurityKey_, bucketKey) as RecordsClient<RecordData>,\n );\n }\n return this._recordsCache.get(bucketKey) as RecordsClient<T>;\n }\n\n // ─── Auth ─────────────────────────────────────────────────────────────────\n\n /**\n * Get the AuthClient.\n * Auth routes are NOT bucket-scoped in the URL — the bucket is determined\n * server-side from the API key itself.\n *\n * @example\n * ```ts\n * const { user, session } = await db.auth().signup({ email: 'alice@example.com', password: 'pw' });\n * ```\n */\n auth(): AuthClient {\n if (!this._authClient) {\n this._authClient = new AuthClient(this.http, this.authKey_);\n }\n return this._authClient;\n }\n\n // ─── Analytics ────────────────────────────────────────────────────────────\n\n /**\n * Get an AnalyticsClient for a bucket.\n *\n * @example\n * ```ts\n * const { count } = await db.analytics('orders').count();\n * ```\n */\n analytics(bucketKey: string): AnalyticsClient {\n if (!this._analyticsCache.has(bucketKey)) {\n this._analyticsCache.set(\n bucketKey,\n new AnalyticsClient(this.http, this.bucketSecurityKey_, bucketKey),\n );\n }\n return this._analyticsCache.get(bucketKey)!;\n }\n\n // ─── Storage ──────────────────────────────────────────────────────────────\n\n /**\n * Get a StorageManager for a named storage key.\n * The name must match a key in the `storageKeys` config object.\n *\n * Attach `.scope('prefix/')` to get a path-prefixed ScopedStorage.\n *\n * @example\n * ```ts\n * const avatars = db.storage('avatars');\n * const result = await avatars.upload(file, 'alice.jpg', { isPublic: true });\n *\n * // Scoped:\n * const userFiles = db.storage('documents').scope(`users/${userId}/`);\n * await userFiles.upload(pdf, 'contract.pdf');\n * ```\n */\n storage(keyName: string): StorageManager & { scope: (prefix: string) => ScopedStorage } {\n const ssk = this.storageKeys_[keyName];\n if (!ssk) {\n const available = Object.keys(this.storageKeys_).join(', ');\n throw new Error(\n `[HydrousDB] Unknown storage key name \"${keyName}\". ` +\n `Available keys: ${available}. ` +\n `Add it to storageKeys in your createClient() config.`,\n );\n }\n\n if (!this._storageCache.has(keyName)) {\n this._storageCache.set(keyName, new StorageManager(this.http, ssk));\n }\n\n const mgr = this._storageCache.get(keyName)!;\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 ──────────────────────────────────────────────────────────────────\n\n/**\n * Create a HydrousDB client.\n *\n * @example\n * ```ts\n * import { createClient } from 'hydrous-sdk';\n *\n * const db = createClient({\n * authKey: 'hk_auth_…',\n * bucketSecurityKey: 'hk_bucket_…',\n * storageKeys: { avatars: 'ssk_…' },\n * });\n * ```\n */\nexport function createClient(config: HydrousConfig): HydrousClient {\n return new HydrousClient(config);\n}\n"]}