UNPKG

lambdaorm-base

Version:
472 lines 20 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SchemaExtender = void 0; const domain_1 = require("../../domain"); const typ3s_1 = require("typ3s"); class SchemaExtender { // eslint-disable-next-line no-useless-constructor constructor(exp, helper) { this.exp = exp; this.helper = helper; } extend(schema) { this.extendEnums(schema); this.extendEntities(schema); this.complete(schema); this.extendMappings(schema); this.extendDataSources(schema); this.extendDataStages(schema); // views if (schema.infrastructure && (!schema.infrastructure.views || !schema.infrastructure.views.length || schema.infrastructure.views.length === 0)) { schema.infrastructure.views = [{ name: 'default', entities: [] }]; } // exclude entities not used in mapping if (schema.infrastructure && schema.infrastructure.mappings) { for (let i = 0, length = schema.infrastructure.mappings.length; i < length; i++) { schema.infrastructure.mappings[i] = this.clearMapping2(schema, schema.infrastructure.mappings[i]); } } } extendEnums(schema) { if (schema.domain.enums === undefined) { schema.domain.enums = []; } if (Array.isArray(schema.domain.enums)) { for (const _enum of schema.domain.enums) { if (_enum && _enum.extends) { this.extendEnum(_enum, schema.domain.enums); } } schema.domain.enums = this.clearEnums(schema.domain.enums); } } extendEntities(schema) { if (schema.domain.entities === undefined) { schema.domain.entities = []; } for (const entity of schema.domain.entities) { this.entitySecureArrays(entity); } for (const entity of schema.domain.entities) { if (entity && entity.extends) { this.extendEntity(entity, schema.domain.entities); } } schema.domain.entities = this.clearEntities(schema.domain.entities); } entitySecureArrays(entity) { if (entity.uniqueKey === undefined) { entity.uniqueKey = []; } if (entity.primaryKey === undefined) { entity.primaryKey = []; } if (entity.required === undefined) { entity.required = []; } if (entity.indexes === undefined) { entity.indexes = []; } if (entity.properties === undefined) { entity.properties = []; } if (entity.relations === undefined) { entity.relations = []; } if (entity.dependents === undefined) { entity.dependents = []; } if (entity.constraints === undefined) { entity.constraints = []; } } extendMappings(schema) { if (!schema.infrastructure) { return; } if (!schema.infrastructure.mappings || !schema.infrastructure.mappings.length || schema.infrastructure.mappings.length === 0) { if (schema.infrastructure.sources && schema.infrastructure.sources.length === 1 && schema.infrastructure.sources[0].name) { if (!schema.infrastructure.sources[0].mapping) { schema.infrastructure.sources[0].mapping = schema.infrastructure.sources[0].name; } schema.infrastructure.mappings = [{ name: schema.infrastructure.sources[0].mapping, entities: [] }]; } else { schema.infrastructure.mappings = [{ name: 'default', entities: [] }]; } } else { // extend entities into mapping for (const mapping of schema.infrastructure.mappings) { if (mapping.entities === undefined) { mapping.entities = []; } for (const entity of mapping.entities) { this.extendEntityMapping(entity, mapping.entities); } } // extends mappings for (const mapping of schema.infrastructure.mappings) { this.extendMapping(mapping, schema.infrastructure.mappings); } } // extend mapping for model for (let i = 0, length = schema.infrastructure.mappings.length; i < length; i++) { schema.infrastructure.mappings[i].entities = this.helper.obj.extends(schema.infrastructure.mappings[i].entities, schema.domain.entities); schema.infrastructure.mappings[i] = this.clearMapping(schema.infrastructure.mappings[i]); const mapping = schema.infrastructure.mappings[i]; if (mapping && mapping.entities) { this.completeMapping(schema.infrastructure.mappings[i]); } } } extendDataSources(schema) { if (!schema.infrastructure || !schema.infrastructure.mappings) { return; } if (!schema.infrastructure.sources || !schema.infrastructure.sources.length || schema.infrastructure.sources.length === 0) { this.helper.logger.log('sources not defined'); schema.infrastructure.sources = [{ name: 'default', dialect: domain_1.DIALECT_DEFAULT, mapping: schema.infrastructure.mappings[0].name, connection: null }]; } for (const source of schema.infrastructure.sources) { if (source.mapping === undefined) { source.mapping = schema.infrastructure.mappings[0].name; } } } extendDataStages(schema) { if (!schema.infrastructure || !schema.infrastructure.mappings || !schema.infrastructure.sources) { return; } if (!schema.infrastructure.stages || !schema.infrastructure.stages.length || schema.infrastructure.stages.length === 0) { schema.infrastructure.stages = [{ name: 'default', sources: [{ name: schema.infrastructure.sources[0].name }] }]; } for (const stage of schema.infrastructure.stages) { if (stage.sources === undefined) { stage.sources = [{ name: schema.infrastructure.sources[0].name }]; } } } complete(schema) { if (schema) { if (schema.domain.enums) { this.completeEnums(schema.domain.enums); } if (schema.domain.entities) { if (schema.infrastructure && schema.infrastructure.views) { this.completeEntities(schema.domain.entities, schema.infrastructure.views); } if (schema.domain.entities && schema.domain.entities.length) { this.completeRelations(schema.domain.entities); this.completeDependents(schema.domain.entities); } } } } isCompound(parent, child) { const parentRoot = parent.split('.')[0]; const childRoot = child.split('.')[0]; return parentRoot === childRoot; } clearEnums(source) { const target = []; if (source && source.length) { for (const sourceEnum of source) { if (sourceEnum.abstract === true) continue; target.push(sourceEnum); } } return target; } clearEntities(source) { const target = []; if (source && source.length) { for (const sourceEntity of source) { if (sourceEntity.abstract === true) continue; target.push(sourceEntity); } } return target; } completeEnums(enums) { if (enums && enums.length) { for (const _enum of enums) { if (_enum.values === undefined || _enum.values === null) { _enum.values = []; } else { for (const value of _enum.values) { if (value.value === undefined) { value.value = value.name; } } } } } } completeEntities(entities, views) { if (entities && entities.length) { for (const entity of entities) { this.completeEntity(entity, views); } } } completeEntity(entity, views) { this.entitySecureArrays(entity); entity.composite = entity.name.includes('.'); this.completeEntityProperties(entity); this.completeEntityRelations(entity); if (entity.properties) { entity.hadReadExps = entity.properties.some(p => p.readExp !== undefined); entity.hadWriteExps = entity.properties.some(p => p.writeExp !== undefined); entity.hadReadValues = entity.properties.some(p => p.readValue !== undefined); entity.hadWriteValues = entity.properties.some(p => p.writeValue !== undefined); entity.hadDefaults = entity.properties.some(p => p.default !== undefined); entity.hadViewReadExp = views ? views.some(p => p.entities ? p.entities.some(q => q.name === entity.name && q.properties ? q.properties.some(r => r.readExp !== undefined) : false) : false) : false; } else { entity.hadReadExps = false; entity.hadWriteExps = false; entity.hadReadValues = false; entity.hadWriteValues = false; entity.hadDefaults = false; entity.hadViewReadExp = false; } } completeEntityProperties(entity) { if (entity.properties !== undefined) { for (const property of entity.properties) { if (property.autoIncrement) { property.required = false; } else if (property.required === undefined) { property.required = ((entity.required && entity.required.includes(property.name)) || (entity.primaryKey && entity.primaryKey.includes(property.name)) || (entity.uniqueKey && entity.uniqueKey.includes(property.name))); } if (property.type === undefined) property.type = typ3s_1.Primitive.string; if (property.type === typ3s_1.Primitive.string && property.length === undefined) property.length = this.helper.schema.DEFAULT_LENGTH; if (property.length !== undefined && isNaN(property.length)) { throw new domain_1.SchemaError(`Invalid length in ${entity.name}.${property.name}`); } } } } completeEntityRelations(entity) { if (entity.relations !== undefined) { for (const relation of entity.relations) { if (relation.type === undefined) relation.type = domain_1.RelationType.oneToMany; // All relations manyToOne are weak if (relation.type === domain_1.RelationType.manyToOne) relation.weak = true; if (relation.weak === undefined) relation.weak = false; } } } completeRelations(entities) { for (const source of entities) { if (source.relations) { for (const sourceRelation of source.relations) { if (sourceRelation.target && (sourceRelation.type === domain_1.RelationType.oneToMany || sourceRelation.type === domain_1.RelationType.oneToOne)) { this.completeRelation(source, sourceRelation, entities); } } } else { source.relations = []; } } } completeRelation(source, sourceRelation, entities) { const targetEntity = entities.find(p => p.name === sourceRelation.entity); if (targetEntity && targetEntity.relations) { const exists = targetEntity.relations.find(p => p.name === sourceRelation.target) !== undefined; if (!exists) { targetEntity.relations.push({ name: sourceRelation.target, type: sourceRelation.type === domain_1.RelationType.oneToOne ? domain_1.RelationType.oneToOne : domain_1.RelationType.manyToOne, composite: this.isCompound(targetEntity.name, source.name), from: sourceRelation.to, entity: source.name, weak: true, to: sourceRelation.from, target: sourceRelation.name }); } } } completeDependents(entities) { for (const entity of entities) { entity.dependents = []; for (const related of entities) { if (!related.relations) { continue; } for (const relation of related.relations) { if (relation.entity === entity.name && !relation.weak) { const dependent = { entity: related.name, relation }; entity.dependents.push(dependent); } } } } } extendEnum(_enum, enums) { const base = enums.find(p => p.name === _enum.extends); if (base === undefined) { throw new domain_1.SchemaError(`${_enum.extends} not found`); } if (base.extends) { this.extendEnum(base, enums); } // extend values if (base.values !== undefined && base.values.length > 0) { if (_enum.values === undefined || _enum.values === null) { _enum.values = []; } _enum.values = this.helper.obj.extends(_enum.values, base.values); } // elimina dado que ya fue extendido delete _enum.extends; } extendEntity(entity, entities) { const base = entities.find(p => p.name === entity.extends); if (base === undefined) { throw new domain_1.SchemaError(`${entity.extends} not found`); } if (base.extends) { this.extendEntity(base, entities); } if (entity.primaryKey === undefined && base.primaryKey !== undefined) entity.primaryKey = base.primaryKey; // extend properties if (base.properties !== undefined && base.properties.length > 0) { if (entity.properties === undefined) { entity.properties = []; } entity.properties = this.helper.obj.extends(entity.properties, base.properties); } // extend relations if (base.relations && base.relations.length > 0) { entity.relations = this.helper.obj.extends(entity.relations, base.relations); } // elimina dado que ya fue extendido delete entity.extends; } extendMapping(mapping, mappings) { if (mapping && mapping.extends) { const base = mappings.find(p => p.name === mapping.extends); if (base === undefined) { throw new domain_1.SchemaError(`${mapping.extends} not found`); } this.extendMapping(base, mappings); mapping.entities = this.helper.obj.extends(mapping.entities, base.entities); // elimina dado que ya fue extendido delete mapping.extends; } } extendEntityMapping(entity, entities) { if (entity && entity.extends) { const base = entities.find(p => p.name === entity.extends); if (base === undefined) { throw new domain_1.SchemaError(`${entity.extends} not found`); } this.extendEntityMapping(base, entities); if (entity.uniqueKey === undefined && base.uniqueKey !== undefined) { entity.uniqueKey = base.uniqueKey; } if (entity.mapping === undefined && base.mapping !== undefined) { entity.mapping = base.mapping; } this.extendEntityMappingIndexes(entity, base); this.extendEntityMappingProperties(entity, base); // delete since it was already extended delete entity.extends; } } extendEntityMappingIndexes(entity, base) { if (base.indexes !== undefined && base.indexes.length > 0) { if (entity.indexes === undefined) { entity.indexes = []; } entity.indexes = this.helper.obj.extends(entity.indexes, base.indexes); } } extendEntityMappingProperties(entity, base) { if (base.properties !== undefined && base.properties.length > 0) { if (entity.properties === undefined) { entity.properties = []; } entity.properties = this.helper.obj.extends(entity.properties, base.properties); } } completeMapping(mapping) { if (mapping.entities === undefined) { return; } for (const entity of mapping.entities) { if (this.helper.val.isEmpty(entity.mapping)) { entity.mapping = entity.name; } if (entity.properties === undefined || entity.properties.length === 0) { entity.hadKeys = false; continue; } for (const property of entity.properties) { if (this.helper.val.isEmpty(property.mapping)) { property.mapping = property.name; } } entity.hadKeys = entity.properties.some(p => p.key !== undefined); } } clearMapping(source) { const target = { name: source.name, mapping: source.mapping, entities: [] }; if (source && source.entities) { for (const sourceEntity of source.entities) { if (sourceEntity.abstract === true) continue; if (target.entities === undefined) target.entities = []; target.entities.push(sourceEntity); } } return target; } clearMapping2(schema, source) { const target = { name: source.name, mapping: source.mapping, entities: [] }; if (source && source.entities) { for (const sourceEntity of source.entities) { if (!this.existsInMapping(schema, source.name, sourceEntity.name)) continue; if (target.entities === undefined) target.entities = []; target.entities.push(sourceEntity); } } return target; } existsInMapping(schema, mapping, entity) { if (!schema.infrastructure || !schema.infrastructure.sources || !schema.infrastructure.stages) { return false; } // const context = { entity, action: ObservableAction.ddl, read: false, write: true, dml: false, ddl: true } const info = { entity, action: domain_1.SentenceAction.undefined, category: domain_1.SentenceCategory.undefined, type: domain_1.SentenceType.dml }; const dataSourcesNames = schema.infrastructure.sources.filter(p => p.mapping === mapping).map(p => p.name); for (const stage of schema.infrastructure.stages) { const ruleDataSources = stage.sources.filter(p => dataSourcesNames.includes(p.name)); for (const ruleDataSource of ruleDataSources) { if (ruleDataSource.condition === undefined || this.exp.eval(ruleDataSource.condition, info)) { return true; } } } return false; } } exports.SchemaExtender = SchemaExtender; //# sourceMappingURL=schemaExtender.js.map