better-supabase 0.4.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 +2 -0
- package/dist/channel-FQW-CnGR.d.ts +70 -0
- package/dist/cli/bin.js +1 -1
- package/dist/cli/codemod-DqV7612m.js +388 -0
- package/dist/cli/{config-D9R0o1LH.js → config-CPVpXP5I.js} +78 -8
- package/dist/cli/{config-SSKSTUl2.js → config-dtoekM0v.js} +1 -1
- package/dist/cli/{read-sets-CMa29t9a.js → diff-SjkO5rNr.js} +1 -220
- package/dist/cli/{dist-CFgGknmZ.js → dist-DBPdlPYK.js} +4 -4
- package/dist/cli/{dist-B1MvLv-M.js → dist-DreZ24Sz.js} +1 -1
- package/dist/cli/{dist-Du7VnEUG.js → dist-xn4wlboc.js} +112 -1
- package/dist/cli/{doctor-BOym3mbL.js → doctor-L7Z8mYTx.js} +531 -50
- package/dist/cli/{env-BZ0uy8XK.js → env-DmKv_G4A.js} +1 -1
- package/dist/cli/gen-BJc9vdyu.js +2 -0
- package/dist/cli/{gen-Ccn_p90L.js → gen-C2osRcr5.js} +283 -87
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/cli/{init-ClnxRYBF.js → init-Saf5-R9T.js} +2 -2
- package/dist/cli/{introspect-DxqfkVIv.js → introspect--H7oGmcd.js} +2 -2
- package/dist/cli/{openapi-8WHjxiTJ.js → openapi-Cp5Fyta-.js} +1 -1
- package/dist/cli/read-sets-BfMQcKy8.js +289 -0
- package/dist/cli/{run-CP20LKk_.js → run-BKR2W_79.js} +16 -12
- package/dist/cli/{seed-5J6eu_Xg.js → seed-CUlqWh-8.js} +1 -1
- package/dist/cli/sql-DzPbfngx.js +348 -0
- package/dist/cli/{version-5mW_8sY1.js → version-BDJuO0UR.js} +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +3 -10
- package/dist/clone-BfgmLU90.js +21 -0
- package/dist/{compiler-DB3aSFOA.d.ts → compiler-BXH_aZ7N.d.ts} +2 -2
- package/dist/config/index.d.ts +4 -4
- package/dist/config/index.js +4 -4
- package/dist/{config-CbvFmGD8.js → config-DreERlKo.js} +1 -1
- package/dist/{config-C1CYcm6o.d.ts → config-T_ejwyd3.d.ts} +176 -11
- package/dist/{define-CRS2MRV3.d.ts → define-Bp_BZa5h.d.ts} +11 -7
- package/dist/{define-Bh0AqTik.js → define-cNKzqwL_.js} +202 -16
- package/dist/edge/index.d.ts +16 -5
- package/dist/edge/index.js +10 -7
- package/dist/{entitlements-Dm-FHpNH.d.ts → entitlements-DUxU4oHe.d.ts} +1 -1
- package/dist/env/index.d.ts +2 -2
- package/dist/env/index.js +34 -1
- package/dist/{errors-L0xK41y_.js → errors-DtwXa6b8.js} +1 -0
- package/dist/events/index.d.ts +3 -2
- package/dist/events/index.js +65 -12
- package/dist/events-aIO7vsIk.d.ts +230 -0
- package/dist/{result-CqEsbgYs.d.ts → executor-BunPOO-k.d.ts} +200 -1
- package/dist/{executor-CZ7ImRiD.d.ts → executor-Cghdstwu.d.ts} +1 -2
- package/dist/{executor-CVt6dD0B.js → executor-XycESQPH.js} +3 -3
- package/dist/hono/index.d.ts +17 -6
- package/dist/hono/index.js +40 -5
- package/dist/impersonation-VfaGc4Q_.js +41 -0
- package/dist/{index-BBdvo-5d.d.ts → index-BGdgBPdf.d.ts} +49 -6
- package/dist/{index-BhHEC04r.d.ts → index-C7f8cOBM.d.ts} +2 -2
- package/dist/{index-Dy6kuF0P.d.ts → index-CLg87OBW.d.ts} +6 -1
- package/dist/{index-D5IfUIDh.d.ts → index-DOESKG27.d.ts} +33 -8
- package/dist/{index-DFmOpBGC.d.ts → index-DgILJRXj.d.ts} +35 -9
- package/dist/{index-RlLXd8dL.d.ts → index-DmXSxbLi.d.ts} +4 -4
- package/dist/{index-Cf-D2jk1.d.ts → index-Dxn2a5cw.d.ts} +2 -2
- package/dist/{index-528Ugmyp.d.ts → index-SaTsEfGP.d.ts} +76 -8
- package/dist/{index-BAy4tsAP.d.ts → index-fag8VJZ2.d.ts} +3 -4
- package/dist/index.d.ts +30 -13
- package/dist/index.js +10 -9
- package/dist/jobs/index.d.ts +147 -101
- package/dist/jobs/index.js +744 -237
- package/dist/{json-schema-DP6V7cbr.js → json-schema-m1fiwKgN.js} +22 -1
- 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-BpxDfnbg.js → kits-CGLLrNPd.js} +37 -9
- package/dist/list/index.d.ts +1 -1
- package/dist/{live-BHakSWWo.d.ts → live-D9W2M5aO.d.ts} +6 -5
- package/dist/mcp/index.d.ts +25 -8
- package/dist/mcp/index.js +23 -14
- package/dist/{mfa-C7MNQ1Ob.d.ts → mfa-CusDgPaD.d.ts} +5 -1
- package/dist/next/index.d.ts +31 -10
- package/dist/next/index.js +136 -27
- 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 +2 -2
- package/dist/orgs/index.d.ts +132 -0
- package/dist/orgs/index.js +245 -0
- package/dist/orpc/index.d.ts +28 -8
- package/dist/orpc/index.js +16 -3
- package/dist/otel/index.d.ts +21 -2
- package/dist/otel/index.js +50 -9
- 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-bNhvJwRh.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 +15 -10
- 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 +2 -2
- package/dist/plugins/tenant/index.js +38 -20
- 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-DFwEQwmN.d.ts → pool-C9voM4Kw.d.ts} +17 -6
- package/dist/postgres/index.d.ts +5 -5
- package/dist/postgres/index.js +20 -11
- package/dist/{postgrest-Bc-0Xw62.d.ts → postgrest-CruYKAvV.d.ts} +1 -1
- package/dist/{problem-BihjPR0t.js → problem-BW1KhzSG.js} +2 -1
- package/dist/{problem-U8UEKccv.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-BMMSWbI7.js → query-CCbo44lG.js} +2 -2
- 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 +14 -3
- package/dist/react/server.js +10 -2
- package/dist/react/session.d.ts +7 -1
- package/dist/react/session.js +9 -1
- package/dist/{react-CQHMaESR.js → react-C_s7kiNz.js} +103 -11
- package/dist/{read-set-FWK8qQ58.js → read-set-DQFt1N_Y.js} +22 -1
- package/dist/realtime/index.d.ts +3 -3
- package/dist/realtime/index.js +5 -4
- package/dist/{refresh-BwYkyNOQ.d.ts → refresh-BTrQ_ZTp.d.ts} +1 -1
- package/dist/{resolve-BAqQcwMW.d.ts → resolve-C15TJq77.d.ts} +11 -5
- package/dist/{resource-My_y-Syh.js → resource-CRxxwkQq.js} +22 -7
- package/dist/{resource-BJcaIfxi.d.ts → resource-D8iqWMr-.d.ts} +5 -5
- package/dist/respond-D2OQl62-.d.ts +371 -0
- package/dist/{result-Bj6yt33D.js → result-BKiliPY7.js} +1 -1
- package/dist/server/index.d.ts +14 -12
- package/dist/server/index.js +11 -17
- package/dist/{server-BA75B0mT.js → server-Csx2sRjg.js} +251 -34
- package/dist/{shared-DnoCdMDr.js → shared-D1dRUrAg.js} +16 -2
- package/dist/signers-Cc6r98SW.d.ts +162 -0
- package/dist/{simplify-Cqvfr9dj.js → simplify-_0oUKqCd.js} +4 -115
- package/dist/sql/index.d.ts +247 -10
- package/dist/sql/index.js +8590 -779
- package/dist/{sql-B34HU2DI.js → sql-Coh6n4cC.js} +9 -2
- package/dist/ssr/index.d.ts +4 -4
- package/dist/ssr/index.js +1 -2
- package/dist/{standard-BRyBGTtp.js → standard-D7r6dMUu.js} +6 -3
- package/dist/{standard-BsaCYQJc.d.ts → standard-J4YgMOLm.d.ts} +1 -1
- package/dist/{stats-C_YxA2r1.js → stats-Bqob3WqT.js} +4 -4
- package/dist/storage/index.d.ts +4 -4
- package/dist/storage/index.js +155 -26
- 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/{permdock-sql-C4KFzLc9.js → template-TxrGI5jR.js} +2 -31
- package/dist/{temporal-BwshQk0W.js → temporal-CVlIV2DZ.js} +17 -4
- package/dist/{temporal-required-CBNHT6ni.js → temporal-required-CAt4Dc9Z.js} +2 -2
- package/dist/testing/index.d.ts +100 -10
- package/dist/testing/index.js +336 -8
- package/dist/{types-DONv9SHN.d.ts → types-Dnf_wRDz.d.ts} +26 -3
- package/dist/user-change-CHFEUro1.js +49 -0
- package/dist/{webhooks-Bh_Jf_-l.js → verify-Ce49ETPz.js} +5 -5
- package/dist/{version-Bmf7_FzM.js → version-DM_Roffb.js} +1 -1
- package/dist/{view-B64o81wp.d.ts → view-BEf0diC5.d.ts} +8 -3
- package/dist/{mfa-byfjruR9.js → view-Bq64ki8-.js} +95 -38
- package/dist/webhooks/index.d.ts +135 -4
- package/dist/webhooks/index.js +588 -2
- package/dist/wire-D2dT86vi.js +35 -0
- package/package.json +16 -8
- package/schemas/config-v1.json +131 -1
- package/schemas/doctor-report-v1.json +10 -0
- package/skills/better-supabase/SKILL.md +9 -6
- package/skills/better-supabase/references/plugins.md +6 -3
- package/skills/better-supabase/references/troubleshooting.md +1 -0
- package/skills/better-supabase-api/SKILL.md +9 -2
- package/skills/better-supabase-api/references/adapters.md +11 -8
- package/skills/better-supabase-auth/SKILL.md +3 -0
- package/skills/better-supabase-auth/references/permdock.md +56 -11
- package/dist/cli/gen-D5cLCULx.js +0 -2
- package/dist/cli/sql-D4VbqmXi.js +0 -199
- package/dist/events-B21UOhvP.d.ts +0 -84
- package/dist/executor-B5IoUxLE.d.ts +0 -195
- package/dist/invalidate-CgxmRamI.js +0 -24
- package/dist/permdock-sql-DImJULY-.d.ts +0 -17
- package/dist/plugin-BqR6wKMB.js +0 -23
- package/dist/respond-DgIbdrt8.d.ts +0 -194
- package/dist/view-BrJI2LKp.js +0 -45
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { i as sqlString, r as sqlIdent } from "./template-TxrGI5jR.js";
|
|
2
|
+
//#region src/core/permdock-sql.ts
|
|
3
|
+
const SCOPE = /^[a-z][a-z0-9_]*$/;
|
|
4
|
+
/** PermDock's default `rls.schema`, a schema the Data API does not expose. */
|
|
5
|
+
const PERMDOCK_SCHEMA = "permdock";
|
|
6
|
+
/** PermDock splits a key with row conditions into `key#1`, `key#2`, ...: those need its own policies. */
|
|
7
|
+
const SPLIT_KEY = /#\d+$/;
|
|
8
|
+
function permdockKeyStatus(catalog, key) {
|
|
9
|
+
const entry = catalog.permissions.find((permission) => permission.key === key);
|
|
10
|
+
if (!entry) return "missing";
|
|
11
|
+
if (entry.rowConditions === true) return "row-conditions";
|
|
12
|
+
if (entry.rowConditions === false) return "scope-only";
|
|
13
|
+
return "no-flag";
|
|
14
|
+
}
|
|
15
|
+
const REGENERATE = "Regenerate permissions.catalog.json with a current `permdock catalog`, which writes rowConditions for every permission.";
|
|
16
|
+
/**
|
|
17
|
+
* The SQL condition for one PermDock permission key. `id` is the text
|
|
18
|
+
* expression holding the scope id; it is compared as text, so a malformed
|
|
19
|
+
* path never raises a cast error.
|
|
20
|
+
*
|
|
21
|
+
* The helpers check role and scope, not a permission's row conditions, so
|
|
22
|
+
* the condition is only correct for permissions whose grants have none
|
|
23
|
+
* beyond the scope. `#n` keys are refused. With a catalog, only keys it marks
|
|
24
|
+
* `rowConditions: false` are accepted: `true`, a missing flag and a key the
|
|
25
|
+
* catalog doesn't list are refused.
|
|
26
|
+
*/
|
|
27
|
+
function permdockCheck(where, target, key, id, catalog) {
|
|
28
|
+
if (key === "") throw new TypeError(`${where}: a PermDock permission key is empty`);
|
|
29
|
+
if (SPLIT_KEY.test(key)) throw new TypeError(`${where}: "${key}" is one part of a permission PermDock splits by row condition. Use PermDock's generated policies for it.`);
|
|
30
|
+
if (catalog) {
|
|
31
|
+
const status = permdockKeyStatus(catalog, key);
|
|
32
|
+
switch (status) {
|
|
33
|
+
case "scope-only": break;
|
|
34
|
+
case "row-conditions": throw new TypeError(`${where}: "${key}" has row conditions in PermDock's catalog (rowConditions: true), which the SQL helpers don't check. Use PermDock's generated policies for it.`);
|
|
35
|
+
case "no-flag": throw new TypeError(`${where}: "${key}" has no rowConditions flag in PermDock's catalog, so whether the SQL helpers check it fully is unknown. ${REGENERATE}`);
|
|
36
|
+
case "missing": throw new TypeError(`${where}: "${key}" is not in PermDock's catalog. ${REGENERATE}`);
|
|
37
|
+
default: return status;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const schema = sqlIdent(target.schema ?? "permdock");
|
|
41
|
+
if (target.scope === "global") return `(select ${schema}.permdock_has(${sqlString(key)}))`;
|
|
42
|
+
if (!SCOPE.test(target.scope)) throw new TypeError(`${where}: invalid PermDock scope "${target.scope}"`);
|
|
43
|
+
if (id === void 0) throw new TypeError(`${where}: scope "${target.scope}" needs a segment`);
|
|
44
|
+
return `${id} in (select t.id::text from ${schema}.${sqlIdent(`permitted_${target.scope}_ids`)}(${sqlString(key)}) as t(id))`;
|
|
45
|
+
}
|
|
46
|
+
/** The keys a bucket or topic PermDock policy names. */
|
|
47
|
+
function permdockKeys(policy) {
|
|
48
|
+
return Object.values(policy.permdock).filter((key) => typeof key === "string");
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { permdockKeys as i, permdockCheck as n, permdockKeyStatus as r, PERMDOCK_SCHEMA as t };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//#region src/core/plugin.ts
|
|
2
|
+
const PLUGIN_API_VERSION = 1;
|
|
3
|
+
const RANK = {
|
|
4
|
+
pre: 0,
|
|
5
|
+
normal: 1,
|
|
6
|
+
post: 2
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* `rules()` checks the query as the caller wrote it, so it runs before every
|
|
10
|
+
* other `pre` plugin (soft delete turns deletes into updates, tenant adds
|
|
11
|
+
* filters).
|
|
12
|
+
*/
|
|
13
|
+
function rankOf(plugin) {
|
|
14
|
+
return plugin.name === "rules" ? -1 : RANK[plugin.enforce ?? "normal"];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Plugins in hook order: `rules`, then `pre`, then unmarked in `use()` order,
|
|
18
|
+
* then `post`.
|
|
19
|
+
*/
|
|
20
|
+
function orderPlugins(plugins) {
|
|
21
|
+
return plugins.map((plugin, index) => ({
|
|
22
|
+
plugin,
|
|
23
|
+
index
|
|
24
|
+
})).sort((a, b) => rankOf(a.plugin) - rankOf(b.plugin) || a.index - b.index).map(({ plugin }) => plugin);
|
|
25
|
+
}
|
|
26
|
+
/** Identity helper that fixes `apiVersion` and infers the plugin types. */
|
|
27
|
+
function definePlugin(plugin) {
|
|
28
|
+
return {
|
|
29
|
+
...plugin,
|
|
30
|
+
apiVersion: 1
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Tenants that `tenant()` resolved from claims, per connection context. */
|
|
34
|
+
const resolvedTenants = /* @__PURE__ */ new WeakMap();
|
|
35
|
+
/** Records the tenant a plugin resolved for `context`, so mutation notices carry it. */
|
|
36
|
+
function recordTenant(context, tenant) {
|
|
37
|
+
resolvedTenants.set(context, tenant);
|
|
38
|
+
}
|
|
39
|
+
/** `context.tenant`, else the tenant a plugin resolved for this connection. */
|
|
40
|
+
function tenantOf(context) {
|
|
41
|
+
return context.tenant ?? resolvedTenants.get(context);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A symbol key, so JSON, claims and spread request data can't set it, while
|
|
45
|
+
* `$with` copies it to the derived context.
|
|
46
|
+
*/
|
|
47
|
+
const ALL_TENANTS = Symbol("better-supabase.allTenants");
|
|
48
|
+
/** `context`, marked so `tenant()` and tenant buckets skip their tenant scope. */
|
|
49
|
+
function allTenantsContext(context) {
|
|
50
|
+
return {
|
|
51
|
+
...context,
|
|
52
|
+
[ALL_TENANTS]: true
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function spansAllTenants(context) {
|
|
56
|
+
return Object.hasOwn(context, ALL_TENANTS);
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { recordTenant as a, orderPlugins as i, allTenantsContext as n, spansAllTenants as o, definePlugin as r, tenantOf as s, PLUGIN_API_VERSION as t };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { v as ErrorMapper } from "./result-CqEsbgYs.js";
|
|
2
|
+
import { F as TableMeta, j as SchemaMeta, r as AnyModels } from "./types-Dnf_wRDz.js";
|
|
3
|
+
import { H as MutationOp, S as ErrorMapper, U as Operation, r as Executor } from "./executor-BunPOO-k.js";
|
|
5
4
|
//#region src/core/plugin.d.ts
|
|
6
5
|
/** Who is making the request. */
|
|
7
6
|
interface Actor {
|
|
@@ -32,11 +31,24 @@ interface HookArgs {
|
|
|
32
31
|
readonly now: () => Temporal.Instant;
|
|
33
32
|
}
|
|
34
33
|
type MutationKind = "insert" | "upsert" | "update" | "delete";
|
|
34
|
+
/** What the caller asked for: `softDelete` is a `delete` that a plugin turned into an update. */
|
|
35
|
+
type MutationIntent = MutationKind | "softDelete";
|
|
35
36
|
interface MutationEvent {
|
|
36
37
|
readonly table: TableMeta;
|
|
38
|
+
/** The statement that ran. */
|
|
37
39
|
readonly kind: MutationKind;
|
|
38
|
-
/**
|
|
40
|
+
/** What the caller asked for; differs from `kind` when a plugin rewrote the mutation. */
|
|
41
|
+
readonly intent?: MutationIntent;
|
|
42
|
+
/** App-cased rows returned by the mutation. A copy: changing it never changes the result. */
|
|
39
43
|
readonly rows: readonly Readonly<Record<string, unknown>>[];
|
|
44
|
+
/**
|
|
45
|
+
* App-cased primary keys of the changed rows, when they are known: from
|
|
46
|
+
* the returned rows, or from a `where` on the primary key when nothing is
|
|
47
|
+
* returned (soft deletes, `returning: false`).
|
|
48
|
+
*/
|
|
49
|
+
readonly keys?: readonly Readonly<Record<string, unknown>>[];
|
|
50
|
+
/** The tenant of the write: `context.tenant`, or the one `tenant()` resolved. */
|
|
51
|
+
readonly tenant?: string;
|
|
40
52
|
readonly context: RequestContext;
|
|
41
53
|
}
|
|
42
54
|
/** Runtime handle passed to `Plugin.repository`. */
|
|
@@ -116,4 +128,4 @@ declare function definePlugin<const Name extends string, Ext extends RepositoryE
|
|
|
116
128
|
readonly apiVersion?: 1;
|
|
117
129
|
}): Plugin<Name, Ext>;
|
|
118
130
|
//#endregion
|
|
119
|
-
export {
|
|
131
|
+
export { WithExtension as _, ExtensionOf as a, MutationEvent as c, NoExtension as d, PLUGIN_API_VERSION as f, RequestContext as g, RepositoryExtension as h, CallOptions as i, MutationIntent as l, RepositoryApi as m, AnyPlugin as n, HasFlag as o, Plugin as p, ApplyExtension as r, HookArgs as s, Actor as t, MutationKind as u, definePlugin as v };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { g as RequestContext, p as Plugin } from "../../plugin-o144f322.js";
|
|
2
2
|
//#region src/plugins/actor/index.d.ts
|
|
3
3
|
export interface ActorOptions {
|
|
4
4
|
/** Custom actor id resolution. Defaults to `context.actor.id` for users and services. */
|
|
@@ -7,7 +7,10 @@ export interface ActorOptions {
|
|
|
7
7
|
/**
|
|
8
8
|
* Stamps the columns generated as `Flags.actor`: `createdBy` on insert and
|
|
9
9
|
* `updatedBy` on insert and update. Soft deletes are updates, so they record
|
|
10
|
-
* who deleted the row.
|
|
10
|
+
* who deleted the row. `impersonatedBy` gets `context.actor.impersonator` on
|
|
11
|
+
* an impersonated insert or update and is left alone otherwise, so a user's
|
|
12
|
+
* own update keeps the stamp, like the SQL kit's `track_actor`. Without an
|
|
13
|
+
* actor (anonymous requests) nothing is set.
|
|
11
14
|
*/
|
|
12
15
|
export declare function actor(options?: ActorOptions): Plugin<"actor">;
|
|
13
16
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { r as definePlugin } from "../../plugin-DwARMuQp.js";
|
|
2
|
+
import { a as insertsOnly, i as guardManaged, t as dbName, u as withDefault } from "../../shared-D1dRUrAg.js";
|
|
3
3
|
//#region src/plugins/actor/index.ts
|
|
4
4
|
function defaultActor(context) {
|
|
5
5
|
const actor = context.actor;
|
|
@@ -8,30 +8,44 @@ function defaultActor(context) {
|
|
|
8
8
|
/**
|
|
9
9
|
* Stamps the columns generated as `Flags.actor`: `createdBy` on insert and
|
|
10
10
|
* `updatedBy` on insert and update. Soft deletes are updates, so they record
|
|
11
|
-
* who deleted the row.
|
|
11
|
+
* who deleted the row. `impersonatedBy` gets `context.actor.impersonator` on
|
|
12
|
+
* an impersonated insert or update and is left alone otherwise, so a user's
|
|
13
|
+
* own update keeps the stamp, like the SQL kit's `track_actor`. Without an
|
|
14
|
+
* actor (anonymous requests) nothing is set.
|
|
12
15
|
*/
|
|
13
16
|
function actor(options = {}) {
|
|
14
17
|
const resolve = options.resolve ?? defaultActor;
|
|
15
18
|
return definePlugin({
|
|
16
19
|
name: "actor",
|
|
17
|
-
beforeMutation(op, { table, context }) {
|
|
20
|
+
beforeMutation(op, { table, context, options }) {
|
|
18
21
|
const flags = table.flags.actor;
|
|
19
22
|
if (!flags) return op;
|
|
20
|
-
const id = resolve(context);
|
|
21
|
-
if (id === void 0) return op;
|
|
22
23
|
const created = dbName(table, flags.createdBy);
|
|
23
24
|
const updated = dbName(table, flags.updatedBy);
|
|
25
|
+
const impersonated = dbName(table, flags.impersonatedBy);
|
|
26
|
+
guardManaged(op, [
|
|
27
|
+
created,
|
|
28
|
+
updated,
|
|
29
|
+
impersonated
|
|
30
|
+
], "actor", options);
|
|
31
|
+
const id = resolve(context);
|
|
32
|
+
if (id === void 0) return op;
|
|
33
|
+
const impersonator = context.actor?.impersonator;
|
|
34
|
+
const stamp = (row) => {
|
|
35
|
+
const stamped = withDefault(row, updated, id);
|
|
36
|
+
return impersonator === void 0 ? stamped : withDefault(stamped, impersonated, impersonator);
|
|
37
|
+
};
|
|
24
38
|
switch (op.kind) {
|
|
25
39
|
case "insert": {
|
|
26
40
|
const stampCreated = insertsOnly(op);
|
|
27
41
|
return {
|
|
28
42
|
...op,
|
|
29
|
-
rows: op.rows.map((row) =>
|
|
43
|
+
rows: op.rows.map((row) => stamp(stampCreated ? withDefault(row, created, id) : row))
|
|
30
44
|
};
|
|
31
45
|
}
|
|
32
46
|
case "update": return {
|
|
33
47
|
...op,
|
|
34
|
-
set:
|
|
48
|
+
set: stamp(op.set)
|
|
35
49
|
};
|
|
36
50
|
case "delete": return op;
|
|
37
51
|
default: return op;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { U as Operation } from "../../executor-BunPOO-k.js";
|
|
2
|
+
import { h as RepositoryExtension, p as Plugin } from "../../plugin-o144f322.js";
|
|
3
3
|
//#region src/plugins/rules/index.d.ts
|
|
4
4
|
export type RuleLevel = "off" | "warn" | "error";
|
|
5
5
|
/** A level, or a level with the rule's option: `['error', 500]`. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as dbError, t as DbException } from "../../errors-
|
|
1
|
+
import { n as dbError, t as DbException } from "../../errors-DtwXa6b8.js";
|
|
2
2
|
import { t as lookupOf } from "../../lookup-BaP5bI27.js";
|
|
3
|
-
import {
|
|
4
|
-
import { n as claimAt, r as claimsOf } from "../../claims-BAf6c7is.js";
|
|
3
|
+
import { r as definePlugin } from "../../plugin-DwARMuQp.js";
|
|
4
|
+
import { i as tenantClaimPaths, n as claimAt, r as claimsOf } from "../../claims-BAf6c7is.js";
|
|
5
5
|
//#region src/plugins/rules/index.ts
|
|
6
6
|
/** Catches data-exposure and correctness mistakes; everything else off. */
|
|
7
7
|
function safe() {
|
|
@@ -121,8 +121,12 @@ function checks(rules) {
|
|
|
121
121
|
const maxLimit = optionOf(rules.maxLimit, 1e3);
|
|
122
122
|
const maxDepth = optionOf(rules.maxIncludeDepth, 3);
|
|
123
123
|
return {
|
|
124
|
-
noUnboundedFindMany: (op) => op.kind === "select" && op.single === void 0 && !op.head && op.limit === void 0 ? "findMany without limit reads every visible row" : void 0,
|
|
125
|
-
maxLimit: (op) =>
|
|
124
|
+
noUnboundedFindMany: (op) => op.kind === "select" && op.single === void 0 && !op.head && op.limit === void 0 && op.selection.aggregate === void 0 ? "findMany without limit reads every visible row" : void 0,
|
|
125
|
+
maxLimit: (op) => {
|
|
126
|
+
if (op.kind !== "select" || op.limit === void 0) return;
|
|
127
|
+
const limit = op.lookAhead === true ? op.limit - 1 : op.limit;
|
|
128
|
+
return limit > maxLimit ? `limit ${limit} is above the maximum of ${maxLimit}` : void 0;
|
|
129
|
+
},
|
|
126
130
|
requireOrderByForCursor: (op) => op.kind === "select" && !op.head && op.orderBy.length === 0 && (op.offset !== void 0 || op.limit !== void 0 && op.limit > 1) ? "paging without orderBy returns rows in no stable order" : void 0,
|
|
127
131
|
maxIncludeDepth: (op) => {
|
|
128
132
|
const max = maxDepth;
|
|
@@ -132,14 +136,15 @@ function checks(rules) {
|
|
|
132
136
|
},
|
|
133
137
|
requireTenantContext: (op, { context, schema }) => {
|
|
134
138
|
if (!op.table.flags.tenant || context.actor?.kind === "service") return;
|
|
135
|
-
|
|
136
|
-
|
|
139
|
+
if (typeof context.tenant === "string") return;
|
|
140
|
+
const claim = optionOf(rules.requireTenantContext, void 0);
|
|
141
|
+
const paths = claim === void 0 ? tenantClaimPaths(claimsOf(schema).tenant) : [claim];
|
|
142
|
+
return paths.some((path) => claimAt(context.claims, path) !== void 0) ? void 0 : `"${op.table.key}" is tenant-scoped but the request has no tenant (context.tenant or claim ${paths.map((path) => `"${path}"`).join(" or ")})`;
|
|
137
143
|
},
|
|
138
144
|
noAdminInBrowser: (_op, { context }) => context.actor?.kind === "service" && isBrowser() ? "a service-role connection is running in a browser" : void 0,
|
|
139
145
|
noSensitiveSelect: (op, { options }) => {
|
|
140
|
-
if (options["sensitive"] === true) return;
|
|
141
|
-
const
|
|
142
|
-
const columns = selection ? sensitiveColumns(selection, op.table) : [];
|
|
146
|
+
if (options["sensitive"] === true || op.kind !== "select") return;
|
|
147
|
+
const columns = sensitiveColumns(op.selection, op.table);
|
|
143
148
|
return columns.length > 0 ? `reads sensitive column(s) ${columns.join(", ")}; pass { sensitive: true } to allow` : void 0;
|
|
144
149
|
},
|
|
145
150
|
noDeleteManyWithoutWhere: (op) => op.kind === "delete" && op.where === void 0 ? "delete without where removes every visible row" : void 0,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { w as PrimaryKeyValue } from "../../types-Dnf_wRDz.js";
|
|
2
|
+
import { a as AsyncResult } from "../../executor-BunPOO-k.js";
|
|
3
|
+
import { h as RepositoryExtension, o as HasFlag, p as Plugin } from "../../plugin-o144f322.js";
|
|
4
4
|
//#region src/plugins/soft-delete/index.d.ts
|
|
5
5
|
export interface SoftDeleteFindArgs {
|
|
6
6
|
/** Include soft-deleted rows of the queried table. */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as and } from "../../types-6cYK9pbJ.js";
|
|
2
|
-
import { i as ok, t as AsyncResult } from "../../result-
|
|
3
|
-
import {
|
|
2
|
+
import { i as ok, t as AsyncResult } from "../../result-BKiliPY7.js";
|
|
3
|
+
import { r as definePlugin } from "../../plugin-DwARMuQp.js";
|
|
4
4
|
import { n as scopeOperation } from "../../scope-CDHcS7dE.js";
|
|
5
|
-
import { a as
|
|
5
|
+
import { a as insertsOnly, i as guardManaged, o as isNotNull, s as isNull, t as dbName, u as withDefault } from "../../shared-D1dRUrAg.js";
|
|
6
6
|
//#region src/plugins/soft-delete/index.ts
|
|
7
7
|
function deletedColumn(table) {
|
|
8
8
|
return dbName(table, table.flags.softDelete);
|
|
@@ -39,9 +39,17 @@ function softDelete() {
|
|
|
39
39
|
};
|
|
40
40
|
},
|
|
41
41
|
beforeMutation(op, { table, options, now }) {
|
|
42
|
-
if (op.kind !== "delete" || options["hard"] === true) return op;
|
|
43
42
|
const column = deletedColumn(table);
|
|
44
43
|
if (!column) return op;
|
|
44
|
+
guardManaged(op, [column], "softDelete", options);
|
|
45
|
+
if (op.kind === "insert") {
|
|
46
|
+
if (insertsOnly(op)) return op;
|
|
47
|
+
return {
|
|
48
|
+
...op,
|
|
49
|
+
rows: op.rows.map((row) => withDefault(row, column, null))
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (op.kind !== "delete" || options["hard"] === true) return op;
|
|
45
53
|
return {
|
|
46
54
|
kind: "update",
|
|
47
55
|
table,
|
|
@@ -58,7 +66,8 @@ function softDelete() {
|
|
|
58
66
|
const result = await update(key, { [flag]: null }, {
|
|
59
67
|
...args,
|
|
60
68
|
withDeleted: true,
|
|
61
|
-
returning: false
|
|
69
|
+
returning: false,
|
|
70
|
+
override: true
|
|
62
71
|
});
|
|
63
72
|
return result.ok ? ok(void 0) : result;
|
|
64
73
|
}) };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { j as SchemaMeta } from "../../types-Dnf_wRDz.js";
|
|
2
|
+
import { g as RequestContext, h as RepositoryExtension, o as HasFlag, p as Plugin } from "../../plugin-o144f322.js";
|
|
3
3
|
//#region src/plugins/tenant/index.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Dotted paths to the string claims of `C` (up to three levels), e.g.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as dbError, t as DbException } from "../../errors-
|
|
2
|
-
import {
|
|
1
|
+
import { n as dbError, t as DbException } from "../../errors-DtwXa6b8.js";
|
|
2
|
+
import { a as recordTenant, o as spansAllTenants, r as definePlugin } from "../../plugin-DwARMuQp.js";
|
|
3
3
|
import { n as scopeOperation } from "../../scope-CDHcS7dE.js";
|
|
4
4
|
import { i as tenantClaimPaths, n as claimAt, r as claimsOf } from "../../claims-BAf6c7is.js";
|
|
5
|
-
import { n as equals, r as forbidden, t as dbName } from "../../shared-
|
|
5
|
+
import { a as insertsOnly, n as equals, r as forbidden, t as dbName } from "../../shared-D1dRUrAg.js";
|
|
6
6
|
//#region src/plugins/tenant/index.ts
|
|
7
7
|
/**
|
|
8
8
|
* The tenant for a request: `context.tenant`, then the configured claim.
|
|
@@ -18,6 +18,11 @@ function resolveTenant(context, options = {}, schema) {
|
|
|
18
18
|
if (value !== void 0) return value;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/** Tenant columns may be numeric; the resolved tenant is always a string. */
|
|
22
|
+
function sameTenant(value, id) {
|
|
23
|
+
if (value === id) return true;
|
|
24
|
+
return (typeof value === "number" || typeof value === "bigint") && String(value) === id;
|
|
25
|
+
}
|
|
21
26
|
function tenantColumn(table) {
|
|
22
27
|
return dbName(table, table.flags.tenant);
|
|
23
28
|
}
|
|
@@ -32,21 +37,32 @@ function tenant(options = {}) {
|
|
|
32
37
|
const onMissing = options.onMissing ?? "error";
|
|
33
38
|
/** A context is fixed for a connection, so its tenant is resolved once. */
|
|
34
39
|
const resolved = /* @__PURE__ */ new WeakMap();
|
|
35
|
-
const
|
|
40
|
+
const resolvedFor = (context, schema) => {
|
|
36
41
|
let id = resolved.get(context);
|
|
37
42
|
if (id === void 0 && !resolved.has(context)) {
|
|
38
43
|
id = resolveTenant(context, options, schema);
|
|
39
44
|
resolved.set(context, id);
|
|
45
|
+
if (id !== void 0) recordTenant(context, id);
|
|
40
46
|
}
|
|
41
|
-
|
|
47
|
+
return id;
|
|
48
|
+
};
|
|
49
|
+
const missing = (table) => {
|
|
50
|
+
throw new DbException(dbError("forbidden", `No tenant in the request context for "${table.key}"`));
|
|
51
|
+
};
|
|
52
|
+
const current = (table, context, schema) => {
|
|
53
|
+
const id = resolvedFor(context, schema);
|
|
54
|
+
if (id === void 0 && onMissing === "error" && tenantColumn(table)) missing(table);
|
|
42
55
|
return id;
|
|
43
56
|
};
|
|
44
57
|
return definePlugin({
|
|
45
58
|
name: "tenant",
|
|
46
59
|
transformQuery(op, { context, schema, options: call }) {
|
|
47
|
-
if (call["allTenants"] === true) return op;
|
|
48
|
-
const id =
|
|
49
|
-
if (id === void 0)
|
|
60
|
+
if (call["allTenants"] === true || spansAllTenants(context)) return op;
|
|
61
|
+
const id = resolvedFor(context, schema);
|
|
62
|
+
if (id === void 0) {
|
|
63
|
+
if (onMissing === "error") scopeOperation(op, (table) => tenantColumn(table) ? missing(table) : void 0);
|
|
64
|
+
return op;
|
|
65
|
+
}
|
|
50
66
|
return scopeOperation(op, (table) => {
|
|
51
67
|
const column = tenantColumn(table);
|
|
52
68
|
return column ? equals(column, id) : void 0;
|
|
@@ -54,22 +70,24 @@ function tenant(options = {}) {
|
|
|
54
70
|
},
|
|
55
71
|
beforeMutation(op, { table, context, schema, options: call }) {
|
|
56
72
|
const column = tenantColumn(table);
|
|
57
|
-
if (!column || call["allTenants"] === true) return op;
|
|
73
|
+
if (!column || call["allTenants"] === true || spansAllTenants(context)) return op;
|
|
58
74
|
const id = current(table, context, schema);
|
|
59
75
|
if (id === void 0) return op;
|
|
60
76
|
switch (op.kind) {
|
|
61
|
-
case "insert":
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
case "insert":
|
|
78
|
+
if (!insertsOnly(op) && !op.onConflict?.columns.includes(column)) forbidden(`An upsert on ${table.key} that updates on conflict needs the tenant column "${column}" in its conflict target`);
|
|
79
|
+
return {
|
|
80
|
+
...op,
|
|
81
|
+
rows: op.rows.map((row) => {
|
|
82
|
+
if (column in row && !sameTenant(row[column], id)) forbidden(`Cannot write a ${table.key} row for another tenant`);
|
|
83
|
+
return {
|
|
84
|
+
...row,
|
|
85
|
+
[column]: id
|
|
86
|
+
};
|
|
87
|
+
})
|
|
88
|
+
};
|
|
71
89
|
case "update":
|
|
72
|
-
if (column in op.set && op.set[column]
|
|
90
|
+
if (column in op.set && !sameTenant(op.set[column], id)) forbidden(`Cannot move a ${table.key} row to another tenant`);
|
|
73
91
|
return op;
|
|
74
92
|
case "delete": return op;
|
|
75
93
|
default: return op;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { r as definePlugin } from "../../plugin-DwARMuQp.js";
|
|
2
|
+
import { a as insertsOnly, i as guardManaged, t as dbName, u as withDefault } from "../../shared-D1dRUrAg.js";
|
|
3
3
|
//#region src/plugins/timestamps/index.ts
|
|
4
4
|
/**
|
|
5
5
|
* Stamps the columns generated as `Flags.timestamps`: `createdAt` on insert,
|
|
@@ -9,11 +9,12 @@ import { i as insertsOnly, l as withDefault, t as dbName } from "../../shared-Dn
|
|
|
9
9
|
function timestamps() {
|
|
10
10
|
return definePlugin({
|
|
11
11
|
name: "timestamps",
|
|
12
|
-
beforeMutation(op, { table, now }) {
|
|
12
|
+
beforeMutation(op, { table, now, options }) {
|
|
13
13
|
const flags = table.flags.timestamps;
|
|
14
14
|
if (!flags) return op;
|
|
15
15
|
const created = dbName(table, flags.createdAt);
|
|
16
16
|
const updated = dbName(table, flags.updatedAt);
|
|
17
|
+
guardManaged(op, [created, updated], "timestamps", options);
|
|
17
18
|
const stamp = now().toString();
|
|
18
19
|
switch (op.kind) {
|
|
19
20
|
case "insert": {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as StandardSchemaV1 } from "../../standard-
|
|
1
|
+
import { p as Plugin } from "../../plugin-o144f322.js";
|
|
2
|
+
import { t as StandardSchemaV1 } from "../../standard-J4YgMOLm.js";
|
|
3
3
|
//#region src/plugins/validation/index.d.ts
|
|
4
4
|
export interface TableValidators {
|
|
5
5
|
/** Validates inserts and upserts, with app-cased keys. */
|
|
@@ -1,13 +1,33 @@
|
|
|
1
|
-
import { n as dbError, t as DbException } from "../../errors-
|
|
2
|
-
import { n as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { n as dbError, t as DbException } from "../../errors-DtwXa6b8.js";
|
|
2
|
+
import { n as decodeValue, r as encodeValue } from "../../wire-D2dT86vi.js";
|
|
3
|
+
import { r as definePlugin } from "../../plugin-DwARMuQp.js";
|
|
4
|
+
import { t as validate } from "../../standard-D7r6dMUu.js";
|
|
5
|
+
import { c as toApp, l as toDb } from "../../shared-D1dRUrAg.js";
|
|
5
6
|
//#region src/plugins/validation/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* Rows reach plugins in wire form (ISO text, decimal text), while generated
|
|
9
|
+
* validators expect the column codecs' app values (Temporal, `bigint`).
|
|
10
|
+
*/
|
|
11
|
+
function decoded(table, row) {
|
|
12
|
+
const app = toApp(table, row);
|
|
13
|
+
for (const [name, value] of Object.entries(app)) {
|
|
14
|
+
const codec = table.columns[name]?.codec;
|
|
15
|
+
if (codec === void 0 || typeof value !== "string") continue;
|
|
16
|
+
try {
|
|
17
|
+
app[name] = decodeValue(codec, value);
|
|
18
|
+
} catch {}
|
|
19
|
+
}
|
|
20
|
+
return app;
|
|
21
|
+
}
|
|
22
|
+
function encoded(row) {
|
|
23
|
+
for (const [name, value] of Object.entries(row)) row[name] = encodeValue(value);
|
|
24
|
+
return row;
|
|
25
|
+
}
|
|
6
26
|
async function check(schema, table, row, label, index) {
|
|
7
|
-
const result = await validate(schema,
|
|
27
|
+
const result = await validate(schema, decoded(table, row), label);
|
|
8
28
|
if (result.ok) {
|
|
9
29
|
const output = result.data;
|
|
10
|
-
return typeof output === "object" && output !== null ? toDb(table, output) : { ...row };
|
|
30
|
+
return typeof output === "object" && output !== null ? encoded(toDb(table, output)) : { ...row };
|
|
11
31
|
}
|
|
12
32
|
const error = result.error;
|
|
13
33
|
if (index === void 0 || error.kind !== "validation") throw new DbException(error);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as Executor } from "./executor-
|
|
2
|
-
import { t as SqlClient } from "./executor-
|
|
1
|
+
import { r as Executor } from "./executor-BunPOO-k.js";
|
|
2
|
+
import { t as SqlClient } from "./executor-Cghdstwu.js";
|
|
3
3
|
//#region src/postgres/pool.d.ts
|
|
4
4
|
/** The part of a `pg` pool client `createPostgres` uses. */
|
|
5
5
|
interface PgPoolClient {
|
|
@@ -48,11 +48,22 @@ interface SqlClaims {
|
|
|
48
48
|
readonly role?: string;
|
|
49
49
|
readonly [claim: string]: unknown;
|
|
50
50
|
}
|
|
51
|
+
/** What every transaction of a user session sets besides the claims and role. */
|
|
52
|
+
interface SessionOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Transaction-local settings, e.g. `{ 'better_supabase.tenant': id }`.
|
|
55
|
+
* Names need a dot (custom settings); `role` and `request.jwt.claims` are
|
|
56
|
+
* set from the claims.
|
|
57
|
+
*/
|
|
58
|
+
readonly settings?: Readonly<Record<string, string>>;
|
|
59
|
+
/** Runs every transaction with `begin read only`: writes fail with 25006. */
|
|
60
|
+
readonly readOnly?: boolean;
|
|
61
|
+
}
|
|
51
62
|
interface BetterPostgres {
|
|
52
63
|
/** Connects as the connection-string role. On Supabase that bypasses RLS. */
|
|
53
64
|
readonly admin: SqlClient;
|
|
54
65
|
/** Runs every query as the given user, with RLS, like PostgREST does. */
|
|
55
|
-
asUser(claims: SqlClaims): SqlClient;
|
|
66
|
+
asUser(claims: SqlClaims, options?: SessionOptions): SqlClient;
|
|
56
67
|
/** Runs every query as `anon`. */
|
|
57
68
|
readonly anon: SqlClient;
|
|
58
69
|
/**
|
|
@@ -60,11 +71,11 @@ interface BetterPostgres {
|
|
|
60
71
|
* `createServer` calls it for `ctx.sql`, so only apps that pass `postgres`
|
|
61
72
|
* bundle the SQL compiler.
|
|
62
73
|
*/
|
|
63
|
-
executorFor(claims: SqlClaims): Executor;
|
|
74
|
+
executorFor(claims: SqlClaims, options?: SessionOptions): Executor;
|
|
64
75
|
/** Runs `fn` in one transaction. Pass claims to run it as a user. */
|
|
65
76
|
transaction<T>(fn: (client: SqlClient) => Promise<T>, options?: {
|
|
66
77
|
readonly claims?: SqlClaims;
|
|
67
|
-
}): Promise<T>;
|
|
78
|
+
} & SessionOptions): Promise<T>;
|
|
68
79
|
end(): Promise<void>;
|
|
69
80
|
[Symbol.asyncDispose](): Promise<void>;
|
|
70
81
|
}
|
|
@@ -75,4 +86,4 @@ interface BetterPostgres {
|
|
|
75
86
|
*/
|
|
76
87
|
declare function createPostgres(options?: PostgresOptions): BetterPostgres;
|
|
77
88
|
//#endregion
|
|
78
|
-
export { PostgresTimeouts as a, PostgresOptions as i, PgPool as n,
|
|
89
|
+
export { PostgresTimeouts as a, createPostgres as c, PostgresOptions as i, PgPool as n, SessionOptions as o, PgPoolClient as r, SqlClaims as s, BetterPostgres as t };
|
package/dist/postgres/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as fromPgError, r as postgresExecutor, t as SqlClient } from "../executor-
|
|
3
|
-
import { a as PostgresTimeouts, i as PostgresOptions, n as PgPool, o as
|
|
4
|
-
import { t as Compiler } from "../compiler-
|
|
1
|
+
import { U as Operation } from "../executor-BunPOO-k.js";
|
|
2
|
+
import { n as fromPgError, r as postgresExecutor, t as SqlClient } from "../executor-Cghdstwu.js";
|
|
3
|
+
import { a as PostgresTimeouts, c as createPostgres, i as PostgresOptions, n as PgPool, o as SessionOptions, r as PgPoolClient, s as SqlClaims, t as BetterPostgres } from "../pool-C9voM4Kw.js";
|
|
4
|
+
import { t as Compiler } from "../compiler-BXH_aZ7N.js";
|
|
5
5
|
//#region src/compile/sql.d.ts
|
|
6
6
|
interface SqlQuery {
|
|
7
7
|
readonly text: string;
|
|
@@ -30,4 +30,4 @@ export declare function compileSql(op: Operation): SqlPlan;
|
|
|
30
30
|
//#region src/postgres/compiler.d.ts
|
|
31
31
|
export declare const sqlCompiler: Compiler<SqlPlan>;
|
|
32
32
|
//#endregion
|
|
33
|
-
export { type BetterPostgres, type PgPool, type PgPoolClient, type PostgresOptions, type PostgresTimeouts, type SqlClaims, type SqlClient, type SqlPlan, type SqlQuery, createPostgres, fromPgError, postgresExecutor };
|
|
33
|
+
export { type BetterPostgres, type PgPool, type PgPoolClient, type PostgresOptions, type PostgresTimeouts, type SessionOptions, type SqlClaims, type SqlClient, type SqlPlan, type SqlQuery, createPostgres, fromPgError, postgresExecutor };
|