better-supabase 0.3.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 +9 -6
- package/bin/better-supabase.js +4 -0
- package/dist/{base64-CQeB1eSf.js → base64-D2gsioCY.js} +2 -2
- package/dist/channel-FQW-CnGR.d.ts +70 -0
- package/dist/claims-BAf6c7is.js +48 -0
- package/dist/cli/_format-Cax5EsM9.js +101 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +48 -0
- package/dist/cli/codemod-DqV7612m.js +388 -0
- package/dist/cli/command-CK14fP91.js +502 -0
- package/dist/cli/compare-BmIWVEui.js +9 -0
- package/dist/cli/config-CPVpXP5I.js +1965 -0
- package/dist/cli/config-dtoekM0v.js +2 -0
- package/dist/cli/db-DOBPt660.js +52 -0
- package/dist/cli/diff-SjkO5rNr.js +752 -0
- package/dist/cli/dist-DBPdlPYK.js +1112 -0
- package/dist/cli/dist-DreZ24Sz.js +129 -0
- package/dist/cli/dist-xn4wlboc.js +732 -0
- package/dist/cli/doctor-L7Z8mYTx.js +2863 -0
- package/dist/cli/env-DmKv_G4A.js +108 -0
- package/dist/cli/env-jIFUADLY.js +511 -0
- package/dist/cli/errors-4v4DTtda.js +56 -0
- package/dist/cli/fastest-levenshtein-CFN-lNDv.js +120 -0
- package/dist/cli/gen-BJc9vdyu.js +2 -0
- package/dist/cli/gen-C2osRcr5.js +2204 -0
- package/dist/cli/index.d.ts +493 -0
- package/dist/cli/index.js +184 -0
- package/dist/cli/init-Saf5-R9T.js +550 -0
- package/dist/cli/introspect--H7oGmcd.js +81 -0
- package/dist/cli/io-k41_z-jT.js +24 -0
- package/dist/cli/json5-ChRycquj.js +787 -0
- package/dist/cli/jsonc-BUniUpOk.js +2 -0
- package/dist/cli/jsonc-D5Fu67jw.js +45 -0
- package/dist/cli/keys-ByKHnvP9.js +83 -0
- package/dist/cli/ohash-D7bG_EOb.js +277 -0
- package/dist/cli/openapi-Cp5Fyta-.js +66 -0
- package/dist/cli/project-B_GeXyHh.js +70 -0
- package/dist/cli/prompts-BNcNfAve.js +1142 -0
- package/dist/cli/prompts-BTYQGunc.js +2 -0
- package/dist/cli/read-sets-BfMQcKy8.js +289 -0
- package/dist/cli/rolldown-runtime-BPOCksWG.js +24 -0
- package/dist/cli/run-BKR2W_79.js +351 -0
- package/dist/cli/seed-CUlqWh-8.js +98 -0
- package/dist/cli/skills-LJJIhLFR.js +137 -0
- package/dist/cli/sql-DzPbfngx.js +348 -0
- package/dist/cli/style-C0NFdJRL.js +29 -0
- package/dist/cli/toml-DB-MNnFs.js +424 -0
- package/dist/cli/version-BDJuO0UR.js +4 -0
- package/dist/cli/yaml-CYCbJ6et.js +2252 -0
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +15 -22
- package/dist/clone-BfgmLU90.js +21 -0
- package/dist/{compiler-2zqGzxVZ.d.ts → compiler-BXH_aZ7N.d.ts} +2 -2
- package/dist/config/index.d.ts +4 -4
- package/dist/config/index.js +5 -5
- package/dist/{config-DOsGYSiT.js → config-DreERlKo.js} +1 -1
- package/dist/{config-C1CYcm6o.d.ts → config-T_ejwyd3.d.ts} +176 -11
- package/dist/{define-DUbydmJa.d.ts → define-Bp_BZa5h.d.ts} +37 -29
- package/dist/{define-DF341GDj.js → define-cNKzqwL_.js} +356 -89
- package/dist/edge/index.d.ts +20 -13
- package/dist/edge/index.js +55 -26
- package/dist/{entitlements-DvJXoI02.d.ts → entitlements-DUxU4oHe.d.ts} +2 -2
- package/dist/env/index.d.ts +2 -2
- package/dist/env/index.js +34 -1
- package/dist/{errors-Bl3rkOzo.js → errors-DtwXa6b8.js} +2 -1
- package/dist/events/index.d.ts +3 -2
- package/dist/events/index.js +69 -16
- package/dist/events-aIO7vsIk.d.ts +230 -0
- package/dist/executor-BunPOO-k.d.ts +402 -0
- package/dist/{executor-B26lgbHD.d.ts → executor-Cghdstwu.d.ts} +1 -2
- package/dist/{executor-C57jx2pn.js → executor-XycESQPH.js} +3 -3
- package/dist/hono/index.d.ts +27 -23
- package/dist/hono/index.js +46 -11
- package/dist/impersonation-VfaGc4Q_.js +41 -0
- package/dist/{index-BNsABq7P.d.ts → index-BGdgBPdf.d.ts} +66 -25
- package/dist/{index-qriRM9cZ.d.ts → index-C7f8cOBM.d.ts} +4 -4
- package/dist/{index-Dy6kuF0P.d.ts → index-CLg87OBW.d.ts} +6 -1
- package/dist/{index-GV77NpRP.d.ts → index-DOESKG27.d.ts} +34 -9
- package/dist/{index-CriFFJ_p.d.ts → index-DgILJRXj.d.ts} +43 -17
- package/dist/{index-UJ-LUxtI.d.ts → index-DmXSxbLi.d.ts} +14 -14
- package/dist/{index-Cf-D2jk1.d.ts → index-Dxn2a5cw.d.ts} +2 -2
- package/dist/{index-CTTMS6_1.d.ts → index-SaTsEfGP.d.ts} +86 -9
- package/dist/{index-CADlNHK-.d.ts → index-fag8VJZ2.d.ts} +5 -6
- package/dist/index.d.ts +34 -17
- package/dist/index.js +15 -14
- package/dist/jobs/index.d.ts +147 -95
- package/dist/jobs/index.js +773 -250
- package/dist/{json-schema--aOXAGfU.js → json-schema-m1fiwKgN.js} +23 -2
- 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-Be4GwsqI.js → kits-CGLLrNPd.js} +38 -10
- package/dist/list/index.d.ts +1 -1
- package/dist/list/index.js +3 -3
- package/dist/{live-D8rV1Ldw.js → live-CdJBOc4f.js} +13 -9
- package/dist/{live-QE3UPbGm.d.ts → live-D9W2M5aO.d.ts} +16 -15
- package/dist/lookup-BaP5bI27.js +18 -0
- package/dist/mcp/index.d.ts +39 -22
- package/dist/mcp/index.js +39 -25
- package/dist/{mfa-x3V3vGh-.d.ts → mfa-CusDgPaD.d.ts} +5 -1
- package/dist/next/image/index.js +6 -3
- package/dist/next/index.d.ts +60 -36
- package/dist/next/index.js +167 -50
- 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 +6 -6
- package/dist/orgs/index.d.ts +132 -0
- package/dist/orgs/index.js +245 -0
- package/dist/orpc/index.d.ts +37 -20
- package/dist/orpc/index.js +24 -11
- package/dist/otel/index.d.ts +24 -5
- package/dist/otel/index.js +124 -64
- 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-DVRB8qNE.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 +52 -17
- 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 +3 -3
- package/dist/plugins/tenant/index.js +45 -21
- 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-B9qsLyFR.d.ts → pool-C9voM4Kw.d.ts} +24 -6
- package/dist/postgres/index.d.ts +5 -5
- package/dist/postgres/index.js +20 -10
- package/dist/{postgrest-DmBlevh-.d.ts → postgrest-CruYKAvV.d.ts} +1 -1
- package/dist/{problem-CGt1ADix.js → problem-BW1KhzSG.js} +2 -1
- package/dist/{problem-Z2RTQjZD.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-BdKLTPlj.js → query-CCbo44lG.js} +18 -18
- 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 +16 -5
- package/dist/react/server.js +12 -4
- package/dist/react/session.d.ts +10 -4
- package/dist/react/session.js +11 -3
- package/dist/{react-DNBYNazu.js → react-C_s7kiNz.js} +138 -46
- package/dist/{read-set-D0qBcboM.js → read-set-DQFt1N_Y.js} +71 -15
- package/dist/realtime/index.d.ts +3 -3
- package/dist/realtime/index.js +14 -12
- package/dist/{index-kpgopLNv.d.ts → refresh-BTrQ_ZTp.d.ts} +6 -3
- package/dist/{resolve-BRciX2jK.d.ts → resolve-C15TJq77.d.ts} +22 -11
- package/dist/{resource-D30rp0GN.js → resource-CRxxwkQq.js} +24 -9
- package/dist/{resource-CwVgiI5q.d.ts → resource-D8iqWMr-.d.ts} +6 -6
- package/dist/respond-D2OQl62-.d.ts +371 -0
- package/dist/{result-DWXatkd6.js → result-BKiliPY7.js} +2 -2
- package/dist/server/index.d.ts +17 -15
- package/dist/server/index.js +16 -22
- package/dist/server-Csx2sRjg.js +655 -0
- package/dist/{shared-_6-uPL7E.js → shared-D1dRUrAg.js} +19 -4
- package/dist/signers-Cc6r98SW.d.ts +162 -0
- package/dist/{simplify-LakqK1vH.js → simplify-_0oUKqCd.js} +27 -95
- package/dist/sql/index.d.ts +247 -10
- package/dist/sql/index.js +8591 -780
- package/dist/{sql-BIgk12ew.js → sql-Coh6n4cC.js} +11 -3
- package/dist/ssr/index.d.ts +4 -4
- package/dist/ssr/index.js +1 -2
- package/dist/{standard-FUi3Z3-7.js → standard-D7r6dMUu.js} +6 -3
- package/dist/{standard-eudBiRk1.d.ts → standard-J4YgMOLm.d.ts} +1 -1
- package/dist/{stats-D78UQ8Yu.js → stats-Bqob3WqT.js} +34 -9
- package/dist/storage/index.d.ts +4 -4
- package/dist/storage/index.js +174 -27
- 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/{tables-Dhha3BXM.js → tables-Cb-3_VWc.js} +14 -0
- package/dist/{permdock-sql-Bta_G0v-.js → template-TxrGI5jR.js} +2 -31
- package/dist/{temporal-BwshQk0W.js → temporal-CVlIV2DZ.js} +17 -4
- package/dist/{temporal-required-CMxeSVPo.js → temporal-required-CAt4Dc9Z.js} +2 -2
- package/dist/testing/index.d.ts +113 -24
- package/dist/testing/index.js +375 -47
- package/dist/{types-DONv9SHN.d.ts → types-Dnf_wRDz.d.ts} +26 -3
- package/dist/user-change-CHFEUro1.js +49 -0
- package/dist/{webhooks-CAIFQSTM.js → verify-Ce49ETPz.js} +38 -19
- package/dist/{version-BfpG2gks.js → version-DM_Roffb.js} +1 -1
- package/dist/{view-3Po_PVlr.d.ts → view-BEf0diC5.d.ts} +10 -5
- package/dist/{mfa-BxoR1RkN.js → view-Bq64ki8-.js} +210 -64
- package/dist/webhooks/index.d.ts +136 -5
- package/dist/webhooks/index.js +588 -2
- package/dist/wire-D2dT86vi.js +35 -0
- package/package.json +50 -10
- package/schemas/config-v1.json +131 -1
- package/schemas/doctor-report-v1.json +10 -0
- package/skills/better-supabase/SKILL.md +60 -10
- package/skills/better-supabase/references/plugins.md +13 -14
- package/skills/better-supabase/references/troubleshooting.md +25 -4
- package/skills/better-supabase-api/SKILL.md +74 -19
- package/skills/better-supabase-api/references/adapters.md +48 -27
- package/skills/better-supabase-auth/SKILL.md +149 -0
- package/skills/better-supabase-auth/references/permdock.md +100 -0
- package/skills/better-supabase-testing/SKILL.md +58 -4
- package/dist/claims-CoTobNC-.js +0 -25
- package/dist/events-Do8jXh4D.d.ts +0 -84
- package/dist/executor-DynmIWhq.d.ts +0 -195
- package/dist/invalidate-DbxuL2jL.js +0 -18
- package/dist/permdock-sql-DImJULY-.d.ts +0 -17
- package/dist/plugin-BqR6wKMB.js +0 -23
- package/dist/respond-C44EZAJo.js +0 -399
- package/dist/respond-DAkPIdTH.d.ts +0 -175
- package/dist/result-c2OYgCV2.d.ts +0 -203
- package/dist/view-wZ-9qIUz.js +0 -45
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { U as Operation, _ as DbError } from "./executor-BunPOO-k.js";
|
|
3
|
+
import { g as RequestContext, l as MutationIntent, u as MutationKind } from "./plugin-o144f322.js";
|
|
4
|
+
//#region src/core/logger.d.ts
|
|
5
|
+
type LogFields = Readonly<Record<string, unknown>>;
|
|
6
|
+
/**
|
|
7
|
+
* Where better-supabase reports problems it swallows on purpose: event
|
|
8
|
+
* handlers, `afterMutation` hooks, sinks and cache adapters that throw.
|
|
9
|
+
* Structured loggers (pino, consola, OpenTelemetry logs) fit directly.
|
|
10
|
+
*/
|
|
11
|
+
interface Logger {
|
|
12
|
+
debug(message: string, fields?: LogFields): void;
|
|
13
|
+
info(message: string, fields?: LogFields): void;
|
|
14
|
+
warn(message: string, fields?: LogFields): void;
|
|
15
|
+
error(message: string, fields?: LogFields): void;
|
|
16
|
+
}
|
|
17
|
+
/** The default: `console`, with a `better-supabase:` prefix. */
|
|
18
|
+
declare const consoleLogger: Logger;
|
|
19
|
+
declare const silentLogger: Logger;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/core/kit-events.d.ts
|
|
22
|
+
/** `support.*`: support sessions, where a platform admin views the app as a user. */
|
|
23
|
+
interface SupportEventData {
|
|
24
|
+
/** Absent on `support.denied`. */
|
|
25
|
+
readonly sessionId?: string;
|
|
26
|
+
readonly adminId: string;
|
|
27
|
+
readonly targetUserId: string;
|
|
28
|
+
readonly reason?: string;
|
|
29
|
+
readonly readOnly?: boolean;
|
|
30
|
+
readonly expiresAt?: Temporal.Instant;
|
|
31
|
+
/** `support.denied`: which check refused it. */
|
|
32
|
+
readonly denial?: "authorize" | "permission" | "policy" | "store";
|
|
33
|
+
/** `support.ended`: who or what ended it. */
|
|
34
|
+
readonly endedBy?: "admin" | "expired" | "revoked";
|
|
35
|
+
}
|
|
36
|
+
/** `org.*`: organizations and their members. */
|
|
37
|
+
interface OrgEventData {
|
|
38
|
+
readonly organizationId: string;
|
|
39
|
+
/** The member the event is about. */
|
|
40
|
+
readonly userId?: string;
|
|
41
|
+
readonly role?: string;
|
|
42
|
+
readonly previousRole?: string;
|
|
43
|
+
}
|
|
44
|
+
/** `invitation.*`. The token is never part of the event. */
|
|
45
|
+
interface InvitationEventData {
|
|
46
|
+
readonly invitationId: string;
|
|
47
|
+
/** Absent for a platform-scope invitation. */
|
|
48
|
+
readonly organizationId?: string;
|
|
49
|
+
readonly email?: string;
|
|
50
|
+
readonly role?: string;
|
|
51
|
+
}
|
|
52
|
+
/** `notification.*`. */
|
|
53
|
+
interface NotificationEventData {
|
|
54
|
+
readonly notificationId: string;
|
|
55
|
+
readonly type: string;
|
|
56
|
+
readonly recipientIds?: readonly string[];
|
|
57
|
+
readonly channel?: string;
|
|
58
|
+
readonly error?: string;
|
|
59
|
+
}
|
|
60
|
+
/** `webhook.*`: outgoing webhooks. */
|
|
61
|
+
interface WebhookEventData {
|
|
62
|
+
readonly endpointId: string;
|
|
63
|
+
readonly deliveryId?: string;
|
|
64
|
+
readonly eventType?: string;
|
|
65
|
+
/** The HTTP status of the attempt, when there was a response. */
|
|
66
|
+
readonly status?: number;
|
|
67
|
+
readonly attempt?: number;
|
|
68
|
+
readonly error?: string;
|
|
69
|
+
}
|
|
70
|
+
/** Every kit event type and its data. */
|
|
71
|
+
interface KitEventMap {
|
|
72
|
+
"support.started": SupportEventData;
|
|
73
|
+
"support.ended": SupportEventData;
|
|
74
|
+
"support.denied": SupportEventData;
|
|
75
|
+
"org.created": OrgEventData;
|
|
76
|
+
"org.updated": OrgEventData;
|
|
77
|
+
"org.deleted": OrgEventData;
|
|
78
|
+
"org.member_added": OrgEventData;
|
|
79
|
+
"org.member_removed": OrgEventData;
|
|
80
|
+
"org.member_left": OrgEventData;
|
|
81
|
+
"org.role_changed": OrgEventData;
|
|
82
|
+
"org.ownership_transferred": OrgEventData;
|
|
83
|
+
"org.switched": OrgEventData;
|
|
84
|
+
"invitation.created": InvitationEventData;
|
|
85
|
+
"invitation.resent": InvitationEventData;
|
|
86
|
+
"invitation.accepted": InvitationEventData;
|
|
87
|
+
"invitation.declined": InvitationEventData;
|
|
88
|
+
"invitation.revoked": InvitationEventData;
|
|
89
|
+
"notification.created": NotificationEventData;
|
|
90
|
+
"notification.delivered": NotificationEventData;
|
|
91
|
+
"notification.failed": NotificationEventData;
|
|
92
|
+
"webhook.delivered": WebhookEventData;
|
|
93
|
+
"webhook.failed": WebhookEventData;
|
|
94
|
+
"webhook.disabled": WebhookEventData;
|
|
95
|
+
}
|
|
96
|
+
type KitEventType = keyof KitEventMap;
|
|
97
|
+
/** Where an event came from, beyond its data. */
|
|
98
|
+
interface KitEventMeta {
|
|
99
|
+
/** e.g. `organizations/<id>`; becomes the CloudEvents `subject`. */
|
|
100
|
+
readonly subject?: string;
|
|
101
|
+
readonly tenant?: string;
|
|
102
|
+
/** The user who caused it. */
|
|
103
|
+
readonly actorId?: string;
|
|
104
|
+
readonly context?: RequestContext;
|
|
105
|
+
}
|
|
106
|
+
/** A kit event as `betterSupabase.on('kit', handler)` receives it. */
|
|
107
|
+
type KitEvent<K extends KitEventType = KitEventType> = { readonly [T in K]: KitEventMeta & {
|
|
108
|
+
readonly type: T;
|
|
109
|
+
/** A copy: changing it never changes what the kit does (invariant 5). */
|
|
110
|
+
readonly data: KitEventMap[T];
|
|
111
|
+
readonly time: Temporal.Instant;
|
|
112
|
+
}; }[K];
|
|
113
|
+
/** A type, or a `prefix.*` pattern such as `support.*`. */
|
|
114
|
+
type KitEventPattern = KitEventType | `${KitEventType extends `${infer P}.${string}` ? P : never}.*`;
|
|
115
|
+
/** The event types a pattern matches. */
|
|
116
|
+
type KitEventsMatching<P extends KitEventPattern> = P extends `${infer Prefix}.*` ? Extract<KitEventType, `${Prefix}.${string}`> : Extract<P, KitEventType>;
|
|
117
|
+
/**
|
|
118
|
+
* Fixed OpenTelemetry attribute names for kit work, so dashboards and
|
|
119
|
+
* queries can rely on them.
|
|
120
|
+
*/
|
|
121
|
+
declare const KIT_ATTRIBUTES: {
|
|
122
|
+
readonly event: "better_supabase.kit.event";
|
|
123
|
+
readonly tenant: "better_supabase.tenant";
|
|
124
|
+
readonly actor: "better_supabase.actor.id";
|
|
125
|
+
readonly supportSessionId: "better_supabase.support.session_id";
|
|
126
|
+
readonly orgId: "better_supabase.org.id";
|
|
127
|
+
readonly invitationId: "better_supabase.invitation.id";
|
|
128
|
+
readonly notificationType: "better_supabase.notification.type";
|
|
129
|
+
readonly webhookEndpointId: "better_supabase.webhook.endpoint_id";
|
|
130
|
+
};
|
|
131
|
+
/** The `KIT_ATTRIBUTES` an event carries. */
|
|
132
|
+
declare function kitEventAttributes(event: KitEvent): Record<string, string>;
|
|
133
|
+
/**
|
|
134
|
+
* Listens to the kit events that match `pattern` (`'support.started'` or
|
|
135
|
+
* `'support.*'`). Returns a function that stops listening.
|
|
136
|
+
*/
|
|
137
|
+
declare function onKitEvent<P extends KitEventPattern>(betterSupabase: {
|
|
138
|
+
readonly events: EventHub;
|
|
139
|
+
}, pattern: P, handler: (event: KitEvent<KitEventsMatching<P>>) => void): () => void;
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/core/events.d.ts
|
|
142
|
+
interface QueryEvent {
|
|
143
|
+
readonly table: string;
|
|
144
|
+
readonly operation: Operation["kind"];
|
|
145
|
+
readonly ok: boolean;
|
|
146
|
+
readonly durationMs: number;
|
|
147
|
+
readonly rows: number;
|
|
148
|
+
/**
|
|
149
|
+
* An unbounded read returned `maxRows` rows: PostgREST's `db-max-rows`
|
|
150
|
+
* probably cut it short. Add `limit` or use `paginate`.
|
|
151
|
+
*/
|
|
152
|
+
readonly truncated: boolean;
|
|
153
|
+
}
|
|
154
|
+
interface MutationNotice {
|
|
155
|
+
readonly table: string;
|
|
156
|
+
readonly kind: MutationKind;
|
|
157
|
+
/** See `MutationEvent.intent`. */
|
|
158
|
+
readonly intent?: MutationIntent;
|
|
159
|
+
/** A copy of the returned rows: changing it never changes the result. */
|
|
160
|
+
readonly rows: readonly Readonly<Record<string, unknown>>[];
|
|
161
|
+
/** See `MutationEvent.keys`. */
|
|
162
|
+
readonly keys?: readonly Readonly<Record<string, unknown>>[];
|
|
163
|
+
/** See `MutationEvent.tenant`. */
|
|
164
|
+
readonly tenant?: string;
|
|
165
|
+
readonly context: RequestContext;
|
|
166
|
+
}
|
|
167
|
+
/** A successful RPC registered with `betterSupabase.defineRpc(name, { invalidates })`. */
|
|
168
|
+
interface RpcNotice {
|
|
169
|
+
readonly name: string;
|
|
170
|
+
/** App keys of the tables the function changes. */
|
|
171
|
+
readonly invalidates: readonly string[];
|
|
172
|
+
readonly context: RequestContext;
|
|
173
|
+
}
|
|
174
|
+
interface ErrorEvent {
|
|
175
|
+
readonly table?: string;
|
|
176
|
+
readonly error: DbError;
|
|
177
|
+
}
|
|
178
|
+
interface AuthEvent {
|
|
179
|
+
readonly source: "bearer" | "cookie" | "none";
|
|
180
|
+
readonly ok: boolean;
|
|
181
|
+
readonly userId?: string;
|
|
182
|
+
/**
|
|
183
|
+
* Why there is no user: the anon reason (`expired`, `signed_out`, ...) or
|
|
184
|
+
* the invalid reason (`token`, `claims`, `actor`).
|
|
185
|
+
*/
|
|
186
|
+
readonly reason?: "none" | "expired" | "signed_out" | "refresh_failed" | "token" | "claims" | "actor";
|
|
187
|
+
/** The user's `source` as the resolver set it, e.g. a custom resolver's name. */
|
|
188
|
+
readonly rawSource?: string;
|
|
189
|
+
}
|
|
190
|
+
interface RefreshEvent {
|
|
191
|
+
readonly ok: boolean;
|
|
192
|
+
readonly shared: boolean;
|
|
193
|
+
readonly durationMs: number;
|
|
194
|
+
}
|
|
195
|
+
interface BetterSupabaseEvents {
|
|
196
|
+
query: QueryEvent;
|
|
197
|
+
mutation: MutationNotice;
|
|
198
|
+
rpc: RpcNotice;
|
|
199
|
+
error: ErrorEvent;
|
|
200
|
+
auth: AuthEvent;
|
|
201
|
+
refresh: RefreshEvent;
|
|
202
|
+
/** Support sessions, organizations, invitations, notifications and webhooks. */
|
|
203
|
+
kit: KitEvent;
|
|
204
|
+
}
|
|
205
|
+
type EventName = keyof BetterSupabaseEvents;
|
|
206
|
+
type EventHandler<K extends EventName> = (event: BetterSupabaseEvents[K]) => void;
|
|
207
|
+
/**
|
|
208
|
+
* Observers only: a handler that throws is reported to the logger and never
|
|
209
|
+
* changes a result.
|
|
210
|
+
*/
|
|
211
|
+
declare class EventHub {
|
|
212
|
+
#private;
|
|
213
|
+
readonly logger: Logger;
|
|
214
|
+
constructor(logger?: Logger);
|
|
215
|
+
on<K extends EventName>(name: K, handler: EventHandler<K>): () => void;
|
|
216
|
+
has(name: EventName): boolean;
|
|
217
|
+
/**
|
|
218
|
+
* Keeps async work a handler started (a sink send) until it settles, so
|
|
219
|
+
* adapters can hand it to `after()` or `waitUntil`. Its outcome is ignored:
|
|
220
|
+
* handlers report their own failures.
|
|
221
|
+
*/
|
|
222
|
+
track(work: PromiseLike<unknown>): void;
|
|
223
|
+
/** Whether tracked work is still running. */
|
|
224
|
+
get pending(): boolean;
|
|
225
|
+
/** Resolves once the work tracked so far has settled. Never rejects. */
|
|
226
|
+
settled(): Promise<void>;
|
|
227
|
+
emit<K extends EventName>(name: K, event: BetterSupabaseEvents[K]): void;
|
|
228
|
+
}
|
|
229
|
+
//#endregion
|
|
230
|
+
export { kitEventAttributes as C, consoleLogger as D, Logger as E, silentLogger as O, WebhookEventData as S, LogFields as T, KitEventType as _, EventHub as a, OrgEventData as b, QueryEvent as c, InvitationEventData as d, KIT_ATTRIBUTES as f, KitEventPattern as g, KitEventMeta as h, EventHandler as i, RefreshEvent as l, KitEventMap as m, BetterSupabaseEvents as n, EventName as o, KitEvent as p, ErrorEvent as r, MutationNotice as s, AuthEvent as t, RpcNotice as u, KitEventsMatching as v, onKitEvent as w, SupportEventData as x, NotificationEventData as y };
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { E as RelationMeta, F as TableMeta, l as Codec } from "./types-Dnf_wRDz.js";
|
|
2
|
+
//#region src/ir/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* The query IR. Every repository call becomes one of these operations; the
|
|
5
|
+
* executor compiles it to PostgREST or SQL. Column names in the IR are
|
|
6
|
+
* database names; `Selection` carries the app aliases.
|
|
7
|
+
*/
|
|
8
|
+
type ColumnOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "is" | "like" | "ilike" | "contains" | "containedBy" | "overlaps" | "fts";
|
|
9
|
+
type Quantifier = "some" | "none" | "every";
|
|
10
|
+
type Condition = {
|
|
11
|
+
readonly kind: "and";
|
|
12
|
+
readonly items: readonly Condition[];
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: "or";
|
|
15
|
+
readonly items: readonly Condition[];
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: "not";
|
|
18
|
+
readonly item: Condition;
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: "column";
|
|
21
|
+
readonly column: string;
|
|
22
|
+
readonly op: ColumnOp;
|
|
23
|
+
readonly value: unknown;
|
|
24
|
+
/** Full-text search configuration for `fts`. */
|
|
25
|
+
readonly config?: string;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: "relation";
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly relation: RelationMeta;
|
|
30
|
+
readonly target: TableMeta;
|
|
31
|
+
readonly quantifier: Quantifier;
|
|
32
|
+
readonly where: Condition | undefined;
|
|
33
|
+
};
|
|
34
|
+
interface SelectColumn {
|
|
35
|
+
/** Key in the returned row. */
|
|
36
|
+
readonly alias: string;
|
|
37
|
+
/** Database column name. */
|
|
38
|
+
readonly column: string;
|
|
39
|
+
/** Read the column as text, so exact `int8`/`numeric` values survive JSON. */
|
|
40
|
+
readonly cast?: "text";
|
|
41
|
+
/** Decodes the returned value (see `ColumnMeta.codec`). */
|
|
42
|
+
readonly codec?: Codec;
|
|
43
|
+
}
|
|
44
|
+
interface OrderTerm {
|
|
45
|
+
readonly column: string;
|
|
46
|
+
readonly direction: "asc" | "desc";
|
|
47
|
+
readonly nulls?: "first" | "last";
|
|
48
|
+
}
|
|
49
|
+
interface Include {
|
|
50
|
+
readonly alias: string;
|
|
51
|
+
readonly relation: RelationMeta;
|
|
52
|
+
readonly target: TableMeta;
|
|
53
|
+
readonly selection: Selection;
|
|
54
|
+
readonly where: Condition | undefined;
|
|
55
|
+
readonly orderBy: readonly OrderTerm[];
|
|
56
|
+
readonly limit: number | undefined;
|
|
57
|
+
/** Drop parent rows without a match (`!inner`). */
|
|
58
|
+
readonly required: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* `_count` include: returns the number of matching related rows instead of
|
|
61
|
+
* rows, folded into `row._count[count]` when decoded.
|
|
62
|
+
*/
|
|
63
|
+
readonly count?: string;
|
|
64
|
+
/**
|
|
65
|
+
* `_sum`/`_avg`/`_min`/`_max` include: `selection.aggregate` holds the
|
|
66
|
+
* measures, folded into `row[`_${fn}`][name]` when decoded.
|
|
67
|
+
*/
|
|
68
|
+
readonly aggregate?: {
|
|
69
|
+
readonly fn: AggregateFn;
|
|
70
|
+
readonly name: string;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
type AggregateFn = "sum" | "avg" | "min" | "max";
|
|
74
|
+
interface Measure {
|
|
75
|
+
readonly fn: AggregateFn;
|
|
76
|
+
/** Key in the returned row (`_sum_amount`, or the column alias in an include). */
|
|
77
|
+
readonly key: string;
|
|
78
|
+
/** App column name, the key under `_sum` in the decoded row. */
|
|
79
|
+
readonly alias: string;
|
|
80
|
+
/** Database column name. */
|
|
81
|
+
readonly column: string;
|
|
82
|
+
/** Read the result as text, so exact `int8`/`numeric` values survive JSON. */
|
|
83
|
+
readonly cast?: "text";
|
|
84
|
+
readonly codec?: Codec;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Aggregates instead of rows. `Selection.columns` become the grouping
|
|
88
|
+
* columns; without any, the result is exactly one row.
|
|
89
|
+
*/
|
|
90
|
+
interface Aggregation {
|
|
91
|
+
/** Also return `_count`, the number of rows in each group. */
|
|
92
|
+
readonly count: boolean;
|
|
93
|
+
readonly measures: readonly Measure[];
|
|
94
|
+
}
|
|
95
|
+
interface Selection {
|
|
96
|
+
readonly columns: readonly SelectColumn[];
|
|
97
|
+
readonly includes: readonly Include[];
|
|
98
|
+
readonly aggregate?: Aggregation;
|
|
99
|
+
}
|
|
100
|
+
type CountMode = "exact" | "planned" | "estimated";
|
|
101
|
+
interface SelectOp {
|
|
102
|
+
readonly kind: "select";
|
|
103
|
+
readonly table: TableMeta;
|
|
104
|
+
readonly selection: Selection;
|
|
105
|
+
readonly where: Condition | undefined;
|
|
106
|
+
readonly orderBy: readonly OrderTerm[];
|
|
107
|
+
readonly limit: number | undefined;
|
|
108
|
+
readonly offset: number | undefined;
|
|
109
|
+
readonly count: CountMode | undefined;
|
|
110
|
+
/** Only count, return no rows. */
|
|
111
|
+
readonly head: boolean;
|
|
112
|
+
readonly single: "one" | "maybe" | undefined;
|
|
113
|
+
/** `limit` includes one row past the page, which `paginate()` reads to set `hasMore`. */
|
|
114
|
+
readonly lookAhead?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Read from this set-returning function instead of the table (`db.$search`).
|
|
117
|
+
* Only executors with `functionSources` honor it.
|
|
118
|
+
*/
|
|
119
|
+
readonly source?: FunctionSource;
|
|
120
|
+
}
|
|
121
|
+
/** A function returning `setof <table>`, called with named arguments. */
|
|
122
|
+
interface FunctionSource {
|
|
123
|
+
readonly schema: string;
|
|
124
|
+
readonly name: string;
|
|
125
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
126
|
+
}
|
|
127
|
+
interface InsertOp {
|
|
128
|
+
readonly kind: "insert";
|
|
129
|
+
readonly table: TableMeta;
|
|
130
|
+
/** Rows keyed by database column names. */
|
|
131
|
+
readonly rows: readonly Readonly<Record<string, unknown>>[];
|
|
132
|
+
readonly returning: Selection | undefined;
|
|
133
|
+
readonly onConflict: {
|
|
134
|
+
readonly columns: readonly string[];
|
|
135
|
+
readonly action: "update" | "ignore";
|
|
136
|
+
} | undefined;
|
|
137
|
+
/** Missing columns become `null` instead of their default in bulk inserts. */
|
|
138
|
+
readonly defaultToNull: boolean;
|
|
139
|
+
}
|
|
140
|
+
interface UpdateOp {
|
|
141
|
+
readonly kind: "update";
|
|
142
|
+
readonly table: TableMeta;
|
|
143
|
+
/** Keyed by database column names. */
|
|
144
|
+
readonly set: Readonly<Record<string, unknown>>;
|
|
145
|
+
readonly where: Condition | undefined;
|
|
146
|
+
readonly returning: Selection | undefined;
|
|
147
|
+
}
|
|
148
|
+
interface DeleteOp {
|
|
149
|
+
readonly kind: "delete";
|
|
150
|
+
readonly table: TableMeta;
|
|
151
|
+
readonly where: Condition | undefined;
|
|
152
|
+
readonly returning: Selection | undefined;
|
|
153
|
+
}
|
|
154
|
+
type Operation = SelectOp | InsertOp | UpdateOp | DeleteOp;
|
|
155
|
+
type MutationOp = InsertOp | UpdateOp | DeleteOp;
|
|
156
|
+
declare const and: (...items: (Condition | undefined)[]) => Condition | undefined;
|
|
157
|
+
declare const or: (...items: Condition[]) => Condition;
|
|
158
|
+
declare const not: (item: Condition) => Condition;
|
|
159
|
+
declare const column: (name: string, op: ColumnOp, value: unknown) => Condition;
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/core/errors.d.ts
|
|
162
|
+
/**
|
|
163
|
+
* Extra fields carried by each error kind. Plugins can add kinds through the
|
|
164
|
+
* `errors` extension point; apps that want the new kinds in the union can add
|
|
165
|
+
* them to this interface.
|
|
166
|
+
*/
|
|
167
|
+
interface DbErrorKinds {
|
|
168
|
+
not_found: Record<never, never>;
|
|
169
|
+
unauthorized: Record<never, never>;
|
|
170
|
+
/**
|
|
171
|
+
* `required`: the assurance level the route needs, when a second factor is
|
|
172
|
+
* missing. `scopes`: the OAuth scopes the route needs, when a delegated
|
|
173
|
+
* token lacks one (`INSUFFICIENT_SCOPE`).
|
|
174
|
+
*/
|
|
175
|
+
forbidden: {
|
|
176
|
+
required?: "aal1" | "aal2";
|
|
177
|
+
scopes?: readonly string[];
|
|
178
|
+
};
|
|
179
|
+
conflict: {
|
|
180
|
+
constraint?: string;
|
|
181
|
+
columns?: readonly string[];
|
|
182
|
+
};
|
|
183
|
+
foreign_key: {
|
|
184
|
+
constraint?: string;
|
|
185
|
+
columns?: readonly string[];
|
|
186
|
+
};
|
|
187
|
+
check: {
|
|
188
|
+
constraint?: string;
|
|
189
|
+
};
|
|
190
|
+
not_null: {
|
|
191
|
+
column?: string;
|
|
192
|
+
};
|
|
193
|
+
exclusion: {
|
|
194
|
+
constraint?: string;
|
|
195
|
+
};
|
|
196
|
+
invalid_input: Record<never, never>;
|
|
197
|
+
/** A stored value the app type can't hold, e.g. `infinity` for a Temporal timestamp. */
|
|
198
|
+
invalid_value: {
|
|
199
|
+
column?: string;
|
|
200
|
+
};
|
|
201
|
+
raised: Record<never, never>;
|
|
202
|
+
timeout: Record<never, never>;
|
|
203
|
+
serialization: Record<never, never>;
|
|
204
|
+
network: Record<never, never>;
|
|
205
|
+
aborted: Record<never, never>;
|
|
206
|
+
invalid_request: Record<never, never>;
|
|
207
|
+
validation: {
|
|
208
|
+
issues: readonly ValidationIssue[];
|
|
209
|
+
};
|
|
210
|
+
multiple_rows: Record<never, never>;
|
|
211
|
+
stale: Record<never, never>;
|
|
212
|
+
/** `retryAfter`: seconds until the window resets (the `Retry-After` header). */
|
|
213
|
+
rate_limited: {
|
|
214
|
+
retryAfter?: number;
|
|
215
|
+
};
|
|
216
|
+
unexpected: Record<never, never>;
|
|
217
|
+
}
|
|
218
|
+
type DbErrorKind = keyof DbErrorKinds;
|
|
219
|
+
interface ValidationIssue {
|
|
220
|
+
readonly message: string;
|
|
221
|
+
readonly path?: readonly PropertyKey[];
|
|
222
|
+
}
|
|
223
|
+
interface DbErrorBase<K extends DbErrorKind> {
|
|
224
|
+
readonly kind: K;
|
|
225
|
+
readonly message: string;
|
|
226
|
+
/** SQLSTATE or PostgREST code (`23505`, `PGRST116`), when known. */
|
|
227
|
+
readonly code?: string;
|
|
228
|
+
/** Suggested HTTP status, used by the RFC 9457 mapping. */
|
|
229
|
+
readonly status: number;
|
|
230
|
+
readonly details?: string;
|
|
231
|
+
/** Postgres `HINT`. `raised` errors use it as an app-level error code. */
|
|
232
|
+
readonly hint?: string;
|
|
233
|
+
/** App-cased table key the operation ran against. */
|
|
234
|
+
readonly table?: string;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* A database error as plain, serializable data. Safe to send across server
|
|
238
|
+
* action and RPC boundaries.
|
|
239
|
+
*/
|
|
240
|
+
type DbError = { [K in DbErrorKind]: DbErrorBase<K> & DbErrorKinds[K]; }[DbErrorKind];
|
|
241
|
+
type DbErrorOf<K extends DbErrorKind> = Extract<DbError, {
|
|
242
|
+
kind: K;
|
|
243
|
+
}>;
|
|
244
|
+
declare function statusOf(kind: DbErrorKind): number;
|
|
245
|
+
type ExtraOf<K extends DbErrorKind> = Record<never, never> extends DbErrorKinds[K] ? [extra?: DbErrorKinds[K] & Partial<Omit<DbErrorBase<K>, "kind">>] : [extra: DbErrorKinds[K] & Partial<Omit<DbErrorBase<K>, "kind">>];
|
|
246
|
+
/** Creates a `DbError` with the default status for its kind. */
|
|
247
|
+
declare function dbError<K extends DbErrorKind>(kind: K, message: string, ...[extra]: ExtraOf<K>): DbErrorOf<K>;
|
|
248
|
+
declare function isDbError(value: unknown): value is DbError;
|
|
249
|
+
/**
|
|
250
|
+
* A unique violation, optionally for one constraint. Accepts a `DbError` or a
|
|
251
|
+
* `DbException`. Pass the generated `UniqueConstraint` type to check names:
|
|
252
|
+
* `isConflict<UniqueConstraint>(error, 'customers_organization_id_kvk_key')`.
|
|
253
|
+
*/
|
|
254
|
+
declare const isConflict: <C extends string = string>(error: unknown, constraint?: NoInfer<C>) => error is DbErrorOf<"conflict"> & {
|
|
255
|
+
readonly constraint: C;
|
|
256
|
+
};
|
|
257
|
+
/** A CHECK violation, optionally for one constraint (`CheckConstraint`). */
|
|
258
|
+
declare const isCheck: <C extends string = string>(error: unknown, constraint?: NoInfer<C>) => error is DbErrorOf<"check"> & {
|
|
259
|
+
readonly constraint: C;
|
|
260
|
+
};
|
|
261
|
+
/** A foreign key violation, optionally for one constraint (`ForeignKeyConstraint`). */
|
|
262
|
+
declare const isForeignKey: <C extends string = string>(error: unknown, constraint?: NoInfer<C>) => error is DbErrorOf<"foreign_key"> & {
|
|
263
|
+
readonly constraint: C;
|
|
264
|
+
};
|
|
265
|
+
/** Thrown by `.orThrow()`. Carries the plain `DbError` as `error`. */
|
|
266
|
+
declare class DbException extends Error {
|
|
267
|
+
override readonly name = "DbException";
|
|
268
|
+
readonly error: DbError;
|
|
269
|
+
constructor(error: DbError);
|
|
270
|
+
get kind(): DbErrorKind;
|
|
271
|
+
}
|
|
272
|
+
/** Raw error shape shared by PostgREST responses and `pg` errors. */
|
|
273
|
+
interface RawDbError {
|
|
274
|
+
readonly message?: string;
|
|
275
|
+
readonly code?: string;
|
|
276
|
+
readonly details?: string | null;
|
|
277
|
+
readonly hint?: string | null;
|
|
278
|
+
readonly constraint?: string;
|
|
279
|
+
readonly column?: string;
|
|
280
|
+
readonly table?: string;
|
|
281
|
+
readonly name?: string;
|
|
282
|
+
}
|
|
283
|
+
type ErrorMapper = (raw: RawDbError, fallback: DbError) => DbError | undefined;
|
|
284
|
+
/**
|
|
285
|
+
* Maps a PostgREST or Postgres error to a `DbError`. Custom mappers run
|
|
286
|
+
* first; the first one that returns an error wins.
|
|
287
|
+
*/
|
|
288
|
+
declare function mapDbError(raw: RawDbError, mappers?: readonly ErrorMapper[]): DbError;
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/core/result.d.ts
|
|
291
|
+
/** Turns a `DbError` into the error `.orThrow()` throws; set with `betterSupabase.mapError()`. */
|
|
292
|
+
type ThrowMapper = (error: DbError) => unknown;
|
|
293
|
+
type Ok<T> = {
|
|
294
|
+
readonly ok: true;
|
|
295
|
+
readonly data: T;
|
|
296
|
+
readonly error: null;
|
|
297
|
+
};
|
|
298
|
+
type Err<E = DbError> = {
|
|
299
|
+
readonly ok: false;
|
|
300
|
+
readonly data: null;
|
|
301
|
+
readonly error: E;
|
|
302
|
+
};
|
|
303
|
+
type Result<T, E = DbError> = Ok<T> | Err<E>;
|
|
304
|
+
declare function ok<T>(data: T): Ok<T>;
|
|
305
|
+
declare function err<E = DbError>(error: E): Err<E>;
|
|
306
|
+
/**
|
|
307
|
+
* A lazy-free `PromiseLike<Result<T>>` with helpers. `await` gives the
|
|
308
|
+
* `Result`; `.orThrow()` gives the data or throws a `DbException`.
|
|
309
|
+
*/
|
|
310
|
+
declare class AsyncResult<T> implements PromiseLike<Result<T>> {
|
|
311
|
+
#private;
|
|
312
|
+
constructor(promise: Promise<Result<T>>);
|
|
313
|
+
static from<T>(run: () => Promise<Result<T>>): AsyncResult<T>;
|
|
314
|
+
static ok<T>(data: T): AsyncResult<T>;
|
|
315
|
+
static err<T = never>(error: DbError): AsyncResult<T>;
|
|
316
|
+
then<R1 = Result<T>, R2 = never>(onfulfilled?: ((value: Result<T>) => R1 | PromiseLike<R1>) | null, onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null): Promise<R1 | R2>;
|
|
317
|
+
/**
|
|
318
|
+
* Resolves with the data, or rejects with a `DbException`. Pass `factory`
|
|
319
|
+
* to throw your own error instead, e.g. an HTTP error for your framework;
|
|
320
|
+
* without it, the mapper from `betterSupabase.mapError()` applies when one is set.
|
|
321
|
+
*/
|
|
322
|
+
orThrow(factory?: (error: DbError) => unknown): Promise<T>;
|
|
323
|
+
/** Resolves with the data, or `fallback` when the result is an error. */
|
|
324
|
+
unwrapOr<F>(fallback: F): Promise<T | F>;
|
|
325
|
+
map<U>(fn: (data: T) => U): AsyncResult<U>;
|
|
326
|
+
mapError(fn: (error: DbError) => DbError): AsyncResult<T>;
|
|
327
|
+
andThen<U>(fn: (data: T) => PromiseLike<Result<U>>): AsyncResult<U>;
|
|
328
|
+
}
|
|
329
|
+
/** What `toBetterResult` returns: the `status`/`value`/`error` fields every better-result value has. */
|
|
330
|
+
type BetterResultValue<T, E> = {
|
|
331
|
+
readonly status: "ok";
|
|
332
|
+
readonly value: T;
|
|
333
|
+
} | {
|
|
334
|
+
readonly status: "error";
|
|
335
|
+
readonly error: E;
|
|
336
|
+
};
|
|
337
|
+
/** The part of better-result's `Result` namespace `toBetterResult` calls. */
|
|
338
|
+
interface BetterResultApi<T, E> {
|
|
339
|
+
ok(value: NoInfer<T>): unknown;
|
|
340
|
+
err(error: NoInfer<E>): unknown;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Builds a better-result value with the `Result` namespace you pass, so
|
|
344
|
+
* better-result stays your dependency. Errors go through `mapError`, or, for a
|
|
345
|
+
* result from a `db` of `betterSupabase.mapError(fn)`, through `fn` (typed `unknown`).
|
|
346
|
+
* The value is a real `Ok`/`Err`: cast it (`as Result<T, E>`) for its
|
|
347
|
+
* methods in types; the cast itself is not checked against `T`.
|
|
348
|
+
*
|
|
349
|
+
* ```ts
|
|
350
|
+
* import { Result } from 'better-result';
|
|
351
|
+
* const customer = toBetterResult(await db.customers.findById(id), Result, toAppError);
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
declare function toBetterResult<T, E>(result: Result<T>, api: BetterResultApi<T, E>, mapError: (error: DbError) => E): BetterResultValue<T, E>;
|
|
355
|
+
declare function toBetterResult<T>(result: Result<T>, api: BetterResultApi<T, DbError>): BetterResultValue<T, DbError>;
|
|
356
|
+
declare function toBetterResult<T, E>(result: AsyncResult<T>, api: BetterResultApi<T, E>, mapError: (error: DbError) => E): Promise<BetterResultValue<T, E>>;
|
|
357
|
+
declare function toBetterResult<T>(result: AsyncResult<T>, api: BetterResultApi<T, unknown>): Promise<BetterResultValue<T, unknown>>;
|
|
358
|
+
/**
|
|
359
|
+
* Converts a better-result value back into a `Result`, by its `status`
|
|
360
|
+
* field, so it works across better-result versions. A `DbError`, or an
|
|
361
|
+
* error whose `cause` is one, is kept; others go through `mapError`
|
|
362
|
+
* (default `toDbError`).
|
|
363
|
+
*/
|
|
364
|
+
declare function fromBetterResult<T>(result: BetterResultValue<T, unknown>, mapError?: (error: unknown) => DbError): Result<T>;
|
|
365
|
+
declare function toDbError(cause: unknown): DbError;
|
|
366
|
+
//#endregion
|
|
367
|
+
//#region src/core/executor.d.ts
|
|
368
|
+
interface ExecuteContext {
|
|
369
|
+
readonly signal?: AbortSignal;
|
|
370
|
+
readonly errorMappers: readonly ErrorMapper[];
|
|
371
|
+
}
|
|
372
|
+
interface ExecuteResult {
|
|
373
|
+
/** Rows keyed by the aliases in the operation's selection. */
|
|
374
|
+
readonly rows: readonly Record<string, unknown>[];
|
|
375
|
+
readonly count: number | null;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Runs IR operations. PostgREST (`postgrestExecutor`) and SQL
|
|
379
|
+
* (`better-supabase/postgres`) are built in; any other backend can implement
|
|
380
|
+
* this interface and prove it with `testExecutor` from `better-supabase/testing`.
|
|
381
|
+
*/
|
|
382
|
+
interface Executor {
|
|
383
|
+
readonly name: string;
|
|
384
|
+
/** Honors `SelectOp.source`. `db.$search` fails on executors without it. */
|
|
385
|
+
readonly functionSources?: boolean;
|
|
386
|
+
execute(op: Operation, context: ExecuteContext): Promise<Result<ExecuteResult>>;
|
|
387
|
+
/** Calls a database function. Optional; `db.$rpc` fails without it. */
|
|
388
|
+
rpc?(name: string, args: Readonly<Record<string, unknown>>, context: RpcContext): Promise<Result<unknown>>;
|
|
389
|
+
/**
|
|
390
|
+
* Runs several reads together, for `db.$many`: one transaction on a SQL
|
|
391
|
+
* connection. Returns one result per operation, in order. Optional;
|
|
392
|
+
* without it `db.$many` runs the operations in parallel.
|
|
393
|
+
*/
|
|
394
|
+
batch?(ops: readonly Operation[], context: ExecuteContext): Promise<readonly Result<ExecuteResult>[]>;
|
|
395
|
+
}
|
|
396
|
+
interface RpcContext extends ExecuteContext {
|
|
397
|
+
readonly schema: string;
|
|
398
|
+
/** The function is `stable`: send it as a GET, so read replicas can serve it. */
|
|
399
|
+
readonly get?: boolean;
|
|
400
|
+
}
|
|
401
|
+
//#endregion
|
|
402
|
+
export { or as $, mapDbError as A, InsertOp as B, RawDbError as C, isConflict as D, isCheck as E, Condition as F, Quantifier as G, MutationOp as H, CountMode as I, Selection as J, SelectColumn as K, DeleteOp as L, AggregateFn as M, Aggregation as N, isDbError as O, ColumnOp as P, not as Q, FunctionSource as R, ErrorMapper as S, dbError as T, Operation as U, Measure as V, OrderTerm as W, and as X, UpdateOp as Y, column as Z, DbError as _, AsyncResult as a, DbErrorOf as b, Err as c, ThrowMapper as d, err as f, toDbError as g, toBetterResult as h, RpcContext as i, statusOf as j, isForeignKey as k, Ok as l, ok as m, ExecuteResult as n, BetterResultApi as o, fromBetterResult as p, SelectOp as q, Executor as r, BetterResultValue as s, ExecuteContext as t, Result as u, DbErrorKind as v, ValidationIssue as w, DbException as x, DbErrorKinds as y, Include as z };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { r as Executor } from "./executor-
|
|
2
|
-
import { y as RawDbError } from "./result-c2OYgCV2.js";
|
|
1
|
+
import { C as RawDbError, r as Executor } from "./executor-BunPOO-k.js";
|
|
3
2
|
//#region src/postgres/executor.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Anything that runs parameterized SQL: `ctx.postgres` from
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as mapDbError, n as dbError } from "./errors-
|
|
2
|
-
import { i as ok, n as err, o as toDbError } from "./result-
|
|
3
|
-
import { t as compileSql } from "./sql-
|
|
1
|
+
import { c as mapDbError, n as dbError } from "./errors-DtwXa6b8.js";
|
|
2
|
+
import { i as ok, n as err, o as toDbError } from "./result-BKiliPY7.js";
|
|
3
|
+
import { t as compileSql } from "./sql-Coh6n4cC.js";
|
|
4
4
|
//#region src/postgres/executor.ts
|
|
5
5
|
function isPgError(value) {
|
|
6
6
|
return typeof value === "object" && value !== null && typeof value.code === "string";
|