@rebasepro/client 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,7 +16,7 @@ pnpm add @rebasepro/client
16
16
  - **Authentication** — email/password, Google, 10+ OAuth providers, session management, password reset
17
17
  - **Admin** — user CRUD for admins
18
18
  - **Storage** — file upload, download, delete, list
19
- - **Realtime** — WebSocket subscriptions for collection and entity changes
19
+ - **Realtime** — WebSocket subscriptions for collection and snapshot changes
20
20
  - **Cron** — list, trigger, and manage cron jobs
21
21
  - **Custom functions** — invoke server-side Hono route functions
22
22
  - **Type-safe data proxy** — `client.data.products` auto-maps to the `products` collection
@@ -49,18 +49,18 @@ pnpm add @rebasepro/client
49
49
  | Method | Description |
50
50
  |---|---|
51
51
  | `find(params?)` | Query with pagination. Returns `FindResponse<M>` (`{ data, meta }`) |
52
- | `findById(id)` | Fetch a single entity. Returns `Entity<M> \| undefined` |
53
- | `create(data, id?)` | Create entity. Returns `Entity<M>` |
54
- | `update(id, data)` | Update entity. Returns `Entity<M>` |
55
- | `delete(id)` | Delete entity |
56
- | `count(params?)` | Count matching entities |
52
+ | `findById(id)` | Fetch a single snapshot. Returns `Snapshot<M> \| undefined` |
53
+ | `create(data, id?)` | Create snapshot. Returns `Snapshot<M>` |
54
+ | `update(id, data)` | Update snapshot. Returns `Snapshot<M>` |
55
+ | `delete(id)` | Delete snapshot |
56
+ | `count(params?)` | Count matching snapshots |
57
57
  | `where(col, op, val)` | Start a fluent query — returns `QueryBuilder` |
58
58
  | `orderBy(col, dir?)` | Order results — returns `QueryBuilder` |
59
59
  | `limit(n)` / `offset(n)` | Pagination — returns `QueryBuilder` |
60
60
  | `search(str)` | Full-text search — returns `QueryBuilder` |
61
- | `include(...rels)` | Include related entities — returns `QueryBuilder` |
61
+ | `include(...rels)` | Include related snapshots — returns `QueryBuilder` |
62
62
  | `listen(params, onUpdate, onError?)` | Realtime subscription (requires WebSocket) |
63
- | `listenById(id, onUpdate, onError?)` | Realtime single-entity subscription |
63
+ | `listenById(id, onUpdate, onError?)` | Realtime single-snapshot subscription |
64
64
 
65
65
  ### Auth Module (`client.auth`)
66
66
 
@@ -119,7 +119,7 @@ pnpm add @rebasepro/client
119
119
  | `createCookieStorage(options?)` | Cookie-based auth storage adapter |
120
120
  | `createMemoryStorage()` | In-memory auth storage adapter |
121
121
  | `QueryBuilder` | Fluent query builder (also re-exported from `@rebasepro/common`) |
122
- | `Entity`, `FindResponse` | Re-exported from `@rebasepro/types` |
122
+ | `Snapshot`, `FindResponse` | Re-exported from `@rebasepro/types` |
123
123
 
124
124
  ## Quick Start
125
125
 
@@ -159,6 +159,6 @@ const unsubscribe = client.data.products.listen(
159
159
  ## Related Packages
160
160
 
161
161
  - [`@rebasepro/common`](../common) — `QueryBuilder`, `buildRebaseData`, shared utilities
162
- - [`@rebasepro/types`](../types) — `Entity`, `FindResponse`, `CollectionAccessor`, etc.
162
+ - [`@rebasepro/types`](../types) — `Snapshot`, `FindResponse`, `CollectionAccessor`, etc.
163
163
  - [`@rebasepro/utils`](../utils) — `toSnakeCase` and other helpers
164
164
  - [`@rebasepro/auth`](../auth) — React hook adapter that wraps `client.auth` for CMS integration
package/dist/auth.d.ts CHANGED
@@ -1,27 +1,16 @@
1
1
  import { Transport } from "./transport";
2
- import { AuthChangeEvent } from "@rebasepro/types";
3
- export interface RebaseUser {
2
+ import type { AuthChangeEvent, RebaseSession, AuthTokens, DeviceSession, User } from "@rebasepro/types";
3
+ export type { RebaseSession, AuthTokens, AuthChangeEvent, DeviceSession } from "@rebasepro/types";
4
+ /** @deprecated Use `User` from `@rebasepro/types` instead. */
5
+ export type RebaseUser = User;
6
+ /** @deprecated Use `AuthTokens` from `@rebasepro/types` instead. */
7
+ export type RebaseTokens = AuthTokens;
8
+ /** Minimal, non-sensitive user profile returned by {@link findUserByEmail}. */
9
+ export interface PublicUserProfile {
4
10
  uid: string;
5
- email: string | null;
6
11
  displayName: string | null;
7
12
  photoURL: string | null;
8
- emailVerified?: boolean;
9
- roles?: string[];
10
- providerId: string;
11
- isAnonymous: boolean;
12
13
  }
13
- export interface RebaseTokens {
14
- accessToken: string;
15
- refreshToken: string;
16
- accessTokenExpiresAt: number;
17
- }
18
- export interface RebaseSession {
19
- accessToken: string;
20
- refreshToken: string;
21
- expiresAt: number;
22
- user: RebaseUser;
23
- }
24
- export type { AuthChangeEvent };
25
14
  export interface AuthConfig {
26
15
  needsSetup: boolean;
27
16
  registrationEnabled: boolean;
@@ -42,15 +31,21 @@ export interface CreateAuthOptions {
42
31
  authPath?: string;
43
32
  autoRefresh?: boolean;
44
33
  persistSession?: boolean;
34
+ /**
35
+ * Authentication flow mode.
36
+ * - 'json' (default): Tokens are sent/received in JSON bodies. Refresh token is stored in local storage.
37
+ * - 'cookie': Refresh token is sent/received via httpOnly cookies. Access token remains in memory.
38
+ */
39
+ authFlowMode?: "json" | "cookie";
45
40
  }
46
41
  export declare function createAuth(transport: Transport, options?: CreateAuthOptions): {
47
42
  signInWithEmail: (email: string, password: string) => Promise<{
48
- user: RebaseUser;
43
+ user: User;
49
44
  accessToken: string;
50
45
  refreshToken: string;
51
46
  }>;
52
47
  signUp: (email: string, password: string, displayName?: string) => Promise<{
53
- user: RebaseUser;
48
+ user: User;
54
49
  accessToken: string;
55
50
  refreshToken: string;
56
51
  }>;
@@ -62,27 +57,27 @@ export declare function createAuth(transport: Transport, options?: CreateAuthOpt
62
57
  code: string;
63
58
  redirectUri: string;
64
59
  }) => Promise<{
65
- user: RebaseUser;
60
+ user: User;
66
61
  accessToken: string;
67
62
  refreshToken: string;
68
63
  }>;
69
64
  signInWithLinkedin: (code: string, redirectUri: string) => Promise<{
70
- user: RebaseUser;
65
+ user: User;
71
66
  accessToken: string;
72
67
  refreshToken: string;
73
68
  }>;
74
69
  signInWithOAuth: (providerId: string, payload: Record<string, unknown>) => Promise<{
75
- user: RebaseUser;
70
+ user: User;
76
71
  accessToken: string;
77
72
  refreshToken: string;
78
73
  }>;
79
74
  signInWithGitHub: (code: string, redirectUri: string) => Promise<{
80
- user: RebaseUser;
75
+ user: User;
81
76
  accessToken: string;
82
77
  refreshToken: string;
83
78
  }>;
84
79
  signInWithMicrosoft: (code: string, redirectUri: string) => Promise<{
85
- user: RebaseUser;
80
+ user: User;
86
81
  accessToken: string;
87
82
  refreshToken: string;
88
83
  }>;
@@ -93,52 +88,53 @@ export declare function createAuth(transport: Transport, options?: CreateAuthOpt
93
88
  };
94
89
  email?: string;
95
90
  }) => Promise<{
96
- user: RebaseUser;
91
+ user: User;
97
92
  accessToken: string;
98
93
  refreshToken: string;
99
94
  }>;
100
95
  signInWithFacebook: (code: string, redirectUri: string) => Promise<{
101
- user: RebaseUser;
96
+ user: User;
102
97
  accessToken: string;
103
98
  refreshToken: string;
104
99
  }>;
105
100
  signInWithTwitter: (code: string, redirectUri: string, codeVerifier: string) => Promise<{
106
- user: RebaseUser;
101
+ user: User;
107
102
  accessToken: string;
108
103
  refreshToken: string;
109
104
  }>;
110
105
  signInWithDiscord: (code: string, redirectUri: string) => Promise<{
111
- user: RebaseUser;
106
+ user: User;
112
107
  accessToken: string;
113
108
  refreshToken: string;
114
109
  }>;
115
110
  signInWithGitLab: (code: string, redirectUri: string) => Promise<{
116
- user: RebaseUser;
111
+ user: User;
117
112
  accessToken: string;
118
113
  refreshToken: string;
119
114
  }>;
120
115
  signInWithBitbucket: (code: string, redirectUri: string) => Promise<{
121
- user: RebaseUser;
116
+ user: User;
122
117
  accessToken: string;
123
118
  refreshToken: string;
124
119
  }>;
125
120
  signInWithSlack: (code: string, redirectUri: string) => Promise<{
126
- user: RebaseUser;
121
+ user: User;
127
122
  accessToken: string;
128
123
  refreshToken: string;
129
124
  }>;
130
125
  signInWithSpotify: (code: string, redirectUri: string) => Promise<{
131
- user: RebaseUser;
126
+ user: User;
132
127
  accessToken: string;
133
128
  refreshToken: string;
134
129
  }>;
135
130
  signOut: () => Promise<void>;
136
131
  refreshSession: () => Promise<RebaseSession>;
137
- getUser: () => Promise<RebaseUser>;
132
+ getUser: () => Promise<User>;
133
+ findUserByEmail: (email: string) => Promise<PublicUserProfile | null>;
138
134
  updateUser: (updates: {
139
135
  displayName?: string;
140
136
  photoURL?: string;
141
- }) => Promise<RebaseUser>;
137
+ }) => Promise<User>;
142
138
  resetPasswordForEmail: (email: string) => Promise<{
143
139
  success: boolean;
144
140
  message: string;
@@ -164,11 +160,11 @@ export declare function createAuth(transport: Transport, options?: CreateAuthOpt
164
160
  message: string;
165
161
  }>;
166
162
  verifyMagicLink: (token: string) => Promise<{
167
- user: RebaseUser;
163
+ user: User;
168
164
  accessToken: string;
169
165
  refreshToken: string;
170
166
  }>;
171
- getSessions: () => Promise<Record<string, unknown>[]>;
167
+ getSessions: () => Promise<DeviceSession[]>;
172
168
  revokeSession: (sessionId: string) => Promise<{
173
169
  success: boolean;
174
170
  }>;
@@ -178,6 +174,7 @@ export declare function createAuth(transport: Transport, options?: CreateAuthOpt
178
174
  getAuthConfig: () => Promise<AuthConfig>;
179
175
  getSession: () => RebaseSession | null;
180
176
  onAuthStateChange: (callback: (event: AuthChangeEvent, session: RebaseSession | null) => void) => () => boolean;
177
+ isInitialized: () => Promise<void>;
181
178
  };
182
179
  export interface CookieStorageOptions {
183
180
  path?: string;
@@ -1,21 +1,17 @@
1
1
  import { FindParams, Transport } from "./transport";
2
2
  import { RebaseWebSocketClient } from "./websocket";
3
- import { CollectionAccessor, LogicalCondition, WhereFilterOp, WhereValue } from "@rebasepro/types";
4
- import { QueryBuilder } from "./query_builder";
3
+ import { SDKCollectionClient } from "@rebasepro/types";
5
4
  /**
6
- * CollectionClient extends `CollectionAccessor` from `@rebasepro/types` so that
7
- * `client.data` can be passed directly to the core Rebase component.
5
+ * The concrete, HTTP-backed implementation of the public
6
+ * {@link SDKCollectionClient} contract flat rows (no Entity wrapper), plus
7
+ * fluent query-builder methods (`.where()`, `.orderBy()`, …).
8
8
  *
9
- * Additionally it exposes fluent query builder methods like `.where()`, `.orderBy()`.
9
+ * This is what `createRebaseClient().data.<collection>` returns. It is not a
10
+ * separate API from {@link SDKCollectionClient}; it only widens it with
11
+ * `count()`. Program against {@link SDKCollectionClient} when you want a
12
+ * transport-agnostic type.
10
13
  */
11
- export interface CollectionClient<M extends Record<string, unknown> = Record<string, unknown>> extends CollectionAccessor<M> {
12
- where<K extends keyof M & string>(column: K, operator: WhereFilterOp, value: WhereValue<M[K]>): QueryBuilder<M>;
13
- where(logicalCondition: LogicalCondition): QueryBuilder<M>;
14
- orderBy(column: keyof M & string, direction?: "asc" | "desc"): QueryBuilder<M>;
15
- limit(count: number): QueryBuilder<M>;
16
- offset(count: number): QueryBuilder<M>;
17
- search(searchString: string): QueryBuilder<M>;
18
- include(...relations: string[]): QueryBuilder<M>;
14
+ export interface CollectionClient<M extends Record<string, unknown> = Record<string, unknown>, I = Partial<M>, U = Partial<M>> extends SDKCollectionClient<M, I, U> {
19
15
  count(params?: FindParams): Promise<number>;
20
16
  }
21
17
  export declare function createCollectionClient<M extends Record<string, unknown> = Record<string, unknown>>(transport: Transport, slug: string, ws?: RebaseWebSocketClient): CollectionClient<M>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Client-side logic error (e.g. accessing an unknown collection when a typed
3
+ * dictionary is available). A subclass of {@link RebaseApiError}, so a single
4
+ * `catch (e) { if (e instanceof RebaseApiError) ... }` covers it too.
5
+ *
6
+ * The canonical definition now lives in `@rebasepro/types`; re-exported here to
7
+ * preserve the historical `import { RebaseClientError } from ".../errors"` path.
8
+ */
9
+ export { RebaseClientError } from "@rebasepro/types";
package/dist/index.d.ts CHANGED
@@ -6,20 +6,24 @@ import { createApiKeys, CreateApiKeysOptions } from "./api-keys";
6
6
  import { CollectionClient } from "./collection";
7
7
  import { createFunctionsClient } from "./functions";
8
8
  import { RebaseWebSocketClient } from "./websocket";
9
- import { RebaseClient, RebaseData, StorageSource, StorageSourceDefinition, StorageSourceRegistry } from "@rebasepro/types";
10
- export * from "./transport";
11
- export * from "./auth";
12
- export * from "./admin";
13
- export * from "./cron";
14
- export * from "./api-keys";
15
- export * from "./collection";
16
- export * from "./query_builder";
17
- export * from "./websocket";
18
- export * from "./storage";
19
- export * from "./storage-registry";
20
- export * from "./reviver";
21
- export * from "./functions";
22
- export type { Entity, FindResponse } from "@rebasepro/types";
9
+ import { InsertOf, RebaseClient, RebaseSdkData, RowOf, StorageSource, StorageSourceDefinition, StorageSourceRegistry, UpdateOf } from "@rebasepro/types";
10
+ export { RebaseApiError } from "./transport";
11
+ export { RebaseClientError } from "./errors";
12
+ export type { RebaseClientConfig, FindParams, FindResponse } from "./transport";
13
+ export type { CollectionClient } from "./collection";
14
+ export type { FindResult, SDKCollectionClient, SDKQueryBuilderInterface, PaginationMeta } from "@rebasepro/types";
15
+ export { QueryBuilder, or, and, cond } from "@rebasepro/common";
16
+ export { createCookieStorage, createMemoryStorage } from "./auth";
17
+ export type { AuthConfig, AuthStorage, CookieStorageOptions, CreateAuthOptions } from "./auth";
18
+ export type { RebaseSession, AuthTokens, AuthChangeEvent, DeviceSession } from "@rebasepro/types";
19
+ /** @deprecated Import `User` / `AuthTokens` from `@rebasepro/types` instead. */
20
+ export type { RebaseUser, RebaseTokens } from "./auth";
21
+ export type { CreateAdminOptions } from "./admin";
22
+ export type { AdminUser } from "./admin";
23
+ export type { CreateCronOptions } from "./cron";
24
+ export type { ApiKeyMasked, ApiKeyPermission, ApiKeyWithSecret, CreateApiKeyRequest, CreateApiKeysOptions, UpdateApiKeyRequest } from "./api-keys";
25
+ export type { FunctionInvokeOptions, FunctionsClient } from "./functions";
26
+ export { RebaseWebSocketClient } from "./websocket";
23
27
  export interface CreateRebaseClientOptions extends RebaseClientConfig {
24
28
  auth?: CreateAuthOptions;
25
29
  admin?: CreateAdminOptions;
@@ -42,15 +46,12 @@ export interface CreateRebaseClientOptions extends RebaseClientConfig {
42
46
  collections?: Record<string, string>;
43
47
  }
44
48
  type KebabToCamelCase<S extends string> = S extends `${infer T}-${infer U}` ? `${T}${Capitalize<KebabToCamelCase<U>>}` : S;
49
+ type DBEntry<DB, S extends string> = KebabToCamelCase<S> extends keyof DB ? DB[KebabToCamelCase<S>] : unknown;
45
50
  type TypedDataLayer<DB> = {
46
- collection<S extends string>(slug: S): CollectionClient<KebabToCamelCase<S> extends keyof DB ? (DB[KebabToCamelCase<S>] extends {
47
- Row: infer R extends Record<string, unknown>;
48
- } ? R : Record<string, unknown>) : Record<string, unknown>>;
51
+ collection<S extends string>(slug: S): CollectionClient<RowOf<DBEntry<DB, S>>, InsertOf<DBEntry<DB, S>>, UpdateOf<DBEntry<DB, S>>>;
49
52
  } & {
50
- [K in keyof DB]: CollectionClient<DB[K] extends {
51
- Row: infer R extends Record<string, unknown>;
52
- } ? R : Record<string, unknown>>;
53
- } & RebaseData;
53
+ [K in keyof DB]: CollectionClient<RowOf<DB[K]>, InsertOf<DB[K]>, UpdateOf<DB[K]>>;
54
+ } & RebaseSdkData;
54
55
  /**
55
56
  * The return type of `createRebaseClient<DB>()`.
56
57
  *
@@ -58,7 +59,7 @@ type TypedDataLayer<DB> = {
58
59
  * capabilities populated and the `data` layer narrowed to provide
59
60
  * typed collection accessors when a `DB` schema generic is supplied.
60
61
  */
61
- export type CreateRebaseClientResult<DB = Record<string, unknown>> = Omit<RebaseClient, "data"> & {
62
+ export type CreateRebaseClientResult<DB = Record<string, unknown>> = Omit<RebaseClient<DB>, "data" | "email"> & {
62
63
  setToken: (token: string | null) => void;
63
64
  setAuthTokenGetter: (getter: () => Promise<string | null>) => void;
64
65
  setOnUnauthorized: (handler: () => Promise<boolean>) => void;