@linabase/js 0.5.1 → 0.5.3

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/dist/index.d.ts CHANGED
@@ -20,6 +20,43 @@ interface CsvQueryResult {
20
20
  error: PostgrestError | null;
21
21
  count: number | null;
22
22
  }
23
+ /**
24
+ * Chainable query builder for a Postgres table.
25
+ *
26
+ * Created by `linabase.from(table)`. Every chained method returns the same
27
+ * client so you can keep adding filters, modifiers, and projections. Awaiting
28
+ * the chain (or calling a terminal method like `.single()` or `.csv()`)
29
+ * sends the request.
30
+ *
31
+ * Queries respect row-level security: signed-in users see only the rows
32
+ * their RLS policies allow.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const { data, error } = await linabase
37
+ * .from("posts")
38
+ * .select("id, title, author:profiles(name)")
39
+ * .eq("published", true)
40
+ * .order("created_at", { ascending: false })
41
+ * .limit(20);
42
+ * ```
43
+ *
44
+ * @example Insert
45
+ * ```ts
46
+ * await linabase
47
+ * .from("posts")
48
+ * .insert({ title: "Hello", body: "World" });
49
+ * ```
50
+ *
51
+ * @example Update + return updated rows
52
+ * ```ts
53
+ * const { data } = await linabase
54
+ * .from("posts")
55
+ * .update({ title: "Edited" })
56
+ * .eq("id", 42)
57
+ * .select();
58
+ * ```
59
+ */
23
60
  declare class DatabaseClient {
24
61
  private request;
25
62
  private table;
@@ -34,11 +71,36 @@ declare class DatabaseClient {
34
71
  private _abortSignal;
35
72
  private _schema;
36
73
  constructor(request: RequestFn$3, table: string);
37
- /** Select columns. Supports nested joins: "*, comments(*)" and aliases: "full_name:name" */
74
+ /**
75
+ * Pick which columns to return. Supports nested joins (`"*, comments(*)"`)
76
+ * and column aliases (`"full_name:name"`). When chained after a mutation
77
+ * (`insert` / `update` / `upsert` / `delete`), it switches the request to
78
+ * `Prefer: return=representation` so the modified rows come back.
79
+ *
80
+ * @param columns - Postgres-style column list. Defaults to `"*"`.
81
+ * @param options - `count` returns a row count alongside the data; `head`
82
+ * omits the rows entirely (useful for count-only queries).
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * await linabase.from("posts").select("id, title");
87
+ * await linabase.from("posts").select("*, author:profiles(name)");
88
+ * await linabase.from("posts").select("*", { count: "exact", head: true });
89
+ * ```
90
+ */
38
91
  select(columns?: string, options?: {
39
92
  count?: "exact" | "estimated" | "planned";
40
93
  head?: boolean;
41
94
  }): this;
95
+ /**
96
+ * Insert one row or many. Returns the inserted rows by default.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * await linabase.from("posts").insert({ title: "Hi" });
101
+ * await linabase.from("posts").insert([{ title: "A" }, { title: "B" }]);
102
+ * ```
103
+ */
42
104
  insert(data: Record<string, any> | Record<string, any>[], options?: {
43
105
  defaultToNull?: boolean;
44
106
  }): this;
@@ -48,7 +110,31 @@ declare class DatabaseClient {
48
110
  onConflict?: string;
49
111
  defaultToNull?: boolean;
50
112
  }): this;
113
+ /**
114
+ * Update rows that match the active filters.
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * await linabase
119
+ * .from("posts")
120
+ * .update({ published: true })
121
+ * .eq("id", 42);
122
+ * ```
123
+ */
51
124
  update(data: Record<string, any>): this;
125
+ /**
126
+ * Delete rows that match the active filters. **Always** combine with at
127
+ * least one filter (e.g. `.eq("id", x)`) — calling `.delete()` on a bare
128
+ * builder removes every row in the table.
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * await linabase
133
+ * .from("posts")
134
+ * .delete()
135
+ * .eq("id", 42);
136
+ * ```
137
+ */
52
138
  delete(options?: {
53
139
  count?: "exact" | "estimated" | "planned";
54
140
  }): this;
@@ -159,6 +245,23 @@ declare class RpcClient {
159
245
  }
160
246
 
161
247
  type RequestFn$2 = (path: string, options?: RequestInit) => Promise<Response>;
248
+ /**
249
+ * S3-compatible storage API for a project.
250
+ *
251
+ * Exposed via `linabase.storage`. Provides bucket management at the top
252
+ * level; per-bucket file operations live on {@link BucketClient}, accessed
253
+ * via `linabase.storage.from("bucket-name")`.
254
+ *
255
+ * @example
256
+ * ```ts
257
+ * // Top-level bucket management
258
+ * await linabase.storage.createBucket("avatars", { public: true });
259
+ * const { data: buckets } = await linabase.storage.listBuckets();
260
+ *
261
+ * // File operations on a bucket
262
+ * await linabase.storage.from("avatars").upload("alice.png", file);
263
+ * ```
264
+ */
162
265
  declare class StorageClient {
163
266
  private request;
164
267
  private baseUrl;
@@ -175,11 +278,50 @@ declare class StorageClient {
175
278
  error: any;
176
279
  }>;
177
280
  }
281
+ /**
282
+ * Operations against a single storage bucket: upload, download, list,
283
+ * delete, signed URLs, public URLs, move, and copy.
284
+ *
285
+ * Created by `linabase.storage.from(bucketName)`. Most file paths inside
286
+ * a bucket are arbitrary keys; common conventions are
287
+ * `userId/filename.ext` or `category/asset.ext`.
288
+ *
289
+ * @example
290
+ * ```ts
291
+ * const bucket = linabase.storage.from("avatars");
292
+ *
293
+ * await bucket.upload(`${user.id}/avatar.png`, file, { upsert: true });
294
+ *
295
+ * // Public bucket: anyone can fetch the URL.
296
+ * const { data: { publicUrl } } = bucket.getPublicUrl(`${user.id}/avatar.png`);
297
+ *
298
+ * // Private bucket: time-limited URL.
299
+ * const { data } = await bucket.createSignedUrl(`${user.id}/report.pdf`, 3600);
300
+ * ```
301
+ */
178
302
  declare class BucketClient {
179
303
  private request;
180
304
  private bucket;
181
305
  private baseUrl;
182
306
  constructor(request: RequestFn$2, bucket: string, baseUrl?: string);
307
+ /**
308
+ * Upload a file to the bucket at the given path.
309
+ *
310
+ * @param path - Object key inside the bucket (e.g. `userId/avatar.png`).
311
+ * @param file - File contents as `Blob`, `File`, or `ArrayBuffer`.
312
+ * @param options.contentType - Override the content type. Inferred from
313
+ * `File`/`Blob` when not set.
314
+ * @param options.upsert - If true, replaces an existing object at the same
315
+ * path. Defaults to false (returns an error if the path is taken).
316
+ *
317
+ * @example
318
+ * ```ts
319
+ * const file = e.target.files![0];
320
+ * await linabase.storage
321
+ * .from("avatars")
322
+ * .upload(`${userId}/avatar.png`, file, { upsert: true });
323
+ * ```
324
+ */
183
325
  upload(path: string, file: Blob | File | ArrayBuffer, options?: {
184
326
  contentType?: string;
185
327
  upsert?: boolean;
@@ -188,6 +330,18 @@ declare class BucketClient {
188
330
  data: any;
189
331
  error: any;
190
332
  }>;
333
+ /**
334
+ * Download an object as a `Blob`.
335
+ *
336
+ * @example
337
+ * ```ts
338
+ * const { data } = await linabase.storage.from("docs").download("file.pdf");
339
+ * if (data) {
340
+ * const url = URL.createObjectURL(data);
341
+ * window.open(url);
342
+ * }
343
+ * ```
344
+ */
191
345
  download(path: string): Promise<{
192
346
  data: Blob | null;
193
347
  error: any;
@@ -200,6 +354,19 @@ declare class BucketClient {
200
354
  data: any;
201
355
  error: any;
202
356
  }>;
357
+ /**
358
+ * Build a public URL for an object in a public bucket. No request is made;
359
+ * this just constructs the URL synchronously.
360
+ *
361
+ * For private buckets, use {@link createSignedUrl} instead.
362
+ *
363
+ * @example
364
+ * ```ts
365
+ * const { data: { publicUrl } } = linabase.storage
366
+ * .from("avatars")
367
+ * .getPublicUrl(`${userId}/avatar.png`, { transform: { width: 64, height: 64 } });
368
+ * ```
369
+ */
203
370
  getPublicUrl(path: string, options?: {
204
371
  transform?: {
205
372
  width?: number;
@@ -212,6 +379,18 @@ declare class BucketClient {
212
379
  publicUrl: string;
213
380
  };
214
381
  };
382
+ /**
383
+ * Generate a time-limited signed URL for a private object. Valid for
384
+ * `expiresIn` seconds.
385
+ *
386
+ * @example
387
+ * ```ts
388
+ * const { data } = await linabase.storage
389
+ * .from("docs")
390
+ * .createSignedUrl(`${userId}/report.pdf`, 3600);
391
+ * if (data) window.open(data.signedUrl);
392
+ * ```
393
+ */
215
394
  createSignedUrl(path: string, expiresIn: number): Promise<{
216
395
  data: {
217
396
  signedUrl: string;
@@ -277,6 +456,30 @@ interface AuthUser {
277
456
  created_at: string;
278
457
  updated_at: string;
279
458
  }
459
+ /**
460
+ * Authentication API for a Linabase project.
461
+ *
462
+ * Exposed via `linabase.auth` on the client returned by `createClient`. Handles
463
+ * sign-up, sign-in (password / magic-link / OAuth), session management, and
464
+ * — when called with a service-role key — server-side admin operations under
465
+ * `auth.admin`.
466
+ *
467
+ * Sessions are persisted in the configured storage (defaults to localStorage
468
+ * in the browser, in-memory in Node). The current access token is automatically
469
+ * attached to every database, storage, and function request.
470
+ *
471
+ * @example
472
+ * ```ts
473
+ * const { data, error } = await linabase.auth.signInWithPassword({
474
+ * email: "alice@example.com",
475
+ * password: "correct horse battery staple",
476
+ * });
477
+ *
478
+ * linabase.auth.onAuthStateChange((event, session) => {
479
+ * console.log(event, session?.user.email);
480
+ * });
481
+ * ```
482
+ */
280
483
  declare class AuthClient {
281
484
  private request;
282
485
  private listeners;
@@ -319,6 +522,22 @@ declare class AuthClient {
319
522
  data: AuthSession | null;
320
523
  error: any;
321
524
  }>;
525
+ /**
526
+ * Create a new user account with email + password.
527
+ *
528
+ * On success, the user is signed in and the session is persisted. Pass
529
+ * extra metadata via `data`; it is stored on the user record and
530
+ * available later as `user.user_metadata`.
531
+ *
532
+ * @example
533
+ * ```ts
534
+ * const { data, error } = await linabase.auth.signUp({
535
+ * email: "alice@example.com",
536
+ * password: "correct horse battery staple",
537
+ * data: { full_name: "Alice" },
538
+ * });
539
+ * ```
540
+ */
322
541
  signUp(params: {
323
542
  email: string;
324
543
  password: string;
@@ -327,6 +546,21 @@ declare class AuthClient {
327
546
  data: AuthSession | null;
328
547
  error: any;
329
548
  }>;
549
+ /**
550
+ * Sign in an existing user with email + password.
551
+ *
552
+ * Alias of {@link signInWithPassword}. On success, the session is persisted
553
+ * and subsequent SDK calls use the returned access token automatically.
554
+ *
555
+ * @example
556
+ * ```ts
557
+ * const { data, error } = await linabase.auth.signIn({
558
+ * email: "alice@example.com",
559
+ * password: "correct horse battery staple",
560
+ * });
561
+ * if (error) console.error(error.message);
562
+ * ```
563
+ */
330
564
  signIn(params: {
331
565
  email: string;
332
566
  password: string;
@@ -350,15 +584,96 @@ declare class AuthClient {
350
584
  data: AuthSession | null;
351
585
  error: any;
352
586
  }>;
587
+ /**
588
+ * Sign in with a device-bound secret. Intended for mobile clients that
589
+ * generate a random secret on first launch and persist it in the device
590
+ * keychain. No email or password is involved.
591
+ *
592
+ * Pass `create: true` on first launch to register a new anonymous user.
593
+ * Subsequent launches should call without `create` (or with `create: false`)
594
+ * to refuse silent account creation if the keychain entry was lost.
595
+ *
596
+ * Requires "Device-bound sign-ins" to be enabled in the project's Auth
597
+ * Settings.
598
+ *
599
+ * @example
600
+ * ```ts
601
+ * const secret = getOrCreateDeviceSecret();
602
+ * const { data, error } = await linabase.auth.signInWithDevice({
603
+ * deviceSecret: secret,
604
+ * create: true,
605
+ * });
606
+ * ```
607
+ */
608
+ signInWithDevice(params: {
609
+ deviceSecret: string;
610
+ create?: boolean;
611
+ data?: Record<string, unknown>;
612
+ }): Promise<{
613
+ data: AuthSession | null;
614
+ error: any;
615
+ }>;
616
+ /**
617
+ * Sign in with an Apple Game Center identity assertion. The mobile client
618
+ * obtains the assertion fields via
619
+ * `GKLocalPlayer.local.fetchItems(forIdentityVerificationSignature:)` (iOS
620
+ * 13.5+) and forwards them here. The project must have the app's bundle ID
621
+ * configured in the Game Center allowlist.
622
+ */
623
+ signInWithGameCenter(params: {
624
+ playerId: string;
625
+ bundleId: string;
626
+ publicKeyURL: string;
627
+ signature: string;
628
+ salt: string;
629
+ timestamp: number;
630
+ displayName?: string;
631
+ }): Promise<{
632
+ data: AuthSession | null;
633
+ error: any;
634
+ }>;
635
+ /**
636
+ * Sign in with a Google Play Games server auth code obtained via
637
+ * `PlayGamesSignInClient.requestServerSideAccess(serverClientId)`. The
638
+ * project must have the matching OAuth client configured in Auth Settings.
639
+ */
640
+ signInWithPlayGames(params: {
641
+ serverAuthCode: string;
642
+ redirectUri?: string;
643
+ }): Promise<{
644
+ data: AuthSession | null;
645
+ error: any;
646
+ }>;
353
647
  signInWithOAuth(params: {
354
648
  provider: OAuthProvider;
355
649
  redirectTo?: string;
356
650
  }): {
357
651
  url: string;
358
652
  };
653
+ /**
654
+ * Sign the current user out, clear the persisted session, and revoke the
655
+ * refresh token on the server. Fires a `SIGNED_OUT` event to listeners
656
+ * registered with `onAuthStateChange`.
657
+ *
658
+ * @example
659
+ * ```ts
660
+ * await linabase.auth.signOut();
661
+ * ```
662
+ */
359
663
  signOut(): Promise<{
360
664
  error: any;
361
665
  }>;
666
+ /**
667
+ * Return the current persisted session. Auto-refreshes if the access
668
+ * token is expired and a refresh token is available. Returns
669
+ * `{ session: null }` when the user isn't signed in.
670
+ *
671
+ * @example
672
+ * ```ts
673
+ * const { data: { session } } = await linabase.auth.getSession();
674
+ * if (session) console.log("Signed in as", session.user.email);
675
+ * ```
676
+ */
362
677
  getSession(): Promise<{
363
678
  data: {
364
679
  session: AuthSession | null;
@@ -451,6 +766,18 @@ declare class AuthClient {
451
766
  deleteUser(id: string): Promise<{
452
767
  error: any;
453
768
  }>;
769
+ listSessions(userId: string): Promise<{
770
+ data: any;
771
+ error: any;
772
+ }>;
773
+ deleteSession(userId: string, sessionId: string): Promise<{
774
+ data: any;
775
+ error: any;
776
+ }>;
777
+ deleteOtherSessions(userId: string, exceptSessionId?: string): Promise<{
778
+ data: any;
779
+ error: any;
780
+ }>;
454
781
  };
455
782
  get mfa(): {
456
783
  enroll(params: {
@@ -492,14 +819,44 @@ declare class AuthClient {
492
819
  }
493
820
 
494
821
  type RequestFn = (path: string, options?: RequestInit) => Promise<Response>;
822
+ /** Options for {@link FunctionsClient.invoke}. */
495
823
  interface FunctionInvokeOptions {
824
+ /** JSON body for POST, or query parameters for GET. */
496
825
  body?: Record<string, any>;
826
+ /** HTTP method. Defaults to `POST`. */
497
827
  method?: "GET" | "POST";
828
+ /** Extra request headers (merged with auth headers). */
498
829
  headers?: Record<string, string>;
499
830
  }
831
+ /**
832
+ * Invoke server-side functions registered with the project.
833
+ *
834
+ * Exposed via `linabase.functions`. The auth token, when set, is forwarded
835
+ * automatically so the function can identify the calling user.
836
+ *
837
+ * @example
838
+ * ```ts
839
+ * const { data, error } = await linabase.functions.invoke("send-welcome", {
840
+ * body: { userId: user.id },
841
+ * });
842
+ * ```
843
+ */
500
844
  declare class FunctionsClient {
501
845
  private request;
502
846
  constructor(request: RequestFn);
847
+ /**
848
+ * Call a function by name.
849
+ *
850
+ * @param name - Function slug as registered on the project.
851
+ * @param options - Body, method, and optional extra headers.
852
+ * @returns `{ data, error }` — `data` is the parsed JSON response, `error`
853
+ * is an object with `message` if the call failed (HTTP non-2xx or thrown).
854
+ *
855
+ * @example
856
+ * ```ts
857
+ * await linabase.functions.invoke("ping");
858
+ * ```
859
+ */
503
860
  invoke<T = any>(name: string, options?: FunctionInvokeOptions): Promise<{
504
861
  data: T | null;
505
862
  error: any;
@@ -545,23 +902,64 @@ interface LinabaseConfig {
545
902
  detectSessionInUrl?: boolean;
546
903
  };
547
904
  }
905
+ /**
906
+ * The Linabase client. Returned by {@link createClient}.
907
+ *
908
+ * Combines query, auth, storage, and function-invocation APIs behind a
909
+ * single object. Most apps create one client per project at startup and
910
+ * reuse it everywhere.
911
+ */
548
912
  interface LinabaseClient {
913
+ /** Start a query against a table in the project's `public` schema. */
549
914
  from: (table: string) => DatabaseClient;
915
+ /** Target a non-default schema (`auth`, `storage`, etc.) for the next query. */
550
916
  schema: (schemaName: string) => {
551
917
  from: (table: string) => DatabaseClient;
552
918
  };
919
+ /** Call a Postgres function (RPC). */
553
920
  rpc: (fn: string, args?: Record<string, any>) => ReturnType<RpcClient["call"]>;
921
+ /** S3-compatible object storage for the project. */
554
922
  storage: StorageClient;
923
+ /** User auth: sign in, sign up, sessions, OAuth, admin operations. */
555
924
  auth: AuthClient;
925
+ /** Invoke server-side functions. */
556
926
  functions: FunctionsClient;
557
927
  /** Realtime channel (stub; not yet supported). Returns a chainable no-op. */
558
928
  channel: (name: string) => any;
559
929
  /** Remove a realtime channel (stub; not yet supported). */
560
930
  removeChannel: (channel: any) => void;
931
+ /** Generate TypeScript types for the project's database schema. */
561
932
  generateTypes: () => Promise<string>;
562
933
  /** Returns a new client that targets the given branch via X-Branch header. */
563
934
  branch: (slug: string) => LinabaseClient;
564
935
  }
936
+ /**
937
+ * Create a Linabase client for a project.
938
+ *
939
+ * The client is the single entry point to the SDK. Every query, auth call,
940
+ * and storage operation goes through it. The same instance can be reused
941
+ * across the app; it tracks the user's session internally.
942
+ *
943
+ * @param config - Connection details. `url` is the project's Linabase API
944
+ * URL, and `anonKey` is the public API key (safe to ship in frontend
945
+ * bundles). Use `serviceRoleKey` only on a trusted server.
946
+ * @returns A {@link LinabaseClient} instance.
947
+ *
948
+ * @example
949
+ * ```ts
950
+ * import { createClient } from "@linabase/js";
951
+ *
952
+ * const linabase = createClient({
953
+ * url: "https://linabase.com",
954
+ * anonKey: "lb_anon_...",
955
+ * });
956
+ *
957
+ * const { data, error } = await linabase
958
+ * .from("posts")
959
+ * .select("*, author:profiles(name)")
960
+ * .eq("published", true);
961
+ * ```
962
+ */
565
963
  declare function createClient(config: LinabaseConfig): LinabaseClient;
566
964
 
567
965
  export { AuthClient, type AuthSession, type AuthUser, BucketClient, type CsvQueryResult, DatabaseClient, type FunctionInvokeOptions, FunctionsClient, type LinabaseClient, type LinabaseConfig, type OAuthProvider, type PostgrestError, type QueryResult, RpcClient, type SessionStorage, type SingleQueryResult, StorageClient, createClient };