UNPKG

@fusions/core

Version:

262 lines (261 loc) 10.8 kB
"use strict"; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var ModelError_1 = __importDefault(require("./Errors/ModelError")); var Model = /** @class */ (function () { function Model(props) { this.name = props.name.toLowerCase(); this.scopes = props.scopes; this.models = props.models; this.endpoints = props.endpoints; this.hooksToSet = []; var _a = this.parseStruct(props.struct), struct = _a.struct, externHooks = _a.externHooks, internHooks = _a.internHooks; this.struct = struct; this.resolvePointer = this.resolvePointer.bind(this); this.getHooks = this.getHooks.bind(this); } Model.prototype.getHooks = function (field, toSetAt, toSetAtField, fn) { var _this = this; if (fn === null) { //default on fields return [ { toSetAt: [toSetAt, toSetAtField], matchOn: [toSetAtField, field], from: [toSetAt, toSetAtField], to: [this.name, field] } ]; } else if (fn.startsWith("on")) { //on function is set var param = fn.slice(fn.indexOf("(") + 1, fn.indexOf(")")).split("="); var toSetAtMatch_1 = "", toMatchAt_1 = ""; //set matching like params in on function param.forEach(function (f) { if (f.startsWith("&")) { toSetAtMatch_1 = f.split(".")[1]; } else { toMatchAt_1 = f; } }); return [ { toSetAt: [toSetAt, toSetAtField], matchOn: [toSetAtMatch_1, toMatchAt_1], from: [toSetAt, toSetAtField], to: [this.name, field] }, { toSetAt: [this.name, toMatchAt_1], matchOn: [toSetAtMatch_1, toMatchAt_1], from: [toSetAt, toSetAtField], to: [this.name, field] } ]; } else if (fn.startsWith("count")) { return [ { toSetAt: [toSetAt, toSetAtField], matchOn: [toSetAtField, field], from: [toSetAt, toSetAtField], to: [this.name, field], function: ["count"] } ]; } else if (fn.startsWith("ref")) { var refName_1 = "$ref_" + this.name + "_" + toSetAt; //reference function is set var conditionHook_1 = { toSetAt: [this.name, field], matchOn: ["id", "id"], from: [this.name, field], to: [refName_1, "type"], external: [] }; var params = fn.slice(fn.indexOf("(") + 1, fn.indexOf(")")).split(","); //loop through reference fields and create hooks var paramHooks = params.map(function (param) { if (param.startsWith("&")) { //extern hook var _a = param.split("=>"), path = _a[0], alias = _a[1]; var _b = path.slice(1).split("."), at = _b[0], atField = _b[1]; if (typeof conditionHook_1.external !== "undefined") conditionHook_1.external.push({ from: [at.toLowerCase(), atField], as: alias }); //extern hooks always match via id => type and have alias names return { toSetAt: [at.toLowerCase(), atField], matchOn: ["id", "type"], from: [at.toLowerCase(), atField], to: [refName_1, alias] }; } else { //hook for this model matches on id => id return { toSetAt: [_this.name, param], matchOn: ["id", "id"], from: [_this.name, param], to: [refName_1, param] }; } }); return __spreadArrays([conditionHook_1], paramHooks); } throw new ModelError_1.default("Unknown pointer function " + fn); }; Model.prototype.setHooks = function (hooksToSet) { var _this = this; hooksToSet.forEach(function (hookToSet) { var _a = hookToSet.toSetAt, model = _a[0], field = _a[1]; var matchOn = hookToSet.matchOn, from = hookToSet.from, to = hookToSet.to, external = hookToSet.external; //define source field if (model === to[0]) { _this.struct[to[1]].sourceField = field; } _this.struct[field].hooks.push({ from: from, to: to, matchOn: matchOn, external: external, function: hookToSet.function }); }); this.hooksToSet = []; }; Model.prototype.isPointer = function (toCheck) { var index = toCheck.indexOf("&"); //& operator may be on index 1 because of array pointer [&Model.field] return index === 0 || index === 1; }; Model.prototype.resolvePointer = function (pointer, field) { //check if pointer is in array var isArray = pointer.startsWith("["); if (isArray) { pointer = pointer.substr(1, pointer.length - 2); } //parse pointer var _a = pointer.split(":"), toSetAtPath = _a[0], fn = _a[1]; var _b = toSetAtPath.slice(1).split("."), toSetAt = _b[0], toSetAtField = _b[1]; //parse hooks var hooks = this.getHooks(field, toSetAt.toLowerCase(), toSetAtField, fn || null); var targetModel = this.models.find(function (model) { return model.name.toLowerCase() === toSetAt.toLowerCase(); }); //check if target exists if (!targetModel || !targetModel.struct[toSetAtField]) { throw new ModelError_1.default("Pointer " + pointer + " is pointing to nowhere."); } var functionsForcingType = { count: "int" }; var type = ""; //function applyed forces a var fnName = fn ? fn.substring(0, fn.indexOf("(")) : null; if (fnName && functionsForcingType[fnName]) { type = functionsForcingType[fnName]; } //get target type else { var value = targetModel.struct[toSetAtField]; if (typeof value === "string") { type = value.split(" ")[0]; } if (typeof value === "object") { type = value.type; } if (isArray) { type = "[" + type + "]"; } } return { type: type, hooks: hooks }; }; Model.prototype.parseStruct = function (struct) { var _this = this; //parses simple string defintions var parseField = function (definition, field) { var settings = definition.split(" "); var type = settings[0], pointer = null; //if field is pointer get target type for validation if (_this.isPointer(type)) { var resolved = _this.resolvePointer(type, field); type = resolved.type; //refactor when time because u dont neet all models to be inited to set hooks _this.hooksToSet = __spreadArrays(_this.hooksToSet, resolved.hooks); } //default field definition var toSet = { key: false, primary: false, required: false, immutable: false, options: {}, hooks: [], type: type, pointer: pointer, struct: null }; settings.splice(1).forEach(function (setting) { switch (setting) { case "key": toSet.key = true; break; case "primary": toSet.primary = true; break; case "required": toSet.required = true; break; case "immutable": toSet.immutable = true; break; default: var def = setting.split("="); toSet.options[def[0]] = def[1]; } }); return toSet; }; //parsing struct and sub objects => recursive functions var parseObject = function (subStruct) { var toReturn = {}; Object.keys(subStruct).forEach(function (field) { var definition = subStruct[field]; //if object ist a string parse it with simple field parser if (typeof definition === "string") toReturn[field] = parseField(definition, field); else { //else check if its type is a string or a nested object. if object parse recursive with this function toReturn[field] = { key: Boolean(definition.key), primary: Boolean(definition.primary), required: Boolean(definition.required), immutable: Boolean(definition.immutable), type: definition.type, options: {}, hooks: [], pointer: null, struct: definition.type === "object" ? parseObject(definition.struct) : null }; } }); return toReturn; }; return { struct: parseObject(struct), internHooks: {}, externHooks: {} }; }; return Model; }()); exports.default = Model;