UNPKG

shyft

Version:

Model driven GraphQL API framework

273 lines (272 loc) 14.1 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); }; 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;