@roundtable-bb/sdk 0.1.6 → 0.1.12

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/src/request.ts CHANGED
@@ -1,36 +1,74 @@
1
1
  export interface RoundtableClientOpts {
2
- baseUrl: string
3
- token?: string
2
+ baseURL: string;
3
+ token?: string;
4
+ }
5
+
6
+ interface RouteAuth {
7
+ acceptsApiKey?: boolean;
8
+ acceptsBetterAuth?: boolean;
9
+ acceptsTenantJwt?: boolean;
10
+ requiresToken?: boolean;
11
+ tenantUseCredentials?: boolean;
4
12
  }
5
13
 
6
14
  export async function request<T>(
7
15
  opts: RoundtableClientOpts,
8
16
  method: string,
9
17
  path: string,
10
- options?: { body?: unknown; query?: Record<string, unknown>; useCredentials?: boolean },
18
+ options?: {
19
+ body?: unknown;
20
+ query?: Record<string, unknown>;
21
+ useCredentials?: boolean;
22
+ routeAuth?: RouteAuth;
23
+ },
11
24
  ): Promise<T> {
12
- const url = new URL(`${opts.baseUrl}${path}`)
25
+ const routeAuth = options?.routeAuth;
26
+ let useCredentials = options?.useCredentials ?? false;
27
+
28
+ // Decide auth strategy
29
+ if (routeAuth) {
30
+ // TenantClient: use credentials if explicitly required by route
31
+ if (routeAuth.tenantUseCredentials) {
32
+ useCredentials = true;
33
+ }
34
+ // If token is available, use it (prefer token over credentials)
35
+ else if (opts.token && routeAuth.acceptsApiKey) {
36
+ useCredentials = false;
37
+ }
38
+ // If no token but route accepts better-auth: use credentials
39
+ else if (!opts.token && routeAuth.acceptsBetterAuth) {
40
+ useCredentials = true;
41
+ }
42
+ // Otherwise: make request without auth (backend will respond 401/403 if needed)
43
+ }
44
+
45
+ const url = new URL(`${opts.baseURL}${path}`);
13
46
  if (options?.query) {
14
47
  for (const [k, v] of Object.entries(options.query)) {
15
- if (v !== undefined && v !== null) url.searchParams.set(k, String(v))
48
+ if (v !== undefined && v !== null) url.searchParams.set(k, String(v));
16
49
  }
17
50
  }
18
51
 
19
52
  const res = await fetch(url.toString(), {
20
53
  method,
21
- credentials: options?.useCredentials ? 'include' : undefined,
54
+ credentials: useCredentials ? 'include' : undefined,
22
55
  headers: {
23
- ...(options?.body !== undefined ? { 'Content-Type': 'application/json' } : {}),
24
- ...(opts.token ? { Authorization: `Bearer ${opts.token}` } : {}),
56
+ ...(options?.body !== undefined
57
+ ? { 'Content-Type': 'application/json' }
58
+ : {}),
59
+ ...(opts.token && !useCredentials
60
+ ? { Authorization: `Bearer ${opts.token}` }
61
+ : {}),
25
62
  },
26
- body: options?.body !== undefined ? JSON.stringify(options.body) : undefined,
27
- })
63
+ body:
64
+ options?.body !== undefined ? JSON.stringify(options.body) : undefined,
65
+ });
28
66
 
29
- if (res.status === 204) return undefined as T
67
+ if (res.status === 204) return undefined as T;
30
68
  if (!res.ok) {
31
- const err = await res.json().catch(() => ({ message: res.statusText }))
32
- const msg = (err as { message?: string }).message ?? res.statusText
33
- throw Object.assign(new Error(msg), { status: res.status })
69
+ const err = await res.json().catch(() => ({ message: res.statusText }));
70
+ const msg = (err as { message?: string }).message ?? res.statusText;
71
+ throw Object.assign(new Error(msg), { status: res.status });
34
72
  }
35
- return res.json() as Promise<T>
73
+ return (await res.json()) as T;
36
74
  }