better-supabase 0.1.0 → 0.3.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 (149) hide show
  1. package/README.md +34 -31
  2. package/dist/base64-CQeB1eSf.js +42 -0
  3. package/dist/claims-CoTobNC-.js +25 -0
  4. package/dist/client/index.d.ts +1 -1
  5. package/dist/client/index.js +4 -14
  6. package/dist/{compiler-DL18ukPe.d.ts → compiler-2zqGzxVZ.d.ts} +2 -2
  7. package/dist/config/index.d.ts +4 -3
  8. package/dist/config/index.js +5 -3
  9. package/dist/config-Be4GwsqI.js +129 -0
  10. package/dist/{index-BD6wKthp.d.ts → config-C1CYcm6o.d.ts} +75 -54
  11. package/dist/{config-D-aR2ZoN.js → config-DOsGYSiT.js} +14 -136
  12. package/dist/{define-QGkq04oe.js → define-DF341GDj.js} +133 -110
  13. package/dist/{define-CTfWw-SS.d.ts → define-DUbydmJa.d.ts} +32 -14
  14. package/dist/edge/index.d.ts +4 -4
  15. package/dist/edge/index.js +4 -4
  16. package/dist/entitlements-CTEBm7IB.js +20 -0
  17. package/dist/entitlements-DvJXoI02.d.ts +42 -0
  18. package/dist/env/index.js +203 -1
  19. package/dist/events/index.d.ts +1 -1
  20. package/dist/events/index.js +139 -1
  21. package/dist/{events-2OJsVG_d.d.ts → events-Do8jXh4D.d.ts} +3 -3
  22. package/dist/{executor-Bje4suQF.d.ts → executor-B26lgbHD.d.ts} +2 -2
  23. package/dist/{executor-Ceq60hPM.js → executor-C57jx2pn.js} +7 -2
  24. package/dist/{executor-Bazhgsgq.d.ts → executor-DynmIWhq.d.ts} +2 -2
  25. package/dist/guards-BnzDvFrz.js +10 -0
  26. package/dist/hono/index.d.ts +5 -5
  27. package/dist/hono/index.js +4 -4
  28. package/dist/{index-Hf8PP9sP.d.ts → index-BNsABq7P.d.ts} +17 -13
  29. package/dist/{index-JXHBuS53.d.ts → index-CADlNHK-.d.ts} +27 -14
  30. package/dist/{index-Nxo3TJcm.d.ts → index-CTTMS6_1.d.ts} +27 -8
  31. package/dist/index-Cf-D2jk1.d.ts +50 -0
  32. package/dist/{index-Dup-nSe9.d.ts → index-CriFFJ_p.d.ts} +4 -4
  33. package/dist/{index-DQVvHzjW.d.ts → index-GV77NpRP.d.ts} +5 -4
  34. package/dist/{index-Sw43J8HG.d.ts → index-UJ-LUxtI.d.ts} +6 -6
  35. package/dist/{index-cEeweTeM.d.ts → index-kpgopLNv.d.ts} +4 -3
  36. package/dist/{index-DRid0qIv.d.ts → index-qriRM9cZ.d.ts} +7 -2
  37. package/dist/index.d.ts +13 -13
  38. package/dist/index.js +18 -8
  39. package/dist/jobs/index.d.ts +25 -24
  40. package/dist/jobs/index.js +19 -12
  41. package/dist/{json-schema-BbwO2mZg.js → json-schema--aOXAGfU.js} +9 -3
  42. package/dist/lint/index.js +1 -1
  43. package/dist/list/index.d.ts +2 -2
  44. package/dist/list/index.js +128 -93
  45. package/dist/{live-6b9i72Ux.d.ts → live-QE3UPbGm.d.ts} +27 -6
  46. package/dist/logger-glM28NVN.js +21 -0
  47. package/dist/mcp/index.d.ts +59 -15
  48. package/dist/mcp/index.js +229 -67
  49. package/dist/{mfa-CpogP66z.js → mfa-BxoR1RkN.js} +97 -22
  50. package/dist/{mfa-TVia554c.d.ts → mfa-x3V3vGh-.d.ts} +1 -1
  51. package/dist/next/index.d.ts +51 -38
  52. package/dist/next/index.js +31 -25
  53. package/dist/openapi/index.d.ts +1 -1
  54. package/dist/openapi/index.js +58 -35
  55. package/dist/orpc/index.d.ts +6 -6
  56. package/dist/orpc/index.js +3 -3
  57. package/dist/otel/index.d.ts +3 -3
  58. package/dist/otel/index.js +5 -3
  59. package/dist/{template-BeOGnynM.js → permdock-sql-Bta_G0v-.js} +32 -3
  60. package/dist/permdock-sql-DImJULY-.d.ts +17 -0
  61. package/dist/{plugin-HvGqCurB.d.ts → plugin-DVRB8qNE.d.ts} +5 -4
  62. package/dist/plugins/actor/index.d.ts +1 -1
  63. package/dist/plugins/rules/index.d.ts +4 -3
  64. package/dist/plugins/rules/index.js +8 -15
  65. package/dist/plugins/soft-delete/index.d.ts +3 -3
  66. package/dist/plugins/soft-delete/index.js +2 -2
  67. package/dist/plugins/tenant/index.d.ts +10 -4
  68. package/dist/plugins/tenant/index.js +15 -13
  69. package/dist/plugins/timestamps/index.d.ts +1 -1
  70. package/dist/plugins/timestamps/index.js +1 -1
  71. package/dist/plugins/validation/index.d.ts +2 -2
  72. package/dist/pool-B9qsLyFR.d.ts +71 -0
  73. package/dist/postgres/index.d.ts +10 -5
  74. package/dist/postgres/index.js +36 -16
  75. package/dist/{postgrest-Dm-vhY6R.d.ts → postgrest-DmBlevh-.d.ts} +1 -1
  76. package/dist/{problem-DPu6Fh-t.js → problem-CGt1ADix.js} +14 -8
  77. package/dist/{problem-DlgB0lYl.d.ts → problem-Z2RTQjZD.d.ts} +6 -4
  78. package/dist/query/index.d.ts +2 -2
  79. package/dist/query/index.js +1 -1
  80. package/dist/{query-ChvDbsDE.js → query-BdKLTPlj.js} +2 -2
  81. package/dist/react/index.d.ts +7 -7
  82. package/dist/react/index.js +3 -3
  83. package/dist/react/server.d.ts +5 -5
  84. package/dist/react/server.js +1 -1
  85. package/dist/react/session.d.ts +21 -2
  86. package/dist/react/session.js +19 -1
  87. package/dist/{react-CrOvrnIP.js → react-DNBYNazu.js} +28 -23
  88. package/dist/{read-set-DhX2d04c.js → read-set-D0qBcboM.js} +3 -3
  89. package/dist/realtime/index.d.ts +4 -2
  90. package/dist/realtime/index.js +30 -14
  91. package/dist/{resolve-DW8h9NPm.d.ts → resolve-BRciX2jK.d.ts} +25 -9
  92. package/dist/{resource-SkPTRJDD.d.ts → resource-CwVgiI5q.d.ts} +16 -7
  93. package/dist/{resource-CYiu6Ygi.js → resource-D30rp0GN.js} +38 -16
  94. package/dist/{respond-4-dhoV7x.js → respond-C44EZAJo.js} +38 -19
  95. package/dist/{respond-PoTpy5DT.d.ts → respond-DAkPIdTH.d.ts} +23 -17
  96. package/dist/{result-CTkCZ6JA.d.ts → result-c2OYgCV2.d.ts} +13 -8
  97. package/dist/server/index.d.ts +35 -10
  98. package/dist/server/index.js +38 -9
  99. package/dist/{simplify-oHiDKRVQ.js → simplify-LakqK1vH.js} +22 -28
  100. package/dist/{spec-pins-t6sPaHvl.js → spec-pins-C3oc-Tdp.js} +1 -1
  101. package/dist/{spec-pins-CJPVghHy.d.ts → spec-pins-CqorWDnO.d.ts} +1 -1
  102. package/dist/sql/index.d.ts +139 -0
  103. package/dist/sql/index.js +1983 -0
  104. package/dist/{sql-M8l3fnS0.js → sql-BIgk12ew.js} +72 -16
  105. package/dist/ssr/index.d.ts +5 -5
  106. package/dist/ssr/index.js +3 -3
  107. package/dist/{standard-CyhRzctb.d.ts → standard-eudBiRk1.d.ts} +1 -1
  108. package/dist/{stats-3iy8u3_P.js → stats-D78UQ8Yu.js} +8 -7
  109. package/dist/storage/index.d.ts +4 -2
  110. package/dist/storage/index.js +530 -1
  111. package/dist/{tables-rZxRxNPW.js → tables-Dhha3BXM.js} +5 -5
  112. package/dist/temporal-BwshQk0W.js +27 -0
  113. package/dist/temporal-required-CMxeSVPo.js +19 -0
  114. package/dist/testing/index.d.ts +49 -16
  115. package/dist/testing/index.js +233 -66
  116. package/dist/{types-C2fslP1z.d.ts → types-DONv9SHN.d.ts} +68 -12
  117. package/dist/{version-Cqq1m3UY.js → version-BfpG2gks.js} +1 -1
  118. package/dist/view-3Po_PVlr.d.ts +79 -0
  119. package/dist/{view-B6F9QbG-.js → view-wZ-9qIUz.js} +12 -2
  120. package/dist/webhooks/index.d.ts +19 -17
  121. package/dist/webhooks/index.js +1 -1
  122. package/dist/{webhooks-DbMTJJX2.js → webhooks-CAIFQSTM.js} +12 -10
  123. package/package.json +30 -30
  124. package/schemas/config-v1.json +80 -5
  125. package/schemas/doctor-report-v1.json +18 -1
  126. package/schemas/snapshot-v2.json +39 -0
  127. package/skills/better-supabase/SKILL.md +23 -11
  128. package/skills/better-supabase/references/plugins.md +28 -16
  129. package/skills/better-supabase/references/troubleshooting.md +15 -15
  130. package/skills/better-supabase-api/SKILL.md +9 -9
  131. package/skills/better-supabase-api/references/adapters.md +30 -25
  132. package/skills/better-supabase-testing/SKILL.md +15 -11
  133. package/bin/better-supabase.js +0 -3
  134. package/dist/casing-da0uRTqt.js +0 -14
  135. package/dist/cli/bin.d.ts +0 -1
  136. package/dist/cli/bin.js +0 -15
  137. package/dist/cli/index.d.ts +0 -226
  138. package/dist/cli/index.js +0 -3
  139. package/dist/cli-CoByWYja.js +0 -6472
  140. package/dist/entitlements-BBg61DQZ.d.ts +0 -20
  141. package/dist/entitlements-BC_khwRy.js +0 -17
  142. package/dist/env-BEToab0I.js +0 -204
  143. package/dist/events-BuzTgn2D.js +0 -135
  144. package/dist/pool-BFeqzwQS.d.ts +0 -37
  145. package/dist/seed-CzecODcJ.js +0 -101
  146. package/dist/session-C3osL21k.d.ts +0 -21
  147. package/dist/session-CD-3orO_.js +0 -19
  148. package/dist/storage-BWXVUXGk.js +0 -461
  149. package/dist/view-B0ltUmTi.d.ts +0 -43
@@ -1,12 +1,12 @@
1
- import { n as AnyModels, t as AnyFunctions } from "./types-C2fslP1z.js";
2
- import { p as DbError, t as AsyncResult } from "./result-CTkCZ6JA.js";
3
- import { I as StatsRecorder, P as DbStats, t as BetterSupabase, y as Db } from "./define-CTfWw-SS.js";
4
- import { h as RequestContext } from "./plugin-HvGqCurB.js";
1
+ import { n as AnyModels, t as AnyFunctions } from "./types-DONv9SHN.js";
2
+ import { p as DbError, t as AsyncResult } from "./result-c2OYgCV2.js";
3
+ import { I as StatsRecorder, P as DbStats, t as BetterSupabase, y as Db } from "./define-DUbydmJa.js";
4
+ import { h as RequestContext } from "./plugin-DVRB8qNE.js";
5
5
  import { t as BetterSupabaseEnv } from "./index-Dy6kuF0P.js";
6
- import { r as SqlClaims, t as Postgres } from "./pool-BFeqzwQS.js";
7
- import { o as ImpersonationOptions, t as Aal } from "./mfa-TVia554c.js";
8
- import { a as ResolveAuthOptions, r as AuthState, t as AuthResolution } from "./resolve-DW8h9NPm.js";
9
- import { n as Bucket } from "./index-Nxo3TJcm.js";
6
+ import { o as SqlClaims, r as Postgres } from "./pool-B9qsLyFR.js";
7
+ import { o as ImpersonationOptions, t as Aal } from "./mfa-x3V3vGh-.js";
8
+ import { a as ResolveAuthOptions, r as AuthState, t as AuthResolution } from "./resolve-BRciX2jK.js";
9
+ import { n as Bucket } from "./index-CTTMS6_1.js";
10
10
  import { SupabaseClient } from "@supabase/supabase-js";
11
11
  //#region src/server/delete-account.d.ts
12
12
  interface DeleteAccountOptions {
@@ -67,9 +67,9 @@ interface ServerOptions {
67
67
  readonly pinMs?: number;
68
68
  };
69
69
  }
70
- interface ServerContext<M extends AnyModels, F extends AnyFunctions, E, C = unknown> {
71
- readonly auth: AuthState<C>;
72
- readonly resolution: AuthResolution<C>;
70
+ interface ServerContext<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> {
71
+ readonly auth: AuthState<C, P>;
72
+ readonly resolution: AuthResolution<C, P>;
73
73
  /** supabase-js client scoped to the caller (RLS applies). */
74
74
  readonly supabase: SupabaseClient;
75
75
  /** Repositories over PostgREST as the caller. */
@@ -88,18 +88,18 @@ interface ContextOptions {
88
88
  /** Also records this context's calls into a request-wide recorder. */
89
89
  readonly stats?: StatsRecorder;
90
90
  }
91
- interface BetterServer<M extends AnyModels, F extends AnyFunctions, E, C = unknown> {
91
+ interface BetterServer<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> {
92
92
  readonly env: BetterSupabaseEnv;
93
93
  resolve(request: Request, options?: {
94
94
  readonly refresh?: boolean;
95
- }): Promise<AuthResolution<C>>;
95
+ }): Promise<AuthResolution<C, P>>;
96
96
  /**
97
97
  * Resolves auth and binds repositories to the caller. Refreshes an expired
98
98
  * cookie session only with `refresh: true`; send `ctx.resolution.apply(response)`.
99
99
  */
100
- context(request: Request, options?: ContextOptions): Promise<ServerContext<M, F, E, C>>;
100
+ context(request: Request, options?: ContextOptions): Promise<ServerContext<M, F, E, C, P>>;
101
101
  /** The context for an auth state resolved elsewhere (the proxy, a queue message). */
102
- contextFor(auth: AuthState<C>, options?: ContextOptions): ServerContext<M, F, E, C>;
102
+ contextFor(auth: AuthState<C, P>, options?: ContextOptions): ServerContext<M, F, E, C, P>;
103
103
  /** A stateless supabase-js client for an auth state, optionally with extra request headers. */
104
104
  supabaseFor(auth: AuthState, headers?: Readonly<Record<string, string>>): SupabaseClient;
105
105
  /** Repositories for an auth state (e.g. one resolved by the proxy). */
@@ -123,7 +123,7 @@ interface BetterServer<M extends AnyModels, F extends AnyFunctions, E, C = unkno
123
123
  * Server-side entry point for APIs, jobs, MCP servers and framework
124
124
  * adapters. Holds the secrets; `sb` stays isomorphic.
125
125
  */
126
- declare function createServer<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown>(sb: BetterSupabase<M, D, F, E, C>, options?: ServerOptions): BetterServer<M, F, E, C>;
126
+ declare function createServer<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(sb: BetterSupabase<M, D, F, E, C, P>, options?: ServerOptions): BetterServer<M, F, E, C, P>;
127
127
  //#endregion
128
128
  //#region src/server/respond.d.ts
129
129
  type AuthKind = AuthState["kind"];
@@ -135,9 +135,15 @@ interface GuardOptions {
135
135
  * `required: 'aal2'` until the user verifies a second factor.
136
136
  */
137
137
  readonly aal?: Aal;
138
+ /**
139
+ * OAuth scopes a delegated token (an OAuth client or an `act` chain) needs.
140
+ * A missing one answers 403 with `error="insufficient_scope"`. The user's
141
+ * own session is not limited by scopes.
142
+ */
143
+ readonly scopes?: readonly string[];
138
144
  }
139
145
  /** `undefined` when `auth` may pass; otherwise the 401/403 error to send. */
140
- declare function guard(auth: AuthState, allow?: GuardOptions["allow"], aal?: Aal): DbError | undefined;
146
+ declare function guard(auth: AuthState, allow?: GuardOptions["allow"], aal?: Aal, scopes?: readonly string[]): DbError | undefined;
141
147
  declare function isResult(value: unknown): value is {
142
148
  ok: boolean;
143
149
  data: unknown;
@@ -7,9 +7,14 @@
7
7
  interface DbErrorKinds {
8
8
  not_found: Record<never, never>;
9
9
  unauthorized: Record<never, never>;
10
- /** `required`: the assurance level the route needs, when a second factor is missing. */
10
+ /**
11
+ * `required`: the assurance level the route needs, when a second factor is
12
+ * missing. `scopes`: the OAuth scopes the route needs, when a delegated
13
+ * token lacks one (`INSUFFICIENT_SCOPE`).
14
+ */
11
15
  forbidden: {
12
16
  required?: "aal1" | "aal2";
17
+ scopes?: readonly string[];
13
18
  };
14
19
  conflict: {
15
20
  constraint?: string;
@@ -158,7 +163,7 @@ declare class AsyncResult<T> implements PromiseLike<Result<T>> {
158
163
  andThen<U>(fn: (data: T) => PromiseLike<Result<U>>): AsyncResult<U>;
159
164
  }
160
165
  /** What `toBetterResult` returns: the `status`/`value`/`error` fields every better-result value has. */
161
- type BetterResultShape<T, E> = {
166
+ type BetterResultValue<T, E> = {
162
167
  readonly status: "ok";
163
168
  readonly value: T;
164
169
  } | {
@@ -182,17 +187,17 @@ interface BetterResultApi<T, E> {
182
187
  * const customer = toBetterResult(await db.customers.findById(id), Result, toAppError);
183
188
  * ```
184
189
  */
185
- declare function toBetterResult<T, E>(result: Result<T>, api: BetterResultApi<T, E>, mapError: (error: DbError) => E): BetterResultShape<T, E>;
186
- declare function toBetterResult<T>(result: Result<T>, api: BetterResultApi<T, DbError>): BetterResultShape<T, DbError>;
187
- declare function toBetterResult<T, E>(result: AsyncResult<T>, api: BetterResultApi<T, E>, mapError: (error: DbError) => E): Promise<BetterResultShape<T, E>>;
188
- declare function toBetterResult<T>(result: AsyncResult<T>, api: BetterResultApi<T, unknown>): Promise<BetterResultShape<T, unknown>>;
190
+ declare function toBetterResult<T, E>(result: Result<T>, api: BetterResultApi<T, E>, mapError: (error: DbError) => E): BetterResultValue<T, E>;
191
+ declare function toBetterResult<T>(result: Result<T>, api: BetterResultApi<T, DbError>): BetterResultValue<T, DbError>;
192
+ declare function toBetterResult<T, E>(result: AsyncResult<T>, api: BetterResultApi<T, E>, mapError: (error: DbError) => E): Promise<BetterResultValue<T, E>>;
193
+ declare function toBetterResult<T>(result: AsyncResult<T>, api: BetterResultApi<T, unknown>): Promise<BetterResultValue<T, unknown>>;
189
194
  /**
190
195
  * Converts a better-result value back into a `Result`, by its `status`
191
196
  * field, so it works across better-result versions. A `DbError`, or an
192
197
  * error whose `cause` is one, is kept; others go through `mapError`
193
198
  * (default `toDbError`).
194
199
  */
195
- declare function fromBetterResult<T>(result: BetterResultShape<T, unknown>, mapError?: (error: unknown) => DbError): Result<T>;
200
+ declare function fromBetterResult<T>(result: BetterResultValue<T, unknown>, mapError?: (error: unknown) => DbError): Result<T>;
196
201
  declare function toDbError(cause: unknown): DbError;
197
202
  //#endregion
198
- export { isConflict as C, statusOf as D, mapDbError as E, isCheck as S, isForeignKey as T, DbException as _, Ok as a, ValidationIssue as b, err as c, toBetterResult as d, toDbError as f, DbErrorOf as g, DbErrorKinds as h, Err as i, fromBetterResult as l, DbErrorKind as m, BetterResultApi as n, Result as o, DbError as p, BetterResultShape as r, ThrowMapper as s, AsyncResult as t, ok as u, ErrorMapper as v, isDbError as w, dbError as x, RawDbError as y };
203
+ export { isConflict as C, statusOf as D, mapDbError as E, isCheck as S, isForeignKey as T, DbException as _, Ok as a, ValidationIssue as b, err as c, toBetterResult as d, toDbError as f, DbErrorOf as g, DbErrorKinds as h, Err as i, fromBetterResult as l, DbErrorKind as m, BetterResultApi as n, Result as o, DbError as p, BetterResultValue as r, ThrowMapper as s, AsyncResult as t, ok as u, ErrorMapper as v, isDbError as w, dbError as x, RawDbError as y };
@@ -1,12 +1,14 @@
1
- import { n as AnyModels, t as AnyFunctions } from "../types-C2fslP1z.js";
2
- import { t as BetterSupabase, y as Db } from "../define-CTfWw-SS.js";
3
- import { h as RequestContext } from "../plugin-HvGqCurB.js";
4
- import { a as checkAal, c as impersonatorOf, i as amrOf, n as AmrEntry, o as ImpersonationOptions, r as aalOf, s as Impersonator, t as Aal } from "../mfa-TVia554c.js";
5
- import { _ as readSession, a as ResolveAuthOptions, b as writeSession, c as clientIp, d as CookieOptions, f as CookieRecord, i as InvalidReason, l as resolveAuth, m as StoredSession, n as AuthResolver, o as ResolvedState, p as CookieWrite, r as AuthState, s as authContext, t as AuthResolution, u as AUTH_CACHE_HEADERS, y as sessionCookieName } from "../resolve-DW8h9NPm.js";
6
- import { _ as DeleteAccountResult, a as guard, c as settle, d as ServerContext, f as ServerOptions, g as DeleteAccountOptions, h as ReplicaState, i as Settled, l as BetterServer, m as PRIMARY_COOKIE, n as GuardOptions, o as isResult, p as createServer, r as RespondOptions, s as respond, t as AuthKind, u as ContextOptions } from "../respond-PoTpy5DT.js";
7
- import { a as defineResource, i as ResourceRouteOptions, n as ResourceInput, r as ResourceList, t as ResourceHandler } from "../resource-SkPTRJDD.js";
8
- import { a as ProblemResponseOptions, c as problemResponse, i as ProblemOptions, l as toProblem, n as PROBLEM_TYPE_BASE, o as fromProblem, r as ProblemDetails, s as isProblem, t as PROBLEM_CONTENT_TYPE } from "../problem-DlgB0lYl.js";
9
- import { n as RefreshOutcome, r as refreshSession } from "../index-cEeweTeM.js";
1
+ import { n as AnyModels, t as AnyFunctions } from "../types-DONv9SHN.js";
2
+ import { p as DbError } from "../result-c2OYgCV2.js";
3
+ import { t as BetterSupabase, y as Db } from "../define-DUbydmJa.js";
4
+ import { h as RequestContext } from "../plugin-DVRB8qNE.js";
5
+ import { a as checkAal, c as impersonatorOf, i as amrOf, n as AmrEntry, o as ImpersonationOptions, r as aalOf, s as Impersonator, t as Aal } from "../mfa-x3V3vGh-.js";
6
+ import { _ as readSession, a as ResolveAuthOptions, b as writeSession, c as clientIp, d as CookieOptions, f as CookieRecord, i as InvalidReason, l as resolveAuth, m as StoredSession, n as AuthResolver, o as ResolvedState, p as CookieWrite, r as AuthState, s as authContext, t as AuthResolution, u as AUTH_CACHE_HEADERS, y as sessionCookieName } from "../resolve-BRciX2jK.js";
7
+ import { _ as DeleteAccountResult, a as guard, c as settle, d as ServerContext, f as ServerOptions, g as DeleteAccountOptions, h as ReplicaState, i as Settled, l as BetterServer, m as PRIMARY_COOKIE, n as GuardOptions, o as isResult, p as createServer, r as RespondOptions, s as respond, t as AuthKind, u as ContextOptions } from "../respond-DAkPIdTH.js";
8
+ import { a as ResourceRouteOptions, i as ResourcePagination, n as ResourceInput, o as defineResource, r as ResourceList, t as ResourceHandler } from "../resource-CwVgiI5q.js";
9
+ import { a as ProblemResponseOptions, c as problemResponse, i as ProblemOptions, l as toProblem, n as PROBLEM_TYPE_BASE, o as fromProblem, r as ProblemDetails, s as isProblem, t as PROBLEM_CONTENT_TYPE } from "../problem-Z2RTQjZD.js";
10
+ import { a as SessionDelegation, i as SessionActor, n as toSession, r as ActClaim, t as AuthSession } from "../view-3Po_PVlr.js";
11
+ import { n as RefreshOutcome, r as refreshSession } from "../index-kpgopLNv.js";
10
12
  import { SupabaseClient } from "@supabase/supabase-js";
11
13
  import { Middleware } from "@supabase/middleware";
12
14
  import { AuthMode, JWTClaims, UserClaims } from "@supabase/server";
@@ -39,4 +41,27 @@ export declare function withBetterPostgres<M extends AnyModels, D, F extends Any
39
41
  readonly postgres: PostgresApi;
40
42
  }, Db<M, F, E, undefined>>;
41
43
  //#endregion
42
- export { AUTH_CACHE_HEADERS, type Aal, type AmrEntry, type AuthKind, type AuthResolution, type AuthResolver, type AuthState, type BetterServer, type ContextOptions, type CookieOptions, type CookieRecord, type CookieWrite, type DeleteAccountOptions, type DeleteAccountResult, type GuardOptions, type ImpersonationOptions, type Impersonator, type InvalidReason, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, type ProblemDetails, type ProblemOptions, type ProblemResponseOptions, type RefreshOutcome, type ReplicaState, type ResolveAuthOptions, type ResolvedState, type ResourceHandler, type ResourceInput, type ResourceList, type ResourceRouteOptions, type RespondOptions, type ServerContext, type ServerOptions, type Settled, type StoredSession, type SupabaseAuthContext, aalOf, amrOf, authContext, checkAal, clientIp, createServer, defineResource, fromProblem, guard, impersonatorOf, isProblem, isResult, problemResponse, readSession, refreshSession, resolveAuth, respond, sessionCookieName, settle, toProblem, writeSession };
44
+ //#region src/auth/revocation.d.ts
45
+ /** A client that can read `auth.sessions`, such as `createPostgres().admin`. */
46
+ interface SessionLookup {
47
+ queryRaw<T = Record<string, unknown>>(text: string, params?: unknown[]): Promise<T[]>;
48
+ }
49
+ /**
50
+ * `undefined` when the user token's session still exists in `auth.sessions`;
51
+ * otherwise an `unauthorized` error with code `SESSION_REVOKED`. A verified
52
+ * access token stays valid until it expires, even after sign-out; call this
53
+ * before sensitive actions (deleting the account, changing the email) to
54
+ * reject tokens of ended sessions. It costs one query, so nothing calls it
55
+ * by default. Non-user callers pass: `guard` decides about them.
56
+ */
57
+ export declare function checkSession(sql: SessionLookup, auth: {
58
+ readonly kind: "user";
59
+ readonly claims: {
60
+ readonly sub?: unknown;
61
+ readonly session_id?: unknown;
62
+ };
63
+ } | {
64
+ readonly kind: string;
65
+ }): Promise<DbError | undefined>;
66
+ //#endregion
67
+ export { AUTH_CACHE_HEADERS, type Aal, type ActClaim, type AmrEntry, type AuthKind, type AuthResolution, type AuthResolver, type AuthSession, type AuthState, type BetterServer, type ContextOptions, type CookieOptions, type CookieRecord, type CookieWrite, type DeleteAccountOptions, type DeleteAccountResult, type GuardOptions, type ImpersonationOptions, type Impersonator, type InvalidReason, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, type ProblemDetails, type ProblemOptions, type ProblemResponseOptions, type RefreshOutcome, type ReplicaState, type ResolveAuthOptions, type ResolvedState, type ResourceHandler, type ResourceInput, type ResourceList, type ResourcePagination, type ResourceRouteOptions, type RespondOptions, type ServerContext, type ServerOptions, type SessionActor, type SessionDelegation, type SessionLookup, type Settled, type StoredSession, type SupabaseAuthContext, aalOf, amrOf, authContext, checkAal, clientIp, createServer, defineResource, fromProblem, guard, impersonatorOf, isProblem, isResult, problemResponse, readSession, refreshSession, resolveAuth, respond, sessionCookieName, settle, toProblem, toSession, writeSession };
@@ -1,8 +1,10 @@
1
- import { a as problemResponse, i as isProblem, n as PROBLEM_TYPE_BASE, o as toProblem, r as fromProblem, t as PROBLEM_CONTENT_TYPE } from "../problem-DPu6Fh-t.js";
2
- import { a as settle, i as respond, n as guard, o as createServer, r as isResult, u as PRIMARY_COOKIE } from "../respond-4-dhoV7x.js";
3
- import { a as clientIp, f as sessionCookieName, g as impersonatorOf, i as authContext, m as refreshSession, n as amrOf, o as resolveAuth, p as writeSession, r as checkAal, s as AUTH_CACHE_HEADERS, t as aalOf, u as readSession } from "../mfa-CpogP66z.js";
4
- import { n as postgresExecutor } from "../executor-Ceq60hPM.js";
5
- import { t as defineResource } from "../resource-CYiu6Ygi.js";
1
+ import { n as dbError } from "../errors-Bl3rkOzo.js";
2
+ import { a as problemResponse, i as isProblem, n as PROBLEM_TYPE_BASE, o as toProblem, r as fromProblem, t as PROBLEM_CONTENT_TYPE } from "../problem-CGt1ADix.js";
3
+ import { a as settle, i as respond, n as guard, o as createServer, r as isResult, u as PRIMARY_COOKIE } from "../respond-C44EZAJo.js";
4
+ import { a as clientIp, f as sessionCookieName, i as authContext, m as refreshSession, n as amrOf, o as resolveAuth, p as writeSession, r as checkAal, s as AUTH_CACHE_HEADERS, t as aalOf, u as readSession, v as impersonatorOf } from "../mfa-BxoR1RkN.js";
5
+ import { n as postgresExecutor } from "../executor-C57jx2pn.js";
6
+ import { t as toSession } from "../view-wZ-9qIUz.js";
7
+ import { t as defineResource } from "../resource-D30rp0GN.js";
6
8
  import { defineMiddleware } from "@supabase/middleware";
7
9
  //#region src/server/middleware.ts
8
10
  /** Repository context from a `@supabase/server` context. */
@@ -14,8 +16,8 @@ function contextFromSupabase(ctx) {
14
16
  actor: {
15
17
  id: ctx.userClaims.id,
16
18
  kind: "user",
17
- ...ctx.userClaims.role !== void 0 ? { role: ctx.userClaims.role } : {},
18
- ...ctx.userClaims.email !== void 0 ? { email: ctx.userClaims.email } : {}
19
+ ...ctx.userClaims.role === void 0 ? {} : { role: ctx.userClaims.role },
20
+ ...ctx.userClaims.email === void 0 ? {} : { email: ctx.userClaims.email }
19
21
  },
20
22
  claims: ctx.jwtClaims ?? {}
21
23
  };
@@ -29,7 +31,10 @@ function contextFromSupabase(ctx) {
29
31
  };
30
32
  case "publishable":
31
33
  case "none": break;
32
- default: return ctx.authMode;
34
+ default: {
35
+ const unknown = ctx.authMode;
36
+ throw new TypeError(`contextFromSupabase: unknown auth mode "${String(unknown)}"`);
37
+ }
33
38
  }
34
39
  return {
35
40
  actor: {
@@ -65,4 +70,28 @@ function withBetterPostgres(sb) {
65
70
  });
66
71
  }
67
72
  //#endregion
68
- export { AUTH_CACHE_HEADERS, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, aalOf, amrOf, authContext, checkAal, clientIp, contextFromSupabase, createServer, defineResource, fromProblem, guard, impersonatorOf, isProblem, isResult, problemResponse, readSession, refreshSession, resolveAuth, respond, sessionCookieName, settle, toProblem, withBetterPostgres, withBetterSupabase, writeSession };
73
+ //#region src/auth/revocation.ts
74
+ const UUID = /^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/i;
75
+ const ACTIVE = `select exists (
76
+ select 1 from auth.sessions s
77
+ where s.id = $1::uuid and s.user_id = $2::uuid
78
+ and (s.not_after is null or s.not_after > now())
79
+ ) as active`;
80
+ /**
81
+ * `undefined` when the user token's session still exists in `auth.sessions`;
82
+ * otherwise an `unauthorized` error with code `SESSION_REVOKED`. A verified
83
+ * access token stays valid until it expires, even after sign-out; call this
84
+ * before sensitive actions (deleting the account, changing the email) to
85
+ * reject tokens of ended sessions. It costs one query, so nothing calls it
86
+ * by default. Non-user callers pass: `guard` decides about them.
87
+ */
88
+ async function checkSession(sql, auth) {
89
+ if (auth.kind !== "user" || !("claims" in auth)) return void 0;
90
+ const { sub, session_id: sessionId } = auth.claims;
91
+ const revoked = dbError("unauthorized", "This session has ended", { code: "SESSION_REVOKED" });
92
+ if (typeof sessionId !== "string" || typeof sub !== "string" || !UUID.test(sessionId) || !UUID.test(sub)) return revoked;
93
+ const [row] = await sql.queryRaw(ACTIVE, [sessionId, sub]);
94
+ return row?.active === true ? void 0 : revoked;
95
+ }
96
+ //#endregion
97
+ export { AUTH_CACHE_HEADERS, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, aalOf, amrOf, authContext, checkAal, checkSession, clientIp, contextFromSupabase, createServer, defineResource, fromProblem, guard, impersonatorOf, isProblem, isResult, problemResponse, readSession, refreshSession, resolveAuth, respond, sessionCookieName, settle, toProblem, toSession, withBetterPostgres, withBetterSupabase, writeSession };
@@ -1,4 +1,6 @@
1
1
  import { n as dbError, t as DbException } from "./errors-Bl3rkOzo.js";
2
+ import { i as temporalText } from "./temporal-BwshQk0W.js";
3
+ import { t as temporal } from "./temporal-required-CMxeSVPo.js";
2
4
  import { i as or, r as not, t as and } from "./types-6cYK9pbJ.js";
3
5
  //#region src/schema/define.ts
4
6
  /**
@@ -27,17 +29,19 @@ function relationMeta(meta, table, relation) {
27
29
  }
28
30
  //#endregion
29
31
  //#region src/ir/codec.ts
30
- /** Wire form of an app value: `Date` to ISO text, `bigint` to decimal text. */
32
+ /** Wire form of an app value: Temporal values to ISO text, `bigint` to decimal text. */
31
33
  function encodeValue(value) {
32
- if (value instanceof Date) return value.toISOString();
33
34
  if (typeof value === "bigint") return value.toString();
35
+ const text = temporalText(value);
36
+ if (text !== void 0) return text;
34
37
  if (Array.isArray(value)) return value.map(encodeValue);
35
38
  return value;
36
39
  }
37
40
  function decodeScalar(codec, value) {
38
41
  if (value === null || value === void 0) return value;
39
42
  switch (codec) {
40
- case "date": return new Date(value);
43
+ case "instant": return temporal().Instant.from(String(value));
44
+ case "plainDateTime": return temporal().PlainDateTime.from(String(value));
41
45
  case "bigint": return BigInt(value);
42
46
  case "string": return String(value);
43
47
  default: return codec;
@@ -170,7 +174,7 @@ function writable(meta, mode) {
170
174
  }
171
175
  /** Escapes LIKE wildcards so user input matches literally. */
172
176
  function escapeLike(value) {
173
- return value.replace(/[\\%_]/g, (char) => `\\${char}`);
177
+ return value.replaceAll(/[\\%_]/g, (char) => `\\${char}`);
174
178
  }
175
179
  var IrBuilder = class {
176
180
  meta;
@@ -236,8 +240,8 @@ var IrBuilder = class {
236
240
  const keys = Object.keys(value);
237
241
  if (keys.length > 0 && keys.every((key) => key === "is" || key === "isNot")) {
238
242
  const items = [];
239
- if (value.is !== void 0) items.push(value.is === null ? make("none", null) : make("some", value.is));
240
- if (value.isNot !== void 0) items.push(value.isNot === null ? make("some", null) : not(make("some", value.isNot)));
243
+ if (value["is"] !== void 0) items.push(value["is"] === null ? make("none", null) : make("some", value["is"]));
244
+ if (value["isNot"] !== void 0) items.push(value["isNot"] === null ? make("some", null) : not(make("some", value["isNot"])));
241
245
  return and(...items) ?? make("some", null);
242
246
  }
243
247
  }
@@ -341,7 +345,7 @@ var IrBuilder = class {
341
345
  * of each group.
342
346
  */
343
347
  aggregation(table, args) {
344
- const groupBy = args.groupBy ?? [];
348
+ const groupBy = args["groupBy"] ?? [];
345
349
  if (!Array.isArray(groupBy)) invalidRequest(`"groupBy" on "${table.key}" must be an array`, table.key);
346
350
  const columns = groupBy.map((name) => this.selectColumn(table, String(name)));
347
351
  const measures = [];
@@ -350,7 +354,7 @@ var IrBuilder = class {
350
354
  if (value === void 0) continue;
351
355
  for (const alias of this.measured(table, key, value)) measures.push(this.measure(table, fn, alias, `${key}_${alias}`));
352
356
  }
353
- const count = args._count === true;
357
+ const count = args["_count"] === true;
354
358
  if (!count && measures.length === 0) invalidRequest(`aggregate on "${table.key}" needs _count, _sum, _avg, _min or _max`, table.key);
355
359
  return {
356
360
  columns,
@@ -411,13 +415,7 @@ var IrBuilder = class {
411
415
  alias,
412
416
  column
413
417
  };
414
- return codec === "date" ? {
415
- fn,
416
- key,
417
- alias,
418
- column,
419
- codec
420
- } : {
418
+ return {
421
419
  fn,
422
420
  key,
423
421
  alias,
@@ -434,11 +432,7 @@ var IrBuilder = class {
434
432
  alias,
435
433
  column
436
434
  };
437
- return codec === "date" ? {
438
- alias,
439
- column,
440
- codec
441
- } : {
435
+ return {
442
436
  alias,
443
437
  column,
444
438
  cast: "text",
@@ -461,7 +455,7 @@ var IrBuilder = class {
461
455
  columns: [],
462
456
  includes: []
463
457
  },
464
- where: this.where(target, args.where),
458
+ where: this.where(target, args["where"]),
465
459
  orderBy: [],
466
460
  limit: void 0,
467
461
  required: false,
@@ -477,11 +471,11 @@ var IrBuilder = class {
477
471
  alias: name,
478
472
  relation,
479
473
  target,
480
- selection: this.selection(target, args.select, args.include),
481
- where: this.where(target, args.where),
482
- orderBy: this.orderBy(target, args.orderBy),
483
- limit: typeof args.limit === "number" ? args.limit : void 0,
484
- required: args.required === true
474
+ selection: this.selection(target, args["select"], args["include"]),
475
+ where: this.where(target, args["where"]),
476
+ orderBy: this.orderBy(target, args["orderBy"]),
477
+ limit: typeof args["limit"] === "number" ? args["limit"] : void 0,
478
+ required: args["required"] === true
485
479
  };
486
480
  }
487
481
  orderBy(table, input) {
@@ -498,8 +492,8 @@ var IrBuilder = class {
498
492
  direction: spec
499
493
  });
500
494
  else if (isPlainObject(spec)) {
501
- const direction = spec.direction === "desc" ? "desc" : "asc";
502
- const nulls = spec.nulls;
495
+ const direction = spec["direction"] === "desc" ? "desc" : "asc";
496
+ const nulls = spec["nulls"];
503
497
  terms.push(nulls === "first" || nulls === "last" ? {
504
498
  column,
505
499
  direction,
@@ -5,7 +5,7 @@
5
5
  */
6
6
  const SPEC_PINS = {
7
7
  otelSemconv: "1.37.0",
8
- mcp: "2025-06-18",
8
+ mcp: "2026-07-28",
9
9
  openapi: "3.1.1",
10
10
  cloudevents: "1.0.2",
11
11
  standardWebhooks: "1.0.0",
@@ -5,7 +5,7 @@
5
5
  */
6
6
  declare const SPEC_PINS: {
7
7
  readonly otelSemconv: "1.37.0";
8
- readonly mcp: "2025-06-18";
8
+ readonly mcp: "2026-07-28";
9
9
  readonly openapi: "3.1.1";
10
10
  readonly cloudevents: "1.0.2";
11
11
  readonly standardWebhooks: "1.0.0";
@@ -0,0 +1,139 @@
1
+ import { s as ClaimsMeta } from "../types-DONv9SHN.js";
2
+ import { B as ReadSet } from "../define-DUbydmJa.js";
3
+ import { b as ResolvedConfig } from "../config-C1CYcm6o.js";
4
+ import { n as permdockKeys } from "../permdock-sql-DImJULY-.js";
5
+ //#region src/sql/kit.d.ts
6
+ /**
7
+ * SQL kit modules for `better-supabase sql add`. Every module is idempotent
8
+ * (`create or replace`, `if not exists`), so re-running it upgrades in place.
9
+ */
10
+ interface SqlModule {
11
+ readonly name: string;
12
+ readonly title: string;
13
+ readonly description: string;
14
+ /** Modules this one needs, added along with it. */
15
+ readonly requires: readonly string[];
16
+ /** What it needs instead when the layout has `permdock`. */
17
+ readonly permdockRequires?: readonly string[];
18
+ /** `schema` files go with your schemas; `test` files go to `supabase/tests`. */
19
+ readonly target: "schema" | "test";
20
+ /** The module with the default claim names. */
21
+ readonly sql: string;
22
+ /** The module for configured claim names (`config.claims`), when it reads claims. */
23
+ readonly render?: (claims: ClaimsMeta, layout: KitLayout) => string;
24
+ }
25
+ /** New modules go at the end: the position is part of the file name. */
26
+ export declare const SQL_MODULES: Readonly<Record<string, SqlModule>>;
27
+ /** The modules to install for `names`, dependencies first. Throws on an unknown name. */
28
+ export declare function resolveModules(names: readonly string[], layout?: KitLayout): SqlModule[];
29
+ interface KitFile {
30
+ readonly module: string;
31
+ readonly path: string;
32
+ readonly contents: string;
33
+ }
34
+ interface KitLayout {
35
+ /** Directory for schema modules. Defaults to `supabase/schemas`. */
36
+ readonly dir?: string;
37
+ /** File prefix. Defaults to `900_better_supabase`. */
38
+ readonly prefix?: string;
39
+ /** Directory for pgTAP files. Defaults to `supabase/tests`. */
40
+ readonly testsDir?: string;
41
+ /** Version stamped into the header. */
42
+ readonly version?: string;
43
+ /** `config.realtime.tables`: registered at the end of the `realtime-tables` module. */
44
+ readonly realtimeTables?: readonly string[];
45
+ /** Tenant column passed to `track_realtime`; tables without it broadcast unscoped. */
46
+ readonly tenantColumn?: string;
47
+ /** Check constraints for the `jsonb-schemas` module. */
48
+ readonly jsonSchemas?: readonly JsonSchemaCheck[];
49
+ /** `config.expose`: the grants the `grants` module writes. */
50
+ readonly grants?: readonly TableGrant[];
51
+ /** `config.readSets`, compiled: the functions the `read-sets` module writes. */
52
+ readonly readSets?: readonly {
53
+ readonly name: string;
54
+ readonly sql: string;
55
+ }[];
56
+ /** `config.entitlements`: where the `entitlements` module finds each tenant's Stripe customer. */
57
+ readonly entitlements?: EntitlementsSource;
58
+ /** `config.vectorSearch`: the tables the `vector-search` module writes a search function for. */
59
+ readonly vectorSearch?: readonly VectorSearchTable[];
60
+ /** `config.claims`: claim names the modules read and write. */
61
+ readonly claims?: ClaimsMeta;
62
+ /** PermDock's helpers and membership sources, from its manifest: `entitlements` reads them instead of `tenant`. */
63
+ readonly permdock?: KitPermdock;
64
+ }
65
+ /** One PermDock membership source, from the manifest's `memberships`. */
66
+ interface KitMembershipSource {
67
+ /** `schema.table`. */
68
+ readonly table: string;
69
+ readonly userColumn: string;
70
+ readonly scope: {
71
+ readonly column: string;
72
+ } | {
73
+ readonly value: string;
74
+ };
75
+ readonly idColumn: string;
76
+ }
77
+ /** Where PermDock's `member_<scope>_ids` helpers live, and the tables behind them. */
78
+ interface KitPermdock {
79
+ /** PermDock's `rls.schema`. */
80
+ readonly schema: string;
81
+ /** The PermDock scope tenants map to, e.g. `organization`. */
82
+ readonly scope: string;
83
+ readonly memberships: readonly KitMembershipSource[];
84
+ }
85
+ /** An embedding column `db.$search` can query. */
86
+ interface VectorSearchTable {
87
+ /** `table` or `schema.table`. */
88
+ readonly table: string;
89
+ readonly column: string;
90
+ readonly distance: "cosine" | "l2" | "inner_product";
91
+ }
92
+ /** The table holding each tenant's Stripe customer id. */
93
+ interface EntitlementsSource {
94
+ /** `table` or `schema.table`. */
95
+ readonly table: string;
96
+ /** Column with the Stripe customer id (`cus_...`). */
97
+ readonly column: string;
98
+ /** Column with the tenant id. */
99
+ readonly key: string;
100
+ }
101
+ /** Privileges one Data API role gets on a table or view. */
102
+ interface TableGrant {
103
+ /** `table` or `schema.table`. */
104
+ readonly table: string;
105
+ readonly role: "anon" | "authenticated";
106
+ readonly privileges: readonly ("select" | "insert" | "update" | "delete")[];
107
+ }
108
+ /** A jsonb column and the JSON Schema its values must match. */
109
+ interface JsonSchemaCheck {
110
+ /** `table` or `schema.table`. */
111
+ readonly table: string;
112
+ readonly column: string;
113
+ readonly schema: Readonly<Record<string, unknown>>;
114
+ }
115
+ /** Whether an installed file matches, ignoring the version stamped in its header. */
116
+ export declare function sameKitFile(current: string | undefined, expected: string): boolean;
117
+ /** The files `sql add` writes for these modules. */
118
+ export declare function renderKit(names: readonly string[], layout?: KitLayout): KitFile[];
119
+ //#endregion
120
+ //#region src/sql/layout.d.ts
121
+ /** Where and how `sql add` writes kit files for this config. */
122
+ export declare function kitLayout(config: ResolvedConfig, testsDir?: string, readSets?: KitLayout["readSets"], permdock?: KitPermdock): KitLayout;
123
+ //#endregion
124
+ //#region src/sql/read-sets.d.ts
125
+ /** A read set compiled to the SQL of its function. */
126
+ interface CompiledReadSet {
127
+ readonly name: string;
128
+ readonly sql: string;
129
+ }
130
+ /**
131
+ * The function for a read set: `stable`, `security invoker` (RLS applies to
132
+ * the caller) and with an empty `search_path`. Parameters are read from the
133
+ * `p jsonb` argument; nothing is built dynamically.
134
+ */
135
+ export declare function compileReadSet(set: ReadSet): Promise<CompiledReadSet>;
136
+ /** Compiles every set, sorted by name. Throws on a duplicate name. */
137
+ export declare function compileReadSets(sets: readonly ReadSet[]): Promise<CompiledReadSet[]>;
138
+ //#endregion
139
+ export { type CompiledReadSet, type KitFile, type KitLayout, type KitPermdock, type SqlModule, permdockKeys };