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
|
@@ -1,3 +1,163 @@
|
|
|
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
|
|
1
161
|
//#region src/core/errors.d.ts
|
|
2
162
|
/**
|
|
3
163
|
* Extra fields carried by each error kind. Plugins can add kinds through the
|
|
@@ -34,6 +194,10 @@ interface DbErrorKinds {
|
|
|
34
194
|
constraint?: string;
|
|
35
195
|
};
|
|
36
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
|
+
};
|
|
37
201
|
raised: Record<never, never>;
|
|
38
202
|
timeout: Record<never, never>;
|
|
39
203
|
serialization: Record<never, never>;
|
|
@@ -200,4 +364,39 @@ declare function toBetterResult<T>(result: AsyncResult<T>, api: BetterResultApi<
|
|
|
200
364
|
declare function fromBetterResult<T>(result: BetterResultValue<T, unknown>, mapError?: (error: unknown) => DbError): Result<T>;
|
|
201
365
|
declare function toDbError(cause: unknown): DbError;
|
|
202
366
|
//#endregion
|
|
203
|
-
|
|
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-CqEsbgYs.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";
|
package/dist/hono/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as BetterSupabase } from "../define-
|
|
3
|
-
import { r as AuthState } from "../resolve-
|
|
4
|
-
import { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-
|
|
5
|
-
import { a as ResourceRouteOptions } from "../resource-
|
|
1
|
+
import { P as TableKey, n as AnyFunctions, r as AnyModels } from "../types-Dnf_wRDz.js";
|
|
2
|
+
import { t as BetterSupabase } from "../define-Bp_BZa5h.js";
|
|
3
|
+
import { r as AuthState } from "../resolve-C15TJq77.js";
|
|
4
|
+
import { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-D2OQl62-.js";
|
|
5
|
+
import { a as ResourceRouteOptions } from "../resource-D8iqWMr-.js";
|
|
6
6
|
import { Context, ErrorHandler, Hono, MiddlewareHandler } from "hono";
|
|
7
7
|
//#region src/hono/index.d.ts
|
|
8
8
|
/** Hono `Env` with the request's better-supabase context in `c.var`. */
|
|
@@ -18,13 +18,24 @@ export interface HonoOptions extends ServerOptions {
|
|
|
18
18
|
readonly exposeErrors?: boolean;
|
|
19
19
|
}
|
|
20
20
|
export interface BetterHono<M extends AnyModels, F extends AnyFunctions, E, C = unknown, P = unknown> extends BetterServer<M, F, E, C, P> {
|
|
21
|
+
/**
|
|
22
|
+
* The app's Hono `Env`, for `new Hono<typeof bs.Env>()` and
|
|
23
|
+
* `Context<typeof bs.Env>`. Type only: `undefined` at runtime.
|
|
24
|
+
*/
|
|
25
|
+
readonly Env: HonoEnv<M, F, E, C, P>;
|
|
26
|
+
/** `new Hono<typeof bs.Env>()` with `onError(bs.onError)` installed. */
|
|
27
|
+
app(): Hono<HonoEnv<M, F, E, C, P>>;
|
|
21
28
|
/** Resolves the caller, enforces `allow` and sets `c.var.bs`, `c.var.db`, `c.var.auth`. */
|
|
22
29
|
middleware(options?: MiddlewareOptions): MiddlewareHandler<HonoEnv<M, F, E, C, P>>;
|
|
23
30
|
/** Wraps a handler: `Result`s become JSON or Problem Details, `undefined` becomes 204. */
|
|
24
31
|
handler(fn: (c: Context<HonoEnv<M, F, E, C, P>>, ctx: ServerContext<M, F, E, C, P>) => unknown, options?: {
|
|
25
32
|
readonly status?: number;
|
|
26
33
|
}): (c: Context<HonoEnv<M, F, E, C, P>>) => Promise<Response>;
|
|
27
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* `app.onError(bs.onError)`: `DbException`s (and errors caused by a `DbError`)
|
|
36
|
+
* become Problem Details, Hono's `HTTPException`s keep their own response,
|
|
37
|
+
* and anything else is a 500.
|
|
38
|
+
*/
|
|
28
39
|
readonly onError: ErrorHandler<HonoEnv<M, F, E, C, P>>;
|
|
29
40
|
/**
|
|
30
41
|
* REST routes for a table matching `createOpenApi`. Mount with
|
package/dist/hono/index.js
CHANGED
|
@@ -1,19 +1,48 @@
|
|
|
1
|
-
import { n as dbError, r as dbErrorOf } from "../errors-
|
|
2
|
-
import { a as problemResponse } from "../problem-
|
|
3
|
-
import {
|
|
4
|
-
import { t as defineResource } from "../resource-
|
|
1
|
+
import { n as dbError, r as dbErrorOf } from "../errors-DtwXa6b8.js";
|
|
2
|
+
import { a as problemResponse } from "../problem-BW1KhzSG.js";
|
|
3
|
+
import { d as guard, i as rememberVerifiedFor, n as createServer, p as respond, r as extendServer, u as defaultExpose } from "../server-Csx2sRjg.js";
|
|
4
|
+
import { t as defineResource } from "../resource-CRxxwkQq.js";
|
|
5
5
|
import { Hono } from "hono";
|
|
6
|
+
import { HTTPException } from "hono/http-exception";
|
|
6
7
|
//#region src/hono/index.ts
|
|
7
8
|
function contextOf(c) {
|
|
8
9
|
const ctx = c.get("bs");
|
|
9
10
|
if (!ctx) throw new TypeError("better-supabase: no context on this request; add app.use(bs.middleware()) first");
|
|
10
11
|
return ctx;
|
|
11
12
|
}
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === "object" && value !== null;
|
|
15
|
+
}
|
|
16
|
+
function isJwtClaims(value) {
|
|
17
|
+
return isRecord(value) && typeof value["sub"] === "string";
|
|
18
|
+
}
|
|
19
|
+
function isUserClaims(value) {
|
|
20
|
+
return isRecord(value) && typeof value["id"] === "string";
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The bearer token `withSupabase` from `@supabase/server/adapters/hono`
|
|
24
|
+
* verified for this request, with the claims it stored in
|
|
25
|
+
* `c.var.supabaseContext`.
|
|
26
|
+
*/
|
|
27
|
+
function verifiedBySupabase(c) {
|
|
28
|
+
const supabase = c.var["supabaseContext"];
|
|
29
|
+
if (!isRecord(supabase) || supabase["authMode"] !== "user") return void 0;
|
|
30
|
+
const { jwtClaims, userClaims } = supabase;
|
|
31
|
+
const header = c.req.header("authorization");
|
|
32
|
+
const token = header?.startsWith("Bearer ") ? header.slice(7) : "";
|
|
33
|
+
if (!token || !isJwtClaims(jwtClaims) || !isUserClaims(userClaims)) return void 0;
|
|
34
|
+
return {
|
|
35
|
+
token,
|
|
36
|
+
claims: jwtClaims,
|
|
37
|
+
user: userClaims
|
|
38
|
+
};
|
|
39
|
+
}
|
|
12
40
|
/** Hono integration: a server plus middleware, handlers and REST resources. */
|
|
13
41
|
function createHono(betterSupabase, options = {}) {
|
|
14
42
|
const server = createServer(betterSupabase, options);
|
|
15
43
|
const expose = options.exposeErrors ?? defaultExpose();
|
|
16
44
|
const onError = (cause, c) => {
|
|
45
|
+
if (cause instanceof HTTPException) return cause.getResponse();
|
|
17
46
|
const instance = new URL(c.req.url).pathname;
|
|
18
47
|
const thrown = dbErrorOf(cause);
|
|
19
48
|
if (thrown) return problemResponse(thrown, {
|
|
@@ -27,9 +56,15 @@ function createHono(betterSupabase, options = {}) {
|
|
|
27
56
|
});
|
|
28
57
|
};
|
|
29
58
|
return extendServer(server, {
|
|
59
|
+
Env: void 0,
|
|
30
60
|
onError,
|
|
61
|
+
app() {
|
|
62
|
+
return new Hono().onError(onError);
|
|
63
|
+
},
|
|
31
64
|
middleware(middlewareOptions = {}) {
|
|
32
65
|
return async (c, next) => {
|
|
66
|
+
const verified = verifiedBySupabase(c);
|
|
67
|
+
if (verified) rememberVerifiedFor(server, verified);
|
|
33
68
|
const ctx = await server.context(c.req.raw, { refresh: middlewareOptions.refresh ?? false });
|
|
34
69
|
const denied = guard(ctx.auth, middlewareOptions.allow, middlewareOptions.aal, middlewareOptions.scopes);
|
|
35
70
|
if (denied) return ctx.resolution.apply(problemResponse(denied, {
|
|
@@ -40,7 +75,7 @@ function createHono(betterSupabase, options = {}) {
|
|
|
40
75
|
c.set("db", ctx.db);
|
|
41
76
|
c.set("auth", ctx.auth);
|
|
42
77
|
await next();
|
|
43
|
-
c.res = ctx.
|
|
78
|
+
c.res = ctx.apply(c.res);
|
|
44
79
|
};
|
|
45
80
|
},
|
|
46
81
|
handler(fn, handlerOptions = {}) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/auth/impersonation.ts
|
|
2
|
+
/** The `act` claim for an impersonated session. */
|
|
3
|
+
function actClaim(options) {
|
|
4
|
+
return {
|
|
5
|
+
sub: options.actor,
|
|
6
|
+
reason: options.reason
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
/** The impersonator in `claims.act`, or `undefined` for a normal session. */
|
|
10
|
+
function impersonatorOf(claims) {
|
|
11
|
+
const act = claims["act"];
|
|
12
|
+
if (typeof act !== "object" || act === null) return void 0;
|
|
13
|
+
const { sub, reason, session_id, read_only } = act;
|
|
14
|
+
if (typeof sub !== "string" || sub === "") return void 0;
|
|
15
|
+
return {
|
|
16
|
+
id: sub,
|
|
17
|
+
...typeof reason === "string" ? { reason } : {},
|
|
18
|
+
...typeof session_id === "string" ? { sessionId: session_id } : {},
|
|
19
|
+
...typeof read_only === "boolean" ? { readOnly: read_only } : {}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The repository context of a signed-in user: the actor, with the
|
|
24
|
+
* impersonator from `act`, and the claims. Every adapter builds it here, so
|
|
25
|
+
* plugins see the same actor on the server, in middleware and in the browser.
|
|
26
|
+
*/
|
|
27
|
+
function userContext(user, claims) {
|
|
28
|
+
const impersonator = impersonatorOf(claims);
|
|
29
|
+
return {
|
|
30
|
+
actor: {
|
|
31
|
+
id: user.id,
|
|
32
|
+
kind: "user",
|
|
33
|
+
...user.role ? { role: user.role } : {},
|
|
34
|
+
...user.email ? { email: user.email } : {},
|
|
35
|
+
...impersonator ? { impersonator: impersonator.id } : {}
|
|
36
|
+
},
|
|
37
|
+
claims
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { impersonatorOf as n, userContext as r, actClaim as t };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Z as QuerySpec } from "./define-
|
|
3
|
-
import { i as ClientAuth, t as AuthSnapshot } from "./index-
|
|
1
|
+
import { _ as DbError } from "./executor-BunPOO-k.js";
|
|
2
|
+
import { Z as QuerySpec } from "./define-Bp_BZa5h.js";
|
|
3
|
+
import { i as ClientAuth, t as AuthSnapshot } from "./index-DmXSxbLi.js";
|
|
4
4
|
import { n as TemplateValues } from "./template-mbvlysOo.js";
|
|
5
|
-
import { t as AuthSession } from "./view-
|
|
6
|
-
import { a as LiveSource, g as Topic, h as SubscriptionStatus, p as SubscribeOptions, r as LiveCountSeed, u as EventSchemas, v as TopicHandlers, y as TopicMessage } from "./live-
|
|
5
|
+
import { t as AuthSession } from "./view-BEf0diC5.js";
|
|
6
|
+
import { a as LiveSource, g as Topic, h as SubscriptionStatus, p as SubscribeOptions, r as LiveCountSeed, u as EventSchemas, v as TopicHandlers, y as TopicMessage } from "./live-D9W2M5aO.js";
|
|
7
7
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
8
8
|
import { ReactNode } from "react";
|
|
9
9
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
@@ -115,4 +115,47 @@ interface LiveCount {
|
|
|
115
115
|
*/
|
|
116
116
|
declare function useLiveCount(source: QuerySpec<string, "count", number> | LiveCountSeed | null | undefined, options?: LiveCountHookOptions): LiveCount;
|
|
117
117
|
//#endregion
|
|
118
|
-
|
|
118
|
+
//#region src/react/notifications.d.ts
|
|
119
|
+
/** Loads one list of items, e.g. a server action that calls `notifications.list()`. */
|
|
120
|
+
type NotificationSource<T> = () => Promise<readonly T[]>;
|
|
121
|
+
interface UseNotificationsOptions<T> {
|
|
122
|
+
/**
|
|
123
|
+
* The private topic the `notifications` module broadcasts to, e.g.
|
|
124
|
+
* `notifications:${userId}` (`kits.notifications.options.topic`). `null`
|
|
125
|
+
* loads once without realtime.
|
|
126
|
+
*/
|
|
127
|
+
readonly topic: string | null;
|
|
128
|
+
/** The notifications, newest first. */
|
|
129
|
+
readonly load: NotificationSource<T>;
|
|
130
|
+
/** More items merged in, such as running jobs or pending approvals. */
|
|
131
|
+
readonly sources?: readonly NotificationSource<T>[];
|
|
132
|
+
/** Orders the merged list. Defaults to the order the sources return. */
|
|
133
|
+
readonly sort?: (a: T, b: T) => number;
|
|
134
|
+
/** The badge number. Defaults to the items without a `readAt`. */
|
|
135
|
+
readonly count?: (items: readonly T[]) => number;
|
|
136
|
+
/** Runs for each broadcast, e.g. to show a toast for `notification_created`. */
|
|
137
|
+
readonly onMessage?: (event: string, payload: unknown) => void;
|
|
138
|
+
}
|
|
139
|
+
interface NotificationsState<T> {
|
|
140
|
+
/** `undefined` until the first load. */
|
|
141
|
+
readonly items: readonly T[] | undefined;
|
|
142
|
+
readonly count: number;
|
|
143
|
+
readonly status: SubscriptionStatus;
|
|
144
|
+
readonly error: unknown;
|
|
145
|
+
/** Loads again, e.g. after marking items read. */
|
|
146
|
+
readonly refresh: () => Promise<void>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The signed-in user's notifications, kept current: loads them, then loads
|
|
150
|
+
* again after each broadcast on `topic` and after the channel rejoins.
|
|
151
|
+
*
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const { items, count } = useNotifications({
|
|
154
|
+
* topic: `org:${orgId}:notifications:${userId}`,
|
|
155
|
+
* load: () => listNotifications(orgId),
|
|
156
|
+
* });
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
declare function useNotifications<T>(options: UseNotificationsOptions<T>): NotificationsState<T>;
|
|
160
|
+
//#endregion
|
|
161
|
+
export { useBroadcast as _, BetterHooks as a, useSupabase as b, BroadcastOptions as c, LiveCount as d, LiveCountHookOptions as f, useAuth as g, createHooks as h, useNotifications as i, ClaimsOf as l, ProfileOf as m, NotificationsState as n, BetterSupabaseProvider as o, LiveQueryHookOptions as p, UseNotificationsOptions as r, BetterSupabaseProviderProps as s, NotificationSource as t, ClientLike as u, useLiveCount as v, useLiveQuery as y };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { p as OpenApiParameter } from "./index-
|
|
1
|
+
import { j as SchemaMeta } from "./types-Dnf_wRDz.js";
|
|
2
|
+
import { p as OpenApiParameter } from "./index-fag8VJZ2.js";
|
|
3
3
|
//#region src/openapi/index.d.ts
|
|
4
4
|
type Json = Record<string, unknown>;
|
|
5
5
|
type ResourceOperation = "list" | "get" | "create" | "update" | "delete";
|
|
@@ -10,6 +10,8 @@ interface BetterSupabaseEnv {
|
|
|
10
10
|
readonly secretKeys?: Readonly<Record<string, string>>;
|
|
11
11
|
/** `SUPABASE_JWKS_URL`, or `<url>/auth/v1/.well-known/jwks.json`. */
|
|
12
12
|
readonly jwksUrl: URL;
|
|
13
|
+
/** `SUPABASE_JWKS`: inline keys, used instead of fetching `jwksUrl`. */
|
|
14
|
+
readonly jwks?: InlineJwks;
|
|
13
15
|
/** Direct Postgres connection string (`SUPABASE_DB_URL` / `DATABASE_URL`). */
|
|
14
16
|
readonly dbUrl?: string;
|
|
15
17
|
/** Project ref for hosted projects (`<ref>.supabase.co`). */
|
|
@@ -17,6 +19,8 @@ interface BetterSupabaseEnv {
|
|
|
17
19
|
/** `SUPABASE_READ_URL`: a read replica or the `<ref>-all` load balancer, for reads. */
|
|
18
20
|
readonly readUrl?: string;
|
|
19
21
|
}
|
|
22
|
+
/** A JSON Web Key Set, as `@supabase/server` verifies with it. */
|
|
23
|
+
type InlineJwks = Exclude<SupabaseEnv["jwks"], URL | null>;
|
|
20
24
|
interface PublicEnv {
|
|
21
25
|
readonly url: string;
|
|
22
26
|
readonly publishableKey: string;
|
|
@@ -46,6 +50,7 @@ declare const ENV_VARIABLES: {
|
|
|
46
50
|
readonly secretKey: readonly string[];
|
|
47
51
|
readonly dbUrl: readonly string[];
|
|
48
52
|
readonly jwksUrl: readonly string[];
|
|
53
|
+
readonly jwks: readonly string[];
|
|
49
54
|
readonly readUrl: readonly string[];
|
|
50
55
|
};
|
|
51
56
|
declare class EnvValidationError extends Error {
|
|
@@ -68,4 +73,4 @@ declare function publicEnv(env: BetterSupabaseEnv): PublicEnv;
|
|
|
68
73
|
/** Converts to `@supabase/server`'s `SupabaseEnv` (the `env` option of `withSupabase`). */
|
|
69
74
|
declare function toServerEnv(env: BetterSupabaseEnv): SupabaseEnv;
|
|
70
75
|
//#endregion
|
|
71
|
-
export { EnvResult as a,
|
|
76
|
+
export { EnvResult as a, InlineJwks as c, loadEnv as d, parseEnv as f, EnvOptions as i, PublicEnv as l, toServerEnv as m, ENV_VARIABLES as n, EnvSource as o, publicEnv as p, EnvIssue as r, EnvValidationError as s, BetterSupabaseEnv as t, envSchema as u };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import {
|
|
3
|
-
import { a as EventHub, s as MutationNotice } from "./events-
|
|
4
|
-
import { l as
|
|
2
|
+
import { j as SchemaMeta } from "./types-Dnf_wRDz.js";
|
|
3
|
+
import { a as EventHub, g as KitEventPattern, p as KitEvent, s as MutationNotice } from "./events-aIO7vsIk.js";
|
|
4
|
+
import { l as MutationIntent } from "./plugin-o144f322.js";
|
|
5
5
|
//#region src/events/index.d.ts
|
|
6
6
|
/** A CloudEvents 1.0 event. Extension attributes are lowercase alphanumerics. */
|
|
7
7
|
interface CloudEvent<T = unknown> {
|
|
@@ -16,10 +16,11 @@ interface CloudEvent<T = unknown> {
|
|
|
16
16
|
readonly data?: T;
|
|
17
17
|
readonly [extension: string]: unknown;
|
|
18
18
|
}
|
|
19
|
-
declare const ROW_EVENT_TYPES: { readonly [K in
|
|
19
|
+
declare const ROW_EVENT_TYPES: { readonly [K in MutationIntent]: string; };
|
|
20
20
|
interface RowEventData {
|
|
21
21
|
readonly table: string;
|
|
22
22
|
readonly row: Readonly<Record<string, unknown>>;
|
|
23
|
+
readonly actorId?: string;
|
|
23
24
|
}
|
|
24
25
|
interface CloudEventOptions {
|
|
25
26
|
/** URI-reference of the producer, e.g. `https://crm.example.com` or `/crm`. */
|
|
@@ -35,8 +36,10 @@ interface EventSink {
|
|
|
35
36
|
}
|
|
36
37
|
/**
|
|
37
38
|
* One CloudEvent per mutated row: `dev.better-supabase.row.created` with the
|
|
38
|
-
* app-cased row
|
|
39
|
-
* `partitionkey
|
|
39
|
+
* app-cased row and the actor in `data`, the primary key as `subject` and the
|
|
40
|
+
* tenant as `partitionkey`. Writes that return no rows (soft
|
|
41
|
+
* deletes, `returning: false`) send one event per known primary key, with the
|
|
42
|
+
* key as `row`.
|
|
40
43
|
*/
|
|
41
44
|
declare function toCloudEvents(notice: MutationNotice, options: CloudEventOptions & {
|
|
42
45
|
readonly meta?: SchemaMeta;
|
|
@@ -49,12 +52,34 @@ interface ForwardOptions extends CloudEventOptions {
|
|
|
49
52
|
}
|
|
50
53
|
/**
|
|
51
54
|
* Sends a CloudEvent for every mutation to `sink`. Returns a function that
|
|
52
|
-
* stops forwarding.
|
|
55
|
+
* stops forwarding. Sends in flight are tracked on `betterSupabase.events`
|
|
56
|
+
* (`settled()`), which the Next adapter hands to `after()` and the edge
|
|
57
|
+
* entry to `waitUntil`. Use an outbox (SQL kit) when events must not be lost.
|
|
53
58
|
*/
|
|
54
59
|
declare function forwardMutations(betterSupabase: {
|
|
55
60
|
readonly events: EventHub;
|
|
56
61
|
readonly meta: SchemaMeta;
|
|
57
62
|
}, sink: EventSink, options: ForwardOptions): () => void;
|
|
63
|
+
/**
|
|
64
|
+
* A kit event as a CloudEvent: `dev.better-supabase.support.started` with
|
|
65
|
+
* the event data and the actor (`actorId`) as `data` and the tenant as
|
|
66
|
+
* `partitionkey`.
|
|
67
|
+
*/
|
|
68
|
+
declare function kitCloudEvent(event: KitEvent, options: CloudEventOptions): CloudEvent;
|
|
69
|
+
interface ForwardKitOptions extends CloudEventOptions {
|
|
70
|
+
/** Only forward events that match, e.g. `support.*`. Defaults to all. */
|
|
71
|
+
readonly types?: readonly KitEventPattern[];
|
|
72
|
+
/** Sink failures never fail the kit call. Defaults to the `Logger`. */
|
|
73
|
+
readonly onError?: (error: unknown, events: readonly CloudEvent[]) => void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Sends a CloudEvent for every kit event (`support.*`, `org.*`, ...) to
|
|
77
|
+
* `sink`. Returns a function that stops forwarding. Like
|
|
78
|
+
* `forwardMutations`, sends are tracked on `betterSupabase.events`.
|
|
79
|
+
*/
|
|
80
|
+
declare function forwardKitEvents(betterSupabase: {
|
|
81
|
+
readonly events: EventHub;
|
|
82
|
+
}, sink: EventSink, options: ForwardKitOptions): () => void;
|
|
58
83
|
type HttpMode = "structured" | "binary" | "batch";
|
|
59
84
|
/** The HTTP protocol binding: headers and body for one event (or a batch). */
|
|
60
85
|
declare function toHttp(events: CloudEvent | readonly CloudEvent[], mode?: HttpMode): {
|
|
@@ -72,4 +97,4 @@ interface HttpSinkOptions {
|
|
|
72
97
|
/** POSTs events to `url`. Non-2xx responses reject. */
|
|
73
98
|
declare function httpSink(url: string | URL, options?: HttpSinkOptions): EventSink;
|
|
74
99
|
//#endregion
|
|
75
|
-
export {
|
|
100
|
+
export { toHttp as _, ForwardOptions as a, ROW_EVENT_TYPES as c, forwardMutations as d, fromHttp as f, toCloudEvents as g, kitCloudEvent as h, ForwardKitOptions as i, RowEventData as l, isCloudEvent as m, CloudEventOptions as n, HttpMode as o, httpSink as p, EventSink as r, HttpSinkOptions as s, CloudEvent as t, forwardKitEvents as u };
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { C as FindExt, Ct as WhereInput, M as UpsertArgs, N as WriteArgs, S as DeleteExt, T as OffsetPageArgs, X as InferResult, Z as QuerySpec, _ as CursorPage, it as AggregateResult, j as UpdateArgs, k as Returned, l as CacheAdapter, lt as FindFirstArgs, rt as AggregateArgs, st as CountArgs, t as BetterSupabase, ut as FindManyArgs, v as CursorPageArgs, vt as Payload, w as OffsetPage, x as DeleteArgs, y as Db, yt as ReadArgs } from "./define-
|
|
4
|
-
import { DataTag, InfiniteData, QueryClient, SkipToken } from "@tanstack/query-core";
|
|
1
|
+
import { P as TableKey, R as UniqueWhere, _ as Insert, n as AnyFunctions, r as AnyModels, w as PrimaryKeyValue, z as Update } from "./types-Dnf_wRDz.js";
|
|
2
|
+
import { x as DbException } from "./executor-BunPOO-k.js";
|
|
3
|
+
import { C as FindExt, Ct as WhereInput, M as UpsertArgs, N as WriteArgs, S as DeleteExt, T as OffsetPageArgs, X as InferResult, Z as QuerySpec, _ as CursorPage, it as AggregateResult, j as UpdateArgs, k as Returned, l as CacheAdapter, lt as FindFirstArgs, rt as AggregateArgs, st as CountArgs, t as BetterSupabase, ut as FindManyArgs, v as CursorPageArgs, vt as Payload, w as OffsetPage, x as DeleteArgs, y as Db, yt as ReadArgs } from "./define-Bp_BZa5h.js";
|
|
4
|
+
import { DataTag, InfiniteData, QueryClient, QueryMeta, SkipToken } from "@tanstack/query-core";
|
|
5
5
|
//#region src/query/invalidate.d.ts
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Carried by every better-supabase query: the tables whose changes make it
|
|
8
|
+
* stale, on top of the app's `Register['queryMeta']`, so the options stay
|
|
9
|
+
* assignable to `useQuery` when the app narrows its query meta.
|
|
10
|
+
*/
|
|
11
|
+
type BetterQueryMeta = QueryMeta & {
|
|
8
12
|
readonly bsTables: readonly string[];
|
|
9
|
-
|
|
10
|
-
}
|
|
13
|
+
};
|
|
11
14
|
/**
|
|
12
15
|
* Invalidates every query that read one of `tables`: better-supabase queries
|
|
13
16
|
* by their `meta.bsTables`, and other `['bs', table, ...]` keys by prefix.
|
|
@@ -114,4 +117,27 @@ declare function queryCache(client: QueryClient): CacheAdapter;
|
|
|
114
117
|
/** Invalidates affected queries for every mutation and declared RPC `betterSupabase` performs in this runtime. */
|
|
115
118
|
declare function invalidateOnMutation<M extends AnyModels, D, F extends AnyFunctions, E>(betterSupabase: BetterSupabase<M, D, F, E>, client: QueryClient): () => void;
|
|
116
119
|
//#endregion
|
|
117
|
-
|
|
120
|
+
//#region src/query/user-change.d.ts
|
|
121
|
+
/** The part of `createClient().auth` that `clearOnUserChange` reads. */
|
|
122
|
+
interface UserChangeSource {
|
|
123
|
+
subscribe(listener: () => void): () => void;
|
|
124
|
+
current(): {
|
|
125
|
+
readonly status: string;
|
|
126
|
+
readonly user: {
|
|
127
|
+
readonly id: string;
|
|
128
|
+
} | null;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Removes every `['bs', ...]` query when the signed-in user changes or signs
|
|
133
|
+
* out, so the next user never sees the previous user's rows. Returns the
|
|
134
|
+
* function that stops listening. `BetterSupabaseProvider` calls it for React;
|
|
135
|
+
* call it yourself with Vue, Solid, Svelte or Angular Query.
|
|
136
|
+
*
|
|
137
|
+
* ```ts
|
|
138
|
+
* const stop = clearOnUserChange(queryClient, bs.auth);
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
declare function clearOnUserChange(queryClient: Pick<QueryClient, "removeQueries">, auth: UserChangeSource): () => void;
|
|
142
|
+
//#endregion
|
|
143
|
+
export { MutationOptionsOf as a, QueryKeyOf as c, createQueries as d, invalidateOnMutation as f, invalidateTables as h, InfiniteOptionsOf as i, QueryOptionsOf as l, BetterQueryMeta as m, clearOnUserChange as n, QueriesOptions as o, queryCache as p, BetterQueries as r, QueryHelpers as s, UserChangeSource as t, TableQueries as u };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { t as BetterSupabase, y as Db } from "./define-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { n as AnyFunctions, r as AnyModels } from "./types-Dnf_wRDz.js";
|
|
2
|
+
import { t as BetterSupabase, y as Db } from "./define-Bp_BZa5h.js";
|
|
3
|
+
import { l as PublicEnv } from "./index-CLg87OBW.js";
|
|
4
|
+
import { r as BetterQueries } from "./index-DgILJRXj.js";
|
|
5
5
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
6
6
|
//#region src/client/index.d.ts
|
|
7
7
|
interface ClientOptions {
|