UNPKG

drizzle-orm

Version:

Drizzle ORM package for SQL databases

328 lines • 11.4 kB
"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