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/hono/index.d.ts
CHANGED
|
@@ -1,45 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as BetterSupabase } from "../define-
|
|
3
|
-
import { r as AuthState } from "../resolve-
|
|
4
|
-
import {
|
|
5
|
-
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 { r as AuthState } from "../resolve-C15TJq77.js";
|
|
4
|
+
import { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-D2OQl62-.js";
|
|
5
|
+
import { a as ResourceRouteOptions } from "../resource-D8iqWMr-.js";
|
|
6
6
|
import { Context, ErrorHandler, Hono, MiddlewareHandler } from "hono";
|
|
7
7
|
//#region src/hono/index.d.ts
|
|
8
8
|
/** Hono `Env` with the request's better-supabase context in `c.var`. */
|
|
9
|
-
export interface
|
|
9
|
+
export interface HonoEnv<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> {
|
|
10
10
|
Variables: {
|
|
11
|
-
readonly bs: ServerContext<M, F, E>;
|
|
12
|
-
readonly db: ServerContext<M, F, E>["db"];
|
|
13
|
-
readonly auth: AuthState
|
|
11
|
+
readonly bs: ServerContext<M, F, E, C, P>;
|
|
12
|
+
readonly db: ServerContext<M, F, E, C, P>["db"];
|
|
13
|
+
readonly auth: AuthState<C, P>;
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
export interface HonoOptions extends ServerOptions {
|
|
17
17
|
/** Include error details in problem responses. Defaults to `NODE_ENV === 'development'`. */
|
|
18
18
|
readonly exposeErrors?: boolean;
|
|
19
19
|
}
|
|
20
|
-
export interface
|
|
20
|
+
export interface BetterHono<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> extends BetterServer<M, F, E, C, P> {
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* The app's Hono `Env`, for `new Hono<typeof bs.Env>()` and
|
|
23
|
+
* `Context<typeof bs.Env>`. Type only: `undefined` at runtime.
|
|
24
24
|
*/
|
|
25
|
-
readonly
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
readonly Env: HonoEnv<M, F, E, C, P>;
|
|
26
|
+
/** `new Hono<typeof bs.Env>()` with `onError(bs.onError)` installed. */
|
|
27
|
+
app(): Hono<HonoEnv<M, F, E, C, P>>;
|
|
28
28
|
/** Resolves the caller, enforces `allow` and sets `c.var.bs`, `c.var.db`, `c.var.auth`. */
|
|
29
|
-
middleware(options?: MiddlewareOptions): MiddlewareHandler<
|
|
29
|
+
middleware(options?: MiddlewareOptions): MiddlewareHandler<HonoEnv<M, F, E, C, P>>;
|
|
30
30
|
/** Wraps a handler: `Result`s become JSON or Problem Details, `undefined` becomes 204. */
|
|
31
|
-
|
|
31
|
+
handler(fn: (c: Context<HonoEnv<M, F, E, C, P>>, ctx: ServerContext<M, F, E, C, P>) => unknown, options?: {
|
|
32
32
|
readonly status?: number;
|
|
33
|
-
}): (c: Context<
|
|
34
|
-
/**
|
|
35
|
-
|
|
33
|
+
}): (c: Context<HonoEnv<M, F, E, C, P>>) => Promise<Response>;
|
|
34
|
+
/**
|
|
35
|
+
* `app.onError(bs.onError)`: `DbException`s (and errors caused by a `DbError`)
|
|
36
|
+
* become Problem Details, Hono's `HTTPException`s keep their own response,
|
|
37
|
+
* and anything else is a 500.
|
|
38
|
+
*/
|
|
39
|
+
readonly onError: ErrorHandler<HonoEnv<M, F, E, C, P>>;
|
|
36
40
|
/**
|
|
37
41
|
* REST routes for a table matching `createOpenApi`. Mount with
|
|
38
42
|
* `app.route('/customers', bs.resource('customers'))` behind `middleware()`.
|
|
39
43
|
*/
|
|
40
|
-
resource<T extends TableKey<M>>(table: T, options?: ResourceRouteOptions<M, T>): Hono<
|
|
44
|
+
resource<T extends TableKey<M>>(table: T, options?: ResourceRouteOptions<M, T>): Hono<HonoEnv<M, F, E, C, P>>;
|
|
41
45
|
}
|
|
42
46
|
/** Hono integration: a server plus middleware, handlers and REST resources. */
|
|
43
|
-
export declare function createHono<M extends AnyModels, D, F extends AnyFunctions, E>(
|
|
47
|
+
export declare function createHono<M extends AnyModels, D, F extends AnyFunctions, E, C = unknown, P = unknown>(betterSupabase: BetterSupabase<M, D, F, E, C, P>, options?: HonoOptions): BetterHono<M, F, E, C, P>;
|
|
44
48
|
//#endregion
|
|
45
|
-
export type { GuardOptions, ResourceRouteOptions };
|
|
49
|
+
export type { GuardOptions, MiddlewareOptions, ResourceRouteOptions };
|
package/dist/hono/index.js
CHANGED
|
@@ -1,19 +1,48 @@
|
|
|
1
|
-
import { n as dbError, r as dbErrorOf } from "../errors-
|
|
2
|
-
import { a as problemResponse } from "../problem-
|
|
3
|
-
import { i as
|
|
4
|
-
import { t as defineResource } from "../resource-
|
|
1
|
+
import { n as dbError, r as dbErrorOf } from "../errors-DtwXa6b8.js";
|
|
2
|
+
import { a as problemResponse } from "../problem-BW1KhzSG.js";
|
|
3
|
+
import { d as guard, i as rememberVerifiedFor, 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
|
import { Hono } from "hono";
|
|
6
|
+
import { HTTPException } from "hono/http-exception";
|
|
6
7
|
//#region src/hono/index.ts
|
|
7
8
|
function contextOf(c) {
|
|
8
9
|
const ctx = c.get("bs");
|
|
9
10
|
if (!ctx) throw new TypeError("better-supabase: no context on this request; add app.use(bs.middleware()) first");
|
|
10
11
|
return ctx;
|
|
11
12
|
}
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === "object" && value !== null;
|
|
15
|
+
}
|
|
16
|
+
function isJwtClaims(value) {
|
|
17
|
+
return isRecord(value) && typeof value["sub"] === "string";
|
|
18
|
+
}
|
|
19
|
+
function isUserClaims(value) {
|
|
20
|
+
return isRecord(value) && typeof value["id"] === "string";
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The bearer token `withSupabase` from `@supabase/server/adapters/hono`
|
|
24
|
+
* verified for this request, with the claims it stored in
|
|
25
|
+
* `c.var.supabaseContext`.
|
|
26
|
+
*/
|
|
27
|
+
function verifiedBySupabase(c) {
|
|
28
|
+
const supabase = c.var["supabaseContext"];
|
|
29
|
+
if (!isRecord(supabase) || supabase["authMode"] !== "user") return void 0;
|
|
30
|
+
const { jwtClaims, userClaims } = supabase;
|
|
31
|
+
const header = c.req.header("authorization");
|
|
32
|
+
const token = header?.startsWith("Bearer ") ? header.slice(7) : "";
|
|
33
|
+
if (!token || !isJwtClaims(jwtClaims) || !isUserClaims(userClaims)) return void 0;
|
|
34
|
+
return {
|
|
35
|
+
token,
|
|
36
|
+
claims: jwtClaims,
|
|
37
|
+
user: userClaims
|
|
38
|
+
};
|
|
39
|
+
}
|
|
12
40
|
/** Hono integration: a server plus middleware, handlers and REST resources. */
|
|
13
|
-
function createHono(
|
|
14
|
-
const server = createServer(
|
|
41
|
+
function createHono(betterSupabase, options = {}) {
|
|
42
|
+
const server = createServer(betterSupabase, options);
|
|
15
43
|
const expose = options.exposeErrors ?? defaultExpose();
|
|
16
44
|
const onError = (cause, c) => {
|
|
45
|
+
if (cause instanceof HTTPException) return cause.getResponse();
|
|
17
46
|
const instance = new URL(c.req.url).pathname;
|
|
18
47
|
const thrown = dbErrorOf(cause);
|
|
19
48
|
if (thrown) return problemResponse(thrown, {
|
|
@@ -27,9 +56,15 @@ function createHono(sb, options = {}) {
|
|
|
27
56
|
});
|
|
28
57
|
};
|
|
29
58
|
return extendServer(server, {
|
|
59
|
+
Env: void 0,
|
|
30
60
|
onError,
|
|
61
|
+
app() {
|
|
62
|
+
return new Hono().onError(onError);
|
|
63
|
+
},
|
|
31
64
|
middleware(middlewareOptions = {}) {
|
|
32
65
|
return async (c, next) => {
|
|
66
|
+
const verified = verifiedBySupabase(c);
|
|
67
|
+
if (verified) rememberVerifiedFor(server, verified);
|
|
33
68
|
const ctx = await server.context(c.req.raw, { refresh: middlewareOptions.refresh ?? false });
|
|
34
69
|
const denied = guard(ctx.auth, middlewareOptions.allow, middlewareOptions.aal, middlewareOptions.scopes);
|
|
35
70
|
if (denied) return ctx.resolution.apply(problemResponse(denied, {
|
|
@@ -40,21 +75,21 @@ function createHono(sb, options = {}) {
|
|
|
40
75
|
c.set("db", ctx.db);
|
|
41
76
|
c.set("auth", ctx.auth);
|
|
42
77
|
await next();
|
|
43
|
-
c.res = ctx.
|
|
78
|
+
c.res = ctx.apply(c.res);
|
|
44
79
|
};
|
|
45
80
|
},
|
|
46
|
-
|
|
81
|
+
handler(fn, handlerOptions = {}) {
|
|
47
82
|
return (c) => {
|
|
48
83
|
const ctx = contextOf(c);
|
|
49
|
-
return respond(() =>
|
|
84
|
+
return respond(() => fn(c, ctx), {
|
|
50
85
|
instance: new URL(c.req.url).pathname,
|
|
51
86
|
expose,
|
|
52
|
-
...
|
|
87
|
+
...handlerOptions
|
|
53
88
|
});
|
|
54
89
|
};
|
|
55
90
|
},
|
|
56
91
|
resource(table, resourceOptions) {
|
|
57
|
-
const resource = defineResource(
|
|
92
|
+
const resource = defineResource(betterSupabase, table, resourceOptions);
|
|
58
93
|
const app = new Hono();
|
|
59
94
|
const serve = (item) => (c) => resource.handle(c.req.raw, contextOf(c).db, item ? c.req.param("id") : void 0, {
|
|
60
95
|
instance: new URL(c.req.url).pathname,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/auth/impersonation.ts
|
|
2
|
+
/** The `act` claim for an impersonated session. */
|
|
3
|
+
function actClaim(options) {
|
|
4
|
+
return {
|
|
5
|
+
sub: options.actor,
|
|
6
|
+
reason: options.reason
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
/** The impersonator in `claims.act`, or `undefined` for a normal session. */
|
|
10
|
+
function impersonatorOf(claims) {
|
|
11
|
+
const act = claims["act"];
|
|
12
|
+
if (typeof act !== "object" || act === null) return void 0;
|
|
13
|
+
const { sub, reason, session_id, read_only } = act;
|
|
14
|
+
if (typeof sub !== "string" || sub === "") return void 0;
|
|
15
|
+
return {
|
|
16
|
+
id: sub,
|
|
17
|
+
...typeof reason === "string" ? { reason } : {},
|
|
18
|
+
...typeof session_id === "string" ? { sessionId: session_id } : {},
|
|
19
|
+
...typeof read_only === "boolean" ? { readOnly: read_only } : {}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The repository context of a signed-in user: the actor, with the
|
|
24
|
+
* impersonator from `act`, and the claims. Every adapter builds it here, so
|
|
25
|
+
* plugins see the same actor on the server, in middleware and in the browser.
|
|
26
|
+
*/
|
|
27
|
+
function userContext(user, claims) {
|
|
28
|
+
const impersonator = impersonatorOf(claims);
|
|
29
|
+
return {
|
|
30
|
+
actor: {
|
|
31
|
+
id: user.id,
|
|
32
|
+
kind: "user",
|
|
33
|
+
...user.role ? { role: user.role } : {},
|
|
34
|
+
...user.email ? { email: user.email } : {},
|
|
35
|
+
...impersonator ? { impersonator: impersonator.id } : {}
|
|
36
|
+
},
|
|
37
|
+
claims
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { impersonatorOf as n, userContext as r, actClaim as t };
|
|
@@ -1,61 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Z as QuerySpec } from "./define-
|
|
3
|
-
import { i as
|
|
1
|
+
import { _ as DbError } from "./executor-BunPOO-k.js";
|
|
2
|
+
import { Z as QuerySpec } from "./define-Bp_BZa5h.js";
|
|
3
|
+
import { i as ClientAuth, t as AuthSnapshot } from "./index-DmXSxbLi.js";
|
|
4
4
|
import { n as TemplateValues } from "./template-mbvlysOo.js";
|
|
5
|
-
import { t as AuthSession } from "./view-
|
|
6
|
-
import { a as LiveSource, g as Topic, h as SubscriptionStatus, p as SubscribeOptions, r as LiveCountSeed, u as EventSchemas, v as TopicHandlers, y as TopicMessage } from "./live-
|
|
7
|
-
import "./entitlements-DvJXoI02.js";
|
|
8
|
-
import "./react/session.js";
|
|
5
|
+
import { t as AuthSession } from "./view-BEf0diC5.js";
|
|
6
|
+
import { a as LiveSource, g as Topic, h as SubscriptionStatus, p as SubscribeOptions, r as LiveCountSeed, u as EventSchemas, v as TopicHandlers, y as TopicMessage } from "./live-D9W2M5aO.js";
|
|
9
7
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
10
8
|
import { ReactNode } from "react";
|
|
11
9
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
12
10
|
import { QueryClient } from "@tanstack/query-core";
|
|
13
11
|
//#region src/react/hooks.d.ts
|
|
14
|
-
/** The parts of `
|
|
15
|
-
interface
|
|
16
|
-
readonly
|
|
12
|
+
/** The parts of `createClient()` the provider needs. */
|
|
13
|
+
interface ClientLike {
|
|
14
|
+
readonly betterSupabase: LiveSource;
|
|
17
15
|
readonly supabase: SupabaseClient;
|
|
18
|
-
readonly auth:
|
|
16
|
+
readonly auth: ClientAuth;
|
|
19
17
|
readonly db: object;
|
|
20
18
|
readonly queries: object;
|
|
21
19
|
}
|
|
22
20
|
interface BetterSupabaseProviderProps {
|
|
23
|
-
readonly
|
|
21
|
+
readonly client: ClientLike;
|
|
24
22
|
/** better-supabase queries are removed when the user signs out or changes. */
|
|
25
23
|
readonly queryClient?: QueryClient;
|
|
26
24
|
readonly children?: ReactNode;
|
|
27
25
|
}
|
|
28
|
-
/** Provides the
|
|
26
|
+
/** Provides the better-supabase client to the hooks. */
|
|
29
27
|
declare function BetterSupabaseProvider(props: BetterSupabaseProviderProps): ReactNode;
|
|
30
28
|
/** The session state for UI: `loading`, `signed-out` or `signed-in` with the user and claims. */
|
|
31
29
|
declare function useAuth(): AuthSnapshot;
|
|
32
30
|
declare function useSupabase(): SupabaseClient;
|
|
33
|
-
interface BetterHooks<B extends
|
|
31
|
+
interface BetterHooks<B extends ClientLike> {
|
|
34
32
|
/** Repositories bound to the current session. Re-renders when the user changes. */
|
|
35
33
|
readonly useDb: () => B["db"];
|
|
36
34
|
/** TanStack Query option factories: `useQuery(useQueries().customers.findMany())`. */
|
|
37
35
|
readonly useQueries: () => B["queries"];
|
|
38
36
|
readonly useSupabase: () => SupabaseClient;
|
|
39
37
|
readonly useAuth: () => AuthSnapshot;
|
|
40
|
-
/** `useSession()` typed by the
|
|
38
|
+
/** `useSession()` typed by the client's `betterSupabase.claims(schema)` and `betterSupabase.userMetadata(schema)`. */
|
|
41
39
|
readonly useSession: () => AuthSession<ClaimsOf<B>, ProfileOf<B>>;
|
|
42
40
|
}
|
|
43
|
-
/** The claims type of a
|
|
44
|
-
type ClaimsOf<B extends
|
|
41
|
+
/** The claims type of a client's `betterSupabase.claims(schema)`, `unknown` without one. */
|
|
42
|
+
type ClaimsOf<B extends ClientLike> = B["betterSupabase"] extends {
|
|
45
43
|
readonly claimsSchema: StandardSchemaV1<unknown, infer C> | undefined;
|
|
46
44
|
} ? C : unknown;
|
|
47
|
-
/** The profile type of a
|
|
48
|
-
type ProfileOf<B extends
|
|
45
|
+
/** The profile type of a client's `betterSupabase.userMetadata(schema)`, `unknown` without one. */
|
|
46
|
+
type ProfileOf<B extends ClientLike> = B["betterSupabase"] extends {
|
|
49
47
|
readonly userMetadataSchema: StandardSchemaV1<unknown, infer P> | undefined;
|
|
50
48
|
} ? P : unknown;
|
|
51
49
|
/**
|
|
52
50
|
* Hooks typed for your schema.
|
|
53
51
|
*
|
|
54
52
|
* ```ts
|
|
55
|
-
* export const { useDb, useQueries, useAuth } = createHooks<typeof
|
|
53
|
+
* export const { useDb, useQueries, useAuth } = createHooks<typeof bs>();
|
|
56
54
|
* ```
|
|
57
55
|
*/
|
|
58
|
-
declare function createHooks<B extends
|
|
56
|
+
declare function createHooks<B extends ClientLike>(): BetterHooks<B>;
|
|
59
57
|
interface BroadcastOptions extends Omit<SubscribeOptions, "onStatus"> {
|
|
60
58
|
/**
|
|
61
59
|
* Refetch after each message: table keys (every query that read one of
|
|
@@ -88,7 +86,7 @@ interface LiveQueryHookOptions {
|
|
|
88
86
|
* resubscribes when the spec, tenant or user changes.
|
|
89
87
|
*
|
|
90
88
|
* ```ts
|
|
91
|
-
* const spec =
|
|
89
|
+
* const spec = betterSupabase.spec.customers.findMany({ include: { notes: true } });
|
|
92
90
|
* const { data } = useQuery(q.$spec(spec));
|
|
93
91
|
* useLiveQuery(spec);
|
|
94
92
|
* ```
|
|
@@ -108,13 +106,56 @@ interface LiveCount {
|
|
|
108
106
|
/**
|
|
109
107
|
* A count that stays current: refetches only the `count` spec (a HEAD
|
|
110
108
|
* request) after each debounced change to a table it reads, and after the
|
|
111
|
-
* channel rejoins. Takes a spec or a `
|
|
109
|
+
* channel rejoins. Takes a spec or a `bs.liveCount()` seed; pass `null` to
|
|
112
110
|
* pause. Doesn't need a `QueryClient`.
|
|
113
111
|
*
|
|
114
112
|
* ```tsx
|
|
115
|
-
* const { count } = useLiveCount(seed); // seed = await
|
|
113
|
+
* const { count } = useLiveCount(seed); // seed = await bs.liveCount(spec)
|
|
116
114
|
* ```
|
|
117
115
|
*/
|
|
118
116
|
declare function useLiveCount(source: QuerySpec<string, "count", number> | LiveCountSeed | null | undefined, options?: LiveCountHookOptions): LiveCount;
|
|
119
117
|
//#endregion
|
|
120
|
-
|
|
118
|
+
//#region src/react/notifications.d.ts
|
|
119
|
+
/** Loads one list of items, e.g. a server action that calls `notifications.list()`. */
|
|
120
|
+
type NotificationSource<T> = () => Promise<readonly T[]>;
|
|
121
|
+
interface UseNotificationsOptions<T> {
|
|
122
|
+
/**
|
|
123
|
+
* The private topic the `notifications` module broadcasts to, e.g.
|
|
124
|
+
* `notifications:${userId}` (`kits.notifications.options.topic`). `null`
|
|
125
|
+
* loads once without realtime.
|
|
126
|
+
*/
|
|
127
|
+
readonly topic: string | null;
|
|
128
|
+
/** The notifications, newest first. */
|
|
129
|
+
readonly load: NotificationSource<T>;
|
|
130
|
+
/** More items merged in, such as running jobs or pending approvals. */
|
|
131
|
+
readonly sources?: readonly NotificationSource<T>[];
|
|
132
|
+
/** Orders the merged list. Defaults to the order the sources return. */
|
|
133
|
+
readonly sort?: (a: T, b: T) => number;
|
|
134
|
+
/** The badge number. Defaults to the items without a `readAt`. */
|
|
135
|
+
readonly count?: (items: readonly T[]) => number;
|
|
136
|
+
/** Runs for each broadcast, e.g. to show a toast for `notification_created`. */
|
|
137
|
+
readonly onMessage?: (event: string, payload: unknown) => void;
|
|
138
|
+
}
|
|
139
|
+
interface NotificationsState<T> {
|
|
140
|
+
/** `undefined` until the first load. */
|
|
141
|
+
readonly items: readonly T[] | undefined;
|
|
142
|
+
readonly count: number;
|
|
143
|
+
readonly status: SubscriptionStatus;
|
|
144
|
+
readonly error: unknown;
|
|
145
|
+
/** Loads again, e.g. after marking items read. */
|
|
146
|
+
readonly refresh: () => Promise<void>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The signed-in user's notifications, kept current: loads them, then loads
|
|
150
|
+
* again after each broadcast on `topic` and after the channel rejoins.
|
|
151
|
+
*
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const { items, count } = useNotifications({
|
|
154
|
+
* topic: `org:${orgId}:notifications:${userId}`,
|
|
155
|
+
* load: () => listNotifications(orgId),
|
|
156
|
+
* });
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
declare function useNotifications<T>(options: UseNotificationsOptions<T>): NotificationsState<T>;
|
|
160
|
+
//#endregion
|
|
161
|
+
export { useBroadcast as _, BetterHooks as a, useSupabase as b, BroadcastOptions as c, LiveCount as d, LiveCountHookOptions as f, useAuth as g, createHooks as h, useNotifications as i, ClaimsOf as l, ProfileOf as m, NotificationsState as n, BetterSupabaseProvider as o, LiveQueryHookOptions as p, UseNotificationsOptions as r, BetterSupabaseProviderProps as s, NotificationSource as t, ClientLike as u, useLiveCount as v, useLiveQuery as y };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { p as OpenApiParameter } from "./index-
|
|
1
|
+
import { j as SchemaMeta } from "./types-Dnf_wRDz.js";
|
|
2
|
+
import { p as OpenApiParameter } from "./index-fag8VJZ2.js";
|
|
3
3
|
//#region src/openapi/index.d.ts
|
|
4
4
|
type Json = Record<string, unknown>;
|
|
5
5
|
type ResourceOperation = "list" | "get" | "create" | "update" | "delete";
|
|
@@ -68,13 +68,13 @@ declare const PROBLEM_SCHEMA: Json;
|
|
|
68
68
|
* schemes and Problem Details errors.
|
|
69
69
|
*
|
|
70
70
|
* ```ts
|
|
71
|
-
* const doc = createOpenApi(
|
|
71
|
+
* const doc = createOpenApi(betterSupabase, {
|
|
72
72
|
* info: { title: 'CRM API', version: '1.0.0' },
|
|
73
73
|
* resources: { customers: { list: customerList }, notes: { operations: ['list', 'get'] } },
|
|
74
74
|
* });
|
|
75
75
|
* ```
|
|
76
76
|
*/
|
|
77
|
-
declare function createOpenApi(
|
|
77
|
+
declare function createOpenApi(betterSupabase: {
|
|
78
78
|
readonly meta: SchemaMeta;
|
|
79
79
|
}, options: OpenApiOptions): OpenApiDocument;
|
|
80
80
|
//#endregion
|
|
@@ -10,6 +10,8 @@ interface BetterSupabaseEnv {
|
|
|
10
10
|
readonly secretKeys?: Readonly<Record<string, string>>;
|
|
11
11
|
/** `SUPABASE_JWKS_URL`, or `<url>/auth/v1/.well-known/jwks.json`. */
|
|
12
12
|
readonly jwksUrl: URL;
|
|
13
|
+
/** `SUPABASE_JWKS`: inline keys, used instead of fetching `jwksUrl`. */
|
|
14
|
+
readonly jwks?: InlineJwks;
|
|
13
15
|
/** Direct Postgres connection string (`SUPABASE_DB_URL` / `DATABASE_URL`). */
|
|
14
16
|
readonly dbUrl?: string;
|
|
15
17
|
/** Project ref for hosted projects (`<ref>.supabase.co`). */
|
|
@@ -17,6 +19,8 @@ interface BetterSupabaseEnv {
|
|
|
17
19
|
/** `SUPABASE_READ_URL`: a read replica or the `<ref>-all` load balancer, for reads. */
|
|
18
20
|
readonly readUrl?: string;
|
|
19
21
|
}
|
|
22
|
+
/** A JSON Web Key Set, as `@supabase/server` verifies with it. */
|
|
23
|
+
type InlineJwks = Exclude<SupabaseEnv["jwks"], URL | null>;
|
|
20
24
|
interface PublicEnv {
|
|
21
25
|
readonly url: string;
|
|
22
26
|
readonly publishableKey: string;
|
|
@@ -46,6 +50,7 @@ declare const ENV_VARIABLES: {
|
|
|
46
50
|
readonly secretKey: readonly string[];
|
|
47
51
|
readonly dbUrl: readonly string[];
|
|
48
52
|
readonly jwksUrl: readonly string[];
|
|
53
|
+
readonly jwks: readonly string[];
|
|
49
54
|
readonly readUrl: readonly string[];
|
|
50
55
|
};
|
|
51
56
|
declare class EnvValidationError extends Error {
|
|
@@ -68,4 +73,4 @@ declare function publicEnv(env: BetterSupabaseEnv): PublicEnv;
|
|
|
68
73
|
/** Converts to `@supabase/server`'s `SupabaseEnv` (the `env` option of `withSupabase`). */
|
|
69
74
|
declare function toServerEnv(env: BetterSupabaseEnv): SupabaseEnv;
|
|
70
75
|
//#endregion
|
|
71
|
-
export { EnvResult as a,
|
|
76
|
+
export { EnvResult as a, InlineJwks as c, loadEnv as d, parseEnv as f, EnvOptions as i, PublicEnv as l, toServerEnv as m, ENV_VARIABLES as n, EnvSource as o, publicEnv as p, EnvIssue as r, EnvValidationError as s, BetterSupabaseEnv as t, envSchema as u };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import {
|
|
3
|
-
import { a as EventHub, s as MutationNotice } from "./events-
|
|
4
|
-
import { l as
|
|
2
|
+
import { j as SchemaMeta } from "./types-Dnf_wRDz.js";
|
|
3
|
+
import { a as EventHub, g as KitEventPattern, p as KitEvent, s as MutationNotice } from "./events-aIO7vsIk.js";
|
|
4
|
+
import { l as MutationIntent } from "./plugin-o144f322.js";
|
|
5
5
|
//#region src/events/index.d.ts
|
|
6
6
|
/** A CloudEvents 1.0 event. Extension attributes are lowercase alphanumerics. */
|
|
7
7
|
interface CloudEvent<T = unknown> {
|
|
@@ -16,10 +16,11 @@ interface CloudEvent<T = unknown> {
|
|
|
16
16
|
readonly data?: T;
|
|
17
17
|
readonly [extension: string]: unknown;
|
|
18
18
|
}
|
|
19
|
-
declare const ROW_EVENT_TYPES: { readonly [K in
|
|
19
|
+
declare const ROW_EVENT_TYPES: { readonly [K in MutationIntent]: string; };
|
|
20
20
|
interface RowEventData {
|
|
21
21
|
readonly table: string;
|
|
22
22
|
readonly row: Readonly<Record<string, unknown>>;
|
|
23
|
+
readonly actorId?: string;
|
|
23
24
|
}
|
|
24
25
|
interface CloudEventOptions {
|
|
25
26
|
/** URI-reference of the producer, e.g. `https://crm.example.com` or `/crm`. */
|
|
@@ -35,8 +36,10 @@ interface EventSink {
|
|
|
35
36
|
}
|
|
36
37
|
/**
|
|
37
38
|
* One CloudEvent per mutated row: `dev.better-supabase.row.created` with the
|
|
38
|
-
* app-cased row
|
|
39
|
-
* `partitionkey
|
|
39
|
+
* app-cased row and the actor in `data`, the primary key as `subject` and the
|
|
40
|
+
* tenant as `partitionkey`. Writes that return no rows (soft
|
|
41
|
+
* deletes, `returning: false`) send one event per known primary key, with the
|
|
42
|
+
* key as `row`.
|
|
40
43
|
*/
|
|
41
44
|
declare function toCloudEvents(notice: MutationNotice, options: CloudEventOptions & {
|
|
42
45
|
readonly meta?: SchemaMeta;
|
|
@@ -49,12 +52,34 @@ interface ForwardOptions extends CloudEventOptions {
|
|
|
49
52
|
}
|
|
50
53
|
/**
|
|
51
54
|
* Sends a CloudEvent for every mutation to `sink`. Returns a function that
|
|
52
|
-
* stops forwarding.
|
|
55
|
+
* stops forwarding. Sends in flight are tracked on `betterSupabase.events`
|
|
56
|
+
* (`settled()`), which the Next adapter hands to `after()` and the edge
|
|
57
|
+
* entry to `waitUntil`. Use an outbox (SQL kit) when events must not be lost.
|
|
53
58
|
*/
|
|
54
|
-
declare function forwardMutations(
|
|
59
|
+
declare function forwardMutations(betterSupabase: {
|
|
55
60
|
readonly events: EventHub;
|
|
56
61
|
readonly meta: SchemaMeta;
|
|
57
62
|
}, sink: EventSink, options: ForwardOptions): () => void;
|
|
63
|
+
/**
|
|
64
|
+
* A kit event as a CloudEvent: `dev.better-supabase.support.started` with
|
|
65
|
+
* the event data and the actor (`actorId`) as `data` and the tenant as
|
|
66
|
+
* `partitionkey`.
|
|
67
|
+
*/
|
|
68
|
+
declare function kitCloudEvent(event: KitEvent, options: CloudEventOptions): CloudEvent;
|
|
69
|
+
interface ForwardKitOptions extends CloudEventOptions {
|
|
70
|
+
/** Only forward events that match, e.g. `support.*`. Defaults to all. */
|
|
71
|
+
readonly types?: readonly KitEventPattern[];
|
|
72
|
+
/** Sink failures never fail the kit call. Defaults to the `Logger`. */
|
|
73
|
+
readonly onError?: (error: unknown, events: readonly CloudEvent[]) => void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Sends a CloudEvent for every kit event (`support.*`, `org.*`, ...) to
|
|
77
|
+
* `sink`. Returns a function that stops forwarding. Like
|
|
78
|
+
* `forwardMutations`, sends are tracked on `betterSupabase.events`.
|
|
79
|
+
*/
|
|
80
|
+
declare function forwardKitEvents(betterSupabase: {
|
|
81
|
+
readonly events: EventHub;
|
|
82
|
+
}, sink: EventSink, options: ForwardKitOptions): () => void;
|
|
58
83
|
type HttpMode = "structured" | "binary" | "batch";
|
|
59
84
|
/** The HTTP protocol binding: headers and body for one event (or a batch). */
|
|
60
85
|
declare function toHttp(events: CloudEvent | readonly CloudEvent[], mode?: HttpMode): {
|
|
@@ -72,4 +97,4 @@ interface HttpSinkOptions {
|
|
|
72
97
|
/** POSTs events to `url`. Non-2xx responses reject. */
|
|
73
98
|
declare function httpSink(url: string | URL, options?: HttpSinkOptions): EventSink;
|
|
74
99
|
//#endregion
|
|
75
|
-
export {
|
|
100
|
+
export { toHttp as _, ForwardOptions as a, ROW_EVENT_TYPES as c, forwardMutations as d, fromHttp as f, toCloudEvents as g, kitCloudEvent as h, ForwardKitOptions as i, RowEventData as l, isCloudEvent as m, CloudEventOptions as n, HttpMode as o, httpSink as p, EventSink as r, HttpSinkOptions as s, CloudEvent as t, forwardKitEvents as u };
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { C as FindExt, Ct as WhereInput, M as UpsertArgs, N as WriteArgs, S as DeleteExt, T as OffsetPageArgs, X as InferResult, Z as QuerySpec, _ as CursorPage, it as AggregateResult, j as UpdateArgs, k as Returned, l as CacheAdapter, lt as FindFirstArgs, rt as AggregateArgs, st as CountArgs, t as BetterSupabase, ut as FindManyArgs, v as CursorPageArgs, vt as Payload, w as OffsetPage, x as DeleteArgs, y as Db, yt as ReadArgs } from "./define-
|
|
4
|
-
import { DataTag, InfiniteData, QueryClient, SkipToken } from "@tanstack/query-core";
|
|
1
|
+
import { P as TableKey, R as UniqueWhere, _ as Insert, n as AnyFunctions, r as AnyModels, w as PrimaryKeyValue, z as Update } from "./types-Dnf_wRDz.js";
|
|
2
|
+
import { x as DbException } from "./executor-BunPOO-k.js";
|
|
3
|
+
import { C as FindExt, Ct as WhereInput, M as UpsertArgs, N as WriteArgs, S as DeleteExt, T as OffsetPageArgs, X as InferResult, Z as QuerySpec, _ as CursorPage, it as AggregateResult, j as UpdateArgs, k as Returned, l as CacheAdapter, lt as FindFirstArgs, rt as AggregateArgs, st as CountArgs, t as BetterSupabase, ut as FindManyArgs, v as CursorPageArgs, vt as Payload, w as OffsetPage, x as DeleteArgs, y as Db, yt as ReadArgs } from "./define-Bp_BZa5h.js";
|
|
4
|
+
import { DataTag, InfiniteData, QueryClient, QueryMeta, SkipToken } from "@tanstack/query-core";
|
|
5
5
|
//#region src/query/invalidate.d.ts
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Carried by every better-supabase query: the tables whose changes make it
|
|
8
|
+
* stale, on top of the app's `Register['queryMeta']`, so the options stay
|
|
9
|
+
* assignable to `useQuery` when the app narrows its query meta.
|
|
10
|
+
*/
|
|
11
|
+
type BetterQueryMeta = QueryMeta & {
|
|
8
12
|
readonly bsTables: readonly string[];
|
|
9
|
-
|
|
10
|
-
}
|
|
13
|
+
};
|
|
11
14
|
/**
|
|
12
15
|
* Invalidates every query that read one of `tables`: better-supabase queries
|
|
13
16
|
* by their `meta.bsTables`, and other `['bs', table, ...]` keys by prefix.
|
|
@@ -76,7 +79,7 @@ interface TableQueries<M extends AnyModels, T extends TableKey<M>, E> {
|
|
|
76
79
|
type RpcArgsOf<F extends AnyFunctions, N extends keyof F> = F[N]["Args"];
|
|
77
80
|
interface QueryHelpers<M extends AnyModels, F extends AnyFunctions> {
|
|
78
81
|
/** Prefix of every better-supabase key. */
|
|
79
|
-
readonly key: readonly ["bs"];
|
|
82
|
+
readonly $key: readonly ["bs"];
|
|
80
83
|
/** Query options for a `QuerySpec`, for example one sent from a Server Component. */
|
|
81
84
|
$spec<S extends QuerySpec<TableKey<M>>>(spec: S | SkipToken): QueryOptionsOf<InferResult<S>>;
|
|
82
85
|
/** Fetches a spec into `queryClient` for server rendering and hydration. */
|
|
@@ -85,11 +88,11 @@ interface QueryHelpers<M extends AnyModels, F extends AnyFunctions> {
|
|
|
85
88
|
$rpc<N extends Extract<keyof F, string>>(name: N, args?: RpcArgsOf<F, N> | SkipToken, options?: {
|
|
86
89
|
readonly tables?: readonly TableKey<M>[];
|
|
87
90
|
}): QueryOptionsOf<F[N]["Returns"]>;
|
|
88
|
-
/** Mutation options for a database function; invalidates what `
|
|
91
|
+
/** Mutation options for a database function; invalidates what `betterSupabase.defineRpc` declared. */
|
|
89
92
|
$rpcMutation<N extends Extract<keyof F, string>>(name: N): MutationOptionsOf<RpcArgsOf<F, N>, F[N]["Returns"]>;
|
|
90
93
|
}
|
|
91
|
-
type
|
|
92
|
-
interface
|
|
94
|
+
type BetterQueries<M extends AnyModels, E, F extends AnyFunctions = AnyFunctions> = { readonly [T in TableKey<M>]: TableQueries<M, T, E>; } & QueryHelpers<M, F>;
|
|
95
|
+
interface QueriesOptions {
|
|
93
96
|
/**
|
|
94
97
|
* `staleTime` for every query option. Set it above zero when rendering on
|
|
95
98
|
* the server so hydrated data isn't refetched on mount.
|
|
@@ -104,14 +107,37 @@ interface CreateQueriesOptions {
|
|
|
104
107
|
* changed table.
|
|
105
108
|
*
|
|
106
109
|
* ```ts
|
|
107
|
-
* const q = createQueries(
|
|
110
|
+
* const q = createQueries(betterSupabase, () => bs.db);
|
|
108
111
|
* const { data } = useQuery(q.customers.findMany({ select: ['id', 'name'] }));
|
|
109
112
|
* ```
|
|
110
113
|
*/
|
|
111
|
-
declare function createQueries<M extends AnyModels, D, F extends AnyFunctions, E>(
|
|
114
|
+
declare function createQueries<M extends AnyModels, D, F extends AnyFunctions, E>(betterSupabase: BetterSupabase<M, D, F, E>, db: Db<M, F, E, unknown> | (() => Db<M, F, E, unknown>), options?: QueriesOptions): BetterQueries<M, E, F>;
|
|
112
115
|
/** Invalidates every query that read a table in the target. */
|
|
113
116
|
declare function queryCache(client: QueryClient): CacheAdapter;
|
|
114
|
-
/** Invalidates affected queries for every mutation and declared RPC `
|
|
115
|
-
declare function invalidateOnMutation<M extends AnyModels, D, F extends AnyFunctions, E>(
|
|
117
|
+
/** Invalidates affected queries for every mutation and declared RPC `betterSupabase` performs in this runtime. */
|
|
118
|
+
declare function invalidateOnMutation<M extends AnyModels, D, F extends AnyFunctions, E>(betterSupabase: BetterSupabase<M, D, F, E>, client: QueryClient): () => void;
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/query/user-change.d.ts
|
|
121
|
+
/** The part of `createClient().auth` that `clearOnUserChange` reads. */
|
|
122
|
+
interface UserChangeSource {
|
|
123
|
+
subscribe(listener: () => void): () => void;
|
|
124
|
+
current(): {
|
|
125
|
+
readonly status: string;
|
|
126
|
+
readonly user: {
|
|
127
|
+
readonly id: string;
|
|
128
|
+
} | null;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Removes every `['bs', ...]` query when the signed-in user changes or signs
|
|
133
|
+
* out, so the next user never sees the previous user's rows. Returns the
|
|
134
|
+
* function that stops listening. `BetterSupabaseProvider` calls it for React;
|
|
135
|
+
* call it yourself with Vue, Solid, Svelte or Angular Query.
|
|
136
|
+
*
|
|
137
|
+
* ```ts
|
|
138
|
+
* const stop = clearOnUserChange(queryClient, bs.auth);
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
declare function clearOnUserChange(queryClient: Pick<QueryClient, "removeQueries">, auth: UserChangeSource): () => void;
|
|
116
142
|
//#endregion
|
|
117
|
-
export {
|
|
143
|
+
export { MutationOptionsOf as a, QueryKeyOf as c, createQueries as d, invalidateOnMutation as f, invalidateTables as h, InfiniteOptionsOf as i, QueryOptionsOf as l, BetterQueryMeta as m, clearOnUserChange as n, QueriesOptions as o, queryCache as p, BetterQueries as r, QueryHelpers as s, UserChangeSource as t, TableQueries as u };
|