primitive-admin 1.1.0 → 1.2.0-alpha.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.
Files changed (62) hide show
  1. package/README.md +11 -11
  2. package/assets/skill/skills/primitive-platform/SKILL.md +6 -0
  3. package/dist/src/commands/collections.js +20 -17
  4. package/dist/src/commands/collections.js.map +1 -1
  5. package/dist/src/commands/database-types.js +13 -313
  6. package/dist/src/commands/database-types.js.map +1 -1
  7. package/dist/src/commands/databases.js +0 -19
  8. package/dist/src/commands/databases.js.map +1 -1
  9. package/dist/src/commands/groups.js +16 -0
  10. package/dist/src/commands/groups.js.map +1 -1
  11. package/dist/src/commands/llm.js +9 -6
  12. package/dist/src/commands/llm.js.map +1 -1
  13. package/dist/src/commands/settings.d.ts +18 -0
  14. package/dist/src/commands/settings.js +54 -0
  15. package/dist/src/commands/settings.js.map +1 -0
  16. package/dist/src/commands/sync.d.ts +1 -4
  17. package/dist/src/commands/sync.js +42 -45
  18. package/dist/src/commands/sync.js.map +1 -1
  19. package/dist/src/commands/workflows.js +3 -3
  20. package/dist/src/commands/workflows.js.map +1 -1
  21. package/dist/src/lib/api-client.d.ts +3 -40
  22. package/dist/src/lib/api-client.js +20 -69
  23. package/dist/src/lib/api-client.js.map +1 -1
  24. package/dist/src/lib/app-match-guard.d.ts +44 -0
  25. package/dist/src/lib/app-match-guard.js +72 -0
  26. package/dist/src/lib/app-match-guard.js.map +1 -0
  27. package/dist/src/lib/collection-export.d.ts +37 -9
  28. package/dist/src/lib/collection-export.js +48 -12
  29. package/dist/src/lib/collection-export.js.map +1 -1
  30. package/dist/src/lib/function-triggers.d.ts +66 -0
  31. package/dist/src/lib/function-triggers.js +285 -0
  32. package/dist/src/lib/function-triggers.js.map +1 -0
  33. package/dist/src/lib/generated-allowlist.js +0 -1
  34. package/dist/src/lib/generated-allowlist.js.map +1 -1
  35. package/dist/src/lib/generated-config-surfaces.js +56 -32
  36. package/dist/src/lib/generated-config-surfaces.js.map +1 -1
  37. package/dist/src/lib/generated-sdk-types.d.ts +1 -1
  38. package/dist/src/lib/generated-sdk-types.js +1 -1
  39. package/dist/src/lib/generated-sdk-types.js.map +1 -1
  40. package/dist/src/lib/generated-workflow-model-fields.d.ts +20 -0
  41. package/dist/src/lib/generated-workflow-model-fields.js +53 -0
  42. package/dist/src/lib/generated-workflow-model-fields.js.map +1 -0
  43. package/dist/src/lib/google-client-secret-status.d.ts +35 -0
  44. package/dist/src/lib/google-client-secret-status.js +56 -0
  45. package/dist/src/lib/google-client-secret-status.js.map +1 -0
  46. package/dist/src/lib/log-inspection.d.ts +1 -6
  47. package/dist/src/lib/log-inspection.js +5 -7
  48. package/dist/src/lib/log-inspection.js.map +1 -1
  49. package/dist/src/lib/migration-nag.d.ts +2 -2
  50. package/dist/src/lib/migration-nag.js +4 -3
  51. package/dist/src/lib/migration-nag.js.map +1 -1
  52. package/dist/src/lib/paginate.d.ts +8 -24
  53. package/dist/src/lib/paginate.js +8 -21
  54. package/dist/src/lib/paginate.js.map +1 -1
  55. package/dist/src/lib/sync-dir-selector.d.ts +1 -1
  56. package/dist/src/lib/sync-dir-selector.js +1 -1
  57. package/dist/src/lib/toml-database-config.js +2 -2
  58. package/dist/src/lib/toml-database-config.js.map +1 -1
  59. package/dist/src/lib/workflow-field-descriptor.d.ts +91 -0
  60. package/dist/src/lib/workflow-field-descriptor.js +153 -0
  61. package/dist/src/lib/workflow-field-descriptor.js.map +1 -0
  62. package/package.json +2 -2
@@ -412,13 +412,10 @@ export class ApiClient {
412
412
  qs.set("cursor", params.cursor);
413
413
  const q = qs.toString();
414
414
  const resp = await this.get(`/admin/api/admins/me/apps${q ? `?${q}` : ""}`);
415
- // The server now emits `items` with `apps` as a deprecation-window alias
416
- // (#1316). Read `items` first so listings keep working once the alias is
417
- // removed; fall back to the legacy `apps` key meanwhile.
418
415
  return {
419
- items: resp?.items ?? (Array.isArray(resp?.apps) ? resp.apps : []),
416
+ items: resp?.items ?? [],
420
417
  hasMore: resp?.hasMore,
421
- nextCursor: resp?.nextCursor ?? resp?.cursor ?? null,
418
+ nextCursor: resp?.nextCursor ?? null,
422
419
  };
423
420
  }
424
421
  /**
@@ -455,15 +452,13 @@ export class ApiClient {
455
452
  if (cursor)
456
453
  qs.set("cursor", cursor);
457
454
  const resp = await this.get(`/admin/api/apps?${qs.toString()}`);
458
- // `items` first, with the `apps` alias (#1316) as the fallback,
459
- // exactly as `listApps()` reads its own envelope.
460
- const rows = resp.items ?? (Array.isArray(resp.apps) ? resp.apps : []);
455
+ const rows = resp.items ?? [];
461
456
  return {
462
457
  items: rows.map((row) => ({
463
458
  appId: String(row.appId ?? row.id ?? ""),
464
459
  name: String(row.name ?? ""),
465
460
  })),
466
- nextCursor: resp.nextCursor ?? resp.cursor,
461
+ nextCursor: resp.nextCursor,
467
462
  };
468
463
  });
469
464
  return drainAppsUntilConverged(drainOnce);
@@ -596,14 +591,11 @@ export class ApiClient {
596
591
  // ============================================
597
592
  async listInvitations(appId, params) {
598
593
  const result = await this.get(`/app/${appId}/api/invitations`, params);
599
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
600
- // so the CLI keeps paginating against pre-#1316 servers.
601
- const nextCursor = result?.nextCursor ?? result?.cursor;
594
+ const nextCursor = result?.nextCursor;
602
595
  return {
603
596
  items: result?.items ?? [],
604
597
  nextCursor,
605
598
  hasMore: result?.hasMore ?? nextCursor != null,
606
- cursor: nextCursor,
607
599
  };
608
600
  }
609
601
  async createInvitation(appId, data) {
@@ -633,12 +625,9 @@ export class ApiClient {
633
625
  // ============================================
634
626
  async listDeferredGrants(appId, params) {
635
627
  const result = await this.get(`/app/${appId}/api/deferred-grants`, params);
636
- // `items` is the key every list envelope is built from (#3646, #1982);
637
- // `grants` is the deprecated legacy name, read only as a fallback.
638
- const items = result?.items ?? result?.grants ?? [];
628
+ const items = result?.items ?? [];
639
629
  return {
640
630
  items,
641
- grants: items,
642
631
  nextCursor: result?.nextCursor ?? null,
643
632
  hasMore: result?.hasMore,
644
633
  };
@@ -1020,13 +1009,11 @@ export class ApiClient {
1020
1009
  }
1021
1010
  async listWebhookEvents(appId, webhookId, params) {
1022
1011
  const result = await this.get(`/admin/api/apps/${appId}/webhooks/${webhookId}/events`, params);
1023
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias.
1024
- const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
1012
+ const nextCursor = result?.nextCursor ?? null;
1025
1013
  return {
1026
1014
  items: result?.items ?? [],
1027
1015
  hasMore: result?.hasMore ?? !!nextCursor,
1028
1016
  nextCursor,
1029
- cursor: nextCursor,
1030
1017
  };
1031
1018
  }
1032
1019
  // ============================================
@@ -1576,13 +1563,11 @@ export class ApiClient {
1576
1563
  }
1577
1564
  async listWorkflowRuns(appId, workflowId, params) {
1578
1565
  const result = await this.get(`/admin/api/apps/${appId}/workflows/${workflowId}/runs`, params);
1579
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias.
1580
- const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
1566
+ const nextCursor = result?.nextCursor ?? null;
1581
1567
  return {
1582
1568
  items: result?.items ?? [],
1583
1569
  hasMore: result?.hasMore,
1584
1570
  nextCursor,
1585
- cursor: nextCursor,
1586
1571
  resumeAfter: result?.resumeAfter,
1587
1572
  scanned: typeof result?.scanned === "number" ? result.scanned : undefined,
1588
1573
  };
@@ -1594,12 +1579,11 @@ export class ApiClient {
1594
1579
  */
1595
1580
  async listUserWorkflowRuns(appId, userId, params) {
1596
1581
  const result = await this.get(`/admin/api/apps/${appId}/users/${encodeURIComponent(userId)}/workflow-runs`, params);
1597
- const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
1582
+ const nextCursor = result?.nextCursor ?? null;
1598
1583
  return {
1599
1584
  items: result?.items ?? [],
1600
1585
  hasMore: result?.hasMore,
1601
1586
  nextCursor,
1602
- cursor: nextCursor,
1603
1587
  scanned: typeof result?.scanned === "number" ? result.scanned : undefined,
1604
1588
  };
1605
1589
  }
@@ -1707,17 +1691,12 @@ export class ApiClient {
1707
1691
  }
1708
1692
  async listAllAdmins(params) {
1709
1693
  const result = await this.get("/admin/api/admins", params);
1710
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias.
1711
- const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
1712
- const items = result?.items ?? result?.admins ?? [];
1694
+ const nextCursor = result?.nextCursor ?? null;
1695
+ const items = result?.items ?? [];
1713
1696
  return {
1714
- // `items` is the key every list envelope is built from (#3646, #1982);
1715
- // `admins` is the deprecated legacy name, read only as a fallback.
1716
1697
  items,
1717
- admins: items,
1718
1698
  hasMore: result?.hasMore,
1719
1699
  nextCursor,
1720
- cursor: nextCursor,
1721
1700
  };
1722
1701
  }
1723
1702
  async searchAdminByEmail(email) {
@@ -1963,14 +1942,6 @@ export class ApiClient {
1963
1942
  async removeDatabaseManager(appId, databaseId, userId) {
1964
1943
  return this.delete(`/app/${appId}/api/databases/${databaseId}/permissions/${userId}`);
1965
1944
  }
1966
- /** @deprecated Use {@link addDatabaseManager} instead. */
1967
- async grantDatabasePermission(appId, databaseId, data) {
1968
- return this.addDatabaseManager(appId, databaseId, data.userId);
1969
- }
1970
- /** @deprecated Use {@link removeDatabaseManager} instead. */
1971
- async revokeDatabasePermission(appId, databaseId, userId) {
1972
- return this.delete(`/app/${appId}/api/databases/${databaseId}/permissions/${userId}`);
1973
- }
1974
1945
  // ============================================
1975
1946
  // DATABASE RECORDS & SCHEMA
1976
1947
  // ============================================
@@ -2272,14 +2243,11 @@ export class ApiClient {
2272
2243
  // ============================================
2273
2244
  async listGroups(appId, params) {
2274
2245
  const result = await this.get(`/app/${appId}/api/groups`, params);
2275
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
2276
- // so the CLI keeps paginating against pre-#1316 servers.
2277
- const nextCursor = result?.nextCursor ?? result?.cursor;
2246
+ const nextCursor = result?.nextCursor;
2278
2247
  return {
2279
2248
  items: result?.items ?? [],
2280
2249
  nextCursor,
2281
2250
  hasMore: result?.hasMore ?? nextCursor != null,
2282
- cursor: nextCursor,
2283
2251
  };
2284
2252
  }
2285
2253
  async createGroup(appId, data) {
@@ -2311,14 +2279,11 @@ export class ApiClient {
2311
2279
  ...(options?.limit !== undefined ? { limit: options.limit } : {}),
2312
2280
  ...(options?.cursor ? { cursor: options.cursor } : {}),
2313
2281
  });
2314
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
2315
- // so the CLI keeps paginating against pre-#1316 servers.
2316
- const nextCursor = result?.nextCursor ?? result?.cursor;
2282
+ const nextCursor = result?.nextCursor;
2317
2283
  return {
2318
2284
  items: result?.items ?? [],
2319
2285
  nextCursor,
2320
2286
  hasMore: result?.hasMore ?? nextCursor != null,
2321
- cursor: nextCursor,
2322
2287
  };
2323
2288
  }
2324
2289
  async addGroupMember(appId, groupType, groupId, data) {
@@ -2365,7 +2330,7 @@ export class ApiClient {
2365
2330
  return {
2366
2331
  items: result?.items ?? [],
2367
2332
  hasMore: result?.hasMore,
2368
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2333
+ nextCursor: result?.nextCursor ?? null,
2369
2334
  };
2370
2335
  }
2371
2336
  async listAllCollections(appId, params) {
@@ -2379,7 +2344,7 @@ export class ApiClient {
2379
2344
  return {
2380
2345
  items: result?.items ?? [],
2381
2346
  hasMore: result?.hasMore,
2382
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2347
+ nextCursor: result?.nextCursor ?? null,
2383
2348
  };
2384
2349
  }
2385
2350
  async createCollection(appId, data) {
@@ -2408,7 +2373,7 @@ export class ApiClient {
2408
2373
  return {
2409
2374
  items: result?.items ?? [],
2410
2375
  hasMore: result?.hasMore,
2411
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2376
+ nextCursor: result?.nextCursor ?? null,
2412
2377
  };
2413
2378
  }
2414
2379
  async addCollectionDocument(appId, collectionId, data) {
@@ -2427,7 +2392,7 @@ export class ApiClient {
2427
2392
  const result = await this.get(`/app/${appId}/api/documents/${documentId}/collections${q ? `?${q}` : ""}`);
2428
2393
  return {
2429
2394
  items: result?.items ?? [],
2430
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2395
+ nextCursor: result?.nextCursor ?? null,
2431
2396
  };
2432
2397
  }
2433
2398
  // ============================================
@@ -2675,9 +2640,6 @@ export class ApiClient {
2675
2640
  * through the caller's document permission (reader+) or the app-admin arm.
2676
2641
  * Returns the unified `{ items, hasMore, nextCursor? }` envelope. The cursor
2677
2642
  * is an opaque token — feed `nextCursor` back as `cursor` for the next page.
2678
- * The server also dual-emits a deprecated `cursor` alias (#1316); the
2679
- * normalizer drops it so CLI output is already on `nextCursor` when #1982
2680
- * removes it.
2681
2643
  */
2682
2644
  async queryDocumentRecords(appId, documentId, modelName, queryOptions) {
2683
2645
  const query = {};
@@ -3002,9 +2964,6 @@ export class ApiClient {
3002
2964
  * of them". `paginateAll` carries the repeat-cursor and max-page guards, so
3003
2965
  * a server handing out a non-advancing cursor fails loudly instead of
3004
2966
  * looping forever.
3005
- *
3006
- * Tolerant of a pre-contract server, which answers with a bare
3007
- * `{ documents }` array and no cursor: that reads as a single page.
3008
2967
  */
3009
2968
  async listAdminDocuments(appId, userId) {
3010
2969
  return paginateAll(async (cursor) => {
@@ -3022,9 +2981,6 @@ export class ApiClient {
3022
2981
  * `--limit`/`--cursor` asked for, with the server's own page boundary
3023
2982
  * beside it. `documents export-all`, which really does mean every document,
3024
2983
  * keeps the walking `listAdminDocuments()` above.
3025
- *
3026
- * Tolerant of a pre-contract server, which answers with a bare
3027
- * `{ documents }` array and no cursor: that reads as a single page.
3028
2984
  */
3029
2985
  async listAdminDocumentsPage(appId, userId, options = {}) {
3030
2986
  const params = new URLSearchParams({ userId });
@@ -3034,11 +2990,9 @@ export class ApiClient {
3034
2990
  params.set("cursor", options.cursor);
3035
2991
  const result = await this.get(`/admin/api/apps/${appId}/documents?${params.toString()}`);
3036
2992
  return {
3037
- items: result?.items ?? result?.documents ?? [],
2993
+ items: result?.items ?? [],
3038
2994
  hasMore: result?.hasMore,
3039
- // #1316: prefer `nextCursor`; the deprecated `cursor` alias keeps a
3040
- // shipped CLI paginating against a server that still dual-emits.
3041
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2995
+ nextCursor: result?.nextCursor ?? null,
3042
2996
  };
3043
2997
  }
3044
2998
  /**
@@ -3115,14 +3069,11 @@ export class ApiClient {
3115
3069
  }
3116
3070
  async listBucketBlobs(appId, bucketIdOrKey, params) {
3117
3071
  const result = await this.get(`/app/${appId}/api/blob-buckets/${encodeURIComponent(bucketIdOrKey)}/blobs`, params);
3118
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
3119
- // so the CLI keeps paginating against pre-#1316 servers.
3120
- const nextCursor = result?.nextCursor ?? result?.cursor;
3072
+ const nextCursor = result?.nextCursor;
3121
3073
  return {
3122
3074
  items: result?.items ?? [],
3123
3075
  nextCursor,
3124
3076
  hasMore: result?.hasMore ?? nextCursor != null,
3125
- cursor: nextCursor,
3126
3077
  };
3127
3078
  }
3128
3079
  async uploadBucketBlob(appId, bucketIdOrKey, data, meta) {