UNPKG

@terabits/grapi

Version:

Grapi Schema Generator For GraphQL Server

226 lines (225 loc) 11.7 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; exports.__esModule = true; exports.createRelation = void 0; var constants_1 = require("../../constants"); var lodash_1 = require("../../lodash"); var relationField_1 = __importDefault(require("../relationField")); var types_1 = require("./types"); var createDefaultRelationName = function (relationConfig) { var sourceName = relationConfig.source.getNamings().capitalSingular; var targetName = relationConfig.target.getNamings().capitalSingular; return "".concat(sourceName, "And").concat(targetName, "On").concat(relationConfig.sourceField); }; var toRelation; (function (toRelation) { toRelation["one"] = "1"; toRelation["many"] = "*"; })(toRelation || (toRelation = {})); var configModelRelation = function (sourceModel, targetModel, sourceFieldName, targetFieldName, relationType, metadata, name) { return { name: name, metadata: metadata, type: relationType, source: sourceModel, target: targetModel, sourceField: sourceFieldName, targetField: targetFieldName }; }; var configRelation = function (sourceSide, targetSide, metadata, name, relationType) { return configModelRelation(sourceSide.sourceModel, sourceSide.targetModel, sourceSide.fieldName, targetSide.fieldName, relationType, metadata, name); }; var configRelationField = function (relationField, relationType, relationShip) { relationField.setRelationType(relationType); relationField.setRelation(relationShip); }; var configRelationFields = function (sourceField, targetField, relationSource, relationTarget, relationType) { configRelationField(sourceField, relationType, relationSource); configRelationField(targetField, relationType, relationTarget); }; var createRelation = function (models) { var findModel = function (name) { return models.find(function (model) { return model.getName() === name; }); }; var modelRelations = []; var relationTable = {}; var relationsWithName = {}; models.forEach(function (model) { relationTable[model.getName()] = {}; (0, lodash_1.forEach)(model.getFields(), function (field, fieldName) { if (!(field instanceof relationField_1["default"])) { return; } var relationToModel = field.getRelationTo(); var relationToModelName = relationToModel.getName(); var relationField = { type: field.isList() ? toRelation.many : toRelation.one, fieldName: fieldName, field: field, sourceModel: model, targetModel: relationToModel }; var 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 }; var isCircular = (0, lodash_1.get)(field.getRelationConfig(), 'isCircular') || (0, lodash_1.get)(field.getMetadata('relation'), 'isCircular'); if (isCircular === 'true') relationsWithName[relationName].targetSide = relationField; } else if (relationsWithName[relationName]) { relationsWithName[relationName].targetSide = relationField; } return; } var targetRelation = relationTable[model.getName()][relationToModelName]; if (!targetRelation) { relationTable[model.getName()][relationToModelName] = []; } relationTable[model.getName()][relationToModelName].push(relationField); }); }); (0, lodash_1.forEach)(relationsWithName, function (_a, name) { var sourceSide = _a.sourceSide, targetSide = _a.targetSide; var relation; var sourceField = sourceSide.field; var 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); var metadata = sourceField.getMetadata(constants_1.RELATION_DIRECTIVE_NAME); relation = { name: 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(), function (value) { if (value instanceof Object) { return value.key; } return value; }) : metadata }; modelRelations.push(relation); return; } var relationConfig = sourceField.getRelationConfig(); var 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 ".concat(sourceSide.type, " to ").concat(targetSide.type)); } configRelationFields(sourceField, targetField, relationFields.relation, relationFields.relation, relationFields.type); modelRelations.push(relation); }); (0, lodash_1.forEach)(relationTable, function (toRelationMap, fromModelName) { (0, lodash_1.forEach)(toRelationMap, function (fields, toModelName) { var otherSideFields = (0, lodash_1.get)(relationTable, [toModelName, fromModelName]); fields.forEach(function (_a) { var type = _a.type, field = _a.field, fieldName = _a.fieldName, built = _a.built; if (built) { return; } var relationConfig; var fromModel = findModel(fromModelName); var 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) }; var uniRelationName = createDefaultRelationName(relationConfig); field.setRelationName(uniRelationName); modelRelations.push(__assign({ name: uniRelationName }, relationConfig)); return; } var 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 ".concat(type, " to ").concat(otherSide.type)); } otherSide.built = true; var relationName = createDefaultRelationName(relationConfig); field.setRelationName(relationName); otherSide.field.setRelationName(relationName); modelRelations.push(__assign({ name: relationName }, relationConfig)); }); }); }); return modelRelations; }; exports.createRelation = createRelation;