better-supabase 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/README.md +37 -33
  2. package/dist/base64-D2gsioCY.js +42 -0
  3. package/dist/claims-BAf6c7is.js +48 -0
  4. package/dist/cli/_format-Cax5EsM9.js +101 -0
  5. package/dist/cli/bin.js +39 -6
  6. package/dist/cli/command-CK14fP91.js +502 -0
  7. package/dist/cli/compare-BmIWVEui.js +9 -0
  8. package/dist/cli/config-D9R0o1LH.js +1895 -0
  9. package/dist/cli/config-SSKSTUl2.js +2 -0
  10. package/dist/cli/db-DOBPt660.js +52 -0
  11. package/dist/cli/dist-B1MvLv-M.js +129 -0
  12. package/dist/cli/dist-CFgGknmZ.js +1112 -0
  13. package/dist/cli/dist-Du7VnEUG.js +621 -0
  14. package/dist/cli/doctor-BOym3mbL.js +2382 -0
  15. package/dist/cli/env-BZ0uy8XK.js +108 -0
  16. package/dist/cli/env-jIFUADLY.js +511 -0
  17. package/dist/cli/errors-4v4DTtda.js +56 -0
  18. package/dist/cli/fastest-levenshtein-CFN-lNDv.js +120 -0
  19. package/dist/cli/gen-Ccn_p90L.js +2008 -0
  20. package/dist/cli/gen-D5cLCULx.js +2 -0
  21. package/dist/cli/index.d.ts +295 -28
  22. package/dist/cli/index.js +184 -3
  23. package/dist/cli/init-ClnxRYBF.js +550 -0
  24. package/dist/cli/introspect-DxqfkVIv.js +81 -0
  25. package/dist/cli/io-k41_z-jT.js +24 -0
  26. package/dist/cli/json5-ChRycquj.js +787 -0
  27. package/dist/cli/jsonc-BUniUpOk.js +2 -0
  28. package/dist/cli/jsonc-D5Fu67jw.js +45 -0
  29. package/dist/cli/keys-ByKHnvP9.js +83 -0
  30. package/dist/cli/ohash-D7bG_EOb.js +277 -0
  31. package/dist/cli/openapi-8WHjxiTJ.js +66 -0
  32. package/dist/cli/project-B_GeXyHh.js +70 -0
  33. package/dist/cli/prompts-BNcNfAve.js +1142 -0
  34. package/dist/cli/prompts-BTYQGunc.js +2 -0
  35. package/dist/cli/read-sets-CMa29t9a.js +971 -0
  36. package/dist/cli/rolldown-runtime-BPOCksWG.js +24 -0
  37. package/dist/cli/run-CP20LKk_.js +347 -0
  38. package/dist/cli/seed-5J6eu_Xg.js +98 -0
  39. package/dist/cli/skills-LJJIhLFR.js +137 -0
  40. package/dist/cli/sql-D4VbqmXi.js +199 -0
  41. package/dist/cli/style-C0NFdJRL.js +29 -0
  42. package/dist/cli/toml-DB-MNnFs.js +424 -0
  43. package/dist/{version-Cqq1m3UY.js → cli/version-5mW_8sY1.js} +1 -1
  44. package/dist/cli/yaml-CYCbJ6et.js +2252 -0
  45. package/dist/client/index.d.ts +2 -2
  46. package/dist/client/index.js +15 -25
  47. package/dist/{compiler-CZ9nIuqy.d.ts → compiler-DB3aSFOA.d.ts} +2 -2
  48. package/dist/config/index.d.ts +4 -3
  49. package/dist/config/index.js +5 -3
  50. package/dist/config-BpxDfnbg.js +129 -0
  51. package/dist/{index-DOsjFvMf.d.ts → config-C1CYcm6o.d.ts} +49 -49
  52. package/dist/{config-ClDXmVtY.js → config-CbvFmGD8.js} +14 -137
  53. package/dist/{define-BXMYD9AY.js → define-Bh0AqTik.js} +221 -120
  54. package/dist/{define-e3zI4_4g.d.ts → define-CRS2MRV3.d.ts} +36 -31
  55. package/dist/edge/index.d.ts +9 -13
  56. package/dist/edge/index.js +51 -25
  57. package/dist/{entitlements-Dng-ctuT.d.ts → entitlements-Dm-FHpNH.d.ts} +2 -2
  58. package/dist/env/index.js +203 -1
  59. package/dist/{errors-Bl3rkOzo.js → errors-L0xK41y_.js} +1 -1
  60. package/dist/events/index.d.ts +1 -1
  61. package/dist/events/index.js +139 -1
  62. package/dist/{events-DOt3nSO-.d.ts → events-B21UOhvP.d.ts} +4 -4
  63. package/dist/{executor-CGdNQ27g.d.ts → executor-B5IoUxLE.d.ts} +2 -2
  64. package/dist/{executor-DeppvirK.js → executor-CVt6dD0B.js} +9 -4
  65. package/dist/{executor-BYXQ9AGn.d.ts → executor-CZ7ImRiD.d.ts} +2 -2
  66. package/dist/hono/index.d.ts +17 -24
  67. package/dist/hono/index.js +11 -11
  68. package/dist/{index-DuP14VHo.d.ts → index-528Ugmyp.d.ts} +30 -10
  69. package/dist/{index-Bw1bwtC0.d.ts → index-BAy4tsAP.d.ts} +28 -15
  70. package/dist/{index-CBDufH1M.d.ts → index-BBdvo-5d.d.ts} +24 -26
  71. package/dist/{index-DbxFr7XG.d.ts → index-BhHEC04r.d.ts} +9 -4
  72. package/dist/index-Cf-D2jk1.d.ts +50 -0
  73. package/dist/{index-Ciu5Xlml.d.ts → index-D5IfUIDh.d.ts} +6 -5
  74. package/dist/{index-K-3WM2Hp.d.ts → index-DFmOpBGC.d.ts} +13 -13
  75. package/dist/{index-D4v7sncu.d.ts → index-RlLXd8dL.d.ts} +13 -13
  76. package/dist/index.d.ts +17 -17
  77. package/dist/index.js +23 -14
  78. package/dist/{invalidate-DbxuL2jL.js → invalidate-CgxmRamI.js} +7 -1
  79. package/dist/jobs/index.d.ts +33 -26
  80. package/dist/jobs/index.js +44 -22
  81. package/dist/{json-schema-BpYqkCKf.js → json-schema-DP6V7cbr.js} +8 -3
  82. package/dist/lint/index.js +1 -1
  83. package/dist/list/index.d.ts +2 -2
  84. package/dist/list/index.js +131 -96
  85. package/dist/{live-DJyZMD6w.d.ts → live-BHakSWWo.d.ts} +26 -16
  86. package/dist/{live-D8rV1Ldw.js → live-CdJBOc4f.js} +13 -9
  87. package/dist/lookup-BaP5bI27.js +18 -0
  88. package/dist/mcp/index.d.ts +34 -27
  89. package/dist/mcp/index.js +59 -25
  90. package/dist/{mfa-TVia554c.d.ts → mfa-C7MNQ1Ob.d.ts} +1 -1
  91. package/dist/{mfa-CpLfJSde.js → mfa-byfjruR9.js} +190 -46
  92. package/dist/next/image/index.js +6 -3
  93. package/dist/next/index.d.ts +64 -48
  94. package/dist/next/index.js +63 -50
  95. package/dist/openapi/index.d.ts +1 -1
  96. package/dist/openapi/index.js +61 -38
  97. package/dist/orpc/index.d.ts +18 -21
  98. package/dist/orpc/index.js +12 -12
  99. package/dist/otel/index.d.ts +5 -5
  100. package/dist/otel/index.js +84 -63
  101. package/dist/{permdock-sql-CghlHPuH.js → permdock-sql-C4KFzLc9.js} +12 -7
  102. package/dist/permdock-sql-DImJULY-.d.ts +17 -0
  103. package/dist/{plugin-C4TR9J0Z.d.ts → plugin-bNhvJwRh.d.ts} +5 -4
  104. package/dist/plugins/actor/index.d.ts +1 -1
  105. package/dist/plugins/actor/index.js +1 -1
  106. package/dist/plugins/rules/index.d.ts +2 -2
  107. package/dist/plugins/rules/index.js +46 -16
  108. package/dist/plugins/soft-delete/index.d.ts +3 -3
  109. package/dist/plugins/soft-delete/index.js +4 -4
  110. package/dist/plugins/tenant/index.d.ts +3 -3
  111. package/dist/plugins/tenant/index.js +10 -4
  112. package/dist/plugins/timestamps/index.d.ts +1 -1
  113. package/dist/plugins/timestamps/index.js +2 -2
  114. package/dist/plugins/validation/index.d.ts +2 -2
  115. package/dist/plugins/validation/index.js +3 -3
  116. package/dist/pool-DFwEQwmN.d.ts +78 -0
  117. package/dist/postgres/index.d.ts +10 -5
  118. package/dist/postgres/index.js +37 -16
  119. package/dist/{postgrest-cAEQ_IQN.d.ts → postgrest-Bc-0Xw62.d.ts} +1 -1
  120. package/dist/{problem-BTkTtRV9.js → problem-BihjPR0t.js} +11 -5
  121. package/dist/{problem-DlgB0lYl.d.ts → problem-U8UEKccv.d.ts} +6 -4
  122. package/dist/query/index.d.ts +2 -2
  123. package/dist/query/index.js +2 -2
  124. package/dist/{query-ChvDbsDE.js → query-BMMSWbI7.js} +19 -19
  125. package/dist/react/index.d.ts +7 -7
  126. package/dist/react/index.js +2 -2
  127. package/dist/react/server.d.ts +6 -6
  128. package/dist/react/server.js +3 -3
  129. package/dist/react/session.d.ts +21 -2
  130. package/dist/react/session.js +19 -1
  131. package/dist/{react-C83BdBGt.js → react-CQHMaESR.js} +59 -55
  132. package/dist/{read-set-4lI3W_gZ.js → read-set-FWK8qQ58.js} +51 -16
  133. package/dist/realtime/index.d.ts +4 -3
  134. package/dist/realtime/index.js +19 -17
  135. package/dist/{index-CG69s15v.d.ts → refresh-BwYkyNOQ.d.ts} +7 -3
  136. package/dist/{resolve-CjHILk2w.d.ts → resolve-BAqQcwMW.d.ts} +17 -11
  137. package/dist/{resource-CgZa3YG_.d.ts → resource-BJcaIfxi.d.ts} +17 -8
  138. package/dist/{resource-BHEWmQJK.js → resource-My_y-Syh.js} +43 -21
  139. package/dist/{respond-Dne1ARSa.d.ts → respond-DgIbdrt8.d.ts} +39 -14
  140. package/dist/{result-DWXatkd6.js → result-Bj6yt33D.js} +2 -2
  141. package/dist/{result-CTkCZ6JA.d.ts → result-CqEsbgYs.d.ts} +16 -11
  142. package/dist/server/index.d.ts +38 -13
  143. package/dist/server/index.js +43 -14
  144. package/dist/{respond-DMcbQwfN.js → server-BA75B0mT.js} +151 -96
  145. package/dist/{shared-_6-uPL7E.js → shared-DnoCdMDr.js} +4 -3
  146. package/dist/{simplify-bwJpLnaS.js → simplify-Cqvfr9dj.js} +76 -39
  147. package/dist/sql/index.d.ts +139 -0
  148. package/dist/sql/index.js +1983 -0
  149. package/dist/{sql-DTjA1LPj.js → sql-B34HU2DI.js} +74 -17
  150. package/dist/ssr/index.d.ts +4 -4
  151. package/dist/ssr/index.js +2 -2
  152. package/dist/{standard-FUi3Z3-7.js → standard-BRyBGTtp.js} +2 -2
  153. package/dist/{standard-CyhRzctb.d.ts → standard-BsaCYQJc.d.ts} +1 -1
  154. package/dist/{stats-C5W-rBfR.js → stats-C_YxA2r1.js} +40 -14
  155. package/dist/storage/index.d.ts +4 -3
  156. package/dist/storage/index.js +548 -1
  157. package/dist/{tables-rZxRxNPW.js → tables-Cb-3_VWc.js} +19 -5
  158. package/dist/temporal-BwshQk0W.js +27 -0
  159. package/dist/temporal-required-CBNHT6ni.js +19 -0
  160. package/dist/testing/index.d.ts +25 -24
  161. package/dist/testing/index.js +165 -66
  162. package/dist/{types-C83v5SQz.d.ts → types-DONv9SHN.d.ts} +14 -11
  163. package/dist/version-Bmf7_FzM.js +4 -0
  164. package/dist/{view-D1s0wa0T.d.ts → view-B64o81wp.d.ts} +36 -6
  165. package/dist/{view-aOYizTeE.js → view-BrJI2LKp.js} +11 -2
  166. package/dist/webhooks/index.d.ts +19 -17
  167. package/dist/webhooks/index.js +1 -1
  168. package/dist/{webhooks-DMipjhSP.js → webhooks-Bh_Jf_-l.js} +45 -24
  169. package/package.json +50 -22
  170. package/schemas/config-v1.json +31 -1
  171. package/schemas/doctor-report-v1.json +17 -1
  172. package/schemas/snapshot-v2.json +35 -0
  173. package/skills/better-supabase/SKILL.md +77 -18
  174. package/skills/better-supabase/references/plugins.md +21 -22
  175. package/skills/better-supabase/references/troubleshooting.md +38 -18
  176. package/skills/better-supabase-api/SKILL.md +66 -18
  177. package/skills/better-supabase-api/references/adapters.md +64 -41
  178. package/skills/better-supabase-auth/SKILL.md +146 -0
  179. package/skills/better-supabase-auth/references/permdock.md +55 -0
  180. package/skills/better-supabase-testing/SKILL.md +68 -11
  181. package/dist/casing-da0uRTqt.js +0 -14
  182. package/dist/claims-CoTobNC-.js +0 -25
  183. package/dist/cli-DrSgDOQC.js +0 -6646
  184. package/dist/env-BEToab0I.js +0 -204
  185. package/dist/events-BuzTgn2D.js +0 -135
  186. package/dist/pool-R2m_DkXi.d.ts +0 -37
  187. package/dist/seed-CzecODcJ.js +0 -101
  188. package/dist/session-C3LxnQ0e.d.ts +0 -22
  189. package/dist/session-CqEwzVup.js +0 -20
  190. package/dist/storage-DuGn38fr.js +0 -527
@@ -0,0 +1,2 @@
1
+ import { t as i } from "./jsonc-D5Fu67jw.js";
2
+ export { i as parseJSONC };
@@ -0,0 +1,45 @@
1
+ import { n as o, t as i$2 } from "./_format-Cax5EsM9.js";
2
+ //#region ../../node_modules/.pnpm/confbox@0.3.1/node_modules/confbox/dist/_chunks/libs/strip-json-comments.mjs
3
+ const e = Symbol(`singleComment`);
4
+ const t = Symbol(`multiComment`);
5
+ const n = () => ``;
6
+ const r = (e, t, n) => e.slice(t, n).replace(/[^ \t\r\n]/g, ` `);
7
+ const i$1 = (e, t) => {
8
+ let n = t - 1, r = 0;
9
+ for (; e[n] === `\\`;) --n, r += 1;
10
+ return !!(r % 2);
11
+ };
12
+ function a(a, { whitespace: o = !0, trailingCommas: s = !1 } = {}) {
13
+ if (typeof a != `string`) throw TypeError(`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof a}\``);
14
+ let c = o ? r : n, l = !1, u = !1, d = 0, f = ``, p = ``, m = -1;
15
+ for (let n = 0; n < a.length; n++) {
16
+ let r = a[n], o = a[n + 1];
17
+ if (!u && r === `"` && (i$1(a, n) || (l = !l)), !l) {
18
+ if (!u && r + o === `//`) f += a.slice(d, n), d = n, u = e, n++;
19
+ else if (u === e && r + o === `\r
20
+ `) {
21
+ n++, u = !1, f += c(a, d, n), d = n;
22
+ continue;
23
+ } else if (u === e && r === `
24
+ `) u = !1, f += c(a, d, n), d = n;
25
+ else if (!u && r + o === `/*`) {
26
+ f += a.slice(d, n), d = n, u = t, n++;
27
+ continue;
28
+ } else if (u === t && r + o === `*/`) {
29
+ n++, u = !1, f += c(a, d, n + 1), d = n + 1;
30
+ continue;
31
+ } else s && !u && (m === -1 ? r === `,` && (p += f + a.slice(d, n), f = ``, d = n, m = n) : r === `}` || r === `]` ? (f += a.slice(d, n), p += c(f, 0, 1) + f.slice(1), f = ``, d = n, m = -1) : r !== ` ` && r !== ` ` && r !== `\r` && r !== `
32
+ ` && (f += a.slice(d, n), d = n, m = -1));
33
+ }
34
+ }
35
+ let h = u === e ? c(a, d) : a.slice(d);
36
+ return p + f + h;
37
+ }
38
+ //#endregion
39
+ //#region ../../node_modules/.pnpm/confbox@0.3.1/node_modules/confbox/dist/jsonc.mjs
40
+ function i(r, i) {
41
+ let a$1 = JSON.parse(a(i$2(r), { trailingCommas: i?.allowTrailingComma }));
42
+ return o(r, a$1, i), a$1;
43
+ }
44
+ //#endregion
45
+ export { i as t };
@@ -0,0 +1,83 @@
1
+ import { r as defineCliCommand } from "./command-CK14fP91.js";
2
+ import { t as display } from "./io-k41_z-jT.js";
3
+ import { dirname, resolve } from "node:path";
4
+ import { existsSync } from "node:fs";
5
+ import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
6
+ //#region src/cli/commands/keys.ts
7
+ const ARGS = {
8
+ out: {
9
+ type: "string",
10
+ description: "Defaults to supabase/signing_keys.json",
11
+ valueHint: "file"
12
+ },
13
+ rotate: {
14
+ type: "boolean",
15
+ description: "Put a new key first (it signs) and keep the old ones (they still verify)"
16
+ },
17
+ force: {
18
+ type: "boolean",
19
+ description: "Replace the file"
20
+ }
21
+ };
22
+ async function createSigningKey() {
23
+ const pair = await crypto.subtle.generateKey({
24
+ name: "ECDSA",
25
+ namedCurve: "P-256"
26
+ }, true, ["sign", "verify"]);
27
+ const jwk = await crypto.subtle.exportKey("jwk", pair.privateKey);
28
+ return {
29
+ kty: "EC",
30
+ kid: crypto.randomUUID(),
31
+ use: "sig",
32
+ key_ops: ["sign", "verify"],
33
+ alg: "ES256",
34
+ ext: true,
35
+ crv: jwk.crv,
36
+ x: jwk.x,
37
+ y: jwk.y,
38
+ d: jwk.d
39
+ };
40
+ }
41
+ async function runKeys(config, args) {
42
+ const out = args.out ?? "supabase/signing_keys.json";
43
+ const path = resolve(config.root, out);
44
+ const rotate = args.rotate === true;
45
+ const exists = existsSync(path);
46
+ if (exists && !rotate && args.force !== true) return {
47
+ code: 1,
48
+ error: `${display(config.root, out)} exists. Use --rotate to add a key or --force to replace it.`
49
+ };
50
+ const previous = exists && rotate ? JSON.parse(await readFile(path, "utf8")) : [];
51
+ if (!Array.isArray(previous)) return {
52
+ code: 1,
53
+ error: `${display(config.root, out)} is not a JSON array of keys.`
54
+ };
55
+ const key = await createSigningKey();
56
+ await mkdir(dirname(path), { recursive: true });
57
+ await writeFile(path, `${JSON.stringify([key, ...previous], null, 2)}\n`, { mode: 384 });
58
+ await chmod(path, 384);
59
+ const lines = [`Wrote ${display(config.root, out)} with key ${key.kid}${previous.length > 0 ? ` (${previous.length} older key${previous.length === 1 ? "" : "s"} kept for verification)` : ""}.`];
60
+ const toml = resolve(config.root, "supabase/config.toml");
61
+ if (!(existsSync(toml) && /^\s*signing_keys_path\s*=/m.test(await readFile(toml, "utf8")))) {
62
+ const relativeToSupabase = out.startsWith("supabase/") ? `./${out.slice(9)}` : out;
63
+ lines.push("", "Add it to supabase/config.toml and restart the stack:", " [auth]", ` signing_keys_path = "${relativeToSupabase}"`);
64
+ }
65
+ const gitignored = [resolve(config.root, ".gitignore"), resolve(config.root, "supabase/.gitignore")];
66
+ let ignored = false;
67
+ for (const file of gitignored) if (existsSync(file) && (await readFile(file, "utf8")).includes("signing_keys")) ignored = true;
68
+ if (!ignored) lines.push("", `Warning: add ${out} to .gitignore; it holds a private key.`);
69
+ return {
70
+ code: 0,
71
+ output: lines.join("\n")
72
+ };
73
+ }
74
+ const keysCommand = defineCliCommand({
75
+ meta: {
76
+ name: "keys",
77
+ description: "Creates an ES256 signing key for the local stack, so local tokens verify through JWKS like hosted ones"
78
+ },
79
+ args: ARGS,
80
+ run: (args, { config }) => runKeys(config, args)
81
+ });
82
+ //#endregion
83
+ export { keysCommand };
@@ -0,0 +1,277 @@
1
+ import { createHash } from "node:crypto";
2
+ //#region ../../node_modules/.pnpm/c12@4.0.0-rc.2_dotenv@17.4.2_jiti@2.7.0_magicast@0.5.5/node_modules/c12/dist/_chunks/libs/ohash.mjs
3
+ var __defProp = Object.defineProperty;
4
+ var __exportAll = (all, no_symbols) => {
5
+ let target = {};
6
+ for (var name in all) __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
11
+ return target;
12
+ };
13
+ function serialize(input) {
14
+ if (typeof input === "string") return `'${input}'`;
15
+ return new Serializer().serialize(input);
16
+ }
17
+ const asciiOrder = " _-,;:!?.'\"()[]{}@*/\\&#%`^+<=>|~$0123456789abcdefghijklmnopqrstuvwxyz";
18
+ const asciiWeights = /*@__PURE__*/ (function() {
19
+ const weights = /* @__PURE__ */ new Uint8Array(128);
20
+ for (let i = 0; i < 69; i++) weights[asciiOrder.charCodeAt(i)] = i + 1;
21
+ for (let code = 65; code <= 90; code++) weights[code] = weights[code + 32];
22
+ return weights;
23
+ })();
24
+ function compareStrings(a, b) {
25
+ if (a === b) return 0;
26
+ const length = Math.min(a.length, b.length);
27
+ let tieBreaker = 0;
28
+ for (let i = 0; i < length; i++) {
29
+ const codeA = a.charCodeAt(i);
30
+ const codeB = b.charCodeAt(i);
31
+ if (codeA === codeB) continue;
32
+ const weightA = codeA < 128 && asciiWeights[codeA] ? asciiWeights[codeA] : codeA + 128;
33
+ const weightB = codeB < 128 && asciiWeights[codeB] ? asciiWeights[codeB] : codeB + 128;
34
+ if (weightA !== weightB) return weightA < weightB ? -1 : 1;
35
+ if (tieBreaker === 0) tieBreaker = codeA > codeB ? -1 : 1;
36
+ }
37
+ if (a.length !== b.length) return a.length < b.length ? -1 : 1;
38
+ return tieBreaker;
39
+ }
40
+ const Serializer = /*@__PURE__*/ (function() {
41
+ class Serializer {
42
+ #context = /* @__PURE__ */ new Map();
43
+ compare(a, b) {
44
+ const typeA = typeof a;
45
+ const typeB = typeof b;
46
+ if (typeA === "string" && typeB === "string") return compareStrings(a, b);
47
+ if (typeA === "number" && typeB === "number") return a - b;
48
+ return compareStrings(this.serialize(a, true), this.serialize(b, true));
49
+ }
50
+ serialize(value, noQuotes) {
51
+ if (value === null) return "null";
52
+ switch (typeof value) {
53
+ case "string": return noQuotes ? value : `'${value}'`;
54
+ case "bigint": return `${value}n`;
55
+ case "object": return this.$object(value);
56
+ case "function": return this.$function(value);
57
+ }
58
+ return String(value);
59
+ }
60
+ serializeObject(object) {
61
+ const objString = Object.prototype.toString.call(object);
62
+ if (objString !== "[object Object]") return this.serializeBuiltInType(objString.length < 10 ? `unknown:${objString}` : objString.slice(8, -1), object);
63
+ const constructor = object.constructor;
64
+ const objName = constructor === Object || constructor === void 0 ? "" : constructor.name;
65
+ if (objName !== "" && globalThis[objName] === constructor) return this.serializeBuiltInType(objName, object);
66
+ if ("toJSON" in object && typeof object.toJSON === "function") {
67
+ const json = object.toJSON();
68
+ return objName + (json !== null && typeof json === "object" ? this.$object(json) : `(${this.serialize(json)})`);
69
+ }
70
+ const keys = Object.keys(object).sort(compareStrings);
71
+ let content = `${objName}{`;
72
+ for (let i = 0; i < keys.length; i++) {
73
+ const key = keys[i];
74
+ content += `${key}:${this.serialize(object[key])}`;
75
+ if (i < keys.length - 1) content += ",";
76
+ }
77
+ return content + "}";
78
+ }
79
+ serializeBuiltInType(type, object) {
80
+ const handler = this["$" + type];
81
+ if (handler) return handler.call(this, object);
82
+ if (typeof object.entries === "function") return this.serializeObjectEntries(type, object.entries());
83
+ throw new Error(`Cannot serialize ${type}`);
84
+ }
85
+ serializeObjectEntries(type, entries) {
86
+ const sortedEntries = Array.from(entries).sort((a, b) => this.compare(a[0], b[0]));
87
+ let content = `${type}{`;
88
+ for (let i = 0; i < sortedEntries.length; i++) {
89
+ const [key, value] = sortedEntries[i];
90
+ content += `${this.serialize(key, true)}:${this.serialize(value)}`;
91
+ if (i < sortedEntries.length - 1) content += ",";
92
+ }
93
+ return content + "}";
94
+ }
95
+ $object(object) {
96
+ let content = this.#context.get(object);
97
+ if (content === void 0) {
98
+ this.#context.set(object, `#${this.#context.size}`);
99
+ content = this.serializeObject(object);
100
+ this.#context.set(object, content);
101
+ }
102
+ return content;
103
+ }
104
+ $function(fn) {
105
+ const fnStr = Function.prototype.toString.call(fn);
106
+ if (fnStr.slice(-15) === "[native code] }") return `${fn.name || ""}()[native]`;
107
+ return `${fn.name}(${fn.length})${fnStr.replace(/\s*\n\s*/g, "")}`;
108
+ }
109
+ $Array(arr) {
110
+ let content = "[";
111
+ for (let i = 0; i < arr.length; i++) {
112
+ content += this.serialize(arr[i]);
113
+ if (i < arr.length - 1) content += ",";
114
+ }
115
+ return content + "]";
116
+ }
117
+ $Date(date) {
118
+ try {
119
+ return `Date(${date.toISOString()})`;
120
+ } catch {
121
+ return `Date(null)`;
122
+ }
123
+ }
124
+ $ArrayBuffer(arr) {
125
+ return `ArrayBuffer[${new Uint8Array(arr).join(",")}]`;
126
+ }
127
+ $Set(set) {
128
+ return `Set${this.$Array(Array.from(set).sort((a, b) => this.compare(a, b)))}`;
129
+ }
130
+ $Map(map) {
131
+ return this.serializeObjectEntries("Map", map.entries());
132
+ }
133
+ }
134
+ for (const type of [
135
+ "Error",
136
+ "RegExp",
137
+ "URL"
138
+ ]) Serializer.prototype["$" + type] = function(val) {
139
+ return `${type}(${val})`;
140
+ };
141
+ for (const type of [
142
+ "Int8Array",
143
+ "Uint8Array",
144
+ "Uint8ClampedArray",
145
+ "Int16Array",
146
+ "Uint16Array",
147
+ "Int32Array",
148
+ "Uint32Array",
149
+ "Float32Array",
150
+ "Float64Array"
151
+ ]) Serializer.prototype["$" + type] = function(arr) {
152
+ return `${type}[${arr.join(",")}]`;
153
+ };
154
+ for (const type of ["BigInt64Array", "BigUint64Array"]) Serializer.prototype["$" + type] = function(arr) {
155
+ return `${type}[${arr.join("n,")}${arr.length > 0 ? "n" : ""}]`;
156
+ };
157
+ return Serializer;
158
+ })();
159
+ const fastHash = /*@__PURE__*/ (() => globalThis.process?.getBuiltinModule?.("crypto")?.hash)();
160
+ const algorithm = "sha256";
161
+ const encoding = "base64url";
162
+ function digest(data) {
163
+ if (fastHash) return fastHash(algorithm, data, encoding);
164
+ const h = createHash(algorithm).update(data);
165
+ return globalThis.process?.versions?.webcontainer ? h.digest().toString(encoding) : h.digest(encoding);
166
+ }
167
+ var dist_exports = /* @__PURE__ */ __exportAll({ digest: () => digest });
168
+ var utils_exports = /* @__PURE__ */ __exportAll({ diff: () => diff });
169
+ const PROTO_KEY = "__proto__";
170
+ function diff(obj1, obj2) {
171
+ const diffs = [];
172
+ _diff(obj1, obj2, "", diffs);
173
+ return diffs;
174
+ }
175
+ function _diff(v1, v2, key, out) {
176
+ if (v1 === v2) return;
177
+ const leaf1 = v1 === null || typeof v1 !== "object";
178
+ const leaf2 = v2 === null || typeof v2 !== "object";
179
+ if (!leaf1 && !leaf2) {
180
+ const entries1 = _entries(v1);
181
+ const entries2 = _entries(v2);
182
+ for (const [k, child1] of entries1) {
183
+ const childKey = key ? `${key}.${k}` : k;
184
+ if (entries2.has(k)) _diff(child1, entries2.get(k), childKey, out);
185
+ else out.push(new DiffEntry(childKey, "removed", void 0, _toHashedObject(child1, childKey)));
186
+ }
187
+ for (const [k, child2] of entries2) {
188
+ if (entries1.has(k)) continue;
189
+ const childKey = key ? `${key}.${k}` : k;
190
+ out.push(new DiffEntry(childKey, "added", _toHashedObject(child2, childKey)));
191
+ }
192
+ return;
193
+ }
194
+ if (_hasKeys(v1, leaf1) || _hasKeys(v2, leaf2)) return;
195
+ const node1 = _emptyOrLeafNode(v1, key, leaf1);
196
+ const node2 = _emptyOrLeafNode(v2, key, leaf2);
197
+ if (node1.hash !== node2.hash) out.push(new DiffEntry(key, "changed", node2, node1));
198
+ }
199
+ function _entries(value) {
200
+ const entries = /* @__PURE__ */ new Map();
201
+ for (const key in value) if (key !== PROTO_KEY) entries.set(key, value[key]);
202
+ return entries;
203
+ }
204
+ function _hasKeys(value, isLeaf) {
205
+ if (isLeaf) return false;
206
+ for (const key in value) if (key !== PROTO_KEY) return true;
207
+ return false;
208
+ }
209
+ function _emptyOrLeafNode(value, key, isLeaf) {
210
+ return isLeaf ? new DiffHashedObject(key, value, _leafHash(value)) : new DiffHashedObject(key, value, "{}", Object.create(null));
211
+ }
212
+ function _toHashedObject(obj, key = "") {
213
+ if (obj === null || typeof obj !== "object") return new DiffHashedObject(key, obj, _leafHash(obj));
214
+ const props = Object.create(null);
215
+ const hashes = [];
216
+ for (const _key in obj) {
217
+ if (_key === PROTO_KEY) continue;
218
+ const child = _toHashedObject(obj[_key], key ? `${key}.${_key}` : _key);
219
+ props[_key] = child;
220
+ hashes.push(child.hash);
221
+ }
222
+ return new DiffHashedObject(key, obj, `{${hashes.join(":")}}`, props);
223
+ }
224
+ function _leafHash(value) {
225
+ switch (typeof value) {
226
+ case "string": return `'${value}'`;
227
+ case "number":
228
+ case "boolean": return "" + value;
229
+ case "bigint": return `${value}n`;
230
+ default: return serialize(value);
231
+ }
232
+ }
233
+ var DiffEntry = class {
234
+ key;
235
+ type;
236
+ newValue;
237
+ oldValue;
238
+ constructor(key, type, newValue, oldValue) {
239
+ this.key = key;
240
+ this.type = type;
241
+ this.newValue = newValue;
242
+ this.oldValue = oldValue;
243
+ }
244
+ toString() {
245
+ return this.toJSON();
246
+ }
247
+ toJSON() {
248
+ switch (this.type) {
249
+ case "added": return `Added \`${this.key}\``;
250
+ case "removed": return `Removed \`${this.key}\``;
251
+ case "changed": return `Changed \`${this.key}\` from \`${this.oldValue?.toString() || "-"}\` to \`${this.newValue?.toString()}\``;
252
+ }
253
+ }
254
+ };
255
+ var DiffHashedObject = class {
256
+ key;
257
+ value;
258
+ hash;
259
+ props;
260
+ constructor(key, value, hash, props) {
261
+ this.key = key;
262
+ this.value = value;
263
+ this.hash = hash;
264
+ this.props = props;
265
+ }
266
+ toString() {
267
+ if (this.props) return `{${Object.keys(this.props).join(",")}}`;
268
+ else return JSON.stringify(this.value);
269
+ }
270
+ toJSON() {
271
+ const k = this.key || ".";
272
+ if (this.props) return `${k}({${Object.keys(this.props).join(",")}})`;
273
+ return `${k}(${this.value})`;
274
+ }
275
+ };
276
+ //#endregion
277
+ export { dist_exports, utils_exports };
@@ -0,0 +1,66 @@
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 { r as importExport } from "./config-D9R0o1LH.js";
4
+ import { resolve } from "node:path";
5
+ import { existsSync } from "node:fs";
6
+ import { readFile } from "node:fs/promises";
7
+ //#region src/cli/commands/openapi.ts
8
+ const ARGS = {
9
+ action: {
10
+ type: "positional",
11
+ required: false,
12
+ description: "emit"
13
+ },
14
+ check: {
15
+ type: "boolean",
16
+ description: "Fail when the file differs from the document"
17
+ },
18
+ entry: {
19
+ type: "string",
20
+ description: "Defaults to openapi.entry. Exports `openapi` or default: a document or a function returning one",
21
+ valueHint: "file"
22
+ },
23
+ out: {
24
+ type: "string",
25
+ description: "Defaults to openapi.output",
26
+ valueHint: "file"
27
+ }
28
+ };
29
+ async function runOpenApi(config, args) {
30
+ const [action] = args._;
31
+ if (action !== "emit") return {
32
+ code: 2,
33
+ error: `${action ? `Unknown openapi action "${action}"` : "Name an action"}. Run \`better-supabase openapi emit\`.`
34
+ };
35
+ const entry = args.entry ?? config.openapi.entry;
36
+ const out = args.out ?? config.openapi.output;
37
+ const exported = await importExport(resolve(config.root, entry), "openapi");
38
+ const document = typeof exported === "function" ? await exported() : exported;
39
+ if (typeof document !== "object" || document === null || !("openapi" in document)) return {
40
+ code: 1,
41
+ error: `${display(config.root, entry)} must export an OpenAPI document (createOpenApi(...)) as \`openapi\` or default.`
42
+ };
43
+ const contents = `${JSON.stringify(document, null, 2)}\n`;
44
+ const path = resolve(config.root, out);
45
+ if (args.check === true) return (existsSync(path) ? await readFile(path, "utf8") : void 0) === contents ? {
46
+ code: 0,
47
+ output: `${display(config.root, out)} is up to date.`
48
+ } : {
49
+ code: 1,
50
+ error: `${display(config.root, out)} is out of date. Run \`better-supabase openapi emit\`.`
51
+ };
52
+ return {
53
+ code: 0,
54
+ output: `${await writeIfChanged(path, contents) ? "Wrote" : "Unchanged"} ${display(config.root, out)}`
55
+ };
56
+ }
57
+ const openapiCommand = defineCliCommand({
58
+ meta: {
59
+ name: "openapi",
60
+ description: "Writes the document your createOpenApi() module exports, so CI can check it for drift"
61
+ },
62
+ args: ARGS,
63
+ run: (args, { config }) => runOpenApi(config, args)
64
+ });
65
+ //#endregion
66
+ export { openapiCommand };
@@ -0,0 +1,70 @@
1
+ import { join } from "node:path";
2
+ import { existsSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ //#region src/cli/project.ts
5
+ const FRAMEWORK_PACKAGES = [
6
+ ["next", "next"],
7
+ ["hono", "hono"],
8
+ ["orpc", "@orpc/server"],
9
+ ["vite", "vite"],
10
+ ["expo", "expo"],
11
+ ["tanstack-query", "@tanstack/react-query"]
12
+ ];
13
+ async function readJson(path) {
14
+ if (!existsSync(path)) return void 0;
15
+ const text = await readFile(path, "utf8");
16
+ try {
17
+ return JSON.parse(text.replaceAll(/^\s*\/\/.*$/gm, "").replaceAll(/,(\s*[}\]])/g, "$1"));
18
+ } catch {
19
+ return;
20
+ }
21
+ }
22
+ function packageManager(root, declared) {
23
+ if (typeof declared === "string") {
24
+ const name = declared.split("@")[0];
25
+ if (name === "pnpm" || name === "npm" || name === "yarn" || name === "bun") return name;
26
+ }
27
+ if (existsSync(join(root, "pnpm-lock.yaml"))) return "pnpm";
28
+ if (existsSync(join(root, "bun.lock")) || existsSync(join(root, "bun.lockb"))) return "bun";
29
+ if (existsSync(join(root, "yarn.lock"))) return "yarn";
30
+ return existsSync(join(root, "package-lock.json")) ? "npm" : "pnpm";
31
+ }
32
+ async function detectProject(root) {
33
+ const pkg = await readJson(join(root, "package.json")) ?? {};
34
+ const dependencies = {};
35
+ for (const field of [
36
+ "peerDependencies",
37
+ "devDependencies",
38
+ "dependencies"
39
+ ]) Object.assign(dependencies, pkg[field] ?? {});
40
+ const options = (await readJson(join(root, "tsconfig.json")))?.["compilerOptions"] ?? {};
41
+ return {
42
+ root,
43
+ name: typeof pkg["name"] === "string" ? pkg["name"] : void 0,
44
+ frameworks: FRAMEWORK_PACKAGES.filter(([, name]) => name in dependencies).map(([framework]) => framework),
45
+ packageManager: packageManager(root, pkg["packageManager"]),
46
+ dependencies,
47
+ srcDir: existsSync(join(root, "src")) ? "src" : ".",
48
+ tsExtensions: options["allowImportingTsExtensions"] === true || options["rewriteRelativeImportExtensions"] === true,
49
+ hasSupabase: existsSync(join(root, "supabase", "config.toml"))
50
+ };
51
+ }
52
+ function installCommand(manager, packages, dev = false) {
53
+ const list = packages.join(" ");
54
+ switch (manager) {
55
+ case "pnpm": return `pnpm add ${dev ? "-D " : ""}${list}`;
56
+ case "bun": return `bun add ${dev ? "-d " : ""}${list}`;
57
+ case "yarn": return `yarn add ${dev ? "-D " : ""}${list}`;
58
+ case "npm": return `npm install ${dev ? "-D " : ""}${list}`;
59
+ default: return manager;
60
+ }
61
+ }
62
+ /** Env variable prefix the framework exposes to the browser. */
63
+ function publicPrefix(project) {
64
+ if (project.frameworks.includes("next")) return "NEXT_PUBLIC_";
65
+ if (project.frameworks.includes("expo")) return "EXPO_PUBLIC_";
66
+ if (project.frameworks.includes("vite")) return "VITE_";
67
+ return "";
68
+ }
69
+ //#endregion
70
+ export { installCommand as n, publicPrefix as r, detectProject as t };