better-supabase 0.4.0 → 0.5.1
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 +135 -16
- package/dist/actor-DaJjqD5R.d.ts +43 -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-C_A-KEAz.js} +533 -50
- package/dist/cli/{env-BZ0uy8XK.js → env-DmKv_G4A.js} +1 -1
- package/dist/cli/gen-CIdSQZad.js +2 -0
- package/dist/cli/{gen-Ccn_p90L.js → gen-CjElD1Vw.js} +321 -88
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/cli/{init-ClnxRYBF.js → init-DMa6M7hV.js} +2 -2
- package/dist/cli/{introspect-DxqfkVIv.js → introspect-BKlaIu_M.js} +2 -2
- package/dist/cli/{openapi-8WHjxiTJ.js → openapi-Cp5Fyta-.js} +1 -1
- package/dist/cli/read-sets-VQcPgxU9.js +436 -0
- package/dist/cli/{run-CP20LKk_.js → run-Bo_NLT5n.js} +16 -12
- package/dist/cli/{seed-5J6eu_Xg.js → seed-CUlqWh-8.js} +1 -1
- package/dist/cli/sql-CVx-1O8G.js +373 -0
- package/dist/cli/{version-5mW_8sY1.js → version-BCtlgDQx.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-C1CYcm6o.d.ts → config-Bv7gvfzC.d.ts} +185 -11
- package/dist/{config-CbvFmGD8.js → config-DreERlKo.js} +1 -1
- 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-BiJZ4t49.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-BgSHAYLf.js +133 -0
- package/dist/{resolve-BAqQcwMW.d.ts → impersonation-BmePsuxz.d.ts} +36 -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-Cf-D2jk1.d.ts → index-CWMDdEr4.d.ts} +2 -2
- 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-BBdvo-5d.d.ts → index-Dp2VDwog.d.ts} +49 -6
- 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-Cu96oJdw.d.ts} +2 -16
- 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-CFPX0Qft.d.ts} +1 -1
- package/dist/{resource-BJcaIfxi.d.ts → resource-DNRFP7KR.d.ts} +5 -5
- package/dist/{resource-My_y-Syh.js → resource-mqfJW4YF.js} +22 -7
- package/dist/respond-BR1fJWOB.d.ts +377 -0
- package/dist/{result-Bj6yt33D.js → result-BKiliPY7.js} +1 -1
- package/dist/server/index.d.ts +15 -12
- package/dist/server/index.js +11 -17
- package/dist/{server-BA75B0mT.js → server-B1mZ7CgQ.js} +259 -37
- 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 +283 -11
- package/dist/sql/index.js +8705 -775
- 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-CEPwlw2G.d.ts +89 -0
- package/dist/support-view-B8SlToQX.d.ts +17 -0
- package/dist/support-view-g4YLBeqX.js +18 -0
- package/dist/support-wHnK6zp-.js +293 -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 +132 -10
- package/dist/testing/index.js +476 -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-DOYTYwHP.js} +1 -1
- package/dist/{mfa-byfjruR9.js → view-Bn6HNKUe.js} +97 -98
- package/dist/{view-B64o81wp.d.ts → view-CbgObAeb.d.ts} +22 -31
- 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 +27 -19
- package/schemas/config-v1.json +131 -1
- package/schemas/doctor-report-v1.json +11 -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 +18 -7
- package/skills/better-supabase-auth/references/permdock.md +78 -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 {
|
|
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 { o as AuthState } from "../impersonation-BmePsuxz.js";
|
|
4
|
+
import { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-BR1fJWOB.js";
|
|
5
|
+
import { a as ResourceRouteOptions } from "../resource-DNRFP7KR.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-B1mZ7CgQ.js";
|
|
4
|
+
import { t as defineResource } from "../resource-mqfJW4YF.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,133 @@
|
|
|
1
|
+
//#region src/auth/actor.ts
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function copyAct(level) {
|
|
6
|
+
const entries = Object.entries(level).map(([key, value]) => [key, key === "act" && isRecord(value) ? copyAct(value) : value]);
|
|
7
|
+
return Object.fromEntries(entries);
|
|
8
|
+
}
|
|
9
|
+
const INVALID = {
|
|
10
|
+
ok: false,
|
|
11
|
+
reason: "invalid-chain"
|
|
12
|
+
};
|
|
13
|
+
function actorAt(outer, id) {
|
|
14
|
+
const kind = outer["kind"];
|
|
15
|
+
const sessionId = outer["session_id"];
|
|
16
|
+
const readOnly = outer["read_only"];
|
|
17
|
+
const reason = outer["reason"];
|
|
18
|
+
if (kind === "support" || kind === void 0 && sessionId !== void 0) {
|
|
19
|
+
if (typeof sessionId !== "string" || sessionId === "") return INVALID;
|
|
20
|
+
if (readOnly !== void 0 && typeof readOnly !== "boolean") return INVALID;
|
|
21
|
+
return {
|
|
22
|
+
ok: true,
|
|
23
|
+
actor: {
|
|
24
|
+
kind: "support",
|
|
25
|
+
id,
|
|
26
|
+
sessionId,
|
|
27
|
+
readOnly: readOnly ?? true,
|
|
28
|
+
...typeof reason === "string" ? { reason } : {}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (kind === "impersonation") return {
|
|
33
|
+
ok: true,
|
|
34
|
+
actor: {
|
|
35
|
+
kind: "impersonation",
|
|
36
|
+
id,
|
|
37
|
+
...typeof reason === "string" ? { reason } : {}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
if (kind !== void 0) return INVALID;
|
|
41
|
+
return {
|
|
42
|
+
ok: true,
|
|
43
|
+
actor: {
|
|
44
|
+
kind: "oauth-client",
|
|
45
|
+
id,
|
|
46
|
+
chain: copyAct(outer)
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reads only `act` and `client_id`, the way PermDock's `actorOf` does. An
|
|
52
|
+
* `act` that is not a chain of objects each with a non-empty `sub`, a
|
|
53
|
+
* `kind` other than `support` or `impersonation`, or a support level without
|
|
54
|
+
* a `session_id` is `{ ok: false }`: the session must not pass as the user
|
|
55
|
+
* alone.
|
|
56
|
+
*/
|
|
57
|
+
function actorOf(claims) {
|
|
58
|
+
const outer = claims["act"];
|
|
59
|
+
if (outer !== void 0) {
|
|
60
|
+
if (!isRecord(outer)) return INVALID;
|
|
61
|
+
const id = outer["sub"];
|
|
62
|
+
if (typeof id !== "string" || id === "") return INVALID;
|
|
63
|
+
let level = outer["act"];
|
|
64
|
+
while (level !== void 0) {
|
|
65
|
+
if (!isRecord(level)) return INVALID;
|
|
66
|
+
const sub = level["sub"];
|
|
67
|
+
if (typeof sub !== "string" || sub === "") return INVALID;
|
|
68
|
+
level = level["act"];
|
|
69
|
+
}
|
|
70
|
+
return actorAt(outer, id);
|
|
71
|
+
}
|
|
72
|
+
const client = claims["client_id"];
|
|
73
|
+
if (typeof client === "string" && client !== "") return {
|
|
74
|
+
ok: true,
|
|
75
|
+
actor: {
|
|
76
|
+
id: client,
|
|
77
|
+
kind: "oauth-client"
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
return { ok: true };
|
|
81
|
+
}
|
|
82
|
+
/** The OAuth `scope` claim (a space-separated string or a list); `undefined` when empty. */
|
|
83
|
+
function delegationOf(claims) {
|
|
84
|
+
const scope = claims["scope"];
|
|
85
|
+
const scopes = typeof scope === "string" ? scope.split(/\s+/u).filter(Boolean) : Array.isArray(scope) ? scope.filter((item) => typeof item === "string") : [];
|
|
86
|
+
return scopes.length > 0 ? { scopes } : void 0;
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/auth/impersonation.ts
|
|
90
|
+
/** The `act` claim for an impersonated session. */
|
|
91
|
+
function actClaim(options) {
|
|
92
|
+
return {
|
|
93
|
+
kind: "impersonation",
|
|
94
|
+
sub: options.actor,
|
|
95
|
+
reason: options.reason
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The admin in `claims.act`: a support session or an impersonated session
|
|
100
|
+
* (`actorOf` reads the same level, so the two always agree). `undefined`
|
|
101
|
+
* for a normal session, an OAuth client or agent chain, and an invalid `act`.
|
|
102
|
+
*/
|
|
103
|
+
function impersonatorOf(claims) {
|
|
104
|
+
const outcome = actorOf(claims);
|
|
105
|
+
const actor = outcome.ok ? outcome.actor : void 0;
|
|
106
|
+
if (actor === void 0) return void 0;
|
|
107
|
+
switch (actor.kind) {
|
|
108
|
+
case "oauth-client": return;
|
|
109
|
+
case "support":
|
|
110
|
+
case "impersonation": return { ...actor };
|
|
111
|
+
default: return actor;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The repository context of a signed-in user: the actor, with the
|
|
116
|
+
* impersonator from `act`, and the claims. Every adapter builds it here, so
|
|
117
|
+
* plugins see the same actor on the server, in middleware and in the browser.
|
|
118
|
+
*/
|
|
119
|
+
function userContext(user, claims) {
|
|
120
|
+
const impersonator = impersonatorOf(claims);
|
|
121
|
+
return {
|
|
122
|
+
actor: {
|
|
123
|
+
id: user.id,
|
|
124
|
+
kind: "user",
|
|
125
|
+
...user.role ? { role: user.role } : {},
|
|
126
|
+
...user.email ? { email: user.email } : {},
|
|
127
|
+
...impersonator ? { impersonator: impersonator.id } : {}
|
|
128
|
+
},
|
|
129
|
+
claims
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
export { delegationOf as a, actorOf as i, impersonatorOf as n, userContext as r, actClaim as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { t as StandardSchemaV1 } from "./standard-
|
|
5
|
-
import { t as BetterSupabaseEnv } from "./index-
|
|
1
|
+
import { _ as DbError } from "./executor-BunPOO-k.js";
|
|
2
|
+
import { E as Logger, l as RefreshEvent } from "./events-aIO7vsIk.js";
|
|
3
|
+
import { g as RequestContext } from "./plugin-o144f322.js";
|
|
4
|
+
import { t as StandardSchemaV1 } from "./standard-J4YgMOLm.js";
|
|
5
|
+
import { t as BetterSupabaseEnv } from "./index-CLg87OBW.js";
|
|
6
6
|
import { CookieOptions } from "@supabase/ssr";
|
|
7
7
|
import { JWTClaims, SupabaseEnv, UserClaims } from "@supabase/server";
|
|
8
8
|
//#region src/auth/session.d.ts
|
|
@@ -119,6 +119,12 @@ interface ResolveAuthOptions {
|
|
|
119
119
|
readonly name?: string;
|
|
120
120
|
readonly options?: CookieOptions;
|
|
121
121
|
};
|
|
122
|
+
/**
|
|
123
|
+
* Read the session cookie. Defaults to true. `false` suits endpoints only
|
|
124
|
+
* bearer clients call (MCP): a browser's cookie then can't authorize a
|
|
125
|
+
* request another site makes it send.
|
|
126
|
+
*/
|
|
127
|
+
readonly cookies?: boolean;
|
|
122
128
|
/** Inline JWKS instead of fetching `env.jwksUrl` (tests, air-gapped). */
|
|
123
129
|
readonly jwks?: SupabaseEnv["jwks"];
|
|
124
130
|
/**
|
|
@@ -173,4 +179,28 @@ declare function resolveAuth(request: Request, options: ResolveAuthOptions): Pro
|
|
|
173
179
|
/** The repository context (`actor`, `claims`) for an auth state. */
|
|
174
180
|
declare function authContext(auth: AuthState): RequestContext;
|
|
175
181
|
//#endregion
|
|
176
|
-
|
|
182
|
+
//#region src/auth/impersonation.d.ts
|
|
183
|
+
/** The admin acting as the user, from the RFC 8693 `act` claim. */
|
|
184
|
+
interface Impersonator {
|
|
185
|
+
/** `act.kind`: a support session or an impersonated session. */
|
|
186
|
+
readonly kind: "support" | "impersonation";
|
|
187
|
+
readonly id: string;
|
|
188
|
+
readonly reason?: string;
|
|
189
|
+
/** The support session, when the admin started one (`act.session_id`). */
|
|
190
|
+
readonly sessionId?: string;
|
|
191
|
+
/** Whether the support session blocks writes (`act.read_only`). */
|
|
192
|
+
readonly readOnly?: boolean;
|
|
193
|
+
}
|
|
194
|
+
/** `actingAs(userId, claims, { actor, reason })`: who acts, and why (recorded by the audit module). */
|
|
195
|
+
interface ImpersonationOptions {
|
|
196
|
+
readonly actor: string;
|
|
197
|
+
readonly reason: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* The admin in `claims.act`: a support session or an impersonated session
|
|
201
|
+
* (`actorOf` reads the same level, so the two always agree). `undefined`
|
|
202
|
+
* for a normal session, an OAuth client or agent chain, and an invalid `act`.
|
|
203
|
+
*/
|
|
204
|
+
declare function impersonatorOf(claims: Readonly<Record<string, unknown>>): Impersonator | undefined;
|
|
205
|
+
//#endregion
|
|
206
|
+
export { writeSession as C, sessionCookieName as S, StoredSession as _, AuthResolver as a, readSession as b, ResolveAuthOptions as c, clientIp as d, resolveAuth as f, CookieWrite as g, CookieRecord as h, AuthResolution as i, ResolvedState as l, CookieOptions as m, Impersonator as n, AuthState as o, AUTH_CACHE_HEADERS as p, impersonatorOf as r, InvalidReason as s, ImpersonationOptions as t, authContext as u, applyCookieWrites as v, serializeCookie as x, parseCookies 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,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { d as Generator } from "./config-
|
|
1
|
+
import { c as ClaimsMeta, j as SchemaMeta } from "./types-Dnf_wRDz.js";
|
|
2
|
+
import { d as Generator } from "./config-Bv7gvfzC.js";
|
|
3
3
|
//#region src/core/claims.d.ts
|
|
4
4
|
declare const DEFAULT_CLAIMS: ClaimsMeta;
|
|
5
5
|
/** Where the active tenant is read from: the top-level claim, then `app_metadata`. */
|