flowjv
Version:
Flow based approach to JSON validation!
243 lines (242 loc) • 9.88 kB
JavaScript
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.combineDependencies = exports.getDependencies = exports.execJSONExpression = void 0;
var immutable_1 = require("../helper/immutable");
var execJSONExpression = function (logic, data) {
data.refPath = data.refPath || [];
if (typeof logic === "number" ||
typeof logic === "string" ||
typeof logic === "boolean") {
return logic;
}
if (typeof logic === "function") {
return logic({
data: data.data,
context: data.context,
ref: immutable_1.get(data.data, data.refPath),
});
}
if (!Array.isArray(logic) && typeof logic === "object") {
return logic.func({
data: data.data,
context: data.context,
ref: immutable_1.get(data.data, data.refPath),
});
}
switch (logic[0]) {
// Data Access Operation.
case "$ref": {
return immutable_1.get(data.data, data.refPath);
}
case "$context":
var _a = __read(logic, 3), _ = _a[0], key = _a[1], defaultValue = _a[2];
var refPath = key.split(".");
return immutable_1.get(data.context, refPath, defaultValue);
case "$data": {
var _b = __read(logic, 3), _1 = _b[0], key_1 = _b[1], defaultValue_1 = _b[2];
var refPath_1 = key_1.split(".");
return immutable_1.get(data.data, refPath_1, defaultValue_1);
}
case "!": {
var _c = __read(logic, 2), _2 = _c[0], arg = _c[1];
return !exports.execJSONExpression(arg, data);
}
// Logical operators
case "?:": {
var _d = __read(logic, 4), _3 = _d[0], cond = _d[1], case1 = _d[2], case2 = _d[3];
if (exports.execJSONExpression(cond, data)) {
return exports.execJSONExpression(case1, data);
}
return exports.execJSONExpression(case2, data);
}
case "enum": {
var _e = __read(logic), _4 = _e[0], val = _e[1], enums = _e.slice(2);
var value = exports.execJSONExpression(val, data);
var enumValues = new Set(enums.map(function (v) { return exports.execJSONExpression(v, data); }));
if (enumValues.has(value)) {
return true;
}
return false;
}
// ASSERT CHAIN OPS
case "===": {
var _f = __read(logic), _5 = _f[0], args = _f.slice(1);
return helper.assertChainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 === v2; });
}
case "!==": {
var _g = __read(logic), _6 = _g[0], args = _g.slice(1);
return helper.assertChainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 !== v2; });
}
case ">": {
var _h = __read(logic), _7 = _h[0], args = _h.slice(1);
return helper.assertChainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 > v2; });
}
case ">=": {
var _j = __read(logic), _8 = _j[0], args = _j.slice(1);
return helper.assertChainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 >= v2; });
}
case "<": {
var _k = __read(logic), _9 = _k[0], args = _k.slice(1);
return helper.assertChainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 < v2; });
}
case "<=": {
var _l = __read(logic), _10 = _l[0], args = _l.slice(1);
return helper.assertChainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 <= v2; });
}
// CHAIN OPS
case "||": {
var _m = __read(logic), _11 = _m[0], args = _m.slice(1);
return helper.chainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 || v2; });
}
case "&&": {
var _o = __read(logic), _12 = _o[0], args = _o.slice(1);
return helper.chainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 && v2; });
}
case "+": {
var _p = __read(logic), _13 = _p[0], args = _p.slice(1);
return helper.chainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 + v2; });
}
case "-": {
var _q = __read(logic), _14 = _q[0], args = _q.slice(1);
return helper.chainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 - v2; });
}
case "*": {
var _r = __read(logic), _15 = _r[0], args = _r.slice(1);
return helper.chainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 * v2; });
}
case "/": {
var _s = __read(logic), _16 = _s[0], args = _s.slice(1);
return helper.chainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 / v2; });
}
case "%": {
var _t = __read(logic), _17 = _t[0], args = _t.slice(1);
return helper.chainOp(helper.mapExpToValue(args, data), function (v1, v2) { return v1 % v2; });
}
case "str:fmt:email": {
var _u = __read(logic, 2), _18 = _u[0], arg = _u[1];
var regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var value = exports.execJSONExpression(arg, data);
if (typeof value === "string")
return regex.test(value);
else
return false;
}
case "str:len": {
var _v = __read(logic, 2), _19 = _v[0], arg = _v[1];
var value = exports.execJSONExpression(arg, data);
if (typeof value !== "string") {
return 0;
}
return value.length;
}
}
};
exports.execJSONExpression = execJSONExpression;
var helper = {
mapExpToValue: function (exps, data) {
return exps.map(function (exp) { return exports.execJSONExpression(exp, data); });
},
chainOp: function (values, operation) {
return values.reduce(function (agg, v, i) { return (i === 0 ? agg : operation(agg, v)); }, values[0]);
},
assertChainOp: function (values, operation) {
for (var i = 1; i < values.length; i++) {
if (!operation(values[i - 1], values[i])) {
return false;
}
}
return true;
},
};
function getDependencies(expr) {
var e_1, _a;
var _b, _c, _d, _e;
var dependsOn = [];
if (typeof expr === "number" ||
typeof expr === "string" ||
typeof expr === "boolean") {
return dependsOn;
}
if (typeof expr === "function") {
return null;
}
if (!Array.isArray(expr) && typeof expr === "object") {
return (_c = (_b = expr.deps) === null || _b === void 0 ? void 0 : _b.data) !== null && _c !== void 0 ? _c : [];
}
// Logic for dependencies goes here.
switch (expr[0]) {
case "$data": {
return [expr[1]];
}
}
var _f = __read(expr), _ = _f[0], args = _f.slice(1);
try {
for (var args_1 = __values(args), args_1_1 = args_1.next(); !args_1_1.done; args_1_1 = args_1.next()) {
var arg = args_1_1.value;
if (typeof arg === "number" ||
typeof arg === "string" ||
typeof arg === "boolean" ||
typeof arg === "undefined") {
continue;
}
if (typeof arg === "function") {
return null;
}
if (!Array.isArray(arg) && typeof arg === "object") {
((_d = arg.deps) === null || _d === void 0 ? void 0 : _d.data) && dependsOn.push.apply(dependsOn, __spreadArray([], __read((_e = arg.deps) === null || _e === void 0 ? void 0 : _e.data)));
continue;
}
var deps = getDependencies(arg);
if (deps === null) {
return null;
}
deps && dependsOn.push.apply(dependsOn, __spreadArray([], __read(deps)));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (args_1_1 && !args_1_1.done && (_a = args_1.return)) _a.call(args_1);
}
finally { if (e_1) throw e_1.error; }
}
return dependsOn;
}
exports.getDependencies = getDependencies;
// Combine Dependencies.
function combineDependencies(d1, d2) {
return d1 && d2 ? __spreadArray(__spreadArray([], __read(d1)), __read(d2)) : null;
}
exports.combineDependencies = combineDependencies;