hydrousdb 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +686 -0
- package/dist/analytics/index.d.mts +178 -0
- package/dist/analytics/index.d.ts +178 -0
- package/dist/analytics/index.js +221 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/index.mjs +219 -0
- package/dist/analytics/index.mjs.map +1 -0
- package/dist/auth/index.d.mts +180 -0
- package/dist/auth/index.d.ts +180 -0
- package/dist/auth/index.js +220 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +218 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/http-CIXLF5GV.d.mts +466 -0
- package/dist/http-CIXLF5GV.d.ts +466 -0
- package/dist/index.d.mts +73 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.js +810 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +801 -0
- package/dist/index.mjs.map +1 -0
- package/dist/records/index.d.mts +124 -0
- package/dist/records/index.d.ts +124 -0
- package/dist/records/index.js +226 -0
- package/dist/records/index.js.map +1 -0
- package/dist/records/index.mjs +224 -0
- package/dist/records/index.mjs.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/errors.ts","../src/utils/http.ts","../src/utils/query.ts","../src/records/client.ts","../src/auth/client.ts","../src/analytics/client.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { HydrousErrorBody } from '../types/index.js';\n\n/**\n * Thrown for any non-2xx response from the HydrousDB API.\n */\nexport class HydrousError extends Error {\n /** HTTP status code */\n readonly status: number;\n /** Machine-readable error code from the API */\n readonly code: string | undefined;\n /** Detailed validation messages */\n readonly details: string[];\n /** Server-generated request ID for support */\n readonly requestId: string | undefined;\n\n constructor(body: HydrousErrorBody, status: number) {\n super(body.error);\n this.name = 'HydrousError';\n this.status = status;\n this.code = body.code;\n this.details = body.details ?? [];\n this.requestId = body.requestId;\n }\n}\n\n/**\n * Thrown when a network request fails (e.g. no connectivity, DNS failure).\n */\nexport class HydrousNetworkError extends Error {\n readonly cause: unknown;\n\n constructor(message: string, cause?: unknown) {\n super(message);\n this.name = 'HydrousNetworkError';\n this.cause = cause;\n }\n}\n\n/**\n * Thrown when a request exceeds the configured timeout.\n */\nexport class HydrousTimeoutError extends Error {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`);\n this.name = 'HydrousTimeoutError';\n }\n}\n","import { HydrousError, HydrousNetworkError, HydrousTimeoutError } from './errors.js';\nimport type { HydrousErrorBody, RequestOptions } from '../types/index.js';\n\nconst DEFAULT_BASE_URL = 'https://db-api-82687684612.us-central1.run.app';\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_RETRIES = 2;\n\n// Statuses that are safe to retry\nconst RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);\n\nexport interface HttpClientConfig {\n apiKey: string;\n bucketKey: string;\n baseUrl?: string;\n timeout?: number;\n retries?: number;\n}\n\nexport class HttpClient {\n readonly baseUrl: string;\n readonly bucketKey: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly retries: number;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.bucketKey = config.bucketKey;\n this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.retries = config.retries ?? DEFAULT_RETRIES;\n }\n\n // ── Core request ────────────────────────────────────────────────────────────\n\n async request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n params?: Record<string, string | number | boolean | undefined | null>;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n /** Return raw Response instead of parsed JSON (used by HEAD) */\n raw?: boolean;\n }\n ): Promise<T> {\n const url = this.buildUrl(path, options?.params);\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...options?.headers,\n };\n\n const init: RequestInit = {\n method,\n headers,\n signal: this.buildSignal(options?.signal),\n };\n\n if (options?.body !== undefined) {\n init.body = JSON.stringify(options.body);\n }\n\n return this.executeWithRetry<T>(url, init, options?.raw ?? false, this.retries);\n }\n\n // ── Convenience methods ──────────────────────────────────────────────────────\n\n get<T>(path: string, params?: Record<string, string | number | boolean | undefined | null>, opts?: RequestOptions): Promise<T> {\n return this.request<T>('GET', path, { params, ...opts });\n }\n\n post<T>(path: string, body?: unknown, opts?: RequestOptions): Promise<T> {\n return this.request<T>('POST', path, { body, ...opts });\n }\n\n patch<T>(path: string, body?: unknown, opts?: RequestOptions): Promise<T> {\n return this.request<T>('PATCH', path, { body, ...opts });\n }\n\n delete<T>(path: string, params?: Record<string, string | number | boolean | undefined | null>, opts?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', path, { params, ...opts });\n }\n\n head(path: string, params?: Record<string, string | number | boolean | undefined | null>, opts?: RequestOptions): Promise<Response> {\n return this.request<Response>('HEAD', path, { params, raw: true, ...opts });\n }\n\n // ── Internals ────────────────────────────────────────────────────────────────\n\n private buildUrl(\n path: string,\n params?: Record<string, string | number | boolean | undefined | null>\n ): string {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null && v !== '') {\n url.searchParams.set(k, String(v));\n }\n }\n }\n\n return url.toString();\n }\n\n private buildSignal(userSignal?: AbortSignal): AbortSignal {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort('timeout'), this.timeout);\n\n // If the user passes their own signal, propagate its abort\n userSignal?.addEventListener('abort', () => {\n clearTimeout(timeoutId);\n controller.abort(userSignal.reason);\n });\n\n return controller.signal;\n }\n\n private async executeWithRetry<T>(\n url: string,\n init: RequestInit,\n raw: boolean,\n retriesLeft: number\n ): Promise<T> {\n try {\n const res = await fetch(url, init);\n\n // Raw mode — return the Response object directly (HEAD)\n if (raw) return res as unknown as T;\n\n if (res.ok) {\n if (res.status === 204) return undefined as unknown as T;\n return (await res.json()) as T;\n }\n\n // Non-ok response — try to parse error body\n let body: HydrousErrorBody;\n try {\n body = (await res.json()) as HydrousErrorBody;\n } catch {\n body = { success: false, error: `HTTP ${res.status}: ${res.statusText}` };\n }\n\n // Retry on transient server errors\n if (retriesLeft > 0 && RETRYABLE_STATUSES.has(res.status)) {\n await sleep(500 * (this.retries - retriesLeft + 1)); // linear back-off\n return this.executeWithRetry<T>(url, init, raw, retriesLeft - 1);\n }\n\n throw new HydrousError(body, res.status);\n\n } catch (err) {\n if (err instanceof HydrousError) throw err;\n\n // AbortError from our own timeout\n if (err instanceof Error && err.message === 'timeout') {\n throw new HydrousTimeoutError(this.timeout);\n }\n\n // Genuine network error — retry\n if (retriesLeft > 0) {\n await sleep(500 * (this.retries - retriesLeft + 1));\n return this.executeWithRetry<T>(url, init, raw, retriesLeft - 1);\n }\n\n throw new HydrousNetworkError(\n `Network request failed: ${err instanceof Error ? err.message : String(err)}`,\n err\n );\n }\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","import type { Filter, QueryOptions } from '../types/index.js';\n\n/**\n * Converts a QueryOptions object into a flat Record suitable for URLSearchParams.\n *\n * Filter fields use the `field[op]=value` convention:\n * { field: 'status', op: '==', value: 'active' } → status=active\n * { field: 'score', op: '>', value: 50 } → score[>]=50\n */\nexport function buildQueryParams(\n opts: QueryOptions\n): Record<string, string | number | boolean> {\n const params: Record<string, string | number | boolean> = {};\n\n if (opts.timeScope) params['timeScope'] = opts.timeScope;\n if (opts.year) params['year'] = opts.year;\n if (opts.sortOrder) params['sortOrder'] = opts.sortOrder;\n if (opts.limit) params['limit'] = opts.limit;\n if (opts.cursor) params['cursor'] = opts.cursor;\n if (opts.fields) params['fields'] = opts.fields;\n\n for (const filter of opts.filters ?? []) {\n const paramKey = filter.op === '==' ? filter.field : `${filter.field}[${filter.op}]`;\n params[paramKey] = filter.value as string | number | boolean;\n }\n\n return params;\n}\n\n/**\n * Validates a filter array and throws a descriptive error if invalid.\n */\nexport function validateFilters(filters: Filter[]): void {\n const VALID_OPS = new Set(['==', '!=', '>', '<', '>=', '<=', 'contains']);\n\n if (filters.length > 3) {\n throw new Error('HydrousDB supports a maximum of 3 filters per query.');\n }\n\n for (const f of filters) {\n if (!VALID_OPS.has(f.op)) {\n throw new Error(\n `Invalid filter operator \"${f.op}\". Valid operators: ${[...VALID_OPS].join(', ')}`\n );\n }\n if (!f.field || typeof f.field !== 'string') {\n throw new Error('Each filter must have a non-empty \"field\" string.');\n }\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport { buildQueryParams, validateFilters } from '../utils/query.js';\nimport type {\n GetRecordOptions,\n GetRecordResponse,\n GetSnapshotResponse,\n QueryOptions,\n QueryResponse,\n InsertRecordPayload,\n InsertRecordResponse,\n UpdateRecordPayload,\n UpdateRecordResponse,\n DeleteRecordResponse,\n RecordExistsInfo,\n BatchUpdatePayload,\n BatchUpdateResponse,\n BatchDeletePayload,\n BatchDeleteResponse,\n BatchInsertPayload,\n BatchInsertResponse,\n RecordData,\n HydrousRecord,\n RequestOptions,\n} from '../types/index.js';\n\nexport class RecordsClient {\n constructor(private readonly http: HttpClient) { }\n\n private get path() {\n return `/api/${this.http.bucketKey}`;\n }\n\n // ── GET — single record ────────────────────────────────────────────────────\n\n /**\n * Fetch a single record by ID.\n *\n * @example\n * const { data } = await db.records.get('rec_abc123');\n * const { data, history } = await db.records.get('rec_abc123', { showHistory: true });\n */\n async get(recordId: string, options?: GetRecordOptions & RequestOptions): Promise<GetRecordResponse> {\n const params: Record<string, string | number | boolean | undefined | null> = { recordId };\n if (options?.showHistory) params['showHistory'] = 'true';\n return this.http.get<GetRecordResponse>(this.path, params, options);\n }\n\n // ── GET — historical snapshot ──────────────────────────────────────────────\n\n /**\n * Fetch a specific historical version (generation) of a record.\n *\n * @example\n * const { data } = await db.records.getSnapshot('rec_abc123', '1700000000000000');\n */\n async getSnapshot(recordId: string, generation: string, opts?: RequestOptions): Promise<GetSnapshotResponse> {\n return this.http.get<GetSnapshotResponse>(this.path, { recordId, generation }, opts);\n }\n\n // ── GET — collection query ─────────────────────────────────────────────────\n\n /**\n * Query a collection with optional filters, sorting, and pagination.\n *\n * @example\n * // Simple query\n * const { data, meta } = await db.records.query({ limit: 50, sortOrder: 'desc' });\n *\n * // Filtered query\n * const { data } = await db.records.query({\n * filters: [{ field: 'status', op: '==', value: 'active' }],\n * timeScope: '7d',\n * });\n *\n * // Paginated\n * let cursor: string | null = null;\n * do {\n * const result = await db.records.query({ limit: 100, cursor: cursor ?? undefined });\n * cursor = result.meta.nextCursor;\n * } while (cursor);\n */\n async query<T extends RecordData = RecordData>(\n options?: QueryOptions & RequestOptions\n ): Promise<QueryResponse<T>> {\n if (options?.filters) validateFilters(options.filters);\n const params = buildQueryParams(options ?? {});\n return this.http.get<QueryResponse<T>>(this.path, params, options);\n }\n\n // ── POST — insert ──────────────────────────────────────────────────────────\n\n /**\n * Insert a new record.\n *\n * @example\n * const { data, meta } = await db.records.insert({\n * values: { name: 'Alice', score: 99 },\n * queryableFields: ['name'],\n * userEmail: 'alice@example.com',\n * });\n */\n async insert(payload: InsertRecordPayload, opts?: RequestOptions): Promise<InsertRecordResponse> {\n return this.http.post<InsertRecordResponse>(this.path, payload, opts);\n }\n\n // ── PATCH — update ─────────────────────────────────────────────────────────\n\n /**\n * Update an existing record.\n *\n * @example\n * await db.records.update({\n * recordId: 'rec_abc123',\n * values: { score: 100 },\n * track_record_history: true,\n * });\n */\n async update(payload: UpdateRecordPayload, opts?: RequestOptions): Promise<UpdateRecordResponse> {\n return this.http.patch<UpdateRecordResponse>(this.path, payload, opts);\n }\n\n // ── DELETE ─────────────────────────────────────────────────────────────────\n\n /**\n * Delete a record permanently.\n *\n * @example\n * await db.records.delete('rec_abc123');\n */\n async delete(recordId: string, opts?: RequestOptions): Promise<DeleteRecordResponse> {\n return this.http.delete<DeleteRecordResponse>(this.path, { recordId }, opts);\n }\n\n // ── HEAD — existence check ─────────────────────────────────────────────────\n\n /**\n * Check whether a record exists without fetching its full data.\n * Returns `null` if the record is not found.\n *\n * @example\n * const info = await db.records.exists('rec_abc123');\n * if (info?.exists) console.log('found at', info.updatedAt);\n */\n async exists(recordId: string, opts?: RequestOptions): Promise<RecordExistsInfo | null> {\n const res = await this.http.head(this.path, { recordId }, opts);\n\n if (res.status === 404) return null;\n if (!res.ok) return null;\n\n return {\n exists: true,\n id: res.headers.get('X-Record-Id') ?? recordId,\n createdAt: res.headers.get('X-Created-At') ?? '',\n updatedAt: res.headers.get('X-Updated-At') ?? '',\n sizeBytes: res.headers.get('X-Size-Bytes') ?? '',\n };\n }\n\n // ── Batch — update ─────────────────────────────────────────────────────────\n\n /**\n * Update up to 500 records in a single request.\n *\n * @example\n * await db.records.batchUpdate({\n * updates: [\n * { recordId: 'rec_1', values: { status: 'archived' } },\n * { recordId: 'rec_2', values: { status: 'archived' } },\n * ],\n * });\n */\n async batchUpdate(payload: BatchUpdatePayload, opts?: RequestOptions): Promise<BatchUpdateResponse> {\n return this.http.post<BatchUpdateResponse>(\n `${this.path}/batch/update`,\n payload,\n opts\n );\n }\n\n // ── Batch — delete ─────────────────────────────────────────────────────────\n\n /**\n * Delete up to 500 records in a single request.\n *\n * @example\n * await db.records.batchDelete({ recordIds: ['rec_1', 'rec_2', 'rec_3'] });\n */\n async batchDelete(payload: BatchDeletePayload, opts?: RequestOptions): Promise<BatchDeleteResponse> {\n return this.http.post<BatchDeleteResponse>(\n `${this.path}/batch/delete`,\n payload,\n opts\n );\n }\n\n // ── Batch — insert ─────────────────────────────────────────────────────────\n\n /**\n * Insert up to 500 records in a single request.\n * Returns HTTP 207 (multi-status) — check `meta.failed` for partial failures.\n *\n * @example\n * const result = await db.records.batchInsert({\n * records: [{ name: 'Alice' }, { name: 'Bob' }],\n * queryableFields: ['name'],\n * });\n */\n async batchInsert(payload: BatchInsertPayload, opts?: RequestOptions): Promise<BatchInsertResponse> {\n return this.http.post<BatchInsertResponse>(\n `${this.path}/batch/insert`,\n payload,\n opts\n );\n }\n\n // ── Helpers ────────────────────────────────────────────────────────────────\n\n /**\n * Fetch ALL records matching a query, automatically following cursors.\n * Use with care on large collections — prefer `query()` with manual pagination.\n *\n * @example\n * const allRecords = await db.records.queryAll({\n * filters: [{ field: 'type', op: '==', value: 'invoice' }],\n * });\n */\n async queryAll<T extends RecordData = RecordData>(\n options?: Omit<QueryOptions, 'cursor'> & RequestOptions\n ): Promise<(T & HydrousRecord)[]> {\n const all: (T & HydrousRecord)[] = [];\n let cursor: string | null = null;\n\n do {\n const result: any = await this.query<T>(cursor ? { ...options, cursor } : { ...options });\n all.push(...result.data);\n cursor = result.meta.nextCursor ?? null;\n } while (cursor);\n\n return all;\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport type {\n SignUpPayload,\n SignUpResponse,\n SignInPayload,\n SignInResponse,\n SignOutPayload,\n ValidateSessionResponse,\n RefreshSessionResponse,\n GetUserResponse,\n ListUsersResponse,\n UpdateUserPayload,\n UpdateUserResponse,\n PasswordChangePayload,\n PasswordResetRequestPayload,\n PasswordResetConfirmPayload,\n EmailVerifyRequestPayload,\n EmailVerifyConfirmPayload,\n AccountLockPayload,\n AccountLockResponse,\n AuthUser,\n RequestOptions,\n} from '../types/index.js';\n\nexport class AuthClient {\n constructor(private readonly http: HttpClient) {}\n\n private get path() {\n return `/auth/${this.http.bucketKey}`;\n }\n\n // ── Sign-up ────────────────────────────────────────────────────────────────\n\n /**\n * Create a new user account. Returns the user and a session immediately.\n *\n * @example\n * const { data, session } = await db.auth.signUp({\n * email: 'alice@example.com',\n * password: 'Str0ngP@ss!',\n * fullName: 'Alice Smith',\n * });\n * // Store session.sessionId and session.refreshToken in your app\n */\n async signUp(payload: SignUpPayload, opts?: RequestOptions): Promise<SignUpResponse> {\n return this.http.post<SignUpResponse>(`${this.path}/signup`, payload, opts);\n }\n\n // ── Sign-in ────────────────────────────────────────────────────────────────\n\n /**\n * Authenticate with email + password. Returns user data and a new session.\n *\n * @example\n * const { data, session } = await db.auth.signIn({\n * email: 'alice@example.com',\n * password: 'Str0ngP@ss!',\n * });\n */\n async signIn(payload: SignInPayload, opts?: RequestOptions): Promise<SignInResponse> {\n return this.http.post<SignInResponse>(`${this.path}/signin`, payload, opts);\n }\n\n // ── Sign-out ───────────────────────────────────────────────────────────────\n\n /**\n * Revoke a session (or all sessions for a user).\n *\n * @example\n * // Single device\n * await db.auth.signOut({ sessionId: 'sess_...' });\n *\n * // All devices\n * await db.auth.signOut({ allDevices: true, userId: 'user_...' });\n */\n async signOut(payload: SignOutPayload, opts?: RequestOptions): Promise<{ success: true; message: string }> {\n return this.http.post(`${this.path}/signout`, payload, opts);\n }\n\n // ── Session: validate ──────────────────────────────────────────────────────\n\n /**\n * Validate a session token — use this on every protected request in your backend.\n *\n * @example\n * try {\n * const { data } = await db.auth.validateSession(sessionId);\n * // data is the authenticated user\n * } catch (err) {\n * // Session expired or invalid\n * }\n */\n async validateSession(sessionId: string, opts?: RequestOptions): Promise<ValidateSessionResponse> {\n return this.http.post<ValidateSessionResponse>(`${this.path}/session/validate`, { sessionId }, opts);\n }\n\n // ── Session: refresh ───────────────────────────────────────────────────────\n\n /**\n * Exchange a refresh token for a new session (rotation).\n * The old session is revoked.\n *\n * @example\n * const { session } = await db.auth.refreshSession(refreshToken);\n */\n async refreshSession(refreshToken: string, opts?: RequestOptions): Promise<RefreshSessionResponse> {\n return this.http.post<RefreshSessionResponse>(`${this.path}/session/refresh`, { refreshToken }, opts);\n }\n\n // ── User: get ──────────────────────────────────────────────────────────────\n\n /**\n * Fetch a user by their ID.\n *\n * @example\n * const { data } = await db.auth.getUser('user_abc123');\n */\n async getUser(userId: string, opts?: RequestOptions): Promise<GetUserResponse> {\n return this.http.get<GetUserResponse>(`${this.path}/user`, { userId }, opts);\n }\n\n // ── User: list ─────────────────────────────────────────────────────────────\n\n /**\n * List users with cursor-based pagination.\n *\n * @example\n * const { data, meta } = await db.auth.listUsers({ limit: 50 });\n */\n async listUsers(options?: { limit?: number; cursor?: string } & RequestOptions): Promise<ListUsersResponse> {\n const params: Record<string, string | number | boolean | undefined | null> = {\n limit: options?.limit,\n };\n if (options?.cursor) params['cursor'] = options.cursor;\n return this.http.get<ListUsersResponse>(`${this.path}/users`, params, options);\n }\n\n // ── User: update ───────────────────────────────────────────────────────────\n\n /**\n * Update user profile fields.\n *\n * @example\n * await db.auth.updateUser({ userId: 'user_abc', updates: { fullName: 'Bob Smith' } });\n */\n async updateUser(payload: UpdateUserPayload, opts?: RequestOptions): Promise<UpdateUserResponse> {\n return this.http.patch<UpdateUserResponse>(`${this.path}/user`, payload, opts);\n }\n\n // ── User: delete ───────────────────────────────────────────────────────────\n\n /**\n * Soft-delete a user. All their sessions are revoked automatically.\n *\n * @example\n * await db.auth.deleteUser('user_abc123');\n */\n async deleteUser(userId: string, opts?: RequestOptions): Promise<{ success: true; message: string }> {\n return this.http.delete(`${this.path}/user`, { userId }, opts);\n }\n\n // ── Password: change ───────────────────────────────────────────────────────\n\n /**\n * Change password for a signed-in user (requires old password).\n * All sessions are revoked after success.\n *\n * @example\n * await db.auth.changePassword({\n * userId: 'user_abc',\n * oldPassword: 'Old@Pass1',\n * newPassword: 'New@Pass2',\n * });\n */\n async changePassword(payload: PasswordChangePayload, opts?: RequestOptions): Promise<{ success: true; message: string }> {\n return this.http.post(`${this.path}/password/change`, payload, opts);\n }\n\n // ── Password: reset request ────────────────────────────────────────────────\n\n /**\n * Request a password reset email.\n * Always returns success to prevent email enumeration.\n *\n * @example\n * await db.auth.requestPasswordReset({ email: 'alice@example.com' });\n */\n async requestPasswordReset(payload: PasswordResetRequestPayload, opts?: RequestOptions): Promise<{ success: true; message: string }> {\n return this.http.post(`${this.path}/password/reset/request`, payload, opts);\n }\n\n // ── Password: reset confirm ────────────────────────────────────────────────\n\n /**\n * Confirm a password reset using the token from the reset email.\n *\n * @example\n * await db.auth.confirmPasswordReset({ resetToken: 'tok_...', newPassword: 'New@Pass2' });\n */\n async confirmPasswordReset(payload: PasswordResetConfirmPayload, opts?: RequestOptions): Promise<{ success: true; message: string }> {\n return this.http.post(`${this.path}/password/reset/confirm`, payload, opts);\n }\n\n // ── Email: verify request ──────────────────────────────────────────────────\n\n /**\n * Send a verification email to the user.\n *\n * @example\n * await db.auth.requestEmailVerification({ userId: 'user_abc' });\n */\n async requestEmailVerification(payload: EmailVerifyRequestPayload, opts?: RequestOptions): Promise<{ success: true; message: string }> {\n return this.http.post(`${this.path}/email/verify/request`, payload, opts);\n }\n\n // ── Email: verify confirm ──────────────────────────────────────────────────\n\n /**\n * Confirm email address using the token from the verification email.\n *\n * @example\n * await db.auth.confirmEmailVerification({ verifyToken: 'tok_...' });\n */\n async confirmEmailVerification(payload: EmailVerifyConfirmPayload, opts?: RequestOptions): Promise<{ success: true; message: string }> {\n return this.http.post(`${this.path}/email/verify/confirm`, payload, opts);\n }\n\n // ── Account: lock ──────────────────────────────────────────────────────────\n\n /**\n * Lock a user account for a given duration (default: 15 min).\n *\n * @example\n * await db.auth.lockAccount({ userId: 'user_abc', duration: 30 * 60 * 1000 });\n */\n async lockAccount(payload: AccountLockPayload, opts?: RequestOptions): Promise<AccountLockResponse> {\n return this.http.post<AccountLockResponse>(`${this.path}/account/lock`, payload, opts);\n }\n\n // ── Account: unlock ────────────────────────────────────────────────────────\n\n /**\n * Unlock a previously locked user account.\n *\n * @example\n * await db.auth.unlockAccount('user_abc');\n */\n async unlockAccount(userId: string, opts?: RequestOptions): Promise<{ success: true; message: string }> {\n return this.http.post(`${this.path}/account/unlock`, { userId }, opts);\n }\n\n // ── Helpers ────────────────────────────────────────────────────────────────\n\n /**\n * Fetch all users, automatically following cursors.\n *\n * @example\n * const users = await db.auth.listAllUsers();\n */\n async listAllUsers(opts?: RequestOptions): Promise<AuthUser[]> {\n const all: AuthUser[] = [];\n let cursor: string | null = null;\n\n do {\n const result = await this.listUsers(cursor ? { cursor, ...opts } : { ...opts });\n all.push(...result.data);\n cursor = result.meta.nextCursor ?? null;\n } while (cursor);\n\n return all;\n }\n}\n","import type { HttpClient } from '../utils/http.js';\nimport type {\n AnalyticsQuery,\n AnalyticsResponse,\n DateRange,\n Filter,\n MultiMetricItem,\n RequestOptions,\n CountResult,\n DistributionItem,\n SumResult,\n TimeSeriesPoint,\n FieldTimeSeriesPoint,\n TopNItem,\n FieldStatsResult,\n FilteredRecordsResult,\n StorageStatsResult,\n} from '../types/index.js';\n\n// Typed wrapper so callers get proper return types\ntype AnalyticsResult<T> = Omit<AnalyticsResponse, 'data'> & { data: T; queryType: string; bucketKey: string | null; projectId: string };\n\nexport class AnalyticsClient {\n constructor(private readonly http: HttpClient) {}\n\n private get path() {\n // POST /api/analytics/:bucketKey/:key — bucketKey and apiKey both in URL\n return `/api/analytics/${this.http.bucketKey}/${this.http.bucketKey}`;\n }\n\n // ── Raw query ─────────────────────────────────────────────────────────────\n\n /**\n * Run any analytics query with full control over the payload.\n * Prefer the typed convenience methods below for everyday use.\n */\n async query<T = unknown>(payload: AnalyticsQuery, opts?: RequestOptions): Promise<AnalyticsResult<T>> {\n return this.http.post<AnalyticsResult<T>>(this.path, payload, opts);\n }\n\n // ── count ──────────────────────────────────────────────────────────────────\n\n /**\n * Total record count, optionally scoped to a date range.\n * Server `queryType`: **\"count\"**\n *\n * @example\n * const { data } = await db.analytics.count();\n * console.log(data.count); // 1234\n *\n * // With date range\n * const { data } = await db.analytics.count({\n * dateRange: { startDate: '2025-01-01', endDate: '2025-12-31' }\n * });\n */\n async count(options?: { dateRange?: DateRange } & RequestOptions): Promise<AnalyticsResult<CountResult>> {\n return this.query<CountResult>({ queryType: 'count', dateRange: options?.dateRange }, options);\n }\n\n // ── distribution ───────────────────────────────────────────────────────────\n\n /**\n * Value distribution (histogram) for a field.\n * Server `queryType`: **\"distribution\"**\n *\n * @example\n * const { data } = await db.analytics.distribution('status');\n * // [{ value: 'active', count: 80 }, { value: 'archived', count: 20 }]\n */\n async distribution(\n field: string,\n options?: { limit?: number; order?: 'asc' | 'desc'; dateRange?: DateRange } & RequestOptions\n ): Promise<AnalyticsResult<DistributionItem[]>> {\n return this.query<DistributionItem[]>({\n queryType: 'distribution',\n field,\n limit: options?.limit,\n order: options?.order,\n dateRange: options?.dateRange,\n }, options);\n }\n\n // ── sum ────────────────────────────────────────────────────────────────────\n\n /**\n * Sum a numeric field, with optional group-by.\n * Server `queryType`: **\"sum\"**\n *\n * @example\n * const { data } = await db.analytics.sum('revenue', { groupBy: 'region' });\n */\n async sum(\n field: string,\n options?: { groupBy?: string; limit?: number; dateRange?: DateRange } & RequestOptions\n ): Promise<AnalyticsResult<SumResult>> {\n return this.query<SumResult>({\n queryType: 'sum',\n field,\n groupBy: options?.groupBy,\n limit: options?.limit,\n dateRange: options?.dateRange,\n }, options);\n }\n\n // ── timeSeries ─────────────────────────────────────────────────────────────\n\n /**\n * Record count grouped over time.\n * Server `queryType`: **\"timeSeries\"**\n *\n * @example\n * const { data } = await db.analytics.timeSeries({ granularity: 'day' });\n * // [{ date: '2025-01-01', count: 42 }, ...]\n */\n async timeSeries(options?: {\n granularity?: 'hour' | 'day' | 'week' | 'month';\n dateRange?: DateRange;\n } & RequestOptions): Promise<AnalyticsResult<TimeSeriesPoint[]>> {\n return this.query<TimeSeriesPoint[]>({\n queryType: 'timeSeries',\n granularity: options?.granularity,\n dateRange: options?.dateRange,\n }, options);\n }\n\n // ── fieldTimeSeries ────────────────────────────────────────────────────────\n\n /**\n * Aggregate a numeric field over time.\n * Server `queryType`: **\"fieldTimeSeries\"**\n *\n * @example\n * const { data } = await db.analytics.fieldTimeSeries('revenue', {\n * granularity: 'month',\n * aggregation: 'sum',\n * });\n */\n async fieldTimeSeries(\n field: string,\n options?: {\n aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'count';\n granularity?: 'hour' | 'day' | 'week' | 'month';\n dateRange?: DateRange;\n } & RequestOptions\n ): Promise<AnalyticsResult<FieldTimeSeriesPoint[]>> {\n return this.query<FieldTimeSeriesPoint[]>({\n queryType: 'fieldTimeSeries',\n field,\n aggregation: options?.aggregation,\n granularity: options?.granularity,\n dateRange: options?.dateRange,\n }, options);\n }\n\n // ── topN ───────────────────────────────────────────────────────────────────\n\n /**\n * Top N most frequent values for a field.\n * Server `queryType`: **\"topN\"**\n *\n * @example\n * const { data } = await db.analytics.topN('country', 5);\n * // [{ label: 'US', value: 'US', count: 500 }, ...]\n */\n async topN(\n field: string,\n n = 10,\n options?: { labelField?: string; order?: 'asc' | 'desc'; dateRange?: DateRange } & RequestOptions\n ): Promise<AnalyticsResult<TopNItem[]>> {\n return this.query<TopNItem[]>({\n queryType: 'topN',\n field,\n n,\n labelField: options?.labelField,\n order: options?.order,\n dateRange: options?.dateRange,\n }, options);\n }\n\n // ── stats ──────────────────────────────────────────────────────────────────\n\n /**\n * Statistical summary for a numeric field: min, max, avg, stddev, p50, p90, p99.\n * Server `queryType`: **\"stats\"**\n *\n * @example\n * const { data } = await db.analytics.stats('score');\n * console.log(data.avg, data.p99);\n */\n async stats(\n field: string,\n options?: { dateRange?: DateRange } & RequestOptions\n ): Promise<AnalyticsResult<FieldStatsResult>> {\n return this.query<FieldStatsResult>({ queryType: 'stats', field, dateRange: options?.dateRange }, options);\n }\n\n // ── records ────────────────────────────────────────────────────────────────\n\n /**\n * Filtered, paginated raw records with optional field projection.\n * Supports filter ops: == != > < >= <= CONTAINS\n * Server `queryType`: **\"records\"**\n *\n * @example\n * const { data } = await db.analytics.records({\n * filters: [{ field: 'role', op: '==', value: 'admin' }],\n * selectFields: ['email', 'createdAt'],\n * limit: 25,\n * });\n * console.log(data.data, data.hasMore);\n */\n async records(options?: {\n filters?: Filter[];\n selectFields?: string[];\n limit?: number;\n offset?: number;\n orderBy?: string;\n order?: 'asc' | 'desc';\n dateRange?: DateRange;\n } & RequestOptions): Promise<AnalyticsResult<FilteredRecordsResult>> {\n return this.query<FilteredRecordsResult>({\n queryType: 'records',\n filters: options?.filters,\n selectFields: options?.selectFields,\n limit: options?.limit,\n offset: options?.offset,\n orderBy: options?.orderBy,\n order: options?.order,\n dateRange: options?.dateRange,\n }, options);\n }\n\n // ── multiMetric ────────────────────────────────────────────────────────────\n\n /**\n * Multiple aggregations in a single BigQuery call — ideal for dashboard stat cards.\n * Server `queryType`: **\"multiMetric\"**\n *\n * @example\n * const { data } = await db.analytics.multiMetric([\n * { name: 'totalRevenue', field: 'amount', aggregation: 'sum' },\n * { name: 'avgScore', field: 'score', aggregation: 'avg' },\n * { name: 'userCount', field: 'userId', aggregation: 'count' },\n * ]);\n * console.log(data.totalRevenue, data.avgScore, data.userCount);\n */\n async multiMetric(\n metrics: MultiMetricItem[],\n options?: { dateRange?: DateRange } & RequestOptions\n ): Promise<AnalyticsResult<Record<string, number>>> {\n return this.query<Record<string, number>>({\n queryType: 'multiMetric',\n metrics,\n dateRange: options?.dateRange,\n }, options);\n }\n\n // ── storageStats ───────────────────────────────────────────────────────────\n\n /**\n * Storage statistics for the bucket — total records, bytes, avg/min/max size.\n * Server `queryType`: **\"storageStats\"**\n *\n * @example\n * const { data } = await db.analytics.storageStats();\n * console.log(data.totalRecords, data.totalBytes);\n */\n async storageStats(\n options?: { dateRange?: DateRange } & RequestOptions\n ): Promise<AnalyticsResult<StorageStatsResult>> {\n return this.query<StorageStatsResult>({ queryType: 'storageStats', dateRange: options?.dateRange }, options);\n }\n\n // ── crossBucket ────────────────────────────────────────────────────────────\n\n /**\n * Compare a metric across multiple buckets in one query.\n * Server `queryType`: **\"crossBucket\"**\n *\n * @example\n * const { data } = await db.analytics.crossBucket({\n * bucketKeys: ['sales', 'refunds', 'trials'],\n * field: 'amount',\n * aggregation: 'sum',\n * });\n */\n async crossBucket(options: {\n bucketKeys: string[];\n field: string;\n aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'count';\n dateRange?: DateRange;\n } & RequestOptions): Promise<AnalyticsResult<unknown>> {\n return this.query<unknown>({\n queryType: 'crossBucket',\n bucketKeys: options.bucketKeys,\n field: options.field,\n aggregation: options.aggregation,\n dateRange: options.dateRange,\n }, options);\n }\n}\n","import { HttpClient } from './utils/http.js';\nimport { RecordsClient } from './records/client.js';\nimport { AuthClient } from './auth/client.js';\nimport { AnalyticsClient } from './analytics/client.js';\nimport type { HydrousConfig } from './types/index.js';\n\nexport { HydrousError, HydrousNetworkError, HydrousTimeoutError } from './utils/errors.js';\nexport type { HydrousConfig } from './types/index.js';\n\n/**\n * The main entry point for the HydrousDB SDK.\n *\n * @example\n * import { createClient } from 'hydrousdb';\n *\n * const db = createClient({\n * apiKey: 'your-api-key',\n * bucketKey: 'your-bucket',\n * });\n *\n * // Records\n * const { data } = await db.records.get('rec_abc123');\n *\n * // Auth\n * const { data, session } = await db.auth.signIn({ email: 'a@b.com', password: '...' });\n *\n * // Analytics\n * const { data } = await db.analytics.count();\n */\nexport class HydrousClient {\n /** Record CRUD and batch operations */\n readonly records: RecordsClient;\n /** User authentication and session management */\n readonly auth: AuthClient;\n /** Analytics and aggregations */\n readonly analytics: AnalyticsClient;\n\n private readonly http: HttpClient;\n\n constructor(config: HydrousConfig) {\n if (!config.apiKey) throw new Error('[hydrousdb] apiKey is required');\n if (!config.bucketKey) throw new Error('[hydrousdb] bucketKey is required');\n\n this.http = new HttpClient(config);\n this.records = new RecordsClient(this.http);\n this.auth = new AuthClient(this.http);\n this.analytics = new AnalyticsClient(this.http);\n }\n}\n\n/**\n * Create a HydrousDB client.\n *\n * @example\n * const db = createClient({ apiKey: '...', bucketKey: '...' });\n */\nexport function createClient(config: HydrousConfig): HydrousClient {\n return new HydrousClient(config);\n}\n"]}
|