better-supabase 0.4.0 → 0.5.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 +2 -0
- package/dist/channel-FQW-CnGR.d.ts +70 -0
- package/dist/cli/bin.js +1 -1
- package/dist/cli/codemod-DqV7612m.js +388 -0
- package/dist/cli/{config-D9R0o1LH.js → config-CPVpXP5I.js} +78 -8
- package/dist/cli/{config-SSKSTUl2.js → config-dtoekM0v.js} +1 -1
- package/dist/cli/{read-sets-CMa29t9a.js → diff-SjkO5rNr.js} +1 -220
- package/dist/cli/{dist-CFgGknmZ.js → dist-DBPdlPYK.js} +4 -4
- package/dist/cli/{dist-B1MvLv-M.js → dist-DreZ24Sz.js} +1 -1
- package/dist/cli/{dist-Du7VnEUG.js → dist-xn4wlboc.js} +112 -1
- package/dist/cli/{doctor-BOym3mbL.js → doctor-L7Z8mYTx.js} +531 -50
- package/dist/cli/{env-BZ0uy8XK.js → env-DmKv_G4A.js} +1 -1
- package/dist/cli/gen-BJc9vdyu.js +2 -0
- package/dist/cli/{gen-Ccn_p90L.js → gen-C2osRcr5.js} +283 -87
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/cli/{init-ClnxRYBF.js → init-Saf5-R9T.js} +2 -2
- package/dist/cli/{introspect-DxqfkVIv.js → introspect--H7oGmcd.js} +2 -2
- package/dist/cli/{openapi-8WHjxiTJ.js → openapi-Cp5Fyta-.js} +1 -1
- package/dist/cli/read-sets-BfMQcKy8.js +289 -0
- package/dist/cli/{run-CP20LKk_.js → run-BKR2W_79.js} +16 -12
- package/dist/cli/{seed-5J6eu_Xg.js → seed-CUlqWh-8.js} +1 -1
- package/dist/cli/sql-DzPbfngx.js +348 -0
- package/dist/cli/{version-5mW_8sY1.js → version-BDJuO0UR.js} +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +3 -10
- package/dist/clone-BfgmLU90.js +21 -0
- package/dist/{compiler-DB3aSFOA.d.ts → compiler-BXH_aZ7N.d.ts} +2 -2
- package/dist/config/index.d.ts +4 -4
- package/dist/config/index.js +4 -4
- package/dist/{config-CbvFmGD8.js → config-DreERlKo.js} +1 -1
- package/dist/{config-C1CYcm6o.d.ts → config-T_ejwyd3.d.ts} +176 -11
- package/dist/{define-CRS2MRV3.d.ts → define-Bp_BZa5h.d.ts} +11 -7
- package/dist/{define-Bh0AqTik.js → define-cNKzqwL_.js} +202 -16
- package/dist/edge/index.d.ts +16 -5
- package/dist/edge/index.js +10 -7
- package/dist/{entitlements-Dm-FHpNH.d.ts → entitlements-DUxU4oHe.d.ts} +1 -1
- package/dist/env/index.d.ts +2 -2
- package/dist/env/index.js +34 -1
- package/dist/{errors-L0xK41y_.js → errors-DtwXa6b8.js} +1 -0
- package/dist/events/index.d.ts +3 -2
- package/dist/events/index.js +65 -12
- package/dist/events-aIO7vsIk.d.ts +230 -0
- package/dist/{result-CqEsbgYs.d.ts → executor-BunPOO-k.d.ts} +200 -1
- package/dist/{executor-CZ7ImRiD.d.ts → executor-Cghdstwu.d.ts} +1 -2
- package/dist/{executor-CVt6dD0B.js → executor-XycESQPH.js} +3 -3
- package/dist/hono/index.d.ts +17 -6
- package/dist/hono/index.js +40 -5
- package/dist/impersonation-VfaGc4Q_.js +41 -0
- package/dist/{index-BBdvo-5d.d.ts → index-BGdgBPdf.d.ts} +49 -6
- package/dist/{index-BhHEC04r.d.ts → index-C7f8cOBM.d.ts} +2 -2
- package/dist/{index-Dy6kuF0P.d.ts → index-CLg87OBW.d.ts} +6 -1
- package/dist/{index-D5IfUIDh.d.ts → index-DOESKG27.d.ts} +33 -8
- package/dist/{index-DFmOpBGC.d.ts → index-DgILJRXj.d.ts} +35 -9
- package/dist/{index-RlLXd8dL.d.ts → index-DmXSxbLi.d.ts} +4 -4
- package/dist/{index-Cf-D2jk1.d.ts → index-Dxn2a5cw.d.ts} +2 -2
- package/dist/{index-528Ugmyp.d.ts → index-SaTsEfGP.d.ts} +76 -8
- package/dist/{index-BAy4tsAP.d.ts → index-fag8VJZ2.d.ts} +3 -4
- package/dist/index.d.ts +30 -13
- package/dist/index.js +10 -9
- package/dist/jobs/index.d.ts +147 -101
- package/dist/jobs/index.js +744 -237
- package/dist/{json-schema-DP6V7cbr.js → json-schema-m1fiwKgN.js} +22 -1
- package/dist/kit-events-CTFDfSwb.js +60 -0
- package/dist/kit-transport-B82k1djG.d.ts +33 -0
- package/dist/kit-transport-DJlHQUBU.js +55 -0
- package/dist/{config-BpxDfnbg.js → kits-CGLLrNPd.js} +37 -9
- package/dist/list/index.d.ts +1 -1
- package/dist/{live-BHakSWWo.d.ts → live-D9W2M5aO.d.ts} +6 -5
- package/dist/mcp/index.d.ts +25 -8
- package/dist/mcp/index.js +23 -14
- package/dist/{mfa-C7MNQ1Ob.d.ts → mfa-CusDgPaD.d.ts} +5 -1
- package/dist/next/index.d.ts +31 -10
- package/dist/next/index.js +136 -27
- package/dist/notifications/index.d.ts +162 -0
- package/dist/notifications/index.js +264 -0
- package/dist/openapi/index.d.ts +1 -1
- package/dist/openapi/index.js +2 -2
- package/dist/orgs/index.d.ts +132 -0
- package/dist/orgs/index.js +245 -0
- package/dist/orpc/index.d.ts +28 -8
- package/dist/orpc/index.js +16 -3
- package/dist/otel/index.d.ts +21 -2
- package/dist/otel/index.js +50 -9
- package/dist/permdock-sql-C2Inc6Xc.d.ts +29 -0
- package/dist/permdock-sql-DgOfeixi.js +51 -0
- package/dist/plugin-DwARMuQp.js +59 -0
- package/dist/{plugin-bNhvJwRh.d.ts → plugin-o144f322.d.ts} +17 -5
- package/dist/plugins/actor/index.d.ts +5 -2
- package/dist/plugins/actor/index.js +22 -8
- package/dist/plugins/rules/index.d.ts +2 -2
- package/dist/plugins/rules/index.js +15 -10
- package/dist/plugins/soft-delete/index.d.ts +3 -3
- package/dist/plugins/soft-delete/index.js +14 -5
- package/dist/plugins/tenant/index.d.ts +2 -2
- package/dist/plugins/tenant/index.js +38 -20
- package/dist/plugins/timestamps/index.d.ts +1 -1
- package/dist/plugins/timestamps/index.js +4 -3
- package/dist/plugins/validation/index.d.ts +2 -2
- package/dist/plugins/validation/index.js +26 -6
- package/dist/{pool-DFwEQwmN.d.ts → pool-C9voM4Kw.d.ts} +17 -6
- package/dist/postgres/index.d.ts +5 -5
- package/dist/postgres/index.js +20 -11
- package/dist/{postgrest-Bc-0Xw62.d.ts → postgrest-CruYKAvV.d.ts} +1 -1
- package/dist/{problem-BihjPR0t.js → problem-BW1KhzSG.js} +2 -1
- package/dist/{problem-U8UEKccv.d.ts → problem-Blxe8S31.d.ts} +1 -1
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +3 -3
- package/dist/{query-BMMSWbI7.js → query-CCbo44lG.js} +2 -2
- package/dist/queue-BYUCjr59.d.ts +252 -0
- package/dist/react/index.d.ts +8 -7
- package/dist/react/index.js +4 -3
- package/dist/react/server.d.ts +14 -3
- package/dist/react/server.js +10 -2
- package/dist/react/session.d.ts +7 -1
- package/dist/react/session.js +9 -1
- package/dist/{react-CQHMaESR.js → react-C_s7kiNz.js} +103 -11
- package/dist/{read-set-FWK8qQ58.js → read-set-DQFt1N_Y.js} +22 -1
- package/dist/realtime/index.d.ts +3 -3
- package/dist/realtime/index.js +5 -4
- package/dist/{refresh-BwYkyNOQ.d.ts → refresh-BTrQ_ZTp.d.ts} +1 -1
- package/dist/{resolve-BAqQcwMW.d.ts → resolve-C15TJq77.d.ts} +11 -5
- package/dist/{resource-My_y-Syh.js → resource-CRxxwkQq.js} +22 -7
- package/dist/{resource-BJcaIfxi.d.ts → resource-D8iqWMr-.d.ts} +5 -5
- package/dist/respond-D2OQl62-.d.ts +371 -0
- package/dist/{result-Bj6yt33D.js → result-BKiliPY7.js} +1 -1
- package/dist/server/index.d.ts +14 -12
- package/dist/server/index.js +11 -17
- package/dist/{server-BA75B0mT.js → server-Csx2sRjg.js} +251 -34
- package/dist/{shared-DnoCdMDr.js → shared-D1dRUrAg.js} +16 -2
- package/dist/signers-Cc6r98SW.d.ts +162 -0
- package/dist/{simplify-Cqvfr9dj.js → simplify-_0oUKqCd.js} +4 -115
- package/dist/sql/index.d.ts +247 -10
- package/dist/sql/index.js +8590 -779
- package/dist/{sql-B34HU2DI.js → sql-Coh6n4cC.js} +9 -2
- package/dist/ssr/index.d.ts +4 -4
- package/dist/ssr/index.js +1 -2
- package/dist/{standard-BRyBGTtp.js → standard-D7r6dMUu.js} +6 -3
- package/dist/{standard-BsaCYQJc.d.ts → standard-J4YgMOLm.d.ts} +1 -1
- package/dist/{stats-C_YxA2r1.js → stats-Bqob3WqT.js} +4 -4
- package/dist/storage/index.d.ts +4 -4
- package/dist/storage/index.js +155 -26
- package/dist/support-DT-OhSxD.d.ts +88 -0
- package/dist/support-Dk6vdmEw.js +291 -0
- package/dist/support-view-Da5peKFg.d.ts +17 -0
- package/dist/support-view-g4YLBeqX.js +18 -0
- package/dist/{permdock-sql-C4KFzLc9.js → template-TxrGI5jR.js} +2 -31
- package/dist/{temporal-BwshQk0W.js → temporal-CVlIV2DZ.js} +17 -4
- package/dist/{temporal-required-CBNHT6ni.js → temporal-required-CAt4Dc9Z.js} +2 -2
- package/dist/testing/index.d.ts +100 -10
- package/dist/testing/index.js +336 -8
- package/dist/{types-DONv9SHN.d.ts → types-Dnf_wRDz.d.ts} +26 -3
- package/dist/user-change-CHFEUro1.js +49 -0
- package/dist/{webhooks-Bh_Jf_-l.js → verify-Ce49ETPz.js} +5 -5
- package/dist/{version-Bmf7_FzM.js → version-DM_Roffb.js} +1 -1
- package/dist/{view-B64o81wp.d.ts → view-BEf0diC5.d.ts} +8 -3
- package/dist/{mfa-byfjruR9.js → view-Bq64ki8-.js} +95 -38
- package/dist/webhooks/index.d.ts +135 -4
- package/dist/webhooks/index.js +588 -2
- package/dist/wire-D2dT86vi.js +35 -0
- package/package.json +16 -8
- package/schemas/config-v1.json +131 -1
- package/schemas/doctor-report-v1.json +10 -0
- package/skills/better-supabase/SKILL.md +9 -6
- package/skills/better-supabase/references/plugins.md +6 -3
- package/skills/better-supabase/references/troubleshooting.md +1 -0
- package/skills/better-supabase-api/SKILL.md +9 -2
- package/skills/better-supabase-api/references/adapters.md +11 -8
- package/skills/better-supabase-auth/SKILL.md +3 -0
- package/skills/better-supabase-auth/references/permdock.md +56 -11
- package/dist/cli/gen-D5cLCULx.js +0 -2
- package/dist/cli/sql-D4VbqmXi.js +0 -199
- package/dist/events-B21UOhvP.d.ts +0 -84
- package/dist/executor-B5IoUxLE.d.ts +0 -195
- package/dist/invalidate-CgxmRamI.js +0 -24
- package/dist/permdock-sql-DImJULY-.d.ts +0 -17
- package/dist/plugin-BqR6wKMB.js +0 -23
- package/dist/respond-DgIbdrt8.d.ts +0 -194
- package/dist/view-BrJI2LKp.js +0 -45
package/README.md
CHANGED
|
@@ -64,6 +64,8 @@ if (!result.ok) return result; // DbError: kind, message, status, code
|
|
|
64
64
|
| `better-supabase/hono`, `/orpc`, `/edge` | Framework adapters |
|
|
65
65
|
| `better-supabase/mcp` | MCP servers whose tools run as the signed-in user |
|
|
66
66
|
| `better-supabase/jobs` | Supabase Queues jobs, idempotency keys and a webhook inbox |
|
|
67
|
+
| `better-supabase/orgs` | Organizations, members, invitations and switching from the SQL kit |
|
|
68
|
+
| `better-supabase/notifications` | Sending, listing and delivering notifications from the SQL kit |
|
|
67
69
|
| `better-supabase/list` | Search, facets, sorting and pagination from one definition |
|
|
68
70
|
| `better-supabase/storage`, `/realtime` | Typed bucket paths and broadcast topics |
|
|
69
71
|
| `better-supabase/env` | Validated Supabase settings |
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
//#region src/notifications/types.d.ts
|
|
3
|
+
/** A subject a notification is about, e.g. `{ type: 'task', id: '42' }`. */
|
|
4
|
+
interface NotificationSubject {
|
|
5
|
+
readonly type: string;
|
|
6
|
+
readonly id: string;
|
|
7
|
+
/** Shown in the list, e.g. the task title, kept as it was at send time. */
|
|
8
|
+
readonly label?: string;
|
|
9
|
+
}
|
|
10
|
+
/** One notification as its recipient sees it. */
|
|
11
|
+
interface NotificationItem<K extends string = string, D = unknown> {
|
|
12
|
+
/** The recipient row id: pass it to `markRead` and `dismiss`. */
|
|
13
|
+
readonly id: string;
|
|
14
|
+
/** The shared event id, the same for every recipient. */
|
|
15
|
+
readonly eventId: string;
|
|
16
|
+
readonly type: K;
|
|
17
|
+
readonly data: D;
|
|
18
|
+
readonly tenant: string | null;
|
|
19
|
+
readonly actorId: string | null;
|
|
20
|
+
readonly subject: NotificationSubject | null;
|
|
21
|
+
readonly summary: string | null;
|
|
22
|
+
readonly actionPath: string | null;
|
|
23
|
+
readonly priority: string | null;
|
|
24
|
+
readonly createdAt: Temporal.Instant;
|
|
25
|
+
readonly readAt: Temporal.Instant | null;
|
|
26
|
+
readonly resolvedAt: Temporal.Instant | null;
|
|
27
|
+
}
|
|
28
|
+
/** What `render` returns: the text for one notification, in one locale. */
|
|
29
|
+
interface RenderedText {
|
|
30
|
+
readonly title: string;
|
|
31
|
+
readonly body?: string;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/notifications/channel.d.ts
|
|
35
|
+
/** One pending delivery a channel sends: the notification and who gets it. */
|
|
36
|
+
interface NotificationMessage {
|
|
37
|
+
readonly deliveryId: string;
|
|
38
|
+
/** The channel name, e.g. `email`. */
|
|
39
|
+
readonly channel: string;
|
|
40
|
+
/** 1 on the first try. */
|
|
41
|
+
readonly attempts: number;
|
|
42
|
+
readonly userId: string;
|
|
43
|
+
/** The recipient's `auth.users` email, for email channels. */
|
|
44
|
+
readonly email: string | null;
|
|
45
|
+
readonly notification: NotificationItem;
|
|
46
|
+
/** What `render` returned for it, when `createNotifications` has one. */
|
|
47
|
+
readonly text?: RenderedText;
|
|
48
|
+
}
|
|
49
|
+
interface NotificationSendResult {
|
|
50
|
+
/** `skipped` when the channel decided not to send. Defaults to `sent`. */
|
|
51
|
+
readonly status?: "sent" | "skipped";
|
|
52
|
+
/** The provider's name, e.g. `resend` or `fcm`. */
|
|
53
|
+
readonly provider?: string;
|
|
54
|
+
/** The provider's id for the message, kept for support and webhooks. */
|
|
55
|
+
readonly providerMessageId?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Sends notifications on one channel (email, push, Slack). The delivery
|
|
59
|
+
* worker (`notifications.deliver()`) claims pending deliveries for the
|
|
60
|
+
* channel's `name` and calls `send` for each. Throwing retries the delivery
|
|
61
|
+
* after its lease, up to `maxAttempts`, then marks it `failed`.
|
|
62
|
+
*/
|
|
63
|
+
interface NotificationChannel {
|
|
64
|
+
readonly apiVersion: 1;
|
|
65
|
+
/** Matches the `channel` the deliveries were created for. */
|
|
66
|
+
readonly name: string;
|
|
67
|
+
send(message: NotificationMessage): NotificationSendResult | void | Promise<NotificationSendResult | void>;
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
export { NotificationSubject as a, NotificationItem as i, NotificationMessage as n, RenderedText as o, NotificationSendResult as r, NotificationChannel as t };
|
package/dist/cli/bin.js
CHANGED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import { r as defineCliCommand } from "./command-CK14fP91.js";
|
|
2
|
+
import { r as writeIfChanged } from "./io-k41_z-jT.js";
|
|
3
|
+
import { i as plain, r as painter } from "./style-C0NFdJRL.js";
|
|
4
|
+
import { t as fileDiff } from "./diff-SjkO5rNr.js";
|
|
5
|
+
import { extname, join, relative, resolve } from "node:path";
|
|
6
|
+
import { readFile, readdir, stat } from "node:fs/promises";
|
|
7
|
+
//#region src/cli/codemod.ts
|
|
8
|
+
const CODEMODS = {
|
|
9
|
+
"0.4": {
|
|
10
|
+
name: "0.4",
|
|
11
|
+
description: "Renames from 0.3 to 0.4 (the naming page lists them)",
|
|
12
|
+
imports: {
|
|
13
|
+
createBrowser: "createClient",
|
|
14
|
+
BetterBrowser: "BetterClient",
|
|
15
|
+
BrowserOptions: "ClientOptions",
|
|
16
|
+
BrowserAuth: "ClientAuth",
|
|
17
|
+
BetterEnv: "HonoEnv",
|
|
18
|
+
HandlerOptions: "MiddlewareOptions",
|
|
19
|
+
Queries: "BetterQueries",
|
|
20
|
+
CreateQueriesOptions: "QueriesOptions",
|
|
21
|
+
Postgres: "BetterPostgres",
|
|
22
|
+
DefineSupabaseOptions: "SupabaseOptions"
|
|
23
|
+
},
|
|
24
|
+
members: [
|
|
25
|
+
{
|
|
26
|
+
from: "serverFor",
|
|
27
|
+
to: "contextForSession"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
from: "toORPCError",
|
|
31
|
+
to: "toOrpcError"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
from: "$table",
|
|
35
|
+
to: "$tableName",
|
|
36
|
+
notCalled: true
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
props: [{
|
|
40
|
+
component: "BetterSupabaseProvider",
|
|
41
|
+
from: "browser",
|
|
42
|
+
to: "client"
|
|
43
|
+
}],
|
|
44
|
+
review: [
|
|
45
|
+
{
|
|
46
|
+
pattern: /\.server\(\)/,
|
|
47
|
+
message: "`next.server()` is `bs.context()` on the createNext() instance"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
pattern: /\.handle\(\)/,
|
|
51
|
+
message: "Hono's `bs.handle()` is `bs.handler()`"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
pattern: /\bmcp\.handler\b/,
|
|
55
|
+
message: "`mcp.handler` is `bs.endpoint`"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
pattern: /\.sb\b/,
|
|
59
|
+
message: "`client.sb` is `client.betterSupabase`"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
pattern: /\btestExecutor\(\s*\{[^}]*\bsb\b/,
|
|
63
|
+
message: "`{ sb }` in testExecutor is `{ betterSupabase }`"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
"0.5": {
|
|
68
|
+
name: "0.5",
|
|
69
|
+
description: "Renames from 0.4 to 0.5: createMcp's scopes is advertisedScopes",
|
|
70
|
+
options: [{
|
|
71
|
+
call: "createMcp",
|
|
72
|
+
from: "scopes",
|
|
73
|
+
to: "advertisedScopes"
|
|
74
|
+
}]
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
/** `[start, end)` ranges of code, outside strings, template literals and comments. */
|
|
78
|
+
function codeRanges(text) {
|
|
79
|
+
const ranges = [];
|
|
80
|
+
let start = 0;
|
|
81
|
+
let index = 0;
|
|
82
|
+
const skip = (end) => {
|
|
83
|
+
if (index > start) ranges.push([start, index]);
|
|
84
|
+
index = end;
|
|
85
|
+
start = end;
|
|
86
|
+
};
|
|
87
|
+
while (index < text.length) {
|
|
88
|
+
const char = text[index];
|
|
89
|
+
const next = text[index + 1];
|
|
90
|
+
if (char === "/" && next === "/") {
|
|
91
|
+
const end = text.indexOf("\n", index);
|
|
92
|
+
skip(end === -1 ? text.length : end);
|
|
93
|
+
} else if (char === "/" && next === "*") {
|
|
94
|
+
const end = text.indexOf("*/", index + 2);
|
|
95
|
+
skip(end === -1 ? text.length : end + 2);
|
|
96
|
+
} else if (char === "\"" || char === "'" || char === "`") {
|
|
97
|
+
let end = index + 1;
|
|
98
|
+
while (end < text.length && text[end] !== char) {
|
|
99
|
+
if (text[end] === "\\") end += 1;
|
|
100
|
+
if (char !== "`" && text[end] === "\n") break;
|
|
101
|
+
end += 1;
|
|
102
|
+
}
|
|
103
|
+
skip(text[end] === char ? end + 1 : Math.min(end, text.length));
|
|
104
|
+
} else index += 1;
|
|
105
|
+
}
|
|
106
|
+
if (index > start) ranges.push([start, index]);
|
|
107
|
+
return ranges;
|
|
108
|
+
}
|
|
109
|
+
function applyEdits(text, edits) {
|
|
110
|
+
let out = "";
|
|
111
|
+
let cursor = 0;
|
|
112
|
+
for (const edit of [...edits].sort((a, b) => a.start - b.start)) {
|
|
113
|
+
if (edit.start < cursor) continue;
|
|
114
|
+
out += text.slice(cursor, edit.start) + edit.text;
|
|
115
|
+
cursor = edit.end;
|
|
116
|
+
}
|
|
117
|
+
return out + text.slice(cursor);
|
|
118
|
+
}
|
|
119
|
+
const escapeRegExp = (value) => value.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
120
|
+
function inCode(ranges, index) {
|
|
121
|
+
let low = 0;
|
|
122
|
+
let high = ranges.length - 1;
|
|
123
|
+
while (low <= high) {
|
|
124
|
+
const middle = low + high >> 1;
|
|
125
|
+
const [start, end] = ranges[middle];
|
|
126
|
+
if (index < start) high = middle - 1;
|
|
127
|
+
else if (index >= end) low = middle + 1;
|
|
128
|
+
else return true;
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
const OPENING = "({[";
|
|
133
|
+
const CLOSING = ")}]";
|
|
134
|
+
/** Matches of `pattern` that start in code. */
|
|
135
|
+
function codeMatches(text, pattern, ranges) {
|
|
136
|
+
return [...text.matchAll(pattern)].filter((match) => inCode(ranges, match.index));
|
|
137
|
+
}
|
|
138
|
+
const IMPORT = /\b(import|export)\s+(type\s+)?\{([^}]*)\}\s*from\s*(["'])better-supabase(?:\/[\w./-]*)?\4/g;
|
|
139
|
+
function renameImports(text, renames) {
|
|
140
|
+
const ranges = codeRanges(text);
|
|
141
|
+
const locals = /* @__PURE__ */ new Set();
|
|
142
|
+
const edits = [];
|
|
143
|
+
for (const match of codeMatches(text, IMPORT, ranges)) {
|
|
144
|
+
const list = match[3];
|
|
145
|
+
const listStart = match.index + match[0].indexOf("{") + 1;
|
|
146
|
+
const renamed = list.replaceAll(/(\btype\s+)?([\w$]+)(\s+as\s+[\w$]+)?/g, (spec, type, name, alias) => {
|
|
147
|
+
const to = renames[name];
|
|
148
|
+
if (to === void 0) return spec;
|
|
149
|
+
if (alias === void 0 && match[1] === "import") locals.add(name);
|
|
150
|
+
return `${type ?? ""}${to}${alias ?? ""}`;
|
|
151
|
+
});
|
|
152
|
+
if (renamed !== list) edits.push({
|
|
153
|
+
start: listStart,
|
|
154
|
+
end: listStart + list.length,
|
|
155
|
+
text: renamed
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
text: applyEdits(text, edits),
|
|
160
|
+
locals
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function renameIdentifiers(text, renames) {
|
|
164
|
+
if (renames.size === 0) return text;
|
|
165
|
+
const ranges = codeRanges(text);
|
|
166
|
+
const names = [...renames.keys()].map(escapeRegExp).join("|");
|
|
167
|
+
return applyEdits(text, codeMatches(text, new RegExp(`(?<![\\w$.])(?:${names})(?![\\w$])`, "g"), ranges).map((match) => ({
|
|
168
|
+
start: match.index,
|
|
169
|
+
end: match.index + match[0].length,
|
|
170
|
+
text: renames.get(match[0])
|
|
171
|
+
})));
|
|
172
|
+
}
|
|
173
|
+
function renameMembers(text, members) {
|
|
174
|
+
const ranges = codeRanges(text);
|
|
175
|
+
return applyEdits(text, members.flatMap((member) => codeMatches(text, new RegExp(`\\.${escapeRegExp(member.from)}(?![\\w$])${member.notCalled === true ? "(?!\\s*\\()" : ""}`, "g"), ranges).map((match) => ({
|
|
176
|
+
start: match.index,
|
|
177
|
+
end: match.index + match[0].length,
|
|
178
|
+
text: `.${member.to}`
|
|
179
|
+
}))));
|
|
180
|
+
}
|
|
181
|
+
function renameProps(text, props) {
|
|
182
|
+
const ranges = codeRanges(text);
|
|
183
|
+
const edits = [];
|
|
184
|
+
for (const prop of props) {
|
|
185
|
+
const tag = new RegExp(`<${escapeRegExp(prop.component)}(?![\\w$.])`, "g");
|
|
186
|
+
for (const match of codeMatches(text, tag, ranges)) {
|
|
187
|
+
let depth = 0;
|
|
188
|
+
for (let index = match.index + match[0].length; index < text.length; index += 1) {
|
|
189
|
+
if (!inCode(ranges, index)) continue;
|
|
190
|
+
const char = text[index];
|
|
191
|
+
if (char === "{") depth += 1;
|
|
192
|
+
else if (char === "}") depth -= 1;
|
|
193
|
+
else if (char === ">" && depth === 0) break;
|
|
194
|
+
if (depth === 0 && /\s/.test(text[index - 1] ?? "") && text.startsWith(`${prop.from}=`, index)) edits.push({
|
|
195
|
+
start: index,
|
|
196
|
+
end: index + prop.from.length,
|
|
197
|
+
text: prop.to
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return applyEdits(text, edits);
|
|
203
|
+
}
|
|
204
|
+
/** The index after the bracket that closes the one at `open`, in code only. */
|
|
205
|
+
function closing(text, open, ranges) {
|
|
206
|
+
let depth = 0;
|
|
207
|
+
for (let index = open; index < text.length; index += 1) {
|
|
208
|
+
if (!inCode(ranges, index)) continue;
|
|
209
|
+
const char = text[index];
|
|
210
|
+
if (OPENING.includes(char)) depth += 1;
|
|
211
|
+
else if (CLOSING.includes(char)) {
|
|
212
|
+
depth -= 1;
|
|
213
|
+
if (depth === 0) return index + 1;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return text.length;
|
|
217
|
+
}
|
|
218
|
+
/** Calls `visit(index, depth)` for each code character from `open` to its closing bracket. */
|
|
219
|
+
function walkBrackets(text, open, ranges, visit) {
|
|
220
|
+
const end = closing(text, open, ranges);
|
|
221
|
+
let depth = 0;
|
|
222
|
+
for (let index = open; index < end; index += 1) {
|
|
223
|
+
if (!inCode(ranges, index)) continue;
|
|
224
|
+
const char = text[index];
|
|
225
|
+
if (OPENING.includes(char)) depth += 1;
|
|
226
|
+
else if (CLOSING.includes(char)) depth -= 1;
|
|
227
|
+
visit(index, depth, char);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/** Where `key` is a top-level key of the object literal at `open`. */
|
|
231
|
+
function topLevelKeys(text, open, key, ranges) {
|
|
232
|
+
const keys = [];
|
|
233
|
+
let previous = "";
|
|
234
|
+
walkBrackets(text, open, ranges, (index, depth, char) => {
|
|
235
|
+
if (depth === 1 && (previous === "{" || previous === ",") && text.startsWith(key, index) && !/[\w$]/.test(text[index + key.length] ?? "")) {
|
|
236
|
+
const after = /^\s*(\S)/.exec(text.slice(index + key.length))?.[1];
|
|
237
|
+
if (after === ":") keys.push({
|
|
238
|
+
index,
|
|
239
|
+
shorthand: false
|
|
240
|
+
});
|
|
241
|
+
else if (after === "," || after === "}") keys.push({
|
|
242
|
+
index,
|
|
243
|
+
shorthand: true
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
if (depth === 1 && !/\s/.test(char)) previous = char;
|
|
247
|
+
});
|
|
248
|
+
return keys;
|
|
249
|
+
}
|
|
250
|
+
function renameOptions(text, options) {
|
|
251
|
+
const ranges = codeRanges(text);
|
|
252
|
+
const edits = [];
|
|
253
|
+
for (const option of options) {
|
|
254
|
+
const call = new RegExp(`(?<![\\w$.])${escapeRegExp(option.call)}\\s*(?:<[^>]*>)?\\s*\\(`, "g");
|
|
255
|
+
for (const match of codeMatches(text, call, ranges)) {
|
|
256
|
+
const objects = [];
|
|
257
|
+
walkBrackets(text, match.index + match[0].length - 1, ranges, (index, depth, char) => {
|
|
258
|
+
if (depth === 2 && char === "{") objects.push(index);
|
|
259
|
+
});
|
|
260
|
+
for (const object of objects) for (const { index, shorthand } of topLevelKeys(text, object, option.from, ranges)) edits.push({
|
|
261
|
+
start: index,
|
|
262
|
+
end: index + option.from.length,
|
|
263
|
+
text: shorthand ? `${option.to}: ${option.from}` : option.to
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return applyEdits(text, edits);
|
|
268
|
+
}
|
|
269
|
+
/** Applies one codemod to a source file. */
|
|
270
|
+
function applyCodemod(codemod, source) {
|
|
271
|
+
let text = source;
|
|
272
|
+
if (codemod.imports) {
|
|
273
|
+
const imported = renameImports(text, codemod.imports);
|
|
274
|
+
text = renameIdentifiers(imported.text, new Map([...imported.locals].map((name) => [name, codemod.imports[name]])));
|
|
275
|
+
}
|
|
276
|
+
if (codemod.members) text = renameMembers(text, codemod.members);
|
|
277
|
+
if (codemod.props) text = renameProps(text, codemod.props);
|
|
278
|
+
if (codemod.options) text = renameOptions(text, codemod.options);
|
|
279
|
+
const review = (codemod.review ?? []).flatMap((hint) => text.split("\n").flatMap((line, index) => hint.pattern.test(line) ? [{
|
|
280
|
+
line: index + 1,
|
|
281
|
+
message: hint.message
|
|
282
|
+
}] : []));
|
|
283
|
+
return {
|
|
284
|
+
text,
|
|
285
|
+
review
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/cli/commands/codemod.ts
|
|
290
|
+
const CODEMOD_ARGS = {
|
|
291
|
+
name: {
|
|
292
|
+
type: "positional",
|
|
293
|
+
required: false,
|
|
294
|
+
description: "The codemod (0.4 or 0.5), then the files or directories to rewrite (default: the project)"
|
|
295
|
+
},
|
|
296
|
+
"dry-run": {
|
|
297
|
+
type: "boolean",
|
|
298
|
+
description: "Show the changes without writing them"
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
302
|
+
".ts",
|
|
303
|
+
".tsx",
|
|
304
|
+
".mts",
|
|
305
|
+
".cts",
|
|
306
|
+
".js",
|
|
307
|
+
".jsx",
|
|
308
|
+
".mjs",
|
|
309
|
+
".cjs"
|
|
310
|
+
]);
|
|
311
|
+
const SKIPPED_DIRS = /* @__PURE__ */ new Set([
|
|
312
|
+
"node_modules",
|
|
313
|
+
".git",
|
|
314
|
+
".next",
|
|
315
|
+
".turbo",
|
|
316
|
+
".vercel",
|
|
317
|
+
"dist",
|
|
318
|
+
"build",
|
|
319
|
+
"coverage"
|
|
320
|
+
]);
|
|
321
|
+
/** Source files under `path`, skipping dependencies, build output and `.d.ts` files. */
|
|
322
|
+
async function sourceFiles(path) {
|
|
323
|
+
const info = await stat(path).catch(() => void 0);
|
|
324
|
+
if (!info) return [];
|
|
325
|
+
if (info.isFile()) return [path];
|
|
326
|
+
const files = [];
|
|
327
|
+
for (const entry of await readdir(path, { withFileTypes: true })) {
|
|
328
|
+
const full = join(path, entry.name);
|
|
329
|
+
if (entry.isDirectory()) {
|
|
330
|
+
if (!SKIPPED_DIRS.has(entry.name)) files.push(...await sourceFiles(full));
|
|
331
|
+
} else if (SOURCE_EXTENSIONS.has(extname(entry.name)) && !entry.name.endsWith(".d.ts")) files.push(full);
|
|
332
|
+
}
|
|
333
|
+
return files.sort();
|
|
334
|
+
}
|
|
335
|
+
async function runCodemod(config, args, paint = plain) {
|
|
336
|
+
const [name, ...paths] = args._;
|
|
337
|
+
const names = Object.entries(CODEMODS).map(([key, codemod]) => ` ${key.padEnd(5)} ${codemod.description}`).join("\n");
|
|
338
|
+
if (name === void 0) return {
|
|
339
|
+
code: 2,
|
|
340
|
+
error: `Name a codemod:\n${names}`
|
|
341
|
+
};
|
|
342
|
+
const codemod = CODEMODS[name];
|
|
343
|
+
if (!codemod) return {
|
|
344
|
+
code: 2,
|
|
345
|
+
error: `Unknown codemod "${name}". Codemods:\n${names}`
|
|
346
|
+
};
|
|
347
|
+
const roots = (paths.length > 0 ? paths : ["."]).map((path) => resolve(config.root, path));
|
|
348
|
+
const files = [...new Set((await Promise.all(roots.map(sourceFiles))).flat())];
|
|
349
|
+
const dryRun = args["dry-run"] === true;
|
|
350
|
+
const changed = [];
|
|
351
|
+
const diffs = [];
|
|
352
|
+
const review = [];
|
|
353
|
+
for (const file of files) {
|
|
354
|
+
const source = await readFile(file, "utf8");
|
|
355
|
+
const result = applyCodemod(codemod, source);
|
|
356
|
+
const path = relative(config.root, file);
|
|
357
|
+
review.push(...result.review.map((hint) => ({
|
|
358
|
+
file: path,
|
|
359
|
+
...hint
|
|
360
|
+
})));
|
|
361
|
+
if (result.text === source) continue;
|
|
362
|
+
changed.push(path);
|
|
363
|
+
if (dryRun) diffs.push(fileDiff(path, source, result.text, paint));
|
|
364
|
+
else await writeIfChanged(file, result.text);
|
|
365
|
+
}
|
|
366
|
+
const lines = [...diffs, changed.length === 0 ? `Nothing to change in ${String(files.length)} files.` : `${dryRun ? "Would update" : "Updated"} ${String(changed.length)} of ${String(files.length)} files:\n${changed.map((path) => ` ${path}`).join("\n")}`];
|
|
367
|
+
if (review.length > 0) lines.push("", "Check these by hand:", ...review.map((hint) => ` ${hint.file}:${String(hint.line)}: ${hint.message}`));
|
|
368
|
+
return {
|
|
369
|
+
code: 0,
|
|
370
|
+
output: lines.join("\n"),
|
|
371
|
+
data: {
|
|
372
|
+
codemod: codemod.name,
|
|
373
|
+
dryRun,
|
|
374
|
+
changed,
|
|
375
|
+
review
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
const codemodCommand = defineCliCommand({
|
|
380
|
+
meta: {
|
|
381
|
+
name: "codemod",
|
|
382
|
+
description: "Rewrites imports and calls for renamed better-supabase APIs"
|
|
383
|
+
},
|
|
384
|
+
args: CODEMOD_ARGS,
|
|
385
|
+
run: (args, { config, io }) => runCodemod(config, args, painter(io.color))
|
|
386
|
+
});
|
|
387
|
+
//#endregion
|
|
388
|
+
export { codemodCommand };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as CliError } from "./errors-4v4DTtda.js";
|
|
2
2
|
import { t as display } from "./io-k41_z-jT.js";
|
|
3
|
-
import { c as resolve$1, i as extname, n as basename$1, o as join$1, r as dirname$1, s as normalize$1, t as resolveModulePath } from "./dist-
|
|
4
|
-
import { a as literal, c as
|
|
3
|
+
import { c as resolve$1, i as extname$1, n as basename$1, o as join$1, r as dirname$1, s as normalize$1, t as resolveModulePath } from "./dist-DBPdlPYK.js";
|
|
4
|
+
import { _ as unknown, a as literal, c as objectWithRest, f as record, g as union, h as string, i as getDotPath, l as optional, m as strictObject, n as boolean, o as nullable, p as safeParse, r as custom, s as number, t as array, u as picklist } from "./dist-xn4wlboc.js";
|
|
5
5
|
import * as nodeUtil from "node:util";
|
|
6
6
|
import { join, posix, resolve } from "node:path";
|
|
7
7
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
@@ -454,7 +454,7 @@ async function loadConfig$1(options) {
|
|
|
454
454
|
dir: options.cwd
|
|
455
455
|
}));
|
|
456
456
|
if (options.globalRc) {
|
|
457
|
-
const { findWorkspaceDir } = await import("./dist-
|
|
457
|
+
const { findWorkspaceDir } = await import("./dist-DreZ24Sz.js");
|
|
458
458
|
const workspaceDir = await findWorkspaceDir(options.cwd).catch(() => {});
|
|
459
459
|
if (workspaceDir) rcSources.push(read({
|
|
460
460
|
name: options.rcFile,
|
|
@@ -470,7 +470,7 @@ async function loadConfig$1(options) {
|
|
|
470
470
|
}
|
|
471
471
|
if (options.packageJson) {
|
|
472
472
|
const keys = (Array.isArray(options.packageJson) ? options.packageJson : [typeof options.packageJson === "string" ? options.packageJson : options.name]).filter((t) => t && typeof t === "string");
|
|
473
|
-
const { readPackageJSON } = await import("./dist-
|
|
473
|
+
const { readPackageJSON } = await import("./dist-DreZ24Sz.js");
|
|
474
474
|
const pkgJsonFile = await readPackageJSON(options.cwd).catch(() => {});
|
|
475
475
|
rawConfigs.packageJson = _merger({}, ...keys.map((key) => pkgJsonFile?.[key]));
|
|
476
476
|
}
|
|
@@ -602,7 +602,7 @@ async function resolveConfig$1(source, options, sourceOptions = {}) {
|
|
|
602
602
|
})).dir;
|
|
603
603
|
}
|
|
604
604
|
if (NPM_PACKAGE_RE.test(source)) source = tryResolve(source, options) || source;
|
|
605
|
-
const ext = extname(source);
|
|
605
|
+
const ext = extname$1(source);
|
|
606
606
|
const isDir = _isDirectory(resolve$1(options.cwd, source)) ?? (!ext || ext === basename$1(source));
|
|
607
607
|
const cwd = resolve$1(options.cwd, isDir ? source : dirname$1(source));
|
|
608
608
|
if (isDir) source = options.configFile;
|
|
@@ -616,7 +616,7 @@ async function resolveConfig$1(source, options, sourceOptions = {}) {
|
|
|
616
616
|
res.configFile = tryResolve(resolve$1(cwd, source), options) || tryResolve(resolve$1(cwd, ".config", source.replace(/\.config$/, "")), options) || tryResolve(resolve$1(cwd, ".config", source), options) || source;
|
|
617
617
|
if (!existsSync(res.configFile)) return res;
|
|
618
618
|
res._configFile = res.configFile;
|
|
619
|
-
const configFileExt = extname(res.configFile) || "";
|
|
619
|
+
const configFileExt = extname$1(res.configFile) || "";
|
|
620
620
|
if (configFileExt in ASYNC_LOADERS) res.config = (await ASYNC_LOADERS[configFileExt]())(await readFile(res.configFile, "utf8"));
|
|
621
621
|
else {
|
|
622
622
|
const _resolveModule = options.resolveModule || ((mod) => mod.default || mod);
|
|
@@ -696,6 +696,56 @@ const isGenerator = (value) => typeof value === "object" && value !== null && "n
|
|
|
696
696
|
* checks the leaves a typo or an old value breaks; nested objects the
|
|
697
697
|
* library reads loosely stay loose.
|
|
698
698
|
*/
|
|
699
|
+
const kitModuleEntries = {
|
|
700
|
+
mode: optional(picklist([
|
|
701
|
+
"managed",
|
|
702
|
+
"adopt",
|
|
703
|
+
"custom"
|
|
704
|
+
])),
|
|
705
|
+
schema: optional(string()),
|
|
706
|
+
tables: optional(record(string(), nullable(string()))),
|
|
707
|
+
columns: optional(record(string(), record(string(), nullable(string())))),
|
|
708
|
+
idType: optional(string()),
|
|
709
|
+
permissions: optional(stringRecord),
|
|
710
|
+
options: optional(record(string(), unknown())),
|
|
711
|
+
hooks: optional(strictObject({
|
|
712
|
+
schema: optional(string()),
|
|
713
|
+
functions: optional(stringRecord)
|
|
714
|
+
})),
|
|
715
|
+
events: optional(boolean())
|
|
716
|
+
};
|
|
717
|
+
const accessKit = strictObject({
|
|
718
|
+
...kitModuleEntries,
|
|
719
|
+
model: optional(picklist([
|
|
720
|
+
"roles",
|
|
721
|
+
"catalog",
|
|
722
|
+
"permdock",
|
|
723
|
+
"custom"
|
|
724
|
+
])),
|
|
725
|
+
roles: optional(record(string(), strings)),
|
|
726
|
+
functions: optional(strictObject({
|
|
727
|
+
can: optional(string()),
|
|
728
|
+
tenantIdsWith: optional(string()),
|
|
729
|
+
isPlatform: optional(string()),
|
|
730
|
+
canUser: optional(string()),
|
|
731
|
+
canAssign: optional(string()),
|
|
732
|
+
permissionClaims: optional(string())
|
|
733
|
+
})),
|
|
734
|
+
platformClaim: optional(string()),
|
|
735
|
+
disabled: optional(strictObject({
|
|
736
|
+
tenant: optional(string()),
|
|
737
|
+
user: optional(string()),
|
|
738
|
+
userKey: optional(string())
|
|
739
|
+
})),
|
|
740
|
+
activeTenant: optional(union([picklist(["claim", "resolver"]), strictObject({
|
|
741
|
+
profileColumn: string(),
|
|
742
|
+
key: optional(string())
|
|
743
|
+
})])),
|
|
744
|
+
permdock: optional(strictObject({
|
|
745
|
+
schema: optional(string()),
|
|
746
|
+
scope: optional(string())
|
|
747
|
+
}))
|
|
748
|
+
});
|
|
699
749
|
const ConfigSchema = strictObject({
|
|
700
750
|
$schema: optional(string()),
|
|
701
751
|
source: optional(strictObject({
|
|
@@ -744,7 +794,10 @@ const ConfigSchema = strictObject({
|
|
|
744
794
|
})),
|
|
745
795
|
buckets: optional(record(string(), record(string(), unknown()))),
|
|
746
796
|
topics: optional(stringRecord),
|
|
747
|
-
realtime: optional(strictObject({
|
|
797
|
+
realtime: optional(strictObject({
|
|
798
|
+
tables: optional(strings),
|
|
799
|
+
global: optional(strings)
|
|
800
|
+
})),
|
|
748
801
|
entitlements: optional(strictObject({
|
|
749
802
|
customer: optional(string()),
|
|
750
803
|
key: optional(string()),
|
|
@@ -768,6 +821,7 @@ const ConfigSchema = strictObject({
|
|
|
768
821
|
testsDir: optional(string()),
|
|
769
822
|
kit: optional(strings)
|
|
770
823
|
})),
|
|
824
|
+
kits: optional(objectWithRest({ access: optional(accessKit) }, strictObject(kitModuleEntries))),
|
|
771
825
|
seed: optional(strictObject({
|
|
772
826
|
entry: optional(string()),
|
|
773
827
|
output: optional(string())
|
|
@@ -1747,6 +1801,22 @@ function pgFunctionHooks(document) {
|
|
|
1747
1801
|
}] : [];
|
|
1748
1802
|
});
|
|
1749
1803
|
}
|
|
1804
|
+
/** The enabled Auth hooks with an `http://` or `https://` URI, by hook name. */
|
|
1805
|
+
function httpHooks(document) {
|
|
1806
|
+
const hooks = tomlGet(document, ["auth", "hook"]);
|
|
1807
|
+
if (typeof hooks !== "object" || Array.isArray(hooks)) return [];
|
|
1808
|
+
return Object.entries(hooks).flatMap(([hook, table]) => {
|
|
1809
|
+
if (typeof table !== "object" || Array.isArray(table)) return [];
|
|
1810
|
+
const { enabled, uri, secrets } = table;
|
|
1811
|
+
if (enabled !== true && enabled !== "true" || typeof uri !== "string") return [];
|
|
1812
|
+
if (!/^https?:\/\//i.test(uri.trim()) || !URL.canParse(uri.trim())) return [];
|
|
1813
|
+
return [{
|
|
1814
|
+
hook,
|
|
1815
|
+
uri: new URL(uri.trim()),
|
|
1816
|
+
secrets: typeof secrets === "string" ? secrets : void 0
|
|
1817
|
+
}];
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1750
1820
|
/** pg-delta when `[experimental.pgdelta] enabled = true`, otherwise the legacy migra engine. */
|
|
1751
1821
|
function diffEngine(toml) {
|
|
1752
1822
|
const enabled = tomlGet(toml?.document ?? {}, [
|
|
@@ -1892,4 +1962,4 @@ async function databaseUrl(config, env, fromStdin) {
|
|
|
1892
1962
|
return `postgresql://postgres:postgres@127.0.0.1:${await readSupabasePort(config.root, "db") ?? 54322}/postgres`;
|
|
1893
1963
|
}
|
|
1894
1964
|
//#endregion
|
|
1895
|
-
export { loadConfig as a, diffEngine as c,
|
|
1965
|
+
export { loadConfig as a, diffEngine as c, pgFunctionHooks as d, readSupabaseToml as f, importModule as i, httpHooks as l, tomlGet as m, findConfig as n, readSupabasePort as o, schemaPaths as p, importExport as r, stdinDatabaseUrl as s, databaseUrl as t, migrationCommand as u };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as loadConfig, i as importModule, n as findConfig, o as readSupabasePort, r as importExport, s as stdinDatabaseUrl, t as databaseUrl } from "./config-
|
|
1
|
+
import { a as loadConfig, i as importModule, n as findConfig, o as readSupabasePort, r as importExport, s as stdinDatabaseUrl, t as databaseUrl } from "./config-CPVpXP5I.js";
|
|
2
2
|
export { databaseUrl, findConfig, importExport, importModule, loadConfig, readSupabasePort, stdinDatabaseUrl };
|