@rebasepro/client 0.2.3 → 0.2.4

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rebasepro/client",
3
3
  "type": "module",
4
- "version": "0.2.3",
4
+ "version": "0.2.4",
5
5
  "description": "HTTP SDK client for the Rebase custom backend",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/rebaseco"
@@ -30,9 +30,9 @@
30
30
  "./package.json": "./package.json"
31
31
  },
32
32
  "dependencies": {
33
- "@rebasepro/common": "0.2.3",
34
- "@rebasepro/utils": "0.2.3",
35
- "@rebasepro/types": "0.2.3"
33
+ "@rebasepro/common": "0.2.4",
34
+ "@rebasepro/types": "0.2.4",
35
+ "@rebasepro/utils": "0.2.4"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@jest/globals": "^29.7.0",
package/src/admin.ts CHANGED
@@ -16,7 +16,6 @@ export interface RebaseRole {
16
16
  name: string;
17
17
  isAdmin: boolean;
18
18
  defaultPermissions: Record<string, unknown> | null;
19
- config: Record<string, unknown> | null;
20
19
  }
21
20
 
22
21
  export interface CreateAdminOptions {
@@ -76,14 +75,14 @@ export function createAdmin(transport: Transport, options?: CreateAdminOptions)
76
75
  return transport.request<{ role: RebaseRole }>(adminPath + "/roles/" + encodeURIComponent(roleId), { method: "GET" });
77
76
  }
78
77
 
79
- async function createRole(data: { id: string, name: string, isAdmin?: boolean, defaultPermissions?: Record<string, unknown>, config?: Record<string, unknown> }) {
78
+ async function createRole(data: { id: string, name: string, isAdmin?: boolean, defaultPermissions?: Record<string, unknown> }) {
80
79
  return transport.request<{ role: RebaseRole }>(adminPath + "/roles", {
81
80
  method: "POST",
82
81
  body: JSON.stringify(data)
83
82
  });
84
83
  }
85
84
 
86
- async function updateRole(roleId: string, data: { name?: string, isAdmin?: boolean, defaultPermissions?: Record<string, unknown>, config?: Record<string, unknown> }) {
85
+ async function updateRole(roleId: string, data: { name?: string, isAdmin?: boolean, defaultPermissions?: Record<string, unknown> }) {
87
86
  return transport.request<{ role: RebaseRole }>(adminPath + "/roles/" + encodeURIComponent(roleId), {
88
87
  method: "PUT",
89
88
  body: JSON.stringify(data)
package/src/auth.ts CHANGED
@@ -29,7 +29,9 @@ export type AuthChangeEvent = "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "
29
29
  export interface AuthConfig {
30
30
  needsSetup: boolean;
31
31
  registrationEnabled: boolean;
32
- emailServiceEnabled: boolean;
32
+ emailServiceEnabled?: boolean;
33
+ passwordReset?: boolean;
34
+ emailVerification?: boolean;
33
35
  enabledProviders: string[];
34
36
  }
35
37
 
package/src/index.ts CHANGED
@@ -25,9 +25,15 @@ export interface CreateRebaseClientOptions extends RebaseClientConfig {
25
25
 
26
26
  import { RebaseWebSocketClient } from "./websocket";
27
27
  import { RebaseClient as BaseRebaseClient, RebaseData, CollectionAccessor, StorageSource } from "@rebasepro/types";
28
+ export type { Entity, FindResponse } from "@rebasepro/types";
28
29
  import { toSnakeCase } from "@rebasepro/utils";
29
30
 
30
- export type RebaseClient<DB = Record<string, unknown>> = BaseRebaseClient<DB> & {
31
+ type KebabToCamelCase<S extends string> =
32
+ S extends `${infer T}-${infer U}`
33
+ ? `${T}${Capitalize<KebabToCamelCase<U>>}`
34
+ : S;
35
+
36
+ export type RebaseClient<DB = Record<string, unknown>> = Omit<BaseRebaseClient<DB>, "data"> & {
31
37
  setToken: (token: string | null) => void;
32
38
  setAuthTokenGetter: (getter: () => Promise<string | null>) => void;
33
39
  setOnUnauthorized: (handler: () => Promise<boolean>) => void;
@@ -39,15 +45,17 @@ export type RebaseClient<DB = Record<string, unknown>> = BaseRebaseClient<DB> &
39
45
  ws?: RebaseWebSocketClient;
40
46
  storage?: StorageSource;
41
47
  call: <T = unknown>(endpoint: string, payload?: unknown) => Promise<T>;
42
- data: RebaseData & {
43
- collection<K extends keyof DB>(slug: Extract<K, string>): CollectionClient<
44
- DB[K] extends { Row: infer R extends Record<string, unknown> } ? R : Record<string, unknown>
48
+ data: {
49
+ collection<S extends string>(slug: S): CollectionClient<
50
+ KebabToCamelCase<S> extends keyof DB
51
+ ? (DB[KebabToCamelCase<S>] extends { Row: infer R extends Record<string, unknown> } ? R : Record<string, unknown>)
52
+ : Record<string, unknown>
45
53
  >;
46
54
  } & {
47
55
  [K in keyof DB]: CollectionClient<
48
56
  DB[K] extends { Row: infer R extends Record<string, unknown> } ? R : Record<string, unknown>
49
57
  >;
50
- };
58
+ } & RebaseData;
51
59
  };
52
60
 
53
61
  import { createStorage } from "./storage";
package/src/transport.ts CHANGED
@@ -169,15 +169,23 @@ headers });
169
169
  if (res.status === 204) return undefined as T; // SAFETY: HTTP 204 No Content has no body
170
170
 
171
171
  const text = await res.text().catch(() => "");
172
- let body: any = {};
172
+ let body: Record<string, unknown> = {};
173
173
  if (text) {
174
174
  try {
175
- body = JSON.parse(text, rebaseReviver);
175
+ body = JSON.parse(text, rebaseReviver) as Record<string, unknown>;
176
176
  } catch (e) {
177
177
  // If not valid JSON, fallback
178
178
  }
179
179
  }
180
180
 
181
+ const getErrorField = (obj: Record<string, unknown>, field: string): unknown => {
182
+ const err = obj?.error;
183
+ if (err && typeof err === "object" && err !== null && field in (err as Record<string, unknown>)) {
184
+ return (err as Record<string, unknown>)[field];
185
+ }
186
+ return obj?.[field];
187
+ };
188
+
181
189
  if (res.status === 401 && onUnauthorizedHandler) {
182
190
  const retried = await onUnauthorizedHandler();
183
191
  if (retried) {
@@ -195,7 +203,7 @@ headers });
195
203
  headers: retryHeaders });
196
204
  if (retryRes.status === 204) return undefined as T; // SAFETY: HTTP 204 No Content has no body
197
205
  const retryText = await retryRes.text().catch(() => "");
198
- let retryBody: any = {};
206
+ let retryBody: Record<string, unknown> = {};
199
207
  if (retryText) {
200
208
  try {
201
209
  retryBody = JSON.parse(retryText, rebaseReviver);
@@ -209,9 +217,9 @@ headers: retryHeaders });
209
217
  }
210
218
  throw new RebaseApiError(
211
219
  retryRes.status,
212
- retryBody?.error?.message || retryBody?.message || fallbackMessage || `Request failed with status ${retryRes.status}`,
213
- retryBody?.error?.code || retryBody?.code,
214
- retryBody?.error?.details || retryBody?.details
220
+ String(getErrorField(retryBody, "message") || fallbackMessage || `Request failed with status ${retryRes.status}`),
221
+ getErrorField(retryBody, "code") as string | undefined,
222
+ getErrorField(retryBody, "details")
215
223
  );
216
224
  }
217
225
  return retryBody as T;
@@ -226,9 +234,9 @@ headers: retryHeaders });
226
234
  }
227
235
  throw new RebaseApiError(
228
236
  res.status,
229
- body?.error?.message || body?.message || fallbackMessage || `Request failed with status ${res.status}`,
230
- body?.error?.code || body?.code,
231
- body?.error?.details || body?.details
237
+ String(getErrorField(body, "message") || fallbackMessage || `Request failed with status ${res.status}`),
238
+ getErrorField(body, "code") as string | undefined,
239
+ getErrorField(body, "details")
232
240
  );
233
241
  }
234
242