@giaeulate/baas-sdk 1.1.1 → 1.3.0

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.cjs ADDED
@@ -0,0 +1,1985 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ BaasClient: () => BaasClient,
24
+ HttpClient: () => HttpClient,
25
+ QueryBuilder: () => QueryBuilder
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/http-client.ts
30
+ var HttpClient = class {
31
+ url;
32
+ apiKey = "";
33
+ keyType;
34
+ token = null;
35
+ environment = "prod";
36
+ _onForceLogout = null;
37
+ constructor(url, apiKey, options) {
38
+ let baseUrl = url || (typeof window !== "undefined" ? window.location.origin : "http://localhost:8080");
39
+ this.url = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
40
+ if (apiKey) this.apiKey = apiKey;
41
+ this.keyType = options?.keyType ?? "service_role";
42
+ this.warnIfUnsafeKey();
43
+ this.token = typeof localStorage !== "undefined" ? this.cleanValue(localStorage.getItem("baas_token")) : null;
44
+ }
45
+ /** SECURITY: a service_role key bypasses RLS and grants admin over every
46
+ * tenant. If it ends up in a browser bundle, anyone can extract it. Warn
47
+ * loudly when a non-anon key is constructed in a browser context. */
48
+ warnIfUnsafeKey() {
49
+ const inBrowser = typeof window !== "undefined" && typeof document !== "undefined";
50
+ if (inBrowser && this.apiKey && this.keyType !== "anon") {
51
+ console.warn(
52
+ '[baas-sdk] SECURITY WARNING: a non-anon (service_role) key is running in a browser. It bypasses Row-Level Security and grants admin over ALL tenants, and is extractable from the bundle. Mint an anon key in the dashboard and construct the client with { keyType: "anon" }.'
53
+ );
54
+ }
55
+ }
56
+ /**
57
+ * Set the auth token manually (e.g. restoring from SecureStore in React Native).
58
+ * Persists to both the in-memory property and localStorage so getDynamicToken() works.
59
+ */
60
+ setToken(token) {
61
+ this.token = token;
62
+ if (token) {
63
+ localStorage.setItem("baas_token", token);
64
+ } else {
65
+ localStorage.removeItem("baas_token");
66
+ }
67
+ }
68
+ /**
69
+ * Register a callback invoked on forced logout (401).
70
+ * Use this in React Native instead of the default window.location redirect.
71
+ */
72
+ onForceLogout(callback) {
73
+ this._onForceLogout = callback;
74
+ }
75
+ cleanValue(val) {
76
+ if (!val || val === "null" || val === "undefined") return null;
77
+ return val.trim();
78
+ }
79
+ /**
80
+ * Public header generator for adapters
81
+ */
82
+ getHeaders(contentType = "application/json") {
83
+ const dynamicToken = this.getDynamicToken();
84
+ const headers = {
85
+ "apikey": this.apiKey
86
+ };
87
+ if (contentType) {
88
+ headers["Content-Type"] = contentType;
89
+ }
90
+ if (dynamicToken) {
91
+ headers["Authorization"] = `Bearer ${dynamicToken}`;
92
+ }
93
+ if (this.environment && this.environment !== "prod") {
94
+ headers["X-Environment"] = this.environment;
95
+ }
96
+ const csrfToken = this.getCSRFToken();
97
+ if (csrfToken) {
98
+ headers["X-CSRF-Token"] = csrfToken;
99
+ }
100
+ return headers;
101
+ }
102
+ getDynamicToken() {
103
+ return this.cleanValue(this.token || localStorage.getItem("baas_token"));
104
+ }
105
+ /**
106
+ * Core HTTP request method - DRY principle
107
+ */
108
+ async request(endpoint, options = {}) {
109
+ const { method = "GET", body, headers: customHeaders, skipAuth = false } = options;
110
+ const headers = { ...this.getHeaders(), ...customHeaders };
111
+ const fetchOptions = {
112
+ method,
113
+ headers,
114
+ credentials: "include"
115
+ };
116
+ if (body !== void 0) {
117
+ fetchOptions.body = JSON.stringify(body);
118
+ }
119
+ const res = await fetch(`${this.url}${endpoint}`, fetchOptions);
120
+ if (res.status === 204) {
121
+ return { success: true };
122
+ }
123
+ const data = await res.json().catch(() => null);
124
+ if (!res.ok) {
125
+ if (res.status === 401 && !skipAuth) {
126
+ this.forceLogout();
127
+ }
128
+ if (res.status === 403 && data?.error === "ip_not_allowed") {
129
+ this.handleIPBlocked(data.ip);
130
+ }
131
+ const rateLimited = res.status === 429;
132
+ const retryHint = res.headers.get("retry-after") || res.headers.get("x-ratelimit-reset");
133
+ return {
134
+ error: data?.error || `Request failed: ${res.status}`,
135
+ status: res.status,
136
+ ...rateLimited ? { rateLimited: true, retryAfter: retryHint ? parseInt(retryHint, 10) : void 0 } : {},
137
+ ...data
138
+ };
139
+ }
140
+ return data;
141
+ }
142
+ get(endpoint) {
143
+ return this.request(endpoint);
144
+ }
145
+ post(endpoint, body) {
146
+ return this.request(endpoint, { method: "POST", body });
147
+ }
148
+ put(endpoint, body) {
149
+ return this.request(endpoint, { method: "PUT", body });
150
+ }
151
+ patch(endpoint, body) {
152
+ return this.request(endpoint, { method: "PATCH", body });
153
+ }
154
+ delete(endpoint) {
155
+ return this.request(endpoint, { method: "DELETE" });
156
+ }
157
+ getCSRFToken() {
158
+ if (typeof document === "undefined") return null;
159
+ const match = document.cookie.match(/(?:^|;\s*)csrf_token=([^;]*)/);
160
+ return match ? decodeURIComponent(match[1]) : null;
161
+ }
162
+ setEnvironment(env) {
163
+ this.environment = env;
164
+ }
165
+ getEnvironment() {
166
+ return this.environment;
167
+ }
168
+ logout() {
169
+ this.token = null;
170
+ localStorage.removeItem("baas_token");
171
+ }
172
+ forceLogout() {
173
+ this.logout();
174
+ if (this._onForceLogout) {
175
+ this._onForceLogout();
176
+ return;
177
+ }
178
+ if (typeof window !== "undefined" && window.location && window.location.search !== void 0) {
179
+ if (!window.location.search.includes("expired")) {
180
+ window.location.href = "/authentication/login?reason=expired";
181
+ }
182
+ }
183
+ }
184
+ handleIPBlocked(ip) {
185
+ if (typeof window !== "undefined") {
186
+ const params = ip ? `?ip=${encodeURIComponent(ip)}` : "";
187
+ if (!window.location.pathname.includes("/blocked")) {
188
+ window.location.href = `/blocked${params}`;
189
+ }
190
+ }
191
+ }
192
+ };
193
+
194
+ // src/query-builder.ts
195
+ var QueryBuilder = class {
196
+ table;
197
+ url;
198
+ client;
199
+ queryParams = new URLSearchParams();
200
+ // @ts-ignore - used for future filter improvements
201
+ filters = [];
202
+ constructor(table, url, client) {
203
+ this.table = table;
204
+ this.url = url;
205
+ this.client = client;
206
+ }
207
+ select(columns = "*") {
208
+ this.queryParams.set("select", columns);
209
+ return this;
210
+ }
211
+ eq(column, value) {
212
+ this.queryParams.set(column, `eq.${value}`);
213
+ return this;
214
+ }
215
+ neq(column, value) {
216
+ this.queryParams.set(column, `neq.${value}`);
217
+ return this;
218
+ }
219
+ gt(column, value) {
220
+ this.queryParams.set(column, `gt.${value}`);
221
+ return this;
222
+ }
223
+ gte(column, value) {
224
+ this.queryParams.set(column, `gte.${value}`);
225
+ return this;
226
+ }
227
+ lt(column, value) {
228
+ this.queryParams.set(column, `lt.${value}`);
229
+ return this;
230
+ }
231
+ lte(column, value) {
232
+ this.queryParams.set(column, `lte.${value}`);
233
+ return this;
234
+ }
235
+ like(column, value) {
236
+ this.queryParams.set(column, `like.${value}`);
237
+ return this;
238
+ }
239
+ ilike(column, value) {
240
+ this.queryParams.set(column, `ilike.${value}`);
241
+ return this;
242
+ }
243
+ is(column, value) {
244
+ this.queryParams.set(column, `is.${value}`);
245
+ return this;
246
+ }
247
+ in(column, values) {
248
+ this.queryParams.set(column, `in.(${values.join(",")})`);
249
+ return this;
250
+ }
251
+ not(column, operator, value) {
252
+ this.queryParams.set(column, `not.${operator}.${value}`);
253
+ return this;
254
+ }
255
+ /** Array/jsonb/range contains (@>). Arrays become a `{a,b}` literal. */
256
+ contains(column, values) {
257
+ this.queryParams.set(column, `cs.${this.arrayLiteral(values)}`);
258
+ return this;
259
+ }
260
+ /** Array/jsonb/range contained-by (<@). */
261
+ containedBy(column, values) {
262
+ this.queryParams.set(column, `cd.${this.arrayLiteral(values)}`);
263
+ return this;
264
+ }
265
+ /** Array/range overlap (&&). */
266
+ overlaps(column, values) {
267
+ this.queryParams.set(column, `ov.${this.arrayLiteral(values)}`);
268
+ return this;
269
+ }
270
+ /** Full-text search (@@). type: fts|plfts|phfts|wfts (tsquery flavour). */
271
+ textSearch(column, query, type = "fts") {
272
+ this.queryParams.set(column, `${type}.${query}`);
273
+ return this;
274
+ }
275
+ arrayLiteral(values) {
276
+ return Array.isArray(values) ? `{${values.join(",")}}` : `${values}`;
277
+ }
278
+ /** OR group: `or=(c1,c2)`. Members are dotted `col.op.value` strings. */
279
+ or(filters) {
280
+ this.queryParams.set("or", `(${filters})`);
281
+ return this;
282
+ }
283
+ /** AND group: `and=(c1,c2)` — e.g. a range `qty.gt.5,qty.lt.20`. */
284
+ and(filters) {
285
+ this.queryParams.set("and", `(${filters})`);
286
+ return this;
287
+ }
288
+ /** Negated AND group: `not.and=(...)`. */
289
+ notAnd(filters) {
290
+ this.queryParams.set("not.and", `(${filters})`);
291
+ return this;
292
+ }
293
+ /** Negated OR group: `not.or=(...)`. */
294
+ notOr(filters) {
295
+ this.queryParams.set("not.or", `(${filters})`);
296
+ return this;
297
+ }
298
+ order(column, { ascending = true } = {}) {
299
+ this.queryParams.set("order", `${column}.${ascending ? "asc" : "desc"}`);
300
+ return this;
301
+ }
302
+ limit(count) {
303
+ this.queryParams.set("limit", count.toString());
304
+ return this;
305
+ }
306
+ offset(count) {
307
+ this.queryParams.set("offset", count.toString());
308
+ return this;
309
+ }
310
+ async get() {
311
+ const res = await fetch(`${this.url}/api/v1/data/${this.table}?${this.queryParams.toString()}`, {
312
+ headers: { ...this.getHeaders(), "Cache-Control": "no-cache" },
313
+ cache: "no-store"
314
+ });
315
+ return await this.handleResponse(res);
316
+ }
317
+ async insert(data) {
318
+ const res = await fetch(`${this.url}/api/v1/data/${this.table}`, {
319
+ method: "POST",
320
+ headers: this.getHeaders(),
321
+ body: JSON.stringify(data)
322
+ });
323
+ return await this.handleResponse(res);
324
+ }
325
+ async update(id, data) {
326
+ const res = await fetch(`${this.url}/api/v1/data/${this.table}/${id}`, {
327
+ method: "PATCH",
328
+ headers: this.getHeaders(),
329
+ body: JSON.stringify(data)
330
+ });
331
+ return await this.handleResponse(res);
332
+ }
333
+ async delete(id) {
334
+ const res = await fetch(`${this.url}/api/v1/data/${this.table}/${id}`, {
335
+ method: "DELETE",
336
+ headers: this.getHeaders()
337
+ });
338
+ if (res.status === 204) return { success: true };
339
+ return await this.handleResponse(res);
340
+ }
341
+ /** Insert-or-update on conflict. [onConflict] is the conflict-target column(s). */
342
+ async upsert(data, onConflict) {
343
+ const res = await fetch(`${this.url}/api/v1/data/${this.table}/upsert`, {
344
+ method: "POST",
345
+ headers: this.getHeaders(),
346
+ body: JSON.stringify({ ...data, on_conflict: onConflict })
347
+ });
348
+ return await this.handleResponse(res);
349
+ }
350
+ /**
351
+ * Count rows matching the current filters (PostgREST parity). Sends
352
+ * `Prefer: count=exact` and parses the total from the `Content-Range`
353
+ * response header. Returns `{ count, error, status }`.
354
+ */
355
+ async count() {
356
+ const res = await fetch(`${this.url}/api/v1/data/${this.table}?${this.queryParams.toString()}`, {
357
+ headers: { ...this.getHeaders(), Prefer: "count=exact", "Cache-Control": "no-cache" },
358
+ cache: "no-store"
359
+ });
360
+ if (!res.ok) {
361
+ if (res.status === 401) this.client.forceLogout();
362
+ const body = await res.json().catch(() => null);
363
+ return { count: 0, error: body?.error || "Request failed", status: res.status };
364
+ }
365
+ const cr = res.headers.get("content-range");
366
+ const total = cr && cr.includes("/") ? parseInt(cr.split("/").pop() || "", 10) : NaN;
367
+ return { count: Number.isNaN(total) ? 0 : total, error: null, status: res.status };
368
+ }
369
+ getHeaders() {
370
+ return this.client.getHeaders();
371
+ }
372
+ async handleResponse(res) {
373
+ const text = await res.text();
374
+ let data = null;
375
+ try {
376
+ data = text ? JSON.parse(text) : null;
377
+ } catch {
378
+ }
379
+ if (!res.ok) {
380
+ if (res.status === 401) {
381
+ this.client.forceLogout();
382
+ }
383
+ return { data: null, error: data?.error || "Request failed", status: res.status };
384
+ }
385
+ return { data, error: null, status: res.status };
386
+ }
387
+ };
388
+
389
+ // src/modules/auth.ts
390
+ function createAuthModule(client) {
391
+ const get = (endpoint) => client.get(endpoint);
392
+ const post = (endpoint, body) => client.post(endpoint, body);
393
+ return {
394
+ async login(email, password) {
395
+ const res = await fetch(`${client.url}/api/login`, {
396
+ method: "POST",
397
+ headers: client.getHeaders(),
398
+ body: JSON.stringify({ email, password })
399
+ });
400
+ const contentType = res.headers.get("content-type");
401
+ if (!contentType?.includes("application/json")) {
402
+ throw new Error(`Login failed: Server returned ${res.status}. Please check your connection.`);
403
+ }
404
+ const data = await res.json().catch(() => {
405
+ throw new Error(`Login failed: Invalid JSON response (status ${res.status})`);
406
+ });
407
+ if (!res.ok) {
408
+ throw new Error(data?.error || `Login failed: ${res.status}`);
409
+ }
410
+ if (data.token) {
411
+ client.token = data.token;
412
+ localStorage.setItem("baas_token", data.token);
413
+ }
414
+ return data;
415
+ },
416
+ async logout() {
417
+ try {
418
+ await post("/api/logout");
419
+ } finally {
420
+ client.token = null;
421
+ localStorage.removeItem("baas_token");
422
+ }
423
+ },
424
+ // Anonymous sign-in (Supabase parity). Response carries access_token (+ a
425
+ // back-compat `token`); store whichever is present.
426
+ async signInAnonymous() {
427
+ const data = await post("/api/auth/anonymous");
428
+ const tok = data?.access_token || data?.token;
429
+ if (tok) {
430
+ client.token = tok;
431
+ localStorage.setItem("baas_token", tok);
432
+ }
433
+ return data;
434
+ },
435
+ // Passwordless: request a magic link + 6-digit email OTP. Always resolves on
436
+ // a well-formed request (no account enumeration).
437
+ async requestOtp(email, createUser = true) {
438
+ return post("/api/auth/otp", { email, create_user: createUser });
439
+ },
440
+ // Verify a passwordless OTP/magic-link and complete sign-in.
441
+ async verifyOtp(type, email, token) {
442
+ const data = await post("/api/auth/verify", { type, email, token });
443
+ const tok = data?.access_token || data?.token;
444
+ if (tok) {
445
+ client.token = tok;
446
+ localStorage.setItem("baas_token", tok);
447
+ }
448
+ return data;
449
+ },
450
+ // Upgrade the current anonymous guest to a real account (preserves user id).
451
+ // Requires the anonymous Bearer to be set (call after signInAnonymous).
452
+ async upgradeAnonymous(email, password) {
453
+ const data = await post("/api/auth/upgrade", { email, password });
454
+ const tok = data?.access_token || data?.token;
455
+ if (tok) {
456
+ client.token = tok;
457
+ localStorage.setItem("baas_token", tok);
458
+ }
459
+ return data;
460
+ },
461
+ async verifyMFA(mfaToken, code) {
462
+ const data = await post("/api/mfa/finalize", { mfa_token: mfaToken, code });
463
+ if (data.token) {
464
+ client.token = data.token;
465
+ localStorage.setItem("baas_token", data.token);
466
+ }
467
+ return data;
468
+ },
469
+ async verifyMFAWithRecoveryCode(mfaToken, recoveryCode) {
470
+ const data = await post("/api/mfa/finalize", { mfa_token: mfaToken, recovery_code: recoveryCode });
471
+ if (data.token) {
472
+ client.token = data.token;
473
+ localStorage.setItem("baas_token", data.token);
474
+ }
475
+ return data;
476
+ },
477
+ async setupMFA() {
478
+ return post("/api/mfa/setup");
479
+ },
480
+ async enableMFA(secret, code, recoveryCodes) {
481
+ const body = { secret, code };
482
+ if (recoveryCodes) {
483
+ body.recovery_codes = recoveryCodes;
484
+ }
485
+ return post("/api/mfa/enable", body);
486
+ },
487
+ async disableMFA(code) {
488
+ return post("/api/mfa/disable", { code });
489
+ },
490
+ async getProfile() {
491
+ return get("/api/profile");
492
+ },
493
+ async register(email, password) {
494
+ const data = await post("/api/register", { email, password });
495
+ if (data.error) {
496
+ throw new Error(data.error);
497
+ }
498
+ return data;
499
+ },
500
+ async forgotPassword(email) {
501
+ return post("/api/auth/forgot-password", { email });
502
+ },
503
+ async resetPassword(token, newPassword) {
504
+ return post("/api/auth/reset-password", { token, new_password: newPassword });
505
+ },
506
+ async validateResetToken(token) {
507
+ return get(`/api/auth/validate-reset-token?token=${token}`);
508
+ },
509
+ async verifyEmail(token) {
510
+ return post("/api/auth/verify-email", { token });
511
+ },
512
+ async requestEmailVerification() {
513
+ return post("/api/auth/request-verification");
514
+ },
515
+ async getAuthProviders() {
516
+ return get("/api/auth/providers");
517
+ },
518
+ async getAuthProvider(provider) {
519
+ return get(`/api/auth/providers/${provider}`);
520
+ },
521
+ async configureAuthProvider(provider, clientID, clientSecret, enabled) {
522
+ return post("/api/auth/providers", {
523
+ provider,
524
+ client_id: clientID,
525
+ client_secret: clientSecret,
526
+ enabled
527
+ });
528
+ }
529
+ };
530
+ }
531
+
532
+ // src/modules/users.ts
533
+ function createUsersModule(client) {
534
+ const get = (endpoint) => client.get(endpoint);
535
+ const put = (endpoint, body) => client.put(endpoint, body);
536
+ const del = (endpoint) => client.delete(endpoint);
537
+ return {
538
+ async list(limit = 20, offset = 0) {
539
+ return get(`/api/users?limit=${limit}&offset=${offset}`);
540
+ },
541
+ async update(id, updates) {
542
+ return put(`/api/users/${id}`, updates);
543
+ },
544
+ async delete(id) {
545
+ return del(`/api/users/${id}`);
546
+ }
547
+ };
548
+ }
549
+
550
+ // src/modules/database.ts
551
+ function createDatabaseModule(client) {
552
+ const get = (endpoint) => client.get(endpoint);
553
+ const post = (endpoint, body) => client.post(endpoint, body);
554
+ const patch = (endpoint, body) => client.patch(endpoint, body);
555
+ const del = (endpoint) => client.delete(endpoint);
556
+ return {
557
+ // Schemas
558
+ async getSchemas(options) {
559
+ const params = new URLSearchParams();
560
+ if (options?.search) params.append("search", options.search);
561
+ if (options?.limit) params.append("limit", options.limit.toString());
562
+ if (options?.offset) params.append("offset", options.offset.toString());
563
+ const query = params.toString();
564
+ return get(`/api/schemas${query ? `?${query}` : ""}`);
565
+ },
566
+ async getSchema(name) {
567
+ return get(`/api/schemas/${name}`);
568
+ },
569
+ async saveSchemas(data) {
570
+ return post("/api/schemas", data);
571
+ },
572
+ // Tables
573
+ async createTable(tableName, definition) {
574
+ return post("/api/schemas/tables", { table_name: tableName, definition });
575
+ },
576
+ async dropTable(tableName) {
577
+ return del(`/api/schemas/tables/${tableName}`);
578
+ },
579
+ async renameTable(tableName, newName) {
580
+ return post(`/api/schemas/tables/${tableName}/rename`, { new_name: newName });
581
+ },
582
+ // Columns
583
+ async addColumn(tableName, column) {
584
+ return post(`/api/schemas/tables/${tableName}/columns`, column);
585
+ },
586
+ async dropColumn(tableName, columnName) {
587
+ return del(`/api/schemas/tables/${tableName}/columns/${columnName}`);
588
+ },
589
+ async modifyColumn(tableName, columnName, changes) {
590
+ return patch(`/api/schemas/tables/${tableName}/columns/${columnName}`, changes);
591
+ },
592
+ async renameColumn(tableName, columnName, newName) {
593
+ return post(`/api/schemas/tables/${tableName}/columns/${columnName}/rename`, { new_name: newName });
594
+ },
595
+ async setColumnDefault(tableName, columnName, defaultValue) {
596
+ return patch(`/api/schemas/tables/${tableName}/columns/${columnName}/default`, { default_value: defaultValue });
597
+ },
598
+ // Foreign Keys
599
+ async addForeignKey(tableName, fk) {
600
+ return post(`/api/schemas/tables/${tableName}/foreign-keys`, fk);
601
+ },
602
+ async listForeignKeys(tableName) {
603
+ return get(`/api/schemas/tables/${tableName}/foreign-keys`);
604
+ },
605
+ async dropForeignKey(tableName, constraintName) {
606
+ return del(`/api/schemas/tables/${tableName}/foreign-keys/${constraintName}`);
607
+ },
608
+ // Constraints
609
+ async addUniqueConstraint(tableName, columnName) {
610
+ return post(`/api/schemas/tables/${tableName}/constraints/unique`, { column: columnName });
611
+ },
612
+ async dropConstraint(tableName, constraintName) {
613
+ return del(`/api/schemas/tables/${tableName}/constraints/${constraintName}`);
614
+ },
615
+ // Data operations
616
+ async raw(query) {
617
+ return post("/api/v1/sql", { query });
618
+ },
619
+ async queryData(tableName, options) {
620
+ const params = new URLSearchParams();
621
+ if (options.page) params.append("page", options.page.toString());
622
+ if (options.limit) params.append("limit", options.limit.toString());
623
+ if (options.filters && options.filters.length > 0) {
624
+ params.append("filters", JSON.stringify(options.filters));
625
+ }
626
+ return get(`/api/v1/data/${tableName}/query?${params.toString()}`);
627
+ },
628
+ async downloadExport(tableName, format, filters) {
629
+ const params = new URLSearchParams();
630
+ if (filters && filters.length > 0) {
631
+ params.append("filters", JSON.stringify(filters));
632
+ }
633
+ const res = await fetch(`${client.url}/api/v1/export/${tableName}/${format}?${params.toString()}`, {
634
+ headers: client.getHeaders()
635
+ });
636
+ if (!res.ok) {
637
+ const data = await res.json();
638
+ return { error: data.error || `Export failed: ${res.status}` };
639
+ }
640
+ const blob = await res.blob();
641
+ const url = window.URL.createObjectURL(blob);
642
+ const a = document.createElement("a");
643
+ a.href = url;
644
+ a.download = `${tableName}_${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.${format === "backup" ? "dump" : format}`;
645
+ document.body.appendChild(a);
646
+ a.click();
647
+ window.URL.revokeObjectURL(url);
648
+ document.body.removeChild(a);
649
+ return { success: true };
650
+ }
651
+ };
652
+ }
653
+
654
+ // src/modules/storage.ts
655
+ function createStorageModule(client) {
656
+ const get = (endpoint) => client.get(endpoint);
657
+ const post = (endpoint, body) => client.post(endpoint, body);
658
+ const put = (endpoint, body) => client.put(endpoint, body);
659
+ const del = (endpoint) => client.delete(endpoint);
660
+ async function uploadFile(fileOrTable, fileOrBucketId) {
661
+ let file;
662
+ let bucketId;
663
+ if (fileOrTable instanceof File) {
664
+ file = fileOrTable;
665
+ bucketId = typeof fileOrBucketId === "string" ? fileOrBucketId : void 0;
666
+ } else {
667
+ file = fileOrBucketId;
668
+ bucketId = void 0;
669
+ }
670
+ const formData = new FormData();
671
+ formData.append("file", file);
672
+ if (bucketId) {
673
+ formData.append("bucket_id", bucketId);
674
+ }
675
+ const headers = client.getHeaders("");
676
+ const res = await fetch(`${client.url}/api/storage/upload`, {
677
+ method: "POST",
678
+ headers,
679
+ body: formData
680
+ });
681
+ if (!res.ok) {
682
+ if (res.status === 401) client.forceLogout();
683
+ const err = await res.json().catch(() => ({ error: `Upload failed: ${res.status}` }));
684
+ throw new Error(err.error ?? `Upload failed: ${res.status}`);
685
+ }
686
+ return res.json();
687
+ }
688
+ return {
689
+ upload: uploadFile,
690
+ async listFiles() {
691
+ return get("/api/storage/files");
692
+ },
693
+ async getFile(fileId, expiresIn) {
694
+ const q = expiresIn && expiresIn > 0 ? `?expiresIn=${expiresIn}` : "";
695
+ return get(`/api/storage/files/${fileId}${q}`);
696
+ },
697
+ async createSignedUrl(fileId, expiresIn) {
698
+ const res = await get(
699
+ `/api/storage/files/${fileId}${expiresIn && expiresIn > 0 ? `?expiresIn=${expiresIn}` : ""}`
700
+ );
701
+ return { signedUrl: res?.url };
702
+ },
703
+ async deleteFile(fileId) {
704
+ return del(`/api/storage/files/${fileId}`);
705
+ },
706
+ async createBucket(name, isPublic = false) {
707
+ return post("/api/storage/buckets", { name, is_public: isPublic });
708
+ },
709
+ async updateBucket(bucketId, opts) {
710
+ return put(`/api/storage/buckets/${bucketId}`, { is_public: opts.isPublic });
711
+ },
712
+ async listBuckets() {
713
+ return get("/api/storage/buckets");
714
+ },
715
+ async getBucket(bucketId) {
716
+ return get(`/api/storage/buckets/${bucketId}`);
717
+ },
718
+ async deleteBucket(bucketId) {
719
+ return del(`/api/storage/buckets/${bucketId}`);
720
+ },
721
+ async listBucketFiles(bucketId) {
722
+ return get(`/api/storage/buckets/${bucketId}/files`);
723
+ },
724
+ async download(fileId) {
725
+ const res = await fetch(`${client.url}/api/storage/files/${fileId}/download`, {
726
+ headers: client.getHeaders("")
727
+ });
728
+ if (!res.ok) {
729
+ if (res.status === 401) client.forceLogout();
730
+ const err = await res.json().catch(() => ({ error: `Download failed: ${res.status}` }));
731
+ throw new Error(err.error ?? `Download failed: ${res.status}`);
732
+ }
733
+ return res.blob();
734
+ }
735
+ };
736
+ }
737
+
738
+ // src/modules/backups.ts
739
+ function createBackupsModule(client) {
740
+ const get = (endpoint) => client.get(endpoint);
741
+ const post = (endpoint, body) => client.post(endpoint, body);
742
+ const del = (endpoint) => client.delete(endpoint);
743
+ return {
744
+ async create(options) {
745
+ return post("/api/backups", options || {});
746
+ },
747
+ async list() {
748
+ return get("/api/backups");
749
+ },
750
+ async get(backupId) {
751
+ return get(`/api/backups/${backupId}`);
752
+ },
753
+ async restore(backupId) {
754
+ return post(`/api/backups/${backupId}/restore`, {});
755
+ },
756
+ async delete(backupId) {
757
+ return del(`/api/backups/${backupId}`);
758
+ },
759
+ getDownloadUrl(backupId) {
760
+ const token = client.getDynamicToken();
761
+ return `${client.url}/api/backups/${backupId}/download?access_token=${token}&apikey=${client.apiKey}`;
762
+ },
763
+ async listTables() {
764
+ return get("/api/backups/tables");
765
+ },
766
+ async importFile(formData) {
767
+ const headers = client.getHeaders();
768
+ delete headers["Content-Type"];
769
+ const res = await fetch(`${client.url}/api/import`, {
770
+ method: "POST",
771
+ headers,
772
+ body: formData
773
+ });
774
+ const data = await res.json();
775
+ if (!res.ok && res.status === 401) client.forceLogout();
776
+ return data;
777
+ }
778
+ };
779
+ }
780
+
781
+ // src/modules/migrations.ts
782
+ function createMigrationsModule(client) {
783
+ const get = (endpoint) => client.get(endpoint);
784
+ const post = (endpoint, body) => client.post(endpoint, body);
785
+ const del = (endpoint) => client.delete(endpoint);
786
+ return {
787
+ async create(input) {
788
+ return post("/api/migrations", input);
789
+ },
790
+ async list() {
791
+ return get("/api/migrations");
792
+ },
793
+ async get(id) {
794
+ return get(`/api/migrations/${id}`);
795
+ },
796
+ async apply(id) {
797
+ return post(`/api/migrations/${id}/apply`, {});
798
+ },
799
+ async rollback(id) {
800
+ return post(`/api/migrations/${id}/rollback`, {});
801
+ },
802
+ async delete(id) {
803
+ return del(`/api/migrations/${id}`);
804
+ },
805
+ async generate(tableName, changes) {
806
+ return post("/api/migrations/generate", { table_name: tableName, changes });
807
+ }
808
+ };
809
+ }
810
+
811
+ // src/modules/functions.ts
812
+ function createFunctionsModule(client) {
813
+ const post = (endpoint, body) => client.post(endpoint, body);
814
+ const get = (endpoint) => client.get(endpoint);
815
+ const del = (endpoint) => client.delete(endpoint);
816
+ const put = (endpoint, body) => client.put(endpoint, body);
817
+ return {
818
+ async invoke(id, data = {}) {
819
+ return post(`/api/functions/${id}/execute`, data);
820
+ },
821
+ async get(id) {
822
+ return get(`/api/functions/${id}`);
823
+ },
824
+ async list() {
825
+ return get("/api/functions");
826
+ },
827
+ async create(name, code, options) {
828
+ return post("/api/functions", { name, code, ...options });
829
+ },
830
+ async delete(id) {
831
+ return del(`/api/functions/${id}`);
832
+ },
833
+ async update(id, code, options) {
834
+ const current = await get(`/api/functions/${id}`);
835
+ const name = current?.name ?? current?.data?.name;
836
+ return post("/api/functions", { name, code, ...options });
837
+ },
838
+ async executeCode(code, options) {
839
+ return post("/api/functions/execute", { code, ...options });
840
+ },
841
+ async listHooks() {
842
+ return get("/api/hooks");
843
+ },
844
+ async createHook(data) {
845
+ return post("/api/hooks", data);
846
+ },
847
+ async deleteHook(id) {
848
+ return del(`/api/hooks/${id}`);
849
+ }
850
+ };
851
+ }
852
+
853
+ // src/modules/jobs.ts
854
+ function createJobsModule(client) {
855
+ const get = (endpoint) => client.get(endpoint);
856
+ const post = (endpoint, body) => client.post(endpoint, body);
857
+ const put = (endpoint, body) => client.put(endpoint, body);
858
+ const del = (endpoint) => client.delete(endpoint);
859
+ return {
860
+ async create(input) {
861
+ return post("/api/jobs", input);
862
+ },
863
+ async list() {
864
+ return get("/api/jobs");
865
+ },
866
+ async get(id) {
867
+ return get(`/api/jobs/${id}`);
868
+ },
869
+ async update(id, input) {
870
+ return put(`/api/jobs/${id}`, input);
871
+ },
872
+ async delete(id) {
873
+ return del(`/api/jobs/${id}`);
874
+ },
875
+ async toggle(id, enabled) {
876
+ return post(`/api/jobs/${id}/toggle`, { enabled });
877
+ },
878
+ async runNow(id) {
879
+ return post(`/api/jobs/${id}/run`);
880
+ },
881
+ async getExecutions(id, limit) {
882
+ const params = new URLSearchParams();
883
+ if (limit) params.set("limit", limit.toString());
884
+ return get(`/api/jobs/${id}/executions?${params.toString()}`);
885
+ }
886
+ };
887
+ }
888
+
889
+ // src/modules/env-vars.ts
890
+ function createEnvVarsModule(client) {
891
+ const get = (endpoint) => client.get(endpoint);
892
+ const post = (endpoint, body) => client.post(endpoint, body);
893
+ const put = (endpoint, body) => client.put(endpoint, body);
894
+ const del = (endpoint) => client.delete(endpoint);
895
+ return {
896
+ async create(input) {
897
+ return post("/api/env-vars", input);
898
+ },
899
+ async list() {
900
+ return get("/api/env-vars");
901
+ },
902
+ async get(id) {
903
+ return get(`/api/env-vars/${id}`);
904
+ },
905
+ async update(id, value) {
906
+ return put(`/api/env-vars/${id}`, { value });
907
+ },
908
+ async delete(id) {
909
+ return del(`/api/env-vars/${id}`);
910
+ }
911
+ };
912
+ }
913
+
914
+ // src/modules/email.ts
915
+ function createEmailModule(client) {
916
+ const get = (endpoint) => client.get(endpoint);
917
+ const post = (endpoint, body) => client.post(endpoint, body);
918
+ const put = (endpoint, body) => client.put(endpoint, body);
919
+ const del = (endpoint) => client.delete(endpoint);
920
+ return {
921
+ async send(input) {
922
+ return post("/api/email/send", input);
923
+ },
924
+ async getConfig() {
925
+ return get("/api/email/config");
926
+ },
927
+ async saveConfig(config) {
928
+ return post("/api/email/config", config);
929
+ },
930
+ async createTemplate(template) {
931
+ return post("/api/email/templates", template);
932
+ },
933
+ async listTemplates() {
934
+ return get("/api/email/templates");
935
+ },
936
+ async getTemplate(id) {
937
+ return get(`/api/email/templates/${id}`);
938
+ },
939
+ async updateTemplate(id, template) {
940
+ return put(`/api/email/templates/${id}`, template);
941
+ },
942
+ async deleteTemplate(id) {
943
+ return del(`/api/email/templates/${id}`);
944
+ },
945
+ async getLogs(options) {
946
+ const params = new URLSearchParams();
947
+ if (options?.limit) params.set("limit", options.limit.toString());
948
+ if (options?.offset) params.set("offset", options.offset.toString());
949
+ return get(`/api/email/logs?${params.toString()}`);
950
+ }
951
+ };
952
+ }
953
+
954
+ // src/modules/search.ts
955
+ function createSearchModule(client) {
956
+ const post = (endpoint, body) => client.post(endpoint, body);
957
+ return {
958
+ async search(query, options) {
959
+ return post("/api/search", {
960
+ query,
961
+ tables: options?.tables,
962
+ columns: options?.columns,
963
+ limit: options?.limit,
964
+ offset: options?.offset
965
+ });
966
+ },
967
+ async createIndex(table, columns) {
968
+ return post("/api/search/index", { table, columns });
969
+ }
970
+ };
971
+ }
972
+
973
+ // src/modules/graphql.ts
974
+ function createGraphQLModule(client) {
975
+ const get = (endpoint) => client.get(endpoint);
976
+ const post = (endpoint, body) => client.post(endpoint, body);
977
+ return {
978
+ async query(query, variables) {
979
+ return post("/api/graphql", { query, variables });
980
+ },
981
+ async getSchema() {
982
+ return post("/api/graphql", {
983
+ query: "{ __schema { queryType { name } mutationType { name } types { name kind } } }"
984
+ });
985
+ },
986
+ getPlaygroundUrl() {
987
+ return `${client.url}/api/graphql/playground`;
988
+ }
989
+ };
990
+ }
991
+
992
+ // src/modules/metrics.ts
993
+ function createMetricsModule(client) {
994
+ const get = (endpoint) => client.get(endpoint);
995
+ return {
996
+ async getDashboardStats() {
997
+ return get("/api/metrics/dashboard");
998
+ },
999
+ async getRequestLogs(options) {
1000
+ const params = new URLSearchParams();
1001
+ if (options?.limit) params.set("limit", options.limit.toString());
1002
+ if (options?.offset) params.set("offset", options.offset.toString());
1003
+ if (options?.method) params.set("method", options.method);
1004
+ if (options?.status) params.set("status", options.status);
1005
+ if (options?.path) params.set("path", options.path);
1006
+ return get(`/api/metrics/requests?${params.toString()}`);
1007
+ },
1008
+ async getApplicationLogs(options) {
1009
+ const params = new URLSearchParams();
1010
+ if (options?.limit) params.set("limit", options.limit.toString());
1011
+ if (options?.offset) params.set("offset", options.offset.toString());
1012
+ if (options?.level) params.set("level", options.level);
1013
+ if (options?.source) params.set("source", options.source);
1014
+ if (options?.search) params.set("search", options.search);
1015
+ return get(`/api/metrics/logs?${params.toString()}`);
1016
+ },
1017
+ async getTimeseries(metric, options) {
1018
+ const params = new URLSearchParams({ metric });
1019
+ if (options?.interval) params.set("interval", options.interval);
1020
+ if (options?.start) params.set("start", options.start);
1021
+ if (options?.end) params.set("end", options.end);
1022
+ return get(`/api/metrics/timeseries?${params.toString()}`);
1023
+ }
1024
+ };
1025
+ }
1026
+
1027
+ // src/modules/audit.ts
1028
+ function createAuditModule(client) {
1029
+ const get = (endpoint) => client.get(endpoint);
1030
+ const del = (endpoint) => client.delete(endpoint);
1031
+ return {
1032
+ async list(options) {
1033
+ const params = new URLSearchParams();
1034
+ if (options?.limit) params.set("limit", options.limit.toString());
1035
+ if (options?.offset) params.set("offset", options.offset.toString());
1036
+ if (options?.action) params.set("action", options.action);
1037
+ if (options?.user_id) params.set("user_id", options.user_id);
1038
+ if (options?.method) params.set("method", options.method);
1039
+ if (options?.path) params.set("path", options.path);
1040
+ if (options?.status_code) params.set("status_code", options.status_code.toString());
1041
+ if (options?.start_date) params.set("start_date", options.start_date);
1042
+ if (options?.end_date) params.set("end_date", options.end_date);
1043
+ return get(`/api/audit/logs?${params.toString()}`);
1044
+ },
1045
+ async getActions() {
1046
+ return get("/api/audit/actions");
1047
+ },
1048
+ async exportLogs(format, options) {
1049
+ const params = new URLSearchParams();
1050
+ params.set("format", format);
1051
+ if (options?.action) params.set("action", options.action);
1052
+ if (options?.method) params.set("method", options.method);
1053
+ if (options?.path) params.set("path", options.path);
1054
+ if (options?.status_code) params.set("status_code", options.status_code.toString());
1055
+ if (options?.start_date) params.set("start_date", options.start_date);
1056
+ if (options?.end_date) params.set("end_date", options.end_date);
1057
+ const res = await fetch(`${client.url}/api/audit/export?${params.toString()}`, {
1058
+ headers: client.getHeaders(),
1059
+ credentials: "include"
1060
+ });
1061
+ if (!res.ok) {
1062
+ const data = await res.json();
1063
+ return { error: data.error || `Export failed: ${res.status}` };
1064
+ }
1065
+ const blob = await res.blob();
1066
+ const url = window.URL.createObjectURL(blob);
1067
+ const a = document.createElement("a");
1068
+ a.href = url;
1069
+ a.download = `audit_logs_${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.${format}`;
1070
+ document.body.appendChild(a);
1071
+ a.click();
1072
+ window.URL.revokeObjectURL(url);
1073
+ document.body.removeChild(a);
1074
+ return { success: true };
1075
+ },
1076
+ async purgePreview(olderThanDays) {
1077
+ return get(`/api/audit/purge/preview?older_than_days=${olderThanDays}`);
1078
+ },
1079
+ async purge(olderThanDays) {
1080
+ return del(`/api/audit/purge?older_than_days=${olderThanDays}`);
1081
+ }
1082
+ };
1083
+ }
1084
+
1085
+ // src/modules/webhooks.ts
1086
+ function createWebhooksModule(client) {
1087
+ const get = (endpoint) => client.get(endpoint);
1088
+ const post = (endpoint, body) => client.post(endpoint, body);
1089
+ const put = (endpoint, body) => client.put(endpoint, body);
1090
+ const del = (endpoint) => client.delete(endpoint);
1091
+ return {
1092
+ async list() {
1093
+ return get("/api/webhooks");
1094
+ },
1095
+ async get(id) {
1096
+ return get(`/api/webhooks/${id}`);
1097
+ },
1098
+ async create(input) {
1099
+ return post("/api/webhooks", input);
1100
+ },
1101
+ async update(id, input) {
1102
+ return put(`/api/webhooks/${id}`, input);
1103
+ },
1104
+ async delete(id) {
1105
+ return del(`/api/webhooks/${id}`);
1106
+ },
1107
+ async test(id) {
1108
+ return post(`/api/webhooks/${id}/test`);
1109
+ }
1110
+ };
1111
+ }
1112
+
1113
+ // src/modules/log-drains.ts
1114
+ function createLogDrainsModule(client) {
1115
+ const get = (endpoint) => client.get(endpoint);
1116
+ const post = (endpoint, body) => client.post(endpoint, body);
1117
+ const put = (endpoint, body) => client.put(endpoint, body);
1118
+ const del = (endpoint) => client.delete(endpoint);
1119
+ return {
1120
+ async create(input) {
1121
+ return post("/api/log-drains", input);
1122
+ },
1123
+ async list() {
1124
+ return get("/api/log-drains");
1125
+ },
1126
+ async get(id) {
1127
+ return get(`/api/log-drains/${id}`);
1128
+ },
1129
+ async update(id, input) {
1130
+ return put(`/api/log-drains/${id}`, input);
1131
+ },
1132
+ async delete(id) {
1133
+ return del(`/api/log-drains/${id}`);
1134
+ },
1135
+ async toggle(id, enabled) {
1136
+ return post(`/api/log-drains/${id}/toggle`, { enabled });
1137
+ },
1138
+ async test(id) {
1139
+ return post(`/api/log-drains/${id}/test`);
1140
+ }
1141
+ };
1142
+ }
1143
+
1144
+ // src/modules/branches.ts
1145
+ function createBranchesModule(client) {
1146
+ const get = (endpoint) => client.get(endpoint);
1147
+ const post = (endpoint, body) => client.post(endpoint, body);
1148
+ const del = (endpoint) => client.delete(endpoint);
1149
+ return {
1150
+ async create(input) {
1151
+ return post("/api/branches", input);
1152
+ },
1153
+ async list() {
1154
+ return get("/api/branches");
1155
+ },
1156
+ async get(id) {
1157
+ return get(`/api/branches/${id}`);
1158
+ },
1159
+ async delete(id) {
1160
+ return del(`/api/branches/${id}`);
1161
+ },
1162
+ async merge(id, targetBranchId) {
1163
+ return post(`/api/branches/${id}/merge`, { target_branch_id: targetBranchId });
1164
+ },
1165
+ async reset(id) {
1166
+ return post(`/api/branches/${id}/reset`);
1167
+ }
1168
+ };
1169
+ }
1170
+
1171
+ // src/realtime.ts
1172
+ var RealtimeService = class {
1173
+ constructor(url, apiKey, tokenProvider, wsConstructor = typeof WebSocket !== "undefined" ? WebSocket : null) {
1174
+ this.url = url;
1175
+ this.apiKey = apiKey;
1176
+ this.tokenProvider = tokenProvider;
1177
+ this.wsConstructor = wsConstructor;
1178
+ }
1179
+ socket = null;
1180
+ subscribers = /* @__PURE__ */ new Map();
1181
+ reconnectAttempts = 0;
1182
+ maxReconnectAttempts = 5;
1183
+ reconnectInterval = 3e3;
1184
+ /**
1185
+ * Initialize the WebSocket connection
1186
+ */
1187
+ connect() {
1188
+ if (this.socket?.readyState === WebSocket.OPEN) return Promise.resolve();
1189
+ return new Promise((resolve, reject) => {
1190
+ const token = this.tokenProvider();
1191
+ if (!token) {
1192
+ reject(new Error("Missing authentication token for Realtime connection"));
1193
+ return;
1194
+ }
1195
+ const wsUrl = this.url.replace(/^http/, "ws") + "/api/ws";
1196
+ const fullUrl = this.apiKey ? `${wsUrl}?apikey=${this.apiKey}&token=${token}` : `${wsUrl}?token=${token}`;
1197
+ if (!this.wsConstructor) {
1198
+ reject(new Error("WebSocket constructor not provided or available in this environment"));
1199
+ return;
1200
+ }
1201
+ const socket = new this.wsConstructor(fullUrl);
1202
+ this.socket = socket;
1203
+ socket.onopen = () => {
1204
+ console.log("BaaS Realtime: Connected");
1205
+ this.reconnectAttempts = 0;
1206
+ for (const table of this.subscribers.keys()) {
1207
+ this.sendSub("subscribe", table);
1208
+ }
1209
+ resolve();
1210
+ };
1211
+ socket.onmessage = (event) => {
1212
+ const raw = event.data;
1213
+ const parts = raw.split("\n").filter((s) => s.trim());
1214
+ for (const part of parts) {
1215
+ try {
1216
+ const payload = JSON.parse(part);
1217
+ this.handleEvent(payload);
1218
+ } catch {
1219
+ const chunks = part.replace(/\}\s*\{/g, "}\n{").split("\n");
1220
+ for (const chunk of chunks) {
1221
+ try {
1222
+ const payload = JSON.parse(chunk);
1223
+ this.handleEvent(payload);
1224
+ } catch {
1225
+ }
1226
+ }
1227
+ }
1228
+ }
1229
+ };
1230
+ socket.onerror = (error) => {
1231
+ console.error("BaaS Realtime: WebSocket Error", error);
1232
+ reject(error);
1233
+ };
1234
+ socket.onclose = () => {
1235
+ console.log("BaaS Realtime: Disconnected");
1236
+ this.socket = null;
1237
+ this.attemptReconnect();
1238
+ };
1239
+ });
1240
+ }
1241
+ /**
1242
+ * Subscribe to changes on a specific table
1243
+ */
1244
+ async subscribe(table, action, callback) {
1245
+ await this.connect();
1246
+ const isNewTable = !this.subscribers.has(table);
1247
+ if (isNewTable) {
1248
+ this.subscribers.set(table, /* @__PURE__ */ new Set());
1249
+ }
1250
+ const sub = { action, callback };
1251
+ this.subscribers.get(table).add(sub);
1252
+ if (isNewTable && table !== "*") {
1253
+ this.sendSub("subscribe", table);
1254
+ }
1255
+ return {
1256
+ unsubscribe: () => {
1257
+ const tableSubs = this.subscribers.get(table);
1258
+ if (tableSubs) {
1259
+ tableSubs.delete(sub);
1260
+ if (tableSubs.size === 0) {
1261
+ this.subscribers.delete(table);
1262
+ if (table !== "*") this.sendSub("unsubscribe", table);
1263
+ }
1264
+ }
1265
+ }
1266
+ };
1267
+ }
1268
+ /** Send a subscribe/unsubscribe control frame to the server. */
1269
+ sendSub(event, table) {
1270
+ if (this.socket?.readyState === WebSocket.OPEN) {
1271
+ this.socket.send(JSON.stringify({ event, table }));
1272
+ }
1273
+ }
1274
+ /**
1275
+ * Handle incoming CDC events from the server
1276
+ */
1277
+ handleEvent(payload) {
1278
+ const tableSubs = this.subscribers.get(payload.table);
1279
+ if (tableSubs) {
1280
+ for (const sub of tableSubs) {
1281
+ if (sub.action === "*" || sub.action.toLowerCase() === payload.action.toLowerCase()) {
1282
+ sub.callback(payload);
1283
+ }
1284
+ }
1285
+ }
1286
+ const wildcardSubs = this.subscribers.get("*");
1287
+ if (wildcardSubs) {
1288
+ for (const sub of wildcardSubs) {
1289
+ if (sub.action === "*" || sub.action.toLowerCase() === payload.action.toLowerCase()) {
1290
+ sub.callback(payload);
1291
+ }
1292
+ }
1293
+ }
1294
+ }
1295
+ /**
1296
+ * Attempt to reconnect on connection loss
1297
+ */
1298
+ attemptReconnect() {
1299
+ if (this.reconnectAttempts < this.maxReconnectAttempts) {
1300
+ this.reconnectAttempts++;
1301
+ console.log(`BaaS Realtime: Attempting reconnect ${this.reconnectAttempts}/${this.maxReconnectAttempts}...`);
1302
+ setTimeout(() => this.connect(), this.reconnectInterval);
1303
+ } else {
1304
+ console.error("BaaS Realtime: Max reconnect attempts reached");
1305
+ }
1306
+ }
1307
+ /**
1308
+ * Close the connection
1309
+ */
1310
+ disconnect() {
1311
+ if (this.socket) {
1312
+ this.socket.onclose = null;
1313
+ this.socket.close();
1314
+ this.socket = null;
1315
+ }
1316
+ }
1317
+ /** @internal - For testing only */
1318
+ get _socket() {
1319
+ return this.socket;
1320
+ }
1321
+ };
1322
+
1323
+ // src/modules/realtime.ts
1324
+ function createRealtimeModule(client) {
1325
+ const service = new RealtimeService(
1326
+ client.url,
1327
+ client.apiKey,
1328
+ () => client.getDynamicToken(),
1329
+ typeof WebSocket !== "undefined" ? WebSocket : void 0
1330
+ );
1331
+ return {
1332
+ async subscribe(table, action, callback) {
1333
+ return service.subscribe(table, action, callback);
1334
+ }
1335
+ };
1336
+ }
1337
+
1338
+ // src/modules/api-keys.ts
1339
+ function createApiKeysModule(client) {
1340
+ const get = (endpoint) => client.get(endpoint);
1341
+ const post = (endpoint, body) => client.post(endpoint, body);
1342
+ const del = (endpoint) => client.delete(endpoint);
1343
+ return {
1344
+ async create(name, permissions, expiresAt) {
1345
+ return post("/api/api-keys", { name, permissions, expires_at: expiresAt });
1346
+ },
1347
+ async list() {
1348
+ return get("/api/api-keys");
1349
+ },
1350
+ async revoke(keyId) {
1351
+ return post(`/api/api-keys/${keyId}/revoke`, {});
1352
+ },
1353
+ async delete(keyId) {
1354
+ return del(`/api/api-keys/${keyId}`);
1355
+ },
1356
+ async getInstanceToken() {
1357
+ return get("/api/api-keys/instance");
1358
+ },
1359
+ async regenerateInstanceToken() {
1360
+ return post("/api/api-keys/instance/regenerate", {});
1361
+ }
1362
+ };
1363
+ }
1364
+
1365
+ // src/modules/environments.ts
1366
+ function createEnvironmentsModule(client) {
1367
+ const get = (endpoint) => client.get(endpoint);
1368
+ const post = (endpoint, body) => client.post(endpoint, body);
1369
+ return {
1370
+ async status() {
1371
+ return get("/api/environments/status");
1372
+ },
1373
+ async init() {
1374
+ return post("/api/environments/init");
1375
+ },
1376
+ async promote() {
1377
+ return post("/api/environments/promote");
1378
+ },
1379
+ async revert() {
1380
+ return post("/api/environments/revert");
1381
+ },
1382
+ setActive(env) {
1383
+ client.setEnvironment(env);
1384
+ },
1385
+ getActive() {
1386
+ return client.getEnvironment();
1387
+ }
1388
+ };
1389
+ }
1390
+
1391
+ // src/modules/cors-origins.ts
1392
+ function createCorsOriginsModule(client) {
1393
+ const get = (endpoint) => client.get(endpoint);
1394
+ const post = (endpoint, body) => client.post(endpoint, body);
1395
+ const del = (endpoint) => client.delete(endpoint);
1396
+ return {
1397
+ async list() {
1398
+ return get("/api/cors-origins");
1399
+ },
1400
+ async create(origin, description) {
1401
+ return post("/api/cors-origins", { origin, description: description || "" });
1402
+ },
1403
+ async delete(id) {
1404
+ return del(`/api/cors-origins/${id}`);
1405
+ }
1406
+ };
1407
+ }
1408
+
1409
+ // src/modules/policies.ts
1410
+ function createPoliciesModule(client) {
1411
+ const get = (endpoint) => client.get(endpoint);
1412
+ const post = (endpoint, body) => client.post(endpoint, body);
1413
+ const del = (endpoint) => client.delete(endpoint);
1414
+ return {
1415
+ async create(input) {
1416
+ return post("/api/policies", input);
1417
+ },
1418
+ async list() {
1419
+ return get("/api/policies");
1420
+ },
1421
+ async delete(id) {
1422
+ return del(`/api/policies/${id}`);
1423
+ }
1424
+ };
1425
+ }
1426
+
1427
+ // src/modules/ip-whitelist.ts
1428
+ function createIPWhitelistModule(client) {
1429
+ const get = (endpoint) => client.get(endpoint);
1430
+ const post = (endpoint, body) => client.post(endpoint, body);
1431
+ const del = (endpoint) => client.delete(endpoint);
1432
+ return {
1433
+ async list() {
1434
+ return get("/api/ip-whitelist");
1435
+ },
1436
+ async create(ipAddress, description) {
1437
+ return post("/api/ip-whitelist", { ip_address: ipAddress, description: description || "" });
1438
+ },
1439
+ async delete(id) {
1440
+ return del(`/api/ip-whitelist/${id}`);
1441
+ }
1442
+ };
1443
+ }
1444
+
1445
+ // src/modules/cache.ts
1446
+ function createCacheModule(client) {
1447
+ const get = (endpoint) => client.get(endpoint);
1448
+ const post = (endpoint, body) => client.post(endpoint, body);
1449
+ const patch = (endpoint, body) => client.patch(endpoint, body);
1450
+ const del = (endpoint) => client.delete(endpoint);
1451
+ return {
1452
+ async getStatus() {
1453
+ return get("/api/cache/status");
1454
+ },
1455
+ async getStats() {
1456
+ return get("/api/cache/stats");
1457
+ },
1458
+ async listPolicies() {
1459
+ return get("/api/cache/policies");
1460
+ },
1461
+ async updatePolicy(namespace, body) {
1462
+ return patch(`/api/cache/policies/${encodeURIComponent(namespace)}`, body);
1463
+ },
1464
+ async removePolicy(namespace) {
1465
+ return del(`/api/cache/policies/${encodeURIComponent(namespace)}`);
1466
+ },
1467
+ async invalidateNamespace(namespace) {
1468
+ return post(`/api/cache/invalidate/${encodeURIComponent(namespace)}`);
1469
+ },
1470
+ async invalidateAll() {
1471
+ return post("/api/cache/invalidate-all");
1472
+ },
1473
+ async listKeys(prefix, cursor = 0, count = 100) {
1474
+ const params = new URLSearchParams({ prefix, cursor: String(cursor), count: String(count) });
1475
+ return get(`/api/cache/keys?${params}`);
1476
+ },
1477
+ async inspectKey(key) {
1478
+ return get(`/api/cache/keys/inspect?key=${encodeURIComponent(key)}`);
1479
+ }
1480
+ };
1481
+ }
1482
+
1483
+ // src/client.ts
1484
+ var BaasClient = class extends HttpClient {
1485
+ // Feature modules
1486
+ auth;
1487
+ users;
1488
+ database;
1489
+ storage;
1490
+ backups;
1491
+ migrations;
1492
+ functions;
1493
+ jobs;
1494
+ envVars;
1495
+ email;
1496
+ searchService;
1497
+ graphqlService;
1498
+ metrics;
1499
+ audit;
1500
+ webhooks;
1501
+ logDrains;
1502
+ branches;
1503
+ realtime;
1504
+ apiKeys;
1505
+ environments;
1506
+ corsOrigins;
1507
+ policies;
1508
+ ipWhitelist;
1509
+ cache;
1510
+ constructor(url, apiKey, options) {
1511
+ super(url, apiKey, options);
1512
+ this.auth = createAuthModule(this);
1513
+ this.users = createUsersModule(this);
1514
+ this.database = createDatabaseModule(this);
1515
+ this.storage = createStorageModule(this);
1516
+ this.backups = createBackupsModule(this);
1517
+ this.migrations = createMigrationsModule(this);
1518
+ this.functions = createFunctionsModule(this);
1519
+ this.jobs = createJobsModule(this);
1520
+ this.envVars = createEnvVarsModule(this);
1521
+ this.email = createEmailModule(this);
1522
+ this.searchService = createSearchModule(this);
1523
+ this.graphqlService = createGraphQLModule(this);
1524
+ this.metrics = createMetricsModule(this);
1525
+ this.audit = createAuditModule(this);
1526
+ this.webhooks = createWebhooksModule(this);
1527
+ this.logDrains = createLogDrainsModule(this);
1528
+ this.branches = createBranchesModule(this);
1529
+ this.realtime = createRealtimeModule(this);
1530
+ this.apiKeys = createApiKeysModule(this);
1531
+ this.environments = createEnvironmentsModule(this);
1532
+ this.corsOrigins = createCorsOriginsModule(this);
1533
+ this.policies = createPoliciesModule(this);
1534
+ this.ipWhitelist = createIPWhitelistModule(this);
1535
+ this.cache = createCacheModule(this);
1536
+ }
1537
+ /**
1538
+ * Create a query builder for fluent data queries
1539
+ */
1540
+ from(table) {
1541
+ return new QueryBuilder(table, this.url, this);
1542
+ }
1543
+ /**
1544
+ * Invoke a PL/pgSQL function (PostgREST `.rpc()` parity). Runs under the
1545
+ * caller's RLS context; args bind by name and are $N-safe. Pass [params] for
1546
+ * POST (named args in the body) or set `opts.get = true` for the GET variant.
1547
+ */
1548
+ async rpc(fn, params, opts) {
1549
+ if (opts?.get) {
1550
+ const qs = params ? "?" + new URLSearchParams(Object.entries(params).map(([k, v]) => [k, String(v)])).toString() : "";
1551
+ return this.get(`/api/v1/rpc/${fn}${qs}`);
1552
+ }
1553
+ return this.post(`/api/v1/rpc/${fn}`, params ?? {});
1554
+ }
1555
+ // ============================================
1556
+ // BACKWARD COMPATIBILITY METHODS
1557
+ // These delegate to the appropriate modules
1558
+ // ============================================
1559
+ // Auth shortcuts
1560
+ async login(email, password) {
1561
+ return this.auth.login(email, password);
1562
+ }
1563
+ async verifyMFA(mfaToken, code) {
1564
+ return this.auth.verifyMFA(mfaToken, code);
1565
+ }
1566
+ async getProfile() {
1567
+ return this.auth.getProfile();
1568
+ }
1569
+ async register(email, password) {
1570
+ return this.auth.register(email, password);
1571
+ }
1572
+ async forgotPassword(email) {
1573
+ return this.auth.forgotPassword(email);
1574
+ }
1575
+ async resetPassword(token, newPassword) {
1576
+ return this.auth.resetPassword(token, newPassword);
1577
+ }
1578
+ async validateResetToken(token) {
1579
+ return this.auth.validateResetToken(token);
1580
+ }
1581
+ async verifyEmail(token) {
1582
+ return this.auth.verifyEmail(token);
1583
+ }
1584
+ async requestEmailVerification() {
1585
+ return this.auth.requestEmailVerification();
1586
+ }
1587
+ async getAuthProviders() {
1588
+ return this.auth.getAuthProviders();
1589
+ }
1590
+ async getAuthProvider(provider) {
1591
+ return this.auth.getAuthProvider(provider);
1592
+ }
1593
+ async configureAuthProvider(provider, clientID, clientSecret, enabled) {
1594
+ return this.auth.configureAuthProvider(provider, clientID, clientSecret, enabled);
1595
+ }
1596
+ // Users shortcuts
1597
+ async listUsers(limit = 20, offset = 0) {
1598
+ return this.users.list(limit, offset);
1599
+ }
1600
+ async updateUser(id, updates) {
1601
+ return this.users.update(id, updates);
1602
+ }
1603
+ async deleteUser(id) {
1604
+ return this.users.delete(id);
1605
+ }
1606
+ // Database shortcuts
1607
+ async raw(query) {
1608
+ return this.database.raw(query);
1609
+ }
1610
+ async getSchemas(options) {
1611
+ return this.database.getSchemas(options);
1612
+ }
1613
+ async getSchema(name) {
1614
+ return this.database.getSchema(name);
1615
+ }
1616
+ async createTable(tableName, definition) {
1617
+ return this.database.createTable(tableName, definition);
1618
+ }
1619
+ async dropTable(tableName) {
1620
+ return this.database.dropTable(tableName);
1621
+ }
1622
+ async renameTable(tableName, newName) {
1623
+ return this.database.renameTable(tableName, newName);
1624
+ }
1625
+ async addColumn(tableName, column) {
1626
+ return this.database.addColumn(tableName, column);
1627
+ }
1628
+ async dropColumn(tableName, columnName) {
1629
+ return this.database.dropColumn(tableName, columnName);
1630
+ }
1631
+ async modifyColumn(tableName, columnName, changes) {
1632
+ return this.database.modifyColumn(tableName, columnName, changes);
1633
+ }
1634
+ async renameColumn(tableName, columnName, newName) {
1635
+ return this.database.renameColumn(tableName, columnName, newName);
1636
+ }
1637
+ async setColumnDefault(tableName, columnName, defaultValue) {
1638
+ return this.database.setColumnDefault(tableName, columnName, defaultValue);
1639
+ }
1640
+ async addForeignKey(tableName, fk) {
1641
+ return this.database.addForeignKey(tableName, fk);
1642
+ }
1643
+ async listForeignKeys(tableName) {
1644
+ return this.database.listForeignKeys(tableName);
1645
+ }
1646
+ async dropForeignKey(tableName, constraintName) {
1647
+ return this.database.dropForeignKey(tableName, constraintName);
1648
+ }
1649
+ async addUniqueConstraint(tableName, columnName) {
1650
+ return this.database.addUniqueConstraint(tableName, columnName);
1651
+ }
1652
+ async dropConstraint(tableName, constraintName) {
1653
+ return this.database.dropConstraint(tableName, constraintName);
1654
+ }
1655
+ async queryData(tableName, options) {
1656
+ return this.database.queryData(tableName, options);
1657
+ }
1658
+ async downloadExport(tableName, format, filters) {
1659
+ return this.database.downloadExport(tableName, format, filters);
1660
+ }
1661
+ // Storage shortcuts
1662
+ async upload(file, bucketId) {
1663
+ return this.storage.upload(file, bucketId);
1664
+ }
1665
+ async listStorageFiles() {
1666
+ return this.storage.listFiles();
1667
+ }
1668
+ async getStorageFile(fileId) {
1669
+ return this.storage.getFile(fileId);
1670
+ }
1671
+ async deleteStorageFile(fileId) {
1672
+ return this.storage.deleteFile(fileId);
1673
+ }
1674
+ async createStorageBucket(name, isPublic) {
1675
+ return this.storage.createBucket(name, isPublic);
1676
+ }
1677
+ async listStorageBuckets() {
1678
+ return this.storage.listBuckets();
1679
+ }
1680
+ async getStorageBucket(bucketId) {
1681
+ return this.storage.getBucket(bucketId);
1682
+ }
1683
+ async deleteStorageBucket(bucketId) {
1684
+ return this.storage.deleteBucket(bucketId);
1685
+ }
1686
+ async listStorageBucketFiles(bucketId) {
1687
+ return this.storage.listBucketFiles(bucketId);
1688
+ }
1689
+ // Functions shortcuts
1690
+ async invokeFunction(id, data) {
1691
+ return this.functions.invoke(id, data);
1692
+ }
1693
+ // API Keys shortcuts
1694
+ async createApiKey(name, permissions, expiresAt) {
1695
+ return this.apiKeys.create(name, permissions, expiresAt);
1696
+ }
1697
+ async listApiKeys() {
1698
+ return this.apiKeys.list();
1699
+ }
1700
+ async revokeApiKey(keyId) {
1701
+ return this.apiKeys.revoke(keyId);
1702
+ }
1703
+ async deleteApiKey(keyId) {
1704
+ return this.apiKeys.delete(keyId);
1705
+ }
1706
+ async getInstanceToken() {
1707
+ return this.apiKeys.getInstanceToken();
1708
+ }
1709
+ async regenerateInstanceToken() {
1710
+ return this.apiKeys.regenerateInstanceToken();
1711
+ }
1712
+ // Backups shortcuts
1713
+ async createBackup(options) {
1714
+ return this.backups.create(options);
1715
+ }
1716
+ async listBackups() {
1717
+ return this.backups.list();
1718
+ }
1719
+ async getBackup(backupId) {
1720
+ return this.backups.get(backupId);
1721
+ }
1722
+ async restoreBackup(backupId) {
1723
+ return this.backups.restore(backupId);
1724
+ }
1725
+ async deleteBackup(backupId) {
1726
+ return this.backups.delete(backupId);
1727
+ }
1728
+ getBackupDownloadUrl(backupId) {
1729
+ return this.backups.getDownloadUrl(backupId);
1730
+ }
1731
+ async listBackupTables() {
1732
+ return this.backups.listTables();
1733
+ }
1734
+ async importFile(formData) {
1735
+ return this.backups.importFile(formData);
1736
+ }
1737
+ // Search shortcuts
1738
+ async search(query, options) {
1739
+ return this.searchService.search(query, options);
1740
+ }
1741
+ async createSearchIndex(table, columns) {
1742
+ return this.searchService.createIndex(table, columns);
1743
+ }
1744
+ // GraphQL shortcuts
1745
+ async graphql(query, variables) {
1746
+ return this.graphqlService.query(query, variables);
1747
+ }
1748
+ getGraphQLPlaygroundUrl() {
1749
+ return this.graphqlService.getPlaygroundUrl();
1750
+ }
1751
+ // Migrations shortcuts
1752
+ async createMigration(input) {
1753
+ return this.migrations.create(input);
1754
+ }
1755
+ async listMigrations() {
1756
+ return this.migrations.list();
1757
+ }
1758
+ async getMigration(id) {
1759
+ return this.migrations.get(id);
1760
+ }
1761
+ async applyMigration(id) {
1762
+ return this.migrations.apply(id);
1763
+ }
1764
+ async rollbackMigration(id) {
1765
+ return this.migrations.rollback(id);
1766
+ }
1767
+ async deleteMigration(id) {
1768
+ return this.migrations.delete(id);
1769
+ }
1770
+ async generateMigration(tableName, changes) {
1771
+ return this.migrations.generate(tableName, changes);
1772
+ }
1773
+ // Email shortcuts
1774
+ async sendEmail(input) {
1775
+ return this.email.send(input);
1776
+ }
1777
+ async getEmailConfig() {
1778
+ return this.email.getConfig();
1779
+ }
1780
+ async saveEmailConfig(config) {
1781
+ return this.email.saveConfig(config);
1782
+ }
1783
+ async createEmailTemplate(template) {
1784
+ return this.email.createTemplate(template);
1785
+ }
1786
+ async listEmailTemplates() {
1787
+ return this.email.listTemplates();
1788
+ }
1789
+ async getEmailTemplate(id) {
1790
+ return this.email.getTemplate(id);
1791
+ }
1792
+ async updateEmailTemplate(id, template) {
1793
+ return this.email.updateTemplate(id, template);
1794
+ }
1795
+ async deleteEmailTemplate(id) {
1796
+ return this.email.deleteTemplate(id);
1797
+ }
1798
+ async getEmailLogs(options) {
1799
+ return this.email.getLogs(options);
1800
+ }
1801
+ // Metrics shortcuts
1802
+ async getDashboardStats() {
1803
+ return this.metrics.getDashboardStats();
1804
+ }
1805
+ async getRequestLogs(options) {
1806
+ return this.metrics.getRequestLogs(options);
1807
+ }
1808
+ async getApplicationLogs(options) {
1809
+ return this.metrics.getApplicationLogs(options);
1810
+ }
1811
+ async getMetricTimeseries(metric, options) {
1812
+ return this.metrics.getTimeseries(metric, options);
1813
+ }
1814
+ // Jobs shortcuts
1815
+ async createJob(input) {
1816
+ return this.jobs.create(input);
1817
+ }
1818
+ async listJobs() {
1819
+ return this.jobs.list();
1820
+ }
1821
+ async getJob(id) {
1822
+ return this.jobs.get(id);
1823
+ }
1824
+ async updateJob(id, input) {
1825
+ return this.jobs.update(id, input);
1826
+ }
1827
+ async deleteJob(id) {
1828
+ return this.jobs.delete(id);
1829
+ }
1830
+ async toggleJob(id, enabled) {
1831
+ return this.jobs.toggle(id, enabled);
1832
+ }
1833
+ async runJobNow(id) {
1834
+ return this.jobs.runNow(id);
1835
+ }
1836
+ async getJobExecutions(id, limit) {
1837
+ return this.jobs.getExecutions(id, limit);
1838
+ }
1839
+ // Env Vars shortcuts
1840
+ async createEnvVar(input) {
1841
+ return this.envVars.create(input);
1842
+ }
1843
+ async listEnvVars() {
1844
+ return this.envVars.list();
1845
+ }
1846
+ async getEnvVar(id) {
1847
+ return this.envVars.get(id);
1848
+ }
1849
+ async updateEnvVar(id, value) {
1850
+ return this.envVars.update(id, value);
1851
+ }
1852
+ async deleteEnvVar(id) {
1853
+ return this.envVars.delete(id);
1854
+ }
1855
+ // Branches shortcuts
1856
+ async createBranch(input) {
1857
+ return this.branches.create(input);
1858
+ }
1859
+ async listBranches() {
1860
+ return this.branches.list();
1861
+ }
1862
+ async getBranch(id) {
1863
+ return this.branches.get(id);
1864
+ }
1865
+ async deleteBranch(id) {
1866
+ return this.branches.delete(id);
1867
+ }
1868
+ async mergeBranch(id, targetBranchId) {
1869
+ return this.branches.merge(id, targetBranchId);
1870
+ }
1871
+ async resetBranch(id) {
1872
+ return this.branches.reset(id);
1873
+ }
1874
+ // Log Drains shortcuts
1875
+ async createLogDrain(input) {
1876
+ return this.logDrains.create(input);
1877
+ }
1878
+ async listLogDrains() {
1879
+ return this.logDrains.list();
1880
+ }
1881
+ async getLogDrain(id) {
1882
+ return this.logDrains.get(id);
1883
+ }
1884
+ async updateLogDrain(id, input) {
1885
+ return this.logDrains.update(id, input);
1886
+ }
1887
+ async deleteLogDrain(id) {
1888
+ return this.logDrains.delete(id);
1889
+ }
1890
+ async toggleLogDrain(id, enabled) {
1891
+ return this.logDrains.toggle(id, enabled);
1892
+ }
1893
+ async testLogDrain(id) {
1894
+ return this.logDrains.test(id);
1895
+ }
1896
+ // Webhooks shortcuts
1897
+ async listWebhooks() {
1898
+ return this.webhooks.list();
1899
+ }
1900
+ async getWebhook(id) {
1901
+ return this.webhooks.get(id);
1902
+ }
1903
+ async createWebhook(input) {
1904
+ return this.webhooks.create(input);
1905
+ }
1906
+ async updateWebhook(id, input) {
1907
+ return this.webhooks.update(id, input);
1908
+ }
1909
+ async deleteWebhook(id) {
1910
+ return this.webhooks.delete(id);
1911
+ }
1912
+ async testWebhook(id) {
1913
+ return this.webhooks.test(id);
1914
+ }
1915
+ // Audit shortcuts
1916
+ async listAuditLogs(options) {
1917
+ return this.audit.list(options);
1918
+ }
1919
+ async getAuditActions() {
1920
+ return this.audit.getActions();
1921
+ }
1922
+ async exportAuditLogs(format, options) {
1923
+ return this.audit.exportLogs(format, options);
1924
+ }
1925
+ async previewPurgeAuditLogs(olderThanDays) {
1926
+ return this.audit.purgePreview(olderThanDays);
1927
+ }
1928
+ async purgeAuditLogs(olderThanDays) {
1929
+ return this.audit.purge(olderThanDays);
1930
+ }
1931
+ // Realtime shortcuts
1932
+ subscribe(table, action, callback) {
1933
+ return this.realtime.subscribe(table, action, callback);
1934
+ }
1935
+ // Environment shortcuts
1936
+ async getEnvironmentStatus() {
1937
+ return this.environments.status();
1938
+ }
1939
+ async initTestEnvironment() {
1940
+ return this.environments.init();
1941
+ }
1942
+ async promoteTestToProd() {
1943
+ return this.environments.promote();
1944
+ }
1945
+ async revertTestEnvironment() {
1946
+ return this.environments.revert();
1947
+ }
1948
+ // CORS Origins shortcuts
1949
+ async listCorsOrigins() {
1950
+ return this.corsOrigins.list();
1951
+ }
1952
+ async addCorsOrigin(origin, description) {
1953
+ return this.corsOrigins.create(origin, description);
1954
+ }
1955
+ async deleteCorsOrigin(id) {
1956
+ return this.corsOrigins.delete(id);
1957
+ }
1958
+ // Policies shortcuts
1959
+ async listPolicies() {
1960
+ return this.policies.list();
1961
+ }
1962
+ async createPolicy(input) {
1963
+ return this.policies.create(input);
1964
+ }
1965
+ async deletePolicy(id) {
1966
+ return this.policies.delete(id);
1967
+ }
1968
+ // IP Whitelist shortcuts
1969
+ async listIPWhitelist() {
1970
+ return this.ipWhitelist.list();
1971
+ }
1972
+ async addIPWhitelistEntry(ipAddress, description) {
1973
+ return this.ipWhitelist.create(ipAddress, description);
1974
+ }
1975
+ async deleteIPWhitelistEntry(id) {
1976
+ return this.ipWhitelist.delete(id);
1977
+ }
1978
+ };
1979
+ // Annotate the CommonJS export names for ESM import in node:
1980
+ 0 && (module.exports = {
1981
+ BaasClient,
1982
+ HttpClient,
1983
+ QueryBuilder
1984
+ });
1985
+ //# sourceMappingURL=index.cjs.map