hydrousdb 1.1.0 → 1.1.1

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/README.md CHANGED
@@ -65,7 +65,7 @@ yarn add hydrousdb
65
65
  import { createClient } from 'hydrousdb';
66
66
 
67
67
  const db = createClient({
68
- apiKey: 'your-api-key',
68
+ authKey: 'your-auth-key',
69
69
  bucketKey: 'your-bucket-key',
70
70
  });
71
71
 
@@ -103,7 +103,7 @@ import { createClient } from 'hydrousdb';
103
103
 
104
104
  // The client is re-used across all server components in the same process
105
105
  export const db = createClient({
106
- apiKey: process.env.HYDROUS_API_KEY!,
106
+ authKey: process.env.HYDROUS_AUTH_KEY!,
107
107
  bucketKey: process.env.HYDROUS_BUCKET_KEY!,
108
108
  });
109
109
  ```
@@ -196,7 +196,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
196
196
  import { createClient, HydrousError } from 'hydrousdb';
197
197
 
198
198
  const db = createClient({
199
- apiKey: process.env.HYDROUS_API_KEY!,
199
+ authKey: process.env.HYDROUS_AUTH_KEY!,
200
200
  bucketKey: process.env.HYDROUS_BUCKET_KEY!,
201
201
  });
202
202
 
@@ -229,7 +229,7 @@ export default defineNuxtPlugin(() => {
229
229
  const config = useRuntimeConfig();
230
230
 
231
231
  const db = createClient({
232
- apiKey: config.hydrousApiKey as string,
232
+ authKey: config.hydrousAuthKey as string,
233
233
  bucketKey: config.hydrousBucketKey as string,
234
234
  });
235
235
 
@@ -273,7 +273,7 @@ const { data: records, pending } = await useAsyncData('records', () =>
273
273
  import { createClient } from 'hydrousdb';
274
274
 
275
275
  const db = createClient({
276
- apiKey: import.meta.env.VITE_HYDROUS_API_KEY,
276
+ authKey: import.meta.env.VITE_HYDROUS_AUTH_KEY,
277
277
  bucketKey: import.meta.env.VITE_HYDROUS_BUCKET_KEY,
278
278
  });
279
279
 
@@ -292,7 +292,7 @@ import { useEffect, useState } from 'react';
292
292
  import { createClient, HydrousRecord, HydrousError } from 'hydrousdb';
293
293
 
294
294
  const db = createClient({
295
- apiKey: import.meta.env.VITE_HYDROUS_API_KEY,
295
+ authKey: import.meta.env.VITE_HYDROUS_AUTH_KEY,
296
296
  bucketKey: import.meta.env.VITE_HYDROUS_BUCKET_KEY,
297
297
  });
298
298
 
@@ -326,7 +326,7 @@ import express from 'express';
326
326
  import { createClient, HydrousError } from 'hydrousdb';
327
327
 
328
328
  const db = createClient({
329
- apiKey: process.env.HYDROUS_API_KEY!,
329
+ authKey: process.env.HYDROUS_AUTH_KEY!,
330
330
  bucketKey: process.env.HYDROUS_BUCKET_KEY!,
331
331
  });
332
332
  const app = express();
@@ -355,7 +355,7 @@ app.listen(3000, () => console.log('Listening on :3000'));
355
355
  import { createClient } from 'hydrousdb';
356
356
 
357
357
  const db = createClient({
358
- apiKey: string, // required — your HydrousDB API key
358
+ authKey: string, // required — your HydrousDB auth service key
359
359
  bucketKey: string, // required — your bucket identifier
360
360
  baseUrl?: string, // override API base URL
361
361
  timeout?: number, // request timeout in ms (default: 30_000)
@@ -1,5 +1,5 @@
1
- import { a9 as HttpClient, c as AnalyticsQuery, V as RequestOptions, e as AnalyticsResponse, D as DateRange, C as CountResult, p as DistributionItem, a1 as SumResult, a2 as TimeSeriesPoint, r as FieldTimeSeriesPoint, a3 as TopNItem, F as FieldStatsResult, s as Filter, u as FilteredRecordsResult, M as MultiMetricItem, a0 as StorageStatsResult } from '../http-CIXLF5GV.mjs';
2
- export { d as AnalyticsQueryType } from '../http-CIXLF5GV.mjs';
1
+ import { a9 as HttpClient, c as AnalyticsQuery, V as RequestOptions, e as AnalyticsResponse, D as DateRange, C as CountResult, p as DistributionItem, a1 as SumResult, a2 as TimeSeriesPoint, r as FieldTimeSeriesPoint, a3 as TopNItem, F as FieldStatsResult, s as Filter, u as FilteredRecordsResult, M as MultiMetricItem, a0 as StorageStatsResult } from '../http-DbiqdKlw.mjs';
2
+ export { d as AnalyticsQueryType } from '../http-DbiqdKlw.mjs';
3
3
 
4
4
  type AnalyticsResult<T> = Omit<AnalyticsResponse, 'data'> & {
5
5
  data: T;
@@ -1,5 +1,5 @@
1
- import { a9 as HttpClient, c as AnalyticsQuery, V as RequestOptions, e as AnalyticsResponse, D as DateRange, C as CountResult, p as DistributionItem, a1 as SumResult, a2 as TimeSeriesPoint, r as FieldTimeSeriesPoint, a3 as TopNItem, F as FieldStatsResult, s as Filter, u as FilteredRecordsResult, M as MultiMetricItem, a0 as StorageStatsResult } from '../http-CIXLF5GV.js';
2
- export { d as AnalyticsQueryType } from '../http-CIXLF5GV.js';
1
+ import { a9 as HttpClient, c as AnalyticsQuery, V as RequestOptions, e as AnalyticsResponse, D as DateRange, C as CountResult, p as DistributionItem, a1 as SumResult, a2 as TimeSeriesPoint, r as FieldTimeSeriesPoint, a3 as TopNItem, F as FieldStatsResult, s as Filter, u as FilteredRecordsResult, M as MultiMetricItem, a0 as StorageStatsResult } from '../http-DbiqdKlw.js';
2
+ export { d as AnalyticsQueryType } from '../http-DbiqdKlw.js';
3
3
 
4
4
  type AnalyticsResult<T> = Omit<AnalyticsResponse, 'data'> & {
5
5
  data: T;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/analytics/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["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"]}
1
+ {"version":3,"sources":["../../src/analytics/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["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 — both segments use bucketKey\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"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/analytics/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["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"]}
1
+ {"version":3,"sources":["../../src/analytics/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["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 — both segments use bucketKey\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"]}
@@ -1,5 +1,5 @@
1
- import { a9 as HttpClient, _ as SignUpPayload, V as RequestOptions, $ as SignUpResponse, X as SignInPayload, Y as SignInResponse, Z as SignOutPayload, a8 as ValidateSessionResponse, U as RefreshSessionResponse, x as GetUserResponse, L as ListUsersResponse, a6 as UpdateUserPayload, a7 as UpdateUserResponse, K as PasswordChangePayload, O as PasswordResetRequestPayload, N as PasswordResetConfirmPayload, q as EmailVerifyRequestPayload, E as EmailVerifyConfirmPayload, A as AccountLockPayload, b as AccountLockResponse, g as AuthUser } from '../http-CIXLF5GV.mjs';
2
- export { W as SessionInfo } from '../http-CIXLF5GV.mjs';
1
+ import { a9 as HttpClient, _ as SignUpPayload, V as RequestOptions, $ as SignUpResponse, X as SignInPayload, Y as SignInResponse, Z as SignOutPayload, a8 as ValidateSessionResponse, U as RefreshSessionResponse, x as GetUserResponse, L as ListUsersResponse, a6 as UpdateUserPayload, a7 as UpdateUserResponse, K as PasswordChangePayload, O as PasswordResetRequestPayload, N as PasswordResetConfirmPayload, q as EmailVerifyRequestPayload, E as EmailVerifyConfirmPayload, A as AccountLockPayload, b as AccountLockResponse, g as AuthUser } from '../http-DbiqdKlw.mjs';
2
+ export { W as SessionInfo } from '../http-DbiqdKlw.mjs';
3
3
 
4
4
  declare class AuthClient {
5
5
  private readonly http;
@@ -1,5 +1,5 @@
1
- import { a9 as HttpClient, _ as SignUpPayload, V as RequestOptions, $ as SignUpResponse, X as SignInPayload, Y as SignInResponse, Z as SignOutPayload, a8 as ValidateSessionResponse, U as RefreshSessionResponse, x as GetUserResponse, L as ListUsersResponse, a6 as UpdateUserPayload, a7 as UpdateUserResponse, K as PasswordChangePayload, O as PasswordResetRequestPayload, N as PasswordResetConfirmPayload, q as EmailVerifyRequestPayload, E as EmailVerifyConfirmPayload, A as AccountLockPayload, b as AccountLockResponse, g as AuthUser } from '../http-CIXLF5GV.js';
2
- export { W as SessionInfo } from '../http-CIXLF5GV.js';
1
+ import { a9 as HttpClient, _ as SignUpPayload, V as RequestOptions, $ as SignUpResponse, X as SignInPayload, Y as SignInResponse, Z as SignOutPayload, a8 as ValidateSessionResponse, U as RefreshSessionResponse, x as GetUserResponse, L as ListUsersResponse, a6 as UpdateUserPayload, a7 as UpdateUserResponse, K as PasswordChangePayload, O as PasswordResetRequestPayload, N as PasswordResetConfirmPayload, q as EmailVerifyRequestPayload, E as EmailVerifyConfirmPayload, A as AccountLockPayload, b as AccountLockResponse, g as AuthUser } from '../http-DbiqdKlw.js';
2
+ export { W as SessionInfo } from '../http-DbiqdKlw.js';
3
3
 
4
4
  declare class AuthClient {
5
5
  private readonly http;
@@ -6,7 +6,7 @@ var AuthClient = class {
6
6
  this.http = http;
7
7
  }
8
8
  get path() {
9
- return `/auth/${this.http.bucketKey}`;
9
+ return `/auth/${this.http.authKey}`;
10
10
  }
11
11
  // ── Sign-up ────────────────────────────────────────────────────────────────
12
12
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/auth/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["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"]}
1
+ {"version":3,"sources":["../../src/auth/client.ts"],"names":[],"mappings":";;;AAwBO,IAAM,aAAN,MAAiB;AAAA,EACtB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA,EAEhD,IAAY,IAAA,GAAO;AACjB,IAAA,OAAO,CAAA,MAAA,EAAS,IAAA,CAAK,IAAA,CAAK,OAAO,CAAA,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,MAAA,CAAO,OAAA,EAAwB,IAAA,EAAgD;AACnF,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAAqB,CAAA,EAAG,KAAK,IAAI,CAAA,OAAA,CAAA,EAAW,SAAS,IAAI,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,MAAA,CAAO,OAAA,EAAwB,IAAA,EAAgD;AACnF,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAAqB,CAAA,EAAG,KAAK,IAAI,CAAA,OAAA,CAAA,EAAW,SAAS,IAAI,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,OAAA,CAAQ,OAAA,EAAyB,IAAA,EAAoE;AACzG,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAA,QAAA,CAAA,EAAY,SAAS,IAAI,CAAA;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,eAAA,CAAgB,SAAA,EAAmB,IAAA,EAAyD;AAChG,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA8B,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,iBAAA,CAAA,EAAqB,EAAE,SAAA,EAAU,EAAG,IAAI,CAAA;AAAA,EACrG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,cAAA,CAAe,YAAA,EAAsB,IAAA,EAAwD;AACjG,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA6B,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,gBAAA,CAAA,EAAoB,EAAE,YAAA,EAAa,EAAG,IAAI,CAAA;AAAA,EACtG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAA,CAAQ,MAAA,EAAgB,IAAA,EAAiD;AAC7E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAqB,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,KAAA,CAAA,EAAS,EAAE,MAAA,EAAO,EAAG,IAAI,CAAA;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,UAAU,OAAA,EAA4F;AAC1G,IAAA,MAAM,MAAA,GAAuE;AAAA,MAC3E,OAAO,OAAA,EAAS;AAAA,KAClB;AACA,IAAA,IAAI,OAAA,EAAS,MAAA,EAAQ,MAAA,CAAO,QAAQ,IAAI,OAAA,CAAQ,MAAA;AAChD,IAAA,OAAO,IAAA,CAAK,KAAK,GAAA,CAAuB,CAAA,EAAG,KAAK,IAAI,CAAA,MAAA,CAAA,EAAU,QAAQ,OAAO,CAAA;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,UAAA,CAAW,OAAA,EAA4B,IAAA,EAAoD;AAC/F,IAAA,OAAO,IAAA,CAAK,KAAK,KAAA,CAA0B,CAAA,EAAG,KAAK,IAAI,CAAA,KAAA,CAAA,EAAS,SAAS,IAAI,CAAA;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,UAAA,CAAW,MAAA,EAAgB,IAAA,EAAoE;AACnG,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,KAAA,CAAA,EAAS,EAAE,MAAA,EAAO,EAAG,IAAI,CAAA;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,cAAA,CAAe,OAAA,EAAgC,IAAA,EAAoE;AACvH,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAA,gBAAA,CAAA,EAAoB,SAAS,IAAI,CAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,oBAAA,CAAqB,OAAA,EAAsC,IAAA,EAAoE;AACnI,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAA,uBAAA,CAAA,EAA2B,SAAS,IAAI,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAAA,CAAqB,OAAA,EAAsC,IAAA,EAAoE;AACnI,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAA,uBAAA,CAAA,EAA2B,SAAS,IAAI,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,wBAAA,CAAyB,OAAA,EAAoC,IAAA,EAAoE;AACrI,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAA,qBAAA,CAAA,EAAyB,SAAS,IAAI,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,wBAAA,CAAyB,OAAA,EAAoC,IAAA,EAAoE;AACrI,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAA,qBAAA,CAAA,EAAyB,SAAS,IAAI,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WAAA,CAAY,OAAA,EAA6B,IAAA,EAAqD;AAClG,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAA0B,CAAA,EAAG,KAAK,IAAI,CAAA,aAAA,CAAA,EAAiB,SAAS,IAAI,CAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAA,CAAc,MAAA,EAAgB,IAAA,EAAoE;AACtG,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,eAAA,CAAA,EAAmB,EAAE,MAAA,EAAO,EAAG,IAAI,CAAA;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAa,IAAA,EAA4C;AAC7D,IAAA,MAAM,MAAkB,EAAC;AACzB,IAAA,IAAI,MAAA,GAAwB,IAAA;AAE5B,IAAA,GAAG;AACD,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,GAAS,EAAE,MAAA,EAAQ,GAAG,IAAA,EAAK,GAAI,EAAE,GAAG,MAAM,CAAA;AAC9E,MAAA,GAAA,CAAI,IAAA,CAAK,GAAG,MAAA,CAAO,IAAI,CAAA;AACvB,MAAA,MAAA,GAAS,MAAA,CAAO,KAAK,UAAA,IAAc,IAAA;AAAA,IACrC,CAAA,QAAS,MAAA;AAET,IAAA,OAAO,GAAA;AAAA,EACT;AACF","file":"index.js","sourcesContent":["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.authKey}`;\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"]}
@@ -4,7 +4,7 @@ var AuthClient = class {
4
4
  this.http = http;
5
5
  }
6
6
  get path() {
7
- return `/auth/${this.http.bucketKey}`;
7
+ return `/auth/${this.http.authKey}`;
8
8
  }
9
9
  // ── Sign-up ────────────────────────────────────────────────────────────────
10
10
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/auth/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["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"]}
1
+ {"version":3,"sources":["../../src/auth/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["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.authKey}`;\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"]}
@@ -25,9 +25,9 @@ interface RequestOptions {
25
25
  headers?: Record<string, string>;
26
26
  }
27
27
  interface HydrousConfig {
28
- /** Your HydrousDB API key */
29
- apiKey: string;
30
- /** Your bucket key */
28
+ /** Your HydrousDB auth service key */
29
+ authKey: string;
30
+ /** Your bucket key (used for records, analytics, and buckets services) */
31
31
  bucketKey: string;
32
32
  /** Override the default base URL (advanced use) */
33
33
  baseUrl?: string;
@@ -432,7 +432,7 @@ interface HydrousErrorBody {
432
432
  }
433
433
 
434
434
  interface HttpClientConfig {
435
- apiKey: string;
435
+ authKey: string;
436
436
  bucketKey: string;
437
437
  baseUrl?: string;
438
438
  timeout?: number;
@@ -441,7 +441,7 @@ interface HttpClientConfig {
441
441
  declare class HttpClient {
442
442
  readonly baseUrl: string;
443
443
  readonly bucketKey: string;
444
- private readonly apiKey;
444
+ readonly authKey: string;
445
445
  private readonly timeout;
446
446
  private readonly retries;
447
447
  constructor(config: HttpClientConfig);
@@ -25,9 +25,9 @@ interface RequestOptions {
25
25
  headers?: Record<string, string>;
26
26
  }
27
27
  interface HydrousConfig {
28
- /** Your HydrousDB API key */
29
- apiKey: string;
30
- /** Your bucket key */
28
+ /** Your HydrousDB auth service key */
29
+ authKey: string;
30
+ /** Your bucket key (used for records, analytics, and buckets services) */
31
31
  bucketKey: string;
32
32
  /** Override the default base URL (advanced use) */
33
33
  baseUrl?: string;
@@ -432,7 +432,7 @@ interface HydrousErrorBody {
432
432
  }
433
433
 
434
434
  interface HttpClientConfig {
435
- apiKey: string;
435
+ authKey: string;
436
436
  bucketKey: string;
437
437
  baseUrl?: string;
438
438
  timeout?: number;
@@ -441,7 +441,7 @@ interface HttpClientConfig {
441
441
  declare class HttpClient {
442
442
  readonly baseUrl: string;
443
443
  readonly bucketKey: string;
444
- private readonly apiKey;
444
+ readonly authKey: string;
445
445
  private readonly timeout;
446
446
  private readonly retries;
447
447
  constructor(config: HttpClientConfig);
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { RecordsClient } from './records/index.mjs';
2
2
  import { AuthClient } from './auth/index.mjs';
3
3
  import { AnalyticsClient } from './analytics/index.mjs';
4
- import { H as HydrousErrorBody, a as HydrousConfig } from './http-CIXLF5GV.mjs';
5
- export { A as AccountLockPayload, b as AccountLockResponse, c as AnalyticsQuery, d as AnalyticsQueryType, e as AnalyticsResponse, f as ApiMeta, g as AuthUser, B as BatchDeletePayload, h as BatchDeleteResponse, i as BatchInsertPayload, j as BatchInsertResponse, k as BatchResult, l as BatchUpdateItem, m as BatchUpdatePayload, n as BatchUpdateResponse, C as CountResult, D as DateRange, o as DeleteRecordResponse, p as DistributionItem, E as EmailVerifyConfirmPayload, q as EmailVerifyRequestPayload, F as FieldStatsResult, r as FieldTimeSeriesPoint, s as Filter, t as FilterOp, u as FilteredRecordsResult, G as GetRecordOptions, v as GetRecordResponse, w as GetSnapshotResponse, x as GetUserResponse, y as HistoryEntry, z as HydrousRecord, I as InsertRecordPayload, J as InsertRecordResponse, L as ListUsersResponse, M as MultiMetricItem, P as PaginationMeta, K as PasswordChangePayload, N as PasswordResetConfirmPayload, O as PasswordResetRequestPayload, Q as QueryOptions, R as QueryResponse, S as RecordData, T as RecordExistsInfo, U as RefreshSessionResponse, V as RequestOptions, W as SessionInfo, X as SignInPayload, Y as SignInResponse, Z as SignOutPayload, _ as SignUpPayload, $ as SignUpResponse, a0 as StorageStatsResult, a1 as SumResult, a2 as TimeSeriesPoint, a3 as TopNItem, a4 as UpdateRecordPayload, a5 as UpdateRecordResponse, a6 as UpdateUserPayload, a7 as UpdateUserResponse, a8 as ValidateSessionResponse } from './http-CIXLF5GV.mjs';
4
+ import { H as HydrousErrorBody, a as HydrousConfig } from './http-DbiqdKlw.mjs';
5
+ export { A as AccountLockPayload, b as AccountLockResponse, c as AnalyticsQuery, d as AnalyticsQueryType, e as AnalyticsResponse, f as ApiMeta, g as AuthUser, B as BatchDeletePayload, h as BatchDeleteResponse, i as BatchInsertPayload, j as BatchInsertResponse, k as BatchResult, l as BatchUpdateItem, m as BatchUpdatePayload, n as BatchUpdateResponse, C as CountResult, D as DateRange, o as DeleteRecordResponse, p as DistributionItem, E as EmailVerifyConfirmPayload, q as EmailVerifyRequestPayload, F as FieldStatsResult, r as FieldTimeSeriesPoint, s as Filter, t as FilterOp, u as FilteredRecordsResult, G as GetRecordOptions, v as GetRecordResponse, w as GetSnapshotResponse, x as GetUserResponse, y as HistoryEntry, z as HydrousRecord, I as InsertRecordPayload, J as InsertRecordResponse, L as ListUsersResponse, M as MultiMetricItem, P as PaginationMeta, K as PasswordChangePayload, N as PasswordResetConfirmPayload, O as PasswordResetRequestPayload, Q as QueryOptions, R as QueryResponse, S as RecordData, T as RecordExistsInfo, U as RefreshSessionResponse, V as RequestOptions, W as SessionInfo, X as SignInPayload, Y as SignInResponse, Z as SignOutPayload, _ as SignUpPayload, $ as SignUpResponse, a0 as StorageStatsResult, a1 as SumResult, a2 as TimeSeriesPoint, a3 as TopNItem, a4 as UpdateRecordPayload, a5 as UpdateRecordResponse, a6 as UpdateUserPayload, a7 as UpdateUserResponse, a8 as ValidateSessionResponse } from './http-DbiqdKlw.mjs';
6
6
 
7
7
  /**
8
8
  * Thrown for any non-2xx response from the HydrousDB API.
@@ -39,7 +39,7 @@ declare class HydrousTimeoutError extends Error {
39
39
  * import { createClient } from 'hydrousdb';
40
40
  *
41
41
  * const db = createClient({
42
- * apiKey: 'your-api-key',
42
+ * authKey: 'your-auth-key',
43
43
  * bucketKey: 'your-bucket',
44
44
  * });
45
45
  *
@@ -66,7 +66,7 @@ declare class HydrousClient {
66
66
  * Create a HydrousDB client.
67
67
  *
68
68
  * @example
69
- * const db = createClient({ apiKey: '...', bucketKey: '...' });
69
+ * const db = createClient({ authKey: '...', bucketKey: '...' });
70
70
  */
71
71
  declare function createClient(config: HydrousConfig): HydrousClient;
72
72
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { RecordsClient } from './records/index.js';
2
2
  import { AuthClient } from './auth/index.js';
3
3
  import { AnalyticsClient } from './analytics/index.js';
4
- import { H as HydrousErrorBody, a as HydrousConfig } from './http-CIXLF5GV.js';
5
- export { A as AccountLockPayload, b as AccountLockResponse, c as AnalyticsQuery, d as AnalyticsQueryType, e as AnalyticsResponse, f as ApiMeta, g as AuthUser, B as BatchDeletePayload, h as BatchDeleteResponse, i as BatchInsertPayload, j as BatchInsertResponse, k as BatchResult, l as BatchUpdateItem, m as BatchUpdatePayload, n as BatchUpdateResponse, C as CountResult, D as DateRange, o as DeleteRecordResponse, p as DistributionItem, E as EmailVerifyConfirmPayload, q as EmailVerifyRequestPayload, F as FieldStatsResult, r as FieldTimeSeriesPoint, s as Filter, t as FilterOp, u as FilteredRecordsResult, G as GetRecordOptions, v as GetRecordResponse, w as GetSnapshotResponse, x as GetUserResponse, y as HistoryEntry, z as HydrousRecord, I as InsertRecordPayload, J as InsertRecordResponse, L as ListUsersResponse, M as MultiMetricItem, P as PaginationMeta, K as PasswordChangePayload, N as PasswordResetConfirmPayload, O as PasswordResetRequestPayload, Q as QueryOptions, R as QueryResponse, S as RecordData, T as RecordExistsInfo, U as RefreshSessionResponse, V as RequestOptions, W as SessionInfo, X as SignInPayload, Y as SignInResponse, Z as SignOutPayload, _ as SignUpPayload, $ as SignUpResponse, a0 as StorageStatsResult, a1 as SumResult, a2 as TimeSeriesPoint, a3 as TopNItem, a4 as UpdateRecordPayload, a5 as UpdateRecordResponse, a6 as UpdateUserPayload, a7 as UpdateUserResponse, a8 as ValidateSessionResponse } from './http-CIXLF5GV.js';
4
+ import { H as HydrousErrorBody, a as HydrousConfig } from './http-DbiqdKlw.js';
5
+ export { A as AccountLockPayload, b as AccountLockResponse, c as AnalyticsQuery, d as AnalyticsQueryType, e as AnalyticsResponse, f as ApiMeta, g as AuthUser, B as BatchDeletePayload, h as BatchDeleteResponse, i as BatchInsertPayload, j as BatchInsertResponse, k as BatchResult, l as BatchUpdateItem, m as BatchUpdatePayload, n as BatchUpdateResponse, C as CountResult, D as DateRange, o as DeleteRecordResponse, p as DistributionItem, E as EmailVerifyConfirmPayload, q as EmailVerifyRequestPayload, F as FieldStatsResult, r as FieldTimeSeriesPoint, s as Filter, t as FilterOp, u as FilteredRecordsResult, G as GetRecordOptions, v as GetRecordResponse, w as GetSnapshotResponse, x as GetUserResponse, y as HistoryEntry, z as HydrousRecord, I as InsertRecordPayload, J as InsertRecordResponse, L as ListUsersResponse, M as MultiMetricItem, P as PaginationMeta, K as PasswordChangePayload, N as PasswordResetConfirmPayload, O as PasswordResetRequestPayload, Q as QueryOptions, R as QueryResponse, S as RecordData, T as RecordExistsInfo, U as RefreshSessionResponse, V as RequestOptions, W as SessionInfo, X as SignInPayload, Y as SignInResponse, Z as SignOutPayload, _ as SignUpPayload, $ as SignUpResponse, a0 as StorageStatsResult, a1 as SumResult, a2 as TimeSeriesPoint, a3 as TopNItem, a4 as UpdateRecordPayload, a5 as UpdateRecordResponse, a6 as UpdateUserPayload, a7 as UpdateUserResponse, a8 as ValidateSessionResponse } from './http-DbiqdKlw.js';
6
6
 
7
7
  /**
8
8
  * Thrown for any non-2xx response from the HydrousDB API.
@@ -39,7 +39,7 @@ declare class HydrousTimeoutError extends Error {
39
39
  * import { createClient } from 'hydrousdb';
40
40
  *
41
41
  * const db = createClient({
42
- * apiKey: 'your-api-key',
42
+ * authKey: 'your-auth-key',
43
43
  * bucketKey: 'your-bucket',
44
44
  * });
45
45
  *
@@ -66,7 +66,7 @@ declare class HydrousClient {
66
66
  * Create a HydrousDB client.
67
67
  *
68
68
  * @example
69
- * const db = createClient({ apiKey: '...', bucketKey: '...' });
69
+ * const db = createClient({ authKey: '...', bucketKey: '...' });
70
70
  */
71
71
  declare function createClient(config: HydrousConfig): HydrousClient;
72
72
 
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ var DEFAULT_RETRIES = 2;
32
32
  var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
33
33
  var HttpClient = class {
34
34
  constructor(config) {
35
- this.apiKey = config.apiKey;
35
+ this.authKey = config.authKey;
36
36
  this.bucketKey = config.bucketKey;
37
37
  this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
38
38
  this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
@@ -358,7 +358,7 @@ var AuthClient = class {
358
358
  this.http = http;
359
359
  }
360
360
  get path() {
361
- return `/auth/${this.http.bucketKey}`;
361
+ return `/auth/${this.http.authKey}`;
362
362
  }
363
363
  // ── Sign-up ────────────────────────────────────────────────────────────────
364
364
  /**
@@ -786,7 +786,7 @@ var AnalyticsClient = class {
786
786
  // src/client.ts
787
787
  var HydrousClient = class {
788
788
  constructor(config) {
789
- if (!config.apiKey) throw new Error("[hydrousdb] apiKey is required");
789
+ if (!config.authKey) throw new Error("[hydrousdb] authKey is required");
790
790
  if (!config.bucketKey) throw new Error("[hydrousdb] bucketKey is required");
791
791
  this.http = new HttpClient(config);
792
792
  this.records = new RecordsClient(this.http);