@openforis/arena-core 2.18.0 → 2.18.2

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.
Files changed (35) hide show
  1. package/dist/esm/expression/javascript/global.js +2 -0
  2. package/dist/esm/expression/javascript/global.js.map +1 -1
  3. package/dist/esm/expression/javascript/node/call.js +23 -4
  4. package/dist/esm/expression/javascript/node/call.js.map +1 -1
  5. package/dist/esm/expression/javascript/node/identifier.js +3 -3
  6. package/dist/esm/expression/javascript/node/identifier.js.map +1 -1
  7. package/dist/esm/nodeDefExpressionEvaluator/functions.js +10 -8
  8. package/dist/esm/nodeDefExpressionEvaluator/functions.js.map +1 -1
  9. package/dist/esm/record/_records/recordGetters.js +6 -0
  10. package/dist/esm/record/_records/recordGetters.js.map +1 -1
  11. package/dist/esm/record/_records/recordUpdater.js +2 -2
  12. package/dist/esm/record/_records/recordUpdater.js.map +1 -1
  13. package/dist/esm/record/recordNodesUpdater/recordNodesDeleter.js +1 -2
  14. package/dist/esm/record/recordNodesUpdater/recordNodesDeleter.js.map +1 -1
  15. package/dist/esm/record/recordNodesUpdater/recordNodesUpdater.js +3 -2
  16. package/dist/esm/record/recordNodesUpdater/recordNodesUpdater.js.map +1 -1
  17. package/dist/expression/javascript/global.d.ts +1 -0
  18. package/dist/expression/javascript/global.js +4 -1
  19. package/dist/expression/javascript/global.js.map +1 -1
  20. package/dist/expression/javascript/node/call.js +22 -3
  21. package/dist/expression/javascript/node/call.js.map +1 -1
  22. package/dist/expression/javascript/node/identifier.js +2 -2
  23. package/dist/expression/javascript/node/identifier.js.map +1 -1
  24. package/dist/nodeDefExpressionEvaluator/functions.js +10 -8
  25. package/dist/nodeDefExpressionEvaluator/functions.js.map +1 -1
  26. package/dist/record/_records/recordGetters.d.ts +6 -1
  27. package/dist/record/_records/recordGetters.js +8 -1
  28. package/dist/record/_records/recordGetters.js.map +1 -1
  29. package/dist/record/_records/recordUpdater.js +2 -2
  30. package/dist/record/_records/recordUpdater.js.map +1 -1
  31. package/dist/record/recordNodesUpdater/recordNodesDeleter.js +1 -2
  32. package/dist/record/recordNodesUpdater/recordNodesDeleter.js.map +1 -1
  33. package/dist/record/recordNodesUpdater/recordNodesUpdater.js +3 -2
  34. package/dist/record/recordNodesUpdater/recordNodesUpdater.js.map +1 -1
  35. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"recordUpdater.js","sourceRoot":"","sources":["../../../../src/record/_records/recordUpdater.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,aAAa,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AACnE,OAAO,EAAuB,2BAA2B,EAAE,MAAM,uBAAuB,CAAA;AAExF,MAAM,CAAC,MAAM,QAAQ,GACnB,CAAC,KAAyC,EAAE,OAAO,GAAwB,2BAA2B,EAAE,EAAE,CAC1G,CAAC,MAAmB,EAAe,EAAE;;IACnC,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,mCAAQ,2BAA2B,GAAK,OAAO,CAAE,CAAA;IAElG,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,mBAAM,MAAM,CAAE,CAAA;IACzD,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;IACzD,MAAM,KAAK,SAAG,aAAa,CAAC,WAAW,mCAAI,EAAE,CAAA;IAE7C,6FAA6F;IAC7F,sEAAsE;IACtE,MAAM,YAAY,GAAuC,EAAE,CAAA;IAC3D,IAAI,gBAAgB,EAAE,CAAC;QACrB,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;YACtC,IAAI,CAAC,uBAAuB,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBAC7E,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,aAAa,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IACzD,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,KAAK,mCAAQ,WAAW,GAAK,KAAK,CAAE,CAAA;IACpD,CAAC;IACD,IAAI,gBAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7D,aAAa,CAAC,WAAW,GAAG,uBAAuB,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;IAC9G,CAAC;IACD,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA;AAEH,MAAM,CAAC,MAAM,OAAO,GAClB,CAAC,IAAqB,EAAE,OAAO,GAAwB,2BAA2B,EAAE,EAAE,CACtF,CAAC,MAAmB,EAAE,EAAE,CACtB,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA","sourcesContent":["import { ArenaRecordNode } from '../../node'\nimport { ArenaRecord } from '../record'\nimport * as RecordGetters from './recordGetters'\nimport { RecordNodesIndexUpdater } from './recordNodesIndexUpdater'\nimport { RecordUpdateOptions, RecordUpdateOptionsDefaults } from './recordUpdateOptions'\n\nexport const addNodes =\n (nodes: { [key: string]: ArenaRecordNode }, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord): ArenaRecord => {\n const { sideEffect, updateNodesIndex, sortNodes } = { ...RecordUpdateOptionsDefaults, ...options }\n\n const recordUpdated = sideEffect ? record : { ...record }\n const recordNodes = RecordGetters.getNodes(recordUpdated)\n const index = recordUpdated._nodesIndex ?? {}\n\n // index only the nodes not already indexed with the same parent, node def and hierarchy code\n // (e.g. nodes with only an updated value don't need any index change)\n const nodesToIndex: { [key: string]: ArenaRecordNode } = {}\n if (updateNodesIndex) {\n for (const [nodeUuid, node] of Object.entries(nodes)) {\n const nodePrev = recordNodes[nodeUuid]\n if (!RecordNodesIndexUpdater.isNodeIndexUnchanged({ index, node, nodePrev })) {\n nodesToIndex[nodeUuid] = node\n }\n }\n }\n\n if (sideEffect) {\n recordUpdated.nodes = Object.assign(recordNodes, nodes)\n } else {\n recordUpdated.nodes = { ...recordNodes, ...nodes }\n }\n if (updateNodesIndex && Object.keys(nodesToIndex).length > 0) {\n recordUpdated._nodesIndex = RecordNodesIndexUpdater.addNodes(nodesToIndex, { sideEffect, sortNodes })(index)\n }\n return recordUpdated\n }\n\nexport const addNode =\n (node: ArenaRecordNode, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord) =>\n addNodes({ [node.uuid]: node }, options)(record)\n"]}
1
+ {"version":3,"file":"recordUpdater.js","sourceRoot":"","sources":["../../../../src/record/_records/recordUpdater.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,aAAa,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AACnE,OAAO,EAAuB,2BAA2B,EAAE,MAAM,uBAAuB,CAAA;AAExF,MAAM,CAAC,MAAM,QAAQ,GACnB,CAAC,KAAyC,EAAE,OAAO,GAAwB,2BAA2B,EAAE,EAAE,CAC1G,CAAC,MAAmB,EAAe,EAAE;IACnC,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,mCAAQ,2BAA2B,GAAK,OAAO,CAAE,CAAA;IAElG,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,mBAAM,MAAM,CAAE,CAAA;IACzD,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;IACzD,iGAAiG;IACjG,MAAM,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEvF,6FAA6F;IAC7F,sEAAsE;IACtE,MAAM,YAAY,GAAuC,EAAE,CAAA;IAC3D,IAAI,gBAAgB,EAAE,CAAC;QACrB,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;YACtC,IAAI,CAAC,uBAAuB,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBAC7E,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,aAAa,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IACzD,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,KAAK,mCAAQ,WAAW,GAAK,KAAK,CAAE,CAAA;IACpD,CAAC;IACD,IAAI,gBAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7D,aAAa,CAAC,WAAW,GAAG,uBAAuB,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;IAC9G,CAAC;IACD,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA;AAEH,MAAM,CAAC,MAAM,OAAO,GAClB,CAAC,IAAqB,EAAE,OAAO,GAAwB,2BAA2B,EAAE,EAAE,CACtF,CAAC,MAAmB,EAAE,EAAE,CACtB,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA","sourcesContent":["import { ArenaRecordNode } from '../../node'\nimport { ArenaRecord } from '../record'\nimport * as RecordGetters from './recordGetters'\nimport { RecordNodesIndexUpdater } from './recordNodesIndexUpdater'\nimport { RecordUpdateOptions, RecordUpdateOptionsDefaults } from './recordUpdateOptions'\n\nexport const addNodes =\n (nodes: { [key: string]: ArenaRecordNode }, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord): ArenaRecord => {\n const { sideEffect, updateNodesIndex, sortNodes } = { ...RecordUpdateOptionsDefaults, ...options }\n\n const recordUpdated = sideEffect ? record : { ...record }\n const recordNodes = RecordGetters.getNodes(recordUpdated)\n // index got before adding the new nodes (a missing index is built from the current record nodes)\n const index = updateNodesIndex ? RecordGetters.getNodesIndexOrBuild(recordUpdated) : {}\n\n // index only the nodes not already indexed with the same parent, node def and hierarchy code\n // (e.g. nodes with only an updated value don't need any index change)\n const nodesToIndex: { [key: string]: ArenaRecordNode } = {}\n if (updateNodesIndex) {\n for (const [nodeUuid, node] of Object.entries(nodes)) {\n const nodePrev = recordNodes[nodeUuid]\n if (!RecordNodesIndexUpdater.isNodeIndexUnchanged({ index, node, nodePrev })) {\n nodesToIndex[nodeUuid] = node\n }\n }\n }\n\n if (sideEffect) {\n recordUpdated.nodes = Object.assign(recordNodes, nodes)\n } else {\n recordUpdated.nodes = { ...recordNodes, ...nodes }\n }\n if (updateNodesIndex && Object.keys(nodesToIndex).length > 0) {\n recordUpdated._nodesIndex = RecordNodesIndexUpdater.addNodes(nodesToIndex, { sideEffect, sortNodes })(index)\n }\n return recordUpdated\n }\n\nexport const addNode =\n (node: ArenaRecordNode, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord) =>\n addNodes({ [node.uuid]: node }, options)(record)\n"]}
@@ -33,7 +33,6 @@ const _dissocValidationFieldsOfDeletedNodes = (params) => {
33
33
  return Object.assign(Object.assign({}, validation), { fields: fieldsUpdated });
34
34
  };
35
35
  export const removeNodes = (nodeUuids, options = RecordUpdateOptionsDefaults) => (record) => {
36
- var _a;
37
36
  const { sideEffect, updateNodesIndex } = Object.assign(Object.assign({}, RecordUpdateOptionsDefaults), options);
38
37
  const recordUpdated = sideEffect ? record : Object.assign({}, record);
39
38
  const recordNodes = RecordGetters.getNodes(recordUpdated);
@@ -64,7 +63,7 @@ export const removeNodes = (nodeUuids, options = RecordUpdateOptionsDefaults) =>
64
63
  recordUpdated.nodes = recordNodesUpdated;
65
64
  // update nodes index (copying every index part only once)
66
65
  if (updateNodesIndex) {
67
- recordUpdated._nodesIndex = RecordNodesIndexUpdater.removeNodes(Object.values(nodesDeleted), { sideEffect })((_a = record._nodesIndex) !== null && _a !== void 0 ? _a : {});
66
+ recordUpdated._nodesIndex = RecordNodesIndexUpdater.removeNodes(Object.values(nodesDeleted), { sideEffect })(RecordGetters.getNodesIndexOrBuild(record));
68
67
  }
69
68
  return new RecordUpdateResult({ record: recordUpdated, nodes: nodesDeleted, nodesDeleted });
70
69
  };
@@ -1 +1 @@
1
- {"version":3,"file":"recordNodesDeleter.js","sourceRoot":"","sources":["../../../../src/record/recordNodesUpdater/recordNodesDeleter.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArenaRecordNode, NodesMap } from '../../node'\nimport { Validation, Validations } from '../../validation'\nimport * as RecordGetters from '../_records/recordGetters'\nimport { RecordNodesIndexUpdater } from '../_records/recordNodesIndexUpdater'\nimport { RecordUpdateOptions, RecordUpdateOptionsDefaults } from '../_records/recordUpdateOptions'\nimport { ArenaRecord } from '../record'\nimport { RecordValidations } from '../recordValidations'\nimport { RecordUpdateResult } from './recordUpdateResult'\n\nconst _getChildrenCountValidationParentUuid = (fieldKey: string): string | undefined => {\n if (!RecordValidations.isValidationChildrenCountKey(fieldKey)) return undefined\n // children count field key format: {prefix}{parentUuid}_{childDefUuid}\n const keyWithoutPrefix = fieldKey.substring(RecordValidations.prefixValidationFieldChildrenCount.length)\n const separatorIndex = keyWithoutPrefix.indexOf('_')\n return separatorIndex >= 0 ? keyWithoutPrefix.substring(0, separatorIndex) : keyWithoutPrefix\n}\n\n/**\n * Removes the validation of the deleted nodes and the validation of their children count.\n */\nconst _dissocValidationFieldsOfDeletedNodes = (params: {\n validation: Validation\n nodesDeleted: NodesMap\n sideEffect: boolean\n}): Validation => {\n const { validation, nodesDeleted, sideEffect } = params\n const fields = Validations.getFieldValidations(validation)\n const fieldsUpdated = sideEffect ? fields : { ...fields }\n for (const fieldKey of Object.keys(fieldsUpdated)) {\n const nodeUuid = _getChildrenCountValidationParentUuid(fieldKey) ?? fieldKey\n if (nodesDeleted[nodeUuid]) {\n delete fieldsUpdated[fieldKey]\n }\n }\n if (sideEffect) {\n validation.fields = fieldsUpdated\n return validation\n }\n return { ...validation, fields: fieldsUpdated }\n}\n\nexport const removeNodes =\n (nodeUuids: string[], options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord): RecordUpdateResult => {\n const { sideEffect, updateNodesIndex } = { ...RecordUpdateOptionsDefaults, ...options }\n\n const recordUpdated = sideEffect ? record : { ...record }\n\n const recordNodes = RecordGetters.getNodes(recordUpdated)\n\n const nodesDeleted: NodesMap = {}\n const recordNodesUpdated = sideEffect ? recordNodes : { ...recordNodes }\n\n const deleteDescendantNode = (visitedNode: ArenaRecordNode) => {\n const visitedNodeUuid = visitedNode.uuid\n if (nodesDeleted[visitedNodeUuid]) return\n\n // delete node from 'nodes'\n delete recordNodesUpdated[visitedNodeUuid]\n\n const visitedNodeUpdated = sideEffect ? visitedNode : { ...visitedNode }\n visitedNodeUpdated.deleted = true\n nodesDeleted[visitedNodeUuid] = visitedNodeUpdated\n }\n\n nodeUuids.forEach((nodeUuid) => {\n const node = recordNodesUpdated[nodeUuid]\n if (!node) return\n\n RecordGetters.visitDescendantsAndSelf(node, deleteDescendantNode)(record)\n })\n\n // delete nodes from validation (in a single pass over the validation fields)\n recordUpdated.validation = Validations.cleanup(\n _dissocValidationFieldsOfDeletedNodes({\n validation: Validations.getValidation(record),\n nodesDeleted,\n sideEffect: !!sideEffect,\n })\n )\n\n recordUpdated.nodes = recordNodesUpdated\n // update nodes index (copying every index part only once)\n if (updateNodesIndex) {\n recordUpdated._nodesIndex = RecordNodesIndexUpdater.removeNodes(Object.values(nodesDeleted), { sideEffect })(\n record._nodesIndex ?? {}\n )\n }\n return new RecordUpdateResult({ record: recordUpdated, nodes: nodesDeleted, nodesDeleted })\n }\n\nexport const removeNode =\n (nodeUuid: string, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord): RecordUpdateResult =>\n removeNodes([nodeUuid], options)(record)\n"]}
1
+ {"version":3,"file":"recordNodesDeleter.js","sourceRoot":"","sources":["../../../../src/record/recordNodesUpdater/recordNodesDeleter.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArenaRecordNode, NodesMap } from '../../node'\nimport { Validation, Validations } from '../../validation'\nimport * as RecordGetters from '../_records/recordGetters'\nimport { RecordNodesIndexUpdater } from '../_records/recordNodesIndexUpdater'\nimport { RecordUpdateOptions, RecordUpdateOptionsDefaults } from '../_records/recordUpdateOptions'\nimport { ArenaRecord } from '../record'\nimport { RecordValidations } from '../recordValidations'\nimport { RecordUpdateResult } from './recordUpdateResult'\n\nconst _getChildrenCountValidationParentUuid = (fieldKey: string): string | undefined => {\n if (!RecordValidations.isValidationChildrenCountKey(fieldKey)) return undefined\n // children count field key format: {prefix}{parentUuid}_{childDefUuid}\n const keyWithoutPrefix = fieldKey.substring(RecordValidations.prefixValidationFieldChildrenCount.length)\n const separatorIndex = keyWithoutPrefix.indexOf('_')\n return separatorIndex >= 0 ? keyWithoutPrefix.substring(0, separatorIndex) : keyWithoutPrefix\n}\n\n/**\n * Removes the validation of the deleted nodes and the validation of their children count.\n */\nconst _dissocValidationFieldsOfDeletedNodes = (params: {\n validation: Validation\n nodesDeleted: NodesMap\n sideEffect: boolean\n}): Validation => {\n const { validation, nodesDeleted, sideEffect } = params\n const fields = Validations.getFieldValidations(validation)\n const fieldsUpdated = sideEffect ? fields : { ...fields }\n for (const fieldKey of Object.keys(fieldsUpdated)) {\n const nodeUuid = _getChildrenCountValidationParentUuid(fieldKey) ?? fieldKey\n if (nodesDeleted[nodeUuid]) {\n delete fieldsUpdated[fieldKey]\n }\n }\n if (sideEffect) {\n validation.fields = fieldsUpdated\n return validation\n }\n return { ...validation, fields: fieldsUpdated }\n}\n\nexport const removeNodes =\n (nodeUuids: string[], options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord): RecordUpdateResult => {\n const { sideEffect, updateNodesIndex } = { ...RecordUpdateOptionsDefaults, ...options }\n\n const recordUpdated = sideEffect ? record : { ...record }\n\n const recordNodes = RecordGetters.getNodes(recordUpdated)\n\n const nodesDeleted: NodesMap = {}\n const recordNodesUpdated = sideEffect ? recordNodes : { ...recordNodes }\n\n const deleteDescendantNode = (visitedNode: ArenaRecordNode) => {\n const visitedNodeUuid = visitedNode.uuid\n if (nodesDeleted[visitedNodeUuid]) return\n\n // delete node from 'nodes'\n delete recordNodesUpdated[visitedNodeUuid]\n\n const visitedNodeUpdated = sideEffect ? visitedNode : { ...visitedNode }\n visitedNodeUpdated.deleted = true\n nodesDeleted[visitedNodeUuid] = visitedNodeUpdated\n }\n\n nodeUuids.forEach((nodeUuid) => {\n const node = recordNodesUpdated[nodeUuid]\n if (!node) return\n\n RecordGetters.visitDescendantsAndSelf(node, deleteDescendantNode)(record)\n })\n\n // delete nodes from validation (in a single pass over the validation fields)\n recordUpdated.validation = Validations.cleanup(\n _dissocValidationFieldsOfDeletedNodes({\n validation: Validations.getValidation(record),\n nodesDeleted,\n sideEffect: !!sideEffect,\n })\n )\n\n recordUpdated.nodes = recordNodesUpdated\n // update nodes index (copying every index part only once)\n if (updateNodesIndex) {\n recordUpdated._nodesIndex = RecordNodesIndexUpdater.removeNodes(Object.values(nodesDeleted), { sideEffect })(\n RecordGetters.getNodesIndexOrBuild(record)\n )\n }\n return new RecordUpdateResult({ record: recordUpdated, nodes: nodesDeleted, nodesDeleted })\n }\n\nexport const removeNode =\n (nodeUuid: string, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord): RecordUpdateResult =>\n removeNodes([nodeUuid], options)(record)\n"]}
@@ -46,8 +46,9 @@ const dependentsUpdaters = [
46
46
  ];
47
47
  export const updateNodesDependents = (params) => __awaiter(void 0, void 0, void 0, function* () {
48
48
  var _a;
49
- const { survey, record, nodes, sideEffect = false } = params;
50
- const initialNodesToVisit = sideEffect ? nodes : Object.assign({}, nodes);
49
+ const { survey, record, nodes } = params;
50
+ // always copy: the nodes passed (e.g. the deleted nodes) must not collect the dependent nodes visited
51
+ const initialNodesToVisit = Object.assign({}, nodes);
51
52
  // include onUpdate dependents (always included in every record update)
52
53
  const onUpdateDependentDefs = Surveys.getOnUpdateDependents({ survey });
53
54
  if (onUpdateDependentDefs.length > 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"recordNodesUpdater.js","sourceRoot":"","sources":["../../../../src/record/recordNodesUpdater/recordNodesUpdater.ts"],"names":[],"mappings":"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","sourcesContent":["import { Queue } from '../../utils'\n\nimport { Dictionary } from '../../common'\nimport { ArenaRecordNode } from '../../node'\nimport { NodeDefCountType } from '../../nodeDef'\nimport { Surveys } from '../../survey'\nimport { getNodesByDefUuid } from '../_records/recordGetters'\nimport { updateSelfAndDependentsApplicable } from './recordNodeDependentsApplicableUpdater'\nimport { updateDependentCodeAttributes } from './recordNodeDependentsCodeAttributesUpdater'\nimport { updateDependentsCount } from './recordNodeDependentsCountUpdater'\nimport { updateSelfAndDependentsDefaultValues } from './recordNodeDependentsDefaultValuesUpdater'\nimport { updateSelfAndDependentsEditable } from './recordNodeDependentsEditableUpdater'\nimport { updateDependentEnumeratedEntities } from './recordNodeDependentsEnumeratedEntitiesUpdater'\nimport { updateDependentEnumeratingItemsEntities } from './recordNodeDependentsEnumeratingItemsUpdater'\nimport { updateSelfAndDependentsFileNames } from './recordNodeDependentsFileNamesEvaluator'\nimport { RecordNodeDependentsUpdateParams } from './recordNodeDependentsUpdateParams'\nimport { updateSelfAndDependentsRequired } from './recordNodeDependentsRequiredUpdater'\nimport { updateSelfAndDependentsVisible } from './recordNodeDependentsVisibleUpdater'\nimport { NodesUpdateParams } from './recordNodesCreator'\nimport { RecordUpdateResult } from './recordUpdateResult'\n\n/**\n * Nodes can be visited maximum 2 times during the update of the dependent nodes, to avoid loops in the evaluation.\n * The first time the applicability can depend on attributes with default values not applied yet.\n * The second time the applicability expression can be evaluated correctly.\n */\nconst MAX_DEPENDENTS_VISITING_TIMES = 2\n\ntype RecordNodeDependentsUpdater = (params: RecordNodeDependentsUpdateParams) => Promise<RecordUpdateResult>\n\n/**\n * Updaters applied (in this order) to every visited node and to its dependents.\n */\nconst dependentsUpdaters: RecordNodeDependentsUpdater[] = [\n (params) => updateDependentsCount({ ...params, countType: NodeDefCountType.min }),\n (params) => updateDependentsCount({ ...params, countType: NodeDefCountType.max }),\n updateSelfAndDependentsApplicable,\n updateSelfAndDependentsDefaultValues,\n updateSelfAndDependentsEditable,\n updateSelfAndDependentsRequired,\n updateSelfAndDependentsVisible,\n updateDependentCodeAttributes,\n updateDependentEnumeratedEntities,\n updateDependentEnumeratingItemsEntities,\n updateSelfAndDependentsFileNames,\n]\n\nexport const updateNodesDependents = async (\n params: NodesUpdateParams & { nodes: Dictionary<ArenaRecordNode> }\n): Promise<RecordUpdateResult> => {\n const { survey, record, nodes, sideEffect = false } = params\n const initialNodesToVisit = sideEffect ? nodes : { ...nodes }\n\n // include onUpdate dependents (always included in every record update)\n const onUpdateDependentDefs = Surveys.getOnUpdateDependents({ survey })\n if (onUpdateDependentDefs.length > 0) {\n for (const dependentDef of onUpdateDependentDefs) {\n const dependentNodes = getNodesByDefUuid(dependentDef.uuid)(record)\n for (const node of dependentNodes) {\n initialNodesToVisit[node.uuid] = node\n }\n }\n }\n\n const updateResult = new RecordUpdateResult({ record, nodes: initialNodesToVisit })\n\n const createNodeUpdateParams = (node: ArenaRecordNode): RecordNodeDependentsUpdateParams => ({\n ...params,\n record: updateResult.record, // updateResult.record changes at every step (when sideEffect=false)\n node,\n })\n\n const nodeUuidsToVisit = new Queue(Object.keys(initialNodesToVisit))\n\n // Avoid loops: visit the same node maximum 2 times (the second time the applicability could have been changed)\n const visitedCountByUuid: Dictionary<number> = {}\n\n while (!nodeUuidsToVisit.isEmpty()) {\n const nodeUuid = nodeUuidsToVisit.dequeue()!\n\n const visitedCount = visitedCountByUuid[nodeUuid] ?? 0\n\n if (visitedCount < MAX_DEPENDENTS_VISITING_TIMES) {\n const nodesUpdatedCurrent: Dictionary<ArenaRecordNode> = {}\n for (const dependentsUpdater of dependentsUpdaters) {\n // updaters must run sequentially: each one works on the record (and node) updated by the previous ones\n const node = updateResult.getNodeByUuid(nodeUuid)\n const dependentsUpdateResult = await dependentsUpdater(createNodeUpdateParams(node)) // NOSONAR\n updateResult.merge(dependentsUpdateResult)\n Object.assign(nodesUpdatedCurrent, dependentsUpdateResult.nodes)\n }\n\n // Mark updated nodes to visit\n nodeUuidsToVisit.enqueueItems(Object.keys(nodesUpdatedCurrent))\n\n // Mark node as visited\n visitedCountByUuid[nodeUuid] = visitedCount + 1\n }\n }\n\n return updateResult\n}\n"]}
1
+ {"version":3,"file":"recordNodesUpdater.js","sourceRoot":"","sources":["../../../../src/record/recordNodesUpdater/recordNodesUpdater.ts"],"names":[],"mappings":"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","sourcesContent":["import { Queue } from '../../utils'\n\nimport { Dictionary } from '../../common'\nimport { ArenaRecordNode } from '../../node'\nimport { NodeDefCountType } from '../../nodeDef'\nimport { Surveys } from '../../survey'\nimport { getNodesByDefUuid } from '../_records/recordGetters'\nimport { updateSelfAndDependentsApplicable } from './recordNodeDependentsApplicableUpdater'\nimport { updateDependentCodeAttributes } from './recordNodeDependentsCodeAttributesUpdater'\nimport { updateDependentsCount } from './recordNodeDependentsCountUpdater'\nimport { updateSelfAndDependentsDefaultValues } from './recordNodeDependentsDefaultValuesUpdater'\nimport { updateSelfAndDependentsEditable } from './recordNodeDependentsEditableUpdater'\nimport { updateDependentEnumeratedEntities } from './recordNodeDependentsEnumeratedEntitiesUpdater'\nimport { updateDependentEnumeratingItemsEntities } from './recordNodeDependentsEnumeratingItemsUpdater'\nimport { updateSelfAndDependentsFileNames } from './recordNodeDependentsFileNamesEvaluator'\nimport { RecordNodeDependentsUpdateParams } from './recordNodeDependentsUpdateParams'\nimport { updateSelfAndDependentsRequired } from './recordNodeDependentsRequiredUpdater'\nimport { updateSelfAndDependentsVisible } from './recordNodeDependentsVisibleUpdater'\nimport { NodesUpdateParams } from './recordNodesCreator'\nimport { RecordUpdateResult } from './recordUpdateResult'\n\n/**\n * Nodes can be visited maximum 2 times during the update of the dependent nodes, to avoid loops in the evaluation.\n * The first time the applicability can depend on attributes with default values not applied yet.\n * The second time the applicability expression can be evaluated correctly.\n */\nconst MAX_DEPENDENTS_VISITING_TIMES = 2\n\ntype RecordNodeDependentsUpdater = (params: RecordNodeDependentsUpdateParams) => Promise<RecordUpdateResult>\n\n/**\n * Updaters applied (in this order) to every visited node and to its dependents.\n */\nconst dependentsUpdaters: RecordNodeDependentsUpdater[] = [\n (params) => updateDependentsCount({ ...params, countType: NodeDefCountType.min }),\n (params) => updateDependentsCount({ ...params, countType: NodeDefCountType.max }),\n updateSelfAndDependentsApplicable,\n updateSelfAndDependentsDefaultValues,\n updateSelfAndDependentsEditable,\n updateSelfAndDependentsRequired,\n updateSelfAndDependentsVisible,\n updateDependentCodeAttributes,\n updateDependentEnumeratedEntities,\n updateDependentEnumeratingItemsEntities,\n updateSelfAndDependentsFileNames,\n]\n\nexport const updateNodesDependents = async (\n params: NodesUpdateParams & { nodes: Dictionary<ArenaRecordNode> }\n): Promise<RecordUpdateResult> => {\n const { survey, record, nodes } = params\n // always copy: the nodes passed (e.g. the deleted nodes) must not collect the dependent nodes visited\n const initialNodesToVisit = { ...nodes }\n\n // include onUpdate dependents (always included in every record update)\n const onUpdateDependentDefs = Surveys.getOnUpdateDependents({ survey })\n if (onUpdateDependentDefs.length > 0) {\n for (const dependentDef of onUpdateDependentDefs) {\n const dependentNodes = getNodesByDefUuid(dependentDef.uuid)(record)\n for (const node of dependentNodes) {\n initialNodesToVisit[node.uuid] = node\n }\n }\n }\n\n const updateResult = new RecordUpdateResult({ record, nodes: initialNodesToVisit })\n\n const createNodeUpdateParams = (node: ArenaRecordNode): RecordNodeDependentsUpdateParams => ({\n ...params,\n record: updateResult.record, // updateResult.record changes at every step (when sideEffect=false)\n node,\n })\n\n const nodeUuidsToVisit = new Queue(Object.keys(initialNodesToVisit))\n\n // Avoid loops: visit the same node maximum 2 times (the second time the applicability could have been changed)\n const visitedCountByUuid: Dictionary<number> = {}\n\n while (!nodeUuidsToVisit.isEmpty()) {\n const nodeUuid = nodeUuidsToVisit.dequeue()!\n\n const visitedCount = visitedCountByUuid[nodeUuid] ?? 0\n\n if (visitedCount < MAX_DEPENDENTS_VISITING_TIMES) {\n const nodesUpdatedCurrent: Dictionary<ArenaRecordNode> = {}\n for (const dependentsUpdater of dependentsUpdaters) {\n // updaters must run sequentially: each one works on the record (and node) updated by the previous ones\n const node = updateResult.getNodeByUuid(nodeUuid)\n const dependentsUpdateResult = await dependentsUpdater(createNodeUpdateParams(node)) // NOSONAR\n updateResult.merge(dependentsUpdateResult)\n Object.assign(nodesUpdatedCurrent, dependentsUpdateResult.nodes)\n }\n\n // Mark updated nodes to visit\n nodeUuidsToVisit.enqueueItems(Object.keys(nodesUpdatedCurrent))\n\n // Mark node as visited\n visitedCountByUuid[nodeUuid] = visitedCount + 1\n }\n }\n\n return updateResult\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":";;;;;;;;;;;;AAAA,0CAA6D;AAG7D,qCAMmB;AACnB,sCAAmD;AACnD,kDAAgF;AAEhF,gHAAgH;AAChH,MAAM,iCAAiC,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAA;AAElF,6FAA6F;AAC7F,MAAM,yBAAyB,GAAG,CAAC,MAAwB,EAAE,IAAW,EAAW,EAAE;IACnF,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IACrC,OAAO,CACL,CAAC,QAAQ;QACT,QAAQ,CAAC,IAAI,KAAK,yBAAkB,CAAC,UAAU;QAC/C,iCAAiC,CAAC,GAAG,CAAE,QAAiC,CAAC,IAAI,CAAC;QAC9E,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAC5B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG,CAAC,OAAe,EAAQ,EAAE;IACzD,IAAI,IAAA,mCAAoB,EAAC,OAAO,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;IACxF,CAAC;AACH,CAAC,CAAA;AAED,iHAAiH;AACjH,MAAM,sBAAsB,GAAG,CAAC,QAAa,EAAE,IAAW,EAAE,mBAA4B,EAAQ,EAAE;IAChG,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAA;IAClC,IAAI,CAAC,mBAAmB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,YAAY,MAAM,CAAC;QAAE,OAAM;IACpF,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,uCAAwB,CAAC,CAAA;IACjH,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,6BAA6B,EAAE;YAC9E,SAAS,EAAE,uCAAwB;YACnC,MAAM,EAAE,YAAY,CAAC,MAAM;SAC5B,CAAC,CAAA;IACJ,CAAC;AACH,CAAC,CAAA;AAED,mBAAwD,SAAQ,8BAA0C;IAClG,QAAQ,CAAC,cAA8B;;YAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,cAAc,CAAA;YAEjC,IAAI,MAAM,CAAC,IAAI,KAAK,yBAAkB,CAAC,MAAM,EAAE,CAAC;gBAC9C,OAAO,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;YACpD,CAAC;iBAAM,IAAI,MAAM,CAAC,IAAI,KAAK,yBAAkB,CAAC,UAAU,EAAE,CAAC;gBACzD,OAAO,IAAI,CAAC,kBAAkB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;YACxD,CAAC;YAED,iEAAiE;YACjE,sCAAsC;YACtC,MAAM,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;QAC5F,CAAC;KAAA;IAEa,cAAc,CAAC,cAA8B,EAAE,MAAwB;;YACnF,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAA;YAE9C,yCAAyC;YACzC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;YAClE,IAAI,EAAE,EAAE,CAAC;gBACP,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;gBACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;gBAC3E,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;gBAC9G,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,CAAA;gBACjC,MAAM,mBAAmB,GAAG,yBAAyB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;gBACnE,IAAI,mBAAmB,EAAE,CAAC;oBACxB,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;gBACnC,CAAC;gBACD,sBAAsB,CAAC,QAAQ,EAAE,IAAI,EAAE,mBAAmB,CAAC,CAAA;gBAC3D,OAAO,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAA;YACnC,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;KAAA;IAEa,kBAAkB,CAAC,cAA8B,EAAE,MAA4B;;YAC3F,8CAA8C;YAC9C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAA;YAC9C,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;YAE9C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;YAE/B,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;YACrD,IAAI,YAAY,EAAE,CAAC;gBACjB,8CAA8C;gBAC9C,OAAO,IAAI,CAAC,wBAAwB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;YAC9D,CAAC;YACD,gCAAgC;YAChC,MAAM,QAAQ,GAAG,IAAA,gCAAuB,EAAC,MAAM,EAAE,aAAa,CAAC,CAAA;YAC/D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,4GAA4G;gBAC5G,MAAM,UAAU,mCAAQ,IAAI,CAAC,OAAO,KAAE,cAAc,EAAE,KAAK,GAAE,CAAA;gBAC7D,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;gBACnG,OAAO,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAA;YAC1B,CAAC;YAED,MAAM,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QACvF,CAAC;KAAA;IAEa,wBAAwB,CAAC,cAA8B,EAAE,MAAc;;YACnF,8CAA8C;YAC9C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAA;YAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAA;YAE/B,MAAM,kBAAkB,GAA0B,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;YAElF,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAA;YAEhF,IAAI,OAAO,GAAG,QAAQ;gBACpB,MAAM,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,0BAA0B,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;YAC7G,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,IAAI,CAAC,IAAI,OAAO,GAAG,QAAQ;gBAC/D,MAAM,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;YAE9G,qBAAqB;YACrB,MAAM,WAAW,mCAAQ,IAAI,CAAC,OAAO,KAAE,cAAc,EAAE,mBAAmB,GAAE,CAAA;YAC5E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;YAEpG,uEAAuE;YACvE,wEAAwE;YACxE,sCAAsC;YACtC,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;QACxC,CAAC;KAAA;CACF","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"]}
@@ -2,10 +2,15 @@ import { Dictionary, TraverseMethod } from '../../common';
2
2
  import { ArenaRecordNode, NodePointer, NodesMap } from '../../node';
3
3
  import { NodeDef, NodeDefCode, NodeDefCodeProps, NodeDefProps, NodeDefType } from '../../nodeDef';
4
4
  import { Survey, SurveyDependencyType } from '../../survey/survey';
5
- import { ArenaRecord } from '../record';
5
+ import { ArenaRecord, RecordNodesIndex } from '../record';
6
6
  export declare const getCycle: (record: ArenaRecord) => string;
7
7
  export declare const getNodes: (record: ArenaRecord) => Dictionary<ArenaRecordNode>;
8
8
  export declare const getNodesArray: (record: ArenaRecord) => ArenaRecordNode[];
9
+ /**
10
+ * Returns the nodes index of the record or, if missing, a new index built from all the record nodes (not stored in the record).
11
+ * To be used before updating the index: a partial index would be trusted by the getters.
12
+ */
13
+ export declare const getNodesIndexOrBuild: (record: ArenaRecord) => RecordNodesIndex;
9
14
  /**
10
15
  * Returns the node with the specified uuid, or undefined if not found.
11
16
  * Like the other node getters, it does not throw an error when the node is not found.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isInAnalysisStep = exports.getStep = exports.isEmpty = exports.isNodeEmpty = exports.isNodeFilledByUser = exports.getCategoryItemUuid = exports.getAncestorCodePath = exports.getAncestorCodeAttributes = exports.getDependentNodePointers = exports.findEntityWithSameKeysInAnotherRecord = exports.findEntityByKeyValues = exports.getNodeIndex = exports.getAttributeSiblings = exports.getEntitySiblings = exports.getEntityKeyValues = exports.getEntityKeyValuesByDefUuid = exports.getEntityKeyNodes = exports.getEntityKeyNodesByDefUuid = exports.findDescendantOrSelf = exports.visitDescendantsAndSelf = exports.isDescendantOf = exports.getDescendant = exports.getDescendantsOrSelf = exports.getAncestorsAndSelf = exports.getAncestor = exports.findAncestor = exports.visitAncestorsAndSelf = exports.getParentCodeAttribute = exports.getDependentCodeAttributes = exports.isNodeRequired = exports.isNodeVisible = exports.isNodeEditable = exports.isNodeApplicable = exports.getNodesByDefUuid = exports.getParent = exports.getChild = exports.getChildren = exports.getRoot = exports.getNodesByUuids = exports.getNodeByUuid = exports.getNodesArray = exports.getNodes = exports.getCycle = void 0;
3
+ exports.isInAnalysisStep = exports.getStep = exports.isEmpty = exports.isNodeEmpty = exports.isNodeFilledByUser = exports.getCategoryItemUuid = exports.getAncestorCodePath = exports.getAncestorCodeAttributes = exports.getDependentNodePointers = exports.findEntityWithSameKeysInAnotherRecord = exports.findEntityByKeyValues = exports.getNodeIndex = exports.getAttributeSiblings = exports.getEntitySiblings = exports.getEntityKeyValues = exports.getEntityKeyValuesByDefUuid = exports.getEntityKeyNodes = exports.getEntityKeyNodesByDefUuid = exports.findDescendantOrSelf = exports.visitDescendantsAndSelf = exports.isDescendantOf = exports.getDescendant = exports.getDescendantsOrSelf = exports.getAncestorsAndSelf = exports.getAncestor = exports.findAncestor = exports.visitAncestorsAndSelf = exports.getParentCodeAttribute = exports.getDependentCodeAttributes = exports.isNodeRequired = exports.isNodeVisible = exports.isNodeEditable = exports.isNodeApplicable = exports.getNodesByDefUuid = exports.getParent = exports.getChild = exports.getChildren = exports.getRoot = exports.getNodesByUuids = exports.getNodeByUuid = exports.getNodesIndexOrBuild = exports.getNodesArray = exports.getNodes = exports.getCycle = void 0;
4
4
  const common_1 = require("../../common");
5
5
  const error_1 = require("../../error");
6
6
  const node_1 = require("../../node");
@@ -11,6 +11,7 @@ const utils_1 = require("../../utils");
11
11
  const record_1 = require("../record");
12
12
  const recordStep_1 = require("../recordStep");
13
13
  const recordNodesIndexReader_1 = require("./recordNodesIndexReader");
14
+ const recordNodesIndexUpdater_1 = require("./recordNodesIndexUpdater");
14
15
  const nodeDefSelfReferences_1 = require("./nodeDefSelfReferences");
15
16
  const getCycle = (record) => { var _a; return (_a = record.cycle) !== null && _a !== void 0 ? _a : survey_1.defaultCycle; };
16
17
  exports.getCycle = getCycle;
@@ -18,6 +19,12 @@ const getNodes = (record) => { var _a; return (_a = record.nodes) !== null && _a
18
19
  exports.getNodes = getNodes;
19
20
  const getNodesArray = (record) => Object.values((0, exports.getNodes)(record));
20
21
  exports.getNodesArray = getNodesArray;
22
+ /**
23
+ * Returns the nodes index of the record or, if missing, a new index built from all the record nodes (not stored in the record).
24
+ * To be used before updating the index: a partial index would be trusted by the getters.
25
+ */
26
+ const getNodesIndexOrBuild = (record) => { var _a; return (_a = record._nodesIndex) !== null && _a !== void 0 ? _a : recordNodesIndexUpdater_1.RecordNodesIndexUpdater.initializeIndex(record); };
27
+ exports.getNodesIndexOrBuild = getNodesIndexOrBuild;
21
28
  /**
22
29
  * Returns the node with the specified uuid, or undefined if not found.
23
30
  * Like the other node getters, it does not throw an error when the node is not found.