Socket
Socket
Sign inDemoInstall

@jsonlang/core

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jsonlang/core - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

dist/core/decorators.d.ts

5

dist/app/app.d.ts
import { RuleCore } from '../core';
export declare class JsonLang extends RuleCore {
private mathRules;
private logicalRules;
private objectRules;
private arrayRules;
constructor();
private registerBuiltinRules;
}
//# sourceMappingURL=app.d.ts.map

38

dist/app/app.js

@@ -17,27 +17,2 @@ "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 __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
exports.__esModule = true;

@@ -51,14 +26,3 @@ exports.JsonLang = void 0;

var _this = _super.call(this) || this;
_this.registerBuiltinRules = function () {
var mathRules = _this.mathRules.getRules();
var logicalRules = _this.logicalRules.getRules();
var objectRules = _this.objectRules.getRules();
var arrayRules = _this.arrayRules.getRules();
_this.registerMany(new Map(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(mathRules), false), __read(logicalRules), false), __read(objectRules), false), __read(arrayRules), false)));
};
_this.mathRules = new rule_1.MathRules();
_this.logicalRules = new rule_1.LogicalRules();
_this.objectRules = new rule_1.ObjectRules();
_this.arrayRules = new rule_1.ArrayRules();
_this.registerBuiltinRules();
_this["import"](rule_1.DataRules);
return _this;

@@ -65,0 +29,0 @@ }

@@ -1,20 +0,21 @@

import { IJsonLangParams, IRulesCore, RuleHandler, RuleIdentifier, RuleResult, Rules } from './core.types';
export declare class RuleCore implements IRulesCore {
import { IJsonLangParams, RuleHandler, RuleResult, Rules, RuleDefinition, JsonLangOptions, SyncJsonLangOptions, AsyncJsonLangOptions } from './core.types';
export declare class RuleCore {
private rules;
private ruleIds;
constructor();
private rulesDefinitions;
private sync;
constructor(options?: JsonLangOptions);
/**
* @param {IJsonLangParams} jsonLang
* @param {Object} data.
* @returns {RuleResult}
* @description is the `Sync` version of jsonLang, use it to run all builtin rules and any extended `Sync` Rules
* @returns {Promise<RuleResult> | RuleResult}
* @description use it to run all rules and any extended `Sync/Async` Rules
*/
execute(rules: IJsonLangParams, data?: {}): RuleResult;
execute(rules: IJsonLangParams, data?: {}, options?: AsyncJsonLangOptions): Promise<RuleResult>;
execute(rules: IJsonLangParams, data?: {}, options?: SyncJsonLangOptions): RuleResult;
/**
* @param {IJsonLangParams} jsonLang
* @param {Object} data.
* @returns {Promise<RuleResult>}
* @description is the `Async` version of jsonLang, use it to run all builtin rules and any extended `Sync/Async` Rules
* @param {Class[]} RuleClasses - Array of Classes which contain methods/rules.
* @returns {void}
* @description to extend JsonLang by importing a class with @JsonLangExtension decorator, and register its methods by @RuleExtension decorator
*/
executeAsync(rules: IJsonLangParams, data?: {}): Promise<RuleResult>;
import: (...ruleClasses: any[]) => void;
/**

@@ -25,3 +26,3 @@ * @param {Rules} rules - Map of Rules.

*/
registerMany: (rules: Rules, group?: string) => void;
registerMany: (rules: Rules) => void;
/**

@@ -33,21 +34,19 @@ * @param {RuleIdentifier} ruleIdentifier

*/
registerOne: (ruleIdentifier: RuleIdentifier, ruleHandler: RuleHandler) => void;
registerOne: (definition: Omit<RuleDefinition, 'sync'>, ruleHandler: RuleHandler) => void;
/**
* @returns {RuleIdentifier[]}
* @description Get rules identifiers
* @param {string[]} rules - Optional Array of Rules' names or shortcuts to get their definitions.
* @returns {RuleDefinition[]}
* @description Get rules definitions, if no rules names passed, it will return all rules definitions
*/
getRulesIds: () => RuleIdentifier[];
getRulesDefinitions: (rules?: string[]) => RuleDefinition[];
private setRuleWithDefinition;
private createRunContext;
private createAsyncRunContext;
private createSyncRunContext;
private resolveRuleInputs;
private resolveRuleAsyncInputs;
private getAllInputs;
private resolveSyncRuleInputs;
private getInputsWithActions;
private getRuleParams;
private getHandlerInnerRules;
private getHandlerArgs;
private isRule;
private setOutputValue;
private getOutputValue;
private getDate;
}
//# sourceMappingURL=core.d.ts.map
"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);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

@@ -28,3 +17,3 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }

if (f) throw new TypeError("Generator is already executing.");
while (_) try {
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;

@@ -78,6 +67,40 @@ if (y = 0, t) op = [op[0] & 2, t.value];

var core_types_1 = require("./core.types");
var rule_parser_1 = require("./rule-parser");
var RuleCore = /** @class */ (function () {
function RuleCore() {
function RuleCore(options) {
var _this = this;
/**
* @param {Class[]} RuleClasses - Array of Classes which contain methods/rules.
* @returns {void}
* @description to extend JsonLang by importing a class with @JsonLangExtension decorator, and register its methods by @RuleExtension decorator
*/
this["import"] = function () {
var ruleClasses = [];
for (var _i = 0; _i < arguments.length; _i++) {
ruleClasses[_i] = arguments[_i];
}
__spreadArray([], __read(ruleClasses), false).forEach(function (RuleClass) {
console.log('RuleClass', RuleClass);
if (!RuleClass.prototype)
return;
var ruleClass = new RuleClass();
console.log('ruleClass', ruleClass);
var propertyNames = Object.getOwnPropertyNames(RuleClass.prototype);
propertyNames.forEach(function (propertyName) {
var _a;
console.log('propertyName', propertyName);
var group = ((_a = Reflect.getMetadata('jsonlang:group', RuleClass)) === null || _a === void 0 ? void 0 : _a.name) || 'Others';
var ruleDefinition = Reflect.getMetadata('jsonlang:rule', RuleClass, propertyName);
console.log('ruleDefinition', ruleDefinition);
if (ruleDefinition) {
var handler = ruleClass[propertyName].bind(ruleClass);
console.log('handler', handler);
ruleDefinition.identifier.group = ruleDefinition.identifier.group || group;
var ruleHandler = ruleDefinition.sync ? { sync: handler } : { async: handler };
_this.setRuleWithDefinition(ruleDefinition, ruleHandler);
}
});
});
};
/**
* @param {Rules} rules - Map of Rules.

@@ -87,4 +110,4 @@ * @returns {void}

*/
this.registerMany = function (rules, group) {
rules.forEach(function (value, key) { return _this.registerOne(__assign({ group: group }, key), value); });
this.registerMany = function (rules) {
rules.forEach(function (value, key) { return _this.registerOne(key, value); });
};

@@ -97,183 +120,191 @@ /**

*/
this.registerOne = function (ruleIdentifier, ruleHandler) {
_this.rules.set(ruleIdentifier.name, ruleHandler);
_this.ruleIds.add(ruleIdentifier);
if (ruleIdentifier.shortcut)
_this.rules.set(ruleIdentifier.shortcut, ruleHandler);
this.registerOne = function (definition, ruleHandler) {
var handler = ruleHandler.sync || ruleHandler.async;
var ruleDefinition = rule_parser_1.RuleDefinitionParser.parse(handler, [], definition);
_this.setRuleWithDefinition(ruleDefinition, ruleHandler);
};
/**
* @returns {RuleIdentifier[]}
* @description Get rules identifiers
* @param {string[]} rules - Optional Array of Rules' names or shortcuts to get their definitions.
* @returns {RuleDefinition[]}
* @description Get rules definitions, if no rules names passed, it will return all rules definitions
*/
this.getRulesIds = function () { return __spreadArray([], __read(_this.ruleIds), false); };
this.createRunContext = function (outputs, data) {
var run = function (scopedData) {
var localData = scopedData;
var innerRun = function (jsonLang) {
if (!_this.isRule(jsonLang))
return jsonLang;
var _a = _this.getRuleParams(jsonLang), ruleHandler = _a.ruleHandler, rule = _a.rule, _b = _a.inputs, inputs = _b === void 0 ? [] : _b, output = _a.output;
var resolvedInputs = _this.resolveRuleInputs(inputs, ruleHandler, innerRun, run);
resolvedInputs = _this.getAllInputs(rule, resolvedInputs, outputs, data, localData);
var result = ruleHandler.apply(void 0, __spreadArray([], __read(resolvedInputs), false));
this.getRulesDefinitions = function (rules) {
var definitions = new Map();
_this.rulesDefinitions.forEach(function (definition, rule) {
var id = definition.identifier.name + definition.identifier.shortcut || '';
if (rules) {
if (rules.includes(rule))
definitions.set(id, definition);
}
else {
definitions.set(id, definition);
}
});
return __spreadArray([], __read(definitions.values()), false);
};
this.createRunContext = function (localDataStore, data) {
var runner = function (jsonLang, localData) { return __awaiter(_this, void 0, void 0, function () {
var _a, ruleHandler, rule, _b, inputs, output, resolvedInputs, handler, result, error_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (localData === null || localData === void 0 ? void 0 : localData.key)
localDataStore.set(localData.key, localData === null || localData === void 0 ? void 0 : localData.value);
if (!this.isRule(jsonLang))
return [2 /*return*/, jsonLang];
_a = this.getRuleParams(jsonLang), ruleHandler = _a.ruleHandler, rule = _a.rule, _b = _a.inputs, inputs = _b === void 0 ? [] : _b, output = _a.output;
_c.label = 1;
case 1:
_c.trys.push([1, 4, , 5]);
return [4 /*yield*/, this.resolveRuleInputs(rule, inputs, runner, data, localDataStore)];
case 2:
resolvedInputs = _c.sent();
handler = ruleHandler.async || ruleHandler.sync;
return [4 /*yield*/, handler.apply(void 0, __spreadArray([], __read(resolvedInputs), false))];
case 3:
result = _c.sent();
if (output)
localDataStore.set(output, result);
return [2 /*return*/, result];
case 4:
error_1 = _c.sent();
throw Error("Failed to Run \"".concat(rule, "\" cause of ").concat(error_1));
case 5: return [2 /*return*/];
}
});
}); };
return runner;
};
this.createSyncRunContext = function (localDataStore, data) {
var runner = function (jsonLang, localData) {
if (localData === null || localData === void 0 ? void 0 : localData.key)
localDataStore.set(localData.key, localData === null || localData === void 0 ? void 0 : localData.value);
if (!_this.isRule(jsonLang))
return jsonLang;
var _a = _this.getRuleParams(jsonLang), ruleHandler = _a.ruleHandler, rule = _a.rule, _b = _a.inputs, inputs = _b === void 0 ? [] : _b, output = _a.output;
try {
var resolvedInputs = _this.resolveSyncRuleInputs(rule, inputs, runner, data, localDataStore);
var handler = ruleHandler.sync;
var result = handler.apply(void 0, __spreadArray([], __read(resolvedInputs), false));
if (output)
_this.setOutputValue(output, result, outputs);
localDataStore.set(output, result);
return result;
};
return innerRun;
}
catch (error) {
throw Error("Failed to Run \"".concat(rule, "\" cause of ").concat(error));
}
};
return run;
return runner;
};
this.createAsyncRunContext = function (outputs, syncRun, data) {
var run = function (scopedData) {
var localData = scopedData;
var innerRun = function (jsonLang) { return __awaiter(_this, void 0, void 0, function () {
var _a, ruleHandler, rule, _b, inputs, output, resolvedInputs, result, error_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (!this.isRule(jsonLang))
return [2 /*return*/, jsonLang];
_a = this.getRuleParams(jsonLang), ruleHandler = _a.ruleHandler, rule = _a.rule, _b = _a.inputs, inputs = _b === void 0 ? [] : _b, output = _a.output;
_c.label = 1;
case 1:
_c.trys.push([1, 4, , 5]);
return [4 /*yield*/, this.resolveRuleAsyncInputs(inputs, ruleHandler, innerRun, syncRun, run)];
case 2:
resolvedInputs = _c.sent();
resolvedInputs = this.getAllInputs(rule, resolvedInputs, outputs, data, localData);
return [4 /*yield*/, ruleHandler.apply(void 0, __spreadArray([], __read(resolvedInputs), false))];
case 3:
result = _c.sent();
if (output)
this.setOutputValue(output, result, outputs);
return [2 /*return*/, result];
case 4:
error_1 = _c.sent();
throw Error("Failed to Run \"".concat(rule, "\" cause of ").concat(error_1));
case 5: return [2 /*return*/];
}
});
}); };
return innerRun;
};
return run;
this.resolveRuleInputs = function (rule, inputs, runner, globalData, localDataStore) {
if (globalData === void 0) { globalData = {}; }
return __awaiter(_this, void 0, void 0, function () {
var resolvedInputs, innerRules, i, input, result, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
resolvedInputs = [];
innerRules = this.getHandlerInnerRules(rule);
i = 0;
_b.label = 1;
case 1:
if (!(i < inputs.length)) return [3 /*break*/, 6];
input = inputs[i];
if (!(this.isRule(input) && !innerRules.rules.includes(i))) return [3 /*break*/, 3];
return [4 /*yield*/, runner(input)];
case 2:
_a = _b.sent();
return [3 /*break*/, 4];
case 3:
_a = input;
_b.label = 4;
case 4:
result = _a;
resolvedInputs.push(result);
_b.label = 5;
case 5:
i++;
return [3 /*break*/, 1];
case 6: return [2 /*return*/, this.getInputsWithActions(runner, globalData, localDataStore, innerRules, resolvedInputs)];
}
});
});
};
this.resolveRuleInputs = function (inputs, ruleHandler, run, runner) {
var innerRules = _this.getHandlerInnerRules(ruleHandler);
var resolvedInputs = inputs.map(function (input, i) {
return _this.isRule(input) && !innerRules.rules.includes(i) ? run(input) : input;
});
this.resolveSyncRuleInputs = function (rule, inputs, runner, globalData, localDataStore) {
if (globalData === void 0) { globalData = {}; }
var resolvedInputs = [];
var innerRules = _this.getHandlerInnerRules(rule);
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
var result = _this.isRule(input) && !innerRules.rules.includes(i) ? runner(input) : input;
resolvedInputs.push(result);
}
return _this.getInputsWithActions(runner, globalData, localDataStore, innerRules, resolvedInputs);
};
this.getInputsWithActions = function (runner, globalData, localDataStore, innerRules, resolvedInputs) {
if (globalData === void 0) { globalData = {}; }
if (innerRules.runner)
resolvedInputs.splice(innerRules.runner, 0, runner);
if (innerRules.localData)
resolvedInputs.splice(innerRules.localData, 0, localDataStore);
if (innerRules.globalData)
resolvedInputs.splice(innerRules.globalData, 0, globalData);
return resolvedInputs;
};
this.resolveRuleAsyncInputs = function (inputs, ruleHandler, run, runner, asyncRunner) { return __awaiter(_this, void 0, void 0, function () {
var innerRules, resolvedInputs, i, input, result, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
innerRules = this.getHandlerInnerRules(ruleHandler);
resolvedInputs = [];
i = 0;
_b.label = 1;
case 1:
if (!(i < inputs.length)) return [3 /*break*/, 6];
input = inputs[i];
if (!(this.isRule(input) && !innerRules.rules.includes(i))) return [3 /*break*/, 3];
return [4 /*yield*/, run(input)];
case 2:
_a = _b.sent();
return [3 /*break*/, 4];
case 3:
_a = input;
_b.label = 4;
case 4:
result = _a;
resolvedInputs.push(result);
_b.label = 5;
case 5:
i++;
return [3 /*break*/, 1];
case 6:
if (innerRules.runner)
resolvedInputs.splice(innerRules.runner, 0, runner);
if (innerRules.asyncRunner)
resolvedInputs.splice(innerRules.asyncRunner, 0, asyncRunner);
return [2 /*return*/, resolvedInputs];
this.getHandlerInnerRules = function (rule) {
var _a;
var innerRules = { runner: null, globalData: null, localData: null, rules: [] };
var _b = __read(_this.getRulesDefinitions([rule]), 1), definition = _b[0];
if (!(definition === null || definition === void 0 ? void 0 : definition.inputs))
return innerRules;
if (((_a = definition === null || definition === void 0 ? void 0 : definition.inputs) === null || _a === void 0 ? void 0 : _a.type) && Object.keys(definition === null || definition === void 0 ? void 0 : definition.inputs).length === 1) {
if (definition.inputs.type === 'runner')
innerRules.runner = 0;
if (definition.inputs.type === 'globalData')
innerRules.globalData = 0;
if (definition.inputs.type === 'localData')
innerRules.localData = 0;
if (definition.inputs.type === 'rule')
innerRules.rules = [0];
}
else {
for (var key in definition === null || definition === void 0 ? void 0 : definition.inputs) {
if (definition.inputs[key].type === 'runner')
innerRules.runner = definition.inputs[key].index;
if (definition.inputs[key].type === 'globalData')
innerRules.globalData = definition.inputs[key].index;
if (definition.inputs[key].type === 'localData')
innerRules.localData = definition.inputs[key].index;
if (definition.inputs[key].type === 'rule')
innerRules.rules.push(definition.inputs[key].index);
}
});
}); };
this.getHandlerInnerRules = function (ruleHandler) {
var innerRules = { runner: null, asyncRunner: null, rules: [] };
_this.getHandlerArgs(ruleHandler).forEach(function (arg, i) {
if (arg === '$runner') {
innerRules.runner = i;
}
else if (arg === '$asyncRunner') {
innerRules.asyncRunner = i;
}
else if (arg.startsWith('$rule')) {
innerRules.rules.push(i);
}
});
}
return innerRules;
};
this.getHandlerArgs = function (ruleHandler) {
var _a, _b, _c, _d;
return ((_d = (_c = (_b = (_a = ruleHandler
.toString()) === null || _a === void 0 ? void 0 : _a.match(/\((.*?)\)/)) === null || _b === void 0 ? void 0 : _b[1]) === null || _c === void 0 ? void 0 : _c.split(',')) === null || _d === void 0 ? void 0 : _d.map(function (i) { return i.trim(); })) || [];
};
this.isRule = function (data) { return (data && typeof data === 'object' && data[core_types_1.RuleParams.Rule]); };
this.setOutputValue = function (out, value, outputs) {
outputs.set(out, value);
};
this.getOutputValue = function (varName, outputs) {
var outputValue = outputs.get(varName);
if (!outputValue)
throw Error("The \"".concat(varName, "\" output value is not exist"));
return outputValue;
};
this.getDate = function (data) {
if (!data)
throw Error('There is no data passed');
return data;
};
this.sync = (options === null || options === void 0 ? void 0 : options.sync) || false;
this.rules = new Map();
this.ruleIds = new Set();
this.registerOne({ name: core_types_1.CoreRules.Var, group: 'Core' }, this.getOutputValue);
this.registerOne({ name: core_types_1.CoreRules.Data, group: 'Core' }, this.getDate);
this.rulesDefinitions = new Map();
}
/**
* @param {IJsonLangParams} jsonLang
* @param {Object} data.
* @returns {RuleResult}
* @description is the `Sync` version of jsonLang, use it to run all builtin rules and any extended `Sync` Rules
*/
RuleCore.prototype.execute = function (rules, data) {
var outputs = new Map();
var run = this.createRunContext(outputs, data);
return run()(rules);
RuleCore.prototype.execute = function (rules, data, options) {
var localData = new Map();
var sync = (options === null || options === void 0 ? void 0 : options.sync) || this.sync;
return sync ? this.createSyncRunContext(localData, data)(rules) : this.createRunContext(localData, data)(rules);
};
/**
* @param {IJsonLangParams} jsonLang
* @param {Object} data.
* @returns {Promise<RuleResult>}
* @description is the `Async` version of jsonLang, use it to run all builtin rules and any extended `Sync/Async` Rules
*/
RuleCore.prototype.executeAsync = function (rules, data) {
var outputs = new Map();
var syncRun = this.createRunContext(outputs, data);
var run = this.createAsyncRunContext(outputs, syncRun, data);
return run()(rules);
};
RuleCore.prototype.getAllInputs = function (rule, inputs, outputs, data, scopedData) {
var params = inputs;
if (rule === core_types_1.CoreRules.Var) {
params = [inputs === null || inputs === void 0 ? void 0 : inputs[0], outputs];
RuleCore.prototype.setRuleWithDefinition = function (definition, ruleHandler) {
var finalDefinition = definition;
var finalRuleHandler = ruleHandler;
var existingRule = this.rules.get(definition.identifier.name);
if (existingRule) {
finalRuleHandler = Object.assign(existingRule, ruleHandler);
finalDefinition = this.rulesDefinitions.get(definition.identifier.name) || definition;
}
else if (rule === core_types_1.CoreRules.Data) {
params = (inputs === null || inputs === void 0 ? void 0 : inputs[0]) === 'Local' ? [scopedData] : [data];
finalRuleHandler.async = finalRuleHandler.async || finalRuleHandler.sync;
finalRuleHandler.sync = finalRuleHandler.sync || finalRuleHandler.async;
this.rules.set(definition.identifier.name, finalRuleHandler);
this.rulesDefinitions.set(definition.identifier.name, finalDefinition);
if (definition.identifier.shortcut) {
this.rulesDefinitions.set(definition.identifier.shortcut, finalDefinition);
this.rules.set(definition.identifier.shortcut, finalRuleHandler);
}
return params;
};

@@ -280,0 +311,0 @@ RuleCore.prototype.getRuleParams = function (jsonLang) {

@@ -1,8 +0,2 @@

export declare type IRulesCore = {
registerOne(ruleIdentifier: RuleIdentifier, ruleHandler: RuleHandler): void;
registerMany(rules: Rules): void;
execute(rules: IJsonLangParams, data?: {}): RuleResult;
executeAsync(rules: IJsonLangParams, data?: {}): Promise<RuleResult>;
};
export declare type RuleIdentifier = {
export type RuleIdentifier = {
/**

@@ -24,6 +18,20 @@ * the `Rule` name i.e. "And", "Or"

*/
export declare type RuleHandler = ((...inputs: RuleInput[]) => RuleResult) | ((...inputs: RuleInput[]) => Promise<RuleResult>);
export declare type RuleInput = string | number | boolean | bigint | string[] | number[] | boolean[] | bigint[] | any | IJsonLangParams;
export declare type RuleResult = string | number | boolean | bigint | string[] | number[] | boolean[] | bigint[] | any | IJsonLangParams;
export declare type RulesValidation = {
export type AsyncRuleHandler = ((...inputs: RuleInput[]) => Promise<RuleResult>);
export type SyncRuleHandler = ((...inputs: RuleInput[]) => RuleResult);
export type RuleInput = string | number | boolean | bigint | string[] | number[] | boolean[] | bigint[] | {
[key: string]: any;
} | IJsonLangParams;
export type RuleResult = string | number | boolean | bigint | string[] | number[] | boolean[] | bigint[] | {
[key: string]: any;
} | IJsonLangParams;
export type JsonLangOptions = {
sync?: boolean;
};
export type SyncJsonLangOptions = JsonLangOptions & {
sync?: true;
};
export type AsyncJsonLangOptions = JsonLangOptions & {
sync?: false;
};
export type RulesValidation = {
isValid: boolean;

@@ -37,3 +45,3 @@ errors: string[];

}
export declare type IJsonLangParams = {
export type IJsonLangParams = {
/**

@@ -53,5 +61,2 @@ * Rule: is rule name itself. i.e. "And", "Or", "==", ">"

};
export interface RulesImplementation {
getRules(): Rules;
}
/**

@@ -62,17 +67,64 @@ * A Set of Rules

*/
export declare type Rules = Map<RuleIdentifier, RuleHandler>;
export type Rules = Map<Omit<RuleDefinition, 'sync'>, RuleHandler>;
export type RuleHandler = {
sync: SyncRuleHandler;
async?: SyncRuleHandler;
} | {
sync?: SyncRuleHandler;
async: AsyncRuleHandler;
};
export declare enum CoreRules {
Var = "Var",
Data = "Data"
}
export declare enum DataScope {
Global = "Global",
Local = "Local"
External = "External",
Internal = "Internal"
}
export declare type Runner = (scopedData?: any) => (jsonLang: IJsonLangParams) => any;
export type LocalData = {
key: string;
value: any;
};
export interface JsonSchema {
title?: string;
description?: string;
type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'rule' | 'runner' | 'globalData' | 'localData' | 'null' | 'any';
nullable?: boolean;
examples?: any[];
deprecated?: boolean;
items?: JsonSchema | JsonSchema[];
properties?: {
[propertyName: string]: (JsonSchema);
};
format?: string;
default?: any;
maximum?: number;
minimum?: number;
maxLength?: number;
minLength?: number;
pattern?: string;
maxItems?: number;
minItems?: number;
uniqueItems?: boolean;
maxProperties?: number;
minProperties?: number;
required?: string[];
enum?: any[];
}
export type RuleInputs = {
[key in string]: JsonSchema;
} | JsonSchema;
export type RuleOutput = JsonSchema;
export type RuleDefinition = {
identifier: RuleIdentifier;
sync?: boolean;
inputs?: RuleInputs;
output?: RuleOutput;
};
export type Runner = (jsonLang: IJsonLangParams, localData?: LocalData) => any;
export interface InnerRules {
runner: number | null;
asyncRunner: number | null;
globalData: number | null;
localData: number | null;
rules: number[];
}
//# sourceMappingURL=core.types.d.ts.map

@@ -10,6 +10,4 @@ "use strict";

})(RuleParams = exports.RuleParams || (exports.RuleParams = {}));
;
var CoreRules;
(function (CoreRules) {
CoreRules["Var"] = "Var";
CoreRules["Data"] = "Data";

@@ -19,6 +17,6 @@ })(CoreRules = exports.CoreRules || (exports.CoreRules = {}));

(function (DataScope) {
DataScope["Global"] = "Global";
DataScope["Local"] = "Local";
DataScope["External"] = "External";
DataScope["Internal"] = "Internal";
})(DataScope = exports.DataScope || (exports.DataScope = {}));
;
//# sourceMappingURL=core.types.js.map

@@ -0,3 +1,5 @@

import 'reflect-metadata';
export * from './core';
export * from './core.types';
export * from './decorators';
//# sourceMappingURL=index.d.ts.map

@@ -17,4 +17,6 @@ "use strict";

exports.__esModule = true;
require("reflect-metadata");
__exportStar(require("./core"), exports);
__exportStar(require("./core.types"), exports);
__exportStar(require("./decorators"), exports);
//# sourceMappingURL=index.js.map
export * from './app';
export * from './core/core.types';
export * from './core';
export * from './rule';
//# sourceMappingURL=index.d.ts.map

@@ -18,3 +18,4 @@ "use strict";

__exportStar(require("./app"), exports);
__exportStar(require("./core/core.types"), exports);
__exportStar(require("./core"), exports);
__exportStar(require("./rule"), exports);
//# sourceMappingURL=index.js.map

@@ -1,5 +0,2 @@

export * from './logical';
export * from './math';
export * from './object';
export * from './array';
export * from './data';
//# sourceMappingURL=index.d.ts.map

@@ -17,6 +17,3 @@ "use strict";

exports.__esModule = true;
__exportStar(require("./logical"), exports);
__exportStar(require("./math"), exports);
__exportStar(require("./object"), exports);
__exportStar(require("./array"), exports);
__exportStar(require("./data"), exports);
//# sourceMappingURL=index.js.map
{
"name": "@jsonlang/core",
"version": "0.0.1",
"description": "Json Programming Language",
"version": "0.0.2",
"description": "Json Programming Language Core",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ahmed-medhat-tawfiq"
},
{
"type": "opencollective",
"url": "https://opencollective.com/jsonlang-js"
}
],
"publishConfig": {
"access": "public"
},
"main": "./dist/index.js",

@@ -10,3 +23,3 @@ "types": "./dist/index.d.ts",

"scripts": {
"dev": "ts-node -r tsconfig-paths/register src/app/app.ts",
"start": "concurrently --handle-input \"wait-on dist/index.js && nodemon\" \"tsc -w\" ",
"build": "rimraf ./dist/ && tsc",

@@ -18,13 +31,14 @@ "release": "npm run build && npm publish --access public",

"type": "git",
"url": "git+https://github.com/JsonlangJs/jsonlang-js.git"
"url": "git+https://github.com/JsonlangJs/jsonlang.git"
},
"keywords": [
"JsonLang",
"json-lang",
"jsonlang-core",
"rules",
"conditions",
"json-rules",
"JsonLang",
"json-code",
"JsonRules",
"json-programming",
"json-language",
"json-code",
"json-conditions"

@@ -35,3 +49,3 @@ ],

"bugs": {
"url": "https://github.com/JsonlangJs/jsonlang-js/issues",
"url": "https://github.com/JsonlangJs/jsonlang/issues",
"email": "ahmed.medhat.tawfiq@gmail.com"

@@ -42,3 +56,5 @@ },

"@types/node": "^18.7.23",
"concurrently": "^7.6.0",
"jest": "^29.1.1",
"nodemon": "^2.0.20",
"rimraf": "^3.0.2",

@@ -48,6 +64,9 @@ "ts-jest": "^29.0.3",

"tsconfig-paths": "^4.1.0",
"typescript": "^4.8.4"
"typescript": "^4.8.4",
"wait-on": "^7.0.1"
},
"dependencies": {
}
"reflect-metadata": "^0.1.13"
},
"gitHead": "fc7cdb70359d2c7b45852843c4e3d13bee7adbd2"
}
# 👋 **JsonLang**
<a href="https://jsonlang.dev"><img align="center" src="./assets/default-monochrome.svg" height="200" width="300" alt="JsonLang Logo"/></a></br></br>
<a href="https://jsonlang.dev"><img align="center" src="./jsonlang.svg" height="50%" width="60%" alt="JsonLang Logo"/></a></br></br>
[https://jsonlang.dev](https://jsonlang.dev)
<ul>
<li style="display:inline; margin:17px; font-size:17px"><a href="https://jsonlang.dev"><b>Website</b></a></li>
<li style="display:inline; margin:17px; font-size:17px"><a href="https://jsonlang.dev/docs/intro"><b>Tutorial</b></a></li>
<li style="display:inline; margin:17px; font-size:17px"><a href="https://jsonlang.dev/playground/"><b>Live Playground (Try it NOW)</b></a></li>
<li style="display:inline; margin:17px; font-size:17px"><a href="https://jsonlang.dev/docs/category/examples"><b>Examples</b></a></li>
</ul>
</br></br></br>
It is a Typescript package that provides a simple JSON Programming Language, allowing you to execute a safe logic in Frontend or Backend (NodeJS). Furthermore, it can be stored in the database and rendered to the Frontend-Side to execute/run some business logic.

@@ -19,12 +24,14 @@

[![codecov](https://codecov.io/gh/ahmed-medhat-tawfiq/jsonlang-js/branch/master/graph/badge.svg?token=35JEA7G369)](https://codecov.io/gh/ahmed-medhat-tawfiq/jsonlang-js)
[![Maintenance](https://img.shields.io/maintenance/yes/2022.svg)](https://github.com/JsonlangJs/jsonlang-js/graphs/commit-activity)
[![Build](https://img.shields.io/github/workflow/status/ahmed-medhat-tawfiq/jsonlang-js/Deploy/master)](https://github.com/JsonlangJs/jsonlang-js/actions)
[![Maintenance](https://img.shields.io/maintenance/yes/2023.svg)](https://github.com/JsonlangJs/jsonlang-js/graphs/commit-activity)
[![Build](https://img.shields.io/github/actions/workflow/status/jsonlangjs/jsonlang/deploy-package.yml?branch=master)](https://github.com/JsonlangJs/jsonlang/actions)
[![Programming Language](https://img.shields.io/badge/typescript-100%25-blue.svg)](https://img.shields.io/badge/typescript-100%25-blue.svg)
[![License](https://img.shields.io/github/license/ahmed-medhat-tawfiq/jsonlang-js.svg)](https://github.com/JsonlangJs/jsonlang-js/blob/master/LICENSE)
[![License](https://img.shields.io/github/license/jsonlangjs/jsonlang.svg)](https://github.com/JsonlangJs/jsonlang/blob/master/LICENSE)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fahmed-medhat-tawfiq%2Fjsonlang-js.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fahmed-medhat-tawfiq%2Fjsonlang-js?ref=badge_shield)
[![Github Sponsor](https://camo.githubusercontent.com/7d9333b097b2f54a8957d126ab82937811489c9b75c3850f609985cf94cd29fe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2532302d53706f6e736f722532306d652532306f6e2532304769744875622d6f72616e6765)](https://github.com/sponsors/ahmed-medhat-tawfiq)
</br></br>
</br>
</br></br></br>
## ⏬ **Installation**

@@ -40,3 +47,3 @@

1. Typescript. It's a strongly typed npm package
1. the JsonLang structure is Simple and Optimized. Its [structure](#🏗️-structure) and [rules](#⚒️-builtin-rules) have a shortcut to make your JSON in a small size.
1. the JsonLang structure is Simple and Optimized. Its [structure](#%EF%B8%8F-structure) and [rules](#%EF%B8%8F-builtin-rules) have a shortcut to make your JSON in a small size.
1. Its structure is always Consistent. i.e. `{"$R": "R1", "$I": ["value1", "value2", {"$R": "R2", "$I": [...] }, ...] }`.

@@ -47,4 +54,15 @@ 1. Safe & Secure. Each Rule has a secure handler.

1. DRY. You can pass any rule result in a variable to be used in another rule which makes JsonLang JSON more optimized
</br></br>
</br></br></br>
## 🏗️ **Structure**
</br>
JsonLang have three main parameters:
1. **$R**: (`String`) is the rule name itself. i.e. `and`, `or`, `==`, `>`.
1. **$I**: (`any[]`) is an array of inputs which will be passed to the `Rule` handler/function, their type depends on the `Rule` handler, or it can be a nested rule
1. **$O**?: (`Symbol [Optional]`), is an optional field, it accept a name of variable which used to save the Rule result in a [variable](#core) and can be called in any other rule by `{ "$R": "Var": "$I": ["variableX"] }`. The output value should be unique. If you define the same value more than once, the last one will override the value of the previous one.
</br></br></br>
## 🛠️ **Methods**

@@ -54,25 +72,33 @@ </br>

### **Execute**
</br>
``` js
execute = (jsonLang: IJsonLangParams, data?: {}): RuleResult
async execute(jsonLang: IJsonLangParams, data?: {}, options?: { sync: false }): Promise<RuleResult>
```
Execute is used to run the JsonLang and takes two parameters.
1. **JsonLang**: check the [Structure](#🏗️-structure)
1. **JsonLang**: check the [Structure](#%EF%B8%8F-structure)
1. **Data**: schemaless data object to read/write to it. To get data use the Rule [Data](#core)
1. **options**: execution options. it has one property called `sync` if it false the execute will be async for async rules, else it will be sync
Execute is the `Sync` version of JsonLang, use it to run all [builtin rules](#⚒️-builtin-rules) and any [extended](#extend) `Sync` Rules
Execute is the `Async` version of JsonLang, use it to run all [builtin rules](#%EF%B8%8F-builtin-rules) and any [extended](#extend) `Sync` or `Async` Rules
</br>
``` js
executeAsync = async (jsonLang: IJsonLangParams, data?: {}): Promise<RuleResult>
execute(jsonLang: IJsonLangParams, data: {} | undefined, options: { sync: true }): RuleResult
```
Execute is the `Async` version of JsonLang, use it to run all [builtin rules](#⚒️-builtin-rules) and any [extended](#extend) `Sync` or `Async` Rules
</br></br>
Execute is the `Sync` version of JsonLang, use it to run all [builtin rules](#%EF%B8%8F-builtin-rules) and any [extended](#extend) `Sync` Rules
</br></br></br>
### **Extend**
</br>
#### **The First Way**:
</br>
``` js
registerOne = (ruleIdentifier: RuleIdentifier, ruleHandler: RuleHandler): void
registerOne(ruleDefinition: RuleDefinition, ruleHandler: RuleHandler): void
```

@@ -82,21 +108,81 @@

1. **ruleIdentifier**: Object `{ name: string, shortcut?: string }`, `name`(required) is the `Rule` name, and `shortcut`(optional) is the shortcut. i.e `Sum` is the `name`, and `+` is the `shortcut`.
1. **ruleHandler**: Sync/Async Function `(...inputs: RuleInput[]) => RuleResult)`, `inputs`(required) is array of all inputs needs for the handler [check Input in Structure](#🏗️-structure), and `data` is the schemaless data [check Data in the Execute Section](#execute)
* **ruleDefinition**: Object of
* identifier: `{ name: string, shortcut?: string, group?: string }`, `name`(required) is the `Rule` name, `shortcut`(optional) is the shortcut. i.e `Sum` is the `name`, and `+` is the `shortcut`, and `group` a name of group to categorize/group set of rule under group.
* inputs: JsonSchema to define the rule inputs
* output: JsonSchema to define the rule output
* **ruleHandler**: Object of two props sync & async, you need to pass the implementation Function `(...inputs: RuleInput[]) => RuleResult)`, `inputs`(required) is array of all inputs needs for the handler [check Input in Structure](#%EF%B8%8F-structure), and `data` is the schemaless data [check Data in the Execute Section](#execute)
</br>
``` js
registerMany(rules: Rules): void
registerMany(rules: Rules): void
```
registerMany allows registering a `Map()` of rules. The `Map key` is `RuleIdentifier`, and the `Map value` is the `RuleHandler`
</br></br>
registerMany allows registering a `Map()` of rules. The `Map key` is `RuleDefinition`, and the `Map value` is the `RuleHandler`
</br>
#### **The Second Way**:
</br>
This way is the best practice way to extend JSONLang using decorators and import
``` js
import { JsonLang } from '@jsonlang/core';
import { MathRules } from '@jsonlang/math';
import { LogicRules } from '@jsonlang/logic';
import { ArrayRules } from '@jsonlang/array';
import { ObjectRules } from '@jsonlang/object';
const jsonLang = new JsonLang();
jsonLang.import(MathRules, LogicRules, ArrayRules, ObjectRules);
```
</br>
**Example**
``` js
import { JsonLang } from '@jsonlang/core';
const jsonLang = new JsonLang();
@JsonLangExtension('Test') // here pass the groupName
export class TestRules {
@RuleExtension({
/* rule name and shortcut */
identifier: { name: 'RuleOne', shortcut: 'R' },
/* key-value pair <variableName, jsonschema> for rule's inputs */
inputs: { inputOne: {type: 'string', enum: ['TP', 'RF']}, inputTwo: {type: 'number'} },
/* jsonschema object for rule's output */
output: { type: 'boolean', default: false }
})
RuleOne(
inputOne: string,
inputTwo: number
): boolean {
// do the implementation here
}
@RuleExtension({
identifier: { name: 'RuleTwo' },
inputs: { type: 'array', items: { type: 'string' } },
output: { type: 'number' }
})
RuleTwo(...inputs: string[]): number {
// do the implementation here
}
}
jsonLang.import(TestRules);
```
</br></br></br>
## 🏗️ **Structure**
JsonLang have three main parameters:
1. **$R**: (`String`) is the rule name itself. i.e. `and`, `or`, `==`, `>`.
1. **$I**: (`any[]`) is an array of inputs which will be passed to the `Rule` handler/function, their type depends on the `Rule` handler, or it can be a nested rule
1. **$O**?: (`Symbol [Optional]`), is an optional field, it accept a name of variable which used to save the Rule result in a [variable](#core) and can be called in any other rule by `{ "$R": "Var": "$I": ["variableX"] }`. The output value should be unique. If you define the same value more than once, the last one will override the value of the previous one.
</br></br>
## ⚒️ **Builtin Rules**

@@ -107,15 +193,36 @@ </br>

* **Var**
* Input[]: Array<string> (Size: 1), for the Variable name of the Output.
* Output: Any (depends on the output value).
* Description: used to get the value of any `Output` from any rules, [Check the Output part](#🏗️-structure).
</br>
[**For more Info and examples**](https://jsonlang.dev/docs/rules/core)
</br></br>
``` js
import { JsonLang } from '@jsonlang/core';
```
* **Data**
* Input[]?: Array<string> (Size: 1) Enum of "Global" or "Local", defaulted with "Global".
* Input[]: Array<string> (Size: 2) var name you need to access, Enum of "External" or "Internal"
* Output: any.
* Description: if the Input is `["Global"]` it will return the schemaless data object which you pass it to the [execute](#execute) method, else if the input is `["Local"]`, it will return the value passed from the parent rule like [filter in array rules](#array).
</br>
* Description: if the Input is `["External"]` it will return the schemaless data object which you pass it to the [execute](#execute) method, else if the input is `["Internal"]`, it will return the value of any `Output` from any rules, [Check the Output part](#%EF%B8%8F-structure) or the value passed from the parent rule like [filter in array rules](#array).
* [**More...**](https://jsonlang.dev/docs/category/rules)
</br></br>
### **Logical**
</br>
[**For more Info and examples**](https://jsonlang.dev/docs/rules/logical)
</br></br>
``` js
import { JsonLang } from '@jsonlang/core';
import { LogicRules } from '@jsonlang/logic';
const jsonLang = new JsonLang();
jsonLang.import(LogicRules);
```
</br>
* **And** or **&&**

@@ -165,6 +272,23 @@ * Input[]: Array<any> (Size: Unlimited).

* Description: It takes an array of 2 inputs to compare if element one `Less Than or Equal` element two or not.
</br>
* [**More...**](https://jsonlang.dev/docs/category/rules)
</br></br>
### **Math**
</br>
[**For more Info and examples**](https://jsonlang.dev/docs/rules/math)
</br></br>
``` js
import { JsonLang } from '@jsonlang/core';
import { MathRules } from '@jsonlang/math';
const jsonLang = new JsonLang();
jsonLang.import(MathRules);
```
</br>
* **IsNumber**

@@ -194,29 +318,23 @@ * Input[]: Array<number> (Size: 1).

* Description: Used to Divide all values. i.e. `Input1 / Input2 / .... / InputN`.
* [**More...**](https://jsonlang.dev/docs/category/rules)
</br></br>
### **Array**
</br>
### **Object**
[**For more Info and examples**](https://jsonlang.dev/docs/rules/array)
</br></br>
* **Get** [In Progress]
* Input[]: Array<mixed> (Size: 3) {path: string, defaultValue?: any, data:{}}.
* Output: Any.
* Description: It accepts two inputs, the 1st one (required) is a path to get the [Data](#execute), and the 2nd one (optional) is a default value of the path is not found. the `path` must follow the dotted style `var1.var2` for nested fields and brackets with number for arrays `var1.var2[3].var3`
``` js
import { JsonLang } from '@jsonlang/core';
import { ArrayRules } from '@jsonlang/array';
* **Set** [In Progress]
* Input[]: Array<mixed> (Size: 3) {path: string, value: any, data:{}}.
* Output: Any.
* Description: It accepts two inputs. The 1st one (required) is a path to update/mutate the [Data](#execute), and the 2nd one is the value to set. the `path` must follow the dotted style `var1.var2` for nested fields and brackets with number for arrays `var1.var2[3].var3`. If the `path` does not exist, the `Set` Rule will create it.
const jsonLang = new JsonLang();
* **Update** [In Progress]
* Input[]: Array<mixed> (Size: 3) {path: string, value: any, data:{}}.
* Output: Any.
* Description: It accepts two inputs. The 1st one (required) is a path to update/mutate the [Data](#execute), and the 2nd one is the value to update. the `path` must follow the dotted style `var1.var2` for nested fields and brackets with number for arrays `var1.var2[3].var3`. If the `path` does not exist, the `Update` rule won't do anything.
jsonLang.import(ArrayRules);
```
* **Delete** [In Progress]
* Input[]: Array<string> (Size: 2) {path: string, data:{}}.
* Output: Any.
* Description: It accepts two inputs, a path to mutate the [Data](#execute) by deleting a field in the request path. the `path` must follow the dotted style `var1.var2` for nested fields and brackets with number for arrays `var1.var2[3].var3`. If the `path` does not exist, the `Delete` rule won't do anything.
</br>
### **Array**
* **All**

@@ -230,3 +348,3 @@ * Input[]: Array<any> (Size: Unlimited).

* Output: Any[].
* Description: It accepts array of elements with any type to filter them using nested/inner rules, the filter rule will pass each elements as a Data with scope `Local`, to access it by the inner rules, you will need to use [Data](#core) Rule with scope local, check this [example](#Access-Inner-Data).
* Description: It accepts array of elements with any type to filter them using nested/inner rules, the filter rule will pass each elements as a Data with scope `Internal`, to access it by the inner rules, you will need to use [Data](#core) Rule with scope local, check this [example](#Access-Inner-Data).

@@ -236,3 +354,3 @@ * **Map**

* Output: Any[].
* Description: It accepts array of elements with any type to map them using nested/inner rules, the filter rule will pass each elements as a Data with scope `Local`, to access it by the inner rules, you will need to use [Data](#execute) Rule with scope local.
* Description: It accepts array of elements with any type to map them using nested/inner rules, the filter rule will pass each elements as a Data with scope `Internal`, to access it by the inner rules, you will need to use [Data](#core) Rule with scope local.

@@ -242,3 +360,3 @@ * **Foreach**

* Output: true.
* Description: It accepts array of elements with any type to iterate over them using nested/inner rules, the filter rule will pass each elements as a Data with scope `Local`, to access it by the inner rules, you will need to use [Data](#execute) Rule with scope local.
* Description: It accepts array of elements with any type to iterate over them using nested/inner rules, the filter rule will pass each elements as a Data with scope `Internal`, to access it by the inner rules, you will need to use [Data](#core) Rule with scope local.

@@ -249,21 +367,72 @@ * **Flatten**

* Description: It accepts array of elements with any type to flatten this array with any level.
* [**More...**](https://jsonlang.dev/docs/category/rules)
</br></br>
### **Object**
</br>
[**For more Info and examples**](https://jsonlang.dev/docs/rules/object)
</br></br>
``` js
import { JsonLang } from '@jsonlang/core';
import { ObjectRules } from '@jsonlang/object';
const jsonLang = new JsonLang();
jsonLang.import(ObjectRules);
```
</br>
* **Get** [In Progress]
* Input[]: Array<mixed> (Size: 3) {path: string, defaultValue?: any, data:{}}.
* Output: Any.
* Description: It accepts two inputs, the 1st one (required) is a path to get the [Data](#execute), and the 2nd one (optional) is a default value of the path is not found. the `path` must follow the dotted style `var1.var2` for nested fields and brackets with number for arrays `var1.var2[3].var3`
* **Set** [In Progress]
* Input[]: Array<mixed> (Size: 3) {path: string, value: any, data:{}}.
* Output: Any.
* Description: It accepts two inputs. The 1st one (required) is a path to update/mutate the [Data](#execute), and the 2nd one is the value to set. the `path` must follow the dotted style `var1.var2` for nested fields and brackets with number for arrays `var1.var2[3].var3`. If the `path` does not exist, the `Set` Rule will create it.
* **Update** [In Progress]
* Input[]: Array<mixed> (Size: 3) {path: string, value: any, data:{}}.
* Output: Any.
* Description: It accepts two inputs. The 1st one (required) is a path to update/mutate the [Data](#execute), and the 2nd one is the value to update. the `path` must follow the dotted style `var1.var2` for nested fields and brackets with number for arrays `var1.var2[3].var3`. If the `path` does not exist, the `Update` rule won't do anything.
* **Delete** [In Progress]
* Input[]: Array<string> (Size: 2) {path: string, data:{}}.
* Output: Any.
* Description: It accepts two inputs, a path to mutate the [Data](#execute) by deleting a field in the request path. the `path` must follow the dotted style `var1.var2` for nested fields and brackets with number for arrays `var1.var2[3].var3`. If the `path` does not exist, the `Delete` rule won't do anything.
* [**More...**](https://jsonlang.dev/docs/category/rules)
</br></br></br>
## 💻**Examples**
</br>
[**For more examples**](https://jsonlang.dev/docs/category/examples)
</br></br>
### **One Level Example**
</br>
```js
import { JsonLang } from '@jsonlang/core';
import { LogicRules } from '@jsonlang/logic';
const jsonLang = new JsonLang();
jsonLang.execute( { "$R": "LessThan" , "$I": [10, 20] } ); // true
jsonLang.import(LogicRules);
jsonLang.execute( { "$R": "LessThan" , "$I": [10, 20] }, undefined, { sync: true } ); // true
// or for short
jsonLang.execute( { "$R": "<" , "$I": [10, 20] } ); // true
jsonLang.execute( { "$R": "<" , "$I": [10, 20] }, undefined, { sync: true } ); // true
// or use the async function
jsonLang.executeAsync( { "$R": "<" , "$I": [10, 20] } )
jsonLang.execute( { "$R": "<" , "$I": [10, 20] } )
.then(result => {

@@ -277,8 +446,13 @@ console.log(result); // true

### **Nested Levels Example**
</br>
```js
import { JsonLang } from '@jsonlang/core';
import { MathRules } from '@jsonlang/math';
import { ObjectRules } from '@jsonlang/object';
const jsonLang = new JsonLang();
jsonLang.import(MathRules, ObjectRules);
const result = jsonLang.execute({

@@ -304,5 +478,5 @@ $R: '+',

{ $R: 'Var', $I: ['x'] },
{ $R: 'Get', $I: ['user.age', null, { $R: 'Data', $I: ['Global'] }] }
{ $R: 'Get', $I: ['user.age', null, { $R: 'Data', $I: ['External'] }] }
]
}, { user: { name: 'test', age: 100 } });
}, { user: { name: 'test', age: 100 } }, { sync: true });

@@ -315,12 +489,18 @@ console.log(result);

### **Access Inner Data**
</br>
```js
import { JsonLang } from '@jsonlang/core';
import { LogicRules } from '@jsonlang/logic';
import { ArrayRules } from '@jsonlang/array';
import { ObjectRules } from '@jsonlang/object';
const jsonLang = new JsonLang();
jsonLang.import(LogicRules, ArrayRules, ObjectRules);
const result = jsonLang.execute({ $R: 'All', $I: [
{
$R: 'Filter',
$I: [[1, 3, 5], { $R: '>', $I: [{ $R: 'Data', $I: ['Local'] }, 2] }]
$I: [[1, 3, 5], 'i', { $R: '>', $I: [{ $R: 'Data', $I: ['Internal'] }, 2] }],
},

@@ -330,7 +510,8 @@ {

$I: [
{ $R: 'Get', $I: ['data.test', null, { $R: 'Data', $I: ['Global'] }] },
{ $R: '<', $I: [{ $R: 'Data', $I: ['Local'] }, 500] }
{ $R: 'Get', $I: ['data.test', null, { $R: 'Data', $I: ['External'] }] },
'j',
{ $R: '<', $I: [{ $R: 'Data', $I: ['Internal'] }, 500] }
]
}
] }, { data: { id: 'test', test: [100, 300, 700] } });
] }, { data: { id: 'test', test: [100, 300, 700] } }, { sync: true });

@@ -344,13 +525,18 @@ console.log(result);

### **Extend Rules Example**
</br>
```js
import { JsonLang } from '@jsonlang/core';
import { ObjectRules } from '@jsonlang/object';
const jsonLang = new JsonLang();
jsonLang.registerOne({ name: 'Test', shortcut: 't' }, (input: any) => {
return `${input} Test`
jsonLang.import(ObjectRules);
jsonLang.registerOne({ name: 'Test', shortcut: 't' }, {
sync: (input: any) => { return `${input} Test` },
async: async (input: any) => { return `${input} Test` }
});
const result = jsonLang.execute({
const result = await jsonLang.execute({
$R: 'Test',

@@ -360,3 +546,3 @@ $I: [

]
}, { user: { name: 'test', age: 100 } });
}, { user: { name: 'test', age: 100 } }, { sync: true });

@@ -366,5 +552,6 @@ console.log(result);

```
</br></br>
</br></br></br>
## 🧱 **Customization**
</br>

@@ -374,6 +561,7 @@ You can extend JsonLang and add any logic you want from well-known sync/async packages like lodash, moment, ajv, axios, mysql, mongoose, ...etc.

Just use the [register functions](#extend) and follow its structure to add whatever you want.
</br></br>
</br></br></br>
## ⚠️ **Warnings**
</br>

@@ -385,22 +573,26 @@ JsonLang can be extended with any function, and you can override the existing rules, but make sure that any method you will add won't:

1. Block the event loop in backend nodejs https://nodejs.org/en/docs/guides/dont-block-the-event-loop/
1. abuse the CPU or the memory
1. Abuse the CPU or the memory
</br></br>
## 🔌 **Compatibility**
</br>
This library uses `Array.map` and `Array.reduce`, so it's not *exactly* Internet Explorer 8 friendly.
</br></br>
</br></br></br>
## 📗 **What's Next?**
</br>
* Adding more math, logic, object, array, date, and casting methods.
* Allow importing packages to extend JsonLang easily.
* Provide plugins to wrap well-known packages like MathJs, Jsonata, Axios, Lodash, MomentJs, ...etc.
* Make a UI Editor generate the JSON of JsonLang.
* Allow Writing Rules as expression. i.e. `And(true, Or(1, Get('var1.var2', 0)))`.
* Public website has good documentation, for example, playground to try JsonLang, use-cases session has many ideas for using JsonLang.
</br></br>
* Adding Jsonschema validation for rules inputs
* Allow saving, loading, calling other block of rules.
* Allow logging with different level for rules while execution.
* Make a UI diagram react npm package to generate, show, build, run and show instances logs.
* Add more use-cases for many ideas for using JsonLang.
</br></br></br>
## 📜 **License**
</br>
JsonLang is [MIT licensed](LICENSE)
**JsonLang** is [ **MIT licensed**](LICENSE)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc