UNPKG

@cheetah.js/orm

Version:
142 lines (141 loc) 5.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ModelTransformer = void 0; const value_object_1 = require("../common/value-object"); const utils_1 = require("../utils"); class ModelTransformer { constructor(entityStorage) { this.entityStorage = entityStorage; } transform(model, statement, data) { const instanceMap = this.createInstances(model, statement); const optionsMap = this.buildOptionsMap(instanceMap); this.populateProperties(data, instanceMap, optionsMap); this.linkJoinedEntities(statement, instanceMap, optionsMap); this.resetChangedValues(instanceMap); return instanceMap[statement.alias]; } createInstances(model, statement) { const instance = this.createInstance(model); const instanceMap = { [statement.alias]: instance, }; if (statement.join) { this.addJoinedInstances(statement, instanceMap); } return instanceMap; } createInstance(model) { const instance = new model(); instance.$_isPersisted = true; return instance; } addJoinedInstances(statement, instanceMap) { statement.join.forEach(join => { const joinInstance = this.createInstance(join.joinEntity); instanceMap[join.joinAlias] = joinInstance; }); } buildOptionsMap(instanceMap) { const optionsMap = new Map(); for (const [alias, instance] of Object.entries(instanceMap)) { const options = this.entityStorage.get(instance.constructor); if (options) { optionsMap.set(alias, options); } } return optionsMap; } populateProperties(data, instanceMap, optionsMap) { Object.entries(data).forEach(([key, value]) => { const { alias, propertyName } = this.parseColumnKey(key); const entity = instanceMap[alias]; if (!entity) { return; } this.setPropertyValue(entity, propertyName, value, optionsMap.get(alias)); }); } parseColumnKey(key) { const index = key.indexOf('_'); return { alias: key.substring(0, index), propertyName: key.substring(index + 1), }; } setPropertyValue(entity, columnName, value, options) { const propertyInfo = this.findPropertyByColumnName(columnName, options); if (!propertyInfo) { return; } const { key, property } = propertyInfo; if (this.isValueObjectType(property.type)) { entity[key] = new property.type(value); return; } entity[key] = value; } findPropertyByColumnName(columnName, options) { // First, try to find in regular properties const entry = Object.entries(options.properties).find(([_, prop]) => prop.options.columnName === columnName); if (entry) { return { key: entry[0], property: entry[1] }; } // If not found, try to find in relations (many-to-one) const relation = options.relations?.find((rel) => rel.columnName === columnName && rel.relation === 'many-to-one'); if (relation) { return { key: relation.propertyKey, property: relation }; } return null; } isValueObjectType(type) { return (0, utils_1.extendsFrom)(value_object_1.ValueObject, type?.prototype); } linkJoinedEntities(statement, instanceMap, optionsMap) { if (!statement.join) { return; } statement.join.forEach(join => { this.linkSingleJoin(join, instanceMap, optionsMap); }); } linkSingleJoin(join, instanceMap, optionsMap) { const { joinAlias, originAlias, propertyKey } = join; const originEntity = instanceMap[originAlias]; const joinEntity = instanceMap[joinAlias]; if (!originEntity || !joinEntity) { return; } const property = this.findRelationProperty(originAlias, propertyKey, optionsMap); if (property) { this.attachJoinedEntity(originEntity, joinEntity, propertyKey, property); } } findRelationProperty(alias, propertyKey, optionsMap) { return optionsMap.get(alias)?.relations.find(rel => rel.propertyKey === propertyKey); } attachJoinedEntity(originEntity, joinEntity, propertyKey, property) { if (property.type === Array) { originEntity[propertyKey] = this.appendToArray(originEntity[propertyKey], joinEntity); } else { originEntity[propertyKey] = joinEntity; } } appendToArray(existingArray, newItem) { return existingArray ? [...existingArray, newItem] : [newItem]; } resetChangedValues(instanceMap) { Object.values(instanceMap).forEach(instance => { const currentValues = {}; for (const key in instance) { if (!key.startsWith('_') && !key.startsWith('$')) { currentValues[key] = instance[key]; } } instance._oldValues = currentValues; instance._changedValues = {}; }); } } exports.ModelTransformer = ModelTransformer;