@selvajs/supabase-provider 0.17.0-beta.4 → 0.18.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 (78) hide show
  1. package/README.md +26 -39
  2. package/dist/auth/SupabaseAuthProvider.d.ts +37 -82
  3. package/dist/auth/SupabaseAuthProvider.d.ts.map +1 -1
  4. package/dist/auth/SupabaseAuthProvider.js +62 -114
  5. package/dist/auth/SupabaseAuthProvider.js.map +1 -1
  6. package/dist/cli/sync-migrations.js +4 -6
  7. package/dist/cli/sync-migrations.js.map +1 -1
  8. package/dist/data/SupabaseAuditQuery.d.ts +3 -3
  9. package/dist/data/SupabaseAuditQuery.d.ts.map +1 -1
  10. package/dist/data/SupabaseAuditQuery.js +8 -14
  11. package/dist/data/SupabaseAuditQuery.js.map +1 -1
  12. package/dist/data/SupabaseComputeServerStore.d.ts +7 -13
  13. package/dist/data/SupabaseComputeServerStore.d.ts.map +1 -1
  14. package/dist/data/SupabaseComputeServerStore.js +15 -39
  15. package/dist/data/SupabaseComputeServerStore.js.map +1 -1
  16. package/dist/data/SupabaseDataProvider.d.ts +30 -46
  17. package/dist/data/SupabaseDataProvider.d.ts.map +1 -1
  18. package/dist/data/SupabaseDataProvider.js +39 -66
  19. package/dist/data/SupabaseDataProvider.js.map +1 -1
  20. package/dist/data/SupabaseDefinitionStore.d.ts +3 -10
  21. package/dist/data/SupabaseDefinitionStore.d.ts.map +1 -1
  22. package/dist/data/SupabaseDefinitionStore.js +29 -39
  23. package/dist/data/SupabaseDefinitionStore.js.map +1 -1
  24. package/dist/data/SupabaseInviteStore.d.ts +6 -6
  25. package/dist/data/SupabaseInviteStore.d.ts.map +1 -1
  26. package/dist/data/SupabaseInviteStore.js +16 -15
  27. package/dist/data/SupabaseInviteStore.js.map +1 -1
  28. package/dist/data/SupabaseOrgStore.d.ts +0 -4
  29. package/dist/data/SupabaseOrgStore.d.ts.map +1 -1
  30. package/dist/data/SupabaseOrgStore.js +19 -29
  31. package/dist/data/SupabaseOrgStore.js.map +1 -1
  32. package/dist/data/SupabaseProjectStore.d.ts +4 -8
  33. package/dist/data/SupabaseProjectStore.d.ts.map +1 -1
  34. package/dist/data/SupabaseProjectStore.js +15 -26
  35. package/dist/data/SupabaseProjectStore.js.map +1 -1
  36. package/dist/data/SupabaseShareLinkStore.d.ts +4 -9
  37. package/dist/data/SupabaseShareLinkStore.d.ts.map +1 -1
  38. package/dist/data/SupabaseShareLinkStore.js +9 -18
  39. package/dist/data/SupabaseShareLinkStore.js.map +1 -1
  40. package/dist/data/SupabaseSolveMetricSink.d.ts +13 -14
  41. package/dist/data/SupabaseSolveMetricSink.d.ts.map +1 -1
  42. package/dist/data/SupabaseSolveMetricSink.js +13 -14
  43. package/dist/data/SupabaseSolveMetricSink.js.map +1 -1
  44. package/dist/data/client.d.ts +25 -54
  45. package/dist/data/client.d.ts.map +1 -1
  46. package/dist/data/client.js +6 -14
  47. package/dist/data/client.js.map +1 -1
  48. package/dist/data/errors.d.ts.map +1 -1
  49. package/dist/data/errors.js.map +1 -1
  50. package/dist/data/migrationHead.d.ts +4 -11
  51. package/dist/data/migrationHead.d.ts.map +1 -1
  52. package/dist/data/migrationHead.js +4 -11
  53. package/dist/data/migrationHead.js.map +1 -1
  54. package/dist/data/pagination.d.ts +5 -16
  55. package/dist/data/pagination.d.ts.map +1 -1
  56. package/dist/data/pagination.js +5 -16
  57. package/dist/data/pagination.js.map +1 -1
  58. package/dist/data/query.d.ts +2 -14
  59. package/dist/data/query.d.ts.map +1 -1
  60. package/dist/data/query.js +1 -9
  61. package/dist/data/query.js.map +1 -1
  62. package/dist/data/rowStamp.d.ts +8 -24
  63. package/dist/data/rowStamp.d.ts.map +1 -1
  64. package/dist/data/rowStamp.js +8 -24
  65. package/dist/data/rowStamp.js.map +1 -1
  66. package/dist/permissions/SupabasePlatformPermissionStore.d.ts +8 -10
  67. package/dist/permissions/SupabasePlatformPermissionStore.d.ts.map +1 -1
  68. package/dist/permissions/SupabasePlatformPermissionStore.js +9 -15
  69. package/dist/permissions/SupabasePlatformPermissionStore.js.map +1 -1
  70. package/dist/storage/SupabaseStorageProvider.d.ts +14 -35
  71. package/dist/storage/SupabaseStorageProvider.d.ts.map +1 -1
  72. package/dist/storage/SupabaseStorageProvider.js +10 -25
  73. package/dist/storage/SupabaseStorageProvider.js.map +1 -1
  74. package/dist/userProfile/SupabaseUserProfileProvider.d.ts.map +1 -1
  75. package/dist/userProfile/SupabaseUserProfileProvider.js +8 -15
  76. package/dist/userProfile/SupabaseUserProfileProvider.js.map +1 -1
  77. package/package.json +6 -6
  78. package/supabase/migrations/20260817120000_invite_platform_permissions.sql +16 -0
@@ -1,14 +1,7 @@
1
1
  /**
2
- * The migration head this build of the provider expects the database to be at
3
- * — the timestamp prefix of the newest file in `supabase/migrations/`.
4
- *
5
- * Compared against `selva.migration_head()` (a SECURITY DEFINER function over
6
- * `supabase_migrations.schema_migrations`) in
7
- * `SupabaseDataProvider.verifySchemaVersion` to drive the boot-time app↔DB
8
- * schema handshake (audit O3).
9
- *
10
- * MUST be bumped whenever a migration is added — `migration-head.test.ts`
11
- * asserts this constant matches the migrations directory, so CI catches drift.
2
+ * Timestamp prefix of the newest file in `supabase/migrations/`. Bump this
3
+ * whenever a migration is added — `migration-head.test.ts` asserts it
4
+ * matches the migrations directory, so CI catches drift.
12
5
  */
13
- export const EXPECTED_MIGRATION_HEAD = '20260717120000';
6
+ export const EXPECTED_MIGRATION_HEAD = '20260817120000';
14
7
  //# sourceMappingURL=migrationHead.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrationHead.js","sourceRoot":"","sources":["../../src/data/migrationHead.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,gBAAgB,CAAC"}
1
+ {"version":3,"file":"migrationHead.js","sourceRoot":"","sources":["../../src/data/migrationHead.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,gBAAgB,CAAC"}
@@ -1,13 +1,8 @@
1
1
  /**
2
- * Pagination helpers shared across Supabase stores.
3
- *
4
- * The platform contract specifies cursor pagination (`ListOptions.cursor`).
5
- * Because Supabase/Postgres has no built-in opaque cursor format, we encode
6
- * an offset as the cursor — simple, correct for stable sorts, and good
7
- * enough for the volumes Selva deals with (admin/definition lists are
8
- * bounded; nothing is infinite scroll over millions of rows).
9
- *
10
- * Keyset pagination would be faster at scale if it ever matters.
2
+ * `ListOptions.cursor` is meant to be opaque; here it's just an offset
3
+ * encoded as a string. Simple and correct for stable sorts, fine at Selva's
4
+ * scale (bounded admin/definition lists, not infinite scroll over millions
5
+ * of rows). Keyset pagination would be faster if that ever changes.
11
6
  */
12
7
  import type { ListOptions } from '@selvajs/platform';
13
8
  export interface RangeSpec {
@@ -15,16 +10,10 @@ export interface RangeSpec {
15
10
  to: number;
16
11
  limit: number;
17
12
  }
18
- /** Decode an opaque cursor string. Returns 0 for missing/invalid cursors. */
13
+ /** Returns 0 for a missing or invalid cursor. */
19
14
  export declare function decodeCursor(cursor: string | undefined): number;
20
15
  export declare function encodeCursor(offset: number): string;
21
- /** Clamp limit + compute the PostgREST `range(from, to)` bounds. */
22
16
  export declare function toRange(opts: Pick<ListOptions, 'limit' | 'cursor'> | undefined): RangeSpec;
23
- /**
24
- * Build the `nextCursor` from the count returned by PostgREST. Returns
25
- * undefined when there is no next page.
26
- */
27
17
  export declare function nextCursorFromRange(range: RangeSpec, returnedCount: number, totalCount: number | null | undefined): string | undefined;
28
- /** Map `ListOptions.orderBy` to a Postgres column name. */
29
18
  export declare function orderColumn(orderBy: ListOptions['orderBy'] | undefined): string;
30
19
  //# sourceMappingURL=pagination.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/data/pagination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACd;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI/D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,oEAAoE;AACpE,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,CAAC,GAAG,SAAS,GAAG,SAAS,CAI1F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,MAAM,GAAG,SAAS,CAOpB;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,GAAG,SAAS,GAAG,MAAM,CAU/E"}
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/data/pagination.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACd;AAED,iDAAiD;AACjD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI/D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,CAAC,GAAG,SAAS,GAAG,SAAS,CAI1F;AAED,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,MAAM,GAAG,SAAS,CAOpB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,GAAG,SAAS,GAAG,MAAM,CAU/E"}
@@ -1,16 +1,11 @@
1
1
  /**
2
- * Pagination helpers shared across Supabase stores.
3
- *
4
- * The platform contract specifies cursor pagination (`ListOptions.cursor`).
5
- * Because Supabase/Postgres has no built-in opaque cursor format, we encode
6
- * an offset as the cursor — simple, correct for stable sorts, and good
7
- * enough for the volumes Selva deals with (admin/definition lists are
8
- * bounded; nothing is infinite scroll over millions of rows).
9
- *
10
- * Keyset pagination would be faster at scale if it ever matters.
2
+ * `ListOptions.cursor` is meant to be opaque; here it's just an offset
3
+ * encoded as a string. Simple and correct for stable sorts, fine at Selva's
4
+ * scale (bounded admin/definition lists, not infinite scroll over millions
5
+ * of rows). Keyset pagination would be faster if that ever changes.
11
6
  */
12
7
  import { DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT } from '@selvajs/platform';
13
- /** Decode an opaque cursor string. Returns 0 for missing/invalid cursors. */
8
+ /** Returns 0 for a missing or invalid cursor. */
14
9
  export function decodeCursor(cursor) {
15
10
  if (!cursor)
16
11
  return 0;
@@ -20,16 +15,11 @@ export function decodeCursor(cursor) {
20
15
  export function encodeCursor(offset) {
21
16
  return String(offset);
22
17
  }
23
- /** Clamp limit + compute the PostgREST `range(from, to)` bounds. */
24
18
  export function toRange(opts) {
25
19
  const limit = Math.min(Math.max(opts?.limit ?? DEFAULT_PAGE_LIMIT, 1), MAX_PAGE_LIMIT);
26
20
  const from = decodeCursor(opts?.cursor);
27
21
  return { from, to: from + limit - 1, limit };
28
22
  }
29
- /**
30
- * Build the `nextCursor` from the count returned by PostgREST. Returns
31
- * undefined when there is no next page.
32
- */
33
23
  export function nextCursorFromRange(range, returnedCount, totalCount) {
34
24
  const consumed = range.from + returnedCount;
35
25
  if (totalCount != null) {
@@ -38,7 +28,6 @@ export function nextCursorFromRange(range, returnedCount, totalCount) {
38
28
  // Without total, we can only infer "there might be more" if we got a full page.
39
29
  return returnedCount >= range.limit ? encodeCursor(consumed) : undefined;
40
30
  }
41
- /** Map `ListOptions.orderBy` to a Postgres column name. */
42
31
  export function orderColumn(orderBy) {
43
32
  switch (orderBy) {
44
33
  case 'name':
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/data/pagination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AASvE,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,MAA0B;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;AACvB,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,OAAO,CAAC,IAAuD;IAC9E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,kBAAkB,EAAE,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAClC,KAAgB,EAChB,aAAqB,EACrB,UAAqC;IAErC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5C,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACxB,OAAO,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,CAAC;IACD,gFAAgF;IAChF,OAAO,aAAa,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1E,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,WAAW,CAAC,OAA2C;IACtE,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,MAAM;YACV,OAAO,MAAM,CAAC;QACf,KAAK,WAAW;YACf,OAAO,YAAY,CAAC;QACrB,KAAK,WAAW,CAAC;QACjB;YACC,OAAO,YAAY,CAAC;IACtB,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/data/pagination.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AASvE,iDAAiD;AACjD,MAAM,UAAU,YAAY,CAAC,MAA0B;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAuD;IAC9E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,kBAAkB,EAAE,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAClC,KAAgB,EAChB,aAAqB,EACrB,UAAqC;IAErC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5C,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACxB,OAAO,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,CAAC;IACD,gFAAgF;IAChF,OAAO,aAAa,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAA2C;IACtE,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,MAAM;YACV,OAAO,MAAM,CAAC;QACf,KAAK,WAAW;YACf,OAAO,YAAY,CAAC;QACrB,KAAK,WAAW,CAAC;QACjB;YACC,OAAO,YAAY,CAAC;IACtB,CAAC;AACF,CAAC"}
@@ -1,20 +1,8 @@
1
- /**
2
- * Small query-builder helpers shared across Supabase stores.
3
- */
4
- /**
5
- * The slice of a PostgREST filter builder these helpers touch: an `.is()`
6
- * method that returns the same builder for chaining. Generic over the builder
7
- * type so the caller's concrete builder (and its row generic) flows through.
8
- */
1
+ /** Minimal PostgREST filter-builder slice these helpers need, generic so the caller's row type flows through. */
9
2
  interface DeletableQuery {
10
3
  is(column: string, value: null): this;
11
4
  }
12
- /**
13
- * Apply the soft-delete filter `deleted_at IS NULL`. The `.is('deleted_at', null)`
14
- * idiom is repeated across every store that soft-deletes; this names it.
15
- *
16
- * let q = notDeleted(client.from('projects').select(COLS));
17
- */
5
+ /** `deleted_at IS NULL`, named once instead of repeated across every soft-deleting store. */
18
6
  export declare function notDeleted<Q extends DeletableQuery>(query: Q): Q;
19
7
  export {};
20
8
  //# sourceMappingURL=query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/data/query.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,UAAU,cAAc;IACvB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;CACtC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEhE"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/data/query.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH,UAAU,cAAc;IACvB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;CACtC;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEhE"}
@@ -1,12 +1,4 @@
1
- /**
2
- * Small query-builder helpers shared across Supabase stores.
3
- */
4
- /**
5
- * Apply the soft-delete filter `deleted_at IS NULL`. The `.is('deleted_at', null)`
6
- * idiom is repeated across every store that soft-deletes; this names it.
7
- *
8
- * let q = notDeleted(client.from('projects').select(COLS));
9
- */
1
+ /** `deleted_at IS NULL`, named once instead of repeated across every soft-deleting store. */
10
2
  export function notDeleted(query) {
11
3
  return query.is('deleted_at', null);
12
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/data/query.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAA2B,KAAQ;IAC5D,OAAO,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/data/query.ts"],"names":[],"mappings":"AAKA,6FAA6F;AAC7F,MAAM,UAAU,UAAU,CAA2B,KAAQ;IAC5D,OAAO,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC"}
@@ -1,35 +1,19 @@
1
1
  import type { RequestContext } from '@selvajs/platform';
2
2
  /**
3
- * Row-level (snake_case) audit-stamp helpers for Supabase stores.
3
+ * Translates platform's camelCase audit fields (`updatedAt`/`updatedBy`) to
4
+ * the snake_case columns every Supabase row uses.
4
5
  *
5
- * Platform's `auditUpdate` / `auditSoftDelete` emit camelCase *domain* fields
6
- * (`updatedAt` / `updatedBy`), but Postgres rows are snake_case, so every store
7
- * hand-translated them. These helpers own that translation once. Row-column
8
- * naming is a provider concern, so they live here rather than in platform.
6
+ * `updated_by` is written only when `ctx.userId` is set. On system contexts
7
+ * `auditUpdate`/`auditSoftDelete` fall back to `''`, and the column FKs
8
+ * `auth.users(id)` — writing `''` violates the FK — so it's omitted instead,
9
+ * leaving the existing value untouched.
9
10
  *
10
- * Two deliberate rules, matched to how the engine's stores already write rows:
11
- * - `updated_by` is written ONLY when `ctx.userId` is set. On system contexts
12
- * it's the empty string, and the column FKs `auth.users(id)` with
13
- * `ON DELETE SET NULL` — writing `''` would violate the FK, so it's omitted
14
- * and the existing value is left untouched.
15
- * - Plain updates DON'T stamp `updated_at`: a per-table `updated_at` trigger
16
- * already sets it. Only the soft-delete stamp writes `updated_at` explicitly,
17
- * so it matches `deleted_at` (a single timestamp for the deletion event).
18
- */
19
- /**
20
- * Stamp for a plain UPDATE: `{ updated_by }` when the context carries a user,
21
- * `{}` otherwise (the DB trigger handles `updated_at`). Spread into the row:
22
- * `const row = { ...patch, ...stampUpdate(ctx) }`.
11
+ * Plain updates don't stamp `updated_at`: a per-table trigger already sets
12
+ * it. Only soft-delete sets `updated_at` explicitly, to match `deleted_at`.
23
13
  */
24
14
  export declare function stampUpdate(ctx: RequestContext): {
25
15
  updated_by?: string;
26
16
  };
27
- /**
28
- * Stamp for a soft-delete: `{ deleted_at, updated_at, updated_by? }`. `updated_at`
29
- * is set explicitly to equal `deleted_at`; `updated_by` follows the same
30
- * omit-when-empty rule as {@link stampUpdate}. `fallbackActor` defaults to
31
- * `ctx.userId` (matching the engine stores' `auditSoftDelete(ctx, ctx.userId)`).
32
- */
33
17
  export declare function stampSoftDelete(ctx: RequestContext, fallbackActor?: string | null | undefined): {
34
18
  deleted_at: string;
35
19
  updated_at: string;
@@ -1 +1 @@
1
- {"version":3,"file":"rowStamp.d.ts","sourceRoot":"","sources":["../../src/data/rowStamp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAExE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC9B,GAAG,EAAE,cAAc,EACnB,aAAa,GAAE,MAAM,GAAG,IAAI,GAAG,SAAsB,GACnD;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAQjE"}
1
+ {"version":3,"file":"rowStamp.d.ts","sourceRoot":"","sources":["../../src/data/rowStamp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD;;;;;;;;;;;GAWG;AAEH,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAExE;AAED,wBAAgB,eAAe,CAC9B,GAAG,EAAE,cAAc,EACnB,aAAa,GAAE,MAAM,GAAG,IAAI,GAAG,SAAsB,GACnD;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAQjE"}
@@ -1,35 +1,19 @@
1
1
  import { auditSoftDelete } from '@selvajs/platform';
2
2
  /**
3
- * Row-level (snake_case) audit-stamp helpers for Supabase stores.
3
+ * Translates platform's camelCase audit fields (`updatedAt`/`updatedBy`) to
4
+ * the snake_case columns every Supabase row uses.
4
5
  *
5
- * Platform's `auditUpdate` / `auditSoftDelete` emit camelCase *domain* fields
6
- * (`updatedAt` / `updatedBy`), but Postgres rows are snake_case, so every store
7
- * hand-translated them. These helpers own that translation once. Row-column
8
- * naming is a provider concern, so they live here rather than in platform.
6
+ * `updated_by` is written only when `ctx.userId` is set. On system contexts
7
+ * `auditUpdate`/`auditSoftDelete` fall back to `''`, and the column FKs
8
+ * `auth.users(id)` — writing `''` violates the FK — so it's omitted instead,
9
+ * leaving the existing value untouched.
9
10
  *
10
- * Two deliberate rules, matched to how the engine's stores already write rows:
11
- * - `updated_by` is written ONLY when `ctx.userId` is set. On system contexts
12
- * it's the empty string, and the column FKs `auth.users(id)` with
13
- * `ON DELETE SET NULL` — writing `''` would violate the FK, so it's omitted
14
- * and the existing value is left untouched.
15
- * - Plain updates DON'T stamp `updated_at`: a per-table `updated_at` trigger
16
- * already sets it. Only the soft-delete stamp writes `updated_at` explicitly,
17
- * so it matches `deleted_at` (a single timestamp for the deletion event).
18
- */
19
- /**
20
- * Stamp for a plain UPDATE: `{ updated_by }` when the context carries a user,
21
- * `{}` otherwise (the DB trigger handles `updated_at`). Spread into the row:
22
- * `const row = { ...patch, ...stampUpdate(ctx) }`.
11
+ * Plain updates don't stamp `updated_at`: a per-table trigger already sets
12
+ * it. Only soft-delete sets `updated_at` explicitly, to match `deleted_at`.
23
13
  */
24
14
  export function stampUpdate(ctx) {
25
15
  return ctx.userId ? { updated_by: ctx.userId } : {};
26
16
  }
27
- /**
28
- * Stamp for a soft-delete: `{ deleted_at, updated_at, updated_by? }`. `updated_at`
29
- * is set explicitly to equal `deleted_at`; `updated_by` follows the same
30
- * omit-when-empty rule as {@link stampUpdate}. `fallbackActor` defaults to
31
- * `ctx.userId` (matching the engine stores' `auditSoftDelete(ctx, ctx.userId)`).
32
- */
33
17
  export function stampSoftDelete(ctx, fallbackActor = ctx.userId) {
34
18
  const stamp = auditSoftDelete(ctx, fallbackActor);
35
19
  const row = {
@@ -1 +1 @@
1
- {"version":3,"file":"rowStamp.js","sourceRoot":"","sources":["../../src/data/rowStamp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAmB;IAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC9B,GAAmB,EACnB,gBAA2C,GAAG,CAAC,MAAM;IAErD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAClD,MAAM,GAAG,GAAoE;QAC5E,UAAU,EAAE,KAAK,CAAC,SAAS;QAC3B,UAAU,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;IACF,IAAI,KAAK,CAAC,SAAS;QAAE,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC;IACtD,OAAO,GAAG,CAAC;AACZ,CAAC"}
1
+ {"version":3,"file":"rowStamp.js","sourceRoot":"","sources":["../../src/data/rowStamp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;GAWG;AAEH,MAAM,UAAU,WAAW,CAAC,GAAmB;IAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,eAAe,CAC9B,GAAmB,EACnB,gBAA2C,GAAG,CAAC,MAAM;IAErD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAClD,MAAM,GAAG,GAAoE;QAC5E,UAAU,EAAE,KAAK,CAAC,SAAS;QAC3B,UAAU,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;IACF,IAAI,KAAK,CAAC,SAAS;QAAE,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC;IACtD,OAAO,GAAG,CAAC;AACZ,CAAC"}
@@ -1,17 +1,15 @@
1
1
  import type { IPlatformPermissionStore, PlatformPermission, RequestContext, UserManagementResult } from '@selvajs/platform';
2
2
  import type { ClientBundle } from '../data/client.js';
3
3
  /**
4
- * Supabase-backed platform-permission store. Reads and writes
5
- * `public.user_profiles.platform_permissions` (auto-seeded by the
6
- * `handle_new_auth_user` trigger). Service-role throughout — the store's own
7
- * `assertAdmin` / `assertCanRead` enforce the auth boundary at the app level
8
- * since RLS on `user_profiles` is coarse-grained for cross-user reads.
4
+ * Reads and writes `public.user_profiles.platform_permissions` (auto-seeded
5
+ * by the `handle_new_auth_user` trigger). Service-role throughout — RLS on
6
+ * `user_profiles` is too coarse for cross-user reads, so `assertAdmin` /
7
+ * `assertCanRead` enforce the auth boundary here instead.
9
8
  *
10
- * Disabled-user state is sourced from `auth.users.user_metadata.disabled` and
11
- * mirrored into `user_profiles.disabled` by the `sync_auth_user_disabled`
12
- * trigger, so the invariant counters exclude disabled admins in a single
13
- * indexed query (matches `Permissions.md §10` "enabled instance_admin"
14
- * semantics) instead of cross-referencing the auth admin API per candidate.
9
+ * `user_profiles.disabled` mirrors `auth.users.user_metadata.disabled` via
10
+ * the `sync_auth_user_disabled` trigger, so admin-count queries can exclude
11
+ * disabled admins with a single indexed query instead of cross-referencing
12
+ * the auth admin API per candidate.
15
13
  */
16
14
  export declare class SupabasePlatformPermissionStore implements IPlatformPermissionStore {
17
15
  private readonly clients;
@@ -1 +1 @@
1
- {"version":3,"file":"SupabasePlatformPermissionStore.d.ts","sourceRoot":"","sources":["../../src/permissions/SupabasePlatformPermissionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,qBAAa,+BAAgC,YAAW,wBAAwB;IACnE,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY;IAElD,OAAO,CAAC,MAAM;IAIR,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAW1E,WAAW,CAChB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAevC,GAAG,CACR,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,oBAAoB,CAAC;IA8B1B,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAUxD,4BAA4B,CAAC,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAIlF,uBAAuB;CAUrC"}
1
+ {"version":3,"file":"SupabasePlatformPermissionStore.d.ts","sourceRoot":"","sources":["../../src/permissions/SupabasePlatformPermissionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,+BAAgC,YAAW,wBAAwB;IACnE,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY;IAElD,OAAO,CAAC,MAAM;IAIR,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAW1E,WAAW,CAChB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAevC,GAAG,CACR,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,oBAAoB,CAAC;IA0B1B,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAUxD,4BAA4B,CAAC,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAIlF,uBAAuB;CAUrC"}
@@ -1,16 +1,14 @@
1
1
  import { ProviderError, hasPermission, ALL_PLATFORM_PERMISSIONS } from '@selvajs/platform';
2
2
  /**
3
- * Supabase-backed platform-permission store. Reads and writes
4
- * `public.user_profiles.platform_permissions` (auto-seeded by the
5
- * `handle_new_auth_user` trigger). Service-role throughout — the store's own
6
- * `assertAdmin` / `assertCanRead` enforce the auth boundary at the app level
7
- * since RLS on `user_profiles` is coarse-grained for cross-user reads.
3
+ * Reads and writes `public.user_profiles.platform_permissions` (auto-seeded
4
+ * by the `handle_new_auth_user` trigger). Service-role throughout — RLS on
5
+ * `user_profiles` is too coarse for cross-user reads, so `assertAdmin` /
6
+ * `assertCanRead` enforce the auth boundary here instead.
8
7
  *
9
- * Disabled-user state is sourced from `auth.users.user_metadata.disabled` and
10
- * mirrored into `user_profiles.disabled` by the `sync_auth_user_disabled`
11
- * trigger, so the invariant counters exclude disabled admins in a single
12
- * indexed query (matches `Permissions.md §10` "enabled instance_admin"
13
- * semantics) instead of cross-referencing the auth admin API per candidate.
8
+ * `user_profiles.disabled` mirrors `auth.users.user_metadata.disabled` via
9
+ * the `sync_auth_user_disabled` trigger, so admin-count queries can exclude
10
+ * disabled admins with a single indexed query instead of cross-referencing
11
+ * the auth admin API per candidate.
14
12
  */
15
13
  export class SupabasePlatformPermissionStore {
16
14
  clients;
@@ -49,9 +47,6 @@ export class SupabasePlatformPermissionStore {
49
47
  }
50
48
  async set(ctx, userId, permissions) {
51
49
  assertAdmin(ctx);
52
- // 1. Confirm the target exists in the auth backend (the FK + trigger
53
- // means the user_profiles row should exist post-signup; if not,
54
- // treat as not_found rather than auto-creating).
55
50
  const { data: existing, error: fetchError } = await this.client()
56
51
  .from('user_profiles')
57
52
  .select('platform_permissions')
@@ -61,7 +56,7 @@ export class SupabasePlatformPermissionStore {
61
56
  throw mapError(fetchError);
62
57
  if (!existing)
63
58
  return 'not_found';
64
- // 2. §2 invariant: refuse if dropping the last instance_admin.
59
+ // Refuse to drop the last enabled instance_admin.
65
60
  const wasAdmin = (existing.platform_permissions ?? []).includes('instance_admin');
66
61
  const willBeAdmin = permissions.includes('instance_admin');
67
62
  if (wasAdmin && !willBeAdmin) {
@@ -69,7 +64,6 @@ export class SupabasePlatformPermissionStore {
69
64
  if (others === 0)
70
65
  return 'last_admin';
71
66
  }
72
- // 3. Apply.
73
67
  const { error } = await this.client()
74
68
  .from('user_profiles')
75
69
  .update({ platform_permissions: [...permissions] })
@@ -1 +1 @@
1
- {"version":3,"file":"SupabasePlatformPermissionStore.js","sourceRoot":"","sources":["../../src/permissions/SupabasePlatformPermissionStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SupabasePlatformPermissionStore.js","sourceRoot":"","sources":["../../src/permissions/SupabasePlatformPermissionStore.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAG3F;;;;;;;;;;GAUG;AACH,MAAM,OAAO,+BAA+B;IACd;IAA7B,YAA6B,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;IAAG,CAAC;IAE9C,MAAM;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAmB,EAAE,MAAc;QAC/C,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;aACzC,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC,sBAAsB,CAAC;aAC9B,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;aACrB,WAAW,EAAE,CAAC;QAChB,IAAI,KAAK;YAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,WAAW,CAAC,IAAI,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,WAAW,CAChB,GAAmB,EACnB,OAA0B;QAE1B,WAAW,CAAC,GAAG,CAAC,CAAC;QACjB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAgC,CAAC;QACpD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC;QACrC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;aACzC,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC,+BAA+B,CAAC;aACvC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;QAC9B,IAAI,KAAK;YAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;YAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAiB,EAAE,WAAW,CAAC,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAa,CAAC,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,GAAG,CACR,GAAmB,EACnB,MAAc,EACd,WAA0C;QAE1C,WAAW,CAAC,GAAG,CAAC,CAAC;QACjB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;aAC/D,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC,sBAAsB,CAAC;aAC9B,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;aACrB,WAAW,EAAE,CAAC;QAChB,IAAI,UAAU;YAAE,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ;YAAE,OAAO,WAAW,CAAC;QAElC,kDAAkD;QAClD,MAAM,QAAQ,GAAG,CAAC,QAAQ,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QAClF,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QAC3D,IAAI,QAAQ,IAAI,CAAC,WAAW,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;YAC1D,IAAI,MAAM,KAAK,CAAC;gBAAE,OAAO,YAAY,CAAC;QACvC,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;aACnC,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC;aAClD,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACxB,IAAI,KAAK;YAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAoB;QAC1C,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;aAC1C,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;aACjD,QAAQ,CAAC,sBAAsB,EAAE,CAAC,gBAAgB,CAAC,CAAC;aACpD,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACxB,IAAI,KAAK;YAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,4BAA4B,CAAC,IAAoB,EAAE,aAAqB;QAC7E,OAAO,IAAI,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC;IACpD,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,aAAqB;QAC1D,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;aAC1C,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;aACjD,QAAQ,CAAC,sBAAsB,EAAE,CAAC,gBAAgB,CAAC,CAAC;aACpD,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC;aACrB,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAChC,IAAI,KAAK;YAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,KAAK,IAAI,CAAC,CAAC;IACnB,CAAC;CACD;AAED,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAEpE,SAAS,WAAW,CAAC,GAAsB;IAC1C,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAA2B,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,aAAa,CAAC,GAAmB,EAAE,MAAc;IACzD,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO;IACvB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO;IAClC,IAAI,aAAa,CAAC,GAAG,EAAE,gBAAgB,CAAC;QAAE,OAAO;IACjD,MAAM,IAAI,aAAa,CAAC,mDAAmD,EAAE,GAAG,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,WAAW,CAAC,GAAmB;IACvC,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO;IACvB,IAAI,aAAa,CAAC,GAAG,EAAE,gBAAgB,CAAC;QAAE,OAAO;IACjD,MAAM,IAAI,aAAa,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;AACpE,CAAC;AAOD,SAAS,QAAQ,CAAC,CAAU;IAC3B,MAAM,EAAE,GAAG,CAAmB,CAAC;IAC/B,IAAI,EAAE,EAAE,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,aAAa,CAAC,EAAE,CAAC,OAAO,IAAI,kBAAkB,EAAE,GAAG,CAAC,CAAC;IAC1F,IAAI,EAAE,EAAE,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,aAAa,CAAC,EAAE,CAAC,OAAO,IAAI,uBAAuB,EAAE,GAAG,CAAC,CAAC;IAC/F,IAAI,CAAC,YAAY,KAAK;QAAE,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,CAAwC,CAAC;QACrD,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC"}
@@ -1,39 +1,25 @@
1
1
  import type { IStorageProvider } from '@selvajs/platform/storage';
2
2
  /**
3
- * Storage backend for Selva on Supabase Storage.
4
- *
5
- * Uses two buckets:
6
- * - {publicBucket} (public): org branding, archive thumbnails, anything
7
- * CDN-safe. `getPublicUrl` returns the direct CDN URL.
8
- * - {privateBucket} (private): .gh / .ghx source files plus every asset
9
- * class that isn't `public` (definition covers, org private files).
10
- * `getPublicUrl` returns the authenticated proxy URL
11
- * (`${privateUrlPrefix}/{path}`) — the consuming app must have a route at
12
- * that prefix that authenticates the request and streams the bytes via
13
- * `get()`.
14
- *
15
- * Routing is derived from the extension and `classifyAssetPath`, so callers
16
- * building paths via `definitionPaths` never have to think about buckets.
3
+ * Storage backend for Selva on Supabase Storage. Routes each path to one of
4
+ * two buckets: `publicBucket` (CDN-readable, `getPublicUrl` returns the
5
+ * direct CDN URL) or `privateBucket` (`getPublicUrl` returns
6
+ * `${privateUrlPrefix}/{path}` — the consuming app must route that prefix
7
+ * through an auth check and `get()`).
17
8
  */
18
9
  export interface SupabaseStorageProviderConfig {
19
10
  /** Supabase project URL (e.g. http://127.0.0.1:54321 for local stack). */
20
11
  supabaseUrl: string;
21
12
  /**
22
- * Service-role key. Required because the provider runs server-side and
23
- * must bypass RLS for server-internal actions (admin uploads, janitor
24
- * cleanup). The provider is never used directly from the browser.
13
+ * Service-role key. The provider runs server-side and must bypass RLS
14
+ * for server-internal actions (admin uploads, janitor cleanup) — never
15
+ * used from the browser.
25
16
  */
26
17
  serviceRoleKey: string;
27
18
  /** Bucket for CDN-readable objects. Default: "selva-public". */
28
19
  publicBucket?: string;
29
20
  /** Bucket for authenticated-only objects. Default: "selva-private". */
30
21
  privateBucket?: string;
31
- /**
32
- * URL prefix the app exposes for authenticated file downloads. Used by
33
- * `getPublicUrl` for private-bucket paths. Default: "/api/files".
34
- * The matching SvelteKit route is expected to call `get()` and stream
35
- * bytes back after an auth check.
36
- */
22
+ /** URL prefix for authenticated file downloads, used by `getPublicUrl`. Default: "/api/files". */
37
23
  privateUrlPrefix?: string;
38
24
  }
39
25
  export declare class SupabaseStorageProvider implements IStorageProvider {
@@ -45,14 +31,10 @@ export declare class SupabaseStorageProvider implements IStorageProvider {
45
31
  static fromEnv(env: Record<string, string | undefined>): SupabaseStorageProvider;
46
32
  constructor(config: SupabaseStorageProviderConfig);
47
33
  /**
48
- * Route a storage path to a bucket. A path is private when either:
49
- * - it's a `.gh`/`.ghx` source file — confidentiality by extension, so a
50
- * path-scheme rename can't silently move sources into the public bucket;
51
- * - it classifies as a non-`public` asset class (`classifyAssetPath`) —
52
- * e.g. `orgs/{id}/private/*` pricing sheets are members-only and must
53
- * never land in the CDN-readable bucket. Definition covers classify as
54
- * `project`-visible and are private for the same reason.
55
- * Everything else (branding, archives, thumbnails) is public.
34
+ * `.gh`/`.ghx` source files are always private, regardless of what
35
+ * `classifyAssetPath` says — confidentiality by extension means a
36
+ * path-scheme rename can't silently move sources into the public bucket.
37
+ * Everything else routes by asset class.
56
38
  */
57
39
  private bucketFor;
58
40
  get(storagePath: string): Promise<Uint8Array | null>;
@@ -60,10 +42,7 @@ export declare class SupabaseStorageProvider implements IStorageProvider {
60
42
  delete(storagePath: string): Promise<void>;
61
43
  deletePrefix(prefix: string): Promise<void>;
62
44
  private deletePrefixInBucket;
63
- /**
64
- * Recursively list every key under a prefix. `storage-js`'s `list` API
65
- * only returns the immediate children of a "folder", so we DFS.
66
- */
45
+ /** storage-js's `list` only returns immediate children of a "folder", so DFS to get everything under `prefix`. */
67
46
  private listAllKeys;
68
47
  getPublicUrl(storagePath: string): string;
69
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SupabaseStorageProvider.d.ts","sourceRoot":"","sources":["../../src/storage/SupabaseStorageProvider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,6BAA6B;IAC7C,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,uBAAwB,YAAW,gBAAgB;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,uBAAuB;gBAcpE,MAAM,EAAE,6BAA6B;IAWjD;;;;;;;;;OASG;IACH,OAAO,CAAC,SAAS;IAOX,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAcpD,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB/E,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YASnC,oBAAoB;IAYlC;;;OAGG;YACW,WAAW;IAuBzB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;CAOzC"}
1
+ {"version":3,"file":"SupabaseStorageProvider.d.ts","sourceRoot":"","sources":["../../src/storage/SupabaseStorageProvider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC7C,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kGAAkG;IAClG,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,uBAAwB,YAAW,gBAAgB;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,uBAAuB;gBAcpE,MAAM,EAAE,6BAA6B;IAUjD;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAOX,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAapD,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc/E,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAQnC,oBAAoB;IAYlC,kHAAkH;YACpG,WAAW;IAuBzB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;CAMzC"}
@@ -27,19 +27,14 @@ export class SupabaseStorageProvider {
27
27
  });
28
28
  this.publicBucket = config.publicBucket ?? 'selva-public';
29
29
  this.privateBucket = config.privateBucket ?? 'selva-private';
30
- // Direct CDN URL format: {supabaseUrl}/storage/v1/object/public/{bucket}/{path}
31
30
  this.publicBaseUrl = `${config.supabaseUrl.replace(/\/$/, '')}/storage/v1/object/public/${this.publicBucket}`;
32
31
  this.privateUrlPrefix = (config.privateUrlPrefix ?? '/api/files').replace(/\/$/, '');
33
32
  }
34
33
  /**
35
- * Route a storage path to a bucket. A path is private when either:
36
- * - it's a `.gh`/`.ghx` source file — confidentiality by extension, so a
37
- * path-scheme rename can't silently move sources into the public bucket;
38
- * - it classifies as a non-`public` asset class (`classifyAssetPath`) —
39
- * e.g. `orgs/{id}/private/*` pricing sheets are members-only and must
40
- * never land in the CDN-readable bucket. Definition covers classify as
41
- * `project`-visible and are private for the same reason.
42
- * Everything else (branding, archives, thumbnails) is public.
34
+ * `.gh`/`.ghx` source files are always private, regardless of what
35
+ * `classifyAssetPath` says — confidentiality by extension means a
36
+ * path-scheme rename can't silently move sources into the public bucket.
37
+ * Everything else routes by asset class.
43
38
  */
44
39
  bucketFor(storagePath) {
45
40
  if (/\.(gh|ghx)$/i.test(storagePath))
@@ -53,8 +48,7 @@ export class SupabaseStorageProvider {
53
48
  const bucket = this.bucketFor(storagePath);
54
49
  const { data, error } = await this.client.storage.from(bucket).download(storagePath);
55
50
  if (error) {
56
- // storage-js surfaces 404 as an error with message "Object not found".
57
- // Normalize any "not found" to null — we don't have a stable status code.
51
+ // storage-js has no stable status code for 404 — match the message instead.
58
52
  const msg = error.message ?? '';
59
53
  if (/not found/i.test(msg) || /no such key/i.test(msg))
60
54
  return null;
@@ -64,16 +58,13 @@ export class SupabaseStorageProvider {
64
58
  return new Uint8Array(buffer);
65
59
  }
66
60
  async put(storagePath, data, contentType) {
67
- // Normalize images through the shared helper so this provider produces
68
- // the same bytes / extensions as LocalStorageProvider for the same input.
69
61
  const transcoded = await transcodeImageIfNeeded(data, contentType, storagePath);
70
62
  const bucket = this.bucketFor(transcoded.path);
71
63
  const { error } = await this.client.storage
72
64
  .from(bucket)
73
65
  .upload(transcoded.path, transcoded.data, {
74
66
  contentType: transcoded.contentType,
75
- // Objects are content-addressed (GUID/hash prefixes) and effectively
76
- // immutable, so let CDN/browser cache them for a year.
67
+ // Objects are content-addressed and immutable — cache for a year.
77
68
  cacheControl: '31536000',
78
69
  upsert: true
79
70
  });
@@ -83,13 +74,11 @@ export class SupabaseStorageProvider {
83
74
  async delete(storagePath) {
84
75
  const bucket = this.bucketFor(storagePath);
85
76
  const { error } = await this.client.storage.from(bucket).remove([storagePath]);
86
- // remove() does not error for missing paths — it just returns an empty array.
87
77
  if (error)
88
78
  throw error;
89
79
  }
90
80
  async deletePrefix(prefix) {
91
- // Hit both buckets: a definition's GUID prefix may have files in each.
92
- // Scoped by the trailing slash in the prefix, so siblings aren't touched.
81
+ // A definition's GUID prefix may have files in either bucket.
93
82
  await Promise.all([
94
83
  this.deletePrefixInBucket(this.publicBucket, prefix),
95
84
  this.deletePrefixInBucket(this.privateBucket, prefix)
@@ -100,7 +89,7 @@ export class SupabaseStorageProvider {
100
89
  const keys = await this.listAllKeys(bucket, normalized);
101
90
  if (keys.length === 0)
102
91
  return;
103
- // `remove` accepts up to 1000 paths; batch just in case.
92
+ // remove() caps out at 1000 paths per call.
104
93
  for (let i = 0; i < keys.length; i += 1000) {
105
94
  const slice = keys.slice(i, i + 1000);
106
95
  const { error } = await this.client.storage.from(bucket).remove(slice);
@@ -108,10 +97,7 @@ export class SupabaseStorageProvider {
108
97
  throw error;
109
98
  }
110
99
  }
111
- /**
112
- * Recursively list every key under a prefix. `storage-js`'s `list` API
113
- * only returns the immediate children of a "folder", so we DFS.
114
- */
100
+ /** storage-js's `list` only returns immediate children of a "folder", so DFS to get everything under `prefix`. */
115
101
  async listAllKeys(bucket, prefix) {
116
102
  const out = [];
117
103
  const stack = [prefix];
@@ -125,7 +111,7 @@ export class SupabaseStorageProvider {
125
111
  throw error;
126
112
  for (const entry of data ?? []) {
127
113
  const full = dir ? `${dir}/${entry.name}` : entry.name;
128
- // Folder entries have `id === null` in storage-js.
114
+ // storage-js marks folder entries with id === null.
129
115
  if (entry.id === null) {
130
116
  stack.push(full);
131
117
  }
@@ -140,7 +126,6 @@ export class SupabaseStorageProvider {
140
126
  if (this.bucketFor(storagePath) === this.publicBucket) {
141
127
  return `${this.publicBaseUrl}/${storagePath}`;
142
128
  }
143
- // Private files: the app's authenticated proxy route. See `privateUrlPrefix`.
144
129
  return `${this.privateUrlPrefix}/${storagePath}`;
145
130
  }
146
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SupabaseStorageProvider.js","sourceRoot":"","sources":["../../src/storage/SupabaseStorageProvider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SupabaseStorageProvider.js","sourceRoot":"","sources":["../../src/storage/SupabaseStorageProvider.ts"],"names":[],"mappings":"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"}