better-supabase 0.0.0 → 0.1.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.
Files changed (154) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -1
  3. package/bin/better-supabase.js +3 -0
  4. package/dist/casing-da0uRTqt.js +14 -0
  5. package/dist/cli/bin.d.ts +1 -0
  6. package/dist/cli/bin.js +15 -0
  7. package/dist/cli/index.d.ts +226 -0
  8. package/dist/cli/index.js +3 -0
  9. package/dist/cli-CoByWYja.js +6472 -0
  10. package/dist/client/index.d.ts +2 -0
  11. package/dist/client/index.js +112 -0
  12. package/dist/compiler-DL18ukPe.d.ts +14 -0
  13. package/dist/config/index.d.ts +3 -0
  14. package/dist/config/index.js +3 -0
  15. package/dist/config-D-aR2ZoN.js +276 -0
  16. package/dist/define-CTfWw-SS.d.ts +662 -0
  17. package/dist/define-QGkq04oe.js +1068 -0
  18. package/dist/edge/index.d.ts +43 -0
  19. package/dist/edge/index.js +103 -0
  20. package/dist/entitlements-BBg61DQZ.d.ts +20 -0
  21. package/dist/entitlements-BC_khwRy.js +17 -0
  22. package/dist/env/index.d.ts +2 -0
  23. package/dist/env/index.js +2 -0
  24. package/dist/env-BEToab0I.js +204 -0
  25. package/dist/errors-Bl3rkOzo.js +196 -0
  26. package/dist/events/index.d.ts +2 -0
  27. package/dist/events/index.js +2 -0
  28. package/dist/events-2OJsVG_d.d.ts +84 -0
  29. package/dist/events-BuzTgn2D.js +135 -0
  30. package/dist/executor-Bazhgsgq.d.ts +195 -0
  31. package/dist/executor-Bje4suQF.d.ts +25 -0
  32. package/dist/executor-Ceq60hPM.js +89 -0
  33. package/dist/hono/index.d.ts +45 -0
  34. package/dist/hono/index.js +70 -0
  35. package/dist/index-BD6wKthp.d.ts +597 -0
  36. package/dist/index-DQVvHzjW.d.ts +74 -0
  37. package/dist/index-DRid0qIv.d.ts +76 -0
  38. package/dist/index-Dup-nSe9.d.ts +117 -0
  39. package/dist/index-Dy6kuF0P.d.ts +71 -0
  40. package/dist/index-Hf8PP9sP.d.ts +116 -0
  41. package/dist/index-JXHBuS53.d.ts +144 -0
  42. package/dist/index-Nxo3TJcm.d.ts +208 -0
  43. package/dist/index-Sw43J8HG.d.ts +62 -0
  44. package/dist/index-cEeweTeM.d.ts +38 -0
  45. package/dist/index.d.ts +110 -0
  46. package/dist/index.js +42 -0
  47. package/dist/invalidate-DbxuL2jL.js +18 -0
  48. package/dist/jobs/index.d.ts +173 -0
  49. package/dist/jobs/index.js +477 -0
  50. package/dist/json-schema-BbwO2mZg.js +181 -0
  51. package/dist/lint/index.d.ts +75 -0
  52. package/dist/lint/index.js +167 -0
  53. package/dist/list/index.d.ts +2 -0
  54. package/dist/list/index.js +410 -0
  55. package/dist/live-6b9i72Ux.d.ts +180 -0
  56. package/dist/live-D8rV1Ldw.js +168 -0
  57. package/dist/mcp/index.d.ts +105 -0
  58. package/dist/mcp/index.js +330 -0
  59. package/dist/mfa-CpogP66z.js +521 -0
  60. package/dist/mfa-TVia554c.d.ts +44 -0
  61. package/dist/next/image/index.d.ts +34 -0
  62. package/dist/next/image/index.js +40 -0
  63. package/dist/next/index.d.ts +210 -0
  64. package/dist/next/index.js +426 -0
  65. package/dist/openapi/index.d.ts +2 -0
  66. package/dist/openapi/index.js +332 -0
  67. package/dist/orpc/index.d.ts +46 -0
  68. package/dist/orpc/index.js +50 -0
  69. package/dist/otel/index.d.ts +40 -0
  70. package/dist/otel/index.js +168 -0
  71. package/dist/path-Cv__-OTj.d.ts +17 -0
  72. package/dist/plugin-BqR6wKMB.js +23 -0
  73. package/dist/plugin-HvGqCurB.d.ts +118 -0
  74. package/dist/plugins/actor/index.d.ts +13 -0
  75. package/dist/plugins/actor/index.js +43 -0
  76. package/dist/plugins/rules/index.d.ts +88 -0
  77. package/dist/plugins/rules/index.js +174 -0
  78. package/dist/plugins/soft-delete/index.d.ts +38 -0
  79. package/dist/plugins/soft-delete/index.js +69 -0
  80. package/dist/plugins/tenant/index.d.ts +43 -0
  81. package/dist/plugins/tenant/index.js +73 -0
  82. package/dist/plugins/timestamps/index.d.ts +9 -0
  83. package/dist/plugins/timestamps/index.js +37 -0
  84. package/dist/plugins/validation/index.d.ts +24 -0
  85. package/dist/plugins/validation/index.js +59 -0
  86. package/dist/pool-BFeqzwQS.d.ts +37 -0
  87. package/dist/postgres/index.d.ts +28 -0
  88. package/dist/postgres/index.js +79 -0
  89. package/dist/postgrest-Dm-vhY6R.d.ts +43 -0
  90. package/dist/problem-DPu6Fh-t.js +97 -0
  91. package/dist/problem-DlgB0lYl.d.ts +47 -0
  92. package/dist/query/index.d.ts +2 -0
  93. package/dist/query/index.js +3 -0
  94. package/dist/query-ChvDbsDE.js +186 -0
  95. package/dist/react/index.d.ts +7 -0
  96. package/dist/react/index.js +5 -0
  97. package/dist/react/server.d.ts +13 -0
  98. package/dist/react/server.js +25 -0
  99. package/dist/react/session.d.ts +2 -0
  100. package/dist/react/session.js +3 -0
  101. package/dist/react-CrOvrnIP.js +241 -0
  102. package/dist/read-set-DhX2d04c.js +216 -0
  103. package/dist/realtime/index.d.ts +3 -0
  104. package/dist/realtime/index.js +253 -0
  105. package/dist/resolve-DW8h9NPm.d.ts +155 -0
  106. package/dist/resource-CYiu6Ygi.js +175 -0
  107. package/dist/resource-SkPTRJDD.d.ts +65 -0
  108. package/dist/respond-4-dhoV7x.js +380 -0
  109. package/dist/respond-PoTpy5DT.d.ts +169 -0
  110. package/dist/result-CTkCZ6JA.d.ts +198 -0
  111. package/dist/result-DWXatkd6.js +103 -0
  112. package/dist/scope-CDHcS7dE.js +90 -0
  113. package/dist/seed-CzecODcJ.js +101 -0
  114. package/dist/server/index.d.ts +42 -0
  115. package/dist/server/index.js +68 -0
  116. package/dist/session-C3osL21k.d.ts +21 -0
  117. package/dist/session-CD-3orO_.js +19 -0
  118. package/dist/shared-_6-uPL7E.js +57 -0
  119. package/dist/simplify-oHiDKRVQ.js +665 -0
  120. package/dist/spec-pins-CJPVghHy.d.ts +20 -0
  121. package/dist/spec-pins-t6sPaHvl.js +20 -0
  122. package/dist/sql-M8l3fnS0.js +260 -0
  123. package/dist/ssr/index.d.ts +5 -0
  124. package/dist/ssr/index.js +4 -0
  125. package/dist/standard-CyhRzctb.d.ts +7 -0
  126. package/dist/standard-FUi3Z3-7.js +21 -0
  127. package/dist/stats-3iy8u3_P.js +566 -0
  128. package/dist/storage/index.d.ts +4 -0
  129. package/dist/storage/index.js +2 -0
  130. package/dist/storage-BWXVUXGk.js +461 -0
  131. package/dist/tables-rZxRxNPW.js +59 -0
  132. package/dist/template-BeOGnynM.js +93 -0
  133. package/dist/template-mbvlysOo.d.ts +6 -0
  134. package/dist/testing/index.d.ts +294 -0
  135. package/dist/testing/index.js +751 -0
  136. package/dist/types-6cYK9pbJ.js +29 -0
  137. package/dist/types-C2fslP1z.d.ts +195 -0
  138. package/dist/version-Cqq1m3UY.js +4 -0
  139. package/dist/view-B0ltUmTi.d.ts +43 -0
  140. package/dist/view-B6F9QbG-.js +35 -0
  141. package/dist/webhooks/index.d.ts +152 -0
  142. package/dist/webhooks/index.js +2 -0
  143. package/dist/webhooks-DbMTJJX2.js +139 -0
  144. package/package.json +246 -17
  145. package/schemas/config-v1.json +328 -0
  146. package/schemas/doctor-report-v1.json +105 -0
  147. package/schemas/snapshot-v2.json +1002 -0
  148. package/skills/better-supabase/SKILL.md +84 -0
  149. package/skills/better-supabase/references/plugins.md +56 -0
  150. package/skills/better-supabase/references/troubleshooting.md +39 -0
  151. package/skills/better-supabase-api/SKILL.md +67 -0
  152. package/skills/better-supabase-api/references/adapters.md +108 -0
  153. package/skills/better-supabase-testing/SKILL.md +65 -0
  154. package/index.js +0 -1
@@ -0,0 +1,2 @@
1
+ import { a as BrowserOptions, i as BrowserAuth, n as AuthUser, o as createBrowser, r as BetterBrowser, t as AuthSnapshot } from "../index-Sw43J8HG.js";
2
+ export { AuthSnapshot, AuthUser, BetterBrowser, BrowserAuth, BrowserOptions, createBrowser };
@@ -0,0 +1,112 @@
1
+ import { a as parseEnv, n as EnvValidationError } from "../env-BEToab0I.js";
2
+ import { t as createQueries } from "../query-ChvDbsDE.js";
3
+ import { createBrowserClient } from "@supabase/ssr";
4
+ import { createClient } from "@supabase/supabase-js";
5
+ //#region src/client/index.ts
6
+ const LOADING = {
7
+ status: "loading",
8
+ user: null,
9
+ claims: null
10
+ };
11
+ const SIGNED_OUT = {
12
+ status: "signed-out",
13
+ user: null,
14
+ claims: null
15
+ };
16
+ function decodeClaims(token) {
17
+ const part = token.split(".")[1];
18
+ if (!part) return {};
19
+ try {
20
+ const bytes = Uint8Array.from(atob(part.replace(/-/g, "+").replace(/_/g, "/")), (char) => char.charCodeAt(0));
21
+ const parsed = JSON.parse(new TextDecoder().decode(bytes));
22
+ return typeof parsed === "object" && parsed !== null ? parsed : {};
23
+ } catch {
24
+ return {};
25
+ }
26
+ }
27
+ function snapshotOf(session) {
28
+ if (!session) return SIGNED_OUT;
29
+ const claims = decodeClaims(session.access_token);
30
+ const role = typeof claims["role"] === "string" ? claims["role"] : session.user.role;
31
+ return {
32
+ status: "signed-in",
33
+ user: {
34
+ id: session.user.id,
35
+ ...session.user.email ? { email: session.user.email } : {},
36
+ ...role ? { role } : {}
37
+ },
38
+ claims
39
+ };
40
+ }
41
+ function contextOf(snapshot) {
42
+ if (snapshot.status !== "signed-in") return {
43
+ actor: {
44
+ id: "anon",
45
+ kind: "anon",
46
+ role: "anon"
47
+ },
48
+ claims: { role: "anon" }
49
+ };
50
+ return {
51
+ actor: {
52
+ id: snapshot.user.id,
53
+ kind: "user",
54
+ ...snapshot.user.role ? { role: snapshot.user.role } : {},
55
+ ...snapshot.user.email ? { email: snapshot.user.email } : {}
56
+ },
57
+ claims: snapshot.claims
58
+ };
59
+ }
60
+ function clientFor(options) {
61
+ if (options.client) return options.client;
62
+ if (!options.env) throw new TypeError("createBrowser needs `env` ({ url, publishableKey }) or `client`");
63
+ const checked = parseEnv({
64
+ SUPABASE_URL: options.env.url,
65
+ SUPABASE_PUBLISHABLE_KEY: options.env.publishableKey
66
+ });
67
+ if (!checked.ok) throw new EnvValidationError(checked.issues);
68
+ if (options.storage === "local") return createClient(checked.env.url, checked.env.publishableKey);
69
+ return createBrowserClient(checked.env.url, checked.env.publishableKey);
70
+ }
71
+ /**
72
+ * The browser side: a supabase-js client, repositories that follow the
73
+ * session, TanStack Query options and an auth store for UI state.
74
+ *
75
+ * ```ts
76
+ * export const browser = createBrowser(sb, { env: { url, publishableKey } });
77
+ * ```
78
+ */
79
+ function createBrowser(sb, options = {}) {
80
+ const supabase = clientFor(options);
81
+ let snapshot = LOADING;
82
+ let db;
83
+ const listeners = /* @__PURE__ */ new Set();
84
+ supabase.auth.onAuthStateChange((_event, session) => {
85
+ const next = snapshotOf(session);
86
+ if (!(next.status !== snapshot.status || next.user?.id !== snapshot.user?.id || next.status === "signed-in" && snapshot.status === "signed-in" && next.claims["exp"] !== snapshot.claims["exp"])) return;
87
+ snapshot = next;
88
+ db = void 0;
89
+ for (const listener of listeners) listener();
90
+ });
91
+ const browser = {
92
+ sb,
93
+ supabase,
94
+ get db() {
95
+ db ??= sb.connect(supabase, contextOf(snapshot));
96
+ return db;
97
+ },
98
+ queries: createQueries(sb, () => browser.db),
99
+ auth: {
100
+ current: () => snapshot,
101
+ subscribe: (listener) => {
102
+ listeners.add(listener);
103
+ return () => {
104
+ listeners.delete(listener);
105
+ };
106
+ }
107
+ }
108
+ };
109
+ return browser;
110
+ }
111
+ //#endregion
112
+ export { createBrowser };
@@ -0,0 +1,14 @@
1
+ import { g as Operation } from "./executor-Bazhgsgq.js";
2
+ import { i as PostgrestPlan } from "./postgrest-Dm-vhY6R.js";
3
+ //#region src/core/compiler.d.ts
4
+ /**
5
+ * Turns an IR operation into something a backend runs. An `Executor` for a
6
+ * new backend usually pairs with a `Compiler` for it.
7
+ */
8
+ interface Compiler<TTarget> {
9
+ readonly target: string;
10
+ compile(op: Operation): TTarget;
11
+ }
12
+ declare const postgrestCompiler: Compiler<PostgrestPlan>;
13
+ //#endregion
14
+ export { postgrestCompiler as n, Compiler as t };
@@ -0,0 +1,3 @@
1
+ import { A as resolveConfig, C as SqlConfig, D as VectorDistance, E as TimestampsConfig, F as valibot, I as JsonSchemaGeneratorOptions, L as buildJsonSchema, M as ZodGeneratorOptions, N as zod, O as VectorSearchConfig, P as ValibotGeneratorOptions, R as jsonSchema, S as SourceConfig, T as TenantConfig, _ as RealtimeConfig, a as CodecsConfig, b as SeedConfig, c as ExposeConfig, d as GeneratorInput, f as JsonSchemaSource, g as Privilege, h as PluginFlagsConfig, i as CONFIG_SCHEMA_URL, j as resolveJsonSchema, k as defineConfig, l as GeneratedFile, m as OpenApiConfig, n as BetterSupabaseConfig, o as DoctorConfig, p as JsonTypeConfig, r as BucketConfig, s as EntitlementsConfig, t as ActorConfig, u as Generator, v as ResolvedConfig, w as TableConfig, x as SoftDeleteConfig, y as ResolvedExpose } from "../index-BD6wKthp.js";
2
+ import { i as Casing } from "../types-C2fslP1z.js";
3
+ export { ActorConfig, BetterSupabaseConfig, BucketConfig, CONFIG_SCHEMA_URL, type Casing, CodecsConfig, DoctorConfig, EntitlementsConfig, ExposeConfig, GeneratedFile, Generator, GeneratorInput, type JsonSchemaGeneratorOptions, JsonSchemaSource, JsonTypeConfig, OpenApiConfig, PluginFlagsConfig, Privilege, RealtimeConfig, ResolvedConfig, ResolvedExpose, SeedConfig, SoftDeleteConfig, SourceConfig, SqlConfig, TableConfig, TenantConfig, TimestampsConfig, type ValibotGeneratorOptions, VectorDistance, VectorSearchConfig, type ZodGeneratorOptions, buildJsonSchema, defineConfig, jsonSchema, resolveConfig, resolveJsonSchema, valibot, zod };
@@ -0,0 +1,3 @@
1
+ import { n as jsonSchema, t as buildJsonSchema } from "../json-schema-BbwO2mZg.js";
2
+ import { a as zod, i as resolveJsonSchema, n as defineConfig, o as valibot, r as resolveConfig, t as CONFIG_SCHEMA_URL } from "../config-D-aR2ZoN.js";
3
+ export { CONFIG_SCHEMA_URL, buildJsonSchema, defineConfig, jsonSchema, resolveConfig, resolveJsonSchema, valibot, zod };
@@ -0,0 +1,276 @@
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-BbwO2mZg.js";
2
+ //#region src/generators/valibot.ts
3
+ function scalar$1(kind) {
4
+ switch (kind.kind) {
5
+ case "uuid": return "v.pipe(v.string(), v.uuid())";
6
+ case "string": return "v.string()";
7
+ case "integer": return "v.pipe(v.number(), v.integer())";
8
+ case "number": return "v.number()";
9
+ case "boolean": return "v.boolean()";
10
+ case "datetime": return "v.pipe(v.string(), v.isoTimestamp())";
11
+ case "date": return "v.pipe(v.string(), v.isoDate())";
12
+ case "dateObject": return "v.date()";
13
+ case "bigint": return "v.bigint()";
14
+ case "json": return "json";
15
+ case "enum": return `v.picklist([${kind.values.map((value) => JSON.stringify(value)).join(", ")}])`;
16
+ case "unknown": return "v.unknown()";
17
+ default: return kind;
18
+ }
19
+ }
20
+ function field$1(table, plan, jsonImports) {
21
+ const imported = jsonImports.get(`${table}.${plan.column.db}`);
22
+ let expr = imported ? imported : plan.customJson ? `v.custom<NonNullable<RowOf<'${table}'>['${plan.name}']>>((value) => value !== undefined)` : plan.column.storage !== void 0 ? `(v.string() as unknown as v.GenericSchema<${rowType(table, plan)}>)` : scalar$1(plan.scalar);
23
+ if (plan.column.array) expr = `v.array(${expr})`;
24
+ if (plan.nullable) expr = `v.nullable(${expr})`;
25
+ if (plan.optional) expr = `v.exactOptional(${expr})`;
26
+ return ` ${propertyKey(plan.name)}: ${expr},`;
27
+ }
28
+ /** Valibot schemas for every table's Row, Insert and Update shape. */
29
+ function valibot(options = {}) {
30
+ return {
31
+ name: "valibot",
32
+ generate(input) {
33
+ const path = options.output ?? siblingPath(input.config.output, "valibot.ts");
34
+ const imports = /* @__PURE__ */ new Map();
35
+ const jsonImports = /* @__PURE__ */ new Map();
36
+ const tableNames = new Map(Object.values(input.meta.tables).map((t) => [t.name, t.key]));
37
+ for (const [key, spec] of Object.entries(options.json ?? {})) {
38
+ const [tableName, column] = key.split(".");
39
+ const { from, name } = parseImport(spec);
40
+ const specifier = from.startsWith(".") ? input.importPath(path, from) : from;
41
+ imports.set(specifier, [...imports.get(specifier) ?? [], name]);
42
+ jsonImports.set(`${tableNames.get(tableName ?? "") ?? tableName}.${column}`, name);
43
+ }
44
+ const lines = [
45
+ HEADER,
46
+ "import * as v from \"valibot\";",
47
+ ""
48
+ ];
49
+ lines.push(`import type { InsertOf, Json, RowOf, UpdateOf } from ${JSON.stringify(input.importPath(path, input.config.output))};`);
50
+ for (const [from, names] of imports) lines.push(`import { ${[...new Set(names)].sort().join(", ")} } from ${JSON.stringify(from)};`);
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
+ const validators = [];
53
+ const validatorTypes = [];
54
+ for (const [key, table] of tableEntries(input)) {
55
+ lines.push("");
56
+ const variants = variantsFor(table);
57
+ for (const variant of variants) {
58
+ const name = schemaName(key, variant);
59
+ lines.push(`export const ${name}: v.GenericSchema<${variant}Of<'${key}'>> = v.object({`);
60
+ for (const plan of fieldsFor(table, variant, input)) lines.push(field$1(key, plan, jsonImports));
61
+ lines.push("});");
62
+ }
63
+ if (variants.includes("Insert")) {
64
+ const insert = schemaName(key, "Insert");
65
+ const update = schemaName(key, "Update");
66
+ validators.push(` ${propertyKey(key)}: { insert: ${insert}, update: ${update} },`);
67
+ validatorTypes.push(` readonly ${propertyKey(key)}: { readonly insert: typeof ${insert}; readonly update: typeof ${update} };`);
68
+ }
69
+ }
70
+ lines.push("", "/** Write validators for the validation plugin. */");
71
+ lines.push("export const validators: {", ...validatorTypes, "} = {", ...validators, "};", "");
72
+ return [{
73
+ path,
74
+ contents: lines.join("\n")
75
+ }];
76
+ }
77
+ };
78
+ }
79
+ //#endregion
80
+ //#region src/generators/zod.ts
81
+ function scalar(kind) {
82
+ switch (kind.kind) {
83
+ case "uuid": return "z.guid()";
84
+ case "string": return "z.string()";
85
+ case "integer": return "z.int()";
86
+ case "number": return "z.number()";
87
+ case "boolean": return "z.boolean()";
88
+ case "datetime": return "z.iso.datetime({ offset: true })";
89
+ case "date": return "z.iso.date()";
90
+ case "dateObject": return "z.date()";
91
+ case "bigint": return "z.bigint()";
92
+ case "json": return "z.json()";
93
+ case "enum": return `z.enum([${kind.values.map((value) => JSON.stringify(value)).join(", ")}])`;
94
+ case "unknown": return "z.unknown()";
95
+ default: return kind;
96
+ }
97
+ }
98
+ function field(table, plan, jsonImports) {
99
+ const imported = jsonImports.get(`${table}.${plan.column.db}`);
100
+ let expr = imported ? imported : plan.customJson ? `z.custom<NonNullable<RowOf<'${table}'>['${plan.name}']>>((value) => value !== undefined)` : plan.column.storage !== void 0 ? `(z.string() as unknown as z.ZodType<${rowType(table, plan)}>)` : scalar(plan.scalar);
101
+ if (plan.column.array) expr = `z.array(${expr})`;
102
+ if (plan.nullable) expr = `${expr}.nullable()`;
103
+ if (plan.optional) expr = `${expr}.exactOptional()`;
104
+ return ` ${propertyKey(plan.name)}: ${expr},`;
105
+ }
106
+ /** Zod 4 schemas for every table's Row, Insert and Update shape. */
107
+ function zod(options = {}) {
108
+ return {
109
+ name: "zod",
110
+ generate(input) {
111
+ const path = options.output ?? siblingPath(input.config.output, "zod.ts");
112
+ const imports = /* @__PURE__ */ new Map();
113
+ const jsonImports = /* @__PURE__ */ new Map();
114
+ const tableNames = new Map(Object.values(input.meta.tables).map((t) => [t.name, t.key]));
115
+ for (const [key, spec] of Object.entries(options.json ?? {})) {
116
+ const [tableName, column] = key.split(".");
117
+ const { from, name } = parseImport(spec);
118
+ const specifier = from.startsWith(".") ? input.importPath(path, from) : from;
119
+ imports.set(specifier, [...imports.get(specifier) ?? [], name]);
120
+ jsonImports.set(`${tableNames.get(tableName ?? "") ?? tableName}.${column}`, name);
121
+ }
122
+ const lines = [
123
+ HEADER,
124
+ "import { z } from \"zod\";",
125
+ ""
126
+ ];
127
+ lines.push(`import type { InsertOf, RowOf, UpdateOf } from ${JSON.stringify(input.importPath(path, input.config.output))};`);
128
+ for (const [from, names] of imports) lines.push(`import { ${[...new Set(names)].sort().join(", ")} } from ${JSON.stringify(from)};`);
129
+ const validators = [];
130
+ for (const [key, table] of tableEntries(input)) {
131
+ lines.push("");
132
+ const variants = variantsFor(table);
133
+ for (const variant of variants) {
134
+ const name = schemaName(key, variant);
135
+ lines.push(`export const ${name}: z.ZodType<${variant}Of<'${key}'>> = z.object({`);
136
+ for (const plan of fieldsFor(table, variant, input)) lines.push(field(key, plan, jsonImports));
137
+ lines.push("});");
138
+ }
139
+ if (variants.includes("Insert")) validators.push(` ${propertyKey(key)}: { insert: ${schemaName(key, "Insert")}, update: ${schemaName(key, "Update")} },`);
140
+ }
141
+ lines.push("", "/** Write validators for the validation plugin. */");
142
+ lines.push("export const validators: {");
143
+ for (const [key, table] of tableEntries(input)) {
144
+ if (!variantsFor(table).includes("Insert")) continue;
145
+ lines.push(` readonly ${propertyKey(key)}: { readonly insert: typeof ${schemaName(key, "Insert")}; readonly update: typeof ${schemaName(key, "Update")} };`);
146
+ }
147
+ lines.push("} = {", ...validators, "};", "");
148
+ return [{
149
+ path,
150
+ contents: lines.join("\n")
151
+ }];
152
+ }
153
+ };
154
+ }
155
+ //#endregion
156
+ //#region src/config/index.ts
157
+ /** The JSON Schema document for a `json[...].schema` entry. */
158
+ function resolveJsonSchema(source) {
159
+ const standard = source["~standard"];
160
+ if (standard === void 0) return source;
161
+ const jsonSchema = standard.jsonSchema;
162
+ 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");
163
+ return jsonSchema.input({ target: "draft-2020-12" });
164
+ }
165
+ function entitlementsOf(config = {}) {
166
+ const customer = config.customer ?? "organizations.stripe_customer_id";
167
+ const dot = customer.lastIndexOf(".");
168
+ if (dot <= 0) throw new TypeError(`entitlements.customer must be "table.column", got "${customer}"`);
169
+ return {
170
+ table: customer.slice(0, dot),
171
+ column: customer.slice(dot + 1),
172
+ key: config.key ?? "id"
173
+ };
174
+ }
175
+ function vectorSearchOf(config = {}) {
176
+ return Object.entries(config).map(([table, entry]) => typeof entry === "string" ? {
177
+ table,
178
+ column: entry,
179
+ distance: "cosine"
180
+ } : {
181
+ table,
182
+ column: entry.column,
183
+ distance: entry.distance ?? "cosine"
184
+ });
185
+ }
186
+ const CONFIG_SCHEMA_URL = "https://unpkg.com/better-supabase/schemas/config-v1.json";
187
+ /** Identity helper that types `better-supabase.config.ts`. */
188
+ function defineConfig(config) {
189
+ return config;
190
+ }
191
+ function pick(value, defaults) {
192
+ if (value === void 0 || value === false) return void 0;
193
+ if (value === true) return defaults;
194
+ return {
195
+ ...defaults,
196
+ ...value
197
+ };
198
+ }
199
+ function resolveExpose(entry) {
200
+ if (Array.isArray(entry)) return {
201
+ anon: [],
202
+ authenticated: entry
203
+ };
204
+ const roles = entry;
205
+ return {
206
+ anon: roles.anon ?? [],
207
+ authenticated: roles.authenticated ?? []
208
+ };
209
+ }
210
+ /** Applies defaults. Paths stay relative to `root`. */
211
+ function resolveConfig(config, root) {
212
+ const output = config.output ?? "src/lib/supabase/generated.ts";
213
+ return {
214
+ root,
215
+ source: config.source ?? {},
216
+ schemas: config.schemas ?? ["public"],
217
+ casing: config.casing ?? "snake",
218
+ tables: config.tables ?? {},
219
+ output,
220
+ databaseTypesOutput: output.replace(/[^/]+$/, "database.types.ts"),
221
+ postgrestVersion: config.postgrestVersion ?? "13",
222
+ json: config.json ?? {},
223
+ codecs: {
224
+ timestamptz: config.codecs?.timestamptz ?? "string",
225
+ int8: config.codecs?.int8 ?? "number",
226
+ numeric: config.codecs?.numeric ?? "number"
227
+ },
228
+ sensitive: config.sensitive ?? [],
229
+ storagePaths: config.storagePaths ?? {},
230
+ expose: Object.fromEntries(Object.entries(config.expose ?? {}).map(([table, entry]) => [table, resolveExpose(entry)])),
231
+ readSets: config.readSets ?? [],
232
+ generators: config.generators ?? [],
233
+ plugins: {
234
+ timestamps: pick(config.plugins?.timestamps, {
235
+ createdAt: "created_at",
236
+ updatedAt: "updated_at"
237
+ }),
238
+ softDelete: pick(config.plugins?.softDelete, { column: "deleted_at" }),
239
+ tenant: pick(config.plugins?.tenant, {
240
+ column: "organization_id",
241
+ claim: "org_id"
242
+ }),
243
+ actor: pick(config.plugins?.actor, {
244
+ createdBy: "created_by",
245
+ updatedBy: "updated_by"
246
+ })
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
+ }
273
+ };
274
+ }
275
+ //#endregion
276
+ export { zod as a, resolveJsonSchema as i, defineConfig as n, valibot as o, resolveConfig as r, CONFIG_SCHEMA_URL as t };