shyft
Version:
Model driven GraphQL API framework
253 lines (252 loc) • 13.5 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.isSchema = exports.Schema = void 0;
var util_1 = require("../util");
var Entity_1 = require("../entity/Entity");
var Action_1 = require("../action/Action");
var DataTypeUser_1 = require("../datatype/DataTypeUser");
var StorageType_1 = require("../storage/StorageType");
var Permission_1 = require("../permission/Permission");
var ViewEntity_1 = require("../entity/ViewEntity");
var ShadowEntity_1 = require("../entity/ShadowEntity");
var Schema = /** @class */ (function () {
function Schema(setup) {
var _this = this;
if (setup === void 0) { setup = {
entities: null,
defaultStorageType: null,
actions: null,
defaultActionPermissions: null,
permissionsMap: null,
}; }
this._entityMap = {};
this._actionMap = {};
this._userEntity = null;
this._entityMap = {};
this._actionMap = {};
this._isValidated = false;
this._userEntity = null;
var entities = setup.entities, defaultStorageType = setup.defaultStorageType, actions = setup.actions, permissionsMap = setup.permissionsMap, defaultActionPermissions = setup.defaultActionPermissions;
if (defaultStorageType) {
util_1.passOrThrow(StorageType_1.isStorageType(defaultStorageType), function () { return 'Provided default storage type is invalid'; });
}
this.defaultStorageType = defaultStorageType;
if (permissionsMap) {
util_1.passOrThrow(util_1.isMap(permissionsMap), function () { return 'Provided permissionsMap is invalid'; });
var permissionsMapKeys = Object.keys(permissionsMap);
permissionsMapKeys.map(function (key) {
util_1.passOrThrow(['entities', 'actions'].includes(key), function () {
return 'Unknown property used in permissionsMap (allowed: entities, actions)';
});
});
if (permissionsMap.entities) {
util_1.passOrThrow(util_1.isMap(permissionsMap.entities), function () { return 'Provided permissionsMap.entities is invalid'; });
var entityNames = Object.keys(permissionsMap.entities);
entityNames.map(function (entityName) {
var entityPermissions = permissionsMap.entities[entityName];
if (entityPermissions) {
util_1.passOrThrow(util_1.isMap(entityPermissions), function () { return "Provided permissionsMap for '" + entityName + "' is invalid"; });
if (entityPermissions.read) {
util_1.passOrThrow(Permission_1.isPermission(entityPermissions.read) ||
Permission_1.isPermissionsArray(entityPermissions.read), function () {
return "Invalid 'read' permission definition in permissionsMap for '" + entityName + "'";
});
}
if (entityPermissions.find) {
util_1.passOrThrow(Permission_1.isPermission(entityPermissions.find) ||
Permission_1.isPermissionsArray(entityPermissions.find), function () {
return "Invalid 'find' permission definition in permissionsMap for '" + entityName + "'";
});
}
if (entityPermissions.mutations) {
util_1.passOrThrow(util_1.isMap(entityPermissions.mutations), function () {
return "Definition of mutations in permissionsMap for '" + entityName + "' needs to be a map of mutations and permissions";
});
var mutationNames = Object.keys(entityPermissions.mutations);
mutationNames.map(function (mutationName) {
util_1.passOrThrow(Permission_1.isPermission(entityPermissions.mutations[mutationName]) ||
Permission_1.isPermissionsArray(entityPermissions.mutations[mutationName]), function () {
return "Invalid mutation permission definition in permissionsMap for '" + entityName + "." + mutationName + "'";
});
});
}
}
});
}
this.permissionsMap = permissionsMap;
}
if (defaultActionPermissions) {
util_1.passOrThrow(Permission_1.isPermission(defaultActionPermissions) ||
Permission_1.isPermissionsArray(defaultActionPermissions), function () { return 'Invalid permission definition for defaultActionPermissions'; });
this.defaultActionPermissions = defaultActionPermissions;
}
if (entities) {
util_1.passOrThrow(util_1.isArray(entities, true), function () { return "Schema needs 'entities' to be an array of type Entity"; });
entities.map(function (entity) { return _this.addEntity(entity); });
}
if (actions) {
util_1.passOrThrow(util_1.isArray(actions), function () { return "Schema needs 'actions' to be an array of type Action"; });
actions.map(function (action) { return _this.addAction(action); });
}
}
Schema.prototype.addEntity = function (entity) {
var _this = this;
util_1.passOrThrow(Entity_1.isEntity(entity) || ViewEntity_1.isViewEntity(entity) || ShadowEntity_1.isShadowEntity(entity), function () {
return 'Provided object to schema is not an entity or view entity or shadow entity';
});
util_1.passOrThrow(!this._entityMap[entity.name], function () { return "Entity '" + entity.name + "' already registered with this schema"; });
if (entity.isUserEntity) {
util_1.passOrThrow(!this._userEntity, function () {
return "Entity '" + entity.name + "' cannot be set as user entity, " +
("'" + _this._userEntity.name + "' is already the user entity");
});
this._userEntity = entity;
}
if (this.defaultStorageType) {
entity._injectStorageTypeBySchema(this.defaultStorageType);
}
if (this.permissionsMap && this.permissionsMap.entities) {
var entityDefaultPermissions = this.permissionsMap.entities[entity.name] || {};
entityDefaultPermissions.mutations =
entityDefaultPermissions.mutations || {};
entityDefaultPermissions.subscriptions =
entityDefaultPermissions.subscriptions || {};
var defaultPermissions = this.permissionsMap.entities._defaultPermissions;
defaultPermissions.mutations = defaultPermissions.mutations || {};
defaultPermissions.subscriptions = defaultPermissions.subscriptions || {};
var newDefaultPermissions = {
read: entityDefaultPermissions.read || defaultPermissions.read,
find: entityDefaultPermissions.find || defaultPermissions.find,
mutations: __assign(__assign({}, defaultPermissions.mutations), entityDefaultPermissions.mutations),
subscriptions: __assign(__assign({}, defaultPermissions.subscriptions), entityDefaultPermissions.subscriptions),
};
if (Entity_1.isEntity(entity) || ViewEntity_1.isViewEntity(entity)) {
entity._injectDefaultPermissionsBySchema(newDefaultPermissions);
}
}
entity._isRegistered = true;
this._entityMap[entity.name] = entity;
this._isValidated = false;
};
Schema.prototype.getUserEntity = function (throwIfMissing) {
util_1.passOrThrow(!throwIfMissing || this._userEntity, function () { return 'There is no user entity registered yet'; });
return this._userEntity;
};
Schema.prototype._lazyLoadMissingEntities = function () {
var _this = this;
var foundMissingCount = 0;
var entityNames = Object.keys(this._entityMap);
entityNames.forEach(function (entityName) {
var entity = _this._entityMap[entityName];
var attributes = entity.getAttributes();
var attributeNames = Object.keys(attributes);
attributeNames.forEach(function (attributeName) {
var attribute = attributes[attributeName];
if (Entity_1.isEntity(attribute.type)) {
// const attributeTypeAsEntity = attribute.type as Entity
var targetEntity_1 = attribute.type;
if (_this._entityMap[targetEntity_1.name]) {
util_1.passOrThrow(targetEntity_1._isRegistered, function () {
return "Referenced entity '" + targetEntity_1.name + "' already registered with this schema";
});
}
else {
_this.addEntity(targetEntity_1);
foundMissingCount++;
}
}
});
});
if (foundMissingCount > 0) {
this._lazyLoadMissingEntities();
}
};
Schema.prototype.validate = function () {
var _this = this;
if (this._isValidated) {
return;
}
util_1.passOrThrow(util_1.isMap(this._entityMap, true), function () { return 'Schema has no entities'; });
this._lazyLoadMissingEntities();
var entityNames = Object.keys(this._entityMap);
if (this.permissionsMap && this.permissionsMap.entities) {
var permissionsMapEntityNames = Object.keys(this.permissionsMap.entities);
permissionsMapEntityNames.map(function (permissionsMapEntityName) {
util_1.passOrThrow(entityNames.includes(permissionsMapEntityName) ||
permissionsMapEntityName === '_defaultPermissions', function () {
return "permissionsMap includes permissions for unknown entity " + permissionsMapEntityName;
});
});
}
entityNames.forEach(function (entityName) {
var entity = _this._entityMap[entityName];
var attributes = entity.getAttributes();
var attributeNames = Object.keys(attributes);
// trigger validation and generation of permissions and indexes
if (Entity_1.isEntity(entity) || ViewEntity_1.isViewEntity(entity)) {
entity.getPermissions();
}
if (Entity_1.isEntity(entity)) {
var entityAsEntity = entity;
entityAsEntity.getIndexes();
}
attributeNames.forEach(function (attributeName) {
var attribute = attributes[attributeName];
if (Entity_1.isEntity(attribute.type)) {
var targetEntity_2 = attribute.type;
util_1.passOrThrow(_this._entityMap[targetEntity_2.name], function () {
return "Entity '" + targetEntity_2.name + "' (referenced by '" + entity.name + "') " +
'needs to be registered with this schema';
});
// keep track of references
targetEntity_2.referencedBy(entity.name, attributeName);
}
else if (DataTypeUser_1.isDataTypeUser(attribute.type)) {
// replace with actual user entity
attribute.type = _this.getUserEntity(true);
}
});
});
var actionNames = Object.keys(this._actionMap);
actionNames.forEach(function (actionName) {
var action = _this._actionMap[actionName];
// trigger validation and generation of permissions
action.getPermissions();
});
this._isValidated = true;
};
Schema.prototype.getEntities = function () {
this.validate();
return this._entityMap;
};
Schema.prototype.addAction = function (action) {
util_1.passOrThrow(Action_1.isAction(action), function () { return 'Provided object to schema is not an action'; });
util_1.passOrThrow(!this._actionMap[action.name], function () { return "Action '" + action.name + "' already registered with this schema"; });
if (this.defaultActionPermissions) {
action._injectDefaultPermissionsBySchema(this.defaultActionPermissions);
}
this._actionMap[action.name] = action;
this._isValidated = false;
};
Schema.prototype.getActions = function () {
this.validate();
return this._actionMap;
};
return Schema;
}());
exports.Schema = Schema;
var isSchema = function (obj) {
return obj instanceof Schema;
};
exports.isSchema = isSchema;