@rebasepro/server-postgres 0.11.0 → 0.11.1-canary.g8caabf3
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/collections/buildRegistry.d.ts +1 -1
- package/dist/{ensure-collection-tables-DGMYK0fr.js → ensure-collection-tables-DWEvKSY8.js} +2 -2
- package/dist/{ensure-collection-tables-DGMYK0fr.js.map → ensure-collection-tables-DWEvKSY8.js.map} +1 -1
- package/dist/index.es.js +13 -9
- package/dist/index.es.js.map +1 -1
- package/dist/schema/dynamic-tables.d.ts +1 -1
- package/dist/schema/introspect-runtime.d.ts +1 -1
- package/dist/services/FetchService.d.ts +1 -1
- package/dist/src-D5xBTl32.js.map +1 -1
- package/dist/{src-3VmUJ8Xn.js → src-Da-RFMnG.js} +3 -3
- package/dist/src-Da-RFMnG.js.map +1 -0
- package/package.json +6 -6
- package/src/PostgresBootstrapper.ts +4 -4
- package/src/collections/buildRegistry.ts +1 -1
- package/src/schema/dynamic-tables.ts +1 -1
- package/src/schema/generate-drizzle-schema-logic.ts +10 -2
- package/src/schema/introspect-runtime.ts +1 -1
- package/src/services/FetchService.ts +1 -1
- package/src/utils/drizzle-conditions.ts +18 -1
- package/dist/src-3VmUJ8Xn.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/server-postgres",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.1-canary.g8caabf3",
|
|
5
5
|
"description": "PostgreSQL data source backend implementation for Rebase with Drizzle ORM",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/rebaseco"
|
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
"execa": "^9.6.1",
|
|
48
48
|
"pg": "^8.21.0",
|
|
49
49
|
"ws": "^8.21.0",
|
|
50
|
-
"@rebasepro/
|
|
51
|
-
"@rebasepro/
|
|
52
|
-
"@rebasepro/utils": "0.11.
|
|
53
|
-
"@rebasepro/
|
|
54
|
-
"@rebasepro/
|
|
50
|
+
"@rebasepro/common": "0.11.1-canary.g8caabf3",
|
|
51
|
+
"@rebasepro/codegen": "0.11.1-canary.g8caabf3",
|
|
52
|
+
"@rebasepro/utils": "0.11.1-canary.g8caabf3",
|
|
53
|
+
"@rebasepro/server": "0.11.1-canary.g8caabf3",
|
|
54
|
+
"@rebasepro/types": "0.11.1-canary.g8caabf3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@hono/node-server": "^2.0.11",
|
|
@@ -112,10 +112,10 @@ export function createPostgresBootstrapper(pgConfig: PostgresDriverConfig): Back
|
|
|
112
112
|
async initializeDriver(config: unknown): Promise<InitializedDriver> {
|
|
113
113
|
// config is passed from coordinator, we merge it with our internal pgConfig if needed
|
|
114
114
|
// Currently config from init.ts is `{ collections, collectionRegistry, mode }`
|
|
115
|
-
const { collections, collectionRegistry,
|
|
115
|
+
const { collections, collectionRegistry, introspectCollections, baas } = config as {
|
|
116
116
|
collections?: CollectionConfig[];
|
|
117
117
|
collectionRegistry?: unknown;
|
|
118
|
-
|
|
118
|
+
introspectCollections?: boolean;
|
|
119
119
|
baas?: { unprotectedTables?: "exclude" | "serve" };
|
|
120
120
|
};
|
|
121
121
|
// Secure by default: a table with no RLS is not served.
|
|
@@ -126,13 +126,13 @@ export function createPostgresBootstrapper(pgConfig: PostgresDriverConfig): Back
|
|
|
126
126
|
? (connection as Record<string, unknown>).$client
|
|
127
127
|
: connection) as import("pg").Pool;
|
|
128
128
|
|
|
129
|
-
// ──
|
|
129
|
+
// ── No declared collections: derive the schema from the database ──
|
|
130
130
|
// No collection files and no generated drizzle schema exist, so read
|
|
131
131
|
// the live database and build both from what is actually there.
|
|
132
132
|
let introspectedCollections: CollectionConfig[] | undefined;
|
|
133
133
|
let introspectedTables: Record<string, PgTable> | undefined;
|
|
134
134
|
let introspectedRelations: Record<string, Relations> | undefined;
|
|
135
|
-
if (
|
|
135
|
+
if (introspectCollections && (!collections || collections.length === 0)) {
|
|
136
136
|
const pgSchemaName = pgConfig.introspectionSchema ?? "public";
|
|
137
137
|
const schema = await introspectSchema(rawClient, pgSchemaName);
|
|
138
138
|
|
|
@@ -9,7 +9,7 @@ import { assertRelationsResolve } from "./validate-relations";
|
|
|
9
9
|
/**
|
|
10
10
|
* Everything a registry is built from: the collections, and the drizzle schema
|
|
11
11
|
* they are backed by. In BaaS mode all of it is introspected from the live
|
|
12
|
-
* database;
|
|
12
|
+
* database; when collections are declared it comes from the config and the generated schema.
|
|
13
13
|
*/
|
|
14
14
|
export interface RegistrySchema {
|
|
15
15
|
collections?: CollectionConfig[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Build drizzle tables at runtime from an introspected schema.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* A project with declared collections gets its drizzle tables from a generated `schema.generated.ts` that
|
|
5
5
|
* the developer commits. BaaS mode has no such file — it points at a database
|
|
6
6
|
* and serves it — so the equivalent table objects are constructed here from
|
|
7
7
|
* `information_schema` metadata.
|
|
@@ -708,9 +708,17 @@ export const generateSchema = async (collections: CollectionConfig[], stripPolic
|
|
|
708
708
|
emittedRelationNames.add(deduplicationKey);
|
|
709
709
|
|
|
710
710
|
switch (rel.kind) {
|
|
711
|
-
case "belongsTo":
|
|
712
|
-
|
|
711
|
+
case "belongsTo": {
|
|
712
|
+
// `localKey` is a COLUMN name; the generated Drizzle
|
|
713
|
+
// object is keyed by PROPERTY. They differ whenever
|
|
714
|
+
// the property is camelCase — `user_id` is exposed
|
|
715
|
+
// as `userId` — and emitting the column produces a
|
|
716
|
+
// schema that does not compile. The three other
|
|
717
|
+
// emission sites normalise; this one did not.
|
|
718
|
+
const localFieldKey = resolvePropertyKeyForColumn(collection, rel.localKey);
|
|
719
|
+
tableRelations.push(` "${relationKey}": one(${targetTableVar}, {\n fields: [${tableVarName}.${localFieldKey}],\n references: [${targetTableVar}.${getPrimaryKeyName(target)}],\n relationName: \"${drizzleRelationName}\"\n })`);
|
|
713
720
|
break;
|
|
721
|
+
}
|
|
714
722
|
|
|
715
723
|
case "hasOne":
|
|
716
724
|
// The foreign key lives on the TARGET table. Drizzle pairs
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* single config file.
|
|
8
8
|
*
|
|
9
9
|
* Distinct from `introspect-db.ts`, which runs the same queries but emits
|
|
10
|
-
* TypeScript *source* for a developer to edit and commit (
|
|
10
|
+
* TypeScript *source* for a developer to edit and commit (declared collections). The two
|
|
11
11
|
* share the mapping helpers in `introspect-db-logic.ts` so a table is described
|
|
12
12
|
* the same way whether it was generated or introspected.
|
|
13
13
|
*/
|
|
@@ -85,7 +85,7 @@ export class FetchService {
|
|
|
85
85
|
* Converts collection relations to a Drizzle-compatible `with` object.
|
|
86
86
|
*
|
|
87
87
|
* When `include` is provided, only those relations are loaded.
|
|
88
|
-
* When `include` is absent, ALL relations are loaded (
|
|
88
|
+
* When `include` is absent, ALL relations are loaded (the admin path).
|
|
89
89
|
*
|
|
90
90
|
* Automatically detects many-to-many junction tables and nests
|
|
91
91
|
* the target relation so actual row data is returned.
|
|
@@ -99,7 +99,24 @@ export class DrizzleConditionBuilder {
|
|
|
99
99
|
// Correlated, not joined: a join through a junction multiplies
|
|
100
100
|
// the target rows by the number of matching links and silently
|
|
101
101
|
// breaks `limit`/`offset`.
|
|
102
|
-
|
|
102
|
+
//
|
|
103
|
+
// The junction is aliased and referenced by identifier, never as a
|
|
104
|
+
// Drizzle column. A column object carries no table qualifier of its
|
|
105
|
+
// own — it is rendered against whatever the surrounding builder
|
|
106
|
+
// thinks the current table is — so inside `db.query.findMany`, which
|
|
107
|
+
// aliases the root table, `${sourceCol}` came out qualified with the
|
|
108
|
+
// *target's* alias: `podcast.podcast_id`, a column that does not
|
|
109
|
+
// exist. That aborts the transaction, and the fallback read then
|
|
110
|
+
// fails on the poisoned transaction rather than on anything to do
|
|
111
|
+
// with the relation. Only `targetIdColumn` stays a column object,
|
|
112
|
+
// because that one *must* bind to the outer row to correlate.
|
|
113
|
+
//
|
|
114
|
+
// Aliasing also disambiguates a self-referential many-to-many, where
|
|
115
|
+
// the junction and the target are the same table.
|
|
116
|
+
const junctionAlias = "__rel_m2m";
|
|
117
|
+
const junctionRef = (column: AnyPgColumn) =>
|
|
118
|
+
sql`${sql.identifier(junctionAlias)}.${sql.identifier(column.name)}`;
|
|
119
|
+
return sql`EXISTS (SELECT 1 FROM ${junctionTable} AS ${sql.identifier(junctionAlias)} WHERE ${junctionRef(targetCol)} = ${targetIdColumn} AND ${junctionRef(sourceCol)} = ${parentId})`;
|
|
103
120
|
}
|
|
104
121
|
|
|
105
122
|
case "hasOne":
|