@rebasepro/server-postgres 0.12.1-canary.g4e7bcbf → 0.12.1-canary.g6861540
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/auth/services.d.ts +6 -1
- package/dist/backup/backup-service.d.ts +10 -1
- package/dist/backup/pg-tools.d.ts +47 -0
- package/dist/{backup-service-DLb2drIH.js → backup-service-CD8o_1Sl.js} +136 -10
- package/dist/backup-service-CD8o_1Sl.js.map +1 -0
- package/dist/{ensure-collection-policies-Dv21KDMJ.js → ensure-collection-policies-BrUVgjz3.js} +2 -2
- package/dist/{ensure-collection-policies-Dv21KDMJ.js.map → ensure-collection-policies-BrUVgjz3.js.map} +1 -1
- package/dist/{ensure-collection-tables-CT6xHB1d.js → ensure-collection-tables-Da2oGkX2.js} +2 -2
- package/dist/{ensure-collection-tables-CT6xHB1d.js.map → ensure-collection-tables-Da2oGkX2.js.map} +1 -1
- package/dist/index.es.js +256 -88
- package/dist/index.es.js.map +1 -1
- 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/services/RelationService.d.ts +24 -1
- package/dist/services/channel-bus/index.d.ts +1 -7
- package/dist/services/collection-helpers.d.ts +24 -1
- package/dist/{src-BkdpiQdw.js → src-CzbghKwf.js} +43 -5
- package/dist/src-CzbghKwf.js.map +1 -0
- package/dist/utils/connection-string.d.ts +29 -0
- package/dist/utils/drizzle-conditions.d.ts +5 -4
- package/package.json +6 -6
- package/src/auth/services.ts +6 -3
- 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.ts +11 -4
- package/src/collections/validate-relations.ts +15 -0
- package/src/data-transformer.ts +9 -3
- package/src/schema/generate-drizzle-schema-logic.ts +7 -1
- 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 +364 -68
- 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/services/PersistService.ts +20 -6
- package/src/services/RelationService.ts +211 -45
- package/src/services/channel-bus/index.ts +0 -9
- package/src/services/collection-helpers.ts +40 -1
- package/src/utils/connection-string.ts +58 -0
- package/src/utils/drizzle-conditions.ts +31 -6
- package/dist/backup-service-DLb2drIH.js.map +0 -1
- package/dist/src-BkdpiQdw.js.map +0 -1
package/dist/index.es.js
CHANGED
|
@@ -2,11 +2,11 @@ import { createRequire as __createRequire } from "module";
|
|
|
2
2
|
import process from "process";
|
|
3
3
|
__createRequire(import.meta.url);
|
|
4
4
|
import { a as guardPoolAgainstDirtyRelease, i as createReadReplicaConnection, n as createDirectDatabaseConnection, o as pinSearchPath, r as createPostgresDatabaseConnection } from "./connection-BuZ97wsr.js";
|
|
5
|
-
import { C as updateDateAutoValues, D as mergeDeep, E as getPolicyNamesForRule, M as hasForeignKeyOnTarget, N as isManyToMany, O as camelCase, P as Vector, S as normalizeToEntityRelation, _ as buildCompositeId, a as getJunctionSecurityRules, b as createRelationRef, c as policyToPostgres, d as findRelation, f as getColumnName, g as resolveCollectionRelations, h as getTableVarName, i as getJunctionCollectionConfig, k as toSnakeCase, l as securityRuleToConditions, m as getTableName$1, n as CollectionRegistry, o as resolveJunctionSpecs, p as getEnumVarName, r as resolveStringColumnLength, s as getEffectiveSecurityRules, t as buildSdkData, u as findAnonymousGrants, v as getDeclaredPrimaryKeys, w as generateForeignKeyName, x as createRelationRefWithData, y as parseIdValues } from "./src-
|
|
5
|
+
import { C as updateDateAutoValues, D as mergeDeep, E as getPolicyNamesForRule, M as hasForeignKeyOnTarget, N as isManyToMany, O as camelCase, P as Vector, S as normalizeToEntityRelation, _ as buildCompositeId, a as getJunctionSecurityRules, b as createRelationRef, c as policyToPostgres, d as findRelation, f as getColumnName, g as resolveCollectionRelations, h as getTableVarName, i as getJunctionCollectionConfig, k as toSnakeCase, l as securityRuleToConditions, m as getTableName$1, n as CollectionRegistry, o as resolveJunctionSpecs, p as getEnumVarName, r as resolveStringColumnLength, s as getEffectiveSecurityRules, t as buildSdkData, u as findAnonymousGrants, v as getDeclaredPrimaryKeys, w as generateForeignKeyName, x as createRelationRefWithData, y as parseIdValues } from "./src-CzbghKwf.js";
|
|
6
6
|
import { n as isPostgresCollectionConfig, r as isRelationalCollectionConfig } from "./src-DoU9yPqq.js";
|
|
7
7
|
import { t as ANONYMOUS_USER_ID } from "./policy-CeA1JcxP.js";
|
|
8
8
|
import { t as createPostgresWebSocket } from "./websocket-B2LsrINK.js";
|
|
9
|
-
import { A as
|
|
9
|
+
import { A as parsePgToolMajor, C as checkToolServerCompatibility, D as parseBackupDestination, E as joinStorageKey, M as serverVersionNumToMajor, N as splitGlobalsStatements, O as parseBackupTimestamp, P as withDatabaseName, S as buildRowSecurityPgOptions, T as globalsFileForDump, _ as buildBackupFilename, a as detectToolMajor, b as buildPgRestoreArgs, c as listBackups, d as resolvePgBinary, f as restoreDump, g as selectBackupsToPrune, h as require_source, i as createDump, j as resolveConnectionString, k as parseDbNameFromUrl, l as preflight, m as validateDump, n as applyGlobals, o as ensureDatabaseExists, p as uploadBackup, s as getServerVersionMajor, t as BackupToolError, u as pruneBackups, v as buildPgDumpArgs, w as diagnoseRowSecurityDumpFailure, x as buildPgRestoreListArgs, y as buildPgDumpallGlobalsArgs } from "./backup-service-CD8o_1Sl.js";
|
|
10
10
|
import { Client, Pool } from "pg";
|
|
11
11
|
import { drizzle } from "drizzle-orm/node-postgres";
|
|
12
12
|
import { ApiError, createEmailService, loadCollectionsFromDirectory, logger } from "@rebasepro/server";
|
|
@@ -50,6 +50,39 @@ function resolveClientListLimit(rawLimit, opts = {}) {
|
|
|
50
50
|
return opts.vectorSearch ? opts.vectorDefaultLimit ?? 10 : opts.defaultLimit ?? 50;
|
|
51
51
|
}
|
|
52
52
|
//#endregion
|
|
53
|
+
//#region ../common/src/util/email.ts
|
|
54
|
+
/**
|
|
55
|
+
* Email normalization — one implementation, because the database enforces it.
|
|
56
|
+
*
|
|
57
|
+
* `ensureAuthTablesExist` puts a `UNIQUE INDEX ON users (lower(email))` on the
|
|
58
|
+
* auth table. That index decides what "the same address" means, and it does not
|
|
59
|
+
* trim: to Postgres, `' foo@bar.com'` and `'foo@bar.com'` are two addresses and
|
|
60
|
+
* both may exist. So every write that reaches the column has to agree with
|
|
61
|
+
* every read, exactly, or the two disagree in the one direction that matters —
|
|
62
|
+
* a row that exists and cannot be found.
|
|
63
|
+
*
|
|
64
|
+
* That is not hypothetical. The lookup path trimmed and the admin create paths
|
|
65
|
+
* did not, so a user created through `POST /api/data/users` or
|
|
66
|
+
* `POST /api/auth/admin/users` with a stray space was stored untrimmed,
|
|
67
|
+
* survived the unique index alongside the real address, and was unreachable by
|
|
68
|
+
* login forever after. The HTTP auth routes were unaffected only because Zod's
|
|
69
|
+
* `.email()` happens to reject surrounding whitespace — a guard on a different
|
|
70
|
+
* layer, for a different reason, that the admin paths do not sit behind.
|
|
71
|
+
*
|
|
72
|
+
* It lives in `common` because `server`, `server-postgres` and `server-mongo`
|
|
73
|
+
* all write this column and must agree exactly, and `common` is the only
|
|
74
|
+
* package all three already depend on.
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* Canonical form of an email address: trimmed, lower-cased.
|
|
78
|
+
*
|
|
79
|
+
* Non-strings pass through untouched, so this is safe to apply to a value out
|
|
80
|
+
* of a partial update payload whose type is not known yet.
|
|
81
|
+
*/
|
|
82
|
+
function normalizeEmail(email) {
|
|
83
|
+
return typeof email === "string" ? email.trim().toLowerCase() : email;
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
53
86
|
//#region ../common/src/util/callbacks.ts
|
|
54
87
|
/**
|
|
55
88
|
* Helper function to recursively check if there are any callbacks in the properties.
|
|
@@ -282,6 +315,35 @@ function requirePrimaryKeys(collection, registry) {
|
|
|
282
315
|
return keys;
|
|
283
316
|
}
|
|
284
317
|
/**
|
|
318
|
+
* The column on the *source* table that a `hasOne`/`hasMany` link points at.
|
|
319
|
+
*
|
|
320
|
+
* `sourceKey` is authored when the two sides join on a natural key — an
|
|
321
|
+
* external identity id, a SKU — and left off when they join on the row id,
|
|
322
|
+
* which is the overwhelming majority. That makes `undefined` the only optional
|
|
323
|
+
* field on a resolved relation, so it gets exactly one reader: this function.
|
|
324
|
+
* Every consumer that needs the column asks here, and none of them re-derives
|
|
325
|
+
* "or else the primary key" for itself. That is the whole point — the fallback
|
|
326
|
+
* chains this codebase removed from relation resolution were dangerous because
|
|
327
|
+
* they were *duplicated* and could disagree, not because they existed.
|
|
328
|
+
*/
|
|
329
|
+
function sourceKeyField(relation, sourceCollection, registry) {
|
|
330
|
+
if (relation.sourceKey) return relation.sourceKey;
|
|
331
|
+
return requirePrimaryKeys(sourceCollection, registry)[0].fieldName;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Whether this link joins on something other than the source's primary key.
|
|
335
|
+
*
|
|
336
|
+
* Callers that hold a parent *id* — which is most of them, since an id is what
|
|
337
|
+
* a URL carries — must translate it to the source key's value before it can be
|
|
338
|
+
* compared with the target's foreign key. Those that hold the parent *row*, or
|
|
339
|
+
* that build a correlated subquery over the source table, can read the column
|
|
340
|
+
* directly and skip the lookup.
|
|
341
|
+
*/
|
|
342
|
+
function joinsOnNaturalKey(relation, sourceCollection, registry) {
|
|
343
|
+
if (!relation.sourceKey) return false;
|
|
344
|
+
return relation.sourceKey !== requirePrimaryKeys(sourceCollection, registry)[0].fieldName;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
285
347
|
* Collections whose key the *browser* cannot resolve, and what it will do
|
|
286
348
|
* instead.
|
|
287
349
|
*
|
|
@@ -452,7 +514,9 @@ var DrizzleConditionBuilder = class {
|
|
|
452
514
|
case "hasMany": {
|
|
453
515
|
const fkColumn = targetTable[relation.foreignKeyOnTarget];
|
|
454
516
|
if (!fkColumn) throw new Error(`Foreign key column '${relation.foreignKeyOnTarget}' not found in the target table of relation '${relation.relationName}'.`);
|
|
455
|
-
return eq(fkColumn, parentId);
|
|
517
|
+
if (!relation.sourceKey) return eq(fkColumn, parentId);
|
|
518
|
+
const { table, idColumn } = parent();
|
|
519
|
+
return sql`${fkColumn} = (SELECT ${sql.identifier(relation.sourceKey)} FROM ${table} WHERE ${idColumn} = ${parentId})`;
|
|
456
520
|
}
|
|
457
521
|
case "belongsTo": {
|
|
458
522
|
const { table, idColumn } = parent();
|
|
@@ -542,12 +606,16 @@ var DrizzleConditionBuilder = class {
|
|
|
542
606
|
column: foreignKey
|
|
543
607
|
};
|
|
544
608
|
}
|
|
545
|
-
if (relation && (hasForeignKeyOnTarget(relation) || isManyToMany(relation)) && registry && sourceIdColumn)
|
|
546
|
-
|
|
547
|
-
relation,
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
609
|
+
if (relation && (hasForeignKeyOnTarget(relation) || isManyToMany(relation)) && registry && sourceIdColumn) {
|
|
610
|
+
const correlationColumn = hasForeignKeyOnTarget(relation) && relation.sourceKey ? columnAt(relation.sourceKey) : sourceIdColumn;
|
|
611
|
+
if (!correlationColumn) throw new Error(`\`sourceKey: "${relation.sourceKey}"\` on relation '${relation.relationName}' is not a column on '${collectionPath}', so a filter on that relation has nothing to correlate against.`);
|
|
612
|
+
return {
|
|
613
|
+
kind: "relation",
|
|
614
|
+
relation,
|
|
615
|
+
registry,
|
|
616
|
+
sourceIdColumn: correlationColumn
|
|
617
|
+
};
|
|
618
|
+
}
|
|
551
619
|
}
|
|
552
620
|
for (const guess of [`${field}_id`, generateForeignKeyName(field)]) {
|
|
553
621
|
const foreignKey = columnAt(guess);
|
|
@@ -1346,8 +1414,9 @@ async function parseDataFromServer(data, collection, db, registry) {
|
|
|
1346
1414
|
} else if (hasForeignKeyOnTarget(relation) && db && registry) try {
|
|
1347
1415
|
const targetCollection = relation.target();
|
|
1348
1416
|
const targetTable = registry.getTable(getTableName$1(targetCollection));
|
|
1349
|
-
const
|
|
1350
|
-
|
|
1417
|
+
const pks = getPrimaryKeys(collection, registry);
|
|
1418
|
+
const currentId = relation.sourceKey ? data[relation.sourceKey] : buildCompositeId(data, pks);
|
|
1419
|
+
if (targetTable && currentId !== void 0 && currentId !== null && currentId !== "") {
|
|
1351
1420
|
const foreignKeyColumn = targetTable[relation.foreignKeyOnTarget];
|
|
1352
1421
|
if (foreignKeyColumn) {
|
|
1353
1422
|
const relatedRows = await db.select().from(targetTable).where(eq(foreignKeyColumn, currentId)).limit(relation.cardinality === "one" ? 1 : 100);
|
|
@@ -1719,8 +1788,67 @@ var RelationService = class {
|
|
|
1719
1788
|
* reading. Left alone it would silently match on the first key column and
|
|
1720
1789
|
* hand a tenant's rows to its neighbour — say so instead.
|
|
1721
1790
|
*/
|
|
1722
|
-
assertSingleKeyAddressable(parentCollection, parentPks, via) {
|
|
1723
|
-
if (
|
|
1791
|
+
assertSingleKeyAddressable(parentCollection, parentPks, via, relation) {
|
|
1792
|
+
if (relation && hasForeignKeyOnTarget(relation) && relation.sourceKey) return;
|
|
1793
|
+
if (parentPks.length > 1) throw new Error(`Relation on '${parentCollection.slug}' uses '${via}', a single foreign-key column, but '${parentCollection.slug}' is keyed on ${parentPks.map((k) => `'${k.fieldName}'`).join(" + ")}. One column cannot reference a composite key — give the relation a \`sourceKey\` naming a single unique column to point at, or express it with \`joinPath\`, whose \`on.from\`/\`on.to\` take every key column.`);
|
|
1794
|
+
}
|
|
1795
|
+
/**
|
|
1796
|
+
* What the target's foreign key holds, for each of these parent rows.
|
|
1797
|
+
*
|
|
1798
|
+
* Ordinarily the parent's id, and then this is free. When the relation
|
|
1799
|
+
* declares a `sourceKey` the two are different values, and the mapping
|
|
1800
|
+
* between them lives in the source table — so it costs one SELECT, issued
|
|
1801
|
+
* once for the whole batch rather than per parent.
|
|
1802
|
+
*
|
|
1803
|
+
* Both directions come back because both are needed and deriving one from
|
|
1804
|
+
* the other by hand is how a batch loader ends up attributing a child to the
|
|
1805
|
+
* wrong parent: reads translate id → key to build the WHERE, and then
|
|
1806
|
+
* translate key → id to attribute each row that comes back.
|
|
1807
|
+
*/
|
|
1808
|
+
/**
|
|
1809
|
+
* The value a related row's foreign key must hold to belong to this parent.
|
|
1810
|
+
*
|
|
1811
|
+
* `undefined` when the parent's source key is null — which is not an error
|
|
1812
|
+
* here, only in the callers that were about to write it. Exposed for
|
|
1813
|
+
* {@link PersistService}, which stamps this onto a child created under a
|
|
1814
|
+
* nested path and would otherwise write the id and lose the row.
|
|
1815
|
+
*/
|
|
1816
|
+
async parentKeyValue(parentCollection, relation, parentId, db = this.db) {
|
|
1817
|
+
const { keyByParentId } = await this.resolveSourceKeys(parentCollection, relation, [parentId], db);
|
|
1818
|
+
return keyByParentId.get(String(parentId));
|
|
1819
|
+
}
|
|
1820
|
+
async resolveSourceKeys(parentCollection, relation, parentIds, db = this.db) {
|
|
1821
|
+
const keyByParentId = /* @__PURE__ */ new Map();
|
|
1822
|
+
const parentIdByKey = /* @__PURE__ */ new Map();
|
|
1823
|
+
const parentPks = requirePrimaryKeys(parentCollection, this.registry);
|
|
1824
|
+
if (!joinsOnNaturalKey(relation, parentCollection, this.registry)) {
|
|
1825
|
+
for (const id of parentIds) {
|
|
1826
|
+
const value = parseIdValues(id, parentPks)[parentPks[0].fieldName];
|
|
1827
|
+
keyByParentId.set(String(id), value);
|
|
1828
|
+
parentIdByKey.set(String(value), id);
|
|
1829
|
+
}
|
|
1830
|
+
return {
|
|
1831
|
+
keyByParentId,
|
|
1832
|
+
parentIdByKey
|
|
1833
|
+
};
|
|
1834
|
+
}
|
|
1835
|
+
const field = sourceKeyField(relation, parentCollection, this.registry);
|
|
1836
|
+
const parentTable = getTableForCollection(parentCollection, this.registry);
|
|
1837
|
+
if (!parentTable[field]) throw new Error(`\`sourceKey: "${field}"\` on relation '${relation.relationName}' is not a column on '${parentCollection.slug}'. It names a column on the source table, not on the target.`);
|
|
1838
|
+
const rows = await db.select().from(parentTable).where(this.parentKeyCondition(parentTable, parentPks, parentIds));
|
|
1839
|
+
for (const row of rows) {
|
|
1840
|
+
const keyValue = row[field];
|
|
1841
|
+
if (keyValue === null || keyValue === void 0) continue;
|
|
1842
|
+
const parentId = buildCompositeId(row, parentPks);
|
|
1843
|
+
keyByParentId.set(String(parentId), keyValue);
|
|
1844
|
+
const existing = parentIdByKey.get(String(keyValue));
|
|
1845
|
+
if (existing !== void 0 && String(existing) !== String(parentId)) throw new Error(`\`sourceKey: "${field}"\` on relation '${relation.relationName}' is not unique on '${parentCollection.slug}': rows '${existing}' and '${parentId}' both hold '${keyValue}'. Add a unique constraint — a link that addresses more than one source row cannot say which one a related row belongs to.`);
|
|
1846
|
+
parentIdByKey.set(String(keyValue), parentId);
|
|
1847
|
+
}
|
|
1848
|
+
return {
|
|
1849
|
+
keyByParentId,
|
|
1850
|
+
parentIdByKey
|
|
1851
|
+
};
|
|
1724
1852
|
}
|
|
1725
1853
|
/**
|
|
1726
1854
|
* Fetch rows related to a parent row through a specific relation
|
|
@@ -1779,6 +1907,8 @@ var RelationService = class {
|
|
|
1779
1907
|
}
|
|
1780
1908
|
return rows;
|
|
1781
1909
|
}
|
|
1910
|
+
const matchValue = hasForeignKeyOnTarget(relation) ? (await this.resolveSourceKeys(parentCollection, relation, [parentId])).keyByParentId.get(String(parentId)) : parsedParentId;
|
|
1911
|
+
if (matchValue === void 0) return [];
|
|
1782
1912
|
let query = this.db.select().from(targetTable).$dynamic();
|
|
1783
1913
|
const additionalFilters = [];
|
|
1784
1914
|
if (options.searchString) {
|
|
@@ -1787,7 +1917,7 @@ var RelationService = class {
|
|
|
1787
1917
|
const searchCombined = DrizzleConditionBuilder.combineConditionsWithOr(searchConditions);
|
|
1788
1918
|
if (searchCombined) additionalFilters.push(searchCombined);
|
|
1789
1919
|
}
|
|
1790
|
-
query = applyDynamicRelationQuery(query, query, relation,
|
|
1920
|
+
query = applyDynamicRelationQuery(query, query, relation, matchValue, targetTable, parentTable, parentIdCol, idField, this.registry, additionalFilters);
|
|
1791
1921
|
if (options.limit) query = query.limit(options.limit);
|
|
1792
1922
|
const results = await query;
|
|
1793
1923
|
if (!results || !Array.isArray(results)) return [];
|
|
@@ -1830,8 +1960,10 @@ var RelationService = class {
|
|
|
1830
1960
|
const parentTable = this.registry.getTable(getTableName$1(parentCollection));
|
|
1831
1961
|
if (!parentTable) throw new Error("Parent table not found");
|
|
1832
1962
|
const parentIdCol = parentTable[parentIdInfo.fieldName];
|
|
1963
|
+
const matchValue = hasForeignKeyOnTarget(relation) ? (await this.resolveSourceKeys(parentCollection, relation, [parentId])).keyByParentId.get(String(parentId)) : parsedParentId;
|
|
1964
|
+
if (matchValue === void 0) return 0;
|
|
1833
1965
|
let query = this.db.select({ count: sql`count(distinct ${targetIdField})` }).from(targetTable).$dynamic();
|
|
1834
|
-
query = DrizzleConditionBuilder.buildRelationCountQuery(query, relation,
|
|
1966
|
+
query = DrizzleConditionBuilder.buildRelationCountQuery(query, relation, matchValue, targetTable, parentTable, parentIdCol, targetIdField, this.registry, additionalFilters);
|
|
1835
1967
|
const result = await query;
|
|
1836
1968
|
return Number(result[0]?.count || 0);
|
|
1837
1969
|
}
|
|
@@ -1958,17 +2090,24 @@ var RelationService = class {
|
|
|
1958
2090
|
}
|
|
1959
2091
|
return resultMap;
|
|
1960
2092
|
}
|
|
1961
|
-
this.assertSingleKeyAddressable(parentCollection, parentPks, hasForeignKeyOnTarget(relation) ? relation.foreignKeyOnTarget : relation.relationName);
|
|
2093
|
+
this.assertSingleKeyAddressable(parentCollection, parentPks, hasForeignKeyOnTarget(relation) ? relation.foreignKeyOnTarget : relation.relationName, relation);
|
|
2094
|
+
const { keyByParentId, parentIdByKey } = hasForeignKeyOnTarget(relation) ? await this.resolveSourceKeys(parentCollection, relation, parentIds) : {
|
|
2095
|
+
keyByParentId: /* @__PURE__ */ new Map(),
|
|
2096
|
+
parentIdByKey: /* @__PURE__ */ new Map()
|
|
2097
|
+
};
|
|
2098
|
+
const matchValues = hasForeignKeyOnTarget(relation) ? [...keyByParentId.values()] : parsedParentIds;
|
|
2099
|
+
if (matchValues.length === 0) return /* @__PURE__ */ new Map();
|
|
1962
2100
|
let query = this.db.select().from(targetTable).$dynamic();
|
|
1963
|
-
query = applyDynamicRelationQuery(query, query, relation,
|
|
2101
|
+
query = applyDynamicRelationQuery(query, query, relation, matchValues, targetTable, parentTable, parentIdCol, targetIdField, this.registry, []);
|
|
1964
2102
|
const results = await query;
|
|
1965
2103
|
const resultMap = /* @__PURE__ */ new Map();
|
|
1966
|
-
const parentIdSet = new Set(parsedParentIds.map(String));
|
|
1967
2104
|
for (const row of results) {
|
|
1968
2105
|
const targetRow = row[getTableName$1(targetCollection)] || row;
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
if (
|
|
2106
|
+
if (!hasForeignKeyOnTarget(relation)) continue;
|
|
2107
|
+
const foreignKeyValue = targetRow[relation.foreignKeyOnTarget];
|
|
2108
|
+
if (foreignKeyValue === void 0 || foreignKeyValue === null) continue;
|
|
2109
|
+
const parentId = parentIdByKey.get(String(foreignKeyValue));
|
|
2110
|
+
if (parentId !== void 0) resultMap.set(String(parentId), await this.toRelatedRow(targetRow, targetCollection, targetPks));
|
|
1972
2111
|
}
|
|
1973
2112
|
return resultMap;
|
|
1974
2113
|
}
|
|
@@ -2046,17 +2185,24 @@ var RelationService = class {
|
|
|
2046
2185
|
}
|
|
2047
2186
|
return resultMap;
|
|
2048
2187
|
}
|
|
2049
|
-
this.assertSingleKeyAddressable(parentCollection, parentPks, hasForeignKeyOnTarget(relation) ? relation.foreignKeyOnTarget : relation.relationName);
|
|
2188
|
+
this.assertSingleKeyAddressable(parentCollection, parentPks, hasForeignKeyOnTarget(relation) ? relation.foreignKeyOnTarget : relation.relationName, relation);
|
|
2189
|
+
const { keyByParentId, parentIdByKey } = hasForeignKeyOnTarget(relation) ? await this.resolveSourceKeys(parentCollection, relation, parentIds) : {
|
|
2190
|
+
keyByParentId: /* @__PURE__ */ new Map(),
|
|
2191
|
+
parentIdByKey: /* @__PURE__ */ new Map()
|
|
2192
|
+
};
|
|
2193
|
+
const matchValues = hasForeignKeyOnTarget(relation) ? [...keyByParentId.values()] : parsedParentIds;
|
|
2194
|
+
if (matchValues.length === 0) return /* @__PURE__ */ new Map();
|
|
2050
2195
|
let query = this.db.select().from(targetTable).$dynamic();
|
|
2051
|
-
query = applyDynamicRelationQuery(query, query, relation,
|
|
2196
|
+
query = applyDynamicRelationQuery(query, query, relation, matchValues, targetTable, parentTable, parentIdCol, targetIdField, this.registry, []);
|
|
2052
2197
|
const results = await query;
|
|
2053
2198
|
const resultMap = /* @__PURE__ */ new Map();
|
|
2054
|
-
const parentIdSet = new Set(parsedParentIds.map(String));
|
|
2055
2199
|
for (const row of results) {
|
|
2056
2200
|
const targetRow = row[getTableName$1(targetCollection)] || row;
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
if (
|
|
2201
|
+
if (!hasForeignKeyOnTarget(relation)) continue;
|
|
2202
|
+
const foreignKeyValue = targetRow[relation.foreignKeyOnTarget];
|
|
2203
|
+
if (foreignKeyValue === void 0 || foreignKeyValue === null) continue;
|
|
2204
|
+
const parentId = parentIdByKey.get(String(foreignKeyValue));
|
|
2205
|
+
if (parentId !== void 0) {
|
|
2060
2206
|
const key = String(parentId);
|
|
2061
2207
|
const arr = resultMap.get(key) || [];
|
|
2062
2208
|
arr.push(await this.toRelatedRow(targetRow, targetCollection, targetPks));
|
|
@@ -2155,14 +2301,13 @@ var RelationService = class {
|
|
|
2155
2301
|
logger.warn(`Invalid inverse-many config for relation '${key}' in collection '${collection.slug}'`);
|
|
2156
2302
|
continue;
|
|
2157
2303
|
}
|
|
2158
|
-
const
|
|
2159
|
-
|
|
2160
|
-
const parsedParentId = parseIdValues(id, parentPks)[parentIdInfo.fieldName];
|
|
2304
|
+
const parentKeyValue = (await this.resolveSourceKeys(collection, relation, [id], tx)).keyByParentId.get(String(id));
|
|
2305
|
+
if (parentKeyValue === void 0) throw new Error(`Cannot write relation '${key}' on '${collection.slug}': row '${id}' has no value in \`sourceKey: "${sourceKeyField(relation, collection, this.registry)}"\`, so there is nothing for the related rows to point at.`);
|
|
2161
2306
|
if (targetEntityIds.length > 0) {
|
|
2162
2307
|
const parsedTargetIds = targetEntityIds.map((id) => parseIdValues(id, targetPks)[targetIdInfo.fieldName]);
|
|
2163
|
-
await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: null }).where(and(eq(fkCol,
|
|
2164
|
-
await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]:
|
|
2165
|
-
} else await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: null }).where(eq(fkCol,
|
|
2308
|
+
await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: null }).where(and(eq(fkCol, parentKeyValue), sql`${targetIdCol} NOT IN (${sql.join(parsedTargetIds)})`));
|
|
2309
|
+
await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: parentKeyValue }).where(inArray(targetIdCol, parsedTargetIds));
|
|
2310
|
+
} else await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: null }).where(eq(fkCol, parentKeyValue));
|
|
2166
2311
|
} else logger.warn(`Many relation '${key}' in collection '${collection.slug}' lacks write configuration and will be skipped during save.`);
|
|
2167
2312
|
}
|
|
2168
2313
|
}
|
|
@@ -2177,8 +2322,7 @@ var RelationService = class {
|
|
|
2177
2322
|
const targetTable = getTableForCollection(targetCollection, this.registry);
|
|
2178
2323
|
const targetPks = requirePrimaryKeys(targetCollection, this.registry);
|
|
2179
2324
|
const targetIdInfo = targetPks[0];
|
|
2180
|
-
|
|
2181
|
-
const sourceIdInfo = sourcePks[0];
|
|
2325
|
+
requirePrimaryKeys(sourceCollection, this.registry)[0];
|
|
2182
2326
|
if (relation.kind === "via") {
|
|
2183
2327
|
await this.updateInverseJoinPathRelation(tx, sourceCollection, sourceEntityId, targetCollection, relation, newValue);
|
|
2184
2328
|
continue;
|
|
@@ -2200,13 +2344,14 @@ var RelationService = class {
|
|
|
2200
2344
|
logger.warn(`Foreign key column '${relation.foreignKeyOnTarget}' not found in target table for relation '${relation.relationName}'`);
|
|
2201
2345
|
continue;
|
|
2202
2346
|
}
|
|
2203
|
-
const
|
|
2204
|
-
if (
|
|
2347
|
+
const sourceKeyValue = (await this.resolveSourceKeys(sourceCollection, relation, [sourceEntityId], tx)).keyByParentId.get(String(sourceEntityId));
|
|
2348
|
+
if (sourceKeyValue === void 0) throw new Error(`Cannot write relation '${relation.relationName}' on '${sourceCollection.slug}': row '${sourceEntityId}' has no value in \`sourceKey: "${sourceKeyField(relation, sourceCollection, this.registry)}"\`, so there is nothing for the related row to point at.`);
|
|
2349
|
+
if (newValue === null || newValue === void 0) await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: null }).where(eq(foreignKeyColumn, sourceKeyValue));
|
|
2205
2350
|
else {
|
|
2206
2351
|
const parsedNewTargetId = parseIdValues(newValue, targetPks)[targetIdInfo.fieldName];
|
|
2207
2352
|
const targetIdField = targetTable[targetIdInfo.fieldName];
|
|
2208
|
-
await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: null }).where(eq(foreignKeyColumn,
|
|
2209
|
-
await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]:
|
|
2353
|
+
await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: null }).where(eq(foreignKeyColumn, sourceKeyValue));
|
|
2354
|
+
await tx.update(targetTable).set({ [relation.foreignKeyOnTarget]: sourceKeyValue }).where(eq(targetIdField, parsedNewTargetId));
|
|
2210
2355
|
}
|
|
2211
2356
|
} catch (e) {
|
|
2212
2357
|
logger.warn(`Failed to update inverse relation '${relation.relationName}'`, { error: e });
|
|
@@ -3797,10 +3942,11 @@ var PersistService = class {
|
|
|
3797
3942
|
} else {
|
|
3798
3943
|
const targetColumnName = this.resolveParentForeignKeyColumn(hop);
|
|
3799
3944
|
if (targetColumnName) {
|
|
3800
|
-
const
|
|
3945
|
+
const parentKeyValue = hasForeignKeyOnTarget(hop.relation) ? await this.relationService.parentKeyValue(hop.parentCollection, hop.relation, hop.parentId) : parentIdForWrite();
|
|
3946
|
+
if (parentKeyValue === void 0) throw ApiError.badRequest(`Cannot create under "${collectionPath}": the parent row has no value in \`sourceKey\`, so the new row has nothing to point at.`);
|
|
3801
3947
|
const existingValue = effectiveValues[targetColumnName];
|
|
3802
|
-
if (existingValue !== void 0 && existingValue !== null && existingValue !==
|
|
3803
|
-
effectiveValues[targetColumnName] =
|
|
3948
|
+
if (existingValue !== void 0 && existingValue !== null && existingValue !== parentKeyValue) logger.warn(`Overriding provided value '${existingValue}' for FK '${targetColumnName}' with path parent key '${parentKeyValue}'.`);
|
|
3949
|
+
effectiveValues[targetColumnName] = parentKeyValue;
|
|
3804
3950
|
}
|
|
3805
3951
|
}
|
|
3806
3952
|
}
|
|
@@ -6152,8 +6298,9 @@ var generateSchema = async (collections, stripPolicies = false) => {
|
|
|
6152
6298
|
if (!emittedRelationNames.has(deduplicationKey)) {
|
|
6153
6299
|
const otherTableVar = getTableVarName(getTableName$1(otherCollection));
|
|
6154
6300
|
const drizzleFieldKey = resolvePropertyKeyForColumn(collection, otherRel.foreignKeyOnTarget);
|
|
6301
|
+
const referencedKey = otherRel.sourceKey ? resolvePropertyKeyForColumn(otherCollection, otherRel.sourceKey) : getPrimaryKeyName(otherCollection);
|
|
6155
6302
|
const synthKey = `_synth_${otherTableVar}_${drizzleFieldKey}`;
|
|
6156
|
-
tableRelations.push(` "${synthKey}": one(${otherTableVar}, {\n fields: [${tableVarName}.${drizzleFieldKey}],\n references: [${otherTableVar}.${
|
|
6303
|
+
tableRelations.push(` "${synthKey}": one(${otherTableVar}, {\n fields: [${tableVarName}.${drizzleFieldKey}],\n references: [${otherTableVar}.${referencedKey}],\n relationName: \"${drizzleRelationName}\"\n })`);
|
|
6157
6304
|
emittedRelationNames.add(deduplicationKey);
|
|
6158
6305
|
}
|
|
6159
6306
|
}
|
|
@@ -7311,14 +7458,6 @@ function resolveChannelBusSetting(configured) {
|
|
|
7311
7458
|
return raw === "memory" ? { type: "memory" } : { type: "postgres" };
|
|
7312
7459
|
}
|
|
7313
7460
|
/**
|
|
7314
|
-
* @deprecated Use {@link resolveChannelBusSetting}, which also accepts a
|
|
7315
|
-
* supplied {@link ChannelBus} instance. Kept as a narrow alias so existing
|
|
7316
|
-
* config-only callers keep their exact types.
|
|
7317
|
-
*/
|
|
7318
|
-
function resolveChannelBusConfig(configured) {
|
|
7319
|
-
return resolveChannelBusSetting(configured);
|
|
7320
|
-
}
|
|
7321
|
-
/**
|
|
7322
7461
|
* Produce the bus a setting asks for.
|
|
7323
7462
|
*
|
|
7324
7463
|
* An instance is handed straight back — constructing it was the application's
|
|
@@ -8929,7 +9068,7 @@ function createBackupCron(config) {
|
|
|
8929
9068
|
enabled: config.enabled ?? true,
|
|
8930
9069
|
timeoutSeconds: 3600,
|
|
8931
9070
|
async handler({ log }) {
|
|
8932
|
-
const { createDump, pruneBackups, uploadBackup, validateDump } = await import("./backup-service-
|
|
9071
|
+
const { createDump, pruneBackups, uploadBackup, validateDump } = await import("./backup-service-CD8o_1Sl.js").then((n) => n.r);
|
|
8933
9072
|
const { destination } = config;
|
|
8934
9073
|
if (destination.kind !== "local" && !config.storage) throw new Error(`Backup destination is ${destination.kind} but no storage controller was provided. Pass the backend's configured StorageController to createBackupCron({ storage }).`);
|
|
8935
9074
|
log(`Starting backup of "${dbName}"…`);
|
|
@@ -9060,6 +9199,11 @@ function findRelationDefects(collections, registry) {
|
|
|
9060
9199
|
problem: `\`foreignKeyOnTarget: "${relation.foreignKeyOnTarget}"\` is not a column on the target table \`${targetTableName}\``,
|
|
9061
9200
|
fix: `add the column, or set \`foreignKeyOnTarget\` to one of: ${quote(targetColumns)}`
|
|
9062
9201
|
});
|
|
9202
|
+
if (relation.sourceKey && !sourceColumns.has(relation.sourceKey)) defects.push({
|
|
9203
|
+
...at,
|
|
9204
|
+
problem: `\`sourceKey: "${relation.sourceKey}"\` is not a column on \`${sourceTableName}\``,
|
|
9205
|
+
fix: targetColumns.has(relation.sourceKey) ? `it is a column on the *target* table \`${targetTableName}\` — \`sourceKey\` names the column on this collection that the target's foreign key points at, so it must be one of: ${quote(sourceColumns)}` : `add the column, or set \`sourceKey\` to one of: ${quote(sourceColumns)}`
|
|
9206
|
+
});
|
|
9063
9207
|
break;
|
|
9064
9208
|
case "manyToMany": {
|
|
9065
9209
|
const { table, sourceColumn, targetColumn } = relation.through;
|
|
@@ -9811,21 +9955,6 @@ async function ensureAuthTablesExist(db, collection) {
|
|
|
9811
9955
|
}
|
|
9812
9956
|
//#endregion
|
|
9813
9957
|
//#region src/auth/services.ts
|
|
9814
|
-
function getColumnKey(table, ...keys) {
|
|
9815
|
-
if (!table) return void 0;
|
|
9816
|
-
for (const key of keys) {
|
|
9817
|
-
if (key in table) return key;
|
|
9818
|
-
const snake = toSnakeCase(key);
|
|
9819
|
-
if (snake in table) return snake;
|
|
9820
|
-
const camel = camelCase(key);
|
|
9821
|
-
if (camel in table) return camel;
|
|
9822
|
-
}
|
|
9823
|
-
}
|
|
9824
|
-
function getColumn(table, ...keys) {
|
|
9825
|
-
if (!table) return void 0;
|
|
9826
|
-
const key = getColumnKey(table, ...keys);
|
|
9827
|
-
return key ? table[key] : void 0;
|
|
9828
|
-
}
|
|
9829
9958
|
/**
|
|
9830
9959
|
* The single definition of what an email address looks like in storage.
|
|
9831
9960
|
*
|
|
@@ -9840,9 +9969,25 @@ function getColumn(table, ...keys) {
|
|
|
9840
9969
|
*
|
|
9841
9970
|
* Whitespace goes too: a trailing space survives the fold and reproduces the
|
|
9842
9971
|
* problem exactly.
|
|
9972
|
+
*
|
|
9973
|
+
* Re-exported rather than defined here: `@rebasepro/server` and
|
|
9974
|
+
* `@rebasepro/server-mongo` write this column too, and a second copy of this
|
|
9975
|
+
* rule is the defect it exists to prevent.
|
|
9843
9976
|
*/
|
|
9844
|
-
function
|
|
9845
|
-
|
|
9977
|
+
function getColumnKey(table, ...keys) {
|
|
9978
|
+
if (!table) return void 0;
|
|
9979
|
+
for (const key of keys) {
|
|
9980
|
+
if (key in table) return key;
|
|
9981
|
+
const snake = toSnakeCase(key);
|
|
9982
|
+
if (snake in table) return snake;
|
|
9983
|
+
const camel = camelCase(key);
|
|
9984
|
+
if (camel in table) return camel;
|
|
9985
|
+
}
|
|
9986
|
+
}
|
|
9987
|
+
function getColumn(table, ...keys) {
|
|
9988
|
+
if (!table) return void 0;
|
|
9989
|
+
const key = getColumnKey(table, ...keys);
|
|
9990
|
+
return key ? table[key] : void 0;
|
|
9846
9991
|
}
|
|
9847
9992
|
/**
|
|
9848
9993
|
* PostgreSQL implementation of UserRepository.
|
|
@@ -11183,6 +11328,31 @@ function humanize(snakeName) {
|
|
|
11183
11328
|
return snakeName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
11184
11329
|
}
|
|
11185
11330
|
//#endregion
|
|
11331
|
+
//#region src/schema/introspect-db-types.ts
|
|
11332
|
+
/**
|
|
11333
|
+
* The PostgreSQL type → Rebase property type mapping.
|
|
11334
|
+
*
|
|
11335
|
+
* Split out of `introspect-db-logic` so that the structural analysis can use it
|
|
11336
|
+
* without importing the generator, which imports the analysis. Re-exported from
|
|
11337
|
+
* `introspect-db-logic` so existing callers keep their import path.
|
|
11338
|
+
*/
|
|
11339
|
+
/**
|
|
11340
|
+
* Map a PostgreSQL data type to a Rebase property type.
|
|
11341
|
+
*/
|
|
11342
|
+
function mapPgType(dataType) {
|
|
11343
|
+
const dt = dataType.toLowerCase();
|
|
11344
|
+
if (dt === "interval") return "string";
|
|
11345
|
+
if (dt === "array" || dt.startsWith("_")) return "array";
|
|
11346
|
+
if (dt.includes("int") || dt.includes("numeric") || dt.includes("decimal") || dt.includes("serial") || dt === "real" || dt === "float4" || dt === "float8" || dt === "double precision" || dt === "money") return "number";
|
|
11347
|
+
if (dt.includes("bool")) return "boolean";
|
|
11348
|
+
if (dt.includes("time") || dt.includes("date")) return "date";
|
|
11349
|
+
if (dt === "json" || dt === "jsonb") return "map";
|
|
11350
|
+
if (dt === "bytea") return "binary";
|
|
11351
|
+
if (dt === "inet" || dt === "cidr" || dt === "macaddr" || dt === "macaddr8") return "string";
|
|
11352
|
+
if (dt === "uuid") return "string";
|
|
11353
|
+
return "string";
|
|
11354
|
+
}
|
|
11355
|
+
//#endregion
|
|
11186
11356
|
//#region src/schema/introspect-db-logic.ts
|
|
11187
11357
|
var IRREGULAR_SINGULARS = {
|
|
11188
11358
|
people: "person",
|
|
@@ -11287,22 +11457,6 @@ function getIconForTable(tableName) {
|
|
|
11287
11457
|
if (table.includes("comment") || table.includes("review") || table.includes("feedback")) return "MessageCircle";
|
|
11288
11458
|
return "Database";
|
|
11289
11459
|
}
|
|
11290
|
-
/**
|
|
11291
|
-
* Map a PostgreSQL data type to a Rebase property type.
|
|
11292
|
-
*/
|
|
11293
|
-
function mapPgType(dataType) {
|
|
11294
|
-
const dt = dataType.toLowerCase();
|
|
11295
|
-
if (dt === "interval") return "string";
|
|
11296
|
-
if (dt === "array" || dt.startsWith("_")) return "array";
|
|
11297
|
-
if (dt.includes("int") || dt.includes("numeric") || dt.includes("decimal") || dt.includes("serial") || dt === "real" || dt === "float4" || dt === "float8" || dt === "double precision" || dt === "money") return "number";
|
|
11298
|
-
if (dt.includes("bool")) return "boolean";
|
|
11299
|
-
if (dt.includes("time") || dt.includes("date")) return "date";
|
|
11300
|
-
if (dt === "json" || dt === "jsonb") return "map";
|
|
11301
|
-
if (dt === "bytea") return "binary";
|
|
11302
|
-
if (dt === "inet" || dt === "cidr" || dt === "macaddr" || dt === "macaddr8") return "string";
|
|
11303
|
-
if (dt === "uuid") return "string";
|
|
11304
|
-
return "string";
|
|
11305
|
-
}
|
|
11306
11460
|
function buildEnumMap(enumValues) {
|
|
11307
11461
|
const enumMap = /* @__PURE__ */ new Map();
|
|
11308
11462
|
for (const ev of enumValues) {
|
|
@@ -11322,6 +11476,20 @@ function buildTablesMap(tables, columns, pks, fks) {
|
|
|
11322
11476
|
});
|
|
11323
11477
|
return tablesMap;
|
|
11324
11478
|
}
|
|
11479
|
+
/**
|
|
11480
|
+
* Join tables, identified by column name.
|
|
11481
|
+
*
|
|
11482
|
+
* Superseded for the CLI by `classifyTables` in `./introspect-db-structure`,
|
|
11483
|
+
* which asks the database instead: two single-column keys, unique together, no
|
|
11484
|
+
* payload column, nothing referencing the table. This rule folds away
|
|
11485
|
+
* `northwind.order_details` — which has the key shape and carries unit price,
|
|
11486
|
+
* quantity and discount — because it recognises `id`, `created_at` and
|
|
11487
|
+
* `updated_at` by name and calls everything else a foreign key.
|
|
11488
|
+
*
|
|
11489
|
+
* Still used by `./introspect-runtime`, which builds collections in memory from
|
|
11490
|
+
* a narrower set of catalog queries and has no unique-constraint or row-count
|
|
11491
|
+
* data to reason with.
|
|
11492
|
+
*/
|
|
11325
11493
|
function identifyJoinTables(tablesMap) {
|
|
11326
11494
|
const joinTables = /* @__PURE__ */ new Set();
|
|
11327
11495
|
for (const [tableName, meta] of tablesMap.entries()) if (meta.fks.length === 2) {
|
|
@@ -12057,7 +12225,7 @@ function createPostgresBootstrapper(pgConfig) {
|
|
|
12057
12225
|
*/
|
|
12058
12226
|
async ensureCollectionSchema(collections, driverResult, log) {
|
|
12059
12227
|
const internals = driverResult.internals;
|
|
12060
|
-
const { ensureCollectionTables } = await import("./ensure-collection-tables-
|
|
12228
|
+
const { ensureCollectionTables } = await import("./ensure-collection-tables-Da2oGkX2.js");
|
|
12061
12229
|
const plan = await ensureCollectionTables({ async query(text) {
|
|
12062
12230
|
const result = await internals.db.execute(sql.raw(text));
|
|
12063
12231
|
return { rows: result.rows ?? (Array.isArray(result) ? result : []) };
|
|
@@ -12082,7 +12250,7 @@ function createPostgresBootstrapper(pgConfig) {
|
|
|
12082
12250
|
*/
|
|
12083
12251
|
async ensureCollectionPolicies(collections, driverResult, log) {
|
|
12084
12252
|
const internals = driverResult.internals;
|
|
12085
|
-
const { ensureCollectionPolicies } = await import("./ensure-collection-policies-
|
|
12253
|
+
const { ensureCollectionPolicies } = await import("./ensure-collection-policies-BrUVgjz3.js");
|
|
12086
12254
|
const outcome = await ensureCollectionPolicies({ async query(text) {
|
|
12087
12255
|
const result = await internals.db.execute(sql.raw(text));
|
|
12088
12256
|
return { rows: result.rows ?? (Array.isArray(result) ? result : []) };
|
|
@@ -12136,6 +12304,6 @@ function createPostgresAdapter(pgConfig) {
|
|
|
12136
12304
|
};
|
|
12137
12305
|
}
|
|
12138
12306
|
//#endregion
|
|
12139
|
-
export { AuthenticatedPostgresBackendDriver, BackupToolError, BranchService, CHANNEL_BUS_NOTIFY_CHANNEL, DEFAULT_BATCH_WINDOW_MS, DatabasePoolManager, DrizzleConditionBuilder, MemoryChannelBus, PG_NOTIFY_MAX_PAYLOAD_BYTES, PostgresBackendDriver, PostgresChannelBus, PostgresCollectionRegistry, PostgresConditionBuilder, PostgresRealtimeProvider, RealtimeService, appConfig, applyGlobals, backupCronConfigFromEnv, buildBackupFilename, buildPgDumpArgs, buildPgDumpallGlobalsArgs, buildPgRestoreArgs, buildPgRestoreListArgs, checkToolServerCompatibility, configureUnknownFilterFields, createAuthSchema, createBackupCron, createChannelBus, createDirectDatabaseConnection, createDump, createPostgresAdapter, createPostgresBootstrapper, createPostgresDatabaseConnection, createPostgresWebSocket, createReadReplicaConnection, detectToolMajor, ensureDatabaseExists, frameByteLength, generateSchema, getServerVersionMajor, getUnknownFilterFieldsMode, globalsFileForDump, guardPoolAgainstDirtyRelease, isChannelBusInstance, joinStorageKey, listBackups, magicLinkTokens, magicLinkTokensRelations, mfaChallenges, mfaChallengesRelations, mfaFactors, mfaFactorsRelations, parseBackupDestination, parseBackupTimestamp, parseChannelBusFrame, parseChannelBusPayload, parseDbNameFromUrl, parsePgToolMajor, passwordResetTokens, passwordResetTokensRelations, pinSearchPath, preflight, pruneBackups, recoveryCodes, recoveryCodesRelations, refreshTokens, refreshTokensRelations,
|
|
12307
|
+
export { AuthenticatedPostgresBackendDriver, BackupToolError, BranchService, CHANNEL_BUS_NOTIFY_CHANNEL, DEFAULT_BATCH_WINDOW_MS, DatabasePoolManager, DrizzleConditionBuilder, MemoryChannelBus, PG_NOTIFY_MAX_PAYLOAD_BYTES, PostgresBackendDriver, PostgresChannelBus, PostgresCollectionRegistry, PostgresConditionBuilder, PostgresRealtimeProvider, RealtimeService, appConfig, applyGlobals, backupCronConfigFromEnv, buildBackupFilename, buildPgDumpArgs, buildPgDumpallGlobalsArgs, buildPgRestoreArgs, buildPgRestoreListArgs, buildRowSecurityPgOptions, checkToolServerCompatibility, configureUnknownFilterFields, createAuthSchema, createBackupCron, createChannelBus, createDirectDatabaseConnection, createDump, createPostgresAdapter, createPostgresBootstrapper, createPostgresDatabaseConnection, createPostgresWebSocket, createReadReplicaConnection, detectToolMajor, diagnoseRowSecurityDumpFailure, ensureDatabaseExists, frameByteLength, generateSchema, getServerVersionMajor, getUnknownFilterFieldsMode, globalsFileForDump, guardPoolAgainstDirtyRelease, isChannelBusInstance, joinStorageKey, listBackups, magicLinkTokens, magicLinkTokensRelations, mfaChallenges, mfaChallengesRelations, mfaFactors, mfaFactorsRelations, parseBackupDestination, parseBackupTimestamp, parseChannelBusFrame, parseChannelBusPayload, parseDbNameFromUrl, parsePgToolMajor, passwordResetTokens, passwordResetTokensRelations, pinSearchPath, preflight, pruneBackups, recoveryCodes, recoveryCodesRelations, refreshTokens, refreshTokensRelations, resolveChannelBusSetting, resolveConnectionString, resolveDriftCheckName, resolvePgBinary, restoreDump, selectBackupsToPrune, serverVersionNumToMajor, splitGlobalsStatements, uploadBackup, userIdentities, userIdentitiesRelations, users, usersRelations, usersSchema, validateDump, withDatabaseName };
|
|
12140
12308
|
|
|
12141
12309
|
//# sourceMappingURL=index.es.js.map
|