@openforis/arena-core 2.3.42 → 2.4.0

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 (119) hide show
  1. package/dist/esm/record/_records/recordCompletion.js +3 -3
  2. package/dist/esm/record/_records/recordCompletion.js.map +1 -1
  3. package/dist/esm/record/_records/recordGetters.js +221 -143
  4. package/dist/esm/record/_records/recordGetters.js.map +1 -1
  5. package/dist/esm/record/_records/recordPagesValidation.js +5 -5
  6. package/dist/esm/record/_records/recordPagesValidation.js.map +1 -1
  7. package/dist/esm/record/_records/recordUtils.js +3 -7
  8. package/dist/esm/record/_records/recordUtils.js.map +1 -1
  9. package/dist/esm/record/nodePointers.js +1 -1
  10. package/dist/esm/record/nodePointers.js.map +1 -1
  11. package/dist/esm/record/recordCloner.js +1 -1
  12. package/dist/esm/record/recordCloner.js.map +1 -1
  13. package/dist/esm/record/recordExpressionEvaluator/functions.js +4 -5
  14. package/dist/esm/record/recordExpressionEvaluator/functions.js.map +1 -1
  15. package/dist/esm/record/recordExpressionEvaluator/node/identifier/identifier.js +1 -1
  16. package/dist/esm/record/recordExpressionEvaluator/node/identifier/identifier.js.map +1 -1
  17. package/dist/esm/record/recordExpressionEvaluator/node/identifier/nodesFinder.js +2 -2
  18. package/dist/esm/record/recordExpressionEvaluator/node/identifier/nodesFinder.js.map +1 -1
  19. package/dist/esm/record/recordExpressionEvaluator/recordExpressionEvaluator.js +1 -1
  20. package/dist/esm/record/recordExpressionEvaluator/recordExpressionEvaluator.js.map +1 -1
  21. package/dist/esm/record/recordFixer.js +5 -5
  22. package/dist/esm/record/recordFixer.js.map +1 -1
  23. package/dist/esm/record/recordNodesUpdater/recordExpressionValueConverter.js +2 -8
  24. package/dist/esm/record/recordNodesUpdater/recordExpressionValueConverter.js.map +1 -1
  25. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js +6 -6
  26. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js.map +1 -1
  27. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js +1 -1
  28. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js.map +1 -1
  29. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCountUpdater.js +1 -6
  30. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCountUpdater.js.map +1 -1
  31. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js +3 -4
  32. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js.map +1 -1
  33. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js +3 -3
  34. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js.map +1 -1
  35. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js +4 -9
  36. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js.map +1 -1
  37. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js +2 -3
  38. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js.map +1 -1
  39. package/dist/esm/record/recordNodesUpdater/recordNodesDeleter.js +1 -5
  40. package/dist/esm/record/recordNodesUpdater/recordNodesDeleter.js.map +1 -1
  41. package/dist/esm/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js +2 -9
  42. package/dist/esm/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js.map +1 -1
  43. package/dist/esm/record/recordNodesUpdater/recordNodesUpdater.js +1 -1
  44. package/dist/esm/record/recordNodesUpdater/recordNodesUpdater.js.map +1 -1
  45. package/dist/esm/record/recordPrettyPrinter.js +14 -12
  46. package/dist/esm/record/recordPrettyPrinter.js.map +1 -1
  47. package/dist/esm/record/recordUpdater.js +2 -2
  48. package/dist/esm/record/recordUpdater.js.map +1 -1
  49. package/dist/esm/record/recordValidator/attributeKeyValidator.js +4 -4
  50. package/dist/esm/record/recordValidator/attributeKeyValidator.js.map +1 -1
  51. package/dist/esm/record/recordValidator/attributeUniqueValidator.js +1 -1
  52. package/dist/esm/record/recordValidator/attributeUniqueValidator.js.map +1 -1
  53. package/dist/esm/record/recordValidator/attributeValidator.js +8 -10
  54. package/dist/esm/record/recordValidator/attributeValidator.js.map +1 -1
  55. package/dist/esm/record/recordValidator/countVaildator.js +2 -2
  56. package/dist/esm/record/recordValidator/countVaildator.js.map +1 -1
  57. package/dist/esm/record/recordValidator/recordValidator.js +1 -2
  58. package/dist/esm/record/recordValidator/recordValidator.js.map +1 -1
  59. package/dist/record/_records/recordCompletion.js +3 -3
  60. package/dist/record/_records/recordCompletion.js.map +1 -1
  61. package/dist/record/_records/recordGetters.d.ts +104 -51
  62. package/dist/record/_records/recordGetters.js +221 -170
  63. package/dist/record/_records/recordGetters.js.map +1 -1
  64. package/dist/record/_records/recordPagesValidation.js +5 -5
  65. package/dist/record/_records/recordPagesValidation.js.map +1 -1
  66. package/dist/record/_records/recordUtils.js +3 -7
  67. package/dist/record/_records/recordUtils.js.map +1 -1
  68. package/dist/record/nodePointers.js +1 -1
  69. package/dist/record/nodePointers.js.map +1 -1
  70. package/dist/record/recordCloner.js +1 -1
  71. package/dist/record/recordCloner.js.map +1 -1
  72. package/dist/record/recordExpressionEvaluator/functions.js +4 -5
  73. package/dist/record/recordExpressionEvaluator/functions.js.map +1 -1
  74. package/dist/record/recordExpressionEvaluator/node/identifier/identifier.js +1 -1
  75. package/dist/record/recordExpressionEvaluator/node/identifier/identifier.js.map +1 -1
  76. package/dist/record/recordExpressionEvaluator/node/identifier/nodesFinder.js +2 -2
  77. package/dist/record/recordExpressionEvaluator/node/identifier/nodesFinder.js.map +1 -1
  78. package/dist/record/recordExpressionEvaluator/recordExpressionEvaluator.js +1 -1
  79. package/dist/record/recordExpressionEvaluator/recordExpressionEvaluator.js.map +1 -1
  80. package/dist/record/recordFixer.js +5 -5
  81. package/dist/record/recordFixer.js.map +1 -1
  82. package/dist/record/recordNodesUpdater/recordExpressionValueConverter.js +2 -8
  83. package/dist/record/recordNodesUpdater/recordExpressionValueConverter.js.map +1 -1
  84. package/dist/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js +6 -6
  85. package/dist/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js.map +1 -1
  86. package/dist/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js +1 -1
  87. package/dist/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js.map +1 -1
  88. package/dist/record/recordNodesUpdater/recordNodeDependentsCountUpdater.js +1 -6
  89. package/dist/record/recordNodesUpdater/recordNodeDependentsCountUpdater.js.map +1 -1
  90. package/dist/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js +3 -4
  91. package/dist/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js.map +1 -1
  92. package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js +3 -3
  93. package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js.map +1 -1
  94. package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js +4 -9
  95. package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js.map +1 -1
  96. package/dist/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js +2 -3
  97. package/dist/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js.map +1 -1
  98. package/dist/record/recordNodesUpdater/recordNodesDeleter.js +1 -5
  99. package/dist/record/recordNodesUpdater/recordNodesDeleter.js.map +1 -1
  100. package/dist/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js +2 -9
  101. package/dist/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js.map +1 -1
  102. package/dist/record/recordNodesUpdater/recordNodesUpdater.js +1 -1
  103. package/dist/record/recordNodesUpdater/recordNodesUpdater.js.map +1 -1
  104. package/dist/record/recordPrettyPrinter.js +14 -12
  105. package/dist/record/recordPrettyPrinter.js.map +1 -1
  106. package/dist/record/recordUpdater.js +2 -2
  107. package/dist/record/recordUpdater.js.map +1 -1
  108. package/dist/record/recordValidator/attributeKeyValidator.js +4 -4
  109. package/dist/record/recordValidator/attributeKeyValidator.js.map +1 -1
  110. package/dist/record/recordValidator/attributeUniqueValidator.js +1 -1
  111. package/dist/record/recordValidator/attributeUniqueValidator.js.map +1 -1
  112. package/dist/record/recordValidator/attributeValidator.js +8 -10
  113. package/dist/record/recordValidator/attributeValidator.js.map +1 -1
  114. package/dist/record/recordValidator/countVaildator.js +2 -2
  115. package/dist/record/recordValidator/countVaildator.js.map +1 -1
  116. package/dist/record/recordValidator/recordValidator.js +1 -2
  117. package/dist/record/recordValidator/recordValidator.js.map +1 -1
  118. package/dist/record/records.d.ts +340 -40
  119. package/package.json +1 -1
@@ -14,17 +14,17 @@ const getAttributeCompletionStats = (params) => {
14
14
  const minCount = Nodes.getChildrenMinCount({ parentNode: entity, nodeDef });
15
15
  if (Number.isNaN(minCount) || minCount <= 0)
16
16
  return emptyStats();
17
- const filledNodesCount = getChildren(entity, nodeDef.uuid)(record).filter(Nodes.isValueNotBlank).length;
17
+ const filledNodesCount = getChildren({ parentNode: entity, childDefUuid: nodeDef.uuid })(record).filter(Nodes.isValueNotBlank).length;
18
18
  return { total: minCount, filled: Math.min(filledNodesCount, minCount) };
19
19
  }
20
20
  if (!NodeDefs.isRequired(nodeDef) && !NodeDefs.isKey(nodeDef))
21
21
  return emptyStats();
22
- const node = getChildren(entity, nodeDef.uuid)(record)[0];
22
+ const node = getChildren({ parentNode: entity, childDefUuid: nodeDef.uuid })(record)[0];
23
23
  return { total: 1, filled: node && Nodes.isValueNotBlank(node) ? 1 : 0 };
24
24
  };
25
25
  const getChildEntityCompletionStats = (params) => {
26
26
  const { survey, record, parentEntity, nodeDef } = params;
27
- const childEntities = getChildren(parentEntity, nodeDef.uuid)(record);
27
+ const childEntities = getChildren({ parentNode: parentEntity, childDefUuid: nodeDef.uuid })(record);
28
28
  if (NodeDefs.isSingle(nodeDef)) {
29
29
  const childEntity = childEntities[0];
30
30
  return childEntity ? getEntityCompletionStats({ survey, record, entity: childEntity }) : emptyStats();
@@ -1 +1 @@
1
- {"version":3,"file":"recordCompletion.js","sourceRoot":"","sources":["../../../../src/record/_records/recordCompletion.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArenaRecordNode, Nodes } from '../../node'\nimport { NodeDef, NodeDefProps, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { Survey, Surveys } from '../../survey'\nimport { Numbers } from '../../utils'\nimport { ArenaRecord } from '../record'\nimport { getChildren, getRoot } from './recordGetters'\n\nexport interface EntityCompletionStats {\n total: number\n filled: number\n}\n\nconst emptyStats = (): EntityCompletionStats => ({ total: 0, filled: 0 })\n\nconst addStats = (statsAcc: EntityCompletionStats, statsToAdd: EntityCompletionStats): void => {\n statsAcc.total += statsToAdd.total\n statsAcc.filled += statsToAdd.filled\n}\n\nconst getAttributeCompletionStats = (params: {\n record: ArenaRecord\n entity: ArenaRecordNode\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n}): EntityCompletionStats => {\n const { record, entity, nodeDef } = params\n\n if (NodeDefs.isMultiple(nodeDef)) {\n const minCount = Nodes.getChildrenMinCount({ parentNode: entity, nodeDef })\n if (Number.isNaN(minCount) || minCount <= 0) return emptyStats()\n\n const filledNodesCount = getChildren(entity, nodeDef.uuid)(record).filter(Nodes.isValueNotBlank).length\n\n return { total: minCount, filled: Math.min(filledNodesCount, minCount) }\n }\n\n if (!NodeDefs.isRequired(nodeDef) && !NodeDefs.isKey(nodeDef)) return emptyStats()\n\n const node = getChildren(entity, nodeDef.uuid)(record)[0]\n return { total: 1, filled: node && Nodes.isValueNotBlank(node) ? 1 : 0 }\n}\n\nconst getChildEntityCompletionStats = (params: {\n survey: Survey\n record: ArenaRecord\n parentEntity: ArenaRecordNode\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n}): EntityCompletionStats => {\n const { survey, record, parentEntity, nodeDef } = params\n const childEntities = getChildren(parentEntity, nodeDef.uuid)(record)\n\n if (NodeDefs.isSingle(nodeDef)) {\n const childEntity = childEntities[0]\n return childEntity ? getEntityCompletionStats({ survey, record, entity: childEntity }) : emptyStats()\n }\n\n const minCountRaw = Nodes.getChildrenMinCount({ parentNode: parentEntity, nodeDef })\n const minCount = Number.isNaN(minCountRaw) ? 0 : Math.max(minCountRaw, 0)\n // entities added beyond the min count are still expected to be complete\n const expectedCount = Math.max(minCount, childEntities.length)\n if (expectedCount === 0) return emptyStats()\n\n const stats = emptyStats()\n for (let index = 0; index < expectedCount; index++) {\n const childEntity = childEntities[index]\n // a missing repetition (below the min count) counts as a single incomplete unit\n addStats(\n stats,\n childEntity ? getEntityCompletionStats({ survey, record, entity: childEntity }) : { total: 1, filled: 0 }\n )\n }\n return stats\n}\n\nexport const getEntityCompletionStats = (params: {\n survey: Survey\n record: ArenaRecord\n entity: ArenaRecordNode\n includeNestedEntities?: boolean\n}): EntityCompletionStats => {\n const { survey, record, entity, includeNestedEntities = true } = params\n const entityDef = Surveys.getNodeDefByUuid({ survey, uuid: entity.nodeDefUuid })\n const childDefs = Surveys.getNodeDefChildren({ survey, nodeDef: entityDef })\n\n const stats = emptyStats()\n for (const childDef of childDefs) {\n if (!Nodes.isChildApplicable(entity, childDef.uuid)) continue\n\n if (NodeDefs.isEntity(childDef)) {\n if (!includeNestedEntities) continue\n addStats(stats, getChildEntityCompletionStats({ survey, record, parentEntity: entity, nodeDef: childDef }))\n } else {\n addStats(stats, getAttributeCompletionStats({ record, entity, nodeDef: childDef }))\n }\n }\n return stats\n}\n\nconst toCompletionPercent = (stats: EntityCompletionStats): number => {\n const { total, filled } = stats\n if (total <= 0) return 100\n return Numbers.roundToPrecision((filled / total) * 100, 2)\n}\n\n/**\n * Returns the percentage of completion of the given entity (0-100), considering every descendant recursively.\n * A required or key attribute is considered filled when it has a non empty value; multiple attributes and\n * entities are considered filled based on their min count (see Nodes.getChildrenMinCount).\n */\nexport const getEntityCompletionPercent = (params: {\n survey: Survey\n record: ArenaRecord\n entity: ArenaRecordNode\n}): number => toCompletionPercent(getEntityCompletionStats(params))\n\n/**\n * Returns the percentage of completion of the given entity (0-100), considering only its own attributes\n * (nested entities are ignored).\n */\nexport const getEntityOwnCompletionPercent = (params: {\n survey: Survey\n record: ArenaRecord\n entity: ArenaRecordNode\n}): number => toCompletionPercent(getEntityCompletionStats({ ...params, includeNestedEntities: false }))\n\n/**\n * Returns the percentage of completion of the given record (0-100), i.e. the completion of its root entity.\n */\nexport const getRecordCompletionPercent = (params: { survey: Survey; record: ArenaRecord }): number => {\n const { survey, record } = params\n const rootEntity = getRoot(record)\n return rootEntity ? getEntityCompletionPercent({ survey, record, entity: rootEntity }) : 0\n}\n"]}
1
+ {"version":3,"file":"recordCompletion.js","sourceRoot":"","sources":["../../../../src/record/_records/recordCompletion.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArenaRecordNode, Nodes } from '../../node'\nimport { NodeDef, NodeDefProps, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { Survey, Surveys } from '../../survey'\nimport { Numbers } from '../../utils'\nimport { ArenaRecord } from '../record'\nimport { getChildren, getRoot } from './recordGetters'\n\nexport interface EntityCompletionStats {\n total: number\n filled: number\n}\n\nconst emptyStats = (): EntityCompletionStats => ({ total: 0, filled: 0 })\n\nconst addStats = (statsAcc: EntityCompletionStats, statsToAdd: EntityCompletionStats): void => {\n statsAcc.total += statsToAdd.total\n statsAcc.filled += statsToAdd.filled\n}\n\nconst getAttributeCompletionStats = (params: {\n record: ArenaRecord\n entity: ArenaRecordNode\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n}): EntityCompletionStats => {\n const { record, entity, nodeDef } = params\n\n if (NodeDefs.isMultiple(nodeDef)) {\n const minCount = Nodes.getChildrenMinCount({ parentNode: entity, nodeDef })\n if (Number.isNaN(minCount) || minCount <= 0) return emptyStats()\n\n const filledNodesCount = getChildren({ parentNode: entity, childDefUuid: nodeDef.uuid })(record).filter(\n Nodes.isValueNotBlank\n ).length\n\n return { total: minCount, filled: Math.min(filledNodesCount, minCount) }\n }\n\n if (!NodeDefs.isRequired(nodeDef) && !NodeDefs.isKey(nodeDef)) return emptyStats()\n\n const node = getChildren({ parentNode: entity, childDefUuid: nodeDef.uuid })(record)[0]\n return { total: 1, filled: node && Nodes.isValueNotBlank(node) ? 1 : 0 }\n}\n\nconst getChildEntityCompletionStats = (params: {\n survey: Survey\n record: ArenaRecord\n parentEntity: ArenaRecordNode\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n}): EntityCompletionStats => {\n const { survey, record, parentEntity, nodeDef } = params\n const childEntities = getChildren({ parentNode: parentEntity, childDefUuid: nodeDef.uuid })(record)\n\n if (NodeDefs.isSingle(nodeDef)) {\n const childEntity = childEntities[0]\n return childEntity ? getEntityCompletionStats({ survey, record, entity: childEntity }) : emptyStats()\n }\n\n const minCountRaw = Nodes.getChildrenMinCount({ parentNode: parentEntity, nodeDef })\n const minCount = Number.isNaN(minCountRaw) ? 0 : Math.max(minCountRaw, 0)\n // entities added beyond the min count are still expected to be complete\n const expectedCount = Math.max(minCount, childEntities.length)\n if (expectedCount === 0) return emptyStats()\n\n const stats = emptyStats()\n for (let index = 0; index < expectedCount; index++) {\n const childEntity = childEntities[index]\n // a missing repetition (below the min count) counts as a single incomplete unit\n addStats(\n stats,\n childEntity ? getEntityCompletionStats({ survey, record, entity: childEntity }) : { total: 1, filled: 0 }\n )\n }\n return stats\n}\n\nexport const getEntityCompletionStats = (params: {\n survey: Survey\n record: ArenaRecord\n entity: ArenaRecordNode\n includeNestedEntities?: boolean\n}): EntityCompletionStats => {\n const { survey, record, entity, includeNestedEntities = true } = params\n const entityDef = Surveys.getNodeDefByUuid({ survey, uuid: entity.nodeDefUuid })\n const childDefs = Surveys.getNodeDefChildren({ survey, nodeDef: entityDef })\n\n const stats = emptyStats()\n for (const childDef of childDefs) {\n if (!Nodes.isChildApplicable(entity, childDef.uuid)) continue\n\n if (NodeDefs.isEntity(childDef)) {\n if (!includeNestedEntities) continue\n addStats(stats, getChildEntityCompletionStats({ survey, record, parentEntity: entity, nodeDef: childDef }))\n } else {\n addStats(stats, getAttributeCompletionStats({ record, entity, nodeDef: childDef }))\n }\n }\n return stats\n}\n\nconst toCompletionPercent = (stats: EntityCompletionStats): number => {\n const { total, filled } = stats\n if (total <= 0) return 100\n return Numbers.roundToPrecision((filled / total) * 100, 2)\n}\n\n/**\n * Returns the percentage of completion of the given entity (0-100), considering every descendant recursively.\n * A required or key attribute is considered filled when it has a non empty value; multiple attributes and\n * entities are considered filled based on their min count (see Nodes.getChildrenMinCount).\n */\nexport const getEntityCompletionPercent = (params: {\n survey: Survey\n record: ArenaRecord\n entity: ArenaRecordNode\n}): number => toCompletionPercent(getEntityCompletionStats(params))\n\n/**\n * Returns the percentage of completion of the given entity (0-100), considering only its own attributes\n * (nested entities are ignored).\n */\nexport const getEntityOwnCompletionPercent = (params: {\n survey: Survey\n record: ArenaRecord\n entity: ArenaRecordNode\n}): number => toCompletionPercent(getEntityCompletionStats({ ...params, includeNestedEntities: false }))\n\n/**\n * Returns the percentage of completion of the given record (0-100), i.e. the completion of its root entity.\n */\nexport const getRecordCompletionPercent = (params: { survey: Survey; record: ArenaRecord }): number => {\n const { survey, record } = params\n const rootEntity = getRoot(record)\n return rootEntity ? getEntityCompletionPercent({ survey, record, entity: rootEntity }) : 0\n}\n"]}
@@ -1,3 +1,14 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
1
12
  import { TraverseMethod } from '../../common';
2
13
  import { SystemError } from '../../error';
3
14
  import { Nodes } from '../../node';
@@ -9,52 +20,89 @@ import { RECORD_STEP_DEFAULT } from '../record';
9
20
  import { RecordStepAnalysisCode } from '../recordStep';
10
21
  import { RecordNodesIndexReader } from './recordNodesIndexReader';
11
22
  import { NodeDefSelfReferences } from './nodeDefSelfReferences';
23
+ const isRecordParams = (params) => 'record' in params;
24
+ const recordGetter = (getter) => ((params) => isRecordParams(params)
25
+ ? getter(params)
26
+ : (record) => getter(Object.assign(Object.assign({}, params), { record })));
27
+ const positionalRecordGetter = (params) => {
28
+ const { getter, isPositional, toParams } = params;
29
+ return ((...args) => {
30
+ const getterParams = isPositional(args[0]) ? toParams(...args) : args[0];
31
+ return (record) => getter(Object.assign(Object.assign({}, getterParams), { record }));
32
+ });
33
+ };
34
+ const isRecordNode = (arg) => typeof arg === 'object' && arg !== null && 'uuid' in arg && 'nodeDefUuid' in arg;
35
+ const isString = (arg) => typeof arg === 'string';
12
36
  export const getCycle = (record) => { var _a; return (_a = record.cycle) !== null && _a !== void 0 ? _a : defaultCycle; };
13
37
  export const getNodes = (record) => { var _a; return (_a = record.nodes) !== null && _a !== void 0 ? _a : {}; };
14
38
  export const getNodesArray = (record) => Object.values(getNodes(record));
15
- export const getNodeByUuid = (uuid) => (record) => { var _a; return (_a = record.nodes) === null || _a === void 0 ? void 0 : _a[uuid]; };
16
- export const getNodesByUuids = (uuids) => (record) => uuids.map((uuid) => getNodeByUuid(uuid)(record));
39
+ export const getNodeByUuid = positionalRecordGetter({
40
+ getter: ({ record, uuid }) => { var _a; return (_a = record.nodes) === null || _a === void 0 ? void 0 : _a[uuid]; },
41
+ isPositional: isString,
42
+ toParams: (uuid) => ({ uuid }),
43
+ });
44
+ export const getNodesByUuids = positionalRecordGetter({
45
+ getter: ({ record, uuids }) => uuids.map((uuid) => { var _a; return (_a = record.nodes) === null || _a === void 0 ? void 0 : _a[uuid]; }),
46
+ isPositional: Array.isArray,
47
+ toParams: (uuids) => ({ uuids }),
48
+ });
17
49
  export const getRoot = (record) => {
18
50
  const rootUuid = record._nodesIndex ? RecordNodesIndexReader.getNodeRootUuid(record._nodesIndex) : null;
19
51
  if (rootUuid) {
20
- return getNodeByUuid(rootUuid)(record);
52
+ return getNodeByUuid({ uuid: rootUuid })(record);
21
53
  }
22
54
  return getNodesArray(record).find((node) => !node.parentUuid);
23
55
  };
24
- export const getChildren = (parentNode, childDefUuid) => (record) => {
25
- if (record._nodesIndex) {
26
- const childrenUuids = childDefUuid
27
- ? RecordNodesIndexReader.getNodeUuidsByParentAndChildDef({
28
- parentNodeUuid: parentNode.uuid,
29
- childDefUuid,
30
- })(record._nodesIndex)
31
- : RecordNodesIndexReader.getNodeUuidsByParent(parentNode.uuid)(record._nodesIndex);
32
- return getNodesByUuids(childrenUuids)(record);
33
- }
34
- return getNodesArray(record).filter((node) => node.parentUuid === parentNode.uuid && (!childDefUuid || node.nodeDefUuid == childDefUuid));
35
- };
36
- export const getChild = (parentNode, childDefUuid) => (record) => {
37
- const children = getChildren(parentNode, childDefUuid)(record);
38
- const errorParams = { childDefUuid, parentNodeUuid: parentNode.uuid, recordUuid: record.uuid };
39
- if (children.length === 1) {
40
- return children[0];
41
- }
42
- if (children.length > 1) {
43
- throw new SystemError('systemError.record.multipleNodesFound', errorParams);
44
- }
45
- throw new SystemError('systemError.record.childNotFound', errorParams);
46
- };
47
- export const getParent = (node) => (record) => node.parentUuid ? getNodeByUuid(node.parentUuid)(record) : undefined;
48
- export const getNodesByDefUuid = (nodeDefUuid) => (record) => {
49
- if (record._nodesIndex) {
50
- const nodeUuids = RecordNodesIndexReader.getNodeUuidsByDef(nodeDefUuid)(record._nodesIndex);
51
- return getNodesByUuids(nodeUuids)(record);
52
- }
53
- return getNodesArray(record).filter((node) => node.nodeDefUuid === nodeDefUuid);
54
- };
55
- const isNodeFlagTrue = (isChildFlagTrue) => (params) => {
56
+ export const getChildren = positionalRecordGetter({
57
+ getter: ({ record, parentNode, childDefUuid, }) => {
58
+ if (record._nodesIndex) {
59
+ const childrenUuids = childDefUuid
60
+ ? RecordNodesIndexReader.getNodeUuidsByParentAndChildDef({
61
+ parentNodeUuid: parentNode.uuid,
62
+ childDefUuid,
63
+ })(record._nodesIndex)
64
+ : RecordNodesIndexReader.getNodeUuidsByParent(parentNode.uuid)(record._nodesIndex);
65
+ return getNodesByUuids({ uuids: childrenUuids })(record);
66
+ }
67
+ return getNodesArray(record).filter((node) => node.parentUuid === parentNode.uuid && (!childDefUuid || node.nodeDefUuid == childDefUuid));
68
+ },
69
+ isPositional: isRecordNode,
70
+ toParams: (parentNode, childDefUuid) => ({ parentNode, childDefUuid }),
71
+ });
72
+ export const getChild = positionalRecordGetter({
73
+ getter: ({ record, parentNode, childDefUuid, }) => {
74
+ const children = getChildren({ parentNode, childDefUuid })(record);
75
+ const errorParams = { childDefUuid, parentNodeUuid: parentNode.uuid, recordUuid: record.uuid };
76
+ if (children.length === 1) {
77
+ return children[0];
78
+ }
79
+ if (children.length > 1) {
80
+ throw new SystemError('systemError.record.multipleNodesFound', errorParams);
81
+ }
82
+ throw new SystemError('systemError.record.childNotFound', errorParams);
83
+ },
84
+ isPositional: isRecordNode,
85
+ toParams: (parentNode, childDefUuid) => ({ parentNode, childDefUuid }),
86
+ });
87
+ export const getParent = positionalRecordGetter({
88
+ getter: ({ record, node }) => node.parentUuid ? getNodeByUuid({ uuid: node.parentUuid })(record) : undefined,
89
+ isPositional: isRecordNode,
90
+ toParams: (node) => ({ node }),
91
+ });
92
+ export const getNodesByDefUuid = positionalRecordGetter({
93
+ getter: ({ record, nodeDefUuid }) => {
94
+ if (record._nodesIndex) {
95
+ const nodeUuids = RecordNodesIndexReader.getNodeUuidsByDef(nodeDefUuid)(record._nodesIndex);
96
+ return getNodesByUuids({ uuids: nodeUuids })(record);
97
+ }
98
+ return getNodesArray(record).filter((node) => node.nodeDefUuid === nodeDefUuid);
99
+ },
100
+ isPositional: isString,
101
+ toParams: (nodeDefUuid) => ({ nodeDefUuid }),
102
+ });
103
+ const isNodeFlagTrue = (isChildFlagTrue) => recordGetter((params) => {
56
104
  const { record, node } = params;
57
- const ancestorsAndSelf = getAncestorsAndSelf({ record, node });
105
+ const ancestorsAndSelf = getAncestorsAndSelf({ node })(record);
58
106
  for (let i = 0; i < ancestorsAndSelf.length - 1; i++) {
59
107
  const child = ancestorsAndSelf[i];
60
108
  const parent = ancestorsAndSelf[i + 1];
@@ -62,25 +110,29 @@ const isNodeFlagTrue = (isChildFlagTrue) => (params) => {
62
110
  return false;
63
111
  }
64
112
  return true;
65
- };
113
+ });
66
114
  export const isNodeApplicable = isNodeFlagTrue((parent, nodeDefUuid) => Nodes.isChildApplicable(parent, nodeDefUuid));
67
115
  export const isNodeEditable = isNodeFlagTrue((parent, nodeDefUuid) => Nodes.isChildEditable(parent, nodeDefUuid));
68
116
  export const isNodeVisible = isNodeFlagTrue((parent, nodeDefUuid) => Nodes.isChildVisible(parent, nodeDefUuid));
69
- export const getDependentCodeAttributes = (node) => (record) => {
70
- if (record._nodesIndex) {
71
- const nodeUuids = RecordNodesIndexReader.getNodeCodeDependentUuids(node.uuid)(record._nodesIndex);
72
- return getNodesByUuids(nodeUuids)(record);
73
- }
74
- throw new SystemError('record.nodesIndexNotInitialized');
75
- };
117
+ export const getDependentCodeAttributes = positionalRecordGetter({
118
+ getter: ({ record, node }) => {
119
+ if (record._nodesIndex) {
120
+ const nodeUuids = RecordNodesIndexReader.getNodeCodeDependentUuids(node.uuid)(record._nodesIndex);
121
+ return getNodesByUuids({ uuids: nodeUuids })(record);
122
+ }
123
+ throw new SystemError('record.nodesIndexNotInitialized');
124
+ },
125
+ isPositional: isRecordNode,
126
+ toParams: (node) => ({ node }),
127
+ });
76
128
  export const getParentCodeAttribute = (params) => (record) => {
77
129
  const { parentNode, nodeDef } = params;
78
130
  const parentCodeDefUuid = NodeDefs.getParentCodeDefUuid(nodeDef);
79
131
  if (!parentCodeDefUuid)
80
132
  return undefined;
81
- const ancestors = getAncestorsAndSelf({ record, node: parentNode });
133
+ const ancestors = getAncestorsAndSelf({ node: parentNode })(record);
82
134
  for (const ancestor of ancestors) {
83
- const children = getChildren(ancestor, parentCodeDefUuid)(record);
135
+ const children = getChildren({ parentNode: ancestor, childDefUuid: parentCodeDefUuid })(record);
84
136
  if (children.length === 1) {
85
137
  return children[0];
86
138
  }
@@ -88,47 +140,72 @@ export const getParentCodeAttribute = (params) => (record) => {
88
140
  return undefined;
89
141
  };
90
142
  // ancestors
91
- export const visitAncestorsAndSelf = (node, visitor, stopIfFn) => (record) => {
92
- let currentNode = node;
93
- while (currentNode) {
94
- visitor(currentNode);
95
- if (stopIfFn === null || stopIfFn === void 0 ? void 0 : stopIfFn())
96
- break;
97
- currentNode = getParent(currentNode)(record);
98
- }
99
- };
100
- export const findAncestor = (node, predicate) => (record) => {
101
- let result = undefined;
102
- visitAncestorsAndSelf(node, (visitedNode) => {
103
- if (predicate(visitedNode)) {
104
- result = visitedNode;
143
+ /**
144
+ * Visits the specified node and its ancestors, from the node up to the root: the visit stops when the visitor returns true.
145
+ */
146
+ export const visitAncestorsAndSelf = positionalRecordGetter({
147
+ getter: ({ record, node, visitor, }) => {
148
+ let currentNode = node;
149
+ while (currentNode) {
150
+ if (visitor(currentNode))
151
+ return;
152
+ currentNode = getParent({ node: currentNode })(record);
105
153
  }
106
- }, () => !!result)(record);
154
+ },
155
+ isPositional: isRecordNode,
156
+ // deprecated form: the visit stops when stopIfFn returns true
157
+ toParams: (node, visitor, stopIfFn) => ({
158
+ node,
159
+ visitor: (visitedNode) => {
160
+ visitor(visitedNode);
161
+ return !!(stopIfFn === null || stopIfFn === void 0 ? void 0 : stopIfFn());
162
+ },
163
+ }),
164
+ });
165
+ /**
166
+ * Returns the first node satisfying the predicate among the specified node and its ancestors (from the node up to the root).
167
+ */
168
+ export const findAncestor = (params) => (record) => {
169
+ const { node, predicate } = params;
170
+ let result = undefined;
171
+ visitAncestorsAndSelf({
172
+ node,
173
+ visitor: (visitedNode) => {
174
+ if (predicate(visitedNode)) {
175
+ result = visitedNode;
176
+ return true;
177
+ }
178
+ return false;
179
+ },
180
+ })(record);
107
181
  return result;
108
182
  };
109
- export const getAncestor = (params) => {
183
+ export const getAncestor = recordGetter((params) => {
110
184
  const { record, node, ancestorDefUuid } = params;
111
185
  if (node.nodeDefUuid === ancestorDefUuid)
112
186
  return node;
113
- let ancestor = getParent(node)(record);
187
+ let ancestor = getParent({ node })(record);
114
188
  while (ancestor && ancestor.nodeDefUuid !== ancestorDefUuid) {
115
- ancestor = getParent(ancestor)(record);
189
+ ancestor = getParent({ node: ancestor })(record);
116
190
  }
117
191
  return ancestor;
118
- };
192
+ });
119
193
  /**
120
194
  * Returns the list of ancestors from the given node to the root entity
121
195
  */
122
- export const getAncestorsAndSelf = (params) => {
196
+ export const getAncestorsAndSelf = recordGetter((params) => {
123
197
  const { record, node } = params;
124
198
  const ancestors = [];
125
- visitAncestorsAndSelf(node, (currentNode) => {
126
- ancestors.push(currentNode);
199
+ visitAncestorsAndSelf({
200
+ node,
201
+ visitor: (currentNode) => {
202
+ ancestors.push(currentNode);
203
+ },
127
204
  })(record);
128
205
  return ancestors;
129
- };
206
+ });
130
207
  // descendants
131
- export const getDescendantsOrSelf = (params) => {
208
+ export const getDescendantsOrSelf = recordGetter((params) => {
132
209
  const { record, node, nodeDefDescendant } = params;
133
210
  if (nodeDefDescendant.uuid === node.nodeDefUuid)
134
211
  return [node];
@@ -140,22 +217,22 @@ export const getDescendantsOrSelf = (params) => {
140
217
  let currentDescendants = [];
141
218
  for (const currentDescendantDefUuid of descendantNodeDefUuids) {
142
219
  for (const currentAncestor of currentAncestors) {
143
- currentDescendants.push(...getChildren(currentAncestor, currentDescendantDefUuid)(record));
220
+ currentDescendants.push(...getChildren({ parentNode: currentAncestor, childDefUuid: currentDescendantDefUuid })(record));
144
221
  }
145
222
  currentAncestors = currentDescendants;
146
223
  currentDescendants = [];
147
224
  }
148
225
  return currentAncestors; // currentAncestors is equal to the currentDescendants of the last level
149
- };
150
- export const getDescendant = (params) => {
226
+ });
227
+ export const getDescendant = recordGetter((params) => {
151
228
  const { record, node, nodeDefDescendant } = params;
152
- return getDescendantsOrSelf({ record, node, nodeDefDescendant })[0];
153
- };
229
+ return getDescendantsOrSelf({ node, nodeDefDescendant })(record)[0];
230
+ });
154
231
  export const isDescendantOf = (params) => {
155
232
  const { node, ancestor } = params;
156
233
  return Nodes.getHierarchy(node).includes(ancestor.uuid);
157
234
  };
158
- export const visitDescendantsAndSelf = (params) => {
235
+ export const visitDescendantsAndSelf = recordGetter((params) => {
159
236
  const { record, node, visitor, traverseMethod = TraverseMethod.bfs } = params;
160
237
  if (traverseMethod === TraverseMethod.bfs) {
161
238
  const queue = new Queue();
@@ -179,7 +256,7 @@ export const visitDescendantsAndSelf = (params) => {
179
256
  // stop if visitor returns true
180
257
  return;
181
258
  }
182
- const children = getChildren(visitedNode)(record);
259
+ const children = getChildren({ parentNode: visitedNode })(record);
183
260
  // add children to stack in reverse order
184
261
  for (let index = children.length - 1; index >= 0; index--) {
185
262
  const child = children[index];
@@ -187,11 +264,11 @@ export const visitDescendantsAndSelf = (params) => {
187
264
  }
188
265
  }
189
266
  }
190
- };
191
- export const findDescendantOrSelf = (node, predicate) => (record) => {
267
+ });
268
+ export const findDescendantOrSelf = (params) => (record) => {
269
+ const { node, predicate } = params;
192
270
  let found = undefined;
193
271
  visitDescendantsAndSelf({
194
- record,
195
272
  node,
196
273
  visitor: (currentNode) => {
197
274
  if (predicate(currentNode)) {
@@ -200,10 +277,10 @@ export const findDescendantOrSelf = (node, predicate) => (record) => {
200
277
  }
201
278
  return false;
202
279
  },
203
- });
280
+ })(record);
204
281
  return found;
205
282
  };
206
- const getClosestAncestorNode = (params) => {
283
+ const getClosestAncestorNode = recordGetter((params) => {
207
284
  const { record, node, nodeDef, dependentDef, dependencyType } = params;
208
285
  // 1a if dependent def is the same as node def, potentially all nodes with
209
286
  // nodeDefUuid === dependentDef.uuid in record could be dependent of nodeDef;
@@ -211,7 +288,7 @@ const getClosestAncestorNode = (params) => {
211
288
  // unless the node def references itself only among the children of its parent entity (e.g. validation "dbh > 0")
212
289
  if (nodeDef.uuid === dependentDef.uuid) {
213
290
  return NodeDefSelfReferences.isSelfReferenceLocal({ nodeDef, dependencyType })
214
- ? getParent(node)(record)
291
+ ? getParent({ node })(record)
215
292
  : getRoot(record);
216
293
  }
217
294
  // 1 find common ancestor def
@@ -219,69 +296,71 @@ const getClosestAncestorNode = (params) => {
219
296
  if (!commonAncestorDefUuid)
220
297
  return undefined;
221
298
  // 2 get ancestor node with common parent def
222
- return getAncestor({ record, node, ancestorDefUuid: commonAncestorDefUuid });
223
- };
224
- export const getEntityKeyNodesByDefUuid = (params) => {
299
+ return getAncestor({ node, ancestorDefUuid: commonAncestorDefUuid })(record);
300
+ });
301
+ export const getEntityKeyNodesByDefUuid = recordGetter((params) => {
225
302
  const { survey, cycle, record, entity, keyDefs } = params;
226
303
  const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: entity.nodeDefUuid });
227
304
  const nodeDefKeys = keyDefs !== null && keyDefs !== void 0 ? keyDefs : Surveys.getNodeDefKeys({ survey, cycle, nodeDef });
228
305
  return nodeDefKeys.reduce((acc, nodeDefKey) => {
229
- const nodeKey = getDescendant({ record, node: entity, nodeDefDescendant: nodeDefKey });
306
+ const nodeKey = getDescendant({ node: entity, nodeDefDescendant: nodeDefKey })(record);
230
307
  acc[nodeDefKey.uuid] = nodeKey;
231
308
  return acc;
232
309
  }, {});
233
- };
234
- export const getEntityKeyNodes = (params) => Object.values(getEntityKeyNodesByDefUuid(params));
235
- export const getEntityKeyValuesByDefUuid = (params) => {
236
- const keyNodesByDefUuid = getEntityKeyNodesByDefUuid(params);
310
+ });
311
+ export const getEntityKeyNodes = recordGetter((_a) => {
312
+ var { record } = _a, otherParams = __rest(_a, ["record"]);
313
+ return Object.values(getEntityKeyNodesByDefUuid(otherParams)(record));
314
+ });
315
+ export const getEntityKeyValuesByDefUuid = recordGetter((params) => {
316
+ const { record } = params, otherParams = __rest(params, ["record"]);
317
+ const keyNodesByDefUuid = getEntityKeyNodesByDefUuid(otherParams)(record);
237
318
  return Object.entries(keyNodesByDefUuid).reduce((acc, [uuid, keyNode]) => {
238
319
  acc[uuid] = keyNode === null || keyNode === void 0 ? void 0 : keyNode.value;
239
320
  return acc;
240
321
  }, {});
241
- };
242
- export const getEntityKeyValues = (params) => Object.values(getEntityKeyValuesByDefUuid(params));
243
- export const getEntitySiblings = (params) => {
322
+ });
323
+ export const getEntityKeyValues = recordGetter((_a) => {
324
+ var { record } = _a, otherParams = __rest(_a, ["record"]);
325
+ return Object.values(getEntityKeyValuesByDefUuid(otherParams)(record));
326
+ });
327
+ export const getEntitySiblings = recordGetter((params) => {
244
328
  const { record, entity, includeSelf = false } = params;
245
- const parentEntity = getParent(entity)(record);
329
+ const parentEntity = getParent({ node: entity })(record);
246
330
  if (!parentEntity)
247
331
  return [];
248
- const siblingEntities = getChildren(parentEntity, entity.nodeDefUuid)(record);
332
+ const siblingEntities = getChildren({ parentNode: parentEntity, childDefUuid: entity.nodeDefUuid })(record);
249
333
  return includeSelf ? siblingEntities : siblingEntities.filter((sibling) => !Nodes.areEqual(sibling, entity));
250
- };
251
- export const getAttributeSiblings = (params) => {
334
+ });
335
+ export const getAttributeSiblings = recordGetter((params) => {
252
336
  const { record, node, nodeDef } = params;
253
- const parentEntity = getParent(node)(record);
337
+ const parentEntity = getParent({ node })(record);
254
338
  if (!parentEntity)
255
339
  return [];
256
- const siblingParentEntities = getEntitySiblings({ record, entity: parentEntity });
340
+ const siblingParentEntities = getEntitySiblings({ entity: parentEntity })(record);
257
341
  return siblingParentEntities.reduce((siblingsAcc, siblingEntity) => {
258
- siblingsAcc.push(...getChildren(siblingEntity, nodeDef.uuid)(record));
342
+ siblingsAcc.push(...getChildren({ parentNode: siblingEntity, childDefUuid: nodeDef.uuid })(record));
259
343
  return siblingsAcc;
260
344
  }, []);
261
- };
262
- export const getNodeIndex = (params) => {
345
+ });
346
+ export const getNodeIndex = recordGetter((params) => {
263
347
  const { record, node } = params;
264
- const parentEntity = getParent(node)(record);
348
+ const parentEntity = getParent({ node })(record);
265
349
  if (!parentEntity)
266
350
  return 0; // root entity
267
- const siblings = getChildren(parentEntity, node.nodeDefUuid)(record);
351
+ const siblings = getChildren({ parentNode: parentEntity, childDefUuid: node.nodeDefUuid })(record);
268
352
  return siblings.indexOf(node);
269
- };
270
- export const findEntityByKeyValues = (params) => {
353
+ });
354
+ export const findEntityByKeyValues = recordGetter((params) => {
271
355
  const { survey, cycle, record, parentEntity, entityDefUuid, keyValuesByDefUuid } = params;
272
356
  const entityDef = Surveys.getNodeDefByUuid({ survey, uuid: entityDefUuid });
273
- const siblingEntities = getChildren(parentEntity, entityDefUuid)(record);
357
+ const siblingEntities = getChildren({ parentNode: parentEntity, childDefUuid: entityDefUuid })(record);
274
358
  if (NodeDefs.isSingle(entityDef)) {
275
359
  return siblingEntities[0];
276
360
  }
277
361
  const keyDefs = Surveys.getNodeDefKeys({ survey, cycle, nodeDef: entityDef });
278
362
  return siblingEntities.find((siblingEntity) => {
279
- const siblingEntityKeyValuesByDefUuid = getEntityKeyValuesByDefUuid({
280
- survey,
281
- record,
282
- entity: siblingEntity,
283
- keyDefs,
284
- });
363
+ const siblingEntityKeyValuesByDefUuid = getEntityKeyValuesByDefUuid({ survey, entity: siblingEntity, keyDefs })(record);
285
364
  return keyDefs.every((keyDef) => {
286
365
  const keyValue = siblingEntityKeyValuesByDefUuid[keyDef.uuid];
287
366
  const keyValueSearch = keyValuesByDefUuid[keyDef.uuid];
@@ -293,26 +372,19 @@ export const findEntityByKeyValues = (params) => {
293
372
  });
294
373
  });
295
374
  });
296
- };
297
- export const findEntityWithSameKeysInAnotherRecord = (params) => {
375
+ });
376
+ export const findEntityWithSameKeysInAnotherRecord = recordGetter((params) => {
298
377
  const { survey, cycle, entityUuid, record, recordOther } = params;
299
- const entity = getNodeByUuid(entityUuid)(record);
378
+ const entity = getNodeByUuid({ uuid: entityUuid })(record);
300
379
  if (!entity)
301
380
  return undefined;
302
381
  let otherRecordCurrentParentEntity = getRoot(recordOther);
303
382
  if (!otherRecordCurrentParentEntity)
304
383
  return undefined;
305
- const entityAncestorsAndSelf = getAncestorsAndSelf({
306
- record,
307
- node: entity,
308
- });
384
+ const entityAncestorsAndSelf = getAncestorsAndSelf({ node: entity })(record);
309
385
  const ancestorDefUuidsAndKeys = entityAncestorsAndSelf.map((ancestor) => ({
310
386
  entityDefUuid: ancestor.nodeDefUuid,
311
- keyValuesByDefUuid: getEntityKeyValuesByDefUuid({
312
- survey,
313
- record,
314
- entity: ancestor,
315
- }),
387
+ keyValuesByDefUuid: getEntityKeyValuesByDefUuid({ survey, entity: ancestor })(record),
316
388
  }));
317
389
  const ancestorDefUuidsAndKeysToVisit = [...ancestorDefUuidsAndKeys].reverse();
318
390
  for (let index = 1; otherRecordCurrentParentEntity && index < ancestorDefUuidsAndKeysToVisit.length; index++) {
@@ -320,15 +392,14 @@ export const findEntityWithSameKeysInAnotherRecord = (params) => {
320
392
  otherRecordCurrentParentEntity = findEntityByKeyValues({
321
393
  survey,
322
394
  cycle,
323
- record: recordOther,
324
395
  parentEntity: otherRecordCurrentParentEntity,
325
396
  entityDefUuid,
326
397
  keyValuesByDefUuid,
327
- });
398
+ })(recordOther);
328
399
  }
329
400
  return otherRecordCurrentParentEntity;
330
- };
331
- export const getDependentNodePointers = (params) => {
401
+ });
402
+ export const getDependentNodePointers = recordGetter((params) => {
332
403
  const { survey, record, node, dependencyType, includeSelf = false, filterFn = null } = params;
333
404
  const nodeDefUuid = node.nodeDefUuid;
334
405
  const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: nodeDefUuid });
@@ -341,7 +412,7 @@ export const getDependentNodePointers = (params) => {
341
412
  };
342
413
  for (const dependentDef of dependentDefs) {
343
414
  // 1 find common ancestor node
344
- const commonAncestorNode = getClosestAncestorNode({ record, node, nodeDef, dependentDef, dependencyType });
415
+ const commonAncestorNode = getClosestAncestorNode({ node, nodeDef, dependentDef, dependencyType })(record);
345
416
  if (!commonAncestorNode)
346
417
  continue;
347
418
  const nodeDefDependentParent = Surveys.getNodeDefParent({ survey, nodeDef: dependentDef });
@@ -349,10 +420,9 @@ export const getDependentNodePointers = (params) => {
349
420
  throw new SystemError('record.nodes.dependents.dependencyOnRootFound');
350
421
  // 2 find descendant nodes of common parent node with nodeDefUuid = dependentDef uuid
351
422
  const dependentContextNodes = getDescendantsOrSelf({
352
- record,
353
423
  node: commonAncestorNode,
354
424
  nodeDefDescendant: nodeDefDependentParent,
355
- });
425
+ })(record);
356
426
  for (const dependentContextNode of dependentContextNodes) {
357
427
  addToNodePointers({
358
428
  nodeCtx: dependentContextNode,
@@ -361,7 +431,7 @@ export const getDependentNodePointers = (params) => {
361
431
  }
362
432
  }
363
433
  if (includeSelf) {
364
- const parentNode = getParent(node)(record);
434
+ const parentNode = getParent({ node })(record);
365
435
  if (parentNode) {
366
436
  addToNodePointers({
367
437
  nodeCtx: parentNode,
@@ -370,8 +440,8 @@ export const getDependentNodePointers = (params) => {
370
440
  }
371
441
  }
372
442
  return nodePointers;
373
- };
374
- export const getAncestorCodePath = (params) => {
443
+ });
444
+ export const getAncestorCodePath = recordGetter((params) => {
375
445
  const { record, parentNode, nodeDef, survey } = params;
376
446
  const getCodeAttributeItemCode = (codeAttribute) => {
377
447
  var _a;
@@ -393,19 +463,27 @@ export const getAncestorCodePath = (params) => {
393
463
  currentParentCodeAttribute = getParentCodeAttribute({ parentNode, nodeDef: ancestorCodeDef })(record);
394
464
  }
395
465
  return codePaths;
396
- };
397
- export const getCategoryItemUuid = (params) => {
466
+ });
467
+ export const getCategoryItemUuid = recordGetter((params) => {
398
468
  const { survey, nodeDef, record, parentNode, code } = params;
399
469
  const categoryUuid = nodeDef.props.categoryUuid;
400
- const codePaths = [...getAncestorCodePath({ survey, record, parentNode, nodeDef }), code];
470
+ const codePaths = [...getAncestorCodePath({ survey, parentNode, nodeDef })(record), code];
401
471
  const item = Surveys.getCategoryItemByCodePaths({ survey, categoryUuid, codePaths });
402
472
  return item === null || item === void 0 ? void 0 : item.uuid;
403
- };
404
- export const isNodeFilledByUser = (node) => (record) => !!findDescendantOrSelf(node, (visitedNode) => Nodes.hasUserInputValue(visitedNode))(record);
405
- export const isNodeEmpty = (node) => (record) => !isNodeFilledByUser(node)(record);
473
+ });
474
+ export const isNodeFilledByUser = positionalRecordGetter({
475
+ getter: ({ record, node }) => !!findDescendantOrSelf({ node, predicate: (visitedNode) => Nodes.hasUserInputValue(visitedNode) })(record),
476
+ isPositional: isRecordNode,
477
+ toParams: (node) => ({ node }),
478
+ });
479
+ export const isNodeEmpty = positionalRecordGetter({
480
+ getter: ({ record, node }) => !isNodeFilledByUser({ node })(record),
481
+ isPositional: isRecordNode,
482
+ toParams: (node) => ({ node }),
483
+ });
406
484
  export const isEmpty = (record) => {
407
485
  const rootNode = getRoot(record);
408
- return rootNode ? isNodeEmpty(rootNode)(record) : true;
486
+ return rootNode ? isNodeEmpty({ node: rootNode })(record) : true;
409
487
  };
410
488
  export const getStep = (record) => { var _a; return (_a = record.step) !== null && _a !== void 0 ? _a : RECORD_STEP_DEFAULT; };
411
489
  export const isInAnalysisStep = (record) => getStep(record) === RecordStepAnalysisCode;