@bunbase-ae/js 2.16.1-next.366.a8d9838 → 2.16.1-next.369.ceb4362
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/package.json +1 -1
- package/src/admin.ts +108 -4
- package/src/index.ts +5 -0
package/package.json
CHANGED
package/src/admin.ts
CHANGED
|
@@ -359,6 +359,77 @@ export interface SettingsAuditEntry {
|
|
|
359
359
|
changed_at: number;
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
+
// One row from the general admin audit log (`GET /api/v1/admin/audit`).
|
|
363
|
+
// Mirrors the server-side `AuditLogRow` shape (see apps/server/src/auditDb.ts).
|
|
364
|
+
// `before` / `after` / `diff` are JSON strings as stored — callers parse if needed.
|
|
365
|
+
export interface AuditLogEntry {
|
|
366
|
+
id: number;
|
|
367
|
+
ts: number;
|
|
368
|
+
collection: string;
|
|
369
|
+
record_id: string;
|
|
370
|
+
operation: string;
|
|
371
|
+
user_id: string | null;
|
|
372
|
+
tenant_id: string | null;
|
|
373
|
+
ip: string | null;
|
|
374
|
+
user_agent: string | null;
|
|
375
|
+
request_id: string | null;
|
|
376
|
+
before: string | null;
|
|
377
|
+
after: string | null;
|
|
378
|
+
diff: string | null;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export interface AuditListParams {
|
|
382
|
+
/** Filter by audit collection (real collection name, or one of `AUDIT_COLLECTIONS.*`). */
|
|
383
|
+
collection?: string;
|
|
384
|
+
/** Filter by record id. */
|
|
385
|
+
record_id?: string;
|
|
386
|
+
/** Filter by acting user id. The literal `"admin_secret"` matches admin-secret writes. */
|
|
387
|
+
user_id?: string;
|
|
388
|
+
/** Filter by operation name (e.g. `"create"`, `"update"`, `"delete"`). */
|
|
389
|
+
operation?: string;
|
|
390
|
+
/** Inclusive lower bound (epoch ms). */
|
|
391
|
+
from?: number;
|
|
392
|
+
/** Inclusive upper bound (epoch ms). */
|
|
393
|
+
to?: number;
|
|
394
|
+
/** Resume from `next_cursor` returned by a prior call. */
|
|
395
|
+
cursor?: number;
|
|
396
|
+
/** Page size (server caps at 500, defaults to 50). */
|
|
397
|
+
limit?: number;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export interface AuditListResult {
|
|
401
|
+
items: AuditLogEntry[];
|
|
402
|
+
/** Cursor for the next page. `null` when the page wasn't full (end of stream). */
|
|
403
|
+
next_cursor: number | null;
|
|
404
|
+
limit: number;
|
|
405
|
+
/**
|
|
406
|
+
* Total rows matching the `collection` filter, irrespective of pagination.
|
|
407
|
+
* The server only filters this count by `collection` (and tenant), so when
|
|
408
|
+
* other filters are active the count is an overestimate.
|
|
409
|
+
*/
|
|
410
|
+
total: number;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Synthetic audit-only collection names used by the server-side audit log
|
|
414
|
+
// (see apps/server/src/auditDb.ts). Useful for building a "filter by
|
|
415
|
+
// collection" UI like the Studio Audit tab. Real collection names cannot
|
|
416
|
+
// start with `_`, so these never collide with tenant data.
|
|
417
|
+
export const AUDIT_COLLECTIONS = {
|
|
418
|
+
SETTINGS: "_settings",
|
|
419
|
+
BACKUPS: "_backups",
|
|
420
|
+
USERS: "_users",
|
|
421
|
+
API_KEYS: "_api_keys",
|
|
422
|
+
IMPERSONATE: "_impersonate",
|
|
423
|
+
HOOKS: "_hooks",
|
|
424
|
+
LOGS: "_logs",
|
|
425
|
+
TENANT_MEMBERS: "_tenant_members",
|
|
426
|
+
AUDIT_CONFIG: "_audit_config",
|
|
427
|
+
BUCKETS: "_buckets",
|
|
428
|
+
FILES: "_files",
|
|
429
|
+
} as const;
|
|
430
|
+
|
|
431
|
+
export type AuditCollection = (typeof AUDIT_COLLECTIONS)[keyof typeof AUDIT_COLLECTIONS];
|
|
432
|
+
|
|
362
433
|
export interface BackupFile {
|
|
363
434
|
filename: string;
|
|
364
435
|
size: number;
|
|
@@ -935,6 +1006,34 @@ class AdminStorageClient {
|
|
|
935
1006
|
}
|
|
936
1007
|
}
|
|
937
1008
|
|
|
1009
|
+
// General admin audit log client — wraps `GET /api/v1/admin/audit`.
|
|
1010
|
+
//
|
|
1011
|
+
// The Settings → Audit tab's existing `client.admin.settings.getAudit(...)` is
|
|
1012
|
+
// hard-scoped to `collection = "_settings"`. This client exposes the full audit
|
|
1013
|
+
// trail across every synthetic audit collection (see `AUDIT_COLLECTIONS`) so
|
|
1014
|
+
// operators can verify rows for `_tenant_members`, `_buckets`, `_audit_config`,
|
|
1015
|
+
// `_users`, `_api_keys`, `_impersonate`, `_hooks`, `_logs`, `_backups`, `_files`,
|
|
1016
|
+
// and any user-defined collection that has audit emit enabled.
|
|
1017
|
+
//
|
|
1018
|
+
// Tenant isolation: a JWT-authenticated caller scoped to a tenant only sees
|
|
1019
|
+
// rows for that tenant. An admin-secret call sees all rows.
|
|
1020
|
+
class AdminAuditClient {
|
|
1021
|
+
constructor(private readonly http: HttpClient) {}
|
|
1022
|
+
|
|
1023
|
+
async list(params: AuditListParams = {}): Promise<AuditListResult> {
|
|
1024
|
+
const query: Record<string, string> = {};
|
|
1025
|
+
if (params.collection) query.collection = params.collection;
|
|
1026
|
+
if (params.record_id) query.record_id = params.record_id;
|
|
1027
|
+
if (params.user_id) query.user_id = params.user_id;
|
|
1028
|
+
if (params.operation) query.operation = params.operation;
|
|
1029
|
+
if (params.from !== undefined) query.from = String(params.from);
|
|
1030
|
+
if (params.to !== undefined) query.to = String(params.to);
|
|
1031
|
+
if (params.cursor !== undefined) query.cursor = String(params.cursor);
|
|
1032
|
+
if (params.limit !== undefined) query.limit = String(params.limit);
|
|
1033
|
+
return this.http.request<AuditListResult>("GET", "/api/v1/admin/audit", { query });
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
938
1037
|
class AdminSettingsClient {
|
|
939
1038
|
constructor(private readonly http: HttpClient) {}
|
|
940
1039
|
|
|
@@ -1474,10 +1573,13 @@ class AdminSequencesClient {
|
|
|
1474
1573
|
);
|
|
1475
1574
|
}
|
|
1476
1575
|
|
|
1477
|
-
async delete(name: string, opts: SequenceTenantOptions = {}): Promise<
|
|
1478
|
-
await this.http.request
|
|
1479
|
-
|
|
1480
|
-
|
|
1576
|
+
async delete(name: string, opts: SequenceTenantOptions = {}): Promise<boolean> {
|
|
1577
|
+
const res = await this.http.request<{ deleted: boolean }>(
|
|
1578
|
+
"DELETE",
|
|
1579
|
+
`/api/v1/admin/sequences/${encodeURIComponent(name)}`,
|
|
1580
|
+
{ query: tenantQuery(opts) },
|
|
1581
|
+
);
|
|
1582
|
+
return res.deleted;
|
|
1481
1583
|
}
|
|
1482
1584
|
}
|
|
1483
1585
|
|
|
@@ -1500,6 +1602,7 @@ export class AdminClient {
|
|
|
1500
1602
|
readonly relations: AdminRelationsClient;
|
|
1501
1603
|
readonly storage: AdminStorageClient;
|
|
1502
1604
|
readonly settings: AdminSettingsClient;
|
|
1605
|
+
readonly audit: AdminAuditClient;
|
|
1503
1606
|
readonly backups: AdminBackupsClient;
|
|
1504
1607
|
readonly migrations: AdminMigrationsClient;
|
|
1505
1608
|
readonly queries: AdminNamedQueriesClient;
|
|
@@ -1516,6 +1619,7 @@ export class AdminClient {
|
|
|
1516
1619
|
this.relations = new AdminRelationsClient(http);
|
|
1517
1620
|
this.storage = new AdminStorageClient(http);
|
|
1518
1621
|
this.settings = new AdminSettingsClient(http);
|
|
1622
|
+
this.audit = new AdminAuditClient(http);
|
|
1519
1623
|
this.backups = new AdminBackupsClient(http);
|
|
1520
1624
|
this.migrations = new AdminMigrationsClient(http);
|
|
1521
1625
|
this.queries = new AdminNamedQueriesClient(http);
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,11 @@ export {
|
|
|
9
9
|
type AdminStoredFile,
|
|
10
10
|
type AdminTenantMembership,
|
|
11
11
|
type AdminUser,
|
|
12
|
+
AUDIT_COLLECTIONS,
|
|
13
|
+
type AuditCollection,
|
|
14
|
+
type AuditListParams,
|
|
15
|
+
type AuditListResult,
|
|
16
|
+
type AuditLogEntry,
|
|
12
17
|
type BackupDestinationConfig,
|
|
13
18
|
type BackupFile,
|
|
14
19
|
type BackupRetentionPolicy,
|