shyft
Version:
Model driven GraphQL API framework
273 lines (272 loc) • 14.1 kB
JavaScript
"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);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isViewEntity = exports.ViewEntity = void 0;
var util_1 = require("../util");
var constants_1 = require("../constants");
var Permission_1 = require("../permission/Permission");
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 filter_1 = require("../filter");
var Entity_1 = require("./Entity");
var ViewEntity = /** @class */ (function () {
function ViewEntity(setup) {
util_1.passOrThrow(util_1.isMap(setup), function () { return 'ViewEntity requires a setup object'; });
var name = setup.name, description = setup.description, attributes = setup.attributes, storageType = setup.storageType, viewExpression = setup.viewExpression, permissions = setup.permissions, preProcessor = setup.preProcessor, postProcessor = setup.postProcessor, preFilters = setup.preFilters, meta = setup.meta;
Object.keys(setup).map(function (prop) {
util_1.passOrThrow(constants_1.viewEntityPropertiesWhitelist.includes(prop), function () { return "Invalid setup property '" + prop + "' in view entity '" + name + "'"; });
});
util_1.passOrThrow(name, function () { return 'Missing view entity name'; });
util_1.passOrThrow(description, function () { return "Missing description for view entity '" + name + "'"; });
util_1.passOrThrow(util_1.isMap(attributes) || util_1.isFunction(attributes), function () {
return "'attributes' for view entity '" + name + "' needs to be a map of attributes or a function returning a map of attributes";
});
util_1.passOrThrow(viewExpression, function () { return "Missing viewExpression for view entity '" + name + "'"; });
this.name = name;
this.description = description;
this._attributesMap = attributes;
this._primaryAttribute = null;
this.viewExpression = viewExpression;
this._permissions = permissions;
this._preFilters = preFilters;
this.meta = meta;
if (preProcessor) {
util_1.passOrThrow(util_1.isFunction(preProcessor), function () {
return "preProcessor of view entity '" + name + "' needs to be a valid function";
});
this.preProcessor = preProcessor;
}
if (postProcessor) {
util_1.passOrThrow(util_1.isFunction(postProcessor), function () {
return "postProcessor of view entity '" + name + "' needs to be a valid function";
});
this.postProcessor = postProcessor;
}
if (storageType) {
util_1.passOrThrow(StorageType_1.isStorageType(storageType), function () {
return "ViewEntity '" + name + "' needs a valid storage type (defaults to 'StorageTypeNull')";
});
}
else {
this.storageType = StorageTypeNull_1.StorageTypeNull;
this.isFallbackStorageType = true;
this._exposeStorageAccess();
}
}
ViewEntity.prototype._injectStorageTypeBySchema = function (storageType) {
var _this = this;
util_1.passOrThrow(StorageType_1.isStorageType(storageType), function () { return "Provided storage type to view entity '" + _this.name + "' is invalid"; });
if (this.isFallbackStorageType) {
this.storageType = storageType;
this._exposeStorageAccess();
}
};
ViewEntity.prototype._exposeStorageAccess = function () {
this.findOne = this.storageType.findOne;
this.find = this.storageType.find;
};
ViewEntity.prototype._injectDefaultPermissionsBySchema = function (defaultPermissions) {
util_1.passOrThrow(util_1.isMap(defaultPermissions), function () { return 'Provided defaultPermissions is invalid'; });
if (!this._permissions) {
this._permissions = {};
}
this._defaultPermissions = defaultPermissions;
};
ViewEntity.prototype.getAttributes = function () {
if (this._attributes) {
return this._attributes;
}
var ret = (this._attributes = this._processAttributeMap());
return ret;
};
ViewEntity.prototype._processAttribute = function (rawAttribute, attributeName) {
var _this = this;
util_1.passOrThrow(constants_1.attributeNameRegex.test(attributeName), function () {
return "Invalid attribute name '" + attributeName + "' in view entity '" + _this.name + "' (Regex: /" + constants_1.ATTRIBUTE_NAME_PATTERN + "/)";
});
Object.keys(rawAttribute).map(function (prop) {
util_1.passOrThrow(constants_1.viewAttributePropertiesWhitelist.includes(prop), function () {
return "Invalid attribute property '" + prop + "' in view 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 });
util_1.passOrThrow(attribute.description, function () { return "Missing description for '" + _this.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 ViewEntity, 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;
};
ViewEntity.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 view entity '" + _this.name + "' does not return a map";
});
var attributeNames = Object.keys(attributeMap);
util_1.passOrThrow(attributeNames.length > 0, function () { return "ViewEntity '" + _this.name + "' has no attributes defined"; });
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 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;
};
ViewEntity.prototype.getPrimaryAttribute = function () {
return this._primaryAttribute;
};
ViewEntity.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];
};
ViewEntity.prototype._processPermissions = function () {
if (this._permissions) {
var permissions = void 0;
if (typeof this._permissions === 'function') {
permissions = this._permissions();
}
else {
permissions = this._permissions;
}
return Permission_1.processViewEntityPermissions(this, permissions, this._defaultPermissions);
}
else if (this._defaultPermissions) {
return Permission_1.processViewEntityPermissions(this, {}, this._defaultPermissions);
}
return null;
};
ViewEntity.prototype._generatePermissionDescriptions = function () {
if (this.permissions) {
if (this.permissions.find) {
this.descriptionPermissionsFind = Permission_1.generatePermissionDescription(this.permissions.find);
}
if (this.permissions.read) {
this.descriptionPermissionsRead = Permission_1.generatePermissionDescription(this.permissions.read);
}
}
};
ViewEntity.prototype._processPreFilters = function (preFilters) {
return preFilters ? filter_1.processPreFilters(this, preFilters) : null;
};
ViewEntity.prototype.getPreFilters = function () {
if (this.preFilters) {
return this.preFilters;
}
if (typeof this._preFilters === 'function') {
this._preFilters = this._preFilters();
}
this.preFilters = this._processPreFilters(this._preFilters);
return this.preFilters;
};
ViewEntity.prototype.getPermissions = function () {
if (!this._permissions && this._defaultPermissions) {
return this.permissions;
}
this.permissions = this._processPermissions();
this._generatePermissionDescriptions();
return this.permissions;
};
ViewEntity.prototype.getStorageType = function () {
return this.storageType;
};
ViewEntity.prototype.toString = function () {
return this.name;
};
return ViewEntity;
}());
exports.ViewEntity = ViewEntity;
var isViewEntity = function (obj) {
return obj instanceof ViewEntity;
};
exports.isViewEntity = isViewEntity;