UNPKG

@allgemein/expressions

Version:
288 lines (280 loc) 10.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Expressions = void 0; const base_1 = require("@allgemein/base"); const InDesc_1 = require("../descriptors/InDesc"); const NeqDesc_1 = require("../descriptors/NeqDesc"); const LtDesc_1 = require("../descriptors/LtDesc"); const GtDesc_1 = require("../descriptors/GtDesc"); const AndDesc_1 = require("../descriptors/AndDesc"); const EqDesc_1 = require("../descriptors/EqDesc"); const GeDesc_1 = require("../descriptors/GeDesc"); const KeyDesc_1 = require("../descriptors/KeyDesc"); const LeDesc_1 = require("../descriptors/LeDesc"); const OrDesc_1 = require("../descriptors/OrDesc"); const ValueDesc_1 = require("../descriptors/ValueDesc"); const GroupDesc_1 = require("../descriptors/GroupDesc"); const ExpressionInterpreter_1 = require("./ExpressionInterpreter"); const LikeDesc_1 = require("../descriptors/LikeDesc"); const lodash_1 = require("lodash"); const REGEX_ID = /^(([\w_]+)=((\d+)|(\d+(\.|\,)\d+)|\'([^\']*)\'),?)$/; const REGEX_ID_G = /^(([\w_]+)=((\d+)|(\d+(\.|\,)\d+)|\'([^\']*)\'),?)$ /g; const REGEX_ID_K = /^((\d+)|(\d+(\.|\,)\d+),?)+$/; const REGEX_ID_KG = /^((\d+)|(\d+(\.|\,)\d+),?)+$/g; const REGEX_ID_W = /^(\'([^\']*)\',?)+$/; class Expressions { static parse(str) { if ((0, lodash_1.isString)(str)) { // check if JSON string try { let obj = JSON.parse(str.trim()); return this.fromJson(obj); } catch (e) { try { let interpreter = new ExpressionInterpreter_1.ExpressionInterpreter(); return interpreter.interprete(str); } catch (e) { throw e; } } } else if ((0, lodash_1.isPlainObject)(str)) { return this.fromJson(str); } else { throw new base_1.NotSupportedError('object cant be interpreted to conditions, wrong format'); } } //static validate(entityDef:EntityDef, condition:CondDesc) /* static fromJson(object: any): CondDesc { let cond: CondDesc; let q: any = []; Helper.walk(object, (data: WalkValues) => { console.log(data) let op: CondDesc = null; if (/^(\$and|\$or)$/.test(data.key) && isArray(data.value)) { console.log(data.key); if (data.key == '$and') { op = And() } else if (data.key == '$or') { op = Or() } (<any>data).cond = op; } else if (data.key.startsWith('$') && !isPlainObject(data.value)) { if (data.key == '$eq') { let value = null; if (isPlainObject(data.value)) { if (has(data.value, '$key')) { value = Key(data.value.key); } else { // ??? throw new NotSupportedError('object given but without known operator') } } else { value = data.value; } } } else if (!data.key.startsWith('$')) { if (isPlainObject(data.value)) { } else { // eq k = v op = Eq(Key(data.key), Value(data.value)); } } if (!cond) { cond = op; } }); return cond; } */ static exprKeys() { return Object.keys(this.EXPR_REGISTRY); } static fromJson(object, srcKey = null, parent = null) { if ((0, lodash_1.isArray)(object)) { if (!parent || !(parent instanceof GroupDesc_1.GroupDesc)) { parent = (0, OrDesc_1.Or)(); } for (let obj of object) { let sub = this.fromJson(obj, null, parent); if (!(sub instanceof GroupDesc_1.GroupDesc)) { parent.values.push(sub); } } return parent; } else if ((0, lodash_1.isPlainObject)(object)) { let keys = Object.keys(object); let operator = keys.filter(k => k.startsWith('$')); if (keys.length == 1 && operator.length == 1) { let op = operator.shift(); if (op == '$or' || op == '$and') { if ((0, lodash_1.isArray)(object[op])) { let desc = op == '$or' ? (0, OrDesc_1.Or)() : (0, AndDesc_1.And)(); if (parent instanceof GroupDesc_1.GroupDesc) { parent.values.push(desc); } return this.fromJson(object[op], null, desc); } else { throw new base_1.NotSupportedError('or|and must have an array as value ' + JSON.stringify(object, null, 2)); } } else if (this.exprKeys().indexOf(op) > -1) { let key = (0, KeyDesc_1.Key)(srcKey); let value = null; if ((0, lodash_1.isArray)(object[op])) { value = (0, ValueDesc_1.Value)(object[op]); } else if ((0, lodash_1.isPlainObject)(object[op])) { if ((0, lodash_1.has)(object[op], '$key')) { value = (0, KeyDesc_1.Key)(object[op].$key); } else { // ??? throw new base_1.NotSupportedError('object given but without known operator'); } } else { value = (0, ValueDesc_1.Value)(object[op]); } // @ts-ignore return this.EXPR_REGISTRY[op](key, value); } else { throw new base_1.NotSupportedError('operator ' + op + ' not supported'); } } else if (operator.length == 0) { let desc = []; for (let k of keys) { desc.push(this.fromJson(object[k], k, null)); } if (desc.length == 1) { return desc.shift(); } else { return (0, AndDesc_1.And)(...desc); } } else { throw new base_1.NotSupportedError('object has wrong keys ' + JSON.stringify(object, null, 2)); } } else { if (srcKey) { return (0, EqDesc_1.Eq)((0, KeyDesc_1.Key)(srcKey), object); } throw new base_1.NotSupportedError('object cant be resolved ' + JSON.stringify(object, null, 2)); } } static parseLookupConditions(ref, id) { let idProps = ref.getPropertyRefs().filter(p => p.isIdentifier()); if (/^\(.*(\)\s*,\s*\()?.*\)$/.test(id)) { let ids = id.replace(/^\(|\)$/g, '').split(/\)\s*,\s*\(/); return ids.map((_id) => this.parseLookupConditions(ref, _id)); } else if (REGEX_ID.test(id)) { let cond = {}; let e; let keys = {}; while ((e = REGEX_ID_G.exec(id)) !== null) { keys[e[2]] = e[4] || e[5] || e[7]; } for (let idp of idProps) { if (keys[idp.name]) { cond[idp.name] = idp.convert(keys[idp.name]); } } return cond; } else if (/^\d+(,\d+)+$/.test(id)) { let ids = id.split(','); return ids.map((_id) => this.parseLookupConditions(ref, (0, lodash_1.isString)(_id) ? parseInt(_id, 0) : _id)); } else if (REGEX_ID_K.test(id)) { if (/^\'.*\'$/.test(id)) { id = id.replace(/^\'|\'$/g, ''); } const conds = []; let cond = {}; let e; let c = 0; while ((e = REGEX_ID_KG.exec(id)) !== null) { let p = idProps[c]; let v = e[2] || e[3]; c += 1; cond[p.name] = p.convert(v); if (c >= idProps.length) { conds.push((0, lodash_1.clone)(cond)); cond = {}; c = 0; } } return conds.length === 1 ? conds.shift() : conds; } else { if (idProps.length == 1) { const prop = (0, lodash_1.first)(idProps); const ids = id.split(',').map((x) => x.trim()); const conds = []; for (const _id of ids) { const cond = {}; cond[prop.name] = prop.convert(_id); conds.push(cond); } return conds.length === 1 ? conds.shift() : conds; } else { } } throw new base_1.NotYetImplementedError('for ' + id); } static buildLookupConditions(ref, data) { let idProps = ref.getPropertyRefs().filter(p => p.isIdentifier()); if ((0, lodash_1.isArray)(data)) { let collect = []; data.forEach(d => { collect.push(this._buildLookupconditions(idProps, d)); }); if (idProps.length > 1) { return `(${collect.join('),(')})`; } else { return `${collect.join(',')}`; } } else { return this._buildLookupconditions(idProps, data); } } static _buildLookupconditions(idProps, data) { let idPk = []; idProps.forEach(id => { let v = id.get(data); if ((0, lodash_1.isString)(v)) { idPk.push('\'' + v + '\''); } else { idPk.push(v); } }); return idPk.join(','); } } exports.Expressions = Expressions; Expressions.EXPR_REGISTRY = { '$eq': (k, v) => (0, EqDesc_1.Eq)(k, v), '$ne': (k, v) => (0, NeqDesc_1.Neq)(k, v), '$le': (k, v) => (0, LeDesc_1.Le)(k, v), '$lt': (k, v) => (0, LtDesc_1.Lt)(k, v), '$ge': (k, v) => (0, GeDesc_1.Ge)(k, v), '$gt': (k, v) => (0, GtDesc_1.Gt)(k, v), '$like': (k, v) => (0, LikeDesc_1.Like)(k, v), '$in': (k, v) => (0, InDesc_1.In)(k, v) }; //# sourceMappingURL=Expressions.js.map