@terabits/grapi
Version:
Grapi Schema Generator For GraphQL Server
226 lines (225 loc) • 11.7 kB
JavaScript
;
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;