UNPKG

@grapi/server

Version:

Grapi Schema Generator For GraphQL Server

215 lines (214 loc) 10.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createRelation = void 0; const constants_1 = require("../../constants"); const lodash_1 = require("../../lodash"); const relationField_1 = __importDefault(require("../relationField")); const types_1 = require("./types"); const createDefaultRelationName = (relationConfig) => { const sourceName = relationConfig.source.getNamings().capitalSingular; const targetName = relationConfig.target.getNamings().capitalSingular; return `${sourceName}And${targetName}On${relationConfig.sourceField}`; }; var toRelation; (function (toRelation) { toRelation["one"] = "1"; toRelation["many"] = "*"; })(toRelation || (toRelation = {})); const configModelRelation = (sourceModel, targetModel, sourceFieldName, targetFieldName, relationType, metadata, name) => { return { name, metadata, type: relationType, source: sourceModel, target: targetModel, sourceField: sourceFieldName, targetField: targetFieldName }; }; const configRelation = (sourceSide, targetSide, metadata, name, relationType) => { return configModelRelation(sourceSide.sourceModel, sourceSide.targetModel, sourceSide.fieldName, targetSide.fieldName, relationType, metadata, name); }; const configRelationField = (relationField, relationType, relationShip) => { relationField.setRelationType(relationType); relationField.setRelation(relationShip); }; const configRelationFields = (sourceField, targetField, relationSource, relationTarget, relationType) => { configRelationField(sourceField, relationType, relationSource); configRelationField(targetField, relationType, relationTarget); }; const createRelation = (models) => { const findModel = (name) => models.find(model => model.getName() === name); const modelRelations = []; const relationTable = {}; const relationsWithName = {}; models.forEach(model => { relationTable[model.getName()] = {}; (0, lodash_1.forEach)(model.getFields(), (field, fieldName) => { if (!(field instanceof relationField_1.default)) { return; } const relationToModel = field.getRelationTo(); const relationToModelName = relationToModel.getName(); const relationField = { type: field.isList() ? toRelation.many : toRelation.one, fieldName, field, sourceModel: model, targetModel: relationToModel, }; const relationName = (0, lodash_1.get)(field.getRelationConfig(), 'name') || (0, lodash_1.get)(field.getMetadata('relation'), 'name'); if (relationName) { field.setRelationName(relationName); if (!relationsWithName[relationName]) { relationsWithName[relationName] = { sourceSide: relationField }; } else if (relationsWithName[relationName]) { relationsWithName[relationName].targetSide = relationField; } return; } const targetRelation = relationTable[model.getName()][relationToModelName]; if (!targetRelation) { relationTable[model.getName()][relationToModelName] = []; } relationTable[model.getName()][relationToModelName].push(relationField); }); }); (0, lodash_1.forEach)(relationsWithName, ({ sourceSide, targetSide }, name) => { let relation; const sourceField = sourceSide.field; const targetField = (0, lodash_1.get)(targetSide, `field`); if (!targetSide) { configRelationField(sourceField, (sourceSide.type === toRelation.one) ? types_1.RelationType.uniOneToOne : types_1.RelationType.uniOneToMany, (sourceSide.type === toRelation.one) ? types_1.RelationShip.OneToOne : types_1.RelationShip.OneToMany); const metadata = sourceField.getMetadata(constants_1.RELATION_DIRECTIVE_NAME); relation = { name, type: sourceField.getRelationType(), source: sourceSide.sourceModel, target: sourceSide.targetModel, sourceField: sourceSide.fieldName, metadata: (0, lodash_1.get)(metadata, constants_1.RELATION_WITH) ? (0, lodash_1.mapValues)(sourceField.getRelationConfig(), (value) => { if (value instanceof Object) { return value.key; } return value; }) : metadata }; modelRelations.push(relation); return; } const relationConfig = sourceField.getRelationConfig(); const relationFields = {}; if (sourceSide.type === toRelation.one && targetSide.type === toRelation.one) { relationFields.relation = types_1.RelationShip.OneToOne; relationFields.type = types_1.RelationType.biOneToOne; relation = configRelation(sourceSide, targetSide, relationConfig, name, types_1.RelationType.biOneToOne); } else if (sourceSide.type === toRelation.one && targetSide.type === toRelation.many) { relationFields.relation = types_1.RelationShip.OneToMany; relationFields.type = types_1.RelationType.biOneToMany; relation = configModelRelation(sourceSide.targetModel, targetSide.targetModel, targetSide.fieldName, sourceSide.fieldName, types_1.RelationType.biOneToMany, relationConfig, name); } else if (sourceSide.type === toRelation.many && targetSide.type === toRelation.one) { relationFields.relation = types_1.RelationShip.OneToMany; relationFields.type = types_1.RelationType.biOneToMany; relation = configModelRelation(sourceSide.sourceModel, targetSide.sourceModel, sourceSide.fieldName, targetSide.fieldName, types_1.RelationType.biOneToMany, relationConfig, name); } else if (sourceSide.type === toRelation.many && targetSide.type === toRelation.many) { relationFields.relation = types_1.RelationShip.ManyToMany; relationFields.type = types_1.RelationType.biManyToMany; relation = configRelation(sourceSide, targetSide, relationConfig, name, types_1.RelationType.biManyToMany); } else { throw new Error(`unknown relation type from ${sourceSide.type} to ${targetSide.type}`); } configRelationFields(sourceField, targetField, relationFields.relation, relationFields.relation, relationFields.type); modelRelations.push(relation); }); (0, lodash_1.forEach)(relationTable, (toRelationMap, fromModelName) => { (0, lodash_1.forEach)(toRelationMap, (fields, toModelName) => { const otherSideFields = (0, lodash_1.get)(relationTable, [toModelName, fromModelName]); fields.forEach(({ type, field, fieldName, built }) => { if (built) { return; } let relationConfig; const fromModel = findModel(fromModelName); const toModel = findModel(toModelName); if (!otherSideFields || (0, lodash_1.size)(otherSideFields) > 1) { relationConfig = { type: (type === toRelation.one) ? types_1.RelationType.uniOneToOne : types_1.RelationType.uniOneToMany, source: fromModel, target: toModel, sourceField: fieldName, metadata: field.getMetadata(constants_1.RELATION_DIRECTIVE_NAME), }; const uniRelationName = createDefaultRelationName(relationConfig); field.setRelationName(uniRelationName); modelRelations.push({ name: uniRelationName, ...relationConfig, }); return; } const otherSide = otherSideFields[0]; if (type === toRelation.one && otherSide.type === toRelation.one) { relationConfig = { type: types_1.RelationType.biOneToOne, source: fromModel, target: toModel, sourceField: fieldName, targetField: otherSide.fieldName, metadata: field.getRelationConfig(), }; } else if (type === toRelation.one && otherSide.type === toRelation.many) { relationConfig = { type: types_1.RelationType.biOneToMany, source: toModel, target: fromModel, sourceField: otherSide.fieldName, targetField: fieldName, metadata: field.getRelationConfig(), }; } else if (type === toRelation.many && otherSide.type === toRelation.one) { relationConfig = { type: types_1.RelationType.biOneToMany, source: fromModel, target: toModel, sourceField: fieldName, targetField: otherSide.fieldName, metadata: field.getRelationConfig(), }; } else if (type === toRelation.many && otherSide.type === toRelation.many) { relationConfig = { type: types_1.RelationType.biManyToMany, source: fromModel, target: toModel, sourceField: fieldName, targetField: otherSide.fieldName, metadata: field.getRelationConfig(), }; } else { throw new Error(`unknown relation type from ${type} to ${otherSide.type}`); } otherSide.built = true; const relationName = createDefaultRelationName(relationConfig); field.setRelationName(relationName); otherSide.field.setRelationName(relationName); modelRelations.push({ name: relationName, ...relationConfig, }); }); }); }); return modelRelations; }; exports.createRelation = createRelation;