better-supabase 0.2.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.
- package/README.md +34 -31
- package/dist/base64-CQeB1eSf.js +42 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +4 -14
- package/dist/{compiler-CZ9nIuqy.d.ts → compiler-2zqGzxVZ.d.ts} +2 -2
- package/dist/config/index.d.ts +4 -3
- package/dist/config/index.js +5 -3
- package/dist/config-Be4GwsqI.js +129 -0
- package/dist/{index-DOsjFvMf.d.ts → config-C1CYcm6o.d.ts} +49 -49
- package/dist/{config-ClDXmVtY.js → config-DOsGYSiT.js} +14 -137
- package/dist/{define-BXMYD9AY.js → define-DF341GDj.js} +71 -51
- package/dist/{define-e3zI4_4g.d.ts → define-DUbydmJa.d.ts} +10 -9
- package/dist/edge/index.d.ts +4 -4
- package/dist/edge/index.js +4 -4
- package/dist/{entitlements-Dng-ctuT.d.ts → entitlements-DvJXoI02.d.ts} +1 -1
- package/dist/env/index.js +203 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.js +139 -1
- package/dist/{events-DOt3nSO-.d.ts → events-Do8jXh4D.d.ts} +3 -3
- package/dist/{executor-BYXQ9AGn.d.ts → executor-B26lgbHD.d.ts} +2 -2
- package/dist/{executor-DeppvirK.js → executor-C57jx2pn.js} +7 -2
- package/dist/{executor-CGdNQ27g.d.ts → executor-DynmIWhq.d.ts} +2 -2
- package/dist/hono/index.d.ts +5 -5
- package/dist/hono/index.js +4 -4
- package/dist/{index-CBDufH1M.d.ts → index-BNsABq7P.d.ts} +8 -8
- package/dist/{index-Bw1bwtC0.d.ts → index-CADlNHK-.d.ts} +27 -14
- package/dist/{index-DuP14VHo.d.ts → index-CTTMS6_1.d.ts} +19 -8
- package/dist/index-Cf-D2jk1.d.ts +50 -0
- package/dist/{index-K-3WM2Hp.d.ts → index-CriFFJ_p.d.ts} +4 -4
- package/dist/{index-Ciu5Xlml.d.ts → index-GV77NpRP.d.ts} +5 -4
- package/dist/{index-D4v7sncu.d.ts → index-UJ-LUxtI.d.ts} +3 -3
- package/dist/{index-CG69s15v.d.ts → index-kpgopLNv.d.ts} +4 -3
- package/dist/{index-DbxFr7XG.d.ts → index-qriRM9cZ.d.ts} +7 -2
- package/dist/index.d.ts +12 -12
- package/dist/index.js +16 -7
- package/dist/jobs/index.d.ts +25 -24
- package/dist/jobs/index.js +16 -10
- package/dist/{json-schema-BpYqkCKf.js → json-schema--aOXAGfU.js} +7 -2
- package/dist/lint/index.js +1 -1
- package/dist/list/index.d.ts +2 -2
- package/dist/list/index.js +128 -93
- package/dist/{live-DJyZMD6w.d.ts → live-QE3UPbGm.d.ts} +16 -6
- package/dist/mcp/index.d.ts +24 -17
- package/dist/mcp/index.js +41 -12
- package/dist/{mfa-CpLfJSde.js → mfa-BxoR1RkN.js} +74 -19
- package/dist/{mfa-TVia554c.d.ts → mfa-x3V3vGh-.d.ts} +1 -1
- package/dist/next/index.d.ts +39 -26
- package/dist/next/index.js +28 -23
- package/dist/openapi/index.d.ts +1 -1
- package/dist/openapi/index.js +57 -34
- package/dist/orpc/index.d.ts +6 -6
- package/dist/orpc/index.js +3 -3
- package/dist/otel/index.d.ts +2 -2
- package/dist/otel/index.js +4 -2
- package/dist/{permdock-sql-CghlHPuH.js → permdock-sql-Bta_G0v-.js} +11 -6
- package/dist/permdock-sql-DImJULY-.d.ts +17 -0
- package/dist/{plugin-C4TR9J0Z.d.ts → plugin-DVRB8qNE.d.ts} +5 -4
- package/dist/plugins/actor/index.d.ts +1 -1
- package/dist/plugins/rules/index.d.ts +2 -2
- package/dist/plugins/rules/index.js +4 -4
- package/dist/plugins/soft-delete/index.d.ts +3 -3
- package/dist/plugins/soft-delete/index.js +2 -2
- package/dist/plugins/tenant/index.d.ts +2 -2
- package/dist/plugins/timestamps/index.d.ts +1 -1
- package/dist/plugins/timestamps/index.js +1 -1
- package/dist/plugins/validation/index.d.ts +2 -2
- package/dist/pool-B9qsLyFR.d.ts +71 -0
- package/dist/postgres/index.d.ts +10 -5
- package/dist/postgres/index.js +36 -16
- package/dist/{postgrest-cAEQ_IQN.d.ts → postgrest-DmBlevh-.d.ts} +1 -1
- package/dist/{problem-BTkTtRV9.js → problem-CGt1ADix.js} +10 -4
- package/dist/{problem-DlgB0lYl.d.ts → problem-Z2RTQjZD.d.ts} +6 -4
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +1 -1
- package/dist/{query-ChvDbsDE.js → query-BdKLTPlj.js} +2 -2
- package/dist/react/index.d.ts +7 -7
- package/dist/react/index.js +2 -2
- package/dist/react/server.d.ts +3 -3
- package/dist/react/server.js +1 -1
- package/dist/react/session.d.ts +21 -2
- package/dist/react/session.js +19 -1
- package/dist/{react-C83BdBGt.js → react-DNBYNazu.js} +20 -16
- package/dist/{read-set-4lI3W_gZ.js → read-set-D0qBcboM.js} +3 -3
- package/dist/realtime/index.d.ts +4 -3
- package/dist/realtime/index.js +7 -6
- package/dist/{resolve-CjHILk2w.d.ts → resolve-BRciX2jK.d.ts} +6 -5
- package/dist/{resource-CgZa3YG_.d.ts → resource-CwVgiI5q.d.ts} +16 -7
- package/dist/{resource-BHEWmQJK.js → resource-D30rp0GN.js} +38 -16
- package/dist/{respond-DMcbQwfN.js → respond-C44EZAJo.js} +35 -19
- package/dist/{respond-Dne1ARSa.d.ts → respond-DAkPIdTH.d.ts} +15 -9
- package/dist/{result-CTkCZ6JA.d.ts → result-c2OYgCV2.d.ts} +13 -8
- package/dist/server/index.d.ts +35 -10
- package/dist/server/index.js +38 -9
- package/dist/{simplify-bwJpLnaS.js → simplify-LakqK1vH.js} +10 -16
- package/dist/sql/index.d.ts +139 -0
- package/dist/sql/index.js +1983 -0
- package/dist/{sql-DTjA1LPj.js → sql-BIgk12ew.js} +72 -16
- package/dist/ssr/index.d.ts +4 -4
- package/dist/ssr/index.js +2 -2
- package/dist/{standard-CyhRzctb.d.ts → standard-eudBiRk1.d.ts} +1 -1
- package/dist/{stats-C5W-rBfR.js → stats-D78UQ8Yu.js} +8 -7
- package/dist/storage/index.d.ts +4 -3
- package/dist/storage/index.js +530 -1
- package/dist/{tables-rZxRxNPW.js → tables-Dhha3BXM.js} +5 -5
- package/dist/temporal-BwshQk0W.js +27 -0
- package/dist/temporal-required-CMxeSVPo.js +19 -0
- package/dist/testing/index.d.ts +13 -11
- package/dist/testing/index.js +128 -29
- package/dist/{types-C83v5SQz.d.ts → types-DONv9SHN.d.ts} +14 -11
- package/dist/{version-Cqq1m3UY.js → version-BfpG2gks.js} +1 -1
- package/dist/{view-D1s0wa0T.d.ts → view-3Po_PVlr.d.ts} +34 -4
- package/dist/{view-aOYizTeE.js → view-wZ-9qIUz.js} +11 -2
- package/dist/webhooks/index.d.ts +18 -16
- package/dist/webhooks/index.js +1 -1
- package/dist/{webhooks-DMipjhSP.js → webhooks-CAIFQSTM.js} +11 -9
- package/package.json +24 -28
- package/schemas/config-v1.json +31 -1
- package/schemas/doctor-report-v1.json +17 -1
- package/schemas/snapshot-v2.json +35 -0
- package/skills/better-supabase/SKILL.md +23 -11
- package/skills/better-supabase/references/plugins.md +21 -18
- package/skills/better-supabase/references/troubleshooting.md +15 -15
- package/skills/better-supabase-api/SKILL.md +7 -7
- package/skills/better-supabase-api/references/adapters.md +30 -25
- package/skills/better-supabase-testing/SKILL.md +11 -8
- package/bin/better-supabase.js +0 -4
- package/dist/casing-da0uRTqt.js +0 -14
- package/dist/cli/bin.d.ts +0 -1
- package/dist/cli/bin.js +0 -15
- package/dist/cli/index.d.ts +0 -226
- package/dist/cli/index.js +0 -3
- package/dist/cli-DrSgDOQC.js +0 -6646
- package/dist/env-BEToab0I.js +0 -204
- package/dist/events-BuzTgn2D.js +0 -135
- package/dist/pool-R2m_DkXi.d.ts +0 -37
- package/dist/seed-CzecODcJ.js +0 -101
- package/dist/session-C3LxnQ0e.d.ts +0 -22
- package/dist/session-CqEwzVup.js +0 -20
- package/dist/storage-DuGn38fr.js +0 -527
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { i as tenantClaimPaths, n as claimAt, r as claimsOf } from "./claims-CoTobNC-.js";
|
|
2
2
|
import { t as invalidateTables } from "./invalidate-DbxuL2jL.js";
|
|
3
3
|
import { n as liveQuery, t as liveCount } from "./live-D8rV1Ldw.js";
|
|
4
|
-
import {
|
|
4
|
+
import { useSession } from "./react/session.js";
|
|
5
5
|
import { createContext, createElement, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
6
|
-
//#region src/react/
|
|
6
|
+
//#region src/react/hooks.ts
|
|
7
7
|
const BrowserContext = createContext(null);
|
|
8
8
|
const LOADING = {
|
|
9
9
|
status: "loading",
|
|
@@ -91,9 +91,9 @@ function useBroadcast(topic, values, handlers, options) {
|
|
|
91
91
|
const userId = auth.user?.id ?? null;
|
|
92
92
|
if (options?.invalidate && !queryClient) throw new Error("better-supabase: useBroadcast({ invalidate }) needs <BetterSupabaseProvider queryClient={...}>");
|
|
93
93
|
useEffect(() => {
|
|
94
|
-
if (!name || auth.status === "loading") return
|
|
94
|
+
if (!name || auth.status === "loading") return;
|
|
95
95
|
const matched = topic.match(name);
|
|
96
|
-
if (!matched) return
|
|
96
|
+
if (!matched) return;
|
|
97
97
|
const forward = (payload, message) => {
|
|
98
98
|
const current = latest.current;
|
|
99
99
|
const table = current.handlers;
|
|
@@ -153,7 +153,7 @@ function useLiveQuery(spec, options = {}) {
|
|
|
153
153
|
const userId = auth.user?.id ?? null;
|
|
154
154
|
const debounceMs = options.debounceMs;
|
|
155
155
|
useEffect(() => {
|
|
156
|
-
if (!key || !queryClient || auth.status === "loading") return
|
|
156
|
+
if (!key || !queryClient || auth.status === "loading") return;
|
|
157
157
|
const live = liveQuery(browser.sb, browser.supabase, JSON.parse(key), {
|
|
158
158
|
onChange: (tables) => void invalidateTables(queryClient, tables),
|
|
159
159
|
onStatus: setStatus,
|
|
@@ -202,19 +202,23 @@ function useLiveCount(source, options = {}) {
|
|
|
202
202
|
const debounceMs = options.debounceMs;
|
|
203
203
|
const hasInitial = initial !== void 0;
|
|
204
204
|
useEffect(() => {
|
|
205
|
-
if (!key || auth.status === "loading") return
|
|
205
|
+
if (!key || auth.status === "loading") return;
|
|
206
206
|
const live = liveCount(browser.sb, browser.supabase, browser.db, JSON.parse(key), {
|
|
207
207
|
immediate: !hasInitial,
|
|
208
|
-
onCount: (count) =>
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
208
|
+
onCount: (count) => {
|
|
209
|
+
setState({
|
|
210
|
+
key,
|
|
211
|
+
count,
|
|
212
|
+
error: void 0
|
|
213
|
+
});
|
|
214
|
+
},
|
|
215
|
+
onError: (error) => {
|
|
216
|
+
setState((previous) => ({
|
|
217
|
+
key,
|
|
218
|
+
count: previous.key === key ? previous.count : void 0,
|
|
219
|
+
error
|
|
220
|
+
}));
|
|
221
|
+
},
|
|
218
222
|
onStatus: setStatus,
|
|
219
223
|
...tenant === void 0 ? {} : { tenant },
|
|
220
224
|
...debounceMs === void 0 ? {} : { debounceMs }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as IrBuilder, u as tableMeta } from "./simplify-
|
|
2
|
-
import { n as touchedTables } from "./tables-
|
|
1
|
+
import { r as IrBuilder, u as tableMeta } from "./simplify-LakqK1vH.js";
|
|
2
|
+
import { n as touchedTables } from "./tables-Dhha3BXM.js";
|
|
3
3
|
//#region src/core/spec.ts
|
|
4
4
|
const READ_METHODS = [
|
|
5
5
|
"findMany",
|
|
@@ -87,7 +87,7 @@ const TYPE = /^(?:[a-z_][a-z0-9_]*\.)?[a-z_][a-z0-9_]*(?:\[\])?$/;
|
|
|
87
87
|
/** `jsonb_build_object` takes at most 100 arguments. */
|
|
88
88
|
const MAX_ENTRIES = 50;
|
|
89
89
|
/** Placeholders are `NUL bs:<name> NUL`: no real parameter value holds a NUL. */
|
|
90
|
-
const NUL =
|
|
90
|
+
const NUL = "\0";
|
|
91
91
|
const SENTINEL = new RegExp(`${NUL}bs:([a-z_][a-z0-9_]*)${NUL}`, "gi");
|
|
92
92
|
const EXACT = new RegExp(`^${NUL}bs:([a-z_][a-z0-9_]*)${NUL}$`, "i");
|
|
93
93
|
function sentinel(name) {
|
package/dist/realtime/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { x as PermdockTopicPolicy } from "../types-
|
|
1
|
+
import { x as PermdockTopicPolicy } from "../types-DONv9SHN.js";
|
|
2
|
+
import { t as PermdockCatalog } from "../permdock-sql-DImJULY-.js";
|
|
2
3
|
import { n as TemplateValues, t as TemplateParams } from "../template-mbvlysOo.js";
|
|
3
|
-
import { C as defineTopic, S as TriggerOptions, _ as TopicEvent, a as LiveSource, b as TopicOptions, c as liveQuery, d as RealtimeClient, f as RowChange, g as Topic, h as SubscriptionStatus, i as LiveQueryOptions, l as liveTopic, m as Subscription, n as LiveCountOptions, o as LiveSubscription, p as SubscribeOptions, r as LiveCountSeed, s as liveCount, t as CountRunner, u as EventSchemas, v as TopicHandlers, w as rowChange, x as TopicPayload, y as TopicMessage } from "../live-
|
|
4
|
-
export { type CountRunner, EventSchemas, type LiveCountOptions, type LiveCountSeed, type LiveQueryOptions, type LiveSource, type LiveSubscription, type PermdockTopicPolicy, RealtimeClient, RowChange, SubscribeOptions, Subscription, SubscriptionStatus, type TemplateParams, type TemplateValues, Topic, TopicEvent, TopicHandlers, TopicMessage, TopicOptions, TopicPayload, TriggerOptions, defineTopic, liveCount, liveQuery, liveTopic, rowChange };
|
|
4
|
+
import { C as defineTopic, S as TriggerOptions, _ as TopicEvent, a as LiveSource, b as TopicOptions, c as liveQuery, d as RealtimeClient, f as RowChange, g as Topic, h as SubscriptionStatus, i as LiveQueryOptions, l as liveTopic, m as Subscription, n as LiveCountOptions, o as LiveSubscription, p as SubscribeOptions, r as LiveCountSeed, s as liveCount, t as CountRunner, u as EventSchemas, v as TopicHandlers, w as rowChange, x as TopicPayload, y as TopicMessage } from "../live-QE3UPbGm.js";
|
|
5
|
+
export { type CountRunner, type EventSchemas, type LiveCountOptions, type LiveCountSeed, type LiveQueryOptions, type LiveSource, type LiveSubscription, type PermdockCatalog, type PermdockTopicPolicy, type RealtimeClient, type RowChange, type SubscribeOptions, type Subscription, type SubscriptionStatus, type TemplateParams, type TemplateValues, type Topic, type TopicEvent, type TopicHandlers, type TopicMessage, type TopicOptions, type TopicPayload, type TriggerOptions, defineTopic, liveCount, liveQuery, liveTopic, rowChange };
|
package/dist/realtime/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import { i as ok, n as err, t as AsyncResult } from "../result-DWXatkd6.js";
|
|
|
3
3
|
import { i as tenantClaimPaths } from "../claims-CoTobNC-.js";
|
|
4
4
|
import { n as liveQuery, r as liveTopic, t as liveCount } from "../live-D8rV1Ldw.js";
|
|
5
5
|
import { s as toApp } from "../shared-_6-uPL7E.js";
|
|
6
|
-
import { a as
|
|
6
|
+
import { a as sqlIdent, i as slug, o as sqlString, r as parseTemplate, t as permdockCheck } from "../permdock-sql-Bta_G0v-.js";
|
|
7
7
|
import { REALTIME_SUBSCRIBE_STATES } from "@supabase/supabase-js";
|
|
8
|
-
//#region src/realtime/
|
|
8
|
+
//#region src/realtime/topic.ts
|
|
9
9
|
const VALUE = /^[\w.@+=-]+$/;
|
|
10
10
|
function validateValue(_name, value) {
|
|
11
11
|
return VALUE.test(value) ? void 0 : "contains characters topics do not allow";
|
|
@@ -55,7 +55,7 @@ function sendError(status, message) {
|
|
|
55
55
|
*/
|
|
56
56
|
function defineTopic(template, options = {}) {
|
|
57
57
|
const parsed = parseTemplate(template, ":", validateValue);
|
|
58
|
-
const literal = template.
|
|
58
|
+
const literal = template.replaceAll(/\{[^}]+\}/g, " ");
|
|
59
59
|
const name = slug(options.name ?? literal) || "topic";
|
|
60
60
|
const isPrivate = options.private ?? true;
|
|
61
61
|
const schemas = options.events ?? {};
|
|
@@ -71,10 +71,10 @@ function defineTopic(template, options = {}) {
|
|
|
71
71
|
if (!permdock) return void 0;
|
|
72
72
|
const where = `defineTopic(${template})`;
|
|
73
73
|
const id = permdock.scope === "global" ? void 0 : `split_part((select realtime.topic()), ':', ${String(permdock.segment ?? segment(tenantParam ?? "orgId", "PermDock"))})`;
|
|
74
|
-
const receive = permdockCheck(where, permdock, permdock.receive, id);
|
|
74
|
+
const receive = permdockCheck(where, permdock, permdock.receive, id, options.catalog);
|
|
75
75
|
return {
|
|
76
76
|
receive,
|
|
77
|
-
send: permdock.send === void 0 ? receive : permdockCheck(where, permdock, permdock.send, id)
|
|
77
|
+
send: permdock.send === void 0 ? receive : permdockCheck(where, permdock, permdock.send, id, options.catalog)
|
|
78
78
|
};
|
|
79
79
|
})();
|
|
80
80
|
if (!permdock && tenantParam && (options.tenant || parsed.params.includes(tenantParam))) {
|
|
@@ -131,7 +131,7 @@ function defineTopic(template, options = {}) {
|
|
|
131
131
|
if (!db) throw new TypeError(`defineTopic: no column for {${param}} on "${table}"`);
|
|
132
132
|
return `rec.${sqlIdent(db)}::text`;
|
|
133
133
|
});
|
|
134
|
-
const schema = trigger.functionSchema ?? "
|
|
134
|
+
const schema = trigger.functionSchema ?? "better_supabase";
|
|
135
135
|
const fn = `${sqlIdent(schema)}.${sqlIdent(`bs_broadcast_${name}_${slug(meta.name)}`)}`;
|
|
136
136
|
const triggerName = sqlIdent(`bs_broadcast_${name}`);
|
|
137
137
|
const target = `${sqlIdent(meta.schema)}.${sqlIdent(meta.name)}`;
|
|
@@ -142,6 +142,7 @@ function defineTopic(template, options = {}) {
|
|
|
142
142
|
]).join(" or ");
|
|
143
143
|
return [
|
|
144
144
|
`-- better-supabase: broadcast ${meta.name} changes to ${template}`,
|
|
145
|
+
`create schema if not exists ${sqlIdent(schema)};`,
|
|
145
146
|
`create or replace function ${fn}()`,
|
|
146
147
|
"returns trigger",
|
|
147
148
|
"language plpgsql",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { p as DbError } from "./result-
|
|
2
|
-
import { f as Logger, l as RefreshEvent } from "./events-
|
|
3
|
-
import { h as RequestContext } from "./plugin-
|
|
4
|
-
import { t as StandardSchemaV1 } from "./standard-
|
|
1
|
+
import { p as DbError } from "./result-c2OYgCV2.js";
|
|
2
|
+
import { f as Logger, l as RefreshEvent } from "./events-Do8jXh4D.js";
|
|
3
|
+
import { h as RequestContext } from "./plugin-DVRB8qNE.js";
|
|
4
|
+
import { t as StandardSchemaV1 } from "./standard-eudBiRk1.js";
|
|
5
5
|
import { t as BetterSupabaseEnv } from "./index-Dy6kuF0P.js";
|
|
6
6
|
import { CookieOptions } from "@supabase/ssr";
|
|
7
7
|
import { JWTClaims, SupabaseEnv, UserClaims } from "@supabase/server";
|
|
@@ -76,7 +76,7 @@ type AuthState<C = unknown, P = unknown> = {
|
|
|
76
76
|
readonly reason: InvalidReason;
|
|
77
77
|
readonly error: DbError;
|
|
78
78
|
};
|
|
79
|
-
type InvalidReason = "token" | "claims";
|
|
79
|
+
type InvalidReason = "token" | "claims" | "actor";
|
|
80
80
|
/**
|
|
81
81
|
* What an `AuthResolver` returns. `reason` may be left out of an `invalid`
|
|
82
82
|
* state; it then counts as `token`.
|
|
@@ -140,6 +140,7 @@ interface ResolveAuthOptions {
|
|
|
140
140
|
/** Called after every refresh attempt (metrics, logging). */
|
|
141
141
|
readonly onRefresh?: (event: RefreshEvent) => void;
|
|
142
142
|
readonly fetch?: typeof fetch;
|
|
143
|
+
/** Epoch milliseconds, the unit JWT `exp` and `iat` math needs. */
|
|
143
144
|
readonly now?: () => number;
|
|
144
145
|
}
|
|
145
146
|
interface AuthResolution<C = unknown, P = unknown> {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { N as TableKey, P as TableMeta, R as Update,
|
|
2
|
-
import { b as ValidationIssue, o as Result } from "./result-
|
|
3
|
-
import { t as BetterSupabase, xt as SelectArg } from "./define-
|
|
4
|
-
import { r as RespondOptions } from "./respond-
|
|
5
|
-
import { i as ResourceOperation } from "./index-
|
|
1
|
+
import { N as TableKey, P as TableMeta, R as Update, g as Insert, n as AnyModels, t as AnyFunctions } from "./types-DONv9SHN.js";
|
|
2
|
+
import { b as ValidationIssue, o as Result } from "./result-c2OYgCV2.js";
|
|
3
|
+
import { t as BetterSupabase, xt as SelectArg } from "./define-DUbydmJa.js";
|
|
4
|
+
import { r as RespondOptions } from "./respond-DAkPIdTH.js";
|
|
5
|
+
import { i as ResourceOperation } from "./index-qriRM9cZ.js";
|
|
6
6
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
7
7
|
//#region src/server/resource.d.ts
|
|
8
8
|
/** What a resource needs from `defineListQuery`. */
|
|
9
9
|
interface ResourceList {
|
|
10
10
|
readonly table: string;
|
|
11
|
+
readonly pagination?: ResourcePagination;
|
|
11
12
|
readonly openapi: readonly unknown[];
|
|
12
13
|
readonly jsonSchema: Readonly<Record<string, unknown>>;
|
|
13
14
|
parse(input: never): {
|
|
@@ -31,9 +32,16 @@ interface ResourceRouteOptions<M extends AnyModels, T extends TableKey<M>> {
|
|
|
31
32
|
readonly create?: StandardSchemaV1<unknown, Insert<M, T>>;
|
|
32
33
|
readonly update?: StandardSchemaV1<unknown, Update<M, T>>;
|
|
33
34
|
};
|
|
34
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Paging of the default list: `offset` (`page` and `size`) or `cursor`
|
|
37
|
+
* (`after` and `size`, keyset). A `list` query brings its own. Defaults
|
|
38
|
+
* to `offset`.
|
|
39
|
+
*/
|
|
40
|
+
readonly pagination?: ResourcePagination;
|
|
41
|
+
/** Largest page for the default list. Defaults to 200. */
|
|
35
42
|
readonly maxPageSize?: number;
|
|
36
43
|
}
|
|
44
|
+
type ResourcePagination = "offset" | "cursor";
|
|
37
45
|
interface ResourceInput {
|
|
38
46
|
/** Primary key value; strings are converted for integer keys. */
|
|
39
47
|
readonly id?: unknown;
|
|
@@ -49,6 +57,7 @@ interface ResourceHandler {
|
|
|
49
57
|
/** Name of the key parameter, or `undefined` for tables without a single-column key. */
|
|
50
58
|
readonly keyParam: string | undefined;
|
|
51
59
|
readonly list: ResourceList | undefined;
|
|
60
|
+
readonly pagination: ResourcePagination;
|
|
52
61
|
readonly maxPageSize: number;
|
|
53
62
|
/** Runs one operation as whoever `db` is bound to. Resolves to a `Result`. */
|
|
54
63
|
execute(db: object, operation: ResourceOperation, input?: ResourceInput): Promise<Result<unknown>>;
|
|
@@ -62,4 +71,4 @@ interface ResourceHandler {
|
|
|
62
71
|
*/
|
|
63
72
|
declare function defineResource<M extends AnyModels, D, F extends AnyFunctions, E, T extends TableKey<M>>(sb: BetterSupabase<M, D, F, E>, table: T, options?: ResourceRouteOptions<M, T>): ResourceHandler;
|
|
64
73
|
//#endregion
|
|
65
|
-
export {
|
|
74
|
+
export { ResourceRouteOptions as a, ResourcePagination as i, ResourceInput as n, defineResource as o, ResourceList as r, ResourceHandler as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as dbError } from "./errors-Bl3rkOzo.js";
|
|
2
2
|
import { i as ok, n as err } from "./result-DWXatkd6.js";
|
|
3
3
|
import { t as validate } from "./standard-FUi3Z3-7.js";
|
|
4
|
-
import { i as respond } from "./respond-
|
|
4
|
+
import { i as respond } from "./respond-C44EZAJo.js";
|
|
5
5
|
//#region src/server/resource.ts
|
|
6
6
|
const INTEGER = /* @__PURE__ */ new Set([
|
|
7
7
|
"int2",
|
|
@@ -24,24 +24,44 @@ async function readBody(request) {
|
|
|
24
24
|
} catch {}
|
|
25
25
|
return err(dbError("invalid_request", "The request body must be a JSON object"));
|
|
26
26
|
}
|
|
27
|
-
function pageArgs(query, max) {
|
|
27
|
+
function pageArgs(query, max, pagination) {
|
|
28
|
+
const raw = (name) => {
|
|
29
|
+
const value = query instanceof URLSearchParams ? query.get(name) : query?.[name];
|
|
30
|
+
return value === null || value === "" ? void 0 : value;
|
|
31
|
+
};
|
|
28
32
|
const read = (name, fallback) => {
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
-
const
|
|
32
|
-
return Number.isSafeInteger(
|
|
33
|
+
const value = raw(name);
|
|
34
|
+
if (value === void 0) return fallback;
|
|
35
|
+
const number = Number(value);
|
|
36
|
+
return Number.isSafeInteger(number) && number >= 1 ? number : void 0;
|
|
33
37
|
};
|
|
34
|
-
const
|
|
38
|
+
const issues = [];
|
|
35
39
|
const size = read("size", 50);
|
|
36
|
-
if (
|
|
37
|
-
message: "Must be a positive integer",
|
|
38
|
-
path: ["page"]
|
|
39
|
-
}] : [], ...size === void 0 || size > max ? [{
|
|
40
|
+
if (size === void 0 || size > max) issues.push({
|
|
40
41
|
message: `Must be between 1 and ${max}`,
|
|
41
42
|
path: ["size"]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
});
|
|
44
|
+
const [used, unused] = pagination === "cursor" ? ["after", "page"] : ["page", "after"];
|
|
45
|
+
if (raw(unused) !== void 0) issues.push({
|
|
46
|
+
message: `This list pages with \`${used}\``,
|
|
47
|
+
path: [unused]
|
|
48
|
+
});
|
|
49
|
+
const page = read("page", 1);
|
|
50
|
+
if (pagination === "offset" && page === void 0) issues.push({
|
|
51
|
+
message: "Must be a positive integer",
|
|
52
|
+
path: ["page"]
|
|
53
|
+
});
|
|
54
|
+
const after = raw("after");
|
|
55
|
+
if (pagination === "cursor" && after !== void 0 && typeof after !== "string") issues.push({
|
|
56
|
+
message: "Must be text",
|
|
57
|
+
path: ["after"]
|
|
58
|
+
});
|
|
59
|
+
if (issues.length > 0 || size === void 0) return err(dbError("validation", "Invalid page parameters", { issues }));
|
|
60
|
+
return pagination === "cursor" ? ok({
|
|
61
|
+
after: typeof after === "string" ? after : null,
|
|
62
|
+
size
|
|
63
|
+
}) : ok({
|
|
64
|
+
page: page ?? 1,
|
|
45
65
|
size
|
|
46
66
|
});
|
|
47
67
|
}
|
|
@@ -78,6 +98,7 @@ function defineResource(sb, table, options = {}) {
|
|
|
78
98
|
const extra = options.select === void 0 ? {} : { select: options.select };
|
|
79
99
|
const maxPageSize = options.maxPageSize ?? 200;
|
|
80
100
|
const list = options.list;
|
|
101
|
+
const pagination = list ? list.pagination ?? "offset" : options.pagination ?? "offset";
|
|
81
102
|
const execute = async (db, operation, input = {}) => {
|
|
82
103
|
const repository = db[table];
|
|
83
104
|
if (!repository) throw new TypeError(`The db has no "${table}" repository`);
|
|
@@ -90,12 +111,12 @@ function defineResource(sb, table, options = {}) {
|
|
|
90
111
|
if (!query.ok) return err(dbError("validation", "Invalid list query", { issues: query.issues }));
|
|
91
112
|
return settled(list.run(db, query.value, extra));
|
|
92
113
|
}
|
|
93
|
-
const page = pageArgs(input.query, maxPageSize);
|
|
114
|
+
const page = pageArgs(input.query, maxPageSize, pagination);
|
|
94
115
|
if (!page.ok) return page;
|
|
95
116
|
return settled(repository.paginate({
|
|
96
117
|
...extra,
|
|
97
118
|
...page.data,
|
|
98
|
-
count: "exact"
|
|
119
|
+
..."page" in page.data ? { count: "exact" } : {}
|
|
99
120
|
}));
|
|
100
121
|
}
|
|
101
122
|
case "get": {
|
|
@@ -160,6 +181,7 @@ function defineResource(sb, table, options = {}) {
|
|
|
160
181
|
operations,
|
|
161
182
|
keyParam,
|
|
162
183
|
list,
|
|
184
|
+
pagination,
|
|
163
185
|
maxPageSize,
|
|
164
186
|
execute,
|
|
165
187
|
handle(request, db, id, respondOptions = {}) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { n as dbError, o as isDbError, r as dbErrorOf } from "./errors-Bl3rkOzo.js";
|
|
2
2
|
import { i as ok, n as err, o as toDbError, t as AsyncResult } from "./result-DWXatkd6.js";
|
|
3
|
-
import { a as postgrestExecutor, n as StatsRecorder } from "./stats-
|
|
4
|
-
import { a as problemResponse } from "./problem-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { n as postgresExecutor } from "./executor-
|
|
3
|
+
import { a as postgrestExecutor, n as StatsRecorder } from "./stats-D78UQ8Yu.js";
|
|
4
|
+
import { a as problemResponse } from "./problem-CGt1ADix.js";
|
|
5
|
+
import { loadEnv } from "./env/index.js";
|
|
6
|
+
import { _ as actClaim, g as delegationOf, h as actorOf, i as authContext, o as resolveAuth, r as checkAal } from "./mfa-BxoR1RkN.js";
|
|
7
|
+
import { n as postgresExecutor } from "./executor-C57jx2pn.js";
|
|
8
|
+
import { parseCookieHeader, serializeCookieHeader } from "@supabase/ssr";
|
|
8
9
|
import { createClient } from "@supabase/supabase-js";
|
|
9
10
|
//#region src/server/replicas.ts
|
|
10
11
|
/** Cookie holding the epoch ms until which reads stay on the primary. */
|
|
@@ -29,19 +30,18 @@ function replicaState(pinnedUntil = 0, now = Date.now()) {
|
|
|
29
30
|
/** `bs-primary-until` from a `cookie` header, or 0. */
|
|
30
31
|
function pinnedUntil(cookieHeader) {
|
|
31
32
|
if (!cookieHeader) return 0;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const until = Number(value);
|
|
36
|
-
return Number.isFinite(until) ? until : 0;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return 0;
|
|
33
|
+
const value = parseCookieHeader(cookieHeader).find((cookie) => cookie.name === PRIMARY_COOKIE)?.value;
|
|
34
|
+
const until = Number(value);
|
|
35
|
+
return value !== void 0 && Number.isFinite(until) ? until : 0;
|
|
40
36
|
}
|
|
41
37
|
/** A `Set-Cookie` value keeping the next requests on the primary for `pinMs`. */
|
|
42
38
|
function primaryCookie(pinMs, now = Date.now()) {
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
return serializeCookieHeader(PRIMARY_COOKIE, String(now + pinMs), {
|
|
40
|
+
path: "/",
|
|
41
|
+
maxAge: Math.max(1, Math.ceil(pinMs / 1e3)),
|
|
42
|
+
httpOnly: true,
|
|
43
|
+
sameSite: "lax"
|
|
44
|
+
});
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* Reads go to `replica` until the context is pinned; writes, and every read
|
|
@@ -248,7 +248,7 @@ function createServer(sb, options = {}) {
|
|
|
248
248
|
return replica;
|
|
249
249
|
},
|
|
250
250
|
get sql() {
|
|
251
|
-
if (!options.postgres || !sqlClaims) return
|
|
251
|
+
if (!options.postgres || !sqlClaims) return;
|
|
252
252
|
sql ??= sqlFor(sqlClaims, context, recorder);
|
|
253
253
|
return sql;
|
|
254
254
|
},
|
|
@@ -264,7 +264,7 @@ function createServer(sb, options = {}) {
|
|
|
264
264
|
...claims ? { claims } : {},
|
|
265
265
|
...userMetadata ? { userMetadata } : {},
|
|
266
266
|
env: env(),
|
|
267
|
-
...resolveOptions.refresh
|
|
267
|
+
...resolveOptions.refresh === void 0 ? {} : { refresh: resolveOptions.refresh },
|
|
268
268
|
onRefresh: (event) => {
|
|
269
269
|
options.auth?.onRefresh?.(event);
|
|
270
270
|
sb.events.emit("refresh", event);
|
|
@@ -329,10 +329,26 @@ function createServer(sb, options = {}) {
|
|
|
329
329
|
}
|
|
330
330
|
//#endregion
|
|
331
331
|
//#region src/server/respond.ts
|
|
332
|
+
/** The scopes a delegated user token lacks; empty for the user's own session. */
|
|
333
|
+
function missingScopes(auth, required) {
|
|
334
|
+
if (required.length === 0) return [];
|
|
335
|
+
const outcome = actorOf(auth.claims);
|
|
336
|
+
if (!outcome.ok || !outcome.actor) return [];
|
|
337
|
+
const granted = new Set(delegationOf(auth.claims)?.scopes);
|
|
338
|
+
return required.filter((scope) => !granted.has(scope));
|
|
339
|
+
}
|
|
332
340
|
/** `undefined` when `auth` may pass; otherwise the 401/403 error to send. */
|
|
333
|
-
function guard(auth, allow = ["user"], aal = "aal1") {
|
|
341
|
+
function guard(auth, allow = ["user"], aal = "aal1", scopes = []) {
|
|
334
342
|
if (auth.kind === "invalid") return auth.error;
|
|
335
|
-
if (allow.includes(auth.kind))
|
|
343
|
+
if (allow.includes(auth.kind)) {
|
|
344
|
+
const denied = checkAal(auth, aal);
|
|
345
|
+
if (denied || auth.kind !== "user") return denied;
|
|
346
|
+
const missing = missingScopes(auth, scopes);
|
|
347
|
+
return missing.length > 0 ? dbError("forbidden", `The token lacks the scope ${missing.join(" ")}`, {
|
|
348
|
+
code: "INSUFFICIENT_SCOPE",
|
|
349
|
+
scopes
|
|
350
|
+
}) : void 0;
|
|
351
|
+
}
|
|
336
352
|
return auth.kind === "anon" ? dbError("unauthorized", "Sign in to continue", { code: "MISSING_CREDENTIALS" }) : dbError("forbidden", `A ${auth.kind} caller is not allowed here`);
|
|
337
353
|
}
|
|
338
354
|
function isResult(value) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { n as AnyModels, t as AnyFunctions } from "./types-
|
|
2
|
-
import { p as DbError, t as AsyncResult } from "./result-
|
|
3
|
-
import { I as StatsRecorder, P as DbStats, t as BetterSupabase, y as Db } from "./define-
|
|
4
|
-
import { h as RequestContext } from "./plugin-
|
|
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 {
|
|
7
|
-
import { o as ImpersonationOptions, t as Aal } from "./mfa-
|
|
8
|
-
import { a as ResolveAuthOptions, r as AuthState, t as AuthResolution } from "./resolve-
|
|
9
|
-
import { n as Bucket } from "./index-
|
|
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 {
|
|
@@ -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
|
-
/**
|
|
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
|
|
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):
|
|
186
|
-
declare function toBetterResult<T>(result: Result<T>, api: BetterResultApi<T, DbError>):
|
|
187
|
-
declare function toBetterResult<T, E>(result: AsyncResult<T>, api: BetterResultApi<T, E>, mapError: (error: DbError) => E): Promise<
|
|
188
|
-
declare function toBetterResult<T>(result: AsyncResult<T>, api: BetterResultApi<T, unknown>): Promise<
|
|
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:
|
|
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,
|
|
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 };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { n as AnyModels, t as AnyFunctions } from "../types-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { _ as
|
|
7
|
-
import { a as
|
|
8
|
-
import { a as
|
|
9
|
-
import { n as
|
|
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
|
-
|
|
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 };
|