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,6 +1,6 @@
1
- import { n as dbError } from "./errors-Bl3rkOzo.js";
1
+ import { n as dbError } from "./errors-L0xK41y_.js";
2
2
  import { t as consoleLogger } from "./logger-glM28NVN.js";
3
- import { n as decodeJwtPayload } from "./base64-CQeB1eSf.js";
3
+ import { n as decodeJwtPayload } from "./base64-D2gsioCY.js";
4
4
  import { DEFAULT_COOKIE_OPTIONS, createChunks, isChunkLike, parseCookieHeader, serializeCookieHeader, stringFromBase64URL, stringToBase64URL } from "@supabase/ssr";
5
5
  import { extractCredentials, verifyCredentials } from "@supabase/server/core";
6
6
  //#region src/auth/impersonation.ts
@@ -89,6 +89,7 @@ function delegationOf(claims) {
89
89
  * refresh-token reuse interval of Supabase Auth.
90
90
  */
91
91
  const REUSE_MS = 1e4;
92
+ const DEFAULT_TIMEOUT_MS = 5e3;
92
93
  const inflight = /* @__PURE__ */ new Map();
93
94
  const recent = /* @__PURE__ */ new Map();
94
95
  function shared(outcome) {
@@ -98,10 +99,14 @@ function shared(outcome) {
98
99
  } : outcome;
99
100
  }
100
101
  function prune(now) {
101
- for (const [token, entry] of recent) if (entry.until <= now) recent.delete(token);
102
+ for (const [token, entry] of recent) {
103
+ if (entry.until > now) return;
104
+ recent.delete(token);
105
+ }
102
106
  }
103
107
  async function request(refreshToken, options, now) {
104
108
  const doFetch = options.fetch ?? fetch;
109
+ const signal = AbortSignal.timeout(options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
105
110
  let response;
106
111
  try {
107
112
  response = await doFetch(`${options.url}/auth/v1/token?grant_type=refresh_token`, {
@@ -111,7 +116,8 @@ async function request(refreshToken, options, now) {
111
116
  "content-type": "application/json",
112
117
  ...options.forwardedFor ? { "sb-forwarded-for": options.forwardedFor.ip } : {}
113
118
  },
114
- body: JSON.stringify({ refresh_token: refreshToken })
119
+ body: JSON.stringify({ refresh_token: refreshToken }),
120
+ signal
115
121
  });
116
122
  } catch (cause) {
117
123
  return {
@@ -121,6 +127,11 @@ async function request(refreshToken, options, now) {
121
127
  };
122
128
  }
123
129
  const body = await response.json().catch(() => null);
130
+ if (signal.aborted) return {
131
+ ok: false,
132
+ reason: "network",
133
+ message: "refresh timed out"
134
+ };
124
135
  if (!response.ok || !body || typeof body["access_token"] !== "string" || typeof body["refresh_token"] !== "string") {
125
136
  const message = typeof body?.["msg"] === "string" ? body["msg"] : typeof body?.["error_description"] === "string" ? body["error_description"] : `Refresh failed with ${String(response.status)}`;
126
137
  return {
@@ -154,12 +165,16 @@ function refreshSession(refreshToken, options) {
154
165
  const pending = inflight.get(refreshToken);
155
166
  if (pending) return pending.then(shared);
156
167
  const promise = request(refreshToken, options, now).then((outcome) => {
157
- inflight.delete(refreshToken);
158
- if (outcome.ok) recent.set(refreshToken, {
159
- outcome,
160
- until: now + REUSE_MS
161
- });
168
+ if (outcome.ok || outcome.reason === "rejected") {
169
+ recent.delete(refreshToken);
170
+ recent.set(refreshToken, {
171
+ outcome,
172
+ until: now + REUSE_MS
173
+ });
174
+ }
162
175
  return outcome;
176
+ }).finally(() => {
177
+ inflight.delete(refreshToken);
163
178
  });
164
179
  inflight.set(refreshToken, promise);
165
180
  return promise;
@@ -175,8 +190,15 @@ const AUTH_CACHE_HEADERS = {
175
190
  };
176
191
  /** `sb-<first label of the hostname>-auth-token`, the supabase-js default. */
177
192
  function sessionCookieName(url) {
178
- return `sb-${new URL(url).hostname.split(".")[0] ?? ""}-auth-token`;
193
+ let name = cookieNames.get(url);
194
+ if (name === void 0) {
195
+ name = `sb-${new URL(url).hostname.split(".")[0] ?? ""}-auth-token`;
196
+ if (cookieNames.size < 16) cookieNames.set(url, name);
197
+ }
198
+ return name;
179
199
  }
200
+ /** Project URLs come from configuration, so a handful of entries suffice. */
201
+ const cookieNames = /* @__PURE__ */ new Map();
180
202
  function parseCookies(header) {
181
203
  return header ? parseCookieHeader(header) : [];
182
204
  }
@@ -297,8 +319,31 @@ function remembered(memo, token, now) {
297
319
  memo.set(token, hit);
298
320
  return hit;
299
321
  }
300
- function remember(memo, token, user) {
301
- if (user.expiresAt === null) return;
322
+ const NO_SCHEMA = {};
323
+ const checkedByMemo = /* @__PURE__ */ new WeakMap();
324
+ /**
325
+ * Tokens that already passed (or failed) the claims and `userMetadata`
326
+ * schemas, per verification memo and schema pair, so a memo hit skips
327
+ * validation too.
328
+ */
329
+ function checkedFor(memo, options) {
330
+ const claims = options.claims ?? NO_SCHEMA;
331
+ const metadata = options.userMetadata ?? NO_SCHEMA;
332
+ let byClaims = checkedByMemo.get(memo);
333
+ if (!byClaims) checkedByMemo.set(memo, byClaims = /* @__PURE__ */ new WeakMap());
334
+ let byMetadata = byClaims.get(claims);
335
+ if (!byMetadata) byClaims.set(claims, byMetadata = /* @__PURE__ */ new WeakMap());
336
+ let checked = byMetadata.get(metadata);
337
+ if (!checked) byMetadata.set(metadata, checked = /* @__PURE__ */ new Map());
338
+ return checked;
339
+ }
340
+ function withoutSource(state) {
341
+ if (state.kind !== "user") return state;
342
+ const { source: _source, ...rest } = state;
343
+ return rest;
344
+ }
345
+ function remember(memo, token, user, expiresAt) {
346
+ if (expiresAt === null) return;
302
347
  memo.set(token, user);
303
348
  if (memo.size > MEMO_SIZE) memo.delete(memo.keys().next().value);
304
349
  }
@@ -307,10 +352,20 @@ async function verify(credentials, modes, options, source) {
307
352
  const memo = token ? memoFor(options) : void 0;
308
353
  if (token && memo) {
309
354
  const hit = remembered(memo, token, Math.floor((options.now ?? Date.now)() / 1e3));
310
- if (hit) return checkUser({
311
- ...hit,
312
- source
313
- }, options);
355
+ if (hit) {
356
+ const checked = checkedFor(memo, options);
357
+ const known = checked.get(token);
358
+ if (known) return known.kind === "user" ? {
359
+ ...known,
360
+ source
361
+ } : known;
362
+ const state = await checkUser({
363
+ ...hit,
364
+ source
365
+ }, options);
366
+ remember(checked, token, withoutSource(state), hit.expiresAt);
367
+ return state;
368
+ }
314
369
  }
315
370
  const state = await verifyOnce(credentials, modes, options, source);
316
371
  if (token && memo && state.kind === "user") remember(memo, token, {
@@ -319,8 +374,10 @@ async function verify(credentials, modes, options, source) {
319
374
  claims: state.claims,
320
375
  user: state.user,
321
376
  expiresAt: state.expiresAt
322
- });
323
- return checkUser(state, options);
377
+ }, state.expiresAt);
378
+ const checked = await checkUser(state, options);
379
+ if (token && memo && state.kind === "user") remember(checkedFor(memo, options), token, withoutSource(checked), state.expiresAt);
380
+ return checked;
324
381
  }
325
382
  /** Validates a user's claims against `options.claims`, keeping every JWT claim. */
326
383
  async function checkClaims(state, options) {
@@ -368,10 +425,34 @@ async function checkUser(state, options) {
368
425
  };
369
426
  if (!warnedMetadata.has(schema)) {
370
427
  warnedMetadata.add(schema);
371
- (options.logger ?? consoleLogger).warn("user_metadata does not match sb.userMetadata(schema); session.profile is undefined", { paths: outcome.issues.map((issue) => issue.path?.map((segment) => typeof segment === "object" ? String(segment.key) : String(segment)).join(".") ?? "") });
428
+ (options.logger ?? consoleLogger).warn("user_metadata does not match betterSupabase.userMetadata(schema); session.profile is undefined", { paths: outcome.issues.map((issue) => issue.path?.map((segment) => typeof segment === "object" ? String(segment.key) : String(segment)).join(".") ?? "") });
372
429
  }
373
430
  return user;
374
431
  }
432
+ /** A token whose `kid` matches no key: verifying it loads the JWKS and fails. */
433
+ const PREFETCH_TOKEN = `${base64url(JSON.stringify({
434
+ alg: "ES256",
435
+ kid: "better-supabase-prefetch",
436
+ typ: "JWT"
437
+ }))}.e30.AA`;
438
+ function base64url(text) {
439
+ return btoa(text).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
440
+ }
441
+ /**
442
+ * Loads the remote JWKS into the verifier's cache so the first request
443
+ * doesn't wait for it. Never throws; a failure leaves the first request to
444
+ * fetch it as before.
445
+ */
446
+ function prefetchJwks(options) {
447
+ if (options.jwks !== void 0) return Promise.resolve();
448
+ return verifyCredentials({
449
+ token: PREFETCH_TOKEN,
450
+ apikey: null
451
+ }, {
452
+ auth: ["user"],
453
+ env: serverEnv(options)
454
+ }).then(() => {}, () => {});
455
+ }
375
456
  async function verifyOnce(credentials, modes, options, source) {
376
457
  const { data, error } = await verifyCredentials(credentials, {
377
458
  auth: modes,
@@ -406,11 +487,16 @@ async function verifyOnce(credentials, modes, options, source) {
406
487
  }
407
488
  function resolution(auth, cookies, writes = []) {
408
489
  const headers = writes.length > 0 ? AUTH_CACHE_HEADERS : {};
490
+ let requestCookies;
409
491
  return {
410
492
  auth,
411
493
  cookies: writes,
412
494
  headers,
413
- requestCookies: writes.length > 0 ? applyCookieWrites(cookies, writes) : cookies,
495
+ /** Parsed on first read: bearer requests rarely need their cookies. */
496
+ get requestCookies() {
497
+ requestCookies ??= writes.length > 0 ? applyCookieWrites(cookies(), writes) : cookies();
498
+ return requestCookies;
499
+ },
414
500
  apply(response) {
415
501
  if (writes.length === 0) return response;
416
502
  let target = response;
@@ -440,7 +526,8 @@ function clientIp(request) {
440
526
  * set, through a single-flight request, and only then are cookies written.
441
527
  */
442
528
  async function resolveAuth(request, options) {
443
- const cookies = parseCookies(request.headers.get("cookie"));
529
+ let parsed;
530
+ const cookies = () => parsed ??= parseCookies(request.headers.get("cookie"));
444
531
  for (const resolver of options.resolvers ?? []) {
445
532
  const state = await resolver.resolve(request);
446
533
  if (!state) continue;
@@ -460,10 +547,10 @@ async function resolveAuth(request, options) {
460
547
  apikey: credentials.apikey
461
548
  }, options.secret === true ? ["secret"] : options.secret.map((name) => `secret:${name}`), options, "bearer"), cookies);
462
549
  const name = options.cookie?.name ?? sessionCookieName(options.env.url);
463
- const session = readSession(cookies, name);
550
+ const session = readSession(cookies(), name);
464
551
  if (!session) {
465
- const stale = cookies.some((cookie) => cookie.name === name || cookie.name.startsWith(`${name}.`));
466
- const writes = stale && options.refresh ? writeSession(cookies, name, null, options.cookie?.options) : [];
552
+ const stale = cookies().some((cookie) => cookie.name === name || cookie.name.startsWith(`${name}.`));
553
+ const writes = stale && options.refresh ? writeSession(cookies(), name, null, options.cookie?.options) : [];
467
554
  return resolution({
468
555
  kind: "anon",
469
556
  reason: stale ? "signed_out" : "none"
@@ -471,7 +558,8 @@ async function resolveAuth(request, options) {
471
558
  }
472
559
  const now = Math.floor((options.now ?? Date.now)() / 1e3);
473
560
  const expiry = expiryOf(session);
474
- if (expiry !== void 0 && expiry - (options.leeway ?? 60) > now) {
561
+ const leeway = options.refresh ? options.leeway ?? 60 : 0;
562
+ if (expiry !== void 0 && expiry - leeway > now) {
475
563
  const state = await verify({
476
564
  token: session.access_token,
477
565
  apikey: null
@@ -496,7 +584,8 @@ async function resolveAuth(request, options) {
496
584
  secretKey
497
585
  } } : {},
498
586
  ...options.fetch ? { fetch: options.fetch } : {},
499
- ...options.now ? { now: options.now } : {}
587
+ ...options.now ? { now: options.now } : {},
588
+ ...options.refreshTimeoutMs === void 0 ? {} : { timeoutMs: options.refreshTimeoutMs }
500
589
  });
501
590
  options.onRefresh?.({
502
591
  ok: outcome.ok,
@@ -511,9 +600,9 @@ async function resolveAuth(request, options) {
511
600
  return resolution({
512
601
  kind: "anon",
513
602
  reason: "signed_out"
514
- }, cookies, writeSession(cookies, name, null, options.cookie?.options));
603
+ }, cookies, writeSession(cookies(), name, null, options.cookie?.options));
515
604
  }
516
- const writes = writeSession(cookies, name, outcome.session, options.cookie?.options);
605
+ const writes = writeSession(cookies(), name, outcome.session, options.cookie?.options);
517
606
  return resolution(await verify({
518
607
  token: outcome.session.access_token,
519
608
  apikey: null
@@ -593,4 +682,4 @@ function checkAal(auth, required) {
593
682
  });
594
683
  }
595
684
  //#endregion
596
- export { actClaim as _, clientIp as a, applyCookieWrites as c, serializeCookie as d, sessionCookieName as f, delegationOf as g, actorOf as h, authContext as i, parseCookies as l, refreshSession as m, amrOf as n, resolveAuth as o, writeSession as p, checkAal as r, AUTH_CACHE_HEADERS as s, aalOf as t, readSession as u, impersonatorOf as v };
685
+ export { delegationOf as _, clientIp as a, AUTH_CACHE_HEADERS as c, readSession as d, serializeCookie as f, actorOf as g, refreshSession as h, authContext as i, applyCookieWrites as l, writeSession as m, amrOf as n, prefetchJwks as o, sessionCookieName as p, checkAal as r, resolveAuth as s, aalOf as t, parseCookies as u, actClaim as v, impersonatorOf as y };
@@ -21,13 +21,16 @@ const clamp = (value, min, max) => Math.min(max, Math.max(min, Math.round(value)
21
21
  */
22
22
  function createImageLoader(options) {
23
23
  const storage = `${options.url.replace(/\/+$/, "")}/storage/v1`;
24
- const publicPrefixes = [`${storage}/object/public/`, `${storage}/render/image/public/`];
24
+ const publicPrefixes = [`${storage}/object/public/`, `${storage}/render/image/public/`].map((prefix) => ({
25
+ prefix,
26
+ length: new URL(prefix).pathname.length
27
+ }));
25
28
  const fallback = options.fallback ?? (({ src }) => src);
26
29
  return (props) => {
27
- const prefix = publicPrefixes.find((candidate) => props.src.startsWith(candidate));
30
+ const prefix = publicPrefixes.find((candidate) => props.src.startsWith(candidate.prefix));
28
31
  if (prefix === void 0) return fallback(props);
29
32
  const source = new URL(props.src);
30
- const object = source.pathname.slice(new URL(prefix).pathname.length);
33
+ const object = source.pathname.slice(prefix.length);
31
34
  const target = new URL(`${storage}/render/image/public/${object}`);
32
35
  for (const [key, value] of source.searchParams) target.searchParams.set(key, value);
33
36
  target.searchParams.set("width", String(clamp(props.width, 1, MAX_WIDTH)));
@@ -1,12 +1,12 @@
1
1
  import { n as AnyModels, t as AnyFunctions } from "../types-DONv9SHN.js";
2
- import { p as DbError } from "../result-c2OYgCV2.js";
3
- import { B as ReadSet, P as DbStats, Z as QuerySpec, l as CacheAdapter, t as BetterSupabase } from "../define-DUbydmJa.js";
4
- import { n as AmrEntry, s as Impersonator, t as Aal } from "../mfa-x3V3vGh-.js";
5
- import { r as AuthState } from "../resolve-BRciX2jK.js";
6
- import { d as ServerContext, f as ServerOptions, l as BetterServer, n as GuardOptions, t as AuthKind } from "../respond-DAkPIdTH.js";
7
- import { n as toSession, t as AuthSession } from "../view-3Po_PVlr.js";
8
- import { r as LiveCountSeed, t as CountRunner } from "../live-QE3UPbGm.js";
9
- import { n as MembershipClaim, r as hasEntitlement, t as EntitlementKey } from "../entitlements-DvJXoI02.js";
2
+ import { p as DbError } from "../result-CqEsbgYs.js";
3
+ import { B as ReadSet, P as DbStats, Z as QuerySpec, l as CacheAdapter, t as BetterSupabase } from "../define-CRS2MRV3.js";
4
+ import { n as AmrEntry, s as Impersonator, t as Aal } from "../mfa-C7MNQ1Ob.js";
5
+ import { r as AuthState } from "../resolve-BAqQcwMW.js";
6
+ import { d as ContextOptions, f as ServerContext, n as GuardOptions, p as ServerOptions, t as AuthKind, u as BetterServer } from "../respond-DgIbdrt8.js";
7
+ import { n as toSession, t as AuthSession } from "../view-B64o81wp.js";
8
+ import { r as LiveCountSeed, t as CountRunner } from "../live-BHakSWWo.js";
9
+ import { n as MembershipClaim, r as hasEntitlement, t as EntitlementKey } from "../entitlements-Dm-FHpNH.js";
10
10
  import { NextRequest } from "next/server.js";
11
11
  import { StandardSchemaV1 } from "@standard-schema/spec";
12
12
  //#region src/next/collector.d.ts
@@ -33,12 +33,12 @@ interface NextDebugOptions {
33
33
  readonly header?: string;
34
34
  /** Warns in development when one render goes over it. */
35
35
  readonly budget?: DbBudget;
36
- /** Where `next.debugRoute()` is mounted. Defaults to `/api/bs-stats`. */
36
+ /** Where `bs.debugRoute()` is mounted. Defaults to `/api/bs-stats`. */
37
37
  readonly route?: string;
38
38
  }
39
- /** Response header with the URL of the request's totals on `next.debugRoute()`. */
39
+ /** Response header with the URL of the request's totals on `bs.debugRoute()`. */
40
40
  export declare const STATS_URL_HEADER = "x-bs-stats";
41
- interface ProxyOptions<C = unknown, U = unknown> {
41
+ interface ProxyOptions<C = unknown, P = unknown> {
42
42
  /**
43
43
  * Another middleware to compose with, such as next-intl's. It runs on the
44
44
  * original request, alongside auth; its rewrite, redirect or request
@@ -46,9 +46,9 @@ interface ProxyOptions<C = unknown, U = unknown> {
46
46
  */
47
47
  readonly before?: (request: NextRequest) => Response | undefined | Promise<Response | undefined>;
48
48
  /** Answer before rendering, e.g. redirect signed-out users. Refreshed cookies are kept. */
49
- readonly protect?: (auth: AuthState<C, U>, request: NextRequest) => Response | undefined | Promise<Response | undefined>;
49
+ readonly protect?: (auth: AuthState<C, P>, request: NextRequest) => Response | undefined | Promise<Response | undefined>;
50
50
  /** Post-processes the final response; return a new one to replace it. */
51
- readonly after?: (response: Response, auth: AuthState<C, U>) => Response | undefined | void | Promise<Response | undefined | void>;
51
+ readonly after?: (response: Response, auth: AuthState<C, P>) => Response | undefined | void | Promise<Response | undefined | void>;
52
52
  /**
53
53
  * Adds `Server-Timing: bs-proxy;dur=..., bs-verify;dur=...` (ms): the whole
54
54
  * proxy, and resolving the session (a local verify, or a refresh).
@@ -76,25 +76,28 @@ type Unwrapped<T> = T extends {
76
76
  } | {
77
77
  readonly ok: false;
78
78
  } ? D : T;
79
- interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown, U = unknown> extends BetterServer<M, F, E, C, U> {
79
+ interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> extends BetterServer<M, F, E, C, P> {
80
80
  /** `proxy.ts`: refreshes sessions for page loads and server actions. */
81
- proxy(request: NextRequest, options?: ProxyOptions<C, U>): Promise<Response>;
82
- /** Server Components and actions: the caller's context, memoized per request. */
83
- server(): Promise<ServerContext<M, F, E, C, U>>;
81
+ proxy(request: NextRequest, options?: ProxyOptions<C, P>): Promise<Response>;
82
+ /**
83
+ * The caller's context. Without a request (Server Components, actions) it
84
+ * reads the incoming headers and is memoized per request.
85
+ */
86
+ context(request?: Request, options?: ContextOptions): Promise<ServerContext<M, F, E, C, P>>;
84
87
  /**
85
88
  * The verified caller as serializable data (no token, no clients), memoized
86
89
  * per request. Wrap it in a `'use cache: private'` function with Cache
87
90
  * Components and pass the promise to `<SessionProvider>`.
88
91
  */
89
- session(): Promise<AuthSession<C, U>>;
92
+ session(): Promise<AuthSession<C, P>>;
90
93
  /**
91
94
  * The context for a session and its token, without reading the request.
92
95
  * The token is verified again (memoized, no network call); a token for
93
96
  * another user than `session` gives an `invalid` context.
94
97
  */
95
- serverFor(session: AuthSession<C, U>, options: {
98
+ contextForSession(session: AuthSession<C, P>, options: {
96
99
  readonly token: string | null;
97
- }): Promise<ServerContext<M, F, E, C, U>>;
100
+ }): Promise<ServerContext<M, F, E, C, P>>;
98
101
  /**
99
102
  * First statement of an app-authored `'use cache: private'` function: sets
100
103
  * `cacheLife` from the session's expiry (`sessionStale`, capped by
@@ -104,14 +107,14 @@ interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown
104
107
  * ```ts
105
108
  * async function getCustomers() {
106
109
  * 'use cache: private';
107
- * const { db } = await next.cached();
110
+ * const { db } = await bs.cached();
108
111
  * return db.customers.findMany().orThrow();
109
112
  * }
110
113
  * ```
111
114
  */
112
- cached(options?: CachedOptions): Promise<CachedContext<M, F, E, C, U>>;
115
+ cached(options?: CachedOptions): Promise<CachedContext<M, F, E, C, P>>;
113
116
  /**
114
- * Drops every `next.cached()` entry of a user, e.g. after a role change,
117
+ * Drops every `bs.cached()` entry of a user, e.g. after a role change,
115
118
  * and the entries tagged with `tags` (such as PermDock's `snapshotTag(userId)`).
116
119
  */
117
120
  invalidateSession(userId: string, options?: {
@@ -121,18 +124,18 @@ interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown
121
124
  * Counts on the server and returns a serializable seed for
122
125
  * `useLiveCount(seed)`, so the badge renders with a number and the client
123
126
  * only refetches on changes. Pass `db` inside `'use cache: private'`
124
- * (from `next.cached()`); otherwise it uses `next.server()`. A failed
127
+ * (from `bs.cached()`); otherwise it uses `bs.context()`. A failed
125
128
  * count gives `count: null` instead of throwing.
126
129
  */
127
130
  liveCount<T extends Extract<keyof M, string>>(spec: QuerySpec<T, "count", number>, db?: CountRunner): Promise<LiveCountSeed<T>>;
128
131
  /** Route handler with auth, Result unwrapping and Problem Details errors. */
129
- route<P = Record<string, string | string[]>>(handler: (request: NextRequest, ctx: ServerContext<M, F, E, C, U> & {
130
- readonly params: P;
132
+ route<Params = Record<string, string | string[]>>(handler: (request: NextRequest, ctx: ServerContext<M, F, E, C, P> & {
133
+ readonly params: Params;
131
134
  }) => unknown, options?: GuardOptions): (request: NextRequest, segment: {
132
- readonly params: Promise<P>;
135
+ readonly params: Promise<Params>;
133
136
  }) => Promise<Response>;
134
137
  /** Server action returning a serializable `ActionResult`. */
135
- action<S extends StandardSchemaV1 | undefined, T>(options: ActionOptions<S>, fn: (input: ActionParsed<S>, ctx: ServerContext<M, F, E, C, U>) => Promise<T> | T): (input: ActionInput<S>) => Promise<ActionResult<Unwrapped<Awaited<T>>>>;
138
+ action<S extends StandardSchemaV1 | undefined, T>(options: ActionOptions<S>, fn: (input: ActionParsed<S>, ctx: ServerContext<M, F, E, C, P>) => Promise<T> | T): (input: ActionInput<S>) => Promise<ActionResult<Unwrapped<Awaited<T>>>>;
136
139
  /** Tags the current `"use cache"` scope with a table (and row) tag. */
137
140
  cacheTag(table: Extract<keyof M, string>, id?: string | number): void;
138
141
  /**
@@ -172,10 +175,10 @@ interface CachedOptions {
172
175
  /** More `cacheTag`s for the entry, e.g. `snapshotTag(sub)` or `org:<id>`. */
173
176
  readonly tags?: readonly string[];
174
177
  }
175
- type CachedContext<M extends AnyModels, F extends AnyFunctions, E, C = unknown, U = unknown> = ServerContext<M, F, E, C, U> & {
176
- readonly session: AuthSession<C, U>;
178
+ type CachedContext<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> = ServerContext<M, F, E, C, P> & {
179
+ readonly session: AuthSession<C, P>;
177
180
  };
178
- /** The tag `next.cached()` puts on a user's entries. */
181
+ /** The tag `bs.cached()` puts on a user's entries. */
179
182
  export declare function sessionTag(userId: string): string;
180
183
  /** `bs:<table>` or `bs:<table>:<id>`. Mutations invalidate both. */
181
184
  export declare function tagFor(table: string, id?: string | number): string;
@@ -202,7 +205,7 @@ interface RequireAalOptions {
202
205
  * combine it with your sign-in redirect.
203
206
  *
204
207
  * ```ts
205
- * next.proxy(request, {
208
+ * bs.proxy(request, {
206
209
  * protect: requireAal('aal2', { redirect: '/mfa', match: (path) => path.startsWith('/settings') }),
207
210
  * });
208
211
  * ```
@@ -215,9 +218,9 @@ export declare function shouldRefresh(request: Request): boolean;
215
218
  * actions and cache tags, on top of `createServer`.
216
219
  *
217
220
  * ```ts
218
- * export const next = createNext(sb);
221
+ * export const bs = createNext(betterSupabase);
219
222
  * ```
220
223
  */
221
- export declare function createNext<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, U = unknown>(sb: BetterSupabase<M, D, F, E, C, U>, options?: NextOptions): BetterNext<M, F, E, C, U>;
224
+ export declare function createNext<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: NextOptions): BetterNext<M, F, E, C, P>;
222
225
  //#endregion
223
- export { type Aal, type ActionOptions, type ActionResult, type AmrEntry, type AuthKind, type AuthSession, type BetterNext, type CachedContext, type CachedOptions, type DbBudget, type DbStats, type EntitlementKey, type GuardOptions, type Impersonator, type MembershipClaim, type NextDebugOptions, type NextOptions, type ProxyOptions, type RequireAalOptions, type SessionStaleOptions, hasEntitlement, toSession };
226
+ export { type Aal, type ActionOptions, type ActionResult, type AmrEntry, type AuthKind, type AuthSession, type BetterNext, type CachedContext, type CachedOptions, type DbBudget, type DbStats, type EntitlementKey, type GuardOptions, type Impersonator, type LiveCountSeed, type MembershipClaim, type NextDebugOptions, type NextOptions, type ProxyOptions, type RequireAalOptions, type SessionStaleOptions, hasEntitlement, toSession };
@@ -1,13 +1,13 @@
1
- import { n as dbError } from "../errors-Bl3rkOzo.js";
2
- import { n as StatsRecorder, t as EMPTY_STATS } from "../stats-D78UQ8Yu.js";
3
- import { o as isReadSet } from "../read-set-D0qBcboM.js";
4
- import { t as validate } from "../standard-FUi3Z3-7.js";
5
- import { a as problemResponse } from "../problem-CGt1ADix.js";
1
+ import { n as dbError } from "../errors-L0xK41y_.js";
2
+ import { n as StatsRecorder, t as EMPTY_STATS } from "../stats-C_YxA2r1.js";
3
+ import { o as isReadSet } from "../read-set-FWK8qQ58.js";
4
+ import { t as validate } from "../standard-BRyBGTtp.js";
5
+ import { a as problemResponse } from "../problem-BihjPR0t.js";
6
6
  import { t as isList } from "../guards-BnzDvFrz.js";
7
7
  import { t as hasEntitlement } from "../entitlements-CTEBm7IB.js";
8
- import { a as settle, c as withExtra, d as primaryCookie, i as respond, n as guard, o as createServer, s as extendServer, t as defaultExpose, u as PRIMARY_COOKIE } from "../respond-C44EZAJo.js";
9
- import { r as checkAal } from "../mfa-BxoR1RkN.js";
10
- import { t as toSession } from "../view-wZ-9qIUz.js";
8
+ import { a as guard, c as settle, d as primaryCookie, i as defaultExpose, n as extendServer, r as withExtra, s as respond, t as createServer, u as PRIMARY_COOKIE } from "../server-BA75B0mT.js";
9
+ import { r as checkAal } from "../mfa-byfjruR9.js";
10
+ import { t as toSession } from "../view-BrJI2LKp.js";
11
11
  import { cache } from "react";
12
12
  import { cacheLife, cacheTag, revalidateTag, updateTag } from "next/cache.js";
13
13
  import { cookies, headers } from "next/headers.js";
@@ -143,7 +143,7 @@ function serverTimingValue(metrics) {
143
143
  }
144
144
  //#endregion
145
145
  //#region src/next/create.ts
146
- /** Response header with the URL of the request's totals on `next.debugRoute()`. */
146
+ /** Response header with the URL of the request's totals on `bs.debugRoute()`. */
147
147
  const STATS_URL_HEADER = "x-bs-stats";
148
148
  /**
149
149
  * `cacheLife` `stale` seconds for a view of `session`: `max`, but never past
@@ -156,7 +156,7 @@ function sessionStale(session, options = {}, now = Date.now()) {
156
156
  const remaining = session.expiresAt - Math.floor(now / 1e3);
157
157
  return Math.min(max, Math.max(min, remaining));
158
158
  }
159
- /** The tag `next.cached()` puts on a user's entries. */
159
+ /** The tag `bs.cached()` puts on a user's entries. */
160
160
  function sessionTag(userId) {
161
161
  return `bs:session:${userId}`;
162
162
  }
@@ -202,7 +202,7 @@ function formDataObject(form) {
202
202
  * combine it with your sign-in redirect.
203
203
  *
204
204
  * ```ts
205
- * next.proxy(request, {
205
+ * bs.proxy(request, {
206
206
  * protect: requireAal('aal2', { redirect: '/mfa', match: (path) => path.startsWith('/settings') }),
207
207
  * });
208
208
  * ```
@@ -235,20 +235,20 @@ function shouldRefresh(request) {
235
235
  * actions and cache tags, on top of `createServer`.
236
236
  *
237
237
  * ```ts
238
- * export const next = createNext(sb);
238
+ * export const bs = createNext(betterSupabase);
239
239
  * ```
240
240
  */
241
- function createNext(sb, options = {}) {
242
- const base = createServer(sb, options);
241
+ function createNext(betterSupabase, options = {}) {
242
+ const base = createServer(betterSupabase, options);
243
243
  const pinMs = options.replicas?.pinMs ?? 5e3;
244
244
  const expose = options.exposeErrors ?? defaultExpose();
245
- if (options.cacheTags !== false) sb.cache(nextCache());
245
+ if (options.cacheTags !== false) betterSupabase.cache(nextCache());
246
246
  const debug = options.debug;
247
247
  const statsHeader = debug?.header ?? "x-bs-db-calls";
248
248
  const statsRoute = debug?.route ?? "/api/bs-stats";
249
249
  const development = process.env["NODE_ENV"] === "development";
250
250
  const collector = debug?.enabled ? sharedCollector({
251
- logger: sb.events.logger,
251
+ logger: betterSupabase.events.logger,
252
252
  warn: development,
253
253
  ...debug.budget ? { budget: debug.budget } : {}
254
254
  }) : void 0;
@@ -257,34 +257,42 @@ function createNext(sb, options = {}) {
257
257
  return id ? { stats: collector.recorderFor(id) } : {};
258
258
  };
259
259
  const incomingRequest = async () => new Request("http://next.local/", { headers: new Headers(await headers()) });
260
- const server = cache(async () => {
260
+ /** One token verification per render scope backs `context()`, `session()` and `cached()`. */
261
+ const incoming = cache(async () => {
261
262
  const request = await incomingRequest();
262
- return base.context(request, statsFor(request));
263
+ return {
264
+ request,
265
+ resolution: await base.resolve(request, { refresh: false })
266
+ };
263
267
  });
264
- const session = cache(async () => {
265
- const resolution = await base.resolve(await incomingRequest(), { refresh: false });
266
- return toSession(resolution.auth);
268
+ const current = cache(async () => {
269
+ const { request, resolution } = await incoming();
270
+ return base.contextFromResolution(resolution, request, statsFor(request));
267
271
  });
268
- const serverFor = async (view, { token }) => {
272
+ const context = (request, contextOptions) => request ? base.context(request, contextOptions) : current();
273
+ const session = cache(async () => toSession((await incoming()).resolution.auth));
274
+ const contextForSession = async (view, { token }) => {
269
275
  const request = new Request("http://next.local/", { headers: token ? { authorization: `Bearer ${token}` } : {} });
270
276
  const ctx = await base.context(request);
271
277
  if (ctx.auth.kind === "user" ? view.kind === "user" && view.user.id === ctx.auth.user.id : view.kind !== "user") return ctx;
272
278
  return base.contextFor({
273
279
  kind: "invalid",
274
280
  reason: "token",
275
- error: dbError("unauthorized", "The token does not belong to the session passed to serverFor()")
281
+ error: dbError("unauthorized", "The token does not belong to the session passed to contextForSession()")
276
282
  });
277
283
  };
278
- const withAccounts = withExtra(base, { deleteAccount: ((userId, deleteOptions) => base.deleteAccount(userId, deleteOptions).map((result) => {
279
- invalidate(sessionTag(userId));
280
- return result;
281
- })) });
284
+ const withAccounts = withExtra(base, {
285
+ context,
286
+ deleteAccount: ((userId, deleteOptions) => base.deleteAccount(userId, deleteOptions).map((result) => {
287
+ invalidate(sessionTag(userId));
288
+ return result;
289
+ }))
290
+ });
282
291
  return extendServer(withAccounts, {
283
- server,
284
292
  session,
285
- serverFor,
293
+ contextForSession,
286
294
  async cached(cachedOptions = {}) {
287
- const [view, ctx] = await Promise.all([session(), server()]);
295
+ const [view, ctx] = await Promise.all([session(), current()]);
288
296
  const life = cachedOptions.life;
289
297
  const stale = sessionStale(view, life);
290
298
  cacheLife({
@@ -301,7 +309,7 @@ function createNext(sb, options = {}) {
301
309
  for (const tag of invalidateOptions.tags ?? []) invalidate(tag);
302
310
  },
303
311
  async liveCount(spec, db) {
304
- const result = await (db ?? (await server()).db).$run(spec);
312
+ const result = await (db ?? (await current()).db).$run(spec);
305
313
  return {
306
314
  spec,
307
315
  count: result.ok && typeof result.data === "number" ? result.data : null
@@ -378,7 +386,7 @@ function createNext(sb, options = {}) {
378
386
  },
379
387
  action(actionOptions, fn) {
380
388
  return async (input) => {
381
- const ctx = await server();
389
+ const ctx = await current();
382
390
  const denied = guard(ctx.auth, actionOptions.allow, actionOptions.aal, actionOptions.scopes);
383
391
  if (denied) return {
384
392
  ok: false,
@@ -420,7 +428,7 @@ function createNext(sb, options = {}) {
420
428
  const specs = isReadSet(target) ? Object.values(target.specs) : isList(target) ? target : [target];
421
429
  const tags = /* @__PURE__ */ new Set();
422
430
  for (const spec of specs) {
423
- for (const table of sb.tablesOf(spec)) tags.add(tagFor(table));
431
+ for (const table of betterSupabase.tablesOf(spec)) tags.add(tagFor(table));
424
432
  const [id] = spec.args;
425
433
  if (spec.method === "findById" && (typeof id === "string" || typeof id === "number")) tags.add(tagFor(spec.table, id));
426
434
  }
@@ -1,2 +1,2 @@
1
- import { a as ResourceOptions, i as ResourceOperation, n as OpenApiOptions, o as createOpenApi, r as PROBLEM_SCHEMA, t as OpenApiDocument } from "../index-qriRM9cZ.js";
1
+ import { a as ResourceOptions, i as ResourceOperation, n as OpenApiOptions, o as createOpenApi, r as PROBLEM_SCHEMA, t as OpenApiDocument } from "../index-BhHEC04r.js";
2
2
  export { OpenApiDocument, OpenApiOptions, PROBLEM_SCHEMA, ResourceOperation, ResourceOptions, createOpenApi };