better-supabase 0.2.0 → 0.4.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 +37 -33
- package/dist/base64-D2gsioCY.js +42 -0
- package/dist/claims-BAf6c7is.js +48 -0
- package/dist/cli/_format-Cax5EsM9.js +101 -0
- package/dist/cli/bin.js +39 -6
- package/dist/cli/command-CK14fP91.js +502 -0
- package/dist/cli/compare-BmIWVEui.js +9 -0
- package/dist/cli/config-D9R0o1LH.js +1895 -0
- package/dist/cli/config-SSKSTUl2.js +2 -0
- package/dist/cli/db-DOBPt660.js +52 -0
- package/dist/cli/dist-B1MvLv-M.js +129 -0
- package/dist/cli/dist-CFgGknmZ.js +1112 -0
- package/dist/cli/dist-Du7VnEUG.js +621 -0
- package/dist/cli/doctor-BOym3mbL.js +2382 -0
- package/dist/cli/env-BZ0uy8XK.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-Ccn_p90L.js +2008 -0
- package/dist/cli/gen-D5cLCULx.js +2 -0
- package/dist/cli/index.d.ts +295 -28
- package/dist/cli/index.js +184 -3
- package/dist/cli/init-ClnxRYBF.js +550 -0
- package/dist/cli/introspect-DxqfkVIv.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-8WHjxiTJ.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-CMa29t9a.js +971 -0
- package/dist/cli/rolldown-runtime-BPOCksWG.js +24 -0
- package/dist/cli/run-CP20LKk_.js +347 -0
- package/dist/cli/seed-5J6eu_Xg.js +98 -0
- package/dist/cli/skills-LJJIhLFR.js +137 -0
- package/dist/cli/sql-D4VbqmXi.js +199 -0
- package/dist/cli/style-C0NFdJRL.js +29 -0
- package/dist/cli/toml-DB-MNnFs.js +424 -0
- package/dist/{version-Cqq1m3UY.js → cli/version-5mW_8sY1.js} +1 -1
- package/dist/cli/yaml-CYCbJ6et.js +2252 -0
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +15 -25
- package/dist/{compiler-CZ9nIuqy.d.ts → compiler-DB3aSFOA.d.ts} +2 -2
- package/dist/config/index.d.ts +4 -3
- package/dist/config/index.js +5 -3
- package/dist/config-BpxDfnbg.js +129 -0
- package/dist/{index-DOsjFvMf.d.ts → config-C1CYcm6o.d.ts} +49 -49
- package/dist/{config-ClDXmVtY.js → config-CbvFmGD8.js} +14 -137
- package/dist/{define-BXMYD9AY.js → define-Bh0AqTik.js} +221 -120
- package/dist/{define-e3zI4_4g.d.ts → define-CRS2MRV3.d.ts} +36 -31
- package/dist/edge/index.d.ts +9 -13
- package/dist/edge/index.js +51 -25
- package/dist/{entitlements-Dng-ctuT.d.ts → entitlements-Dm-FHpNH.d.ts} +2 -2
- package/dist/env/index.js +203 -1
- package/dist/{errors-Bl3rkOzo.js → errors-L0xK41y_.js} +1 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.js +139 -1
- package/dist/{events-DOt3nSO-.d.ts → events-B21UOhvP.d.ts} +4 -4
- package/dist/{executor-CGdNQ27g.d.ts → executor-B5IoUxLE.d.ts} +2 -2
- package/dist/{executor-DeppvirK.js → executor-CVt6dD0B.js} +9 -4
- package/dist/{executor-BYXQ9AGn.d.ts → executor-CZ7ImRiD.d.ts} +2 -2
- package/dist/hono/index.d.ts +17 -24
- package/dist/hono/index.js +11 -11
- package/dist/{index-DuP14VHo.d.ts → index-528Ugmyp.d.ts} +30 -10
- package/dist/{index-Bw1bwtC0.d.ts → index-BAy4tsAP.d.ts} +28 -15
- package/dist/{index-CBDufH1M.d.ts → index-BBdvo-5d.d.ts} +24 -26
- package/dist/{index-DbxFr7XG.d.ts → index-BhHEC04r.d.ts} +9 -4
- package/dist/index-Cf-D2jk1.d.ts +50 -0
- package/dist/{index-Ciu5Xlml.d.ts → index-D5IfUIDh.d.ts} +6 -5
- package/dist/{index-K-3WM2Hp.d.ts → index-DFmOpBGC.d.ts} +13 -13
- package/dist/{index-D4v7sncu.d.ts → index-RlLXd8dL.d.ts} +13 -13
- package/dist/index.d.ts +17 -17
- package/dist/index.js +23 -14
- package/dist/{invalidate-DbxuL2jL.js → invalidate-CgxmRamI.js} +7 -1
- package/dist/jobs/index.d.ts +33 -26
- package/dist/jobs/index.js +44 -22
- package/dist/{json-schema-BpYqkCKf.js → json-schema-DP6V7cbr.js} +8 -3
- package/dist/lint/index.js +1 -1
- package/dist/list/index.d.ts +2 -2
- package/dist/list/index.js +131 -96
- package/dist/{live-DJyZMD6w.d.ts → live-BHakSWWo.d.ts} +26 -16
- package/dist/{live-D8rV1Ldw.js → live-CdJBOc4f.js} +13 -9
- package/dist/lookup-BaP5bI27.js +18 -0
- package/dist/mcp/index.d.ts +34 -27
- package/dist/mcp/index.js +59 -25
- package/dist/{mfa-TVia554c.d.ts → mfa-C7MNQ1Ob.d.ts} +1 -1
- package/dist/{mfa-CpLfJSde.js → mfa-byfjruR9.js} +190 -46
- package/dist/next/image/index.js +6 -3
- package/dist/next/index.d.ts +64 -48
- package/dist/next/index.js +63 -50
- package/dist/openapi/index.d.ts +1 -1
- package/dist/openapi/index.js +61 -38
- package/dist/orpc/index.d.ts +18 -21
- package/dist/orpc/index.js +12 -12
- package/dist/otel/index.d.ts +5 -5
- package/dist/otel/index.js +84 -63
- package/dist/{permdock-sql-CghlHPuH.js → permdock-sql-C4KFzLc9.js} +12 -7
- package/dist/permdock-sql-DImJULY-.d.ts +17 -0
- package/dist/{plugin-C4TR9J0Z.d.ts → plugin-bNhvJwRh.d.ts} +5 -4
- package/dist/plugins/actor/index.d.ts +1 -1
- package/dist/plugins/actor/index.js +1 -1
- package/dist/plugins/rules/index.d.ts +2 -2
- package/dist/plugins/rules/index.js +46 -16
- package/dist/plugins/soft-delete/index.d.ts +3 -3
- package/dist/plugins/soft-delete/index.js +4 -4
- package/dist/plugins/tenant/index.d.ts +3 -3
- package/dist/plugins/tenant/index.js +10 -4
- package/dist/plugins/timestamps/index.d.ts +1 -1
- package/dist/plugins/timestamps/index.js +2 -2
- package/dist/plugins/validation/index.d.ts +2 -2
- package/dist/plugins/validation/index.js +3 -3
- package/dist/pool-DFwEQwmN.d.ts +78 -0
- package/dist/postgres/index.d.ts +10 -5
- package/dist/postgres/index.js +37 -16
- package/dist/{postgrest-cAEQ_IQN.d.ts → postgrest-Bc-0Xw62.d.ts} +1 -1
- package/dist/{problem-BTkTtRV9.js → problem-BihjPR0t.js} +11 -5
- package/dist/{problem-DlgB0lYl.d.ts → problem-U8UEKccv.d.ts} +6 -4
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +2 -2
- package/dist/{query-ChvDbsDE.js → query-BMMSWbI7.js} +19 -19
- package/dist/react/index.d.ts +7 -7
- package/dist/react/index.js +2 -2
- package/dist/react/server.d.ts +6 -6
- package/dist/react/server.js +3 -3
- package/dist/react/session.d.ts +21 -2
- package/dist/react/session.js +19 -1
- package/dist/{react-C83BdBGt.js → react-CQHMaESR.js} +59 -55
- package/dist/{read-set-4lI3W_gZ.js → read-set-FWK8qQ58.js} +51 -16
- package/dist/realtime/index.d.ts +4 -3
- package/dist/realtime/index.js +19 -17
- package/dist/{index-CG69s15v.d.ts → refresh-BwYkyNOQ.d.ts} +7 -3
- package/dist/{resolve-CjHILk2w.d.ts → resolve-BAqQcwMW.d.ts} +17 -11
- package/dist/{resource-CgZa3YG_.d.ts → resource-BJcaIfxi.d.ts} +17 -8
- package/dist/{resource-BHEWmQJK.js → resource-My_y-Syh.js} +43 -21
- package/dist/{respond-Dne1ARSa.d.ts → respond-DgIbdrt8.d.ts} +39 -14
- package/dist/{result-DWXatkd6.js → result-Bj6yt33D.js} +2 -2
- package/dist/{result-CTkCZ6JA.d.ts → result-CqEsbgYs.d.ts} +16 -11
- package/dist/server/index.d.ts +38 -13
- package/dist/server/index.js +43 -14
- package/dist/{respond-DMcbQwfN.js → server-BA75B0mT.js} +151 -96
- package/dist/{shared-_6-uPL7E.js → shared-DnoCdMDr.js} +4 -3
- package/dist/{simplify-bwJpLnaS.js → simplify-Cqvfr9dj.js} +76 -39
- package/dist/sql/index.d.ts +139 -0
- package/dist/sql/index.js +1983 -0
- package/dist/{sql-DTjA1LPj.js → sql-B34HU2DI.js} +74 -17
- package/dist/ssr/index.d.ts +4 -4
- package/dist/ssr/index.js +2 -2
- package/dist/{standard-FUi3Z3-7.js → standard-BRyBGTtp.js} +2 -2
- package/dist/{standard-CyhRzctb.d.ts → standard-BsaCYQJc.d.ts} +1 -1
- package/dist/{stats-C5W-rBfR.js → stats-C_YxA2r1.js} +40 -14
- package/dist/storage/index.d.ts +4 -3
- package/dist/storage/index.js +548 -1
- package/dist/{tables-rZxRxNPW.js → tables-Cb-3_VWc.js} +19 -5
- package/dist/temporal-BwshQk0W.js +27 -0
- package/dist/temporal-required-CBNHT6ni.js +19 -0
- package/dist/testing/index.d.ts +25 -24
- package/dist/testing/index.js +165 -66
- package/dist/{types-C83v5SQz.d.ts → types-DONv9SHN.d.ts} +14 -11
- package/dist/version-Bmf7_FzM.js +4 -0
- package/dist/{view-D1s0wa0T.d.ts → view-B64o81wp.d.ts} +36 -6
- package/dist/{view-aOYizTeE.js → view-BrJI2LKp.js} +11 -2
- package/dist/webhooks/index.d.ts +19 -17
- package/dist/webhooks/index.js +1 -1
- package/dist/{webhooks-DMipjhSP.js → webhooks-Bh_Jf_-l.js} +45 -24
- package/package.json +50 -22
- package/schemas/config-v1.json +31 -1
- package/schemas/doctor-report-v1.json +17 -1
- package/schemas/snapshot-v2.json +35 -0
- package/skills/better-supabase/SKILL.md +77 -18
- package/skills/better-supabase/references/plugins.md +21 -22
- package/skills/better-supabase/references/troubleshooting.md +38 -18
- package/skills/better-supabase-api/SKILL.md +66 -18
- package/skills/better-supabase-api/references/adapters.md +64 -41
- package/skills/better-supabase-auth/SKILL.md +146 -0
- package/skills/better-supabase-auth/references/permdock.md +55 -0
- package/skills/better-supabase-testing/SKILL.md +68 -11
- package/dist/casing-da0uRTqt.js +0 -14
- package/dist/claims-CoTobNC-.js +0 -25
- package/dist/cli-DrSgDOQC.js +0 -6646
- package/dist/env-BEToab0I.js +0 -204
- package/dist/events-BuzTgn2D.js +0 -135
- package/dist/pool-R2m_DkXi.d.ts +0 -37
- package/dist/seed-CzecODcJ.js +0 -101
- package/dist/session-C3LxnQ0e.d.ts +0 -22
- package/dist/session-CqEwzVup.js +0 -20
- package/dist/storage-DuGn38fr.js +0 -527
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { n as dbError, o as isDbError, r as dbErrorOf } from "./errors-
|
|
2
|
-
import { i as ok, n as err, o as toDbError, t as AsyncResult } from "./result-
|
|
3
|
-
import { a as postgrestExecutor, n as StatsRecorder } from "./stats-
|
|
4
|
-
import { a as problemResponse } from "./problem-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { n as dbError, o as isDbError, r as dbErrorOf } from "./errors-L0xK41y_.js";
|
|
2
|
+
import { i as ok, n as err, o as toDbError, t as AsyncResult } from "./result-Bj6yt33D.js";
|
|
3
|
+
import { a as postgrestExecutor, n as StatsRecorder } from "./stats-C_YxA2r1.js";
|
|
4
|
+
import { a as problemResponse } from "./problem-BihjPR0t.js";
|
|
5
|
+
import { loadEnv } from "./env/index.js";
|
|
6
|
+
import { _ as delegationOf, g as actorOf, i as authContext, o as prefetchJwks, r as checkAal, s as resolveAuth, v as actClaim } from "./mfa-byfjruR9.js";
|
|
7
|
+
import { parseCookieHeader, serializeCookieHeader } from "@supabase/ssr";
|
|
8
8
|
import { createClient } from "@supabase/supabase-js";
|
|
9
|
+
import { PostgrestClient } from "@supabase/postgrest-js";
|
|
9
10
|
//#region src/server/replicas.ts
|
|
10
11
|
/** Cookie holding the epoch ms until which reads stay on the primary. */
|
|
11
12
|
const PRIMARY_COOKIE = "bs-primary-until";
|
|
@@ -26,22 +27,21 @@ function replicaState(pinnedUntil = 0, now = Date.now()) {
|
|
|
26
27
|
}
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
|
-
/** `bs-primary-until` from a `cookie` header, or 0. */
|
|
30
|
-
function pinnedUntil(
|
|
31
|
-
if (!
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const until = Number(value);
|
|
36
|
-
return Number.isFinite(until) ? until : 0;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return 0;
|
|
30
|
+
/** `bs-primary-until` from a `cookie` header or parsed cookies, or 0. */
|
|
31
|
+
function pinnedUntil(cookies) {
|
|
32
|
+
if (!cookies) return 0;
|
|
33
|
+
const value = (typeof cookies === "string" ? parseCookieHeader(cookies) : cookies).find((cookie) => cookie.name === PRIMARY_COOKIE)?.value;
|
|
34
|
+
const until = Number(value);
|
|
35
|
+
return value !== void 0 && Number.isFinite(until) ? until : 0;
|
|
40
36
|
}
|
|
41
37
|
/** A `Set-Cookie` value keeping the next requests on the primary for `pinMs`. */
|
|
42
38
|
function primaryCookie(pinMs, now = Date.now()) {
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
return serializeCookieHeader(PRIMARY_COOKIE, String(now + pinMs), {
|
|
40
|
+
path: "/",
|
|
41
|
+
maxAge: Math.max(1, Math.ceil(pinMs / 1e3)),
|
|
42
|
+
httpOnly: true,
|
|
43
|
+
sameSite: "lax"
|
|
44
|
+
});
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* Reads go to `replica` until the context is pinned; writes, and every read
|
|
@@ -93,7 +93,7 @@ function fromAuthError(raw) {
|
|
|
93
93
|
* Removes a user's Storage objects, then the Auth user, then announces the
|
|
94
94
|
* delete. Rows referencing `auth.users` follow their foreign keys.
|
|
95
95
|
*/
|
|
96
|
-
function deleteAccount(
|
|
96
|
+
function deleteAccount(betterSupabase, service, userId, options = {}) {
|
|
97
97
|
return AsyncResult.from(async () => {
|
|
98
98
|
const client = service();
|
|
99
99
|
const removed = {};
|
|
@@ -121,13 +121,13 @@ function deleteAccount(sb, service, userId, options = {}) {
|
|
|
121
121
|
return err(fromAuthError(cause));
|
|
122
122
|
}
|
|
123
123
|
const context = options.context ?? {};
|
|
124
|
-
|
|
124
|
+
betterSupabase.events.emit("mutation", {
|
|
125
125
|
table: "auth.users",
|
|
126
126
|
kind: "delete",
|
|
127
127
|
rows: [{ id: userId }],
|
|
128
128
|
context
|
|
129
129
|
});
|
|
130
|
-
for (const table of options.cascades ?? [])
|
|
130
|
+
for (const table of options.cascades ?? []) betterSupabase.events.emit("mutation", {
|
|
131
131
|
table,
|
|
132
132
|
kind: "delete",
|
|
133
133
|
rows: [],
|
|
@@ -140,6 +140,78 @@ function deleteAccount(sb, service, userId, options = {}) {
|
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
142
|
//#endregion
|
|
143
|
+
//#region src/server/respond.ts
|
|
144
|
+
/** The scopes a delegated user token lacks; empty for the user's own session. */
|
|
145
|
+
function missingScopes(auth, required) {
|
|
146
|
+
if (required.length === 0) return [];
|
|
147
|
+
const outcome = actorOf(auth.claims);
|
|
148
|
+
if (!outcome.ok || !outcome.actor) return [];
|
|
149
|
+
const granted = new Set(delegationOf(auth.claims)?.scopes);
|
|
150
|
+
return required.filter((scope) => !granted.has(scope));
|
|
151
|
+
}
|
|
152
|
+
/** `undefined` when `auth` may pass; otherwise the 401/403 error to send. */
|
|
153
|
+
function guard(auth, allow = ["user"], aal = "aal1", scopes = []) {
|
|
154
|
+
if (auth.kind === "invalid") return auth.error;
|
|
155
|
+
if (allow.includes(auth.kind)) {
|
|
156
|
+
const denied = checkAal(auth, aal);
|
|
157
|
+
if (denied || auth.kind !== "user") return denied;
|
|
158
|
+
const missing = missingScopes(auth, scopes);
|
|
159
|
+
return missing.length > 0 ? dbError("forbidden", `The token lacks the scope ${missing.join(" ")}`, {
|
|
160
|
+
code: "INSUFFICIENT_SCOPE",
|
|
161
|
+
scopes
|
|
162
|
+
}) : void 0;
|
|
163
|
+
}
|
|
164
|
+
return auth.kind === "anon" ? dbError("unauthorized", "Sign in to continue", { code: "MISSING_CREDENTIALS" }) : dbError("forbidden", `A ${auth.kind} caller is not allowed here`);
|
|
165
|
+
}
|
|
166
|
+
function isResult(value) {
|
|
167
|
+
return typeof value === "object" && value !== null && "ok" in value && "data" in value && "error" in value;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Settles a handler's return value: `Result`s and `AsyncResult`s unwrap,
|
|
171
|
+
* thrown `DbException`s (or errors whose `cause` is a `DbError`) become
|
|
172
|
+
* errors, anything else is data. Other thrown
|
|
173
|
+
* errors propagate.
|
|
174
|
+
*/
|
|
175
|
+
async function settle(run) {
|
|
176
|
+
try {
|
|
177
|
+
const value = await run();
|
|
178
|
+
if (!isResult(value)) return {
|
|
179
|
+
ok: true,
|
|
180
|
+
data: value
|
|
181
|
+
};
|
|
182
|
+
if (value.ok) return {
|
|
183
|
+
ok: true,
|
|
184
|
+
data: value.data
|
|
185
|
+
};
|
|
186
|
+
return {
|
|
187
|
+
ok: false,
|
|
188
|
+
error: isDbError(value.error) ? value.error : toDbError(value.error)
|
|
189
|
+
};
|
|
190
|
+
} catch (cause) {
|
|
191
|
+
const thrown = dbErrorOf(cause);
|
|
192
|
+
if (thrown) return {
|
|
193
|
+
ok: false,
|
|
194
|
+
error: thrown
|
|
195
|
+
};
|
|
196
|
+
throw cause;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/** A handler's value as a response: `Response` as is, data as JSON, errors as Problem Details. */
|
|
200
|
+
async function respond(run, options = {}) {
|
|
201
|
+
const settled = await settle(run);
|
|
202
|
+
if (!settled.ok) return problemResponse(settled.error, options);
|
|
203
|
+
if (settled.data instanceof Response) return settled.data;
|
|
204
|
+
if (settled.data === void 0) return new Response(null, { status: 204 });
|
|
205
|
+
return Response.json(settled.data, { status: options.status ?? 200 });
|
|
206
|
+
}
|
|
207
|
+
/** Prefetching the JWKS would add a network call to every test that builds a server. */
|
|
208
|
+
function defaultPrefetchJwks() {
|
|
209
|
+
return typeof process === "undefined" || process.env["NODE_ENV"] !== "test";
|
|
210
|
+
}
|
|
211
|
+
function defaultExpose() {
|
|
212
|
+
return typeof process !== "undefined" && process.env["NODE_ENV"] === "development";
|
|
213
|
+
}
|
|
214
|
+
//#endregion
|
|
143
215
|
//#region src/server/server.ts
|
|
144
216
|
const STATELESS = {
|
|
145
217
|
persistSession: false,
|
|
@@ -162,13 +234,19 @@ function withExtra(base, extra) {
|
|
|
162
234
|
}
|
|
163
235
|
/**
|
|
164
236
|
* Server-side entry point for APIs, jobs, MCP servers and framework
|
|
165
|
-
* adapters. Holds the secrets; `
|
|
237
|
+
* adapters. Holds the secrets; `betterSupabase` stays isomorphic.
|
|
166
238
|
*/
|
|
167
|
-
function createServer(
|
|
239
|
+
function createServer(betterSupabase, options = {}) {
|
|
168
240
|
let loaded;
|
|
169
241
|
const env = () => loaded ??= options.env ?? loadEnv();
|
|
170
242
|
let adminClient;
|
|
171
243
|
let anonClient;
|
|
244
|
+
if ((options.prefetchJwks ?? defaultPrefetchJwks()) && options.auth?.jwks === void 0) try {
|
|
245
|
+
prefetchJwks({
|
|
246
|
+
...options.auth,
|
|
247
|
+
env: env()
|
|
248
|
+
});
|
|
249
|
+
} catch {}
|
|
172
250
|
const secretKey = () => {
|
|
173
251
|
const key = env().secretKey;
|
|
174
252
|
if (!key) throw new TypeError("admin() needs SUPABASE_SECRET_KEY; it is not set");
|
|
@@ -204,13 +282,38 @@ function createServer(sb, options = {}) {
|
|
|
204
282
|
}
|
|
205
283
|
};
|
|
206
284
|
const supabaseFor = (auth, headers = {}) => supabaseAt(env().url, auth, headers);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
285
|
+
/**
|
|
286
|
+
* The client queries run on. A user's requests need only PostgREST, so they
|
|
287
|
+
* skip building Realtime, Storage and Auth clients per request; the shared
|
|
288
|
+
* service and anon clients are built once anyway.
|
|
289
|
+
*/
|
|
290
|
+
const restAt = (url, auth, headers = {}) => {
|
|
291
|
+
if (auth.kind !== "user") return supabaseAt(url, auth, headers);
|
|
292
|
+
const key = env().publishableKey;
|
|
293
|
+
return new PostgrestClient(new URL("rest/v1", url.endsWith("/") ? url : `${url}/`).href, { headers: {
|
|
294
|
+
...headers,
|
|
295
|
+
apikey: key,
|
|
296
|
+
Authorization: `Bearer ${auth.token}`
|
|
297
|
+
} });
|
|
298
|
+
};
|
|
299
|
+
/** `$client` stays the full Supabase client, built when first read. */
|
|
300
|
+
const withLazyClient = (db, client) => Object.defineProperty(db, "$client", {
|
|
301
|
+
get: client,
|
|
302
|
+
enumerable: true,
|
|
303
|
+
configurable: true
|
|
210
304
|
});
|
|
305
|
+
const dbFor = (auth, context = {}) => {
|
|
306
|
+
let supabase;
|
|
307
|
+
const rest = restAt(env().url, auth);
|
|
308
|
+
const db = betterSupabase.connect(rest, {
|
|
309
|
+
...authContext(auth),
|
|
310
|
+
...context
|
|
311
|
+
});
|
|
312
|
+
return withLazyClient(db, () => supabase ??= supabaseFor(auth));
|
|
313
|
+
};
|
|
211
314
|
const sqlFor = (claims, context, stats) => {
|
|
212
|
-
if (!options.postgres) throw new TypeError("Direct Postgres access needs createServer(
|
|
213
|
-
return
|
|
315
|
+
if (!options.postgres) throw new TypeError("Direct Postgres access needs createServer(betterSupabase, { postgres: createPostgres() })");
|
|
316
|
+
return betterSupabase.connect(options.postgres.executorFor(claims), context, stats ? { stats } : {});
|
|
214
317
|
};
|
|
215
318
|
/** Clients and repositories are built on first access: most scopes use one of them. */
|
|
216
319
|
const contextFor = (resolution, headers, parent, until = 0) => {
|
|
@@ -237,10 +340,12 @@ function createServer(sb, options = {}) {
|
|
|
237
340
|
get db() {
|
|
238
341
|
if (db) return db;
|
|
239
342
|
const url = replicaUrl();
|
|
240
|
-
|
|
343
|
+
const rest = supabase ?? restAt(env().url, auth, headers);
|
|
344
|
+
const connected = betterSupabase.connect(rest, context, {
|
|
241
345
|
stats: recorder,
|
|
242
|
-
...url && replica ? { executor: routedExecutor(postgrestExecutor(
|
|
346
|
+
...url && replica ? { executor: routedExecutor(postgrestExecutor(rest), postgrestExecutor(restAt(url, auth, headers)), replica) } : {}
|
|
243
347
|
});
|
|
348
|
+
db = withLazyClient(connected, client);
|
|
244
349
|
return db;
|
|
245
350
|
},
|
|
246
351
|
get replica() {
|
|
@@ -248,31 +353,32 @@ function createServer(sb, options = {}) {
|
|
|
248
353
|
return replica;
|
|
249
354
|
},
|
|
250
355
|
get sql() {
|
|
251
|
-
if (!options.postgres || !sqlClaims) return
|
|
356
|
+
if (!options.postgres || !sqlClaims) return;
|
|
252
357
|
sql ??= sqlFor(sqlClaims, context, recorder);
|
|
253
358
|
return sql;
|
|
254
359
|
},
|
|
255
360
|
stats: () => recorder.snapshot()
|
|
256
361
|
};
|
|
257
362
|
};
|
|
363
|
+
const fromResolution = (resolution, request, contextOptions) => contextFor(resolution, options.headers?.(request) ?? {}, contextOptions.stats, contextOptions.pinnedUntil ?? (readUrl() ? pinnedUntil(resolution.requestCookies) : 0));
|
|
258
364
|
const resolve = async (request, resolveOptions = {}) => {
|
|
259
|
-
const claims = options.auth?.claims ??
|
|
260
|
-
const userMetadata =
|
|
365
|
+
const claims = options.auth?.claims ?? betterSupabase.claimsSchema;
|
|
366
|
+
const userMetadata = betterSupabase.userMetadataSchema;
|
|
261
367
|
const resolution = await resolveAuth(request, {
|
|
262
|
-
logger:
|
|
368
|
+
logger: betterSupabase.events.logger,
|
|
263
369
|
...options.auth,
|
|
264
370
|
...claims ? { claims } : {},
|
|
265
371
|
...userMetadata ? { userMetadata } : {},
|
|
266
372
|
env: env(),
|
|
267
|
-
...resolveOptions.refresh
|
|
373
|
+
...resolveOptions.refresh === void 0 ? {} : { refresh: resolveOptions.refresh },
|
|
268
374
|
onRefresh: (event) => {
|
|
269
375
|
options.auth?.onRefresh?.(event);
|
|
270
|
-
|
|
376
|
+
betterSupabase.events.emit("refresh", event);
|
|
271
377
|
}
|
|
272
378
|
});
|
|
273
|
-
if (
|
|
379
|
+
if (betterSupabase.events.has("auth")) {
|
|
274
380
|
const { auth } = resolution;
|
|
275
|
-
|
|
381
|
+
betterSupabase.events.emit("auth", {
|
|
276
382
|
source: auth.kind === "user" ? auth.source === "cookie" ? "cookie" : "bearer" : auth.kind === "service" ? "bearer" : "none",
|
|
277
383
|
ok: auth.kind !== "invalid",
|
|
278
384
|
...auth.kind === "user" ? { userId: auth.user.id } : {}
|
|
@@ -296,9 +402,10 @@ function createServer(sb, options = {}) {
|
|
|
296
402
|
}, {}, contextOptions.stats, contextOptions.pinnedUntil),
|
|
297
403
|
async context(request, contextOptions = {}) {
|
|
298
404
|
const resolution = await resolve(request, { refresh: contextOptions.refresh ?? false });
|
|
299
|
-
return
|
|
405
|
+
return fromResolution(resolution, request, contextOptions);
|
|
300
406
|
},
|
|
301
|
-
|
|
407
|
+
contextFromResolution: (resolution, request, contextOptions = {}) => fromResolution(resolution, request, contextOptions),
|
|
408
|
+
admin: (context = {}) => betterSupabase.connect(serviceClient(), {
|
|
302
409
|
actor: {
|
|
303
410
|
id: "service",
|
|
304
411
|
kind: "service",
|
|
@@ -307,7 +414,7 @@ function createServer(sb, options = {}) {
|
|
|
307
414
|
claims: { role: "service_role" },
|
|
308
415
|
...context
|
|
309
416
|
}),
|
|
310
|
-
deleteAccount: (userId, deleteOptions) => deleteAccount(
|
|
417
|
+
deleteAccount: (userId, deleteOptions) => deleteAccount(betterSupabase, serviceClient, userId, deleteOptions),
|
|
311
418
|
actingAs: (userId, claims = {}, impersonation) => {
|
|
312
419
|
const full = {
|
|
313
420
|
role: "authenticated",
|
|
@@ -328,56 +435,4 @@ function createServer(sb, options = {}) {
|
|
|
328
435
|
};
|
|
329
436
|
}
|
|
330
437
|
//#endregion
|
|
331
|
-
|
|
332
|
-
/** `undefined` when `auth` may pass; otherwise the 401/403 error to send. */
|
|
333
|
-
function guard(auth, allow = ["user"], aal = "aal1") {
|
|
334
|
-
if (auth.kind === "invalid") return auth.error;
|
|
335
|
-
if (allow.includes(auth.kind)) return checkAal(auth, aal);
|
|
336
|
-
return auth.kind === "anon" ? dbError("unauthorized", "Sign in to continue", { code: "MISSING_CREDENTIALS" }) : dbError("forbidden", `A ${auth.kind} caller is not allowed here`);
|
|
337
|
-
}
|
|
338
|
-
function isResult(value) {
|
|
339
|
-
return typeof value === "object" && value !== null && "ok" in value && "data" in value && "error" in value;
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Settles a handler's return value: `Result`s and `AsyncResult`s unwrap,
|
|
343
|
-
* thrown `DbException`s (or errors whose `cause` is a `DbError`) become
|
|
344
|
-
* errors, anything else is data. Other thrown
|
|
345
|
-
* errors propagate.
|
|
346
|
-
*/
|
|
347
|
-
async function settle(run) {
|
|
348
|
-
try {
|
|
349
|
-
const value = await run();
|
|
350
|
-
if (!isResult(value)) return {
|
|
351
|
-
ok: true,
|
|
352
|
-
data: value
|
|
353
|
-
};
|
|
354
|
-
if (value.ok) return {
|
|
355
|
-
ok: true,
|
|
356
|
-
data: value.data
|
|
357
|
-
};
|
|
358
|
-
return {
|
|
359
|
-
ok: false,
|
|
360
|
-
error: isDbError(value.error) ? value.error : toDbError(value.error)
|
|
361
|
-
};
|
|
362
|
-
} catch (cause) {
|
|
363
|
-
const thrown = dbErrorOf(cause);
|
|
364
|
-
if (thrown) return {
|
|
365
|
-
ok: false,
|
|
366
|
-
error: thrown
|
|
367
|
-
};
|
|
368
|
-
throw cause;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
/** A handler's value as a response: `Response` as is, data as JSON, errors as Problem Details. */
|
|
372
|
-
async function respond(run, options = {}) {
|
|
373
|
-
const settled = await settle(run);
|
|
374
|
-
if (!settled.ok) return problemResponse(settled.error, options);
|
|
375
|
-
if (settled.data instanceof Response) return settled.data;
|
|
376
|
-
if (settled.data === void 0) return new Response(null, { status: 204 });
|
|
377
|
-
return Response.json(settled.data, { status: options.status ?? 200 });
|
|
378
|
-
}
|
|
379
|
-
function defaultExpose() {
|
|
380
|
-
return typeof process !== "undefined" && process.env["NODE_ENV"] === "development";
|
|
381
|
-
}
|
|
382
|
-
//#endregion
|
|
383
|
-
export { settle as a, withExtra as c, primaryCookie as d, respond as i, DEFAULT_PIN_MS as l, guard as n, createServer as o, isResult as r, extendServer as s, defaultExpose as t, PRIMARY_COOKIE as u };
|
|
438
|
+
export { guard as a, settle as c, primaryCookie as d, defaultExpose as i, DEFAULT_PIN_MS as l, extendServer as n, isResult as o, withExtra as r, respond as s, createServer as t, PRIMARY_COOKIE as u };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { n as dbError, t as DbException } from "./errors-
|
|
1
|
+
import { n as dbError, t as DbException } from "./errors-L0xK41y_.js";
|
|
2
|
+
import { t as lookupOf } from "./lookup-BaP5bI27.js";
|
|
2
3
|
//#region src/plugins/shared.ts
|
|
3
4
|
/** Database column name for an app column, or `undefined` if it is unknown. */
|
|
4
5
|
function dbName(table, app) {
|
|
@@ -44,13 +45,13 @@ function forbidden(message) {
|
|
|
44
45
|
/** Database-keyed row to app-keyed row. */
|
|
45
46
|
function toApp(table, row) {
|
|
46
47
|
const out = {};
|
|
47
|
-
for (const [app, meta] of
|
|
48
|
+
for (const [app, meta] of lookupOf(table).entries) if (meta.db in row) out[app] = row[meta.db];
|
|
48
49
|
return out;
|
|
49
50
|
}
|
|
50
51
|
/** App-keyed row to database-keyed row. Unknown keys are dropped. */
|
|
51
52
|
function toDb(table, row) {
|
|
52
53
|
const out = {};
|
|
53
|
-
for (const [app, meta] of
|
|
54
|
+
for (const [app, meta] of lookupOf(table).entries) if (app in row) out[meta.db] = row[app];
|
|
54
55
|
return out;
|
|
55
56
|
}
|
|
56
57
|
//#endregion
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { n as dbError, t as DbException } from "./errors-
|
|
1
|
+
import { n as dbError, t as DbException } from "./errors-L0xK41y_.js";
|
|
2
|
+
import { t as lookupOf } from "./lookup-BaP5bI27.js";
|
|
3
|
+
import { i as temporalText } from "./temporal-BwshQk0W.js";
|
|
4
|
+
import { t as temporal } from "./temporal-required-CBNHT6ni.js";
|
|
2
5
|
import { i as or, r as not, t as and } from "./types-6cYK9pbJ.js";
|
|
3
6
|
//#region src/schema/define.ts
|
|
4
7
|
/**
|
|
@@ -27,17 +30,19 @@ function relationMeta(meta, table, relation) {
|
|
|
27
30
|
}
|
|
28
31
|
//#endregion
|
|
29
32
|
//#region src/ir/codec.ts
|
|
30
|
-
/** Wire form of an app value:
|
|
33
|
+
/** Wire form of an app value: Temporal values to ISO text, `bigint` to decimal text. */
|
|
31
34
|
function encodeValue(value) {
|
|
32
|
-
if (value
|
|
33
|
-
|
|
35
|
+
if (typeof value !== "object" || value === null) return typeof value === "bigint" ? value.toString() : value;
|
|
36
|
+
const text = temporalText(value);
|
|
37
|
+
if (text !== void 0) return text;
|
|
34
38
|
if (Array.isArray(value)) return value.map(encodeValue);
|
|
35
39
|
return value;
|
|
36
40
|
}
|
|
37
41
|
function decodeScalar(codec, value) {
|
|
38
42
|
if (value === null || value === void 0) return value;
|
|
39
43
|
switch (codec) {
|
|
40
|
-
case "
|
|
44
|
+
case "instant": return temporal().Instant.from(String(value));
|
|
45
|
+
case "plainDateTime": return temporal().PlainDateTime.from(String(value));
|
|
41
46
|
case "bigint": return BigInt(value);
|
|
42
47
|
case "string": return String(value);
|
|
43
48
|
default: return codec;
|
|
@@ -48,6 +53,15 @@ function decode(codec, value) {
|
|
|
48
53
|
}
|
|
49
54
|
/** Whether decoding `selection` changes anything, so plain reads skip the walk. */
|
|
50
55
|
function needsDecoding(selection) {
|
|
56
|
+
let needs = decodes.get(selection);
|
|
57
|
+
if (needs === void 0) {
|
|
58
|
+
needs = computeNeedsDecoding(selection);
|
|
59
|
+
decodes.set(selection, needs);
|
|
60
|
+
}
|
|
61
|
+
return needs;
|
|
62
|
+
}
|
|
63
|
+
const decodes = /* @__PURE__ */ new WeakMap();
|
|
64
|
+
function computeNeedsDecoding(selection) {
|
|
51
65
|
return selection.aggregate !== void 0 || selection.columns.some((column) => column.codec !== void 0) || selection.includes.some((include) => include.count !== void 0 || include.aggregate !== void 0 || needsDecoding(include.selection));
|
|
52
66
|
}
|
|
53
67
|
/** PostgREST returns `[{ count }]` for a `(count)` embed; SQL returns the number. */
|
|
@@ -63,38 +77,51 @@ function measureOf(measure, value) {
|
|
|
63
77
|
return measure.codec ? decodeScalar(measure.codec, value) : value;
|
|
64
78
|
}
|
|
65
79
|
/** Adds `value` under `row[key][name]`, next to what is already there. */
|
|
66
|
-
function fold(row, key, name, value) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
[
|
|
70
|
-
|
|
80
|
+
function fold(row, folded, key, name, value) {
|
|
81
|
+
let target = folded.get(key);
|
|
82
|
+
if (!target) {
|
|
83
|
+
target = { ...row[key] };
|
|
84
|
+
folded.set(key, target);
|
|
85
|
+
row[key] = target;
|
|
86
|
+
}
|
|
87
|
+
target[name] = value;
|
|
88
|
+
}
|
|
89
|
+
const droppedKeys = /* @__PURE__ */ new WeakMap();
|
|
90
|
+
/** Wire keys that decoding folds into `_count`, `_sum` and the rest. */
|
|
91
|
+
function droppedOf(selection) {
|
|
92
|
+
let dropped = droppedKeys.get(selection);
|
|
93
|
+
if (!dropped) {
|
|
94
|
+
dropped = /* @__PURE__ */ new Set([...selection.aggregate?.measures.map((measure) => measure.key) ?? [], ...selection.includes.filter((include) => include.count !== void 0 || include.aggregate !== void 0).map((include) => include.alias)]);
|
|
95
|
+
droppedKeys.set(selection, dropped);
|
|
96
|
+
}
|
|
97
|
+
return dropped;
|
|
71
98
|
}
|
|
72
99
|
function decodeRow(selection, row) {
|
|
73
|
-
const
|
|
100
|
+
const dropped = droppedOf(selection);
|
|
101
|
+
const out = {};
|
|
102
|
+
for (const key in row) if (!dropped.has(key) && Object.hasOwn(row, key)) out[key] = row[key];
|
|
103
|
+
const folded = /* @__PURE__ */ new Map();
|
|
74
104
|
for (const column of selection.columns) if (column.codec && column.alias in out) out[column.alias] = decode(column.codec, out[column.alias]);
|
|
75
105
|
if (selection.aggregate) {
|
|
76
106
|
if (selection.aggregate.count) out["_count"] = countOf(out["_count"]);
|
|
77
107
|
for (const measure of selection.aggregate.measures) {
|
|
78
|
-
const value =
|
|
79
|
-
|
|
80
|
-
fold(out, `_${measure.fn}`, measure.alias, measureOf(measure, value));
|
|
108
|
+
const value = row[measure.key];
|
|
109
|
+
fold(out, folded, `_${measure.fn}`, measure.alias, measureOf(measure, value));
|
|
81
110
|
}
|
|
82
111
|
}
|
|
83
112
|
for (const include of selection.includes) {
|
|
84
|
-
const value =
|
|
113
|
+
const value = row[include.alias];
|
|
85
114
|
if (include.count !== void 0) {
|
|
86
|
-
if (!(include.alias in
|
|
87
|
-
|
|
88
|
-
fold(out, "_count", include.count, countOf(value));
|
|
115
|
+
if (!(include.alias in row)) continue;
|
|
116
|
+
fold(out, folded, "_count", include.count, countOf(value));
|
|
89
117
|
continue;
|
|
90
118
|
}
|
|
91
119
|
if (include.aggregate !== void 0) {
|
|
92
|
-
if (!(include.alias in
|
|
93
|
-
delete out[include.alias];
|
|
120
|
+
if (!(include.alias in row)) continue;
|
|
94
121
|
const inner = Array.isArray(value) ? value[0] : value;
|
|
95
122
|
const measures = {};
|
|
96
123
|
for (const measure of include.selection.aggregate?.measures ?? []) measures[measure.alias] = measureOf(measure, inner?.[measure.key]);
|
|
97
|
-
fold(out, `_${include.aggregate.fn}`, include.aggregate.name, measures);
|
|
124
|
+
fold(out, folded, `_${include.aggregate.fn}`, include.aggregate.name, measures);
|
|
98
125
|
continue;
|
|
99
126
|
}
|
|
100
127
|
if (Array.isArray(value)) out[include.alias] = value.map((item) => decodeRow(include.selection, item));
|
|
@@ -103,8 +130,8 @@ function decodeRow(selection, row) {
|
|
|
103
130
|
return out;
|
|
104
131
|
}
|
|
105
132
|
/** Applies column codecs to returned rows, including embedded relations. */
|
|
106
|
-
function decodeRows(selection, rows) {
|
|
107
|
-
if (!selection || !needsDecoding(selection)) return rows;
|
|
133
|
+
function decodeRows(selection, rows, checked = false) {
|
|
134
|
+
if (!selection || !checked && !needsDecoding(selection)) return rows;
|
|
108
135
|
return rows.map((row) => decodeRow(selection, row));
|
|
109
136
|
}
|
|
110
137
|
//#endregion
|
|
@@ -170,10 +197,22 @@ function writable(meta, mode) {
|
|
|
170
197
|
}
|
|
171
198
|
/** Escapes LIKE wildcards so user input matches literally. */
|
|
172
199
|
function escapeLike(value) {
|
|
173
|
-
return value.
|
|
200
|
+
return value.replaceAll(/[\\%_]/g, (char) => `\\${char}`);
|
|
201
|
+
}
|
|
202
|
+
const builders = /* @__PURE__ */ new WeakMap();
|
|
203
|
+
/** The shared builder for a schema; a builder holds no per-call state. */
|
|
204
|
+
function builderFor(meta) {
|
|
205
|
+
let builder = builders.get(meta);
|
|
206
|
+
if (!builder) {
|
|
207
|
+
builder = new IrBuilder(meta);
|
|
208
|
+
builders.set(meta, builder);
|
|
209
|
+
}
|
|
210
|
+
return builder;
|
|
174
211
|
}
|
|
175
212
|
var IrBuilder = class {
|
|
176
213
|
meta;
|
|
214
|
+
/** Every column of a table, the selection of reads without `select`. */
|
|
215
|
+
#allColumns = /* @__PURE__ */ new WeakMap();
|
|
177
216
|
constructor(meta) {
|
|
178
217
|
this.meta = meta;
|
|
179
218
|
}
|
|
@@ -319,7 +358,7 @@ var IrBuilder = class {
|
|
|
319
358
|
}
|
|
320
359
|
}
|
|
321
360
|
selection(table, select, include) {
|
|
322
|
-
const columns =
|
|
361
|
+
const columns = select?.map((alias) => this.selectColumn(table, alias)) ?? this.allColumns(table);
|
|
323
362
|
const includes = [];
|
|
324
363
|
if (include !== void 0) {
|
|
325
364
|
if (!isPlainObject(include)) invalidRequest(`"include" on "${table.key}" must be an object`, table.key);
|
|
@@ -411,13 +450,7 @@ var IrBuilder = class {
|
|
|
411
450
|
alias,
|
|
412
451
|
column
|
|
413
452
|
};
|
|
414
|
-
return
|
|
415
|
-
fn,
|
|
416
|
-
key,
|
|
417
|
-
alias,
|
|
418
|
-
column,
|
|
419
|
-
codec
|
|
420
|
-
} : {
|
|
453
|
+
return {
|
|
421
454
|
fn,
|
|
422
455
|
key,
|
|
423
456
|
alias,
|
|
@@ -426,6 +459,14 @@ var IrBuilder = class {
|
|
|
426
459
|
codec
|
|
427
460
|
};
|
|
428
461
|
}
|
|
462
|
+
allColumns(table) {
|
|
463
|
+
let columns = this.#allColumns.get(table);
|
|
464
|
+
if (!columns) {
|
|
465
|
+
columns = Object.keys(table.columns).map((alias) => this.selectColumn(table, alias));
|
|
466
|
+
this.#allColumns.set(table, columns);
|
|
467
|
+
}
|
|
468
|
+
return columns;
|
|
469
|
+
}
|
|
429
470
|
/** A selected column, with the cast and codec its metadata asks for. */
|
|
430
471
|
selectColumn(table, alias) {
|
|
431
472
|
const column = this.column(table, alias);
|
|
@@ -434,11 +475,7 @@ var IrBuilder = class {
|
|
|
434
475
|
alias,
|
|
435
476
|
column
|
|
436
477
|
};
|
|
437
|
-
return
|
|
438
|
-
alias,
|
|
439
|
-
column,
|
|
440
|
-
codec
|
|
441
|
-
} : {
|
|
478
|
+
return {
|
|
442
479
|
alias,
|
|
443
480
|
column,
|
|
444
481
|
cast: "text",
|
|
@@ -537,7 +574,7 @@ var IrBuilder = class {
|
|
|
537
574
|
uniqueKey(table, input) {
|
|
538
575
|
if (!isPlainObject(input)) invalidRequest(`"where" on "${table.key}" must be an object`, table.key);
|
|
539
576
|
const given = Object.keys(input).filter((key) => input[key] !== void 0);
|
|
540
|
-
const keys =
|
|
577
|
+
const { keys } = lookupOf(table);
|
|
541
578
|
const match = keys.find((key) => key.length > 0 && key.length === given.length && key.every((column) => given.includes(column)));
|
|
542
579
|
if (!match) {
|
|
543
580
|
const names = keys.filter((key) => key.length > 0).map((key) => `{ ${key.join(", ")} }`).join(", ");
|
|
@@ -662,4 +699,4 @@ function simplifyOrFalse(condition) {
|
|
|
662
699
|
};
|
|
663
700
|
}
|
|
664
701
|
//#endregion
|
|
665
|
-
export { invalidRequest as a, needsDecoding as c, escapeLike as i, defineSchema as l, simplifyOrFalse as n, decodeRows as o,
|
|
702
|
+
export { invalidRequest as a, needsDecoding as c, escapeLike as i, defineSchema as l, simplifyOrFalse as n, decodeRows as o, builderFor as r, encodeValue as s, simplify as t, tableMeta as u };
|