better-supabase 0.2.0 → 0.3.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 +34 -31
- package/dist/base64-CQeB1eSf.js +42 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +4 -14
- package/dist/{compiler-CZ9nIuqy.d.ts → compiler-2zqGzxVZ.d.ts} +2 -2
- package/dist/config/index.d.ts +4 -3
- package/dist/config/index.js +5 -3
- package/dist/config-Be4GwsqI.js +129 -0
- package/dist/{index-DOsjFvMf.d.ts → config-C1CYcm6o.d.ts} +49 -49
- package/dist/{config-ClDXmVtY.js → config-DOsGYSiT.js} +14 -137
- package/dist/{define-BXMYD9AY.js → define-DF341GDj.js} +71 -51
- package/dist/{define-e3zI4_4g.d.ts → define-DUbydmJa.d.ts} +10 -9
- package/dist/edge/index.d.ts +4 -4
- package/dist/edge/index.js +4 -4
- package/dist/{entitlements-Dng-ctuT.d.ts → entitlements-DvJXoI02.d.ts} +1 -1
- package/dist/env/index.js +203 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.js +139 -1
- package/dist/{events-DOt3nSO-.d.ts → events-Do8jXh4D.d.ts} +3 -3
- package/dist/{executor-BYXQ9AGn.d.ts → executor-B26lgbHD.d.ts} +2 -2
- package/dist/{executor-DeppvirK.js → executor-C57jx2pn.js} +7 -2
- package/dist/{executor-CGdNQ27g.d.ts → executor-DynmIWhq.d.ts} +2 -2
- package/dist/hono/index.d.ts +5 -5
- package/dist/hono/index.js +4 -4
- package/dist/{index-CBDufH1M.d.ts → index-BNsABq7P.d.ts} +8 -8
- package/dist/{index-Bw1bwtC0.d.ts → index-CADlNHK-.d.ts} +27 -14
- package/dist/{index-DuP14VHo.d.ts → index-CTTMS6_1.d.ts} +19 -8
- package/dist/index-Cf-D2jk1.d.ts +50 -0
- package/dist/{index-K-3WM2Hp.d.ts → index-CriFFJ_p.d.ts} +4 -4
- package/dist/{index-Ciu5Xlml.d.ts → index-GV77NpRP.d.ts} +5 -4
- package/dist/{index-D4v7sncu.d.ts → index-UJ-LUxtI.d.ts} +3 -3
- package/dist/{index-CG69s15v.d.ts → index-kpgopLNv.d.ts} +4 -3
- package/dist/{index-DbxFr7XG.d.ts → index-qriRM9cZ.d.ts} +7 -2
- package/dist/index.d.ts +12 -12
- package/dist/index.js +16 -7
- package/dist/jobs/index.d.ts +25 -24
- package/dist/jobs/index.js +16 -10
- package/dist/{json-schema-BpYqkCKf.js → json-schema--aOXAGfU.js} +7 -2
- package/dist/lint/index.js +1 -1
- package/dist/list/index.d.ts +2 -2
- package/dist/list/index.js +128 -93
- package/dist/{live-DJyZMD6w.d.ts → live-QE3UPbGm.d.ts} +16 -6
- package/dist/mcp/index.d.ts +24 -17
- package/dist/mcp/index.js +41 -12
- package/dist/{mfa-CpLfJSde.js → mfa-BxoR1RkN.js} +74 -19
- package/dist/{mfa-TVia554c.d.ts → mfa-x3V3vGh-.d.ts} +1 -1
- package/dist/next/index.d.ts +39 -26
- package/dist/next/index.js +28 -23
- package/dist/openapi/index.d.ts +1 -1
- package/dist/openapi/index.js +57 -34
- package/dist/orpc/index.d.ts +6 -6
- package/dist/orpc/index.js +3 -3
- package/dist/otel/index.d.ts +2 -2
- package/dist/otel/index.js +4 -2
- package/dist/{permdock-sql-CghlHPuH.js → permdock-sql-Bta_G0v-.js} +11 -6
- package/dist/permdock-sql-DImJULY-.d.ts +17 -0
- package/dist/{plugin-C4TR9J0Z.d.ts → plugin-DVRB8qNE.d.ts} +5 -4
- package/dist/plugins/actor/index.d.ts +1 -1
- package/dist/plugins/rules/index.d.ts +2 -2
- package/dist/plugins/rules/index.js +4 -4
- package/dist/plugins/soft-delete/index.d.ts +3 -3
- package/dist/plugins/soft-delete/index.js +2 -2
- package/dist/plugins/tenant/index.d.ts +2 -2
- package/dist/plugins/timestamps/index.d.ts +1 -1
- package/dist/plugins/timestamps/index.js +1 -1
- package/dist/plugins/validation/index.d.ts +2 -2
- package/dist/pool-B9qsLyFR.d.ts +71 -0
- package/dist/postgres/index.d.ts +10 -5
- package/dist/postgres/index.js +36 -16
- package/dist/{postgrest-cAEQ_IQN.d.ts → postgrest-DmBlevh-.d.ts} +1 -1
- package/dist/{problem-BTkTtRV9.js → problem-CGt1ADix.js} +10 -4
- package/dist/{problem-DlgB0lYl.d.ts → problem-Z2RTQjZD.d.ts} +6 -4
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +1 -1
- package/dist/{query-ChvDbsDE.js → query-BdKLTPlj.js} +2 -2
- package/dist/react/index.d.ts +7 -7
- package/dist/react/index.js +2 -2
- package/dist/react/server.d.ts +3 -3
- package/dist/react/server.js +1 -1
- package/dist/react/session.d.ts +21 -2
- package/dist/react/session.js +19 -1
- package/dist/{react-C83BdBGt.js → react-DNBYNazu.js} +20 -16
- package/dist/{read-set-4lI3W_gZ.js → read-set-D0qBcboM.js} +3 -3
- package/dist/realtime/index.d.ts +4 -3
- package/dist/realtime/index.js +7 -6
- package/dist/{resolve-CjHILk2w.d.ts → resolve-BRciX2jK.d.ts} +6 -5
- package/dist/{resource-CgZa3YG_.d.ts → resource-CwVgiI5q.d.ts} +16 -7
- package/dist/{resource-BHEWmQJK.js → resource-D30rp0GN.js} +38 -16
- package/dist/{respond-DMcbQwfN.js → respond-C44EZAJo.js} +35 -19
- package/dist/{respond-Dne1ARSa.d.ts → respond-DAkPIdTH.d.ts} +15 -9
- package/dist/{result-CTkCZ6JA.d.ts → result-c2OYgCV2.d.ts} +13 -8
- package/dist/server/index.d.ts +35 -10
- package/dist/server/index.js +38 -9
- package/dist/{simplify-bwJpLnaS.js → simplify-LakqK1vH.js} +10 -16
- package/dist/sql/index.d.ts +139 -0
- package/dist/sql/index.js +1983 -0
- package/dist/{sql-DTjA1LPj.js → sql-BIgk12ew.js} +72 -16
- package/dist/ssr/index.d.ts +4 -4
- package/dist/ssr/index.js +2 -2
- package/dist/{standard-CyhRzctb.d.ts → standard-eudBiRk1.d.ts} +1 -1
- package/dist/{stats-C5W-rBfR.js → stats-D78UQ8Yu.js} +8 -7
- package/dist/storage/index.d.ts +4 -3
- package/dist/storage/index.js +530 -1
- package/dist/{tables-rZxRxNPW.js → tables-Dhha3BXM.js} +5 -5
- package/dist/temporal-BwshQk0W.js +27 -0
- package/dist/temporal-required-CMxeSVPo.js +19 -0
- package/dist/testing/index.d.ts +13 -11
- package/dist/testing/index.js +128 -29
- package/dist/{types-C83v5SQz.d.ts → types-DONv9SHN.d.ts} +14 -11
- package/dist/{version-Cqq1m3UY.js → version-BfpG2gks.js} +1 -1
- package/dist/{view-D1s0wa0T.d.ts → view-3Po_PVlr.d.ts} +34 -4
- package/dist/{view-aOYizTeE.js → view-wZ-9qIUz.js} +11 -2
- package/dist/webhooks/index.d.ts +18 -16
- package/dist/webhooks/index.js +1 -1
- package/dist/{webhooks-DMipjhSP.js → webhooks-CAIFQSTM.js} +11 -9
- package/package.json +24 -28
- 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 +23 -11
- package/skills/better-supabase/references/plugins.md +21 -18
- package/skills/better-supabase/references/troubleshooting.md +15 -15
- package/skills/better-supabase-api/SKILL.md +7 -7
- package/skills/better-supabase-api/references/adapters.md +30 -25
- package/skills/better-supabase-testing/SKILL.md +11 -8
- package/bin/better-supabase.js +0 -4
- package/dist/casing-da0uRTqt.js +0 -14
- package/dist/cli/bin.d.ts +0 -1
- package/dist/cli/bin.js +0 -15
- package/dist/cli/index.d.ts +0 -226
- package/dist/cli/index.js +0 -3
- 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,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as parseImport, c as schemaName, d as variantsFor, i as fieldsFor, l as siblingPath, o as propertyKey, r as HEADER, s as rowType, u as tableEntries } from "./json-schema-BpYqkCKf.js";
|
|
1
|
+
import { a as parseImport, c as schemaName, d as variantsFor, i as fieldsFor, l as siblingPath, o as propertyKey, r as HEADER, s as rowType, u as tableEntries } from "./json-schema--aOXAGfU.js";
|
|
3
2
|
//#region src/generators/valibot.ts
|
|
4
3
|
function scalar$1(kind) {
|
|
5
4
|
switch (kind.kind) {
|
|
@@ -10,7 +9,8 @@ function scalar$1(kind) {
|
|
|
10
9
|
case "boolean": return "v.boolean()";
|
|
11
10
|
case "datetime": return "v.pipe(v.string(), v.isoTimestamp())";
|
|
12
11
|
case "date": return "v.pipe(v.string(), v.isoDate())";
|
|
13
|
-
case "
|
|
12
|
+
case "instant": return "v.instance(Temporal.Instant)";
|
|
13
|
+
case "plainDateTime": return "v.instance(Temporal.PlainDateTime)";
|
|
14
14
|
case "bigint": return "v.bigint()";
|
|
15
15
|
case "json": return "json";
|
|
16
16
|
case "enum": return `v.picklist([${kind.values.map((value) => JSON.stringify(value)).join(", ")}])`;
|
|
@@ -19,7 +19,7 @@ function scalar$1(kind) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
function field$1(table, plan, jsonImports) {
|
|
22
|
-
let expr = jsonImports.get(`${table}.${plan.column.db}`) ?? (plan.customJson ? `v.custom<NonNullable<RowOf<'${table}'>['${plan.name}']>>((value) => value !== undefined)` : plan.column.storage
|
|
22
|
+
let expr = jsonImports.get(`${table}.${plan.column.db}`) ?? (plan.customJson ? `v.custom<NonNullable<RowOf<'${table}'>['${plan.name}']>>((value) => value !== undefined)` : plan.column.storage === void 0 ? scalar$1(plan.scalar) : `(v.string() as unknown as v.GenericSchema<${rowType(table, plan)}>)`);
|
|
23
23
|
if (plan.column.array) expr = `v.array(${expr})`;
|
|
24
24
|
if (plan.nullable) expr = `v.nullable(${expr})`;
|
|
25
25
|
if (plan.optional) expr = `v.exactOptional(${expr})`;
|
|
@@ -44,9 +44,9 @@ function valibot(options = {}) {
|
|
|
44
44
|
const lines = [
|
|
45
45
|
HEADER,
|
|
46
46
|
"import * as v from \"valibot\";",
|
|
47
|
-
""
|
|
47
|
+
"",
|
|
48
|
+
`import type { InsertOf, Json, RowOf, UpdateOf } from ${JSON.stringify(input.importPath(path, input.config.output))};`
|
|
48
49
|
];
|
|
49
|
-
lines.push(`import type { InsertOf, Json, RowOf, UpdateOf } from ${JSON.stringify(input.importPath(path, input.config.output))};`);
|
|
50
50
|
for (const [from, names] of imports) lines.push(`import { ${[...new Set(names)].sort().join(", ")} } from ${JSON.stringify(from)};`);
|
|
51
51
|
lines.push("", "const json: v.GenericSchema<Json> = v.lazy(() =>", " v.union([v.string(), v.number(), v.boolean(), v.null(), v.array(json), v.record(v.string(), v.optional(json))]),", ");");
|
|
52
52
|
const validators = [];
|
|
@@ -67,8 +67,7 @@ function valibot(options = {}) {
|
|
|
67
67
|
validatorTypes.push(` readonly ${propertyKey(key)}: { readonly insert: typeof ${insert}; readonly update: typeof ${update} };`);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
lines.push("", "/** Write validators for the validation plugin. */");
|
|
71
|
-
lines.push("export const validators: {", ...validatorTypes, "} = {", ...validators, "};", "");
|
|
70
|
+
lines.push("", "/** Write validators for the validation plugin. */", "export const validators: {", ...validatorTypes, "} = {", ...validators, "};", "");
|
|
72
71
|
return [{
|
|
73
72
|
path,
|
|
74
73
|
contents: lines.join("\n")
|
|
@@ -87,7 +86,8 @@ function scalar(kind) {
|
|
|
87
86
|
case "boolean": return "z.boolean()";
|
|
88
87
|
case "datetime": return "z.iso.datetime({ offset: true })";
|
|
89
88
|
case "date": return "z.iso.date()";
|
|
90
|
-
case "
|
|
89
|
+
case "instant": return "z.instanceof(Temporal.Instant)";
|
|
90
|
+
case "plainDateTime": return "z.instanceof(Temporal.PlainDateTime)";
|
|
91
91
|
case "bigint": return "z.bigint()";
|
|
92
92
|
case "json": return "z.json()";
|
|
93
93
|
case "enum": return `z.enum([${kind.values.map((value) => JSON.stringify(value)).join(", ")}])`;
|
|
@@ -96,7 +96,7 @@ function scalar(kind) {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
function field(table, plan, jsonImports) {
|
|
99
|
-
let expr = jsonImports.get(`${table}.${plan.column.db}`) ?? (plan.customJson ? `z.custom<NonNullable<RowOf<'${table}'>['${plan.name}']>>((value) => value !== undefined)` : plan.column.storage
|
|
99
|
+
let expr = jsonImports.get(`${table}.${plan.column.db}`) ?? (plan.customJson ? `z.custom<NonNullable<RowOf<'${table}'>['${plan.name}']>>((value) => value !== undefined)` : plan.column.storage === void 0 ? scalar(plan.scalar) : `(z.string() as unknown as z.ZodType<${rowType(table, plan)}>)`);
|
|
100
100
|
if (plan.column.array) expr = `z.array(${expr})`;
|
|
101
101
|
if (plan.nullable) expr = `${expr}.nullable()`;
|
|
102
102
|
if (plan.optional) expr = `${expr}.exactOptional()`;
|
|
@@ -121,9 +121,9 @@ function zod(options = {}) {
|
|
|
121
121
|
const lines = [
|
|
122
122
|
HEADER,
|
|
123
123
|
"import { z } from \"zod\";",
|
|
124
|
-
""
|
|
124
|
+
"",
|
|
125
|
+
`import type { InsertOf, RowOf, UpdateOf } from ${JSON.stringify(input.importPath(path, input.config.output))};`
|
|
125
126
|
];
|
|
126
|
-
lines.push(`import type { InsertOf, RowOf, UpdateOf } from ${JSON.stringify(input.importPath(path, input.config.output))};`);
|
|
127
127
|
for (const [from, names] of imports) lines.push(`import { ${[...new Set(names)].sort().join(", ")} } from ${JSON.stringify(from)};`);
|
|
128
128
|
const validators = [];
|
|
129
129
|
for (const [key, table] of tableEntries(input)) {
|
|
@@ -137,8 +137,7 @@ function zod(options = {}) {
|
|
|
137
137
|
}
|
|
138
138
|
if (variants.includes("Insert")) validators.push(` ${propertyKey(key)}: { insert: ${schemaName(key, "Insert")}, update: ${schemaName(key, "Update")} },`);
|
|
139
139
|
}
|
|
140
|
-
lines.push("", "/** Write validators for the validation plugin. */");
|
|
141
|
-
lines.push("export const validators: {");
|
|
140
|
+
lines.push("", "/** Write validators for the validation plugin. */", "export const validators: {");
|
|
142
141
|
for (const [key, table] of tableEntries(input)) {
|
|
143
142
|
if (!variantsFor(table).includes("Insert")) continue;
|
|
144
143
|
lines.push(` readonly ${propertyKey(key)}: { readonly insert: typeof ${schemaName(key, "Insert")}; readonly update: typeof ${schemaName(key, "Update")} };`);
|
|
@@ -152,126 +151,4 @@ function zod(options = {}) {
|
|
|
152
151
|
};
|
|
153
152
|
}
|
|
154
153
|
//#endregion
|
|
155
|
-
|
|
156
|
-
/** The JSON Schema document for a `json[...].schema` entry. */
|
|
157
|
-
function resolveJsonSchema(source) {
|
|
158
|
-
const standard = source["~standard"];
|
|
159
|
-
if (standard === void 0) return source;
|
|
160
|
-
const jsonSchema = standard.jsonSchema;
|
|
161
|
-
if (typeof jsonSchema?.input !== "function") throw new TypeError("json[...].schema: this Standard Schema library does not implement Standard JSON Schema; pass a JSON Schema object instead");
|
|
162
|
-
return jsonSchema.input({ target: "draft-2020-12" });
|
|
163
|
-
}
|
|
164
|
-
function entitlementsOf(config = {}) {
|
|
165
|
-
const customer = config.customer ?? "organizations.stripe_customer_id";
|
|
166
|
-
const dot = customer.lastIndexOf(".");
|
|
167
|
-
if (dot <= 0) throw new TypeError(`entitlements.customer must be "table.column", got "${customer}"`);
|
|
168
|
-
return {
|
|
169
|
-
table: customer.slice(0, dot),
|
|
170
|
-
column: customer.slice(dot + 1),
|
|
171
|
-
key: config.key ?? "id"
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
function vectorSearchOf(config = {}) {
|
|
175
|
-
return Object.entries(config).map(([table, entry]) => typeof entry === "string" ? {
|
|
176
|
-
table,
|
|
177
|
-
column: entry,
|
|
178
|
-
distance: "cosine"
|
|
179
|
-
} : {
|
|
180
|
-
table,
|
|
181
|
-
column: entry.column,
|
|
182
|
-
distance: entry.distance ?? "cosine"
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
const CONFIG_SCHEMA_URL = "https://unpkg.com/better-supabase/schemas/config-v1.json";
|
|
186
|
-
/** Identity helper that types `better-supabase.config.ts`. */
|
|
187
|
-
function defineConfig(config) {
|
|
188
|
-
return config;
|
|
189
|
-
}
|
|
190
|
-
function pick(value, defaults) {
|
|
191
|
-
if (value === void 0 || value === false) return void 0;
|
|
192
|
-
if (value === true) return defaults;
|
|
193
|
-
return {
|
|
194
|
-
...defaults,
|
|
195
|
-
...value
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
function resolveExpose(entry) {
|
|
199
|
-
if (Array.isArray(entry)) return {
|
|
200
|
-
anon: [],
|
|
201
|
-
authenticated: entry
|
|
202
|
-
};
|
|
203
|
-
const roles = entry;
|
|
204
|
-
return {
|
|
205
|
-
anon: roles.anon ?? [],
|
|
206
|
-
authenticated: roles.authenticated ?? []
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
/** Applies defaults. Paths stay relative to `root`. */
|
|
210
|
-
function resolveConfig(config, root) {
|
|
211
|
-
const output = config.output ?? "src/lib/supabase/generated.ts";
|
|
212
|
-
return {
|
|
213
|
-
root,
|
|
214
|
-
source: config.source ?? {},
|
|
215
|
-
schemas: config.schemas ?? ["public"],
|
|
216
|
-
casing: config.casing ?? "snake",
|
|
217
|
-
tables: config.tables ?? {},
|
|
218
|
-
output,
|
|
219
|
-
databaseTypesOutput: output.replace(/[^/]+$/, "database.types.ts"),
|
|
220
|
-
postgrestVersion: config.postgrestVersion ?? "13",
|
|
221
|
-
json: config.json ?? {},
|
|
222
|
-
codecs: {
|
|
223
|
-
timestamptz: config.codecs?.timestamptz ?? "string",
|
|
224
|
-
int8: config.codecs?.int8 ?? "number",
|
|
225
|
-
numeric: config.codecs?.numeric ?? "number"
|
|
226
|
-
},
|
|
227
|
-
sensitive: config.sensitive ?? [],
|
|
228
|
-
storagePaths: config.storagePaths ?? {},
|
|
229
|
-
expose: Object.fromEntries(Object.entries(config.expose ?? {}).map(([table, entry]) => [table, resolveExpose(entry)])),
|
|
230
|
-
readSets: config.readSets ?? [],
|
|
231
|
-
generators: config.generators ?? [],
|
|
232
|
-
plugins: {
|
|
233
|
-
timestamps: pick(config.plugins?.timestamps, {
|
|
234
|
-
createdAt: "created_at",
|
|
235
|
-
updatedAt: "updated_at"
|
|
236
|
-
}),
|
|
237
|
-
softDelete: pick(config.plugins?.softDelete, { column: "deleted_at" }),
|
|
238
|
-
tenant: pick(config.plugins?.tenant, { column: "organization_id" }),
|
|
239
|
-
actor: pick(config.plugins?.actor, {
|
|
240
|
-
createdBy: "created_by",
|
|
241
|
-
updatedBy: "updated_by"
|
|
242
|
-
})
|
|
243
|
-
},
|
|
244
|
-
claims: {
|
|
245
|
-
...DEFAULT_CLAIMS,
|
|
246
|
-
...config.claims
|
|
247
|
-
},
|
|
248
|
-
buckets: config.buckets ?? {},
|
|
249
|
-
topics: config.topics ?? {},
|
|
250
|
-
realtime: { tables: config.realtime?.tables ?? [] },
|
|
251
|
-
entitlements: entitlementsOf(config.entitlements),
|
|
252
|
-
vectorSearch: vectorSearchOf(config.vectorSearch),
|
|
253
|
-
sql: {
|
|
254
|
-
dir: config.sql?.dir ?? "supabase/schemas",
|
|
255
|
-
prefix: config.sql?.prefix ?? "900_better_supabase",
|
|
256
|
-
testsDir: config.sql?.testsDir ?? "supabase/tests",
|
|
257
|
-
kit: config.sql?.kit ?? []
|
|
258
|
-
},
|
|
259
|
-
seed: {
|
|
260
|
-
entry: config.seed?.entry ?? "supabase/seed.ts",
|
|
261
|
-
output: config.seed?.output ?? "supabase/seeds/000_better_supabase.sql"
|
|
262
|
-
},
|
|
263
|
-
openapi: {
|
|
264
|
-
entry: config.openapi?.entry ?? "src/lib/openapi.ts",
|
|
265
|
-
output: config.openapi?.output ?? "openapi.json"
|
|
266
|
-
},
|
|
267
|
-
doctor: {
|
|
268
|
-
ignore: config.doctor?.ignore ?? [],
|
|
269
|
-
strict: config.doctor?.strict ?? false,
|
|
270
|
-
sources: config.doctor?.sources ?? ["src/**/*.{ts,tsx}"],
|
|
271
|
-
policyHelperLimit: config.doctor?.policyHelperLimit ?? 5,
|
|
272
|
-
...config.doctor?.claimsLimit === void 0 ? {} : { claimsLimit: config.doctor.claimsLimit }
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
//#endregion
|
|
277
|
-
export { zod as a, resolveJsonSchema as i, defineConfig as n, valibot as o, resolveConfig as r, CONFIG_SCHEMA_URL as t };
|
|
154
|
+
export { valibot as n, zod as t };
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { n as dbError, t as DbException } from "./errors-Bl3rkOzo.js";
|
|
2
|
-
import { a as invalidRequest, c as needsDecoding, o as decodeRows, r as IrBuilder, s as encodeValue } from "./simplify-
|
|
3
|
-
import {
|
|
2
|
+
import { a as invalidRequest, c as needsDecoding, o as decodeRows, r as IrBuilder, s as encodeValue } from "./simplify-LakqK1vH.js";
|
|
3
|
+
import { n as nowInstant } from "./temporal-BwshQk0W.js";
|
|
4
|
+
import { i as or, n as column, r as not, t as and } from "./types-6cYK9pbJ.js";
|
|
4
5
|
import { i as ok, n as err, o as toDbError, s as withErrorMapper, t as AsyncResult } from "./result-DWXatkd6.js";
|
|
5
|
-
import { t as invalidationTargets } from "./tables-
|
|
6
|
+
import { t as invalidationTargets } from "./tables-Dhha3BXM.js";
|
|
6
7
|
import { t as consoleLogger } from "./logger-glM28NVN.js";
|
|
7
8
|
import { r as orderPlugins } from "./plugin-BqR6wKMB.js";
|
|
8
|
-
import { a as postgrestExecutor, n as StatsRecorder, r as recordStats } from "./stats-
|
|
9
|
-
import { d as isQuerySpec, f as specTables, n as checkParams, o as isReadSet, r as containsPlaceholder, t as bindParams, u as createSpecs } from "./read-set-
|
|
9
|
+
import { a as postgrestExecutor, n as StatsRecorder, r as recordStats } from "./stats-D78UQ8Yu.js";
|
|
10
|
+
import { d as isQuerySpec, f as specTables, n as checkParams, o as isReadSet, r as containsPlaceholder, t as bindParams, u as createSpecs } from "./read-set-D0qBcboM.js";
|
|
11
|
+
import { a as toBase64Url, t as base64ToText } from "./base64-CQeB1eSf.js";
|
|
10
12
|
import { t as validate } from "./standard-FUi3Z3-7.js";
|
|
11
13
|
//#region src/core/batch.ts
|
|
12
14
|
/**
|
|
@@ -129,27 +131,13 @@ var EventHub = class {
|
|
|
129
131
|
};
|
|
130
132
|
//#endregion
|
|
131
133
|
//#region src/core/cursor.ts
|
|
132
|
-
const encoder = new TextEncoder();
|
|
133
|
-
const decoder = new TextDecoder();
|
|
134
|
-
function toBase64Url(bytes) {
|
|
135
|
-
let binary = "";
|
|
136
|
-
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
137
|
-
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
138
|
-
}
|
|
139
|
-
function fromBase64Url(text) {
|
|
140
|
-
const base64 = text.replace(/-/g, "+").replace(/_/g, "/");
|
|
141
|
-
const binary = atob(base64 + "=".repeat((4 - base64.length % 4) % 4));
|
|
142
|
-
const bytes = new Uint8Array(binary.length);
|
|
143
|
-
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
|
|
144
|
-
return bytes;
|
|
145
|
-
}
|
|
146
134
|
/** Opaque, URL-safe keyset cursor. */
|
|
147
135
|
function encodeCursor(values) {
|
|
148
|
-
return toBase64Url(
|
|
136
|
+
return toBase64Url(JSON.stringify(values));
|
|
149
137
|
}
|
|
150
138
|
function decodeCursor(cursor) {
|
|
151
139
|
try {
|
|
152
|
-
const parsed = JSON.parse(
|
|
140
|
+
const parsed = JSON.parse(base64ToText(cursor));
|
|
153
141
|
return Array.isArray(parsed) ? parsed : void 0;
|
|
154
142
|
} catch {
|
|
155
143
|
return;
|
|
@@ -233,10 +221,16 @@ var OperationRunner = class {
|
|
|
233
221
|
} : { errorMappers: runtime.errorMappers };
|
|
234
222
|
const executed = await runtime.executor.execute(current, context);
|
|
235
223
|
const selection = current.kind === "select" ? current.selection : current.returning;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
224
|
+
let result = executed;
|
|
225
|
+
if (executed.ok && selection && needsDecoding(selection)) try {
|
|
226
|
+
result = ok({
|
|
227
|
+
...executed.data,
|
|
228
|
+
rows: decodeRows(selection, executed.data.rows)
|
|
229
|
+
});
|
|
230
|
+
} catch (cause) {
|
|
231
|
+
if (cause instanceof DbException) return this.fail(op.table, cause.error);
|
|
232
|
+
throw cause;
|
|
233
|
+
}
|
|
240
234
|
const rows = result.ok ? result.data.rows.length : 0;
|
|
241
235
|
const truncated = current.kind === "select" && current.limit === void 0 && current.single === void 0 && !current.head && rows >= runtime.maxRows;
|
|
242
236
|
if (truncated && !runtime.truncatedTables.has(op.table.key)) {
|
|
@@ -515,10 +509,11 @@ function createRepository(runner, table) {
|
|
|
515
509
|
}
|
|
516
510
|
};
|
|
517
511
|
function insertOp(rows, args, conflict) {
|
|
512
|
+
const built = rows.map((row) => builder.row(table, row));
|
|
518
513
|
return {
|
|
519
514
|
kind: "insert",
|
|
520
515
|
table,
|
|
521
|
-
rows:
|
|
516
|
+
rows: conflict && built.length > 1 ? byKey(built, conflict) : built,
|
|
522
517
|
returning: returning(args),
|
|
523
518
|
onConflict: conflict ? {
|
|
524
519
|
columns: conflict,
|
|
@@ -572,7 +567,7 @@ function createRepository(runner, table) {
|
|
|
572
567
|
if (typeof args["after"] === "string") {
|
|
573
568
|
const values = decodeCursor(args["after"]);
|
|
574
569
|
if (!values || values.length !== orderBy.length) return runner.fail(table, dbError("invalid_request", "Invalid cursor"));
|
|
575
|
-
after = keysetCondition(orderBy, values);
|
|
570
|
+
after = keysetCondition(orderBy, values, (name) => Object.values(table.columns).find((meta) => meta.db === name)?.nullable ?? true);
|
|
576
571
|
}
|
|
577
572
|
const op = selectOp(args, {
|
|
578
573
|
selection: withSort,
|
|
@@ -634,24 +629,47 @@ function strip(row, keys) {
|
|
|
634
629
|
for (const key of keys) delete copy[key];
|
|
635
630
|
return copy;
|
|
636
631
|
}
|
|
637
|
-
/**
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
632
|
+
/**
|
|
633
|
+
* Rows in conflict-key order, so concurrent upserts lock the same rows in
|
|
634
|
+
* the same order instead of deadlocking.
|
|
635
|
+
*/
|
|
636
|
+
function byKey(rows, columns) {
|
|
637
|
+
const compare = (left, right) => {
|
|
638
|
+
if (left === right) return 0;
|
|
639
|
+
if (left === null || left === void 0) return 1;
|
|
640
|
+
if (right === null || right === void 0) return -1;
|
|
641
|
+
if (typeof left === "number" && typeof right === "number") return left - right;
|
|
642
|
+
if (typeof left === "bigint" && typeof right === "bigint") return left < right ? -1 : 1;
|
|
643
|
+
const a = String(left);
|
|
644
|
+
const b = String(right);
|
|
645
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
646
|
+
};
|
|
647
|
+
return [...rows].sort((left, right) => {
|
|
648
|
+
for (const column of columns) {
|
|
649
|
+
const order = compare(left[column], right[column]);
|
|
650
|
+
if (order !== 0) return order;
|
|
651
|
+
}
|
|
652
|
+
return 0;
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* The rows after the cursor `values` in `orderBy` order, as an OR of ANDs:
|
|
657
|
+
* `a > x or (a = x and b > y)`. The SQL compiler sends that shape as the row
|
|
658
|
+
* comparison `(a, b) > (x, y)`. Nulls sort where Postgres puts them: last
|
|
659
|
+
* for `asc`, first for `desc`, unless the term says otherwise.
|
|
660
|
+
*/
|
|
661
|
+
function keysetCondition(orderBy, values, nullable) {
|
|
662
|
+
const isNull = (name) => column(name, "is", null);
|
|
663
|
+
const branches = orderBy.flatMap((term, index) => {
|
|
664
|
+
const value = values[index];
|
|
665
|
+
const nullsFirst = (term.nulls ?? (term.direction === "desc" ? "first" : "last")) === "first";
|
|
666
|
+
const after = column(term.column, term.direction === "asc" ? "gt" : "lt", value);
|
|
667
|
+
const step = value === null ? nullsFirst ? not(isNull(term.column)) : void 0 : nullsFirst || !nullable(term.column) ? after : or(after, isNull(term.column));
|
|
668
|
+
if (!step) return [];
|
|
669
|
+
const equal = orderBy.slice(0, index).map((prev, prevIndex) => values[prevIndex] === null ? isNull(prev.column) : column(prev.column, "eq", values[prevIndex]));
|
|
670
|
+
return [and(...equal, step) ?? step];
|
|
653
671
|
});
|
|
654
|
-
return or(...branches);
|
|
672
|
+
return branches.length > 0 ? or(...branches) : column(orderBy[0]?.column ?? "", "in", []);
|
|
655
673
|
}
|
|
656
674
|
//#endregion
|
|
657
675
|
//#region src/core/search.ts
|
|
@@ -796,7 +814,9 @@ var BetterSupabase = class BetterSupabase {
|
|
|
796
814
|
const invalidate = (target) => {
|
|
797
815
|
try {
|
|
798
816
|
const pending = adapter.invalidate(target);
|
|
799
|
-
if (pending) pending.catch((cause) =>
|
|
817
|
+
if (pending) pending.catch((cause) => {
|
|
818
|
+
report(cause, target.table);
|
|
819
|
+
});
|
|
800
820
|
} catch (cause) {
|
|
801
821
|
report(cause, target.table);
|
|
802
822
|
}
|
|
@@ -831,7 +851,7 @@ var BetterSupabase = class BetterSupabase {
|
|
|
831
851
|
context,
|
|
832
852
|
events,
|
|
833
853
|
errorMappers,
|
|
834
|
-
now: this.options.now ??
|
|
854
|
+
now: this.options.now ?? nowInstant,
|
|
835
855
|
maxRows: this.options.maxRows ?? 1e3,
|
|
836
856
|
truncatedTables: this.#truncatedTables
|
|
837
857
|
});
|
|
@@ -985,15 +1005,15 @@ var BetterSupabase = class BetterSupabase {
|
|
|
985
1005
|
const rows = entry.rows ?? [];
|
|
986
1006
|
const result = await runSpec(this.#db(client, {
|
|
987
1007
|
name: "read-set",
|
|
988
|
-
execute:
|
|
1008
|
+
execute: (op) => {
|
|
989
1009
|
if (op.kind === "select" && op.single) {
|
|
990
|
-
if (rows.length > 1) return err(dbError("multiple_rows", `Expected one ${op.table.key} row`));
|
|
991
|
-
if (rows.length === 0 && op.single === "one") return err(dbError("not_found", `No ${op.table.key} row matched`));
|
|
1010
|
+
if (rows.length > 1) return Promise.resolve(err(dbError("multiple_rows", `Expected one ${op.table.key} row`)));
|
|
1011
|
+
if (rows.length === 0 && op.single === "one") return Promise.resolve(err(dbError("not_found", `No ${op.table.key} row matched`)));
|
|
992
1012
|
}
|
|
993
|
-
return ok({
|
|
1013
|
+
return Promise.resolve(ok({
|
|
994
1014
|
rows,
|
|
995
1015
|
count: entry.count ?? null
|
|
996
|
-
});
|
|
1016
|
+
}));
|
|
997
1017
|
}
|
|
998
1018
|
}, context, [], new StatsRecorder(), new EventHub(this.events.logger)), spec, void 0);
|
|
999
1019
|
if (!result.ok) return result;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import { g as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { a as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { A as SchemaMeta, C as PrimaryKeyValue, D as Relations, E as RelationTypes, I as UniqueKeyName, L as UniqueWhere, N as TableKey, O as Row, P as TableMeta, R as Update, g as Insert, j as Simplify, k as Schema, n as AnyModels, t as AnyFunctions } from "./types-DONv9SHN.js";
|
|
3
|
+
import { g as Operation, l as CountMode, r as Executor } from "./executor-DynmIWhq.js";
|
|
4
|
+
import { p as DbError, s as ThrowMapper, t as AsyncResult, v as ErrorMapper } from "./result-c2OYgCV2.js";
|
|
5
|
+
import { a as EventHub, f as Logger, i as EventHandler, o as EventName, s as MutationNotice, u as RpcNotice } from "./events-Do8jXh4D.js";
|
|
6
|
+
import { a as ExtensionOf, g as WithExtension, h as RequestContext, n as AnyPlugin, r as ApplyExtension } from "./plugin-DVRB8qNE.js";
|
|
7
|
+
import { t as StandardSchemaV1 } from "./standard-eudBiRk1.js";
|
|
8
|
+
import { i as PostgrestPlan } from "./postgrest-DmBlevh-.js";
|
|
8
9
|
//#region src/ir/args.d.ts
|
|
9
10
|
interface BaseOps<V> {
|
|
10
11
|
readonly eq?: V;
|
|
@@ -147,7 +148,7 @@ interface AggregateArgs<M extends AnyModels, T extends keyof M> {
|
|
|
147
148
|
type SelectPart<M extends AnyModels, T extends keyof M, A> = A extends {
|
|
148
149
|
readonly select: readonly (infer K)[];
|
|
149
150
|
} ? Pick<Row<M, T>, Extract<K, keyof Row<M, T>>> : Row<M, T>;
|
|
150
|
-
type RelationPayload<M extends AnyModels, R, V> = R extends
|
|
151
|
+
type RelationPayload<M extends AnyModels, R, V> = R extends RelationTypes ? R["kind"] extends "many" ? Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V>[] : R["nullable"] extends true ? Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V> | null : Payload<M, Extract<R["table"], keyof M>, V extends true ? unknown : V> : never;
|
|
151
152
|
type IncludePart<M extends AnyModels, T extends keyof M, A> = A extends {
|
|
152
153
|
readonly include: infer I;
|
|
153
154
|
} ? { -readonly [R in keyof I & keyof Relations<M, T>]: RelationPayload<M, Relations<M, T>[R], I[R]>; } & CountPart<I> & ([keyof I & MeasureKey] extends [never] ? unknown : RelationMeasures<M, T, I>) : unknown;
|
|
@@ -551,7 +552,7 @@ declare function explainPostgrest(op: Operation): PostgrestPlan;
|
|
|
551
552
|
//#region src/core/define.d.ts
|
|
552
553
|
interface DefineSupabaseOptions {
|
|
553
554
|
/** Clock used by plugins (timestamps, soft delete). */
|
|
554
|
-
readonly now?: () =>
|
|
555
|
+
readonly now?: () => Temporal.Instant;
|
|
555
556
|
/** Extra error mappers, run before plugin mappers. */
|
|
556
557
|
readonly errors?: readonly ErrorMapper[];
|
|
557
558
|
/** Receives errors from event handlers, hooks and cache adapters. Defaults to `console`. */
|
package/dist/edge/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { N as TableKey, n as AnyModels, t as AnyFunctions } from "../types-
|
|
2
|
-
import { t as BetterSupabase } from "../define-
|
|
3
|
-
import { d as ServerContext, f as ServerOptions, l as BetterServer, n as GuardOptions } from "../respond-
|
|
4
|
-
import {
|
|
1
|
+
import { N as TableKey, n as AnyModels, t as AnyFunctions } from "../types-DONv9SHN.js";
|
|
2
|
+
import { t as BetterSupabase } from "../define-DUbydmJa.js";
|
|
3
|
+
import { d as ServerContext, f as ServerOptions, l as BetterServer, n as GuardOptions } from "../respond-DAkPIdTH.js";
|
|
4
|
+
import { a as ResourceRouteOptions } from "../resource-CwVgiI5q.js";
|
|
5
5
|
//#region src/edge/index.d.ts
|
|
6
6
|
export interface CorsOptions {
|
|
7
7
|
/** Allowed origins, or `*`. Defaults to `*`. */
|
package/dist/edge/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as dbError } from "../errors-Bl3rkOzo.js";
|
|
2
|
-
import { a as problemResponse } from "../problem-
|
|
3
|
-
import { i as respond, n as guard, o as createServer, s as extendServer, t as defaultExpose } from "../respond-
|
|
4
|
-
import { t as defineResource } from "../resource-
|
|
2
|
+
import { a as problemResponse } from "../problem-CGt1ADix.js";
|
|
3
|
+
import { i as respond, n as guard, o as createServer, s as extendServer, t as defaultExpose } from "../respond-C44EZAJo.js";
|
|
4
|
+
import { t as defineResource } from "../resource-D30rp0GN.js";
|
|
5
5
|
//#region src/edge/index.ts
|
|
6
6
|
const SUPABASE_CORS_HEADERS = [
|
|
7
7
|
"authorization",
|
|
@@ -54,7 +54,7 @@ function createEdge(sb, options = {}) {
|
|
|
54
54
|
});
|
|
55
55
|
const ctx = await server.context(request, { refresh: handlerOptions.refresh ?? false });
|
|
56
56
|
const instance = new URL(request.url).pathname;
|
|
57
|
-
const denied = guard(ctx.auth, handlerOptions.allow, handlerOptions.aal);
|
|
57
|
+
const denied = guard(ctx.auth, handlerOptions.allow, handlerOptions.aal, handlerOptions.scopes);
|
|
58
58
|
let response;
|
|
59
59
|
try {
|
|
60
60
|
response = denied ? problemResponse(denied, {
|