Comparing version 4.0.1 to 4.1.0
{ | ||
"name": "json-e", | ||
"version": "4.0.1", | ||
"version": "4.1.0", | ||
"description": "json parameterization module inspired from json-parameterization", | ||
@@ -5,0 +5,0 @@ "main": "./src/index.js", |
@@ -450,2 +450,50 @@ * [Full documentation](https://json-e.js.org) | ||
### `$switch` | ||
The `$switch` operator behaves like a combination of the `$if` and | ||
`$match` operator for more complex boolean logic. It gets an object, | ||
in which every key is a string expression(s), where at most *one* must | ||
evaluate to `true` and the remaining to `false` based on the context. | ||
The result will be the value corresponding to the key that were | ||
evaluated to `true`. | ||
If there are no matches, the result is either null or if used within an | ||
object or array, omitted from the parent object. | ||
```yaml | ||
template: {$switch: {"x == 10": "ten", "x == 20": "twenty"}} | ||
context: {x: 10} | ||
result: "ten" | ||
``` | ||
```yaml | ||
template: {$switch: {"x < 10": 1}} | ||
context: {x: 10} | ||
result: null | ||
``` | ||
```yaml | ||
template: {a: 1, b: {$switch: {"x == 10 || x == 20": 2, "x > 20": 3}}} | ||
context: {x: 10} | ||
result: {a: 1, b: 2} | ||
``` | ||
```yaml | ||
template: {a: 1, b: {$switch: {"x == 1": 2, "x == 3": 3}}} | ||
context: {x: 2} | ||
result: {a: 1} | ||
``` | ||
```yaml | ||
template: [1, b: {$switch: {"x == 1": 2, "x == 10": 3}}] | ||
context: {x: 2} | ||
result: [1, 2] | ||
``` | ||
```yaml | ||
context: {cond: 3} | ||
template: [0, {$switch: {'cond > 3': 2, 'cond == 5': 3}}] | ||
result: [0] | ||
``` | ||
### `$merge` | ||
@@ -790,2 +838,14 @@ | ||
#### Context | ||
The `defined(varname)` built-in determines if the named variable is defined in the current context. | ||
The current context includes any variables defined or redefined by `$let` or similar operators. | ||
Note that the name must be given as a string. | ||
```yaml | ||
template: {$if: 'defined("x")', then: {$eval: 'x'}, else: 20} | ||
context: {y: 10} | ||
result: 20 | ||
``` | ||
#### Type | ||
@@ -829,2 +889,1 @@ | ||
``` | ||
class ASTNode { | ||
constructor(token) { | ||
this.token = token; | ||
this.constructorName = 'ASTNode'; | ||
} | ||
@@ -12,2 +13,3 @@ } | ||
super(token); | ||
this.constructorName = 'BinOp'; | ||
this.left = left; | ||
@@ -21,2 +23,3 @@ this.right = right; | ||
super(token); | ||
this.constructorName = 'UnaryOp'; | ||
this.expr = expr; | ||
@@ -29,2 +32,3 @@ } | ||
super(token); | ||
this.constructorName = 'FunctionCall'; | ||
this.name = name; | ||
@@ -38,2 +42,3 @@ this.args = args; | ||
this.token = token; | ||
this.constructorName = 'ContextValue'; | ||
} | ||
@@ -45,2 +50,3 @@ } | ||
super(token); | ||
this.constructorName = 'List'; | ||
this.list = list; | ||
@@ -53,2 +59,3 @@ } | ||
super(token); | ||
this.constructorName = 'ValueAccess'; | ||
this.isInterval = isInterval; | ||
@@ -65,2 +72,3 @@ this.arr = arr; | ||
super(token); | ||
this.constructorName = 'Object'; | ||
this.obj = obj; | ||
@@ -78,2 +86,2 @@ } | ||
exports.List = List; | ||
exports.Object = Object; | ||
exports.Object = Object; |
@@ -28,23 +28,32 @@ var {BuiltinError} = require('./error'); | ||
variadic = null, | ||
needsContext = false, | ||
invoke, | ||
}) => context[name] = (...args) => { | ||
if (!variadic && args.length < argumentTests.length) { | ||
throw builtinError(`builtin: ${name}`, `${args.toString()}, too few arguments`); | ||
} | ||
}) => { | ||
context[name] = (...args) => { | ||
let ctx = args.shift(); | ||
if (!variadic && args.length < argumentTests.length) { | ||
throw builtinError(`builtin: ${name}`, `${args.toString()}, too few arguments`); | ||
} | ||
if (minArgs && args.length < minArgs) { | ||
throw builtinError(`builtin: ${name}: expected at least ${minArgs} arguments`); | ||
} | ||
if (minArgs && args.length < minArgs) { | ||
throw builtinError(`builtin: ${name}: expected at least ${minArgs} arguments`); | ||
} | ||
if (variadic) { | ||
argumentTests = args.map(() => variadic); | ||
} | ||
args.forEach((arg, i) => { | ||
if (!argumentTests[i].split('|').some(test => types[test](arg))) { | ||
throw builtinError(`builtin: ${name}`, `argument ${i + 1} to be ${argumentTests[i]} found ${typeof arg}`); | ||
if (variadic) { | ||
argumentTests = args.map(() => variadic); | ||
} | ||
}); | ||
return invoke(...args); | ||
args.forEach((arg, i) => { | ||
if (!argumentTests[i].split('|').some(test => types[test](arg))) { | ||
throw builtinError(`builtin: ${name}`, `argument ${i + 1} to be ${argumentTests[i]} found ${typeof arg}`); | ||
} | ||
}); | ||
if (needsContext) | ||
return invoke(ctx, ...args); | ||
return invoke(...args); | ||
}; | ||
context[name].jsone_builtin = true; | ||
return context[name]; | ||
}; | ||
@@ -124,3 +133,4 @@ | ||
minArgs: 1, | ||
invoke: (str, reference) => fromNow(str, reference || context.now), | ||
needsContext: true, | ||
invoke: (ctx, str, reference) => fromNow(str, reference || ctx.now), | ||
}); | ||
@@ -145,3 +155,4 @@ | ||
argumentTests: ['string'], | ||
invoke: str => context.hasOwnProperty(str) | ||
needsContext: true, | ||
invoke: (ctx, str) => ctx.hasOwnProperty(str) | ||
}); | ||
@@ -148,0 +159,0 @@ |
@@ -237,2 +237,25 @@ /* eslint-disable */ | ||
operators.$switch = (template, context) => { | ||
checkUndefinedProperties(template, ['\\$switch']); | ||
if (!isObject(template['$switch'])) { | ||
throw new TemplateError('$switch can evaluate objects only'); | ||
} | ||
let result = []; | ||
const conditions = template['$switch']; | ||
for (let condition of Object.keys(conditions)) { | ||
if (isTruthy(parse(condition, context))) { | ||
result.push(render(conditions[condition], context)); | ||
} | ||
} | ||
if (result.length > 1) { | ||
throw new TemplateError('$switch can only have one truthy condition'); | ||
} | ||
return result.length > 0 ? result[0] : deleteMarker; | ||
}; | ||
operators.$merge = (template, context) => { | ||
@@ -239,0 +262,0 @@ checkUndefinedProperties(template, ['\\$merge']); |
@@ -12,3 +12,3 @@ const {isFunction, isObject, isString, isArray, isNumber, isInteger, isTruthy} = require("../src/type-utils"); | ||
visit(node) { | ||
let funcName = "visit_" + node.constructor.name; | ||
let funcName = "visit_" + node.constructorName; | ||
return this[funcName](node); | ||
@@ -208,2 +208,5 @@ } | ||
}, this); | ||
if (funcName.hasOwnProperty("jsone_builtin")) { | ||
args.unshift(this.context); | ||
} | ||
return funcName.apply(null, args); | ||
@@ -282,2 +285,2 @@ } else { | ||
exports | ||
.Interpreter = Interpreter; | ||
.Interpreter = Interpreter; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
90000
1329
887