UNPKG

shyft

Version:

Model driven GraphQL API framework

217 lines (216 loc) 11.5 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.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;