better-supabase 0.2.0 → 0.4.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 (190) hide show
  1. package/README.md +37 -33
  2. package/dist/base64-D2gsioCY.js +42 -0
  3. package/dist/claims-BAf6c7is.js +48 -0
  4. package/dist/cli/_format-Cax5EsM9.js +101 -0
  5. package/dist/cli/bin.js +39 -6
  6. package/dist/cli/command-CK14fP91.js +502 -0
  7. package/dist/cli/compare-BmIWVEui.js +9 -0
  8. package/dist/cli/config-D9R0o1LH.js +1895 -0
  9. package/dist/cli/config-SSKSTUl2.js +2 -0
  10. package/dist/cli/db-DOBPt660.js +52 -0
  11. package/dist/cli/dist-B1MvLv-M.js +129 -0
  12. package/dist/cli/dist-CFgGknmZ.js +1112 -0
  13. package/dist/cli/dist-Du7VnEUG.js +621 -0
  14. package/dist/cli/doctor-BOym3mbL.js +2382 -0
  15. package/dist/cli/env-BZ0uy8XK.js +108 -0
  16. package/dist/cli/env-jIFUADLY.js +511 -0
  17. package/dist/cli/errors-4v4DTtda.js +56 -0
  18. package/dist/cli/fastest-levenshtein-CFN-lNDv.js +120 -0
  19. package/dist/cli/gen-Ccn_p90L.js +2008 -0
  20. package/dist/cli/gen-D5cLCULx.js +2 -0
  21. package/dist/cli/index.d.ts +295 -28
  22. package/dist/cli/index.js +184 -3
  23. package/dist/cli/init-ClnxRYBF.js +550 -0
  24. package/dist/cli/introspect-DxqfkVIv.js +81 -0
  25. package/dist/cli/io-k41_z-jT.js +24 -0
  26. package/dist/cli/json5-ChRycquj.js +787 -0
  27. package/dist/cli/jsonc-BUniUpOk.js +2 -0
  28. package/dist/cli/jsonc-D5Fu67jw.js +45 -0
  29. package/dist/cli/keys-ByKHnvP9.js +83 -0
  30. package/dist/cli/ohash-D7bG_EOb.js +277 -0
  31. package/dist/cli/openapi-8WHjxiTJ.js +66 -0
  32. package/dist/cli/project-B_GeXyHh.js +70 -0
  33. package/dist/cli/prompts-BNcNfAve.js +1142 -0
  34. package/dist/cli/prompts-BTYQGunc.js +2 -0
  35. package/dist/cli/read-sets-CMa29t9a.js +971 -0
  36. package/dist/cli/rolldown-runtime-BPOCksWG.js +24 -0
  37. package/dist/cli/run-CP20LKk_.js +347 -0
  38. package/dist/cli/seed-5J6eu_Xg.js +98 -0
  39. package/dist/cli/skills-LJJIhLFR.js +137 -0
  40. package/dist/cli/sql-D4VbqmXi.js +199 -0
  41. package/dist/cli/style-C0NFdJRL.js +29 -0
  42. package/dist/cli/toml-DB-MNnFs.js +424 -0
  43. package/dist/{version-Cqq1m3UY.js → cli/version-5mW_8sY1.js} +1 -1
  44. package/dist/cli/yaml-CYCbJ6et.js +2252 -0
  45. package/dist/client/index.d.ts +2 -2
  46. package/dist/client/index.js +15 -25
  47. package/dist/{compiler-CZ9nIuqy.d.ts → compiler-DB3aSFOA.d.ts} +2 -2
  48. package/dist/config/index.d.ts +4 -3
  49. package/dist/config/index.js +5 -3
  50. package/dist/config-BpxDfnbg.js +129 -0
  51. package/dist/{index-DOsjFvMf.d.ts → config-C1CYcm6o.d.ts} +49 -49
  52. package/dist/{config-ClDXmVtY.js → config-CbvFmGD8.js} +14 -137
  53. package/dist/{define-BXMYD9AY.js → define-Bh0AqTik.js} +221 -120
  54. package/dist/{define-e3zI4_4g.d.ts → define-CRS2MRV3.d.ts} +36 -31
  55. package/dist/edge/index.d.ts +9 -13
  56. package/dist/edge/index.js +51 -25
  57. package/dist/{entitlements-Dng-ctuT.d.ts → entitlements-Dm-FHpNH.d.ts} +2 -2
  58. package/dist/env/index.js +203 -1
  59. package/dist/{errors-Bl3rkOzo.js → errors-L0xK41y_.js} +1 -1
  60. package/dist/events/index.d.ts +1 -1
  61. package/dist/events/index.js +139 -1
  62. package/dist/{events-DOt3nSO-.d.ts → events-B21UOhvP.d.ts} +4 -4
  63. package/dist/{executor-CGdNQ27g.d.ts → executor-B5IoUxLE.d.ts} +2 -2
  64. package/dist/{executor-DeppvirK.js → executor-CVt6dD0B.js} +9 -4
  65. package/dist/{executor-BYXQ9AGn.d.ts → executor-CZ7ImRiD.d.ts} +2 -2
  66. package/dist/hono/index.d.ts +17 -24
  67. package/dist/hono/index.js +11 -11
  68. package/dist/{index-DuP14VHo.d.ts → index-528Ugmyp.d.ts} +30 -10
  69. package/dist/{index-Bw1bwtC0.d.ts → index-BAy4tsAP.d.ts} +28 -15
  70. package/dist/{index-CBDufH1M.d.ts → index-BBdvo-5d.d.ts} +24 -26
  71. package/dist/{index-DbxFr7XG.d.ts → index-BhHEC04r.d.ts} +9 -4
  72. package/dist/index-Cf-D2jk1.d.ts +50 -0
  73. package/dist/{index-Ciu5Xlml.d.ts → index-D5IfUIDh.d.ts} +6 -5
  74. package/dist/{index-K-3WM2Hp.d.ts → index-DFmOpBGC.d.ts} +13 -13
  75. package/dist/{index-D4v7sncu.d.ts → index-RlLXd8dL.d.ts} +13 -13
  76. package/dist/index.d.ts +17 -17
  77. package/dist/index.js +23 -14
  78. package/dist/{invalidate-DbxuL2jL.js → invalidate-CgxmRamI.js} +7 -1
  79. package/dist/jobs/index.d.ts +33 -26
  80. package/dist/jobs/index.js +44 -22
  81. package/dist/{json-schema-BpYqkCKf.js → json-schema-DP6V7cbr.js} +8 -3
  82. package/dist/lint/index.js +1 -1
  83. package/dist/list/index.d.ts +2 -2
  84. package/dist/list/index.js +131 -96
  85. package/dist/{live-DJyZMD6w.d.ts → live-BHakSWWo.d.ts} +26 -16
  86. package/dist/{live-D8rV1Ldw.js → live-CdJBOc4f.js} +13 -9
  87. package/dist/lookup-BaP5bI27.js +18 -0
  88. package/dist/mcp/index.d.ts +34 -27
  89. package/dist/mcp/index.js +59 -25
  90. package/dist/{mfa-TVia554c.d.ts → mfa-C7MNQ1Ob.d.ts} +1 -1
  91. package/dist/{mfa-CpLfJSde.js → mfa-byfjruR9.js} +190 -46
  92. package/dist/next/image/index.js +6 -3
  93. package/dist/next/index.d.ts +64 -48
  94. package/dist/next/index.js +63 -50
  95. package/dist/openapi/index.d.ts +1 -1
  96. package/dist/openapi/index.js +61 -38
  97. package/dist/orpc/index.d.ts +18 -21
  98. package/dist/orpc/index.js +12 -12
  99. package/dist/otel/index.d.ts +5 -5
  100. package/dist/otel/index.js +84 -63
  101. package/dist/{permdock-sql-CghlHPuH.js → permdock-sql-C4KFzLc9.js} +12 -7
  102. package/dist/permdock-sql-DImJULY-.d.ts +17 -0
  103. package/dist/{plugin-C4TR9J0Z.d.ts → plugin-bNhvJwRh.d.ts} +5 -4
  104. package/dist/plugins/actor/index.d.ts +1 -1
  105. package/dist/plugins/actor/index.js +1 -1
  106. package/dist/plugins/rules/index.d.ts +2 -2
  107. package/dist/plugins/rules/index.js +46 -16
  108. package/dist/plugins/soft-delete/index.d.ts +3 -3
  109. package/dist/plugins/soft-delete/index.js +4 -4
  110. package/dist/plugins/tenant/index.d.ts +3 -3
  111. package/dist/plugins/tenant/index.js +10 -4
  112. package/dist/plugins/timestamps/index.d.ts +1 -1
  113. package/dist/plugins/timestamps/index.js +2 -2
  114. package/dist/plugins/validation/index.d.ts +2 -2
  115. package/dist/plugins/validation/index.js +3 -3
  116. package/dist/pool-DFwEQwmN.d.ts +78 -0
  117. package/dist/postgres/index.d.ts +10 -5
  118. package/dist/postgres/index.js +37 -16
  119. package/dist/{postgrest-cAEQ_IQN.d.ts → postgrest-Bc-0Xw62.d.ts} +1 -1
  120. package/dist/{problem-BTkTtRV9.js → problem-BihjPR0t.js} +11 -5
  121. package/dist/{problem-DlgB0lYl.d.ts → problem-U8UEKccv.d.ts} +6 -4
  122. package/dist/query/index.d.ts +2 -2
  123. package/dist/query/index.js +2 -2
  124. package/dist/{query-ChvDbsDE.js → query-BMMSWbI7.js} +19 -19
  125. package/dist/react/index.d.ts +7 -7
  126. package/dist/react/index.js +2 -2
  127. package/dist/react/server.d.ts +6 -6
  128. package/dist/react/server.js +3 -3
  129. package/dist/react/session.d.ts +21 -2
  130. package/dist/react/session.js +19 -1
  131. package/dist/{react-C83BdBGt.js → react-CQHMaESR.js} +59 -55
  132. package/dist/{read-set-4lI3W_gZ.js → read-set-FWK8qQ58.js} +51 -16
  133. package/dist/realtime/index.d.ts +4 -3
  134. package/dist/realtime/index.js +19 -17
  135. package/dist/{index-CG69s15v.d.ts → refresh-BwYkyNOQ.d.ts} +7 -3
  136. package/dist/{resolve-CjHILk2w.d.ts → resolve-BAqQcwMW.d.ts} +17 -11
  137. package/dist/{resource-CgZa3YG_.d.ts → resource-BJcaIfxi.d.ts} +17 -8
  138. package/dist/{resource-BHEWmQJK.js → resource-My_y-Syh.js} +43 -21
  139. package/dist/{respond-Dne1ARSa.d.ts → respond-DgIbdrt8.d.ts} +39 -14
  140. package/dist/{result-DWXatkd6.js → result-Bj6yt33D.js} +2 -2
  141. package/dist/{result-CTkCZ6JA.d.ts → result-CqEsbgYs.d.ts} +16 -11
  142. package/dist/server/index.d.ts +38 -13
  143. package/dist/server/index.js +43 -14
  144. package/dist/{respond-DMcbQwfN.js → server-BA75B0mT.js} +151 -96
  145. package/dist/{shared-_6-uPL7E.js → shared-DnoCdMDr.js} +4 -3
  146. package/dist/{simplify-bwJpLnaS.js → simplify-Cqvfr9dj.js} +76 -39
  147. package/dist/sql/index.d.ts +139 -0
  148. package/dist/sql/index.js +1983 -0
  149. package/dist/{sql-DTjA1LPj.js → sql-B34HU2DI.js} +74 -17
  150. package/dist/ssr/index.d.ts +4 -4
  151. package/dist/ssr/index.js +2 -2
  152. package/dist/{standard-FUi3Z3-7.js → standard-BRyBGTtp.js} +2 -2
  153. package/dist/{standard-CyhRzctb.d.ts → standard-BsaCYQJc.d.ts} +1 -1
  154. package/dist/{stats-C5W-rBfR.js → stats-C_YxA2r1.js} +40 -14
  155. package/dist/storage/index.d.ts +4 -3
  156. package/dist/storage/index.js +548 -1
  157. package/dist/{tables-rZxRxNPW.js → tables-Cb-3_VWc.js} +19 -5
  158. package/dist/temporal-BwshQk0W.js +27 -0
  159. package/dist/temporal-required-CBNHT6ni.js +19 -0
  160. package/dist/testing/index.d.ts +25 -24
  161. package/dist/testing/index.js +165 -66
  162. package/dist/{types-C83v5SQz.d.ts → types-DONv9SHN.d.ts} +14 -11
  163. package/dist/version-Bmf7_FzM.js +4 -0
  164. package/dist/{view-D1s0wa0T.d.ts → view-B64o81wp.d.ts} +36 -6
  165. package/dist/{view-aOYizTeE.js → view-BrJI2LKp.js} +11 -2
  166. package/dist/webhooks/index.d.ts +19 -17
  167. package/dist/webhooks/index.js +1 -1
  168. package/dist/{webhooks-DMipjhSP.js → webhooks-Bh_Jf_-l.js} +45 -24
  169. package/package.json +50 -22
  170. package/schemas/config-v1.json +31 -1
  171. package/schemas/doctor-report-v1.json +17 -1
  172. package/schemas/snapshot-v2.json +35 -0
  173. package/skills/better-supabase/SKILL.md +77 -18
  174. package/skills/better-supabase/references/plugins.md +21 -22
  175. package/skills/better-supabase/references/troubleshooting.md +38 -18
  176. package/skills/better-supabase-api/SKILL.md +66 -18
  177. package/skills/better-supabase-api/references/adapters.md +64 -41
  178. package/skills/better-supabase-auth/SKILL.md +146 -0
  179. package/skills/better-supabase-auth/references/permdock.md +55 -0
  180. package/skills/better-supabase-testing/SKILL.md +68 -11
  181. package/dist/casing-da0uRTqt.js +0 -14
  182. package/dist/claims-CoTobNC-.js +0 -25
  183. package/dist/cli-DrSgDOQC.js +0 -6646
  184. package/dist/env-BEToab0I.js +0 -204
  185. package/dist/events-BuzTgn2D.js +0 -135
  186. package/dist/pool-R2m_DkXi.d.ts +0 -37
  187. package/dist/seed-CzecODcJ.js +0 -101
  188. package/dist/session-C3LxnQ0e.d.ts +0 -22
  189. package/dist/session-CqEwzVup.js +0 -20
  190. package/dist/storage-DuGn38fr.js +0 -527
@@ -1,2 +1,140 @@
1
- import { a as isCloudEvent, i as httpSink, n as forwardMutations, o as toCloudEvents, r as fromHttp, s as toHttp, t as ROW_EVENT_TYPES } from "../events-BuzTgn2D.js";
1
+ import { n as nowInstant } from "../temporal-BwshQk0W.js";
2
+ //#region src/events/index.ts
3
+ const ROW_EVENT_TYPES = {
4
+ insert: "dev.better-supabase.row.created",
5
+ upsert: "dev.better-supabase.row.upserted",
6
+ update: "dev.better-supabase.row.updated",
7
+ delete: "dev.better-supabase.row.deleted"
8
+ };
9
+ function subjectOf(meta, table, row) {
10
+ const key = meta?.tables[table]?.primaryKey;
11
+ if (!key || key.length === 0) return void 0;
12
+ const values = key.map((column) => row[column]);
13
+ if (values.some((value) => value === void 0 || value === null)) return void 0;
14
+ return `${table}/${values.map((value) => encodeURIComponent(String(value))).join(",")}`;
15
+ }
16
+ /**
17
+ * One CloudEvent per mutated row: `dev.better-supabase.row.created` with the
18
+ * app-cased row as `data`, the primary key as `subject`, the tenant as
19
+ * `partitionkey` and the actor as `actorid`.
20
+ */
21
+ function toCloudEvents(notice, options) {
22
+ const type = options.typePrefix ? `${options.typePrefix}.row.${ROW_EVENT_TYPES[notice.kind].split(".").at(-1)}` : ROW_EVENT_TYPES[notice.kind];
23
+ const time = (options.now ?? nowInstant)().toString();
24
+ return notice.rows.map((row) => {
25
+ const subject = subjectOf(options.meta, notice.table, row);
26
+ return {
27
+ specversion: "1.0",
28
+ id: options.id?.() ?? crypto.randomUUID(),
29
+ source: options.source,
30
+ type,
31
+ ...subject ? { subject } : {},
32
+ time,
33
+ datacontenttype: "application/json",
34
+ data: {
35
+ table: notice.table,
36
+ row
37
+ },
38
+ ...notice.context.tenant ? { partitionkey: notice.context.tenant } : {},
39
+ ...notice.context.actor?.id ? { actorid: notice.context.actor.id } : {}
40
+ };
41
+ });
42
+ }
43
+ /**
44
+ * Sends a CloudEvent for every mutation to `sink`. Returns a function that
45
+ * stops forwarding. Use an outbox (SQL kit) when events must not be lost.
46
+ */
47
+ function forwardMutations(betterSupabase, sink, options) {
48
+ return betterSupabase.events.on("mutation", (notice) => {
49
+ if (options.filter && !options.filter(notice)) return;
50
+ const events = toCloudEvents(notice, {
51
+ ...options,
52
+ meta: betterSupabase.meta
53
+ });
54
+ if (events.length === 0) return;
55
+ const report = (error) => {
56
+ (options.onError ?? ((cause) => {
57
+ betterSupabase.events.logger.error("event sink failed", { cause });
58
+ }))(error, events);
59
+ };
60
+ try {
61
+ Promise.resolve(sink.send(events)).catch(report);
62
+ } catch (error) {
63
+ report(error);
64
+ }
65
+ });
66
+ }
67
+ const STRUCTURED = "application/cloudevents+json";
68
+ const BATCH = "application/cloudevents-batch+json";
69
+ /** The HTTP protocol binding: headers and body for one event (or a batch). */
70
+ function toHttp(events, mode = "structured") {
71
+ const list = Array.isArray(events) ? events : [events];
72
+ switch (mode) {
73
+ case "batch": return [{
74
+ headers: { "content-type": BATCH },
75
+ body: JSON.stringify(list)
76
+ }];
77
+ case "structured": return list.map((event) => ({
78
+ headers: { "content-type": STRUCTURED },
79
+ body: JSON.stringify(event)
80
+ }));
81
+ case "binary": return list.map((event) => {
82
+ const headers = {};
83
+ for (const [key, value] of Object.entries(event)) {
84
+ if (key === "data" || key === "datacontenttype" || value === void 0) continue;
85
+ headers[`ce-${key}`] = encodeURIComponent(String(value)).replaceAll("%20", " ");
86
+ }
87
+ headers["content-type"] = event.datacontenttype ?? "application/json";
88
+ return {
89
+ headers,
90
+ body: event.data === void 0 ? "" : JSON.stringify(event.data)
91
+ };
92
+ });
93
+ default: throw new TypeError(`Unknown CloudEvents mode ${String(mode)}`);
94
+ }
95
+ }
96
+ function isCloudEvent(value) {
97
+ if (typeof value !== "object" || value === null) return false;
98
+ const event = value;
99
+ return event["specversion"] === "1.0" && typeof event["id"] === "string" && typeof event["source"] === "string" && typeof event["type"] === "string";
100
+ }
101
+ /** Reads CloudEvents from a request in any of the three HTTP modes. */
102
+ async function fromHttp(request) {
103
+ const contentType = request.headers.get("content-type") ?? "";
104
+ const text = await request.text();
105
+ if (contentType.startsWith(BATCH)) {
106
+ const parsed = JSON.parse(text);
107
+ if (!Array.isArray(parsed) || !parsed.every(isCloudEvent)) throw new TypeError("Invalid CloudEvents batch");
108
+ return parsed;
109
+ }
110
+ if (contentType.startsWith(STRUCTURED)) {
111
+ const parsed = JSON.parse(text);
112
+ if (!isCloudEvent(parsed)) throw new TypeError("Invalid CloudEvent");
113
+ return [parsed];
114
+ }
115
+ const event = {};
116
+ for (const [key, value] of request.headers) if (key.startsWith("ce-")) event[key.slice(3)] = decodeURIComponent(value);
117
+ if (contentType) event["datacontenttype"] = contentType;
118
+ if (text) event["data"] = contentType.includes("json") ? JSON.parse(text) : text;
119
+ if (!isCloudEvent(event)) throw new TypeError("Request is not a CloudEvent");
120
+ return [event];
121
+ }
122
+ /** POSTs events to `url`. Non-2xx responses reject. */
123
+ function httpSink(url, options = {}) {
124
+ const send = options.fetch ?? fetch;
125
+ return { async send(events) {
126
+ for (const message of toHttp(events, options.mode ?? "batch")) {
127
+ const response = await send(url, {
128
+ method: "POST",
129
+ headers: {
130
+ ...options.headers,
131
+ ...message.headers
132
+ },
133
+ body: message.body
134
+ });
135
+ if (!response.ok) throw new Error(`Event sink responded ${String(response.status)}`);
136
+ }
137
+ } };
138
+ }
139
+ //#endregion
2
140
  export { ROW_EVENT_TYPES, forwardMutations, fromHttp, httpSink, isCloudEvent, toCloudEvents, toHttp };
@@ -1,6 +1,6 @@
1
- import { g as Operation } from "./executor-CGdNQ27g.js";
2
- import { p as DbError } from "./result-CTkCZ6JA.js";
3
- import { h as RequestContext, l as MutationKind } from "./plugin-C4TR9J0Z.js";
1
+ import { g as Operation } from "./executor-B5IoUxLE.js";
2
+ import { p as DbError } from "./result-CqEsbgYs.js";
3
+ import { h as RequestContext, l as MutationKind } from "./plugin-bNhvJwRh.js";
4
4
  //#region src/core/logger.d.ts
5
5
  type LogFields = Readonly<Record<string, unknown>>;
6
6
  /**
@@ -37,7 +37,7 @@ interface MutationNotice {
37
37
  readonly rows: readonly Readonly<Record<string, unknown>>[];
38
38
  readonly context: RequestContext;
39
39
  }
40
- /** A successful RPC registered with `sb.defineRpc(name, { invalidates })`. */
40
+ /** A successful RPC registered with `betterSupabase.defineRpc(name, { invalidates })`. */
41
41
  interface RpcNotice {
42
42
  readonly name: string;
43
43
  /** App keys of the tables the function changes. */
@@ -1,5 +1,5 @@
1
- import { P as TableMeta, T as RelationMeta, c as Codec } from "./types-C83v5SQz.js";
2
- import { o as Result, v as ErrorMapper } from "./result-CTkCZ6JA.js";
1
+ import { P as TableMeta, T as RelationMeta, c as Codec } from "./types-DONv9SHN.js";
2
+ import { o as Result, v as ErrorMapper } from "./result-CqEsbgYs.js";
3
3
  //#region src/ir/types.d.ts
4
4
  /**
5
5
  * The query IR. Every repository call becomes one of these operations; the
@@ -1,6 +1,6 @@
1
- import { c as mapDbError, n as dbError } from "./errors-Bl3rkOzo.js";
2
- import { i as ok, n as err, o as toDbError } from "./result-DWXatkd6.js";
3
- import { t as compileSql } from "./sql-DTjA1LPj.js";
1
+ import { c as mapDbError, n as dbError } from "./errors-L0xK41y_.js";
2
+ import { i as ok, n as err, o as toDbError } from "./result-Bj6yt33D.js";
3
+ import { t as compileSql } from "./sql-B34HU2DI.js";
4
4
  //#region src/postgres/executor.ts
5
5
  function isPgError(value) {
6
6
  return typeof value === "object" && value !== null && typeof value.code === "string";
@@ -25,6 +25,11 @@ async function run(client, plan, op) {
25
25
  const [first] = await client.queryRaw(plan.count.text, [...plan.count.params]);
26
26
  count = first?.count ?? 0;
27
27
  } else if (op.kind !== "select") count = rows.length;
28
+ for (const next of plan.chunks ?? []) {
29
+ const more = await run(client, next, op);
30
+ rows.push(...more.rows);
31
+ count = (count ?? 0) + (more.count ?? 0);
32
+ }
28
33
  return {
29
34
  rows,
30
35
  count
@@ -74,7 +79,7 @@ async function executeOn(client, op, context) {
74
79
  if (context.signal?.aborted) return err(dbError("aborted", "The request was aborted"));
75
80
  let result;
76
81
  try {
77
- result = await run(client, plan, op);
82
+ result = plan.chunks && client.transaction ? await client.transaction((scoped) => run(scoped, plan, op)) : await run(client, plan, op);
78
83
  } catch (cause) {
79
84
  const raw = fromPgError(cause);
80
85
  return err(raw ? mapDbError(raw, context.errorMappers) : toDbError(cause));
@@ -1,5 +1,5 @@
1
- import { r as Executor } from "./executor-CGdNQ27g.js";
2
- import { y as RawDbError } from "./result-CTkCZ6JA.js";
1
+ import { r as Executor } from "./executor-B5IoUxLE.js";
2
+ import { y as RawDbError } from "./result-CqEsbgYs.js";
3
3
  //#region src/postgres/executor.d.ts
4
4
  /**
5
5
  * Anything that runs parameterized SQL: `ctx.postgres` from
@@ -1,45 +1,38 @@
1
- import { N as TableKey, n as AnyModels, t as AnyFunctions } from "../types-C83v5SQz.js";
2
- import { t as BetterSupabase } from "../define-e3zI4_4g.js";
3
- import { r as AuthState } from "../resolve-CjHILk2w.js";
4
- import { d as ServerContext, f as ServerOptions, l as BetterServer, n as GuardOptions } from "../respond-Dne1ARSa.js";
5
- import { i as ResourceRouteOptions } from "../resource-CgZa3YG_.js";
1
+ import { N as TableKey, n as AnyModels, t as AnyFunctions } from "../types-DONv9SHN.js";
2
+ import { t as BetterSupabase } from "../define-CRS2MRV3.js";
3
+ import { r as AuthState } from "../resolve-BAqQcwMW.js";
4
+ import { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-DgIbdrt8.js";
5
+ import { a as ResourceRouteOptions } from "../resource-BJcaIfxi.js";
6
6
  import { Context, ErrorHandler, Hono, MiddlewareHandler } from "hono";
7
7
  //#region src/hono/index.d.ts
8
8
  /** Hono `Env` with the request's better-supabase context in `c.var`. */
9
- export interface BetterEnv<M extends AnyModels, F extends AnyFunctions, E> {
9
+ export interface HonoEnv<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> {
10
10
  Variables: {
11
- readonly bs: ServerContext<M, F, E>;
12
- readonly db: ServerContext<M, F, E>["db"];
13
- readonly auth: AuthState;
11
+ readonly bs: ServerContext<M, F, E, C, P>;
12
+ readonly db: ServerContext<M, F, E, C, P>["db"];
13
+ readonly auth: AuthState<C, P>;
14
14
  };
15
15
  }
16
16
  export interface HonoOptions extends ServerOptions {
17
17
  /** Include error details in problem responses. Defaults to `NODE_ENV === 'development'`. */
18
18
  readonly exposeErrors?: boolean;
19
19
  }
20
- export interface MiddlewareOptions extends GuardOptions {
21
- /**
22
- * Refresh an expired cookie session and send the new cookies. Only for
23
- * routes browsers call with cookies; bearer tokens never refresh.
24
- */
25
- readonly refresh?: boolean;
26
- }
27
- export interface BetterHono<M extends AnyModels, F extends AnyFunctions, E> extends BetterServer<M, F, E> {
20
+ export interface BetterHono<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> extends BetterServer<M, F, E, C, P> {
28
21
  /** Resolves the caller, enforces `allow` and sets `c.var.bs`, `c.var.db`, `c.var.auth`. */
29
- middleware(options?: MiddlewareOptions): MiddlewareHandler<BetterEnv<M, F, E>>;
22
+ middleware(options?: MiddlewareOptions): MiddlewareHandler<HonoEnv<M, F, E, C, P>>;
30
23
  /** Wraps a handler: `Result`s become JSON or Problem Details, `undefined` becomes 204. */
31
- handle(handler: (c: Context<BetterEnv<M, F, E>>, ctx: ServerContext<M, F, E>) => unknown, options?: {
24
+ handler(fn: (c: Context<HonoEnv<M, F, E, C, P>>, ctx: ServerContext<M, F, E, C, P>) => unknown, options?: {
32
25
  readonly status?: number;
33
- }): (c: Context<BetterEnv<M, F, E>>) => Promise<Response>;
26
+ }): (c: Context<HonoEnv<M, F, E, C, P>>) => Promise<Response>;
34
27
  /** `app.onError(bs.onError)`: `DbException`s (and errors caused by a `DbError`) become Problem Details, others a 500. */
35
- readonly onError: ErrorHandler<BetterEnv<M, F, E>>;
28
+ readonly onError: ErrorHandler<HonoEnv<M, F, E, C, P>>;
36
29
  /**
37
30
  * REST routes for a table matching `createOpenApi`. Mount with
38
31
  * `app.route('/customers', bs.resource('customers'))` behind `middleware()`.
39
32
  */
40
- resource<T extends TableKey<M>>(table: T, options?: ResourceRouteOptions<M, T>): Hono<BetterEnv<M, F, E>>;
33
+ resource<T extends TableKey<M>>(table: T, options?: ResourceRouteOptions<M, T>): Hono<HonoEnv<M, F, E, C, P>>;
41
34
  }
42
35
  /** Hono integration: a server plus middleware, handlers and REST resources. */
43
- export declare function createHono<M extends AnyModels, D, F extends AnyFunctions, E>(sb: BetterSupabase<M, D, F, E>, options?: HonoOptions): BetterHono<M, F, E>;
36
+ export declare function createHono<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: HonoOptions): BetterHono<M, F, E, C, P>;
44
37
  //#endregion
45
- export type { GuardOptions, ResourceRouteOptions };
38
+ export type { GuardOptions, MiddlewareOptions, ResourceRouteOptions };
@@ -1,7 +1,7 @@
1
- import { n as dbError, r as dbErrorOf } from "../errors-Bl3rkOzo.js";
2
- import { a as problemResponse } from "../problem-BTkTtRV9.js";
3
- import { i as respond, n as guard, o as createServer, s as extendServer, t as defaultExpose } from "../respond-DMcbQwfN.js";
4
- import { t as defineResource } from "../resource-BHEWmQJK.js";
1
+ import { n as dbError, r as dbErrorOf } from "../errors-L0xK41y_.js";
2
+ import { a as problemResponse } from "../problem-BihjPR0t.js";
3
+ import { a as guard, i as defaultExpose, n as extendServer, s as respond, t as createServer } from "../server-BA75B0mT.js";
4
+ import { t as defineResource } from "../resource-My_y-Syh.js";
5
5
  import { Hono } from "hono";
6
6
  //#region src/hono/index.ts
7
7
  function contextOf(c) {
@@ -10,8 +10,8 @@ function contextOf(c) {
10
10
  return ctx;
11
11
  }
12
12
  /** Hono integration: a server plus middleware, handlers and REST resources. */
13
- function createHono(sb, options = {}) {
14
- const server = createServer(sb, options);
13
+ function createHono(betterSupabase, options = {}) {
14
+ const server = createServer(betterSupabase, options);
15
15
  const expose = options.exposeErrors ?? defaultExpose();
16
16
  const onError = (cause, c) => {
17
17
  const instance = new URL(c.req.url).pathname;
@@ -31,7 +31,7 @@ function createHono(sb, options = {}) {
31
31
  middleware(middlewareOptions = {}) {
32
32
  return async (c, next) => {
33
33
  const ctx = await server.context(c.req.raw, { refresh: middlewareOptions.refresh ?? false });
34
- const denied = guard(ctx.auth, middlewareOptions.allow, middlewareOptions.aal);
34
+ const denied = guard(ctx.auth, middlewareOptions.allow, middlewareOptions.aal, middlewareOptions.scopes);
35
35
  if (denied) return ctx.resolution.apply(problemResponse(denied, {
36
36
  instance: new URL(c.req.url).pathname,
37
37
  expose
@@ -43,18 +43,18 @@ function createHono(sb, options = {}) {
43
43
  c.res = ctx.resolution.apply(c.res);
44
44
  };
45
45
  },
46
- handle(handler, handleOptions = {}) {
46
+ handler(fn, handlerOptions = {}) {
47
47
  return (c) => {
48
48
  const ctx = contextOf(c);
49
- return respond(() => handler(c, ctx), {
49
+ return respond(() => fn(c, ctx), {
50
50
  instance: new URL(c.req.url).pathname,
51
51
  expose,
52
- ...handleOptions
52
+ ...handlerOptions
53
53
  });
54
54
  };
55
55
  },
56
56
  resource(table, resourceOptions) {
57
- const resource = defineResource(sb, table, resourceOptions);
57
+ const resource = defineResource(betterSupabase, table, resourceOptions);
58
58
  const app = new Hono();
59
59
  const serve = (item) => (c) => resource.handle(c.req.raw, contextOf(c).db, item ? c.req.param("id") : void 0, {
60
60
  instance: new URL(c.req.url).pathname,
@@ -1,9 +1,11 @@
1
- import { b as PermdockBucketPolicy, i as BucketPolicyName } from "./types-C83v5SQz.js";
2
- import { p as DbError, t as AsyncResult } from "./result-CTkCZ6JA.js";
1
+ /// <reference lib="esnext.temporal" />
2
+ import { b as PermdockBucketPolicy, i as BucketPolicyName } from "./types-DONv9SHN.js";
3
+ import { p as DbError, t as AsyncResult } from "./result-CqEsbgYs.js";
3
4
  import { n as StoragePath, t as PathIn } from "./path-Cv__-OTj.js";
5
+ import { t as PermdockCatalog } from "./permdock-sql-DImJULY-.js";
4
6
  import { n as TemplateValues, t as TemplateParams } from "./template-mbvlysOo.js";
5
7
  import { SupabaseClient } from "@supabase/supabase-js";
6
- //#region src/storage/index.d.ts
8
+ //#region src/storage/bucket.d.ts
7
9
  type BucketPolicy = BucketPolicyName | PermdockBucketPolicy;
8
10
  interface BucketConfig<P extends string = string, Id extends string = string> {
9
11
  /** Bucket id, e.g. `customer-logos`. */
@@ -20,10 +22,16 @@ interface BucketConfig<P extends string = string, Id extends string = string> {
20
22
  * The helpers check role and scope only. Use `permdock` just for
21
23
  * permissions whose grants have no row conditions beyond the scope: for a
22
24
  * permission with row conditions (e.g. `ownerId = principal.id`) the bucket
23
- * grants every object in the scope. Leave those to the policies
24
- * `permdock rls generate` writes.
25
+ * would grant every object in the scope. Pass `catalog` to refuse those
26
+ * keys here; `better-supabase doctor` (BS214) refuses them from the
27
+ * catalog file.
25
28
  */
26
29
  readonly policy?: BucketPolicy;
30
+ /**
31
+ * PermDock's `permissions.catalog.json`. With it, a `permdock` policy
32
+ * naming a permission with `rowConditions: true` throws.
33
+ */
34
+ readonly catalog?: PermdockCatalog;
27
35
  /** `'5MiB'`, `'500KB'` or bytes. */
28
36
  readonly fileSizeLimit?: string | number;
29
37
  /** `['image/png', 'image/*']`. */
@@ -105,14 +113,17 @@ interface ReplaceResult<Id extends string = string> {
105
113
  interface SweepOptions<P extends string> {
106
114
  /** Only look under the path prefix these values fill. */
107
115
  readonly within?: Partial<TemplateValues<P>>;
108
- /** Minimum age in milliseconds, or a cutoff date. */
109
- readonly olderThan: number | Date;
116
+ /**
117
+ * A cutoff instant, or a minimum age. A duration counts a day as 24 hours
118
+ * and cannot use months or years.
119
+ */
120
+ readonly olderThan: Temporal.Instant | Temporal.Duration;
110
121
  /** Returns which of `paths` are still referenced. */
111
122
  readonly referenced: (paths: readonly string[]) => PromiseLike<Iterable<string>> | Iterable<string>;
112
123
  readonly dryRun?: boolean;
113
124
  readonly batchSize?: number;
114
125
  readonly signal?: AbortSignal;
115
- readonly now?: () => number;
126
+ readonly now?: () => Temporal.Instant;
116
127
  }
117
128
  interface SweepResult {
118
129
  readonly scanned: number;
@@ -191,7 +202,16 @@ interface Bucket<P extends string, Id extends string = string> {
191
202
  /** A `[storage.buckets.<id>]` section for `supabase/config.toml`. */
192
203
  toml(): string;
193
204
  drift(actual: ActualBucket | undefined): readonly BucketDrift[];
194
- connect(client: StorageClient): BucketClient<P, Id>;
205
+ connect(client: StorageClient, options?: BucketConnectOptions): BucketClient<P, Id>;
206
+ }
207
+ interface BucketConnectOptions {
208
+ /**
209
+ * Reuse a signed URL for the same path, `ttl`, `transform` and `download`
210
+ * until shortly before it expires (a tenth of the `ttl`, at most a minute).
211
+ * The cache belongs to this connection; connect once per request so URLs
212
+ * never cross users.
213
+ */
214
+ readonly cacheSignedUrls?: boolean;
195
215
  }
196
216
  declare function parseSize(value: string | number): number;
197
217
  /** Maps a Storage error (`StorageApiError`, fetch failures) to a `DbError`. */
@@ -213,4 +233,4 @@ declare function fromStorageError(raw: unknown, table?: string): DbError;
213
233
  */
214
234
  declare function defineBucket<const P extends string, const Id extends string = string>(config: BucketConfig<P, Id>): Bucket<P, Id>;
215
235
  //#endregion
216
- export { parseSize as C, fromStorageError as S, TtlPreset as _, BucketDrift as a, UrlOptions as b, ReplaceOptions as c, StorageClient as d, StoredObject as f, TransformOptions as g, TTL as h, BucketConfig as i, ReplaceResult as l, SweepResult as m, Bucket as n, BucketPolicy as o, SweepOptions as p, BucketClient as r, ObjectTarget as s, ActualBucket as t, Reservation as u, UploadBody as v, defineBucket as x, UploadOptions as y };
236
+ export { fromStorageError as C, defineBucket as S, TransformOptions as _, BucketConnectOptions as a, UploadOptions as b, ObjectTarget as c, Reservation as d, StorageClient as f, TTL as g, SweepResult as h, BucketConfig as i, ReplaceOptions as l, SweepOptions as m, Bucket as n, BucketDrift as o, StoredObject as p, BucketClient as r, BucketPolicy as s, ActualBucket as t, ReplaceResult as u, TtlPreset as v, parseSize as w, UrlOptions as x, UploadBody as y };
@@ -1,14 +1,16 @@
1
- import { N as TableKey, O as Row, n as AnyModels, t as AnyFunctions } from "./types-C83v5SQz.js";
2
- import { l as CountMode } from "./executor-CGdNQ27g.js";
3
- import { b as ValidationIssue, t as AsyncResult } from "./result-CTkCZ6JA.js";
4
- import { C as FindExt, Ct as WhereInput, O as RepositoryOf, T as OffsetPageArgs, dt as IncludeArg, gt as OrderByArg, t as BetterSupabase, vt as Payload, w as OffsetPage, xt as SelectArg } from "./define-e3zI4_4g.js";
1
+ import { N as TableKey, O as Row, n as AnyModels, t as AnyFunctions } from "./types-DONv9SHN.js";
2
+ import { l as CountMode } from "./executor-B5IoUxLE.js";
3
+ import { b as ValidationIssue, t as AsyncResult } from "./result-CqEsbgYs.js";
4
+ import { C as FindExt, Ct as WhereInput, O as RepositoryOf, T as OffsetPageArgs, _ as CursorPage, dt as IncludeArg, gt as OrderByArg, t as BetterSupabase, v as CursorPageArgs, vt as Payload, w as OffsetPage, xt as SelectArg } from "./define-CRS2MRV3.js";
5
5
  import { StandardSchemaV1 } from "@standard-schema/spec";
6
- //#region src/list/index.d.ts
6
+ //#region src/list/list-query.d.ts
7
7
  /** Facet value meaning "not set": filters with `is null`. */
8
8
  declare const UNSET = "__unset__";
9
9
  type Column<M extends AnyModels, T extends keyof M> = Extract<keyof Row<M, T>, string>;
10
10
  type TextColumn<M extends AnyModels, T extends keyof M> = { [K in Column<M, T>]: [NonNullable<Row<M, T>[K]>] extends [string] ? K : never; }[Column<M, T>];
11
- interface ListQueryConfig<M extends AnyModels, T extends keyof M, S extends string, F extends string, C extends boolean = boolean> {
11
+ /** `offset` pages by number; `cursor` continues after the last row (keyset). */
12
+ type ListPagination = "offset" | "cursor";
13
+ interface ListQueryConfig<M extends AnyModels, T extends keyof M, S extends string, F extends string, C extends boolean = boolean, P extends ListPagination = ListPagination> {
12
14
  /**
13
15
  * Also count rows per facet value, with one grouped aggregate that runs
14
16
  * next to the page: 2 calls, 1 wave. Needs PostgREST aggregates.
@@ -26,6 +28,12 @@ interface ListQueryConfig<M extends AnyModels, T extends keyof M, S extends stri
26
28
  /** Named orderings. Add a unique column last for stable pages. */
27
29
  readonly sorts: { readonly [K in S]: OrderByArg<M, T>; };
28
30
  readonly defaultSort: NoInfer<S>;
31
+ /**
32
+ * `cursor` takes an `after` cursor instead of `page` and returns
33
+ * `nextCursor`: the cost of a page stays the same however deep it is, and
34
+ * rows inserted meanwhile don't shift it. Defaults to `offset`.
35
+ */
36
+ readonly pagination?: P;
29
37
  /** Defaults to 50. */
30
38
  readonly pageSize?: number;
31
39
  /** Defaults to 200. */
@@ -36,8 +44,10 @@ interface ListQueryConfig<M extends AnyModels, T extends keyof M, S extends stri
36
44
  interface ListQuery<S extends string, F extends string> {
37
45
  readonly q?: string;
38
46
  readonly sort: S;
39
- /** 1-based. */
47
+ /** 1-based. Always 1 with cursor pagination. */
40
48
  readonly page: number;
49
+ /** Cursor pagination: the `nextCursor` of the previous page. */
50
+ readonly after?: string;
41
51
  readonly size: number;
42
52
  readonly facets: { readonly [K in F]?: readonly string[]; };
43
53
  }
@@ -46,6 +56,7 @@ interface ListQueryInput<S extends string, F extends string> {
46
56
  readonly q?: string;
47
57
  readonly sort?: S;
48
58
  readonly page?: number;
59
+ readonly after?: string;
49
60
  readonly size?: number;
50
61
  readonly facets?: { readonly [K in F]?: readonly string[]; };
51
62
  }
@@ -83,13 +94,14 @@ interface FacetInfo {
83
94
  /** Rows per facet value, keyed by facet and then by value (`UNSET` for empty). */
84
95
  type FacetCounts<F extends string> = { readonly [K in F]: Readonly<Record<string, number>>; };
85
96
  /** A page of a list; with `facetCounts: true`, also the counts per facet value. */
86
- type ListPage<R, F extends string, C extends boolean> = OffsetPage<R> & ([C] extends [true] ? {
97
+ type ListPage<R, F extends string, C extends boolean, P extends ListPagination = "offset"> = ([P] extends ["cursor"] ? CursorPage<R> : OffsetPage<R>) & ([C] extends [true] ? {
87
98
  readonly facetCounts: FacetCounts<F>;
88
99
  } : [C] extends [false] ? unknown : {
89
100
  readonly facetCounts?: FacetCounts<F>;
90
101
  });
91
- interface ListDefinition<M extends AnyModels, T extends TableKey<M>, E, S extends string, F extends string, C extends boolean = false> {
102
+ interface ListDefinition<M extends AnyModels, T extends TableKey<M>, E, S extends string, F extends string, C extends boolean = false, P extends ListPagination = "offset"> {
92
103
  readonly table: T;
104
+ readonly pagination: P;
93
105
  readonly defaults: ListQuery<S, F>;
94
106
  readonly facets: readonly FacetInfo[];
95
107
  /** Validates typed input or URL params. Also a Standard Schema (`schema`). */
@@ -100,13 +112,13 @@ interface ListDefinition<M extends AnyModels, T extends TableKey<M>, E, S extend
100
112
  /** `{ parse, serialize }` per URL key, for routers and nuqs (`list.nuqs(createParser)`). */
101
113
  readonly parsers: ListParsers<S, F>;
102
114
  nuqs<P>(createParser: (spec: ParserSpec<unknown>) => P): { readonly [K in keyof ListParsers<S, F>]: P; };
103
- /** Repository arguments: `where`, `orderBy`, `page`, `size`, `count`. */
104
- args(query: ListQuery<S, F>): OffsetPageArgs<M, T>;
115
+ /** Repository arguments: `where`, `orderBy`, `size`, and `page` and `count` or `after`. */
116
+ args(query: ListQuery<S, F>): [P] extends ["cursor"] ? CursorPageArgs<M, T> : OffsetPageArgs<M, T>;
105
117
  /**
106
118
  * Runs the list against a table, merging your `select`, `include`, `where`
107
119
  * and `count`. One request, plus one for `facetCounts`, always one wave.
108
120
  */
109
- run<const A extends ListExtra<M, T> & FindExt<E, M, T>>(db: { readonly [K in T]: RepositoryOf<M, K, E>; }, query: ListQuery<S, F>, extra?: A): AsyncResult<ListPage<Payload<M, T, A>, F, C>>;
121
+ run<const A extends ListExtra<M, T> & FindExt<E, M, T>>(db: { readonly [K in T]: RepositoryOf<M, K, E>; }, query: ListQuery<S, F>, extra?: A): AsyncResult<ListPage<Payload<M, T, A>, F, C, P>>;
110
122
  /** OpenAPI 3.1 query parameters. */
111
123
  readonly openapi: readonly OpenApiParameter[];
112
124
  /** JSON Schema of the typed input, e.g. for MCP tool arguments. */
@@ -123,6 +135,7 @@ type ListParsers<S extends string, F extends string> = {
123
135
  readonly q: ParserSpec<string>;
124
136
  readonly sort: ParserSpec<S>;
125
137
  readonly page: ParserSpec<number>;
138
+ readonly after: ParserSpec<string>;
126
139
  readonly size: ParserSpec<number>;
127
140
  } & { readonly [K in F]: ParserSpec<readonly string[]>; };
128
141
  /**
@@ -131,7 +144,7 @@ type ListParsers<S extends string, F extends string> = {
131
144
  * OpenAPI parameters and a JSON Schema derived from the same definition.
132
145
  *
133
146
  * ```ts
134
- * export const customerList = defineListQuery(sb, 'customers', {
147
+ * export const customerList = defineListQuery(betterSupabase, 'customers', {
135
148
  * search: ['name', 'kvk'],
136
149
  * facets: { status: 'status' },
137
150
  * sorts: { name: { name: 'asc' }, newest: [{ createdAt: 'desc' }, { id: 'asc' }] },
@@ -139,6 +152,6 @@ type ListParsers<S extends string, F extends string> = {
139
152
  * });
140
153
  * ```
141
154
  */
142
- declare function defineListQuery<M extends AnyModels, D, Fn extends AnyFunctions, E, T extends TableKey<M>, const S extends string, const F extends string = never, const C extends boolean = false>(sb: BetterSupabase<M, D, Fn, E>, table: T, config: ListQueryConfig<M, T, S, F, C>): ListDefinition<M, T, E, S, F, C>;
155
+ declare function defineListQuery<M extends AnyModels, D, Fn extends AnyFunctions, E, T extends TableKey<M>, const S extends string, const F extends string = never, const C extends boolean = false, const P extends ListPagination = "offset">(betterSupabase: BetterSupabase<M, D, Fn, E>, table: T, config: ListQueryConfig<M, T, S, F, C, P>): ListDefinition<M, T, E, S, F, C, P>;
143
156
  //#endregion
144
- export { ListPage as a, ListQuery as c, ListSearchParams as d, OpenApiParameter as f, defineListQuery as h, ListExtra as i, ListQueryConfig as l, UNSET as m, FacetInfo as n, ListParseResult as o, ParserSpec as p, ListDefinition as r, ListParsers as s, FacetCounts as t, ListQueryInput as u };
157
+ export { ListPage as a, ListParsers as c, ListQueryInput as d, ListSearchParams as f, defineListQuery as g, UNSET as h, ListExtra as i, ListQuery as l, ParserSpec as m, FacetInfo as n, ListPagination as o, OpenApiParameter as p, ListDefinition as r, ListParseResult as s, FacetCounts as t, ListQueryConfig as u };
@@ -1,61 +1,59 @@
1
- import { p as DbError } from "./result-CTkCZ6JA.js";
2
- import { Z as QuerySpec } from "./define-e3zI4_4g.js";
3
- import { i as BrowserAuth, t as AuthSnapshot } from "./index-D4v7sncu.js";
1
+ import { p as DbError } from "./result-CqEsbgYs.js";
2
+ import { Z as QuerySpec } from "./define-CRS2MRV3.js";
3
+ import { i as ClientAuth, t as AuthSnapshot } from "./index-RlLXd8dL.js";
4
4
  import { n as TemplateValues } from "./template-mbvlysOo.js";
5
- import { t as AuthSession } from "./view-D1s0wa0T.js";
6
- import { a as LiveSource, g as Topic, h as SubscriptionStatus, p as SubscribeOptions, r as LiveCountSeed, u as EventSchemas, v as TopicHandlers, y as TopicMessage } from "./live-DJyZMD6w.js";
7
- import "./entitlements-Dng-ctuT.js";
8
- import "./session-C3LxnQ0e.js";
5
+ import { t as AuthSession } from "./view-B64o81wp.js";
6
+ import { a as LiveSource, g as Topic, h as SubscriptionStatus, p as SubscribeOptions, r as LiveCountSeed, u as EventSchemas, v as TopicHandlers, y as TopicMessage } from "./live-BHakSWWo.js";
9
7
  import { SupabaseClient } from "@supabase/supabase-js";
10
8
  import { ReactNode } from "react";
11
9
  import { StandardSchemaV1 } from "@standard-schema/spec";
12
10
  import { QueryClient } from "@tanstack/query-core";
13
- //#region src/react/index.d.ts
14
- /** The parts of `createBrowser()` the provider needs. */
15
- interface BrowserLike {
16
- readonly sb: LiveSource;
11
+ //#region src/react/hooks.d.ts
12
+ /** The parts of `createClient()` the provider needs. */
13
+ interface ClientLike {
14
+ readonly betterSupabase: LiveSource;
17
15
  readonly supabase: SupabaseClient;
18
- readonly auth: BrowserAuth;
16
+ readonly auth: ClientAuth;
19
17
  readonly db: object;
20
18
  readonly queries: object;
21
19
  }
22
20
  interface BetterSupabaseProviderProps {
23
- readonly browser: BrowserLike;
21
+ readonly client: ClientLike;
24
22
  /** better-supabase queries are removed when the user signs out or changes. */
25
23
  readonly queryClient?: QueryClient;
26
24
  readonly children?: ReactNode;
27
25
  }
28
- /** Provides the browser client to the hooks. */
26
+ /** Provides the better-supabase client to the hooks. */
29
27
  declare function BetterSupabaseProvider(props: BetterSupabaseProviderProps): ReactNode;
30
28
  /** The session state for UI: `loading`, `signed-out` or `signed-in` with the user and claims. */
31
29
  declare function useAuth(): AuthSnapshot;
32
30
  declare function useSupabase(): SupabaseClient;
33
- interface BetterHooks<B extends BrowserLike> {
31
+ interface BetterHooks<B extends ClientLike> {
34
32
  /** Repositories bound to the current session. Re-renders when the user changes. */
35
33
  readonly useDb: () => B["db"];
36
34
  /** TanStack Query option factories: `useQuery(useQueries().customers.findMany())`. */
37
35
  readonly useQueries: () => B["queries"];
38
36
  readonly useSupabase: () => SupabaseClient;
39
37
  readonly useAuth: () => AuthSnapshot;
40
- /** `useSession()` typed by the browser's `sb.claims(schema)` and `sb.userMetadata(schema)`. */
38
+ /** `useSession()` typed by the client's `betterSupabase.claims(schema)` and `betterSupabase.userMetadata(schema)`. */
41
39
  readonly useSession: () => AuthSession<ClaimsOf<B>, ProfileOf<B>>;
42
40
  }
43
- /** The claims type of a browser's `sb.claims(schema)`, `unknown` without one. */
44
- type ClaimsOf<B extends BrowserLike> = B["sb"] extends {
41
+ /** The claims type of a client's `betterSupabase.claims(schema)`, `unknown` without one. */
42
+ type ClaimsOf<B extends ClientLike> = B["betterSupabase"] extends {
45
43
  readonly claimsSchema: StandardSchemaV1<unknown, infer C> | undefined;
46
44
  } ? C : unknown;
47
- /** The profile type of a browser's `sb.userMetadata(schema)`, `unknown` without one. */
48
- type ProfileOf<B extends BrowserLike> = B["sb"] extends {
45
+ /** The profile type of a client's `betterSupabase.userMetadata(schema)`, `unknown` without one. */
46
+ type ProfileOf<B extends ClientLike> = B["betterSupabase"] extends {
49
47
  readonly userMetadataSchema: StandardSchemaV1<unknown, infer P> | undefined;
50
48
  } ? P : unknown;
51
49
  /**
52
50
  * Hooks typed for your schema.
53
51
  *
54
52
  * ```ts
55
- * export const { useDb, useQueries, useAuth } = createHooks<typeof browser>();
53
+ * export const { useDb, useQueries, useAuth } = createHooks<typeof bs>();
56
54
  * ```
57
55
  */
58
- declare function createHooks<B extends BrowserLike>(): BetterHooks<B>;
56
+ declare function createHooks<B extends ClientLike>(): BetterHooks<B>;
59
57
  interface BroadcastOptions extends Omit<SubscribeOptions, "onStatus"> {
60
58
  /**
61
59
  * Refetch after each message: table keys (every query that read one of
@@ -88,7 +86,7 @@ interface LiveQueryHookOptions {
88
86
  * resubscribes when the spec, tenant or user changes.
89
87
  *
90
88
  * ```ts
91
- * const spec = sb.spec.customers.findMany({ include: { notes: true } });
89
+ * const spec = betterSupabase.spec.customers.findMany({ include: { notes: true } });
92
90
  * const { data } = useQuery(q.$spec(spec));
93
91
  * useLiveQuery(spec);
94
92
  * ```
@@ -108,13 +106,13 @@ interface LiveCount {
108
106
  /**
109
107
  * A count that stays current: refetches only the `count` spec (a HEAD
110
108
  * request) after each debounced change to a table it reads, and after the
111
- * channel rejoins. Takes a spec or a `next.liveCount()` seed; pass `null` to
109
+ * channel rejoins. Takes a spec or a `bs.liveCount()` seed; pass `null` to
112
110
  * pause. Doesn't need a `QueryClient`.
113
111
  *
114
112
  * ```tsx
115
- * const { count } = useLiveCount(seed); // seed = await next.liveCount(spec)
113
+ * const { count } = useLiveCount(seed); // seed = await bs.liveCount(spec)
116
114
  * ```
117
115
  */
118
116
  declare function useLiveCount(source: QuerySpec<string, "count", number> | LiveCountSeed | null | undefined, options?: LiveCountHookOptions): LiveCount;
119
117
  //#endregion
120
- export { BrowserLike as a, LiveCountHookOptions as c, createHooks as d, useAuth as f, useSupabase as g, useLiveQuery as h, BroadcastOptions as i, LiveQueryHookOptions as l, useLiveCount as m, BetterSupabaseProvider as n, ClaimsOf as o, useBroadcast as p, BetterSupabaseProviderProps as r, LiveCount as s, BetterHooks as t, ProfileOf as u };
118
+ export { ClaimsOf as a, LiveCountHookOptions as c, createHooks as d, useAuth as f, useSupabase as g, useLiveQuery as h, BroadcastOptions as i, LiveQueryHookOptions as l, useLiveCount as m, BetterSupabaseProvider as n, ClientLike as o, useBroadcast as p, BetterSupabaseProviderProps as r, LiveCount as s, BetterHooks as t, ProfileOf as u };