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,11 +1,11 @@
1
1
  /// <reference lib="esnext.temporal" />
2
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-DynmIWhq.js";
4
- import { p as DbError, s as ThrowMapper, t as AsyncResult, v as ErrorMapper } from "./result-c2OYgCV2.js";
5
- import { a as EventHub, f as Logger, i as EventHandler, o as EventName, s as MutationNotice, u as RpcNotice } from "./events-Do8jXh4D.js";
6
- import { a as ExtensionOf, g as WithExtension, h as RequestContext, n as AnyPlugin, r as ApplyExtension } from "./plugin-DVRB8qNE.js";
7
- import { t as StandardSchemaV1 } from "./standard-eudBiRk1.js";
8
- import { i as PostgrestPlan } from "./postgrest-DmBlevh-.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";
9
9
  //#region src/ir/args.d.ts
10
10
  interface BaseOps<V> {
11
11
  readonly eq?: V;
@@ -178,13 +178,17 @@ type AggregateResult<M extends AnyModels, T extends keyof M, A> = A extends {
178
178
  readonly groupBy: readonly unknown[];
179
179
  } ? AggregateRow<M, T, A>[] : AggregateRow<M, T, A>;
180
180
  /** The row type returned for read arguments `A` on table `T`. */
181
- 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>;
182
186
  //#endregion
183
187
  //#region src/core/spec.d.ts
184
188
  type ReadMethod = "findMany" | "findFirst" | "findUnique" | "findById" | "count" | "aggregate" | "exists" | "paginate";
185
189
  declare const resultType: unique symbol;
186
190
  /**
187
- * 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
188
192
  * `db.$run(spec)`, send it from a Server Component to the client, or hand it
189
193
  * to `/query` and `/next`. Args never carry a `signal`.
190
194
  */
@@ -269,7 +273,7 @@ interface ReadSetOptions<P extends ReadSetParamTypes> {
269
273
  *
270
274
  * ```ts
271
275
  * export const appChrome = defineReadSet(
272
- * sb,
276
+ * betterSupabase,
273
277
  * 'app_chrome',
274
278
  * { params: { userId: 'uuid' } },
275
279
  * (s, p) => ({
@@ -282,7 +286,7 @@ interface ReadSetOptions<P extends ReadSetParamTypes> {
282
286
  * `p` holds placeholders, not values: pass them straight into `where` (or
283
287
  * `in`), where the function reads them from its `p jsonb` argument.
284
288
  */
285
- 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>;
286
290
  declare function isReadSet(value: unknown): value is ReadSet;
287
291
  /** App keys of every table the set reads. */
288
292
  declare function readSetTables(set: ReadSet, meta?: SchemaMeta): string[];
@@ -385,7 +389,7 @@ type PageOf<M extends AnyModels, T extends keyof M, A> = A extends {
385
389
  readonly after: unknown;
386
390
  } ? CursorPage<Payload<M, T, A>> : OffsetPage<Payload<M, T, A>>;
387
391
  interface Repository<M extends AnyModels, T extends TableKey<M>, E = unknown> {
388
- readonly $table: T;
392
+ readonly $tableName: T;
389
393
  readonly $meta: TableMeta;
390
394
  findMany<const A extends FindManyArgs<M, T> & FindExt<E, M, T>>(args?: A): AsyncResult<Payload<M, T, A>[]>;
391
395
  findFirst<const A extends FindFirstArgs<M, T> & FindExt<E, M, T>>(args?: A): AsyncResult<Payload<M, T, A> | null>;
@@ -471,7 +475,7 @@ interface DbHelpers<M extends AnyModels, F extends AnyFunctions, E, C> {
471
475
  $table<T extends TableKey<M>>(name: T): RepositoryOf<M, T, E>;
472
476
  /** Calls, waves, tables and time for everything run through this `db`. */
473
477
  $stats(): DbStats;
474
- /** Runs a `QuerySpec` built with `sb.spec`. */
478
+ /** Runs a `QuerySpec` built with `betterSupabase.spec`. */
475
479
  $run<S extends QuerySpec<TableKey<M>>>(spec: S, options?: {
476
480
  readonly signal?: AbortSignal;
477
481
  }): AsyncResult<InferResult<S>>;
@@ -516,7 +520,7 @@ interface CacheTarget {
516
520
  /**
517
521
  * Invalidates cached reads after a mutation. First-party adapters:
518
522
  * `nextCache()` (Next.js cache tags) and `queryCache(client)` (TanStack
519
- * Query). Attach one with `sb.cache(adapter)`; prove custom ones with
523
+ * Query). Attach one with `betterSupabase.cache(adapter)`; prove custom ones with
520
524
  * `testCacheAdapter`.
521
525
  */
522
526
  interface CacheAdapter {
@@ -550,20 +554,20 @@ declare function postgrestExecutor(client: PostgrestClientLike): Executor;
550
554
  declare function explainPostgrest(op: Operation): PostgrestPlan;
551
555
  //#endregion
552
556
  //#region src/core/define.d.ts
553
- interface DefineSupabaseOptions {
557
+ interface SupabaseOptions {
554
558
  /** Clock used by plugins (timestamps, soft delete). */
555
559
  readonly now?: () => Temporal.Instant;
556
560
  /** Extra error mappers, run before plugin mappers. */
557
561
  readonly errors?: readonly ErrorMapper[];
558
562
  /** Receives errors from event handlers, hooks and cache adapters. Defaults to `console`. */
559
563
  readonly logger?: Logger;
560
- /** RPCs that change tables, keyed by function name. Prefer `sb.defineRpc()`. */
564
+ /** RPCs that change tables, keyed by function name. Prefer `betterSupabase.defineRpc()`. */
561
565
  readonly rpc?: Readonly<Record<string, RpcDefinition>>;
562
- /** Builds the error `.orThrow()` throws. Prefer `sb.mapError()`. */
566
+ /** Builds the error `.orThrow()` throws. Prefer `betterSupabase.mapError()`. */
563
567
  readonly throwAs?: ThrowMapper;
564
- /** 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. */
565
569
  readonly claims?: StandardSchemaV1;
566
- /** 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. */
567
571
  readonly userMetadata?: StandardSchemaV1;
568
572
  /**
569
573
  * PostgREST's `db-max-rows`: the most rows one read returns. An unbounded
@@ -594,8 +598,8 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
594
598
  readonly schema: Schema<M, D, F>;
595
599
  readonly plugins: readonly AnyPlugin[];
596
600
  readonly events: EventHub;
597
- readonly options: DefineSupabaseOptions;
598
- 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);
599
603
  get meta(): SchemaMeta;
600
604
  /** The schema set by `claims()`; its output types `session.claims`. */
601
605
  get claimsSchema(): StandardSchemaV1<unknown, C> | undefined;
@@ -607,7 +611,7 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
607
611
  * A token that fails it resolves to `{ kind: 'invalid', reason: 'claims' }`.
608
612
  *
609
613
  * ```ts
610
- * const sb = defineSupabase(schema).claims(z.object({ tenant_id: z.uuid() }));
614
+ * const betterSupabase = defineSupabase(schema).claims(z.object({ tenant_id: z.uuid() }));
611
615
  * ```
612
616
  */
613
617
  claims<S extends StandardSchemaV1>(schema: S): BetterSupabase<M, D, F, E, StandardSchemaV1.InferOutput<S>, P>;
@@ -620,7 +624,7 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
620
624
  * the verified claims, never from `profile`.
621
625
  *
622
626
  * ```ts
623
- * const sb = defineSupabase(schema).userMetadata(z.object({ display_name: z.string() }));
627
+ * const betterSupabase = defineSupabase(schema).userMetadata(z.object({ display_name: z.string() }));
624
628
  * ```
625
629
  */
626
630
  userMetadata<S extends StandardSchemaV1>(schema: S): BetterSupabase<M, D, F, E, C, StandardSchemaV1.InferOutput<S>>;
@@ -630,13 +634,13 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
630
634
  * Results themselves keep their `DbError`.
631
635
  *
632
636
  * ```ts
633
- * const sb = defineSupabase(schema).mapError((error) => new AppError(error));
637
+ * const betterSupabase = defineSupabase(schema).mapError((error) => new AppError(error));
634
638
  * ```
635
639
  */
636
640
  mapError(mapper: (error: DbError) => unknown): BetterSupabase<M, D, F, E, C, P>;
637
641
  /**
638
642
  * Builds serializable `QuerySpec`s with the same arguments and result types
639
- * as the repository: `sb.spec.customers.findMany({ select: ['id'] })`.
643
+ * as the repository: `betterSupabase.spec.customers.findMany({ select: ['id'] })`.
640
644
  */
641
645
  get spec(): Specs<M, E>;
642
646
  /** App keys of every table a spec reads; mutations of any of them make it stale. */
@@ -648,7 +652,7 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
648
652
  * invalidate them after it succeeds.
649
653
  *
650
654
  * ```ts
651
- * sb.defineRpc('archive_customer', { invalidates: ['customers', 'notes'] });
655
+ * betterSupabase.defineRpc('archive_customer', { invalidates: ['customers', 'notes'] });
652
656
  * ```
653
657
  */
654
658
  defineRpc(name: Extract<keyof F, string>, options: {
@@ -672,9 +676,9 @@ declare class BetterSupabase<M extends AnyModels = AnyModels, D = unknown, F ext
672
676
  * Creates the data-layer definition from the generated `schema`.
673
677
  *
674
678
  * ```ts
675
- * export const sb = defineSupabase(schema).use(timestamps()).use(softDelete());
679
+ * export const betterSupabase = defineSupabase(schema).use(timestamps()).use(softDelete());
676
680
  * ```
677
681
  */
678
- 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>;
679
683
  //#endregion
680
- 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
1
  import { N as TableKey, n as AnyModels, t as AnyFunctions } from "../types-DONv9SHN.js";
2
- import { t as BetterSupabase } from "../define-DUbydmJa.js";
3
- import { d as ServerContext, f as ServerOptions, l as BetterServer, n as GuardOptions } from "../respond-DAkPIdTH.js";
4
- import { a as ResourceRouteOptions } from "../resource-CwVgiI5q.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-CGt1ADix.js";
3
- import { i as respond, n as guard, o as createServer, s as extendServer, t as defaultExpose } from "../respond-C44EZAJo.js";
4
- import { t as defineResource } from "../resource-D30rp0GN.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,17 +50,20 @@ 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
69
  const denied = guard(ctx.auth, handlerOptions.allow, handlerOptions.aal, handlerOptions.scopes);
@@ -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-3Po_PVlr.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;
@@ -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-GV77NpRP.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 };
@@ -44,17 +44,17 @@ function toCloudEvents(notice, options) {
44
44
  * Sends a CloudEvent for every mutation to `sink`. Returns a function that
45
45
  * stops forwarding. Use an outbox (SQL kit) when events must not be lost.
46
46
  */
47
- function forwardMutations(sb, sink, options) {
48
- return sb.events.on("mutation", (notice) => {
47
+ function forwardMutations(betterSupabase, sink, options) {
48
+ return betterSupabase.events.on("mutation", (notice) => {
49
49
  if (options.filter && !options.filter(notice)) return;
50
50
  const events = toCloudEvents(notice, {
51
51
  ...options,
52
- meta: sb.meta
52
+ meta: betterSupabase.meta
53
53
  });
54
54
  if (events.length === 0) return;
55
55
  const report = (error) => {
56
56
  (options.onError ?? ((cause) => {
57
- sb.events.logger.error("event sink failed", { cause });
57
+ betterSupabase.events.logger.error("event sink failed", { cause });
58
58
  }))(error, events);
59
59
  };
60
60
  try {
@@ -1,6 +1,6 @@
1
- import { g as Operation } from "./executor-DynmIWhq.js";
2
- import { p as DbError } from "./result-c2OYgCV2.js";
3
- import { h as RequestContext, l as MutationKind } from "./plugin-DVRB8qNE.js";
1
+ import { g as Operation } from "./executor-B5IoUxLE.js";
2
+ import { p as DbError } from "./result-CqEsbgYs.js";
3
+ import { h as RequestContext, l as MutationKind } from "./plugin-bNhvJwRh.js";
4
4
  //#region src/core/logger.d.ts
5
5
  type LogFields = Readonly<Record<string, unknown>>;
6
6
  /**
@@ -37,7 +37,7 @@ interface MutationNotice {
37
37
  readonly rows: readonly Readonly<Record<string, unknown>>[];
38
38
  readonly context: RequestContext;
39
39
  }
40
- /** A successful RPC registered with `sb.defineRpc(name, { invalidates })`. */
40
+ /** A successful RPC registered with `betterSupabase.defineRpc(name, { invalidates })`. */
41
41
  interface RpcNotice {
42
42
  readonly name: string;
43
43
  /** App keys of the tables the function changes. */
@@ -1,5 +1,5 @@
1
1
  import { P as TableMeta, T as RelationMeta, c as Codec } from "./types-DONv9SHN.js";
2
- import { o as Result, v as ErrorMapper } from "./result-c2OYgCV2.js";
2
+ import { o as Result, v as ErrorMapper } from "./result-CqEsbgYs.js";
3
3
  //#region src/ir/types.d.ts
4
4
  /**
5
5
  * The query IR. Every repository call becomes one of these operations; the
@@ -1,6 +1,6 @@
1
- import { c as mapDbError, n as dbError } from "./errors-Bl3rkOzo.js";
2
- import { i as ok, n as err, o as toDbError } from "./result-DWXatkd6.js";
3
- import { t as compileSql } from "./sql-BIgk12ew.js";
1
+ import { c as mapDbError, n as dbError } from "./errors-L0xK41y_.js";
2
+ import { i as ok, n as err, o as toDbError } from "./result-Bj6yt33D.js";
3
+ import { t as compileSql } from "./sql-B34HU2DI.js";
4
4
  //#region src/postgres/executor.ts
5
5
  function isPgError(value) {
6
6
  return typeof value === "object" && value !== null && typeof value.code === "string";
@@ -1,5 +1,5 @@
1
- import { r as Executor } from "./executor-DynmIWhq.js";
2
- import { y as RawDbError } from "./result-c2OYgCV2.js";
1
+ import { r as Executor } from "./executor-B5IoUxLE.js";
2
+ import { y as RawDbError } from "./result-CqEsbgYs.js";
3
3
  //#region src/postgres/executor.d.ts
4
4
  /**
5
5
  * Anything that runs parameterized SQL: `ctx.postgres` from
@@ -1,45 +1,38 @@
1
1
  import { N as TableKey, n as AnyModels, t as AnyFunctions } from "../types-DONv9SHN.js";
2
- import { t as BetterSupabase } from "../define-DUbydmJa.js";
3
- import { r as AuthState } from "../resolve-BRciX2jK.js";
4
- import { d as ServerContext, f as ServerOptions, l as BetterServer, n as GuardOptions } from "../respond-DAkPIdTH.js";
5
- import { a as ResourceRouteOptions } from "../resource-CwVgiI5q.js";
2
+ import { t as BetterSupabase } from "../define-CRS2MRV3.js";
3
+ import { r as AuthState } from "../resolve-BAqQcwMW.js";
4
+ import { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-DgIbdrt8.js";
5
+ import { a as ResourceRouteOptions } from "../resource-BJcaIfxi.js";
6
6
  import { Context, ErrorHandler, Hono, MiddlewareHandler } from "hono";
7
7
  //#region src/hono/index.d.ts
8
8
  /** Hono `Env` with the request's better-supabase context in `c.var`. */
9
- export interface BetterEnv<M extends AnyModels, F extends AnyFunctions, E> {
9
+ export interface HonoEnv<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> {
10
10
  Variables: {
11
- readonly bs: ServerContext<M, F, E>;
12
- readonly db: ServerContext<M, F, E>["db"];
13
- readonly auth: AuthState;
11
+ readonly bs: ServerContext<M, F, E, C, P>;
12
+ readonly db: ServerContext<M, F, E, C, P>["db"];
13
+ readonly auth: AuthState<C, P>;
14
14
  };
15
15
  }
16
16
  export interface HonoOptions extends ServerOptions {
17
17
  /** Include error details in problem responses. Defaults to `NODE_ENV === 'development'`. */
18
18
  readonly exposeErrors?: boolean;
19
19
  }
20
- export interface MiddlewareOptions extends GuardOptions {
21
- /**
22
- * Refresh an expired cookie session and send the new cookies. Only for
23
- * routes browsers call with cookies; bearer tokens never refresh.
24
- */
25
- readonly refresh?: boolean;
26
- }
27
- export interface BetterHono<M extends AnyModels, F extends AnyFunctions, E> extends BetterServer<M, F, E> {
20
+ export interface BetterHono<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> extends BetterServer<M, F, E, C, P> {
28
21
  /** Resolves the caller, enforces `allow` and sets `c.var.bs`, `c.var.db`, `c.var.auth`. */
29
- middleware(options?: MiddlewareOptions): MiddlewareHandler<BetterEnv<M, F, E>>;
22
+ middleware(options?: MiddlewareOptions): MiddlewareHandler<HonoEnv<M, F, E, C, P>>;
30
23
  /** Wraps a handler: `Result`s become JSON or Problem Details, `undefined` becomes 204. */
31
- handle(handler: (c: Context<BetterEnv<M, F, E>>, ctx: ServerContext<M, F, E>) => unknown, options?: {
24
+ handler(fn: (c: Context<HonoEnv<M, F, E, C, P>>, ctx: ServerContext<M, F, E, C, P>) => unknown, options?: {
32
25
  readonly status?: number;
33
- }): (c: Context<BetterEnv<M, F, E>>) => Promise<Response>;
26
+ }): (c: Context<HonoEnv<M, F, E, C, P>>) => Promise<Response>;
34
27
  /** `app.onError(bs.onError)`: `DbException`s (and errors caused by a `DbError`) become Problem Details, others a 500. */
35
- readonly onError: ErrorHandler<BetterEnv<M, F, E>>;
28
+ readonly onError: ErrorHandler<HonoEnv<M, F, E, C, P>>;
36
29
  /**
37
30
  * REST routes for a table matching `createOpenApi`. Mount with
38
31
  * `app.route('/customers', bs.resource('customers'))` behind `middleware()`.
39
32
  */
40
- resource<T extends TableKey<M>>(table: T, options?: ResourceRouteOptions<M, T>): Hono<BetterEnv<M, F, E>>;
33
+ resource<T extends TableKey<M>>(table: T, options?: ResourceRouteOptions<M, T>): Hono<HonoEnv<M, F, E, C, P>>;
41
34
  }
42
35
  /** Hono integration: a server plus middleware, handlers and REST resources. */
43
- export declare function createHono<M extends AnyModels, D, F extends AnyFunctions, E>(sb: BetterSupabase<M, D, F, E>, options?: HonoOptions): BetterHono<M, F, E>;
36
+ export declare function createHono<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: HonoOptions): BetterHono<M, F, E, C, P>;
44
37
  //#endregion
45
- export type { GuardOptions, ResourceRouteOptions };
38
+ export type { GuardOptions, MiddlewareOptions, ResourceRouteOptions };
@@ -1,7 +1,7 @@
1
- import { n as dbError, r as dbErrorOf } from "../errors-Bl3rkOzo.js";
2
- import { a as problemResponse } from "../problem-CGt1ADix.js";
3
- import { i as respond, n as guard, o as createServer, s as extendServer, t as defaultExpose } from "../respond-C44EZAJo.js";
4
- import { t as defineResource } from "../resource-D30rp0GN.js";
1
+ import { n as dbError, r as dbErrorOf } from "../errors-L0xK41y_.js";
2
+ import { a as problemResponse } from "../problem-BihjPR0t.js";
3
+ import { a as guard, i as defaultExpose, n as extendServer, s as respond, t as createServer } from "../server-BA75B0mT.js";
4
+ import { t as defineResource } from "../resource-My_y-Syh.js";
5
5
  import { Hono } from "hono";
6
6
  //#region src/hono/index.ts
7
7
  function contextOf(c) {
@@ -10,8 +10,8 @@ function contextOf(c) {
10
10
  return ctx;
11
11
  }
12
12
  /** Hono integration: a server plus middleware, handlers and REST resources. */
13
- function createHono(sb, options = {}) {
14
- const server = createServer(sb, options);
13
+ function createHono(betterSupabase, options = {}) {
14
+ const server = createServer(betterSupabase, options);
15
15
  const expose = options.exposeErrors ?? defaultExpose();
16
16
  const onError = (cause, c) => {
17
17
  const instance = new URL(c.req.url).pathname;
@@ -43,18 +43,18 @@ function createHono(sb, options = {}) {
43
43
  c.res = ctx.resolution.apply(c.res);
44
44
  };
45
45
  },
46
- handle(handler, handleOptions = {}) {
46
+ handler(fn, handlerOptions = {}) {
47
47
  return (c) => {
48
48
  const ctx = contextOf(c);
49
- return respond(() => handler(c, ctx), {
49
+ return respond(() => fn(c, ctx), {
50
50
  instance: new URL(c.req.url).pathname,
51
51
  expose,
52
- ...handleOptions
52
+ ...handlerOptions
53
53
  });
54
54
  };
55
55
  },
56
56
  resource(table, resourceOptions) {
57
- const resource = defineResource(sb, table, resourceOptions);
57
+ const resource = defineResource(betterSupabase, table, resourceOptions);
58
58
  const app = new Hono();
59
59
  const serve = (item) => (c) => resource.handle(c.req.raw, contextOf(c).db, item ? c.req.param("id") : void 0, {
60
60
  instance: new URL(c.req.url).pathname,
@@ -1,6 +1,6 @@
1
1
  /// <reference lib="esnext.temporal" />
2
2
  import { b as PermdockBucketPolicy, i as BucketPolicyName } from "./types-DONv9SHN.js";
3
- import { p as DbError, t as AsyncResult } from "./result-c2OYgCV2.js";
3
+ import { p as DbError, t as AsyncResult } from "./result-CqEsbgYs.js";
4
4
  import { n as StoragePath, t as PathIn } from "./path-Cv__-OTj.js";
5
5
  import { t as PermdockCatalog } from "./permdock-sql-DImJULY-.js";
6
6
  import { n as TemplateValues, t as TemplateParams } from "./template-mbvlysOo.js";
@@ -202,7 +202,16 @@ interface Bucket<P extends string, Id extends string = string> {
202
202
  /** A `[storage.buckets.<id>]` section for `supabase/config.toml`. */
203
203
  toml(): string;
204
204
  drift(actual: ActualBucket | undefined): readonly BucketDrift[];
205
- connect(client: StorageClient): BucketClient<P, Id>;
205
+ connect(client: StorageClient, options?: BucketConnectOptions): BucketClient<P, Id>;
206
+ }
207
+ interface BucketConnectOptions {
208
+ /**
209
+ * Reuse a signed URL for the same path, `ttl`, `transform` and `download`
210
+ * until shortly before it expires (a tenth of the `ttl`, at most a minute).
211
+ * The cache belongs to this connection; connect once per request so URLs
212
+ * never cross users.
213
+ */
214
+ readonly cacheSignedUrls?: boolean;
206
215
  }
207
216
  declare function parseSize(value: string | number): number;
208
217
  /** Maps a Storage error (`StorageApiError`, fetch failures) to a `DbError`. */
@@ -224,4 +233,4 @@ declare function fromStorageError(raw: unknown, table?: string): DbError;
224
233
  */
225
234
  declare function defineBucket<const P extends string, const Id extends string = string>(config: BucketConfig<P, Id>): Bucket<P, Id>;
226
235
  //#endregion
227
- export { parseSize as C, fromStorageError as S, TtlPreset as _, BucketDrift as a, UrlOptions as b, ReplaceOptions as c, StorageClient as d, StoredObject as f, TransformOptions as g, TTL as h, BucketConfig as i, ReplaceResult as l, SweepResult as m, Bucket as n, BucketPolicy as o, SweepOptions as p, BucketClient as r, ObjectTarget as s, ActualBucket as t, Reservation as u, UploadBody as v, defineBucket as x, UploadOptions as y };
236
+ export { fromStorageError as C, defineBucket as S, TransformOptions as _, BucketConnectOptions as a, UploadOptions as b, ObjectTarget as c, Reservation as d, StorageClient as f, TTL as g, SweepResult as h, BucketConfig as i, ReplaceOptions as l, SweepOptions as m, Bucket as n, BucketDrift as o, StoredObject as p, BucketClient as r, BucketPolicy as s, ActualBucket as t, ReplaceResult as u, TtlPreset as v, parseSize as w, UrlOptions as x, UploadBody as y };
@@ -1,7 +1,7 @@
1
1
  import { N as TableKey, O as Row, n as AnyModels, t as AnyFunctions } from "./types-DONv9SHN.js";
2
- import { l as CountMode } from "./executor-DynmIWhq.js";
3
- import { b as ValidationIssue, t as AsyncResult } from "./result-c2OYgCV2.js";
4
- import { C as FindExt, Ct as WhereInput, O as RepositoryOf, T as OffsetPageArgs, _ as CursorPage, dt as IncludeArg, gt as OrderByArg, t as BetterSupabase, v as CursorPageArgs, vt as Payload, w as OffsetPage, xt as SelectArg } from "./define-DUbydmJa.js";
2
+ import { l as CountMode } from "./executor-B5IoUxLE.js";
3
+ import { b as ValidationIssue, t as AsyncResult } from "./result-CqEsbgYs.js";
4
+ import { C as FindExt, Ct as WhereInput, O as RepositoryOf, T as OffsetPageArgs, _ as CursorPage, dt as IncludeArg, gt as OrderByArg, t as BetterSupabase, v as CursorPageArgs, vt as Payload, w as OffsetPage, xt as SelectArg } from "./define-CRS2MRV3.js";
5
5
  import { StandardSchemaV1 } from "@standard-schema/spec";
6
6
  //#region src/list/list-query.d.ts
7
7
  /** Facet value meaning "not set": filters with `is null`. */
@@ -144,7 +144,7 @@ type ListParsers<S extends string, F extends string> = {
144
144
  * OpenAPI parameters and a JSON Schema derived from the same definition.
145
145
  *
146
146
  * ```ts
147
- * export const customerList = defineListQuery(sb, 'customers', {
147
+ * export const customerList = defineListQuery(betterSupabase, 'customers', {
148
148
  * search: ['name', 'kvk'],
149
149
  * facets: { status: 'status' },
150
150
  * sorts: { name: { name: 'asc' }, newest: [{ createdAt: 'desc' }, { id: 'asc' }] },
@@ -152,6 +152,6 @@ type ListParsers<S extends string, F extends string> = {
152
152
  * });
153
153
  * ```
154
154
  */
155
- declare function defineListQuery<M extends AnyModels, D, Fn extends AnyFunctions, E, T extends TableKey<M>, const S extends string, const F extends string = never, const C extends boolean = false, const P extends ListPagination = "offset">(sb: BetterSupabase<M, D, Fn, E>, table: T, config: ListQueryConfig<M, T, S, F, C, P>): ListDefinition<M, T, E, S, F, C, P>;
155
+ declare function defineListQuery<M extends AnyModels, D, Fn extends AnyFunctions, E, T extends TableKey<M>, const S extends string, const F extends string = never, const C extends boolean = false, const P extends ListPagination = "offset">(betterSupabase: BetterSupabase<M, D, Fn, E>, table: T, config: ListQueryConfig<M, T, S, F, C, P>): ListDefinition<M, T, E, S, F, C, P>;
156
156
  //#endregion
157
157
  export { ListPage as a, ListParsers as c, ListQueryInput as d, ListSearchParams as f, defineListQuery as g, UNSET as h, ListExtra as i, ListQuery as l, ParserSpec as m, FacetInfo as n, ListPagination as o, OpenApiParameter as p, ListDefinition as r, ListParseResult as s, FacetCounts as t, ListQueryConfig as u };