UNPKG

@jsonjoy.com/json-expression

Version:

High-performance JSON Pointer implementation

147 lines (146 loc) 5.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.stringOperators = void 0; const tslib_1 = require("tslib"); const codegen_steps_1 = require("../codegen-steps"); const util = tslib_1.__importStar(require("../util")); const binaryOperands = (expr, ctx) => { const left = ctx.eval(expr[1], ctx); const right = ctx.eval(expr[2], ctx); return [left, right]; }; const createValidationOperator = (name, validate) => { return [ name + '?', [], 1, (expr, ctx) => { const email = ctx.eval(expr[1], ctx); return validate(email); }, (ctx) => { ctx.link(validate, 'is_' + name); return new codegen_steps_1.Expression(`is_${name}(${ctx.operands[0]})`); }, ]; }; exports.stringOperators = [ [ '.', ['cat'], -1, (expr, ctx) => { return expr.slice(1).reduce((acc, e) => acc + util.str(ctx.eval(e, ctx)), ''); }, (ctx) => { ctx.link(util.str, 'str'); const parts = []; for (const operand of ctx.operands) { if (operand instanceof codegen_steps_1.Literal) { parts.push(JSON.stringify(util.str(operand.val))); } else if (operand instanceof codegen_steps_1.Expression) { parts.push(`str(${operand})`); } } return new codegen_steps_1.Expression(parts.join('+')); }, ], [ 'contains', [], 2, (expr, ctx) => { const [outer, inner] = binaryOperands(expr, ctx); return util.contains(outer, inner); }, (ctx) => { ctx.link(util.contains, 'contains'); const js = `contains(${ctx.operands[0]},${ctx.operands[1]})`; return new codegen_steps_1.Expression(js); }, ], [ 'starts', [], 2, (expr, ctx) => { const [outer, inner] = binaryOperands(expr, ctx); return util.starts(outer, inner); }, (ctx) => { ctx.link(util.starts, 'starts'); const js = `starts(${ctx.operands[0]},${ctx.operands[1]})`; return new codegen_steps_1.Expression(js); }, ], [ 'ends', [], 2, (expr, ctx) => { const [outer, inner] = binaryOperands(expr, ctx); return util.ends(outer, inner); }, (ctx) => { ctx.link(util.ends, 'ends'); const js = `ends(${ctx.operands[0]},${ctx.operands[1]})`; return new codegen_steps_1.Expression(js); }, ], [ 'substr', [], 3, (expr, ctx) => { const str = ctx.eval(expr[1], ctx); const start = ctx.eval(expr[2], ctx); const end = ctx.eval(expr[3], ctx); return util.substr(str, start, end); }, (ctx) => { ctx.link(util.substr, 'substr'); const js = `substr(${ctx.operands[0]},${ctx.operands[1]},${ctx.operands[2]})`; return new codegen_steps_1.Expression(js); }, ], [ 'matches', [], 2, (expr, ctx) => { let pattern = expr[2]; if (pattern instanceof Array && pattern.length === 1) pattern = pattern[0]; if (typeof pattern !== 'string') throw new Error('"matches" second argument should be a regular expression string.'); if (!ctx.createPattern) throw new Error('"matches" operator requires ".createPattern()" option to be implemented.'); const fn = ctx.createPattern(pattern); const outer = ctx.eval(expr[1], ctx); return fn(util.str(outer)); }, (ctx) => { const pattern = ctx.operands[1]; if (!(pattern instanceof codegen_steps_1.Literal) || typeof pattern.val !== 'string') throw new Error('"matches" second argument should be a regular expression string.'); if (!ctx.createPattern) throw new Error('"matches" operator requires ".createPattern()" option to be implemented.'); const fn = ctx.createPattern(pattern.val); const d = ctx.link(fn); ctx.link(util.str, 'str'); const subject = ctx.operands[0]; return new codegen_steps_1.Expression(`${d}(str(${subject}))`); }, ], createValidationOperator('email', util.isEmail), createValidationOperator('hostname', util.isHostname), createValidationOperator('ip4', util.isIp4), createValidationOperator('ip6', util.isIp6), createValidationOperator('uuid', util.isUuid), createValidationOperator('uri', util.isUri), createValidationOperator('duration', util.isDuration), createValidationOperator('date', util.isDate), createValidationOperator('time', util.isTime), createValidationOperator('dateTime', util.isDateTime), ];