better-supabase 0.3.0 → 0.5.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 +9 -6
- package/bin/better-supabase.js +4 -0
- package/dist/{base64-CQeB1eSf.js → base64-D2gsioCY.js} +2 -2
- package/dist/channel-FQW-CnGR.d.ts +70 -0
- package/dist/claims-BAf6c7is.js +48 -0
- package/dist/cli/_format-Cax5EsM9.js +101 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +48 -0
- package/dist/cli/codemod-DqV7612m.js +388 -0
- package/dist/cli/command-CK14fP91.js +502 -0
- package/dist/cli/compare-BmIWVEui.js +9 -0
- package/dist/cli/config-CPVpXP5I.js +1965 -0
- package/dist/cli/config-dtoekM0v.js +2 -0
- package/dist/cli/db-DOBPt660.js +52 -0
- package/dist/cli/diff-SjkO5rNr.js +752 -0
- package/dist/cli/dist-DBPdlPYK.js +1112 -0
- package/dist/cli/dist-DreZ24Sz.js +129 -0
- package/dist/cli/dist-xn4wlboc.js +732 -0
- package/dist/cli/doctor-L7Z8mYTx.js +2863 -0
- package/dist/cli/env-DmKv_G4A.js +108 -0
- package/dist/cli/env-jIFUADLY.js +511 -0
- package/dist/cli/errors-4v4DTtda.js +56 -0
- package/dist/cli/fastest-levenshtein-CFN-lNDv.js +120 -0
- package/dist/cli/gen-BJc9vdyu.js +2 -0
- package/dist/cli/gen-C2osRcr5.js +2204 -0
- package/dist/cli/index.d.ts +493 -0
- package/dist/cli/index.js +184 -0
- package/dist/cli/init-Saf5-R9T.js +550 -0
- package/dist/cli/introspect--H7oGmcd.js +81 -0
- package/dist/cli/io-k41_z-jT.js +24 -0
- package/dist/cli/json5-ChRycquj.js +787 -0
- package/dist/cli/jsonc-BUniUpOk.js +2 -0
- package/dist/cli/jsonc-D5Fu67jw.js +45 -0
- package/dist/cli/keys-ByKHnvP9.js +83 -0
- package/dist/cli/ohash-D7bG_EOb.js +277 -0
- package/dist/cli/openapi-Cp5Fyta-.js +66 -0
- package/dist/cli/project-B_GeXyHh.js +70 -0
- package/dist/cli/prompts-BNcNfAve.js +1142 -0
- package/dist/cli/prompts-BTYQGunc.js +2 -0
- package/dist/cli/read-sets-BfMQcKy8.js +289 -0
- package/dist/cli/rolldown-runtime-BPOCksWG.js +24 -0
- package/dist/cli/run-BKR2W_79.js +351 -0
- package/dist/cli/seed-CUlqWh-8.js +98 -0
- package/dist/cli/skills-LJJIhLFR.js +137 -0
- package/dist/cli/sql-DzPbfngx.js +348 -0
- package/dist/cli/style-C0NFdJRL.js +29 -0
- package/dist/cli/toml-DB-MNnFs.js +424 -0
- package/dist/cli/version-BDJuO0UR.js +4 -0
- package/dist/cli/yaml-CYCbJ6et.js +2252 -0
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +15 -22
- package/dist/clone-BfgmLU90.js +21 -0
- package/dist/{compiler-2zqGzxVZ.d.ts → compiler-BXH_aZ7N.d.ts} +2 -2
- package/dist/config/index.d.ts +4 -4
- package/dist/config/index.js +5 -5
- package/dist/{config-DOsGYSiT.js → config-DreERlKo.js} +1 -1
- package/dist/{config-C1CYcm6o.d.ts → config-T_ejwyd3.d.ts} +176 -11
- package/dist/{define-DUbydmJa.d.ts → define-Bp_BZa5h.d.ts} +37 -29
- package/dist/{define-DF341GDj.js → define-cNKzqwL_.js} +356 -89
- package/dist/edge/index.d.ts +20 -13
- package/dist/edge/index.js +55 -26
- package/dist/{entitlements-DvJXoI02.d.ts → entitlements-DUxU4oHe.d.ts} +2 -2
- package/dist/env/index.d.ts +2 -2
- package/dist/env/index.js +34 -1
- package/dist/{errors-Bl3rkOzo.js → errors-DtwXa6b8.js} +2 -1
- package/dist/events/index.d.ts +3 -2
- package/dist/events/index.js +69 -16
- package/dist/events-aIO7vsIk.d.ts +230 -0
- package/dist/executor-BunPOO-k.d.ts +402 -0
- package/dist/{executor-B26lgbHD.d.ts → executor-Cghdstwu.d.ts} +1 -2
- package/dist/{executor-C57jx2pn.js → executor-XycESQPH.js} +3 -3
- package/dist/hono/index.d.ts +27 -23
- package/dist/hono/index.js +46 -11
- package/dist/impersonation-VfaGc4Q_.js +41 -0
- package/dist/{index-BNsABq7P.d.ts → index-BGdgBPdf.d.ts} +66 -25
- package/dist/{index-qriRM9cZ.d.ts → index-C7f8cOBM.d.ts} +4 -4
- package/dist/{index-Dy6kuF0P.d.ts → index-CLg87OBW.d.ts} +6 -1
- package/dist/{index-GV77NpRP.d.ts → index-DOESKG27.d.ts} +34 -9
- package/dist/{index-CriFFJ_p.d.ts → index-DgILJRXj.d.ts} +43 -17
- package/dist/{index-UJ-LUxtI.d.ts → index-DmXSxbLi.d.ts} +14 -14
- package/dist/{index-Cf-D2jk1.d.ts → index-Dxn2a5cw.d.ts} +2 -2
- package/dist/{index-CTTMS6_1.d.ts → index-SaTsEfGP.d.ts} +86 -9
- package/dist/{index-CADlNHK-.d.ts → index-fag8VJZ2.d.ts} +5 -6
- package/dist/index.d.ts +34 -17
- package/dist/index.js +15 -14
- package/dist/jobs/index.d.ts +147 -95
- package/dist/jobs/index.js +773 -250
- package/dist/{json-schema--aOXAGfU.js → json-schema-m1fiwKgN.js} +23 -2
- package/dist/kit-events-CTFDfSwb.js +60 -0
- package/dist/kit-transport-B82k1djG.d.ts +33 -0
- package/dist/kit-transport-DJlHQUBU.js +55 -0
- package/dist/{config-Be4GwsqI.js → kits-CGLLrNPd.js} +38 -10
- package/dist/list/index.d.ts +1 -1
- package/dist/list/index.js +3 -3
- package/dist/{live-D8rV1Ldw.js → live-CdJBOc4f.js} +13 -9
- package/dist/{live-QE3UPbGm.d.ts → live-D9W2M5aO.d.ts} +16 -15
- package/dist/lookup-BaP5bI27.js +18 -0
- package/dist/mcp/index.d.ts +39 -22
- package/dist/mcp/index.js +39 -25
- package/dist/{mfa-x3V3vGh-.d.ts → mfa-CusDgPaD.d.ts} +5 -1
- package/dist/next/image/index.js +6 -3
- package/dist/next/index.d.ts +60 -36
- package/dist/next/index.js +167 -50
- package/dist/notifications/index.d.ts +162 -0
- package/dist/notifications/index.js +264 -0
- package/dist/openapi/index.d.ts +1 -1
- package/dist/openapi/index.js +6 -6
- package/dist/orgs/index.d.ts +132 -0
- package/dist/orgs/index.js +245 -0
- package/dist/orpc/index.d.ts +37 -20
- package/dist/orpc/index.js +24 -11
- package/dist/otel/index.d.ts +24 -5
- package/dist/otel/index.js +124 -64
- package/dist/permdock-sql-C2Inc6Xc.d.ts +29 -0
- package/dist/permdock-sql-DgOfeixi.js +51 -0
- package/dist/plugin-DwARMuQp.js +59 -0
- package/dist/{plugin-DVRB8qNE.d.ts → plugin-o144f322.d.ts} +17 -5
- package/dist/plugins/actor/index.d.ts +5 -2
- package/dist/plugins/actor/index.js +22 -8
- package/dist/plugins/rules/index.d.ts +2 -2
- package/dist/plugins/rules/index.js +52 -17
- package/dist/plugins/soft-delete/index.d.ts +3 -3
- package/dist/plugins/soft-delete/index.js +14 -5
- package/dist/plugins/tenant/index.d.ts +3 -3
- package/dist/plugins/tenant/index.js +45 -21
- package/dist/plugins/timestamps/index.d.ts +1 -1
- package/dist/plugins/timestamps/index.js +4 -3
- package/dist/plugins/validation/index.d.ts +2 -2
- package/dist/plugins/validation/index.js +26 -6
- package/dist/{pool-B9qsLyFR.d.ts → pool-C9voM4Kw.d.ts} +24 -6
- package/dist/postgres/index.d.ts +5 -5
- package/dist/postgres/index.js +20 -10
- package/dist/{postgrest-DmBlevh-.d.ts → postgrest-CruYKAvV.d.ts} +1 -1
- package/dist/{problem-CGt1ADix.js → problem-BW1KhzSG.js} +2 -1
- package/dist/{problem-Z2RTQjZD.d.ts → problem-Blxe8S31.d.ts} +1 -1
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +3 -3
- package/dist/{query-BdKLTPlj.js → query-CCbo44lG.js} +18 -18
- package/dist/queue-BYUCjr59.d.ts +252 -0
- package/dist/react/index.d.ts +8 -7
- package/dist/react/index.js +4 -3
- package/dist/react/server.d.ts +16 -5
- package/dist/react/server.js +12 -4
- package/dist/react/session.d.ts +10 -4
- package/dist/react/session.js +11 -3
- package/dist/{react-DNBYNazu.js → react-C_s7kiNz.js} +138 -46
- package/dist/{read-set-D0qBcboM.js → read-set-DQFt1N_Y.js} +71 -15
- package/dist/realtime/index.d.ts +3 -3
- package/dist/realtime/index.js +14 -12
- package/dist/{index-kpgopLNv.d.ts → refresh-BTrQ_ZTp.d.ts} +6 -3
- package/dist/{resolve-BRciX2jK.d.ts → resolve-C15TJq77.d.ts} +22 -11
- package/dist/{resource-D30rp0GN.js → resource-CRxxwkQq.js} +24 -9
- package/dist/{resource-CwVgiI5q.d.ts → resource-D8iqWMr-.d.ts} +6 -6
- package/dist/respond-D2OQl62-.d.ts +371 -0
- package/dist/{result-DWXatkd6.js → result-BKiliPY7.js} +2 -2
- package/dist/server/index.d.ts +17 -15
- package/dist/server/index.js +16 -22
- package/dist/server-Csx2sRjg.js +655 -0
- package/dist/{shared-_6-uPL7E.js → shared-D1dRUrAg.js} +19 -4
- package/dist/signers-Cc6r98SW.d.ts +162 -0
- package/dist/{simplify-LakqK1vH.js → simplify-_0oUKqCd.js} +27 -95
- package/dist/sql/index.d.ts +247 -10
- package/dist/sql/index.js +8591 -780
- package/dist/{sql-BIgk12ew.js → sql-Coh6n4cC.js} +11 -3
- package/dist/ssr/index.d.ts +4 -4
- package/dist/ssr/index.js +1 -2
- package/dist/{standard-FUi3Z3-7.js → standard-D7r6dMUu.js} +6 -3
- package/dist/{standard-eudBiRk1.d.ts → standard-J4YgMOLm.d.ts} +1 -1
- package/dist/{stats-D78UQ8Yu.js → stats-Bqob3WqT.js} +34 -9
- package/dist/storage/index.d.ts +4 -4
- package/dist/storage/index.js +174 -27
- package/dist/support-DT-OhSxD.d.ts +88 -0
- package/dist/support-Dk6vdmEw.js +291 -0
- package/dist/support-view-Da5peKFg.d.ts +17 -0
- package/dist/support-view-g4YLBeqX.js +18 -0
- package/dist/{tables-Dhha3BXM.js → tables-Cb-3_VWc.js} +14 -0
- package/dist/{permdock-sql-Bta_G0v-.js → template-TxrGI5jR.js} +2 -31
- package/dist/{temporal-BwshQk0W.js → temporal-CVlIV2DZ.js} +17 -4
- package/dist/{temporal-required-CMxeSVPo.js → temporal-required-CAt4Dc9Z.js} +2 -2
- package/dist/testing/index.d.ts +113 -24
- package/dist/testing/index.js +375 -47
- package/dist/{types-DONv9SHN.d.ts → types-Dnf_wRDz.d.ts} +26 -3
- package/dist/user-change-CHFEUro1.js +49 -0
- package/dist/{webhooks-CAIFQSTM.js → verify-Ce49ETPz.js} +38 -19
- package/dist/{version-BfpG2gks.js → version-DM_Roffb.js} +1 -1
- package/dist/{view-3Po_PVlr.d.ts → view-BEf0diC5.d.ts} +10 -5
- package/dist/{mfa-BxoR1RkN.js → view-Bq64ki8-.js} +210 -64
- package/dist/webhooks/index.d.ts +136 -5
- package/dist/webhooks/index.js +588 -2
- package/dist/wire-D2dT86vi.js +35 -0
- package/package.json +50 -10
- package/schemas/config-v1.json +131 -1
- package/schemas/doctor-report-v1.json +10 -0
- package/skills/better-supabase/SKILL.md +60 -10
- package/skills/better-supabase/references/plugins.md +13 -14
- package/skills/better-supabase/references/troubleshooting.md +25 -4
- package/skills/better-supabase-api/SKILL.md +74 -19
- package/skills/better-supabase-api/references/adapters.md +48 -27
- package/skills/better-supabase-auth/SKILL.md +149 -0
- package/skills/better-supabase-auth/references/permdock.md +100 -0
- package/skills/better-supabase-testing/SKILL.md +58 -4
- package/dist/claims-CoTobNC-.js +0 -25
- package/dist/events-Do8jXh4D.d.ts +0 -84
- package/dist/executor-DynmIWhq.d.ts +0 -195
- package/dist/invalidate-DbxuL2jL.js +0 -18
- package/dist/permdock-sql-DImJULY-.d.ts +0 -17
- package/dist/plugin-BqR6wKMB.js +0 -23
- package/dist/respond-C44EZAJo.js +0 -399
- package/dist/respond-DAkPIdTH.d.ts +0 -175
- package/dist/result-c2OYgCV2.d.ts +0 -203
- package/dist/view-wZ-9qIUz.js +0 -45
package/dist/mcp/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { n as dbError } from "../errors-
|
|
2
|
-
import { t as base64ToText } from "../base64-
|
|
3
|
-
import { t as validate } from "../standard-
|
|
4
|
-
import { o as toProblem } from "../problem-
|
|
1
|
+
import { n as dbError } from "../errors-DtwXa6b8.js";
|
|
2
|
+
import { t as base64ToText } from "../base64-D2gsioCY.js";
|
|
3
|
+
import { t as validate } from "../standard-D7r6dMUu.js";
|
|
4
|
+
import { a as problemResponse, o as toProblem } from "../problem-BW1KhzSG.js";
|
|
5
5
|
import { t as SPEC_PINS } from "../spec-pins-C3oc-Tdp.js";
|
|
6
|
-
import { t as buildJsonSchema } from "../json-schema
|
|
7
|
-
import { a as
|
|
8
|
-
import { t as defineResource } from "../resource-
|
|
6
|
+
import { t as buildJsonSchema } from "../json-schema-m1fiwKgN.js";
|
|
7
|
+
import { a as withExtra, d as guard, g as jsonResponse, h as jsonReplacer, m as settle, n as createServer, r as extendServer, u as defaultExpose } from "../server-Csx2sRjg.js";
|
|
8
|
+
import { t as defineResource } from "../resource-CRxxwkQq.js";
|
|
9
9
|
import { fromSupabaseUrl, unauthorizedResponse } from "@supabase/server/oauth-protected-resource";
|
|
10
10
|
//#region src/mcp/mcp.ts
|
|
11
11
|
const MCP_PROTOCOL_VERSION = SPEC_PINS.mcp;
|
|
@@ -215,7 +215,7 @@ function textResult(value, isError = false) {
|
|
|
215
215
|
return {
|
|
216
216
|
content: [{
|
|
217
217
|
type: "text",
|
|
218
|
-
text: typeof value === "string" ? value : JSON.stringify(value ?? null)
|
|
218
|
+
text: typeof value === "string" ? value : JSON.stringify(value ?? null, jsonReplacer)
|
|
219
219
|
}],
|
|
220
220
|
...structured ? { structuredContent: structured } : {},
|
|
221
221
|
...isError ? { isError: true } : {}
|
|
@@ -231,17 +231,19 @@ function canonical(request) {
|
|
|
231
231
|
* through RLS. Answers 401 with RFC 9728 metadata so clients can sign in with
|
|
232
232
|
* Supabase Auth's OAuth server.
|
|
233
233
|
*/
|
|
234
|
-
function createMcp(
|
|
235
|
-
const server = createServer(
|
|
234
|
+
function createMcp(betterSupabase, options) {
|
|
235
|
+
const server = createServer(betterSupabase, options);
|
|
236
236
|
const expose = options.exposeErrors ?? defaultExpose();
|
|
237
237
|
const defs = buildJsonSchema({
|
|
238
|
-
meta:
|
|
238
|
+
meta: betterSupabase.meta,
|
|
239
239
|
config: { json: options.json ?? {} }
|
|
240
240
|
})["$defs"];
|
|
241
241
|
const registry = /* @__PURE__ */ new Map();
|
|
242
|
+
let allTools;
|
|
242
243
|
const register = (entry) => {
|
|
243
244
|
if (registry.has(entry.info.name)) throw new TypeError(`Duplicate MCP tool "${entry.info.name}"`);
|
|
244
245
|
registry.set(entry.info.name, entry);
|
|
246
|
+
allTools = void 0;
|
|
245
247
|
};
|
|
246
248
|
const failure = (error) => textResult(toProblem(error, { expose }), true);
|
|
247
249
|
const refused = async (tool, args, ctx) => {
|
|
@@ -256,11 +258,14 @@ function createMcp(sb, options) {
|
|
|
256
258
|
const isVisible = async (tool, ctx) => !options.visible || options.visible(ctx, tool);
|
|
257
259
|
for (const [table, raw] of Object.entries(options.resources ?? {})) {
|
|
258
260
|
if (!raw) continue;
|
|
259
|
-
const
|
|
261
|
+
const key = table;
|
|
262
|
+
const entry = raw;
|
|
263
|
+
const { meta, ...route } = entry === true ? {} : entry;
|
|
264
|
+
const resource = defineResource(betterSupabase, key, route);
|
|
260
265
|
for (const { info, operation } of tableTools(resource, defs)) {
|
|
261
266
|
const ref = {
|
|
262
267
|
info,
|
|
263
|
-
meta:
|
|
268
|
+
meta: meta?.[operation]
|
|
264
269
|
};
|
|
265
270
|
register({
|
|
266
271
|
...ref,
|
|
@@ -302,8 +307,11 @@ function createMcp(sb, options) {
|
|
|
302
307
|
});
|
|
303
308
|
};
|
|
304
309
|
for (const tool of options.tools ?? []) addTool(tool);
|
|
305
|
-
const listTools = () => [...registry.values()].map((entry) => entry.info);
|
|
306
|
-
|
|
310
|
+
const listTools = () => allTools ??= [...registry.values()].map((entry) => entry.info);
|
|
311
|
+
/** Without a `visible` hook every caller sees the same list, built once. */
|
|
312
|
+
const visibleTools = async (context) => {
|
|
313
|
+
if (!options.visible) return listTools();
|
|
314
|
+
const ctx = context();
|
|
307
315
|
const entries = [...registry.values()];
|
|
308
316
|
const shown = await Promise.all(entries.map((entry) => isVisible(entry, ctx)));
|
|
309
317
|
return entries.filter((_, index) => shown[index]).map((e) => e.info);
|
|
@@ -333,7 +341,7 @@ function createMcp(sb, options) {
|
|
|
333
341
|
const outcome = await invoke(name, args, ctx);
|
|
334
342
|
return isRefusal(outcome) ? failure(dbError("forbidden", outcome.refusal)) : outcome;
|
|
335
343
|
};
|
|
336
|
-
const scopes = (options.scopes ?? []).filter((scope) => scope !== "offline_access");
|
|
344
|
+
const scopes = (options.advertisedScopes ?? options.scopes ?? []).filter((scope) => scope !== "offline_access");
|
|
337
345
|
const serverInfo = {
|
|
338
346
|
name: options.name,
|
|
339
347
|
version: options.version,
|
|
@@ -357,6 +365,12 @@ function createMcp(sb, options) {
|
|
|
357
365
|
response.headers.set("www-authenticate", challenge);
|
|
358
366
|
return response;
|
|
359
367
|
};
|
|
368
|
+
/** A missing second factor is no scope problem, and an outage is not the caller's fault. */
|
|
369
|
+
const refuse = (request, denied) => {
|
|
370
|
+
if (denied.kind === "unauthorized") return unauthorized(request);
|
|
371
|
+
if (denied.kind !== "forbidden") return problemResponse(denied, { expose });
|
|
372
|
+
return denied.code === "INSUFFICIENT_AAL" ? rpcError(null, INVALID_REQUEST, denied.message, 403) : forbidden(request, denied.message, denied.scopes);
|
|
373
|
+
};
|
|
360
374
|
const unsupportedVersion = (id, requested) => rpcError(id, UNSUPPORTED_PROTOCOL_VERSION, "Unsupported protocol version", 400, {
|
|
361
375
|
supported: [...SUPPORTED_VERSIONS],
|
|
362
376
|
requested
|
|
@@ -376,7 +390,7 @@ function createMcp(sb, options) {
|
|
|
376
390
|
if (sent === null || headerName(sent) !== name) return mismatch(`Mcp-Name must be ${name}`);
|
|
377
391
|
}
|
|
378
392
|
};
|
|
379
|
-
const
|
|
393
|
+
const endpoint = async (request) => {
|
|
380
394
|
const origin = request.headers.get("origin");
|
|
381
395
|
if (origin && options.allowedOrigins && !options.allowedOrigins.includes(origin)) return rpcError(null, INVALID_REQUEST, "Origin not allowed", 403);
|
|
382
396
|
if (options.allowedHosts && !hostAllowed(request, options.allowedHosts)) return rpcError(null, INVALID_REQUEST, "Host not allowed", 403);
|
|
@@ -386,9 +400,9 @@ function createMcp(sb, options) {
|
|
|
386
400
|
});
|
|
387
401
|
const header = request.headers.get("mcp-protocol-version");
|
|
388
402
|
if (header && !SUPPORTED_VERSIONS.includes(header)) return unsupportedVersion(null, header);
|
|
389
|
-
const ctx = await server.context(request);
|
|
390
|
-
const denied = guard(ctx.auth, options.allow, options.aal);
|
|
391
|
-
if (denied) return
|
|
403
|
+
const ctx = await server.context(request, { cookies: false });
|
|
404
|
+
const denied = guard(ctx.auth, options.allow, options.aal, options.requiredScopes);
|
|
405
|
+
if (denied) return refuse(request, denied);
|
|
392
406
|
let message;
|
|
393
407
|
try {
|
|
394
408
|
message = await request.json();
|
|
@@ -407,7 +421,7 @@ function createMcp(sb, options) {
|
|
|
407
421
|
request,
|
|
408
422
|
signal: request.signal
|
|
409
423
|
});
|
|
410
|
-
const reply = (result) =>
|
|
424
|
+
const reply = (result) => jsonResponse({
|
|
411
425
|
jsonrpc: "2.0",
|
|
412
426
|
id: message.id,
|
|
413
427
|
result: modern ? {
|
|
@@ -437,7 +451,7 @@ function createMcp(sb, options) {
|
|
|
437
451
|
}
|
|
438
452
|
case "ping": return modern ? notFound() : reply({});
|
|
439
453
|
case "tools/list": return reply({
|
|
440
|
-
tools: await visibleTools(toolContext
|
|
454
|
+
tools: await visibleTools(toolContext),
|
|
441
455
|
...modern ? {
|
|
442
456
|
ttlMs: LIST_TTL_MS,
|
|
443
457
|
cacheScope: "private"
|
|
@@ -465,14 +479,14 @@ function createMcp(sb, options) {
|
|
|
465
479
|
}, { headers: { "access-control-allow-origin": "*" } });
|
|
466
480
|
const mcp = extendServer(server, {
|
|
467
481
|
get tools() {
|
|
468
|
-
return listTools();
|
|
482
|
+
return [...listTools()];
|
|
469
483
|
},
|
|
470
484
|
tool(definition) {
|
|
471
485
|
addTool(defineTool(definition));
|
|
472
486
|
return mcp;
|
|
473
487
|
},
|
|
474
488
|
call,
|
|
475
|
-
|
|
489
|
+
endpoint,
|
|
476
490
|
metadata,
|
|
477
491
|
fetch(request) {
|
|
478
492
|
const { pathname } = new URL(request.url);
|
|
@@ -483,7 +497,7 @@ function createMcp(sb, options) {
|
|
|
483
497
|
"access-control-allow-methods": "GET"
|
|
484
498
|
}
|
|
485
499
|
}) : metadata(request));
|
|
486
|
-
return
|
|
500
|
+
return endpoint(request);
|
|
487
501
|
}
|
|
488
502
|
});
|
|
489
503
|
return mcp;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as DbError } from "./executor-BunPOO-k.js";
|
|
2
2
|
//#region src/auth/impersonation.d.ts
|
|
3
3
|
/** The admin acting as the user, from the RFC 8693 `act` claim. */
|
|
4
4
|
interface Impersonator {
|
|
5
5
|
readonly id: string;
|
|
6
6
|
readonly reason?: string;
|
|
7
|
+
/** The support session, when the admin started one (`act.session_id`). */
|
|
8
|
+
readonly sessionId?: string;
|
|
9
|
+
/** Whether the support session blocks writes (`act.read_only`). */
|
|
10
|
+
readonly readOnly?: boolean;
|
|
7
11
|
}
|
|
8
12
|
/** `actingAs(userId, claims, { actor, reason })`: who acts, and why (recorded by the audit module). */
|
|
9
13
|
interface ImpersonationOptions {
|
package/dist/next/image/index.js
CHANGED
|
@@ -21,13 +21,16 @@ const clamp = (value, min, max) => Math.min(max, Math.max(min, Math.round(value)
|
|
|
21
21
|
*/
|
|
22
22
|
function createImageLoader(options) {
|
|
23
23
|
const storage = `${options.url.replace(/\/+$/, "")}/storage/v1`;
|
|
24
|
-
const publicPrefixes = [`${storage}/object/public/`, `${storage}/render/image/public/`]
|
|
24
|
+
const publicPrefixes = [`${storage}/object/public/`, `${storage}/render/image/public/`].map((prefix) => ({
|
|
25
|
+
prefix,
|
|
26
|
+
length: new URL(prefix).pathname.length
|
|
27
|
+
}));
|
|
25
28
|
const fallback = options.fallback ?? (({ src }) => src);
|
|
26
29
|
return (props) => {
|
|
27
|
-
const prefix = publicPrefixes.find((candidate) => props.src.startsWith(candidate));
|
|
30
|
+
const prefix = publicPrefixes.find((candidate) => props.src.startsWith(candidate.prefix));
|
|
28
31
|
if (prefix === void 0) return fallback(props);
|
|
29
32
|
const source = new URL(props.src);
|
|
30
|
-
const object = source.pathname.slice(
|
|
33
|
+
const object = source.pathname.slice(prefix.length);
|
|
31
34
|
const target = new URL(`${storage}/render/image/public/${object}`);
|
|
32
35
|
for (const [key, value] of source.searchParams) target.searchParams.set(key, value);
|
|
33
36
|
target.searchParams.set("width", String(clamp(props.width, 1, MAX_WIDTH)));
|
package/dist/next/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import {
|
|
3
|
-
import { B as ReadSet, P as DbStats, Z as QuerySpec, l as CacheAdapter, t as BetterSupabase } from "../define-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { n as toSession, t as AuthSession } from "../view-
|
|
8
|
-
import { r as LiveCountSeed, t as CountRunner } from "../live-
|
|
9
|
-
import { n as
|
|
1
|
+
import { n as AnyFunctions, r as AnyModels } from "../types-Dnf_wRDz.js";
|
|
2
|
+
import { _ as DbError } from "../executor-BunPOO-k.js";
|
|
3
|
+
import { B as ReadSet, P as DbStats, Z as QuerySpec, l as CacheAdapter, t as BetterSupabase } from "../define-Bp_BZa5h.js";
|
|
4
|
+
import { r as AuthState } from "../resolve-C15TJq77.js";
|
|
5
|
+
import { C as SupportOptions, D as supportSessions, E as SupportStartRequest, T as SupportSessions, b as ActiveSupport, d as ContextOptions, f as ServerContext, n as GuardOptions, p as ServerOptions, t as AuthKind, u as BetterServer, w as SupportPolicy } from "../respond-D2OQl62-.js";
|
|
6
|
+
import { n as AmrEntry, s as Impersonator, t as Aal } from "../mfa-CusDgPaD.js";
|
|
7
|
+
import { n as toSession, t as AuthSession } from "../view-BEf0diC5.js";
|
|
8
|
+
import { r as LiveCountSeed, t as CountRunner } from "../live-D9W2M5aO.js";
|
|
9
|
+
import { n as supportOf, t as SupportView } from "../support-view-Da5peKFg.js";
|
|
10
|
+
import { n as MembershipClaim, r as hasEntitlement, t as EntitlementKey } from "../entitlements-DUxU4oHe.js";
|
|
10
11
|
import { NextRequest } from "next/server.js";
|
|
11
12
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
12
13
|
//#region src/next/collector.d.ts
|
|
@@ -33,12 +34,12 @@ interface NextDebugOptions {
|
|
|
33
34
|
readonly header?: string;
|
|
34
35
|
/** Warns in development when one render goes over it. */
|
|
35
36
|
readonly budget?: DbBudget;
|
|
36
|
-
/** Where `
|
|
37
|
+
/** Where `bs.debugRoute()` is mounted. Defaults to `/api/bs-stats`. */
|
|
37
38
|
readonly route?: string;
|
|
38
39
|
}
|
|
39
|
-
/** Response header with the URL of the request's totals on `
|
|
40
|
+
/** Response header with the URL of the request's totals on `bs.debugRoute()`. */
|
|
40
41
|
export declare const STATS_URL_HEADER = "x-bs-stats";
|
|
41
|
-
interface ProxyOptions<C = unknown,
|
|
42
|
+
interface ProxyOptions<C = unknown, P = unknown> {
|
|
42
43
|
/**
|
|
43
44
|
* Another middleware to compose with, such as next-intl's. It runs on the
|
|
44
45
|
* original request, alongside auth; its rewrite, redirect or request
|
|
@@ -46,9 +47,9 @@ interface ProxyOptions<C = unknown, U = unknown> {
|
|
|
46
47
|
*/
|
|
47
48
|
readonly before?: (request: NextRequest) => Response | undefined | Promise<Response | undefined>;
|
|
48
49
|
/** Answer before rendering, e.g. redirect signed-out users. Refreshed cookies are kept. */
|
|
49
|
-
readonly protect?: (auth: AuthState<C,
|
|
50
|
+
readonly protect?: (auth: AuthState<C, P>, request: NextRequest) => Response | undefined | Promise<Response | undefined>;
|
|
50
51
|
/** Post-processes the final response; return a new one to replace it. */
|
|
51
|
-
readonly after?: (response: Response, auth: AuthState<C,
|
|
52
|
+
readonly after?: (response: Response, auth: AuthState<C, P>) => Response | undefined | void | Promise<Response | undefined | void>;
|
|
52
53
|
/**
|
|
53
54
|
* Adds `Server-Timing: bs-proxy;dur=..., bs-verify;dur=...` (ms): the whole
|
|
54
55
|
* proxy, and resolving the session (a local verify, or a refresh).
|
|
@@ -76,25 +77,28 @@ type Unwrapped<T> = T extends {
|
|
|
76
77
|
} | {
|
|
77
78
|
readonly ok: false;
|
|
78
79
|
} ? D : T;
|
|
79
|
-
interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown,
|
|
80
|
+
interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> extends BetterServer<M, F, E, C, P> {
|
|
80
81
|
/** `proxy.ts`: refreshes sessions for page loads and server actions. */
|
|
81
|
-
proxy(request: NextRequest, options?: ProxyOptions<C,
|
|
82
|
-
/**
|
|
83
|
-
|
|
82
|
+
proxy(request: NextRequest, options?: ProxyOptions<C, P>): Promise<Response>;
|
|
83
|
+
/**
|
|
84
|
+
* The caller's context. Without a request (Server Components, actions) it
|
|
85
|
+
* reads the incoming headers and is memoized per request.
|
|
86
|
+
*/
|
|
87
|
+
context(request?: Request, options?: ContextOptions): Promise<ServerContext<M, F, E, C, P>>;
|
|
84
88
|
/**
|
|
85
89
|
* The verified caller as serializable data (no token, no clients), memoized
|
|
86
90
|
* per request. Wrap it in a `'use cache: private'` function with Cache
|
|
87
91
|
* Components and pass the promise to `<SessionProvider>`.
|
|
88
92
|
*/
|
|
89
|
-
session(): Promise<AuthSession<C,
|
|
93
|
+
session(): Promise<AuthSession<C, P>>;
|
|
90
94
|
/**
|
|
91
95
|
* The context for a session and its token, without reading the request.
|
|
92
96
|
* The token is verified again (memoized, no network call); a token for
|
|
93
97
|
* another user than `session` gives an `invalid` context.
|
|
94
98
|
*/
|
|
95
|
-
|
|
99
|
+
contextForSession(session: AuthSession<C, P>, options: {
|
|
96
100
|
readonly token: string | null;
|
|
97
|
-
}): Promise<ServerContext<M, F, E, C,
|
|
101
|
+
}): Promise<ServerContext<M, F, E, C, P>>;
|
|
98
102
|
/**
|
|
99
103
|
* First statement of an app-authored `'use cache: private'` function: sets
|
|
100
104
|
* `cacheLife` from the session's expiry (`sessionStale`, capped by
|
|
@@ -104,14 +108,14 @@ interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown
|
|
|
104
108
|
* ```ts
|
|
105
109
|
* async function getCustomers() {
|
|
106
110
|
* 'use cache: private';
|
|
107
|
-
* const { db } = await
|
|
111
|
+
* const { db } = await bs.cached();
|
|
108
112
|
* return db.customers.findMany().orThrow();
|
|
109
113
|
* }
|
|
110
114
|
* ```
|
|
111
115
|
*/
|
|
112
|
-
cached(options?: CachedOptions): Promise<CachedContext<M, F, E, C,
|
|
116
|
+
cached(options?: CachedOptions): Promise<CachedContext<M, F, E, C, P>>;
|
|
113
117
|
/**
|
|
114
|
-
* Drops every `
|
|
118
|
+
* Drops every `bs.cached()` entry of a user, e.g. after a role change,
|
|
115
119
|
* and the entries tagged with `tags` (such as PermDock's `snapshotTag(userId)`).
|
|
116
120
|
*/
|
|
117
121
|
invalidateSession(userId: string, options?: {
|
|
@@ -121,18 +125,18 @@ interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown
|
|
|
121
125
|
* Counts on the server and returns a serializable seed for
|
|
122
126
|
* `useLiveCount(seed)`, so the badge renders with a number and the client
|
|
123
127
|
* only refetches on changes. Pass `db` inside `'use cache: private'`
|
|
124
|
-
* (from `
|
|
128
|
+
* (from `bs.cached()`); otherwise it uses `bs.context()`. A failed
|
|
125
129
|
* count gives `count: null` instead of throwing.
|
|
126
130
|
*/
|
|
127
131
|
liveCount<T extends Extract<keyof M, string>>(spec: QuerySpec<T, "count", number>, db?: CountRunner): Promise<LiveCountSeed<T>>;
|
|
128
132
|
/** Route handler with auth, Result unwrapping and Problem Details errors. */
|
|
129
|
-
route<
|
|
130
|
-
readonly params:
|
|
133
|
+
route<Params = Record<string, string | string[]>>(handler: (request: NextRequest, ctx: ServerContext<M, F, E, C, P> & {
|
|
134
|
+
readonly params: Params;
|
|
131
135
|
}) => unknown, options?: GuardOptions): (request: NextRequest, segment: {
|
|
132
|
-
readonly params: Promise<
|
|
136
|
+
readonly params: Promise<Params>;
|
|
133
137
|
}) => Promise<Response>;
|
|
134
138
|
/** Server action returning a serializable `ActionResult`. */
|
|
135
|
-
action<S extends StandardSchemaV1 | undefined, T>(options: ActionOptions<S>, fn: (input: ActionParsed<S>, ctx: ServerContext<M, F, E, C,
|
|
139
|
+
action<S extends StandardSchemaV1 | undefined, T>(options: ActionOptions<S>, fn: (input: ActionParsed<S>, ctx: ServerContext<M, F, E, C, P>) => Promise<T> | T): (input: ActionInput<S>) => Promise<ActionResult<Unwrapped<Awaited<T>>>>;
|
|
136
140
|
/** Tags the current `"use cache"` scope with a table (and row) tag. */
|
|
137
141
|
cacheTag(table: Extract<keyof M, string>, id?: string | number): void;
|
|
138
142
|
/**
|
|
@@ -146,7 +150,27 @@ interface BetterNext<M extends AnyModels, F extends AnyFunctions, E, C = unknown
|
|
|
146
150
|
* `expectDbBudget`. Answers 404 unless `debug` is on.
|
|
147
151
|
*/
|
|
148
152
|
debugRoute(): (request: Request) => Promise<Response>;
|
|
153
|
+
/**
|
|
154
|
+
* Starts a support session for the signed-in admin and sets its cookie,
|
|
155
|
+
* so the admin's next requests render as the target. Call it from a
|
|
156
|
+
* server action.
|
|
157
|
+
*/
|
|
158
|
+
startSupport(request: SupportStartRequest): Promise<ActionResult<SupportStarted>>;
|
|
159
|
+
/** Ends the admin's support session and clears its cookie. Call it from a server action. */
|
|
160
|
+
stopSupport(): Promise<ActionResult<{
|
|
161
|
+
readonly ended: boolean;
|
|
162
|
+
}>>;
|
|
163
|
+
}
|
|
164
|
+
/** What `startSupport` returns: plain data, safe across the action boundary. */
|
|
165
|
+
interface SupportStarted {
|
|
166
|
+
readonly sessionId: string;
|
|
167
|
+
readonly targetUserId: string;
|
|
168
|
+
readonly readOnly: boolean;
|
|
169
|
+
/** ISO 8601. */
|
|
170
|
+
readonly expiresAt: string;
|
|
149
171
|
}
|
|
172
|
+
/** The tag `bs.cached()` adds to entries rendered in a support session. */
|
|
173
|
+
export declare function supportTag(sessionId: string): string;
|
|
150
174
|
interface SessionStaleOptions {
|
|
151
175
|
/** Below this, the result would not be prefetched anyway. Defaults to 30. */
|
|
152
176
|
readonly min?: number;
|
|
@@ -172,10 +196,10 @@ interface CachedOptions {
|
|
|
172
196
|
/** More `cacheTag`s for the entry, e.g. `snapshotTag(sub)` or `org:<id>`. */
|
|
173
197
|
readonly tags?: readonly string[];
|
|
174
198
|
}
|
|
175
|
-
type CachedContext<M extends AnyModels, F extends AnyFunctions, E, C = unknown,
|
|
176
|
-
readonly session: AuthSession<C,
|
|
199
|
+
type CachedContext<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> = ServerContext<M, F, E, C, P> & {
|
|
200
|
+
readonly session: AuthSession<C, P>;
|
|
177
201
|
};
|
|
178
|
-
/** The tag `
|
|
202
|
+
/** The tag `bs.cached()` puts on a user's entries. */
|
|
179
203
|
export declare function sessionTag(userId: string): string;
|
|
180
204
|
/** `bs:<table>` or `bs:<table>:<id>`. Mutations invalidate both. */
|
|
181
205
|
export declare function tagFor(table: string, id?: string | number): string;
|
|
@@ -202,7 +226,7 @@ interface RequireAalOptions {
|
|
|
202
226
|
* combine it with your sign-in redirect.
|
|
203
227
|
*
|
|
204
228
|
* ```ts
|
|
205
|
-
*
|
|
229
|
+
* bs.proxy(request, {
|
|
206
230
|
* protect: requireAal('aal2', { redirect: '/mfa', match: (path) => path.startsWith('/settings') }),
|
|
207
231
|
* });
|
|
208
232
|
* ```
|
|
@@ -215,9 +239,9 @@ export declare function shouldRefresh(request: Request): boolean;
|
|
|
215
239
|
* actions and cache tags, on top of `createServer`.
|
|
216
240
|
*
|
|
217
241
|
* ```ts
|
|
218
|
-
* export const
|
|
242
|
+
* export const bs = createNext(betterSupabase);
|
|
219
243
|
* ```
|
|
220
244
|
*/
|
|
221
|
-
export declare function createNext<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown,
|
|
245
|
+
export declare function createNext<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: NextOptions): BetterNext<M, F, E, C, P>;
|
|
222
246
|
//#endregion
|
|
223
|
-
export { type Aal, type ActionOptions, type ActionResult, type AmrEntry, type AuthKind, type AuthSession, type BetterNext, type CachedContext, type CachedOptions, type DbBudget, type DbStats, type EntitlementKey, type GuardOptions, type Impersonator, type MembershipClaim, type NextDebugOptions, type NextOptions, type ProxyOptions, type RequireAalOptions, type SessionStaleOptions, hasEntitlement, toSession };
|
|
247
|
+
export { type Aal, type ActionOptions, type ActionResult, type ActiveSupport, type AmrEntry, type AuthKind, type AuthSession, type BetterNext, type CachedContext, type CachedOptions, type DbBudget, type DbStats, type EntitlementKey, type GuardOptions, type Impersonator, type LiveCountSeed, type MembershipClaim, type NextDebugOptions, type NextOptions, type ProxyOptions, type RequireAalOptions, type SessionStaleOptions, type SupportOptions, type SupportPolicy, type SupportSessions, type SupportStartRequest, type SupportStarted, type SupportView, hasEntitlement, supportOf, supportSessions, toSession };
|