better-supabase 0.6.0 → 0.7.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 (109) hide show
  1. package/dist/{adapter-Bc1o3zyy.js → adapter-B-tL8hqg.js} +104 -25
  2. package/dist/ai-sdk/batches/index.d.ts +1 -1
  3. package/dist/ai-sdk/index.d.ts +1 -1
  4. package/dist/ai-sdk/mcp/index.d.ts +3 -3
  5. package/dist/{api-keys-rCGtKaZA.d.ts → api-keys-CIjghYjV.d.ts} +1 -1
  6. package/dist/astro/index.d.ts +4 -4
  7. package/dist/astro/index.js +2 -2
  8. package/dist/blocks/ai-providers/index.d.ts +1 -1
  9. package/dist/blocks/api-keys/index.d.ts +2 -2
  10. package/dist/blocks/attachments/index.d.ts +18 -4
  11. package/dist/blocks/attachments/index.js +16 -4
  12. package/dist/blocks/audit/index.js +1 -1
  13. package/dist/blocks/connectors/index.d.ts +1 -1
  14. package/dist/blocks/data-lifecycle/index.d.ts +11 -3
  15. package/dist/blocks/data-lifecycle/index.js +8 -3
  16. package/dist/blocks/entitlements/index.d.ts +1 -1
  17. package/dist/blocks/index.d.ts +1 -1
  18. package/dist/blocks/sso/index.d.ts +1 -1
  19. package/dist/blocks/workflow-builder/index.d.ts +2 -2
  20. package/dist/blocks/workflow-builder/react/index.d.ts +1 -1
  21. package/dist/chat-sdk/index.d.ts +1 -1
  22. package/dist/cli/bin.js +1 -1
  23. package/dist/cli/{doctor-B4JOm_ox.js → doctor-CVdnLahA.js} +66 -14
  24. package/dist/cli/{gen-BGLb_zou.js → gen-AIf4MREI.js} +1 -1
  25. package/dist/cli/gen-DSrahEdX.js +2 -0
  26. package/dist/cli/index.d.ts +1 -1
  27. package/dist/cli/index.js +3 -3
  28. package/dist/cli/{init-BIIwclPg.js → init-Cr6arjXU.js} +1 -1
  29. package/dist/cli/{introspect-DNUTuNvb.js → introspect-Bzuv1HHj.js} +1 -1
  30. package/dist/cli/{run-DNWxHynX.js → run-BO052mki.js} +7 -7
  31. package/dist/cli/{sql-D0GUtUPp.js → sql-B8csQPyn.js} +13 -54
  32. package/dist/cli/sql-layout-D6cphHT3.js +69 -0
  33. package/dist/cli/{version-hr88OZG0.js → version-Bp4fyubI.js} +1 -1
  34. package/dist/{composite-DhE66P5u.js → composite-C6I8ZyaF.js} +1 -1
  35. package/dist/{composite-Bt1YK3Ke.d.ts → composite-CpHLEo-G.d.ts} +3 -3
  36. package/dist/{connectors-hkLCwyEz.d.ts → connectors-CrpknU0P.d.ts} +1 -1
  37. package/dist/credentials/index.d.ts +2 -2
  38. package/dist/{csv-CPAzEmB6.js → csv-DCK-PT1n.js} +1 -1
  39. package/dist/edge/index.d.ts +5 -5
  40. package/dist/edge/index.js +3 -3
  41. package/dist/elysia/index.d.ts +1 -1
  42. package/dist/{ended-jLfvw8h-.d.ts → ended-XjeGQ5XW.d.ts} +4 -1
  43. package/dist/{entitlements-DHrY2UDZ.d.ts → entitlements-BKSVGtrG.d.ts} +1 -1
  44. package/dist/eve/index.d.ts +2 -2
  45. package/dist/eve/index.js +1 -1
  46. package/dist/{executor-D14tGopJ.d.ts → executor-BVBFM86G.d.ts} +1 -1
  47. package/dist/expo/index.d.ts +2 -2
  48. package/dist/expo/index.js +3 -3
  49. package/dist/{framework-CONDyPYx.js → framework-BDCpJI7o.js} +1 -1
  50. package/dist/{framework-DuVb4Xa8.d.ts → framework-KIPvRQJU.d.ts} +4 -4
  51. package/dist/h3/index.d.ts +1 -1
  52. package/dist/h3/v1/index.d.ts +1 -1
  53. package/dist/hono/index.d.ts +6 -6
  54. package/dist/hono/index.js +2 -2
  55. package/dist/{index-DDrYaUcq.d.ts → index-CdZKQF98.d.ts} +1 -1
  56. package/dist/{index-CtuakVRc.d.ts → index-CewnYSpv.d.ts} +1 -1
  57. package/dist/{kit-B5tid-q5.d.ts → kit-CkNzZUqv.d.ts} +3 -3
  58. package/dist/mcp/index.d.ts +3 -3
  59. package/dist/mcp/index.js +1 -1
  60. package/dist/mcp/sdk/index.d.ts +3 -3
  61. package/dist/mcp/sdk/index.js +1 -1
  62. package/dist/nestjs/index.d.ts +2 -2
  63. package/dist/next/index.d.ts +13 -8
  64. package/dist/next/index.js +5 -5
  65. package/dist/node/index.d.ts +2 -2
  66. package/dist/orpc/index.d.ts +4 -4
  67. package/dist/orpc/index.js +1 -1
  68. package/dist/otel/index.js +5 -5
  69. package/dist/{provider-BH5UWZJ6.d.ts → provider-D-UEMvSD.d.ts} +1 -1
  70. package/dist/react/index.d.ts +5 -5
  71. package/dist/react/server.d.ts +5 -5
  72. package/dist/react/session.d.ts +2 -2
  73. package/dist/react-router/index.d.ts +4 -4
  74. package/dist/react-router/index.js +2 -2
  75. package/dist/{refusal-D1rgbzNq.d.ts → refusal-DhSU2Vvr.d.ts} +1 -1
  76. package/dist/{resolve-KW8nCeL6.d.ts → resolve-ChTYeTEl.d.ts} +3 -0
  77. package/dist/{resolve-D_IcnvFd.js → resolve-tJZY3FEa.js} +12 -7
  78. package/dist/{resource-D6Uc7Sk7.d.ts → resource-IPS5xi9q.d.ts} +1 -1
  79. package/dist/{respond-DoBijysA.d.ts → respond-DprrgyXX.d.ts} +1 -1
  80. package/dist/server/index.d.ts +47 -10
  81. package/dist/server/index.js +27 -5
  82. package/dist/{server-CeVeeXwz.d.ts → server-ZSJ9rCcV.d.ts} +27 -3
  83. package/dist/solid/index.d.ts +2 -2
  84. package/dist/solid-start/index.d.ts +4 -4
  85. package/dist/solid-start/index.js +2 -2
  86. package/dist/sql/index.d.ts +10 -0
  87. package/dist/sql/index.js +82 -13
  88. package/dist/ssr/index.d.ts +4 -4
  89. package/dist/ssr/index.js +1 -1
  90. package/dist/{support-BivNqSpK.js → support-DWwzVf-O.js} +1 -1
  91. package/dist/{support-view-33Oi07TT.d.ts → support-view-CVOJJLpc.d.ts} +1 -1
  92. package/dist/svelte/index.d.ts +1 -1
  93. package/dist/sveltekit/index.d.ts +4 -4
  94. package/dist/sveltekit/index.js +2 -2
  95. package/dist/tanstack-start/index.d.ts +4 -4
  96. package/dist/tanstack-start/index.js +2 -2
  97. package/dist/{tenant-icPeuUBN.d.ts → tenant-BxNFk9bx.d.ts} +1 -1
  98. package/dist/testing/index.d.ts +5 -5
  99. package/dist/{types-TaiEeBGA.d.ts → types-6rocye-y.d.ts} +1 -1
  100. package/dist/{types-BI-0Sl2v.d.ts → types-AYOvcyep.d.ts} +1 -1
  101. package/dist/{vault-CSO7ss5C.d.ts → vault-wlbBhqm7.d.ts} +1 -1
  102. package/dist/vercel-connect/index.d.ts +1 -1
  103. package/dist/{version-Bvv6aLjZ.js → version--AolB5ej.js} +1 -1
  104. package/dist/{view-DbxLNu8L.d.ts → view-CF7ihnkg.d.ts} +1 -1
  105. package/dist/vue/index.d.ts +2 -2
  106. package/dist/workflow-sdk/builder/index.d.ts +2 -2
  107. package/package.json +1 -1
  108. package/schemas/doctor-report-v1.json +2 -0
  109. package/dist/cli/gen-DAH8FM2W.js +0 -2
@@ -2,24 +2,61 @@ import { b as DbError } from "../result-D7y2fT87.js";
2
2
  import { a as AnyModels, i as AnyFunctions } from "../types-6BdhkmZe.js";
3
3
  import { m as RequestContext } from "../plugin-FGY8UhYm.js";
4
4
  import { _ as writeSession, a as CookieWrite, c as StoredSession, h as sessionCookieName, n as CookieOptions, p as readSession, r as CookieRecord, t as AUTH_CACHE_HEADERS } from "../session-ChiXDZdZ.js";
5
- import { a as ResolveAuthOptions, c as clientIp, i as InvalidReason, l as resolveAuth, n as AuthResolver, o as ResolvedState, r as AuthState, s as authContext, t as AuthResolution } from "../resolve-KW8nCeL6.js";
5
+ import { a as ResolveAuthOptions, c as clientIp, i as InvalidReason, l as resolveAuth, n as AuthResolver, o as ResolvedState, r as AuthState, s as authContext, t as AuthResolution } from "../resolve-ChTYeTEl.js";
6
6
  import { c as fromProblem, d as toProblem, i as ProblemDetails, l as isProblem, n as PROBLEM_CONTENT_TYPE, o as ProblemOptions, r as PROBLEM_TYPE_BASE, s as ProblemResponseOptions, u as problemResponse } from "../problem-DD8LZFjc.js";
7
7
  import { B as DbStats, b as Db, t as BetterSupabase } from "../define-CJJkkr1-.js";
8
- import { A as clearSupportCookie, B as sqlSupportStore, C as SupportOptions, D as supportSessions, E as SupportStartRequest, F as SupportEndedBy, I as SupportListFilter, L as SupportSession, M as supportCookieValue, N as SqlSupportStoreOptions, O as SUPPORT_COOKIE, P as SupportCallerClaims, R as SupportSessionStore, S as SupportAuthorizeInput, T as SupportSessions, V as supportClaims, _ as DeleteAccountOptions, a as ServerDbOptions, b as ActiveSupport, c as createServer, d as SuspendAccountOptions, f as SuspendAccountResult, g as ReplicaState, h as PRIMARY_COOKIE, i as ServerContext, j as supportCookie, k as SupportCookieOptions, l as extendServer, m as suspendAccount, n as ContextOptions, o as ServerOptions, p as endSessions, r as ForContextOptions, s as TENANT_HEADER, t as BetterServer, u as EndSessionsResult, v as DeleteAccountResult, w as SupportPolicy, x as SupportApi, y as deleteAccount, z as SupportStartInput } from "../server-CeVeeXwz.js";
8
+ import { A as supportSessions, B as SupportSession, C as ActiveSupport, D as SupportPolicy, E as SupportOptions, F as supportCookieValue, H as SupportStartInput, I as SqlSupportStoreOptions, L as SupportCallerClaims, M as SupportCookieOptions, N as clearSupportCookie, O as SupportSessions, P as supportCookie, R as SupportEndedBy, S as deleteAccount, T as SupportAuthorizeInput, U as sqlSupportStore, V as SupportSessionStore, W as supportClaims, _ as RequestIdOptions, a as ServerDbOptions, b as DeleteAccountOptions, c as createServer, d as LastSignIn, f as SuspendAccountOptions, g as suspendAccount, h as lastSignIns, i as ServerContext, j as SUPPORT_COOKIE, k as SupportStartRequest, l as extendServer, m as endSessions, n as ContextOptions, o as ServerOptions, p as SuspendAccountResult, r as ForContextOptions, s as TENANT_HEADER, t as BetterServer, u as EndSessionsResult, v as PRIMARY_COOKIE, w as SupportApi, x as DeleteAccountResult, y as ReplicaState, z as SupportListFilter } from "../server-ZSJ9rCcV.js";
9
9
  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-Daak8ukG.js";
10
10
  import { n as SessionActor, r as SessionDelegation, t as ActClaim } from "../actor-CQTlc1Hh.js";
11
- import { n as toSession, t as AuthSession } from "../view-DbxLNu8L.js";
12
- import { a as SessionEntryConfig, c as withGuard, i as withBetterSupabase, l as ServerCore, n as BetterSupabaseContributions, o as withSession, r as BetterSupabaseEntry, s as GuardEntryConfig, t as BetterSupabaseConfig, u as serverCore } from "../composite-Bt1YK3Ke.js";
13
- import { a as RespondOptions, c as isResult, d as RefreshPolicy, f as isPrefetch, h as shouldRefresh, i as MiddlewareOptions, l as respond, m as shouldCheckSession, n as AuthKind, o as Settled, p as refreshFor, r as GuardOptions, s as guard, u as settle } from "../respond-DoBijysA.js";
14
- import { a as AuthorizedContext, i as AuthorizeOptions, l as hasRole, o as BlockActionOptions, r as ActionResult, s as BlockRequireOptions, u as rolesAt } from "../kit-B5tid-q5.js";
15
- import { a as ResourceRouteOptions, i as ResourcePagination, n as ResourceInput, o as defineResource, r as ResourceList, t as ResourceHandler } from "../resource-D6Uc7Sk7.js";
11
+ import { n as toSession, t as AuthSession } from "../view-CF7ihnkg.js";
12
+ import { a as SessionEntryConfig, c as withGuard, i as withBetterSupabase, l as ServerCore, n as BetterSupabaseContributions, o as withSession, r as BetterSupabaseEntry, s as GuardEntryConfig, t as BetterSupabaseConfig, u as serverCore } from "../composite-CpHLEo-G.js";
13
+ import { a as RespondOptions, c as isResult, d as RefreshPolicy, f as isPrefetch, h as shouldRefresh, i as MiddlewareOptions, l as respond, m as shouldCheckSession, n as AuthKind, o as Settled, p as refreshFor, r as GuardOptions, s as guard, u as settle } from "../respond-DprrgyXX.js";
14
+ import { a as AuthorizedContext, i as AuthorizeOptions, l as hasRole, o as BlockActionOptions, r as ActionResult, s as BlockRequireOptions, u as rolesAt } from "../kit-CkNzZUqv.js";
15
+ import { a as ResourceRouteOptions, i as ResourcePagination, n as ResourceInput, o as defineResource, r as ResourceList, t as ResourceHandler } from "../resource-IPS5xi9q.js";
16
16
  import { i as tagFor, n as cacheTagsOf, r as tagCache, t as TagOptions } from "../tags-Cx-LnIQP.js";
17
- import { n as supportOf, t as SupportView } from "../support-view-33Oi07TT.js";
18
- import { a as sessionStatus, c as refreshSession, i as clearSessionCookies, n as SessionStatus, r as SessionStatusOptions, s as RefreshOutcome, t as ClearSessionCookiesOptions } from "../ended-jLfvw8h-.js";
17
+ import { n as supportOf, t as SupportView } from "../support-view-CVOJJLpc.js";
18
+ import { a as sessionStatus, c as refreshSession, i as clearSessionCookies, n as SessionStatus, r as SessionStatusOptions, s as RefreshOutcome, t as ClearSessionCookiesOptions } from "../ended-XjeGQ5XW.js";
19
19
  import { SupabaseClient } from "@supabase/supabase-js";
20
20
  import { Middleware, SingleKeyEntry } from "@supabase/middleware";
21
21
  import { AuthMode, JWTClaims, UserClaims } from "@supabase/server";
22
22
  import { PostgresApi } from "@supabase/server/middleware/postgres";
23
+ //#region src/blocks/csv.d.ts
24
+ interface CsvOptions {
25
+ /**
26
+ * The columns in order. Defaults to every key of the rows, in the order
27
+ * they first appear.
28
+ */
29
+ readonly columns?: readonly string[];
30
+ /**
31
+ * Prefixes a text cell that starts with `=`, `+`, `-`, `@`, a tab or a
32
+ * carriage return with `'`, so a spreadsheet shows it instead of running
33
+ * it as a formula (CSV injection). Default true.
34
+ */
35
+ readonly escapeFormulas?: boolean;
36
+ }
37
+ /** The columns of `rows`: every key, in the order it first appears. */
38
+ export declare function csvColumns(rows: readonly Readonly<Record<string, unknown>>[]): string[];
39
+ /**
40
+ * RFC 4180 CSV with a header row and CRLF line ends. Objects and arrays are
41
+ * written as JSON, null and undefined as empty cells.
42
+ */
43
+ export declare function toCsv(rows: readonly Readonly<Record<string, unknown>>[], options?: CsvOptions): string;
44
+ //#endregion
45
+ //#region src/server/csv.d.ts
46
+ interface CsvResponseOptions extends CsvOptions {
47
+ /** The download name, such as `invoices.csv`. */
48
+ readonly filename: string;
49
+ /** Extra headers, such as `cache-control`. `content-type` and `content-disposition` win. */
50
+ readonly headers?: ConstructorParameters<typeof Headers>[0];
51
+ readonly status?: number;
52
+ }
53
+ /**
54
+ * `rows` as a CSV download: `text/csv; charset=utf-8` with an `attachment`
55
+ * `Content-Disposition`. Text cells that start with a formula character are
56
+ * escaped unless `escapeFormulas` is false.
57
+ */
58
+ export declare function csvResponse(rows: readonly Readonly<Record<string, unknown>>[], options: CsvResponseOptions): Response;
59
+ //#endregion
23
60
  //#region src/server/audit.d.ts
24
61
  /** The CloudEvents `source` of the events the server sends to its `audit` sink. */
25
62
  export declare const SERVER_EVENT_SOURCE = "/better-supabase/server";
@@ -188,4 +225,4 @@ export declare function withDbStats(options?: {
188
225
  };
189
226
  }, () => DbStats>;
190
227
  //#endregion
191
- export { AUTH_CACHE_HEADERS, type Aal, type AccountEventType, type ActClaim, type ActionResult, type ActiveSupport, type AmrEntry, type AuthKind, type AuthResolution, type AuthResolver, type AuthSession, type AuthState, type AuthorizeOptions, type AuthorizedContext, type BetterServer, type BetterSupabaseConfig, type BetterSupabaseContributions, type BetterSupabaseEntry, type BlockActionOptions, type BlockRequireOptions, type ClearSessionCookiesOptions, type ContextOptions, type CookieOptions, type CookieRecord, type CookieWrite, type DeleteAccountOptions, type DeleteAccountResult, type EndSessionsResult, type ForContextOptions, type GuardEntryConfig, type GuardOptions, type HandleOptions, type ImpersonationOptions, type Impersonator, type InvalidReason, type MiddlewareOptions, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, type ProblemDetails, type ProblemOptions, type ProblemResponseOptions, type RefreshOutcome, type RefreshPolicy, type ReplicaState, type ResolveAuthOptions, type ResolvedState, type ResourceHandler, type ResourceInput, type ResourceList, type ResourcePagination, type ResourceRouteOptions, type RespondOptions, SUPPORT_COOKIE, type ServerContext, type ServerCore, type ServerDbOptions, type ServerOptions, type ServerTiming, type SessionActor, type SessionDelegation, type SessionEntryConfig, type SessionLookup, type SessionStatus, type SessionStatusOptions, type Settled, type SqlSupportStoreOptions, type StoredSession, type SupabaseAuthContext, type SupportApi, type SupportAuthorizeInput, type SupportCallerClaims, type SupportCookieOptions, type SupportEndedBy, type SupportListFilter, type SupportOptions, type SupportPolicy, type SupportSession, type SupportSessionStore, type SupportSessions, type SupportStartInput, type SupportStartRequest, type SupportView, type SuspendAccountOptions, type SuspendAccountResult, TENANT_HEADER, type TagOptions, aalOf, amrOf, authContext, cacheTagsOf, checkAal, clearSessionCookies, clearSupportCookie, clientIp, createServer, defineResource, deleteAccount, endSessions, extendServer, fromProblem, guard, hasRole, impersonatorOf, isPrefetch, isProblem, isResult, problemResponse, readSession, refreshFor, refreshSession, resolveAuth, respond, rolesAt, serverCore, sessionCookieName, sessionStatus, settle, shouldCheckSession, shouldRefresh, sqlSupportStore, supportClaims, supportCookie, supportCookieValue, supportOf, supportSessions, suspendAccount, tagCache, tagFor, toProblem, toSession, withBetterSupabase, withGuard, withSession, writeSession };
228
+ export { AUTH_CACHE_HEADERS, type Aal, type AccountEventType, type ActClaim, type ActionResult, type ActiveSupport, type AmrEntry, type AuthKind, type AuthResolution, type AuthResolver, type AuthSession, type AuthState, type AuthorizeOptions, type AuthorizedContext, type BetterServer, type BetterSupabaseConfig, type BetterSupabaseContributions, type BetterSupabaseEntry, type BlockActionOptions, type BlockRequireOptions, type ClearSessionCookiesOptions, type ContextOptions, type CookieOptions, type CookieRecord, type CookieWrite, type CsvOptions, type CsvResponseOptions, type DeleteAccountOptions, type DeleteAccountResult, type EndSessionsResult, type ForContextOptions, type GuardEntryConfig, type GuardOptions, type HandleOptions, type ImpersonationOptions, type Impersonator, type InvalidReason, type LastSignIn, type MiddlewareOptions, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, type ProblemDetails, type ProblemOptions, type ProblemResponseOptions, type RefreshOutcome, type RefreshPolicy, type ReplicaState, type RequestIdOptions, type ResolveAuthOptions, type ResolvedState, type ResourceHandler, type ResourceInput, type ResourceList, type ResourcePagination, type ResourceRouteOptions, type RespondOptions, SUPPORT_COOKIE, type ServerContext, type ServerCore, type ServerDbOptions, type ServerOptions, type ServerTiming, type SessionActor, type SessionDelegation, type SessionEntryConfig, type SessionLookup, type SessionStatus, type SessionStatusOptions, type Settled, type SqlSupportStoreOptions, type StoredSession, type SupabaseAuthContext, type SupportApi, type SupportAuthorizeInput, type SupportCallerClaims, type SupportCookieOptions, type SupportEndedBy, type SupportListFilter, type SupportOptions, type SupportPolicy, type SupportSession, type SupportSessionStore, type SupportSessions, type SupportStartInput, type SupportStartRequest, type SupportView, type SuspendAccountOptions, type SuspendAccountResult, TENANT_HEADER, type TagOptions, aalOf, amrOf, authContext, cacheTagsOf, checkAal, clearSessionCookies, clearSupportCookie, clientIp, createServer, defineResource, deleteAccount, endSessions, extendServer, fromProblem, guard, hasRole, impersonatorOf, isPrefetch, isProblem, isResult, lastSignIns, problemResponse, readSession, refreshFor, refreshSession, resolveAuth, respond, rolesAt, serverCore, sessionCookieName, sessionStatus, settle, shouldCheckSession, shouldRefresh, sqlSupportStore, supportClaims, supportCookie, supportCookieValue, supportOf, supportSessions, suspendAccount, tagCache, tagFor, toProblem, toSession, withBetterSupabase, withGuard, withSession, writeSession };
@@ -2,20 +2,42 @@ import { n as dbError } from "../errors-B11Duf73.js";
2
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-BreOl8b8.js";
3
3
  import { i as userContext, r as impersonatorOf } from "../impersonation-DcqaTBHx.js";
4
4
  import { t as supportOf } from "../support-view-g4YLBeqX.js";
5
+ import { n as toCsv, t as csvColumns } from "../csv-DCK-PT1n.js";
5
6
  import { n as postgresExecutor } from "../executor-De1Of3m3.js";
6
- import { C as serverCore, D as deleteAccount, E as suspendAccount, T as endSessions, _ as withSession, a as unexpectedResponse, b as shouldCheckSession, c as extendServer, d as clearSupportCookie, f as supportCookie, i as resolveToken, m as supportCookieValue, n as flushEvents, o as TENANT_HEADER, r as handle, s as createServer, u as SUPPORT_COOKIE, v as isPrefetch, w as SERVER_EVENT_SOURCE, x as shouldRefresh, y as refreshFor } from "../adapter-Bc1o3zyy.js";
7
+ import { C as serverCore, D as suspendAccount, E as lastSignIns, O as deleteAccount, T as endSessions, _ as withSession, a as unexpectedResponse, b as shouldCheckSession, c as extendServer, d as clearSupportCookie, f as supportCookie, i as resolveToken, m as supportCookieValue, n as flushEvents, o as TENANT_HEADER, r as handle, s as createServer, u as SUPPORT_COOKIE, v as isPrefetch, w as SERVER_EVENT_SOURCE, x as shouldRefresh, y as refreshFor } from "../adapter-B-tL8hqg.js";
7
8
  import { n as PRIMARY_COOKIE } from "../replicas-CwrYp5Zj.js";
8
- import { _ as writeSession, a as refreshSession, c as AUTH_CACHE_HEADERS, h as sessionCookieName, i as resolveAuth, n as clientIp, o as clearSessionCookies, p as readSession, s as sessionStatus, t as authContext } from "../resolve-D_IcnvFd.js";
9
+ import { _ as writeSession, a as refreshSession, c as AUTH_CACHE_HEADERS, h as sessionCookieName, i as resolveAuth, n as clientIp, o as clearSessionCookies, p as readSession, s as sessionStatus, t as authContext } from "../resolve-tJZY3FEa.js";
9
10
  import { a as checkAal, i as amrOf, n as toSession, r as aalOf } from "../view-BeFcRV6G.js";
10
11
  import { a as respond, i as isResult, o as settle, r as guard } from "../respond-BUgsXNgk.js";
11
- import { n as sqlSupportStore, r as supportClaims, t as supportSessions } from "../support-BivNqSpK.js";
12
+ import { n as sqlSupportStore, r as supportClaims, t as supportSessions } from "../support-DWwzVf-O.js";
12
13
  import { n as jwtClaimsOf, r as userClaimsOf, t as authModeOf } from "../claims-DDBQT6BK.js";
13
- import { n as withGuard, t as withBetterSupabase } from "../composite-DhE66P5u.js";
14
+ import { n as withGuard, t as withBetterSupabase } from "../composite-C6I8ZyaF.js";
14
15
  import { t as defineResource } from "../resource-BsvzCMlX.js";
15
16
  import { i as withServerTiming, n as parseDbStats, r as withDbStats, t as DB_CALLS_HEADER } from "../timing-CyTQPubY.js";
16
17
  import { n as tagCache, r as tagFor, t as cacheTagsOf } from "../tags-B99_U9Pp.js";
17
18
  import { a as rolesAt, r as hasRole } from "../kit-Fm-Fv7q5.js";
18
19
  import { defineMiddleware } from "@supabase/middleware";
20
+ //#region src/server/csv.ts
21
+ function disposition(filename) {
22
+ const safe = filename.replaceAll(/[\r\n]/g, " ");
23
+ return `attachment; filename="${safe.replaceAll(/[^\u0020-\u007E]|["\\]/g, "_")}"; filename*=UTF-8''${encodeURIComponent(safe).replaceAll(/['()*]/g, (char) => `%${char.codePointAt(0).toString(16).toUpperCase()}`)}`;
24
+ }
25
+ /**
26
+ * `rows` as a CSV download: `text/csv; charset=utf-8` with an `attachment`
27
+ * `Content-Disposition`. Text cells that start with a formula character are
28
+ * escaped unless `escapeFormulas` is false.
29
+ */
30
+ function csvResponse(rows, options) {
31
+ const { filename, headers, status, ...csv } = options;
32
+ const response = new Response(toCsv(rows, csv), {
33
+ status: status ?? 200,
34
+ ...headers ? { headers } : {}
35
+ });
36
+ response.headers.set("content-type", "text/csv; charset=utf-8");
37
+ response.headers.set("content-disposition", disposition(filename));
38
+ return response;
39
+ }
40
+ //#endregion
19
41
  //#region src/server/entries/upstream.ts
20
42
  /** Repository context from a `@supabase/server` context. */
21
43
  function contextFromSupabase(ctx) {
@@ -120,4 +142,4 @@ async function checkSession(sql, auth) {
120
142
  return row?.active === true ? void 0 : revoked;
121
143
  }
122
144
  //#endregion
123
- export { AUTH_CACHE_HEADERS, DB_CALLS_HEADER, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, SERVER_EVENT_SOURCE, SUPPORT_COOKIE, TENANT_HEADER, aalOf, amrOf, authContext, authModeOf, cacheTagsOf, checkAal, checkSession, clearSessionCookies, clearSupportCookie, clientIp, contextFromSupabase, createServer, defineResource, deleteAccount, endSessions, extendServer, flushEvents, fromProblem, guard, handle, hasRole, impersonatorOf, isPrefetch, isProblem, isResult, jwtClaimsOf, parseDbStats, problemResponse, readSession, refreshFor, refreshSession, resolveAuth, resolveToken, respond, rolesAt, serverCore, sessionCookieName, sessionStatus, settle, shouldCheckSession, shouldRefresh, sqlSupportStore, supportClaims, supportCookie, supportCookieValue, supportOf, supportSessions, suspendAccount, tagCache, tagFor, toProblem, toSession, unexpectedResponse, userClaimsOf, withBetterDb, withBetterPostgres, withBetterSupabase, withBlock, withDbStats, withGuard, withServerTiming, withSession, writeSession };
145
+ export { AUTH_CACHE_HEADERS, DB_CALLS_HEADER, PRIMARY_COOKIE, PROBLEM_CONTENT_TYPE, PROBLEM_TYPE_BASE, SERVER_EVENT_SOURCE, SUPPORT_COOKIE, TENANT_HEADER, aalOf, amrOf, authContext, authModeOf, cacheTagsOf, checkAal, checkSession, clearSessionCookies, clearSupportCookie, clientIp, contextFromSupabase, createServer, csvColumns, csvResponse, defineResource, deleteAccount, endSessions, extendServer, flushEvents, fromProblem, guard, handle, hasRole, impersonatorOf, isPrefetch, isProblem, isResult, jwtClaimsOf, lastSignIns, parseDbStats, problemResponse, readSession, refreshFor, refreshSession, resolveAuth, resolveToken, respond, rolesAt, serverCore, sessionCookieName, sessionStatus, settle, shouldCheckSession, shouldRefresh, sqlSupportStore, supportClaims, supportCookie, supportCookieValue, supportOf, supportSessions, suspendAccount, tagCache, tagFor, toCsv, toProblem, toSession, unexpectedResponse, userClaimsOf, withBetterDb, withBetterPostgres, withBetterSupabase, withBlock, withDbStats, withGuard, withServerTiming, withSession, writeSession };
@@ -6,8 +6,8 @@ import { m as RequestContext } from "./plugin-FGY8UhYm.js";
6
6
  import { a as EventHub } from "./events-DWDhx77e.js";
7
7
  import { t as BetterSupabaseEnv } from "./index-CLg87OBW.js";
8
8
  import { a as CookieWrite } from "./session-ChiXDZdZ.js";
9
- import { a as ResolveAuthOptions, r as AuthState, t as AuthResolution } from "./resolve-KW8nCeL6.js";
10
- import { r as CredentialProvider } from "./provider-BH5UWZJ6.js";
9
+ import { a as ResolveAuthOptions, r as AuthState, t as AuthResolution } from "./resolve-ChTYeTEl.js";
10
+ import { r as CredentialProvider } from "./provider-D-UEMvSD.js";
11
11
  import { B as DbStats, H as StatsRecorder, b as Db, t as BetterSupabase } from "./define-CJJkkr1-.js";
12
12
  import { r as EventSink } from "./cloud-event-C1JCc1bH.js";
13
13
  import { s as SqlClaims, t as BetterPostgres } from "./pool-CAu2nLrL.js";
@@ -278,6 +278,14 @@ interface ReplicaState {
278
278
  pin(): void;
279
279
  }
280
280
  //#endregion
281
+ //#region src/server/request-ids.d.ts
282
+ interface RequestIdOptions {
283
+ readonly requestHeader?: string;
284
+ readonly correlationHeader?: string;
285
+ readonly incoming?: boolean;
286
+ readonly generate?: boolean;
287
+ }
288
+ //#endregion
281
289
  //#region src/server/suspend-account.d.ts
282
290
  interface EndSessionsResult {
283
291
  readonly userId: string;
@@ -293,6 +301,17 @@ interface SuspendAccountResult {
293
301
  readonly ended: number;
294
302
  }
295
303
  declare function endSessions(sql: SqlClient, userId: string): AsyncResult<EndSessionsResult>;
304
+ interface LastSignIn {
305
+ readonly userId: string;
306
+ /** `null` for a user who never signed in. */
307
+ readonly lastSignInAt: Temporal.Instant | null;
308
+ }
309
+ /**
310
+ * The last sign-in of each user, in one query (`better_supabase.last_sign_ins`
311
+ * from the `sessions` module, which only the service role may call). Users
312
+ * that don't exist are missing from the map.
313
+ */
314
+ declare function lastSignIns(sql: SqlClient, userIds: readonly string[]): AsyncResult<ReadonlyMap<string, LastSignIn>>;
296
315
  declare function suspendAccount(service: SupabaseClient | (() => SupabaseClient), sql: SqlClient, userId: string, options: SuspendAccountOptions): AsyncResult<SuspendAccountResult>;
297
316
  //#endregion
298
317
  //#region src/server/server.d.ts
@@ -334,6 +353,7 @@ interface ServerOptions {
334
353
  * `current_setting('request.headers')` (channel, request id, client IP for audit).
335
354
  */
336
355
  readonly headers?: (request: Request) => Readonly<Record<string, string>>;
356
+ readonly requestIds?: RequestIdOptions | false;
337
357
  /**
338
358
  * PostgREST URL for the caller's reads: a read replica or the `<ref>-all`
339
359
  * load balancer. Defaults to `SUPABASE_READ_URL`; `false` reads from the
@@ -431,6 +451,8 @@ interface ServerContext<M extends AnyModels, F extends AnyFunctions, E, C = unkn
431
451
  readonly support?: ActiveSupport;
432
452
  /** `options.credentials`, when the server has one. */
433
453
  readonly credentials?: CredentialProvider;
454
+ readonly requestId?: string;
455
+ readonly correlationId?: string;
434
456
  }
435
457
  interface ContextOptions {
436
458
  readonly refresh?: boolean;
@@ -447,6 +469,8 @@ interface ContextOptions {
447
469
  * looks it up itself; `contextFromResolution` only uses this.
448
470
  */
449
471
  readonly support?: ActiveSupport;
472
+ readonly requestId?: string;
473
+ readonly correlationId?: string;
450
474
  }
451
475
  interface BetterServer<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> {
452
476
  readonly env: BetterSupabaseEnv;
@@ -513,4 +537,4 @@ declare function extendServer<R extends object>(server: object, extra: Omit<R, S
513
537
  */
514
538
  declare function createServer<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: ServerOptions): BetterServer<M, F, E, C, P>;
515
539
  //#endregion
516
- export { clearSupportCookie as A, sqlSupportStore as B, SupportOptions as C, supportSessions as D, SupportStartRequest as E, SupportEndedBy as F, SupportListFilter as I, SupportSession as L, supportCookieValue as M, SqlSupportStoreOptions as N, SUPPORT_COOKIE as O, SupportCallerClaims as P, SupportSessionStore as R, SupportAuthorizeInput as S, SupportSessions as T, supportClaims as V, DeleteAccountOptions as _, ServerDbOptions as a, ActiveSupport as b, createServer as c, SuspendAccountOptions as d, SuspendAccountResult as f, ReplicaState as g, PRIMARY_COOKIE as h, ServerContext as i, supportCookie as j, SupportCookieOptions as k, extendServer as l, suspendAccount as m, ContextOptions as n, ServerOptions as o, endSessions as p, ForContextOptions as r, TENANT_HEADER as s, BetterServer as t, EndSessionsResult as u, DeleteAccountResult as v, SupportPolicy as w, SupportApi as x, deleteAccount as y, SupportStartInput as z };
540
+ export { supportSessions as A, SupportSession as B, ActiveSupport as C, SupportPolicy as D, SupportOptions as E, supportCookieValue as F, SupportStartInput as H, SqlSupportStoreOptions as I, SupportCallerClaims as L, SupportCookieOptions as M, clearSupportCookie as N, SupportSessions as O, supportCookie as P, SupportEndedBy as R, deleteAccount as S, SupportAuthorizeInput as T, sqlSupportStore as U, SupportSessionStore as V, supportClaims as W, RequestIdOptions as _, ServerDbOptions as a, DeleteAccountOptions as b, createServer as c, LastSignIn as d, SuspendAccountOptions as f, suspendAccount as g, lastSignIns as h, ServerContext as i, SUPPORT_COOKIE as j, SupportStartRequest as k, extendServer as l, endSessions as m, ContextOptions as n, ServerOptions as o, SuspendAccountResult as p, ForContextOptions as r, TENANT_HEADER as s, BetterServer as t, EndSessionsResult as u, PRIMARY_COOKIE as v, SupportApi as w, DeleteAccountResult as x, ReplicaState as y, SupportListFilter as z };
@@ -2,9 +2,9 @@ import { b as DbError } from "../result-D7y2fT87.js";
2
2
  import { it as QuerySpec } from "../define-CJJkkr1-.js";
3
3
  import { n as TemplateValues } from "../template-CwO38Do8.js";
4
4
  import { t as AuthSnapshot } from "../bind-Bu_ZNa3W.js";
5
- import { t as AuthSession } from "../view-DbxLNu8L.js";
5
+ import { t as AuthSession } from "../view-CF7ihnkg.js";
6
6
  import { S as Topic, f as PresenceMember, u as EventSchemas, w as TopicHandlers, x as SubscriptionStatus } from "../index-DunNRdnT.js";
7
- import { t as SupportView } from "../support-view-33Oi07TT.js";
7
+ import { t as SupportView } from "../support-view-CVOJJLpc.js";
8
8
  import { a as BroadcastOptions, c as LiveCountSource, d as PresenceTopic, f as UseActionOptions, i as ActionState, l as LiveQueryHookOptions, n as ActionInputOf, o as ClientLike, r as ActionResultOf, s as LiveCountHookOptions, t as fieldErrorsOf, u as PresenceHookOptions } from "../field-errors-BFOa7WhB.js";
9
9
  import { SupabaseClient } from "@supabase/supabase-js";
10
10
  import { Accessor, JSX } from "solid-js";
@@ -1,9 +1,9 @@
1
1
  import { a as AnyModels, i as AnyFunctions } from "../types-6BdhkmZe.js";
2
2
  import { t as BetterSupabase } from "../define-CJJkkr1-.js";
3
- import { t as BetterServer } from "../server-CeVeeXwz.js";
4
- import { a as AuthorizedContext, c as Unwrapped, n as ActionParsed, o as BlockActionOptions, r as ActionResult, s as BlockRequireOptions } from "../kit-B5tid-q5.js";
5
- import { t as RefusalRedirects } from "../refusal-D1rgbzNq.js";
6
- import { n as FrameworkOptions, t as FrameworkLocals } from "../framework-DuVb4Xa8.js";
3
+ import { t as BetterServer } from "../server-ZSJ9rCcV.js";
4
+ import { a as AuthorizedContext, c as Unwrapped, n as ActionParsed, o as BlockActionOptions, r as ActionResult, s as BlockRequireOptions } from "../kit-CkNzZUqv.js";
5
+ import { t as RefusalRedirects } from "../refusal-DhSU2Vvr.js";
6
+ import { n as FrameworkOptions, t as FrameworkLocals } from "../framework-KIPvRQJU.js";
7
7
  import { StandardSchemaV1 } from "@standard-schema/spec";
8
8
  //#region src/solid-start/index.d.ts
9
9
  /** The part of a SolidStart `FetchEvent` the integration reads and writes. */
@@ -1,7 +1,7 @@
1
- import { c as extendServer, n as flushEvents, s as createServer } from "../adapter-Bc1o3zyy.js";
1
+ import { c as extendServer, n as flushEvents, s as createServer } from "../adapter-B-tL8hqg.js";
2
2
  import { t as defaultExpose } from "../respond-BUgsXNgk.js";
3
3
  import { i as requireCaller, o as runAction } from "../kit-Fm-Fv7q5.js";
4
- import { i as localsOf, r as frameworkEntry } from "../framework-CONDyPYx.js";
4
+ import { i as localsOf, r as frameworkEntry } from "../framework-BDCpJI7o.js";
5
5
  import { r as refusalResponse } from "../refusal-CeJWxmkH.js";
6
6
  import { t as beforeRoute } from "../before-route-CnR0C0Jr.js";
7
7
  //#region src/solid-start/index.ts
@@ -191,6 +191,8 @@ interface ModuleLayout {
191
191
  readonly policyGrants?: readonly TableGrant[];
192
192
  /** The tables the schema files create, for `sql.modules.sessions.options.policies`. */
193
193
  readonly declaredTables?: readonly string[];
194
+ /** The declared tables with row level security on, for tables `fromPolicies` makes service-only. */
195
+ readonly rlsTables?: readonly string[];
194
196
  /** `config.readSets`, compiled: the functions the `read-sets` module writes. */
195
197
  readonly readSets?: readonly {
196
198
  readonly name: string;
@@ -417,6 +419,14 @@ interface PolicyGrant {
417
419
  export declare function declaredTables(files: readonly {
418
420
  readonly text: string;
419
421
  }[], schemas: readonly string[]): string[];
422
+ /**
423
+ * The tables in `schemas` that `files` leave with row level security on:
424
+ * `alter table ... enable row level security`, until a later `disable` or
425
+ * `drop table`.
426
+ */
427
+ export declare function rlsTables(files: readonly {
428
+ readonly text: string;
429
+ }[], schemas: readonly string[]): string[];
420
430
  /**
421
431
  * The privileges the permissive policies in `files` imply, per table and
422
432
  * role: `for all` gives the four commands, `to public` (or no `to`) counts
package/dist/sql/index.js CHANGED
@@ -9,7 +9,7 @@ import { t as FINAL_RUN_STATES$1 } from "../run-state-CgBKzYMW.js";
9
9
  import { t as AI_MESSAGE_PART_TYPES } from "../message-CaKlqdsX.js";
10
10
  import { A as jwtClaim, B as replaceColumnCheck, C as canIn, D as disabledHelpersNeedLaterTables, E as disabledHelpers, F as pageSize, G as splitTable$1, H as serviceGrant, I as quotedTable, J as userGrant, K as tenantIn, L as raise$1, M as membershipDisabledAt, N as membershipSuspended, O as ensureCheck, P as organizationMissing, R as recordTrigger, S as addForeignKey, T as columnsObject, U as serviceOnly$1, V as schemaPreamble, W as sha256Hex, _ as SCHEMA, a as MODULE_PERMISSION_SCOPES, b as activeMembership, c as modulePermission, d as roleNames, f as roleScopeIs, g as NOTHING, h as EQUIVALENT_TRIGGERS, i as MODULE_PERMISSIONS, j as memberAddedRecord, k as jsonSchemaChecks, l as modulePermissionKey, m as tenantScope, n as WORKFLOW_SDK_WORLD, o as accessModel, p as rolesOf, q as updatedAt, s as hasPlatformRoles, u as providerPlatformRoles, v as SERVICE_CALLER, w as columnRef, x as addExtraColumns, y as accessDefinesDisabledHelpers, z as renameSql } from "../workflow-sdk-world-D-prir6O.js";
11
11
  import { c as templateFunctions, i as fillTemplate, o as resolveProviderSql, s as scopeProblems, t as SCOPE_ID_TYPES } from "../access-sql-B0dF-SoF.js";
12
- import { t as VERSION } from "../version-Bvv6aLjZ.js";
12
+ import { t as VERSION } from "../version--AolB5ej.js";
13
13
  //#region src/sql/api-schema.ts
14
14
  /** The roles PostgREST runs a request as. */
15
15
  const API_ROLES = /* @__PURE__ */ new Set([
@@ -10196,6 +10196,20 @@ revoke execute on function better_supabase.audit_settings(regclass) from public,
10196
10196
  revoke execute on function better_supabase.audit_schema_calls(text, text, text[]) from public, anon, authenticated;
10197
10197
  revoke execute on function better_supabase.audit_schema(text, text, text[]) from public, anon, authenticated;`;
10198
10198
  //#endregion
10199
+ //#region src/sql/modules/audit-request.ts
10200
+ const requestHeader = (name) => `better_supabase.request_header(${sqlString(name)})`;
10201
+ const traceId = (setting, header) => `coalesce(better_supabase.request_id_or_null(current_setting(${sqlString(setting)}, true)), better_supabase.request_id_or_null(${requestHeader(header)}))`;
10202
+ const requestIdSql = (ctx) => traceId("better_supabase.request_id", ctx.text("requestIdHeader", "x-request-id").toLowerCase());
10203
+ const correlationIdSql = (ctx) => traceId("better_supabase.correlation_id", ctx.text("correlationIdHeader", "x-correlation-id").toLowerCase());
10204
+ const REQUEST_ID_OR_NULL = `create or replace function better_supabase.request_id_or_null(value text)
10205
+ returns text
10206
+ language sql
10207
+ immutable
10208
+ set search_path = ''
10209
+ as $$
10210
+ select case when value ~ '^[A-Za-z0-9._:;,@/+=-]{1,128}$' then value end;
10211
+ $$;`;
10212
+ //#endregion
10199
10213
  //#region src/sql/modules/audit-retention.ts
10200
10214
  /**
10201
10215
  * `purge_audit_log`, which honours an `audit_retention(tenant)` hook, and
@@ -10437,6 +10451,7 @@ const NAMES$24 = {
10437
10451
  } },
10438
10452
  options: [
10439
10453
  "appendOnly",
10454
+ "correlationIdHeader",
10440
10455
  "eventCategory",
10441
10456
  "eventRoles",
10442
10457
  "trustedRoles",
@@ -10446,6 +10461,7 @@ const NAMES$24 = {
10446
10461
  "keepMappedMetadata",
10447
10462
  "metadataColumns",
10448
10463
  "readPolicy",
10464
+ "requestIdHeader",
10449
10465
  "restricted",
10450
10466
  "tenantColumn",
10451
10467
  "tenantLabel",
@@ -10562,8 +10578,6 @@ function castId(value, idType) {
10562
10578
  default: return idType;
10563
10579
  }
10564
10580
  }
10565
- /** The request header `name`, or null outside a Data API request. */
10566
- const requestHeader = (name) => `better_supabase.request_header(${sqlString(name)})`;
10567
10581
  /** How the caller acted: service, support, impersonation, oauth-client, user or system. */
10568
10582
  const ACTOR_KIND = `case
10569
10583
  when coalesce(auth.jwt() ->> 'role', '') = 'service_role' then 'service'
@@ -10582,7 +10596,7 @@ function contextPairs(ctx, tenant, values) {
10582
10596
  ["tenantLabel", tenantLabel(ctx, tenant)],
10583
10597
  ["targetLabel", values.targetLabel],
10584
10598
  ["summary", values.summary],
10585
- ["requestId", values.requestId ?? requestHeader("x-request-id")],
10599
+ ["requestId", values.requestId ?? requestIdSql(ctx)],
10586
10600
  ["correlationId", values.correlationId],
10587
10601
  ["scope", auditWrite(ctx, "scope", values.scope ?? `case when ${tenant} is null then 'platform' else 'tenant' end`)]
10588
10602
  ];
@@ -10632,7 +10646,8 @@ revoke all on ${ctx.table("restricted")} from anon, authenticated;` : "";
10632
10646
  -- Semantic events (audit_event) and the per-table registry fill these.${add("eventType", "text")}${add("category", "text")}${add("outcome", "text")}${add("source", "text")}${add("targetType", "text")}${add("metadata", "jsonb")}${add("idempotencyKey", "text")}
10633
10647
  -- Who acted and on what, as it was then, for audit pages.${add("actorKind", "text")}${add("actorLabel", "text")}${add("tenantLabel", "text")}${add("targetLabel", "text")}${add("summary", "text")}${add("requestId", "text")}${add("correlationId", "text")}${add("scope", "text")}
10634
10648
  ${ctx.has("log", "table") && ctx.has("log", "record") ? `create index if not exists audit_events_record_idx on ${log} (${c("table")}, ${c("record")}, ${c("occurredAt")} desc);\n` : ""}create index if not exists audit_events_organization_idx on ${log} (${c("tenant")}, ${c("occurredAt")} desc);
10635
- create index if not exists audit_events_occurred_at_idx on ${log} (${c("occurredAt")});${ctx.has("log", "idempotencyKey") ? `
10649
+ create index if not exists audit_events_occurred_at_idx on ${log} (${c("occurredAt")});${ctx.has("log", "correlationId") ? `
10650
+ create index if not exists audit_events_correlation_idx on ${log} (${c("correlationId")}) where ${c("correlationId")} is not null;` : ""}${ctx.has("log", "idempotencyKey") ? `
10636
10651
  create unique index if not exists audit_events_idempotency_idx on ${log} (${c("idempotencyKey")}, ${c("tenant")}) nulls not distinct where ${c("idempotencyKey")} is not null;` : ""}
10637
10652
  alter table ${log} enable row level security;
10638
10653
  revoke all on ${log} from anon, authenticated;
@@ -10682,6 +10697,8 @@ exception when others then
10682
10697
  end;
10683
10698
  $$;
10684
10699
 
10700
+ ${REQUEST_ID_OR_NULL}
10701
+
10685
10702
  -- The client address the API gateway appended to x-forwarded-for (the
10686
10703
  -- right-most hop; clients can forge the ones before it), or null.
10687
10704
  create or replace function better_supabase.request_ip()
@@ -10750,7 +10767,7 @@ function triggerFunction(ctx, tenantColumn, restricted) {
10750
10767
  ...contextPairs(ctx, "row_tenant", {
10751
10768
  targetLabel: "row_data ->> entry.label_column",
10752
10769
  summary: "null",
10753
- correlationId: requestHeader("x-correlation-id")
10770
+ correlationId: correlationIdSql(ctx)
10754
10771
  })
10755
10772
  ]);
10756
10773
  const tenantValue = castId(`row_data ->> coalesce(entry.tenant_column, ${sqlString(tenantColumn)})`, ctx.idType);
@@ -10864,10 +10881,10 @@ function auditEvent(ctx, restricted) {
10864
10881
  ...contextPairs(ctx, "tenant", {
10865
10882
  targetLabel: "target_label",
10866
10883
  summary: "summary",
10867
- correlationId: `coalesce(correlation_id, ${requestHeader("x-correlation-id")})`,
10884
+ correlationId: `coalesce(better_supabase.request_id_or_null(correlation_id), ${correlationIdSql(ctx)})`,
10868
10885
  actorKind: `coalesce(actor_kind, ${ACTOR_KIND})`,
10869
10886
  actorLabel: `coalesce(actor_label, ${ACTOR_LABEL})`,
10870
- requestId: `coalesce(request_id, ${requestHeader("x-request-id")})`,
10887
+ requestId: `coalesce(better_supabase.request_id_or_null(request_id), ${requestIdSql(ctx)})`,
10871
10888
  scope: "coalesce(audit_event.scope, case when tenant is null then 'platform' else 'tenant' end)"
10872
10889
  })
10873
10890
  ]);
@@ -11075,7 +11092,7 @@ const AUDIT = {
11075
11092
  dependencies: (layout) => layout.modules?.["audit"]?.options?.["readPolicy"] === true ? ["access"] : [],
11076
11093
  target: "schema",
11077
11094
  modes: ["managed", "adopt"],
11078
- version: 5,
11095
+ version: 6,
11079
11096
  names: NAMES$24,
11080
11097
  contract: () => [
11081
11098
  {
@@ -11170,6 +11187,11 @@ const AUDIT = {
11170
11187
  from: 4,
11171
11188
  description: "Drops the read-only audit_log view that 0.5 kept for the 0.4 names; read better_supabase.audit_events.",
11172
11189
  sql: (ctx) => `drop view if exists ${sqlIdent(ctx.tableName("log").schema)}.audit_log;`
11190
+ },
11191
+ {
11192
+ from: 5,
11193
+ description: "Row changes and audit_event read the request and correlation ids from the better_supabase.request_id and better_supabase.correlation_id settings, then from the requestIdHeader and correlationIdHeader headers, and keep only ids of up to 128 safe characters; managed logs index correlation_id.",
11194
+ sql: () => ""
11173
11195
  }
11174
11196
  ],
11175
11197
  deprecated: [{
@@ -35105,6 +35127,33 @@ function declaredTables(files, schemas) {
35105
35127
  }
35106
35128
  return [...found];
35107
35129
  }
35130
+ const RLS_TOGGLE = new RegExp(String.raw`\balter\s+table\s+(?:if\s+exists\s+)?(?:only\s+)?(${NAME}(?:\s*\.\s*${NAME})?)\s+(enable|disable)\s+row\s+level\s+security\b`, "gi");
35131
+ /**
35132
+ * The tables in `schemas` that `files` leave with row level security on:
35133
+ * `alter table ... enable row level security`, until a later `disable` or
35134
+ * `drop table`.
35135
+ */
35136
+ function rlsTables(files, schemas) {
35137
+ const found = /* @__PURE__ */ new Set();
35138
+ for (const file of files) {
35139
+ const text = withoutComments(file.text);
35140
+ inOrder([[...text.matchAll(RLS_TOGGLE)].map((match) => ({
35141
+ index: match.index,
35142
+ apply: () => {
35143
+ const table = qualified$1(match[1]);
35144
+ if (!schemas.includes(table.slice(0, table.indexOf(".")))) return;
35145
+ if (match[2].toLowerCase() === "enable") found.add(table);
35146
+ else found.delete(table);
35147
+ }
35148
+ })), [...text.matchAll(DROP_TABLE)].map((match) => ({
35149
+ index: match.index,
35150
+ apply: () => {
35151
+ for (const table of droppedTables(match[1])) found.delete(table);
35152
+ }
35153
+ }))]);
35154
+ }
35155
+ return [...found];
35156
+ }
35108
35157
  const TABLE_CONSTRAINT = /^(constraint|check|unique|primary|foreign|exclude|like)\b/i;
35109
35158
  /**
35110
35159
  * Columns each `create table` in `files` declares, as `schema.table` to
@@ -35487,6 +35536,23 @@ $$;
35487
35536
  revoke execute on function better_supabase.session_active() from public, anon;
35488
35537
  grant execute on function better_supabase.session_active() to authenticated;
35489
35538
 
35539
+ -- The last sign-in of many users in one query, for admin lists. auth.users
35540
+ -- isn't readable through the Data API, so only the service role calls this.
35541
+ create or replace function better_supabase.last_sign_ins(p_users uuid[])
35542
+ returns table (user_id uuid, last_sign_in_at timestamptz)
35543
+ language sql
35544
+ stable
35545
+ security definer
35546
+ set search_path = ''
35547
+ as $$
35548
+ select u.id, u.last_sign_in_at
35549
+ from auth.users u
35550
+ where u.id = any(p_users)
35551
+ $$;
35552
+
35553
+ revoke execute on function better_supabase.last_sign_ins(uuid[]) from public, anon, authenticated;
35554
+ grant execute on function better_supabase.last_sign_ins(uuid[]) to service_role;
35555
+
35490
35556
  -- Restrictive, so it applies on top of the table's other policies. Wrapped in
35491
35557
  -- a select, it runs one indexed lookup per statement:
35492
35558
  -- create policy session_required on public.invoices as restrictive
@@ -37379,17 +37445,20 @@ const keyOf = (name) => name.includes(".") ? name : `public.${name}`;
37379
37445
  * Each listed table's complete privilege set: everything is revoked from
37380
37446
  * the API roles first, then the listed privileges are granted. Policy
37381
37447
  * grants fill tables `expose` doesn't list, with every privilege for
37382
- * `service_role`.
37448
+ * `service_role`. With policy grants on, a declared table that `expose`
37449
+ * doesn't list, with RLS on and no permissive policy reaching it, is service-only.
37383
37450
  */
37384
37451
  function tableGrants(layout) {
37385
37452
  const listed = layout.grants ?? [];
37386
37453
  const named = new Set(listed.map((grant) => keyOf(grant.table)));
37387
37454
  const derived = (layout.policyGrants ?? []).filter((grant) => !named.has(keyOf(grant.table)));
37388
37455
  const derivedTables = [...new Set(derived.map((grant) => grant.table))];
37456
+ const reached = new Set((layout.policyGrants ?? []).map((grant) => keyOf(grant.table)));
37457
+ const serviceOnly = layout.policyGrants === void 0 ? [] : (layout.declaredTables ?? []).filter((table) => (layout.rlsTables ?? []).includes(table) && !named.has(keyOf(table)) && !reached.has(keyOf(table)));
37389
37458
  const grants = [
37390
37459
  ...listed,
37391
37460
  ...derived,
37392
- ...derivedTables.map((table) => ({
37461
+ ...[...derivedTables, ...serviceOnly].map((table) => ({
37393
37462
  table,
37394
37463
  role: "service_role",
37395
37464
  privileges: [
@@ -37407,7 +37476,7 @@ function tableGrants(layout) {
37407
37476
  });
37408
37477
  const all = [...statements, ...functions];
37409
37478
  if (all.length === 0) return "";
37410
- return `\n-- config.expose${derived.length > 0 ? " and the policies (sql.modules.grants.options.fromPolicies)" : ""}\n${all.join("\n")}\n`;
37479
+ return `\n-- config.expose${derived.length > 0 || serviceOnly.length > 0 ? " and the policies (sql.modules.grants.options.fromPolicies)" : ""}\n${all.join("\n")}\n`;
37411
37480
  }
37412
37481
  /** A jsonb column and the JSON Schema its values must match. */
37413
37482
  /** Users with a membership in a tenant of `customer`, from the provider's membership tables. */
@@ -38203,4 +38272,4 @@ async function compileReadSets(sets) {
38203
38272
  return Promise.all(names.map((name) => compileReadSet(byName.get(name))));
38204
38273
  }
38205
38274
  //#endregion
38206
- export { AUDIT_CATEGORIES, MODULE_ID_TYPES, SCOPE_ID_TYPES, SQL_MODULES, adoptedColumnProblems, auditRegistrations, compileReadSet, compileReadSets, contractSignature, customContracts, declaredTables, extensionSchema, isModuleIdType, migrationOptionUses, moduleBody, moduleDeprecations, moduleEventTriggers, moduleFilePaths, moduleFileVersion, moduleIdType, moduleLayout, modulePermissionKeys, moduleSchemaExtensions, moduleTopics, moduleVersion, policyGrants, renderModules, resolveModules, resolveProviderSql, sameModuleFile, scopeProblems, sharedRolesProblems, templateFunctions, upgradePlan };
38275
+ export { AUDIT_CATEGORIES, MODULE_ID_TYPES, SCOPE_ID_TYPES, SQL_MODULES, adoptedColumnProblems, auditRegistrations, compileReadSet, compileReadSets, contractSignature, customContracts, declaredTables, extensionSchema, isModuleIdType, migrationOptionUses, moduleBody, moduleDeprecations, moduleEventTriggers, moduleFilePaths, moduleFileVersion, moduleIdType, moduleLayout, modulePermissionKeys, moduleSchemaExtensions, moduleTopics, moduleVersion, policyGrants, renderModules, resolveModules, resolveProviderSql, rlsTables, sameModuleFile, scopeProblems, sharedRolesProblems, templateFunctions, upgradePlan };
@@ -1,6 +1,6 @@
1
1
  import { _ as writeSession, a as CookieWrite, c as StoredSession, d as clearSessionAtScopes, f as parseCookies, g as sessionEncoding, h as sessionCookieName, i as CookieScope, l as WriteSessionOptions, m as serializeCookie, n as CookieOptions, o as DEFAULT_SESSION_ENCODING, p as readSession, r as CookieRecord, s as SessionEncoding, t as AUTH_CACHE_HEADERS, u as applyCookieWrites } from "../session-ChiXDZdZ.js";
2
- import { a as ResolveAuthOptions, l as resolveAuth, n as AuthResolver, r as AuthState, s as authContext, t as AuthResolution } from "../resolve-KW8nCeL6.js";
3
- import { n as toSession, t as AuthSession } from "../view-DbxLNu8L.js";
4
- import { r as MembershipClaim } from "../entitlements-DHrY2UDZ.js";
5
- import { a as sessionStatus, c as refreshSession, i as clearSessionCookies, n as SessionStatus, o as RefreshOptions, r as SessionStatusOptions, s as RefreshOutcome, t as ClearSessionCookiesOptions } from "../ended-jLfvw8h-.js";
2
+ import { a as ResolveAuthOptions, l as resolveAuth, n as AuthResolver, r as AuthState, s as authContext, t as AuthResolution } from "../resolve-ChTYeTEl.js";
3
+ import { n as toSession, t as AuthSession } from "../view-CF7ihnkg.js";
4
+ import { r as MembershipClaim } from "../entitlements-BKSVGtrG.js";
5
+ import { a as sessionStatus, c as refreshSession, i as clearSessionCookies, n as SessionStatus, o as RefreshOptions, r as SessionStatusOptions, s as RefreshOutcome, t as ClearSessionCookiesOptions } from "../ended-XjeGQ5XW.js";
6
6
  export { AUTH_CACHE_HEADERS, type AuthResolution, type AuthResolver, type AuthSession, type AuthState, type ClearSessionCookiesOptions, type CookieOptions, type CookieRecord, type CookieScope, type CookieWrite, DEFAULT_SESSION_ENCODING, type MembershipClaim, type RefreshOptions, type RefreshOutcome, type ResolveAuthOptions, type SessionEncoding, type SessionStatus, type SessionStatusOptions, type StoredSession, type WriteSessionOptions, applyCookieWrites, authContext, clearSessionAtScopes, clearSessionCookies, parseCookies, readSession, refreshSession, resolveAuth, serializeCookie, sessionCookieName, sessionEncoding, sessionStatus, toSession, writeSession };
package/dist/ssr/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { _ as writeSession, a as refreshSession, c as AUTH_CACHE_HEADERS, d as clearSessionAtScopes, f as parseCookies, g as sessionEncoding, h as sessionCookieName, i as resolveAuth, l as DEFAULT_SESSION_ENCODING, m as serializeCookie, o as clearSessionCookies, p as readSession, s as sessionStatus, t as authContext, u as applyCookieWrites } from "../resolve-D_IcnvFd.js";
1
+ import { _ as writeSession, a as refreshSession, c as AUTH_CACHE_HEADERS, d as clearSessionAtScopes, f as parseCookies, g as sessionEncoding, h as sessionCookieName, i as resolveAuth, l as DEFAULT_SESSION_ENCODING, m as serializeCookie, o as clearSessionCookies, p as readSession, s as sessionStatus, t as authContext, u as applyCookieWrites } from "../resolve-tJZY3FEa.js";
2
2
  import { n as toSession } from "../view-BeFcRV6G.js";
3
3
  export { AUTH_CACHE_HEADERS, DEFAULT_SESSION_ENCODING, applyCookieWrites, authContext, clearSessionAtScopes, clearSessionCookies, parseCookies, readSession, refreshSession, resolveAuth, serializeCookie, sessionCookieName, sessionEncoding, sessionStatus, toSession, writeSession };
@@ -3,7 +3,7 @@ import { t as temporal } from "./temporal-required-BVvW7SYJ.js";
3
3
  import { a as ok, r as err, s as toDbError, t as AsyncResult } from "./result-DzUbqgdW.js";
4
4
  import { n as validate } from "./standard-BK0cqJ7y.js";
5
5
  import { t as fromPgError } from "./executor-De1Of3m3.js";
6
- import { d as clearSupportCookie, f as supportCookie, m as supportCookieValue } from "./adapter-Bc1o3zyy.js";
6
+ import { d as clearSupportCookie, f as supportCookie, m as supportCookieValue } from "./adapter-B-tL8hqg.js";
7
7
  import { r as sqlIdent } from "./template--jDkl3UP.js";
8
8
  import { i as emitBlockEvent } from "./block-events-CrT8r7Fe.js";
9
9
  //#region src/auth/support.ts
@@ -1,4 +1,4 @@
1
- import { t as AuthSession } from "./view-DbxLNu8L.js";
1
+ import { t as AuthSession } from "./view-CF7ihnkg.js";
2
2
  //#region src/auth/support-view.d.ts
3
3
  /** A running support session as the target's view shows it, for a banner. */
4
4
  interface SupportView {
@@ -2,7 +2,7 @@ import { b as DbError } from "../result-D7y2fT87.js";
2
2
  import { it as QuerySpec } from "../define-CJJkkr1-.js";
3
3
  import { n as TemplateValues } from "../template-CwO38Do8.js";
4
4
  import { t as AuthSnapshot } from "../bind-Bu_ZNa3W.js";
5
- import { t as AuthSession } from "../view-DbxLNu8L.js";
5
+ import { t as AuthSession } from "../view-CF7ihnkg.js";
6
6
  import { S as Topic, f as PresenceMember, u as EventSchemas, w as TopicHandlers, x as SubscriptionStatus } from "../index-DunNRdnT.js";
7
7
  import { a as BroadcastOptions, c as LiveCountSource, d as PresenceTopic, f as UseActionOptions, i as ActionState, l as LiveQueryHookOptions, n as ActionInputOf, o as ClientLike, r as ActionResultOf, s as LiveCountHookOptions, t as fieldErrorsOf, u as PresenceHookOptions } from "../field-errors-BFOa7WhB.js";
8
8
  import { SupabaseClient } from "@supabase/supabase-js";
@@ -1,9 +1,9 @@
1
1
  import { a as AnyModels, i as AnyFunctions } from "../types-6BdhkmZe.js";
2
2
  import { t as BetterSupabase } from "../define-CJJkkr1-.js";
3
- import { t as BetterServer } from "../server-CeVeeXwz.js";
4
- import { a as AuthorizedContext, c as Unwrapped, i as AuthorizeOptions, n as ActionParsed, o as BlockActionOptions, r as ActionResult, s as BlockRequireOptions } from "../kit-B5tid-q5.js";
5
- import { t as RefusalRedirects } from "../refusal-D1rgbzNq.js";
6
- import { n as FrameworkOptions, t as FrameworkLocals } from "../framework-DuVb4Xa8.js";
3
+ import { t as BetterServer } from "../server-ZSJ9rCcV.js";
4
+ import { a as AuthorizedContext, c as Unwrapped, i as AuthorizeOptions, n as ActionParsed, o as BlockActionOptions, r as ActionResult, s as BlockRequireOptions } from "../kit-CkNzZUqv.js";
5
+ import { t as RefusalRedirects } from "../refusal-DhSU2Vvr.js";
6
+ import { n as FrameworkOptions, t as FrameworkLocals } from "../framework-KIPvRQJU.js";
7
7
  import { t as Validated } from "../shared-DDSjEGDR.js";
8
8
  import { i as tagFor } from "../tags-Cx-LnIQP.js";
9
9
  import { AnyEntry, Contributions } from "@supabase/middleware";
@@ -1,12 +1,12 @@
1
1
  import { t as DbException } from "../db-exception-CnWcYPxL.js";
2
2
  import { r as dbErrorOf } from "../errors-B11Duf73.js";
3
3
  import { o as toProblem } from "../problem-BreOl8b8.js";
4
- import { c as extendServer, n as flushEvents, s as createServer } from "../adapter-Bc1o3zyy.js";
4
+ import { c as extendServer, n as flushEvents, s as createServer } from "../adapter-B-tL8hqg.js";
5
5
  import { t as defaultExpose } from "../respond-BUgsXNgk.js";
6
6
  import { r as tagFor } from "../tags-B99_U9Pp.js";
7
7
  import { i as requireCaller, o as runAction } from "../kit-Fm-Fv7q5.js";
8
8
  import { n as bufferInPlace, t as around } from "../shared-CBxosKK3.js";
9
- import { a as platformWaitUntil, i as localsOf, n as actionInput, r as frameworkEntry } from "../framework-CONDyPYx.js";
9
+ import { a as platformWaitUntil, i as localsOf, n as actionInput, r as frameworkEntry } from "../framework-BDCpJI7o.js";
10
10
  import { i as refusalTarget } from "../refusal-CeJWxmkH.js";
11
11
  //#region src/bridges/sveltekit.ts
12
12
  /**
@@ -1,9 +1,9 @@
1
1
  import { a as AnyModels, i as AnyFunctions } from "../types-6BdhkmZe.js";
2
2
  import { t as BetterSupabase } from "../define-CJJkkr1-.js";
3
- import { t as BetterServer } from "../server-CeVeeXwz.js";
4
- import { a as AuthorizedContext, c as Unwrapped, i as AuthorizeOptions, n as ActionParsed, o as BlockActionOptions, r as ActionResult, s as BlockRequireOptions } from "../kit-B5tid-q5.js";
5
- import { t as RefusalRedirects } from "../refusal-D1rgbzNq.js";
6
- import { n as FrameworkOptions, t as FrameworkLocals } from "../framework-DuVb4Xa8.js";
3
+ import { t as BetterServer } from "../server-ZSJ9rCcV.js";
4
+ import { a as AuthorizedContext, c as Unwrapped, i as AuthorizeOptions, n as ActionParsed, o as BlockActionOptions, r as ActionResult, s as BlockRequireOptions } from "../kit-CkNzZUqv.js";
5
+ import { t as RefusalRedirects } from "../refusal-DhSU2Vvr.js";
6
+ import { n as FrameworkOptions, t as FrameworkLocals } from "../framework-KIPvRQJU.js";
7
7
  import { t as Validated } from "../shared-DDSjEGDR.js";
8
8
  import { AnyEntry, Contributions } from "@supabase/middleware";
9
9
  import { StandardSchemaV1 } from "@standard-schema/spec";