@openforis/arena-core 2.18.0 → 2.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,8 @@ const globalObjectsDictionary = {
10
10
  const globalObjectsArray = Object.values(globalObjectsDictionary);
11
11
  // properties leading to Object, Function or the prototypes would let an expression run arbitrary code
12
12
  export const isForbiddenPropertyName = (name) => name === 'constructor' || name === 'prototype' || name.startsWith('__');
13
+ // Object and Function (e.g. returned by a function or found as a property value) give access to the same capabilities
14
+ export const isForbiddenValue = (value) => value === Object || value === Function;
13
15
  export const getGlobalObjectProperty = (name, object) => {
14
16
  const globalObject = globalObjectsDictionary[name];
15
17
  if (globalObject) {
@@ -1 +1 @@
1
- {"version":3,"file":"global.js","sourceRoot":"","sources":["../../../../src/expression/javascript/global.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE1D,MAAM,uBAAuB,GAAoB;IAC/C,KAAK;IACL,OAAO;IACP,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,MAAM;CACP,CAAA;AACD,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAA;AAEjE,sGAAsG;AACtG,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAW,EAAE,CAC/D,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;AAEzE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,MAAW,EAAO,EAAE;IACxE,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IAClD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAA;IACrB,CAAC;IACD,IAAI,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAEzE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/E,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA","sourcesContent":["import { Dictionary } from '../../common'\nimport { SystemError, SystemErrorKeys } from '../../error'\n\nconst globalObjectsDictionary: Dictionary<any> = {\n Array,\n Boolean,\n Date,\n Math,\n Number,\n String,\n}\nconst globalObjectsArray = Object.values(globalObjectsDictionary)\n\n// properties leading to Object, Function or the prototypes would let an expression run arbitrary code\nexport const isForbiddenPropertyName = (name: string): boolean =>\n name === 'constructor' || name === 'prototype' || name.startsWith('__')\n\nexport const getGlobalObjectProperty = (name: string, object: any): any => {\n const globalObject = globalObjectsDictionary[name]\n if (globalObject) {\n return globalObject\n }\n if (object && globalObjectsArray.includes(object)) {\n const property = isForbiddenPropertyName(name) ? undefined : object[name]\n\n if (!property) {\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name })\n }\n return property\n }\n return null\n}\n"]}
1
+ {"version":3,"file":"global.js","sourceRoot":"","sources":["../../../../src/expression/javascript/global.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE1D,MAAM,uBAAuB,GAAoB;IAC/C,KAAK;IACL,OAAO;IACP,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,MAAM;CACP,CAAA;AACD,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAA;AAEjE,sGAAsG;AACtG,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAW,EAAE,CAC/D,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;AAEzE,sHAAsH;AACtH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAU,EAAW,EAAE,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,CAAA;AAE/F,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,MAAW,EAAO,EAAE;IACxE,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IAClD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAA;IACrB,CAAC;IACD,IAAI,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAEzE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/E,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA","sourcesContent":["import { Dictionary } from '../../common'\nimport { SystemError, SystemErrorKeys } from '../../error'\n\nconst globalObjectsDictionary: Dictionary<any> = {\n Array,\n Boolean,\n Date,\n Math,\n Number,\n String,\n}\nconst globalObjectsArray = Object.values(globalObjectsDictionary)\n\n// properties leading to Object, Function or the prototypes would let an expression run arbitrary code\nexport const isForbiddenPropertyName = (name: string): boolean =>\n name === 'constructor' || name === 'prototype' || name.startsWith('__')\n\n// Object and Function (e.g. returned by a function or found as a property value) give access to the same capabilities\nexport const isForbiddenValue = (value: any): boolean => value === Object || value === Function\n\nexport const getGlobalObjectProperty = (name: string, object: any): any => {\n const globalObject = globalObjectsDictionary[name]\n if (globalObject) {\n return globalObject\n }\n if (object && globalObjectsArray.includes(object)) {\n const property = isForbiddenPropertyName(name) ? undefined : object[name]\n\n if (!property) {\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name })\n }\n return property\n }\n return null\n}\n"]}
@@ -10,11 +10,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { SystemError, SystemErrorKeys } from '../../../error';
11
11
  import { ExpressionNodeEvaluator, ExpressionNodeType, } from '../../node';
12
12
  import { getGlobalObjectProperty } from '../global';
13
- import { REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety';
13
+ import { hasNestedQuantifiers, REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety';
14
+ // String functions converting a string argument into a regular expression (replace, replaceAll and split don't)
15
+ const stringFunctionsWithRegExpArgument = new Set(['match', 'matchAll', 'search']);
16
+ // e.g. text.match('(a+)+$'): the string pattern is checked like a regular expression literal
17
+ const isRegExpStringPatternCall = (callee, args) => {
18
+ const { computed, property } = callee;
19
+ return (!computed &&
20
+ property.type === ExpressionNodeType.Identifier &&
21
+ stringFunctionsWithRegExpArgument.has(property.name) &&
22
+ typeof args[0] === 'string');
23
+ };
24
+ const checkRegExpStringPattern = (pattern) => {
25
+ if (hasNestedQuantifiers(pattern)) {
26
+ throw new SystemError(SystemErrorKeys.expression.unsafeRegularExpression, { pattern });
27
+ }
28
+ };
14
29
  // e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length
15
- const checkRegExpInputLength = (fnObject, args) => {
30
+ const checkRegExpInputLength = (fnObject, args, regExpStringPattern) => {
16
31
  const values = [fnObject, ...args];
17
- if (!values.some((value) => value instanceof RegExp))
32
+ if (!regExpStringPattern && !values.some((value) => value instanceof RegExp))
18
33
  return;
19
34
  const inputTooLong = values.find((value) => typeof value === 'string' && value.length > REG_EXP_INPUT_MAX_LENGTH);
20
35
  if (inputTooLong !== undefined) {
@@ -49,7 +64,11 @@ export class CallEvaluator extends ExpressionNodeEvaluator {
49
64
  const fnObject = yield this.evaluator.evaluateNode(calleeObj, this.context);
50
65
  const argsEvaluated = yield Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)));
51
66
  const args = argsEvaluated.flat();
52
- checkRegExpInputLength(fnObject, args);
67
+ const regExpStringPattern = isRegExpStringPatternCall(callee, args);
68
+ if (regExpStringPattern) {
69
+ checkRegExpStringPattern(args[0]);
70
+ }
71
+ checkRegExpInputLength(fnObject, args, regExpStringPattern);
53
72
  return fn.call(fnObject, ...args);
54
73
  }
55
74
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"call.js","sourceRoot":"","sources":["../../../../../src/expression/javascript/node/call.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionFunction } from '../../function'\nimport {\n CallExpression,\n ExpressionNodeEvaluator,\n ExpressionNodeType,\n IdentifierExpression,\n MemberExpression,\n} from '../../node'\nimport { getGlobalObjectProperty } from '../global'\nimport { REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety'\n\n// e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length\nconst checkRegExpInputLength = (fnObject: any, args: any[]): void => {\n const values = [fnObject, ...args]\n if (!values.some((value) => value instanceof RegExp)) return\n const inputTooLong = values.find((value) => typeof value === 'string' && value.length > REG_EXP_INPUT_MAX_LENGTH)\n if (inputTooLong !== undefined) {\n throw new SystemError(SystemErrorKeys.expression.regularExpressionInputTooLong, {\n maxLength: REG_EXP_INPUT_MAX_LENGTH,\n length: inputTooLong.length,\n })\n }\n}\n\nexport class CallEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, CallExpression> {\n async evaluate(expressionNode: CallExpression): Promise<any> {\n const { callee } = expressionNode\n\n if (callee.type === ExpressionNodeType.Member) {\n return this.evaluateMember(expressionNode, callee)\n } else if (callee.type === ExpressionNodeType.Identifier) {\n return this.evaluateIdentifier(expressionNode, callee)\n }\n\n // No complex expressions may be put in place of a function body.\n // Only a plain identifier is allowed.\n throw new SystemError(SystemErrorKeys.expression.invalidCalleeType, { type: callee.type })\n }\n\n private async evaluateMember(expressionNode: CallExpression, callee: MemberExpression): Promise<any> {\n const { arguments: exprArgs } = expressionNode\n\n // global function (e.g. Math.round(...))\n const fn = await this.evaluator.evaluateNode(callee, this.context)\n if (fn) {\n const { object: calleeObj } = callee\n const fnObject = await this.evaluator.evaluateNode(calleeObj, this.context)\n const argsEvaluated = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)))\n const args = argsEvaluated.flat()\n checkRegExpInputLength(fnObject, args)\n return fn.call(fnObject, ...args)\n }\n return null\n }\n\n private async evaluateIdentifier(expressionNode: CallExpression, callee: IdentifierExpression): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const { object: contextObject } = this.context\n\n const { name: fnName } = callee\n\n const functionInfo = this.evaluator.functions[fnName]\n if (functionInfo) {\n // The function is among the custom functions.\n return this.evaluateCustomIdentifier(expressionNode, fnName)\n }\n // identifier is a global object\n const globalFn = getGlobalObjectProperty(fnName, contextObject)\n if (globalFn !== null) {\n // global functions like String, Number, must be invoked passing node value as argument, not the node itself\n const contextArg = { ...this.context, evaluateToNode: false }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, contextArg)))\n return globalFn(...args)\n }\n\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name: fnName })\n }\n\n private async evaluateCustomIdentifier(expressionNode: CallExpression, fnName: string): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const numArgs = exprArgs.length\n\n const expressionFunction: ExpressionFunction<C> = this.evaluator.functions[fnName]\n\n const { minArity, maxArity, evaluateArgsToNodes, executor } = expressionFunction\n\n if (numArgs < minArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooFewArguments, { fnName, minArity, numArgs })\n if (maxArity !== undefined && maxArity >= 0 && numArgs > maxArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooManyArguments, { fnName, maxArity, numArgs })\n\n // evaluate arguments\n const argsContext = { ...this.context, evaluateToNode: evaluateArgsToNodes }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, argsContext)))\n\n // Currently there are no side effects from function evaluation so it's\n // safe to call the function even when we're just parsing the expression\n // to find all identifiers being used.\n return executor(this.context)(...args)\n }\n}\n"]}
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../../../../../src/expression/javascript/node/call.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionFunction } from '../../function'\nimport {\n CallExpression,\n ExpressionNodeEvaluator,\n ExpressionNodeType,\n IdentifierExpression,\n MemberExpression,\n} from '../../node'\nimport { getGlobalObjectProperty } from '../global'\nimport { hasNestedQuantifiers, REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety'\n\n// String functions converting a string argument into a regular expression (replace, replaceAll and split don't)\nconst stringFunctionsWithRegExpArgument = new Set(['match', 'matchAll', 'search'])\n\n// e.g. text.match('(a+)+$'): the string pattern is checked like a regular expression literal\nconst isRegExpStringPatternCall = (callee: MemberExpression, args: any[]): boolean => {\n const { computed, property } = callee\n return (\n !computed &&\n property.type === ExpressionNodeType.Identifier &&\n stringFunctionsWithRegExpArgument.has((property as IdentifierExpression).name) &&\n typeof args[0] === 'string'\n )\n}\n\nconst checkRegExpStringPattern = (pattern: string): void => {\n if (hasNestedQuantifiers(pattern)) {\n throw new SystemError(SystemErrorKeys.expression.unsafeRegularExpression, { pattern })\n }\n}\n\n// e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length\nconst checkRegExpInputLength = (fnObject: any, args: any[], regExpStringPattern: boolean): void => {\n const values = [fnObject, ...args]\n if (!regExpStringPattern && !values.some((value) => value instanceof RegExp)) return\n const inputTooLong = values.find((value) => typeof value === 'string' && value.length > REG_EXP_INPUT_MAX_LENGTH)\n if (inputTooLong !== undefined) {\n throw new SystemError(SystemErrorKeys.expression.regularExpressionInputTooLong, {\n maxLength: REG_EXP_INPUT_MAX_LENGTH,\n length: inputTooLong.length,\n })\n }\n}\n\nexport class CallEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, CallExpression> {\n async evaluate(expressionNode: CallExpression): Promise<any> {\n const { callee } = expressionNode\n\n if (callee.type === ExpressionNodeType.Member) {\n return this.evaluateMember(expressionNode, callee)\n } else if (callee.type === ExpressionNodeType.Identifier) {\n return this.evaluateIdentifier(expressionNode, callee)\n }\n\n // No complex expressions may be put in place of a function body.\n // Only a plain identifier is allowed.\n throw new SystemError(SystemErrorKeys.expression.invalidCalleeType, { type: callee.type })\n }\n\n private async evaluateMember(expressionNode: CallExpression, callee: MemberExpression): Promise<any> {\n const { arguments: exprArgs } = expressionNode\n\n // global function (e.g. Math.round(...))\n const fn = await this.evaluator.evaluateNode(callee, this.context)\n if (fn) {\n const { object: calleeObj } = callee\n const fnObject = await this.evaluator.evaluateNode(calleeObj, this.context)\n const argsEvaluated = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)))\n const args = argsEvaluated.flat()\n const regExpStringPattern = isRegExpStringPatternCall(callee, args)\n if (regExpStringPattern) {\n checkRegExpStringPattern(args[0])\n }\n checkRegExpInputLength(fnObject, args, regExpStringPattern)\n return fn.call(fnObject, ...args)\n }\n return null\n }\n\n private async evaluateIdentifier(expressionNode: CallExpression, callee: IdentifierExpression): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const { object: contextObject } = this.context\n\n const { name: fnName } = callee\n\n const functionInfo = this.evaluator.functions[fnName]\n if (functionInfo) {\n // The function is among the custom functions.\n return this.evaluateCustomIdentifier(expressionNode, fnName)\n }\n // identifier is a global object\n const globalFn = getGlobalObjectProperty(fnName, contextObject)\n if (globalFn !== null) {\n // global functions like String, Number, must be invoked passing node value as argument, not the node itself\n const contextArg = { ...this.context, evaluateToNode: false }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, contextArg)))\n return globalFn(...args)\n }\n\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name: fnName })\n }\n\n private async evaluateCustomIdentifier(expressionNode: CallExpression, fnName: string): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const numArgs = exprArgs.length\n\n const expressionFunction: ExpressionFunction<C> = this.evaluator.functions[fnName]\n\n const { minArity, maxArity, evaluateArgsToNodes, executor } = expressionFunction\n\n if (numArgs < minArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooFewArguments, { fnName, minArity, numArgs })\n if (maxArity !== undefined && maxArity >= 0 && numArgs > maxArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooManyArguments, { fnName, maxArity, numArgs })\n\n // evaluate arguments\n const argsContext = { ...this.context, evaluateToNode: evaluateArgsToNodes }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, argsContext)))\n\n // Currently there are no side effects from function evaluation so it's\n // safe to call the function even when we're just parsing the expression\n // to find all identifiers being used.\n return executor(this.context)(...args)\n }\n}\n"]}
@@ -1,12 +1,12 @@
1
1
  import { SystemError, SystemErrorKeys } from '../../../error';
2
2
  import { ExpressionNodeEvaluator } from '../../node';
3
- import { getGlobalObjectProperty, isForbiddenPropertyName } from '../global';
3
+ import { getGlobalObjectProperty, isForbiddenPropertyName, isForbiddenValue } from '../global';
4
4
  const getNativeProperty = (name, object) => {
5
- if (isForbiddenPropertyName(name)) {
5
+ if (isForbiddenPropertyName(name) || isForbiddenValue(object)) {
6
6
  return undefined;
7
7
  }
8
8
  const prop = object === null || object === void 0 ? void 0 : object[name];
9
- if (prop === undefined) {
9
+ if (prop === undefined || isForbiddenValue(prop)) {
10
10
  return undefined;
11
11
  }
12
12
  return typeof prop === 'function' ? prop.bind(object) : prop;
@@ -1 +1 @@
1
- {"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../../../src/expression/javascript/node/identifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE7D,OAAO,EAAE,uBAAuB,EAAwB,MAAM,YAAY,CAAA;AAC1E,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AAE5E,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,MAAW,EAAE,EAAE;IACtD,IAAI,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,IAAI,CAAC,CAAA;IAC3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC9D,CAAC,CAAA;AAED,MAAM,OAAO,mBAAiD,SAAQ,uBAAgD;IACpH;;;;;;OAMG;IACO,0BAA0B,CAAC,cAAoC;QACvE,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAA;QAC/B,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAE9C,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QAC/D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;QAC9B,CAAC;QACD,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QAC7D,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAA;QAClC,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAC,cAAoC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,0BAA0B,CAAC,cAAc,CAAC,CAAA;QAChE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACxC,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACtH,CAAC;CACF","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionNodeEvaluator, IdentifierExpression } from '../../node'\nimport { getGlobalObjectProperty, isForbiddenPropertyName } from '../global'\n\nconst getNativeProperty = (name: string, object: any) => {\n if (isForbiddenPropertyName(name)) {\n return undefined\n }\n const prop = object?.[name]\n if (prop === undefined) {\n return undefined\n }\n return typeof prop === 'function' ? prop.bind(object) : prop\n}\n\nexport class IdentifierEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, IdentifierExpression> {\n /**\n * Looks for the identifier among global or native properties, without throwing when it is not found\n * (creating errors captures stack traces, which is expensive when it happens for every evaluated identifier).\n *\n * @param expressionNode - The identifier expression node.\n * @returns The property value wrapped in an object, or null if the identifier has not been found.\n */\n protected findGlobalOrNativeProperty(expressionNode: IdentifierExpression): { value: any } | null {\n const { name } = expressionNode\n const { object: contextObject } = this.context\n\n const globalProp = getGlobalObjectProperty(name, contextObject)\n if (globalProp !== null) {\n return { value: globalProp }\n }\n const nativeProperty = getNativeProperty(name, contextObject)\n if (nativeProperty !== undefined) {\n return { value: nativeProperty }\n }\n return null\n }\n\n evaluate(expressionNode: IdentifierExpression): Promise<any> {\n const property = this.findGlobalOrNativeProperty(expressionNode)\n if (property) {\n return Promise.resolve(property.value)\n }\n return Promise.reject(new SystemError(SystemErrorKeys.expression.identifierNotFound, { name: expressionNode.name }))\n }\n}\n"]}
1
+ {"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../../../src/expression/javascript/node/identifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE7D,OAAO,EAAE,uBAAuB,EAAwB,MAAM,YAAY,CAAA;AAC1E,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAE9F,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,MAAW,EAAE,EAAE;IACtD,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9D,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,IAAI,CAAC,CAAA;IAC3B,IAAI,IAAI,KAAK,SAAS,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC9D,CAAC,CAAA;AAED,MAAM,OAAO,mBAAiD,SAAQ,uBAAgD;IACpH;;;;;;OAMG;IACO,0BAA0B,CAAC,cAAoC;QACvE,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAA;QAC/B,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAE9C,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QAC/D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;QAC9B,CAAC;QACD,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QAC7D,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAA;QAClC,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAC,cAAoC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,0BAA0B,CAAC,cAAc,CAAC,CAAA;QAChE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACxC,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACtH,CAAC;CACF","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionNodeEvaluator, IdentifierExpression } from '../../node'\nimport { getGlobalObjectProperty, isForbiddenPropertyName, isForbiddenValue } from '../global'\n\nconst getNativeProperty = (name: string, object: any) => {\n if (isForbiddenPropertyName(name) || isForbiddenValue(object)) {\n return undefined\n }\n const prop = object?.[name]\n if (prop === undefined || isForbiddenValue(prop)) {\n return undefined\n }\n return typeof prop === 'function' ? prop.bind(object) : prop\n}\n\nexport class IdentifierEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, IdentifierExpression> {\n /**\n * Looks for the identifier among global or native properties, without throwing when it is not found\n * (creating errors captures stack traces, which is expensive when it happens for every evaluated identifier).\n *\n * @param expressionNode - The identifier expression node.\n * @returns The property value wrapped in an object, or null if the identifier has not been found.\n */\n protected findGlobalOrNativeProperty(expressionNode: IdentifierExpression): { value: any } | null {\n const { name } = expressionNode\n const { object: contextObject } = this.context\n\n const globalProp = getGlobalObjectProperty(name, contextObject)\n if (globalProp !== null) {\n return { value: globalProp }\n }\n const nativeProperty = getNativeProperty(name, contextObject)\n if (nativeProperty !== undefined) {\n return { value: nativeProperty }\n }\n return null\n }\n\n evaluate(expressionNode: IdentifierExpression): Promise<any> {\n const property = this.findGlobalOrNativeProperty(expressionNode)\n if (property) {\n return Promise.resolve(property.value)\n }\n return Promise.reject(new SystemError(SystemErrorKeys.expression.identifierNotFound, { name: expressionNode.name }))\n }\n}\n"]}
@@ -98,21 +98,22 @@ export const nodeDefExpressionFunctions = {
98
98
  categoryItemProp: {
99
99
  minArity: 3,
100
100
  executor: (context) => (categoryName, itemPropName, ...codePaths) => __awaiter(void 0, void 0, void 0, function* () {
101
- var _a, _b;
101
+ var _a;
102
102
  const { survey } = context;
103
103
  if (Objects.isEmpty(categoryName) || Objects.isEmpty(itemPropName) || Objects.isEmpty(codePaths))
104
104
  throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters);
105
105
  const category = getCategoryByName({ survey, categoryName });
106
106
  if (!category)
107
107
  throw new SystemError(SystemErrorKeys.expression.invalidCategoryName, { name: categoryName });
108
- const extraPropDef = (_a = category.props.itemExtraDef) === null || _a === void 0 ? void 0 : _a[itemPropName];
108
+ const { itemExtraDef } = category.props;
109
+ const extraPropDef = itemExtraDef && Object.hasOwn(itemExtraDef, itemPropName) ? itemExtraDef[itemPropName] : undefined;
109
110
  if (!extraPropDef)
110
111
  throw new SystemError(SystemErrorKeys.expression.invalidCategoryExtraProp, { propName: itemPropName });
111
112
  const { uuid: categoryUuid } = category;
112
113
  const categoryItem = yield getOrFetchCategoryItem({ context, categoryUuid, codePaths });
113
114
  if (!categoryItem)
114
115
  return null;
115
- const value = (_b = categoryItem.props.extra) === null || _b === void 0 ? void 0 : _b[itemPropName];
116
+ const value = (_a = categoryItem.props.extra) === null || _a === void 0 ? void 0 : _a[itemPropName];
116
117
  return ExtraProps.convertValue({ survey, extraPropDef, value });
117
118
  }),
118
119
  },
@@ -295,7 +296,7 @@ export const nodeDefExpressionFunctions = {
295
296
  minArity: 3,
296
297
  maxArity: 3,
297
298
  executor: (context) => (taxonomyName, propName, taxonCode) => __awaiter(void 0, void 0, void 0, function* () {
298
- var _a, _b;
299
+ var _a;
299
300
  if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(propName))
300
301
  throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters);
301
302
  if (Objects.isEmpty(taxonCode))
@@ -304,13 +305,14 @@ export const nodeDefExpressionFunctions = {
304
305
  const taxonomy = getTaxonomyByName({ survey, taxonomyName });
305
306
  if (!taxonomy)
306
307
  throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName });
307
- const extraPropDef = (_a = taxonomy.props.extraPropsDefs) === null || _a === void 0 ? void 0 : _a[propName];
308
+ const { extraPropsDefs } = taxonomy.props;
309
+ const extraPropDef = extraPropsDefs && Object.hasOwn(extraPropsDefs, propName) ? extraPropsDefs[propName] : undefined;
308
310
  if (!extraPropDef)
309
311
  throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyExtraProp, { propName });
310
312
  const taxon = yield getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode });
311
313
  if (!taxon)
312
314
  return null;
313
- const value = (_b = taxon.props.extra) === null || _b === void 0 ? void 0 : _b[propName];
315
+ const value = (_a = taxon.props.extra) === null || _a === void 0 ? void 0 : _a[propName];
314
316
  return ExtraProps.convertValue({ survey, extraPropDef, value });
315
317
  }),
316
318
  },
@@ -327,7 +329,7 @@ export const nodeDefExpressionFunctions = {
327
329
  const taxonomy = getTaxonomyByName({ survey, taxonomyName });
328
330
  if (!taxonomy)
329
331
  throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName });
330
- if (!LanguagesISO639part2[vernacularLangCode]) {
332
+ if (!Object.hasOwn(LanguagesISO639part2, vernacularLangCode)) {
331
333
  throw new SystemError(SystemErrorKeys.expression.invalidTaxonVernacularNameLanguageCode, {
332
334
  vernacularLangCode,
333
335
  });
@@ -371,7 +373,7 @@ export const nodeDefExpressionFunctions = {
371
373
  return undefined;
372
374
  const { uuid: surveyUuid } = survey;
373
375
  const combinedExtraProps = Users.getCombinedExtraProps(surveyUuid)(user);
374
- return combinedExtraProps[propName];
376
+ return Object.hasOwn(combinedExtraProps, propName) ? combinedExtraProps[propName] : undefined;
375
377
  },
376
378
  },
377
379
  };
@@ -1 +1 @@
1
- {"version":3,"file":"functions.js","sourceRoot":"","sources":["../../../src/nodeDefExpressionEvaluator/functions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Users } from '../auth'\nimport { CategoryItem } from '../category'\nimport { SystemError, SystemErrorKeys } from '../error'\nimport { ExpressionFunctions } from '../expression'\nimport { ExtraProps } from '../extraProp/extraProps'\nimport { AreaOfInterest, Point, Points } from '../geo'\nimport { LanguagesISO639part2 } from '../language'\nimport { ArenaRecord } from '../record'\nimport { getNodeDefParent } from '../survey/surveys/nodeDefs'\nimport { getCategoryItemByCodePaths, getTaxonByCode } from '../survey/surveys/refsData'\nimport {\n getAreaOfInterestByName,\n getAreasOfInterest,\n getCategoryByName,\n getSRSIndex,\n getTaxonomyByName,\n} from '../survey/surveys/surveysGetters'\nimport { Taxon } from '../taxonomy'\nimport { Dates, Numbers, Objects } from '../utils'\nimport { NodeDefExpressionContext } from './context'\n\nconst sampleGeoJsonPolygon = {\n type: 'Feature',\n geometry: {\n type: 'Polygon',\n coordinates: [\n [\n [100.0, 0.0],\n [101.0, 0.0],\n [101.0, 1.0],\n [100.0, 1.0],\n [100.0, 0.0],\n ],\n ],\n },\n}\n\nconst isNotValidString = (value: string): boolean => Objects.isEmpty(value) || typeof value !== 'string'\n\nconst emptyExecutor = (_context: NodeDefExpressionContext) => () => null\n\nconst isUsingDraftProps = (context: NodeDefExpressionContext) => {\n // use draft props when validating expression or previewing record\n const record: ArenaRecord = (context as any).record\n return !record || !!record.preview\n}\n\nconst getOrFetchCategoryItem = async (params: {\n context: NodeDefExpressionContext\n categoryUuid: string\n codePaths: string[]\n}): Promise<CategoryItem | undefined> => {\n const { context, categoryUuid, codePaths } = params\n // if any code path is empty, return null (no category item can be found)\n if (Objects.isEmpty(codePaths) || codePaths.some(Objects.isEmpty)) {\n return undefined\n }\n const { survey, categoryItemProvider } = context\n const categoryItem = getCategoryItemByCodePaths({ survey, categoryUuid, codePaths })\n const draft = isUsingDraftProps(context)\n return categoryItem ?? categoryItemProvider?.getItemByCodePaths({ survey, categoryUuid, codePaths, draft })\n}\n\nconst getOrFetchTaxon = async (params: {\n context: NodeDefExpressionContext\n taxonomyUuid: string\n taxonCode: string\n}): Promise<Taxon | undefined> => {\n const { context, taxonomyUuid, taxonCode } = params\n if (typeof taxonCode !== 'string' && typeof taxonCode !== 'number') {\n return undefined // node def expression validator could call it passing a node def object\n }\n // if taxonCode is empty, return undefined\n if (Objects.isEmpty(taxonCode)) {\n return undefined\n }\n const { survey, taxonProvider } = context\n const taxon = getTaxonByCode({ survey, taxonomyUuid, taxonCode })\n // fetch draft props when validating expression or previewing record\n const record: ArenaRecord = (context as any).record\n const draft = !record || !!record.preview\n return taxon ?? taxonProvider?.getTaxonByCode({ survey, taxonomyUuid, taxonCode, draft })\n}\n\nconst fetchAreaOfInterest = async (params: {\n context: NodeDefExpressionContext\n name: string\n}): Promise<AreaOfInterest | undefined> => {\n const { context, name } = params\n const { survey, areaOfInterestProvider } = context\n if (!areaOfInterestProvider || !getAreaOfInterestByName({ survey, name })) return undefined\n return areaOfInterestProvider.getAreaOfInterest({ survey, name })\n}\n\n// expression validation (no record): a literal area name must be defined in the survey\nconst validateAreaOfInterestName = (params: { context: NodeDefExpressionContext; name: unknown }): void => {\n const { context, name } = params\n const record: ArenaRecord = (context as any).record\n if (!record && typeof name === 'string' && !getAreaOfInterestByName({ survey: context.survey, name })) {\n throw new SystemError(SystemErrorKeys.expression.areaOfInterestNotFound, { name })\n }\n}\n\nconst distanceToAreaOfInterestBoundary = async (params: {\n context: NodeDefExpressionContext\n point: Point\n name: string\n}): Promise<number | null> => {\n const { context, point, name } = params\n const areaOfInterest = await fetchAreaOfInterest({ context, name })\n if (!areaOfInterest) return null\n return Points.distanceToPolygonBoundary(point, areaOfInterest, getSRSIndex(context.survey))\n}\n\nconst geoDistanceExecutor =\n (context: NodeDefExpressionContext) =>\n (coordinateFrom: Point | string, coordinateTo: Point | string): number | null => {\n const { survey } = context\n const srsIndex = getSRSIndex(survey)\n\n const pointFrom = Points.parse(coordinateFrom)\n const pointTo = Points.parse(coordinateTo)\n\n return pointFrom && pointTo ? Points.distance(pointFrom, pointTo, srsIndex) : null\n }\n\nexport const nodeDefExpressionFunctions: ExpressionFunctions<NodeDefExpressionContext> = {\n categoryItemProp: {\n minArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n async (categoryName: string, itemPropName: string, ...codePaths: string[]): Promise<any> => {\n const { survey } = context\n\n if (Objects.isEmpty(categoryName) || Objects.isEmpty(itemPropName) || Objects.isEmpty(codePaths))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n\n const category = getCategoryByName({ survey, categoryName })\n if (!category) throw new SystemError(SystemErrorKeys.expression.invalidCategoryName, { name: categoryName })\n\n const extraPropDef = category.props.itemExtraDef?.[itemPropName]\n if (!extraPropDef)\n throw new SystemError(SystemErrorKeys.expression.invalidCategoryExtraProp, { propName: itemPropName })\n\n const { uuid: categoryUuid } = category\n const categoryItem = await getOrFetchCategoryItem({ context, categoryUuid, codePaths })\n if (!categoryItem) return null\n\n const value = categoryItem.props.extra?.[itemPropName]\n return ExtraProps.convertValue({ survey, extraPropDef, value })\n },\n },\n count: {\n minArity: 1,\n maxArity: 1,\n executor:\n (_context: NodeDefExpressionContext) =>\n (_nodeSet): number =>\n 1,\n },\n dateTimeDiff: {\n minArity: 4,\n maxArity: 4,\n executor:\n (_context: NodeDefExpressionContext) =>\n (date1: string, time1: string, date2: string, time2: string): number | null => {\n if (isNotValidString(date1) || isNotValidString(time1) || isNotValidString(date2) || isNotValidString(time2))\n return null\n // computed in UTC: in the local time zone of the machine a DST change between the 2 dates would alter the result\n const toUtcMinutes = (date: string, time: string): number => {\n const [year, month, day] = date.split('-').map(Number)\n const [hours, minutes] = time.split(':').map(Number)\n return Date.UTC(year, month - 1, day, hours, minutes) / 60000\n }\n const diff = toUtcMinutes(date1, time1) - toUtcMinutes(date2, time2)\n return Number.isNaN(diff) ? null : diff\n },\n },\n // deprecated, use geoDistance instead\n distance: { minArity: 2, maxArity: 2, executor: geoDistanceExecutor },\n first: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: emptyExecutor,\n },\n geoCoordinateAtDistance: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n (coordinate: Point | string, distanceMeters: number, bearingDeg: number): Point | null => {\n // validate parameters\n const origin = Points.parse(coordinate)\n if (!origin) return null\n\n const distanceMetersNumber = Number(distanceMeters)\n const bearingDegNumber = Number(bearingDeg)\n if (!Number.isFinite(distanceMetersNumber) || distanceMetersNumber < 0 || !Number.isFinite(bearingDegNumber)) {\n return null\n }\n\n const { survey } = context\n const srsIndex = getSRSIndex(survey)\n\n return Points.pointAtDistance({\n origin,\n distanceMeters: distanceMetersNumber,\n bearingDeg: bearingDegNumber,\n srsIndex,\n })\n },\n },\n geoDistance: { minArity: 2, maxArity: 2, executor: geoDistanceExecutor },\n geoAOIContaining: {\n minArity: 1,\n maxArity: 1,\n executor:\n (context: NodeDefExpressionContext) =>\n async (coordinate: Point | string): Promise<string | null> => {\n const point = Points.parse(coordinate)\n if (!point || !context.areaOfInterestProvider) return null\n // the survey order is the priority of overlapping areas\n for (const { name } of getAreasOfInterest(context.survey)) {\n const distance = await distanceToAreaOfInterestBoundary({ context, point, name }) // NOSONAR\n if (distance !== null && distance <= 0) return name\n }\n return null\n },\n },\n geoDistanceToAOIBoundary: {\n minArity: 2,\n maxArity: 2,\n executor:\n (context: NodeDefExpressionContext) =>\n async (coordinate: Point | string, name: string): Promise<number | null> => {\n validateAreaOfInterestName({ context, name })\n const point = Points.parse(coordinate)\n if (!point || typeof name !== 'string') return null\n return distanceToAreaOfInterestBoundary({ context, point, name })\n },\n },\n geoPolygon: {\n minArity: 1,\n evaluateArgsToNodes: true,\n executor: () => () => sampleGeoJsonPolygon,\n },\n includes: {\n minArity: 2,\n maxArity: 2,\n evaluateArgsToNodes: false,\n executor:\n () =>\n (items: any, value: any): boolean =>\n Array.isArray(items) && items.map(String).includes(String(value)),\n },\n index: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: () => () => -1,\n },\n last: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: emptyExecutor,\n },\n now: {\n minArity: 0,\n maxArity: 0,\n evaluateToNode: false,\n executor: () => () => Dates.nowFormattedForStorage(),\n },\n numberToWords: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: false,\n executor:\n (context: NodeDefExpressionContext) =>\n (value: any): string | null => {\n if (Objects.isEmpty(value)) return null\n return Numbers.toWords(value, context.lang)\n },\n },\n parent: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n evaluateToNode: true,\n executor: (context: NodeDefExpressionContext) => (nodeDef) => {\n const { survey } = context\n return getNodeDefParent({ survey, nodeDef })\n },\n },\n prevCycleValue: {\n minArity: 1,\n maxArity: 1,\n executor: emptyExecutor,\n },\n prevCycleValues: {\n minArity: 1,\n maxArity: 1,\n executor: emptyExecutor,\n },\n recordCycle: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordDateCreated: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordDateLastModified: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerEmail: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerName: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerRole: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n sum: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: (_context: NodeDefExpressionContext) => (_nodeSet) => 1,\n },\n taxonProp: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) => async (taxonomyName: string, propName: string, taxonCode: string) => {\n if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(propName))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n if (Objects.isEmpty(taxonCode)) return null\n\n const { survey } = context\n const taxonomy = getTaxonomyByName({ survey, taxonomyName })\n if (!taxonomy) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName })\n\n const extraPropDef = taxonomy.props.extraPropsDefs?.[propName]\n if (!extraPropDef) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyExtraProp, { propName })\n\n const taxon = await getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode })\n if (!taxon) return null\n\n const value = taxon.props.extra?.[propName]\n return ExtraProps.convertValue({ survey, extraPropDef, value })\n },\n },\n taxonVernacularName: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n async (taxonomyName: string, vernacularLangCode: string, taxonCode: string) => {\n if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(vernacularLangCode))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n if (Objects.isEmpty(taxonCode)) return null\n\n const { survey } = context\n const taxonomy = getTaxonomyByName({ survey, taxonomyName })\n if (!taxonomy) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName })\n\n if (!LanguagesISO639part2[vernacularLangCode]) {\n throw new SystemError(SystemErrorKeys.expression.invalidTaxonVernacularNameLanguageCode, {\n vernacularLangCode,\n })\n }\n\n const taxon = await getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode })\n if (!taxon) return null\n\n const vernacularNameArray = taxon.vernacularNames?.[vernacularLangCode]\n // consider first vernacular name object only\n const firstVernacularName = vernacularNameArray?.[0]\n return firstVernacularName?.props?.name\n },\n },\n unique: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: (_context: NodeDefExpressionContext) => (_nodeSet) => [],\n },\n userEmail: {\n minArity: 0,\n maxArity: 0,\n executor: (context: NodeDefExpressionContext) => () => context.user?.email,\n },\n userIsRecordOwner: {\n minArity: 0,\n maxArity: 0,\n executor: (_context: NodeDefExpressionContext) => () => false,\n },\n userName: {\n minArity: 0,\n maxArity: 0,\n executor: (context: NodeDefExpressionContext) => () => context.user?.name,\n },\n userProp: {\n minArity: 1,\n maxArity: 1,\n executor: (context: NodeDefExpressionContext) => (propName: string) => {\n const { user, survey } = context\n if (!survey || !user) return undefined\n const { uuid: surveyUuid } = survey\n const combinedExtraProps = Users.getCombinedExtraProps(surveyUuid)(user)\n return combinedExtraProps[propName]\n },\n },\n}\n"]}
1
+ {"version":3,"file":"functions.js","sourceRoot":"","sources":["../../../src/nodeDefExpressionEvaluator/functions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Users } from '../auth'\nimport { CategoryItem } from '../category'\nimport { SystemError, SystemErrorKeys } from '../error'\nimport { ExpressionFunctions } from '../expression'\nimport { ExtraProps } from '../extraProp/extraProps'\nimport { AreaOfInterest, Point, Points } from '../geo'\nimport { LanguagesISO639part2 } from '../language'\nimport { ArenaRecord } from '../record'\nimport { getNodeDefParent } from '../survey/surveys/nodeDefs'\nimport { getCategoryItemByCodePaths, getTaxonByCode } from '../survey/surveys/refsData'\nimport {\n getAreaOfInterestByName,\n getAreasOfInterest,\n getCategoryByName,\n getSRSIndex,\n getTaxonomyByName,\n} from '../survey/surveys/surveysGetters'\nimport { Taxon } from '../taxonomy'\nimport { Dates, Numbers, Objects } from '../utils'\nimport { NodeDefExpressionContext } from './context'\n\nconst sampleGeoJsonPolygon = {\n type: 'Feature',\n geometry: {\n type: 'Polygon',\n coordinates: [\n [\n [100.0, 0.0],\n [101.0, 0.0],\n [101.0, 1.0],\n [100.0, 1.0],\n [100.0, 0.0],\n ],\n ],\n },\n}\n\nconst isNotValidString = (value: string): boolean => Objects.isEmpty(value) || typeof value !== 'string'\n\nconst emptyExecutor = (_context: NodeDefExpressionContext) => () => null\n\nconst isUsingDraftProps = (context: NodeDefExpressionContext) => {\n // use draft props when validating expression or previewing record\n const record: ArenaRecord = (context as any).record\n return !record || !!record.preview\n}\n\nconst getOrFetchCategoryItem = async (params: {\n context: NodeDefExpressionContext\n categoryUuid: string\n codePaths: string[]\n}): Promise<CategoryItem | undefined> => {\n const { context, categoryUuid, codePaths } = params\n // if any code path is empty, return null (no category item can be found)\n if (Objects.isEmpty(codePaths) || codePaths.some(Objects.isEmpty)) {\n return undefined\n }\n const { survey, categoryItemProvider } = context\n const categoryItem = getCategoryItemByCodePaths({ survey, categoryUuid, codePaths })\n const draft = isUsingDraftProps(context)\n return categoryItem ?? categoryItemProvider?.getItemByCodePaths({ survey, categoryUuid, codePaths, draft })\n}\n\nconst getOrFetchTaxon = async (params: {\n context: NodeDefExpressionContext\n taxonomyUuid: string\n taxonCode: string\n}): Promise<Taxon | undefined> => {\n const { context, taxonomyUuid, taxonCode } = params\n if (typeof taxonCode !== 'string' && typeof taxonCode !== 'number') {\n return undefined // node def expression validator could call it passing a node def object\n }\n // if taxonCode is empty, return undefined\n if (Objects.isEmpty(taxonCode)) {\n return undefined\n }\n const { survey, taxonProvider } = context\n const taxon = getTaxonByCode({ survey, taxonomyUuid, taxonCode })\n // fetch draft props when validating expression or previewing record\n const record: ArenaRecord = (context as any).record\n const draft = !record || !!record.preview\n return taxon ?? taxonProvider?.getTaxonByCode({ survey, taxonomyUuid, taxonCode, draft })\n}\n\nconst fetchAreaOfInterest = async (params: {\n context: NodeDefExpressionContext\n name: string\n}): Promise<AreaOfInterest | undefined> => {\n const { context, name } = params\n const { survey, areaOfInterestProvider } = context\n if (!areaOfInterestProvider || !getAreaOfInterestByName({ survey, name })) return undefined\n return areaOfInterestProvider.getAreaOfInterest({ survey, name })\n}\n\n// expression validation (no record): a literal area name must be defined in the survey\nconst validateAreaOfInterestName = (params: { context: NodeDefExpressionContext; name: unknown }): void => {\n const { context, name } = params\n const record: ArenaRecord = (context as any).record\n if (!record && typeof name === 'string' && !getAreaOfInterestByName({ survey: context.survey, name })) {\n throw new SystemError(SystemErrorKeys.expression.areaOfInterestNotFound, { name })\n }\n}\n\nconst distanceToAreaOfInterestBoundary = async (params: {\n context: NodeDefExpressionContext\n point: Point\n name: string\n}): Promise<number | null> => {\n const { context, point, name } = params\n const areaOfInterest = await fetchAreaOfInterest({ context, name })\n if (!areaOfInterest) return null\n return Points.distanceToPolygonBoundary(point, areaOfInterest, getSRSIndex(context.survey))\n}\n\nconst geoDistanceExecutor =\n (context: NodeDefExpressionContext) =>\n (coordinateFrom: Point | string, coordinateTo: Point | string): number | null => {\n const { survey } = context\n const srsIndex = getSRSIndex(survey)\n\n const pointFrom = Points.parse(coordinateFrom)\n const pointTo = Points.parse(coordinateTo)\n\n return pointFrom && pointTo ? Points.distance(pointFrom, pointTo, srsIndex) : null\n }\n\nexport const nodeDefExpressionFunctions: ExpressionFunctions<NodeDefExpressionContext> = {\n categoryItemProp: {\n minArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n async (categoryName: string, itemPropName: string, ...codePaths: string[]): Promise<any> => {\n const { survey } = context\n\n if (Objects.isEmpty(categoryName) || Objects.isEmpty(itemPropName) || Objects.isEmpty(codePaths))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n\n const category = getCategoryByName({ survey, categoryName })\n if (!category) throw new SystemError(SystemErrorKeys.expression.invalidCategoryName, { name: categoryName })\n\n const { itemExtraDef } = category.props\n const extraPropDef =\n itemExtraDef && Object.hasOwn(itemExtraDef, itemPropName) ? itemExtraDef[itemPropName] : undefined\n if (!extraPropDef)\n throw new SystemError(SystemErrorKeys.expression.invalidCategoryExtraProp, { propName: itemPropName })\n\n const { uuid: categoryUuid } = category\n const categoryItem = await getOrFetchCategoryItem({ context, categoryUuid, codePaths })\n if (!categoryItem) return null\n\n const value = categoryItem.props.extra?.[itemPropName]\n return ExtraProps.convertValue({ survey, extraPropDef, value })\n },\n },\n count: {\n minArity: 1,\n maxArity: 1,\n executor:\n (_context: NodeDefExpressionContext) =>\n (_nodeSet): number =>\n 1,\n },\n dateTimeDiff: {\n minArity: 4,\n maxArity: 4,\n executor:\n (_context: NodeDefExpressionContext) =>\n (date1: string, time1: string, date2: string, time2: string): number | null => {\n if (isNotValidString(date1) || isNotValidString(time1) || isNotValidString(date2) || isNotValidString(time2))\n return null\n // computed in UTC: in the local time zone of the machine a DST change between the 2 dates would alter the result\n const toUtcMinutes = (date: string, time: string): number => {\n const [year, month, day] = date.split('-').map(Number)\n const [hours, minutes] = time.split(':').map(Number)\n return Date.UTC(year, month - 1, day, hours, minutes) / 60000\n }\n const diff = toUtcMinutes(date1, time1) - toUtcMinutes(date2, time2)\n return Number.isNaN(diff) ? null : diff\n },\n },\n // deprecated, use geoDistance instead\n distance: { minArity: 2, maxArity: 2, executor: geoDistanceExecutor },\n first: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: emptyExecutor,\n },\n geoCoordinateAtDistance: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n (coordinate: Point | string, distanceMeters: number, bearingDeg: number): Point | null => {\n // validate parameters\n const origin = Points.parse(coordinate)\n if (!origin) return null\n\n const distanceMetersNumber = Number(distanceMeters)\n const bearingDegNumber = Number(bearingDeg)\n if (!Number.isFinite(distanceMetersNumber) || distanceMetersNumber < 0 || !Number.isFinite(bearingDegNumber)) {\n return null\n }\n\n const { survey } = context\n const srsIndex = getSRSIndex(survey)\n\n return Points.pointAtDistance({\n origin,\n distanceMeters: distanceMetersNumber,\n bearingDeg: bearingDegNumber,\n srsIndex,\n })\n },\n },\n geoDistance: { minArity: 2, maxArity: 2, executor: geoDistanceExecutor },\n geoAOIContaining: {\n minArity: 1,\n maxArity: 1,\n executor:\n (context: NodeDefExpressionContext) =>\n async (coordinate: Point | string): Promise<string | null> => {\n const point = Points.parse(coordinate)\n if (!point || !context.areaOfInterestProvider) return null\n // the survey order is the priority of overlapping areas\n for (const { name } of getAreasOfInterest(context.survey)) {\n const distance = await distanceToAreaOfInterestBoundary({ context, point, name }) // NOSONAR\n if (distance !== null && distance <= 0) return name\n }\n return null\n },\n },\n geoDistanceToAOIBoundary: {\n minArity: 2,\n maxArity: 2,\n executor:\n (context: NodeDefExpressionContext) =>\n async (coordinate: Point | string, name: string): Promise<number | null> => {\n validateAreaOfInterestName({ context, name })\n const point = Points.parse(coordinate)\n if (!point || typeof name !== 'string') return null\n return distanceToAreaOfInterestBoundary({ context, point, name })\n },\n },\n geoPolygon: {\n minArity: 1,\n evaluateArgsToNodes: true,\n executor: () => () => sampleGeoJsonPolygon,\n },\n includes: {\n minArity: 2,\n maxArity: 2,\n evaluateArgsToNodes: false,\n executor:\n () =>\n (items: any, value: any): boolean =>\n Array.isArray(items) && items.map(String).includes(String(value)),\n },\n index: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: () => () => -1,\n },\n last: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: emptyExecutor,\n },\n now: {\n minArity: 0,\n maxArity: 0,\n evaluateToNode: false,\n executor: () => () => Dates.nowFormattedForStorage(),\n },\n numberToWords: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: false,\n executor:\n (context: NodeDefExpressionContext) =>\n (value: any): string | null => {\n if (Objects.isEmpty(value)) return null\n return Numbers.toWords(value, context.lang)\n },\n },\n parent: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n evaluateToNode: true,\n executor: (context: NodeDefExpressionContext) => (nodeDef) => {\n const { survey } = context\n return getNodeDefParent({ survey, nodeDef })\n },\n },\n prevCycleValue: {\n minArity: 1,\n maxArity: 1,\n executor: emptyExecutor,\n },\n prevCycleValues: {\n minArity: 1,\n maxArity: 1,\n executor: emptyExecutor,\n },\n recordCycle: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordDateCreated: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordDateLastModified: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerEmail: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerName: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerRole: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n sum: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: (_context: NodeDefExpressionContext) => (_nodeSet) => 1,\n },\n taxonProp: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) => async (taxonomyName: string, propName: string, taxonCode: string) => {\n if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(propName))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n if (Objects.isEmpty(taxonCode)) return null\n\n const { survey } = context\n const taxonomy = getTaxonomyByName({ survey, taxonomyName })\n if (!taxonomy) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName })\n\n const { extraPropsDefs } = taxonomy.props\n const extraPropDef =\n extraPropsDefs && Object.hasOwn(extraPropsDefs, propName) ? extraPropsDefs[propName] : undefined\n if (!extraPropDef) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyExtraProp, { propName })\n\n const taxon = await getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode })\n if (!taxon) return null\n\n const value = taxon.props.extra?.[propName]\n return ExtraProps.convertValue({ survey, extraPropDef, value })\n },\n },\n taxonVernacularName: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n async (taxonomyName: string, vernacularLangCode: string, taxonCode: string) => {\n if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(vernacularLangCode))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n if (Objects.isEmpty(taxonCode)) return null\n\n const { survey } = context\n const taxonomy = getTaxonomyByName({ survey, taxonomyName })\n if (!taxonomy) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName })\n\n if (!Object.hasOwn(LanguagesISO639part2, vernacularLangCode)) {\n throw new SystemError(SystemErrorKeys.expression.invalidTaxonVernacularNameLanguageCode, {\n vernacularLangCode,\n })\n }\n\n const taxon = await getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode })\n if (!taxon) return null\n\n const vernacularNameArray = taxon.vernacularNames?.[vernacularLangCode]\n // consider first vernacular name object only\n const firstVernacularName = vernacularNameArray?.[0]\n return firstVernacularName?.props?.name\n },\n },\n unique: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: (_context: NodeDefExpressionContext) => (_nodeSet) => [],\n },\n userEmail: {\n minArity: 0,\n maxArity: 0,\n executor: (context: NodeDefExpressionContext) => () => context.user?.email,\n },\n userIsRecordOwner: {\n minArity: 0,\n maxArity: 0,\n executor: (_context: NodeDefExpressionContext) => () => false,\n },\n userName: {\n minArity: 0,\n maxArity: 0,\n executor: (context: NodeDefExpressionContext) => () => context.user?.name,\n },\n userProp: {\n minArity: 1,\n maxArity: 1,\n executor: (context: NodeDefExpressionContext) => (propName: string) => {\n const { user, survey } = context\n if (!survey || !user) return undefined\n const { uuid: surveyUuid } = survey\n const combinedExtraProps = Users.getCombinedExtraProps(surveyUuid)(user)\n return Object.hasOwn(combinedExtraProps, propName) ? combinedExtraProps[propName] : undefined\n },\n },\n}\n"]}
@@ -1,2 +1,3 @@
1
1
  export declare const isForbiddenPropertyName: (name: string) => boolean;
2
+ export declare const isForbiddenValue: (value: any) => boolean;
2
3
  export declare const getGlobalObjectProperty: (name: string, object: any) => any;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getGlobalObjectProperty = exports.isForbiddenPropertyName = void 0;
3
+ exports.getGlobalObjectProperty = exports.isForbiddenValue = exports.isForbiddenPropertyName = void 0;
4
4
  const error_1 = require("../../error");
5
5
  const globalObjectsDictionary = {
6
6
  Array,
@@ -14,6 +14,9 @@ const globalObjectsArray = Object.values(globalObjectsDictionary);
14
14
  // properties leading to Object, Function or the prototypes would let an expression run arbitrary code
15
15
  const isForbiddenPropertyName = (name) => name === 'constructor' || name === 'prototype' || name.startsWith('__');
16
16
  exports.isForbiddenPropertyName = isForbiddenPropertyName;
17
+ // Object and Function (e.g. returned by a function or found as a property value) give access to the same capabilities
18
+ const isForbiddenValue = (value) => value === Object || value === Function;
19
+ exports.isForbiddenValue = isForbiddenValue;
17
20
  const getGlobalObjectProperty = (name, object) => {
18
21
  const globalObject = globalObjectsDictionary[name];
19
22
  if (globalObject) {
@@ -1 +1 @@
1
- {"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/expression/javascript/global.ts"],"names":[],"mappings":";;;AACA,uCAA0D;AAE1D,MAAM,uBAAuB,GAAoB;IAC/C,KAAK;IACL,OAAO;IACP,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,MAAM;CACP,CAAA;AACD,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAA;AAEjE,sGAAsG;AAC/F,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAW,EAAE,CAC/D,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;AAD5D,QAAA,uBAAuB,GAAvB,uBAAuB,CACqC;AAElE,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,MAAW,EAAO,EAAE;IACxE,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IAClD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAA;IACrB,CAAC;IACD,IAAI,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAA,QAAA,uBAAuB,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAEzE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/E,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAdY,QAAA,uBAAuB,GAAvB,uBAAuB,CAcnC","sourcesContent":["import { Dictionary } from '../../common'\nimport { SystemError, SystemErrorKeys } from '../../error'\n\nconst globalObjectsDictionary: Dictionary<any> = {\n Array,\n Boolean,\n Date,\n Math,\n Number,\n String,\n}\nconst globalObjectsArray = Object.values(globalObjectsDictionary)\n\n// properties leading to Object, Function or the prototypes would let an expression run arbitrary code\nexport const isForbiddenPropertyName = (name: string): boolean =>\n name === 'constructor' || name === 'prototype' || name.startsWith('__')\n\nexport const getGlobalObjectProperty = (name: string, object: any): any => {\n const globalObject = globalObjectsDictionary[name]\n if (globalObject) {\n return globalObject\n }\n if (object && globalObjectsArray.includes(object)) {\n const property = isForbiddenPropertyName(name) ? undefined : object[name]\n\n if (!property) {\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name })\n }\n return property\n }\n return null\n}\n"]}
1
+ {"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/expression/javascript/global.ts"],"names":[],"mappings":";;;AACA,uCAA0D;AAE1D,MAAM,uBAAuB,GAAoB;IAC/C,KAAK;IACL,OAAO;IACP,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,MAAM;CACP,CAAA;AACD,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAA;AAEjE,sGAAsG;AAC/F,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAW,EAAE,CAC/D,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;AAD5D,QAAA,uBAAuB,GAAvB,uBAAuB,CACqC;AAEzE,sHAAsH;AAC/G,MAAM,gBAAgB,GAAG,CAAC,KAAU,EAAW,EAAE,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,CAAA;AAAlF,QAAA,gBAAgB,GAAhB,gBAAgB,CAAkE;AAExF,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,MAAW,EAAO,EAAE;IACxE,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IAClD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAA;IACrB,CAAC;IACD,IAAI,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAA,QAAA,uBAAuB,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAEzE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/E,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAdY,QAAA,uBAAuB,GAAvB,uBAAuB,CAcnC","sourcesContent":["import { Dictionary } from '../../common'\nimport { SystemError, SystemErrorKeys } from '../../error'\n\nconst globalObjectsDictionary: Dictionary<any> = {\n Array,\n Boolean,\n Date,\n Math,\n Number,\n String,\n}\nconst globalObjectsArray = Object.values(globalObjectsDictionary)\n\n// properties leading to Object, Function or the prototypes would let an expression run arbitrary code\nexport const isForbiddenPropertyName = (name: string): boolean =>\n name === 'constructor' || name === 'prototype' || name.startsWith('__')\n\n// Object and Function (e.g. returned by a function or found as a property value) give access to the same capabilities\nexport const isForbiddenValue = (value: any): boolean => value === Object || value === Function\n\nexport const getGlobalObjectProperty = (name: string, object: any): any => {\n const globalObject = globalObjectsDictionary[name]\n if (globalObject) {\n return globalObject\n }\n if (object && globalObjectsArray.includes(object)) {\n const property = isForbiddenPropertyName(name) ? undefined : object[name]\n\n if (!property) {\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name })\n }\n return property\n }\n return null\n}\n"]}
@@ -14,10 +14,25 @@ const error_1 = require("../../../error");
14
14
  const node_1 = require("../../node");
15
15
  const global_1 = require("../global");
16
16
  const regExpSafety_1 = require("../regExpSafety");
17
+ // String functions converting a string argument into a regular expression (replace, replaceAll and split don't)
18
+ const stringFunctionsWithRegExpArgument = new Set(['match', 'matchAll', 'search']);
19
+ // e.g. text.match('(a+)+$'): the string pattern is checked like a regular expression literal
20
+ const isRegExpStringPatternCall = (callee, args) => {
21
+ const { computed, property } = callee;
22
+ return (!computed &&
23
+ property.type === node_1.ExpressionNodeType.Identifier &&
24
+ stringFunctionsWithRegExpArgument.has(property.name) &&
25
+ typeof args[0] === 'string');
26
+ };
27
+ const checkRegExpStringPattern = (pattern) => {
28
+ if ((0, regExpSafety_1.hasNestedQuantifiers)(pattern)) {
29
+ throw new error_1.SystemError(error_1.SystemErrorKeys.expression.unsafeRegularExpression, { pattern });
30
+ }
31
+ };
17
32
  // e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length
18
- const checkRegExpInputLength = (fnObject, args) => {
33
+ const checkRegExpInputLength = (fnObject, args, regExpStringPattern) => {
19
34
  const values = [fnObject, ...args];
20
- if (!values.some((value) => value instanceof RegExp))
35
+ if (!regExpStringPattern && !values.some((value) => value instanceof RegExp))
21
36
  return;
22
37
  const inputTooLong = values.find((value) => typeof value === 'string' && value.length > regExpSafety_1.REG_EXP_INPUT_MAX_LENGTH);
23
38
  if (inputTooLong !== undefined) {
@@ -52,7 +67,11 @@ class CallEvaluator extends node_1.ExpressionNodeEvaluator {
52
67
  const fnObject = yield this.evaluator.evaluateNode(calleeObj, this.context);
53
68
  const argsEvaluated = yield Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)));
54
69
  const args = argsEvaluated.flat();
55
- checkRegExpInputLength(fnObject, args);
70
+ const regExpStringPattern = isRegExpStringPatternCall(callee, args);
71
+ if (regExpStringPattern) {
72
+ checkRegExpStringPattern(args[0]);
73
+ }
74
+ checkRegExpInputLength(fnObject, args, regExpStringPattern);
56
75
  return fn.call(fnObject, ...args);
57
76
  }
58
77
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"call.js","sourceRoot":"","sources":["../../../../src/expression/javascript/node/call.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionFunction } from '../../function'\nimport {\n CallExpression,\n ExpressionNodeEvaluator,\n ExpressionNodeType,\n IdentifierExpression,\n MemberExpression,\n} from '../../node'\nimport { getGlobalObjectProperty } from '../global'\nimport { REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety'\n\n// e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length\nconst checkRegExpInputLength = (fnObject: any, args: any[]): void => {\n const values = [fnObject, ...args]\n if (!values.some((value) => value instanceof RegExp)) return\n const inputTooLong = values.find((value) => typeof value === 'string' && value.length > REG_EXP_INPUT_MAX_LENGTH)\n if (inputTooLong !== undefined) {\n throw new SystemError(SystemErrorKeys.expression.regularExpressionInputTooLong, {\n maxLength: REG_EXP_INPUT_MAX_LENGTH,\n length: inputTooLong.length,\n })\n }\n}\n\nexport class CallEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, CallExpression> {\n async evaluate(expressionNode: CallExpression): Promise<any> {\n const { callee } = expressionNode\n\n if (callee.type === ExpressionNodeType.Member) {\n return this.evaluateMember(expressionNode, callee)\n } else if (callee.type === ExpressionNodeType.Identifier) {\n return this.evaluateIdentifier(expressionNode, callee)\n }\n\n // No complex expressions may be put in place of a function body.\n // Only a plain identifier is allowed.\n throw new SystemError(SystemErrorKeys.expression.invalidCalleeType, { type: callee.type })\n }\n\n private async evaluateMember(expressionNode: CallExpression, callee: MemberExpression): Promise<any> {\n const { arguments: exprArgs } = expressionNode\n\n // global function (e.g. Math.round(...))\n const fn = await this.evaluator.evaluateNode(callee, this.context)\n if (fn) {\n const { object: calleeObj } = callee\n const fnObject = await this.evaluator.evaluateNode(calleeObj, this.context)\n const argsEvaluated = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)))\n const args = argsEvaluated.flat()\n checkRegExpInputLength(fnObject, args)\n return fn.call(fnObject, ...args)\n }\n return null\n }\n\n private async evaluateIdentifier(expressionNode: CallExpression, callee: IdentifierExpression): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const { object: contextObject } = this.context\n\n const { name: fnName } = callee\n\n const functionInfo = this.evaluator.functions[fnName]\n if (functionInfo) {\n // The function is among the custom functions.\n return this.evaluateCustomIdentifier(expressionNode, fnName)\n }\n // identifier is a global object\n const globalFn = getGlobalObjectProperty(fnName, contextObject)\n if (globalFn !== null) {\n // global functions like String, Number, must be invoked passing node value as argument, not the node itself\n const contextArg = { ...this.context, evaluateToNode: false }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, contextArg)))\n return globalFn(...args)\n }\n\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name: fnName })\n }\n\n private async evaluateCustomIdentifier(expressionNode: CallExpression, fnName: string): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const numArgs = exprArgs.length\n\n const expressionFunction: ExpressionFunction<C> = this.evaluator.functions[fnName]\n\n const { minArity, maxArity, evaluateArgsToNodes, executor } = expressionFunction\n\n if (numArgs < minArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooFewArguments, { fnName, minArity, numArgs })\n if (maxArity !== undefined && maxArity >= 0 && numArgs > maxArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooManyArguments, { fnName, maxArity, numArgs })\n\n // evaluate arguments\n const argsContext = { ...this.context, evaluateToNode: evaluateArgsToNodes }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, argsContext)))\n\n // Currently there are no side effects from function evaluation so it's\n // safe to call the function even when we're just parsing the expression\n // to find all identifiers being used.\n return executor(this.context)(...args)\n }\n}\n"]}
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../../../../src/expression/javascript/node/call.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionFunction } from '../../function'\nimport {\n CallExpression,\n ExpressionNodeEvaluator,\n ExpressionNodeType,\n IdentifierExpression,\n MemberExpression,\n} from '../../node'\nimport { getGlobalObjectProperty } from '../global'\nimport { hasNestedQuantifiers, REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety'\n\n// String functions converting a string argument into a regular expression (replace, replaceAll and split don't)\nconst stringFunctionsWithRegExpArgument = new Set(['match', 'matchAll', 'search'])\n\n// e.g. text.match('(a+)+$'): the string pattern is checked like a regular expression literal\nconst isRegExpStringPatternCall = (callee: MemberExpression, args: any[]): boolean => {\n const { computed, property } = callee\n return (\n !computed &&\n property.type === ExpressionNodeType.Identifier &&\n stringFunctionsWithRegExpArgument.has((property as IdentifierExpression).name) &&\n typeof args[0] === 'string'\n )\n}\n\nconst checkRegExpStringPattern = (pattern: string): void => {\n if (hasNestedQuantifiers(pattern)) {\n throw new SystemError(SystemErrorKeys.expression.unsafeRegularExpression, { pattern })\n }\n}\n\n// e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length\nconst checkRegExpInputLength = (fnObject: any, args: any[], regExpStringPattern: boolean): void => {\n const values = [fnObject, ...args]\n if (!regExpStringPattern && !values.some((value) => value instanceof RegExp)) return\n const inputTooLong = values.find((value) => typeof value === 'string' && value.length > REG_EXP_INPUT_MAX_LENGTH)\n if (inputTooLong !== undefined) {\n throw new SystemError(SystemErrorKeys.expression.regularExpressionInputTooLong, {\n maxLength: REG_EXP_INPUT_MAX_LENGTH,\n length: inputTooLong.length,\n })\n }\n}\n\nexport class CallEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, CallExpression> {\n async evaluate(expressionNode: CallExpression): Promise<any> {\n const { callee } = expressionNode\n\n if (callee.type === ExpressionNodeType.Member) {\n return this.evaluateMember(expressionNode, callee)\n } else if (callee.type === ExpressionNodeType.Identifier) {\n return this.evaluateIdentifier(expressionNode, callee)\n }\n\n // No complex expressions may be put in place of a function body.\n // Only a plain identifier is allowed.\n throw new SystemError(SystemErrorKeys.expression.invalidCalleeType, { type: callee.type })\n }\n\n private async evaluateMember(expressionNode: CallExpression, callee: MemberExpression): Promise<any> {\n const { arguments: exprArgs } = expressionNode\n\n // global function (e.g. Math.round(...))\n const fn = await this.evaluator.evaluateNode(callee, this.context)\n if (fn) {\n const { object: calleeObj } = callee\n const fnObject = await this.evaluator.evaluateNode(calleeObj, this.context)\n const argsEvaluated = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)))\n const args = argsEvaluated.flat()\n const regExpStringPattern = isRegExpStringPatternCall(callee, args)\n if (regExpStringPattern) {\n checkRegExpStringPattern(args[0])\n }\n checkRegExpInputLength(fnObject, args, regExpStringPattern)\n return fn.call(fnObject, ...args)\n }\n return null\n }\n\n private async evaluateIdentifier(expressionNode: CallExpression, callee: IdentifierExpression): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const { object: contextObject } = this.context\n\n const { name: fnName } = callee\n\n const functionInfo = this.evaluator.functions[fnName]\n if (functionInfo) {\n // The function is among the custom functions.\n return this.evaluateCustomIdentifier(expressionNode, fnName)\n }\n // identifier is a global object\n const globalFn = getGlobalObjectProperty(fnName, contextObject)\n if (globalFn !== null) {\n // global functions like String, Number, must be invoked passing node value as argument, not the node itself\n const contextArg = { ...this.context, evaluateToNode: false }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, contextArg)))\n return globalFn(...args)\n }\n\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name: fnName })\n }\n\n private async evaluateCustomIdentifier(expressionNode: CallExpression, fnName: string): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const numArgs = exprArgs.length\n\n const expressionFunction: ExpressionFunction<C> = this.evaluator.functions[fnName]\n\n const { minArity, maxArity, evaluateArgsToNodes, executor } = expressionFunction\n\n if (numArgs < minArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooFewArguments, { fnName, minArity, numArgs })\n if (maxArity !== undefined && maxArity >= 0 && numArgs > maxArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooManyArguments, { fnName, maxArity, numArgs })\n\n // evaluate arguments\n const argsContext = { ...this.context, evaluateToNode: evaluateArgsToNodes }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, argsContext)))\n\n // Currently there are no side effects from function evaluation so it's\n // safe to call the function even when we're just parsing the expression\n // to find all identifiers being used.\n return executor(this.context)(...args)\n }\n}\n"]}
@@ -5,11 +5,11 @@ const error_1 = require("../../../error");
5
5
  const node_1 = require("../../node");
6
6
  const global_1 = require("../global");
7
7
  const getNativeProperty = (name, object) => {
8
- if ((0, global_1.isForbiddenPropertyName)(name)) {
8
+ if ((0, global_1.isForbiddenPropertyName)(name) || (0, global_1.isForbiddenValue)(object)) {
9
9
  return undefined;
10
10
  }
11
11
  const prop = object === null || object === void 0 ? void 0 : object[name];
12
- if (prop === undefined) {
12
+ if (prop === undefined || (0, global_1.isForbiddenValue)(prop)) {
13
13
  return undefined;
14
14
  }
15
15
  return typeof prop === 'function' ? prop.bind(object) : prop;
@@ -1 +1 @@
1
- {"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../../src/expression/javascript/node/identifier.ts"],"names":[],"mappings":";;;AAAA,0CAA6D;AAE7D,qCAA0E;AAC1E,sCAA4E;AAE5E,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,MAAW,EAAE,EAAE;IACtD,IAAI,IAAA,gCAAuB,EAAC,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,IAAI,CAAC,CAAA;IAC3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC9D,CAAC,CAAA;AAED,yBAA8D,SAAQ,8BAAgD;IACpH;;;;;;OAMG;IACO,0BAA0B,CAAC,cAAoC;QACvE,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAA;QAC/B,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAE9C,MAAM,UAAU,GAAG,IAAA,gCAAuB,EAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QAC/D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;QAC9B,CAAC;QACD,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QAC7D,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAA;QAClC,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAC,cAAoC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,0BAA0B,CAAC,cAAc,CAAC,CAAA;QAChE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACxC,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACtH,CAAC;CACF","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionNodeEvaluator, IdentifierExpression } from '../../node'\nimport { getGlobalObjectProperty, isForbiddenPropertyName } from '../global'\n\nconst getNativeProperty = (name: string, object: any) => {\n if (isForbiddenPropertyName(name)) {\n return undefined\n }\n const prop = object?.[name]\n if (prop === undefined) {\n return undefined\n }\n return typeof prop === 'function' ? prop.bind(object) : prop\n}\n\nexport class IdentifierEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, IdentifierExpression> {\n /**\n * Looks for the identifier among global or native properties, without throwing when it is not found\n * (creating errors captures stack traces, which is expensive when it happens for every evaluated identifier).\n *\n * @param expressionNode - The identifier expression node.\n * @returns The property value wrapped in an object, or null if the identifier has not been found.\n */\n protected findGlobalOrNativeProperty(expressionNode: IdentifierExpression): { value: any } | null {\n const { name } = expressionNode\n const { object: contextObject } = this.context\n\n const globalProp = getGlobalObjectProperty(name, contextObject)\n if (globalProp !== null) {\n return { value: globalProp }\n }\n const nativeProperty = getNativeProperty(name, contextObject)\n if (nativeProperty !== undefined) {\n return { value: nativeProperty }\n }\n return null\n }\n\n evaluate(expressionNode: IdentifierExpression): Promise<any> {\n const property = this.findGlobalOrNativeProperty(expressionNode)\n if (property) {\n return Promise.resolve(property.value)\n }\n return Promise.reject(new SystemError(SystemErrorKeys.expression.identifierNotFound, { name: expressionNode.name }))\n }\n}\n"]}
1
+ {"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../../src/expression/javascript/node/identifier.ts"],"names":[],"mappings":";;;AAAA,0CAA6D;AAE7D,qCAA0E;AAC1E,sCAA8F;AAE9F,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,MAAW,EAAE,EAAE;IACtD,IAAI,IAAA,gCAAuB,EAAC,IAAI,CAAC,IAAI,IAAA,yBAAgB,EAAC,MAAM,CAAC,EAAE,CAAC;QAC9D,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,IAAI,CAAC,CAAA;IAC3B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAA,yBAAgB,EAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC9D,CAAC,CAAA;AAED,yBAA8D,SAAQ,8BAAgD;IACpH;;;;;;OAMG;IACO,0BAA0B,CAAC,cAAoC;QACvE,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAA;QAC/B,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAE9C,MAAM,UAAU,GAAG,IAAA,gCAAuB,EAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QAC/D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;QAC9B,CAAC;QACD,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QAC7D,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAA;QAClC,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAC,cAAoC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,0BAA0B,CAAC,cAAc,CAAC,CAAA;QAChE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACxC,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACtH,CAAC;CACF","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionNodeEvaluator, IdentifierExpression } from '../../node'\nimport { getGlobalObjectProperty, isForbiddenPropertyName, isForbiddenValue } from '../global'\n\nconst getNativeProperty = (name: string, object: any) => {\n if (isForbiddenPropertyName(name) || isForbiddenValue(object)) {\n return undefined\n }\n const prop = object?.[name]\n if (prop === undefined || isForbiddenValue(prop)) {\n return undefined\n }\n return typeof prop === 'function' ? prop.bind(object) : prop\n}\n\nexport class IdentifierEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, IdentifierExpression> {\n /**\n * Looks for the identifier among global or native properties, without throwing when it is not found\n * (creating errors captures stack traces, which is expensive when it happens for every evaluated identifier).\n *\n * @param expressionNode - The identifier expression node.\n * @returns The property value wrapped in an object, or null if the identifier has not been found.\n */\n protected findGlobalOrNativeProperty(expressionNode: IdentifierExpression): { value: any } | null {\n const { name } = expressionNode\n const { object: contextObject } = this.context\n\n const globalProp = getGlobalObjectProperty(name, contextObject)\n if (globalProp !== null) {\n return { value: globalProp }\n }\n const nativeProperty = getNativeProperty(name, contextObject)\n if (nativeProperty !== undefined) {\n return { value: nativeProperty }\n }\n return null\n }\n\n evaluate(expressionNode: IdentifierExpression): Promise<any> {\n const property = this.findGlobalOrNativeProperty(expressionNode)\n if (property) {\n return Promise.resolve(property.value)\n }\n return Promise.reject(new SystemError(SystemErrorKeys.expression.identifierNotFound, { name: expressionNode.name }))\n }\n}\n"]}
@@ -101,21 +101,22 @@ exports.nodeDefExpressionFunctions = {
101
101
  categoryItemProp: {
102
102
  minArity: 3,
103
103
  executor: (context) => (categoryName, itemPropName, ...codePaths) => __awaiter(void 0, void 0, void 0, function* () {
104
- var _a, _b;
104
+ var _a;
105
105
  const { survey } = context;
106
106
  if (utils_1.Objects.isEmpty(categoryName) || utils_1.Objects.isEmpty(itemPropName) || utils_1.Objects.isEmpty(codePaths))
107
107
  throw new error_1.SystemError(error_1.SystemErrorKeys.expression.missingFunctionParameters);
108
108
  const category = (0, surveysGetters_1.getCategoryByName)({ survey, categoryName });
109
109
  if (!category)
110
110
  throw new error_1.SystemError(error_1.SystemErrorKeys.expression.invalidCategoryName, { name: categoryName });
111
- const extraPropDef = (_a = category.props.itemExtraDef) === null || _a === void 0 ? void 0 : _a[itemPropName];
111
+ const { itemExtraDef } = category.props;
112
+ const extraPropDef = itemExtraDef && Object.hasOwn(itemExtraDef, itemPropName) ? itemExtraDef[itemPropName] : undefined;
112
113
  if (!extraPropDef)
113
114
  throw new error_1.SystemError(error_1.SystemErrorKeys.expression.invalidCategoryExtraProp, { propName: itemPropName });
114
115
  const { uuid: categoryUuid } = category;
115
116
  const categoryItem = yield getOrFetchCategoryItem({ context, categoryUuid, codePaths });
116
117
  if (!categoryItem)
117
118
  return null;
118
- const value = (_b = categoryItem.props.extra) === null || _b === void 0 ? void 0 : _b[itemPropName];
119
+ const value = (_a = categoryItem.props.extra) === null || _a === void 0 ? void 0 : _a[itemPropName];
119
120
  return extraProps_1.ExtraProps.convertValue({ survey, extraPropDef, value });
120
121
  }),
121
122
  },
@@ -298,7 +299,7 @@ exports.nodeDefExpressionFunctions = {
298
299
  minArity: 3,
299
300
  maxArity: 3,
300
301
  executor: (context) => (taxonomyName, propName, taxonCode) => __awaiter(void 0, void 0, void 0, function* () {
301
- var _a, _b;
302
+ var _a;
302
303
  if (utils_1.Objects.isEmpty(taxonomyName) || utils_1.Objects.isEmpty(propName))
303
304
  throw new error_1.SystemError(error_1.SystemErrorKeys.expression.missingFunctionParameters);
304
305
  if (utils_1.Objects.isEmpty(taxonCode))
@@ -307,13 +308,14 @@ exports.nodeDefExpressionFunctions = {
307
308
  const taxonomy = (0, surveysGetters_1.getTaxonomyByName)({ survey, taxonomyName });
308
309
  if (!taxonomy)
309
310
  throw new error_1.SystemError(error_1.SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName });
310
- const extraPropDef = (_a = taxonomy.props.extraPropsDefs) === null || _a === void 0 ? void 0 : _a[propName];
311
+ const { extraPropsDefs } = taxonomy.props;
312
+ const extraPropDef = extraPropsDefs && Object.hasOwn(extraPropsDefs, propName) ? extraPropsDefs[propName] : undefined;
311
313
  if (!extraPropDef)
312
314
  throw new error_1.SystemError(error_1.SystemErrorKeys.expression.invalidTaxonomyExtraProp, { propName });
313
315
  const taxon = yield getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode });
314
316
  if (!taxon)
315
317
  return null;
316
- const value = (_b = taxon.props.extra) === null || _b === void 0 ? void 0 : _b[propName];
318
+ const value = (_a = taxon.props.extra) === null || _a === void 0 ? void 0 : _a[propName];
317
319
  return extraProps_1.ExtraProps.convertValue({ survey, extraPropDef, value });
318
320
  }),
319
321
  },
@@ -330,7 +332,7 @@ exports.nodeDefExpressionFunctions = {
330
332
  const taxonomy = (0, surveysGetters_1.getTaxonomyByName)({ survey, taxonomyName });
331
333
  if (!taxonomy)
332
334
  throw new error_1.SystemError(error_1.SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName });
333
- if (!language_1.LanguagesISO639part2[vernacularLangCode]) {
335
+ if (!Object.hasOwn(language_1.LanguagesISO639part2, vernacularLangCode)) {
334
336
  throw new error_1.SystemError(error_1.SystemErrorKeys.expression.invalidTaxonVernacularNameLanguageCode, {
335
337
  vernacularLangCode,
336
338
  });
@@ -374,7 +376,7 @@ exports.nodeDefExpressionFunctions = {
374
376
  return undefined;
375
377
  const { uuid: surveyUuid } = survey;
376
378
  const combinedExtraProps = auth_1.Users.getCombinedExtraProps(surveyUuid)(user);
377
- return combinedExtraProps[propName];
379
+ return Object.hasOwn(combinedExtraProps, propName) ? combinedExtraProps[propName] : undefined;
378
380
  },
379
381
  },
380
382
  };
@@ -1 +1 @@
1
- {"version":3,"file":"functions.js","sourceRoot":"","sources":["../../src/nodeDefExpressionEvaluator/functions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Users } from '../auth'\nimport { CategoryItem } from '../category'\nimport { SystemError, SystemErrorKeys } from '../error'\nimport { ExpressionFunctions } from '../expression'\nimport { ExtraProps } from '../extraProp/extraProps'\nimport { AreaOfInterest, Point, Points } from '../geo'\nimport { LanguagesISO639part2 } from '../language'\nimport { ArenaRecord } from '../record'\nimport { getNodeDefParent } from '../survey/surveys/nodeDefs'\nimport { getCategoryItemByCodePaths, getTaxonByCode } from '../survey/surveys/refsData'\nimport {\n getAreaOfInterestByName,\n getAreasOfInterest,\n getCategoryByName,\n getSRSIndex,\n getTaxonomyByName,\n} from '../survey/surveys/surveysGetters'\nimport { Taxon } from '../taxonomy'\nimport { Dates, Numbers, Objects } from '../utils'\nimport { NodeDefExpressionContext } from './context'\n\nconst sampleGeoJsonPolygon = {\n type: 'Feature',\n geometry: {\n type: 'Polygon',\n coordinates: [\n [\n [100.0, 0.0],\n [101.0, 0.0],\n [101.0, 1.0],\n [100.0, 1.0],\n [100.0, 0.0],\n ],\n ],\n },\n}\n\nconst isNotValidString = (value: string): boolean => Objects.isEmpty(value) || typeof value !== 'string'\n\nconst emptyExecutor = (_context: NodeDefExpressionContext) => () => null\n\nconst isUsingDraftProps = (context: NodeDefExpressionContext) => {\n // use draft props when validating expression or previewing record\n const record: ArenaRecord = (context as any).record\n return !record || !!record.preview\n}\n\nconst getOrFetchCategoryItem = async (params: {\n context: NodeDefExpressionContext\n categoryUuid: string\n codePaths: string[]\n}): Promise<CategoryItem | undefined> => {\n const { context, categoryUuid, codePaths } = params\n // if any code path is empty, return null (no category item can be found)\n if (Objects.isEmpty(codePaths) || codePaths.some(Objects.isEmpty)) {\n return undefined\n }\n const { survey, categoryItemProvider } = context\n const categoryItem = getCategoryItemByCodePaths({ survey, categoryUuid, codePaths })\n const draft = isUsingDraftProps(context)\n return categoryItem ?? categoryItemProvider?.getItemByCodePaths({ survey, categoryUuid, codePaths, draft })\n}\n\nconst getOrFetchTaxon = async (params: {\n context: NodeDefExpressionContext\n taxonomyUuid: string\n taxonCode: string\n}): Promise<Taxon | undefined> => {\n const { context, taxonomyUuid, taxonCode } = params\n if (typeof taxonCode !== 'string' && typeof taxonCode !== 'number') {\n return undefined // node def expression validator could call it passing a node def object\n }\n // if taxonCode is empty, return undefined\n if (Objects.isEmpty(taxonCode)) {\n return undefined\n }\n const { survey, taxonProvider } = context\n const taxon = getTaxonByCode({ survey, taxonomyUuid, taxonCode })\n // fetch draft props when validating expression or previewing record\n const record: ArenaRecord = (context as any).record\n const draft = !record || !!record.preview\n return taxon ?? taxonProvider?.getTaxonByCode({ survey, taxonomyUuid, taxonCode, draft })\n}\n\nconst fetchAreaOfInterest = async (params: {\n context: NodeDefExpressionContext\n name: string\n}): Promise<AreaOfInterest | undefined> => {\n const { context, name } = params\n const { survey, areaOfInterestProvider } = context\n if (!areaOfInterestProvider || !getAreaOfInterestByName({ survey, name })) return undefined\n return areaOfInterestProvider.getAreaOfInterest({ survey, name })\n}\n\n// expression validation (no record): a literal area name must be defined in the survey\nconst validateAreaOfInterestName = (params: { context: NodeDefExpressionContext; name: unknown }): void => {\n const { context, name } = params\n const record: ArenaRecord = (context as any).record\n if (!record && typeof name === 'string' && !getAreaOfInterestByName({ survey: context.survey, name })) {\n throw new SystemError(SystemErrorKeys.expression.areaOfInterestNotFound, { name })\n }\n}\n\nconst distanceToAreaOfInterestBoundary = async (params: {\n context: NodeDefExpressionContext\n point: Point\n name: string\n}): Promise<number | null> => {\n const { context, point, name } = params\n const areaOfInterest = await fetchAreaOfInterest({ context, name })\n if (!areaOfInterest) return null\n return Points.distanceToPolygonBoundary(point, areaOfInterest, getSRSIndex(context.survey))\n}\n\nconst geoDistanceExecutor =\n (context: NodeDefExpressionContext) =>\n (coordinateFrom: Point | string, coordinateTo: Point | string): number | null => {\n const { survey } = context\n const srsIndex = getSRSIndex(survey)\n\n const pointFrom = Points.parse(coordinateFrom)\n const pointTo = Points.parse(coordinateTo)\n\n return pointFrom && pointTo ? Points.distance(pointFrom, pointTo, srsIndex) : null\n }\n\nexport const nodeDefExpressionFunctions: ExpressionFunctions<NodeDefExpressionContext> = {\n categoryItemProp: {\n minArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n async (categoryName: string, itemPropName: string, ...codePaths: string[]): Promise<any> => {\n const { survey } = context\n\n if (Objects.isEmpty(categoryName) || Objects.isEmpty(itemPropName) || Objects.isEmpty(codePaths))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n\n const category = getCategoryByName({ survey, categoryName })\n if (!category) throw new SystemError(SystemErrorKeys.expression.invalidCategoryName, { name: categoryName })\n\n const extraPropDef = category.props.itemExtraDef?.[itemPropName]\n if (!extraPropDef)\n throw new SystemError(SystemErrorKeys.expression.invalidCategoryExtraProp, { propName: itemPropName })\n\n const { uuid: categoryUuid } = category\n const categoryItem = await getOrFetchCategoryItem({ context, categoryUuid, codePaths })\n if (!categoryItem) return null\n\n const value = categoryItem.props.extra?.[itemPropName]\n return ExtraProps.convertValue({ survey, extraPropDef, value })\n },\n },\n count: {\n minArity: 1,\n maxArity: 1,\n executor:\n (_context: NodeDefExpressionContext) =>\n (_nodeSet): number =>\n 1,\n },\n dateTimeDiff: {\n minArity: 4,\n maxArity: 4,\n executor:\n (_context: NodeDefExpressionContext) =>\n (date1: string, time1: string, date2: string, time2: string): number | null => {\n if (isNotValidString(date1) || isNotValidString(time1) || isNotValidString(date2) || isNotValidString(time2))\n return null\n // computed in UTC: in the local time zone of the machine a DST change between the 2 dates would alter the result\n const toUtcMinutes = (date: string, time: string): number => {\n const [year, month, day] = date.split('-').map(Number)\n const [hours, minutes] = time.split(':').map(Number)\n return Date.UTC(year, month - 1, day, hours, minutes) / 60000\n }\n const diff = toUtcMinutes(date1, time1) - toUtcMinutes(date2, time2)\n return Number.isNaN(diff) ? null : diff\n },\n },\n // deprecated, use geoDistance instead\n distance: { minArity: 2, maxArity: 2, executor: geoDistanceExecutor },\n first: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: emptyExecutor,\n },\n geoCoordinateAtDistance: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n (coordinate: Point | string, distanceMeters: number, bearingDeg: number): Point | null => {\n // validate parameters\n const origin = Points.parse(coordinate)\n if (!origin) return null\n\n const distanceMetersNumber = Number(distanceMeters)\n const bearingDegNumber = Number(bearingDeg)\n if (!Number.isFinite(distanceMetersNumber) || distanceMetersNumber < 0 || !Number.isFinite(bearingDegNumber)) {\n return null\n }\n\n const { survey } = context\n const srsIndex = getSRSIndex(survey)\n\n return Points.pointAtDistance({\n origin,\n distanceMeters: distanceMetersNumber,\n bearingDeg: bearingDegNumber,\n srsIndex,\n })\n },\n },\n geoDistance: { minArity: 2, maxArity: 2, executor: geoDistanceExecutor },\n geoAOIContaining: {\n minArity: 1,\n maxArity: 1,\n executor:\n (context: NodeDefExpressionContext) =>\n async (coordinate: Point | string): Promise<string | null> => {\n const point = Points.parse(coordinate)\n if (!point || !context.areaOfInterestProvider) return null\n // the survey order is the priority of overlapping areas\n for (const { name } of getAreasOfInterest(context.survey)) {\n const distance = await distanceToAreaOfInterestBoundary({ context, point, name }) // NOSONAR\n if (distance !== null && distance <= 0) return name\n }\n return null\n },\n },\n geoDistanceToAOIBoundary: {\n minArity: 2,\n maxArity: 2,\n executor:\n (context: NodeDefExpressionContext) =>\n async (coordinate: Point | string, name: string): Promise<number | null> => {\n validateAreaOfInterestName({ context, name })\n const point = Points.parse(coordinate)\n if (!point || typeof name !== 'string') return null\n return distanceToAreaOfInterestBoundary({ context, point, name })\n },\n },\n geoPolygon: {\n minArity: 1,\n evaluateArgsToNodes: true,\n executor: () => () => sampleGeoJsonPolygon,\n },\n includes: {\n minArity: 2,\n maxArity: 2,\n evaluateArgsToNodes: false,\n executor:\n () =>\n (items: any, value: any): boolean =>\n Array.isArray(items) && items.map(String).includes(String(value)),\n },\n index: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: () => () => -1,\n },\n last: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: emptyExecutor,\n },\n now: {\n minArity: 0,\n maxArity: 0,\n evaluateToNode: false,\n executor: () => () => Dates.nowFormattedForStorage(),\n },\n numberToWords: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: false,\n executor:\n (context: NodeDefExpressionContext) =>\n (value: any): string | null => {\n if (Objects.isEmpty(value)) return null\n return Numbers.toWords(value, context.lang)\n },\n },\n parent: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n evaluateToNode: true,\n executor: (context: NodeDefExpressionContext) => (nodeDef) => {\n const { survey } = context\n return getNodeDefParent({ survey, nodeDef })\n },\n },\n prevCycleValue: {\n minArity: 1,\n maxArity: 1,\n executor: emptyExecutor,\n },\n prevCycleValues: {\n minArity: 1,\n maxArity: 1,\n executor: emptyExecutor,\n },\n recordCycle: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordDateCreated: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordDateLastModified: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerEmail: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerName: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerRole: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n sum: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: (_context: NodeDefExpressionContext) => (_nodeSet) => 1,\n },\n taxonProp: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) => async (taxonomyName: string, propName: string, taxonCode: string) => {\n if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(propName))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n if (Objects.isEmpty(taxonCode)) return null\n\n const { survey } = context\n const taxonomy = getTaxonomyByName({ survey, taxonomyName })\n if (!taxonomy) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName })\n\n const extraPropDef = taxonomy.props.extraPropsDefs?.[propName]\n if (!extraPropDef) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyExtraProp, { propName })\n\n const taxon = await getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode })\n if (!taxon) return null\n\n const value = taxon.props.extra?.[propName]\n return ExtraProps.convertValue({ survey, extraPropDef, value })\n },\n },\n taxonVernacularName: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n async (taxonomyName: string, vernacularLangCode: string, taxonCode: string) => {\n if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(vernacularLangCode))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n if (Objects.isEmpty(taxonCode)) return null\n\n const { survey } = context\n const taxonomy = getTaxonomyByName({ survey, taxonomyName })\n if (!taxonomy) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName })\n\n if (!LanguagesISO639part2[vernacularLangCode]) {\n throw new SystemError(SystemErrorKeys.expression.invalidTaxonVernacularNameLanguageCode, {\n vernacularLangCode,\n })\n }\n\n const taxon = await getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode })\n if (!taxon) return null\n\n const vernacularNameArray = taxon.vernacularNames?.[vernacularLangCode]\n // consider first vernacular name object only\n const firstVernacularName = vernacularNameArray?.[0]\n return firstVernacularName?.props?.name\n },\n },\n unique: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: (_context: NodeDefExpressionContext) => (_nodeSet) => [],\n },\n userEmail: {\n minArity: 0,\n maxArity: 0,\n executor: (context: NodeDefExpressionContext) => () => context.user?.email,\n },\n userIsRecordOwner: {\n minArity: 0,\n maxArity: 0,\n executor: (_context: NodeDefExpressionContext) => () => false,\n },\n userName: {\n minArity: 0,\n maxArity: 0,\n executor: (context: NodeDefExpressionContext) => () => context.user?.name,\n },\n userProp: {\n minArity: 1,\n maxArity: 1,\n executor: (context: NodeDefExpressionContext) => (propName: string) => {\n const { user, survey } = context\n if (!survey || !user) return undefined\n const { uuid: surveyUuid } = survey\n const combinedExtraProps = Users.getCombinedExtraProps(surveyUuid)(user)\n return combinedExtraProps[propName]\n },\n },\n}\n"]}
1
+ {"version":3,"file":"functions.js","sourceRoot":"","sources":["../../src/nodeDefExpressionEvaluator/functions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Users } from '../auth'\nimport { CategoryItem } from '../category'\nimport { SystemError, SystemErrorKeys } from '../error'\nimport { ExpressionFunctions } from '../expression'\nimport { ExtraProps } from '../extraProp/extraProps'\nimport { AreaOfInterest, Point, Points } from '../geo'\nimport { LanguagesISO639part2 } from '../language'\nimport { ArenaRecord } from '../record'\nimport { getNodeDefParent } from '../survey/surveys/nodeDefs'\nimport { getCategoryItemByCodePaths, getTaxonByCode } from '../survey/surveys/refsData'\nimport {\n getAreaOfInterestByName,\n getAreasOfInterest,\n getCategoryByName,\n getSRSIndex,\n getTaxonomyByName,\n} from '../survey/surveys/surveysGetters'\nimport { Taxon } from '../taxonomy'\nimport { Dates, Numbers, Objects } from '../utils'\nimport { NodeDefExpressionContext } from './context'\n\nconst sampleGeoJsonPolygon = {\n type: 'Feature',\n geometry: {\n type: 'Polygon',\n coordinates: [\n [\n [100.0, 0.0],\n [101.0, 0.0],\n [101.0, 1.0],\n [100.0, 1.0],\n [100.0, 0.0],\n ],\n ],\n },\n}\n\nconst isNotValidString = (value: string): boolean => Objects.isEmpty(value) || typeof value !== 'string'\n\nconst emptyExecutor = (_context: NodeDefExpressionContext) => () => null\n\nconst isUsingDraftProps = (context: NodeDefExpressionContext) => {\n // use draft props when validating expression or previewing record\n const record: ArenaRecord = (context as any).record\n return !record || !!record.preview\n}\n\nconst getOrFetchCategoryItem = async (params: {\n context: NodeDefExpressionContext\n categoryUuid: string\n codePaths: string[]\n}): Promise<CategoryItem | undefined> => {\n const { context, categoryUuid, codePaths } = params\n // if any code path is empty, return null (no category item can be found)\n if (Objects.isEmpty(codePaths) || codePaths.some(Objects.isEmpty)) {\n return undefined\n }\n const { survey, categoryItemProvider } = context\n const categoryItem = getCategoryItemByCodePaths({ survey, categoryUuid, codePaths })\n const draft = isUsingDraftProps(context)\n return categoryItem ?? categoryItemProvider?.getItemByCodePaths({ survey, categoryUuid, codePaths, draft })\n}\n\nconst getOrFetchTaxon = async (params: {\n context: NodeDefExpressionContext\n taxonomyUuid: string\n taxonCode: string\n}): Promise<Taxon | undefined> => {\n const { context, taxonomyUuid, taxonCode } = params\n if (typeof taxonCode !== 'string' && typeof taxonCode !== 'number') {\n return undefined // node def expression validator could call it passing a node def object\n }\n // if taxonCode is empty, return undefined\n if (Objects.isEmpty(taxonCode)) {\n return undefined\n }\n const { survey, taxonProvider } = context\n const taxon = getTaxonByCode({ survey, taxonomyUuid, taxonCode })\n // fetch draft props when validating expression or previewing record\n const record: ArenaRecord = (context as any).record\n const draft = !record || !!record.preview\n return taxon ?? taxonProvider?.getTaxonByCode({ survey, taxonomyUuid, taxonCode, draft })\n}\n\nconst fetchAreaOfInterest = async (params: {\n context: NodeDefExpressionContext\n name: string\n}): Promise<AreaOfInterest | undefined> => {\n const { context, name } = params\n const { survey, areaOfInterestProvider } = context\n if (!areaOfInterestProvider || !getAreaOfInterestByName({ survey, name })) return undefined\n return areaOfInterestProvider.getAreaOfInterest({ survey, name })\n}\n\n// expression validation (no record): a literal area name must be defined in the survey\nconst validateAreaOfInterestName = (params: { context: NodeDefExpressionContext; name: unknown }): void => {\n const { context, name } = params\n const record: ArenaRecord = (context as any).record\n if (!record && typeof name === 'string' && !getAreaOfInterestByName({ survey: context.survey, name })) {\n throw new SystemError(SystemErrorKeys.expression.areaOfInterestNotFound, { name })\n }\n}\n\nconst distanceToAreaOfInterestBoundary = async (params: {\n context: NodeDefExpressionContext\n point: Point\n name: string\n}): Promise<number | null> => {\n const { context, point, name } = params\n const areaOfInterest = await fetchAreaOfInterest({ context, name })\n if (!areaOfInterest) return null\n return Points.distanceToPolygonBoundary(point, areaOfInterest, getSRSIndex(context.survey))\n}\n\nconst geoDistanceExecutor =\n (context: NodeDefExpressionContext) =>\n (coordinateFrom: Point | string, coordinateTo: Point | string): number | null => {\n const { survey } = context\n const srsIndex = getSRSIndex(survey)\n\n const pointFrom = Points.parse(coordinateFrom)\n const pointTo = Points.parse(coordinateTo)\n\n return pointFrom && pointTo ? Points.distance(pointFrom, pointTo, srsIndex) : null\n }\n\nexport const nodeDefExpressionFunctions: ExpressionFunctions<NodeDefExpressionContext> = {\n categoryItemProp: {\n minArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n async (categoryName: string, itemPropName: string, ...codePaths: string[]): Promise<any> => {\n const { survey } = context\n\n if (Objects.isEmpty(categoryName) || Objects.isEmpty(itemPropName) || Objects.isEmpty(codePaths))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n\n const category = getCategoryByName({ survey, categoryName })\n if (!category) throw new SystemError(SystemErrorKeys.expression.invalidCategoryName, { name: categoryName })\n\n const { itemExtraDef } = category.props\n const extraPropDef =\n itemExtraDef && Object.hasOwn(itemExtraDef, itemPropName) ? itemExtraDef[itemPropName] : undefined\n if (!extraPropDef)\n throw new SystemError(SystemErrorKeys.expression.invalidCategoryExtraProp, { propName: itemPropName })\n\n const { uuid: categoryUuid } = category\n const categoryItem = await getOrFetchCategoryItem({ context, categoryUuid, codePaths })\n if (!categoryItem) return null\n\n const value = categoryItem.props.extra?.[itemPropName]\n return ExtraProps.convertValue({ survey, extraPropDef, value })\n },\n },\n count: {\n minArity: 1,\n maxArity: 1,\n executor:\n (_context: NodeDefExpressionContext) =>\n (_nodeSet): number =>\n 1,\n },\n dateTimeDiff: {\n minArity: 4,\n maxArity: 4,\n executor:\n (_context: NodeDefExpressionContext) =>\n (date1: string, time1: string, date2: string, time2: string): number | null => {\n if (isNotValidString(date1) || isNotValidString(time1) || isNotValidString(date2) || isNotValidString(time2))\n return null\n // computed in UTC: in the local time zone of the machine a DST change between the 2 dates would alter the result\n const toUtcMinutes = (date: string, time: string): number => {\n const [year, month, day] = date.split('-').map(Number)\n const [hours, minutes] = time.split(':').map(Number)\n return Date.UTC(year, month - 1, day, hours, minutes) / 60000\n }\n const diff = toUtcMinutes(date1, time1) - toUtcMinutes(date2, time2)\n return Number.isNaN(diff) ? null : diff\n },\n },\n // deprecated, use geoDistance instead\n distance: { minArity: 2, maxArity: 2, executor: geoDistanceExecutor },\n first: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: emptyExecutor,\n },\n geoCoordinateAtDistance: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n (coordinate: Point | string, distanceMeters: number, bearingDeg: number): Point | null => {\n // validate parameters\n const origin = Points.parse(coordinate)\n if (!origin) return null\n\n const distanceMetersNumber = Number(distanceMeters)\n const bearingDegNumber = Number(bearingDeg)\n if (!Number.isFinite(distanceMetersNumber) || distanceMetersNumber < 0 || !Number.isFinite(bearingDegNumber)) {\n return null\n }\n\n const { survey } = context\n const srsIndex = getSRSIndex(survey)\n\n return Points.pointAtDistance({\n origin,\n distanceMeters: distanceMetersNumber,\n bearingDeg: bearingDegNumber,\n srsIndex,\n })\n },\n },\n geoDistance: { minArity: 2, maxArity: 2, executor: geoDistanceExecutor },\n geoAOIContaining: {\n minArity: 1,\n maxArity: 1,\n executor:\n (context: NodeDefExpressionContext) =>\n async (coordinate: Point | string): Promise<string | null> => {\n const point = Points.parse(coordinate)\n if (!point || !context.areaOfInterestProvider) return null\n // the survey order is the priority of overlapping areas\n for (const { name } of getAreasOfInterest(context.survey)) {\n const distance = await distanceToAreaOfInterestBoundary({ context, point, name }) // NOSONAR\n if (distance !== null && distance <= 0) return name\n }\n return null\n },\n },\n geoDistanceToAOIBoundary: {\n minArity: 2,\n maxArity: 2,\n executor:\n (context: NodeDefExpressionContext) =>\n async (coordinate: Point | string, name: string): Promise<number | null> => {\n validateAreaOfInterestName({ context, name })\n const point = Points.parse(coordinate)\n if (!point || typeof name !== 'string') return null\n return distanceToAreaOfInterestBoundary({ context, point, name })\n },\n },\n geoPolygon: {\n minArity: 1,\n evaluateArgsToNodes: true,\n executor: () => () => sampleGeoJsonPolygon,\n },\n includes: {\n minArity: 2,\n maxArity: 2,\n evaluateArgsToNodes: false,\n executor:\n () =>\n (items: any, value: any): boolean =>\n Array.isArray(items) && items.map(String).includes(String(value)),\n },\n index: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: () => () => -1,\n },\n last: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: emptyExecutor,\n },\n now: {\n minArity: 0,\n maxArity: 0,\n evaluateToNode: false,\n executor: () => () => Dates.nowFormattedForStorage(),\n },\n numberToWords: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: false,\n executor:\n (context: NodeDefExpressionContext) =>\n (value: any): string | null => {\n if (Objects.isEmpty(value)) return null\n return Numbers.toWords(value, context.lang)\n },\n },\n parent: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n evaluateToNode: true,\n executor: (context: NodeDefExpressionContext) => (nodeDef) => {\n const { survey } = context\n return getNodeDefParent({ survey, nodeDef })\n },\n },\n prevCycleValue: {\n minArity: 1,\n maxArity: 1,\n executor: emptyExecutor,\n },\n prevCycleValues: {\n minArity: 1,\n maxArity: 1,\n executor: emptyExecutor,\n },\n recordCycle: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordDateCreated: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordDateLastModified: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerEmail: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerName: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n recordOwnerRole: {\n minArity: 0,\n maxArity: 0,\n executor: emptyExecutor,\n },\n sum: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: (_context: NodeDefExpressionContext) => (_nodeSet) => 1,\n },\n taxonProp: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) => async (taxonomyName: string, propName: string, taxonCode: string) => {\n if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(propName))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n if (Objects.isEmpty(taxonCode)) return null\n\n const { survey } = context\n const taxonomy = getTaxonomyByName({ survey, taxonomyName })\n if (!taxonomy) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName })\n\n const { extraPropsDefs } = taxonomy.props\n const extraPropDef =\n extraPropsDefs && Object.hasOwn(extraPropsDefs, propName) ? extraPropsDefs[propName] : undefined\n if (!extraPropDef) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyExtraProp, { propName })\n\n const taxon = await getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode })\n if (!taxon) return null\n\n const value = taxon.props.extra?.[propName]\n return ExtraProps.convertValue({ survey, extraPropDef, value })\n },\n },\n taxonVernacularName: {\n minArity: 3,\n maxArity: 3,\n executor:\n (context: NodeDefExpressionContext) =>\n async (taxonomyName: string, vernacularLangCode: string, taxonCode: string) => {\n if (Objects.isEmpty(taxonomyName) || Objects.isEmpty(vernacularLangCode))\n throw new SystemError(SystemErrorKeys.expression.missingFunctionParameters)\n if (Objects.isEmpty(taxonCode)) return null\n\n const { survey } = context\n const taxonomy = getTaxonomyByName({ survey, taxonomyName })\n if (!taxonomy) throw new SystemError(SystemErrorKeys.expression.invalidTaxonomyName, { name: taxonomyName })\n\n if (!Object.hasOwn(LanguagesISO639part2, vernacularLangCode)) {\n throw new SystemError(SystemErrorKeys.expression.invalidTaxonVernacularNameLanguageCode, {\n vernacularLangCode,\n })\n }\n\n const taxon = await getOrFetchTaxon({ context, taxonomyUuid: taxonomy.uuid, taxonCode })\n if (!taxon) return null\n\n const vernacularNameArray = taxon.vernacularNames?.[vernacularLangCode]\n // consider first vernacular name object only\n const firstVernacularName = vernacularNameArray?.[0]\n return firstVernacularName?.props?.name\n },\n },\n unique: {\n minArity: 1,\n maxArity: 1,\n evaluateArgsToNodes: true,\n executor: (_context: NodeDefExpressionContext) => (_nodeSet) => [],\n },\n userEmail: {\n minArity: 0,\n maxArity: 0,\n executor: (context: NodeDefExpressionContext) => () => context.user?.email,\n },\n userIsRecordOwner: {\n minArity: 0,\n maxArity: 0,\n executor: (_context: NodeDefExpressionContext) => () => false,\n },\n userName: {\n minArity: 0,\n maxArity: 0,\n executor: (context: NodeDefExpressionContext) => () => context.user?.name,\n },\n userProp: {\n minArity: 1,\n maxArity: 1,\n executor: (context: NodeDefExpressionContext) => (propName: string) => {\n const { user, survey } = context\n if (!survey || !user) return undefined\n const { uuid: surveyUuid } = survey\n const combinedExtraProps = Users.getCombinedExtraProps(surveyUuid)(user)\n return Object.hasOwn(combinedExtraProps, propName) ? combinedExtraProps[propName] : undefined\n },\n },\n}\n"]}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "OpenForis",
5
5
  "email": "openforis.arena@gmail.com"
6
6
  },
7
- "version": "2.18.0",
7
+ "version": "2.18.1",
8
8
  "description": "Arena core module",
9
9
  "repository": {
10
10
  "type": "git",