@openforis/arena-core 2.3.42 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/record/_records/recordCompletion.js +3 -3
- package/dist/esm/record/_records/recordCompletion.js.map +1 -1
- package/dist/esm/record/_records/recordGetters.js +221 -143
- package/dist/esm/record/_records/recordGetters.js.map +1 -1
- package/dist/esm/record/_records/recordPagesValidation.js +5 -5
- package/dist/esm/record/_records/recordPagesValidation.js.map +1 -1
- package/dist/esm/record/_records/recordUtils.js +3 -7
- package/dist/esm/record/_records/recordUtils.js.map +1 -1
- package/dist/esm/record/nodePointers.js +1 -1
- package/dist/esm/record/nodePointers.js.map +1 -1
- package/dist/esm/record/recordCloner.js +1 -1
- package/dist/esm/record/recordCloner.js.map +1 -1
- package/dist/esm/record/recordExpressionEvaluator/functions.js +4 -5
- package/dist/esm/record/recordExpressionEvaluator/functions.js.map +1 -1
- package/dist/esm/record/recordExpressionEvaluator/node/identifier/identifier.js +1 -1
- package/dist/esm/record/recordExpressionEvaluator/node/identifier/identifier.js.map +1 -1
- package/dist/esm/record/recordExpressionEvaluator/node/identifier/nodesFinder.js +2 -2
- package/dist/esm/record/recordExpressionEvaluator/node/identifier/nodesFinder.js.map +1 -1
- package/dist/esm/record/recordExpressionEvaluator/recordExpressionEvaluator.js +1 -1
- package/dist/esm/record/recordExpressionEvaluator/recordExpressionEvaluator.js.map +1 -1
- package/dist/esm/record/recordFixer.js +5 -5
- package/dist/esm/record/recordFixer.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordExpressionValueConverter.js +2 -8
- package/dist/esm/record/recordNodesUpdater/recordExpressionValueConverter.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js +6 -6
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCountUpdater.js +1 -6
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCountUpdater.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js +3 -4
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js +3 -3
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js +4 -9
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js +2 -3
- package/dist/esm/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodesDeleter.js +1 -5
- package/dist/esm/record/recordNodesUpdater/recordNodesDeleter.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js +2 -9
- package/dist/esm/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js.map +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodesUpdater.js +1 -1
- package/dist/esm/record/recordNodesUpdater/recordNodesUpdater.js.map +1 -1
- package/dist/esm/record/recordPrettyPrinter.js +14 -12
- package/dist/esm/record/recordPrettyPrinter.js.map +1 -1
- package/dist/esm/record/recordUpdater.js +2 -2
- package/dist/esm/record/recordUpdater.js.map +1 -1
- package/dist/esm/record/recordValidator/attributeKeyValidator.js +4 -4
- package/dist/esm/record/recordValidator/attributeKeyValidator.js.map +1 -1
- package/dist/esm/record/recordValidator/attributeUniqueValidator.js +1 -1
- package/dist/esm/record/recordValidator/attributeUniqueValidator.js.map +1 -1
- package/dist/esm/record/recordValidator/attributeValidator.js +8 -10
- package/dist/esm/record/recordValidator/attributeValidator.js.map +1 -1
- package/dist/esm/record/recordValidator/countVaildator.js +2 -2
- package/dist/esm/record/recordValidator/countVaildator.js.map +1 -1
- package/dist/esm/record/recordValidator/recordValidator.js +1 -2
- package/dist/esm/record/recordValidator/recordValidator.js.map +1 -1
- package/dist/record/_records/recordCompletion.js +3 -3
- package/dist/record/_records/recordCompletion.js.map +1 -1
- package/dist/record/_records/recordGetters.d.ts +104 -51
- package/dist/record/_records/recordGetters.js +221 -170
- package/dist/record/_records/recordGetters.js.map +1 -1
- package/dist/record/_records/recordPagesValidation.js +5 -5
- package/dist/record/_records/recordPagesValidation.js.map +1 -1
- package/dist/record/_records/recordUtils.js +3 -7
- package/dist/record/_records/recordUtils.js.map +1 -1
- package/dist/record/nodePointers.js +1 -1
- package/dist/record/nodePointers.js.map +1 -1
- package/dist/record/recordCloner.js +1 -1
- package/dist/record/recordCloner.js.map +1 -1
- package/dist/record/recordExpressionEvaluator/functions.js +4 -5
- package/dist/record/recordExpressionEvaluator/functions.js.map +1 -1
- package/dist/record/recordExpressionEvaluator/node/identifier/identifier.js +1 -1
- package/dist/record/recordExpressionEvaluator/node/identifier/identifier.js.map +1 -1
- package/dist/record/recordExpressionEvaluator/node/identifier/nodesFinder.js +2 -2
- package/dist/record/recordExpressionEvaluator/node/identifier/nodesFinder.js.map +1 -1
- package/dist/record/recordExpressionEvaluator/recordExpressionEvaluator.js +1 -1
- package/dist/record/recordExpressionEvaluator/recordExpressionEvaluator.js.map +1 -1
- package/dist/record/recordFixer.js +5 -5
- package/dist/record/recordFixer.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordExpressionValueConverter.js +2 -8
- package/dist/record/recordNodesUpdater/recordExpressionValueConverter.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js +6 -6
- package/dist/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js +1 -1
- package/dist/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodeDependentsCountUpdater.js +1 -6
- package/dist/record/recordNodesUpdater/recordNodeDependentsCountUpdater.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js +3 -4
- package/dist/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js +3 -3
- package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js +4 -9
- package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js +2 -3
- package/dist/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodesDeleter.js +1 -5
- package/dist/record/recordNodesUpdater/recordNodesDeleter.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js +2 -9
- package/dist/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js.map +1 -1
- package/dist/record/recordNodesUpdater/recordNodesUpdater.js +1 -1
- package/dist/record/recordNodesUpdater/recordNodesUpdater.js.map +1 -1
- package/dist/record/recordPrettyPrinter.js +14 -12
- package/dist/record/recordPrettyPrinter.js.map +1 -1
- package/dist/record/recordUpdater.js +2 -2
- package/dist/record/recordUpdater.js.map +1 -1
- package/dist/record/recordValidator/attributeKeyValidator.js +4 -4
- package/dist/record/recordValidator/attributeKeyValidator.js.map +1 -1
- package/dist/record/recordValidator/attributeUniqueValidator.js +1 -1
- package/dist/record/recordValidator/attributeUniqueValidator.js.map +1 -1
- package/dist/record/recordValidator/attributeValidator.js +8 -10
- package/dist/record/recordValidator/attributeValidator.js.map +1 -1
- package/dist/record/recordValidator/countVaildator.js +2 -2
- package/dist/record/recordValidator/countVaildator.js.map +1 -1
- package/dist/record/recordValidator/recordValidator.js +1 -2
- package/dist/record/recordValidator/recordValidator.js.map +1 -1
- package/dist/record/records.d.ts +140 -34
- package/package.json +1 -1
|
@@ -55,7 +55,7 @@ const print = (params) => {
|
|
|
55
55
|
parts.push(toPart({ depth, name: NodeDefs.getName(nodeDef), value, infoParts }));
|
|
56
56
|
const childDefs = Surveys.getNodeDefChildrenSorted({ survey, nodeDef, cycle });
|
|
57
57
|
childDefs.forEach((childDef) => {
|
|
58
|
-
const children = RecordGetters.getChildren(node, childDef.uuid)(record);
|
|
58
|
+
const children = RecordGetters.getChildren({ parentNode: node, childDefUuid: childDef.uuid })(record);
|
|
59
59
|
if (children.length === 0) {
|
|
60
60
|
const childInfoParts = getInfoParts({ parentNode: node, childDefUuid: childDef.uuid });
|
|
61
61
|
parts.push(toPart({
|
|
@@ -73,33 +73,35 @@ const print = (params) => {
|
|
|
73
73
|
return parts.join('\n');
|
|
74
74
|
}
|
|
75
75
|
RecordGetters.visitDescendantsAndSelf({
|
|
76
|
-
record,
|
|
77
76
|
node: rootNode,
|
|
78
77
|
visitor: (node) => {
|
|
79
78
|
const { nodeDefUuid } = node;
|
|
80
79
|
const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: nodeDefUuid });
|
|
81
80
|
const value = NodeValueFormatter.format({ survey, cycle, nodeDef, node, value: node.value });
|
|
82
81
|
const depth = Nodes.getHierarchy(node).length;
|
|
83
|
-
const parentNode = NodeDefs.isRoot(nodeDef) ? null : RecordGetters.getParent(node)(record);
|
|
82
|
+
const parentNode = NodeDefs.isRoot(nodeDef) ? null : RecordGetters.getParent({ node })(record);
|
|
84
83
|
const infoParts = getInfoParts({ parentNode, childDefUuid: nodeDefUuid });
|
|
85
84
|
parts.push(toPart({ depth, name: NodeDefs.getName(nodeDef), value, infoParts }));
|
|
86
85
|
return false;
|
|
87
86
|
},
|
|
88
87
|
traverseMethod: TraverseMethod.dfs,
|
|
89
|
-
});
|
|
88
|
+
})(record);
|
|
90
89
|
return parts.join('\n');
|
|
91
90
|
};
|
|
92
91
|
const printNodePath = (params) => {
|
|
93
92
|
const { survey, record, node } = params;
|
|
94
93
|
const parts = [];
|
|
95
|
-
RecordGetters.visitAncestorsAndSelf(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
RecordGetters.visitAncestorsAndSelf({
|
|
95
|
+
node,
|
|
96
|
+
visitor: (visitedNode) => {
|
|
97
|
+
const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: visitedNode.nodeDefUuid });
|
|
98
|
+
let part = NodeDefs.getName(nodeDef);
|
|
99
|
+
if (NodeDefs.isMultiple(nodeDef)) {
|
|
100
|
+
const index = RecordGetters.getNodeIndex({ node: visitedNode })(record);
|
|
101
|
+
part = `${part}[${index}]`;
|
|
102
|
+
}
|
|
103
|
+
parts.unshift(part);
|
|
104
|
+
},
|
|
103
105
|
})(record);
|
|
104
106
|
return parts.join('.');
|
|
105
107
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordPrettyPrinter.js","sourceRoot":"","sources":["../../../src/record/recordPrettyPrinter.ts"],"names":[],"mappings":"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","sourcesContent":["import { Dictionary, TraverseMethod } from '../common'\nimport { ArenaRecordNode, NodeValueFormatter, Nodes } from '../node'\nimport { NodeDefs } from '../nodeDef'\nimport { Survey, Surveys } from '../survey'\nimport { Strings } from '../utils'\nimport { ArenaRecord } from './record'\nimport * as RecordGetters from './_records/recordGetters'\n\ntype PrintOptions = {\n includeEmptyNodes?: boolean\n showNotApplicable?: boolean\n showNotEditable?: boolean\n showNotVisible?: boolean\n}\n\nconst DefaultPrintOptions: PrintOptions = {\n includeEmptyNodes: false,\n showNotApplicable: false,\n showNotEditable: false,\n showNotVisible: false,\n}\n\nconst print = (params: { survey: Survey; record: ArenaRecord; options?: PrintOptions }): string => {\n const { survey, record, options = DefaultPrintOptions } = params\n const { includeEmptyNodes, showNotApplicable, showNotEditable, showNotVisible } = options\n\n const cycle = RecordGetters.getCycle(record)\n const rootNode = RecordGetters.getRoot(record)\n if (!rootNode) {\n return ''\n }\n\n const getInfoParts = (params: { parentNode?: ArenaRecordNode | null; childDefUuid: string }): string[] => {\n const { parentNode, childDefUuid } = params\n if (!parentNode) {\n return []\n }\n const infoParts: string[] = []\n if (showNotApplicable && !Nodes.isChildApplicable(parentNode, childDefUuid)) {\n infoParts.push('not applicable')\n }\n if (showNotEditable && !Nodes.isChildEditable(parentNode, childDefUuid)) {\n infoParts.push('not editable')\n }\n if (showNotVisible && !Nodes.isChildVisible(parentNode, childDefUuid)) {\n infoParts.push('not visible')\n }\n return infoParts\n }\n\n const toPart = (params: { depth: number; name: string; value: string; infoParts?: string[] }): string => {\n const { depth, name, value, infoParts = [] } = params\n const indentation = Strings.repeat(' ', depth)\n let part = `${indentation}${name}: ${value}`\n if (infoParts.length > 0) {\n part += ` (${infoParts.join(', ')})`\n }\n return part\n }\n\n const parts: string[] = []\n\n if (includeEmptyNodes) {\n const printNodeAndChildren = (params: { node: ArenaRecordNode; parentNode: ArenaRecordNode | null }): void => {\n const { node, parentNode } = params\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: node.nodeDefUuid })\n const value = NodeValueFormatter.format({ survey, cycle, nodeDef, node, value: node.value })\n const depth = Nodes.getHierarchy(node).length\n const infoParts = getInfoParts({ parentNode, childDefUuid: node.nodeDefUuid })\n parts.push(toPart({ depth, name: NodeDefs.getName(nodeDef), value, infoParts }))\n\n const childDefs = Surveys.getNodeDefChildrenSorted({ survey, nodeDef, cycle })\n childDefs.forEach((childDef) => {\n const children = RecordGetters.getChildren(node, childDef.uuid)(record)\n if (children.length === 0) {\n const childInfoParts = getInfoParts({ parentNode: node, childDefUuid: childDef.uuid })\n parts.push(\n toPart({\n depth: depth + 1,\n name: NodeDefs.getName(childDef),\n value: '<empty>',\n infoParts: childInfoParts,\n })\n )\n return\n }\n children.forEach((child) => printNodeAndChildren({ node: child, parentNode: node }))\n })\n }\n\n printNodeAndChildren({ node: rootNode, parentNode: null })\n return parts.join('\\n')\n }\n\n RecordGetters.visitDescendantsAndSelf({\n record,\n node: rootNode,\n visitor: (node) => {\n const { nodeDefUuid } = node\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: nodeDefUuid })\n const value = NodeValueFormatter.format({ survey, cycle, nodeDef, node, value: node.value })\n const depth = Nodes.getHierarchy(node).length\n const parentNode = NodeDefs.isRoot(nodeDef) ? null : RecordGetters.getParent(node)(record)\n const infoParts = getInfoParts({ parentNode, childDefUuid: nodeDefUuid })\n parts.push(toPart({ depth, name: NodeDefs.getName(nodeDef), value, infoParts }))\n return false\n },\n traverseMethod: TraverseMethod.dfs,\n })\n return parts.join('\\n')\n}\n\nconst printNodePath = (params: { survey: Survey; record: ArenaRecord; node: ArenaRecordNode }): string => {\n const { survey, record, node } = params\n const parts: string[] = []\n RecordGetters.visitAncestorsAndSelf(node, (visitedNode) => {\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: visitedNode.nodeDefUuid })\n let part = NodeDefs.getName(nodeDef)\n if (NodeDefs.isMultiple(nodeDef)) {\n const index = RecordGetters.getNodeIndex({ record, node: visitedNode })\n part = `${part}[${index}]`\n }\n parts.unshift(part)\n })(record)\n return parts.join('.')\n}\n\nconst printNodesPaths = (params: {\n survey: Survey\n record: ArenaRecord\n nodes: Dictionary<ArenaRecordNode>\n}): string[] => {\n const { survey, record, nodes } = params\n return Object.values(nodes).map((node) => RecordPrettyPrinter.printNodePath({ survey, record, node }))\n}\n\nexport const RecordPrettyPrinter = {\n print,\n printNodePath,\n printNodesPaths,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"recordPrettyPrinter.js","sourceRoot":"","sources":["../../../src/record/recordPrettyPrinter.ts"],"names":[],"mappings":"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","sourcesContent":["import { Dictionary, TraverseMethod } from '../common'\nimport { ArenaRecordNode, NodeValueFormatter, Nodes } from '../node'\nimport { NodeDefs } from '../nodeDef'\nimport { Survey, Surveys } from '../survey'\nimport { Strings } from '../utils'\nimport { ArenaRecord } from './record'\nimport * as RecordGetters from './_records/recordGetters'\n\ntype PrintOptions = {\n includeEmptyNodes?: boolean\n showNotApplicable?: boolean\n showNotEditable?: boolean\n showNotVisible?: boolean\n}\n\nconst DefaultPrintOptions: PrintOptions = {\n includeEmptyNodes: false,\n showNotApplicable: false,\n showNotEditable: false,\n showNotVisible: false,\n}\n\nconst print = (params: { survey: Survey; record: ArenaRecord; options?: PrintOptions }): string => {\n const { survey, record, options = DefaultPrintOptions } = params\n const { includeEmptyNodes, showNotApplicable, showNotEditable, showNotVisible } = options\n\n const cycle = RecordGetters.getCycle(record)\n const rootNode = RecordGetters.getRoot(record)\n if (!rootNode) {\n return ''\n }\n\n const getInfoParts = (params: { parentNode?: ArenaRecordNode | null; childDefUuid: string }): string[] => {\n const { parentNode, childDefUuid } = params\n if (!parentNode) {\n return []\n }\n const infoParts: string[] = []\n if (showNotApplicable && !Nodes.isChildApplicable(parentNode, childDefUuid)) {\n infoParts.push('not applicable')\n }\n if (showNotEditable && !Nodes.isChildEditable(parentNode, childDefUuid)) {\n infoParts.push('not editable')\n }\n if (showNotVisible && !Nodes.isChildVisible(parentNode, childDefUuid)) {\n infoParts.push('not visible')\n }\n return infoParts\n }\n\n const toPart = (params: { depth: number; name: string; value: string; infoParts?: string[] }): string => {\n const { depth, name, value, infoParts = [] } = params\n const indentation = Strings.repeat(' ', depth)\n let part = `${indentation}${name}: ${value}`\n if (infoParts.length > 0) {\n part += ` (${infoParts.join(', ')})`\n }\n return part\n }\n\n const parts: string[] = []\n\n if (includeEmptyNodes) {\n const printNodeAndChildren = (params: { node: ArenaRecordNode; parentNode: ArenaRecordNode | null }): void => {\n const { node, parentNode } = params\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: node.nodeDefUuid })\n const value = NodeValueFormatter.format({ survey, cycle, nodeDef, node, value: node.value })\n const depth = Nodes.getHierarchy(node).length\n const infoParts = getInfoParts({ parentNode, childDefUuid: node.nodeDefUuid })\n parts.push(toPart({ depth, name: NodeDefs.getName(nodeDef), value, infoParts }))\n\n const childDefs = Surveys.getNodeDefChildrenSorted({ survey, nodeDef, cycle })\n childDefs.forEach((childDef) => {\n const children = RecordGetters.getChildren({ parentNode: node, childDefUuid: childDef.uuid })(record)\n if (children.length === 0) {\n const childInfoParts = getInfoParts({ parentNode: node, childDefUuid: childDef.uuid })\n parts.push(\n toPart({\n depth: depth + 1,\n name: NodeDefs.getName(childDef),\n value: '<empty>',\n infoParts: childInfoParts,\n })\n )\n return\n }\n children.forEach((child) => printNodeAndChildren({ node: child, parentNode: node }))\n })\n }\n\n printNodeAndChildren({ node: rootNode, parentNode: null })\n return parts.join('\\n')\n }\n\n RecordGetters.visitDescendantsAndSelf({\n node: rootNode,\n visitor: (node) => {\n const { nodeDefUuid } = node\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: nodeDefUuid })\n const value = NodeValueFormatter.format({ survey, cycle, nodeDef, node, value: node.value })\n const depth = Nodes.getHierarchy(node).length\n const parentNode = NodeDefs.isRoot(nodeDef) ? null : RecordGetters.getParent({ node })(record)\n const infoParts = getInfoParts({ parentNode, childDefUuid: nodeDefUuid })\n parts.push(toPart({ depth, name: NodeDefs.getName(nodeDef), value, infoParts }))\n return false\n },\n traverseMethod: TraverseMethod.dfs,\n })(record)\n return parts.join('\\n')\n}\n\nconst printNodePath = (params: { survey: Survey; record: ArenaRecord; node: ArenaRecordNode }): string => {\n const { survey, record, node } = params\n const parts: string[] = []\n RecordGetters.visitAncestorsAndSelf({\n node,\n visitor: (visitedNode) => {\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: visitedNode.nodeDefUuid })\n let part = NodeDefs.getName(nodeDef)\n if (NodeDefs.isMultiple(nodeDef)) {\n const index = RecordGetters.getNodeIndex({ node: visitedNode })(record)\n part = `${part}[${index}]`\n }\n parts.unshift(part)\n },\n })(record)\n return parts.join('.')\n}\n\nconst printNodesPaths = (params: {\n survey: Survey\n record: ArenaRecord\n nodes: Dictionary<ArenaRecordNode>\n}): string[] => {\n const { survey, record, nodes } = params\n return Object.values(nodes).map((node) => RecordPrettyPrinter.printNodePath({ survey, record, node }))\n}\n\nexport const RecordPrettyPrinter = {\n print,\n printNodePath,\n printNodesPaths,\n}\n"]}
|
|
@@ -25,7 +25,7 @@ const getDependentValidationNodePointers = (params) => {
|
|
|
25
25
|
const uniquePointersByKey = new Map();
|
|
26
26
|
for (const node of Object.values(nodes)) {
|
|
27
27
|
for (const dependencyType of validationDependencyTypes) {
|
|
28
|
-
const nodePointers = Records.getDependentNodePointers({ survey,
|
|
28
|
+
const nodePointers = Records.getDependentNodePointers({ survey, node, dependencyType })(record);
|
|
29
29
|
for (const pointer of nodePointers) {
|
|
30
30
|
const nodeCtxUuid = pointer.nodeCtx.uuid;
|
|
31
31
|
const nodeDefUuid = pointer.nodeDef.uuid;
|
|
@@ -79,7 +79,7 @@ const createRootEntity = (params) => __awaiter(void 0, void 0, void 0, function*
|
|
|
79
79
|
});
|
|
80
80
|
const updateAttributeValue = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
81
|
const { attributeUuid, record, value, dateModified = Dates.nowFormattedForStorage(), sideEffect = false } = params;
|
|
82
|
-
const attribute = Records.getNodeByUuid(attributeUuid)(record);
|
|
82
|
+
const attribute = Records.getNodeByUuid({ uuid: attributeUuid })(record);
|
|
83
83
|
if (!attribute)
|
|
84
84
|
throw new SystemError('record.nodeNotFound');
|
|
85
85
|
let attributeUpdated = sideEffect ? attribute : Object.assign({}, attribute);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordUpdater.js","sourceRoot":"","sources":["../../../src/record/recordUpdater.ts"],"names":[],"mappings":"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","sourcesContent":["import { Dictionary } from '../common'\nimport { SystemError } from '../error'\nimport { ArenaRecordNode, NodePointer, NodesMap } from '../node'\nimport { Survey, SurveyDependencyType, Surveys } from '../survey'\nimport { Dates, Objects } from '../utils'\nimport { Validations } from '../validation/validations'\nimport { NodePointers } from './nodePointers'\nimport { ArenaRecord } from './record'\nimport { RecordNodesUpdater, RecordUpdateResult } from './recordNodesUpdater'\nimport { NodeCreateParams, NodesUpdateParams } from './recordNodesUpdater/recordNodesCreator'\nimport { Records } from './records'\nimport { RecordValidator } from './recordValidator'\n\nconst validationDependencyTypes = [\n SurveyDependencyType.validations,\n SurveyDependencyType.minCount,\n SurveyDependencyType.maxCount,\n]\n\nconst getDependentValidationNodePointers = (params: {\n survey: Survey\n record: ArenaRecord\n nodes: NodesMap\n}): NodePointer[] => {\n const { survey, record, nodes } = params\n const uniquePointersByKey = new Map<string, NodePointer>()\n for (const node of Object.values(nodes)) {\n for (const dependencyType of validationDependencyTypes) {\n const nodePointers = Records.getDependentNodePointers({ survey, record, node, dependencyType })\n for (const pointer of nodePointers) {\n const nodeCtxUuid = pointer.nodeCtx.uuid\n const nodeDefUuid = pointer.nodeDef.uuid\n const key = `${nodeCtxUuid ?? ''}:${nodeDefUuid ?? ''}`\n if (!uniquePointersByKey.has(key)) {\n uniquePointersByKey.set(key, pointer)\n }\n }\n }\n }\n return Array.from(uniquePointersByKey.values())\n}\n\nconst _onRecordNodesCreateOrUpdate = async (\n params: NodesUpdateParams & { nodes: Dictionary<ArenaRecordNode> }\n): Promise<RecordUpdateResult> => {\n const { user, survey, dateModified = Dates.nowFormattedForStorage() } = params\n\n const updateResult = await RecordNodesUpdater.updateNodesDependents(params)\n const { nodes: updatedNodes, record: updatedRecord } = updateResult\n\n const dependentValidationNodePointers = getDependentValidationNodePointers({\n survey,\n record: updatedRecord,\n nodes: updatedNodes,\n })\n\n const dependentValidationNodes = NodePointers.getNodesMapFromNodePointers({\n record: updatedRecord,\n nodePointers: dependentValidationNodePointers,\n })\n\n const nodesToValidate = { ...updatedNodes, ...dependentValidationNodes }\n\n const validationUpdatedNodes = await RecordValidator.validateNodes({\n user,\n survey,\n record: updatedRecord,\n nodes: nodesToValidate,\n })\n\n const validation = Validations.mergeValidations(validationUpdatedNodes)(Validations.getValidation(updatedRecord))\n updatedRecord.validation = validation\n updatedRecord.dateModified = dateModified\n\n updateResult.validation = validation\n\n return updateResult\n}\n\nconst createDescendants = async (params: NodeCreateParams): Promise<RecordUpdateResult> => {\n const { record: updatedRecord, nodes: createdNodes } = await RecordNodesUpdater.createDescendants(params)\n\n return _onRecordNodesCreateOrUpdate({ ...params, record: updatedRecord, nodes: createdNodes })\n}\n\nconst _createNodeAndDescendants = async (params: NodeCreateParams): Promise<RecordUpdateResult> => {\n const { record: updatedRecord, nodes: createdNodes } = await RecordNodesUpdater.createNodeAndDescendants(params)\n\n return _onRecordNodesCreateOrUpdate({ ...params, record: updatedRecord, nodes: createdNodes })\n}\n\nconst createNodeAndDescendants = async (params: NodeCreateParams): Promise<RecordUpdateResult> =>\n _createNodeAndDescendants(params)\n\nconst createRootEntity = async (\n params: NodesUpdateParams & {\n createMultipleEntities?: boolean\n }\n): Promise<RecordUpdateResult> => {\n const { survey, createMultipleEntities = true } = params\n\n return _createNodeAndDescendants({ ...params, nodeDef: Surveys.getNodeDefRoot({ survey }), createMultipleEntities })\n}\n\nconst updateAttributeValue = async (\n params: NodesUpdateParams & {\n attributeUuid: string\n value: any\n }\n): Promise<RecordUpdateResult> => {\n const { attributeUuid, record, value, dateModified = Dates.nowFormattedForStorage(), sideEffect = false } = params\n const attribute = Records.getNodeByUuid(attributeUuid)(record)\n if (!attribute) throw new SystemError('record.nodeNotFound')\n\n let attributeUpdated = sideEffect ? attribute : { ...attribute }\n attributeUpdated.value = value\n attributeUpdated.dateModified = dateModified\n // reset defaultValueApplied flag\n attributeUpdated = Objects.dissocPath({ obj: attributeUpdated, path: ['meta', 'defaultValueApplied'], sideEffect })\n\n const nodesUpdated = { [attributeUuid]: attributeUpdated }\n\n const _record = Records.addNode(attributeUpdated, { sideEffect })(record)\n\n return _onRecordNodesCreateOrUpdate({ ...params, record: _record, nodes: nodesUpdated })\n}\n\nconst deleteNodes = async (\n params: NodesUpdateParams & {\n nodeUuids: string[]\n }\n): Promise<RecordUpdateResult> => {\n const { nodeUuids, record: _record, sideEffect = false } = params\n\n const updateResult = Records.deleteNodes(nodeUuids, { sideEffect })(_record)\n const { record, nodesDeleted } = updateResult\n\n const result = await _onRecordNodesCreateOrUpdate({ ...params, record, nodes: nodesDeleted })\n result.nodesDeleted = nodesDeleted\n return result\n}\n\nconst deleteNode = async (params: NodesUpdateParams & { nodeUuid: string }): Promise<RecordUpdateResult> => {\n const { nodeUuid } = params\n return deleteNodes({ ...params, nodeUuids: [nodeUuid] })\n}\n\nexport const RecordUpdater = {\n createDescendants,\n createNodeAndDescendants,\n createRootEntity,\n updateAttributeValue,\n deleteNode,\n deleteNodes,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"recordUpdater.js","sourceRoot":"","sources":["../../../src/record/recordUpdater.ts"],"names":[],"mappings":"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","sourcesContent":["import { Dictionary } from '../common'\nimport { SystemError } from '../error'\nimport { ArenaRecordNode, NodePointer, NodesMap } from '../node'\nimport { Survey, SurveyDependencyType, Surveys } from '../survey'\nimport { Dates, Objects } from '../utils'\nimport { Validations } from '../validation/validations'\nimport { NodePointers } from './nodePointers'\nimport { ArenaRecord } from './record'\nimport { RecordNodesUpdater, RecordUpdateResult } from './recordNodesUpdater'\nimport { NodeCreateParams, NodesUpdateParams } from './recordNodesUpdater/recordNodesCreator'\nimport { Records } from './records'\nimport { RecordValidator } from './recordValidator'\n\nconst validationDependencyTypes = [\n SurveyDependencyType.validations,\n SurveyDependencyType.minCount,\n SurveyDependencyType.maxCount,\n]\n\nconst getDependentValidationNodePointers = (params: {\n survey: Survey\n record: ArenaRecord\n nodes: NodesMap\n}): NodePointer[] => {\n const { survey, record, nodes } = params\n const uniquePointersByKey = new Map<string, NodePointer>()\n for (const node of Object.values(nodes)) {\n for (const dependencyType of validationDependencyTypes) {\n const nodePointers = Records.getDependentNodePointers({ survey, node, dependencyType })(record)\n for (const pointer of nodePointers) {\n const nodeCtxUuid = pointer.nodeCtx.uuid\n const nodeDefUuid = pointer.nodeDef.uuid\n const key = `${nodeCtxUuid ?? ''}:${nodeDefUuid ?? ''}`\n if (!uniquePointersByKey.has(key)) {\n uniquePointersByKey.set(key, pointer)\n }\n }\n }\n }\n return Array.from(uniquePointersByKey.values())\n}\n\nconst _onRecordNodesCreateOrUpdate = async (\n params: NodesUpdateParams & { nodes: Dictionary<ArenaRecordNode> }\n): Promise<RecordUpdateResult> => {\n const { user, survey, dateModified = Dates.nowFormattedForStorage() } = params\n\n const updateResult = await RecordNodesUpdater.updateNodesDependents(params)\n const { nodes: updatedNodes, record: updatedRecord } = updateResult\n\n const dependentValidationNodePointers = getDependentValidationNodePointers({\n survey,\n record: updatedRecord,\n nodes: updatedNodes,\n })\n\n const dependentValidationNodes = NodePointers.getNodesMapFromNodePointers({\n record: updatedRecord,\n nodePointers: dependentValidationNodePointers,\n })\n\n const nodesToValidate = { ...updatedNodes, ...dependentValidationNodes }\n\n const validationUpdatedNodes = await RecordValidator.validateNodes({\n user,\n survey,\n record: updatedRecord,\n nodes: nodesToValidate,\n })\n\n const validation = Validations.mergeValidations(validationUpdatedNodes)(Validations.getValidation(updatedRecord))\n updatedRecord.validation = validation\n updatedRecord.dateModified = dateModified\n\n updateResult.validation = validation\n\n return updateResult\n}\n\nconst createDescendants = async (params: NodeCreateParams): Promise<RecordUpdateResult> => {\n const { record: updatedRecord, nodes: createdNodes } = await RecordNodesUpdater.createDescendants(params)\n\n return _onRecordNodesCreateOrUpdate({ ...params, record: updatedRecord, nodes: createdNodes })\n}\n\nconst _createNodeAndDescendants = async (params: NodeCreateParams): Promise<RecordUpdateResult> => {\n const { record: updatedRecord, nodes: createdNodes } = await RecordNodesUpdater.createNodeAndDescendants(params)\n\n return _onRecordNodesCreateOrUpdate({ ...params, record: updatedRecord, nodes: createdNodes })\n}\n\nconst createNodeAndDescendants = async (params: NodeCreateParams): Promise<RecordUpdateResult> =>\n _createNodeAndDescendants(params)\n\nconst createRootEntity = async (\n params: NodesUpdateParams & {\n createMultipleEntities?: boolean\n }\n): Promise<RecordUpdateResult> => {\n const { survey, createMultipleEntities = true } = params\n\n return _createNodeAndDescendants({ ...params, nodeDef: Surveys.getNodeDefRoot({ survey }), createMultipleEntities })\n}\n\nconst updateAttributeValue = async (\n params: NodesUpdateParams & {\n attributeUuid: string\n value: any\n }\n): Promise<RecordUpdateResult> => {\n const { attributeUuid, record, value, dateModified = Dates.nowFormattedForStorage(), sideEffect = false } = params\n const attribute = Records.getNodeByUuid({ uuid: attributeUuid })(record)\n if (!attribute) throw new SystemError('record.nodeNotFound')\n\n let attributeUpdated = sideEffect ? attribute : { ...attribute }\n attributeUpdated.value = value\n attributeUpdated.dateModified = dateModified\n // reset defaultValueApplied flag\n attributeUpdated = Objects.dissocPath({ obj: attributeUpdated, path: ['meta', 'defaultValueApplied'], sideEffect })\n\n const nodesUpdated = { [attributeUuid]: attributeUpdated }\n\n const _record = Records.addNode(attributeUpdated, { sideEffect })(record)\n\n return _onRecordNodesCreateOrUpdate({ ...params, record: _record, nodes: nodesUpdated })\n}\n\nconst deleteNodes = async (\n params: NodesUpdateParams & {\n nodeUuids: string[]\n }\n): Promise<RecordUpdateResult> => {\n const { nodeUuids, record: _record, sideEffect = false } = params\n\n const updateResult = Records.deleteNodes(nodeUuids, { sideEffect })(_record)\n const { record, nodesDeleted } = updateResult\n\n const result = await _onRecordNodesCreateOrUpdate({ ...params, record, nodes: nodesDeleted })\n result.nodesDeleted = nodesDeleted\n return result\n}\n\nconst deleteNode = async (params: NodesUpdateParams & { nodeUuid: string }): Promise<RecordUpdateResult> => {\n const { nodeUuid } = params\n return deleteNodes({ ...params, nodeUuids: [nodeUuid] })\n}\n\nexport const RecordUpdater = {\n createDescendants,\n createNodeAndDescendants,\n createRootEntity,\n updateAttributeValue,\n deleteNode,\n deleteNodes,\n}\n"]}
|
|
@@ -21,7 +21,7 @@ const _getKeyValuesByDefUuid = (params) => {
|
|
|
21
21
|
const { survey, record, entity, keyDefs, cache } = params;
|
|
22
22
|
let keyValues = cache === null || cache === void 0 ? void 0 : cache.keyValuesByEntityUuid.get(entity.uuid);
|
|
23
23
|
if (!keyValues) {
|
|
24
|
-
keyValues = Records.getEntityKeyValuesByDefUuid({ survey,
|
|
24
|
+
keyValues = Records.getEntityKeyValuesByDefUuid({ survey, entity, keyDefs })(record);
|
|
25
25
|
cache === null || cache === void 0 ? void 0 : cache.keyValuesByEntityUuid.set(entity.uuid, keyValues);
|
|
26
26
|
}
|
|
27
27
|
return keyValues;
|
|
@@ -29,10 +29,10 @@ const _getKeyValuesByDefUuid = (params) => {
|
|
|
29
29
|
const _isEntityDuplicate = (params) => {
|
|
30
30
|
const { survey, entity, record, entityKeysCache: cache } = params;
|
|
31
31
|
// 1. get sibling entities
|
|
32
|
-
const nodeParent = Records.getParent(entity)(record);
|
|
32
|
+
const nodeParent = Records.getParent({ node: entity })(record);
|
|
33
33
|
if (!nodeParent)
|
|
34
34
|
return false;
|
|
35
|
-
const siblingEntities = Records.getChildren(nodeParent, entity.nodeDefUuid)(record).filter((node) => !Nodes.areEqual(entity, node));
|
|
35
|
+
const siblingEntities = Records.getChildren({ parentNode: nodeParent, childDefUuid: entity.nodeDefUuid })(record).filter((node) => !Nodes.areEqual(entity, node));
|
|
36
36
|
// 2. get key values
|
|
37
37
|
const entityDef = Surveys.getNodeDefByUuid({ survey, uuid: entity.nodeDefUuid });
|
|
38
38
|
const keyDefs = _getKeyDefs({ survey, entityDef, cache });
|
|
@@ -72,7 +72,7 @@ const isNodeDefToBeValidated = (params) => {
|
|
|
72
72
|
const validateAttributeKey = (params) => (_propName, node) => {
|
|
73
73
|
const { survey, nodeDef, record, entityKeysCache } = params;
|
|
74
74
|
if (isNodeDefToBeValidated({ survey, nodeDef })) {
|
|
75
|
-
const entity = Records.getParent(node)(record);
|
|
75
|
+
const entity = Records.getParent({ node })(record);
|
|
76
76
|
if (entity && _isEntityDuplicate({ survey, record, entity, entityKeysCache })) {
|
|
77
77
|
return Promise.resolve(ValidationResultFactory.createInstance({
|
|
78
78
|
valid: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributeKeyValidator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/attributeKeyValidator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAW,QAAQ,EAA6B,MAAM,eAAe,CAAA;AAC5E,OAAO,EAAmB,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAoB,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAChG,OAAO,EAAU,OAAO,EAAE,MAAM,cAAc,CAAA;AAG9C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAWrC,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAoB,EAAE,CAAC,CAAC;IAC3D,sBAAsB,EAAE,IAAI,GAAG,EAAE;IACjC,qBAAqB,EAAE,IAAI,GAAG,EAAE;CACjC,CAAC,CAAA;AAEF,MAAM,WAAW,GAAG,CAAC,MAIpB,EAAwC,EAAE;IACzC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,CAAA;IAC3C,IAAI,OAAO,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAA;QAChE,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,CAAC,MAM/B,EAAmB,EAAE;IACpB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,CAAA;IACzD,IAAI,SAAS,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC7D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,SAAS,GAAG,OAAO,CAAC,2BAA2B,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"attributeKeyValidator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/attributeKeyValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArenaRecord } from '../record'\nimport { Records } from '../records'\nimport { NodeDef, NodeDefs, NodeDefProps, NodeDefType } from '../../nodeDef'\nimport { ArenaRecordNode, Nodes, NodeValues } from '../../node'\nimport { ValidationResult, ValidationResultFactory, ValidationSeverity } from '../../validation'\nimport { Survey, Surveys } from '../../survey'\n\nimport { Dictionary } from '../../common'\nimport { Objects } from '../../utils'\n\n/**\n * Cache of entity key values (and key defs by entity def) used during a single validation run (the record doesn't change):\n * without it, validating the keys of S sibling entities would compute the key values of every sibling S times.\n */\nexport type EntityKeysCache = {\n keyDefsByEntityDefUuid: Map<string, NodeDef<NodeDefType, NodeDefProps>[]>\n keyValuesByEntityUuid: Map<string, Dictionary<any>>\n}\n\nexport const createEntityKeysCache = (): EntityKeysCache => ({\n keyDefsByEntityDefUuid: new Map(),\n keyValuesByEntityUuid: new Map(),\n})\n\nconst _getKeyDefs = (params: {\n survey: Survey\n entityDef: NodeDef<NodeDefType, NodeDefProps>\n cache?: EntityKeysCache\n}): NodeDef<NodeDefType, NodeDefProps>[] => {\n const { survey, entityDef, cache } = params\n let keyDefs = cache?.keyDefsByEntityDefUuid.get(entityDef.uuid)\n if (!keyDefs) {\n keyDefs = Surveys.getNodeDefKeys({ survey, nodeDef: entityDef })\n cache?.keyDefsByEntityDefUuid.set(entityDef.uuid, keyDefs)\n }\n return keyDefs\n}\n\nconst _getKeyValuesByDefUuid = (params: {\n survey: Survey\n record: ArenaRecord\n entity: ArenaRecordNode\n keyDefs: NodeDef<NodeDefType, NodeDefProps>[]\n cache?: EntityKeysCache\n}): Dictionary<any> => {\n const { survey, record, entity, keyDefs, cache } = params\n let keyValues = cache?.keyValuesByEntityUuid.get(entity.uuid)\n if (!keyValues) {\n keyValues = Records.getEntityKeyValuesByDefUuid({ survey, entity, keyDefs })(record)\n cache?.keyValuesByEntityUuid.set(entity.uuid, keyValues)\n }\n return keyValues\n}\n\nconst _isEntityDuplicate = (params: {\n survey: Survey\n record: ArenaRecord\n entity: ArenaRecordNode\n entityKeysCache?: EntityKeysCache\n}): boolean => {\n const { survey, entity, record, entityKeysCache: cache } = params\n // 1. get sibling entities\n const nodeParent = Records.getParent({ node: entity })(record)\n if (!nodeParent) return false\n\n const siblingEntities = Records.getChildren({ parentNode: nodeParent, childDefUuid: entity.nodeDefUuid })(\n record\n ).filter((node) => !Nodes.areEqual(entity, node))\n\n // 2. get key values\n const entityDef = Surveys.getNodeDefByUuid({ survey, uuid: entity.nodeDefUuid })\n const keyDefs = _getKeyDefs({ survey, entityDef, cache })\n\n if (Objects.isEmpty(siblingEntities) || Objects.isEmpty(keyDefs)) {\n return false\n }\n const keyValuesByDefUuid = _getKeyValuesByDefUuid({ survey, record, entity, keyDefs, cache })\n return (\n !Objects.isEmpty(keyValuesByDefUuid) &&\n siblingEntities.some((sibilingEntity) => {\n const siblingKeyValuesByDefUuid = _getKeyValuesByDefUuid({\n survey,\n record,\n entity: sibilingEntity,\n keyDefs,\n cache,\n })\n return keyDefs.every((keyDef) => {\n const keyValue = keyValuesByDefUuid[keyDef.uuid]\n const siblingKeyValue = siblingKeyValuesByDefUuid[keyDef.uuid]\n return NodeValues.isValueEqual({\n survey,\n nodeDef: keyDef,\n value: keyValue,\n valueSearch: siblingKeyValue,\n })\n })\n })\n )\n}\n\nconst isNodeDefToBeValidated = (params: { survey: Survey; nodeDef: NodeDef<NodeDefType, NodeDefProps> }): boolean => {\n const { survey, nodeDef } = params\n if (!NodeDefs.isKey(nodeDef)) return false\n\n const nodeDefParent = Surveys.getNodeDefParent({ survey, nodeDef })\n // root entity key attributes will be validated by another validator\n return !!nodeDefParent && !NodeDefs.isRoot(nodeDefParent)\n}\n\nconst validateAttributeKey =\n (params: {\n survey: Survey\n record: ArenaRecord\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n entityKeysCache?: EntityKeysCache\n }) =>\n (_propName: string, node: ArenaRecordNode): Promise<ValidationResult> => {\n const { survey, nodeDef, record, entityKeysCache } = params\n\n if (isNodeDefToBeValidated({ survey, nodeDef })) {\n const entity = Records.getParent({ node })(record)\n if (entity && _isEntityDuplicate({ survey, record, entity, entityKeysCache })) {\n return Promise.resolve(\n ValidationResultFactory.createInstance({\n valid: false,\n severity: ValidationSeverity.error,\n key: 'record.entity.keyDuplicate',\n })\n )\n }\n }\n\n return Promise.resolve(ValidationResultFactory.createInstance())\n }\n\nexport const AttributeKeyValidator = {\n validateAttributeKey,\n}\n"]}
|
|
@@ -8,7 +8,7 @@ const _isAttributeDuplicate = (params) => {
|
|
|
8
8
|
// blank values are never considered duplicates
|
|
9
9
|
if (Nodes.isValueBlank(attribute))
|
|
10
10
|
return false;
|
|
11
|
-
const nodeSiblings = Records.getAttributeSiblings({
|
|
11
|
+
const nodeSiblings = Records.getAttributeSiblings({ node: attribute, nodeDef })(record);
|
|
12
12
|
return nodeSiblings.some((sibling) => NodeValues.isValueEqual({ survey, nodeDef, value: sibling.value, valueSearch: attribute.value }));
|
|
13
13
|
};
|
|
14
14
|
const isNodeDefToBeValidated = (params) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributeUniqueValidator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/attributeUniqueValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAyB,QAAQ,EAAe,MAAM,eAAe,CAAA;AAC5E,OAAO,EAAU,OAAO,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAoB,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAEhG,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEpC,MAAM,qBAAqB,GAAG,CAAC,MAK9B,EAAW,EAAE;IACZ,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;IACrD,+CAA+C;IAC/C,IAAI,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAA;IAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"attributeUniqueValidator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/attributeUniqueValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAyB,QAAQ,EAAe,MAAM,eAAe,CAAA;AAC5E,OAAO,EAAU,OAAO,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAoB,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAEhG,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEpC,MAAM,qBAAqB,GAAG,CAAC,MAK9B,EAAW,EAAE;IACZ,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;IACrD,+CAA+C;IAC/C,IAAI,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAA;IAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;IACvF,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACnC,UAAU,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,CACjG,CAAA;AACH,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,CAAC,MAAuE,EAAW,EAAE;IAClH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;IAClC,MAAM,kBAAkB,GAAG,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3D,IAAI,EAAC,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,MAAM,CAAA;QAAE,OAAO,KAAK,CAAA;IAE7C,MAAM,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;IACnE,IAAI,CAAC,aAAa,IAAI,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;QACrD,iDAAiD;QACjD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAClC,CAAC,MAA4F,EAAE,EAAE,CACjG,CAAC,SAAiB,EAAE,IAAqB,EAA6B,EAAE;IACtE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;IAE1C,IACE,sBAAsB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC3C,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EACnE,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CACpB,uBAAuB,CAAC,cAAc,CAAC;YACrC,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,kBAAkB,CAAC,KAAK;YAClC,GAAG,EAAE,kCAAkC;SACxC,CAAC,CACH,CAAA;IACH,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,cAAc,EAAE,CAAC,CAAA;AAClE,CAAC,CAAA;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,uBAAuB;CACxB,CAAA","sourcesContent":["import { ArenaRecordNode, Nodes, NodeValues } from '../../node'\nimport { NodeDef, NodeDefProps, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { Survey, Surveys } from '../../survey'\nimport { ValidationResult, ValidationResultFactory, ValidationSeverity } from '../../validation'\nimport { ArenaRecord } from '../record'\nimport { Records } from '../records'\n\nconst _isAttributeDuplicate = (params: {\n survey: Survey\n record: ArenaRecord\n attribute: ArenaRecordNode\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n}): boolean => {\n const { survey, attribute, record, nodeDef } = params\n // blank values are never considered duplicates\n if (Nodes.isValueBlank(attribute)) return false\n const nodeSiblings = Records.getAttributeSiblings({ node: attribute, nodeDef })(record)\n return nodeSiblings.some((sibling) =>\n NodeValues.isValueEqual({ survey, nodeDef, value: sibling.value, valueSearch: attribute.value })\n )\n}\n\nconst isNodeDefToBeValidated = (params: { survey: Survey; nodeDef: NodeDef<NodeDefType, NodeDefProps> }): boolean => {\n const { survey, nodeDef } = params\n const nodeDefValidations = NodeDefs.getValidations(nodeDef)\n if (!nodeDefValidations?.unique) return false\n\n const nodeDefParent = Surveys.getNodeDefParent({ survey, nodeDef })\n if (!nodeDefParent || NodeDefs.isRoot(nodeDefParent)) {\n // uniqueness at record level evaluated elsewhere\n return false\n }\n return true\n}\n\nexport const validateAttributeUnique =\n (params: { survey: Survey; record: ArenaRecord; nodeDef: NodeDef<NodeDefType, NodeDefProps> }) =>\n (_propName: string, node: ArenaRecordNode): Promise<ValidationResult> => {\n const { survey, record, nodeDef } = params\n\n if (\n isNodeDefToBeValidated({ survey, nodeDef }) &&\n _isAttributeDuplicate({ survey, record, attribute: node, nodeDef })\n ) {\n return Promise.resolve(\n ValidationResultFactory.createInstance({\n valid: false,\n severity: ValidationSeverity.error,\n key: 'record.attribute.uniqueDuplicate',\n })\n )\n }\n\n return Promise.resolve(ValidationResultFactory.createInstance())\n }\n\nexport const AttributeUniqueValidator = {\n validateAttributeUnique,\n}\n"]}
|
|
@@ -29,23 +29,22 @@ const _getSiblingNodeKeys = (params) => {
|
|
|
29
29
|
return [];
|
|
30
30
|
}
|
|
31
31
|
const ancestorMultipleEntity = Records.getAncestor({
|
|
32
|
-
record,
|
|
33
32
|
node: attribute,
|
|
34
33
|
ancestorDefUuid: ancestorMultipleEntityDef.uuid,
|
|
35
|
-
});
|
|
34
|
+
})(record);
|
|
36
35
|
if (!ancestorMultipleEntity)
|
|
37
36
|
return [];
|
|
38
|
-
const ancestorMultipleEntityParent = Records.getParent(ancestorMultipleEntity)(record);
|
|
37
|
+
const ancestorMultipleEntityParent = Records.getParent({ node: ancestorMultipleEntity })(record);
|
|
39
38
|
if (!ancestorMultipleEntityParent)
|
|
40
39
|
return [];
|
|
41
40
|
const cacheKey = `${ancestorMultipleEntityParent.uuid}_${ancestorMultipleEntityDef.uuid}`;
|
|
42
41
|
let items = siblingKeyNodesCache === null || siblingKeyNodesCache === void 0 ? void 0 : siblingKeyNodesCache.get(cacheKey);
|
|
43
42
|
if (!items) {
|
|
44
43
|
const keyDefs = Surveys.getNodeDefKeys({ survey, nodeDef: ancestorMultipleEntityDef });
|
|
45
|
-
const entities = Records.getEntitySiblings({
|
|
44
|
+
const entities = Records.getEntitySiblings({ entity: ancestorMultipleEntity, includeSelf: true })(record);
|
|
46
45
|
items = [];
|
|
47
46
|
for (const entity of entities) {
|
|
48
|
-
const keyNodes = Records.getEntityKeyNodes({ survey,
|
|
47
|
+
const keyNodes = Records.getEntityKeyNodes({ survey, entity, keyDefs })(record);
|
|
49
48
|
for (const keyNode of keyNodes) {
|
|
50
49
|
if (!keyNode)
|
|
51
50
|
continue;
|
|
@@ -121,7 +120,7 @@ const _validateNodeValidations = (params) => (_propName, node) => __awaiter(void
|
|
|
121
120
|
});
|
|
122
121
|
const validateAttribute = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
123
122
|
const { survey, record, attribute } = params;
|
|
124
|
-
if (Records.isNodeApplicable({
|
|
123
|
+
if (Records.isNodeApplicable({ node: attribute })(record)) {
|
|
125
124
|
const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: attribute.nodeDefUuid });
|
|
126
125
|
const validatorParams = Object.assign(Object.assign({}, params), { nodeDef });
|
|
127
126
|
return new Validator().validate(attribute, {
|
|
@@ -173,15 +172,14 @@ const findSortedNodesToValidate = (params) => {
|
|
|
173
172
|
// Get dependents and attribute itself
|
|
174
173
|
const nodePointersAttributeAndDependents = Records.getDependentNodePointers({
|
|
175
174
|
survey,
|
|
176
|
-
record,
|
|
177
175
|
node,
|
|
178
176
|
dependencyType: SurveyDependencyType.validations,
|
|
179
177
|
includeSelf: true,
|
|
180
|
-
});
|
|
181
|
-
const nodeParent = Records.getParent(node)(record);
|
|
178
|
+
})(record);
|
|
179
|
+
const nodeParent = Records.getParent({ node })(record);
|
|
182
180
|
result.push(...NodePointers.getNodesFromNodePointers({ record, nodePointers: nodePointersAttributeAndDependents }), ...findSiblingKeyNodesToValidate(Object.assign(Object.assign({}, params), { nodeDef, nodeParent, attribute: node, siblingKeyNodesCache })));
|
|
183
181
|
if ((_a = NodeDefs.getValidations(nodeDef)) === null || _a === void 0 ? void 0 : _a.unique) {
|
|
184
|
-
result.push(...Records.getAttributeSiblings({
|
|
182
|
+
result.push(...Records.getAttributeSiblings({ node, nodeDef })(record));
|
|
185
183
|
}
|
|
186
184
|
}
|
|
187
185
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributeValidator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/attributeValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '../../auth'\nimport { Dictionary } from '../../common'\nimport { Labels } from '../../language'\nimport { ArenaRecordNode, NodeKeys, Nodes, NodeValues } from '../../node'\nimport { NodeDef, NodeDefExpression, NodeDefProps, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { CategoryItemProvider } from '../../nodeDefExpressionEvaluator/categoryItemProvider'\nimport { TaxonProvider } from '../../nodeDefExpressionEvaluator/taxonProvider'\nimport { Survey, Surveys } from '../../survey'\nimport { SurveyDependencyType } from '../../survey/survey'\nimport { Objects } from '../../utils'\nimport {\n ValidationFactory,\n ValidationResult,\n ValidationResultFactory,\n ValidationSeverity,\n Validator,\n} from '../../validation'\nimport { ValidationFields } from '../../validation/validation'\nimport { NodePointers } from '../nodePointers'\nimport { ArenaRecord } from '../record'\nimport { RecordExpressionEvaluator } from '../recordExpressionEvaluator'\nimport { Records } from '../records'\nimport { RecordValidations } from '../recordValidations'\nimport { AttributeKeyValidator, createEntityKeysCache, EntityKeysCache } from './attributeKeyValidator'\nimport { AttributeTypeValidator } from './attributeTypeValidator'\nimport { AttributeUniqueValidator } from './attributeUniqueValidator'\n\nconst expressionEvaluator = new RecordExpressionEvaluator()\n\nexport interface RecordValidatorParams {\n user: User\n survey: Survey\n categoryItemProvider?: CategoryItemProvider\n taxonProvider?: TaxonProvider\n record: ArenaRecord\n}\n\nexport interface AttributeValidatorParams extends RecordValidatorParams {\n attribute: ArenaRecordNode\n}\n\nexport interface AttributesValidatorParams extends RecordValidatorParams {\n nodes: Dictionary<ArenaRecordNode>\n}\n\nexport interface SortedAttributesValidatorParams extends RecordValidatorParams {\n nodesArray: ArenaRecordNode[]\n}\n\ntype SiblingKeyNodeItem = { entityUuid: string; keyNode: ArenaRecordNode; hasErrors: boolean }\n\n// sibling key nodes are cached by ancestor multiple entity parent and def uuid during the same validation call:\n// when many entities are added to the same parent entity (e.g. data import), computing them for every updated\n// key attribute would take a time that grows quadratically with the number of entities\ntype SiblingKeyNodesCache = Map<string, SiblingKeyNodeItem[]>\n\nconst _getSiblingNodeKeys = (\n params: AttributeValidatorParams & { siblingKeyNodesCache?: SiblingKeyNodesCache }\n): SiblingKeyNodeItem[] => {\n const { survey, record, attribute, siblingKeyNodesCache } = params\n\n const attributeDef = Surveys.getNodeDefByUuid({ survey, uuid: attribute.nodeDefUuid })\n const ancestorMultipleEntityDef = Surveys.getNodeDefAncestorMultipleEntity({ survey, nodeDef: attributeDef })\n if (!ancestorMultipleEntityDef) {\n return []\n }\n const ancestorMultipleEntity = Records.getAncestor({\n record,\n node: attribute,\n ancestorDefUuid: ancestorMultipleEntityDef.uuid,\n })\n if (!ancestorMultipleEntity) return []\n\n const ancestorMultipleEntityParent = Records.getParent(ancestorMultipleEntity)(record)\n if (!ancestorMultipleEntityParent) return []\n\n const cacheKey = `${ancestorMultipleEntityParent.uuid}_${ancestorMultipleEntityDef.uuid}`\n let items = siblingKeyNodesCache?.get(cacheKey)\n if (!items) {\n const keyDefs = Surveys.getNodeDefKeys({ survey, nodeDef: ancestorMultipleEntityDef })\n const entities = Records.getEntitySiblings({ record, entity: ancestorMultipleEntity, includeSelf: true })\n items = []\n for (const entity of entities) {\n const keyNodes = Records.getEntityKeyNodes({ survey, record, entity, keyDefs })\n for (const keyNode of keyNodes) {\n if (!keyNode) continue\n const nodeValidation =\n record.validation && RecordValidations.getValidationNode({ nodeUuid: keyNode.uuid })(record.validation)\n items.push({ entityUuid: entity.uuid, keyNode, hasErrors: !!nodeValidation && !nodeValidation.valid })\n }\n }\n siblingKeyNodesCache?.set(cacheKey, items)\n }\n return items.filter((item) => item.entityUuid !== ancestorMultipleEntity.uuid)\n}\n\nconst _getValidationMessagesWithDefault = (params: {\n survey: Survey\n expression: NodeDefExpression\n defaultMessage?: string\n}): Labels => {\n const { survey, expression, defaultMessage } = params\n const messages: Labels = { ...expression.messages }\n\n const languages = Surveys.getLanguages(survey)\n const defaultMessageDefined = Objects.isNotEmpty(defaultMessage)\n\n for (const lang of languages) {\n const customMessage = messages[lang]\n if (Objects.isEmpty(customMessage) && defaultMessageDefined) {\n messages[lang] = defaultMessage\n }\n }\n\n return messages\n}\n\nconst _validateRequired =\n (params: { nodeDef: NodeDef<NodeDefType, NodeDefProps> }) =>\n (_field: string, node: any): Promise<ValidationResult> => {\n const { nodeDef } = params\n const valid = (!NodeDefs.isKey(nodeDef) && !NodeDefs.isRequired(nodeDef)) || !Nodes.isValueBlank(node)\n return Promise.resolve(\n valid\n ? ValidationResultFactory.createInstance()\n : ValidationResultFactory.createInstance({\n key: 'record.attribute.valueRequired',\n severity: ValidationSeverity.error,\n valid,\n })\n )\n }\n\n/**\n * Evaluates the validation expressions.\n */\nconst _validateNodeValidations =\n (params: { user: User; survey: Survey; record: ArenaRecord; nodeDef: NodeDef<NodeDefType, NodeDefProps> }) =>\n async (_propName: string, node: ArenaRecordNode): Promise<ValidationResult> => {\n const { user, survey, record, nodeDef } = params\n if (Nodes.isValueBlank(node)) return ValidationResultFactory.createInstance()\n\n const validations = NodeDefs.getValidations(nodeDef)\n if (!validations?.expressions?.length) return ValidationResultFactory.createInstance()\n\n const applicableExpressionsEval = await expressionEvaluator.evalApplicableExpressions({\n user,\n survey,\n record,\n nodeCtx: node,\n expressions: validations.expressions,\n stopAtFirstFound: false,\n })\n\n let validationResult = ValidationResultFactory.createInstance()\n\n for (const { expression, value: valid } of applicableExpressionsEval) {\n if (!valid) {\n const messages = _getValidationMessagesWithDefault({\n survey,\n expression,\n defaultMessage: expression.expression,\n })\n\n validationResult = ValidationResultFactory.createInstance({\n valid: false,\n key: 'record.attribute.customValidation',\n severity: expression.severity,\n messages,\n })\n break\n }\n }\n\n return validationResult\n }\n\nconst validateAttribute = async (params: AttributeValidatorParams & { entityKeysCache?: EntityKeysCache }) => {\n const { survey, record, attribute } = params\n if (Records.isNodeApplicable({ record, node: attribute })) {\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: attribute.nodeDefUuid })\n const validatorParams = { ...params, nodeDef }\n return new Validator().validate(attribute, {\n [NodeKeys.value]: [\n _validateRequired({ nodeDef }),\n AttributeTypeValidator.validateValueType(validatorParams),\n _validateNodeValidations(validatorParams),\n AttributeKeyValidator.validateAttributeKey(validatorParams),\n AttributeUniqueValidator.validateAttributeUnique(validatorParams),\n ],\n })\n }\n return ValidationFactory.createInstance()\n}\n\nconst findSiblingKeyNodesToValidate = (\n params: AttributeValidatorParams & {\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n nodeParent?: ArenaRecordNode\n siblingKeyNodesCache?: SiblingKeyNodesCache\n }\n) => {\n const { survey, nodeDef, nodeParent: parentNode, attribute } = params\n if (\n !NodeDefs.isKey(nodeDef) ||\n !parentNode ||\n (NodeDefs.isAutoIncrementalKey(nodeDef) && attribute.created && Nodes.isDefaultValueApplied(attribute))\n ) {\n // when a new node is created and the key is autoincremental, its value will be unique\n // and the validation of sibling key attributes is not necessary\n return []\n }\n // when a key attribute is updated, a sibling key attribute with the same value\n // or a sibling attribute with a validation error (duplicate key) should be re-validated\n const siblingNodeKeys = _getSiblingNodeKeys(params)\n const siblingNodeKeysWithSameValue: ArenaRecordNode[] = []\n const siblingNodeKeysWithErrors: ArenaRecordNode[] = []\n siblingNodeKeys.forEach(({ keyNode, hasErrors }) => {\n if (NodeValues.isValueEqual({ survey, nodeDef, parentNode, value: keyNode.value, valueSearch: attribute.value })) {\n siblingNodeKeysWithSameValue.push(keyNode)\n }\n if (hasErrors) {\n siblingNodeKeysWithErrors.push(keyNode)\n }\n })\n return [...siblingNodeKeysWithSameValue, ...siblingNodeKeysWithErrors]\n}\n\nconst findSortedNodesToValidate = (params: SortedAttributesValidatorParams): ArenaRecordNode[] => {\n const { survey, record, nodesArray } = params\n\n const result = []\n const siblingKeyNodesCache: SiblingKeyNodesCache = new Map()\n for (const node of nodesArray) {\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: node.nodeDefUuid })\n if (!NodeDefs.isAttribute(nodeDef)) {\n continue\n }\n // Get dependents and attribute itself\n const nodePointersAttributeAndDependents = Records.getDependentNodePointers({\n survey,\n record,\n node,\n dependencyType: SurveyDependencyType.validations,\n includeSelf: true,\n })\n\n const nodeParent = Records.getParent(node)(record)\n\n result.push(\n ...NodePointers.getNodesFromNodePointers({ record, nodePointers: nodePointersAttributeAndDependents }),\n ...findSiblingKeyNodesToValidate({ ...params, nodeDef, nodeParent, attribute: node, siblingKeyNodesCache })\n )\n\n if (NodeDefs.getValidations(nodeDef)?.unique) {\n result.push(...Records.getAttributeSiblings({ record, node, nodeDef }))\n }\n }\n\n return result\n}\n\nconst validateSelfAndDependentSortedAttributes = async (\n params: SortedAttributesValidatorParams\n): Promise<ValidationFields> => {\n const nodesToValidate: ArenaRecordNode[] = findSortedNodesToValidate(params)\n const validationsByNodeUuid: ValidationFields = {}\n // the record doesn't change during the validation: entity keys can be cached\n const entityKeysCache = createEntityKeysCache()\n\n for (const nodeToValidate of nodesToValidate) {\n const nodeUuid = nodeToValidate.uuid\n // Validate only attributes not deleted and not validated already\n if (!nodeToValidate.deleted && !validationsByNodeUuid[nodeUuid]) {\n // sequential: avoid concurrent item/taxon lookups on large node sets\n const attributeValidatorParams = { ...params, attribute: nodeToValidate, entityKeysCache }\n validationsByNodeUuid[nodeUuid] = await validateAttribute(attributeValidatorParams) // NOSONAR\n }\n }\n return validationsByNodeUuid\n}\n\nexport const AttributeValidator = {\n validateSelfAndDependentSortedAttributes,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"attributeValidator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/attributeValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '../../auth'\nimport { Dictionary } from '../../common'\nimport { Labels } from '../../language'\nimport { ArenaRecordNode, NodeKeys, Nodes, NodeValues } from '../../node'\nimport { NodeDef, NodeDefExpression, NodeDefProps, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { CategoryItemProvider } from '../../nodeDefExpressionEvaluator/categoryItemProvider'\nimport { TaxonProvider } from '../../nodeDefExpressionEvaluator/taxonProvider'\nimport { Survey, Surveys } from '../../survey'\nimport { SurveyDependencyType } from '../../survey/survey'\nimport { Objects } from '../../utils'\nimport {\n ValidationFactory,\n ValidationResult,\n ValidationResultFactory,\n ValidationSeverity,\n Validator,\n} from '../../validation'\nimport { ValidationFields } from '../../validation/validation'\nimport { NodePointers } from '../nodePointers'\nimport { ArenaRecord } from '../record'\nimport { RecordExpressionEvaluator } from '../recordExpressionEvaluator'\nimport { Records } from '../records'\nimport { RecordValidations } from '../recordValidations'\nimport { AttributeKeyValidator, createEntityKeysCache, EntityKeysCache } from './attributeKeyValidator'\nimport { AttributeTypeValidator } from './attributeTypeValidator'\nimport { AttributeUniqueValidator } from './attributeUniqueValidator'\n\nconst expressionEvaluator = new RecordExpressionEvaluator()\n\nexport interface RecordValidatorParams {\n user: User\n survey: Survey\n categoryItemProvider?: CategoryItemProvider\n taxonProvider?: TaxonProvider\n record: ArenaRecord\n}\n\nexport interface AttributeValidatorParams extends RecordValidatorParams {\n attribute: ArenaRecordNode\n}\n\nexport interface AttributesValidatorParams extends RecordValidatorParams {\n nodes: Dictionary<ArenaRecordNode>\n}\n\nexport interface SortedAttributesValidatorParams extends RecordValidatorParams {\n nodesArray: ArenaRecordNode[]\n}\n\ntype SiblingKeyNodeItem = { entityUuid: string; keyNode: ArenaRecordNode; hasErrors: boolean }\n\n// sibling key nodes are cached by ancestor multiple entity parent and def uuid during the same validation call:\n// when many entities are added to the same parent entity (e.g. data import), computing them for every updated\n// key attribute would take a time that grows quadratically with the number of entities\ntype SiblingKeyNodesCache = Map<string, SiblingKeyNodeItem[]>\n\nconst _getSiblingNodeKeys = (\n params: AttributeValidatorParams & { siblingKeyNodesCache?: SiblingKeyNodesCache }\n): SiblingKeyNodeItem[] => {\n const { survey, record, attribute, siblingKeyNodesCache } = params\n\n const attributeDef = Surveys.getNodeDefByUuid({ survey, uuid: attribute.nodeDefUuid })\n const ancestorMultipleEntityDef = Surveys.getNodeDefAncestorMultipleEntity({ survey, nodeDef: attributeDef })\n if (!ancestorMultipleEntityDef) {\n return []\n }\n const ancestorMultipleEntity = Records.getAncestor({\n node: attribute,\n ancestorDefUuid: ancestorMultipleEntityDef.uuid,\n })(record)\n if (!ancestorMultipleEntity) return []\n\n const ancestorMultipleEntityParent = Records.getParent({ node: ancestorMultipleEntity })(record)\n if (!ancestorMultipleEntityParent) return []\n\n const cacheKey = `${ancestorMultipleEntityParent.uuid}_${ancestorMultipleEntityDef.uuid}`\n let items = siblingKeyNodesCache?.get(cacheKey)\n if (!items) {\n const keyDefs = Surveys.getNodeDefKeys({ survey, nodeDef: ancestorMultipleEntityDef })\n const entities = Records.getEntitySiblings({ entity: ancestorMultipleEntity, includeSelf: true })(record)\n items = []\n for (const entity of entities) {\n const keyNodes = Records.getEntityKeyNodes({ survey, entity, keyDefs })(record)\n for (const keyNode of keyNodes) {\n if (!keyNode) continue\n const nodeValidation =\n record.validation && RecordValidations.getValidationNode({ nodeUuid: keyNode.uuid })(record.validation)\n items.push({ entityUuid: entity.uuid, keyNode, hasErrors: !!nodeValidation && !nodeValidation.valid })\n }\n }\n siblingKeyNodesCache?.set(cacheKey, items)\n }\n return items.filter((item) => item.entityUuid !== ancestorMultipleEntity.uuid)\n}\n\nconst _getValidationMessagesWithDefault = (params: {\n survey: Survey\n expression: NodeDefExpression\n defaultMessage?: string\n}): Labels => {\n const { survey, expression, defaultMessage } = params\n const messages: Labels = { ...expression.messages }\n\n const languages = Surveys.getLanguages(survey)\n const defaultMessageDefined = Objects.isNotEmpty(defaultMessage)\n\n for (const lang of languages) {\n const customMessage = messages[lang]\n if (Objects.isEmpty(customMessage) && defaultMessageDefined) {\n messages[lang] = defaultMessage\n }\n }\n\n return messages\n}\n\nconst _validateRequired =\n (params: { nodeDef: NodeDef<NodeDefType, NodeDefProps> }) =>\n (_field: string, node: any): Promise<ValidationResult> => {\n const { nodeDef } = params\n const valid = (!NodeDefs.isKey(nodeDef) && !NodeDefs.isRequired(nodeDef)) || !Nodes.isValueBlank(node)\n return Promise.resolve(\n valid\n ? ValidationResultFactory.createInstance()\n : ValidationResultFactory.createInstance({\n key: 'record.attribute.valueRequired',\n severity: ValidationSeverity.error,\n valid,\n })\n )\n }\n\n/**\n * Evaluates the validation expressions.\n */\nconst _validateNodeValidations =\n (params: { user: User; survey: Survey; record: ArenaRecord; nodeDef: NodeDef<NodeDefType, NodeDefProps> }) =>\n async (_propName: string, node: ArenaRecordNode): Promise<ValidationResult> => {\n const { user, survey, record, nodeDef } = params\n if (Nodes.isValueBlank(node)) return ValidationResultFactory.createInstance()\n\n const validations = NodeDefs.getValidations(nodeDef)\n if (!validations?.expressions?.length) return ValidationResultFactory.createInstance()\n\n const applicableExpressionsEval = await expressionEvaluator.evalApplicableExpressions({\n user,\n survey,\n record,\n nodeCtx: node,\n expressions: validations.expressions,\n stopAtFirstFound: false,\n })\n\n let validationResult = ValidationResultFactory.createInstance()\n\n for (const { expression, value: valid } of applicableExpressionsEval) {\n if (!valid) {\n const messages = _getValidationMessagesWithDefault({\n survey,\n expression,\n defaultMessage: expression.expression,\n })\n\n validationResult = ValidationResultFactory.createInstance({\n valid: false,\n key: 'record.attribute.customValidation',\n severity: expression.severity,\n messages,\n })\n break\n }\n }\n\n return validationResult\n }\n\nconst validateAttribute = async (params: AttributeValidatorParams & { entityKeysCache?: EntityKeysCache }) => {\n const { survey, record, attribute } = params\n if (Records.isNodeApplicable({ node: attribute })(record)) {\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: attribute.nodeDefUuid })\n const validatorParams = { ...params, nodeDef }\n return new Validator().validate(attribute, {\n [NodeKeys.value]: [\n _validateRequired({ nodeDef }),\n AttributeTypeValidator.validateValueType(validatorParams),\n _validateNodeValidations(validatorParams),\n AttributeKeyValidator.validateAttributeKey(validatorParams),\n AttributeUniqueValidator.validateAttributeUnique(validatorParams),\n ],\n })\n }\n return ValidationFactory.createInstance()\n}\n\nconst findSiblingKeyNodesToValidate = (\n params: AttributeValidatorParams & {\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n nodeParent?: ArenaRecordNode\n siblingKeyNodesCache?: SiblingKeyNodesCache\n }\n) => {\n const { survey, nodeDef, nodeParent: parentNode, attribute } = params\n if (\n !NodeDefs.isKey(nodeDef) ||\n !parentNode ||\n (NodeDefs.isAutoIncrementalKey(nodeDef) && attribute.created && Nodes.isDefaultValueApplied(attribute))\n ) {\n // when a new node is created and the key is autoincremental, its value will be unique\n // and the validation of sibling key attributes is not necessary\n return []\n }\n // when a key attribute is updated, a sibling key attribute with the same value\n // or a sibling attribute with a validation error (duplicate key) should be re-validated\n const siblingNodeKeys = _getSiblingNodeKeys(params)\n const siblingNodeKeysWithSameValue: ArenaRecordNode[] = []\n const siblingNodeKeysWithErrors: ArenaRecordNode[] = []\n siblingNodeKeys.forEach(({ keyNode, hasErrors }) => {\n if (NodeValues.isValueEqual({ survey, nodeDef, parentNode, value: keyNode.value, valueSearch: attribute.value })) {\n siblingNodeKeysWithSameValue.push(keyNode)\n }\n if (hasErrors) {\n siblingNodeKeysWithErrors.push(keyNode)\n }\n })\n return [...siblingNodeKeysWithSameValue, ...siblingNodeKeysWithErrors]\n}\n\nconst findSortedNodesToValidate = (params: SortedAttributesValidatorParams): ArenaRecordNode[] => {\n const { survey, record, nodesArray } = params\n\n const result = []\n const siblingKeyNodesCache: SiblingKeyNodesCache = new Map()\n for (const node of nodesArray) {\n const nodeDef = Surveys.getNodeDefByUuid({ survey, uuid: node.nodeDefUuid })\n if (!NodeDefs.isAttribute(nodeDef)) {\n continue\n }\n // Get dependents and attribute itself\n const nodePointersAttributeAndDependents = Records.getDependentNodePointers({\n survey,\n node,\n dependencyType: SurveyDependencyType.validations,\n includeSelf: true,\n })(record)\n\n const nodeParent = Records.getParent({ node })(record)\n\n result.push(\n ...NodePointers.getNodesFromNodePointers({ record, nodePointers: nodePointersAttributeAndDependents }),\n ...findSiblingKeyNodesToValidate({ ...params, nodeDef, nodeParent, attribute: node, siblingKeyNodesCache })\n )\n\n if (NodeDefs.getValidations(nodeDef)?.unique) {\n result.push(...Records.getAttributeSiblings({ node, nodeDef })(record))\n }\n }\n\n return result\n}\n\nconst validateSelfAndDependentSortedAttributes = async (\n params: SortedAttributesValidatorParams\n): Promise<ValidationFields> => {\n const nodesToValidate: ArenaRecordNode[] = findSortedNodesToValidate(params)\n const validationsByNodeUuid: ValidationFields = {}\n // the record doesn't change during the validation: entity keys can be cached\n const entityKeysCache = createEntityKeysCache()\n\n for (const nodeToValidate of nodesToValidate) {\n const nodeUuid = nodeToValidate.uuid\n // Validate only attributes not deleted and not validated already\n if (!nodeToValidate.deleted && !validationsByNodeUuid[nodeUuid]) {\n // sequential: avoid concurrent item/taxon lookups on large node sets\n const attributeValidatorParams = { ...params, attribute: nodeToValidate, entityKeysCache }\n validationsByNodeUuid[nodeUuid] = await validateAttribute(attributeValidatorParams) // NOSONAR\n }\n }\n return validationsByNodeUuid\n}\n\nexport const AttributeValidator = {\n validateSelfAndDependentSortedAttributes,\n}\n"]}
|
|
@@ -46,7 +46,7 @@ const validateChildrenCount = (params) => {
|
|
|
46
46
|
};
|
|
47
47
|
const _countChildren = (params) => {
|
|
48
48
|
const { record, parentNode, childDef } = params;
|
|
49
|
-
const children = Records.getChildren(parentNode, childDef.uuid)(record);
|
|
49
|
+
const children = Records.getChildren({ parentNode, childDefUuid: childDef.uuid })(record);
|
|
50
50
|
const nonEmptyChildren = NodeDefs.isAttribute(childDef)
|
|
51
51
|
? children.filter((child) => !Nodes.isValueBlank(child))
|
|
52
52
|
: children;
|
|
@@ -66,7 +66,7 @@ const getNodePointersToValidate = (params) => {
|
|
|
66
66
|
const { survey, record, node } = params;
|
|
67
67
|
const nodePointersToValidate = [];
|
|
68
68
|
const nodeDef = Surveys.getNodeDefByUuid({ uuid: node.nodeDefUuid, survey });
|
|
69
|
-
const nodeParent = Records.getParent(node)(record);
|
|
69
|
+
const nodeParent = Records.getParent({ node })(record);
|
|
70
70
|
if (nodeParent) {
|
|
71
71
|
// always validate the node itself
|
|
72
72
|
const nodePointer = { nodeCtx: nodeParent, nodeDef };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"countVaildator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/countVaildator.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArenaRecordNode, NodePointer, Nodes } from '../../node'\nimport { NodeDef, NodeDefProps, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { Records } from '../records'\nimport { Validation, ValidationFactory, ValidationResultFactory, ValidationSeverity } from '../../validation'\nimport { ArenaRecord } from '../record'\nimport { Survey, Surveys } from '../../survey'\nimport { RecordValidations } from '../recordValidations'\nimport { ValidationFields } from '../../validation/validation'\n\nconst createValidationResult = (params: {\n nodeDefUuid: string\n isMinCountValidation: boolean\n minCount: number\n maxCount: number\n}): Validation => {\n const { nodeDefUuid, isMinCountValidation, minCount, maxCount } = params\n\n if (minCount === maxCount) {\n return ValidationFactory.createInstance({\n valid: false,\n errors: [\n ValidationResultFactory.createInstance({\n key: 'record.nodes.count.invalid',\n params: { nodeDefUuid, count: minCount },\n severity: ValidationSeverity.error,\n }),\n ],\n })\n }\n return ValidationFactory.createInstance({\n valid: false,\n errors: [\n ValidationResultFactory.createInstance({\n key: isMinCountValidation ? 'record.nodes.count.minNotReached' : 'record.nodes.count.maxExceeded',\n params: { nodeDefUuid, ...(isMinCountValidation ? { minCount } : { maxCount }) },\n severity: ValidationSeverity.error,\n }),\n ],\n })\n}\n\nconst validateChildrenCount = (params: {\n parentNode: ArenaRecordNode\n nodeDefChild: NodeDef<NodeDefType, NodeDefProps>\n count: number\n}): Validation => {\n const { parentNode, nodeDefChild, count } = params\n\n const minCount = Nodes.getChildrenMinCount({ parentNode, nodeDef: nodeDefChild })\n const maxCount = Nodes.getChildrenMaxCount({ parentNode, nodeDef: nodeDefChild })\n\n const minCountValid = Number.isNaN(minCount) || count >= minCount\n const maxCountValid = Number.isNaN(maxCount) || count <= maxCount\n\n return minCountValid && maxCountValid\n ? ValidationFactory.createInstance()\n : createValidationResult({\n nodeDefUuid: nodeDefChild.uuid,\n isMinCountValidation: !minCountValid,\n minCount,\n maxCount,\n })\n}\n\nconst _countChildren = (params: {\n record: ArenaRecord\n parentNode: ArenaRecordNode\n childDef: NodeDef<NodeDefType, NodeDefProps>\n}) => {\n const { record, parentNode, childDef } = params\n const children = Records.getChildren(parentNode, childDef.uuid)(record)\n const nonEmptyChildren = NodeDefs.isAttribute(childDef)\n ? children.filter((child) => !Nodes.isValueBlank(child))\n : children\n return nonEmptyChildren.length\n}\n\nconst isNodePointerToBeValidated = (nodePointer: NodePointer) => NodeDefs.hasMinOrMaxCount(nodePointer.nodeDef)\n\nconst validateNodePointer = (params: {\n record: ArenaRecord\n nodeCtx: ArenaRecordNode\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n}) => {\n const { record, nodeCtx, nodeDef } = params\n // Check children count only for applicable nodes\n if (Nodes.isChildApplicable(nodeCtx, nodeDef.uuid)) {\n const count = _countChildren({ record, parentNode: nodeCtx, childDef: nodeDef })\n return validateChildrenCount({ parentNode: nodeCtx, nodeDefChild: nodeDef, count })\n }\n return ValidationFactory.createInstance()\n}\n\nconst getNodePointersToValidate = (params: {\n survey: Survey\n record: ArenaRecord\n node: ArenaRecordNode\n}): NodePointer[] => {\n const { survey, record, node } = params\n const nodePointersToValidate: NodePointer[] = []\n\n const nodeDef = Surveys.getNodeDefByUuid({ uuid: node.nodeDefUuid, survey })\n\n const nodeParent = Records.getParent(node)(record)\n if (nodeParent) {\n // always validate the node itself\n const nodePointer = { nodeCtx: nodeParent, nodeDef }\n if (isNodePointerToBeValidated(nodePointer)) {\n nodePointersToValidate.push(nodePointer)\n }\n }\n if (NodeDefs.isEntity(nodeDef) && !node.deleted) {\n // validate the count of every node def children\n const childDefs = Surveys.getNodeDefChildren({ survey, nodeDef })\n for (const childDef of childDefs) {\n const nodePointer = { nodeCtx: node, nodeDef: childDef }\n if (isNodePointerToBeValidated(nodePointer)) {\n nodePointersToValidate.push(nodePointer)\n }\n }\n }\n return nodePointersToValidate\n}\n\nconst validateChildrenCountNodesArray = (params: {\n survey: Survey\n record: ArenaRecord\n nodesArray: ArenaRecordNode[]\n}): ValidationFields => {\n const { survey, record, nodesArray } = params\n const validationsAcc: ValidationFields = {}\n for (const node of nodesArray) {\n const nodePointersToValidate = getNodePointersToValidate({ survey, record, node })\n\n for (const nodePointer of nodePointersToValidate) {\n const { nodeCtx, nodeDef } = nodePointer\n // check if validated already\n const validationChildrenCountKey = RecordValidations.getValidationChildrenCountKey({\n nodeParentUuid: nodeCtx.uuid,\n nodeDefChildUuid: nodeDef.uuid,\n })\n if (!(validationChildrenCountKey in validationsAcc)) {\n // validate the children count of this node pointer\n const validationNodePointer = validateNodePointer({ record, nodeCtx, nodeDef })\n validationsAcc[validationChildrenCountKey] = validationNodePointer\n }\n }\n }\n return validationsAcc\n}\n\nconst validateChildrenCountNodes = (params: {\n survey: Survey\n record: ArenaRecord\n nodes: { [key: string]: ArenaRecordNode }\n}): ValidationFields => validateChildrenCountNodesArray({ ...params, nodesArray: Object.values(params.nodes) })\n\nexport const CountValidator = {\n validateChildrenCount,\n validateChildrenCountNodesArray,\n validateChildrenCountNodes,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"countVaildator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/countVaildator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,EAAE,MAAM,YAAY,CAAA;AAChE,OAAO,EAAyB,QAAQ,EAAe,MAAM,eAAe,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAc,iBAAiB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAE7G,OAAO,EAAU,OAAO,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGxD,MAAM,sBAAsB,GAAG,CAAC,MAK/B,EAAc,EAAE;IACf,MAAM,EAAE,WAAW,EAAE,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAExE,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,iBAAiB,CAAC,cAAc,CAAC;YACtC,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE;gBACN,uBAAuB,CAAC,cAAc,CAAC;oBACrC,GAAG,EAAE,4BAA4B;oBACjC,MAAM,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE;oBACxC,QAAQ,EAAE,kBAAkB,CAAC,KAAK;iBACnC,CAAC;aACH;SACF,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,iBAAiB,CAAC,cAAc,CAAC;QACtC,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE;YACN,uBAAuB,CAAC,cAAc,CAAC;gBACrC,GAAG,EAAE,oBAAoB,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,gCAAgC;gBACjG,MAAM,kBAAI,WAAW,IAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAE;gBAChF,QAAQ,EAAE,kBAAkB,CAAC,KAAK;aACnC,CAAC;SACH;KACF,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,qBAAqB,GAAG,CAAC,MAI9B,EAAc,EAAE;IACf,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,MAAM,CAAA;IAElD,MAAM,QAAQ,GAAG,KAAK,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAA;IACjF,MAAM,QAAQ,GAAG,KAAK,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAA;IAEjF,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAA;IACjE,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAA;IAEjE,OAAO,aAAa,IAAI,aAAa;QACnC,CAAC,CAAC,iBAAiB,CAAC,cAAc,EAAE;QACpC,CAAC,CAAC,sBAAsB,CAAC;YACrB,WAAW,EAAE,YAAY,CAAC,IAAI;YAC9B,oBAAoB,EAAE,CAAC,aAAa;YACpC,QAAQ;YACR,QAAQ;SACT,CAAC,CAAA;AACR,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,MAIvB,EAAE,EAAE;IACH,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;IACzF,MAAM,gBAAgB,GAAG,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC;QACrD,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,QAAQ,CAAA;IACZ,OAAO,gBAAgB,CAAC,MAAM,CAAA;AAChC,CAAC,CAAA;AAED,MAAM,0BAA0B,GAAG,CAAC,WAAwB,EAAE,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;AAE/G,MAAM,mBAAmB,GAAG,CAAC,MAI5B,EAAE,EAAE;IACH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;IAC3C,iDAAiD;IACjD,IAAI,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;QAChF,OAAO,qBAAqB,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;IACrF,CAAC;IACD,OAAO,iBAAiB,CAAC,cAAc,EAAE,CAAA;AAC3C,CAAC,CAAA;AAED,MAAM,yBAAyB,GAAG,CAAC,MAIlC,EAAiB,EAAE;IAClB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAA;IACvC,MAAM,sBAAsB,GAAkB,EAAE,CAAA;IAEhD,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAAA;IAE5E,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;IACtD,IAAI,UAAU,EAAE,CAAC;QACf,kCAAkC;QAClC,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAA;QACpD,IAAI,0BAA0B,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5C,sBAAsB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAChD,gDAAgD;QAChD,MAAM,SAAS,GAAG,OAAO,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;QACjE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;YACxD,IAAI,0BAA0B,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC5C,sBAAsB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,sBAAsB,CAAA;AAC/B,CAAC,CAAA;AAED,MAAM,+BAA+B,GAAG,CAAC,MAIxC,EAAoB,EAAE;IACrB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;IAC7C,MAAM,cAAc,GAAqB,EAAE,CAAA;IAC3C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,sBAAsB,GAAG,yBAAyB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QAElF,KAAK,MAAM,WAAW,IAAI,sBAAsB,EAAE,CAAC;YACjD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;YACxC,6BAA6B;YAC7B,MAAM,0BAA0B,GAAG,iBAAiB,CAAC,6BAA6B,CAAC;gBACjF,cAAc,EAAE,OAAO,CAAC,IAAI;gBAC5B,gBAAgB,EAAE,OAAO,CAAC,IAAI;aAC/B,CAAC,CAAA;YACF,IAAI,CAAC,CAAC,0BAA0B,IAAI,cAAc,CAAC,EAAE,CAAC;gBACpD,mDAAmD;gBACnD,MAAM,qBAAqB,GAAG,mBAAmB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;gBAC/E,cAAc,CAAC,0BAA0B,CAAC,GAAG,qBAAqB,CAAA;YACpE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,cAAc,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,0BAA0B,GAAG,CAAC,MAInC,EAAoB,EAAE,CAAC,+BAA+B,iCAAM,MAAM,KAAE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAG,CAAA;AAE/G,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,qBAAqB;IACrB,+BAA+B;IAC/B,0BAA0B;CAC3B,CAAA","sourcesContent":["import { ArenaRecordNode, NodePointer, Nodes } from '../../node'\nimport { NodeDef, NodeDefProps, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { Records } from '../records'\nimport { Validation, ValidationFactory, ValidationResultFactory, ValidationSeverity } from '../../validation'\nimport { ArenaRecord } from '../record'\nimport { Survey, Surveys } from '../../survey'\nimport { RecordValidations } from '../recordValidations'\nimport { ValidationFields } from '../../validation/validation'\n\nconst createValidationResult = (params: {\n nodeDefUuid: string\n isMinCountValidation: boolean\n minCount: number\n maxCount: number\n}): Validation => {\n const { nodeDefUuid, isMinCountValidation, minCount, maxCount } = params\n\n if (minCount === maxCount) {\n return ValidationFactory.createInstance({\n valid: false,\n errors: [\n ValidationResultFactory.createInstance({\n key: 'record.nodes.count.invalid',\n params: { nodeDefUuid, count: minCount },\n severity: ValidationSeverity.error,\n }),\n ],\n })\n }\n return ValidationFactory.createInstance({\n valid: false,\n errors: [\n ValidationResultFactory.createInstance({\n key: isMinCountValidation ? 'record.nodes.count.minNotReached' : 'record.nodes.count.maxExceeded',\n params: { nodeDefUuid, ...(isMinCountValidation ? { minCount } : { maxCount }) },\n severity: ValidationSeverity.error,\n }),\n ],\n })\n}\n\nconst validateChildrenCount = (params: {\n parentNode: ArenaRecordNode\n nodeDefChild: NodeDef<NodeDefType, NodeDefProps>\n count: number\n}): Validation => {\n const { parentNode, nodeDefChild, count } = params\n\n const minCount = Nodes.getChildrenMinCount({ parentNode, nodeDef: nodeDefChild })\n const maxCount = Nodes.getChildrenMaxCount({ parentNode, nodeDef: nodeDefChild })\n\n const minCountValid = Number.isNaN(minCount) || count >= minCount\n const maxCountValid = Number.isNaN(maxCount) || count <= maxCount\n\n return minCountValid && maxCountValid\n ? ValidationFactory.createInstance()\n : createValidationResult({\n nodeDefUuid: nodeDefChild.uuid,\n isMinCountValidation: !minCountValid,\n minCount,\n maxCount,\n })\n}\n\nconst _countChildren = (params: {\n record: ArenaRecord\n parentNode: ArenaRecordNode\n childDef: NodeDef<NodeDefType, NodeDefProps>\n}) => {\n const { record, parentNode, childDef } = params\n const children = Records.getChildren({ parentNode, childDefUuid: childDef.uuid })(record)\n const nonEmptyChildren = NodeDefs.isAttribute(childDef)\n ? children.filter((child) => !Nodes.isValueBlank(child))\n : children\n return nonEmptyChildren.length\n}\n\nconst isNodePointerToBeValidated = (nodePointer: NodePointer) => NodeDefs.hasMinOrMaxCount(nodePointer.nodeDef)\n\nconst validateNodePointer = (params: {\n record: ArenaRecord\n nodeCtx: ArenaRecordNode\n nodeDef: NodeDef<NodeDefType, NodeDefProps>\n}) => {\n const { record, nodeCtx, nodeDef } = params\n // Check children count only for applicable nodes\n if (Nodes.isChildApplicable(nodeCtx, nodeDef.uuid)) {\n const count = _countChildren({ record, parentNode: nodeCtx, childDef: nodeDef })\n return validateChildrenCount({ parentNode: nodeCtx, nodeDefChild: nodeDef, count })\n }\n return ValidationFactory.createInstance()\n}\n\nconst getNodePointersToValidate = (params: {\n survey: Survey\n record: ArenaRecord\n node: ArenaRecordNode\n}): NodePointer[] => {\n const { survey, record, node } = params\n const nodePointersToValidate: NodePointer[] = []\n\n const nodeDef = Surveys.getNodeDefByUuid({ uuid: node.nodeDefUuid, survey })\n\n const nodeParent = Records.getParent({ node })(record)\n if (nodeParent) {\n // always validate the node itself\n const nodePointer = { nodeCtx: nodeParent, nodeDef }\n if (isNodePointerToBeValidated(nodePointer)) {\n nodePointersToValidate.push(nodePointer)\n }\n }\n if (NodeDefs.isEntity(nodeDef) && !node.deleted) {\n // validate the count of every node def children\n const childDefs = Surveys.getNodeDefChildren({ survey, nodeDef })\n for (const childDef of childDefs) {\n const nodePointer = { nodeCtx: node, nodeDef: childDef }\n if (isNodePointerToBeValidated(nodePointer)) {\n nodePointersToValidate.push(nodePointer)\n }\n }\n }\n return nodePointersToValidate\n}\n\nconst validateChildrenCountNodesArray = (params: {\n survey: Survey\n record: ArenaRecord\n nodesArray: ArenaRecordNode[]\n}): ValidationFields => {\n const { survey, record, nodesArray } = params\n const validationsAcc: ValidationFields = {}\n for (const node of nodesArray) {\n const nodePointersToValidate = getNodePointersToValidate({ survey, record, node })\n\n for (const nodePointer of nodePointersToValidate) {\n const { nodeCtx, nodeDef } = nodePointer\n // check if validated already\n const validationChildrenCountKey = RecordValidations.getValidationChildrenCountKey({\n nodeParentUuid: nodeCtx.uuid,\n nodeDefChildUuid: nodeDef.uuid,\n })\n if (!(validationChildrenCountKey in validationsAcc)) {\n // validate the children count of this node pointer\n const validationNodePointer = validateNodePointer({ record, nodeCtx, nodeDef })\n validationsAcc[validationChildrenCountKey] = validationNodePointer\n }\n }\n }\n return validationsAcc\n}\n\nconst validateChildrenCountNodes = (params: {\n survey: Survey\n record: ArenaRecord\n nodes: { [key: string]: ArenaRecordNode }\n}): ValidationFields => validateChildrenCountNodesArray({ ...params, nodesArray: Object.values(params.nodes) })\n\nexport const CountValidator = {\n validateChildrenCount,\n validateChildrenCountNodesArray,\n validateChildrenCountNodes,\n}\n"]}
|
|
@@ -30,13 +30,12 @@ export const validateRecord = (params) => __awaiter(void 0, void 0, void 0, func
|
|
|
30
30
|
const nodesArray = [];
|
|
31
31
|
const nodes = {};
|
|
32
32
|
Records.visitDescendantsAndSelf({
|
|
33
|
-
record,
|
|
34
33
|
node: Records.getRoot(record),
|
|
35
34
|
visitor: (node) => {
|
|
36
35
|
nodesArray.push(node);
|
|
37
36
|
nodes[node.uuid] = node;
|
|
38
37
|
},
|
|
39
|
-
});
|
|
38
|
+
})(record);
|
|
40
39
|
return validateSortedNodes(Object.assign(Object.assign({}, params), { nodesArray }));
|
|
41
40
|
});
|
|
42
41
|
//# sourceMappingURL=recordValidator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordValidator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/recordValidator.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAc,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAEL,kBAAkB,GAGnB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAO,MAAuC,EAAuB,EAAE;IACxG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;IAE7C,yBAAyB;IACzB,MAAM,oBAAoB,GAAG,MAAM,kBAAkB,CAAC,wCAAwC,iCACzF,MAAM,KACT,UAAU,IACV,CAAA;IAEF,4BAA4B;IAC5B,MAAM,oBAAoB,GAAG,cAAc,CAAC,+BAA+B,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAA;IAE3G,uBAAuB;IACvB,OAAO,WAAW,CAAC,mBAAmB,CACpC,iBAAiB,CAAC,cAAc,CAAC;QAC/B,KAAK,EAAE,IAAI;QACX,MAAM,kCACD,oBAAoB,GACpB,oBAAoB,CACxB;KACF,CAAC,CACH,CAAA;AACH,CAAC,CAAA,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,MAAiC,EAAuB,EAAE,kDAC5F,OAAA,mBAAmB,iCAAM,MAAM,KAAE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAG,CAAA,CAE7E,CAAC,CAF4E,CAAA;AAE7E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAO,MAA6B,EAAuB,EAAE;IACzF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACzB,MAAM,UAAU,GAAsB,EAAE,CAAA;IACxC,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,OAAO,CAAC,uBAAuB,CAAC;QAC9B,
|
|
1
|
+
{"version":3,"file":"recordValidator.js","sourceRoot":"","sources":["../../../../src/record/recordValidator/recordValidator.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAc,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAEL,kBAAkB,GAGnB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAO,MAAuC,EAAuB,EAAE;IACxG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;IAE7C,yBAAyB;IACzB,MAAM,oBAAoB,GAAG,MAAM,kBAAkB,CAAC,wCAAwC,iCACzF,MAAM,KACT,UAAU,IACV,CAAA;IAEF,4BAA4B;IAC5B,MAAM,oBAAoB,GAAG,cAAc,CAAC,+BAA+B,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAA;IAE3G,uBAAuB;IACvB,OAAO,WAAW,CAAC,mBAAmB,CACpC,iBAAiB,CAAC,cAAc,CAAC;QAC/B,KAAK,EAAE,IAAI;QACX,MAAM,kCACD,oBAAoB,GACpB,oBAAoB,CACxB;KACF,CAAC,CACH,CAAA;AACH,CAAC,CAAA,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,MAAiC,EAAuB,EAAE,kDAC5F,OAAA,mBAAmB,iCAAM,MAAM,KAAE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAG,CAAA,CAE7E,CAAC,CAF4E,CAAA;AAE7E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAO,MAA6B,EAAuB,EAAE;IACzF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACzB,MAAM,UAAU,GAAsB,EAAE,CAAA;IACxC,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,OAAO,CAAC,uBAAuB,CAAC;QAC9B,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAE;QAC9B,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAChB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;QACzB,CAAC;KACF,CAAC,CAAC,MAAM,CAAC,CAAA;IAEV,OAAO,mBAAmB,iCAAM,MAAM,KAAE,UAAU,IAAG,CAAA;AACvD,CAAC,CAAA,CAAA","sourcesContent":["import { ArenaRecordNode, NodesMap } from '../../node'\nimport { Validation, ValidationFactory } from '../../validation'\nimport { Validations } from '../../validation/validations'\nimport { Records } from '../records'\nimport {\n AttributesValidatorParams,\n AttributeValidator,\n RecordValidatorParams,\n SortedAttributesValidatorParams,\n} from './attributeValidator'\nimport { CountValidator } from './countVaildator'\n\nexport const validateSortedNodes = async (params: SortedAttributesValidatorParams): Promise<Validation> => {\n const { survey, record, nodesArray } = params\n\n // 1. validate attributes\n const attributeValidations = await AttributeValidator.validateSelfAndDependentSortedAttributes({\n ...params,\n nodesArray,\n })\n\n // 2. validate min/max count\n const nodeCountValidations = CountValidator.validateChildrenCountNodesArray({ survey, record, nodesArray })\n\n // 3. merge validations\n return Validations.recalculateValidity(\n ValidationFactory.createInstance({\n valid: true,\n fields: {\n ...attributeValidations,\n ...nodeCountValidations,\n },\n })\n )\n}\n\nexport const validateNodes = async (params: AttributesValidatorParams): Promise<Validation> =>\n validateSortedNodes({ ...params, nodesArray: Object.values(params.nodes) })\n\nexport const validateRecord = async (params: RecordValidatorParams): Promise<Validation> => {\n const { record } = params\n const nodesArray: ArenaRecordNode[] = []\n const nodes: NodesMap = {}\n Records.visitDescendantsAndSelf({\n node: Records.getRoot(record)!,\n visitor: (node) => {\n nodesArray.push(node)\n nodes[node.uuid] = node\n },\n })(record)\n\n return validateSortedNodes({ ...params, nodesArray })\n}\n"]}
|
|
@@ -17,17 +17,17 @@ const getAttributeCompletionStats = (params) => {
|
|
|
17
17
|
const minCount = node_1.Nodes.getChildrenMinCount({ parentNode: entity, nodeDef });
|
|
18
18
|
if (Number.isNaN(minCount) || minCount <= 0)
|
|
19
19
|
return emptyStats();
|
|
20
|
-
const filledNodesCount = (0, recordGetters_1.getChildren)(entity, nodeDef.uuid)(record).filter(node_1.Nodes.isValueNotBlank).length;
|
|
20
|
+
const filledNodesCount = (0, recordGetters_1.getChildren)({ parentNode: entity, childDefUuid: nodeDef.uuid })(record).filter(node_1.Nodes.isValueNotBlank).length;
|
|
21
21
|
return { total: minCount, filled: Math.min(filledNodesCount, minCount) };
|
|
22
22
|
}
|
|
23
23
|
if (!nodeDef_1.NodeDefs.isRequired(nodeDef) && !nodeDef_1.NodeDefs.isKey(nodeDef))
|
|
24
24
|
return emptyStats();
|
|
25
|
-
const node = (0, recordGetters_1.getChildren)(entity, nodeDef.uuid)(record)[0];
|
|
25
|
+
const node = (0, recordGetters_1.getChildren)({ parentNode: entity, childDefUuid: nodeDef.uuid })(record)[0];
|
|
26
26
|
return { total: 1, filled: node && node_1.Nodes.isValueNotBlank(node) ? 1 : 0 };
|
|
27
27
|
};
|
|
28
28
|
const getChildEntityCompletionStats = (params) => {
|
|
29
29
|
const { survey, record, parentEntity, nodeDef } = params;
|
|
30
|
-
const childEntities = (0, recordGetters_1.getChildren)(parentEntity, nodeDef.uuid)(record);
|
|
30
|
+
const childEntities = (0, recordGetters_1.getChildren)({ parentNode: parentEntity, childDefUuid: nodeDef.uuid })(record);
|
|
31
31
|
if (nodeDef_1.NodeDefs.isSingle(nodeDef)) {
|
|
32
32
|
const childEntity = childEntities[0];
|
|
33
33
|
return childEntity ? (0, exports.getEntityCompletionStats)({ survey, record, entity: childEntity }) : emptyStats();
|