@rebasepro/client 0.4.0 → 0.6.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 ADDED
@@ -0,0 +1,164 @@
1
+ # @rebasepro/client
2
+
3
+ HTTP SDK client for the Rebase backend — typed CRUD, auth, storage, realtime WebSockets, admin, cron, and custom functions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @rebasepro/client
9
+ ```
10
+
11
+ ## What This Package Does
12
+
13
+ `@rebasepro/client` is the primary SDK for interacting with a Rebase backend from any JavaScript/TypeScript environment (browser, Node.js, edge). It creates a single client instance that provides:
14
+
15
+ - **Collection CRUD** with a fluent query builder (`.where()`, `.orderBy()`, `.limit()`, etc.)
16
+ - **Authentication** — email/password, Google, 10+ OAuth providers, session management, password reset
17
+ - **Admin** — user CRUD for admins
18
+ - **Storage** — file upload, download, delete, list
19
+ - **Realtime** — WebSocket subscriptions for collection and entity changes
20
+ - **Cron** — list, trigger, and manage cron jobs
21
+ - **Custom functions** — invoke server-side Hono route functions
22
+ - **Type-safe data proxy** — `client.data.products` auto-maps to the `products` collection
23
+
24
+ ## Key Exports
25
+
26
+ ### Client Factory
27
+
28
+ | Export | Description |
29
+ |---|---|
30
+ | `createRebaseClient<DB>(options)` | Create a `RebaseClient` instance. Generic `DB` parameter enables type-safe `client.data.*` access. |
31
+ | `RebaseClient<DB>` | The client type — includes `auth`, `admin`, `cron`, `functions`, `storage`, `ws`, `data`, `call`, and token management methods. |
32
+ | `CreateRebaseClientOptions` | Extends `RebaseClientConfig` with `auth`, `admin`, and `cron` sub-configs. |
33
+
34
+ ### Config
35
+
36
+ | Option | Type | Default | Description |
37
+ |---|---|---|---|
38
+ | `baseUrl` | `string` | `""` | Backend URL (e.g. `http://localhost:3001`) |
39
+ | `token` | `string` | — | Static auth token |
40
+ | `apiPath` | `string` | `"/api"` | API path prefix |
41
+ | `fetch` | `typeof fetch` | `globalThis.fetch` | Custom fetch implementation |
42
+ | `onUnauthorized` | `() => Promise<boolean>` | auto-refresh | Handler for 401 responses |
43
+ | `websocketUrl` | `string` | derived from `baseUrl` | WebSocket URL for realtime |
44
+
45
+ ### Collection Client
46
+
47
+ `client.data.collection("slug")` or `client.data.myCollection` returns a `CollectionClient<M>`:
48
+
49
+ | Method | Description |
50
+ |---|---|
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 |
57
+ | `where(col, op, val)` | Start a fluent query — returns `QueryBuilder` |
58
+ | `orderBy(col, dir?)` | Order results — returns `QueryBuilder` |
59
+ | `limit(n)` / `offset(n)` | Pagination — returns `QueryBuilder` |
60
+ | `search(str)` | Full-text search — returns `QueryBuilder` |
61
+ | `include(...rels)` | Include related entities — returns `QueryBuilder` |
62
+ | `listen(params, onUpdate, onError?)` | Realtime subscription (requires WebSocket) |
63
+ | `listenById(id, onUpdate, onError?)` | Realtime single-entity subscription |
64
+
65
+ ### Auth Module (`client.auth`)
66
+
67
+ | Method | Description |
68
+ |---|---|
69
+ | `signInWithEmail(email, password)` | Email/password login |
70
+ | `signUp(email, password, displayName?)` | Register new user |
71
+ | `signInWithGoogle(payload)` | Google OAuth (ID token, access token, or auth code) |
72
+ | `signInWithOAuth(providerId, payload)` | Generic OAuth for any provider |
73
+ | `signInWithGitHub/Microsoft/Apple/Facebook/Twitter/Discord/GitLab/Bitbucket/Slack/Spotify` | Provider-specific convenience methods |
74
+ | `signOut()` | Sign out and invalidate refresh token |
75
+ | `refreshSession()` | Refresh the access token |
76
+ | `getUser()` / `updateUser(updates)` | Current user profile |
77
+ | `resetPasswordForEmail(email)` | Request password reset |
78
+ | `resetPassword(token, password)` | Complete password reset |
79
+ | `changePassword(old, new)` | Change password (authenticated) |
80
+ | `sendVerificationEmail()` / `verifyEmail(token)` | Email verification |
81
+ | `getSessions()` / `revokeSession(id)` / `revokeAllSessions()` | Session management |
82
+ | `getAuthConfig()` | Fetch backend auth configuration |
83
+ | `getSession()` | Get current session (sync) |
84
+ | `onAuthStateChange(callback)` | Subscribe to auth events (`SIGNED_IN`, `SIGNED_OUT`, `TOKEN_REFRESHED`, `USER_UPDATED`) |
85
+
86
+ ### Storage Module (`client.storage`)
87
+
88
+ | Method | Description |
89
+ |---|---|
90
+ | `putObject({ file, key, metadata, bucket })` | Upload a file |
91
+ | `getSignedUrl(key, bucket?)` | Get download URL + metadata |
92
+ | `getObject(key, bucket?)` | Download file as `File` object |
93
+ | `deleteObject(key, bucket?)` | Delete a file |
94
+ | `listObjects(prefix, options?)` | List files with optional pagination |
95
+
96
+ ### Admin Module (`client.admin`)
97
+
98
+ | Method | Description |
99
+ |---|---|
100
+ | `listUsers()` / `listUsersPaginated(options?)` | List all users |
101
+ | `getUser(userId)` | Get a single user |
102
+ | `createUser(data)` | Create a user |
103
+ | `updateUser(userId, data)` | Update a user |
104
+ | `deleteUser(userId)` | Delete a user |
105
+ | `bootstrap()` | First-user bootstrap |
106
+
107
+ ### Functions Module (`client.functions`)
108
+
109
+ | Method | Description |
110
+ |---|---|
111
+ | `invoke<T>(name, payload?, options?)` | Call a custom backend function at `/api/functions/{name}` |
112
+
113
+ ### Other Exports
114
+
115
+ | Export | Description |
116
+ |---|---|
117
+ | `RebaseApiError` | Error class with `status`, `message`, `code`, `details` |
118
+ | `RebaseWebSocketClient` | WebSocket client for realtime subscriptions |
119
+ | `createCookieStorage(options?)` | Cookie-based auth storage adapter |
120
+ | `createMemoryStorage()` | In-memory auth storage adapter |
121
+ | `QueryBuilder` | Fluent query builder (also re-exported from `@rebasepro/common`) |
122
+ | `Entity`, `FindResponse` | Re-exported from `@rebasepro/types` |
123
+
124
+ ## Quick Start
125
+
126
+ ```ts
127
+ import { createRebaseClient } from "@rebasepro/client";
128
+
129
+ const client = createRebaseClient({
130
+ baseUrl: "http://localhost:3001",
131
+ });
132
+
133
+ // Auth
134
+ await client.auth.signInWithEmail("user@example.com", "password");
135
+
136
+ // CRUD
137
+ const { data: products } = await client.data.products.find({ limit: 10 });
138
+ const product = await client.data.products.create({ name: "Camera", price: 299 });
139
+ await client.data.products.update(product.id, { price: 249 });
140
+ await client.data.products.delete(product.id);
141
+
142
+ // Fluent queries
143
+ const { data: expensive } = await client.data.products
144
+ .where("price", ">=", 100)
145
+ .orderBy("price", "desc")
146
+ .limit(5)
147
+ .find();
148
+
149
+ // Custom function
150
+ const result = await client.functions.invoke("process-order", { orderId: "123" });
151
+
152
+ // Realtime
153
+ const unsubscribe = client.data.products.listen(
154
+ { limit: 50 },
155
+ (response) => console.log("Update:", response.data)
156
+ );
157
+ ```
158
+
159
+ ## Related Packages
160
+
161
+ - [`@rebasepro/common`](../common) — `QueryBuilder`, `buildRebaseData`, shared utilities
162
+ - [`@rebasepro/types`](../types) — `Entity`, `FindResponse`, `CollectionAccessor`, etc.
163
+ - [`@rebasepro/utils`](../utils) — `toSnakeCase` and other helpers
164
+ - [`@rebasepro/auth`](../auth) — React hook adapter that wraps `client.auth` for CMS integration
package/dist/admin.d.ts CHANGED
@@ -1,14 +1,6 @@
1
1
  import type { Transport } from "./transport";
2
- export interface AdminUser {
3
- uid: string;
4
- email: string;
5
- displayName: string | null;
6
- photoURL: string | null;
7
- provider: string;
8
- roles: string[];
9
- createdAt: string;
10
- updatedAt: string;
11
- }
2
+ import { AdminUser } from "@rebasepro/types";
3
+ export type { AdminUser };
12
4
  export interface CreateAdminOptions {
13
5
  adminPath?: string;
14
6
  }
package/dist/auth.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Transport } from "./transport";
2
+ import { AuthChangeEvent } from "@rebasepro/types";
2
3
  export interface RebaseUser {
3
4
  uid: string;
4
5
  email: string | null;
@@ -20,7 +21,7 @@ export interface RebaseSession {
20
21
  expiresAt: number;
21
22
  user: RebaseUser;
22
23
  }
23
- export type AuthChangeEvent = "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "USER_UPDATED";
24
+ export type { AuthChangeEvent };
24
25
  export interface AuthConfig {
25
26
  needsSetup: boolean;
26
27
  registrationEnabled: boolean;
package/dist/index.d.ts CHANGED
@@ -3,7 +3,9 @@ import { createAuth, CreateAuthOptions } from "./auth";
3
3
  import { createAdmin, CreateAdminOptions } from "./admin";
4
4
  import { createCron, CreateCronOptions } from "./cron";
5
5
  import { CollectionClient } from "./collection";
6
- import type { FunctionsClient } from "./functions";
6
+ import { createFunctionsClient } from "./functions";
7
+ import { RebaseWebSocketClient } from "./websocket";
8
+ import { RebaseClient, RebaseData, StorageSource } from "@rebasepro/types";
7
9
  export * from "./transport";
8
10
  export * from "./auth";
9
11
  export * from "./admin";
@@ -14,16 +16,30 @@ export * from "./websocket";
14
16
  export * from "./storage";
15
17
  export * from "./reviver";
16
18
  export * from "./functions";
19
+ export type { Entity, FindResponse } from "@rebasepro/types";
17
20
  export interface CreateRebaseClientOptions extends RebaseClientConfig {
18
21
  auth?: CreateAuthOptions;
19
22
  admin?: CreateAdminOptions;
20
23
  cron?: CreateCronOptions;
21
24
  }
22
- import { RebaseWebSocketClient } from "./websocket";
23
- import { RebaseClient as BaseRebaseClient, RebaseData, StorageSource } from "@rebasepro/types";
24
- export type { Entity, FindResponse } from "@rebasepro/types";
25
25
  type KebabToCamelCase<S extends string> = S extends `${infer T}-${infer U}` ? `${T}${Capitalize<KebabToCamelCase<U>>}` : S;
26
- export type RebaseClient<DB = Record<string, unknown>> = Omit<BaseRebaseClient<DB>, "data"> & {
26
+ type TypedDataLayer<DB> = {
27
+ collection<S extends string>(slug: S): CollectionClient<KebabToCamelCase<S> extends keyof DB ? (DB[KebabToCamelCase<S>] extends {
28
+ Row: infer R extends Record<string, unknown>;
29
+ } ? R : Record<string, unknown>) : Record<string, unknown>>;
30
+ } & {
31
+ [K in keyof DB]: CollectionClient<DB[K] extends {
32
+ Row: infer R extends Record<string, unknown>;
33
+ } ? R : Record<string, unknown>>;
34
+ } & RebaseData;
35
+ /**
36
+ * The return type of `createRebaseClient<DB>()`.
37
+ *
38
+ * This is `RebaseClient` (from `@rebasepro/types`) with all optional
39
+ * capabilities populated and the `data` layer narrowed to provide
40
+ * typed collection accessors when a `DB` schema generic is supplied.
41
+ */
42
+ export type CreateRebaseClientResult<DB = Record<string, unknown>> = Omit<RebaseClient, "data"> & {
27
43
  setToken: (token: string | null) => void;
28
44
  setAuthTokenGetter: (getter: () => Promise<string | null>) => void;
29
45
  setOnUnauthorized: (handler: () => Promise<boolean>) => void;
@@ -31,18 +47,10 @@ export type RebaseClient<DB = Record<string, unknown>> = Omit<BaseRebaseClient<D
31
47
  auth: ReturnType<typeof createAuth>;
32
48
  admin: ReturnType<typeof createAdmin>;
33
49
  cron: ReturnType<typeof createCron>;
34
- functions: FunctionsClient;
50
+ functions: ReturnType<typeof createFunctionsClient>;
35
51
  ws?: RebaseWebSocketClient;
36
- storage?: StorageSource;
52
+ storage: StorageSource;
37
53
  call: <T = unknown>(endpoint: string, payload?: unknown) => Promise<T>;
38
- data: {
39
- collection<S extends string>(slug: S): CollectionClient<KebabToCamelCase<S> extends keyof DB ? (DB[KebabToCamelCase<S>] extends {
40
- Row: infer R extends Record<string, unknown>;
41
- } ? R : Record<string, unknown>) : Record<string, unknown>>;
42
- } & {
43
- [K in keyof DB]: CollectionClient<DB[K] extends {
44
- Row: infer R extends Record<string, unknown>;
45
- } ? R : Record<string, unknown>>;
46
- } & RebaseData;
54
+ data: TypedDataLayer<DB>;
47
55
  };
48
- export declare function createRebaseClient<DB = Record<string, unknown>>(options: CreateRebaseClientOptions): RebaseClient<DB>;
56
+ export declare function createRebaseClient<DB = Record<string, unknown>>(options: CreateRebaseClientOptions): CreateRebaseClientResult<DB>;