shyft
Version:
Model driven GraphQL API framework
217 lines (216 loc) • 11.5 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);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isShadowEntity = exports.ShadowEntity = void 0;
var util_1 = require("../util");
var constants_1 = require("../constants");
var DataType_1 = require("../datatype/DataType");
var StorageType_1 = require("../storage/StorageType");
var StorageTypeNull_1 = require("../storage/StorageTypeNull");
var ComplexDataType_1 = require("../datatype/ComplexDataType");
var Entity_1 = require("./Entity");
var systemAttributes_1 = require("./systemAttributes");
var ShadowEntity = /** @class */ (function () {
function ShadowEntity(setup) {
util_1.passOrThrow(util_1.isMap(setup), function () { return 'ShadowEntity requires a setup object'; });
var name = setup.name, attributes = setup.attributes, storageType = setup.storageType, isUserEntity = setup.isUserEntity, meta = setup.meta;
Object.keys(setup).map(function (prop) {
util_1.passOrThrow(constants_1.shadowEntityPropertiesWhitelist.includes(prop), function () { return "Invalid setup property '" + prop + "' in shadow entity '" + name + "'"; });
});
util_1.passOrThrow(name, function () { return 'Missing shadow entity name'; });
if (attributes) {
util_1.passOrThrow(util_1.isMap(attributes) || util_1.isFunction(attributes), function () {
return "'attributes' for shadow entity '" + name + "' needs to be a map of attributes or a function returning a map of attributes";
});
}
this.name = name;
this.isUserEntity = !!isUserEntity;
this._attributesMap = attributes || (function () { return ({}); });
this._primaryAttribute = null;
this.referencedByEntities = [];
this.meta = meta;
if (storageType) {
util_1.passOrThrow(StorageType_1.isStorageType(storageType), function () {
return "ShadowEntity '" + name + "' needs a valid storage type (defaults to 'StorageTypeNull')";
});
}
else {
this.storageType = StorageTypeNull_1.StorageTypeNull;
this.isFallbackStorageType = true;
}
}
ShadowEntity.prototype._injectStorageTypeBySchema = function (storageType) {
var _this = this;
util_1.passOrThrow(StorageType_1.isStorageType(storageType), function () { return "Provided storage type to shadow entity '" + _this.name + "' is invalid"; });
if (this.isFallbackStorageType) {
this.storageType = storageType;
}
};
ShadowEntity.prototype.getAttributes = function () {
if (this._attributes) {
return this._attributes;
}
var ret = (this._attributes = this._processAttributeMap());
return ret;
};
ShadowEntity.prototype._checkSystemAttributeNameCollision = function (attributeMap, attributeName) {
var _this = this;
util_1.passOrThrow(!attributeMap[attributeName], function () {
return "Attribute name collision with system attribute '" + attributeName + "' in entity '" + _this.name + "'";
});
};
ShadowEntity.prototype._processAttribute = function (rawAttribute, attributeName) {
var _this = this;
util_1.passOrThrow(constants_1.attributeNameRegex.test(attributeName), function () {
return "Invalid attribute name '" + attributeName + "' in shadow entity '" + _this.name + "' (Regex: /" + constants_1.ATTRIBUTE_NAME_PATTERN + "/)";
});
Object.keys(rawAttribute).map(function (prop) {
util_1.passOrThrow(constants_1.shadowEntityAttributePropertiesWhitelist.includes(prop), function () {
return "Invalid attribute property '" + prop + "' in shadow entity '" + _this.name + "' (use 'meta' for custom data)";
});
});
var attribute = __assign(__assign({}, rawAttribute), { primary: !!rawAttribute.primary, required: !!rawAttribute.required || !!rawAttribute.primary, hidden: !!rawAttribute.hidden, name: attributeName });
if (util_1.isFunction(attribute.type)) {
var dataTypeBuilder = attribute.type;
attribute.type = dataTypeBuilder({
setup: attribute,
entity: this,
});
}
util_1.passOrThrow(DataType_1.isDataType(attribute.type) ||
attribute.type instanceof Entity_1.Entity ||
ComplexDataType_1.isComplexDataType(attribute.type), function () {
return "'" + _this.name + "." + attributeName + "' has invalid data type '" + String(attribute.type) + "'";
});
if (DataType_1.isDataType(attribute.type)) {
var attributeType = attribute.type;
if (attributeType.enforceRequired) {
attribute.required = true;
}
}
if (attribute.targetAttributesMap) {
util_1.passOrThrow(attribute.type instanceof ShadowEntity, function () {
return "'" + _this.name + "." + attributeName + "' cannot have a targetAttributesMap as it is not a reference";
});
util_1.passOrThrow(util_1.isMap(attribute.targetAttributesMap), function () {
return "targetAttributesMap for '" + _this.name + "." + attributeName + "' needs to be a map";
});
var localAttributeNames = Object.keys(attribute.targetAttributesMap);
localAttributeNames.map(function (localAttributeName) {
var targetAttribute = attribute.targetAttributesMap[localAttributeName];
util_1.passOrThrow(util_1.isMap(targetAttribute) &&
targetAttribute.name &&
targetAttribute.type, function () {
return "targetAttributesMap for '" + _this.name + "." + attributeName + "' needs to be a map between local and target attributes";
});
// check if attribute is found in target entity
attribute.type.referenceAttribute(targetAttribute.name);
});
}
if (attribute.primary) {
util_1.passOrThrow(!this._primaryAttribute, function () {
return "'" + _this.name + "." + attributeName + "' cannot be set as primary attribute," +
("'" + _this._primaryAttribute.name + "' is already the primary attribute");
});
util_1.passOrThrow(DataType_1.isDataType(attribute.type), function () {
return "Primary attribute '" + _this.name + "." + attributeName + "' has invalid data type '" + String(attribute.type) + "'";
});
attribute.isSystemAttribute = true;
this._primaryAttribute = attribute;
}
util_1.passOrThrow(!attribute.resolve || util_1.isFunction(attribute.resolve), function () { return "'" + _this.name + "." + attributeName + "' has an invalid resolve function'"; });
util_1.passOrThrow(!attribute.validate || util_1.isFunction(attribute.validate), function () { return "'" + _this.name + "." + attributeName + "' has an invalid validate function'"; });
util_1.passOrThrow(!attribute.serialize || util_1.isFunction(attribute.serialize), function () {
return "'" + _this.name + "." + attributeName + "' has an invalid serialize function'";
});
return attribute;
};
ShadowEntity.prototype._collectSystemAttributes = function (attributeMap) {
var list = [];
if (!this.getPrimaryAttribute()) {
var name = systemAttributes_1.systemAttributePrimary.name;
this._checkSystemAttributeNameCollision(attributeMap, name);
attributeMap[name] = systemAttributes_1.systemAttributePrimary;
list.push(name);
}
return list;
};
ShadowEntity.prototype._processAttributeMap = function () {
var _this = this;
// if it's a function, resolve it to get that map
var attributeMap = typeof this._attributesMap === 'object'
? __assign({}, this._attributesMap) : this._attributesMap();
util_1.passOrThrow(util_1.isMap(attributeMap), function () {
return "Attribute definition function for shadow entity '" + _this.name + "' does not return a map";
});
var attributeNames = Object.keys(attributeMap);
var resultAttributes = {};
attributeNames.forEach(function (attributeName) {
resultAttributes[attributeName] = _this._processAttribute(attributeMap[attributeName], attributeName);
});
attributeNames.forEach(function (attributeName) {
var attribute = resultAttributes[attributeName];
if (attribute.targetAttributesMap) {
var localAttributeNames = Object.keys(attribute.targetAttributesMap);
localAttributeNames.map(function (localAttributeName) {
util_1.passOrThrow(resultAttributes[localAttributeName], function () {
return "Unknown local attribute '" + localAttributeName + "' used in targetAttributesMap " +
("for '" + _this.name + "." + attributeName + "'");
});
});
}
});
var systemAttributeNames = this._collectSystemAttributes(attributeMap);
systemAttributeNames.forEach(function (attributeName) {
resultAttributes[attributeName] = _this._processAttribute(attributeMap[attributeName], attributeName);
resultAttributes[attributeName].isSystemAttribute = true;
});
var rankedResultAttributes = {};
Object.keys(resultAttributes).map(function (attributeName) {
var attribute = resultAttributes[attributeName];
if (attribute.primary) {
rankedResultAttributes[attributeName] = attribute;
}
});
Object.keys(resultAttributes).map(function (attributeName) {
var attribute = resultAttributes[attributeName];
if (!attribute.primary) {
rankedResultAttributes[attributeName] = attribute;
}
});
return rankedResultAttributes;
};
ShadowEntity.prototype.getPrimaryAttribute = function () {
return this._primaryAttribute;
};
ShadowEntity.prototype.referenceAttribute = function (attributeName) {
var _this = this;
var attributes = this.getAttributes();
util_1.passOrThrow(attributes[attributeName], function () {
return "Cannot reference attribute '" + _this.name + "." + attributeName + "' as it does not exist";
});
return attributes[attributeName];
};
ShadowEntity.prototype.getStorageType = function () {
return this.storageType;
};
ShadowEntity.prototype.toString = function () {
return this.name;
};
return ShadowEntity;
}());
exports.ShadowEntity = ShadowEntity;
var isShadowEntity = function (obj) {
return obj instanceof ShadowEntity;
};
exports.isShadowEntity = isShadowEntity;