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/edge/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as BetterSupabase } from "../define-
|
|
3
|
-
import {
|
|
4
|
-
import { a as ResourceRouteOptions } from "../resource-
|
|
1
|
+
import { P as TableKey, n as AnyFunctions, r as AnyModels } from "../types-Dnf_wRDz.js";
|
|
2
|
+
import { t as BetterSupabase } from "../define-Bp_BZa5h.js";
|
|
3
|
+
import { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-D2OQl62-.js";
|
|
4
|
+
import { a as ResourceRouteOptions } from "../resource-D8iqWMr-.js";
|
|
5
5
|
//#region src/edge/index.d.ts
|
|
6
6
|
export interface CorsOptions {
|
|
7
7
|
/** Allowed origins, or `*`. Defaults to `*`. */
|
|
@@ -16,28 +16,35 @@ export interface EdgeOptions extends ServerOptions {
|
|
|
16
16
|
readonly cors?: boolean | CorsOptions;
|
|
17
17
|
/** Include error details in problem responses. Defaults to `NODE_ENV === 'development'`. */
|
|
18
18
|
readonly exposeErrors?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Keeps the invocation alive for event sink sends a handler started, e.g.
|
|
21
|
+
* `EdgeRuntime.waitUntil` on Supabase. On Workers the `ctx` the runtime
|
|
22
|
+
* passes to `fetch` is used when this is unset.
|
|
23
|
+
*/
|
|
24
|
+
readonly waitUntil?: (promise: Promise<unknown>) => void;
|
|
19
25
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
/** The platform context Workers pass as the third `fetch` argument. */
|
|
27
|
+
export interface EdgeExecutionContext {
|
|
28
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
23
29
|
}
|
|
24
|
-
|
|
30
|
+
/** `Deno.serve` passes `(request, info)`, Workers `fetch` passes `(request, env, ctx)`. */
|
|
31
|
+
export type EdgeHandler = (request: Request, env?: unknown, executionContext?: EdgeExecutionContext) => Promise<Response>;
|
|
25
32
|
export type ResourceMap<M extends AnyModels> = { readonly [T in TableKey<M>]?: ResourceRouteOptions<M, T> | true; };
|
|
26
|
-
export interface ResourcesOptions extends
|
|
33
|
+
export interface ResourcesOptions extends MiddlewareOptions {
|
|
27
34
|
/** Path before the resources, e.g. `/api` (Supabase: `/<function-name>`). */
|
|
28
35
|
readonly basePath?: string;
|
|
29
36
|
}
|
|
30
|
-
export interface BetterEdge<M extends AnyModels, F extends AnyFunctions, E> extends BetterServer<M, F, E> {
|
|
37
|
+
export interface BetterEdge<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> extends BetterServer<M, F, E, C, P> {
|
|
31
38
|
/**
|
|
32
39
|
* A fetch handler (`Deno.serve`, Workers `fetch`) running as the caller.
|
|
33
40
|
* `Result`s become JSON or Problem Details; `undefined` becomes 204.
|
|
34
41
|
*/
|
|
35
|
-
handler(fn: (request: Request, ctx: ServerContext<M, F, E>) => unknown, options?:
|
|
42
|
+
handler(fn: (request: Request, ctx: ServerContext<M, F, E, C, P>) => unknown, options?: MiddlewareOptions): EdgeHandler;
|
|
36
43
|
/** REST resources matching `createOpenApi`, e.g. `Deno.serve(bs.resources({ customers: true }))`. */
|
|
37
44
|
resources(map: ResourceMap<M>, options?: ResourcesOptions): EdgeHandler;
|
|
38
45
|
}
|
|
39
46
|
export declare const SUPABASE_CORS_HEADERS: readonly string[];
|
|
40
47
|
/** Fetch-handler integration for Supabase Edge Functions, Deno, Bun and Workers. */
|
|
41
|
-
export declare function createEdge<M extends AnyModels, D, F extends AnyFunctions, E>(
|
|
48
|
+
export declare function createEdge<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: EdgeOptions): BetterEdge<M, F, E, C, P>;
|
|
42
49
|
//#endregion
|
|
43
|
-
export type { GuardOptions, ResourceRouteOptions };
|
|
50
|
+
export type { GuardOptions, MiddlewareOptions, ResourceRouteOptions };
|
package/dist/edge/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as dbError } from "../errors-
|
|
2
|
-
import { a as problemResponse } from "../problem-
|
|
3
|
-
import {
|
|
4
|
-
import { t as defineResource } from "../resource-
|
|
1
|
+
import { n as dbError } from "../errors-DtwXa6b8.js";
|
|
2
|
+
import { a as problemResponse } from "../problem-BW1KhzSG.js";
|
|
3
|
+
import { d as guard, n as createServer, p as respond, r as extendServer, u as defaultExpose } from "../server-Csx2sRjg.js";
|
|
4
|
+
import { t as defineResource } from "../resource-CRxxwkQq.js";
|
|
5
5
|
//#region src/edge/index.ts
|
|
6
6
|
const SUPABASE_CORS_HEADERS = [
|
|
7
7
|
"authorization",
|
|
@@ -9,15 +9,11 @@ const SUPABASE_CORS_HEADERS = [
|
|
|
9
9
|
"apikey",
|
|
10
10
|
"content-type"
|
|
11
11
|
];
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
/** The CORS headers for a request's origin; the fixed ones are joined once. */
|
|
13
|
+
function corsFor(cors) {
|
|
14
14
|
const allowed = cors.origin ?? "*";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
else if (origin && (typeof allowed === "string" ? [allowed] : allowed).includes(origin)) value = origin;
|
|
18
|
-
if (!value) return void 0;
|
|
19
|
-
return {
|
|
20
|
-
"access-control-allow-origin": value,
|
|
15
|
+
const origins = new Set(typeof allowed === "string" ? [allowed] : allowed);
|
|
16
|
+
const fixed = {
|
|
21
17
|
"access-control-allow-headers": (cors.headers ?? SUPABASE_CORS_HEADERS).join(", "),
|
|
22
18
|
"access-control-allow-methods": (cors.methods ?? [
|
|
23
19
|
"GET",
|
|
@@ -26,8 +22,21 @@ function corsHeaders(request, cors) {
|
|
|
26
22
|
"DELETE",
|
|
27
23
|
"OPTIONS"
|
|
28
24
|
]).join(", "),
|
|
29
|
-
...cors.maxAge === void 0 ? {} : { "access-control-max-age": String(cors.maxAge) }
|
|
30
|
-
|
|
25
|
+
...cors.maxAge === void 0 ? {} : { "access-control-max-age": String(cors.maxAge) }
|
|
26
|
+
};
|
|
27
|
+
const any = {
|
|
28
|
+
"access-control-allow-origin": "*",
|
|
29
|
+
...fixed
|
|
30
|
+
};
|
|
31
|
+
return (request) => {
|
|
32
|
+
if (allowed === "*") return any;
|
|
33
|
+
const origin = request.headers.get("origin");
|
|
34
|
+
if (!origin || !origins.has(origin)) return;
|
|
35
|
+
return {
|
|
36
|
+
"access-control-allow-origin": origin,
|
|
37
|
+
...fixed,
|
|
38
|
+
vary: "origin"
|
|
39
|
+
};
|
|
31
40
|
};
|
|
32
41
|
}
|
|
33
42
|
function withHeaders(response, headers) {
|
|
@@ -41,17 +50,20 @@ function withHeaders(response, headers) {
|
|
|
41
50
|
return target;
|
|
42
51
|
}
|
|
43
52
|
/** Fetch-handler integration for Supabase Edge Functions, Deno, Bun and Workers. */
|
|
44
|
-
function createEdge(
|
|
45
|
-
const server = createServer(
|
|
53
|
+
function createEdge(betterSupabase, options = {}) {
|
|
54
|
+
const server = createServer(betterSupabase, options);
|
|
46
55
|
const expose = options.exposeErrors ?? defaultExpose();
|
|
47
56
|
const cors = options.cors === true ? {} : options.cors === false ? void 0 : options.cors;
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
const corsHeaders = cors ? corsFor(cors) : void 0;
|
|
58
|
+
const serve = (run, handlerOptions, early) => {
|
|
59
|
+
return async (request, _env, executionContext) => {
|
|
60
|
+
const extra = corsHeaders?.(request);
|
|
51
61
|
if (cors && request.method === "OPTIONS") return new Response(null, {
|
|
52
62
|
status: 204,
|
|
53
63
|
headers: extra ?? {}
|
|
54
64
|
});
|
|
65
|
+
const answered = early?.(request);
|
|
66
|
+
if (answered) return extra ? withHeaders(answered, extra) : answered;
|
|
55
67
|
const ctx = await server.context(request, { refresh: handlerOptions.refresh ?? false });
|
|
56
68
|
const instance = new URL(request.url).pathname;
|
|
57
69
|
const denied = guard(ctx.auth, handlerOptions.allow, handlerOptions.aal, handlerOptions.scopes);
|
|
@@ -67,7 +79,10 @@ function createEdge(sb, options = {}) {
|
|
|
67
79
|
expose
|
|
68
80
|
});
|
|
69
81
|
}
|
|
70
|
-
response = ctx.
|
|
82
|
+
response = ctx.apply(response);
|
|
83
|
+
const { events } = betterSupabase;
|
|
84
|
+
const waitUntil = options.waitUntil ?? executionContext?.waitUntil.bind(executionContext);
|
|
85
|
+
if (events.pending && waitUntil) waitUntil(events.settled());
|
|
71
86
|
return extra ? withHeaders(response, extra) : response;
|
|
72
87
|
};
|
|
73
88
|
};
|
|
@@ -83,19 +98,33 @@ function createEdge(sb, options = {}) {
|
|
|
83
98
|
const handlers = /* @__PURE__ */ new Map();
|
|
84
99
|
for (const [table, resource] of Object.entries(map)) {
|
|
85
100
|
if (!resource) continue;
|
|
86
|
-
handlers.set(table, defineResource(
|
|
101
|
+
handlers.set(table, defineResource(betterSupabase, table, resource === true ? {} : resource));
|
|
87
102
|
}
|
|
88
|
-
|
|
103
|
+
const routes = /* @__PURE__ */ new WeakMap();
|
|
104
|
+
const notFound = (request) => {
|
|
89
105
|
const { pathname } = new URL(request.url);
|
|
90
|
-
const instance = pathname;
|
|
91
106
|
const [table, id, extra] = (pathname.startsWith(`${base}/`) ? pathname.slice(base.length + 1) : void 0)?.split("/") ?? [];
|
|
92
107
|
const handler = table ? handlers.get(table) : void 0;
|
|
93
|
-
if (!handler || extra !== void 0 || id !== void 0 && !handler.keyParam) return problemResponse(dbError("not_found", `No route for ${pathname}`), { instance });
|
|
94
|
-
|
|
108
|
+
if (!handler || extra !== void 0 || id !== void 0 && !handler.keyParam) return problemResponse(dbError("not_found", `No route for ${pathname}`), { instance: pathname });
|
|
109
|
+
let key;
|
|
110
|
+
try {
|
|
111
|
+
key = id === void 0 || id === "" ? void 0 : decodeURIComponent(id);
|
|
112
|
+
} catch {
|
|
113
|
+
return problemResponse(dbError("invalid_input", `Malformed id in ${pathname}`), { instance: pathname });
|
|
114
|
+
}
|
|
115
|
+
routes.set(request, {
|
|
116
|
+
handler,
|
|
117
|
+
id: key,
|
|
118
|
+
instance: pathname
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
return serve((request, ctx) => {
|
|
122
|
+
const { handler, id, instance } = routes.get(request);
|
|
123
|
+
return handler.handle(request, ctx.db, id, {
|
|
95
124
|
instance,
|
|
96
125
|
expose
|
|
97
126
|
});
|
|
98
|
-
}, resourcesOptions);
|
|
127
|
+
}, resourcesOptions, notFound);
|
|
99
128
|
}
|
|
100
129
|
});
|
|
101
130
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as AuthSession } from "./view-
|
|
1
|
+
import { t as AuthSession } from "./view-BEf0diC5.js";
|
|
2
2
|
//#region src/auth/entitlements.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* One entry of the `memberships` claim, in PermDock's shape. PermDock strips
|
|
@@ -25,7 +25,7 @@ interface MembershipClaim {
|
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Entitlement keys of the `features` claim: the literal union when
|
|
28
|
-
* `
|
|
28
|
+
* `betterSupabase.claims(schema)` declares one (`z.enum([...])`), otherwise `string`.
|
|
29
29
|
*/
|
|
30
30
|
type EntitlementKey<C> = C extends {
|
|
31
31
|
readonly features?: infer F;
|
package/dist/env/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as EnvResult, c as
|
|
2
|
-
export { BetterSupabaseEnv, ENV_VARIABLES, EnvIssue, EnvOptions, EnvResult, EnvSource, EnvValidationError, PublicEnv, envSchema, loadEnv, parseEnv, publicEnv, toServerEnv };
|
|
1
|
+
import { a as EnvResult, c as InlineJwks, d as loadEnv, f as parseEnv, i as EnvOptions, l as PublicEnv, m as toServerEnv, n as ENV_VARIABLES, o as EnvSource, p as publicEnv, r as EnvIssue, s as EnvValidationError, t as BetterSupabaseEnv, u as envSchema } from "../index-CLg87OBW.js";
|
|
2
|
+
export { BetterSupabaseEnv, ENV_VARIABLES, EnvIssue, EnvOptions, EnvResult, EnvSource, EnvValidationError, InlineJwks, PublicEnv, envSchema, loadEnv, parseEnv, publicEnv, toServerEnv };
|
package/dist/env/index.js
CHANGED
|
@@ -13,6 +13,7 @@ const ENV_VARIABLES = {
|
|
|
13
13
|
secretKey: ["SUPABASE_SECRET_KEY"],
|
|
14
14
|
dbUrl: ["SUPABASE_DB_URL", "DATABASE_URL"],
|
|
15
15
|
jwksUrl: ["SUPABASE_JWKS_URL"],
|
|
16
|
+
jwks: ["SUPABASE_JWKS"],
|
|
16
17
|
readUrl: ["SUPABASE_READ_URL"]
|
|
17
18
|
};
|
|
18
19
|
const LOOPBACK = /^(localhost|127(?:\.\d{1,3}){3}|\[::1\])$/;
|
|
@@ -57,6 +58,35 @@ function preferred(keys) {
|
|
|
57
58
|
if (!keys) return void 0;
|
|
58
59
|
return keys["default"] ?? Object.values(keys)[0];
|
|
59
60
|
}
|
|
61
|
+
function isJwk(value) {
|
|
62
|
+
return typeof value === "object" && value !== null && "kty" in value && typeof value.kty === "string";
|
|
63
|
+
}
|
|
64
|
+
/** At least one key, each an object with a string `kty`, the shape the verifier reads. */
|
|
65
|
+
function isJwkList(value) {
|
|
66
|
+
return Array.isArray(value) && value.length > 0 && value.every(isJwk);
|
|
67
|
+
}
|
|
68
|
+
/** `SUPABASE_JWKS` as `@supabase/server` reads it: `{"keys":[...]}` or `[...]`. */
|
|
69
|
+
function checkJwks(raw, issues) {
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(raw);
|
|
73
|
+
} catch {
|
|
74
|
+
issues.push({
|
|
75
|
+
variables: ENV_VARIABLES.jwks,
|
|
76
|
+
message: "must be JSON: {\"keys\":[...]} or [...]"
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const keys = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? "keys" in parsed ? parsed.keys : void 0 : parsed;
|
|
81
|
+
if (!isJwkList(keys)) {
|
|
82
|
+
issues.push({
|
|
83
|
+
variables: ENV_VARIABLES.jwks,
|
|
84
|
+
message: "must hold at least one JSON Web Key with a kty"
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
return { keys };
|
|
89
|
+
}
|
|
60
90
|
function checkUrl(value, variables, issues) {
|
|
61
91
|
let url;
|
|
62
92
|
try {
|
|
@@ -132,6 +162,8 @@ function parseEnv(source, options = {}) {
|
|
|
132
162
|
});
|
|
133
163
|
const rawJwks = first(source, ENV_VARIABLES.jwksUrl);
|
|
134
164
|
const jwksOverride = rawJwks ? checkUrl(rawJwks, ENV_VARIABLES.jwksUrl, issues) : void 0;
|
|
165
|
+
const rawInline = first(source, ENV_VARIABLES.jwks);
|
|
166
|
+
const jwks = rawInline ? checkJwks(rawInline, issues) : void 0;
|
|
135
167
|
const rawRead = first(source, ENV_VARIABLES.readUrl);
|
|
136
168
|
const readUrl = rawRead ? checkUrl(rawRead, ENV_VARIABLES.readUrl, issues) : void 0;
|
|
137
169
|
if (issues.length > 0 || !url || !publishableKey) return {
|
|
@@ -146,6 +178,7 @@ function parseEnv(source, options = {}) {
|
|
|
146
178
|
url: base,
|
|
147
179
|
publishableKey,
|
|
148
180
|
jwksUrl: jwksOverride ?? new URL(`${base}/auth/v1/.well-known/jwks.json`),
|
|
181
|
+
...jwks ? { jwks } : {},
|
|
149
182
|
...secretKey ? {
|
|
150
183
|
secretKey,
|
|
151
184
|
secretKeys: {
|
|
@@ -197,7 +230,7 @@ function toServerEnv(env) {
|
|
|
197
230
|
url: env.url,
|
|
198
231
|
publishableKeys: { default: env.publishableKey },
|
|
199
232
|
secretKeys: env.secretKeys ?? (env.secretKey ? { default: env.secretKey } : {}),
|
|
200
|
-
jwks: env.jwksUrl
|
|
233
|
+
jwks: env.jwks ?? env.jwksUrl
|
|
201
234
|
};
|
|
202
235
|
}
|
|
203
236
|
//#endregion
|
|
@@ -9,6 +9,7 @@ const STATUS = {
|
|
|
9
9
|
not_null: 422,
|
|
10
10
|
exclusion: 409,
|
|
11
11
|
invalid_input: 400,
|
|
12
|
+
invalid_value: 500,
|
|
12
13
|
raised: 400,
|
|
13
14
|
timeout: 504,
|
|
14
15
|
serialization: 409,
|
|
@@ -41,7 +42,7 @@ function isDbError(value) {
|
|
|
41
42
|
}
|
|
42
43
|
/**
|
|
43
44
|
* The `DbError` in a `DbError`, a `DbException`, or an error whose `cause`
|
|
44
|
-
* is a `DbError` (what `
|
|
45
|
+
* is a `DbError` (what `betterSupabase.mapError()` mappers should set).
|
|
45
46
|
*/
|
|
46
47
|
function dbErrorOf(value) {
|
|
47
48
|
if (value instanceof DbException) return value.error;
|
package/dist/events/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { C as kitEventAttributes, S as WebhookEventData, _ as KitEventType, b as OrgEventData, d as InvitationEventData, f as KIT_ATTRIBUTES, g as KitEventPattern, h as KitEventMeta, m as KitEventMap, p as KitEvent, v as KitEventsMatching, w as onKitEvent, x as SupportEventData, y as NotificationEventData } from "../events-aIO7vsIk.js";
|
|
2
|
+
import { _ as toHttp, a as ForwardOptions, c as ROW_EVENT_TYPES, d as forwardMutations, f as fromHttp, g as toCloudEvents, h as kitCloudEvent, i as ForwardKitOptions, l as RowEventData, m as isCloudEvent, n as CloudEventOptions, o as HttpMode, p as httpSink, r as EventSink, s as HttpSinkOptions, t as CloudEvent, u as forwardKitEvents } from "../index-DOESKG27.js";
|
|
3
|
+
export { CloudEvent, CloudEventOptions, EventSink, ForwardKitOptions, ForwardOptions, HttpMode, HttpSinkOptions, type InvitationEventData, KIT_ATTRIBUTES, type KitEvent, type KitEventMap, type KitEventMeta, type KitEventPattern, type KitEventType, type KitEventsMatching, type NotificationEventData, type OrgEventData, ROW_EVENT_TYPES, RowEventData, type SupportEventData, type WebhookEventData, forwardKitEvents, forwardMutations, fromHttp, httpSink, isCloudEvent, kitCloudEvent, kitEventAttributes, onKitEvent, toCloudEvents, toHttp };
|
package/dist/events/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { n as nowInstant } from "../temporal-
|
|
1
|
+
import { n as nowInstant } from "../temporal-CVlIV2DZ.js";
|
|
2
|
+
import { i as onKitEvent, r as kitEventAttributes, t as KIT_ATTRIBUTES } from "../kit-events-CTFDfSwb.js";
|
|
2
3
|
//#region src/events/index.ts
|
|
3
4
|
const ROW_EVENT_TYPES = {
|
|
4
5
|
insert: "dev.better-supabase.row.created",
|
|
5
6
|
upsert: "dev.better-supabase.row.upserted",
|
|
6
7
|
update: "dev.better-supabase.row.updated",
|
|
7
|
-
delete: "dev.better-supabase.row.deleted"
|
|
8
|
+
delete: "dev.better-supabase.row.deleted",
|
|
9
|
+
softDelete: "dev.better-supabase.row.softdeleted"
|
|
8
10
|
};
|
|
9
11
|
function subjectOf(meta, table, row) {
|
|
10
12
|
const key = meta?.tables[table]?.primaryKey;
|
|
@@ -15,13 +17,19 @@ function subjectOf(meta, table, row) {
|
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* One CloudEvent per mutated row: `dev.better-supabase.row.created` with the
|
|
18
|
-
* app-cased row
|
|
19
|
-
* `partitionkey
|
|
20
|
+
* app-cased row and the actor in `data`, the primary key as `subject` and the
|
|
21
|
+
* tenant as `partitionkey`. Writes that return no rows (soft
|
|
22
|
+
* deletes, `returning: false`) send one event per known primary key, with the
|
|
23
|
+
* key as `row`.
|
|
20
24
|
*/
|
|
21
25
|
function toCloudEvents(notice, options) {
|
|
22
|
-
const
|
|
26
|
+
const intent = notice.intent ?? notice.kind;
|
|
27
|
+
const type = options.typePrefix ? `${options.typePrefix}.row.${ROW_EVENT_TYPES[intent].split(".").at(-1)}` : ROW_EVENT_TYPES[intent];
|
|
23
28
|
const time = (options.now ?? nowInstant)().toString();
|
|
24
|
-
|
|
29
|
+
const tenant = notice.tenant ?? notice.context.tenant;
|
|
30
|
+
const rows = notice.rows.length > 0 ? notice.rows : notice.keys ?? [];
|
|
31
|
+
const actorId = notice.context.actor?.id;
|
|
32
|
+
return rows.map((row) => {
|
|
25
33
|
const subject = subjectOf(options.meta, notice.table, row);
|
|
26
34
|
return {
|
|
27
35
|
specversion: "1.0",
|
|
@@ -33,32 +41,77 @@ function toCloudEvents(notice, options) {
|
|
|
33
41
|
datacontenttype: "application/json",
|
|
34
42
|
data: {
|
|
35
43
|
table: notice.table,
|
|
36
|
-
row
|
|
44
|
+
row,
|
|
45
|
+
...actorId ? { actorId } : {}
|
|
37
46
|
},
|
|
38
|
-
...
|
|
39
|
-
...notice.context.actor?.id ? { actorid: notice.context.actor.id } : {}
|
|
47
|
+
...tenant ? { partitionkey: tenant } : {}
|
|
40
48
|
};
|
|
41
49
|
});
|
|
42
50
|
}
|
|
43
51
|
/**
|
|
44
52
|
* Sends a CloudEvent for every mutation to `sink`. Returns a function that
|
|
45
|
-
* stops forwarding.
|
|
53
|
+
* stops forwarding. Sends in flight are tracked on `betterSupabase.events`
|
|
54
|
+
* (`settled()`), which the Next adapter hands to `after()` and the edge
|
|
55
|
+
* entry to `waitUntil`. Use an outbox (SQL kit) when events must not be lost.
|
|
46
56
|
*/
|
|
47
|
-
function forwardMutations(
|
|
48
|
-
return
|
|
57
|
+
function forwardMutations(betterSupabase, sink, options) {
|
|
58
|
+
return betterSupabase.events.on("mutation", (notice) => {
|
|
49
59
|
if (options.filter && !options.filter(notice)) return;
|
|
50
60
|
const events = toCloudEvents(notice, {
|
|
51
61
|
...options,
|
|
52
|
-
meta:
|
|
62
|
+
meta: betterSupabase.meta
|
|
53
63
|
});
|
|
54
64
|
if (events.length === 0) return;
|
|
55
65
|
const report = (error) => {
|
|
56
66
|
(options.onError ?? ((cause) => {
|
|
57
|
-
|
|
67
|
+
betterSupabase.events.logger.error("event sink failed", { cause });
|
|
58
68
|
}))(error, events);
|
|
59
69
|
};
|
|
60
70
|
try {
|
|
61
|
-
Promise.resolve(sink.send(events)).catch(report);
|
|
71
|
+
betterSupabase.events.track(Promise.resolve(sink.send(events)).catch(report));
|
|
72
|
+
} catch (error) {
|
|
73
|
+
report(error);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A kit event as a CloudEvent: `dev.better-supabase.support.started` with
|
|
79
|
+
* the event data and the actor (`actorId`) as `data` and the tenant as
|
|
80
|
+
* `partitionkey`.
|
|
81
|
+
*/
|
|
82
|
+
function kitCloudEvent(event, options) {
|
|
83
|
+
return {
|
|
84
|
+
specversion: "1.0",
|
|
85
|
+
id: options.id?.() ?? crypto.randomUUID(),
|
|
86
|
+
source: options.source,
|
|
87
|
+
type: `${options.typePrefix ?? "dev.better-supabase"}.${event.type}`,
|
|
88
|
+
...event.subject ? { subject: event.subject } : {},
|
|
89
|
+
time: (options.now?.() ?? event.time).toString(),
|
|
90
|
+
datacontenttype: "application/json",
|
|
91
|
+
data: event.actorId ? {
|
|
92
|
+
...event.data,
|
|
93
|
+
actorId: event.actorId
|
|
94
|
+
} : event.data,
|
|
95
|
+
...event.tenant ? { partitionkey: event.tenant } : {}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Sends a CloudEvent for every kit event (`support.*`, `org.*`, ...) to
|
|
100
|
+
* `sink`. Returns a function that stops forwarding. Like
|
|
101
|
+
* `forwardMutations`, sends are tracked on `betterSupabase.events`.
|
|
102
|
+
*/
|
|
103
|
+
function forwardKitEvents(betterSupabase, sink, options) {
|
|
104
|
+
const types = options.types;
|
|
105
|
+
return betterSupabase.events.on("kit", (event) => {
|
|
106
|
+
if (types && !types.some((pattern) => pattern.endsWith(".*") ? event.type.startsWith(pattern.slice(0, -1)) : pattern === event.type)) return;
|
|
107
|
+
const events = [kitCloudEvent(event, options)];
|
|
108
|
+
const report = (error) => {
|
|
109
|
+
(options.onError ?? ((cause) => {
|
|
110
|
+
betterSupabase.events.logger.error("event sink failed", { cause });
|
|
111
|
+
}))(error, events);
|
|
112
|
+
};
|
|
113
|
+
try {
|
|
114
|
+
betterSupabase.events.track(Promise.resolve(sink.send(events)).catch(report));
|
|
62
115
|
} catch (error) {
|
|
63
116
|
report(error);
|
|
64
117
|
}
|
|
@@ -137,4 +190,4 @@ function httpSink(url, options = {}) {
|
|
|
137
190
|
} };
|
|
138
191
|
}
|
|
139
192
|
//#endregion
|
|
140
|
-
export { ROW_EVENT_TYPES, forwardMutations, fromHttp, httpSink, isCloudEvent, toCloudEvents, toHttp };
|
|
193
|
+
export { KIT_ATTRIBUTES, ROW_EVENT_TYPES, forwardKitEvents, forwardMutations, fromHttp, httpSink, isCloudEvent, kitCloudEvent, kitEventAttributes, onKitEvent, toCloudEvents, toHttp };
|