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,10 +1,11 @@
1
- import { A as SchemaMeta, C as PrimaryKeyValue, D as Relations, E as RelationShape, I as UniqueKeyName, L as UniqueWhere, N as TableKey, O as Row, P as TableMeta, R as Update, _ as Insert, j as Simplify, k as Schema, n as AnyModels, t as AnyFunctions } from "./types-C83v5SQz.js";
2
- import { g as Operation, l as CountMode, r as Executor } from "./executor-CGdNQ27g.js";
3
- import { p as DbError, s as ThrowMapper, t as AsyncResult, v as ErrorMapper } from "./result-CTkCZ6JA.js";
4
- import { a as EventHub, f as Logger, i as EventHandler, o as EventName, s as MutationNotice, u as RpcNotice } from "./events-DOt3nSO-.js";
5
- import { a as ExtensionOf, g as WithExtension, h as RequestContext, n as AnyPlugin, r as ApplyExtension } from "./plugin-C4TR9J0Z.js";
6
- import { t as StandardSchemaV1 } from "./standard-CyhRzctb.js";
7
- import { i as PostgrestPlan } from "./postgrest-cAEQ_IQN.js";
1
+ /// <reference lib="esnext.temporal" />
2
+ import { A as SchemaMeta, C as PrimaryKeyValue, D as Relations, E as RelationTypes, I as UniqueKeyName, L as UniqueWhere, N as TableKey, O as Row, P as TableMeta, R as Update, g as Insert, j as Simplify, k as Schema, n as AnyModels, t as AnyFunctions } from "./types-DONv9SHN.js";
3
+ import { g as Operation, l as CountMode, r as Executor } from "./executor-B5IoUxLE.js";
4
+ import { p as DbError, s as ThrowMapper, t as AsyncResult, v as ErrorMapper } from "./result-CqEsbgYs.js";
5
+ import { a as EventHub, f as Logger, i as EventHandler, o as EventName, s as MutationNotice, u as RpcNotice } from "./events-B21UOhvP.js";
6
+ import { a as ExtensionOf, g as WithExtension, h as RequestContext, n as AnyPlugin, r as ApplyExtension } from "./plugin-bNhvJwRh.js";
7
+ import { t as StandardSchemaV1 } from "./standard-BsaCYQJc.js";
8
+ import { i as PostgrestPlan } from "./postgrest-Bc-0Xw62.js";
8
9
  //#region src/ir/args.d.ts
9
10
  interface BaseOps<V> {
10
11
  readonly eq?: V;
@@ -147,7 +148,7 @@ interface AggregateArgs<M extends AnyModels, T extends keyof M> {
147
148
  type SelectPart<M extends AnyModels, T extends keyof M, A> = A extends {
148
149
  readonly select: readonly (infer K)[];
149
150
  } ? Pick<Row<M, T>, Extract<K, keyof Row<M, T>>> : Row<M, T>;
150
- type RelationPayload<M extends AnyModels, R, V> = R extends RelationShape ? R["kind"] extends "many" ? Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V>[] : R["nullable"] extends true ? Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V> | null : Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V> : never;
151
+ type RelationPayload<M extends AnyModels, R, V> = R extends RelationTypes ? R["kind"] extends "many" ? Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V>[] : R["nullable"] extends true ? Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V> | null : Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V> : never;
151
152
  type IncludePart<M extends AnyModels, T extends keyof M, A> = A extends {
152
153
  readonly include: infer I;
153
154
  } ? { -readonly [R in keyof I & keyof Relations<M, T>]: RelationPayload<M, Relations<M, T>[R], I[R]>; } & CountPart<I> & ([keyof I & MeasureKey] extends [never] ? unknown : RelationMeasures<M, T, I>) : unknown;
@@ -177,13 +178,17 @@ type AggregateResult<M extends AnyModels, T extends keyof M, A> = A extends {
177
178
  readonly groupBy: readonly unknown[];
178
179
  } ? AggregateRow<M, T, A>[] : AggregateRow<M, T, A>;
179
180
  /** The row type returned for read arguments `A` on table `T`. */
180
- type Payload<M extends AnyModels, T extends keyof M, A> = Simplify<SelectPart<M, T, A> & IncludePart<M, T, A>>;
181
+ type Payload<M extends AnyModels, T extends keyof M, A> = A extends {
182
+ readonly include: unknown;
183
+ } ? Simplify<SelectPart<M, T, A> & IncludePart<M, T, A>> : A extends {
184
+ readonly select: readonly unknown[];
185
+ } ? Simplify<SelectPart<M, T, A>> : Row<M, T>;
181
186
  //#endregion
182
187
  //#region src/core/spec.d.ts
183
188
  type ReadMethod = "findMany" | "findFirst" | "findUnique" | "findById" | "count" | "aggregate" | "exists" | "paginate";
184
189
  declare const resultType: unique symbol;
185
190
  /**
186
- * A read, described as plain JSON: build it with `sb.spec`, run it with
191
+ * A read, described as plain JSON: build it with `betterSupabase.spec`, run it with
187
192
  * `db.$run(spec)`, send it from a Server Component to the client, or hand it
188
193
  * to `/query` and `/next`. Args never carry a `signal`.
189
194
  */
@@ -268,7 +273,7 @@ interface ReadSetOptions<P extends ReadSetParamTypes> {
268
273
  *
269
274
  * ```ts
270
275
  * export const appChrome = defineReadSet(
271
- * sb,
276
+ * betterSupabase,
272
277
  * 'app_chrome',
273
278
  * { params: { userId: 'uuid' } },
274
279
  * (s, p) => ({
@@ -281,7 +286,7 @@ interface ReadSetOptions<P extends ReadSetParamTypes> {
281
286
  * `p` holds placeholders, not values: pass them straight into `where` (or
282
287
  * `in`), where the function reads them from its `p jsonb` argument.
283
288
  */
284
- declare function defineReadSet<M extends AnyModels, D, F extends AnyFunctions, E, const N extends string, const P extends ReadSetParamTypes, const S extends Readonly<Record<string, QuerySpec>>>(sb: BetterSupabase<M, D, F, E>, name: N, options: ReadSetOptions<P>, build: (specs: Specs<M, E>, params: ReadSetParams<P>) => S): ReadSet<N, P, S>;
289
+ declare function defineReadSet<M extends AnyModels, D, F extends AnyFunctions, E, const N extends string, const P extends ReadSetParamTypes, const S extends Readonly<Record<string, QuerySpec>>>(betterSupabase: BetterSupabase<M, D, F, E>, name: N, options: ReadSetOptions<P>, build: (specs: Specs<M, E>, params: ReadSetParams<P>) => S): ReadSet<N, P, S>;
285
290
  declare function isReadSet(value: unknown): value is ReadSet;
286
291
  /** App keys of every table the set reads. */
287
292
  declare function readSetTables(set: ReadSet, meta?: SchemaMeta): string[];
@@ -384,7 +389,7 @@ type PageOf<M extends AnyModels, T extends keyof M, A> = A extends {
384
389
  readonly after: unknown;
385
390
  } ? CursorPage<Payload<M, T, A>> : OffsetPage<Payload<M, T, A>>;
386
391
  interface Repository<M extends AnyModels, T extends TableKey<M>, E = unknown> {
387
- readonly $table: T;
392
+ readonly $tableName: T;
388
393
  readonly $meta: TableMeta;
389
394
  findMany<const A extends FindManyArgs<M, T> & FindExt<E, M, T>>(args?: A): AsyncResult<Payload<M, T, A>[]>;
390
395
  findFirst<const A extends FindFirstArgs<M, T> & FindExt<E, M, T>>(args?: A): AsyncResult<Payload<M, T, A> | null>;
@@ -470,7 +475,7 @@ interface DbHelpers<M extends AnyModels, F extends AnyFunctions, E, C> {
470
475
  $table<T extends TableKey<M>>(name: T): RepositoryOf<M, T, E>;
471
476
  /** Calls, waves, tables and time for everything run through this `db`. */
472
477
  $stats(): DbStats;
473
- /** Runs a `QuerySpec` built with `sb.spec`. */
478
+ /** Runs a `QuerySpec` built with `betterSupabase.spec`. */
474
479
  $run<S extends QuerySpec<TableKey<M>>>(spec: S, options?: {
475
480
  readonly signal?: AbortSignal;
476
481
  }): AsyncResult<InferResult<S>>;
@@ -515,7 +520,7 @@ interface CacheTarget {
515
520
  /**
516
521
  * Invalidates cached reads after a mutation. First-party adapters:
517
522
  * `nextCache()` (Next.js cache tags) and `queryCache(client)` (TanStack
518
- * Query). Attach one with `sb.cache(adapter)`; prove custom ones with
523
+ * Query). Attach one with `betterSupabase.cache(adapter)`; prove custom ones with
519
524
  * `testCacheAdapter`.
520
525
  */
521
526
  interface CacheAdapter {
@@ -549,20 +554,20 @@ declare function postgrestExecutor(client: PostgrestClientLike): Executor;
549
554
  declare function explainPostgrest(op: Operation): PostgrestPlan;
550
555
  //#endregion
551
556
  //#region src/core/define.d.ts
552
- interface DefineSupabaseOptions {
557
+ interface SupabaseOptions {
553
558
  /** Clock used by plugins (timestamps, soft delete). */
554
- readonly now?: () => Date;
559
+ readonly now?: () => Temporal.Instant;
555
560
  /** Extra error mappers, run before plugin mappers. */
556
561
  readonly errors?: readonly ErrorMapper[];
557
562
  /** Receives errors from event handlers, hooks and cache adapters. Defaults to `console`. */
558
563
  readonly logger?: Logger;
559
- /** RPCs that change tables, keyed by function name. Prefer `sb.defineRpc()`. */
564
+ /** RPCs that change tables, keyed by function name. Prefer `betterSupabase.defineRpc()`. */
560
565
  readonly rpc?: Readonly<Record<string, RpcDefinition>>;
561
- /** Builds the error `.orThrow()` throws. Prefer `sb.mapError()`. */
566
+ /** Builds the error `.orThrow()` throws. Prefer `betterSupabase.mapError()`. */
562
567
  readonly throwAs?: ThrowMapper;
563
- /** Validates verified JWT claims on the server. Prefer `sb.claims()`, which also types them. */
568
+ /** Validates verified JWT claims on the server. Prefer `betterSupabase.claims()`, which also types them. */
564
569
  readonly claims?: StandardSchemaV1;
565
- /** Parses `user_metadata` into `session.profile`. Prefer `sb.userMetadata()`, which also types it. */
570
+ /** Parses `user_metadata` into `session.profile`. Prefer `betterSupabase.userMetadata()`, which also types it. */
566
571
  readonly userMetadata?: StandardSchemaV1;
567
572
  /**
568
573
  * PostgREST's `db-max-rows`: the most rows one read returns. An unbounded
@@ -593,8 +598,8 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
593
598
  readonly schema: Schema<M, D, F>;
594
599
  readonly plugins: readonly AnyPlugin[];
595
600
  readonly events: EventHub;
596
- readonly options: DefineSupabaseOptions;
597
- constructor(schema: Schema<M, D, F>, plugins?: readonly AnyPlugin[], options?: DefineSupabaseOptions, events?: EventHub);
601
+ readonly options: SupabaseOptions;
602
+ constructor(schema: Schema<M, D, F>, plugins?: readonly AnyPlugin[], options?: SupabaseOptions, events?: EventHub);
598
603
  get meta(): SchemaMeta;
599
604
  /** The schema set by `claims()`; its output types `session.claims`. */
600
605
  get claimsSchema(): StandardSchemaV1<unknown, C> | undefined;
@@ -606,7 +611,7 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
606
611
  * A token that fails it resolves to `{ kind: 'invalid', reason: 'claims' }`.
607
612
  *
608
613
  * ```ts
609
- * const sb = defineSupabase(schema).claims(z.object({ tenant_id: z.uuid() }));
614
+ * const betterSupabase = defineSupabase(schema).claims(z.object({ tenant_id: z.uuid() }));
610
615
  * ```
611
616
  */
612
617
  claims<S extends StandardSchemaV1>(schema: S): BetterSupabase<M, D, F, E, StandardSchemaV1.InferOutput<S>, P>;
@@ -619,7 +624,7 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
619
624
  * the verified claims, never from `profile`.
620
625
  *
621
626
  * ```ts
622
- * const sb = defineSupabase(schema).userMetadata(z.object({ display_name: z.string() }));
627
+ * const betterSupabase = defineSupabase(schema).userMetadata(z.object({ display_name: z.string() }));
623
628
  * ```
624
629
  */
625
630
  userMetadata<S extends StandardSchemaV1>(schema: S): BetterSupabase<M, D, F, E, C, StandardSchemaV1.InferOutput<S>>;
@@ -629,13 +634,13 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
629
634
  * Results themselves keep their `DbError`.
630
635
  *
631
636
  * ```ts
632
- * const sb = defineSupabase(schema).mapError((error) => new AppError(error));
637
+ * const betterSupabase = defineSupabase(schema).mapError((error) => new AppError(error));
633
638
  * ```
634
639
  */
635
640
  mapError(mapper: (error: DbError) => unknown): BetterSupabase<M, D, F, E, C, P>;
636
641
  /**
637
642
  * Builds serializable `QuerySpec`s with the same arguments and result types
638
- * as the repository: `sb.spec.customers.findMany({ select: ['id'] })`.
643
+ * as the repository: `betterSupabase.spec.customers.findMany({ select: ['id'] })`.
639
644
  */
640
645
  get spec(): Specs<M, E>;
641
646
  /** App keys of every table a spec reads; mutations of any of them make it stale. */
@@ -647,7 +652,7 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
647
652
  * invalidate them after it succeeds.
648
653
  *
649
654
  * ```ts
650
- * sb.defineRpc('archive_customer', { invalidates: ['customers', 'notes'] });
655
+ * betterSupabase.defineRpc('archive_customer', { invalidates: ['customers', 'notes'] });
651
656
  * ```
652
657
  */
653
658
  defineRpc(name: Extract<keyof F, string>, options: {
@@ -671,9 +676,9 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
671
676
  * Creates the data-layer definition from the generated `schema`.
672
677
  *
673
678
  * ```ts
674
- * export const sb = defineSupabase(schema).use(timestamps()).use(softDelete());
679
+ * export const betterSupabase = defineSupabase(schema).use(timestamps()).use(softDelete());
675
680
  * ```
676
681
  */
677
- declare function defineSupabase<M extends AnyModels, D, F extends AnyFunctions>(schema: Schema<M, D, F>, options?: DefineSupabaseOptions): BetterSupabase<M, D, F>;
682
+ declare function defineSupabase<M extends AnyModels, D, F extends AnyFunctions>(schema: Schema<M, D, F>, options?: SupabaseOptions): BetterSupabase<M, D, F>;
678
683
  //#endregion
679
- export { Specs as $, RpcOptions as A, ReadSet as B, FindExt as C, WhereInput as Ct, Repository as D, PageOf as E, EMPTY_STATS as F, ReadSetParams as G, ReadSetParamType as H, StatsRecorder as I, isReadSet as J, ReadSetResult as K, recordStats as L, UpsertArgs as M, WriteArgs as N, RepositoryOf as O, DbStats as P, ReadMethod as Q, SearchArgs as R, DeleteExt as S, SortDirection as St, OffsetPageArgs as T, ReadSetParamTypes as U, ReadSetOptions as V, ReadSetParamValue as W, InferResult as X, readSetTables as Y, QuerySpec as Z, CursorPage as _, OrderByInput as _t, defineSupabase as a, AggregateRow as at, DbHelpers as b, RelationMeasureArg as bt, postgrestExecutor as c, FieldFilter as ct, MemoryCache as d, IncludeArg as dt, TableSpecs as et, cacheTargetOf as f, IncludeArgs as ft, ConflictTarget as g, OrderByArg as gt, rpcCacheTargets as h, NumericMeasureArg as ht, RpcDefinition as i, AggregateResult as it, UpdateArgs as j, Returned as k, CacheAdapter as l, FindFirstArgs as lt, rowKey as m, MeasureKey as mt, ConnectOptions as n, specTables as nt, PostgrestClientLike as o, CountArg as ot, memoryCache as p, MeasureArg as pt, defineReadSet as q, DefineSupabaseOptions as r, AggregateArgs as rt, explainPostgrest as s, CountArgs as st, BetterSupabase as t, isQuerySpec as tt, CacheTarget as u, FindManyArgs as ut, CursorPageArgs as v, Payload as vt, OffsetPage as w, DeleteArgs as x, SelectArg as xt, Db as y, ReadArgs as yt, InferReadSetParams as z };
684
+ export { Specs as $, RpcOptions as A, ReadSet as B, FindExt as C, WhereInput as Ct, Repository as D, PageOf as E, EMPTY_STATS as F, ReadSetParams as G, ReadSetParamType as H, StatsRecorder as I, isReadSet as J, ReadSetResult as K, recordStats as L, UpsertArgs as M, WriteArgs as N, RepositoryOf as O, DbStats as P, ReadMethod as Q, SearchArgs as R, DeleteExt as S, SortDirection as St, OffsetPageArgs as T, ReadSetParamTypes as U, ReadSetOptions as V, ReadSetParamValue as W, InferResult as X, readSetTables as Y, QuerySpec as Z, CursorPage as _, OrderByInput as _t, defineSupabase as a, AggregateRow as at, DbHelpers as b, RelationMeasureArg as bt, postgrestExecutor as c, FieldFilter as ct, MemoryCache as d, IncludeArg as dt, TableSpecs as et, cacheTargetOf as f, IncludeArgs as ft, ConflictTarget as g, OrderByArg as gt, rpcCacheTargets as h, NumericMeasureArg as ht, SupabaseOptions as i, AggregateResult as it, UpdateArgs as j, Returned as k, CacheAdapter as l, FindFirstArgs as lt, rowKey as m, MeasureKey as mt, ConnectOptions as n, specTables as nt, PostgrestClientLike as o, CountArg as ot, memoryCache as p, MeasureArg as pt, defineReadSet as q, RpcDefinition as r, AggregateArgs as rt, explainPostgrest as s, CountArgs as st, BetterSupabase as t, isQuerySpec as tt, CacheTarget as u, FindManyArgs as ut, CursorPageArgs as v, Payload as vt, OffsetPage as w, DeleteArgs as x, SelectArg as xt, Db as y, ReadArgs as yt, InferReadSetParams as z };
@@ -1,7 +1,7 @@
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 { d as ServerContext, f as ServerOptions, l as BetterServer, n as GuardOptions } from "../respond-Dne1ARSa.js";
4
- 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 { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-DgIbdrt8.js";
4
+ import { a as ResourceRouteOptions } from "../resource-BJcaIfxi.js";
5
5
  //#region src/edge/index.d.ts
6
6
  export interface CorsOptions {
7
7
  /** Allowed origins, or `*`. Defaults to `*`. */
@@ -17,27 +17,23 @@ export interface EdgeOptions 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 HandlerOptions extends GuardOptions {
21
- /** Refresh an expired cookie session and send the new cookies. */
22
- readonly refresh?: boolean;
23
- }
24
20
  export type EdgeHandler = (request: Request) => Promise<Response>;
25
21
  export type ResourceMap<M extends AnyModels> = { readonly [T in TableKey<M>]?: ResourceRouteOptions<M, T> | true; };
26
- export interface ResourcesOptions extends HandlerOptions {
22
+ export interface ResourcesOptions extends MiddlewareOptions {
27
23
  /** Path before the resources, e.g. `/api` (Supabase: `/<function-name>`). */
28
24
  readonly basePath?: string;
29
25
  }
30
- export interface BetterEdge<M extends AnyModels, F extends AnyFunctions, E> extends BetterServer<M, F, E> {
26
+ export interface BetterEdge<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> extends BetterServer<M, F, E, C, P> {
31
27
  /**
32
28
  * A fetch handler (`Deno.serve`, Workers `fetch`) running as the caller.
33
29
  * `Result`s become JSON or Problem Details; `undefined` becomes 204.
34
30
  */
35
- handler(fn: (request: Request, ctx: ServerContext<M, F, E>) => unknown, options?: HandlerOptions): EdgeHandler;
31
+ handler(fn: (request: Request, ctx: ServerContext<M, F, E, C, P>) => unknown, options?: MiddlewareOptions): EdgeHandler;
36
32
  /** REST resources matching `createOpenApi`, e.g. `Deno.serve(bs.resources({ customers: true }))`. */
37
33
  resources(map: ResourceMap<M>, options?: ResourcesOptions): EdgeHandler;
38
34
  }
39
35
  export declare const SUPABASE_CORS_HEADERS: readonly string[];
40
36
  /** Fetch-handler integration for Supabase Edge Functions, Deno, Bun and Workers. */
41
- export declare function createEdge<M extends AnyModels, D, F extends AnyFunctions, E>(sb: BetterSupabase<M, D, F, E>, options?: EdgeOptions): BetterEdge<M, F, E>;
37
+ export declare function createEdge<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: EdgeOptions): BetterEdge<M, F, E, C, P>;
42
38
  //#endregion
43
- export type { GuardOptions, ResourceRouteOptions };
39
+ export type { GuardOptions, MiddlewareOptions, ResourceRouteOptions };
@@ -1,7 +1,7 @@
1
- import { n as dbError } 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 } 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
  //#region src/edge/index.ts
6
6
  const SUPABASE_CORS_HEADERS = [
7
7
  "authorization",
@@ -9,15 +9,11 @@ const SUPABASE_CORS_HEADERS = [
9
9
  "apikey",
10
10
  "content-type"
11
11
  ];
12
- function corsHeaders(request, cors) {
13
- const origin = request.headers.get("origin");
12
+ /** The CORS headers for a request's origin; the fixed ones are joined once. */
13
+ function corsFor(cors) {
14
14
  const allowed = cors.origin ?? "*";
15
- let value;
16
- if (allowed === "*") value = "*";
17
- else if (origin && (typeof allowed === "string" ? [allowed] : allowed).includes(origin)) value = origin;
18
- if (!value) return void 0;
19
- return {
20
- "access-control-allow-origin": value,
15
+ const origins = new Set(typeof allowed === "string" ? [allowed] : allowed);
16
+ const fixed = {
21
17
  "access-control-allow-headers": (cors.headers ?? SUPABASE_CORS_HEADERS).join(", "),
22
18
  "access-control-allow-methods": (cors.methods ?? [
23
19
  "GET",
@@ -26,8 +22,21 @@ function corsHeaders(request, cors) {
26
22
  "DELETE",
27
23
  "OPTIONS"
28
24
  ]).join(", "),
29
- ...cors.maxAge === void 0 ? {} : { "access-control-max-age": String(cors.maxAge) },
30
- ...value === "*" ? {} : { vary: "origin" }
25
+ ...cors.maxAge === void 0 ? {} : { "access-control-max-age": String(cors.maxAge) }
26
+ };
27
+ const any = {
28
+ "access-control-allow-origin": "*",
29
+ ...fixed
30
+ };
31
+ return (request) => {
32
+ if (allowed === "*") return any;
33
+ const origin = request.headers.get("origin");
34
+ if (!origin || !origins.has(origin)) return;
35
+ return {
36
+ "access-control-allow-origin": origin,
37
+ ...fixed,
38
+ vary: "origin"
39
+ };
31
40
  };
32
41
  }
33
42
  function withHeaders(response, headers) {
@@ -41,20 +50,23 @@ function withHeaders(response, headers) {
41
50
  return target;
42
51
  }
43
52
  /** Fetch-handler integration for Supabase Edge Functions, Deno, Bun and Workers. */
44
- function createEdge(sb, options = {}) {
45
- const server = createServer(sb, options);
53
+ function createEdge(betterSupabase, options = {}) {
54
+ const server = createServer(betterSupabase, options);
46
55
  const expose = options.exposeErrors ?? defaultExpose();
47
56
  const cors = options.cors === true ? {} : options.cors === false ? void 0 : options.cors;
48
- const serve = (run, handlerOptions) => {
57
+ const corsHeaders = cors ? corsFor(cors) : void 0;
58
+ const serve = (run, handlerOptions, early) => {
49
59
  return async (request) => {
50
- const extra = cors ? corsHeaders(request, cors) : void 0;
60
+ const extra = corsHeaders?.(request);
51
61
  if (cors && request.method === "OPTIONS") return new Response(null, {
52
62
  status: 204,
53
63
  headers: extra ?? {}
54
64
  });
65
+ const answered = early?.(request);
66
+ if (answered) return extra ? withHeaders(answered, extra) : answered;
55
67
  const ctx = await server.context(request, { refresh: handlerOptions.refresh ?? false });
56
68
  const instance = new URL(request.url).pathname;
57
- const denied = guard(ctx.auth, handlerOptions.allow, handlerOptions.aal);
69
+ const denied = guard(ctx.auth, handlerOptions.allow, handlerOptions.aal, handlerOptions.scopes);
58
70
  let response;
59
71
  try {
60
72
  response = denied ? problemResponse(denied, {
@@ -83,19 +95,33 @@ function createEdge(sb, options = {}) {
83
95
  const handlers = /* @__PURE__ */ new Map();
84
96
  for (const [table, resource] of Object.entries(map)) {
85
97
  if (!resource) continue;
86
- handlers.set(table, defineResource(sb, table, resource === true ? {} : resource));
98
+ handlers.set(table, defineResource(betterSupabase, table, resource === true ? {} : resource));
87
99
  }
88
- return serve(async (request, ctx) => {
100
+ const routes = /* @__PURE__ */ new WeakMap();
101
+ const notFound = (request) => {
89
102
  const { pathname } = new URL(request.url);
90
- const instance = pathname;
91
103
  const [table, id, extra] = (pathname.startsWith(`${base}/`) ? pathname.slice(base.length + 1) : void 0)?.split("/") ?? [];
92
104
  const handler = table ? handlers.get(table) : void 0;
93
- if (!handler || extra !== void 0 || id !== void 0 && !handler.keyParam) return problemResponse(dbError("not_found", `No route for ${pathname}`), { instance });
94
- return handler.handle(request, ctx.db, id === void 0 || id === "" ? void 0 : decodeURIComponent(id), {
105
+ if (!handler || extra !== void 0 || id !== void 0 && !handler.keyParam) return problemResponse(dbError("not_found", `No route for ${pathname}`), { instance: pathname });
106
+ let key;
107
+ try {
108
+ key = id === void 0 || id === "" ? void 0 : decodeURIComponent(id);
109
+ } catch {
110
+ return problemResponse(dbError("invalid_request", `Malformed id in ${pathname}`), { instance: pathname });
111
+ }
112
+ routes.set(request, {
113
+ handler,
114
+ id: key,
115
+ instance: pathname
116
+ });
117
+ };
118
+ return serve((request, ctx) => {
119
+ const { handler, id, instance } = routes.get(request);
120
+ return handler.handle(request, ctx.db, id, {
95
121
  instance,
96
122
  expose
97
123
  });
98
- }, resourcesOptions);
124
+ }, resourcesOptions, notFound);
99
125
  }
100
126
  });
101
127
  }
@@ -1,4 +1,4 @@
1
- import { t as AuthSession } from "./view-D1s0wa0T.js";
1
+ import { t as AuthSession } from "./view-B64o81wp.js";
2
2
  //#region src/auth/entitlements.d.ts
3
3
  /**
4
4
  * One entry of the `memberships` claim, in PermDock's shape. PermDock strips
@@ -25,7 +25,7 @@ interface MembershipClaim {
25
25
  }
26
26
  /**
27
27
  * Entitlement keys of the `features` claim: the literal union when
28
- * `sb.claims(schema)` declares one (`z.enum([...])`), otherwise `string`.
28
+ * `betterSupabase.claims(schema)` declares one (`z.enum([...])`), otherwise `string`.
29
29
  */
30
30
  type EntitlementKey<C> = C extends {
31
31
  readonly features?: infer F;
package/dist/env/index.js CHANGED
@@ -1,2 +1,204 @@
1
- import { a as parseEnv, i as loadEnv, n as EnvValidationError, o as publicEnv, r as envSchema, s as toServerEnv, t as ENV_VARIABLES } from "../env-BEToab0I.js";
1
+ //#region src/env/index.ts
2
+ const PREFIXES = [
3
+ "",
4
+ "NEXT_PUBLIC_",
5
+ "VITE_",
6
+ "PUBLIC_",
7
+ "EXPO_PUBLIC_",
8
+ "NUXT_PUBLIC_"
9
+ ];
10
+ const ENV_VARIABLES = {
11
+ url: PREFIXES.map((prefix) => `${prefix}SUPABASE_URL`),
12
+ publishableKey: PREFIXES.flatMap((prefix) => [`${prefix}SUPABASE_PUBLISHABLE_KEY`, `${prefix}SUPABASE_PUBLISHABLE_DEFAULT_KEY`]),
13
+ secretKey: ["SUPABASE_SECRET_KEY"],
14
+ dbUrl: ["SUPABASE_DB_URL", "DATABASE_URL"],
15
+ jwksUrl: ["SUPABASE_JWKS_URL"],
16
+ readUrl: ["SUPABASE_READ_URL"]
17
+ };
18
+ const LOOPBACK = /^(localhost|127(?:\.\d{1,3}){3}|\[::1\])$/;
19
+ const HOSTED = /^([a-z0-9]{20})\.supabase\.co$/;
20
+ var EnvValidationError = class extends Error {
21
+ name = "EnvValidationError";
22
+ issues;
23
+ constructor(issues) {
24
+ super(`Invalid Supabase environment:\n${issues.map((issue) => ` - ${issue.variables[0] ?? "env"}: ${issue.message}`).join("\n")}`);
25
+ this.issues = issues;
26
+ }
27
+ };
28
+ function first(source, names) {
29
+ for (const name of names) {
30
+ const value = source[name]?.trim();
31
+ if (value) return value;
32
+ }
33
+ }
34
+ /** `SUPABASE_*_KEYS` JSON objects, as `@supabase/server` reads them. */
35
+ function keySet(source, name, kind, issues) {
36
+ const raw = source[name];
37
+ if (!raw) return void 0;
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(raw);
41
+ } catch {
42
+ parsed = void 0;
43
+ }
44
+ const entries = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? Object.entries(parsed) : [];
45
+ if (entries.length === 0 || entries.some(([, value]) => typeof value !== "string")) {
46
+ issues.push({
47
+ variables: [name],
48
+ message: "must be a JSON object of key names to keys"
49
+ });
50
+ return;
51
+ }
52
+ const keys = {};
53
+ for (const [key, value] of entries) if (checkKey(value, kind, [name], issues)) keys[key] = value;
54
+ return keys;
55
+ }
56
+ function preferred(keys) {
57
+ if (!keys) return void 0;
58
+ return keys["default"] ?? Object.values(keys)[0];
59
+ }
60
+ function checkUrl(value, variables, issues) {
61
+ let url;
62
+ try {
63
+ url = new URL(value);
64
+ } catch {
65
+ issues.push({
66
+ variables,
67
+ message: "is not a valid URL"
68
+ });
69
+ return;
70
+ }
71
+ if (url.protocol === "https:") return url;
72
+ if (url.protocol === "http:" && LOOPBACK.test(url.hostname)) return url;
73
+ issues.push({
74
+ variables,
75
+ message: "must use https (http is only allowed for localhost / 127.0.0.1 / [::1])"
76
+ });
77
+ }
78
+ function checkKey(value, kind, variables, issues) {
79
+ if (value.startsWith(`sb_${kind}_`)) return true;
80
+ if (value.startsWith("eyJ")) issues.push({
81
+ variables,
82
+ message: `is a legacy JWT key; use the new sb_${kind}_ key (Project Settings > API Keys)`
83
+ });
84
+ else if (value.startsWith(kind === "publishable" ? "sb_secret_" : "sb_publishable_")) issues.push({
85
+ variables,
86
+ message: kind === "publishable" ? "holds a secret key; never expose sb_secret_ keys as publishable" : "holds a publishable key, not a secret key"
87
+ });
88
+ else issues.push({
89
+ variables,
90
+ message: `must start with sb_${kind}_`
91
+ });
92
+ return false;
93
+ }
94
+ /**
95
+ * Reads and validates Supabase settings. Accepts the `SUPABASE_`,
96
+ * `NEXT_PUBLIC_`, `VITE_`, `PUBLIC_`, `EXPO_PUBLIC_` and `NUXT_PUBLIC_`
97
+ * spellings. Issues name variables, never values.
98
+ */
99
+ function parseEnv(source, options = {}) {
100
+ const issues = [];
101
+ const required = new Set(options.require ?? []);
102
+ const rawUrl = first(source, ENV_VARIABLES.url);
103
+ const url = rawUrl ? checkUrl(rawUrl, ENV_VARIABLES.url, issues) : void 0;
104
+ if (!rawUrl) issues.push({
105
+ variables: ENV_VARIABLES.url,
106
+ message: "is not set"
107
+ });
108
+ const publishableKeys = keySet(source, "SUPABASE_PUBLISHABLE_KEYS", "publishable", issues);
109
+ const singlePublishable = first(source, ENV_VARIABLES.publishableKey);
110
+ const publishableKey = singlePublishable ?? preferred(publishableKeys);
111
+ if (!publishableKey) issues.push({
112
+ variables: ENV_VARIABLES.publishableKey,
113
+ message: "is not set"
114
+ });
115
+ else if (singlePublishable) checkKey(publishableKey, "publishable", ENV_VARIABLES.publishableKey, issues);
116
+ const namedSecrets = keySet(source, "SUPABASE_SECRET_KEYS", "secret", issues);
117
+ const singleSecret = first(source, ENV_VARIABLES.secretKey);
118
+ const secretKey = singleSecret ?? preferred(namedSecrets);
119
+ if (singleSecret) checkKey(singleSecret, "secret", ENV_VARIABLES.secretKey, issues);
120
+ else if (!secretKey && required.has("secretKey")) issues.push({
121
+ variables: ENV_VARIABLES.secretKey,
122
+ message: "is not set"
123
+ });
124
+ const dbUrl = first(source, ENV_VARIABLES.dbUrl);
125
+ if (dbUrl && !/^postgres(ql)?:\/\//.test(dbUrl)) issues.push({
126
+ variables: ENV_VARIABLES.dbUrl,
127
+ message: "must be a postgres:// connection string"
128
+ });
129
+ else if (!dbUrl && required.has("dbUrl")) issues.push({
130
+ variables: ENV_VARIABLES.dbUrl,
131
+ message: "is not set"
132
+ });
133
+ const rawJwks = first(source, ENV_VARIABLES.jwksUrl);
134
+ const jwksOverride = rawJwks ? checkUrl(rawJwks, ENV_VARIABLES.jwksUrl, issues) : void 0;
135
+ const rawRead = first(source, ENV_VARIABLES.readUrl);
136
+ const readUrl = rawRead ? checkUrl(rawRead, ENV_VARIABLES.readUrl, issues) : void 0;
137
+ if (issues.length > 0 || !url || !publishableKey) return {
138
+ ok: false,
139
+ issues
140
+ };
141
+ const base = url.href.replace(/\/+$/, "");
142
+ const projectRef = HOSTED.exec(url.hostname)?.[1];
143
+ return {
144
+ ok: true,
145
+ env: {
146
+ url: base,
147
+ publishableKey,
148
+ jwksUrl: jwksOverride ?? new URL(`${base}/auth/v1/.well-known/jwks.json`),
149
+ ...secretKey ? {
150
+ secretKey,
151
+ secretKeys: {
152
+ ...namedSecrets,
153
+ default: secretKey
154
+ }
155
+ } : {},
156
+ ...dbUrl ? { dbUrl } : {},
157
+ ...projectRef ? { projectRef } : {},
158
+ ...readUrl ? { readUrl: readUrl.href.replace(/\/+$/, "") } : {}
159
+ }
160
+ };
161
+ }
162
+ function processEnv() {
163
+ return globalThis.process?.env ?? {};
164
+ }
165
+ /** Like `parseEnv`, but throws `EnvValidationError`. Reads `process.env` by default. */
166
+ function loadEnv(source = processEnv(), options = {}) {
167
+ const result = parseEnv(source, options);
168
+ if (!result.ok) throw new EnvValidationError(result.issues);
169
+ return result.env;
170
+ }
171
+ /** The env validator as a Standard Schema, for t3-env, framework config or any validator slot. */
172
+ function envSchema(options = {}) {
173
+ return { "~standard": {
174
+ version: 1,
175
+ vendor: "better-supabase",
176
+ validate(value) {
177
+ if (typeof value !== "object" || value === null) return { issues: [{ message: "Expected an environment object" }] };
178
+ const result = parseEnv(value, options);
179
+ if (result.ok) return { value: result.env };
180
+ return { issues: result.issues.map((issue) => ({
181
+ message: `${issue.variables[0] ?? "env"} ${issue.message}`,
182
+ path: issue.variables.slice(0, 1)
183
+ })) };
184
+ }
185
+ } };
186
+ }
187
+ /** The parts that are safe in client bundles. */
188
+ function publicEnv(env) {
189
+ return {
190
+ url: env.url,
191
+ publishableKey: env.publishableKey
192
+ };
193
+ }
194
+ /** Converts to `@supabase/server`'s `SupabaseEnv` (the `env` option of `withSupabase`). */
195
+ function toServerEnv(env) {
196
+ return {
197
+ url: env.url,
198
+ publishableKeys: { default: env.publishableKey },
199
+ secretKeys: env.secretKeys ?? (env.secretKey ? { default: env.secretKey } : {}),
200
+ jwks: env.jwksUrl
201
+ };
202
+ }
203
+ //#endregion
2
204
  export { ENV_VARIABLES, EnvValidationError, envSchema, loadEnv, parseEnv, publicEnv, toServerEnv };
@@ -41,7 +41,7 @@ function isDbError(value) {
41
41
  }
42
42
  /**
43
43
  * The `DbError` in a `DbError`, a `DbException`, or an error whose `cause`
44
- * is a `DbError` (what `sb.mapError()` mappers should set).
44
+ * is a `DbError` (what `betterSupabase.mapError()` mappers should set).
45
45
  */
46
46
  function dbErrorOf(value) {
47
47
  if (value instanceof DbException) return value.error;
@@ -1,2 +1,2 @@
1
- import { a as HttpMode, c as RowEventData, d as httpSink, f as isCloudEvent, i as ForwardOptions, l as forwardMutations, m as toHttp, n as CloudEventOptions, o as HttpSinkOptions, p as toCloudEvents, r as EventSink, s as ROW_EVENT_TYPES, t as CloudEvent, u as fromHttp } from "../index-Ciu5Xlml.js";
1
+ import { a as HttpMode, c as RowEventData, d as httpSink, f as isCloudEvent, i as ForwardOptions, l as forwardMutations, m as toHttp, n as CloudEventOptions, o as HttpSinkOptions, p as toCloudEvents, r as EventSink, s as ROW_EVENT_TYPES, t as CloudEvent, u as fromHttp } from "../index-D5IfUIDh.js";
2
2
  export { CloudEvent, CloudEventOptions, EventSink, ForwardOptions, HttpMode, HttpSinkOptions, ROW_EVENT_TYPES, RowEventData, forwardMutations, fromHttp, httpSink, isCloudEvent, toCloudEvents, toHttp };