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,6 +1,150 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import {
|
|
2
|
+
import { a as BucketPolicyName, j as SchemaMeta, o as Casing, t as AccessBucketPolicy, x as PermdockBucketPolicy } from "./types-Dnf_wRDz.js";
|
|
3
3
|
import { GeneratorMetadata } from "@supabase/postgrest-typegen";
|
|
4
|
+
//#region src/config/kits.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* `kits` in `better-supabase.config.ts`: how each SQL kit module maps onto
|
|
7
|
+
* the app's database. A module's contract (the functions other modules and
|
|
8
|
+
* the TypeScript side call) stays the same in every mode; only the tables
|
|
9
|
+
* behind it change.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* `managed`: the kit owns its tables. `adopt`: the kit writes its functions
|
|
13
|
+
* and views over tables the app already has (`tables` and `columns`), never
|
|
14
|
+
* `create table`. `custom`: the app implements the contract functions itself;
|
|
15
|
+
* the kit writes nothing and doctor checks the signatures (BS307).
|
|
16
|
+
*/
|
|
17
|
+
type KitMode = "managed" | "adopt" | "custom";
|
|
18
|
+
/** Options every module takes. */
|
|
19
|
+
interface KitModuleConfig {
|
|
20
|
+
readonly mode?: KitMode;
|
|
21
|
+
/** Schema of the module's functions and managed tables. Defaults to `better_supabase`. */
|
|
22
|
+
readonly schema?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Logical table to `table` or `schema.table`, e.g.
|
|
25
|
+
* `{ memberships: 'public.organization_users' }`. An unqualified name is in
|
|
26
|
+
* `schema`. `null` marks an optional table the app doesn't have.
|
|
27
|
+
*/
|
|
28
|
+
readonly tables?: Readonly<Record<string, string | null>>;
|
|
29
|
+
/**
|
|
30
|
+
* Logical table to logical column to column name, e.g.
|
|
31
|
+
* `{ memberships: { tenant: 'organization_id', role: 'role_id' } }`.
|
|
32
|
+
* `null` marks an optional column the adopted table doesn't have.
|
|
33
|
+
*/
|
|
34
|
+
readonly columns?: Readonly<Record<string, Readonly<Record<string, string | null>>>>;
|
|
35
|
+
/** Type of tenant ids: `uuid` (default), `text`, `bigint` or `integer`. */
|
|
36
|
+
readonly idType?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Kit action to permission key, checked through the access contract, e.g.
|
|
39
|
+
* `{ invite: 'organization.members.invite' }`.
|
|
40
|
+
*/
|
|
41
|
+
readonly permissions?: Readonly<Record<string, string>>;
|
|
42
|
+
/** Module-specific options; each module's docs page lists them. */
|
|
43
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
44
|
+
/**
|
|
45
|
+
* The app's optional `before_*` and `after_*` functions the module calls
|
|
46
|
+
* when they exist, e.g. `after_organization_create(org, user)`. They are
|
|
47
|
+
* looked up in `schema` (default `public`); `functions` maps a hook name
|
|
48
|
+
* to another function, e.g. `{ after_organization_create: 'app.seed_org' }`.
|
|
49
|
+
*/
|
|
50
|
+
readonly hooks?: {
|
|
51
|
+
readonly schema?: string;
|
|
52
|
+
readonly functions?: Readonly<Record<string, string>>;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Whether the module writes its events to the outbox (`emit_event`) when
|
|
56
|
+
* the `outbox` module is installed. Defaults to true.
|
|
57
|
+
*/
|
|
58
|
+
readonly events?: boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Where the active tenant of a request comes from. Every source counts only
|
|
62
|
+
* while the caller is a member, so a stale claim or setting grants nothing.
|
|
63
|
+
*/
|
|
64
|
+
type ActiveTenantSource = "claim" | "resolver" | {
|
|
65
|
+
readonly profileColumn: string;
|
|
66
|
+
readonly key?: string;
|
|
67
|
+
};
|
|
68
|
+
/** URL tenancy: the tenant comes from the request (a slug), not a stored setting. */
|
|
69
|
+
declare const DEFAULT_ACTIVE_TENANT: ActiveTenantSource;
|
|
70
|
+
/**
|
|
71
|
+
* The access contract every kit checks permissions through:
|
|
72
|
+
* `can(scope, id, permission)`, `tenant_ids_with(permission)`,
|
|
73
|
+
* `is_platform(permission)` and `can_user(user, scope, id, permission)`.
|
|
74
|
+
*/
|
|
75
|
+
interface AccessKitConfig extends KitModuleConfig {
|
|
76
|
+
/**
|
|
77
|
+
* `roles`: a fixed role list from `roles` (the default). `catalog`: role,
|
|
78
|
+
* permission and override tables (`tables.roles`, `permissions`,
|
|
79
|
+
* `rolePermissions`, `overrides`, `platformAssignments`). `permdock`:
|
|
80
|
+
* PermDock's `permitted_<scope>_ids` and `permdock_has`. `custom`:
|
|
81
|
+
* expression templates in `functions`.
|
|
82
|
+
*/
|
|
83
|
+
readonly model?: "roles" | "catalog" | "permdock" | "custom";
|
|
84
|
+
/**
|
|
85
|
+
* `roles` model: role name to permission keys. `*` grants everything and
|
|
86
|
+
* `prefix.*` a prefix. Defaults to owner, admin, member and viewer.
|
|
87
|
+
*/
|
|
88
|
+
readonly roles?: Readonly<Record<string, readonly string[]>>;
|
|
89
|
+
/**
|
|
90
|
+
* `custom` model: SQL expressions with `{scope}`, `{id}`, `{permission}`
|
|
91
|
+
* and `{user}` placeholders, e.g.
|
|
92
|
+
* `{ can: 'public.authorize_scope({scope}::public.scope_type, {id}, {permission})' }`.
|
|
93
|
+
*/
|
|
94
|
+
readonly functions?: {
|
|
95
|
+
readonly can?: string;
|
|
96
|
+
readonly tenantIdsWith?: string;
|
|
97
|
+
readonly isPlatform?: string;
|
|
98
|
+
readonly canUser?: string;
|
|
99
|
+
/** `{tenant}` and `{role}`: whether the caller may assign the role. Defaults to true. */
|
|
100
|
+
readonly canAssign?: string;
|
|
101
|
+
/** `{user}`: the permission claim for the access token hook. */
|
|
102
|
+
readonly permissionClaims?: string;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* `roles` model: the JWT claim holding the caller's platform permission
|
|
106
|
+
* keys (an array). Defaults to `platform_permissions`.
|
|
107
|
+
*/
|
|
108
|
+
readonly platformClaim?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Columns that disable a tenant or a user when set, as
|
|
111
|
+
* `schema.table.column`, keyed by the table's `id` (tenant) or the column
|
|
112
|
+
* named in `userKey` (user). Disabled tenants and users get no permissions.
|
|
113
|
+
*/
|
|
114
|
+
readonly disabled?: {
|
|
115
|
+
readonly tenant?: string;
|
|
116
|
+
readonly user?: string;
|
|
117
|
+
readonly userKey?: string;
|
|
118
|
+
};
|
|
119
|
+
readonly activeTenant?: ActiveTenantSource;
|
|
120
|
+
/** `permdock` model: PermDock's `rls.schema` and the scope tenants are. */
|
|
121
|
+
readonly permdock?: {
|
|
122
|
+
readonly schema?: string;
|
|
123
|
+
readonly scope?: string;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** `kits` in the config, keyed by module name. */
|
|
127
|
+
interface KitsConfig {
|
|
128
|
+
readonly access?: AccessKitConfig;
|
|
129
|
+
/** `AccessKitConfig` is listed so an `access` literal passes the excess-property check. */
|
|
130
|
+
readonly [module: string]: KitModuleConfig | AccessKitConfig | undefined;
|
|
131
|
+
}
|
|
132
|
+
/** A module's config with defaults applied. */
|
|
133
|
+
interface ResolvedKitModule {
|
|
134
|
+
readonly mode: KitMode;
|
|
135
|
+
readonly schema: string;
|
|
136
|
+
readonly tables: Readonly<Record<string, string | null>>;
|
|
137
|
+
readonly columns: Readonly<Record<string, Readonly<Record<string, string | null>>>>;
|
|
138
|
+
readonly idType?: string;
|
|
139
|
+
readonly permissions: Readonly<Record<string, string>>;
|
|
140
|
+
readonly options: Readonly<Record<string, unknown>>;
|
|
141
|
+
readonly hooks: {
|
|
142
|
+
readonly schema: string;
|
|
143
|
+
readonly functions: Readonly<Record<string, string>>;
|
|
144
|
+
};
|
|
145
|
+
readonly events: boolean;
|
|
146
|
+
}
|
|
147
|
+
//#endregion
|
|
4
148
|
//#region src/config/snapshot.d.ts
|
|
5
149
|
/**
|
|
6
150
|
* What `better-supabase introspect` reads from Postgres. `generator` is the
|
|
@@ -330,6 +474,8 @@ interface ClaimsConfig {
|
|
|
330
474
|
interface ActorConfig {
|
|
331
475
|
readonly createdBy?: string;
|
|
332
476
|
readonly updatedBy?: string;
|
|
477
|
+
/** Defaults to `impersonated_by`, the column the SQL kit's `track_actor` fills. */
|
|
478
|
+
readonly impersonatedBy?: string;
|
|
333
479
|
}
|
|
334
480
|
interface PluginFlagsConfig {
|
|
335
481
|
readonly timestamps?: boolean | TimestampsConfig;
|
|
@@ -342,8 +488,11 @@ interface BucketConfig {
|
|
|
342
488
|
readonly public?: boolean;
|
|
343
489
|
/** Path template with `{placeholders}`, e.g. `{orgId}/{customerId}/logo.webp`. */
|
|
344
490
|
readonly path: string;
|
|
345
|
-
/**
|
|
346
|
-
|
|
491
|
+
/**
|
|
492
|
+
* Generated storage policy, a PermDock policy (`{ permdock, scope }`) or
|
|
493
|
+
* an access contract policy (`{ access }`).
|
|
494
|
+
*/
|
|
495
|
+
readonly policy?: BucketPolicyName | PermdockBucketPolicy | AccessBucketPolicy;
|
|
347
496
|
readonly fileSizeLimit?: string;
|
|
348
497
|
readonly allowedMimeTypes?: readonly string[];
|
|
349
498
|
}
|
|
@@ -443,12 +592,19 @@ interface RealtimeConfig {
|
|
|
443
592
|
* triggers with `better-supabase sql add realtime-tables`.
|
|
444
593
|
*/
|
|
445
594
|
readonly tables?: readonly string[];
|
|
595
|
+
/**
|
|
596
|
+
* Tables in `tables` without a tenant column. They broadcast on one topic
|
|
597
|
+
* every signed-in user receives. With the `tenant` plugin, a table that
|
|
598
|
+
* lacks the tenant column and is not listed here fails to install.
|
|
599
|
+
*/
|
|
600
|
+
readonly global?: readonly string[];
|
|
446
601
|
}
|
|
447
602
|
interface EntitlementsConfig {
|
|
448
603
|
/**
|
|
449
604
|
* `table.column` (or `schema.table.column`) holding each tenant's Stripe
|
|
450
|
-
* customer id, read by the `entitlements` SQL kit module.
|
|
451
|
-
* `organizations
|
|
605
|
+
* customer id, read by the `entitlements` SQL kit module. Required
|
|
606
|
+
* without the `organizations` module; with it, defaults to the
|
|
607
|
+
* `stripe_customer_id` column that module adds.
|
|
452
608
|
*/
|
|
453
609
|
readonly customer?: string;
|
|
454
610
|
/** The tenant id column of that table. Defaults to `id`. */
|
|
@@ -457,8 +613,9 @@ interface EntitlementsConfig {
|
|
|
457
613
|
* With a PermDock manifest, `has_entitlement` and `feature_claims` read
|
|
458
614
|
* PermDock's memberships (`member_<scope>_ids()` and
|
|
459
615
|
* `member_<scope>_ids_for(user)`) instead of `better_supabase.memberships`.
|
|
460
|
-
* `scope` is the PermDock scope tenants are
|
|
461
|
-
* `false` keeps the
|
|
616
|
+
* `scope` is the PermDock scope tenants are. It defaults to the manifest's
|
|
617
|
+
* root scope (the `rls.scopes` entry without `within`); `false` keeps the
|
|
618
|
+
* kit's memberships table.
|
|
462
619
|
*/
|
|
463
620
|
readonly permdock?: false | {
|
|
464
621
|
readonly scope?: string;
|
|
@@ -558,6 +715,12 @@ interface BetterSupabaseConfig {
|
|
|
558
715
|
*/
|
|
559
716
|
readonly vectorSearch?: Readonly<Record<string, VectorSearchConfig>>;
|
|
560
717
|
readonly sql?: SqlConfig;
|
|
718
|
+
/**
|
|
719
|
+
* How each SQL kit module maps onto the database: `managed` tables, or
|
|
720
|
+
* `adopt` and `custom` over the app's own, with table, column and
|
|
721
|
+
* permission names, keyed by module name.
|
|
722
|
+
*/
|
|
723
|
+
readonly kits?: KitsConfig;
|
|
561
724
|
readonly seed?: SeedConfig;
|
|
562
725
|
readonly openapi?: OpenApiConfig;
|
|
563
726
|
readonly doctor?: DoctorConfig;
|
|
@@ -589,11 +752,12 @@ interface ResolvedConfig {
|
|
|
589
752
|
readonly claims: Required<ClaimsConfig>;
|
|
590
753
|
readonly buckets: Readonly<Record<string, BucketConfig>>;
|
|
591
754
|
readonly entitlements: {
|
|
592
|
-
|
|
593
|
-
readonly
|
|
755
|
+
/** Unset without `entitlements.customer`. */
|
|
756
|
+
readonly table?: string;
|
|
757
|
+
readonly column?: string;
|
|
594
758
|
readonly key: string;
|
|
595
759
|
readonly permdock: false | {
|
|
596
|
-
readonly scope
|
|
760
|
+
readonly scope?: string;
|
|
597
761
|
};
|
|
598
762
|
};
|
|
599
763
|
readonly permdock: Required<PermdockPathsConfig>;
|
|
@@ -605,6 +769,7 @@ interface ResolvedConfig {
|
|
|
605
769
|
readonly topics: Readonly<Record<string, string>>;
|
|
606
770
|
readonly realtime: Required<RealtimeConfig>;
|
|
607
771
|
readonly sql: Required<SqlConfig>;
|
|
772
|
+
readonly kits: KitsConfig;
|
|
608
773
|
readonly seed: Required<SeedConfig>;
|
|
609
774
|
readonly openapi: Required<OpenApiConfig>;
|
|
610
775
|
readonly doctor: Required<Omit<DoctorConfig, "claimsLimit">> & Pick<DoctorConfig, "claimsLimit">;
|
|
@@ -615,4 +780,4 @@ declare function defineConfig(config: BetterSupabaseConfig): BetterSupabaseConfi
|
|
|
615
780
|
/** Applies defaults. Paths stay relative to `root`. */
|
|
616
781
|
declare function resolveConfig(config: BetterSupabaseConfig, root: string): ResolvedConfig;
|
|
617
782
|
//#endregion
|
|
618
|
-
export { GeneratorMetadata as $, VectorSearchConfig as A, CatalogFunction as B, SoftDeleteConfig as C, TenantConfig as D, TableConfig as E, CatalogCheck as F, CatalogTable as G, CatalogGrant as H, CatalogColumn as I, ExtrasFunction as J, CatalogTrigger as K, CatalogColumnGrant as L, resolveConfig as M, resolveJsonSchema as N, TimestampsConfig as O, Catalog as P, ForeignKeyAction as Q, CatalogEnum as R, SeedConfig as S, SqlConfig as T, CatalogIndex as U, CatalogFunctionArg as V, CatalogPolicy as W, ExtrasHookFunction as X, ExtrasHook as Y, ExtrasTable as Z, PluginFlagsConfig as _, ClaimsConfig as a, ResolvedConfig as b, EntitlementsConfig as c, Generator as d, Snapshot as et, GeneratorInput as f, PermdockPathsConfig as g, OpenApiConfig as h, CONFIG_SCHEMA_URL as i, defineConfig as j, VectorDistance as k, ExposeConfig as l, JsonTypeConfig as m, BetterSupabaseConfig as n, SnapshotExtras as nt, CodecsConfig as o, JsonSchemaSource as p, CatalogUnique as q, BucketConfig as r, DoctorConfig as s, ActorConfig as t, SnapshotBucket as tt, GeneratedFile as u, Privilege as v, SourceConfig as w, ResolvedExpose as x, RealtimeConfig as y, CatalogForeignKey as z };
|
|
783
|
+
export { GeneratorMetadata as $, VectorSearchConfig as A, CatalogFunction as B, SoftDeleteConfig as C, TenantConfig as D, TableConfig as E, CatalogCheck as F, CatalogTable as G, CatalogGrant as H, CatalogColumn as I, ExtrasFunction as J, CatalogTrigger as K, CatalogColumnGrant as L, resolveConfig as M, resolveJsonSchema as N, TimestampsConfig as O, Catalog as P, ForeignKeyAction as Q, CatalogEnum as R, SeedConfig as S, SqlConfig as T, CatalogIndex as U, CatalogFunctionArg as V, CatalogPolicy as W, ExtrasHookFunction as X, ExtrasHook as Y, ExtrasTable as Z, PluginFlagsConfig as _, ClaimsConfig as a, DEFAULT_ACTIVE_TENANT as at, ResolvedConfig as b, EntitlementsConfig as c, KitsConfig as ct, Generator as d, Snapshot as et, GeneratorInput as f, PermdockPathsConfig as g, OpenApiConfig as h, CONFIG_SCHEMA_URL as i, ActiveTenantSource as it, defineConfig as j, VectorDistance as k, ExposeConfig as l, ResolvedKitModule as lt, JsonTypeConfig as m, BetterSupabaseConfig as n, SnapshotExtras as nt, CodecsConfig as o, KitMode as ot, JsonSchemaSource as p, CatalogUnique as q, BucketConfig as r, AccessKitConfig as rt, DoctorConfig as s, KitModuleConfig as st, ActorConfig as t, SnapshotBucket as tt, GeneratedFile as u, Privilege as v, SourceConfig as w, ResolvedExpose as x, RealtimeConfig as y, CatalogForeignKey as z };
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { A as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { i as PostgrestPlan } from "./postgrest-Bc-0Xw62.js";
|
|
2
|
+
import { A as Schema, D as RelationTypes, F as TableMeta, L as UniqueKeyName, M as Simplify, O as Relations, P as TableKey, R as UniqueWhere, _ as Insert, j as SchemaMeta, k as Row, n as AnyFunctions, r as AnyModels, w as PrimaryKeyValue, z as Update } from "./types-Dnf_wRDz.js";
|
|
3
|
+
import { I as CountMode, S as ErrorMapper, U as Operation, _ as DbError, a as AsyncResult, d as ThrowMapper, r as Executor } from "./executor-BunPOO-k.js";
|
|
4
|
+
import { E as Logger, a as EventHub, i as EventHandler, o as EventName, s as MutationNotice, u as RpcNotice } from "./events-aIO7vsIk.js";
|
|
5
|
+
import { _ as WithExtension, a as ExtensionOf, g as RequestContext, n as AnyPlugin, r as ApplyExtension } from "./plugin-o144f322.js";
|
|
6
|
+
import { t as StandardSchemaV1 } from "./standard-J4YgMOLm.js";
|
|
7
|
+
import { i as PostgrestPlan } from "./postgrest-CruYKAvV.js";
|
|
9
8
|
//#region src/ir/args.d.ts
|
|
10
9
|
interface BaseOps<V> {
|
|
11
10
|
readonly eq?: V;
|
|
@@ -337,6 +336,11 @@ type DeleteExt<E, M extends AnyModels, T extends keyof M> = ApplyExtension<E, M,
|
|
|
337
336
|
interface WriteArgs<M extends AnyModels, T extends keyof M> extends ReadArgs<M, T> {
|
|
338
337
|
/** `false` skips `RETURNING` (needed when RLS hides the written row). */
|
|
339
338
|
readonly returning?: boolean;
|
|
339
|
+
/**
|
|
340
|
+
* Keep caller-supplied values for columns that `timestamps()`, `actor()`
|
|
341
|
+
* and `softDelete()` fill (imports, backfills). Without it they are refused.
|
|
342
|
+
*/
|
|
343
|
+
readonly override?: boolean;
|
|
340
344
|
}
|
|
341
345
|
interface UpdateArgs<M extends AnyModels, T extends keyof M> extends WriteArgs<M, T> {
|
|
342
346
|
/**
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { t as cloneValue } from "./clone-BfgmLU90.js";
|
|
2
|
+
import { n as dbError, t as DbException } from "./errors-DtwXa6b8.js";
|
|
3
|
+
import { a as invalidRequest, r as builderFor } from "./simplify-_0oUKqCd.js";
|
|
3
4
|
import { t as lookupOf } from "./lookup-BaP5bI27.js";
|
|
4
|
-
import { n as nowInstant } from "./temporal-BwshQk0W.js";
|
|
5
5
|
import { i as or, n as column, r as not, t as and } from "./types-6cYK9pbJ.js";
|
|
6
|
-
import {
|
|
6
|
+
import { n as nowInstant } from "./temporal-CVlIV2DZ.js";
|
|
7
|
+
import { n as decodeValue, r as encodeValue, t as decodeScalar } from "./wire-D2dT86vi.js";
|
|
8
|
+
import { i as ok, n as err, o as toDbError, s as withErrorMapper, t as AsyncResult } from "./result-BKiliPY7.js";
|
|
7
9
|
import { t as invalidationTargets } from "./tables-Cb-3_VWc.js";
|
|
8
10
|
import { t as consoleLogger } from "./logger-glM28NVN.js";
|
|
9
|
-
import {
|
|
10
|
-
import { a as postgrestExecutor, n as StatsRecorder, r as recordStats } from "./stats-
|
|
11
|
-
import { d as isQuerySpec, f as specTables, n as checkParams, o as isReadSet, r as containsPlaceholder, t as bindParams, u as createSpecs } from "./read-set-
|
|
11
|
+
import { i as orderPlugins, s as tenantOf } from "./plugin-DwARMuQp.js";
|
|
12
|
+
import { a as postgrestExecutor, n as StatsRecorder, r as recordStats } from "./stats-Bqob3WqT.js";
|
|
13
|
+
import { d as isQuerySpec, f as specTables, n as checkParams, o as isReadSet, r as containsPlaceholder, t as bindParams, u as createSpecs } from "./read-set-DQFt1N_Y.js";
|
|
12
14
|
import { a as toBase64Url, t as base64ToText } from "./base64-D2gsioCY.js";
|
|
13
|
-
import { t as validate } from "./standard-
|
|
15
|
+
import { t as validate } from "./standard-D7r6dMUu.js";
|
|
14
16
|
//#region src/core/batch.ts
|
|
15
17
|
/**
|
|
16
18
|
* Holds operations until each of `readers` has either submitted one or
|
|
@@ -61,8 +63,9 @@ function rowKey(table, row) {
|
|
|
61
63
|
}
|
|
62
64
|
function cacheTargetOf(meta, notice) {
|
|
63
65
|
const table = meta.tables[notice.table];
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
+
const rows = notice.rows.length > 0 ? notice.rows : notice.keys ?? [];
|
|
67
|
+
const ids = table ? [...new Set(rows.flatMap((row) => rowKey(table, row) ?? []))] : [];
|
|
68
|
+
const tenant = notice.tenant ?? notice.context.tenant;
|
|
66
69
|
return {
|
|
67
70
|
table: notice.table,
|
|
68
71
|
tables: notice.kind === "delete" ? invalidationTargets(meta, notice.table) : [notice.table],
|
|
@@ -108,6 +111,7 @@ function isDevelopment() {
|
|
|
108
111
|
var EventHub = class {
|
|
109
112
|
#handlers = /* @__PURE__ */ new Map();
|
|
110
113
|
#warned = /* @__PURE__ */ new Set();
|
|
114
|
+
#pending = /* @__PURE__ */ new Set();
|
|
111
115
|
logger;
|
|
112
116
|
constructor(logger = consoleLogger) {
|
|
113
117
|
this.logger = logger;
|
|
@@ -130,6 +134,24 @@ var EventHub = class {
|
|
|
130
134
|
has(name) {
|
|
131
135
|
return (this.#handlers.get(name)?.size ?? 0) > 0;
|
|
132
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Keeps async work a handler started (a sink send) until it settles, so
|
|
139
|
+
* adapters can hand it to `after()` or `waitUntil`. Its outcome is ignored:
|
|
140
|
+
* handlers report their own failures.
|
|
141
|
+
*/
|
|
142
|
+
track(work) {
|
|
143
|
+
const settled = Promise.resolve(work).then(() => void 0, () => void 0);
|
|
144
|
+
this.#pending.add(settled);
|
|
145
|
+
settled.then(() => this.#pending.delete(settled));
|
|
146
|
+
}
|
|
147
|
+
/** Whether tracked work is still running. */
|
|
148
|
+
get pending() {
|
|
149
|
+
return this.#pending.size > 0;
|
|
150
|
+
}
|
|
151
|
+
/** Resolves once the work tracked so far has settled. Never rejects. */
|
|
152
|
+
async settled() {
|
|
153
|
+
await Promise.all(this.#pending);
|
|
154
|
+
}
|
|
133
155
|
emit(name, event) {
|
|
134
156
|
const set = this.#handlers.get(name);
|
|
135
157
|
if (!set) return;
|
|
@@ -141,6 +163,99 @@ var EventHub = class {
|
|
|
141
163
|
}
|
|
142
164
|
};
|
|
143
165
|
//#endregion
|
|
166
|
+
//#region src/ir/codec.ts
|
|
167
|
+
/** Whether decoding `selection` changes anything, so plain reads skip the walk. */
|
|
168
|
+
function needsDecoding(selection) {
|
|
169
|
+
let needs = decodes.get(selection);
|
|
170
|
+
if (needs === void 0) {
|
|
171
|
+
needs = computeNeedsDecoding(selection);
|
|
172
|
+
decodes.set(selection, needs);
|
|
173
|
+
}
|
|
174
|
+
return needs;
|
|
175
|
+
}
|
|
176
|
+
const decodes = /* @__PURE__ */ new WeakMap();
|
|
177
|
+
function computeNeedsDecoding(selection) {
|
|
178
|
+
return selection.aggregate !== void 0 || selection.columns.some((column) => column.codec !== void 0) || selection.includes.some((include) => include.count !== void 0 || include.aggregate !== void 0 || needsDecoding(include.selection));
|
|
179
|
+
}
|
|
180
|
+
/** PostgREST returns `[{ count }]` for a `(count)` embed; SQL returns the number. */
|
|
181
|
+
function countOf(value) {
|
|
182
|
+
if (Array.isArray(value)) {
|
|
183
|
+
const first = value[0];
|
|
184
|
+
return Number(first?.count ?? 0);
|
|
185
|
+
}
|
|
186
|
+
return Number(value ?? 0);
|
|
187
|
+
}
|
|
188
|
+
function measureOf(measure, value) {
|
|
189
|
+
if (value === void 0 || value === null) return null;
|
|
190
|
+
return measure.codec ? decodeScalar(measure.codec, value) : value;
|
|
191
|
+
}
|
|
192
|
+
/** Adds `value` under `row[key][name]`, next to what is already there. */
|
|
193
|
+
function fold(row, folded, key, name, value) {
|
|
194
|
+
let target = folded.get(key);
|
|
195
|
+
if (!target) {
|
|
196
|
+
target = { ...row[key] };
|
|
197
|
+
folded.set(key, target);
|
|
198
|
+
row[key] = target;
|
|
199
|
+
}
|
|
200
|
+
target[name] = value;
|
|
201
|
+
}
|
|
202
|
+
const droppedKeys = /* @__PURE__ */ new WeakMap();
|
|
203
|
+
/** Wire keys that decoding folds into `_count`, `_sum` and the rest. */
|
|
204
|
+
function droppedOf(selection) {
|
|
205
|
+
let dropped = droppedKeys.get(selection);
|
|
206
|
+
if (!dropped) {
|
|
207
|
+
dropped = /* @__PURE__ */ new Set([...selection.aggregate?.measures.map((measure) => measure.key) ?? [], ...selection.includes.filter((include) => include.count !== void 0 || include.aggregate !== void 0).map((include) => include.alias)]);
|
|
208
|
+
droppedKeys.set(selection, dropped);
|
|
209
|
+
}
|
|
210
|
+
return dropped;
|
|
211
|
+
}
|
|
212
|
+
function decodeRow(selection, row) {
|
|
213
|
+
const dropped = droppedOf(selection);
|
|
214
|
+
const out = {};
|
|
215
|
+
for (const key in row) if (!dropped.has(key) && Object.hasOwn(row, key)) out[key] = row[key];
|
|
216
|
+
const folded = /* @__PURE__ */ new Map();
|
|
217
|
+
for (const column of selection.columns) {
|
|
218
|
+
if (!column.codec || !(column.alias in out)) continue;
|
|
219
|
+
try {
|
|
220
|
+
out[column.alias] = decodeValue(column.codec, out[column.alias]);
|
|
221
|
+
} catch (cause) {
|
|
222
|
+
if (!(cause instanceof DbException) || cause.error.kind !== "invalid_value") throw cause;
|
|
223
|
+
throw new DbException(dbError("invalid_value", `${column.alias}: ${cause.error.message}`, { column: column.alias }));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (selection.aggregate) {
|
|
227
|
+
if (selection.aggregate.count) out["_count"] = countOf(out["_count"]);
|
|
228
|
+
for (const measure of selection.aggregate.measures) {
|
|
229
|
+
const value = row[measure.key];
|
|
230
|
+
fold(out, folded, `_${measure.fn}`, measure.alias, measureOf(measure, value));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
for (const include of selection.includes) {
|
|
234
|
+
const value = row[include.alias];
|
|
235
|
+
if (include.count !== void 0) {
|
|
236
|
+
if (!(include.alias in row)) continue;
|
|
237
|
+
fold(out, folded, "_count", include.count, countOf(value));
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (include.aggregate !== void 0) {
|
|
241
|
+
if (!(include.alias in row)) continue;
|
|
242
|
+
const inner = Array.isArray(value) ? value[0] : value;
|
|
243
|
+
const measures = {};
|
|
244
|
+
for (const measure of include.selection.aggregate?.measures ?? []) measures[measure.alias] = measureOf(measure, inner?.[measure.key]);
|
|
245
|
+
fold(out, folded, `_${include.aggregate.fn}`, include.aggregate.name, measures);
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
if (Array.isArray(value)) out[include.alias] = value.map((item) => decodeRow(include.selection, item));
|
|
249
|
+
else if (value && typeof value === "object") out[include.alias] = decodeRow(include.selection, value);
|
|
250
|
+
}
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
253
|
+
/** Applies column codecs to returned rows, including embedded relations. */
|
|
254
|
+
function decodeRows(selection, rows, checked = false) {
|
|
255
|
+
if (!selection || !checked && !needsDecoding(selection)) return rows;
|
|
256
|
+
return rows.map((row) => decodeRow(selection, row));
|
|
257
|
+
}
|
|
258
|
+
//#endregion
|
|
144
259
|
//#region src/core/cursor.ts
|
|
145
260
|
/** Opaque, URL-safe keyset cursor. */
|
|
146
261
|
function encodeCursor(values) {
|
|
@@ -208,6 +323,42 @@ function signalOf(args) {
|
|
|
208
323
|
const signal = args?.["signal"];
|
|
209
324
|
return signal instanceof AbortSignal ? signal : void 0;
|
|
210
325
|
}
|
|
326
|
+
function cloneRows(rows) {
|
|
327
|
+
return rows.map((row) => cloneValue(row));
|
|
328
|
+
}
|
|
329
|
+
/** App-cased primary keys of `rows`, or of a `where` that pins the primary key. */
|
|
330
|
+
function keysOf(op, rows) {
|
|
331
|
+
const { primaryKey } = op.table;
|
|
332
|
+
if (primaryKey.length === 0) return void 0;
|
|
333
|
+
const fromRows = rows.flatMap((row) => primaryKey.every((name) => row[name] !== void 0 && row[name] !== null) ? [Object.fromEntries(primaryKey.map((name) => [name, row[name]]))] : []);
|
|
334
|
+
if (fromRows.length > 0) return fromRows;
|
|
335
|
+
if (op.kind === "insert") return void 0;
|
|
336
|
+
return keysFromWhere(op.table, op.where);
|
|
337
|
+
}
|
|
338
|
+
function keysFromWhere(table, where) {
|
|
339
|
+
if (!where) return void 0;
|
|
340
|
+
const { byDb } = lookupOf(table);
|
|
341
|
+
const pinned = /* @__PURE__ */ new Map();
|
|
342
|
+
const items = [];
|
|
343
|
+
const flatten = (condition) => {
|
|
344
|
+
if (condition.kind === "and") condition.items.forEach(flatten);
|
|
345
|
+
else items.push(condition);
|
|
346
|
+
};
|
|
347
|
+
flatten(where);
|
|
348
|
+
for (const item of items) {
|
|
349
|
+
if (item.kind !== "column") continue;
|
|
350
|
+
const app = byDb.get(item.column)?.[0];
|
|
351
|
+
if (app === void 0 || !table.primaryKey.includes(app)) continue;
|
|
352
|
+
if (item.op === "eq") pinned.set(app, [item.value]);
|
|
353
|
+
else if (item.op === "in" && Array.isArray(item.value)) pinned.set(app, item.value);
|
|
354
|
+
}
|
|
355
|
+
if (pinned.size !== table.primaryKey.length) return void 0;
|
|
356
|
+
const [first, ...rest] = table.primaryKey;
|
|
357
|
+
if (first === void 0) return void 0;
|
|
358
|
+
if (rest.length === 0) return (pinned.get(first) ?? []).map((value) => ({ [first]: value }));
|
|
359
|
+
if ([...pinned.values()].some((values) => values.length !== 1)) return void 0;
|
|
360
|
+
return [Object.fromEntries(table.primaryKey.map((name) => [name, pinned.get(name)?.[0]]))];
|
|
361
|
+
}
|
|
211
362
|
function mutationKind(op) {
|
|
212
363
|
if (op.kind === "insert") return op.onConflict ? "upsert" : "insert";
|
|
213
364
|
return op.kind;
|
|
@@ -286,18 +437,25 @@ var OperationRunner = class {
|
|
|
286
437
|
truncated
|
|
287
438
|
});
|
|
288
439
|
if (!result.ok) return this.fail(op.table, result.error);
|
|
289
|
-
if (current.kind !== "select") await this.afterMutation(current, result.data);
|
|
440
|
+
if (current.kind !== "select") await this.afterMutation(op, current, result.data);
|
|
290
441
|
return result;
|
|
291
442
|
}
|
|
292
|
-
async afterMutation(op, data) {
|
|
443
|
+
async afterMutation(requested, op, data) {
|
|
293
444
|
const { runtime } = this;
|
|
294
445
|
const plugins = this.#hooks.afterMutation;
|
|
295
446
|
const listening = runtime.events.has("mutation");
|
|
296
447
|
if (plugins.length === 0 && !listening) return;
|
|
448
|
+
const kind = mutationKind(op);
|
|
449
|
+
const rows = cloneRows(data.rows);
|
|
450
|
+
const keys = keysOf(op, rows);
|
|
451
|
+
const tenant = tenantOf(runtime.context);
|
|
297
452
|
const event = {
|
|
298
453
|
table: op.table,
|
|
299
|
-
kind
|
|
300
|
-
|
|
454
|
+
kind,
|
|
455
|
+
intent: requested.kind === "delete" && op.kind === "update" ? "softDelete" : kind,
|
|
456
|
+
rows,
|
|
457
|
+
...keys ? { keys } : {},
|
|
458
|
+
...tenant === void 0 ? {} : { tenant },
|
|
301
459
|
context: runtime.context
|
|
302
460
|
};
|
|
303
461
|
for (const plugin of plugins) try {
|
|
@@ -309,7 +467,10 @@ var OperationRunner = class {
|
|
|
309
467
|
if (listening) runtime.events.emit("mutation", {
|
|
310
468
|
table: op.table.key,
|
|
311
469
|
kind: event.kind,
|
|
470
|
+
...event.intent ? { intent: event.intent } : {},
|
|
312
471
|
rows: event.rows,
|
|
472
|
+
...event.keys ? { keys: event.keys } : {},
|
|
473
|
+
...event.tenant === void 0 ? {} : { tenant: event.tenant },
|
|
313
474
|
context: event.context
|
|
314
475
|
});
|
|
315
476
|
}
|
|
@@ -325,9 +486,20 @@ var OperationRunner = class {
|
|
|
325
486
|
return err(withTable);
|
|
326
487
|
}
|
|
327
488
|
};
|
|
489
|
+
const sensitiveByTable = /* @__PURE__ */ new WeakMap();
|
|
490
|
+
/** Database names of the table's `config.sensitive` columns. */
|
|
491
|
+
function sensitiveColumnsOf(table) {
|
|
492
|
+
let sensitive = sensitiveByTable.get(table);
|
|
493
|
+
if (!sensitive) {
|
|
494
|
+
sensitive = new Set(lookupOf(table).entries.filter(([, column]) => column.sensitive).map(([, column]) => column.db));
|
|
495
|
+
sensitiveByTable.set(table, sensitive);
|
|
496
|
+
}
|
|
497
|
+
return sensitive;
|
|
498
|
+
}
|
|
328
499
|
/** Creates the runtime repository object for one table. */
|
|
329
500
|
function createRepository(runner, table) {
|
|
330
501
|
const { builder } = runner.runtime;
|
|
502
|
+
const sensitiveDb = sensitiveColumnsOf(table);
|
|
331
503
|
const selection = (args) => builder.selection(table, args?.["select"], args?.["include"]);
|
|
332
504
|
const selectOp = (args, patch = {}) => ({
|
|
333
505
|
kind: "select",
|
|
@@ -342,7 +514,17 @@ function createRepository(runner, table) {
|
|
|
342
514
|
single: void 0,
|
|
343
515
|
...patch
|
|
344
516
|
});
|
|
345
|
-
|
|
517
|
+
/** Writes return every column but the sensitive ones unless they are asked for. */
|
|
518
|
+
const returning = (args) => {
|
|
519
|
+
if (args?.["returning"] === false) return void 0;
|
|
520
|
+
const all = selection(args);
|
|
521
|
+
if (args?.["select"] !== void 0 || args?.["sensitive"] === true) return all;
|
|
522
|
+
const columns = all.columns.filter((entry) => !sensitiveDb.has(entry.column));
|
|
523
|
+
return columns.length === all.columns.length ? all : {
|
|
524
|
+
...all,
|
|
525
|
+
columns
|
|
526
|
+
};
|
|
527
|
+
};
|
|
346
528
|
const run = (op, args) => runner.run(op, optionsOf(args), signalOf(args));
|
|
347
529
|
let primaryOrder;
|
|
348
530
|
/** `primaryKey` holds app names; order terms take database names. */
|
|
@@ -579,8 +761,11 @@ function createRepository(runner, table) {
|
|
|
579
761
|
const number = args["page"] === void 0 ? 1 : Number(args["page"]);
|
|
580
762
|
if (!Number.isInteger(number) || number < 1) return runner.fail(table, dbError("invalid_request", "\"page\" must be a positive integer"));
|
|
581
763
|
const count = args["count"];
|
|
764
|
+
const orderBy = builder.orderBy(table, args["orderBy"]);
|
|
582
765
|
const op = selectOp(args, {
|
|
766
|
+
orderBy: orderBy.length > 0 || table.primaryKey.length === 0 ? orderBy : defaultOrder(),
|
|
583
767
|
limit: size + 1,
|
|
768
|
+
lookAhead: true,
|
|
584
769
|
offset: (number - 1) * size,
|
|
585
770
|
count: count === "exact" || count === "planned" || count === "estimated" ? count : void 0
|
|
586
771
|
});
|
|
@@ -616,6 +801,7 @@ function createRepository(runner, table) {
|
|
|
616
801
|
where: and(builder.where(table, args["where"]), after),
|
|
617
802
|
orderBy,
|
|
618
803
|
limit: size + 1,
|
|
804
|
+
lookAhead: true,
|
|
619
805
|
offset: void 0
|
|
620
806
|
});
|
|
621
807
|
const result = await run(op, args);
|
|
@@ -1169,4 +1355,4 @@ function defineSupabase(schema, options) {
|
|
|
1169
1355
|
return new BetterSupabase(schema, [], options);
|
|
1170
1356
|
}
|
|
1171
1357
|
//#endregion
|
|
1172
|
-
export {
|
|
1358
|
+
export { decodeRows as a, memoryCache as c, encodeCursor as i, rowKey as l, defineSupabase as n, EventHub as o, decodeCursor as r, cacheTargetOf as s, BetterSupabase as t, rpcCacheTargets as u };
|
package/dist/edge/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as BetterSupabase } from "../define-
|
|
3
|
-
import { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-
|
|
4
|
-
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 { f as ServerContext, n as GuardOptions, p as ServerOptions, r as MiddlewareOptions, u as BetterServer } from "../respond-D2OQl62-.js";
|
|
4
|
+
import { a as ResourceRouteOptions } from "../resource-D8iqWMr-.js";
|
|
5
5
|
//#region src/edge/index.d.ts
|
|
6
6
|
export interface CorsOptions {
|
|
7
7
|
/** Allowed origins, or `*`. Defaults to `*`. */
|
|
@@ -16,8 +16,19 @@ export interface EdgeOptions extends ServerOptions {
|
|
|
16
16
|
readonly cors?: boolean | CorsOptions;
|
|
17
17
|
/** Include error details in problem responses. Defaults to `NODE_ENV === 'development'`. */
|
|
18
18
|
readonly exposeErrors?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Keeps the invocation alive for event sink sends a handler started, e.g.
|
|
21
|
+
* `EdgeRuntime.waitUntil` on Supabase. On Workers the `ctx` the runtime
|
|
22
|
+
* passes to `fetch` is used when this is unset.
|
|
23
|
+
*/
|
|
24
|
+
readonly waitUntil?: (promise: Promise<unknown>) => void;
|
|
25
|
+
}
|
|
26
|
+
/** The platform context Workers pass as the third `fetch` argument. */
|
|
27
|
+
export interface EdgeExecutionContext {
|
|
28
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
19
29
|
}
|
|
20
|
-
|
|
30
|
+
/** `Deno.serve` passes `(request, info)`, Workers `fetch` passes `(request, env, ctx)`. */
|
|
31
|
+
export type EdgeHandler = (request: Request, env?: unknown, executionContext?: EdgeExecutionContext) => Promise<Response>;
|
|
21
32
|
export type ResourceMap<M extends AnyModels> = { readonly [T in TableKey<M>]?: ResourceRouteOptions<M, T> | true; };
|
|
22
33
|
export interface ResourcesOptions extends MiddlewareOptions {
|
|
23
34
|
/** Path before the resources, e.g. `/api` (Supabase: `/<function-name>`). */
|