primitive-admin 1.0.59 → 1.0.61
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/bin/primitive.js +6 -0
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/admins.js +22 -8
- package/dist/src/commands/admins.js.map +1 -1
- package/dist/src/commands/analytics.js +60 -0
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/blob-buckets.js +37 -2
- package/dist/src/commands/blob-buckets.js.map +1 -1
- package/dist/src/commands/connections.d.ts +2 -0
- package/dist/src/commands/connections.js +95 -0
- package/dist/src/commands/connections.js.map +1 -0
- package/dist/src/commands/guides.d.ts +4 -29
- package/dist/src/commands/guides.js +9 -59
- package/dist/src/commands/guides.js.map +1 -1
- package/dist/src/commands/init.js +12 -4
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/locks.d.ts +8 -0
- package/dist/src/commands/locks.js +160 -0
- package/dist/src/commands/locks.js.map +1 -0
- package/dist/src/commands/sessions.d.ts +2 -0
- package/dist/src/commands/sessions.js +63 -0
- package/dist/src/commands/sessions.js.map +1 -0
- package/dist/src/commands/skill.js +2 -2
- package/dist/src/commands/skill.js.map +1 -1
- package/dist/src/commands/sync.js +120 -13
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/workflows.js +56 -13
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +95 -0
- package/dist/src/lib/api-client.js +137 -15
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/channel.d.ts +30 -0
- package/dist/src/lib/channel.js +68 -0
- package/dist/src/lib/channel.js.map +1 -0
- package/dist/src/lib/generated-allowlist.js +11 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -1
- package/dist/src/lib/skill-installer.d.ts +4 -2
- package/dist/src/lib/skill-installer.js +139 -11
- package/dist/src/lib/skill-installer.js.map +1 -1
- package/dist/src/lib/template.d.ts +16 -1
- package/dist/src/lib/template.js +37 -6
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/workflow-fragments.d.ts +23 -0
- package/dist/src/lib/workflow-fragments.js +229 -8
- package/dist/src/lib/workflow-fragments.js.map +1 -1
- package/dist/src/lib/workflow-payload.d.ts +1 -1
- package/dist/src/lib/workflow-payload.js +17 -0
- package/dist/src/lib/workflow-payload.js.map +1 -1
- package/dist/src/lib/workflow-toml-validator.d.ts +57 -1
- package/dist/src/lib/workflow-toml-validator.js +104 -1
- package/dist/src/lib/workflow-toml-validator.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata for a single bucket blob, as returned by the metadata endpoint
|
|
3
|
+
* `GET blob-buckets/:bucketId/blobs/:blobId/metadata`. Mirrors the published
|
|
4
|
+
* JS client's `BlobInfo` shape.
|
|
5
|
+
*/
|
|
6
|
+
export interface BlobInfo {
|
|
7
|
+
blobId: string;
|
|
8
|
+
bucketId: string;
|
|
9
|
+
filename: string | null;
|
|
10
|
+
contentType: string | null;
|
|
11
|
+
numBytes: number;
|
|
12
|
+
sha256: string | null;
|
|
13
|
+
tags: string[];
|
|
14
|
+
createdBy: string | null;
|
|
15
|
+
uploaded?: string | null;
|
|
16
|
+
etag?: string | null;
|
|
17
|
+
}
|
|
1
18
|
export declare class ApiError extends Error {
|
|
2
19
|
statusCode: number;
|
|
3
20
|
code?: string;
|
|
@@ -262,6 +279,22 @@ interface AnalyticsEventsGroupedResponse {
|
|
|
262
279
|
rows: AnalyticsGroupedRow[];
|
|
263
280
|
_timing: AnalyticsTiming;
|
|
264
281
|
}
|
|
282
|
+
interface AnalyticsErrorGroupRow {
|
|
283
|
+
fingerprint: string;
|
|
284
|
+
normalized_title: string;
|
|
285
|
+
source: string;
|
|
286
|
+
status_class: string;
|
|
287
|
+
total: number;
|
|
288
|
+
daily: Array<{
|
|
289
|
+
day: string;
|
|
290
|
+
count: number;
|
|
291
|
+
}>;
|
|
292
|
+
}
|
|
293
|
+
interface AnalyticsErrorsGroupsResponse {
|
|
294
|
+
window_days: number;
|
|
295
|
+
rows: AnalyticsErrorGroupRow[];
|
|
296
|
+
_timing: AnalyticsTiming;
|
|
297
|
+
}
|
|
265
298
|
interface AnalyticsIntegrationMetric {
|
|
266
299
|
integrationKey: string;
|
|
267
300
|
invocations: number;
|
|
@@ -379,6 +412,9 @@ export declare class ApiClient {
|
|
|
379
412
|
cursor?: string;
|
|
380
413
|
}): Promise<{
|
|
381
414
|
items: any[];
|
|
415
|
+
nextCursor?: string;
|
|
416
|
+
hasMore?: boolean;
|
|
417
|
+
/** @deprecated Alias of `nextCursor` (#1316). */
|
|
382
418
|
cursor?: string;
|
|
383
419
|
}>;
|
|
384
420
|
createInvitation(appId: string, data: {
|
|
@@ -405,9 +441,11 @@ export declare class ApiClient {
|
|
|
405
441
|
type?: string;
|
|
406
442
|
email?: string;
|
|
407
443
|
limit?: number;
|
|
444
|
+
cursor?: string;
|
|
408
445
|
}): Promise<{
|
|
409
446
|
grants: any[];
|
|
410
447
|
nextCursor?: string | null;
|
|
448
|
+
hasMore?: boolean;
|
|
411
449
|
}>;
|
|
412
450
|
revokeDeferredGrant(appId: string, deferredId: string, type: string): Promise<any>;
|
|
413
451
|
listIntegrations(appId: string, params?: {
|
|
@@ -482,7 +520,38 @@ export declare class ApiClient {
|
|
|
482
520
|
listWebhookEvents(appId: string, webhookId: string, params?: {
|
|
483
521
|
limit?: number;
|
|
484
522
|
}): Promise<any>;
|
|
523
|
+
/**
|
|
524
|
+
* List the live connections the server believes exist for exactly one of a
|
|
525
|
+
* document, user, or database. Read-only inspection over admin-api. Rows are
|
|
526
|
+
* per-connection-×-subscription bindings, so `connectionId` is not unique
|
|
527
|
+
* across rows. `params` on a database-subscription row is caller-defined
|
|
528
|
+
* bound CEL input — typed `unknown`.
|
|
529
|
+
*/
|
|
530
|
+
listConnections(appId: string, selector: {
|
|
531
|
+
documentId?: string;
|
|
532
|
+
userId?: string;
|
|
533
|
+
databaseId?: string;
|
|
534
|
+
}, params?: {
|
|
535
|
+
limit?: number;
|
|
536
|
+
cursor?: string;
|
|
537
|
+
}): Promise<{
|
|
538
|
+
items: unknown[];
|
|
539
|
+
nextCursor?: string | null;
|
|
540
|
+
}>;
|
|
541
|
+
listSessions(appId: string, userId: string, params?: {
|
|
542
|
+
limit?: number;
|
|
543
|
+
cursor?: string;
|
|
544
|
+
}): Promise<{
|
|
545
|
+
items: unknown[];
|
|
546
|
+
nextCursor?: string | null;
|
|
547
|
+
}>;
|
|
485
548
|
testWebhook(appId: string, webhookId: string, payload?: any): Promise<any>;
|
|
549
|
+
listLocks(appId: string): Promise<{
|
|
550
|
+
locks: any[];
|
|
551
|
+
}>;
|
|
552
|
+
getLockStatus(appId: string, key: string): Promise<any>;
|
|
553
|
+
acquireLock(appId: string, key: string, ttlMs: number): Promise<any>;
|
|
554
|
+
releaseLock(appId: string, key: string, handleId: string): Promise<any>;
|
|
486
555
|
listCronTriggers(appId: string): Promise<{
|
|
487
556
|
items: any[];
|
|
488
557
|
}>;
|
|
@@ -710,6 +779,8 @@ export declare class ApiClient {
|
|
|
710
779
|
forward?: boolean;
|
|
711
780
|
}): Promise<{
|
|
712
781
|
items: any[];
|
|
782
|
+
nextCursor?: string | null;
|
|
783
|
+
/** @deprecated Alias of `nextCursor` (#1316). */
|
|
713
784
|
cursor?: string | null;
|
|
714
785
|
}>;
|
|
715
786
|
getWorkflowRunStatus(appId: string, workflowId: string, runId: string): Promise<any>;
|
|
@@ -785,6 +856,11 @@ export declare class ApiClient {
|
|
|
785
856
|
windowDays?: number;
|
|
786
857
|
[key: string]: any;
|
|
787
858
|
}): Promise<AnalyticsEventsGroupedResponse>;
|
|
859
|
+
getAnalyticsErrorsGroups(appId: string, params?: {
|
|
860
|
+
windowDays?: number;
|
|
861
|
+
limit?: number;
|
|
862
|
+
[key: string]: any;
|
|
863
|
+
}): Promise<AnalyticsErrorsGroupsResponse>;
|
|
788
864
|
getAnalyticsTopWorkflows(appId: string, params?: {
|
|
789
865
|
windowDays?: number;
|
|
790
866
|
limit?: number;
|
|
@@ -1050,6 +1126,8 @@ export declare class ApiClient {
|
|
|
1050
1126
|
timestamps?: Record<string, any> | null;
|
|
1051
1127
|
schema?: string | null;
|
|
1052
1128
|
metadataManifest?: any;
|
|
1129
|
+
}, options?: {
|
|
1130
|
+
dryRun?: boolean;
|
|
1053
1131
|
}): Promise<any>;
|
|
1054
1132
|
updateDatabaseTypeConfig(appId: string, databaseType: string, data: {
|
|
1055
1133
|
ruleSetId?: string | null;
|
|
@@ -1062,6 +1140,11 @@ export declare class ApiClient {
|
|
|
1062
1140
|
pendingOpDeletes?: string[];
|
|
1063
1141
|
finalOpNames?: string[];
|
|
1064
1142
|
metadataManifest?: any;
|
|
1143
|
+
pendingOpUpdates?: Array<{
|
|
1144
|
+
name: string;
|
|
1145
|
+
access?: string | null;
|
|
1146
|
+
params?: Record<string, any> | null;
|
|
1147
|
+
}>;
|
|
1065
1148
|
}, expectedModifiedAt?: string, options?: {
|
|
1066
1149
|
dryRun?: boolean;
|
|
1067
1150
|
acceptWarnings?: boolean;
|
|
@@ -1089,10 +1172,12 @@ export declare class ApiClient {
|
|
|
1089
1172
|
dryRun?: boolean;
|
|
1090
1173
|
schemaOverride?: string | null;
|
|
1091
1174
|
defaultAccess?: string | null;
|
|
1175
|
+
metadataManifestOverride?: Record<string, any> | null;
|
|
1092
1176
|
}): Promise<any>;
|
|
1093
1177
|
updateDatabaseTypeOperation(appId: string, databaseType: string, name: string, data: Record<string, any>, expectedModifiedAt?: string, options?: {
|
|
1094
1178
|
dryRun?: boolean;
|
|
1095
1179
|
schemaOverride?: string | null;
|
|
1180
|
+
metadataManifestOverride?: Record<string, any> | null;
|
|
1096
1181
|
}): Promise<any>;
|
|
1097
1182
|
deleteDatabaseTypeOperation(appId: string, databaseType: string, name: string): Promise<any>;
|
|
1098
1183
|
listDatabaseTypeSubscriptions(appId: string, databaseType: string): Promise<any[]>;
|
|
@@ -1117,6 +1202,9 @@ export declare class ApiClient {
|
|
|
1117
1202
|
cursor?: string;
|
|
1118
1203
|
}): Promise<{
|
|
1119
1204
|
items: any[];
|
|
1205
|
+
nextCursor?: string;
|
|
1206
|
+
hasMore?: boolean;
|
|
1207
|
+
/** @deprecated Alias of `nextCursor` (#1316). */
|
|
1120
1208
|
cursor?: string;
|
|
1121
1209
|
}>;
|
|
1122
1210
|
createGroup(appId: string, data: {
|
|
@@ -1135,6 +1223,9 @@ export declare class ApiClient {
|
|
|
1135
1223
|
include?: "profiles";
|
|
1136
1224
|
}): Promise<{
|
|
1137
1225
|
items: any[];
|
|
1226
|
+
nextCursor?: string;
|
|
1227
|
+
hasMore?: boolean;
|
|
1228
|
+
/** @deprecated Alias of `nextCursor` (#1316). */
|
|
1138
1229
|
cursor?: string;
|
|
1139
1230
|
}>;
|
|
1140
1231
|
addGroupMember(appId: string, groupType: string, groupId: string, data: {
|
|
@@ -1345,6 +1436,9 @@ export declare class ApiClient {
|
|
|
1345
1436
|
limit?: number;
|
|
1346
1437
|
}): Promise<{
|
|
1347
1438
|
items: any[];
|
|
1439
|
+
nextCursor?: string;
|
|
1440
|
+
hasMore?: boolean;
|
|
1441
|
+
/** @deprecated Alias of `nextCursor` (#1316). */
|
|
1348
1442
|
cursor?: string;
|
|
1349
1443
|
}>;
|
|
1350
1444
|
uploadBucketBlob(appId: string, bucketIdOrKey: string, data: Buffer, meta: {
|
|
@@ -1356,6 +1450,7 @@ export declare class ApiClient {
|
|
|
1356
1450
|
deleteBucketBlob(appId: string, bucketIdOrKey: string, blobId: string): Promise<any>;
|
|
1357
1451
|
deleteBucketBlobs(appId: string, bucketIdOrKey: string, blobIds: string[]): Promise<any>;
|
|
1358
1452
|
getBucketBlobSignedUrl(appId: string, bucketIdOrKey: string, blobId: string, expiresInSeconds?: number): Promise<any>;
|
|
1453
|
+
getBucketBlobMetadata(appId: string, bucketIdOrKey: string, blobId: string): Promise<BlobInfo>;
|
|
1359
1454
|
}
|
|
1360
1455
|
export declare const apiClient: ApiClient;
|
|
1361
1456
|
export {};
|
|
@@ -313,7 +313,14 @@ export class ApiClient {
|
|
|
313
313
|
if (cursor)
|
|
314
314
|
qs.set("cursor", cursor);
|
|
315
315
|
const resp = await this.get(`/admin/api/admins/me/apps?${qs.toString()}`);
|
|
316
|
-
|
|
316
|
+
// The server now emits `items` with `apps` as a deprecation-window
|
|
317
|
+
// alias (#1316). Read `items` first so listings keep working once the
|
|
318
|
+
// alias is removed; fall back to the legacy `apps` key meanwhile.
|
|
319
|
+
return {
|
|
320
|
+
items: resp.items ??
|
|
321
|
+
(Array.isArray(resp.apps) ? resp.apps : []),
|
|
322
|
+
nextCursor: resp.nextCursor ?? resp.cursor,
|
|
323
|
+
};
|
|
317
324
|
});
|
|
318
325
|
return { apps };
|
|
319
326
|
}
|
|
@@ -403,7 +410,16 @@ export class ApiClient {
|
|
|
403
410
|
// INVITATIONS
|
|
404
411
|
// ============================================
|
|
405
412
|
async listInvitations(appId, params) {
|
|
406
|
-
|
|
413
|
+
const result = await this.get(`/app/${appId}/api/invitations`, params);
|
|
414
|
+
// #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
|
|
415
|
+
// so the CLI keeps paginating against pre-#1316 servers.
|
|
416
|
+
const nextCursor = result?.nextCursor ?? result?.cursor;
|
|
417
|
+
return {
|
|
418
|
+
items: result?.items ?? [],
|
|
419
|
+
nextCursor,
|
|
420
|
+
hasMore: result?.hasMore ?? nextCursor != null,
|
|
421
|
+
cursor: nextCursor,
|
|
422
|
+
};
|
|
407
423
|
}
|
|
408
424
|
async createInvitation(appId, data) {
|
|
409
425
|
return this.post(`/app/${appId}/api/invitations`, data);
|
|
@@ -433,8 +449,9 @@ export class ApiClient {
|
|
|
433
449
|
async listDeferredGrants(appId, params) {
|
|
434
450
|
const result = await this.get(`/app/${appId}/api/deferred-grants`, params);
|
|
435
451
|
return {
|
|
436
|
-
grants: result?.grants ?? [],
|
|
452
|
+
grants: result?.grants ?? result?.items ?? [],
|
|
437
453
|
nextCursor: result?.nextCursor ?? null,
|
|
454
|
+
hasMore: result?.hasMore,
|
|
438
455
|
};
|
|
439
456
|
}
|
|
440
457
|
async revokeDeferredGrant(appId, deferredId, type) {
|
|
@@ -576,10 +593,59 @@ export class ApiClient {
|
|
|
576
593
|
const result = await this.get(`/admin/api/apps/${appId}/webhooks/${webhookId}/events`, params);
|
|
577
594
|
return result;
|
|
578
595
|
}
|
|
596
|
+
// ============================================
|
|
597
|
+
// CONNECTIONS INSPECTION (#1968)
|
|
598
|
+
// ============================================
|
|
599
|
+
/**
|
|
600
|
+
* List the live connections the server believes exist for exactly one of a
|
|
601
|
+
* document, user, or database. Read-only inspection over admin-api. Rows are
|
|
602
|
+
* per-connection-×-subscription bindings, so `connectionId` is not unique
|
|
603
|
+
* across rows. `params` on a database-subscription row is caller-defined
|
|
604
|
+
* bound CEL input — typed `unknown`.
|
|
605
|
+
*/
|
|
606
|
+
async listConnections(appId, selector, params) {
|
|
607
|
+
const result = await this.get(`/admin/api/apps/${appId}/connections`, {
|
|
608
|
+
...selector,
|
|
609
|
+
...params,
|
|
610
|
+
});
|
|
611
|
+
return {
|
|
612
|
+
items: result?.items ?? [],
|
|
613
|
+
nextCursor: result?.nextCursor ?? null,
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
async listSessions(appId, userId, params) {
|
|
617
|
+
const result = await this.get(`/admin/api/apps/${appId}/sessions`, {
|
|
618
|
+
userId,
|
|
619
|
+
...params,
|
|
620
|
+
});
|
|
621
|
+
return {
|
|
622
|
+
items: result?.items ?? [],
|
|
623
|
+
nextCursor: result?.nextCursor ?? null,
|
|
624
|
+
};
|
|
625
|
+
}
|
|
579
626
|
async testWebhook(appId, webhookId, payload) {
|
|
580
627
|
return this.post(`/admin/api/apps/${appId}/webhooks/${webhookId}/test`, payload || {});
|
|
581
628
|
}
|
|
582
629
|
// ============================================
|
|
630
|
+
// NAMED LOCKS (#1518)
|
|
631
|
+
// ============================================
|
|
632
|
+
async listLocks(appId) {
|
|
633
|
+
const result = await this.get(`/app/${appId}/api/locks`);
|
|
634
|
+
return { locks: result?.locks ?? [] };
|
|
635
|
+
}
|
|
636
|
+
async getLockStatus(appId, key) {
|
|
637
|
+
return this.post(`/app/${appId}/api/locks/status`, { key });
|
|
638
|
+
}
|
|
639
|
+
async acquireLock(appId, key, ttlMs) {
|
|
640
|
+
return this.post(`/app/${appId}/api/locks/acquire`, { key, ttlMs });
|
|
641
|
+
}
|
|
642
|
+
async releaseLock(appId, key, handleId) {
|
|
643
|
+
return this.post(`/app/${appId}/api/locks/release`, {
|
|
644
|
+
key,
|
|
645
|
+
handle: { handleId },
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
// ============================================
|
|
583
649
|
// CRON TRIGGERS
|
|
584
650
|
// ============================================
|
|
585
651
|
async listCronTriggers(appId) {
|
|
@@ -933,9 +999,12 @@ export class ApiClient {
|
|
|
933
999
|
}
|
|
934
1000
|
async listWorkflowRuns(appId, workflowId, params) {
|
|
935
1001
|
const result = await this.get(`/admin/api/apps/${appId}/workflows/${workflowId}/runs`, params);
|
|
1002
|
+
// #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias.
|
|
1003
|
+
const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
|
|
936
1004
|
return {
|
|
937
1005
|
items: result?.items ?? [],
|
|
938
|
-
|
|
1006
|
+
nextCursor,
|
|
1007
|
+
cursor: nextCursor,
|
|
939
1008
|
};
|
|
940
1009
|
}
|
|
941
1010
|
async getWorkflowRunStatus(appId, workflowId, runId) {
|
|
@@ -1021,6 +1090,9 @@ export class ApiClient {
|
|
|
1021
1090
|
async getAnalyticsEventsGrouped(appId, params) {
|
|
1022
1091
|
return this.get(`/app/${appId}/api/analytics/events/grouped`, params);
|
|
1023
1092
|
}
|
|
1093
|
+
async getAnalyticsErrorsGroups(appId, params) {
|
|
1094
|
+
return this.get(`/app/${appId}/api/analytics/errors/groups`, params);
|
|
1095
|
+
}
|
|
1024
1096
|
async getAnalyticsTopWorkflows(appId, params) {
|
|
1025
1097
|
return this.get(`/app/${appId}/api/analytics/workflows/top`, params);
|
|
1026
1098
|
}
|
|
@@ -1032,9 +1104,12 @@ export class ApiClient {
|
|
|
1032
1104
|
// ============================================
|
|
1033
1105
|
async listAllAdmins(params) {
|
|
1034
1106
|
const result = await this.get("/admin/api/admins", params);
|
|
1107
|
+
// #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias.
|
|
1108
|
+
const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
|
|
1035
1109
|
return {
|
|
1036
|
-
admins: result?.admins ?? [],
|
|
1037
|
-
|
|
1110
|
+
admins: result?.admins ?? result?.items ?? [],
|
|
1111
|
+
nextCursor,
|
|
1112
|
+
cursor: nextCursor,
|
|
1038
1113
|
};
|
|
1039
1114
|
}
|
|
1040
1115
|
async searchAdminByEmail(email) {
|
|
@@ -1338,8 +1413,14 @@ export class ApiClient {
|
|
|
1338
1413
|
async getDatabaseTypeConfig(appId, databaseType) {
|
|
1339
1414
|
return this.get(`/app/${appId}/api/databases/types/${encodeURIComponent(databaseType)}`);
|
|
1340
1415
|
}
|
|
1341
|
-
async createDatabaseTypeConfig(appId, data
|
|
1342
|
-
|
|
1416
|
+
async createDatabaseTypeConfig(appId, data,
|
|
1417
|
+
// Issue #1336 (codex round-1 P2): `dryRun` runs every create-time
|
|
1418
|
+
// validation (inline CEL rule lint, manifest shape, schema TOML parse)
|
|
1419
|
+
// WITHOUT persisting, so a fresh-type `sync push --dry-run` surfaces a
|
|
1420
|
+
// malformed `defaultAccess`/manifest the same way the real POST would.
|
|
1421
|
+
options) {
|
|
1422
|
+
const query = options?.dryRun ? "?dryRun=true" : "";
|
|
1423
|
+
return this.post(`/app/${appId}/api/databases/types${query}`, data);
|
|
1343
1424
|
}
|
|
1344
1425
|
async updateDatabaseTypeConfig(appId, databaseType, data, expectedModifiedAt, options) {
|
|
1345
1426
|
const body = expectedModifiedAt ? { ...data, expectedModifiedAt } : data;
|
|
@@ -1394,16 +1475,24 @@ export class ApiClient {
|
|
|
1394
1475
|
if (options?.dryRun && options.defaultAccess !== undefined) {
|
|
1395
1476
|
body = { ...body, defaultAccess: options.defaultAccess };
|
|
1396
1477
|
}
|
|
1478
|
+
if (options?.dryRun && options.metadataManifestOverride !== undefined) {
|
|
1479
|
+
body = { ...body, metadataManifestOverride: options.metadataManifestOverride };
|
|
1480
|
+
}
|
|
1397
1481
|
return this.post(`/app/${appId}/api/databases/types/${encodeURIComponent(databaseType)}/operations${query}`, body);
|
|
1398
1482
|
}
|
|
1399
1483
|
async updateDatabaseTypeOperation(appId, databaseType, name, data, expectedModifiedAt,
|
|
1400
1484
|
// Issue #813 (1A): dry-run runs the op-edit gate without persisting.
|
|
1401
1485
|
// `schemaOverride` gates against the schema the same push is landing.
|
|
1486
|
+
// Issue #1336: `metadataManifestOverride` gates the op-access lint against
|
|
1487
|
+
// the manifest the same push is landing (see `createDatabaseTypeOperation`).
|
|
1402
1488
|
options) {
|
|
1403
1489
|
let body = expectedModifiedAt ? { ...data, expectedModifiedAt } : { ...data };
|
|
1404
1490
|
if (options?.dryRun && options.schemaOverride !== undefined) {
|
|
1405
1491
|
body = { ...body, schemaOverride: options.schemaOverride };
|
|
1406
1492
|
}
|
|
1493
|
+
if (options?.dryRun && options.metadataManifestOverride !== undefined) {
|
|
1494
|
+
body = { ...body, metadataManifestOverride: options.metadataManifestOverride };
|
|
1495
|
+
}
|
|
1407
1496
|
const query = options?.dryRun ? "?dryRun=true" : "";
|
|
1408
1497
|
return this.patch(`/app/${appId}/api/databases/types/${encodeURIComponent(databaseType)}/operations/${encodeURIComponent(name)}${query}`, body);
|
|
1409
1498
|
}
|
|
@@ -1447,7 +1536,16 @@ export class ApiClient {
|
|
|
1447
1536
|
// GROUPS
|
|
1448
1537
|
// ============================================
|
|
1449
1538
|
async listGroups(appId, params) {
|
|
1450
|
-
|
|
1539
|
+
const result = await this.get(`/app/${appId}/api/groups`, params);
|
|
1540
|
+
// #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
|
|
1541
|
+
// so the CLI keeps paginating against pre-#1316 servers.
|
|
1542
|
+
const nextCursor = result?.nextCursor ?? result?.cursor;
|
|
1543
|
+
return {
|
|
1544
|
+
items: result?.items ?? [],
|
|
1545
|
+
nextCursor,
|
|
1546
|
+
hasMore: result?.hasMore ?? nextCursor != null,
|
|
1547
|
+
cursor: nextCursor,
|
|
1548
|
+
};
|
|
1451
1549
|
}
|
|
1452
1550
|
async createGroup(appId, data) {
|
|
1453
1551
|
return this.post(`/app/${appId}/api/groups`, data);
|
|
@@ -1466,7 +1564,16 @@ export class ApiClient {
|
|
|
1466
1564
|
// ============================================
|
|
1467
1565
|
async listGroupMembers(appId, groupType, groupId, options) {
|
|
1468
1566
|
const qs = options?.include ? `?include=${options.include}` : "";
|
|
1469
|
-
|
|
1567
|
+
const result = await this.get(`/app/${appId}/api/groups/${groupType}/${groupId}/members${qs}`);
|
|
1568
|
+
// #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
|
|
1569
|
+
// so the CLI keeps paginating against pre-#1316 servers.
|
|
1570
|
+
const nextCursor = result?.nextCursor ?? result?.cursor;
|
|
1571
|
+
return {
|
|
1572
|
+
items: result?.items ?? [],
|
|
1573
|
+
nextCursor,
|
|
1574
|
+
hasMore: result?.hasMore ?? nextCursor != null,
|
|
1575
|
+
cursor: nextCursor,
|
|
1576
|
+
};
|
|
1470
1577
|
}
|
|
1471
1578
|
async addGroupMember(appId, groupType, groupId, data) {
|
|
1472
1579
|
return this.post(`/app/${appId}/api/groups/${groupType}/${groupId}/members`, data);
|
|
@@ -1511,7 +1618,7 @@ export class ApiClient {
|
|
|
1511
1618
|
const result = await this.get(`/app/${appId}/api/collections${q ? `?${q}` : ""}`);
|
|
1512
1619
|
return {
|
|
1513
1620
|
items: result?.items ?? [],
|
|
1514
|
-
nextCursor: result?.cursor ?? null,
|
|
1621
|
+
nextCursor: result?.nextCursor ?? result?.cursor ?? null,
|
|
1515
1622
|
};
|
|
1516
1623
|
}
|
|
1517
1624
|
async listAllCollections(appId, params) {
|
|
@@ -1524,7 +1631,7 @@ export class ApiClient {
|
|
|
1524
1631
|
const result = await this.get(`/app/${appId}/api/admin/collections${q ? `?${q}` : ""}`);
|
|
1525
1632
|
return {
|
|
1526
1633
|
items: result?.items ?? [],
|
|
1527
|
-
nextCursor: result?.cursor ?? null,
|
|
1634
|
+
nextCursor: result?.nextCursor ?? result?.cursor ?? null,
|
|
1528
1635
|
};
|
|
1529
1636
|
}
|
|
1530
1637
|
async createCollection(appId, data) {
|
|
@@ -1552,7 +1659,7 @@ export class ApiClient {
|
|
|
1552
1659
|
const result = await this.get(`/app/${appId}/api/collections/${collectionId}/documents${q ? `?${q}` : ""}`);
|
|
1553
1660
|
return {
|
|
1554
1661
|
items: result?.items ?? [],
|
|
1555
|
-
nextCursor: result?.cursor ?? null,
|
|
1662
|
+
nextCursor: result?.nextCursor ?? result?.cursor ?? null,
|
|
1556
1663
|
};
|
|
1557
1664
|
}
|
|
1558
1665
|
async addCollectionDocument(appId, collectionId, data) {
|
|
@@ -1571,7 +1678,7 @@ export class ApiClient {
|
|
|
1571
1678
|
const result = await this.get(`/app/${appId}/api/documents/${documentId}/collections${q ? `?${q}` : ""}`);
|
|
1572
1679
|
return {
|
|
1573
1680
|
items: result?.items ?? [],
|
|
1574
|
-
nextCursor: result?.cursor ?? null,
|
|
1681
|
+
nextCursor: result?.nextCursor ?? result?.cursor ?? null,
|
|
1575
1682
|
};
|
|
1576
1683
|
}
|
|
1577
1684
|
// ============================================
|
|
@@ -1841,7 +1948,16 @@ export class ApiClient {
|
|
|
1841
1948
|
return this.delete(`/app/${appId}/api/blob-buckets/${encodeURIComponent(bucketIdOrKey)}`);
|
|
1842
1949
|
}
|
|
1843
1950
|
async listBucketBlobs(appId, bucketIdOrKey, params) {
|
|
1844
|
-
|
|
1951
|
+
const result = await this.get(`/app/${appId}/api/blob-buckets/${encodeURIComponent(bucketIdOrKey)}/blobs`, params);
|
|
1952
|
+
// #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
|
|
1953
|
+
// so the CLI keeps paginating against pre-#1316 servers.
|
|
1954
|
+
const nextCursor = result?.nextCursor ?? result?.cursor;
|
|
1955
|
+
return {
|
|
1956
|
+
items: result?.items ?? [],
|
|
1957
|
+
nextCursor,
|
|
1958
|
+
hasMore: result?.hasMore ?? nextCursor != null,
|
|
1959
|
+
cursor: nextCursor,
|
|
1960
|
+
};
|
|
1845
1961
|
}
|
|
1846
1962
|
async uploadBucketBlob(appId, bucketIdOrKey, data, meta) {
|
|
1847
1963
|
const credentials = await this.ensureAuthenticated();
|
|
@@ -1896,6 +2012,12 @@ export class ApiClient {
|
|
|
1896
2012
|
expiresInSeconds: expiresInSeconds || 300,
|
|
1897
2013
|
});
|
|
1898
2014
|
}
|
|
2015
|
+
// Blob metadata (#1966): head a single blob without downloading its bytes.
|
|
2016
|
+
// Mirrors listBucketBlobs/downloadBucketBlob addressing; the server heads the
|
|
2017
|
+
// R2 object and returns the serialized BlobInfo shape.
|
|
2018
|
+
async getBucketBlobMetadata(appId, bucketIdOrKey, blobId) {
|
|
2019
|
+
return this.get(`/app/${appId}/api/blob-buckets/${encodeURIComponent(bucketIdOrKey)}/blobs/${blobId}/metadata`);
|
|
2020
|
+
}
|
|
1899
2021
|
}
|
|
1900
2022
|
// Export a singleton instance
|
|
1901
2023
|
export const apiClient = new ApiClient();
|