328 lines
11 KiB
JavaScript
328 lines
11 KiB
JavaScript
"use strict";
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc2) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
var relations_exports = {};
|
|
__export(relations_exports, {
|
|
Many: () => Many,
|
|
One: () => One,
|
|
Relation: () => Relation,
|
|
Relations: () => Relations,
|
|
createMany: () => createMany,
|
|
createOne: () => createOne,
|
|
createTableRelationsHelpers: () => createTableRelationsHelpers,
|
|
extractTablesRelationalConfig: () => extractTablesRelationalConfig,
|
|
getOperators: () => getOperators,
|
|
getOrderByOperators: () => getOrderByOperators,
|
|
mapRelationalRow: () => mapRelationalRow,
|
|
normalizeRelation: () => normalizeRelation,
|
|
relations: () => relations
|
|
});
|
|
module.exports = __toCommonJS(relations_exports);
|
|
var import_table = require("./table.cjs");
|
|
var import_column = require("./column.cjs");
|
|
var import_entity = require("./entity.cjs");
|
|
var import_primary_keys = require("./pg-core/primary-keys.cjs");
|
|
var import_expressions = require("./sql/expressions/index.cjs");
|
|
var import_sql = require("./sql/sql.cjs");
|
|
class Relation {
|
|
constructor(sourceTable, referencedTable, relationName) {
|
|
this.sourceTable = sourceTable;
|
|
this.referencedTable = referencedTable;
|
|
this.relationName = relationName;
|
|
this.referencedTableName = referencedTable[import_table.Table.Symbol.Name];
|
|
}
|
|
static [import_entity.entityKind] = "Relation";
|
|
referencedTableName;
|
|
fieldName;
|
|
}
|
|
class Relations {
|
|
constructor(table, config) {
|
|
this.table = table;
|
|
this.config = config;
|
|
}
|
|
static [import_entity.entityKind] = "Relations";
|
|
}
|
|
class One extends Relation {
|
|
constructor(sourceTable, referencedTable, config, isNullable) {
|
|
super(sourceTable, referencedTable, config?.relationName);
|
|
this.config = config;
|
|
this.isNullable = isNullable;
|
|
}
|
|
static [import_entity.entityKind] = "One";
|
|
withFieldName(fieldName) {
|
|
const relation = new One(
|
|
this.sourceTable,
|
|
this.referencedTable,
|
|
this.config,
|
|
this.isNullable
|
|
);
|
|
relation.fieldName = fieldName;
|
|
return relation;
|
|
}
|
|
}
|
|
class Many extends Relation {
|
|
constructor(sourceTable, referencedTable, config) {
|
|
super(sourceTable, referencedTable, config?.relationName);
|
|
this.config = config;
|
|
}
|
|
static [import_entity.entityKind] = "Many";
|
|
withFieldName(fieldName) {
|
|
const relation = new Many(
|
|
this.sourceTable,
|
|
this.referencedTable,
|
|
this.config
|
|
);
|
|
relation.fieldName = fieldName;
|
|
return relation;
|
|
}
|
|
}
|
|
function getOperators() {
|
|
return {
|
|
and: import_expressions.and,
|
|
between: import_expressions.between,
|
|
eq: import_expressions.eq,
|
|
exists: import_expressions.exists,
|
|
gt: import_expressions.gt,
|
|
gte: import_expressions.gte,
|
|
ilike: import_expressions.ilike,
|
|
inArray: import_expressions.inArray,
|
|
isNull: import_expressions.isNull,
|
|
isNotNull: import_expressions.isNotNull,
|
|
like: import_expressions.like,
|
|
lt: import_expressions.lt,
|
|
lte: import_expressions.lte,
|
|
ne: import_expressions.ne,
|
|
not: import_expressions.not,
|
|
notBetween: import_expressions.notBetween,
|
|
notExists: import_expressions.notExists,
|
|
notLike: import_expressions.notLike,
|
|
notIlike: import_expressions.notIlike,
|
|
notInArray: import_expressions.notInArray,
|
|
or: import_expressions.or,
|
|
sql: import_sql.sql
|
|
};
|
|
}
|
|
function getOrderByOperators() {
|
|
return {
|
|
sql: import_sql.sql,
|
|
asc: import_expressions.asc,
|
|
desc: import_expressions.desc
|
|
};
|
|
}
|
|
function extractTablesRelationalConfig(schema, configHelpers) {
|
|
if (Object.keys(schema).length === 1 && "default" in schema && !(0, import_entity.is)(schema["default"], import_table.Table)) {
|
|
schema = schema["default"];
|
|
}
|
|
const tableNamesMap = {};
|
|
const relationsBuffer = {};
|
|
const tablesConfig = {};
|
|
for (const [key, value] of Object.entries(schema)) {
|
|
if ((0, import_entity.is)(value, import_table.Table)) {
|
|
const dbName = (0, import_table.getTableUniqueName)(value);
|
|
const bufferedRelations = relationsBuffer[dbName];
|
|
tableNamesMap[dbName] = key;
|
|
tablesConfig[key] = {
|
|
tsName: key,
|
|
dbName: value[import_table.Table.Symbol.Name],
|
|
schema: value[import_table.Table.Symbol.Schema],
|
|
columns: value[import_table.Table.Symbol.Columns],
|
|
relations: bufferedRelations?.relations ?? {},
|
|
primaryKey: bufferedRelations?.primaryKey ?? []
|
|
};
|
|
for (const column of Object.values(
|
|
value[import_table.Table.Symbol.Columns]
|
|
)) {
|
|
if (column.primary) {
|
|
tablesConfig[key].primaryKey.push(column);
|
|
}
|
|
}
|
|
const extraConfig = value[import_table.Table.Symbol.ExtraConfigBuilder]?.(value[import_table.Table.Symbol.ExtraConfigColumns]);
|
|
if (extraConfig) {
|
|
for (const configEntry of Object.values(extraConfig)) {
|
|
if ((0, import_entity.is)(configEntry, import_primary_keys.PrimaryKeyBuilder)) {
|
|
tablesConfig[key].primaryKey.push(...configEntry.columns);
|
|
}
|
|
}
|
|
}
|
|
} else if ((0, import_entity.is)(value, Relations)) {
|
|
const dbName = (0, import_table.getTableUniqueName)(value.table);
|
|
const tableName = tableNamesMap[dbName];
|
|
const relations2 = value.config(
|
|
configHelpers(value.table)
|
|
);
|
|
let primaryKey;
|
|
for (const [relationName, relation] of Object.entries(relations2)) {
|
|
if (tableName) {
|
|
const tableConfig = tablesConfig[tableName];
|
|
tableConfig.relations[relationName] = relation;
|
|
if (primaryKey) {
|
|
tableConfig.primaryKey.push(...primaryKey);
|
|
}
|
|
} else {
|
|
if (!(dbName in relationsBuffer)) {
|
|
relationsBuffer[dbName] = {
|
|
relations: {},
|
|
primaryKey
|
|
};
|
|
}
|
|
relationsBuffer[dbName].relations[relationName] = relation;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return { tables: tablesConfig, tableNamesMap };
|
|
}
|
|
function relations(table, relations2) {
|
|
return new Relations(
|
|
table,
|
|
(helpers) => Object.fromEntries(
|
|
Object.entries(relations2(helpers)).map(([key, value]) => [
|
|
key,
|
|
value.withFieldName(key)
|
|
])
|
|
)
|
|
);
|
|
}
|
|
function createOne(sourceTable) {
|
|
return function one(table, config) {
|
|
return new One(
|
|
sourceTable,
|
|
table,
|
|
config,
|
|
config?.fields.reduce((res, f) => res && f.notNull, true) ?? false
|
|
);
|
|
};
|
|
}
|
|
function createMany(sourceTable) {
|
|
return function many(referencedTable, config) {
|
|
return new Many(sourceTable, referencedTable, config);
|
|
};
|
|
}
|
|
function normalizeRelation(schema, tableNamesMap, relation) {
|
|
if ((0, import_entity.is)(relation, One) && relation.config) {
|
|
return {
|
|
fields: relation.config.fields,
|
|
references: relation.config.references
|
|
};
|
|
}
|
|
const referencedTableTsName = tableNamesMap[(0, import_table.getTableUniqueName)(relation.referencedTable)];
|
|
if (!referencedTableTsName) {
|
|
throw new Error(
|
|
`Table "${relation.referencedTable[import_table.Table.Symbol.Name]}" not found in schema`
|
|
);
|
|
}
|
|
const referencedTableConfig = schema[referencedTableTsName];
|
|
if (!referencedTableConfig) {
|
|
throw new Error(`Table "${referencedTableTsName}" not found in schema`);
|
|
}
|
|
const sourceTable = relation.sourceTable;
|
|
const sourceTableTsName = tableNamesMap[(0, import_table.getTableUniqueName)(sourceTable)];
|
|
if (!sourceTableTsName) {
|
|
throw new Error(
|
|
`Table "${sourceTable[import_table.Table.Symbol.Name]}" not found in schema`
|
|
);
|
|
}
|
|
const reverseRelations = [];
|
|
for (const referencedTableRelation of Object.values(
|
|
referencedTableConfig.relations
|
|
)) {
|
|
if (relation.relationName && relation !== referencedTableRelation && referencedTableRelation.relationName === relation.relationName || !relation.relationName && referencedTableRelation.referencedTable === relation.sourceTable) {
|
|
reverseRelations.push(referencedTableRelation);
|
|
}
|
|
}
|
|
if (reverseRelations.length > 1) {
|
|
throw relation.relationName ? new Error(
|
|
`There are multiple relations with name "${relation.relationName}" in table "${referencedTableTsName}"`
|
|
) : new Error(
|
|
`There are multiple relations between "${referencedTableTsName}" and "${relation.sourceTable[import_table.Table.Symbol.Name]}". Please specify relation name`
|
|
);
|
|
}
|
|
if (reverseRelations[0] && (0, import_entity.is)(reverseRelations[0], One) && reverseRelations[0].config) {
|
|
return {
|
|
fields: reverseRelations[0].config.references,
|
|
references: reverseRelations[0].config.fields
|
|
};
|
|
}
|
|
throw new Error(
|
|
`There is not enough information to infer relation "${sourceTableTsName}.${relation.fieldName}"`
|
|
);
|
|
}
|
|
function createTableRelationsHelpers(sourceTable) {
|
|
return {
|
|
one: createOne(sourceTable),
|
|
many: createMany(sourceTable)
|
|
};
|
|
}
|
|
function mapRelationalRow(tablesConfig, tableConfig, row, buildQueryResultSelection, mapColumnValue = (value) => value) {
|
|
const result = {};
|
|
for (const [
|
|
selectionItemIndex,
|
|
selectionItem
|
|
] of buildQueryResultSelection.entries()) {
|
|
if (selectionItem.isJson) {
|
|
const relation = tableConfig.relations[selectionItem.tsKey];
|
|
const rawSubRows = row[selectionItemIndex];
|
|
const subRows = typeof rawSubRows === "string" ? JSON.parse(rawSubRows) : rawSubRows;
|
|
result[selectionItem.tsKey] = (0, import_entity.is)(relation, One) ? subRows && mapRelationalRow(
|
|
tablesConfig,
|
|
tablesConfig[selectionItem.relationTableTsKey],
|
|
subRows,
|
|
selectionItem.selection,
|
|
mapColumnValue
|
|
) : subRows.map(
|
|
(subRow) => mapRelationalRow(
|
|
tablesConfig,
|
|
tablesConfig[selectionItem.relationTableTsKey],
|
|
subRow,
|
|
selectionItem.selection,
|
|
mapColumnValue
|
|
)
|
|
);
|
|
} else {
|
|
const value = mapColumnValue(row[selectionItemIndex]);
|
|
const field = selectionItem.field;
|
|
let decoder;
|
|
if ((0, import_entity.is)(field, import_column.Column)) {
|
|
decoder = field;
|
|
} else if ((0, import_entity.is)(field, import_sql.SQL)) {
|
|
decoder = field.decoder;
|
|
} else {
|
|
decoder = field.sql.decoder;
|
|
}
|
|
result[selectionItem.tsKey] = value === null ? null : decoder.mapFromDriverValue(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
// Annotate the CommonJS export names for ESM import in node:
|
|
0 && (module.exports = {
|
|
Many,
|
|
One,
|
|
Relation,
|
|
Relations,
|
|
createMany,
|
|
createOne,
|
|
createTableRelationsHelpers,
|
|
extractTablesRelationalConfig,
|
|
getOperators,
|
|
getOrderByOperators,
|
|
mapRelationalRow,
|
|
normalizeRelation,
|
|
relations
|
|
});
|
|
//# sourceMappingURL=relations.cjs.map
|