better-supabase 0.4.0 → 0.5.1
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 +135 -16
- package/dist/actor-DaJjqD5R.d.ts +43 -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-C_A-KEAz.js} +533 -50
- package/dist/cli/{env-BZ0uy8XK.js → env-DmKv_G4A.js} +1 -1
- package/dist/cli/gen-CIdSQZad.js +2 -0
- package/dist/cli/{gen-Ccn_p90L.js → gen-CjElD1Vw.js} +321 -88
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/cli/{init-ClnxRYBF.js → init-DMa6M7hV.js} +2 -2
- package/dist/cli/{introspect-DxqfkVIv.js → introspect-BKlaIu_M.js} +2 -2
- package/dist/cli/{openapi-8WHjxiTJ.js → openapi-Cp5Fyta-.js} +1 -1
- package/dist/cli/read-sets-VQcPgxU9.js +436 -0
- package/dist/cli/{run-CP20LKk_.js → run-Bo_NLT5n.js} +16 -12
- package/dist/cli/{seed-5J6eu_Xg.js → seed-CUlqWh-8.js} +1 -1
- package/dist/cli/sql-CVx-1O8G.js +373 -0
- package/dist/cli/{version-5mW_8sY1.js → version-BCtlgDQx.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-C1CYcm6o.d.ts → config-Bv7gvfzC.d.ts} +185 -11
- package/dist/{config-CbvFmGD8.js → config-DreERlKo.js} +1 -1
- 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-BiJZ4t49.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-BgSHAYLf.js +133 -0
- package/dist/{resolve-BAqQcwMW.d.ts → impersonation-BmePsuxz.d.ts} +36 -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-Cf-D2jk1.d.ts → index-CWMDdEr4.d.ts} +2 -2
- 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-BBdvo-5d.d.ts → index-Dp2VDwog.d.ts} +49 -6
- 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-Cu96oJdw.d.ts} +2 -16
- 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-CFPX0Qft.d.ts} +1 -1
- package/dist/{resource-BJcaIfxi.d.ts → resource-DNRFP7KR.d.ts} +5 -5
- package/dist/{resource-My_y-Syh.js → resource-mqfJW4YF.js} +22 -7
- package/dist/respond-BR1fJWOB.d.ts +377 -0
- package/dist/{result-Bj6yt33D.js → result-BKiliPY7.js} +1 -1
- package/dist/server/index.d.ts +15 -12
- package/dist/server/index.js +11 -17
- package/dist/{server-BA75B0mT.js → server-B1mZ7CgQ.js} +259 -37
- 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 +283 -11
- package/dist/sql/index.js +8705 -775
- 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-CEPwlw2G.d.ts +89 -0
- package/dist/support-view-B8SlToQX.d.ts +17 -0
- package/dist/support-view-g4YLBeqX.js +18 -0
- package/dist/support-wHnK6zp-.js +293 -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 +132 -10
- package/dist/testing/index.js +476 -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-DOYTYwHP.js} +1 -1
- package/dist/{mfa-byfjruR9.js → view-Bn6HNKUe.js} +97 -98
- package/dist/{view-B64o81wp.d.ts → view-CbgObAeb.d.ts} +22 -31
- 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 +27 -19
- package/schemas/config-v1.json +131 -1
- package/schemas/doctor-report-v1.json +11 -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 +18 -7
- package/skills/better-supabase-auth/references/permdock.md +78 -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
package/dist/cli/sql-D4VbqmXi.js
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { r as defineCliCommand } from "./command-CK14fP91.js";
|
|
2
|
-
import { r as writeIfChanged, t as display } from "./io-k41_z-jT.js";
|
|
3
|
-
import { i as plain, r as painter } from "./style-C0NFdJRL.js";
|
|
4
|
-
import { d as readSupabaseToml, f as schemaPaths, l as migrationCommand } from "./config-D9R0o1LH.js";
|
|
5
|
-
import { c as readPermdock, l as fileDiff, o as permdockConfig, r as entitlementsMode, t as compiledReadSets } from "./read-sets-CMa29t9a.js";
|
|
6
|
-
import { resolve } from "node:path";
|
|
7
|
-
import { existsSync } from "node:fs";
|
|
8
|
-
import { readFile } from "node:fs/promises";
|
|
9
|
-
import { SQL_MODULES, kitLayout, renderKit, resolveModules, sameKitFile } from "better-supabase/sql";
|
|
10
|
-
//#region src/cli/commands/sql.ts
|
|
11
|
-
const SQL_ARGS = {
|
|
12
|
-
action: {
|
|
13
|
-
type: "positional",
|
|
14
|
-
required: false,
|
|
15
|
-
description: "list (modules and whether they are installed), add <module...>, sync or print <module>"
|
|
16
|
-
},
|
|
17
|
-
check: {
|
|
18
|
-
type: "boolean",
|
|
19
|
-
description: "With sync: fail when a file is stale"
|
|
20
|
-
},
|
|
21
|
-
"tests-dir": {
|
|
22
|
-
type: "string",
|
|
23
|
-
description: "Where the pgtap module goes. Defaults to sql.testsDir",
|
|
24
|
-
valueHint: "dir"
|
|
25
|
-
},
|
|
26
|
-
"dry-run": {
|
|
27
|
-
type: "boolean",
|
|
28
|
-
description: "Show what would be written"
|
|
29
|
-
},
|
|
30
|
-
force: {
|
|
31
|
-
type: "boolean",
|
|
32
|
-
description: "Write tenant even though a permdock.config.ts is present"
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
const USAGE = "Run `better-supabase sql --help` for the actions.";
|
|
36
|
-
/** Modules that fill a claim PermDock's hook also writes (`memberships`). */
|
|
37
|
-
const PERMDOCK_OWNED = /* @__PURE__ */ new Set(["tenant"]);
|
|
38
|
-
/** PermDock's helpers for the `entitlements` module; throws for a scope the manifest lacks. */
|
|
39
|
-
async function permdockFor(config) {
|
|
40
|
-
const mode = entitlementsMode(config, await readPermdock(config.root, config.permdock));
|
|
41
|
-
switch (mode.kind) {
|
|
42
|
-
case "tenant": return;
|
|
43
|
-
case "permdock": return mode.permdock;
|
|
44
|
-
case "invalid": throw new TypeError(mode.problem);
|
|
45
|
-
default: return mode;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
async function layout(config, args) {
|
|
49
|
-
return kitLayout(config, args["tests-dir"], [], await permdockFor(config));
|
|
50
|
-
}
|
|
51
|
-
/** The layout, with `config.readSets` compiled when `names` includes `read-sets`. */
|
|
52
|
-
async function layoutFor(config, args, names) {
|
|
53
|
-
const permdock = await permdockFor(config);
|
|
54
|
-
const needsReadSets = resolveModules(names, { ...permdock ? { permdock } : {} }).some((module) => module.name === "read-sets");
|
|
55
|
-
return kitLayout(config, args["tests-dir"], needsReadSets ? await compiledReadSets(config) : [], permdock);
|
|
56
|
-
}
|
|
57
|
-
async function write(config, args, names, kit) {
|
|
58
|
-
const lines = [];
|
|
59
|
-
const dryRun = args["dry-run"] === true;
|
|
60
|
-
for (const file of renderKit(names, kit)) {
|
|
61
|
-
const path = resolve(config.root, file.path);
|
|
62
|
-
const shown = display(config.root, file.path);
|
|
63
|
-
if (dryRun) {
|
|
64
|
-
lines.push(`Would write ${shown} (${file.module})`);
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
const wrote = await writeIfChanged(path, file.contents);
|
|
68
|
-
lines.push(`${wrote ? "Wrote" : "Unchanged"} ${shown} (${file.module})`);
|
|
69
|
-
}
|
|
70
|
-
return lines;
|
|
71
|
-
}
|
|
72
|
-
/** A note when migra's `schema_paths` is set and misses kit files, which `supabase db diff` would then skip. */
|
|
73
|
-
async function unlistedKitFiles(config, names, kit) {
|
|
74
|
-
const order = await schemaPaths(config.root, await readSupabaseToml(config.root));
|
|
75
|
-
if (!order.configured) return [];
|
|
76
|
-
const unlisted = new Set(order.unlisted);
|
|
77
|
-
const listed = new Set(order.files.filter((path) => !unlisted.has(path)));
|
|
78
|
-
const dir = `${config.sql.dir.replace(/\/$/, "")}/`;
|
|
79
|
-
const missing = renderKit(names, kit).map((file) => file.path).filter((path) => path.startsWith(dir) && !listed.has(path));
|
|
80
|
-
if (missing.length === 0) return [];
|
|
81
|
-
return [
|
|
82
|
-
"",
|
|
83
|
-
"supabase/config.toml sets [db.migrations] schema_paths, and no entry matches these files, so `supabase db diff` skips them.",
|
|
84
|
-
"Add them before the schemas that call their functions:",
|
|
85
|
-
...missing.map((path) => ` "./${path.startsWith("supabase/") ? path.slice(9) : path}",`)
|
|
86
|
-
];
|
|
87
|
-
}
|
|
88
|
-
async function runSql(config, args, paint = plain) {
|
|
89
|
-
const [action, ...names] = args._;
|
|
90
|
-
switch (action) {
|
|
91
|
-
case "list": {
|
|
92
|
-
const kit = await layout(config, args);
|
|
93
|
-
const files = new Map(renderKit(Object.keys(SQL_MODULES), kit).map((file) => [file.module, file.path]));
|
|
94
|
-
return {
|
|
95
|
-
code: 0,
|
|
96
|
-
output: `${Object.values(SQL_MODULES).map((module) => {
|
|
97
|
-
const path = files.get(module.name);
|
|
98
|
-
const installed = existsSync(resolve(config.root, path));
|
|
99
|
-
const tracked = config.sql.kit.includes(module.name);
|
|
100
|
-
const mark = installed ? tracked ? "●" : "○" : " ";
|
|
101
|
-
const requires = kit.permdock && module.permdockRequires ? module.permdockRequires : module.requires;
|
|
102
|
-
const needs = requires.length > 0 ? ` (needs ${requires.join(", ")})` : "";
|
|
103
|
-
return `${mark} ${module.name.padEnd(15)} ${module.description}${needs}`;
|
|
104
|
-
}).join("\n")}\n\n● installed and in sql.kit ○ installed, not in sql.kit`
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
case "add": {
|
|
108
|
-
if (names.length === 0) return {
|
|
109
|
-
code: 2,
|
|
110
|
-
error: `Name at least one module.\n${USAGE}`
|
|
111
|
-
};
|
|
112
|
-
const unknown = names.filter((name) => !(name in SQL_MODULES));
|
|
113
|
-
if (unknown.length > 0) return {
|
|
114
|
-
code: 2,
|
|
115
|
-
error: `Unknown module ${unknown.join(", ")}. Available: ${Object.keys(SQL_MODULES).join(", ")}`
|
|
116
|
-
};
|
|
117
|
-
const permdock = permdockConfig(config.root);
|
|
118
|
-
const hookModules = names.filter((name) => PERMDOCK_OWNED.has(name));
|
|
119
|
-
if (permdock && hookModules.length > 0 && args.force !== true) return {
|
|
120
|
-
code: 1,
|
|
121
|
-
error: [
|
|
122
|
-
`${permdock} is present, so PermDock owns the access token hook and the memberships claim.`,
|
|
123
|
-
`${hookModules.join(" and ")} would add a second source for them. Use \`permdock supabase hook generate\` instead,`,
|
|
124
|
-
"or pass --force to write the modules anyway."
|
|
125
|
-
].join("\n")
|
|
126
|
-
};
|
|
127
|
-
const kit = await layoutFor(config, args, names);
|
|
128
|
-
const lines = await write(config, args, names, kit);
|
|
129
|
-
const pulledIn = resolveModules(names, kit).map((module) => module.name).filter((name) => PERMDOCK_OWNED.has(name) && !names.includes(name));
|
|
130
|
-
if (permdock && pulledIn.length > 0) lines.push("", `${pulledIn.join(" and ")} came along as a dependency: its memberships table backs has_org_role() and has_entitlement().`, `PermDock's hook still owns the memberships claim, so don't call better_supabase.membership_claims from a hook.`, "List better_supabase.memberships as a PermDock membership source if both should agree.");
|
|
131
|
-
const untracked = resolveModules(names, kit).map((module) => module.name).filter((name) => !config.sql.kit.includes(name));
|
|
132
|
-
if (untracked.length > 0) lines.push("", `Add them to your config so \`sql sync --check\` keeps them current:`, ` sql: { kit: [${[...config.sql.kit, ...untracked].map((name) => `'${name}'`).join(", ")}] }`);
|
|
133
|
-
if (args["dry-run"] !== true) lines.push(...await unlistedKitFiles(config, names, kit));
|
|
134
|
-
lines.push("", `Then create a migration: ${migrationCommand(await readSupabaseToml(config.root), "better_supabase_kit")}`);
|
|
135
|
-
return {
|
|
136
|
-
code: 0,
|
|
137
|
-
output: lines.join("\n")
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
case "sync": {
|
|
141
|
-
if (config.sql.kit.length === 0) return {
|
|
142
|
-
code: 0,
|
|
143
|
-
output: "sql.kit is empty; nothing to sync."
|
|
144
|
-
};
|
|
145
|
-
if (args.check !== true) return {
|
|
146
|
-
code: 0,
|
|
147
|
-
output: (await write(config, args, config.sql.kit, await layoutFor(config, args, config.sql.kit))).join("\n")
|
|
148
|
-
};
|
|
149
|
-
const stale = [];
|
|
150
|
-
const diffs = [];
|
|
151
|
-
for (const file of renderKit(config.sql.kit, await layoutFor(config, args, config.sql.kit))) {
|
|
152
|
-
const current = await readFile(resolve(config.root, file.path), "utf8").catch(() => void 0);
|
|
153
|
-
if (!sameKitFile(current, file.contents)) {
|
|
154
|
-
const shown = display(config.root, file.path);
|
|
155
|
-
stale.push(shown);
|
|
156
|
-
diffs.push(fileDiff(shown, current, file.contents, paint));
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return stale.length === 0 ? {
|
|
160
|
-
code: 0,
|
|
161
|
-
output: "SQL kit files are up to date."
|
|
162
|
-
} : {
|
|
163
|
-
code: 1,
|
|
164
|
-
output: diffs.join("\n\n"),
|
|
165
|
-
error: `Out of date: ${stale.join(", ")}. Run \`better-supabase sql sync\`.`
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
case "print": {
|
|
169
|
-
const [name] = names;
|
|
170
|
-
const module = name ? SQL_MODULES[name] : void 0;
|
|
171
|
-
if (!module) return {
|
|
172
|
-
code: 2,
|
|
173
|
-
error: `Name one module: ${Object.keys(SQL_MODULES).join(", ")}`
|
|
174
|
-
};
|
|
175
|
-
return {
|
|
176
|
-
code: 0,
|
|
177
|
-
output: module.render ? module.render(config.claims, await layout(config, args)) : module.sql
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
case void 0: return {
|
|
181
|
-
code: 2,
|
|
182
|
-
error: `Name an action.\n${USAGE}`
|
|
183
|
-
};
|
|
184
|
-
default: return {
|
|
185
|
-
code: 2,
|
|
186
|
-
error: `Unknown sql action "${action}".\n${USAGE}`
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
const sqlCommand = defineCliCommand({
|
|
191
|
-
meta: {
|
|
192
|
-
name: "sql",
|
|
193
|
-
description: "Lists, adds, syncs and prints SQL kit modules"
|
|
194
|
-
},
|
|
195
|
-
args: SQL_ARGS,
|
|
196
|
-
run: (args, { config, io }) => runSql(config, args, painter(io.color))
|
|
197
|
-
});
|
|
198
|
-
//#endregion
|
|
199
|
-
export { sqlCommand };
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { g as Operation } from "./executor-B5IoUxLE.js";
|
|
2
|
-
import { p as DbError } from "./result-CqEsbgYs.js";
|
|
3
|
-
import { h as RequestContext, l as MutationKind } from "./plugin-bNhvJwRh.js";
|
|
4
|
-
//#region src/core/logger.d.ts
|
|
5
|
-
type LogFields = Readonly<Record<string, unknown>>;
|
|
6
|
-
/**
|
|
7
|
-
* Where better-supabase reports problems it swallows on purpose: event
|
|
8
|
-
* handlers, `afterMutation` hooks, sinks and cache adapters that throw.
|
|
9
|
-
* Structured loggers (pino, consola, OpenTelemetry logs) fit directly.
|
|
10
|
-
*/
|
|
11
|
-
interface Logger {
|
|
12
|
-
debug(message: string, fields?: LogFields): void;
|
|
13
|
-
info(message: string, fields?: LogFields): void;
|
|
14
|
-
warn(message: string, fields?: LogFields): void;
|
|
15
|
-
error(message: string, fields?: LogFields): void;
|
|
16
|
-
}
|
|
17
|
-
/** The default: `console`, with a `better-supabase:` prefix. */
|
|
18
|
-
declare const consoleLogger: Logger;
|
|
19
|
-
declare const silentLogger: Logger;
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region src/core/events.d.ts
|
|
22
|
-
interface QueryEvent {
|
|
23
|
-
readonly table: string;
|
|
24
|
-
readonly operation: Operation["kind"];
|
|
25
|
-
readonly ok: boolean;
|
|
26
|
-
readonly durationMs: number;
|
|
27
|
-
readonly rows: number;
|
|
28
|
-
/**
|
|
29
|
-
* An unbounded read returned `maxRows` rows: PostgREST's `db-max-rows`
|
|
30
|
-
* probably cut it short. Add `limit` or use `paginate`.
|
|
31
|
-
*/
|
|
32
|
-
readonly truncated: boolean;
|
|
33
|
-
}
|
|
34
|
-
interface MutationNotice {
|
|
35
|
-
readonly table: string;
|
|
36
|
-
readonly kind: MutationKind;
|
|
37
|
-
readonly rows: readonly Readonly<Record<string, unknown>>[];
|
|
38
|
-
readonly context: RequestContext;
|
|
39
|
-
}
|
|
40
|
-
/** A successful RPC registered with `betterSupabase.defineRpc(name, { invalidates })`. */
|
|
41
|
-
interface RpcNotice {
|
|
42
|
-
readonly name: string;
|
|
43
|
-
/** App keys of the tables the function changes. */
|
|
44
|
-
readonly invalidates: readonly string[];
|
|
45
|
-
readonly context: RequestContext;
|
|
46
|
-
}
|
|
47
|
-
interface ErrorEvent {
|
|
48
|
-
readonly table?: string;
|
|
49
|
-
readonly error: DbError;
|
|
50
|
-
}
|
|
51
|
-
interface AuthEvent {
|
|
52
|
-
readonly source: "bearer" | "cookie" | "none";
|
|
53
|
-
readonly ok: boolean;
|
|
54
|
-
readonly userId?: string;
|
|
55
|
-
}
|
|
56
|
-
interface RefreshEvent {
|
|
57
|
-
readonly ok: boolean;
|
|
58
|
-
readonly shared: boolean;
|
|
59
|
-
readonly durationMs: number;
|
|
60
|
-
}
|
|
61
|
-
interface BetterSupabaseEvents {
|
|
62
|
-
query: QueryEvent;
|
|
63
|
-
mutation: MutationNotice;
|
|
64
|
-
rpc: RpcNotice;
|
|
65
|
-
error: ErrorEvent;
|
|
66
|
-
auth: AuthEvent;
|
|
67
|
-
refresh: RefreshEvent;
|
|
68
|
-
}
|
|
69
|
-
type EventName = keyof BetterSupabaseEvents;
|
|
70
|
-
type EventHandler<K extends EventName> = (event: BetterSupabaseEvents[K]) => void;
|
|
71
|
-
/**
|
|
72
|
-
* Observers only: a handler that throws is reported to the logger and never
|
|
73
|
-
* changes a result.
|
|
74
|
-
*/
|
|
75
|
-
declare class EventHub {
|
|
76
|
-
#private;
|
|
77
|
-
readonly logger: Logger;
|
|
78
|
-
constructor(logger?: Logger);
|
|
79
|
-
on<K extends EventName>(name: K, handler: EventHandler<K>): () => void;
|
|
80
|
-
has(name: EventName): boolean;
|
|
81
|
-
emit<K extends EventName>(name: K, event: BetterSupabaseEvents[K]): void;
|
|
82
|
-
}
|
|
83
|
-
//#endregion
|
|
84
|
-
export { EventHub as a, QueryEvent as c, LogFields as d, Logger as f, EventHandler as i, RefreshEvent as l, silentLogger as m, BetterSupabaseEvents as n, EventName as o, consoleLogger as p, ErrorEvent as r, MutationNotice as s, AuthEvent as t, RpcNotice as u };
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { P as TableMeta, T as RelationMeta, c as Codec } from "./types-DONv9SHN.js";
|
|
2
|
-
import { o as Result, v as ErrorMapper } from "./result-CqEsbgYs.js";
|
|
3
|
-
//#region src/ir/types.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* The query IR. Every repository call becomes one of these operations; the
|
|
6
|
-
* executor compiles it to PostgREST or SQL. Column names in the IR are
|
|
7
|
-
* database names; `Selection` carries the app aliases.
|
|
8
|
-
*/
|
|
9
|
-
type ColumnOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "is" | "like" | "ilike" | "contains" | "containedBy" | "overlaps" | "fts";
|
|
10
|
-
type Quantifier = "some" | "none" | "every";
|
|
11
|
-
type Condition = {
|
|
12
|
-
readonly kind: "and";
|
|
13
|
-
readonly items: readonly Condition[];
|
|
14
|
-
} | {
|
|
15
|
-
readonly kind: "or";
|
|
16
|
-
readonly items: readonly Condition[];
|
|
17
|
-
} | {
|
|
18
|
-
readonly kind: "not";
|
|
19
|
-
readonly item: Condition;
|
|
20
|
-
} | {
|
|
21
|
-
readonly kind: "column";
|
|
22
|
-
readonly column: string;
|
|
23
|
-
readonly op: ColumnOp;
|
|
24
|
-
readonly value: unknown;
|
|
25
|
-
/** Full-text search configuration for `fts`. */
|
|
26
|
-
readonly config?: string;
|
|
27
|
-
} | {
|
|
28
|
-
readonly kind: "relation";
|
|
29
|
-
readonly name: string;
|
|
30
|
-
readonly relation: RelationMeta;
|
|
31
|
-
readonly target: TableMeta;
|
|
32
|
-
readonly quantifier: Quantifier;
|
|
33
|
-
readonly where: Condition | undefined;
|
|
34
|
-
};
|
|
35
|
-
interface SelectColumn {
|
|
36
|
-
/** Key in the returned row. */
|
|
37
|
-
readonly alias: string;
|
|
38
|
-
/** Database column name. */
|
|
39
|
-
readonly column: string;
|
|
40
|
-
/** Read the column as text, so exact `int8`/`numeric` values survive JSON. */
|
|
41
|
-
readonly cast?: "text";
|
|
42
|
-
/** Decodes the returned value (see `ColumnMeta.codec`). */
|
|
43
|
-
readonly codec?: Codec;
|
|
44
|
-
}
|
|
45
|
-
interface OrderTerm {
|
|
46
|
-
readonly column: string;
|
|
47
|
-
readonly direction: "asc" | "desc";
|
|
48
|
-
readonly nulls?: "first" | "last";
|
|
49
|
-
}
|
|
50
|
-
interface Include {
|
|
51
|
-
readonly alias: string;
|
|
52
|
-
readonly relation: RelationMeta;
|
|
53
|
-
readonly target: TableMeta;
|
|
54
|
-
readonly selection: Selection;
|
|
55
|
-
readonly where: Condition | undefined;
|
|
56
|
-
readonly orderBy: readonly OrderTerm[];
|
|
57
|
-
readonly limit: number | undefined;
|
|
58
|
-
/** Drop parent rows without a match (`!inner`). */
|
|
59
|
-
readonly required: boolean;
|
|
60
|
-
/**
|
|
61
|
-
* `_count` include: returns the number of matching related rows instead of
|
|
62
|
-
* rows, folded into `row._count[count]` when decoded.
|
|
63
|
-
*/
|
|
64
|
-
readonly count?: string;
|
|
65
|
-
/**
|
|
66
|
-
* `_sum`/`_avg`/`_min`/`_max` include: `selection.aggregate` holds the
|
|
67
|
-
* measures, folded into `row[`_${fn}`][name]` when decoded.
|
|
68
|
-
*/
|
|
69
|
-
readonly aggregate?: {
|
|
70
|
-
readonly fn: AggregateFn;
|
|
71
|
-
readonly name: string;
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
type AggregateFn = "sum" | "avg" | "min" | "max";
|
|
75
|
-
interface Measure {
|
|
76
|
-
readonly fn: AggregateFn;
|
|
77
|
-
/** Key in the returned row (`_sum_amount`, or the column alias in an include). */
|
|
78
|
-
readonly key: string;
|
|
79
|
-
/** App column name, the key under `_sum` in the decoded row. */
|
|
80
|
-
readonly alias: string;
|
|
81
|
-
/** Database column name. */
|
|
82
|
-
readonly column: string;
|
|
83
|
-
/** Read the result as text, so exact `int8`/`numeric` values survive JSON. */
|
|
84
|
-
readonly cast?: "text";
|
|
85
|
-
readonly codec?: Codec;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Aggregates instead of rows. `Selection.columns` become the grouping
|
|
89
|
-
* columns; without any, the result is exactly one row.
|
|
90
|
-
*/
|
|
91
|
-
interface Aggregation {
|
|
92
|
-
/** Also return `_count`, the number of rows in each group. */
|
|
93
|
-
readonly count: boolean;
|
|
94
|
-
readonly measures: readonly Measure[];
|
|
95
|
-
}
|
|
96
|
-
interface Selection {
|
|
97
|
-
readonly columns: readonly SelectColumn[];
|
|
98
|
-
readonly includes: readonly Include[];
|
|
99
|
-
readonly aggregate?: Aggregation;
|
|
100
|
-
}
|
|
101
|
-
type CountMode = "exact" | "planned" | "estimated";
|
|
102
|
-
interface SelectOp {
|
|
103
|
-
readonly kind: "select";
|
|
104
|
-
readonly table: TableMeta;
|
|
105
|
-
readonly selection: Selection;
|
|
106
|
-
readonly where: Condition | undefined;
|
|
107
|
-
readonly orderBy: readonly OrderTerm[];
|
|
108
|
-
readonly limit: number | undefined;
|
|
109
|
-
readonly offset: number | undefined;
|
|
110
|
-
readonly count: CountMode | undefined;
|
|
111
|
-
/** Only count, return no rows. */
|
|
112
|
-
readonly head: boolean;
|
|
113
|
-
readonly single: "one" | "maybe" | undefined;
|
|
114
|
-
/**
|
|
115
|
-
* Read from this set-returning function instead of the table (`db.$search`).
|
|
116
|
-
* Only executors with `functionSources` honor it.
|
|
117
|
-
*/
|
|
118
|
-
readonly source?: FunctionSource;
|
|
119
|
-
}
|
|
120
|
-
/** A function returning `setof <table>`, called with named arguments. */
|
|
121
|
-
interface FunctionSource {
|
|
122
|
-
readonly schema: string;
|
|
123
|
-
readonly name: string;
|
|
124
|
-
readonly args: Readonly<Record<string, unknown>>;
|
|
125
|
-
}
|
|
126
|
-
interface InsertOp {
|
|
127
|
-
readonly kind: "insert";
|
|
128
|
-
readonly table: TableMeta;
|
|
129
|
-
/** Rows keyed by database column names. */
|
|
130
|
-
readonly rows: readonly Readonly<Record<string, unknown>>[];
|
|
131
|
-
readonly returning: Selection | undefined;
|
|
132
|
-
readonly onConflict: {
|
|
133
|
-
readonly columns: readonly string[];
|
|
134
|
-
readonly action: "update" | "ignore";
|
|
135
|
-
} | undefined;
|
|
136
|
-
/** Missing columns become `null` instead of their default in bulk inserts. */
|
|
137
|
-
readonly defaultToNull: boolean;
|
|
138
|
-
}
|
|
139
|
-
interface UpdateOp {
|
|
140
|
-
readonly kind: "update";
|
|
141
|
-
readonly table: TableMeta;
|
|
142
|
-
/** Keyed by database column names. */
|
|
143
|
-
readonly set: Readonly<Record<string, unknown>>;
|
|
144
|
-
readonly where: Condition | undefined;
|
|
145
|
-
readonly returning: Selection | undefined;
|
|
146
|
-
}
|
|
147
|
-
interface DeleteOp {
|
|
148
|
-
readonly kind: "delete";
|
|
149
|
-
readonly table: TableMeta;
|
|
150
|
-
readonly where: Condition | undefined;
|
|
151
|
-
readonly returning: Selection | undefined;
|
|
152
|
-
}
|
|
153
|
-
type Operation = SelectOp | InsertOp | UpdateOp | DeleteOp;
|
|
154
|
-
type MutationOp = InsertOp | UpdateOp | DeleteOp;
|
|
155
|
-
declare const and: (...items: (Condition | undefined)[]) => Condition | undefined;
|
|
156
|
-
declare const or: (...items: Condition[]) => Condition;
|
|
157
|
-
declare const not: (item: Condition) => Condition;
|
|
158
|
-
declare const column: (name: string, op: ColumnOp, value: unknown) => Condition;
|
|
159
|
-
//#endregion
|
|
160
|
-
//#region src/core/executor.d.ts
|
|
161
|
-
interface ExecuteContext {
|
|
162
|
-
readonly signal?: AbortSignal;
|
|
163
|
-
readonly errorMappers: readonly ErrorMapper[];
|
|
164
|
-
}
|
|
165
|
-
interface ExecuteResult {
|
|
166
|
-
/** Rows keyed by the aliases in the operation's selection. */
|
|
167
|
-
readonly rows: readonly Record<string, unknown>[];
|
|
168
|
-
readonly count: number | null;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Runs IR operations. PostgREST (`postgrestExecutor`) and SQL
|
|
172
|
-
* (`better-supabase/postgres`) are built in; any other backend can implement
|
|
173
|
-
* this interface and prove it with `testExecutor` from `better-supabase/testing`.
|
|
174
|
-
*/
|
|
175
|
-
interface Executor {
|
|
176
|
-
readonly name: string;
|
|
177
|
-
/** Honors `SelectOp.source`. `db.$search` fails on executors without it. */
|
|
178
|
-
readonly functionSources?: boolean;
|
|
179
|
-
execute(op: Operation, context: ExecuteContext): Promise<Result<ExecuteResult>>;
|
|
180
|
-
/** Calls a database function. Optional; `db.$rpc` fails without it. */
|
|
181
|
-
rpc?(name: string, args: Readonly<Record<string, unknown>>, context: RpcContext): Promise<Result<unknown>>;
|
|
182
|
-
/**
|
|
183
|
-
* Runs several reads together, for `db.$many`: one transaction on a SQL
|
|
184
|
-
* connection. Returns one result per operation, in order. Optional;
|
|
185
|
-
* without it `db.$many` runs the operations in parallel.
|
|
186
|
-
*/
|
|
187
|
-
batch?(ops: readonly Operation[], context: ExecuteContext): Promise<readonly Result<ExecuteResult>[]>;
|
|
188
|
-
}
|
|
189
|
-
interface RpcContext extends ExecuteContext {
|
|
190
|
-
readonly schema: string;
|
|
191
|
-
/** The function is `stable`: send it as a GET, so read replicas can serve it. */
|
|
192
|
-
readonly get?: boolean;
|
|
193
|
-
}
|
|
194
|
-
//#endregion
|
|
195
|
-
export { and as C, or as E, UpdateOp as S, not as T, OrderTerm as _, AggregateFn as a, SelectOp as b, Condition as c, FunctionSource as d, Include as f, Operation as g, MutationOp as h, RpcContext as i, CountMode as l, Measure as m, ExecuteResult as n, Aggregation as o, InsertOp as p, Executor as r, ColumnOp as s, ExecuteContext as t, DeleteOp as u, Quantifier as v, column as w, Selection as x, SelectColumn as y };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
//#region src/query/invalidate.ts
|
|
2
|
-
function isString(value) {
|
|
3
|
-
return typeof value === "string";
|
|
4
|
-
}
|
|
5
|
-
function queryTables(query) {
|
|
6
|
-
const tables = query.meta?.["bsTables"];
|
|
7
|
-
if (Array.isArray(tables)) {
|
|
8
|
-
const list = tables;
|
|
9
|
-
return list.every(isString) ? list : list.filter(isString);
|
|
10
|
-
}
|
|
11
|
-
const [prefix, table] = query.queryKey;
|
|
12
|
-
return prefix === "bs" && typeof table === "string" ? [table] : void 0;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Invalidates every query that read one of `tables`: better-supabase queries
|
|
16
|
-
* by their `meta.bsTables`, and other `['bs', table, ...]` keys by prefix.
|
|
17
|
-
*/
|
|
18
|
-
function invalidateTables(client, tables) {
|
|
19
|
-
if (tables.length === 0) return Promise.resolve();
|
|
20
|
-
const changed = new Set(tables);
|
|
21
|
-
return client.invalidateQueries({ predicate: (query) => queryTables(query)?.some((table) => changed.has(table)) ?? false });
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
|
-
export { invalidateTables as t };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//#region src/core/permdock-sql.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* The part of PermDock's `permissions.catalog.json` the Storage and Realtime
|
|
4
|
-
* builders read: `import catalog from './permissions.catalog.json'`.
|
|
5
|
-
*/
|
|
6
|
-
interface PermdockCatalog {
|
|
7
|
-
readonly permissions: readonly {
|
|
8
|
-
readonly key: string;
|
|
9
|
-
readonly rowConditions?: boolean;
|
|
10
|
-
}[];
|
|
11
|
-
}
|
|
12
|
-
/** The keys a bucket or topic PermDock policy names. */
|
|
13
|
-
declare function permdockKeys(policy: {
|
|
14
|
-
readonly permdock: object;
|
|
15
|
-
}): string[];
|
|
16
|
-
//#endregion
|
|
17
|
-
export { permdockKeys as n, PermdockCatalog as t };
|
package/dist/plugin-BqR6wKMB.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
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
|
-
/** Plugins in hook order: `pre`, then unmarked in `use()` order, then `post`. */
|
|
9
|
-
function orderPlugins(plugins) {
|
|
10
|
-
return plugins.map((plugin, index) => ({
|
|
11
|
-
plugin,
|
|
12
|
-
index
|
|
13
|
-
})).sort((a, b) => RANK[a.plugin.enforce ?? "normal"] - RANK[b.plugin.enforce ?? "normal"] || a.index - b.index).map(({ plugin }) => plugin);
|
|
14
|
-
}
|
|
15
|
-
/** Identity helper that fixes `apiVersion` and infers the plugin types. */
|
|
16
|
-
function definePlugin(plugin) {
|
|
17
|
-
return {
|
|
18
|
-
...plugin,
|
|
19
|
-
apiVersion: 1
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
//#endregion
|
|
23
|
-
export { definePlugin as n, orderPlugins as r, PLUGIN_API_VERSION as t };
|