@kividb/client 0.1.0 → 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 +75 -5
- package/dist/index.cjs +73 -0
- package/dist/index.d.cts +89 -1
- package/dist/index.d.ts +89 -1
- package/dist/index.js +72 -0
- package/package.json +1 -1
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 `
|
|
5
|
-
and Node 22+ (uses global `fetch` and `WebSocket`, no runtime
|
|
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
|
|
|
@@ -134,3 +133,74 @@ channel.unsubscribe();
|
|
|
134
133
|
One WebSocket is shared per project across all channels. It reconnects with
|
|
135
134
|
backoff and re-subscribes automatically; `DELETE` postgres events are delivered
|
|
136
135
|
only to `service_role` tokens (a documented v1 server limitation).
|
|
136
|
+
|
|
137
|
+
## Migrations
|
|
138
|
+
|
|
139
|
+
Create and evolve your schema from code instead of the dashboard. Requires the
|
|
140
|
+
**service key** (server-side only — never ship it to a browser):
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const kdb = createClient(KIVIDB_URL, process.env.KIVIDB_SERVICE_KEY!);
|
|
144
|
+
|
|
145
|
+
await kdb.migrations.apply([
|
|
146
|
+
{
|
|
147
|
+
name: "0001_messages",
|
|
148
|
+
sql: `
|
|
149
|
+
create table messages (
|
|
150
|
+
id uuid primary key default gen_random_uuid(),
|
|
151
|
+
room text not null,
|
|
152
|
+
body text not null,
|
|
153
|
+
created_at timestamptz not null default now()
|
|
154
|
+
);
|
|
155
|
+
alter table messages enable row level security;
|
|
156
|
+
`,
|
|
157
|
+
},
|
|
158
|
+
]);
|
|
159
|
+
|
|
160
|
+
const { data } = await kdb.migrations.list(); // the applied-migrations ledger
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`apply` is idempotent: each migration is recorded by name in a per-project
|
|
164
|
+
ledger, so re-running the same list skips what's already applied — keep one
|
|
165
|
+
array in your repo, append to it, and run it on every deploy. Applied
|
|
166
|
+
migrations are immutable (changing an applied name's SQL is a 409; add a new
|
|
167
|
+
one instead). Each migration runs in its own transaction as the project owner
|
|
168
|
+
role, with your project schema as the `search_path` — remember to enable RLS
|
|
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
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
FilterBuilder: () => FilterBuilder,
|
|
25
25
|
FromBuilder: () => FromBuilder,
|
|
26
26
|
KividbClient: () => KividbClient,
|
|
27
|
+
MigrationsClient: () => MigrationsClient,
|
|
27
28
|
RealtimeChannel: () => RealtimeChannel,
|
|
28
29
|
RealtimeClient: () => RealtimeClient,
|
|
29
30
|
StorageClient: () => StorageClient,
|
|
@@ -302,6 +303,34 @@ function base64UrlDecode(segment) {
|
|
|
302
303
|
return new TextDecoder().decode(bytes);
|
|
303
304
|
}
|
|
304
305
|
|
|
306
|
+
// src/migrations.ts
|
|
307
|
+
var MigrationsClient = class {
|
|
308
|
+
constructor(cfg) {
|
|
309
|
+
this.cfg = cfg;
|
|
310
|
+
}
|
|
311
|
+
cfg;
|
|
312
|
+
get endpoint() {
|
|
313
|
+
return `${this.cfg.rest}/${this.cfg.project}/-/migrations`;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Apply migrations in order, skipping ones already applied. On a failure the
|
|
317
|
+
* error's `details` carry `failed` (the migration that broke) plus the
|
|
318
|
+
* `applied`/`skipped` progress before it; already-applied migrations stay
|
|
319
|
+
* applied and skip on the next run.
|
|
320
|
+
*/
|
|
321
|
+
apply(migrations) {
|
|
322
|
+
return request(this.endpoint, {
|
|
323
|
+
method: "POST",
|
|
324
|
+
body: JSON.stringify({ migrations }),
|
|
325
|
+
token: this.cfg.key
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
/** The applied-migrations ledger, oldest first. */
|
|
329
|
+
list() {
|
|
330
|
+
return request(this.endpoint, { token: this.cfg.key });
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
305
334
|
// src/postgrest.ts
|
|
306
335
|
var FromBuilder = class {
|
|
307
336
|
constructor(ctx, table) {
|
|
@@ -732,6 +761,42 @@ var StorageClient = class {
|
|
|
732
761
|
from(bucket) {
|
|
733
762
|
return new BucketApi(this.ctx, bucket);
|
|
734
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
|
+
}
|
|
735
800
|
};
|
|
736
801
|
|
|
737
802
|
// src/index.ts
|
|
@@ -770,6 +835,11 @@ var KividbClient = class {
|
|
|
770
835
|
anonKey,
|
|
771
836
|
session: this.session
|
|
772
837
|
});
|
|
838
|
+
this.migrations = new MigrationsClient({
|
|
839
|
+
rest: this.endpoints.rest,
|
|
840
|
+
project: this.project,
|
|
841
|
+
key: anonKey
|
|
842
|
+
});
|
|
773
843
|
this.session.hydrateSync();
|
|
774
844
|
void this.session.hydrate();
|
|
775
845
|
}
|
|
@@ -778,6 +848,8 @@ var KividbClient = class {
|
|
|
778
848
|
auth;
|
|
779
849
|
realtime;
|
|
780
850
|
storage;
|
|
851
|
+
/** Schema migrations — requires the client to hold the service key. */
|
|
852
|
+
migrations;
|
|
781
853
|
project;
|
|
782
854
|
endpoints;
|
|
783
855
|
session;
|
|
@@ -819,6 +891,7 @@ function createServerClient(url, anonKey, options) {
|
|
|
819
891
|
FilterBuilder,
|
|
820
892
|
FromBuilder,
|
|
821
893
|
KividbClient,
|
|
894
|
+
MigrationsClient,
|
|
822
895
|
RealtimeChannel,
|
|
823
896
|
RealtimeClient,
|
|
824
897
|
StorageClient,
|
package/dist/index.d.cts
CHANGED
|
@@ -203,6 +203,58 @@ interface CookieMethods {
|
|
|
203
203
|
/** Cookie name carrying the JSON session for a given project. */
|
|
204
204
|
declare function sessionCookieName(project: string): string;
|
|
205
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Schema migrations, applied through the data API's service_role-only
|
|
208
|
+
* `/:project/-/migrations` endpoint. Create the client with the project's
|
|
209
|
+
* **service key** (never ship that key to a browser):
|
|
210
|
+
*
|
|
211
|
+
* const kdb = createClient(url, serviceKey);
|
|
212
|
+
* await kdb.migrations.apply([
|
|
213
|
+
* { name: "0001_messages", sql: `create table messages (…); alter table messages enable row level security;` },
|
|
214
|
+
* ]);
|
|
215
|
+
*
|
|
216
|
+
* Applying is idempotent: each migration is recorded in a per-project ledger
|
|
217
|
+
* by name, so re-running the same list skips what's already applied. Applied
|
|
218
|
+
* migrations are immutable — changing the SQL of an applied name is a 409;
|
|
219
|
+
* add a new migration instead.
|
|
220
|
+
*/
|
|
221
|
+
/** A named schema migration. Names must be unique and are applied in order. */
|
|
222
|
+
interface Migration {
|
|
223
|
+
name: string;
|
|
224
|
+
sql: string;
|
|
225
|
+
}
|
|
226
|
+
interface ApplyMigrationsResult {
|
|
227
|
+
/** Names applied by this call, in order. */
|
|
228
|
+
applied: string[];
|
|
229
|
+
/** Names already in the ledger (identical SQL), skipped. */
|
|
230
|
+
skipped: string[];
|
|
231
|
+
}
|
|
232
|
+
/** A ledger entry for an applied migration. */
|
|
233
|
+
interface AppliedMigration {
|
|
234
|
+
name: string;
|
|
235
|
+
/** sha256 of the SQL as applied. */
|
|
236
|
+
checksum: string;
|
|
237
|
+
applied_at: string;
|
|
238
|
+
}
|
|
239
|
+
declare class MigrationsClient {
|
|
240
|
+
private readonly cfg;
|
|
241
|
+
constructor(cfg: {
|
|
242
|
+
rest: string;
|
|
243
|
+
project: string;
|
|
244
|
+
key: string;
|
|
245
|
+
});
|
|
246
|
+
private get endpoint();
|
|
247
|
+
/**
|
|
248
|
+
* Apply migrations in order, skipping ones already applied. On a failure the
|
|
249
|
+
* error's `details` carry `failed` (the migration that broke) plus the
|
|
250
|
+
* `applied`/`skipped` progress before it; already-applied migrations stay
|
|
251
|
+
* applied and skip on the next run.
|
|
252
|
+
*/
|
|
253
|
+
apply(migrations: Migration[]): Promise<KividbResponse<ApplyMigrationsResult>>;
|
|
254
|
+
/** The applied-migrations ledger, oldest first. */
|
|
255
|
+
list(): Promise<KividbResponse<AppliedMigration[]>>;
|
|
256
|
+
}
|
|
257
|
+
|
|
206
258
|
interface Context {
|
|
207
259
|
rest: string;
|
|
208
260
|
project: string;
|
|
@@ -399,6 +451,24 @@ interface SignedUrl {
|
|
|
399
451
|
exp: number;
|
|
400
452
|
expiresAt: string;
|
|
401
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
|
+
}
|
|
402
472
|
interface Ctx {
|
|
403
473
|
storage: string;
|
|
404
474
|
project: string;
|
|
@@ -433,6 +503,22 @@ declare class StorageClient {
|
|
|
433
503
|
constructor(ctx: Ctx);
|
|
434
504
|
/** Operate on a bucket. */
|
|
435
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>>;
|
|
436
522
|
}
|
|
437
523
|
|
|
438
524
|
/**
|
|
@@ -463,6 +549,8 @@ declare class KividbClient {
|
|
|
463
549
|
readonly auth: AuthClient;
|
|
464
550
|
readonly realtime: RealtimeClient;
|
|
465
551
|
readonly storage: StorageClient;
|
|
552
|
+
/** Schema migrations — requires the client to hold the service key. */
|
|
553
|
+
readonly migrations: MigrationsClient;
|
|
466
554
|
readonly project: string;
|
|
467
555
|
private readonly endpoints;
|
|
468
556
|
private readonly session;
|
|
@@ -490,4 +578,4 @@ declare function createServerClient(url: string, anonKey: string, options: Omit<
|
|
|
490
578
|
cookies: CookieMethods;
|
|
491
579
|
}): KividbClient;
|
|
492
580
|
|
|
493
|
-
export { AuthClient, type AuthEvent, type AuthListener, type ClientOptions, type CookieMethods, type CookieOptions, FilterBuilder, FromBuilder, KividbClient, type KividbError, type KividbResponse, 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
|
@@ -203,6 +203,58 @@ interface CookieMethods {
|
|
|
203
203
|
/** Cookie name carrying the JSON session for a given project. */
|
|
204
204
|
declare function sessionCookieName(project: string): string;
|
|
205
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Schema migrations, applied through the data API's service_role-only
|
|
208
|
+
* `/:project/-/migrations` endpoint. Create the client with the project's
|
|
209
|
+
* **service key** (never ship that key to a browser):
|
|
210
|
+
*
|
|
211
|
+
* const kdb = createClient(url, serviceKey);
|
|
212
|
+
* await kdb.migrations.apply([
|
|
213
|
+
* { name: "0001_messages", sql: `create table messages (…); alter table messages enable row level security;` },
|
|
214
|
+
* ]);
|
|
215
|
+
*
|
|
216
|
+
* Applying is idempotent: each migration is recorded in a per-project ledger
|
|
217
|
+
* by name, so re-running the same list skips what's already applied. Applied
|
|
218
|
+
* migrations are immutable — changing the SQL of an applied name is a 409;
|
|
219
|
+
* add a new migration instead.
|
|
220
|
+
*/
|
|
221
|
+
/** A named schema migration. Names must be unique and are applied in order. */
|
|
222
|
+
interface Migration {
|
|
223
|
+
name: string;
|
|
224
|
+
sql: string;
|
|
225
|
+
}
|
|
226
|
+
interface ApplyMigrationsResult {
|
|
227
|
+
/** Names applied by this call, in order. */
|
|
228
|
+
applied: string[];
|
|
229
|
+
/** Names already in the ledger (identical SQL), skipped. */
|
|
230
|
+
skipped: string[];
|
|
231
|
+
}
|
|
232
|
+
/** A ledger entry for an applied migration. */
|
|
233
|
+
interface AppliedMigration {
|
|
234
|
+
name: string;
|
|
235
|
+
/** sha256 of the SQL as applied. */
|
|
236
|
+
checksum: string;
|
|
237
|
+
applied_at: string;
|
|
238
|
+
}
|
|
239
|
+
declare class MigrationsClient {
|
|
240
|
+
private readonly cfg;
|
|
241
|
+
constructor(cfg: {
|
|
242
|
+
rest: string;
|
|
243
|
+
project: string;
|
|
244
|
+
key: string;
|
|
245
|
+
});
|
|
246
|
+
private get endpoint();
|
|
247
|
+
/**
|
|
248
|
+
* Apply migrations in order, skipping ones already applied. On a failure the
|
|
249
|
+
* error's `details` carry `failed` (the migration that broke) plus the
|
|
250
|
+
* `applied`/`skipped` progress before it; already-applied migrations stay
|
|
251
|
+
* applied and skip on the next run.
|
|
252
|
+
*/
|
|
253
|
+
apply(migrations: Migration[]): Promise<KividbResponse<ApplyMigrationsResult>>;
|
|
254
|
+
/** The applied-migrations ledger, oldest first. */
|
|
255
|
+
list(): Promise<KividbResponse<AppliedMigration[]>>;
|
|
256
|
+
}
|
|
257
|
+
|
|
206
258
|
interface Context {
|
|
207
259
|
rest: string;
|
|
208
260
|
project: string;
|
|
@@ -399,6 +451,24 @@ interface SignedUrl {
|
|
|
399
451
|
exp: number;
|
|
400
452
|
expiresAt: string;
|
|
401
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
|
+
}
|
|
402
472
|
interface Ctx {
|
|
403
473
|
storage: string;
|
|
404
474
|
project: string;
|
|
@@ -433,6 +503,22 @@ declare class StorageClient {
|
|
|
433
503
|
constructor(ctx: Ctx);
|
|
434
504
|
/** Operate on a bucket. */
|
|
435
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>>;
|
|
436
522
|
}
|
|
437
523
|
|
|
438
524
|
/**
|
|
@@ -463,6 +549,8 @@ declare class KividbClient {
|
|
|
463
549
|
readonly auth: AuthClient;
|
|
464
550
|
readonly realtime: RealtimeClient;
|
|
465
551
|
readonly storage: StorageClient;
|
|
552
|
+
/** Schema migrations — requires the client to hold the service key. */
|
|
553
|
+
readonly migrations: MigrationsClient;
|
|
466
554
|
readonly project: string;
|
|
467
555
|
private readonly endpoints;
|
|
468
556
|
private readonly session;
|
|
@@ -490,4 +578,4 @@ declare function createServerClient(url: string, anonKey: string, options: Omit<
|
|
|
490
578
|
cookies: CookieMethods;
|
|
491
579
|
}): KividbClient;
|
|
492
580
|
|
|
493
|
-
export { AuthClient, type AuthEvent, type AuthListener, type ClientOptions, type CookieMethods, type CookieOptions, FilterBuilder, FromBuilder, KividbClient, type KividbError, type KividbResponse, 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
|
@@ -265,6 +265,34 @@ function base64UrlDecode(segment) {
|
|
|
265
265
|
return new TextDecoder().decode(bytes);
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
+
// src/migrations.ts
|
|
269
|
+
var MigrationsClient = class {
|
|
270
|
+
constructor(cfg) {
|
|
271
|
+
this.cfg = cfg;
|
|
272
|
+
}
|
|
273
|
+
cfg;
|
|
274
|
+
get endpoint() {
|
|
275
|
+
return `${this.cfg.rest}/${this.cfg.project}/-/migrations`;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Apply migrations in order, skipping ones already applied. On a failure the
|
|
279
|
+
* error's `details` carry `failed` (the migration that broke) plus the
|
|
280
|
+
* `applied`/`skipped` progress before it; already-applied migrations stay
|
|
281
|
+
* applied and skip on the next run.
|
|
282
|
+
*/
|
|
283
|
+
apply(migrations) {
|
|
284
|
+
return request(this.endpoint, {
|
|
285
|
+
method: "POST",
|
|
286
|
+
body: JSON.stringify({ migrations }),
|
|
287
|
+
token: this.cfg.key
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/** The applied-migrations ledger, oldest first. */
|
|
291
|
+
list() {
|
|
292
|
+
return request(this.endpoint, { token: this.cfg.key });
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
268
296
|
// src/postgrest.ts
|
|
269
297
|
var FromBuilder = class {
|
|
270
298
|
constructor(ctx, table) {
|
|
@@ -695,6 +723,42 @@ var StorageClient = class {
|
|
|
695
723
|
from(bucket) {
|
|
696
724
|
return new BucketApi(this.ctx, bucket);
|
|
697
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
|
+
}
|
|
698
762
|
};
|
|
699
763
|
|
|
700
764
|
// src/index.ts
|
|
@@ -733,6 +797,11 @@ var KividbClient = class {
|
|
|
733
797
|
anonKey,
|
|
734
798
|
session: this.session
|
|
735
799
|
});
|
|
800
|
+
this.migrations = new MigrationsClient({
|
|
801
|
+
rest: this.endpoints.rest,
|
|
802
|
+
project: this.project,
|
|
803
|
+
key: anonKey
|
|
804
|
+
});
|
|
736
805
|
this.session.hydrateSync();
|
|
737
806
|
void this.session.hydrate();
|
|
738
807
|
}
|
|
@@ -741,6 +810,8 @@ var KividbClient = class {
|
|
|
741
810
|
auth;
|
|
742
811
|
realtime;
|
|
743
812
|
storage;
|
|
813
|
+
/** Schema migrations — requires the client to hold the service key. */
|
|
814
|
+
migrations;
|
|
744
815
|
project;
|
|
745
816
|
endpoints;
|
|
746
817
|
session;
|
|
@@ -781,6 +852,7 @@ export {
|
|
|
781
852
|
FilterBuilder,
|
|
782
853
|
FromBuilder,
|
|
783
854
|
KividbClient,
|
|
855
|
+
MigrationsClient,
|
|
784
856
|
RealtimeChannel,
|
|
785
857
|
RealtimeClient,
|
|
786
858
|
StorageClient,
|