@kividb/client 0.1.1 → 0.1.2

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
@@ -1,11 +1,9 @@
1
1
  # @kividb/client
2
2
 
3
3
  The JavaScript/TypeScript client SDK for kividb — a thin, typed wrapper over the
4
- `data-api`, `auth`, and `realtime` services. Works in browsers, React Native,
5
- and Node 22+ (uses global `fetch` and `WebSocket`, no runtime dependencies).
6
-
7
- > Status: initial scaffold. Covers the full data, auth, and realtime surface the
8
- > services expose today. Storage and edge-function helpers are not built yet.
4
+ `data-api`, `auth`, `realtime`, and `storage` services. Works in browsers,
5
+ React Native, and Node 22+ (uses global `fetch` and `WebSocket`, no runtime
6
+ dependencies).
9
7
 
10
8
  ## Install
11
9
 
@@ -32,6 +30,7 @@ const kdb = createClient("http://localhost", ANON_KEY, {
32
30
  auth: "http://localhost:4000",
33
31
  rest: "http://localhost:4001",
34
32
  realtime: "ws://localhost:4002",
33
+ storage: "http://localhost:4004",
35
34
  });
36
35
  ```
37
36
 
@@ -168,3 +167,40 @@ migrations are immutable (changing an applied name's SQL is a 409; add a new
168
167
  one instead). Each migration runs in its own transaction as the project owner
169
168
  role, with your project schema as the `search_path` — remember to enable RLS
170
169
  on new tables, and don't put `begin`/`commit` inside the SQL.
170
+
171
+ ## Storage
172
+
173
+ Objects live in buckets. Object requests carry the signed-in user's token (or
174
+ the anon key), so storage RLS applies exactly like data requests:
175
+
176
+ ```ts
177
+ await kdb.storage.from("avatars").upload("user-42/photo.png", file);
178
+ const { data: blob } = await kdb.storage.from("avatars").download("user-42/photo.png");
179
+ const { data: objects } = await kdb.storage.from("avatars").list("user-42/");
180
+ await kdb.storage.from("avatars").remove(["user-42/photo.png"]);
181
+
182
+ const { data: signed } = await kdb.storage.from("private-docs").createSignedUrl("report.pdf", 3600);
183
+ kdb.storage.from("avatars").getPublicUrl("user-42/photo.png"); // public buckets
184
+ kdb.storage.from("avatars").getRenderUrl("user-42/photo.png", { width: 128, format: "webp" });
185
+ ```
186
+
187
+ ### Buckets
188
+
189
+ Creating and deleting buckets requires the **service key** (server-side only);
190
+ listing and reading bucket metadata work with any key:
191
+
192
+ ```ts
193
+ const kdb = createClient(KIVIDB_URL, process.env.KIVIDB_SERVICE_KEY!);
194
+
195
+ await kdb.storage.createBucket("avatars", { public: true });
196
+ await kdb.storage.createBucket("attachments", {
197
+ allowedMimeTypes: ["image/png", "image/jpeg", "application/pdf"],
198
+ maxObjectSize: 10_000_000, // bytes
199
+ });
200
+
201
+ const { data: buckets } = await kdb.storage.listBuckets();
202
+ const { data: bucket } = await kdb.storage.getBucket("attachments");
203
+ await kdb.storage.deleteBucket("attachments"); // 409 unless the bucket is empty
204
+ ```
205
+
206
+ Bucket names are 2–63 chars: lowercase letters, digits, `.`, `_` or `-`.
package/dist/index.cjs CHANGED
@@ -761,6 +761,42 @@ var StorageClient = class {
761
761
  from(bucket) {
762
762
  return new BucketApi(this.ctx, bucket);
763
763
  }
764
+ token() {
765
+ return this.ctx.session.accessToken() ?? this.ctx.anonKey;
766
+ }
767
+ bucketsUrl(name) {
768
+ const base = `${this.ctx.storage}/${this.ctx.project}/buckets`;
769
+ return name ? `${base}/${encodeURIComponent(name)}` : base;
770
+ }
771
+ /** All buckets in the project (any key; bucket metadata is readable). */
772
+ listBuckets() {
773
+ return request(this.bucketsUrl(), { token: this.token() });
774
+ }
775
+ /** One bucket's metadata, or a 404 error if it doesn't exist. */
776
+ getBucket(name) {
777
+ return request(this.bucketsUrl(name), { token: this.token() });
778
+ }
779
+ /**
780
+ * Create a bucket. Requires the service_role key. Names are 2–63 chars of
781
+ * lowercase letters, digits, ".", "_" or "-".
782
+ */
783
+ createBucket(name, options = {}) {
784
+ return request(this.bucketsUrl(), {
785
+ method: "POST",
786
+ token: this.token(),
787
+ body: JSON.stringify({ name, ...options })
788
+ });
789
+ }
790
+ /**
791
+ * Delete an empty bucket (a non-empty bucket is a 409 — remove its objects
792
+ * first). Requires the service_role key.
793
+ */
794
+ deleteBucket(name) {
795
+ return request(this.bucketsUrl(name), {
796
+ method: "DELETE",
797
+ token: this.token()
798
+ });
799
+ }
764
800
  };
765
801
 
766
802
  // src/index.ts
package/dist/index.d.cts CHANGED
@@ -451,6 +451,24 @@ interface SignedUrl {
451
451
  exp: number;
452
452
  expiresAt: string;
453
453
  }
454
+ /** A bucket as the storage service returns it. */
455
+ interface BucketInfo {
456
+ id: string;
457
+ name: string;
458
+ public: boolean;
459
+ allowedMimeTypes: string[] | null;
460
+ maxObjectSize: number | null;
461
+ createdAt: string;
462
+ updatedAt: string;
463
+ }
464
+ interface CreateBucketOptions {
465
+ /** Public buckets serve objects at a token-less URL. Default false. */
466
+ public?: boolean;
467
+ /** Restrict uploads to these mime types (e.g. ["image/*"]). Null = any. */
468
+ allowedMimeTypes?: string[] | null;
469
+ /** Per-object size cap in bytes. Null = the service default. */
470
+ maxObjectSize?: number | null;
471
+ }
454
472
  interface Ctx {
455
473
  storage: string;
456
474
  project: string;
@@ -485,6 +503,22 @@ declare class StorageClient {
485
503
  constructor(ctx: Ctx);
486
504
  /** Operate on a bucket. */
487
505
  from(bucket: string): BucketApi;
506
+ private token;
507
+ private bucketsUrl;
508
+ /** All buckets in the project (any key; bucket metadata is readable). */
509
+ listBuckets(): Promise<KividbResponse<BucketInfo[]>>;
510
+ /** One bucket's metadata, or a 404 error if it doesn't exist. */
511
+ getBucket(name: string): Promise<KividbResponse<BucketInfo>>;
512
+ /**
513
+ * Create a bucket. Requires the service_role key. Names are 2–63 chars of
514
+ * lowercase letters, digits, ".", "_" or "-".
515
+ */
516
+ createBucket(name: string, options?: CreateBucketOptions): Promise<KividbResponse<BucketInfo>>;
517
+ /**
518
+ * Delete an empty bucket (a non-empty bucket is a 409 — remove its objects
519
+ * first). Requires the service_role key.
520
+ */
521
+ deleteBucket(name: string): Promise<KividbResponse<null>>;
488
522
  }
489
523
 
490
524
  /**
@@ -544,4 +578,4 @@ declare function createServerClient(url: string, anonKey: string, options: Omit<
544
578
  cookies: CookieMethods;
545
579
  }): KividbClient;
546
580
 
547
- export { type AppliedMigration, type ApplyMigrationsResult, AuthClient, type AuthEvent, type AuthListener, type ClientOptions, type CookieMethods, type CookieOptions, FilterBuilder, FromBuilder, KividbClient, type KividbError, type KividbResponse, type Migration, MigrationsClient, type OAuthProvider, type PostgresChange, RealtimeChannel, RealtimeClient, type Row, type Session, type SessionStore, type SignedUrl, StorageClient, type StorageObjectInfo, type TransformOptions, type UploadBody, type UploadOptions, type User, createBrowserClient, createClient, createServerClient, projectFromAnonKey, sessionCookieName };
581
+ export { type AppliedMigration, type ApplyMigrationsResult, AuthClient, type AuthEvent, type AuthListener, type BucketInfo, type ClientOptions, type CookieMethods, type CookieOptions, type CreateBucketOptions, FilterBuilder, FromBuilder, KividbClient, type KividbError, type KividbResponse, type Migration, MigrationsClient, type OAuthProvider, type PostgresChange, RealtimeChannel, RealtimeClient, type Row, type Session, type SessionStore, type SignedUrl, StorageClient, type StorageObjectInfo, type TransformOptions, type UploadBody, type UploadOptions, type User, createBrowserClient, createClient, createServerClient, projectFromAnonKey, sessionCookieName };
package/dist/index.d.ts CHANGED
@@ -451,6 +451,24 @@ interface SignedUrl {
451
451
  exp: number;
452
452
  expiresAt: string;
453
453
  }
454
+ /** A bucket as the storage service returns it. */
455
+ interface BucketInfo {
456
+ id: string;
457
+ name: string;
458
+ public: boolean;
459
+ allowedMimeTypes: string[] | null;
460
+ maxObjectSize: number | null;
461
+ createdAt: string;
462
+ updatedAt: string;
463
+ }
464
+ interface CreateBucketOptions {
465
+ /** Public buckets serve objects at a token-less URL. Default false. */
466
+ public?: boolean;
467
+ /** Restrict uploads to these mime types (e.g. ["image/*"]). Null = any. */
468
+ allowedMimeTypes?: string[] | null;
469
+ /** Per-object size cap in bytes. Null = the service default. */
470
+ maxObjectSize?: number | null;
471
+ }
454
472
  interface Ctx {
455
473
  storage: string;
456
474
  project: string;
@@ -485,6 +503,22 @@ declare class StorageClient {
485
503
  constructor(ctx: Ctx);
486
504
  /** Operate on a bucket. */
487
505
  from(bucket: string): BucketApi;
506
+ private token;
507
+ private bucketsUrl;
508
+ /** All buckets in the project (any key; bucket metadata is readable). */
509
+ listBuckets(): Promise<KividbResponse<BucketInfo[]>>;
510
+ /** One bucket's metadata, or a 404 error if it doesn't exist. */
511
+ getBucket(name: string): Promise<KividbResponse<BucketInfo>>;
512
+ /**
513
+ * Create a bucket. Requires the service_role key. Names are 2–63 chars of
514
+ * lowercase letters, digits, ".", "_" or "-".
515
+ */
516
+ createBucket(name: string, options?: CreateBucketOptions): Promise<KividbResponse<BucketInfo>>;
517
+ /**
518
+ * Delete an empty bucket (a non-empty bucket is a 409 — remove its objects
519
+ * first). Requires the service_role key.
520
+ */
521
+ deleteBucket(name: string): Promise<KividbResponse<null>>;
488
522
  }
489
523
 
490
524
  /**
@@ -544,4 +578,4 @@ declare function createServerClient(url: string, anonKey: string, options: Omit<
544
578
  cookies: CookieMethods;
545
579
  }): KividbClient;
546
580
 
547
- export { type AppliedMigration, type ApplyMigrationsResult, AuthClient, type AuthEvent, type AuthListener, type ClientOptions, type CookieMethods, type CookieOptions, FilterBuilder, FromBuilder, KividbClient, type KividbError, type KividbResponse, type Migration, MigrationsClient, type OAuthProvider, type PostgresChange, RealtimeChannel, RealtimeClient, type Row, type Session, type SessionStore, type SignedUrl, StorageClient, type StorageObjectInfo, type TransformOptions, type UploadBody, type UploadOptions, type User, createBrowserClient, createClient, createServerClient, projectFromAnonKey, sessionCookieName };
581
+ export { type AppliedMigration, type ApplyMigrationsResult, AuthClient, type AuthEvent, type AuthListener, type BucketInfo, type ClientOptions, type CookieMethods, type CookieOptions, type CreateBucketOptions, FilterBuilder, FromBuilder, KividbClient, type KividbError, type KividbResponse, type Migration, MigrationsClient, type OAuthProvider, type PostgresChange, RealtimeChannel, RealtimeClient, type Row, type Session, type SessionStore, type SignedUrl, StorageClient, type StorageObjectInfo, type TransformOptions, type UploadBody, type UploadOptions, type User, createBrowserClient, createClient, createServerClient, projectFromAnonKey, sessionCookieName };
package/dist/index.js CHANGED
@@ -723,6 +723,42 @@ var StorageClient = class {
723
723
  from(bucket) {
724
724
  return new BucketApi(this.ctx, bucket);
725
725
  }
726
+ token() {
727
+ return this.ctx.session.accessToken() ?? this.ctx.anonKey;
728
+ }
729
+ bucketsUrl(name) {
730
+ const base = `${this.ctx.storage}/${this.ctx.project}/buckets`;
731
+ return name ? `${base}/${encodeURIComponent(name)}` : base;
732
+ }
733
+ /** All buckets in the project (any key; bucket metadata is readable). */
734
+ listBuckets() {
735
+ return request(this.bucketsUrl(), { token: this.token() });
736
+ }
737
+ /** One bucket's metadata, or a 404 error if it doesn't exist. */
738
+ getBucket(name) {
739
+ return request(this.bucketsUrl(name), { token: this.token() });
740
+ }
741
+ /**
742
+ * Create a bucket. Requires the service_role key. Names are 2–63 chars of
743
+ * lowercase letters, digits, ".", "_" or "-".
744
+ */
745
+ createBucket(name, options = {}) {
746
+ return request(this.bucketsUrl(), {
747
+ method: "POST",
748
+ token: this.token(),
749
+ body: JSON.stringify({ name, ...options })
750
+ });
751
+ }
752
+ /**
753
+ * Delete an empty bucket (a non-empty bucket is a 409 — remove its objects
754
+ * first). Requires the service_role key.
755
+ */
756
+ deleteBucket(name) {
757
+ return request(this.bucketsUrl(name), {
758
+ method: "DELETE",
759
+ token: this.token()
760
+ });
761
+ }
726
762
  };
727
763
 
728
764
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kividb/client",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "JavaScript/TypeScript client SDK for kividb — typed database queries, auth, realtime, and storage",
5
5
  "license": "MIT",
6
6
  "repository": {