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.
Files changed (139) hide show
  1. package/README.md +34 -31
  2. package/dist/base64-CQeB1eSf.js +42 -0
  3. package/dist/client/index.d.ts +1 -1
  4. package/dist/client/index.js +4 -14
  5. package/dist/{compiler-CZ9nIuqy.d.ts → compiler-2zqGzxVZ.d.ts} +2 -2
  6. package/dist/config/index.d.ts +4 -3
  7. package/dist/config/index.js +5 -3
  8. package/dist/config-Be4GwsqI.js +129 -0
  9. package/dist/{index-DOsjFvMf.d.ts → config-C1CYcm6o.d.ts} +49 -49
  10. package/dist/{config-ClDXmVtY.js → config-DOsGYSiT.js} +14 -137
  11. package/dist/{define-BXMYD9AY.js → define-DF341GDj.js} +71 -51
  12. package/dist/{define-e3zI4_4g.d.ts → define-DUbydmJa.d.ts} +10 -9
  13. package/dist/edge/index.d.ts +4 -4
  14. package/dist/edge/index.js +4 -4
  15. package/dist/{entitlements-Dng-ctuT.d.ts → entitlements-DvJXoI02.d.ts} +1 -1
  16. package/dist/env/index.js +203 -1
  17. package/dist/events/index.d.ts +1 -1
  18. package/dist/events/index.js +139 -1
  19. package/dist/{events-DOt3nSO-.d.ts → events-Do8jXh4D.d.ts} +3 -3
  20. package/dist/{executor-BYXQ9AGn.d.ts → executor-B26lgbHD.d.ts} +2 -2
  21. package/dist/{executor-DeppvirK.js → executor-C57jx2pn.js} +7 -2
  22. package/dist/{executor-CGdNQ27g.d.ts → executor-DynmIWhq.d.ts} +2 -2
  23. package/dist/hono/index.d.ts +5 -5
  24. package/dist/hono/index.js +4 -4
  25. package/dist/{index-CBDufH1M.d.ts → index-BNsABq7P.d.ts} +8 -8
  26. package/dist/{index-Bw1bwtC0.d.ts → index-CADlNHK-.d.ts} +27 -14
  27. package/dist/{index-DuP14VHo.d.ts → index-CTTMS6_1.d.ts} +19 -8
  28. package/dist/index-Cf-D2jk1.d.ts +50 -0
  29. package/dist/{index-K-3WM2Hp.d.ts → index-CriFFJ_p.d.ts} +4 -4
  30. package/dist/{index-Ciu5Xlml.d.ts → index-GV77NpRP.d.ts} +5 -4
  31. package/dist/{index-D4v7sncu.d.ts → index-UJ-LUxtI.d.ts} +3 -3
  32. package/dist/{index-CG69s15v.d.ts → index-kpgopLNv.d.ts} +4 -3
  33. package/dist/{index-DbxFr7XG.d.ts → index-qriRM9cZ.d.ts} +7 -2
  34. package/dist/index.d.ts +12 -12
  35. package/dist/index.js +16 -7
  36. package/dist/jobs/index.d.ts +25 -24
  37. package/dist/jobs/index.js +16 -10
  38. package/dist/{json-schema-BpYqkCKf.js → json-schema--aOXAGfU.js} +7 -2
  39. package/dist/lint/index.js +1 -1
  40. package/dist/list/index.d.ts +2 -2
  41. package/dist/list/index.js +128 -93
  42. package/dist/{live-DJyZMD6w.d.ts → live-QE3UPbGm.d.ts} +16 -6
  43. package/dist/mcp/index.d.ts +24 -17
  44. package/dist/mcp/index.js +41 -12
  45. package/dist/{mfa-CpLfJSde.js → mfa-BxoR1RkN.js} +74 -19
  46. package/dist/{mfa-TVia554c.d.ts → mfa-x3V3vGh-.d.ts} +1 -1
  47. package/dist/next/index.d.ts +39 -26
  48. package/dist/next/index.js +28 -23
  49. package/dist/openapi/index.d.ts +1 -1
  50. package/dist/openapi/index.js +57 -34
  51. package/dist/orpc/index.d.ts +6 -6
  52. package/dist/orpc/index.js +3 -3
  53. package/dist/otel/index.d.ts +2 -2
  54. package/dist/otel/index.js +4 -2
  55. package/dist/{permdock-sql-CghlHPuH.js → permdock-sql-Bta_G0v-.js} +11 -6
  56. package/dist/permdock-sql-DImJULY-.d.ts +17 -0
  57. package/dist/{plugin-C4TR9J0Z.d.ts → plugin-DVRB8qNE.d.ts} +5 -4
  58. package/dist/plugins/actor/index.d.ts +1 -1
  59. package/dist/plugins/rules/index.d.ts +2 -2
  60. package/dist/plugins/rules/index.js +4 -4
  61. package/dist/plugins/soft-delete/index.d.ts +3 -3
  62. package/dist/plugins/soft-delete/index.js +2 -2
  63. package/dist/plugins/tenant/index.d.ts +2 -2
  64. package/dist/plugins/timestamps/index.d.ts +1 -1
  65. package/dist/plugins/timestamps/index.js +1 -1
  66. package/dist/plugins/validation/index.d.ts +2 -2
  67. package/dist/pool-B9qsLyFR.d.ts +71 -0
  68. package/dist/postgres/index.d.ts +10 -5
  69. package/dist/postgres/index.js +36 -16
  70. package/dist/{postgrest-cAEQ_IQN.d.ts → postgrest-DmBlevh-.d.ts} +1 -1
  71. package/dist/{problem-BTkTtRV9.js → problem-CGt1ADix.js} +10 -4
  72. package/dist/{problem-DlgB0lYl.d.ts → problem-Z2RTQjZD.d.ts} +6 -4
  73. package/dist/query/index.d.ts +2 -2
  74. package/dist/query/index.js +1 -1
  75. package/dist/{query-ChvDbsDE.js → query-BdKLTPlj.js} +2 -2
  76. package/dist/react/index.d.ts +7 -7
  77. package/dist/react/index.js +2 -2
  78. package/dist/react/server.d.ts +3 -3
  79. package/dist/react/server.js +1 -1
  80. package/dist/react/session.d.ts +21 -2
  81. package/dist/react/session.js +19 -1
  82. package/dist/{react-C83BdBGt.js → react-DNBYNazu.js} +20 -16
  83. package/dist/{read-set-4lI3W_gZ.js → read-set-D0qBcboM.js} +3 -3
  84. package/dist/realtime/index.d.ts +4 -3
  85. package/dist/realtime/index.js +7 -6
  86. package/dist/{resolve-CjHILk2w.d.ts → resolve-BRciX2jK.d.ts} +6 -5
  87. package/dist/{resource-CgZa3YG_.d.ts → resource-CwVgiI5q.d.ts} +16 -7
  88. package/dist/{resource-BHEWmQJK.js → resource-D30rp0GN.js} +38 -16
  89. package/dist/{respond-DMcbQwfN.js → respond-C44EZAJo.js} +35 -19
  90. package/dist/{respond-Dne1ARSa.d.ts → respond-DAkPIdTH.d.ts} +15 -9
  91. package/dist/{result-CTkCZ6JA.d.ts → result-c2OYgCV2.d.ts} +13 -8
  92. package/dist/server/index.d.ts +35 -10
  93. package/dist/server/index.js +38 -9
  94. package/dist/{simplify-bwJpLnaS.js → simplify-LakqK1vH.js} +10 -16
  95. package/dist/sql/index.d.ts +139 -0
  96. package/dist/sql/index.js +1983 -0
  97. package/dist/{sql-DTjA1LPj.js → sql-BIgk12ew.js} +72 -16
  98. package/dist/ssr/index.d.ts +4 -4
  99. package/dist/ssr/index.js +2 -2
  100. package/dist/{standard-CyhRzctb.d.ts → standard-eudBiRk1.d.ts} +1 -1
  101. package/dist/{stats-C5W-rBfR.js → stats-D78UQ8Yu.js} +8 -7
  102. package/dist/storage/index.d.ts +4 -3
  103. package/dist/storage/index.js +530 -1
  104. package/dist/{tables-rZxRxNPW.js → tables-Dhha3BXM.js} +5 -5
  105. package/dist/temporal-BwshQk0W.js +27 -0
  106. package/dist/temporal-required-CMxeSVPo.js +19 -0
  107. package/dist/testing/index.d.ts +13 -11
  108. package/dist/testing/index.js +128 -29
  109. package/dist/{types-C83v5SQz.d.ts → types-DONv9SHN.d.ts} +14 -11
  110. package/dist/{version-Cqq1m3UY.js → version-BfpG2gks.js} +1 -1
  111. package/dist/{view-D1s0wa0T.d.ts → view-3Po_PVlr.d.ts} +34 -4
  112. package/dist/{view-aOYizTeE.js → view-wZ-9qIUz.js} +11 -2
  113. package/dist/webhooks/index.d.ts +18 -16
  114. package/dist/webhooks/index.js +1 -1
  115. package/dist/{webhooks-DMipjhSP.js → webhooks-CAIFQSTM.js} +11 -9
  116. package/package.json +24 -28
  117. package/schemas/config-v1.json +31 -1
  118. package/schemas/doctor-report-v1.json +17 -1
  119. package/schemas/snapshot-v2.json +35 -0
  120. package/skills/better-supabase/SKILL.md +23 -11
  121. package/skills/better-supabase/references/plugins.md +21 -18
  122. package/skills/better-supabase/references/troubleshooting.md +15 -15
  123. package/skills/better-supabase-api/SKILL.md +7 -7
  124. package/skills/better-supabase-api/references/adapters.md +30 -25
  125. package/skills/better-supabase-testing/SKILL.md +11 -8
  126. package/bin/better-supabase.js +0 -4
  127. package/dist/casing-da0uRTqt.js +0 -14
  128. package/dist/cli/bin.d.ts +0 -1
  129. package/dist/cli/bin.js +0 -15
  130. package/dist/cli/index.d.ts +0 -226
  131. package/dist/cli/index.js +0 -3
  132. package/dist/cli-DrSgDOQC.js +0 -6646
  133. package/dist/env-BEToab0I.js +0 -204
  134. package/dist/events-BuzTgn2D.js +0 -135
  135. package/dist/pool-R2m_DkXi.d.ts +0 -37
  136. package/dist/seed-CzecODcJ.js +0 -101
  137. package/dist/session-C3LxnQ0e.d.ts +0 -22
  138. package/dist/session-CqEwzVup.js +0 -20
  139. package/dist/storage-DuGn38fr.js +0 -527
@@ -1,204 +0,0 @@
1
- //#region src/env/index.ts
2
- const PREFIXES = [
3
- "",
4
- "NEXT_PUBLIC_",
5
- "VITE_",
6
- "PUBLIC_",
7
- "EXPO_PUBLIC_",
8
- "NUXT_PUBLIC_"
9
- ];
10
- const ENV_VARIABLES = {
11
- url: PREFIXES.map((prefix) => `${prefix}SUPABASE_URL`),
12
- publishableKey: PREFIXES.flatMap((prefix) => [`${prefix}SUPABASE_PUBLISHABLE_KEY`, `${prefix}SUPABASE_PUBLISHABLE_DEFAULT_KEY`]),
13
- secretKey: ["SUPABASE_SECRET_KEY"],
14
- dbUrl: ["SUPABASE_DB_URL", "DATABASE_URL"],
15
- jwksUrl: ["SUPABASE_JWKS_URL"],
16
- readUrl: ["SUPABASE_READ_URL"]
17
- };
18
- const LOOPBACK = /^(localhost|127(?:\.\d{1,3}){3}|\[::1\])$/;
19
- const HOSTED = /^([a-z0-9]{20})\.supabase\.co$/;
20
- var EnvValidationError = class extends Error {
21
- name = "EnvValidationError";
22
- issues;
23
- constructor(issues) {
24
- super(`Invalid Supabase environment:\n${issues.map((issue) => ` - ${issue.variables[0] ?? "env"}: ${issue.message}`).join("\n")}`);
25
- this.issues = issues;
26
- }
27
- };
28
- function first(source, names) {
29
- for (const name of names) {
30
- const value = source[name]?.trim();
31
- if (value) return value;
32
- }
33
- }
34
- /** `SUPABASE_*_KEYS` JSON objects, as `@supabase/server` reads them. */
35
- function keySet(source, name, kind, issues) {
36
- const raw = source[name];
37
- if (!raw) return void 0;
38
- let parsed;
39
- try {
40
- parsed = JSON.parse(raw);
41
- } catch {
42
- parsed = void 0;
43
- }
44
- const entries = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? Object.entries(parsed) : [];
45
- if (entries.length === 0 || entries.some(([, value]) => typeof value !== "string")) {
46
- issues.push({
47
- variables: [name],
48
- message: "must be a JSON object of key names to keys"
49
- });
50
- return;
51
- }
52
- const keys = {};
53
- for (const [key, value] of entries) if (checkKey(value, kind, [name], issues)) keys[key] = value;
54
- return keys;
55
- }
56
- function preferred(keys) {
57
- if (!keys) return void 0;
58
- return keys["default"] ?? Object.values(keys)[0];
59
- }
60
- function checkUrl(value, variables, issues) {
61
- let url;
62
- try {
63
- url = new URL(value);
64
- } catch {
65
- issues.push({
66
- variables,
67
- message: "is not a valid URL"
68
- });
69
- return;
70
- }
71
- if (url.protocol === "https:") return url;
72
- if (url.protocol === "http:" && LOOPBACK.test(url.hostname)) return url;
73
- issues.push({
74
- variables,
75
- message: "must use https (http is only allowed for localhost / 127.0.0.1 / [::1])"
76
- });
77
- }
78
- function checkKey(value, kind, variables, issues) {
79
- if (value.startsWith(`sb_${kind}_`)) return true;
80
- if (value.startsWith("eyJ")) issues.push({
81
- variables,
82
- message: `is a legacy JWT key; use the new sb_${kind}_ key (Project Settings > API Keys)`
83
- });
84
- else if (value.startsWith(kind === "publishable" ? "sb_secret_" : "sb_publishable_")) issues.push({
85
- variables,
86
- message: kind === "publishable" ? "holds a secret key; never expose sb_secret_ keys as publishable" : "holds a publishable key, not a secret key"
87
- });
88
- else issues.push({
89
- variables,
90
- message: `must start with sb_${kind}_`
91
- });
92
- return false;
93
- }
94
- /**
95
- * Reads and validates Supabase settings. Accepts the `SUPABASE_`,
96
- * `NEXT_PUBLIC_`, `VITE_`, `PUBLIC_`, `EXPO_PUBLIC_` and `NUXT_PUBLIC_`
97
- * spellings. Issues name variables, never values.
98
- */
99
- function parseEnv(source, options = {}) {
100
- const issues = [];
101
- const required = new Set(options.require ?? []);
102
- const rawUrl = first(source, ENV_VARIABLES.url);
103
- const url = rawUrl ? checkUrl(rawUrl, ENV_VARIABLES.url, issues) : void 0;
104
- if (!rawUrl) issues.push({
105
- variables: ENV_VARIABLES.url,
106
- message: "is not set"
107
- });
108
- const publishableKeys = keySet(source, "SUPABASE_PUBLISHABLE_KEYS", "publishable", issues);
109
- const singlePublishable = first(source, ENV_VARIABLES.publishableKey);
110
- const publishableKey = singlePublishable ?? preferred(publishableKeys);
111
- if (!publishableKey) issues.push({
112
- variables: ENV_VARIABLES.publishableKey,
113
- message: "is not set"
114
- });
115
- else if (singlePublishable) checkKey(publishableKey, "publishable", ENV_VARIABLES.publishableKey, issues);
116
- const namedSecrets = keySet(source, "SUPABASE_SECRET_KEYS", "secret", issues);
117
- const singleSecret = first(source, ENV_VARIABLES.secretKey);
118
- const secretKey = singleSecret ?? preferred(namedSecrets);
119
- if (singleSecret) checkKey(singleSecret, "secret", ENV_VARIABLES.secretKey, issues);
120
- else if (!secretKey && required.has("secretKey")) issues.push({
121
- variables: ENV_VARIABLES.secretKey,
122
- message: "is not set"
123
- });
124
- const dbUrl = first(source, ENV_VARIABLES.dbUrl);
125
- if (dbUrl && !/^postgres(ql)?:\/\//.test(dbUrl)) issues.push({
126
- variables: ENV_VARIABLES.dbUrl,
127
- message: "must be a postgres:// connection string"
128
- });
129
- else if (!dbUrl && required.has("dbUrl")) issues.push({
130
- variables: ENV_VARIABLES.dbUrl,
131
- message: "is not set"
132
- });
133
- const rawJwks = first(source, ENV_VARIABLES.jwksUrl);
134
- const jwksOverride = rawJwks ? checkUrl(rawJwks, ENV_VARIABLES.jwksUrl, issues) : void 0;
135
- const rawRead = first(source, ENV_VARIABLES.readUrl);
136
- const readUrl = rawRead ? checkUrl(rawRead, ENV_VARIABLES.readUrl, issues) : void 0;
137
- if (issues.length > 0 || !url || !publishableKey) return {
138
- ok: false,
139
- issues
140
- };
141
- const base = url.href.replace(/\/+$/, "");
142
- const projectRef = HOSTED.exec(url.hostname)?.[1];
143
- return {
144
- ok: true,
145
- env: {
146
- url: base,
147
- publishableKey,
148
- jwksUrl: jwksOverride ?? new URL(`${base}/auth/v1/.well-known/jwks.json`),
149
- ...secretKey ? {
150
- secretKey,
151
- secretKeys: {
152
- ...namedSecrets,
153
- default: secretKey
154
- }
155
- } : {},
156
- ...dbUrl ? { dbUrl } : {},
157
- ...projectRef ? { projectRef } : {},
158
- ...readUrl ? { readUrl: readUrl.href.replace(/\/+$/, "") } : {}
159
- }
160
- };
161
- }
162
- function processEnv() {
163
- return globalThis.process?.env ?? {};
164
- }
165
- /** Like `parseEnv`, but throws `EnvValidationError`. Reads `process.env` by default. */
166
- function loadEnv(source = processEnv(), options = {}) {
167
- const result = parseEnv(source, options);
168
- if (!result.ok) throw new EnvValidationError(result.issues);
169
- return result.env;
170
- }
171
- /** The env validator as a Standard Schema, for t3-env, framework config or any validator slot. */
172
- function envSchema(options = {}) {
173
- return { "~standard": {
174
- version: 1,
175
- vendor: "better-supabase",
176
- validate(value) {
177
- if (typeof value !== "object" || value === null) return { issues: [{ message: "Expected an environment object" }] };
178
- const result = parseEnv(value, options);
179
- if (result.ok) return { value: result.env };
180
- return { issues: result.issues.map((issue) => ({
181
- message: `${issue.variables[0] ?? "env"} ${issue.message}`,
182
- path: issue.variables.slice(0, 1)
183
- })) };
184
- }
185
- } };
186
- }
187
- /** The parts that are safe in client bundles. */
188
- function publicEnv(env) {
189
- return {
190
- url: env.url,
191
- publishableKey: env.publishableKey
192
- };
193
- }
194
- /** Converts to `@supabase/server`'s `SupabaseEnv` (the `env` option of `withSupabase`). */
195
- function toServerEnv(env) {
196
- return {
197
- url: env.url,
198
- publishableKeys: { default: env.publishableKey },
199
- secretKeys: env.secretKeys ?? (env.secretKey ? { default: env.secretKey } : {}),
200
- jwks: env.jwksUrl
201
- };
202
- }
203
- //#endregion
204
- export { parseEnv as a, loadEnv as i, EnvValidationError as n, publicEnv as o, envSchema as r, toServerEnv as s, ENV_VARIABLES as t };
@@ -1,135 +0,0 @@
1
- //#region src/events/index.ts
2
- const ROW_EVENT_TYPES = {
3
- insert: "dev.better-supabase.row.created",
4
- upsert: "dev.better-supabase.row.upserted",
5
- update: "dev.better-supabase.row.updated",
6
- delete: "dev.better-supabase.row.deleted"
7
- };
8
- function subjectOf(meta, table, row) {
9
- const key = meta?.tables[table]?.primaryKey;
10
- if (!key || key.length === 0) return void 0;
11
- const values = key.map((column) => row[column]);
12
- if (values.some((value) => value === void 0 || value === null)) return void 0;
13
- return `${table}/${values.map((value) => encodeURIComponent(String(value))).join(",")}`;
14
- }
15
- /**
16
- * One CloudEvent per mutated row: `dev.better-supabase.row.created` with the
17
- * app-cased row as `data`, the primary key as `subject`, the tenant as
18
- * `partitionkey` and the actor as `actorid`.
19
- */
20
- function toCloudEvents(notice, options) {
21
- const type = options.typePrefix ? `${options.typePrefix}.row.${ROW_EVENT_TYPES[notice.kind].split(".").at(-1)}` : ROW_EVENT_TYPES[notice.kind];
22
- const time = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
23
- return notice.rows.map((row) => {
24
- const subject = subjectOf(options.meta, notice.table, row);
25
- return {
26
- specversion: "1.0",
27
- id: options.id?.() ?? crypto.randomUUID(),
28
- source: options.source,
29
- type,
30
- ...subject ? { subject } : {},
31
- time,
32
- datacontenttype: "application/json",
33
- data: {
34
- table: notice.table,
35
- row
36
- },
37
- ...notice.context.tenant ? { partitionkey: notice.context.tenant } : {},
38
- ...notice.context.actor?.id ? { actorid: notice.context.actor.id } : {}
39
- };
40
- });
41
- }
42
- /**
43
- * Sends a CloudEvent for every mutation to `sink`. Returns a function that
44
- * stops forwarding. Use an outbox (SQL kit) when events must not be lost.
45
- */
46
- function forwardMutations(sb, sink, options) {
47
- return sb.events.on("mutation", (notice) => {
48
- if (options.filter && !options.filter(notice)) return;
49
- const events = toCloudEvents(notice, {
50
- ...options,
51
- meta: sb.meta
52
- });
53
- if (events.length === 0) return;
54
- const report = (error) => (options.onError ?? ((cause) => sb.events.logger.error("event sink failed", { cause })))(error, events);
55
- try {
56
- Promise.resolve(sink.send(events)).catch(report);
57
- } catch (error) {
58
- report(error);
59
- }
60
- });
61
- }
62
- const STRUCTURED = "application/cloudevents+json";
63
- const BATCH = "application/cloudevents-batch+json";
64
- /** The HTTP protocol binding: headers and body for one event (or a batch). */
65
- function toHttp(events, mode = "structured") {
66
- const list = Array.isArray(events) ? events : [events];
67
- switch (mode) {
68
- case "batch": return [{
69
- headers: { "content-type": BATCH },
70
- body: JSON.stringify(list)
71
- }];
72
- case "structured": return list.map((event) => ({
73
- headers: { "content-type": STRUCTURED },
74
- body: JSON.stringify(event)
75
- }));
76
- case "binary": return list.map((event) => {
77
- const headers = {};
78
- for (const [key, value] of Object.entries(event)) {
79
- if (key === "data" || key === "datacontenttype" || value === void 0) continue;
80
- headers[`ce-${key}`] = encodeURIComponent(String(value)).replace(/%20/g, " ");
81
- }
82
- headers["content-type"] = event.datacontenttype ?? "application/json";
83
- return {
84
- headers,
85
- body: event.data === void 0 ? "" : JSON.stringify(event.data)
86
- };
87
- });
88
- default: throw new TypeError(`Unknown CloudEvents mode ${String(mode)}`);
89
- }
90
- }
91
- function isCloudEvent(value) {
92
- if (typeof value !== "object" || value === null) return false;
93
- const event = value;
94
- return event["specversion"] === "1.0" && typeof event["id"] === "string" && typeof event["source"] === "string" && typeof event["type"] === "string";
95
- }
96
- /** Reads CloudEvents from a request in any of the three HTTP modes. */
97
- async function fromHttp(request) {
98
- const contentType = request.headers.get("content-type") ?? "";
99
- const text = await request.text();
100
- if (contentType.startsWith(BATCH)) {
101
- const parsed = JSON.parse(text);
102
- if (!Array.isArray(parsed) || !parsed.every(isCloudEvent)) throw new TypeError("Invalid CloudEvents batch");
103
- return parsed;
104
- }
105
- if (contentType.startsWith(STRUCTURED)) {
106
- const parsed = JSON.parse(text);
107
- if (!isCloudEvent(parsed)) throw new TypeError("Invalid CloudEvent");
108
- return [parsed];
109
- }
110
- const event = {};
111
- for (const [key, value] of request.headers) if (key.startsWith("ce-")) event[key.slice(3)] = decodeURIComponent(value);
112
- if (contentType) event["datacontenttype"] = contentType;
113
- if (text) event["data"] = /json/.test(contentType) ? JSON.parse(text) : text;
114
- if (!isCloudEvent(event)) throw new TypeError("Request is not a CloudEvent");
115
- return [event];
116
- }
117
- /** POSTs events to `url`. Non-2xx responses reject. */
118
- function httpSink(url, options = {}) {
119
- const send = options.fetch ?? fetch;
120
- return { async send(events) {
121
- for (const message of toHttp(events, options.mode ?? "batch")) {
122
- const response = await send(url, {
123
- method: "POST",
124
- headers: {
125
- ...options.headers,
126
- ...message.headers
127
- },
128
- body: message.body
129
- });
130
- if (!response.ok) throw new Error(`Event sink responded ${String(response.status)}`);
131
- }
132
- } };
133
- }
134
- //#endregion
135
- export { isCloudEvent as a, httpSink as i, forwardMutations as n, toCloudEvents as o, fromHttp as r, toHttp as s, ROW_EVENT_TYPES as t };
@@ -1,37 +0,0 @@
1
- import { t as SqlClient } from "./executor-BYXQ9AGn.js";
2
- //#region src/postgres/pool.d.ts
3
- interface PostgresOptions {
4
- /** Defaults to `$SUPABASE_DB_URL`, then `$DATABASE_URL`. */
5
- readonly connectionString?: string;
6
- readonly max?: number;
7
- /** Statement timeout in milliseconds, applied per transaction. */
8
- readonly statementTimeout?: number;
9
- }
10
- /** JWT claims to run as. `role` must be `authenticated` or `anon`. */
11
- interface SqlClaims {
12
- readonly sub?: string;
13
- readonly role?: string;
14
- readonly [claim: string]: unknown;
15
- }
16
- interface Postgres {
17
- /** Connects as the connection-string role. On Supabase that bypasses RLS. */
18
- readonly admin: SqlClient;
19
- /** Runs every query as the given user, with RLS, like PostgREST does. */
20
- asUser(claims: SqlClaims): SqlClient;
21
- /** Runs every query as `anon`. */
22
- readonly anon: SqlClient;
23
- /** Runs `fn` in one transaction. Pass claims to run it as a user. */
24
- transaction<T>(fn: (client: SqlClient) => Promise<T>, options?: {
25
- readonly claims?: SqlClaims;
26
- }): Promise<T>;
27
- end(): Promise<void>;
28
- [Symbol.asyncDispose](): Promise<void>;
29
- }
30
- /**
31
- * A pooled Postgres connection for jobs, scripts and tests. Each query (or
32
- * transaction) runs in its own transaction; claims and role are
33
- * transaction-local, so nothing leaks back into the pool.
34
- */
35
- declare function createPostgres(options?: PostgresOptions): Postgres;
36
- //#endregion
37
- export { createPostgres as i, PostgresOptions as n, SqlClaims as r, Postgres as t };
@@ -1,101 +0,0 @@
1
- //#region src/testing/seed.ts
2
- const SEED = Symbol.for("better-supabase.seed");
3
- function isSeed(value) {
4
- return typeof value === "object" && value !== null && SEED in value;
5
- }
6
- const quote = (text) => `'${text.replaceAll("'", "''")}'`;
7
- function arrayLiteral(values) {
8
- return `{${values.map((value) => {
9
- if (value === null) return "NULL";
10
- if (Array.isArray(value)) return arrayLiteral(value);
11
- return `"${(value instanceof Date ? value.toISOString() : String(value)).replace(/[\\"]/g, "\\$&")}"`;
12
- }).join(",")}}`;
13
- }
14
- function literal(value, column, where) {
15
- if (value === null) return "null";
16
- if (column.json) return quote(JSON.stringify(value));
17
- if (Array.isArray(value)) return quote(arrayLiteral(value));
18
- if (value instanceof Date) return quote(value.toISOString());
19
- const kind = typeof value;
20
- switch (kind) {
21
- case "string": return quote(value);
22
- case "boolean":
23
- case "bigint": return String(value);
24
- case "number":
25
- if (!Number.isFinite(value)) throw new TypeError(`${where}: ${String(value)} is not a finite number`);
26
- return String(value);
27
- case "object":
28
- case "function":
29
- case "symbol":
30
- case "undefined": throw new TypeError(`${where}: unsupported value of type ${kind}`);
31
- default: throw new TypeError(`${where}: unsupported value of type ${String(kind)}`);
32
- }
33
- }
34
- const ident = (name) => `"${name.replaceAll("\"", "\"\"")}"`;
35
- /** Parents first (by forward relations), otherwise in the order given. */
36
- function order(meta, keys) {
37
- const sorted = [];
38
- const visiting = /* @__PURE__ */ new Set();
39
- const visit = (key) => {
40
- if (sorted.includes(key) || visiting.has(key)) return;
41
- visiting.add(key);
42
- for (const relation of Object.values(meta.tables[key]?.relations ?? {})) if (relation.direction === "forward" && relation.table !== key && keys.includes(relation.table)) visit(relation.table);
43
- visiting.delete(key);
44
- sorted.push(key);
45
- };
46
- for (const key of keys) visit(key);
47
- return sorted;
48
- }
49
- function statement(table, rows) {
50
- const entries = Object.entries(rows);
51
- if (entries.length === 0) return void 0;
52
- const columns = [];
53
- for (const [, row] of entries) for (const [key, value] of Object.entries(row)) {
54
- if (value === void 0 || columns.includes(key)) continue;
55
- const column = table.columns[key];
56
- if (!column) throw new TypeError(`seed ${table.key}: unknown column "${key}"`);
57
- if (column.generated) throw new TypeError(`seed ${table.key}: "${key}" is a generated column`);
58
- columns.push(key);
59
- }
60
- const values = entries.map(([name, row]) => {
61
- return ` (${columns.map((key) => row[key] === void 0 ? "default" : literal(row[key], table.columns[key], `seed ${table.key}.${name}.${key}`)).join(", ")})`;
62
- });
63
- return `insert into ${`${ident(table.schema)}.${ident(table.name)}`} (${columns.map((key) => ident(table.columns[key].db)).join(", ")}) values\n${values.join(",\n")}\non conflict do nothing;`;
64
- }
65
- /**
66
- * Typed fixtures shared by `supabase/seeds` and your tests. Rows use app
67
- * casing and Insert types; `better-supabase seed` renders them to SQL.
68
- *
69
- * ```ts
70
- * export const seed = defineSeed(sb, {
71
- * organizations: { acme: { id: ACME, name: 'Acme' } },
72
- * customers: { first: { organizationId: ACME, name: 'First customer' } },
73
- * });
74
- * ```
75
- */
76
- function defineSeed(sb, fixtures) {
77
- const meta = sb.meta;
78
- const statements = () => {
79
- const keys = Object.keys(fixtures).filter((key) => fixtures[key] !== void 0);
80
- for (const key of keys) {
81
- const table = meta.tables[key];
82
- if (!table) throw new TypeError(`seed: unknown table "${key}"`);
83
- if (table.kind === "view") throw new TypeError(`seed: "${key}" is a view`);
84
- }
85
- return order(meta, keys).flatMap((key) => {
86
- const sql = statement(meta.tables[key], fixtures[key]);
87
- return sql ? [sql] : [];
88
- });
89
- };
90
- return {
91
- [SEED]: true,
92
- rows: fixtures,
93
- statements,
94
- sql: () => statements().join("\n\n"),
95
- async insert(sql) {
96
- for (const text of statements()) await sql.queryRaw(text);
97
- }
98
- };
99
- }
100
- //#endregion
101
- export { isSeed as n, defineSeed as t };
@@ -1,22 +0,0 @@
1
- import { t as AuthSession } from "./view-D1s0wa0T.js";
2
- import { ReactNode } from "react";
3
- //#region src/react/session.d.ts
4
- interface SessionProviderProps {
5
- /**
6
- * An unresolved `next.session()` promise, created inside a `<Suspense>`
7
- * boundary so the layout itself never waits for auth.
8
- */
9
- readonly sessionPromise: Promise<AuthSession>;
10
- readonly children?: ReactNode;
11
- }
12
- /** Shares the server-verified session with Client Components. */
13
- declare function SessionProvider(props: SessionProviderProps): ReactNode;
14
- /**
15
- * The session from the nearest `<SessionProvider>`. Suspends until the
16
- * promise resolves, so render it inside `<Suspense>`. `C` types the claims
17
- * (the output of `sb.claims(schema)`) and `P` the profile (the output of
18
- * `sb.userMetadata(schema)`); `createHooks().useSession` infers both.
19
- */
20
- declare function useSession<C = unknown, P = unknown>(): AuthSession<C, P>;
21
- //#endregion
22
- export { SessionProviderProps as n, useSession as r, SessionProvider as t };
@@ -1,20 +0,0 @@
1
- import { createContext, createElement, use, useContext } from "react";
2
- //#region src/react/session.ts
3
- const SessionContext = createContext(null);
4
- /** Shares the server-verified session with Client Components. */
5
- function SessionProvider(props) {
6
- return createElement(SessionContext.Provider, { value: props.sessionPromise }, props.children);
7
- }
8
- /**
9
- * The session from the nearest `<SessionProvider>`. Suspends until the
10
- * promise resolves, so render it inside `<Suspense>`. `C` types the claims
11
- * (the output of `sb.claims(schema)`) and `P` the profile (the output of
12
- * `sb.userMetadata(schema)`); `createHooks().useSession` infers both.
13
- */
14
- function useSession() {
15
- const promise = useContext(SessionContext);
16
- if (!promise) throw new Error("better-supabase: useSession() needs <SessionProvider sessionPromise={...}>");
17
- return use(promise);
18
- }
19
- //#endregion
20
- export { useSession as n, SessionProvider as t };