@rebasepro/server-postgres 0.12.1-canary.gf5f1d39 → 0.13.1-canary.g18cfeb7
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/dist/PostgresBackendDriver.d.ts +49 -2
- package/dist/PostgresBootstrapper.d.ts +25 -1
- package/dist/auth/services.d.ts +21 -0
- package/dist/{src-BbFOPJ1S.js → auth-users-columns-Do9mw5Y5.js} +602 -200
- package/dist/auth-users-columns-Do9mw5Y5.js.map +1 -0
- package/dist/backup/backup-service.d.ts +10 -1
- package/dist/backup/pg-tools.d.ts +47 -0
- package/dist/backup-service-Bww-Lg0s.js +8999 -0
- package/dist/backup-service-Bww-Lg0s.js.map +1 -0
- package/dist/cli-helpers.d.ts +40 -1
- package/dist/connection-BuZ97wsr.js +250 -0
- package/dist/connection-BuZ97wsr.js.map +1 -0
- package/dist/connection.d.ts +42 -0
- package/dist/ensure-collection-policies-DMUdRQdM.js +57 -0
- package/dist/ensure-collection-policies-DMUdRQdM.js.map +1 -0
- package/dist/ensure-collection-tables-DSIxvLLD.js +694 -0
- package/dist/ensure-collection-tables-DSIxvLLD.js.map +1 -0
- package/dist/index.es.js +1701 -10167
- package/dist/index.es.js.map +1 -1
- package/dist/policy-CPkCqVTz.js +105 -0
- package/dist/policy-CPkCqVTz.js.map +1 -0
- package/dist/rls-bootstrap-sql-Bpv3nUZo.js +244 -0
- package/dist/rls-bootstrap-sql-Bpv3nUZo.js.map +1 -0
- package/dist/schema/auth-schema.d.ts +83 -144
- package/dist/schema/auth-users-columns.d.ts +97 -0
- package/dist/schema/ensure-collection-policies.d.ts +60 -0
- package/dist/schema/ensure-collection-tables.d.ts +45 -3
- package/dist/schema/generate-drizzle-schema-logic.d.ts +1 -1
- package/dist/schema/generate-postgres-ddl-logic.d.ts +137 -3
- package/dist/schema/generated-schema-staleness.d.ts +39 -0
- package/dist/schema/introspect-db-constraints.d.ts +57 -0
- package/dist/schema/introspect-db-logic.d.ts +94 -5
- package/dist/schema/introspect-db-queries.d.ts +119 -0
- package/dist/schema/introspect-db-structure.d.ts +263 -0
- package/dist/schema/introspect-db-types.d.ts +11 -0
- package/dist/schema/rls-bootstrap-sql.d.ts +135 -0
- package/dist/security/rls-enforcement.d.ts +53 -2
- package/dist/services/FetchService.d.ts +14 -8
- package/dist/services/RelationService.d.ts +24 -1
- package/dist/services/channel-bus/index.d.ts +1 -7
- package/dist/services/collection-helpers.d.ts +36 -2
- package/dist/services/dataService.d.ts +5 -1
- package/dist/services/realtimeService.d.ts +25 -21
- package/dist/services/row-pipeline.d.ts +1 -1
- package/dist/{src-Zqwaw3P5.js → src-C_wvdMnl.js} +78 -145
- package/dist/src-C_wvdMnl.js.map +1 -0
- package/dist/utils/connection-string.d.ts +29 -0
- package/dist/utils/drizzle-conditions.d.ts +5 -4
- package/dist/utils/pg-error-utils.d.ts +35 -0
- package/dist/websocket-D0TBU3ia.js +530 -0
- package/dist/websocket-D0TBU3ia.js.map +1 -0
- package/package.json +17 -16
- package/src/PostgresAdapter.ts +21 -2
- package/src/PostgresBackendDriver.ts +169 -3
- package/src/PostgresBootstrapper.ts +233 -35
- package/src/auth/ensure-tables.ts +335 -81
- package/src/auth/services.ts +24 -2
- package/src/backup/backup-cli.ts +41 -2
- package/src/backup/backup-service.ts +38 -5
- package/src/backup/pg-tools.ts +96 -3
- package/src/cli-helpers.ts +92 -9
- package/src/cli.ts +219 -56
- package/src/collections/validate-relations.ts +136 -14
- package/src/connection.ts +73 -0
- package/src/data-transformer.ts +22 -6
- package/src/databasePoolManager.ts +5 -2
- package/src/history/ensure-history-table.ts +7 -0
- package/src/schema/auth-schema.ts +30 -19
- package/src/schema/auth-users-columns.ts +131 -0
- package/src/schema/doctor.ts +7 -5
- package/src/schema/ensure-collection-policies.ts +105 -0
- package/src/schema/ensure-collection-tables.test.ts +105 -9
- package/src/schema/ensure-collection-tables.ts +301 -44
- package/src/schema/generate-drizzle-schema-logic.ts +49 -7
- package/src/schema/generate-postgres-ddl-logic.ts +474 -27
- package/src/schema/generated-schema-staleness.ts +169 -0
- package/src/schema/introspect-db-constraints.ts +385 -0
- package/src/schema/introspect-db-inference.ts +18 -8
- package/src/schema/introspect-db-logic.ts +385 -71
- package/src/schema/introspect-db-queries.ts +326 -0
- package/src/schema/introspect-db-structure.ts +670 -0
- package/src/schema/introspect-db-types.ts +56 -0
- package/src/schema/introspect-db.ts +37 -80
- package/src/schema/introspect-runtime.test.ts +56 -8
- package/src/schema/introspect-runtime.ts +31 -9
- package/src/schema/non-sql-collections.test.ts +131 -0
- package/src/schema/rls-bootstrap-sql.ts +288 -0
- package/src/security/anonymous-grants.test.ts +4 -2
- package/src/security/policy-drift.test.ts +11 -3
- package/src/security/rls-enforcement.ts +141 -3
- package/src/services/BranchService.ts +71 -28
- package/src/services/FetchService.ts +100 -107
- package/src/services/PersistService.ts +34 -7
- package/src/services/RelationService.ts +249 -48
- package/src/services/channel-bus/index.ts +0 -9
- package/src/services/channel-history.ts +8 -0
- package/src/services/channel-presence.ts +6 -0
- package/src/services/collection-helpers.ts +69 -3
- package/src/services/dataService.ts +5 -1
- package/src/services/realtimeService.ts +38 -35
- package/src/services/row-pipeline.ts +1 -1
- package/src/utils/connection-string.ts +58 -0
- package/src/utils/drizzle-conditions.ts +31 -6
- package/src/utils/pg-error-utils.ts +65 -0
- package/src/websocket.ts +18 -9
- package/dist/chunk-DSJWtz9O.js +0 -40
- package/dist/ensure-collection-tables-CNTcZGvn.js +0 -304
- package/dist/ensure-collection-tables-CNTcZGvn.js.map +0 -1
- package/dist/schema/auth-bootstrap-sql.d.ts +0 -24
- package/dist/src-BbFOPJ1S.js.map +0 -1
- package/dist/src-Zqwaw3P5.js.map +0 -1
- package/src/schema/auth-bootstrap-sql.ts +0 -47
|
@@ -141,7 +141,7 @@ export declare class FetchService {
|
|
|
141
141
|
/**
|
|
142
142
|
* Fallback path used when db.query is unavailable.
|
|
143
143
|
*
|
|
144
|
-
* The primary path runs the results through `
|
|
144
|
+
* The primary path runs the results through `toFlatRow`, which maps
|
|
145
145
|
* relations from what drizzle already nested — no query per row. This one
|
|
146
146
|
* has no nesting to read, so it resolves relations itself, in batches.
|
|
147
147
|
*
|
|
@@ -153,6 +153,16 @@ export declare class FetchService {
|
|
|
153
153
|
*/
|
|
154
154
|
fetchCollection<M extends Record<string, unknown>>(collectionPath: string, options?: {
|
|
155
155
|
filter?: FilterValues<Extract<keyof M, string>>;
|
|
156
|
+
/**
|
|
157
|
+
* An `or(...)`/`and(...)` group, applied alongside `filter`.
|
|
158
|
+
*
|
|
159
|
+
* `fetchRowsWithConditions` below has always applied this; it was
|
|
160
|
+
* simply absent from this signature, so the only callers that could
|
|
161
|
+
* pass one were the ones that went around this method. Realtime
|
|
162
|
+
* came through here, which is why a subscription filtered by a
|
|
163
|
+
* logical group was pushed every row in the table.
|
|
164
|
+
*/
|
|
165
|
+
logical?: LogicalCondition;
|
|
156
166
|
orderBy?: string;
|
|
157
167
|
order?: "desc" | "asc";
|
|
158
168
|
limit?: number;
|
|
@@ -177,6 +187,7 @@ export declare class FetchService {
|
|
|
177
187
|
*/
|
|
178
188
|
count<M extends Record<string, unknown>>(collectionPath: string, options?: {
|
|
179
189
|
filter?: FilterValues<Extract<keyof M, string>>;
|
|
190
|
+
logical?: LogicalCondition;
|
|
180
191
|
searchString?: string;
|
|
181
192
|
databaseId?: string;
|
|
182
193
|
}): Promise<number>;
|
|
@@ -198,6 +209,8 @@ export declare class FetchService {
|
|
|
198
209
|
*/
|
|
199
210
|
fetchCollectionForRest<M extends Record<string, unknown>>(collectionPath: string, options?: {
|
|
200
211
|
filter?: FilterValues<Extract<keyof M, string>>;
|
|
212
|
+
/** An `or(...)`/`and(...)` group, applied alongside `filter`. */
|
|
213
|
+
logical?: LogicalCondition;
|
|
201
214
|
orderBy?: string;
|
|
202
215
|
order?: "desc" | "asc";
|
|
203
216
|
limit?: number;
|
|
@@ -223,13 +236,6 @@ export declare class FetchService {
|
|
|
223
236
|
* Note: Primary path now uses inline `getQueryBuilder()` checks.
|
|
224
237
|
*/
|
|
225
238
|
private hasDrizzleQueryAPI;
|
|
226
|
-
/**
|
|
227
|
-
* Attempt to use Drizzle's relational query API (db.query.<table>.findMany)
|
|
228
|
-
* for efficient JOIN-based relation loading.
|
|
229
|
-
* Returns null if the API is not available or the query fails.
|
|
230
|
-
* Note: Primary path now uses `buildWithConfig` + `buildDrizzleQueryOptions`.
|
|
231
|
-
*/
|
|
232
|
-
private fetchWithDrizzleQuery;
|
|
233
239
|
/**
|
|
234
240
|
* Fallback path used when db.query is unavailable.
|
|
235
241
|
* The primary path uses db.query.findMany with `with` config, which
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DrizzleClient } from "../interfaces";
|
|
2
|
-
import { CollectionConfig, FilterValues, ResolvedRelation, ResolvedManyToMany } from "@rebasepro/types";
|
|
2
|
+
import { CollectionConfig, FilterValues, ResolvedRelation, ResolvedManyToMany, ResolvedHasMany, ResolvedHasOne } from "@rebasepro/types";
|
|
3
3
|
import { type ResolvedVia } from "@rebasepro/types";
|
|
4
4
|
import { PostgresCollectionRegistry } from "../collections/PostgresCollectionRegistry";
|
|
5
5
|
import type { NestedPathHop } from "./nested-path";
|
|
@@ -56,6 +56,29 @@ export declare class RelationService {
|
|
|
56
56
|
* hand a tenant's rows to its neighbour — say so instead.
|
|
57
57
|
*/
|
|
58
58
|
private assertSingleKeyAddressable;
|
|
59
|
+
/**
|
|
60
|
+
* What the target's foreign key holds, for each of these parent rows.
|
|
61
|
+
*
|
|
62
|
+
* Ordinarily the parent's id, and then this is free. When the relation
|
|
63
|
+
* declares a `sourceKey` the two are different values, and the mapping
|
|
64
|
+
* between them lives in the source table — so it costs one SELECT, issued
|
|
65
|
+
* once for the whole batch rather than per parent.
|
|
66
|
+
*
|
|
67
|
+
* Both directions come back because both are needed and deriving one from
|
|
68
|
+
* the other by hand is how a batch loader ends up attributing a child to the
|
|
69
|
+
* wrong parent: reads translate id → key to build the WHERE, and then
|
|
70
|
+
* translate key → id to attribute each row that comes back.
|
|
71
|
+
*/
|
|
72
|
+
/**
|
|
73
|
+
* The value a related row's foreign key must hold to belong to this parent.
|
|
74
|
+
*
|
|
75
|
+
* `undefined` when the parent's source key is null — which is not an error
|
|
76
|
+
* here, only in the callers that were about to write it. Exposed for
|
|
77
|
+
* {@link PersistService}, which stamps this onto a child created under a
|
|
78
|
+
* nested path and would otherwise write the id and lose the row.
|
|
79
|
+
*/
|
|
80
|
+
parentKeyValue(parentCollection: CollectionConfig, relation: ResolvedHasOne | ResolvedHasMany, parentId: string | number, db?: DrizzleClient): Promise<string | number | undefined>;
|
|
81
|
+
private resolveSourceKeys;
|
|
59
82
|
/**
|
|
60
83
|
* Fetch rows related to a parent row through a specific relation
|
|
61
84
|
*/
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* `types/channel_bus.ts` for the contract such a package implements.
|
|
16
16
|
*/
|
|
17
17
|
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
18
|
-
import { type ChannelBus, type
|
|
18
|
+
import { type ChannelBus, type ChannelBusSetting } from "@rebasepro/types";
|
|
19
19
|
export * from "./ChannelBus";
|
|
20
20
|
export { PostgresChannelBus, CHANNEL_BUS_NOTIFY_CHANNEL, PG_NOTIFY_MAX_PAYLOAD_BYTES, DEFAULT_BATCH_WINDOW_MS, parseChannelBusFrame, parseChannelBusPayload } from "./PostgresChannelBus";
|
|
21
21
|
export interface ChannelBusDeps {
|
|
@@ -37,12 +37,6 @@ export interface ChannelBusDeps {
|
|
|
37
37
|
* mean silently discarding the object the application handed us.
|
|
38
38
|
*/
|
|
39
39
|
export declare function resolveChannelBusSetting(configured?: ChannelBusSetting): ChannelBusSetting;
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated Use {@link resolveChannelBusSetting}, which also accepts a
|
|
42
|
-
* supplied {@link ChannelBus} instance. Kept as a narrow alias so existing
|
|
43
|
-
* config-only callers keep their exact types.
|
|
44
|
-
*/
|
|
45
|
-
export declare function resolveChannelBusConfig(configured?: ChannelBusConfig): ChannelBusConfig;
|
|
46
40
|
/**
|
|
47
41
|
* Produce the bus a setting asks for.
|
|
48
42
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PgTable, AnyPgColumn } from "drizzle-orm/pg-core";
|
|
2
|
-
import { CollectionConfig } from "@rebasepro/types";
|
|
2
|
+
import { CollectionConfig, ResolvedHasMany, ResolvedHasOne } from "@rebasepro/types";
|
|
3
3
|
import { PostgresCollectionRegistry } from "../collections/PostgresCollectionRegistry";
|
|
4
|
-
export { buildCompositeId, parseIdValues, COMPOSITE_ID_SEPARATOR } from "@rebasepro/common";
|
|
4
|
+
export { buildCompositeId, parseIdValues, isAddressableId, COMPOSITE_ID_SEPARATOR } from "@rebasepro/common";
|
|
5
5
|
export type { PrimaryKeyInfo } from "@rebasepro/common";
|
|
6
6
|
import type { PrimaryKeyInfo } from "@rebasepro/common";
|
|
7
7
|
/**
|
|
@@ -22,6 +22,17 @@ export interface DrizzleColumnMeta {
|
|
|
22
22
|
}
|
|
23
23
|
/** Safely extract Drizzle column metadata from a column object. */
|
|
24
24
|
export declare function getColumnMeta(col: AnyPgColumn): DrizzleColumnMeta;
|
|
25
|
+
/**
|
|
26
|
+
* Whether an address could name a row in this table, judged by the columns.
|
|
27
|
+
*
|
|
28
|
+
* {@link getPrimaryKeys} lets a config's `isId: "uuid"` win over the schema, so
|
|
29
|
+
* its `isUUID` is a claim rather than a fact — right for deriving addresses,
|
|
30
|
+
* wrong for refusing a query. Here the Drizzle column type decides, because it
|
|
31
|
+
* is what Postgres will enforce: a `uuid` column meets `/c/products/new` with
|
|
32
|
+
* `22P02`, which aborts the surrounding transaction and turns every later
|
|
33
|
+
* statement into an unrelated-looking `25P02`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function idCanAddressTable(id: string | number, table: PgTable, idInfoArray: PrimaryKeyInfo[]): boolean;
|
|
25
36
|
export declare function getCollectionByPath(collectionPath: string, registry: PostgresCollectionRegistry): CollectionConfig;
|
|
26
37
|
export declare function getTableForCollection(collection: CollectionConfig, registry: PostgresCollectionRegistry): PgTable<any>;
|
|
27
38
|
/**
|
|
@@ -55,6 +66,29 @@ export declare function getPrimaryKeys(collection: CollectionConfig, registry: P
|
|
|
55
66
|
* wrong and which collection it is wrong about.
|
|
56
67
|
*/
|
|
57
68
|
export declare function requirePrimaryKeys(collection: CollectionConfig, registry: PostgresCollectionRegistry): PrimaryKeyInfo[];
|
|
69
|
+
/**
|
|
70
|
+
* The column on the *source* table that a `hasOne`/`hasMany` link points at.
|
|
71
|
+
*
|
|
72
|
+
* `sourceKey` is authored when the two sides join on a natural key — an
|
|
73
|
+
* external identity id, a SKU — and left off when they join on the row id,
|
|
74
|
+
* which is the overwhelming majority. That makes `undefined` the only optional
|
|
75
|
+
* field on a resolved relation, so it gets exactly one reader: this function.
|
|
76
|
+
* Every consumer that needs the column asks here, and none of them re-derives
|
|
77
|
+
* "or else the primary key" for itself. That is the whole point — the fallback
|
|
78
|
+
* chains this codebase removed from relation resolution were dangerous because
|
|
79
|
+
* they were *duplicated* and could disagree, not because they existed.
|
|
80
|
+
*/
|
|
81
|
+
export declare function sourceKeyField(relation: ResolvedHasOne | ResolvedHasMany, sourceCollection: CollectionConfig, registry: PostgresCollectionRegistry): string;
|
|
82
|
+
/**
|
|
83
|
+
* Whether this link joins on something other than the source's primary key.
|
|
84
|
+
*
|
|
85
|
+
* Callers that hold a parent *id* — which is most of them, since an id is what
|
|
86
|
+
* a URL carries — must translate it to the source key's value before it can be
|
|
87
|
+
* compared with the target's foreign key. Those that hold the parent *row*, or
|
|
88
|
+
* that build a correlated subquery over the source table, can read the column
|
|
89
|
+
* directly and skip the lookup.
|
|
90
|
+
*/
|
|
91
|
+
export declare function joinsOnNaturalKey(relation: ResolvedHasOne | ResolvedHasMany, sourceCollection: CollectionConfig, registry: PostgresCollectionRegistry): boolean;
|
|
58
92
|
/**
|
|
59
93
|
* Collections whose key the *browser* cannot resolve, and what it will do
|
|
60
94
|
* instead.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FilterValues } from "@rebasepro/types";
|
|
1
|
+
import { FilterValues, LogicalCondition } from "@rebasepro/types";
|
|
2
2
|
import type { VectorSearchParams } from "@rebasepro/types";
|
|
3
3
|
import { FetchService } from "./FetchService";
|
|
4
4
|
import { PersistService } from "./PersistService";
|
|
@@ -36,6 +36,8 @@ export declare class DataService implements DataRepository {
|
|
|
36
36
|
*/
|
|
37
37
|
fetchCollection<M extends Record<string, unknown>>(collectionPath: string, options?: {
|
|
38
38
|
filter?: FilterValues<Extract<keyof M, string>>;
|
|
39
|
+
/** An `or(...)`/`and(...)` group, applied alongside `filter`. */
|
|
40
|
+
logical?: LogicalCondition;
|
|
39
41
|
orderBy?: string;
|
|
40
42
|
order?: "desc" | "asc";
|
|
41
43
|
limit?: number;
|
|
@@ -60,6 +62,8 @@ export declare class DataService implements DataRepository {
|
|
|
60
62
|
*/
|
|
61
63
|
count<M extends Record<string, unknown>>(collectionPath: string, options?: {
|
|
62
64
|
filter?: FilterValues<Extract<keyof M, string>>;
|
|
65
|
+
/** An `or(...)`/`and(...)` group, applied alongside `filter`. */
|
|
66
|
+
logical?: LogicalCondition;
|
|
63
67
|
searchString?: string;
|
|
64
68
|
databaseId?: string;
|
|
65
69
|
}): Promise<number>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WebSocket } from "ws";
|
|
2
2
|
import { EventEmitter } from "events";
|
|
3
|
-
import { DataDriver, WebSocketMessage } from "@rebasepro/types";
|
|
3
|
+
import { DataDriver, WebSocketMessage, LogicalCondition } from "@rebasepro/types";
|
|
4
4
|
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
5
5
|
import { RealtimeProvider, CollectionSubscriptionConfig, SingleSubscriptionConfig } from "../interfaces";
|
|
6
6
|
import { PostgresCollectionRegistry } from "../collections/PostgresCollectionRegistry";
|
|
@@ -14,6 +14,27 @@ export interface SubscriptionAuthContext {
|
|
|
14
14
|
uid: string;
|
|
15
15
|
roles: string[];
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* The narrowing a collection subscription was created with, kept so that every
|
|
19
|
+
* refetch answers the same query the initial fetch did.
|
|
20
|
+
*
|
|
21
|
+
* Named once because it used to be written out inline in five places, and a
|
|
22
|
+
* field missing from one of them is accepted over the wire and then silently
|
|
23
|
+
* ignored: `offset` was declared on the incoming props and never stored, so a
|
|
24
|
+
* live list on page three served page one, and `logical` was never stored
|
|
25
|
+
* either, so an `or(...)` subscription was pushed every row in the table.
|
|
26
|
+
*/
|
|
27
|
+
type StoredCollectionRequest = {
|
|
28
|
+
filter?: Record<string, unknown>;
|
|
29
|
+
logical?: LogicalCondition;
|
|
30
|
+
orderBy?: string;
|
|
31
|
+
order?: "desc" | "asc";
|
|
32
|
+
limit?: number;
|
|
33
|
+
offset?: number;
|
|
34
|
+
startAfter?: Record<string, unknown>;
|
|
35
|
+
databaseId?: string;
|
|
36
|
+
searchString?: string;
|
|
37
|
+
};
|
|
17
38
|
/**
|
|
18
39
|
* PostgreSQL-specific realtime service.
|
|
19
40
|
* Handles WebSocket connections and subscriptions for real-time row updates.
|
|
@@ -128,16 +149,7 @@ export declare class RealtimeService extends EventEmitter implements RealtimePro
|
|
|
128
149
|
type: "collection" | "single";
|
|
129
150
|
path: string;
|
|
130
151
|
id?: string | number;
|
|
131
|
-
collectionRequest?:
|
|
132
|
-
filter?: Record<string, unknown>;
|
|
133
|
-
orderBy?: string;
|
|
134
|
-
order?: "desc" | "asc";
|
|
135
|
-
limit?: number;
|
|
136
|
-
offset?: number;
|
|
137
|
-
startAfter?: Record<string, unknown>;
|
|
138
|
-
databaseId?: string;
|
|
139
|
-
searchString?: string;
|
|
140
|
-
};
|
|
152
|
+
collectionRequest?: StoredCollectionRequest;
|
|
141
153
|
authContext?: SubscriptionAuthContext;
|
|
142
154
|
}>;
|
|
143
155
|
registerDataDriverSubscription(subscriptionId: string, subscription: {
|
|
@@ -145,16 +157,7 @@ export declare class RealtimeService extends EventEmitter implements RealtimePro
|
|
|
145
157
|
type: "collection" | "single";
|
|
146
158
|
path: string;
|
|
147
159
|
id?: string | number;
|
|
148
|
-
collectionRequest?:
|
|
149
|
-
filter?: Record<string, unknown>;
|
|
150
|
-
orderBy?: string;
|
|
151
|
-
order?: "desc" | "asc";
|
|
152
|
-
limit?: number;
|
|
153
|
-
offset?: number;
|
|
154
|
-
startAfter?: Record<string, unknown>;
|
|
155
|
-
databaseId?: string;
|
|
156
|
-
searchString?: string;
|
|
157
|
-
};
|
|
160
|
+
collectionRequest?: StoredCollectionRequest;
|
|
158
161
|
authContext?: SubscriptionAuthContext;
|
|
159
162
|
}): void;
|
|
160
163
|
addSubscriptionCallback(subscriptionId: string, callback: (data: Record<string, unknown>[] | Record<string, unknown> | null) => void): void;
|
|
@@ -497,3 +500,4 @@ export declare class RealtimeService extends EventEmitter implements RealtimePro
|
|
|
497
500
|
* This allows code to use PostgresRealtimeProvider alongside future MongoRealtimeProvider, etc.
|
|
498
501
|
*/
|
|
499
502
|
export declare const PostgresRealtimeProvider: typeof RealtimeService;
|
|
503
|
+
export {};
|
|
@@ -47,7 +47,7 @@ export declare function relationTargetAddress(targetRow: Record<string, unknown>
|
|
|
47
47
|
* expects real types. The row's own address is *not* among the columns — it is
|
|
48
48
|
* derived by the consumer from the collection's primary keys.
|
|
49
49
|
*/
|
|
50
|
-
export declare function
|
|
50
|
+
export declare function toFlatRow(row: Record<string, unknown>, collection: CollectionConfig, registry: PostgresCollectionRegistry): Record<string, unknown>;
|
|
51
51
|
/**
|
|
52
52
|
* The row REST serves: every column under its own name, with the value Postgres
|
|
53
53
|
* returned, and relations inlined as the target's columns.
|
|
@@ -1,48 +1,6 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "module";
|
|
2
2
|
import "process";
|
|
3
3
|
__createRequire(import.meta.url);
|
|
4
|
-
//#region ../types/src/types/entities.ts
|
|
5
|
-
/**
|
|
6
|
-
* Class used to create a reference to a entity in a different path
|
|
7
|
-
*/
|
|
8
|
-
var EntityRelation = class {
|
|
9
|
-
__type = "relation";
|
|
10
|
-
/**
|
|
11
|
-
* ID of the entity
|
|
12
|
-
*/
|
|
13
|
-
id;
|
|
14
|
-
/**
|
|
15
|
-
* A string representing the path of the referenced document (relative
|
|
16
|
-
* to the root of the database).
|
|
17
|
-
*/
|
|
18
|
-
path;
|
|
19
|
-
/**
|
|
20
|
-
* Pre-fetched data payload to eliminate N+1 queries.
|
|
21
|
-
* When present, clients can use this directly instead of fetching.
|
|
22
|
-
*/
|
|
23
|
-
data;
|
|
24
|
-
constructor(id, path, data) {
|
|
25
|
-
this.id = id;
|
|
26
|
-
this.path = path;
|
|
27
|
-
this.data = data;
|
|
28
|
-
}
|
|
29
|
-
get pathWithId() {
|
|
30
|
-
return `${this.path}/${this.id}`;
|
|
31
|
-
}
|
|
32
|
-
isEntityReference() {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
isEntityRelation() {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
var Vector = class {
|
|
40
|
-
value;
|
|
41
|
-
constructor(value) {
|
|
42
|
-
this.value = value;
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
//#endregion
|
|
46
4
|
//#region ../types/src/types/filter-operators.ts
|
|
47
5
|
/** Maps REST short-code operators to their canonical equivalents. */
|
|
48
6
|
var REST_TO_CANONICAL = {
|
|
@@ -67,7 +25,7 @@ var REST_TO_CANONICAL = {
|
|
|
67
25
|
* Operators that test for null/not-null and therefore ignore their value.
|
|
68
26
|
* Codecs normalize the value of these conditions to `null`.
|
|
69
27
|
*/
|
|
70
|
-
var NULL_OPS = new Set(["is-null", "is-not-null"]);
|
|
28
|
+
var NULL_OPS = /* @__PURE__ */ new Set(["is-null", "is-not-null"]);
|
|
71
29
|
/**
|
|
72
30
|
* Every canonical operator, in a stable order. Useful for engine capability
|
|
73
31
|
* declarations ({@link DataSourceCapabilities.filterOperators}) and for
|
|
@@ -273,120 +231,95 @@ function getDeclaredSubcollections(collection) {
|
|
|
273
231
|
return collection.subcollections;
|
|
274
232
|
}
|
|
275
233
|
//#endregion
|
|
276
|
-
//#region ../types/src/types/
|
|
277
|
-
/** @group Models */
|
|
278
|
-
function hasForeignKeyOnTarget(relation) {
|
|
279
|
-
return relation.kind === "hasOne" || relation.kind === "hasMany";
|
|
280
|
-
}
|
|
281
|
-
/** @group Models */
|
|
282
|
-
function isManyToMany(relation) {
|
|
283
|
-
return relation.kind === "manyToMany";
|
|
284
|
-
}
|
|
285
|
-
//#endregion
|
|
286
|
-
//#region ../types/src/types/policy.ts
|
|
234
|
+
//#region ../types/src/types/rls-functions.ts
|
|
287
235
|
/**
|
|
288
|
-
* The
|
|
236
|
+
* The SQL helper functions RLS policies call, and the schema they live in.
|
|
289
237
|
*
|
|
290
|
-
*
|
|
291
|
-
* `NULL`, and `NULL` is how the trusted server context is recognised, so an
|
|
292
|
-
* anonymous visitor would be promoted to server privileges. The driver
|
|
293
|
-
* therefore substitutes this sentinel at the single chokepoint where the GUC
|
|
294
|
-
* is set.
|
|
238
|
+
* ## One schema, and it is ours
|
|
295
239
|
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
240
|
+
* Rebase creates exactly one schema in a project's database: `rebase`. These
|
|
241
|
+
* three functions live in it alongside the framework's own tables, and that is
|
|
242
|
+
* the whole contract — a reader can look at a database and know precisely which
|
|
243
|
+
* namespace belongs to the framework and that nothing else was touched.
|
|
300
244
|
*
|
|
301
|
-
*
|
|
245
|
+
* It used to be two. `uid()`, `jwt()` and `roles()` sat in a schema called
|
|
246
|
+
* `auth`, which is Supabase's name, chosen so that a developer who had written
|
|
247
|
+
* Supabase RLS would recognise `auth.uid()`. The familiarity was real but the
|
|
248
|
+
* name was not Rebase's to take, and taking it had a concrete cost: pointing
|
|
249
|
+
* Rebase at a database that already had a Supabase `auth` schema meant
|
|
250
|
+
* `CREATE OR REPLACE FUNCTION auth.uid() RETURNS text` against Supabase's
|
|
251
|
+
* `RETURNS uuid`, which Postgres rejects outright —
|
|
252
|
+
*
|
|
253
|
+
* ERROR: cannot change return type of existing function
|
|
254
|
+
* HINT: Use DROP FUNCTION auth.uid() first.
|
|
255
|
+
*
|
|
256
|
+
* — and the failure landed inside a catch-all that logged a warning and carried
|
|
257
|
+
* on, leaving a database with auth tables, no helper functions, and policies
|
|
258
|
+
* calling functions that did not exist. Under `rebase db migrate` the same
|
|
259
|
+
* statements aborted the migration instead.
|
|
260
|
+
*
|
|
261
|
+
* `rebase.uid()` collides with nobody. A Supabase database keeps its `auth`
|
|
262
|
+
* schema untouched and gains a `rebase` one, which is what a gradual migration
|
|
263
|
+
* needs.
|
|
264
|
+
*
|
|
265
|
+
* ## Why functions at all, rather than inlining `current_setting`
|
|
266
|
+
*
|
|
267
|
+
* Because the indirection has already been spent once. `uid()` resolves
|
|
268
|
+
* `app.uid` and falls back to the pre-rename `app.user_id`, so that during a
|
|
269
|
+
* rolling deploy — old and new pods serving one database — both eras resolve
|
|
270
|
+
* the principal. That was a single `CREATE OR REPLACE`. Inlined into policy
|
|
271
|
+
* bodies it would have been a rewrite of every policy on every table.
|
|
272
|
+
*
|
|
273
|
+
* ## Why the name is not configurable
|
|
274
|
+
*
|
|
275
|
+
* A policy body is stored SQL: Postgres parses `USING (…)` once and keeps it, so
|
|
276
|
+
* these strings are written into every policy in every database Rebase has
|
|
277
|
+
* provisioned. Everything that reads policies back — the SQL-to-policy parser
|
|
278
|
+
* behind the admin UI, the drift checker, `rls-check` — would have to know the
|
|
279
|
+
* configured value to recognise its own output. One frozen name is the feature.
|
|
302
280
|
*/
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
var policy = {
|
|
306
|
-
true: () => ({ kind: "true" }),
|
|
307
|
-
false: () => ({ kind: "false" }),
|
|
308
|
-
and: (...operands) => ({
|
|
309
|
-
kind: "and",
|
|
310
|
-
operands
|
|
311
|
-
}),
|
|
312
|
-
or: (...operands) => ({
|
|
313
|
-
kind: "or",
|
|
314
|
-
operands
|
|
315
|
-
}),
|
|
316
|
-
not: (operand) => ({
|
|
317
|
-
kind: "not",
|
|
318
|
-
operand
|
|
319
|
-
}),
|
|
320
|
-
compare: (left, op, right) => ({
|
|
321
|
-
kind: "compare",
|
|
322
|
-
op,
|
|
323
|
-
left,
|
|
324
|
-
right
|
|
325
|
-
}),
|
|
326
|
-
rolesOverlap: (roles) => ({
|
|
327
|
-
kind: "rolesOverlap",
|
|
328
|
-
roles
|
|
329
|
-
}),
|
|
330
|
-
rolesContain: (roles) => ({
|
|
331
|
-
kind: "rolesContain",
|
|
332
|
-
roles
|
|
333
|
-
}),
|
|
334
|
-
authenticated: () => ({ kind: "authenticated" }),
|
|
335
|
-
serverContext: () => ({ kind: "serverContext" }),
|
|
336
|
-
existsIn: (args) => ({
|
|
337
|
-
kind: "existsIn",
|
|
338
|
-
collection: args.collection,
|
|
339
|
-
where: args.where
|
|
340
|
-
}),
|
|
341
|
-
raw: (sql) => ({
|
|
342
|
-
kind: "raw",
|
|
343
|
-
sql
|
|
344
|
-
}),
|
|
345
|
-
field: (name) => ({
|
|
346
|
-
kind: "field",
|
|
347
|
-
name
|
|
348
|
-
}),
|
|
349
|
-
outerField: (name) => ({
|
|
350
|
-
kind: "outerField",
|
|
351
|
-
name
|
|
352
|
-
}),
|
|
353
|
-
literal: (value) => ({
|
|
354
|
-
kind: "literal",
|
|
355
|
-
value
|
|
356
|
-
}),
|
|
357
|
-
authUid: () => ({ kind: "authUid" }),
|
|
358
|
-
authRoles: () => ({ kind: "authRoles" })
|
|
359
|
-
};
|
|
360
|
-
//#endregion
|
|
361
|
-
//#region ../types/src/types/backend.ts
|
|
281
|
+
/** The schema Rebase owns. The only schema Rebase creates. */
|
|
282
|
+
var REBASE_SCHEMA = "rebase";
|
|
362
283
|
/**
|
|
363
|
-
*
|
|
364
|
-
*
|
|
284
|
+
* The principal of the current request, as text, or NULL in the server context.
|
|
285
|
+
*
|
|
286
|
+
* Never NULL for a user request — an anonymous one carries
|
|
287
|
+
* {@link ANONYMOUS_USER_ID} — which is what makes `IS NULL` a reliable test for
|
|
288
|
+
* the trusted server plane and `IS NOT NULL` a tautology.
|
|
365
289
|
*/
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
290
|
+
var RLS_UID_SQL = `${REBASE_SCHEMA}.uid()`;
|
|
291
|
+
/** The request's roles as a comma-separated string, for `string_to_array`. */
|
|
292
|
+
var RLS_ROLES_SQL = `${REBASE_SCHEMA}.roles()`;
|
|
293
|
+
`${REBASE_SCHEMA}`;
|
|
369
294
|
/**
|
|
370
|
-
*
|
|
371
|
-
*
|
|
295
|
+
* The pre-1.0 spellings, for recognising policies and hand-written SQL that
|
|
296
|
+
* predate the move.
|
|
297
|
+
*
|
|
298
|
+
* Kept because policies outlive the server that wrote them: a database migrated
|
|
299
|
+
* by an older release still holds `auth.uid()` in its policy bodies until the
|
|
300
|
+
* next push or boot recompiles them, and anything that reads policies back has
|
|
301
|
+
* to recognise both eras or report the framework's own output as foreign drift.
|
|
302
|
+
* Also used to give a project whose `securityRules` contain raw `auth.uid()` a
|
|
303
|
+
* message naming the replacement, instead of a parse failure.
|
|
372
304
|
*/
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
//#region ../types/src/types/channel_bus.ts
|
|
305
|
+
var LEGACY_RLS_SCHEMA = "auth";
|
|
306
|
+
`${LEGACY_RLS_SCHEMA}`;
|
|
307
|
+
`${LEGACY_RLS_SCHEMA}`;
|
|
308
|
+
`${LEGACY_RLS_SCHEMA}`;
|
|
378
309
|
/**
|
|
379
|
-
*
|
|
380
|
-
* for a built-in one.
|
|
310
|
+
* Rewrites the pre-1.0 function calls in a fragment of policy SQL.
|
|
381
311
|
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
* transport package — is still recognised.
|
|
312
|
+
* Deliberately anchored on a word boundary and the schema qualifier, so a column
|
|
313
|
+
* called `auth_uid` or a table named `auth` is left alone.
|
|
385
314
|
*/
|
|
386
|
-
function
|
|
387
|
-
return
|
|
315
|
+
function rewriteLegacyRlsFunctions(sql) {
|
|
316
|
+
return sql.replace(/\bauth\.(uid|jwt|roles)\s*\(\s*\)/gi, (_match, fn) => `${REBASE_SCHEMA}.${fn.toLowerCase()}()`);
|
|
317
|
+
}
|
|
318
|
+
/** Whether a fragment of SQL still calls the pre-1.0 functions. */
|
|
319
|
+
function usesLegacyRlsFunctions(sql) {
|
|
320
|
+
return /\bauth\.(uid|jwt|roles)\s*\(\s*\)/i.test(sql);
|
|
388
321
|
}
|
|
389
322
|
//#endregion
|
|
390
|
-
export {
|
|
323
|
+
export { rewriteLegacyRlsFunctions as a, isPostgresCollectionConfig as c, getDataSourceCapabilities as d, NULL_OPS as f, RLS_UID_SQL as i, isRelationalCollectionConfig as l, toCanonicalOp as m, REBASE_SCHEMA as n, usesLegacyRlsFunctions as o, REST_TO_CANONICAL as p, RLS_ROLES_SQL as r, getDeclaredSubcollections as s, LEGACY_RLS_SCHEMA as t, DEFAULT_DATA_SOURCE_KEY as u };
|
|
391
324
|
|
|
392
|
-
//# sourceMappingURL=src-
|
|
325
|
+
//# sourceMappingURL=src-C_wvdMnl.js.map
|