better-supabase 0.3.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 (172) hide show
  1. package/README.md +7 -6
  2. package/bin/better-supabase.js +4 -0
  3. package/dist/{base64-CQeB1eSf.js → base64-D2gsioCY.js} +2 -2
  4. package/dist/claims-BAf6c7is.js +48 -0
  5. package/dist/cli/_format-Cax5EsM9.js +101 -0
  6. package/dist/cli/bin.d.ts +1 -0
  7. package/dist/cli/bin.js +48 -0
  8. package/dist/cli/command-CK14fP91.js +502 -0
  9. package/dist/cli/compare-BmIWVEui.js +9 -0
  10. package/dist/cli/config-D9R0o1LH.js +1895 -0
  11. package/dist/cli/config-SSKSTUl2.js +2 -0
  12. package/dist/cli/db-DOBPt660.js +52 -0
  13. package/dist/cli/dist-B1MvLv-M.js +129 -0
  14. package/dist/cli/dist-CFgGknmZ.js +1112 -0
  15. package/dist/cli/dist-Du7VnEUG.js +621 -0
  16. package/dist/cli/doctor-BOym3mbL.js +2382 -0
  17. package/dist/cli/env-BZ0uy8XK.js +108 -0
  18. package/dist/cli/env-jIFUADLY.js +511 -0
  19. package/dist/cli/errors-4v4DTtda.js +56 -0
  20. package/dist/cli/fastest-levenshtein-CFN-lNDv.js +120 -0
  21. package/dist/cli/gen-Ccn_p90L.js +2008 -0
  22. package/dist/cli/gen-D5cLCULx.js +2 -0
  23. package/dist/cli/index.d.ts +493 -0
  24. package/dist/cli/index.js +184 -0
  25. package/dist/cli/init-ClnxRYBF.js +550 -0
  26. package/dist/cli/introspect-DxqfkVIv.js +81 -0
  27. package/dist/cli/io-k41_z-jT.js +24 -0
  28. package/dist/cli/json5-ChRycquj.js +787 -0
  29. package/dist/cli/jsonc-BUniUpOk.js +2 -0
  30. package/dist/cli/jsonc-D5Fu67jw.js +45 -0
  31. package/dist/cli/keys-ByKHnvP9.js +83 -0
  32. package/dist/cli/ohash-D7bG_EOb.js +277 -0
  33. package/dist/cli/openapi-8WHjxiTJ.js +66 -0
  34. package/dist/cli/project-B_GeXyHh.js +70 -0
  35. package/dist/cli/prompts-BNcNfAve.js +1142 -0
  36. package/dist/cli/prompts-BTYQGunc.js +2 -0
  37. package/dist/cli/read-sets-CMa29t9a.js +971 -0
  38. package/dist/cli/rolldown-runtime-BPOCksWG.js +24 -0
  39. package/dist/cli/run-CP20LKk_.js +347 -0
  40. package/dist/cli/seed-5J6eu_Xg.js +98 -0
  41. package/dist/cli/skills-LJJIhLFR.js +137 -0
  42. package/dist/cli/sql-D4VbqmXi.js +199 -0
  43. package/dist/cli/style-C0NFdJRL.js +29 -0
  44. package/dist/cli/toml-DB-MNnFs.js +424 -0
  45. package/dist/cli/version-5mW_8sY1.js +4 -0
  46. package/dist/cli/yaml-CYCbJ6et.js +2252 -0
  47. package/dist/client/index.d.ts +2 -2
  48. package/dist/client/index.js +13 -13
  49. package/dist/{compiler-2zqGzxVZ.d.ts → compiler-DB3aSFOA.d.ts} +2 -2
  50. package/dist/config/index.js +4 -4
  51. package/dist/{config-Be4GwsqI.js → config-BpxDfnbg.js} +1 -1
  52. package/dist/{config-DOsGYSiT.js → config-CbvFmGD8.js} +1 -1
  53. package/dist/{define-DF341GDj.js → define-Bh0AqTik.js} +160 -79
  54. package/dist/{define-DUbydmJa.d.ts → define-CRS2MRV3.d.ts} +32 -28
  55. package/dist/edge/index.d.ts +8 -12
  56. package/dist/edge/index.js +50 -24
  57. package/dist/{entitlements-DvJXoI02.d.ts → entitlements-Dm-FHpNH.d.ts} +2 -2
  58. package/dist/{errors-Bl3rkOzo.js → errors-L0xK41y_.js} +1 -1
  59. package/dist/events/index.d.ts +1 -1
  60. package/dist/events/index.js +4 -4
  61. package/dist/{events-Do8jXh4D.d.ts → events-B21UOhvP.d.ts} +4 -4
  62. package/dist/{executor-DynmIWhq.d.ts → executor-B5IoUxLE.d.ts} +1 -1
  63. package/dist/{executor-C57jx2pn.js → executor-CVt6dD0B.js} +3 -3
  64. package/dist/{executor-B26lgbHD.d.ts → executor-CZ7ImRiD.d.ts} +2 -2
  65. package/dist/hono/index.d.ts +16 -23
  66. package/dist/hono/index.js +10 -10
  67. package/dist/{index-CTTMS6_1.d.ts → index-528Ugmyp.d.ts} +12 -3
  68. package/dist/{index-CADlNHK-.d.ts → index-BAy4tsAP.d.ts} +5 -5
  69. package/dist/{index-BNsABq7P.d.ts → index-BBdvo-5d.d.ts} +23 -25
  70. package/dist/{index-qriRM9cZ.d.ts → index-BhHEC04r.d.ts} +3 -3
  71. package/dist/{index-GV77NpRP.d.ts → index-D5IfUIDh.d.ts} +3 -3
  72. package/dist/{index-CriFFJ_p.d.ts → index-DFmOpBGC.d.ts} +11 -11
  73. package/dist/{index-UJ-LUxtI.d.ts → index-RlLXd8dL.d.ts} +12 -12
  74. package/dist/index.d.ts +15 -15
  75. package/dist/index.js +13 -13
  76. package/dist/{invalidate-DbxuL2jL.js → invalidate-CgxmRamI.js} +7 -1
  77. package/dist/jobs/index.d.ts +10 -4
  78. package/dist/jobs/index.js +32 -16
  79. package/dist/{json-schema--aOXAGfU.js → json-schema-DP6V7cbr.js} +1 -1
  80. package/dist/list/index.d.ts +1 -1
  81. package/dist/list/index.js +3 -3
  82. package/dist/{live-QE3UPbGm.d.ts → live-BHakSWWo.d.ts} +12 -12
  83. package/dist/{live-D8rV1Ldw.js → live-CdJBOc4f.js} +13 -9
  84. package/dist/lookup-BaP5bI27.js +18 -0
  85. package/dist/mcp/index.d.ts +18 -18
  86. package/dist/mcp/index.js +23 -18
  87. package/dist/{mfa-x3V3vGh-.d.ts → mfa-C7MNQ1Ob.d.ts} +1 -1
  88. package/dist/{mfa-BxoR1RkN.js → mfa-byfjruR9.js} +118 -29
  89. package/dist/next/image/index.js +6 -3
  90. package/dist/next/index.d.ts +38 -35
  91. package/dist/next/index.js +41 -33
  92. package/dist/openapi/index.d.ts +1 -1
  93. package/dist/openapi/index.js +6 -6
  94. package/dist/orpc/index.d.ts +17 -20
  95. package/dist/orpc/index.js +11 -11
  96. package/dist/otel/index.d.ts +5 -5
  97. package/dist/otel/index.js +81 -62
  98. package/dist/{permdock-sql-Bta_G0v-.js → permdock-sql-C4KFzLc9.js} +1 -1
  99. package/dist/{plugin-DVRB8qNE.d.ts → plugin-bNhvJwRh.d.ts} +2 -2
  100. package/dist/plugins/actor/index.d.ts +1 -1
  101. package/dist/plugins/actor/index.js +1 -1
  102. package/dist/plugins/rules/index.d.ts +2 -2
  103. package/dist/plugins/rules/index.js +42 -12
  104. package/dist/plugins/soft-delete/index.d.ts +2 -2
  105. package/dist/plugins/soft-delete/index.js +2 -2
  106. package/dist/plugins/tenant/index.d.ts +2 -2
  107. package/dist/plugins/tenant/index.js +10 -4
  108. package/dist/plugins/timestamps/index.d.ts +1 -1
  109. package/dist/plugins/timestamps/index.js +1 -1
  110. package/dist/plugins/validation/index.d.ts +2 -2
  111. package/dist/plugins/validation/index.js +3 -3
  112. package/dist/{pool-B9qsLyFR.d.ts → pool-DFwEQwmN.d.ts} +11 -4
  113. package/dist/postgres/index.d.ts +5 -5
  114. package/dist/postgres/index.js +3 -2
  115. package/dist/{postgrest-DmBlevh-.d.ts → postgrest-Bc-0Xw62.d.ts} +1 -1
  116. package/dist/{problem-CGt1ADix.js → problem-BihjPR0t.js} +1 -1
  117. package/dist/{problem-Z2RTQjZD.d.ts → problem-U8UEKccv.d.ts} +1 -1
  118. package/dist/query/index.d.ts +2 -2
  119. package/dist/query/index.js +2 -2
  120. package/dist/{query-BdKLTPlj.js → query-BMMSWbI7.js} +18 -18
  121. package/dist/react/index.d.ts +6 -6
  122. package/dist/react/index.js +1 -1
  123. package/dist/react/server.d.ts +5 -5
  124. package/dist/react/server.js +3 -3
  125. package/dist/react/session.d.ts +4 -4
  126. package/dist/react/session.js +2 -2
  127. package/dist/{react-DNBYNazu.js → react-CQHMaESR.js} +39 -39
  128. package/dist/{read-set-D0qBcboM.js → read-set-FWK8qQ58.js} +50 -15
  129. package/dist/realtime/index.d.ts +1 -1
  130. package/dist/realtime/index.js +13 -12
  131. package/dist/{index-kpgopLNv.d.ts → refresh-BwYkyNOQ.d.ts} +6 -3
  132. package/dist/{resolve-BRciX2jK.d.ts → resolve-BAqQcwMW.d.ts} +15 -10
  133. package/dist/{resource-CwVgiI5q.d.ts → resource-BJcaIfxi.d.ts} +5 -5
  134. package/dist/{resource-D30rp0GN.js → resource-My_y-Syh.js} +6 -6
  135. package/dist/{respond-DAkPIdTH.d.ts → respond-DgIbdrt8.d.ts} +31 -12
  136. package/dist/{result-DWXatkd6.js → result-Bj6yt33D.js} +2 -2
  137. package/dist/{result-c2OYgCV2.d.ts → result-CqEsbgYs.d.ts} +3 -3
  138. package/dist/server/index.d.ts +14 -14
  139. package/dist/server/index.js +12 -12
  140. package/dist/{respond-C44EZAJo.js → server-BA75B0mT.js} +139 -100
  141. package/dist/{shared-_6-uPL7E.js → shared-DnoCdMDr.js} +4 -3
  142. package/dist/{simplify-LakqK1vH.js → simplify-Cqvfr9dj.js} +67 -24
  143. package/dist/sql/index.d.ts +1 -1
  144. package/dist/sql/index.js +7 -7
  145. package/dist/{sql-BIgk12ew.js → sql-B34HU2DI.js} +3 -2
  146. package/dist/ssr/index.d.ts +4 -4
  147. package/dist/ssr/index.js +2 -2
  148. package/dist/{standard-FUi3Z3-7.js → standard-BRyBGTtp.js} +2 -2
  149. package/dist/{standard-eudBiRk1.d.ts → standard-BsaCYQJc.d.ts} +1 -1
  150. package/dist/{stats-D78UQ8Yu.js → stats-C_YxA2r1.js} +33 -8
  151. package/dist/storage/index.d.ts +2 -2
  152. package/dist/storage/index.js +26 -8
  153. package/dist/{tables-Dhha3BXM.js → tables-Cb-3_VWc.js} +14 -0
  154. package/dist/{temporal-required-CMxeSVPo.js → temporal-required-CBNHT6ni.js} +1 -1
  155. package/dist/testing/index.d.ts +20 -21
  156. package/dist/testing/index.js +45 -45
  157. package/dist/{version-BfpG2gks.js → version-Bmf7_FzM.js} +1 -1
  158. package/dist/{view-3Po_PVlr.d.ts → view-B64o81wp.d.ts} +5 -5
  159. package/dist/{view-wZ-9qIUz.js → view-BrJI2LKp.js} +1 -1
  160. package/dist/webhooks/index.d.ts +3 -3
  161. package/dist/webhooks/index.js +1 -1
  162. package/dist/{webhooks-CAIFQSTM.js → webhooks-Bh_Jf_-l.js} +37 -18
  163. package/package.json +36 -4
  164. package/skills/better-supabase/SKILL.md +57 -10
  165. package/skills/better-supabase/references/plugins.md +7 -11
  166. package/skills/better-supabase/references/troubleshooting.md +24 -4
  167. package/skills/better-supabase-api/SKILL.md +66 -18
  168. package/skills/better-supabase-api/references/adapters.md +44 -26
  169. package/skills/better-supabase-auth/SKILL.md +146 -0
  170. package/skills/better-supabase-auth/references/permdock.md +55 -0
  171. package/skills/better-supabase-testing/SKILL.md +58 -4
  172. package/dist/claims-CoTobNC-.js +0 -25
@@ -1,9 +1,9 @@
1
- import { n as dbError } from "../errors-Bl3rkOzo.js";
2
- import { i as ok, n as err, t as AsyncResult } from "../result-DWXatkd6.js";
3
- import { i as tenantClaimPaths } from "../claims-CoTobNC-.js";
4
- import { n as liveQuery, r as liveTopic, t as liveCount } from "../live-D8rV1Ldw.js";
5
- import { s as toApp } from "../shared-_6-uPL7E.js";
6
- import { a as sqlIdent, i as slug, o as sqlString, r as parseTemplate, t as permdockCheck } from "../permdock-sql-Bta_G0v-.js";
1
+ import { n as dbError } from "../errors-L0xK41y_.js";
2
+ import { i as ok, n as err, t as AsyncResult } from "../result-Bj6yt33D.js";
3
+ import { i as tenantClaimPaths } from "../claims-BAf6c7is.js";
4
+ import { n as liveQuery, r as liveTopic, t as liveCount } from "../live-CdJBOc4f.js";
5
+ import { s as toApp } from "../shared-DnoCdMDr.js";
6
+ import { a as sqlIdent, i as slug, o as sqlString, r as parseTemplate, t as permdockCheck } from "../permdock-sql-C4KFzLc9.js";
7
7
  import { REALTIME_SUBSCRIBE_STATES } from "@supabase/supabase-js";
8
8
  //#region src/realtime/topic.ts
9
9
  const VALUE = /^[\w.@+=-]+$/;
@@ -119,8 +119,8 @@ function defineTopic(template, options = {}) {
119
119
  }
120
120
  return `${lines.join("\n")}\n`;
121
121
  },
122
- triggerSql(sb, table, trigger) {
123
- const meta = sb.meta.tables[table];
122
+ triggerSql(betterSupabase, table, trigger) {
123
+ const meta = betterSupabase.meta.tables[table];
124
124
  if (!meta) throw new TypeError(`defineTopic: unknown table "${table}"`);
125
125
  const values = trigger.values;
126
126
  const parts = template.split(/(\{[^}]+\})/).filter(Boolean).map((part) => {
@@ -236,13 +236,14 @@ function defineTopic(template, options = {}) {
236
236
  const topic = topicOf(values);
237
237
  const checked = await validate(schemas[event], payload);
238
238
  if (!checked.ok) return err(dbError("validation", `Invalid payload for ${event}`, { issues: checked.issues }));
239
- if (isPrivate) await client.realtime.setAuth();
239
+ const open = client.getChannels().some((existing) => existing.topic === `realtime:${topic}`);
240
+ if (isPrivate && !open) await client.realtime.setAuth();
240
241
  const channel = client.channel(topic, { config: { private: isPrivate } });
241
242
  try {
242
243
  const response = await channel.httpSend(event, checked.value);
243
244
  return response.success ? ok(void 0) : err(sendError(response.status, response.error));
244
245
  } finally {
245
- await client.removeChannel(channel);
246
+ if (!open) await client.removeChannel(channel);
246
247
  }
247
248
  });
248
249
  }
@@ -252,8 +253,8 @@ function defineTopic(template, options = {}) {
252
253
  * Reads a `realtime.broadcast_changes` message as an app-cased row change.
253
254
  * Returns `null` for messages about other tables.
254
255
  */
255
- function rowChange(sb, table, message) {
256
- const meta = sb.meta.tables[table];
256
+ function rowChange(betterSupabase, table, message) {
257
+ const meta = betterSupabase.meta.tables[table];
257
258
  const payload = message.payload;
258
259
  if (!meta || !payload || payload.table !== meta.name || payload.schema && payload.schema !== meta.schema) return null;
259
260
  const operation = payload.operation ?? message.event;
@@ -1,6 +1,4 @@
1
- import { m as StoredSession } from "./resolve-BRciX2jK.js";
2
- import "./view-3Po_PVlr.js";
3
- import "./entitlements-DvJXoI02.js";
1
+ import { m as StoredSession } from "./resolve-BAqQcwMW.js";
4
2
  //#region src/auth/refresh.d.ts
5
3
  interface RefreshOptions {
6
4
  readonly url: string;
@@ -14,6 +12,11 @@ interface RefreshOptions {
14
12
  readonly secretKey: string;
15
13
  };
16
14
  readonly fetch?: typeof fetch;
15
+ /**
16
+ * Milliseconds before a refresh counts as a network failure (the session is
17
+ * kept). 5000 by default.
18
+ */
19
+ readonly timeoutMs?: number;
17
20
  /** Epoch milliseconds, the unit JWT `exp` and `iat` math needs. */
18
21
  readonly now?: () => number;
19
22
  }
@@ -1,7 +1,7 @@
1
- import { p as DbError } from "./result-c2OYgCV2.js";
2
- import { f as Logger, l as RefreshEvent } from "./events-Do8jXh4D.js";
3
- import { h as RequestContext } from "./plugin-DVRB8qNE.js";
4
- import { t as StandardSchemaV1 } from "./standard-eudBiRk1.js";
1
+ import { p as DbError } from "./result-CqEsbgYs.js";
2
+ import { f as Logger, l as RefreshEvent } from "./events-B21UOhvP.js";
3
+ import { h as RequestContext } from "./plugin-bNhvJwRh.js";
4
+ import { t as StandardSchemaV1 } from "./standard-BsaCYQJc.js";
5
5
  import { t as BetterSupabaseEnv } from "./index-Dy6kuF0P.js";
6
6
  import { CookieOptions } from "@supabase/ssr";
7
7
  import { JWTClaims, SupabaseEnv, UserClaims } from "@supabase/server";
@@ -46,9 +46,9 @@ declare function applyCookieWrites(cookies: readonly CookieRecord[], writes: rea
46
46
  //#endregion
47
47
  //#region src/auth/resolve.d.ts
48
48
  /**
49
- * Who is calling. `C` is the claims type from `sb.claims(schema)`; the
49
+ * Who is calling. `C` is the claims type from `betterSupabase.claims(schema)`; the
50
50
  * verified payload keeps every JWT claim and adds the schema's output. `P`
51
- * is the `user_metadata` type from `sb.userMetadata(schema)`.
51
+ * is the `user_metadata` type from `betterSupabase.userMetadata(schema)`.
52
52
  */
53
53
  type AuthState<C = unknown, P = unknown> = {
54
54
  readonly kind: "user";
@@ -59,7 +59,7 @@ type AuthState<C = unknown, P = unknown> = {
59
59
  /** Seconds since epoch, from the token's `exp`. */
60
60
  readonly expiresAt: number | null;
61
61
  /**
62
- * `user_metadata` parsed by `sb.userMetadata(schema)`; `undefined`
62
+ * `user_metadata` parsed by `betterSupabase.userMetadata(schema)`; `undefined`
63
63
  * without a schema or when the metadata fails it. Users can write this
64
64
  * data themselves: use it for display, never for access.
65
65
  */
@@ -101,8 +101,13 @@ interface ResolveAuthOptions {
101
101
  readonly env: BetterSupabaseEnv;
102
102
  /** Allow refreshing an expiring cookie session. Only where cookies can be written (proxy). */
103
103
  readonly refresh?: boolean;
104
- /** Refresh when the token expires within this many seconds. Defaults to 60. */
104
+ /**
105
+ * With `refresh`, refresh when the token expires within this many seconds.
106
+ * Defaults to 60. Without `refresh` a token stays valid until its `exp`.
107
+ */
105
108
  readonly leeway?: number;
109
+ /** Milliseconds before a refresh counts as a network failure. Defaults to 5000. */
110
+ readonly refreshTimeoutMs?: number;
106
111
  /**
107
112
  * Accept `sb_secret_` keys (`apikey` header) as service callers: `true` for
108
113
  * any configured key, or the key names allowed (`['cron']`). Defaults to false.
@@ -117,12 +122,12 @@ interface ResolveAuthOptions {
117
122
  /** Inline JWKS instead of fetching `env.jwksUrl` (tests, air-gapped). */
118
123
  readonly jwks?: SupabaseEnv["jwks"];
119
124
  /**
120
- * Validates the verified claims (`sb.claims(schema)` sets it). A failure
125
+ * Validates the verified claims (`betterSupabase.claims(schema)` sets it). A failure
121
126
  * resolves to `{ kind: 'invalid', reason: 'claims' }`.
122
127
  */
123
128
  readonly claims?: StandardSchemaV1;
124
129
  /**
125
- * Parses `user_metadata` into `profile` (`sb.userMetadata(schema)` sets
130
+ * Parses `user_metadata` into `profile` (`betterSupabase.userMetadata(schema)` sets
126
131
  * it). A failure leaves `profile` undefined and warns once; the session
127
132
  * stays valid.
128
133
  */
@@ -1,8 +1,8 @@
1
1
  import { N as TableKey, P as TableMeta, R as Update, g as Insert, n as AnyModels, t as AnyFunctions } from "./types-DONv9SHN.js";
2
- import { b as ValidationIssue, o as Result } from "./result-c2OYgCV2.js";
3
- import { t as BetterSupabase, xt as SelectArg } from "./define-DUbydmJa.js";
4
- import { r as RespondOptions } from "./respond-DAkPIdTH.js";
5
- import { i as ResourceOperation } from "./index-qriRM9cZ.js";
2
+ import { b as ValidationIssue, o as Result } from "./result-CqEsbgYs.js";
3
+ import { t as BetterSupabase, xt as SelectArg } from "./define-CRS2MRV3.js";
4
+ import { i as RespondOptions } from "./respond-DgIbdrt8.js";
5
+ import { i as ResourceOperation } from "./index-BhHEC04r.js";
6
6
  import { StandardSchemaV1 } from "@standard-schema/spec";
7
7
  //#region src/server/resource.d.ts
8
8
  /** What a resource needs from `defineListQuery`. */
@@ -69,6 +69,6 @@ interface ResourceHandler {
69
69
  * `createOpenApi`: `GET/POST /<table>` and `GET/PATCH/DELETE /<table>/{id}`.
70
70
  * Shared by the HTTP adapters and the MCP table tools.
71
71
  */
72
- declare function defineResource<M extends AnyModels, D, F extends AnyFunctions, E, T extends TableKey<M>>(sb: BetterSupabase<M, D, F, E>, table: T, options?: ResourceRouteOptions<M, T>): ResourceHandler;
72
+ declare function defineResource<M extends AnyModels, D, F extends AnyFunctions, E, T extends TableKey<M>>(betterSupabase: BetterSupabase<M, D, F, E>, table: T, options?: ResourceRouteOptions<M, T>): ResourceHandler;
73
73
  //#endregion
74
74
  export { ResourceRouteOptions as a, ResourcePagination as i, ResourceInput as n, defineResource as o, ResourceList as r, ResourceHandler as t };
@@ -1,7 +1,7 @@
1
- import { n as dbError } from "./errors-Bl3rkOzo.js";
2
- import { i as ok, n as err } from "./result-DWXatkd6.js";
3
- import { t as validate } from "./standard-FUi3Z3-7.js";
4
- import { i as respond } from "./respond-C44EZAJo.js";
1
+ import { n as dbError } from "./errors-L0xK41y_.js";
2
+ import { i as ok, n as err } from "./result-Bj6yt33D.js";
3
+ import { t as validate } from "./standard-BRyBGTtp.js";
4
+ import { s as respond } from "./server-BA75B0mT.js";
5
5
  //#region src/server/resource.ts
6
6
  const INTEGER = /* @__PURE__ */ new Set([
7
7
  "int2",
@@ -82,8 +82,8 @@ function notAllowed(allowed) {
82
82
  * `createOpenApi`: `GET/POST /<table>` and `GET/PATCH/DELETE /<table>/{id}`.
83
83
  * Shared by the HTTP adapters and the MCP table tools.
84
84
  */
85
- function defineResource(sb, table, options = {}) {
86
- const meta = sb.meta.tables[table];
85
+ function defineResource(betterSupabase, table, options = {}) {
86
+ const meta = betterSupabase.meta.tables[table];
87
87
  if (!meta) throw new TypeError(`Unknown table "${table}"`);
88
88
  if (options.list && options.list.table !== table) throw new TypeError(`The list query is for "${options.list.table}", not "${table}"`);
89
89
  const operations = options.operations ?? (meta.kind === "view" ? ["list", "get"] : [
@@ -1,12 +1,12 @@
1
1
  import { n as AnyModels, t as AnyFunctions } from "./types-DONv9SHN.js";
2
- import { p as DbError, t as AsyncResult } from "./result-c2OYgCV2.js";
3
- import { I as StatsRecorder, P as DbStats, t as BetterSupabase, y as Db } from "./define-DUbydmJa.js";
4
- import { h as RequestContext } from "./plugin-DVRB8qNE.js";
2
+ import { p as DbError, t as AsyncResult } from "./result-CqEsbgYs.js";
3
+ import { I as StatsRecorder, P as DbStats, t as BetterSupabase, y as Db } from "./define-CRS2MRV3.js";
4
+ import { h as RequestContext } from "./plugin-bNhvJwRh.js";
5
5
  import { t as BetterSupabaseEnv } from "./index-Dy6kuF0P.js";
6
- import { o as SqlClaims, r as Postgres } from "./pool-B9qsLyFR.js";
7
- import { o as ImpersonationOptions, t as Aal } from "./mfa-x3V3vGh-.js";
8
- import { a as ResolveAuthOptions, r as AuthState, t as AuthResolution } from "./resolve-BRciX2jK.js";
9
- import { n as Bucket } from "./index-CTTMS6_1.js";
6
+ import { o as SqlClaims, t as BetterPostgres } from "./pool-DFwEQwmN.js";
7
+ import { o as ImpersonationOptions, t as Aal } from "./mfa-C7MNQ1Ob.js";
8
+ import { a as ResolveAuthOptions, r as AuthState, t as AuthResolution } from "./resolve-BAqQcwMW.js";
9
+ import { n as Bucket } from "./index-528Ugmyp.js";
10
10
  import { SupabaseClient } from "@supabase/supabase-js";
11
11
  //#region src/server/delete-account.d.ts
12
12
  interface DeleteAccountOptions {
@@ -40,7 +40,7 @@ interface ReplicaState {
40
40
  readonly pinned: boolean;
41
41
  /** This context wrote through its repositories (or called `pin()`). */
42
42
  readonly wrote: boolean;
43
- /** Sends later reads to the primary, e.g. after a write through `$client` or `$sql`. */
43
+ /** Sends later reads to the primary, e.g. after a write through `$client` or `ctx.sql`. */
44
44
  pin(): void;
45
45
  }
46
46
  //#endregion
@@ -49,8 +49,14 @@ interface ServerOptions {
49
49
  /** Defaults to `loadEnv()`. */
50
50
  readonly env?: BetterSupabaseEnv;
51
51
  /** Enables `ctx.sql` and `actingAs()`. */
52
- readonly postgres?: Postgres;
52
+ readonly postgres?: BetterPostgres;
53
53
  readonly auth?: Omit<ResolveAuthOptions, "env">;
54
+ /**
55
+ * Fetch the JWKS when the server is created, so the first request verifies
56
+ * its token without waiting for it. Applies when `env.jwksUrl` is set and
57
+ * `auth.jwks` is not. Defaults to true, except under `NODE_ENV=test`.
58
+ */
59
+ readonly prefetchJwks?: boolean;
54
60
  /**
55
61
  * Extra headers on the caller's PostgREST requests, readable in Postgres as
56
62
  * `current_setting('request.headers')` (channel, request id, client IP for audit).
@@ -98,6 +104,11 @@ interface BetterServer<M extends AnyModels, F extends AnyFunctions, E, C = unkno
98
104
  * cookie session only with `refresh: true`; send `ctx.resolution.apply(response)`.
99
105
  */
100
106
  context(request: Request, options?: ContextOptions): Promise<ServerContext<M, F, E, C, P>>;
107
+ /**
108
+ * The context for a resolution from `resolve(request)`, so one resolution
109
+ * can back several contexts without verifying the token again.
110
+ */
111
+ contextFromResolution(resolution: AuthResolution<C, P>, request: Request, options?: Omit<ContextOptions, "refresh">): ServerContext<M, F, E, C, P>;
101
112
  /** The context for an auth state resolved elsewhere (the proxy, a queue message). */
102
113
  contextFor(auth: AuthState<C, P>, options?: ContextOptions): ServerContext<M, F, E, C, P>;
103
114
  /** A stateless supabase-js client for an auth state, optionally with extra request headers. */
@@ -121,9 +132,9 @@ interface BetterServer<M extends AnyModels, F extends AnyFunctions, E, C = unkno
121
132
  }
122
133
  /**
123
134
  * Server-side entry point for APIs, jobs, MCP servers and framework
124
- * adapters. Holds the secrets; `sb` stays isomorphic.
135
+ * adapters. Holds the secrets; `betterSupabase` stays isomorphic.
125
136
  */
126
- declare function createServer<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(sb: BetterSupabase<M, D, F, E, C, P>, options?: ServerOptions): BetterServer<M, F, E, C, P>;
137
+ declare function createServer<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: ServerOptions): BetterServer<M, F, E, C, P>;
127
138
  //#endregion
128
139
  //#region src/server/respond.d.ts
129
140
  type AuthKind = AuthState["kind"];
@@ -142,6 +153,14 @@ interface GuardOptions {
142
153
  */
143
154
  readonly scopes?: readonly string[];
144
155
  }
156
+ /** Guard options for middleware and fetch handlers that resolve the caller themselves. */
157
+ interface MiddlewareOptions extends GuardOptions {
158
+ /**
159
+ * Refresh an expired cookie session and send the new cookies. Only for
160
+ * routes browsers call with cookies; bearer tokens never refresh.
161
+ */
162
+ readonly refresh?: boolean;
163
+ }
145
164
  /** `undefined` when `auth` may pass; otherwise the 401/403 error to send. */
146
165
  declare function guard(auth: AuthState, allow?: GuardOptions["allow"], aal?: Aal, scopes?: readonly string[]): DbError | undefined;
147
166
  declare function isResult(value: unknown): value is {
@@ -172,4 +191,4 @@ interface RespondOptions {
172
191
  /** A handler's value as a response: `Response` as is, data as JSON, errors as Problem Details. */
173
192
  declare function respond(run: () => unknown, options?: RespondOptions): Promise<Response>;
174
193
  //#endregion
175
- export { DeleteAccountResult as _, guard as a, settle as c, ServerContext as d, ServerOptions as f, DeleteAccountOptions as g, ReplicaState as h, Settled as i, BetterServer as l, PRIMARY_COOKIE as m, GuardOptions as n, isResult as o, createServer as p, RespondOptions as r, respond as s, AuthKind as t, ContextOptions as u };
194
+ export { DeleteAccountOptions as _, Settled as a, respond as c, ContextOptions as d, ServerContext as f, ReplicaState as g, PRIMARY_COOKIE as h, RespondOptions as i, settle as l, createServer as m, GuardOptions as n, guard as o, ServerOptions as p, MiddlewareOptions as r, isResult as s, AuthKind as t, BetterServer as u, DeleteAccountResult as v };
@@ -1,4 +1,4 @@
1
- import { n as dbError, r as dbErrorOf, t as DbException } from "./errors-Bl3rkOzo.js";
1
+ import { n as dbError, r as dbErrorOf, t as DbException } from "./errors-L0xK41y_.js";
2
2
  //#region src/core/result.ts
3
3
  const throwMappers = /* @__PURE__ */ new WeakMap();
4
4
  function inherit(from, next) {
@@ -49,7 +49,7 @@ var AsyncResult = class AsyncResult {
49
49
  /**
50
50
  * Resolves with the data, or rejects with a `DbException`. Pass `factory`
51
51
  * to throw your own error instead, e.g. an HTTP error for your framework;
52
- * without it, the mapper from `sb.mapError()` applies when one is set.
52
+ * without it, the mapper from `betterSupabase.mapError()` applies when one is set.
53
53
  */
54
54
  async orThrow(factory) {
55
55
  const result = await this.#promise;
@@ -124,7 +124,7 @@ type ErrorMapper = (raw: RawDbError, fallback: DbError) => DbError | undefined;
124
124
  declare function mapDbError(raw: RawDbError, mappers?: readonly ErrorMapper[]): DbError;
125
125
  //#endregion
126
126
  //#region src/core/result.d.ts
127
- /** Turns a `DbError` into the error `.orThrow()` throws; set with `sb.mapError()`. */
127
+ /** Turns a `DbError` into the error `.orThrow()` throws; set with `betterSupabase.mapError()`. */
128
128
  type ThrowMapper = (error: DbError) => unknown;
129
129
  type Ok<T> = {
130
130
  readonly ok: true;
@@ -153,7 +153,7 @@ declare class AsyncResult<T> implements PromiseLike<Result<T>> {
153
153
  /**
154
154
  * Resolves with the data, or rejects with a `DbException`. Pass `factory`
155
155
  * to throw your own error instead, e.g. an HTTP error for your framework;
156
- * without it, the mapper from `sb.mapError()` applies when one is set.
156
+ * without it, the mapper from `betterSupabase.mapError()` applies when one is set.
157
157
  */
158
158
  orThrow(factory?: (error: DbError) => unknown): Promise<T>;
159
159
  /** Resolves with the data, or `fallback` when the result is an error. */
@@ -178,7 +178,7 @@ interface BetterResultApi<T, E> {
178
178
  /**
179
179
  * Builds a better-result value with the `Result` namespace you pass, so
180
180
  * better-result stays your dependency. Errors go through `mapError`, or, for a
181
- * result from a `db` of `sb.mapError(fn)`, through `fn` (typed `unknown`).
181
+ * result from a `db` of `betterSupabase.mapError(fn)`, through `fn` (typed `unknown`).
182
182
  * The value is a real `Ok`/`Err`: cast it (`as Result<T, E>`) for its
183
183
  * methods in types; the cast itself is not checked against `T`.
184
184
  *
@@ -1,14 +1,14 @@
1
1
  import { n as AnyModels, t as AnyFunctions } from "../types-DONv9SHN.js";
2
- import { p as DbError } from "../result-c2OYgCV2.js";
3
- import { t as BetterSupabase, y as Db } from "../define-DUbydmJa.js";
4
- import { h as RequestContext } from "../plugin-DVRB8qNE.js";
5
- import { a as checkAal, c as impersonatorOf, i as amrOf, n as AmrEntry, o as ImpersonationOptions, r as aalOf, s as Impersonator, t as Aal } from "../mfa-x3V3vGh-.js";
6
- import { _ as readSession, a as ResolveAuthOptions, b as writeSession, c as clientIp, d as CookieOptions, f as CookieRecord, i as InvalidReason, l as resolveAuth, m as StoredSession, n as AuthResolver, o as ResolvedState, p as CookieWrite, r as AuthState, s as authContext, t as AuthResolution, u as AUTH_CACHE_HEADERS, y as sessionCookieName } from "../resolve-BRciX2jK.js";
7
- import { _ as DeleteAccountResult, a as guard, c as settle, d as ServerContext, f as ServerOptions, g as DeleteAccountOptions, h as ReplicaState, i as Settled, l as BetterServer, m as PRIMARY_COOKIE, n as GuardOptions, o as isResult, p as createServer, r as RespondOptions, s as respond, t as AuthKind, u as ContextOptions } from "../respond-DAkPIdTH.js";
8
- import { a as ResourceRouteOptions, i as ResourcePagination, n as ResourceInput, o as defineResource, r as ResourceList, t as ResourceHandler } from "../resource-CwVgiI5q.js";
9
- import { a as ProblemResponseOptions, c as problemResponse, i as ProblemOptions, l as toProblem, n as PROBLEM_TYPE_BASE, o as fromProblem, r as ProblemDetails, s as isProblem, t as PROBLEM_CONTENT_TYPE } from "../problem-Z2RTQjZD.js";
10
- import { a as SessionDelegation, i as SessionActor, n as toSession, r as ActClaim, t as AuthSession } from "../view-3Po_PVlr.js";
11
- import { n as RefreshOutcome, r as refreshSession } from "../index-kpgopLNv.js";
2
+ import { p as DbError } from "../result-CqEsbgYs.js";
3
+ import { t as BetterSupabase, y as Db } from "../define-CRS2MRV3.js";
4
+ import { h as RequestContext } from "../plugin-bNhvJwRh.js";
5
+ import { a as checkAal, c as impersonatorOf, i as amrOf, n as AmrEntry, o as ImpersonationOptions, r as aalOf, s as Impersonator, t as Aal } from "../mfa-C7MNQ1Ob.js";
6
+ import { _ as readSession, a as ResolveAuthOptions, b as writeSession, c as clientIp, d as CookieOptions, f as CookieRecord, i as InvalidReason, l as resolveAuth, m as StoredSession, n as AuthResolver, o as ResolvedState, p as CookieWrite, r as AuthState, s as authContext, t as AuthResolution, u as AUTH_CACHE_HEADERS, y as sessionCookieName } from "../resolve-BAqQcwMW.js";
7
+ import { _ as DeleteAccountOptions, a as Settled, c as respond, d as ContextOptions, f as ServerContext, g as ReplicaState, h as PRIMARY_COOKIE, i as RespondOptions, l as settle, m as createServer, n as GuardOptions, o as guard, p as ServerOptions, r as MiddlewareOptions, s as isResult, t as AuthKind, u as BetterServer, v as DeleteAccountResult } from "../respond-DgIbdrt8.js";
8
+ import { a as ResourceRouteOptions, i as ResourcePagination, n as ResourceInput, o as defineResource, r as ResourceList, t as ResourceHandler } from "../resource-BJcaIfxi.js";
9
+ import { a as ProblemResponseOptions, c as problemResponse, i as ProblemOptions, l as toProblem, n as PROBLEM_TYPE_BASE, o as fromProblem, r as ProblemDetails, s as isProblem, t as PROBLEM_CONTENT_TYPE } from "../problem-U8UEKccv.js";
10
+ import { a as SessionDelegation, i as SessionActor, n as toSession, r as ActClaim, t as AuthSession } from "../view-B64o81wp.js";
11
+ import { n as RefreshOutcome, r as refreshSession } from "../refresh-BwYkyNOQ.js";
12
12
  import { SupabaseClient } from "@supabase/supabase-js";
13
13
  import { Middleware } from "@supabase/middleware";
14
14
  import { AuthMode, JWTClaims, UserClaims } from "@supabase/server";
@@ -27,17 +27,17 @@ export declare function contextFromSupabase(ctx: SupabaseAuthContext): RequestCo
27
27
  * `ctx.supabase` (the caller-scoped client from `withSupabase`).
28
28
  *
29
29
  * ```ts
30
- * pipeline([withSupabase({ auth: 'user' }), withBetterSupabase(sb)()], (req, ctx) => ...)
30
+ * pipeline([withSupabase({ auth: 'user' }), withBetterSupabase(betterSupabase)()], (req, ctx) => ...)
31
31
  * ```
32
32
  */
33
- export declare function withBetterSupabase<M extends AnyModels, D, F extends AnyFunctions, E>(sb: BetterSupabase<M, D, F, E>): Middleware<"db", void, SupabaseAuthContext & {
33
+ export declare function withBetterSupabase<M extends AnyModels, D, F extends AnyFunctions, E>(betterSupabase: BetterSupabase<M, D, F, E>): Middleware<"db", void, SupabaseAuthContext & {
34
34
  readonly supabase: SupabaseClient;
35
35
  }, Db<M, F, E, SupabaseClient>>;
36
36
  /**
37
37
  * Entry contributing `ctx.sql`: repositories over `ctx.postgres` from
38
38
  * `withPostgresClient`, which runs each query as the caller with RLS.
39
39
  */
40
- export declare function withBetterPostgres<M extends AnyModels, D, F extends AnyFunctions, E>(sb: BetterSupabase<M, D, F, E>): Middleware<"sql", void, SupabaseAuthContext & {
40
+ export declare function withBetterPostgres<M extends AnyModels, D, F extends AnyFunctions, E>(betterSupabase: BetterSupabase<M, D, F, E>): Middleware<"sql", void, SupabaseAuthContext & {
41
41
  readonly postgres: PostgresApi;
42
42
  }, Db<M, F, E, undefined>>;
43
43
  //#endregion
@@ -64,4 +64,4 @@ export declare function checkSession(sql: SessionLookup, auth: {
64
64
  readonly kind: string;
65
65
  }): Promise<DbError | undefined>;
66
66
  //#endregion
67
- export { AUTH_CACHE_HEADERS, type Aal, type ActClaim, type AmrEntry, type AuthKind, type AuthResolution, type AuthResolver, type AuthSession, type AuthState, type BetterServer, type ContextOptions, type CookieOptions, type CookieRecord, type CookieWrite, type DeleteAccountOptions, type DeleteAccountResult, type GuardOptions, type ImpersonationOptions, type Impersonator, type InvalidReason, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, type ProblemDetails, type ProblemOptions, type ProblemResponseOptions, type RefreshOutcome, type ReplicaState, type ResolveAuthOptions, type ResolvedState, type ResourceHandler, type ResourceInput, type ResourceList, type ResourcePagination, type ResourceRouteOptions, type RespondOptions, type ServerContext, type ServerOptions, type SessionActor, type SessionDelegation, type SessionLookup, type Settled, type StoredSession, type SupabaseAuthContext, aalOf, amrOf, authContext, checkAal, clientIp, createServer, defineResource, fromProblem, guard, impersonatorOf, isProblem, isResult, problemResponse, readSession, refreshSession, resolveAuth, respond, sessionCookieName, settle, toProblem, toSession, writeSession };
67
+ export { AUTH_CACHE_HEADERS, type Aal, type ActClaim, type AmrEntry, type AuthKind, type AuthResolution, type AuthResolver, type AuthSession, type AuthState, type BetterServer, type ContextOptions, type CookieOptions, type CookieRecord, type CookieWrite, type DeleteAccountOptions, type DeleteAccountResult, type GuardOptions, type ImpersonationOptions, type Impersonator, type InvalidReason, type MiddlewareOptions, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, type ProblemDetails, type ProblemOptions, type ProblemResponseOptions, type RefreshOutcome, type ReplicaState, type ResolveAuthOptions, type ResolvedState, type ResourceHandler, type ResourceInput, type ResourceList, type ResourcePagination, type ResourceRouteOptions, type RespondOptions, type ServerContext, type ServerOptions, type SessionActor, type SessionDelegation, type SessionLookup, type Settled, type StoredSession, type SupabaseAuthContext, aalOf, amrOf, authContext, checkAal, clientIp, createServer, defineResource, fromProblem, guard, impersonatorOf, isProblem, isResult, problemResponse, readSession, refreshSession, resolveAuth, respond, sessionCookieName, settle, toProblem, toSession, writeSession };
@@ -1,10 +1,10 @@
1
- import { n as dbError } from "../errors-Bl3rkOzo.js";
2
- import { a as problemResponse, i as isProblem, n as PROBLEM_TYPE_BASE, o as toProblem, r as fromProblem, t as PROBLEM_CONTENT_TYPE } from "../problem-CGt1ADix.js";
3
- import { a as settle, i as respond, n as guard, o as createServer, r as isResult, u as PRIMARY_COOKIE } from "../respond-C44EZAJo.js";
4
- import { a as clientIp, f as sessionCookieName, i as authContext, m as refreshSession, n as amrOf, o as resolveAuth, p as writeSession, r as checkAal, s as AUTH_CACHE_HEADERS, t as aalOf, u as readSession, v as impersonatorOf } from "../mfa-BxoR1RkN.js";
5
- import { n as postgresExecutor } from "../executor-C57jx2pn.js";
6
- import { t as toSession } from "../view-wZ-9qIUz.js";
7
- import { t as defineResource } from "../resource-D30rp0GN.js";
1
+ import { n as dbError } from "../errors-L0xK41y_.js";
2
+ import { a as problemResponse, i as isProblem, n as PROBLEM_TYPE_BASE, o as toProblem, r as fromProblem, t as PROBLEM_CONTENT_TYPE } from "../problem-BihjPR0t.js";
3
+ import { a as guard, c as settle, o as isResult, s as respond, t as createServer, u as PRIMARY_COOKIE } from "../server-BA75B0mT.js";
4
+ import { a as clientIp, c as AUTH_CACHE_HEADERS, d as readSession, h as refreshSession, i as authContext, m as writeSession, n as amrOf, p as sessionCookieName, r as checkAal, s as resolveAuth, t as aalOf, y as impersonatorOf } from "../mfa-byfjruR9.js";
5
+ import { n as postgresExecutor } from "../executor-CVt6dD0B.js";
6
+ import { t as toSession } from "../view-BrJI2LKp.js";
7
+ import { t as defineResource } from "../resource-My_y-Syh.js";
8
8
  import { defineMiddleware } from "@supabase/middleware";
9
9
  //#region src/server/middleware.ts
10
10
  /** Repository context from a `@supabase/server` context. */
@@ -50,23 +50,23 @@ function contextFromSupabase(ctx) {
50
50
  * `ctx.supabase` (the caller-scoped client from `withSupabase`).
51
51
  *
52
52
  * ```ts
53
- * pipeline([withSupabase({ auth: 'user' }), withBetterSupabase(sb)()], (req, ctx) => ...)
53
+ * pipeline([withSupabase({ auth: 'user' }), withBetterSupabase(betterSupabase)()], (req, ctx) => ...)
54
54
  * ```
55
55
  */
56
- function withBetterSupabase(sb) {
56
+ function withBetterSupabase(betterSupabase) {
57
57
  return defineMiddleware({
58
58
  key: "db",
59
- run: (_config) => (_req, ctx) => Promise.resolve({ db: sb.connect(ctx.supabase, contextFromSupabase(ctx)) })
59
+ run: (_config) => (_req, ctx) => Promise.resolve({ db: betterSupabase.connect(ctx.supabase, contextFromSupabase(ctx)) })
60
60
  });
61
61
  }
62
62
  /**
63
63
  * Entry contributing `ctx.sql`: repositories over `ctx.postgres` from
64
64
  * `withPostgresClient`, which runs each query as the caller with RLS.
65
65
  */
66
- function withBetterPostgres(sb) {
66
+ function withBetterPostgres(betterSupabase) {
67
67
  return defineMiddleware({
68
68
  key: "sql",
69
- run: (_config) => (_req, ctx) => Promise.resolve({ sql: sb.connect(postgresExecutor(ctx.postgres), contextFromSupabase(ctx)) })
69
+ run: (_config) => (_req, ctx) => Promise.resolve({ sql: betterSupabase.connect(postgresExecutor(ctx.postgres), contextFromSupabase(ctx)) })
70
70
  });
71
71
  }
72
72
  //#endregion