@openforis/arena-core 2.3.40 → 2.3.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/auth/authorizer.d.ts +3 -3
  2. package/dist/auth/authorizer.js.map +1 -1
  3. package/dist/esm/auth/authorizer.js.map +1 -1
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/node/factory.js.map +1 -1
  6. package/dist/esm/node/index.js.map +1 -1
  7. package/dist/esm/node/node.js.map +1 -1
  8. package/dist/esm/node/nodePointer.js.map +1 -1
  9. package/dist/esm/node/nodeValueFormatter.js.map +1 -1
  10. package/dist/esm/node/nodeValues.js.map +1 -1
  11. package/dist/esm/node/nodes.js +1 -1
  12. package/dist/esm/node/nodes.js.map +1 -1
  13. package/dist/esm/node/service.js.map +1 -1
  14. package/dist/esm/nodeDefExpressionEvaluator/functions.js.map +1 -1
  15. package/dist/esm/record/_records/recordCompletion.js.map +1 -1
  16. package/dist/esm/record/_records/recordGetters.js.map +1 -1
  17. package/dist/esm/record/_records/recordNodesIndexUpdater.js.map +1 -1
  18. package/dist/esm/record/_records/recordPagesValidation.js.map +1 -1
  19. package/dist/esm/record/_records/recordUpdater.js.map +1 -1
  20. package/dist/esm/record/_records/recordUtils.js.map +1 -1
  21. package/dist/esm/record/factory.js.map +1 -1
  22. package/dist/esm/record/index.js.map +1 -1
  23. package/dist/esm/record/nodePointers.js.map +1 -1
  24. package/dist/esm/record/record.js.map +1 -1
  25. package/dist/esm/record/recordCloner.js.map +1 -1
  26. package/dist/esm/record/recordExpressionEvaluator/context.js.map +1 -1
  27. package/dist/esm/record/recordExpressionEvaluator/node/identifier/identifier.js.map +1 -1
  28. package/dist/esm/record/recordExpressionEvaluator/node/identifier/nodesFinder.js.map +1 -1
  29. package/dist/esm/record/recordExpressionEvaluator/nodeValueExtractor.js.map +1 -1
  30. package/dist/esm/record/recordExpressionEvaluator/recordExpressionEvaluator.js.map +1 -1
  31. package/dist/esm/record/recordFixer.js.map +1 -1
  32. package/dist/esm/record/recordNodesUpdater/recordEnumeratingItemsExpressionEvaluator.js.map +1 -1
  33. package/dist/esm/record/recordNodesUpdater/recordExpressionValueConverter.js.map +1 -1
  34. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js.map +1 -1
  35. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsBooleanUpdater.js.map +1 -1
  36. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js.map +1 -1
  37. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js.map +1 -1
  38. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js.map +1 -1
  39. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js.map +1 -1
  40. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js.map +1 -1
  41. package/dist/esm/record/recordNodesUpdater/recordNodeDependentsUpdateParams.js.map +1 -1
  42. package/dist/esm/record/recordNodesUpdater/recordNodesCreator.js.map +1 -1
  43. package/dist/esm/record/recordNodesUpdater/recordNodesDeleter.js.map +1 -1
  44. package/dist/esm/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js.map +1 -1
  45. package/dist/esm/record/recordNodesUpdater/recordNodesUpdater.js.map +1 -1
  46. package/dist/esm/record/recordNodesUpdater/recordUpdateResult.js.map +1 -1
  47. package/dist/esm/record/recordPrettyPrinter.js.map +1 -1
  48. package/dist/esm/record/recordUpdater.js.map +1 -1
  49. package/dist/esm/record/recordValidator/attributeKeyValidator.js.map +1 -1
  50. package/dist/esm/record/recordValidator/attributeTypeValidator.js.map +1 -1
  51. package/dist/esm/record/recordValidator/attributeUniqueValidator.js.map +1 -1
  52. package/dist/esm/record/recordValidator/attributeValidator.js.map +1 -1
  53. package/dist/esm/record/recordValidator/countVaildator.js.map +1 -1
  54. package/dist/esm/record/recordValidator/recordValidator.js.map +1 -1
  55. package/dist/esm/record/service.js.map +1 -1
  56. package/dist/esm/tests/builder/recordBuilder/attributeBuilder.js.map +1 -1
  57. package/dist/esm/tests/builder/recordBuilder/entityBuilder.js.map +1 -1
  58. package/dist/esm/tests/builder/recordBuilder/nodeBuilder.js.map +1 -1
  59. package/dist/esm/tests/builder/recordBuilder/recordBuilder.js.map +1 -1
  60. package/dist/index.d.ts +2 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/node/factory.d.ts +4 -4
  63. package/dist/node/factory.js.map +1 -1
  64. package/dist/node/index.d.ts +1 -2
  65. package/dist/node/index.js.map +1 -1
  66. package/dist/node/node.d.ts +7 -2
  67. package/dist/node/node.js.map +1 -1
  68. package/dist/node/nodePointer.d.ts +2 -2
  69. package/dist/node/nodePointer.js.map +1 -1
  70. package/dist/node/nodeValueFormatter.d.ts +2 -2
  71. package/dist/node/nodeValueFormatter.js.map +1 -1
  72. package/dist/node/nodeValues.d.ts +21 -21
  73. package/dist/node/nodeValues.js.map +1 -1
  74. package/dist/node/nodes.d.ts +31 -31
  75. package/dist/node/nodes.js +1 -1
  76. package/dist/node/nodes.js.map +1 -1
  77. package/dist/node/service.d.ts +6 -6
  78. package/dist/node/service.js.map +1 -1
  79. package/dist/nodeDefExpressionEvaluator/functions.js.map +1 -1
  80. package/dist/record/_records/recordCompletion.d.ts +9 -9
  81. package/dist/record/_records/recordCompletion.js.map +1 -1
  82. package/dist/record/_records/recordGetters.d.ts +69 -69
  83. package/dist/record/_records/recordGetters.js.map +1 -1
  84. package/dist/record/_records/recordNodesIndexUpdater.d.ts +9 -9
  85. package/dist/record/_records/recordNodesIndexUpdater.js.map +1 -1
  86. package/dist/record/_records/recordPagesValidation.d.ts +11 -11
  87. package/dist/record/_records/recordPagesValidation.js.map +1 -1
  88. package/dist/record/_records/recordUpdater.d.ts +5 -5
  89. package/dist/record/_records/recordUpdater.js.map +1 -1
  90. package/dist/record/_records/recordUtils.d.ts +6 -6
  91. package/dist/record/_records/recordUtils.js.map +1 -1
  92. package/dist/record/factory.d.ts +2 -2
  93. package/dist/record/factory.js.map +1 -1
  94. package/dist/record/index.d.ts +1 -2
  95. package/dist/record/index.js.map +1 -1
  96. package/dist/record/nodePointers.d.ts +6 -6
  97. package/dist/record/nodePointers.js.map +1 -1
  98. package/dist/record/record.d.ts +8 -5
  99. package/dist/record/record.js.map +1 -1
  100. package/dist/record/recordCloner.d.ts +3 -3
  101. package/dist/record/recordCloner.js.map +1 -1
  102. package/dist/record/recordExpressionEvaluator/context.d.ts +6 -6
  103. package/dist/record/recordExpressionEvaluator/context.js.map +1 -1
  104. package/dist/record/recordExpressionEvaluator/node/identifier/identifier.js.map +1 -1
  105. package/dist/record/recordExpressionEvaluator/node/identifier/nodesFinder.d.ts +5 -5
  106. package/dist/record/recordExpressionEvaluator/node/identifier/nodesFinder.js.map +1 -1
  107. package/dist/record/recordExpressionEvaluator/nodeValueExtractor.d.ts +2 -2
  108. package/dist/record/recordExpressionEvaluator/nodeValueExtractor.js.map +1 -1
  109. package/dist/record/recordExpressionEvaluator/recordExpressionEvaluator.d.ts +4 -4
  110. package/dist/record/recordExpressionEvaluator/recordExpressionEvaluator.js.map +1 -1
  111. package/dist/record/recordFixer.js.map +1 -1
  112. package/dist/record/recordNodesUpdater/recordEnumeratingItemsExpressionEvaluator.d.ts +4 -4
  113. package/dist/record/recordNodesUpdater/recordEnumeratingItemsExpressionEvaluator.js.map +1 -1
  114. package/dist/record/recordNodesUpdater/recordExpressionValueConverter.d.ts +4 -4
  115. package/dist/record/recordNodesUpdater/recordExpressionValueConverter.js.map +1 -1
  116. package/dist/record/recordNodesUpdater/recordNodeDependentsApplicableUpdater.js.map +1 -1
  117. package/dist/record/recordNodesUpdater/recordNodeDependentsBooleanUpdater.d.ts +3 -3
  118. package/dist/record/recordNodesUpdater/recordNodeDependentsBooleanUpdater.js.map +1 -1
  119. package/dist/record/recordNodesUpdater/recordNodeDependentsCodeAttributesUpdater.js.map +1 -1
  120. package/dist/record/recordNodesUpdater/recordNodeDependentsDefaultValuesUpdater.js.map +1 -1
  121. package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.d.ts +2 -2
  122. package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratedEntitiesUpdater.js.map +1 -1
  123. package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.d.ts +2 -2
  124. package/dist/record/recordNodesUpdater/recordNodeDependentsEnumeratingItemsUpdater.js.map +1 -1
  125. package/dist/record/recordNodesUpdater/recordNodeDependentsFileNamesEvaluator.js.map +1 -1
  126. package/dist/record/recordNodesUpdater/recordNodeDependentsUpdateParams.d.ts +2 -2
  127. package/dist/record/recordNodesUpdater/recordNodeDependentsUpdateParams.js.map +1 -1
  128. package/dist/record/recordNodesUpdater/recordNodesCreator.d.ts +4 -4
  129. package/dist/record/recordNodesUpdater/recordNodesCreator.js.map +1 -1
  130. package/dist/record/recordNodesUpdater/recordNodesDeleter.d.ts +3 -3
  131. package/dist/record/recordNodesUpdater/recordNodesDeleter.js.map +1 -1
  132. package/dist/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.d.ts +4 -4
  133. package/dist/record/recordNodesUpdater/recordNodesDependentsUpdaterCommons.js.map +1 -1
  134. package/dist/record/recordNodesUpdater/recordNodesUpdater.d.ts +2 -2
  135. package/dist/record/recordNodesUpdater/recordNodesUpdater.js.map +1 -1
  136. package/dist/record/recordNodesUpdater/recordUpdateResult.d.ts +6 -6
  137. package/dist/record/recordNodesUpdater/recordUpdateResult.js.map +1 -1
  138. package/dist/record/recordPrettyPrinter.d.ts +7 -7
  139. package/dist/record/recordPrettyPrinter.js.map +1 -1
  140. package/dist/record/recordUpdater.js.map +1 -1
  141. package/dist/record/recordValidator/attributeKeyValidator.d.ts +4 -4
  142. package/dist/record/recordValidator/attributeKeyValidator.js.map +1 -1
  143. package/dist/record/recordValidator/attributeTypeValidator.d.ts +4 -4
  144. package/dist/record/recordValidator/attributeTypeValidator.js.map +1 -1
  145. package/dist/record/recordValidator/attributeUniqueValidator.d.ts +4 -4
  146. package/dist/record/recordValidator/attributeUniqueValidator.js.map +1 -1
  147. package/dist/record/recordValidator/attributeValidator.d.ts +6 -6
  148. package/dist/record/recordValidator/attributeValidator.js.map +1 -1
  149. package/dist/record/recordValidator/countVaildator.d.ts +7 -7
  150. package/dist/record/recordValidator/countVaildator.js.map +1 -1
  151. package/dist/record/recordValidator/recordValidator.js.map +1 -1
  152. package/dist/record/records.d.ts +6 -6
  153. package/dist/record/service.d.ts +8 -8
  154. package/dist/record/service.js.map +1 -1
  155. package/dist/tests/builder/recordBuilder/attributeBuilder.d.ts +5 -5
  156. package/dist/tests/builder/recordBuilder/attributeBuilder.js.map +1 -1
  157. package/dist/tests/builder/recordBuilder/entityBuilder.d.ts +5 -5
  158. package/dist/tests/builder/recordBuilder/entityBuilder.js.map +1 -1
  159. package/dist/tests/builder/recordBuilder/nodeBuilder.d.ts +5 -5
  160. package/dist/tests/builder/recordBuilder/nodeBuilder.js.map +1 -1
  161. package/dist/tests/builder/recordBuilder/recordBuilder.d.ts +2 -2
  162. package/dist/tests/builder/recordBuilder/recordBuilder.js.map +1 -1
  163. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
- import { Node } from '../../node';
1
+ import { ArenaRecordNode } from '../../node';
2
2
  import { NodeDefEntity } from '../../nodeDef';
3
3
  import { Survey } from '../../survey';
4
- import { Record } from '../record';
4
+ import { ArenaRecord } from '../record';
5
5
  export type PageValidationStatus = {
6
6
  hasErrors: boolean;
7
7
  hasWarnings: boolean;
@@ -20,19 +20,19 @@ export type PagesValidationProgress = {
20
20
  * Whether a node belongs under a page entity (itself or any descendant of that page).
21
21
  */
22
22
  export declare const nodeBelongsToPage: (params: {
23
- node: Node;
23
+ node: ArenaRecordNode;
24
24
  pageNodeDefUuid: string;
25
- record: Record;
25
+ record: ArenaRecord;
26
26
  }) => boolean;
27
27
  /**
28
28
  * Whether a node belongs to this page only — not to a nested descendant page entity.
29
29
  * When descendantPageUuids is empty, all nodes under the page hierarchy are included.
30
30
  */
31
31
  export declare const nodeBelongsToOwnPage: (params: {
32
- node: Node;
32
+ node: ArenaRecordNode;
33
33
  pageNodeDefUuid: string;
34
34
  descendantPageUuids: string[];
35
- record: Record;
35
+ record: ArenaRecord;
36
36
  }) => boolean;
37
37
  /**
38
38
  * Child page-entity defs displayed in their own page under the given entity.
@@ -65,7 +65,7 @@ export declare const getDescendantPageNodeDefUuids: (params: {
65
65
  export declare const getPageValidationStatus: (params: {
66
66
  pageNodeDefUuid: string;
67
67
  descendantPageUuids?: string[];
68
- record: Record;
68
+ record: ArenaRecord;
69
69
  scopeEntityUuid?: string;
70
70
  }) => PageValidationStatus;
71
71
  /**
@@ -74,7 +74,7 @@ export declare const getPageValidationStatus: (params: {
74
74
  */
75
75
  export declare const getEntitySubtreeStatus: (params: {
76
76
  survey: Survey;
77
- record: Record;
77
+ record: ArenaRecord;
78
78
  entityUuid: string;
79
79
  cycle?: string;
80
80
  }) => EntitySubtreeStatus | null;
@@ -86,7 +86,7 @@ export declare const getEntitySubtreeStatus: (params: {
86
86
  */
87
87
  export declare const getMultiplePageEntitiesStatus: (params: {
88
88
  survey: Survey;
89
- record: Record;
89
+ record: ArenaRecord;
90
90
  pageNodeDefUuid: string;
91
91
  cycle?: string;
92
92
  /** When set, only instances under this ancestor entity are aggregated. */
@@ -98,7 +98,7 @@ export declare const getMultiplePageEntitiesStatus: (params: {
98
98
  export declare const pageHasOwnErrors: (params: {
99
99
  pageNodeDefUuid: string;
100
100
  descendantPageUuids: string[];
101
- record: Record;
101
+ record: ArenaRecord;
102
102
  }) => boolean;
103
103
  /**
104
104
  * Progress of pages without own-field validation errors over all survey pages.
@@ -106,6 +106,6 @@ export declare const pageHasOwnErrors: (params: {
106
106
  */
107
107
  export declare const getRecordPagesValidationProgress: (params: {
108
108
  survey: Survey;
109
- record: Record;
109
+ record: ArenaRecord;
110
110
  cycle?: string;
111
111
  }) => PagesValidationProgress | null;
@@ -1 +1 @@
1
- {"version":3,"file":"recordPagesValidation.js","sourceRoot":"","sources":["../../../src/record/_records/recordPagesValidation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Node, Nodes } from '../../node'\nimport { NodeDefEntity, NodeDefs } from '../../nodeDef'\nimport { Survey, Surveys } from '../../survey'\nimport { Validations } from '../../validation'\nimport { Record } from '../record'\nimport { RecordValidations } from '../recordValidations'\nimport { getEntityCompletionStats } from './recordCompletion'\nimport { getCycle, getNodeByUuid, getNodesByDefUuid, getRoot } from './recordGetters'\n\nexport type PageValidationStatus = {\n hasErrors: boolean\n hasWarnings: boolean\n}\n\nexport type EntitySubtreeStatus = {\n hasErrors: boolean\n hasWarnings: boolean\n isComplete: boolean\n}\n\nexport type PagesValidationProgress = {\n percent: number\n validCount: number\n totalCount: number\n}\n\n/**\n * Whether a node belongs under a page entity (itself or any descendant of that page).\n */\nexport const nodeBelongsToPage = (params: { node: Node; pageNodeDefUuid: string; record: Record }): boolean => {\n const { node, pageNodeDefUuid, record } = params\n if (node.nodeDefUuid === pageNodeDefUuid) return true\n return Nodes.getHierarchy(node).some((ancestorUuid) => {\n const ancestor = getNodeByUuid(ancestorUuid)(record)\n return ancestor?.nodeDefUuid === pageNodeDefUuid\n })\n}\n\n/**\n * Whether a node belongs to this page only — not to a nested descendant page entity.\n * When descendantPageUuids is empty, all nodes under the page hierarchy are included.\n */\nexport const nodeBelongsToOwnPage = (params: {\n node: Node\n pageNodeDefUuid: string\n descendantPageUuids: string[]\n record: Record\n}): boolean => {\n const { node, pageNodeDefUuid, descendantPageUuids, record } = params\n if (!nodeBelongsToPage({ node, pageNodeDefUuid, record })) return false\n if (descendantPageUuids.includes(node.nodeDefUuid)) return false\n return !descendantPageUuids.some((descendantUuid) =>\n nodeBelongsToPage({ node, pageNodeDefUuid: descendantUuid, record })\n )\n}\n\n/**\n * Child page-entity defs displayed in their own page under the given entity.\n */\nexport const getNodeDefChildrenInOwnPage = (params: {\n survey: Survey\n nodeDef: NodeDefEntity\n cycle: string\n}): NodeDefEntity[] => {\n const { survey, nodeDef, cycle } = params\n return Surveys.getNodeDefChildren({ survey, nodeDef, includeAnalysis: true }).filter(\n (child): child is NodeDefEntity => {\n if (!NodeDefs.isEntity(child)) return false\n return NodeDefs.isDisplayInOwnPage(cycle)(child as NodeDefEntity)\n }\n )\n}\n\n/**\n * Collects all page-entity node defs in the survey cycle (root + nested own-pages).\n */\nexport const getPageNodeDefs = (params: { survey: Survey; cycle: string }): NodeDefEntity[] => {\n const { survey, cycle } = params\n const root = Surveys.getNodeDefRoot({ survey }) as NodeDefEntity | undefined\n if (!root) return []\n\n const pages: NodeDefEntity[] = []\n const stack: NodeDefEntity[] = [root]\n while (stack.length > 0) {\n const current = stack.pop()\n if (!current) continue\n pages.push(current)\n stack.push(...getNodeDefChildrenInOwnPage({ survey, nodeDef: current, cycle }))\n }\n return pages\n}\n\n/**\n * Collects descendant page node def UUIDs under a page (not including the page itself).\n */\nexport const getDescendantPageNodeDefUuids = (params: {\n survey: Survey\n cycle: string\n pageNodeDef: NodeDefEntity\n}): string[] => {\n const { survey, cycle, pageNodeDef } = params\n const uuids: string[] = []\n const visit = (nodeDef: NodeDefEntity) => {\n const children = getNodeDefChildrenInOwnPage({ survey, nodeDef, cycle })\n for (const child of children) {\n uuids.push(child.uuid)\n visit(child)\n }\n }\n visit(pageNodeDef)\n return uuids\n}\n\nconst nodeIsUnderEntity = (params: { node: Node; entityUuid: string }): boolean => {\n const { node, entityUuid } = params\n if (node.uuid === entityUuid) return true\n return Nodes.getHierarchy(node).includes(entityUuid)\n}\n\nconst getOwnPageFieldValidationFlags = (params: {\n nodeUuid: string\n pageNodeDefUuid: string\n descendantPageUuids: string[]\n scopeEntityUuid?: string\n record: Record\n recordValidation: ReturnType<typeof Validations.getValidation>\n}): PageValidationStatus | null => {\n const { nodeUuid, pageNodeDefUuid, descendantPageUuids, scopeEntityUuid, record, recordValidation } = params\n\n if (RecordValidations.isValidationChildrenCountKey(nodeUuid)) {\n return getOwnPageChildrenCountValidationFlags({\n childrenCountKey: nodeUuid,\n pageNodeDefUuid,\n descendantPageUuids,\n scopeEntityUuid,\n record,\n recordValidation,\n })\n }\n\n const node = getNodeByUuid(nodeUuid)(record)\n if (!node || !nodeBelongsToOwnPage({ node, pageNodeDefUuid, descendantPageUuids, record })) return null\n if (scopeEntityUuid && !nodeIsUnderEntity({ node, entityUuid: scopeEntityUuid })) return null\n\n const nodeValidation = RecordValidations.getValidationNode({ nodeUuid })(recordValidation)\n if (!nodeValidation) return null\n\n return {\n hasErrors: Validations.hasErrors(nodeValidation),\n hasWarnings: Validations.hasWarnings(nodeValidation),\n }\n}\n\n/**\n * Children-count validations (file min count, inline multiple min/max, etc.) are keyed as\n * `childrenCount_{parentUuid}_{childDefUuid}`, not as node UUIDs.\n * Include them when the parent is on this page, but skip counts that refer to descendant\n * page entities (missing sub-page instances should not paint the parent page red).\n */\nconst getOwnPageChildrenCountValidationFlags = (params: {\n childrenCountKey: string\n pageNodeDefUuid: string\n descendantPageUuids: string[]\n scopeEntityUuid?: string\n record: Record\n recordValidation: ReturnType<typeof Validations.getValidation>\n}): PageValidationStatus | null => {\n const { childrenCountKey, pageNodeDefUuid, descendantPageUuids, scopeEntityUuid, record, recordValidation } = params\n const parentUuid = RecordValidations.extractValidationChildrenCountKeyParentUuid(childrenCountKey)\n const childDefUuid = RecordValidations.extractValidationChildrenCountKeyNodeDefUuid(childrenCountKey)\n if (!parentUuid || !childDefUuid) return null\n\n // Sub-page entity min/max counts belong to navigation of nested pages, not this page's fields.\n if (descendantPageUuids.includes(childDefUuid)) return null\n\n const parentNode = getNodeByUuid(parentUuid)(record)\n if (!parentNode || !nodeBelongsToOwnPage({ node: parentNode, pageNodeDefUuid, descendantPageUuids, record })) {\n return null\n }\n if (scopeEntityUuid && !nodeIsUnderEntity({ node: parentNode, entityUuid: scopeEntityUuid })) return null\n\n const fieldValidation = Validations.getFieldValidation(childrenCountKey)(recordValidation)\n if (!fieldValidation) return null\n\n return {\n hasErrors: Validations.hasErrors(fieldValidation),\n hasWarnings: Validations.hasWarnings(fieldValidation),\n }\n}\n\n/**\n * Aggregates error/warning flags for a page.\n * When descendantPageUuids is non-empty, nested page entities are excluded (own-page scope).\n * When scopeEntityUuid is set, only validations for nodes under that entity instance are included.\n */\nexport const getPageValidationStatus = (params: {\n pageNodeDefUuid: string\n descendantPageUuids?: string[]\n record: Record\n scopeEntityUuid?: string\n}): PageValidationStatus => {\n const { pageNodeDefUuid, descendantPageUuids = [], record, scopeEntityUuid } = params\n const recordValidation = Validations.getValidation(record)\n const fields = Validations.getFieldValidations(recordValidation)\n let hasErrors = false\n let hasWarnings = false\n\n for (const nodeUuid of Object.keys(fields)) {\n const flags = getOwnPageFieldValidationFlags({\n nodeUuid,\n pageNodeDefUuid,\n descendantPageUuids,\n scopeEntityUuid,\n record,\n recordValidation,\n })\n if (!flags) continue\n if (flags.hasErrors) hasErrors = true\n if (flags.hasWarnings) hasWarnings = true\n if (hasErrors && hasWarnings) break\n }\n\n return { hasErrors, hasWarnings }\n}\n\nconst aggregatePageValidationStatuses = (statuses: PageValidationStatus[]): PageValidationStatus => ({\n hasErrors: statuses.some((status) => status.hasErrors),\n hasWarnings: statuses.some((status) => status.hasWarnings),\n})\n\n/**\n * Validation and completion status for one entity instance and its descendant pages.\n * Returns null when the node is missing or is not an entity.\n */\nexport const getEntitySubtreeStatus = (params: {\n survey: Survey\n record: Record\n entityUuid: string\n cycle?: string\n}): EntitySubtreeStatus | null => {\n const { survey, record, entityUuid } = params\n const entity = getNodeByUuid(entityUuid)(record)\n if (!entity) return null\n\n const entityDef = Surveys.getNodeDefByUuid({ survey, uuid: entity.nodeDefUuid })\n if (!NodeDefs.isEntity(entityDef)) return null\n\n const cycle = params.cycle ?? getCycle(record)\n const entityPageDef = entityDef as NodeDefEntity\n const descendantPageUuids = getDescendantPageNodeDefUuids({ survey, cycle, pageNodeDef: entityPageDef })\n const pageUuidsToCheck = [entity.nodeDefUuid, ...descendantPageUuids]\n\n const validationStatuses = pageUuidsToCheck.map((pageNodeDefUuid) => {\n const pageNodeDef = Surveys.getNodeDefByUuid({ survey, uuid: pageNodeDefUuid }) as NodeDefEntity\n const pageDescendantUuids = getDescendantPageNodeDefUuids({ survey, cycle, pageNodeDef })\n return getPageValidationStatus({\n pageNodeDefUuid,\n descendantPageUuids: pageDescendantUuids,\n record,\n scopeEntityUuid: entityUuid,\n })\n })\n\n const { hasErrors, hasWarnings } = aggregatePageValidationStatuses(validationStatuses)\n const { total, filled } = getEntityCompletionStats({ survey, record, entity })\n const isComplete = total > 0 && filled === total && !hasErrors && !hasWarnings\n\n return { hasErrors, hasWarnings, isComplete }\n}\n\n/**\n * Aggregates subtree status across instances of a multiple page entity.\n * When `scopeEntityUuid` is set, only instances under that ancestor entity are included\n * (needed for nested multiples, e.g. Tree under the currently selected Plot).\n * Empty instance lists return a non-complete status with no validation flags.\n */\nexport const getMultiplePageEntitiesStatus = (params: {\n survey: Survey\n record: Record\n pageNodeDefUuid: string\n cycle?: string\n /** When set, only instances under this ancestor entity are aggregated. */\n scopeEntityUuid?: string\n}): EntitySubtreeStatus => {\n const { survey, record, pageNodeDefUuid, scopeEntityUuid } = params\n const instances = getNodesByDefUuid(pageNodeDefUuid)(record).filter((instance) =>\n scopeEntityUuid ? nodeIsUnderEntity({ node: instance, entityUuid: scopeEntityUuid }) : true\n )\n\n if (instances.length === 0) {\n return { hasErrors: false, hasWarnings: false, isComplete: false }\n }\n\n const instanceStatuses = instances\n .map((instance) => getEntitySubtreeStatus({ survey, record, entityUuid: instance.uuid, cycle: params.cycle }))\n .filter((status): status is EntitySubtreeStatus => status !== null)\n\n return {\n hasErrors: instanceStatuses.some((status) => status.hasErrors),\n hasWarnings: instanceStatuses.some((status) => status.hasWarnings),\n isComplete: instanceStatuses.length > 0 && instanceStatuses.every((status) => status.isComplete),\n }\n}\n\n/**\n * Whether the page has validation errors on its own fields (excluding nested page entities).\n */\nexport const pageHasOwnErrors = (params: {\n pageNodeDefUuid: string\n descendantPageUuids: string[]\n record: Record\n}): boolean => getPageValidationStatus(params).hasErrors\n\n/**\n * Progress of pages without own-field validation errors over all survey pages.\n * Warnings do not reduce the score (matches Arena sidebar red-icon signal).\n */\nexport const getRecordPagesValidationProgress = (params: {\n survey: Survey\n record: Record\n cycle?: string\n}): PagesValidationProgress | null => {\n const { survey, record } = params\n if (!getRoot(record)) return null\n\n const cycle = params.cycle ?? getCycle(record)\n const pageNodeDefs = getPageNodeDefs({ survey, cycle })\n const totalCount = pageNodeDefs.length\n if (totalCount === 0) return null\n\n let validCount = 0\n for (const pageNodeDef of pageNodeDefs) {\n const pageNodeDefUuid = pageNodeDef.uuid\n const descendantPageUuids = getDescendantPageNodeDefUuids({ survey, cycle, pageNodeDef })\n if (!pageHasOwnErrors({ pageNodeDefUuid, descendantPageUuids, record })) {\n validCount += 1\n }\n }\n\n const percent = Math.round((validCount / totalCount) * 100)\n return { percent, validCount, totalCount }\n}\n"]}
1
+ {"version":3,"file":"recordPagesValidation.js","sourceRoot":"","sources":["../../../src/record/_records/recordPagesValidation.ts"],"names":[],"mappings":";;;AAAA,qCAAmD;AACnD,2CAAuD;AACvD,yCAA8C;AAC9C,iDAA8C;AAE9C,4DAAwD;AACxD,yDAA6D;AAC7D,mDAAqF;AAmBrF;;GAEG;AACI,MAAM,iBAAiB,GAAG,CAAC,MAIjC,EAAW,EAAE;IACZ,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAChD,IAAI,IAAI,CAAC,WAAW,KAAK,eAAe;QAAE,OAAO,IAAI,CAAA;IACrD,OAAO,YAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE;QACpD,MAAM,QAAQ,GAAG,IAAA,6BAAa,EAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;QACpD,OAAO,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,WAAW,MAAK,eAAe,CAAA;IAClD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAXY,QAAA,iBAAiB,GAAjB,iBAAiB,CAW7B;AAED;;;GAGG;AACI,MAAM,oBAAoB,GAAG,CAAC,MAKpC,EAAW,EAAE;IACZ,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACrE,IAAI,CAAC,IAAA,QAAA,iBAAiB,EAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;QAAE,OAAO,KAAK,CAAA;IACvE,IAAI,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;QAAE,OAAO,KAAK,CAAA;IAChE,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,EAAE,CAClD,IAAA,QAAA,iBAAiB,EAAC,EAAE,IAAI,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CACrE,CAAA;AACH,CAAC,CAAA;AAZY,QAAA,oBAAoB,GAApB,oBAAoB,CAYhC;AAED;;GAEG;AACI,MAAM,2BAA2B,GAAG,CAAC,MAI3C,EAAmB,EAAE;IACpB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,CAAA;IACzC,OAAO,gBAAO,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAClF,CAAC,KAAK,EAA0B,EAAE;QAChC,IAAI,CAAC,kBAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAC3C,OAAO,kBAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,KAAsB,CAAC,CAAA;IACnE,CAAC,CACF,CAAA;AACH,CAAC,CAAA;AAZY,QAAA,2BAA2B,GAA3B,2BAA2B,CAYvC;AAED;;GAEG;AACI,MAAM,eAAe,GAAG,CAAC,MAAyC,EAAmB,EAAE;IAC5F,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAA;IAChC,MAAM,IAAI,GAAG,gBAAO,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAA8B,CAAA;IAC5E,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IAEpB,MAAM,KAAK,GAAoB,EAAE,CAAA;IACjC,MAAM,KAAK,GAAoB,CAAC,IAAI,CAAC,CAAA;IACrC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO;YAAE,SAAQ;QACtB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACnB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAA,QAAA,2BAA2B,EAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IACjF,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAdY,QAAA,eAAe,GAAf,eAAe,CAc3B;AAED;;GAEG;AACI,MAAM,6BAA6B,GAAG,CAAC,MAI7C,EAAY,EAAE;IACb,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAAA;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,CAAC,OAAsB,EAAE,EAAE;QACvC,MAAM,QAAQ,GAAG,IAAA,QAAA,2BAA2B,EAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;QACxE,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACtB,KAAK,CAAC,KAAK,CAAC,CAAA;QACd,CAAC;IACH,CAAC,CAAA;IACD,KAAK,CAAC,WAAW,CAAC,CAAA;IAClB,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAhBY,QAAA,6BAA6B,GAA7B,6BAA6B,CAgBzC;AAED,MAAM,iBAAiB,GAAG,CAAC,MAAqD,EAAW,EAAE;IAC3F,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;IACnC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,IAAI,CAAA;IACzC,OAAO,YAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;AACtD,CAAC,CAAA;AAED,MAAM,8BAA8B,GAAG,CAAC,MAOvC,EAA+B,EAAE;IAChC,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAA;IAE5G,IAAI,qCAAiB,CAAC,4BAA4B,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7D,OAAO,sCAAsC,CAAC;YAC5C,gBAAgB,EAAE,QAAQ;YAC1B,eAAe;YACf,mBAAmB;YACnB,eAAe;YACf,MAAM;YACN,gBAAgB;SACjB,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,IAAA,6BAAa,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAA;IAC5C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAA,QAAA,oBAAoB,EAAC,EAAE,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC;QAAE,OAAO,IAAI,CAAA;IACvG,IAAI,eAAe,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;QAAE,OAAO,IAAI,CAAA;IAE7F,MAAM,cAAc,GAAG,qCAAiB,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAA;IAC1F,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAA;IAEhC,OAAO;QACL,SAAS,EAAE,wBAAW,CAAC,SAAS,CAAC,cAAc,CAAC;QAChD,WAAW,EAAE,wBAAW,CAAC,WAAW,CAAC,cAAc,CAAC;KACrD,CAAA;AACH,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,sCAAsC,GAAG,CAAC,MAO/C,EAA+B,EAAE;IAChC,MAAM,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAA;IACpH,MAAM,UAAU,GAAG,qCAAiB,CAAC,2CAA2C,CAAC,gBAAgB,CAAC,CAAA;IAClG,MAAM,YAAY,GAAG,qCAAiB,CAAC,4CAA4C,CAAC,gBAAgB,CAAC,CAAA;IACrG,IAAI,CAAC,UAAU,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAA;IAE7C,+FAA+F;IAC/F,IAAI,mBAAmB,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAA;IAE3D,MAAM,UAAU,GAAG,IAAA,6BAAa,EAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;IACpD,IAAI,CAAC,UAAU,IAAI,CAAC,IAAA,QAAA,oBAAoB,EAAC,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC7G,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,eAAe,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;QAAE,OAAO,IAAI,CAAA;IAEzG,MAAM,eAAe,GAAG,wBAAW,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,gBAAgB,CAAC,CAAA;IAC1F,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAA;IAEjC,OAAO;QACL,SAAS,EAAE,wBAAW,CAAC,SAAS,CAAC,eAAe,CAAC;QACjD,WAAW,EAAE,wBAAW,CAAC,WAAW,CAAC,eAAe,CAAC;KACtD,CAAA;AACH,CAAC,CAAA;AAED;;;;GAIG;AACI,MAAM,uBAAuB,GAAG,CAAC,MAKvC,EAAwB,EAAE;IACzB,MAAM,EAAE,eAAe,EAAE,mBAAmB,GAAG,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,CAAA;IACrF,MAAM,gBAAgB,GAAG,wBAAW,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,wBAAW,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAA;IAChE,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,IAAI,WAAW,GAAG,KAAK,CAAA;IAEvB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,8BAA8B,CAAC;YAC3C,QAAQ;YACR,eAAe;YACf,mBAAmB;YACnB,eAAe;YACf,MAAM;YACN,gBAAgB;SACjB,CAAC,CAAA;QACF,IAAI,CAAC,KAAK;YAAE,SAAQ;QACpB,IAAI,KAAK,CAAC,SAAS;YAAE,SAAS,GAAG,IAAI,CAAA;QACrC,IAAI,KAAK,CAAC,WAAW;YAAE,WAAW,GAAG,IAAI,CAAA;QACzC,IAAI,SAAS,IAAI,WAAW;YAAE,MAAK;IACrC,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAAA;AACnC,CAAC,CAAA;AA5BY,QAAA,uBAAuB,GAAvB,uBAAuB,CA4BnC;AAED,MAAM,+BAA+B,GAAG,CAAC,QAAgC,EAAwB,EAAE,CAAC,CAAC;IACnG,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;IACtD,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;CAC3D,CAAC,CAAA;AAEF;;;GAGG;AACI,MAAM,sBAAsB,GAAG,CAAC,MAKtC,EAA8B,EAAE;;IAC/B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;IAC7C,MAAM,MAAM,GAAG,IAAA,6BAAa,EAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;IAChD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAExB,MAAM,SAAS,GAAG,gBAAO,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;IAChF,IAAI,CAAC,kBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAA;IAE9C,MAAM,KAAK,SAAG,MAAM,CAAC,KAAK,mCAAI,IAAA,wBAAQ,EAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,aAAa,GAAG,SAA0B,CAAA;IAChD,MAAM,mBAAmB,GAAG,IAAA,QAAA,6BAA6B,EAAC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAA;IACxG,MAAM,gBAAgB,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,mBAAmB,CAAC,CAAA;IAErE,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,EAAE;QAClE,MAAM,WAAW,GAAG,gBAAO,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,CAAkB,CAAA;QAChG,MAAM,mBAAmB,GAAG,IAAA,QAAA,6BAA6B,EAAC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QACzF,OAAO,IAAA,QAAA,uBAAuB,EAAC;YAC7B,eAAe;YACf,mBAAmB,EAAE,mBAAmB;YACxC,MAAM;YACN,eAAe,EAAE,UAAU;SAC5B,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,+BAA+B,CAAC,kBAAkB,CAAC,CAAA;IACtF,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAA,2CAAwB,EAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IAC9E,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,IAAI,MAAM,KAAK,KAAK,IAAI,CAAC,SAAS,IAAI,CAAC,WAAW,CAAA;IAE9E,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,CAAA;AAC/C,CAAC,CAAA;AAlCY,QAAA,sBAAsB,GAAtB,sBAAsB,CAkClC;AAED;;;;;GAKG;AACI,MAAM,6BAA6B,GAAG,CAAC,MAO7C,EAAuB,EAAE;IACxB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,MAAM,CAAA;IACnE,MAAM,SAAS,GAAG,IAAA,iCAAiB,EAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC/E,eAAe,CAAC,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAC5F,CAAA;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAA;IACpE,CAAC;IAED,MAAM,gBAAgB,GAAG,SAAS;SAC/B,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAA,QAAA,sBAAsB,EAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;SAC7G,MAAM,CAAC,CAAC,MAAM,EAAiC,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAA;IAErE,OAAO;QACL,SAAS,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;QAC9D,WAAW,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;QAClE,UAAU,EAAE,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;KACjG,CAAA;AACH,CAAC,CAAA;AA1BY,QAAA,6BAA6B,GAA7B,6BAA6B,CA0BzC;AAED;;GAEG;AACI,MAAM,gBAAgB,GAAG,CAAC,MAIhC,EAAW,EAAE,CAAC,IAAA,QAAA,uBAAuB,EAAC,MAAM,CAAC,CAAC,SAAS,CAAA;AAJ3C,QAAA,gBAAgB,GAAhB,gBAAgB,CAI2B;AAExD;;;GAGG;AACI,MAAM,gCAAgC,GAAG,CAAC,MAIhD,EAAkC,EAAE;;IACnC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACjC,IAAI,CAAC,IAAA,uBAAO,EAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAA;IAEjC,MAAM,KAAK,SAAG,MAAM,CAAC,KAAK,mCAAI,IAAA,wBAAQ,EAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,YAAY,GAAG,IAAA,QAAA,eAAe,EAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IACvD,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAA;IACtC,IAAI,UAAU,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEjC,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,MAAM,eAAe,GAAG,WAAW,CAAC,IAAI,CAAA;QACxC,MAAM,mBAAmB,GAAG,IAAA,QAAA,6BAA6B,EAAC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QACzF,IAAI,CAAC,IAAA,QAAA,gBAAgB,EAAC,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;YACxE,UAAU,IAAI,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAA;IAC3D,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAA;AAC5C,CAAC,CAAA;AAxBY,QAAA,gCAAgC,GAAhC,gCAAgC,CAwB5C","sourcesContent":["import { ArenaRecordNode, Nodes } from '../../node'\nimport { NodeDefEntity, NodeDefs } from '../../nodeDef'\nimport { Survey, Surveys } from '../../survey'\nimport { Validations } from '../../validation'\nimport { ArenaRecord } from '../record'\nimport { RecordValidations } from '../recordValidations'\nimport { getEntityCompletionStats } from './recordCompletion'\nimport { getCycle, getNodeByUuid, getNodesByDefUuid, getRoot } from './recordGetters'\n\nexport type PageValidationStatus = {\n hasErrors: boolean\n hasWarnings: boolean\n}\n\nexport type EntitySubtreeStatus = {\n hasErrors: boolean\n hasWarnings: boolean\n isComplete: boolean\n}\n\nexport type PagesValidationProgress = {\n percent: number\n validCount: number\n totalCount: number\n}\n\n/**\n * Whether a node belongs under a page entity (itself or any descendant of that page).\n */\nexport const nodeBelongsToPage = (params: {\n node: ArenaRecordNode\n pageNodeDefUuid: string\n record: ArenaRecord\n}): boolean => {\n const { node, pageNodeDefUuid, record } = params\n if (node.nodeDefUuid === pageNodeDefUuid) return true\n return Nodes.getHierarchy(node).some((ancestorUuid) => {\n const ancestor = getNodeByUuid(ancestorUuid)(record)\n return ancestor?.nodeDefUuid === pageNodeDefUuid\n })\n}\n\n/**\n * Whether a node belongs to this page only — not to a nested descendant page entity.\n * When descendantPageUuids is empty, all nodes under the page hierarchy are included.\n */\nexport const nodeBelongsToOwnPage = (params: {\n node: ArenaRecordNode\n pageNodeDefUuid: string\n descendantPageUuids: string[]\n record: ArenaRecord\n}): boolean => {\n const { node, pageNodeDefUuid, descendantPageUuids, record } = params\n if (!nodeBelongsToPage({ node, pageNodeDefUuid, record })) return false\n if (descendantPageUuids.includes(node.nodeDefUuid)) return false\n return !descendantPageUuids.some((descendantUuid) =>\n nodeBelongsToPage({ node, pageNodeDefUuid: descendantUuid, record })\n )\n}\n\n/**\n * Child page-entity defs displayed in their own page under the given entity.\n */\nexport const getNodeDefChildrenInOwnPage = (params: {\n survey: Survey\n nodeDef: NodeDefEntity\n cycle: string\n}): NodeDefEntity[] => {\n const { survey, nodeDef, cycle } = params\n return Surveys.getNodeDefChildren({ survey, nodeDef, includeAnalysis: true }).filter(\n (child): child is NodeDefEntity => {\n if (!NodeDefs.isEntity(child)) return false\n return NodeDefs.isDisplayInOwnPage(cycle)(child as NodeDefEntity)\n }\n )\n}\n\n/**\n * Collects all page-entity node defs in the survey cycle (root + nested own-pages).\n */\nexport const getPageNodeDefs = (params: { survey: Survey; cycle: string }): NodeDefEntity[] => {\n const { survey, cycle } = params\n const root = Surveys.getNodeDefRoot({ survey }) as NodeDefEntity | undefined\n if (!root) return []\n\n const pages: NodeDefEntity[] = []\n const stack: NodeDefEntity[] = [root]\n while (stack.length > 0) {\n const current = stack.pop()\n if (!current) continue\n pages.push(current)\n stack.push(...getNodeDefChildrenInOwnPage({ survey, nodeDef: current, cycle }))\n }\n return pages\n}\n\n/**\n * Collects descendant page node def UUIDs under a page (not including the page itself).\n */\nexport const getDescendantPageNodeDefUuids = (params: {\n survey: Survey\n cycle: string\n pageNodeDef: NodeDefEntity\n}): string[] => {\n const { survey, cycle, pageNodeDef } = params\n const uuids: string[] = []\n const visit = (nodeDef: NodeDefEntity) => {\n const children = getNodeDefChildrenInOwnPage({ survey, nodeDef, cycle })\n for (const child of children) {\n uuids.push(child.uuid)\n visit(child)\n }\n }\n visit(pageNodeDef)\n return uuids\n}\n\nconst nodeIsUnderEntity = (params: { node: ArenaRecordNode; entityUuid: string }): boolean => {\n const { node, entityUuid } = params\n if (node.uuid === entityUuid) return true\n return Nodes.getHierarchy(node).includes(entityUuid)\n}\n\nconst getOwnPageFieldValidationFlags = (params: {\n nodeUuid: string\n pageNodeDefUuid: string\n descendantPageUuids: string[]\n scopeEntityUuid?: string\n record: ArenaRecord\n recordValidation: ReturnType<typeof Validations.getValidation>\n}): PageValidationStatus | null => {\n const { nodeUuid, pageNodeDefUuid, descendantPageUuids, scopeEntityUuid, record, recordValidation } = params\n\n if (RecordValidations.isValidationChildrenCountKey(nodeUuid)) {\n return getOwnPageChildrenCountValidationFlags({\n childrenCountKey: nodeUuid,\n pageNodeDefUuid,\n descendantPageUuids,\n scopeEntityUuid,\n record,\n recordValidation,\n })\n }\n\n const node = getNodeByUuid(nodeUuid)(record)\n if (!node || !nodeBelongsToOwnPage({ node, pageNodeDefUuid, descendantPageUuids, record })) return null\n if (scopeEntityUuid && !nodeIsUnderEntity({ node, entityUuid: scopeEntityUuid })) return null\n\n const nodeValidation = RecordValidations.getValidationNode({ nodeUuid })(recordValidation)\n if (!nodeValidation) return null\n\n return {\n hasErrors: Validations.hasErrors(nodeValidation),\n hasWarnings: Validations.hasWarnings(nodeValidation),\n }\n}\n\n/**\n * Children-count validations (file min count, inline multiple min/max, etc.) are keyed as\n * `childrenCount_{parentUuid}_{childDefUuid}`, not as node UUIDs.\n * Include them when the parent is on this page, but skip counts that refer to descendant\n * page entities (missing sub-page instances should not paint the parent page red).\n */\nconst getOwnPageChildrenCountValidationFlags = (params: {\n childrenCountKey: string\n pageNodeDefUuid: string\n descendantPageUuids: string[]\n scopeEntityUuid?: string\n record: ArenaRecord\n recordValidation: ReturnType<typeof Validations.getValidation>\n}): PageValidationStatus | null => {\n const { childrenCountKey, pageNodeDefUuid, descendantPageUuids, scopeEntityUuid, record, recordValidation } = params\n const parentUuid = RecordValidations.extractValidationChildrenCountKeyParentUuid(childrenCountKey)\n const childDefUuid = RecordValidations.extractValidationChildrenCountKeyNodeDefUuid(childrenCountKey)\n if (!parentUuid || !childDefUuid) return null\n\n // Sub-page entity min/max counts belong to navigation of nested pages, not this page's fields.\n if (descendantPageUuids.includes(childDefUuid)) return null\n\n const parentNode = getNodeByUuid(parentUuid)(record)\n if (!parentNode || !nodeBelongsToOwnPage({ node: parentNode, pageNodeDefUuid, descendantPageUuids, record })) {\n return null\n }\n if (scopeEntityUuid && !nodeIsUnderEntity({ node: parentNode, entityUuid: scopeEntityUuid })) return null\n\n const fieldValidation = Validations.getFieldValidation(childrenCountKey)(recordValidation)\n if (!fieldValidation) return null\n\n return {\n hasErrors: Validations.hasErrors(fieldValidation),\n hasWarnings: Validations.hasWarnings(fieldValidation),\n }\n}\n\n/**\n * Aggregates error/warning flags for a page.\n * When descendantPageUuids is non-empty, nested page entities are excluded (own-page scope).\n * When scopeEntityUuid is set, only validations for nodes under that entity instance are included.\n */\nexport const getPageValidationStatus = (params: {\n pageNodeDefUuid: string\n descendantPageUuids?: string[]\n record: ArenaRecord\n scopeEntityUuid?: string\n}): PageValidationStatus => {\n const { pageNodeDefUuid, descendantPageUuids = [], record, scopeEntityUuid } = params\n const recordValidation = Validations.getValidation(record)\n const fields = Validations.getFieldValidations(recordValidation)\n let hasErrors = false\n let hasWarnings = false\n\n for (const nodeUuid of Object.keys(fields)) {\n const flags = getOwnPageFieldValidationFlags({\n nodeUuid,\n pageNodeDefUuid,\n descendantPageUuids,\n scopeEntityUuid,\n record,\n recordValidation,\n })\n if (!flags) continue\n if (flags.hasErrors) hasErrors = true\n if (flags.hasWarnings) hasWarnings = true\n if (hasErrors && hasWarnings) break\n }\n\n return { hasErrors, hasWarnings }\n}\n\nconst aggregatePageValidationStatuses = (statuses: PageValidationStatus[]): PageValidationStatus => ({\n hasErrors: statuses.some((status) => status.hasErrors),\n hasWarnings: statuses.some((status) => status.hasWarnings),\n})\n\n/**\n * Validation and completion status for one entity instance and its descendant pages.\n * Returns null when the node is missing or is not an entity.\n */\nexport const getEntitySubtreeStatus = (params: {\n survey: Survey\n record: ArenaRecord\n entityUuid: string\n cycle?: string\n}): EntitySubtreeStatus | null => {\n const { survey, record, entityUuid } = params\n const entity = getNodeByUuid(entityUuid)(record)\n if (!entity) return null\n\n const entityDef = Surveys.getNodeDefByUuid({ survey, uuid: entity.nodeDefUuid })\n if (!NodeDefs.isEntity(entityDef)) return null\n\n const cycle = params.cycle ?? getCycle(record)\n const entityPageDef = entityDef as NodeDefEntity\n const descendantPageUuids = getDescendantPageNodeDefUuids({ survey, cycle, pageNodeDef: entityPageDef })\n const pageUuidsToCheck = [entity.nodeDefUuid, ...descendantPageUuids]\n\n const validationStatuses = pageUuidsToCheck.map((pageNodeDefUuid) => {\n const pageNodeDef = Surveys.getNodeDefByUuid({ survey, uuid: pageNodeDefUuid }) as NodeDefEntity\n const pageDescendantUuids = getDescendantPageNodeDefUuids({ survey, cycle, pageNodeDef })\n return getPageValidationStatus({\n pageNodeDefUuid,\n descendantPageUuids: pageDescendantUuids,\n record,\n scopeEntityUuid: entityUuid,\n })\n })\n\n const { hasErrors, hasWarnings } = aggregatePageValidationStatuses(validationStatuses)\n const { total, filled } = getEntityCompletionStats({ survey, record, entity })\n const isComplete = total > 0 && filled === total && !hasErrors && !hasWarnings\n\n return { hasErrors, hasWarnings, isComplete }\n}\n\n/**\n * Aggregates subtree status across instances of a multiple page entity.\n * When `scopeEntityUuid` is set, only instances under that ancestor entity are included\n * (needed for nested multiples, e.g. Tree under the currently selected Plot).\n * Empty instance lists return a non-complete status with no validation flags.\n */\nexport const getMultiplePageEntitiesStatus = (params: {\n survey: Survey\n record: ArenaRecord\n pageNodeDefUuid: string\n cycle?: string\n /** When set, only instances under this ancestor entity are aggregated. */\n scopeEntityUuid?: string\n}): EntitySubtreeStatus => {\n const { survey, record, pageNodeDefUuid, scopeEntityUuid } = params\n const instances = getNodesByDefUuid(pageNodeDefUuid)(record).filter((instance) =>\n scopeEntityUuid ? nodeIsUnderEntity({ node: instance, entityUuid: scopeEntityUuid }) : true\n )\n\n if (instances.length === 0) {\n return { hasErrors: false, hasWarnings: false, isComplete: false }\n }\n\n const instanceStatuses = instances\n .map((instance) => getEntitySubtreeStatus({ survey, record, entityUuid: instance.uuid, cycle: params.cycle }))\n .filter((status): status is EntitySubtreeStatus => status !== null)\n\n return {\n hasErrors: instanceStatuses.some((status) => status.hasErrors),\n hasWarnings: instanceStatuses.some((status) => status.hasWarnings),\n isComplete: instanceStatuses.length > 0 && instanceStatuses.every((status) => status.isComplete),\n }\n}\n\n/**\n * Whether the page has validation errors on its own fields (excluding nested page entities).\n */\nexport const pageHasOwnErrors = (params: {\n pageNodeDefUuid: string\n descendantPageUuids: string[]\n record: ArenaRecord\n}): boolean => getPageValidationStatus(params).hasErrors\n\n/**\n * Progress of pages without own-field validation errors over all survey pages.\n * Warnings do not reduce the score (matches Arena sidebar red-icon signal).\n */\nexport const getRecordPagesValidationProgress = (params: {\n survey: Survey\n record: ArenaRecord\n cycle?: string\n}): PagesValidationProgress | null => {\n const { survey, record } = params\n if (!getRoot(record)) return null\n\n const cycle = params.cycle ?? getCycle(record)\n const pageNodeDefs = getPageNodeDefs({ survey, cycle })\n const totalCount = pageNodeDefs.length\n if (totalCount === 0) return null\n\n let validCount = 0\n for (const pageNodeDef of pageNodeDefs) {\n const pageNodeDefUuid = pageNodeDef.uuid\n const descendantPageUuids = getDescendantPageNodeDefUuids({ survey, cycle, pageNodeDef })\n if (!pageHasOwnErrors({ pageNodeDefUuid, descendantPageUuids, record })) {\n validCount += 1\n }\n }\n\n const percent = Math.round((validCount / totalCount) * 100)\n return { percent, validCount, totalCount }\n}\n"]}
@@ -1,7 +1,7 @@
1
- import { Node } from '../../node';
2
- import { Record } from '../record';
1
+ import { ArenaRecordNode } from '../../node';
2
+ import { ArenaRecord } from '../record';
3
3
  import { RecordUpdateOptions } from './recordUpdateOptions';
4
4
  export declare const addNodes: (nodes: {
5
- [key: string]: Node;
6
- }, options?: RecordUpdateOptions) => (record: Record) => Record;
7
- export declare const addNode: (node: Node, options?: RecordUpdateOptions) => (record: Record) => Record;
5
+ [key: string]: ArenaRecordNode;
6
+ }, options?: RecordUpdateOptions) => (record: ArenaRecord) => ArenaRecord;
7
+ export declare const addNode: (node: ArenaRecordNode, options?: RecordUpdateOptions) => (record: ArenaRecord) => ArenaRecord;
@@ -1 +1 @@
1
- {"version":3,"file":"recordUpdater.js","sourceRoot":"","sources":["../../../src/record/_records/recordUpdater.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,MAAY,aAAa,4CAAuB;AAChD,uEAAmE;AACnE,+DAAwF;AAEjF,MAAM,QAAQ,GACnB,CAAC,KAA8B,EAAE,OAAO,GAAwB,iDAA2B,EAAE,EAAE,CAC/F,CAAC,MAAc,EAAU,EAAE;;IACzB,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,mCAAQ,iDAA2B,GAAK,OAAO,CAAE,CAAA;IAElG,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,mBAAM,MAAM,CAAE,CAAA;IACzD,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;IACzD,MAAM,KAAK,SAAG,aAAa,CAAC,WAAW,mCAAI,EAAE,CAAA;IAE7C,6FAA6F;IAC7F,sEAAsE;IACtE,MAAM,YAAY,GAA4B,EAAE,CAAA;IAChD,IAAI,gBAAgB,EAAE,CAAC;QACrB,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;YACtC,IAAI,CAAC,iDAAuB,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBAC7E,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,aAAa,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IACzD,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,KAAK,mCAAQ,WAAW,GAAK,KAAK,CAAE,CAAA;IACpD,CAAC;IACD,IAAI,gBAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7D,aAAa,CAAC,WAAW,GAAG,iDAAuB,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,CAAA;IAC1G,CAAC;IACD,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA;AA9BU,QAAA,QAAQ,GAAR,QAAQ,CA8BlB;AAEI,MAAM,OAAO,GAClB,CAAC,IAAU,EAAE,OAAO,GAAwB,iDAA2B,EAAE,EAAE,CAC3E,CAAC,MAAc,EAAE,EAAE,CACjB,IAAA,QAAA,QAAQ,EAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AAHvC,QAAA,OAAO,GAAP,OAAO,CAGgC","sourcesContent":["import { Node } from '../../node'\nimport { Record } from '../record'\nimport * as RecordGetters from './recordGetters'\nimport { RecordNodesIndexUpdater } from './recordNodesIndexUpdater'\nimport { RecordUpdateOptions, RecordUpdateOptionsDefaults } from './recordUpdateOptions'\n\nexport const addNodes =\n (nodes: { [key: string]: Node }, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: Record): Record => {\n const { sideEffect, updateNodesIndex, sortNodes } = { ...RecordUpdateOptionsDefaults, ...options }\n\n const recordUpdated = sideEffect ? record : { ...record }\n const recordNodes = RecordGetters.getNodes(recordUpdated)\n const index = recordUpdated._nodesIndex ?? {}\n\n // index only the nodes not already indexed with the same parent, node def and hierarchy code\n // (e.g. nodes with only an updated value don't need any index change)\n const nodesToIndex: { [key: string]: Node } = {}\n if (updateNodesIndex) {\n for (const [nodeUuid, node] of Object.entries(nodes)) {\n const nodePrev = recordNodes[nodeUuid]\n if (!RecordNodesIndexUpdater.isNodeIndexUnchanged({ index, node, nodePrev })) {\n nodesToIndex[nodeUuid] = node\n }\n }\n }\n\n if (sideEffect) {\n recordUpdated.nodes = Object.assign(recordNodes, nodes)\n } else {\n recordUpdated.nodes = { ...recordNodes, ...nodes }\n }\n if (updateNodesIndex && Object.keys(nodesToIndex).length > 0) {\n recordUpdated._nodesIndex = RecordNodesIndexUpdater.addNodes(nodesToIndex, sideEffect, sortNodes)(index)\n }\n return recordUpdated\n }\n\nexport const addNode =\n (node: Node, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: Record) =>\n addNodes({ [node.uuid]: node }, options)(record)\n"]}
1
+ {"version":3,"file":"recordUpdater.js","sourceRoot":"","sources":["../../../src/record/_records/recordUpdater.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,MAAY,aAAa,4CAAuB;AAChD,uEAAmE;AACnE,+DAAwF;AAEjF,MAAM,QAAQ,GACnB,CAAC,KAAyC,EAAE,OAAO,GAAwB,iDAA2B,EAAE,EAAE,CAC1G,CAAC,MAAmB,EAAe,EAAE;;IACnC,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,mCAAQ,iDAA2B,GAAK,OAAO,CAAE,CAAA;IAElG,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,mBAAM,MAAM,CAAE,CAAA;IACzD,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;IACzD,MAAM,KAAK,SAAG,aAAa,CAAC,WAAW,mCAAI,EAAE,CAAA;IAE7C,6FAA6F;IAC7F,sEAAsE;IACtE,MAAM,YAAY,GAAuC,EAAE,CAAA;IAC3D,IAAI,gBAAgB,EAAE,CAAC;QACrB,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;YACtC,IAAI,CAAC,iDAAuB,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBAC7E,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,aAAa,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IACzD,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,KAAK,mCAAQ,WAAW,GAAK,KAAK,CAAE,CAAA;IACpD,CAAC;IACD,IAAI,gBAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7D,aAAa,CAAC,WAAW,GAAG,iDAAuB,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,CAAA;IAC1G,CAAC;IACD,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA;AA9BU,QAAA,QAAQ,GAAR,QAAQ,CA8BlB;AAEI,MAAM,OAAO,GAClB,CAAC,IAAqB,EAAE,OAAO,GAAwB,iDAA2B,EAAE,EAAE,CACtF,CAAC,MAAmB,EAAE,EAAE,CACtB,IAAA,QAAA,QAAQ,EAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AAHvC,QAAA,OAAO,GAAP,OAAO,CAGgC","sourcesContent":["import { ArenaRecordNode } from '../../node'\nimport { ArenaRecord } from '../record'\nimport * as RecordGetters from './recordGetters'\nimport { RecordNodesIndexUpdater } from './recordNodesIndexUpdater'\nimport { RecordUpdateOptions, RecordUpdateOptionsDefaults } from './recordUpdateOptions'\n\nexport const addNodes =\n (nodes: { [key: string]: ArenaRecordNode }, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord): ArenaRecord => {\n const { sideEffect, updateNodesIndex, sortNodes } = { ...RecordUpdateOptionsDefaults, ...options }\n\n const recordUpdated = sideEffect ? record : { ...record }\n const recordNodes = RecordGetters.getNodes(recordUpdated)\n const index = recordUpdated._nodesIndex ?? {}\n\n // index only the nodes not already indexed with the same parent, node def and hierarchy code\n // (e.g. nodes with only an updated value don't need any index change)\n const nodesToIndex: { [key: string]: ArenaRecordNode } = {}\n if (updateNodesIndex) {\n for (const [nodeUuid, node] of Object.entries(nodes)) {\n const nodePrev = recordNodes[nodeUuid]\n if (!RecordNodesIndexUpdater.isNodeIndexUnchanged({ index, node, nodePrev })) {\n nodesToIndex[nodeUuid] = node\n }\n }\n }\n\n if (sideEffect) {\n recordUpdated.nodes = Object.assign(recordNodes, nodes)\n } else {\n recordUpdated.nodes = { ...recordNodes, ...nodes }\n }\n if (updateNodesIndex && Object.keys(nodesToIndex).length > 0) {\n recordUpdated._nodesIndex = RecordNodesIndexUpdater.addNodes(nodesToIndex, sideEffect, sortNodes)(index)\n }\n return recordUpdated\n }\n\nexport const addNode =\n (node: ArenaRecordNode, options: RecordUpdateOptions = RecordUpdateOptionsDefaults) =>\n (record: ArenaRecord) =>\n addNodes({ [node.uuid]: node }, options)(record)\n"]}
@@ -1,18 +1,18 @@
1
1
  import { CategoryItem } from '../../category';
2
- import { Node } from '../../node';
2
+ import { ArenaRecordNode } from '../../node';
3
3
  import { NodeDef, NodeDefCode, NodeDefEntity } from '../../nodeDef';
4
4
  import { CategoryItemProvider } from '../../nodeDefExpressionEvaluator/categoryItemProvider';
5
5
  import { Survey } from '../../survey';
6
- import { Record } from '../record';
6
+ import { ArenaRecord } from '../record';
7
7
  export declare const findDependentEnumeratedEntityDefsNotEmpty: (params: {
8
8
  survey: Survey;
9
- node: Node;
9
+ node: ArenaRecordNode;
10
10
  nodeDef: NodeDef<any>;
11
- }) => (record: Record) => NodeDefEntity[];
11
+ }) => (record: ArenaRecord) => NodeDefEntity[];
12
12
  export declare const getEnumeratingCategoryItems: (params: {
13
13
  survey: Survey;
14
14
  enumeratorDef: NodeDefCode;
15
- parentNode: Node;
15
+ parentNode: ArenaRecordNode;
16
16
  categoryItemProvider?: CategoryItemProvider;
17
17
  allowedCodes?: Set<string>;
18
- }) => (record: Record) => Promise<CategoryItem[]>;
18
+ }) => (record: ArenaRecord) => Promise<CategoryItem[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"recordUtils.js","sourceRoot":"","sources":["../../../src/record/_records/recordUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { CategoryItem } from '../../category'\nimport { Node, NodeValues } from '../../node'\nimport { NodeDef, NodeDefCode, NodeDefEntity, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { CategoryItemProvider } from '../../nodeDefExpressionEvaluator/categoryItemProvider'\nimport { Survey, Surveys } from '../../survey'\nimport { Record } from '../record'\nimport {\n getChildren,\n getDescendantsOrSelf,\n getParent,\n getParentCodeAttribute,\n getRoot,\n isNodeFilledByUser,\n} from './recordGetters'\n\nconst findDependentEnumeratedEntityDefs = (params: { survey: Survey; nodeDef: NodeDef<any> }): NodeDefEntity[] => {\n const { survey, nodeDef } = params\n const dependentEnumeratedEntityDefs =\n NodeDefs.getType(nodeDef) === NodeDefType.code\n ? Surveys.getDependentEnumeratedEntityDefs({ survey, nodeDef: nodeDef as NodeDefCode })\n : []\n\n const applicableDependentEnumeratedEntityDefs = Surveys.findApplicableDependentEnumeratedEntityDefs(nodeDef)(survey)\n dependentEnumeratedEntityDefs.push(...applicableDependentEnumeratedEntityDefs)\n\n return dependentEnumeratedEntityDefs\n}\n\nconst hasNodeNonEmptyDescendants = (params: {\n record: Record\n parentNode: Node | undefined\n nodeDefDescendant: NodeDefEntity\n}): boolean => {\n const { record, parentNode, nodeDefDescendant } = params\n const descendants = getDescendantsOrSelf({\n record,\n node: parentNode ?? getRoot(record)!,\n nodeDefDescendant,\n })\n const nonEmptyDescendants = descendants.filter((dependentEntity) =>\n getChildren(dependentEntity)(record).some((childNode) => isNodeFilledByUser(childNode)(record))\n )\n return nonEmptyDescendants.length > 0\n}\n\nexport const findDependentEnumeratedEntityDefsNotEmpty =\n (params: { survey: Survey; node: Node; nodeDef: NodeDef<any> }) => (record: Record) => {\n const { survey, node, nodeDef } = params\n const dependentEnumeratedEntityDefs = findDependentEnumeratedEntityDefs({ survey, nodeDef })\n if (dependentEnumeratedEntityDefs.length === 0) return []\n\n const parentNode = getParent(node)(record)\n\n return dependentEnumeratedEntityDefs.filter((dependentEnumeratedEntityDef) =>\n hasNodeNonEmptyDescendants({ record, parentNode, nodeDefDescendant: dependentEnumeratedEntityDef })\n )\n }\n\nexport const getEnumeratingCategoryItems =\n (params: {\n survey: Survey\n enumeratorDef: NodeDefCode\n parentNode: Node\n categoryItemProvider?: CategoryItemProvider\n allowedCodes?: Set<string>\n }) =>\n async (record: Record): Promise<CategoryItem[]> => {\n const { survey, enumeratorDef, parentNode, categoryItemProvider, allowedCodes } = params\n const categoryUuid = NodeDefs.getCategoryUuid(enumeratorDef)\n if (!categoryUuid) return []\n const category = Surveys.getCategoryByUuid({ survey, categoryUuid })\n if (!category) return []\n\n let parentItemUuid\n const parentCodeDefUuid = NodeDefs.getParentCodeDefUuid(enumeratorDef)\n if (parentCodeDefUuid) {\n const parentCodeAttribute = getParentCodeAttribute({ parentNode, nodeDef: enumeratorDef })(record)\n parentItemUuid = parentCodeAttribute ? NodeValues.getItemUuid(parentCodeAttribute) : null\n if (!parentItemUuid) return []\n }\n let items = Surveys.getEnumeratingCategoryItems({ survey, enumerator: enumeratorDef, parentItemUuid })\n if (items.length === 0 && categoryItemProvider) {\n items = await categoryItemProvider.getItems({ survey, categoryUuid, parentItemUuid, draft: !!record.preview })\n }\n if (allowedCodes) {\n items = items.filter((item) => item.props.code != null && allowedCodes.has(item.props.code))\n }\n return items\n }\n"]}
1
+ {"version":3,"file":"recordUtils.js","sourceRoot":"","sources":["../../../src/record/_records/recordUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { CategoryItem } from '../../category'\nimport { ArenaRecordNode, NodeValues } from '../../node'\nimport { NodeDef, NodeDefCode, NodeDefEntity, NodeDefs, NodeDefType } from '../../nodeDef'\nimport { CategoryItemProvider } from '../../nodeDefExpressionEvaluator/categoryItemProvider'\nimport { Survey, Surveys } from '../../survey'\nimport { ArenaRecord } from '../record'\nimport {\n getChildren,\n getDescendantsOrSelf,\n getParent,\n getParentCodeAttribute,\n getRoot,\n isNodeFilledByUser,\n} from './recordGetters'\n\nconst findDependentEnumeratedEntityDefs = (params: { survey: Survey; nodeDef: NodeDef<any> }): NodeDefEntity[] => {\n const { survey, nodeDef } = params\n const dependentEnumeratedEntityDefs =\n NodeDefs.getType(nodeDef) === NodeDefType.code\n ? Surveys.getDependentEnumeratedEntityDefs({ survey, nodeDef: nodeDef as NodeDefCode })\n : []\n\n const applicableDependentEnumeratedEntityDefs = Surveys.findApplicableDependentEnumeratedEntityDefs(nodeDef)(survey)\n dependentEnumeratedEntityDefs.push(...applicableDependentEnumeratedEntityDefs)\n\n return dependentEnumeratedEntityDefs\n}\n\nconst hasNodeNonEmptyDescendants = (params: {\n record: ArenaRecord\n parentNode: ArenaRecordNode | undefined\n nodeDefDescendant: NodeDefEntity\n}): boolean => {\n const { record, parentNode, nodeDefDescendant } = params\n const descendants = getDescendantsOrSelf({\n record,\n node: parentNode ?? getRoot(record)!,\n nodeDefDescendant,\n })\n const nonEmptyDescendants = descendants.filter((dependentEntity) =>\n getChildren(dependentEntity)(record).some((childNode) => isNodeFilledByUser(childNode)(record))\n )\n return nonEmptyDescendants.length > 0\n}\n\nexport const findDependentEnumeratedEntityDefsNotEmpty =\n (params: { survey: Survey; node: ArenaRecordNode; nodeDef: NodeDef<any> }) => (record: ArenaRecord) => {\n const { survey, node, nodeDef } = params\n const dependentEnumeratedEntityDefs = findDependentEnumeratedEntityDefs({ survey, nodeDef })\n if (dependentEnumeratedEntityDefs.length === 0) return []\n\n const parentNode = getParent(node)(record)\n\n return dependentEnumeratedEntityDefs.filter((dependentEnumeratedEntityDef) =>\n hasNodeNonEmptyDescendants({ record, parentNode, nodeDefDescendant: dependentEnumeratedEntityDef })\n )\n }\n\nexport const getEnumeratingCategoryItems =\n (params: {\n survey: Survey\n enumeratorDef: NodeDefCode\n parentNode: ArenaRecordNode\n categoryItemProvider?: CategoryItemProvider\n allowedCodes?: Set<string>\n }) =>\n async (record: ArenaRecord): Promise<CategoryItem[]> => {\n const { survey, enumeratorDef, parentNode, categoryItemProvider, allowedCodes } = params\n const categoryUuid = NodeDefs.getCategoryUuid(enumeratorDef)\n if (!categoryUuid) return []\n const category = Surveys.getCategoryByUuid({ survey, categoryUuid })\n if (!category) return []\n\n let parentItemUuid\n const parentCodeDefUuid = NodeDefs.getParentCodeDefUuid(enumeratorDef)\n if (parentCodeDefUuid) {\n const parentCodeAttribute = getParentCodeAttribute({ parentNode, nodeDef: enumeratorDef })(record)\n parentItemUuid = parentCodeAttribute ? NodeValues.getItemUuid(parentCodeAttribute) : null\n if (!parentItemUuid) return []\n }\n let items = Surveys.getEnumeratingCategoryItems({ survey, enumerator: enumeratorDef, parentItemUuid })\n if (items.length === 0 && categoryItemProvider) {\n items = await categoryItemProvider.getItems({ survey, categoryUuid, parentItemUuid, draft: !!record.preview })\n }\n if (allowedCodes) {\n items = items.filter((item) => item.props.code != null && allowedCodes.has(item.props.code))\n }\n return items\n }\n"]}
@@ -1,6 +1,6 @@
1
1
  import { Factory } from '../common';
2
2
  import { User } from '../auth';
3
- import { Record } from './record';
3
+ import { ArenaRecord } from './record';
4
4
  import { AppInfo } from '../app';
5
5
  export type RecordFactoryParams = {
6
6
  cycle?: string;
@@ -11,4 +11,4 @@ export type RecordFactoryParams = {
11
11
  user: User;
12
12
  appInfo?: AppInfo;
13
13
  };
14
- export declare const RecordFactory: Factory<Record, RecordFactoryParams>;
14
+ export declare const RecordFactory: Factory<ArenaRecord, RecordFactoryParams>;
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/record/factory.ts"],"names":[],"mappings":";;;AACA,kCAAoD;AACpD,qCAAsD;AACtD,oCAAgC;AAanB,QAAA,aAAa,GAAyC;IACjE,cAAc,EAAE,CAAC,MAA2B,EAAU,EAAE;;;QACtD,MAAM,YAAY,GAAG;YACnB,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,4BAAmB;SAC1B,CAAA;QAED,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,mCACjE,YAAY,GACZ,MAAM,CACV,CAAA;QAED,MAAM,WAAW,GAAG,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,CAAA;QACrF,MAAM,SAAS,SAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,mCAAI,CAAC,YAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,oBAAa,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAE1G,uBACE,KAAK;YACL,WAAW,EACX,UAAU,EAAE,IAAI,CAAC,KAAK,EACtB,SAAS,EAAE,IAAI,CAAC,IAAI,EACpB,SAAS,EACT,SAAS,EAAE,IAAI,CAAC,IAAI,EACpB,OAAO;YACP,IAAI;YACJ,UAAU,EACV,IAAI,EAAE,aAAK,CAAC,EAAE,EAAE,IACb,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACvD;IACH,CAAC;CACF,CAAA","sourcesContent":["import { Factory } from '../common'\nimport { AuthGroupName, User, Users } from '../auth'\nimport { Record, RECORD_STEP_DEFAULT } from './record'\nimport { UUIDs } from '../utils'\nimport { AppInfo } from '../app'\n\nexport type RecordFactoryParams = {\n cycle?: string\n dateCreated?: string\n preview?: boolean\n surveyUuid: string\n step?: string\n user: User\n appInfo?: AppInfo\n}\n\nexport const RecordFactory: Factory<Record, RecordFactoryParams> = {\n createInstance: (params: RecordFactoryParams): Record => {\n const defaultProps = {\n preview: false,\n step: RECORD_STEP_DEFAULT,\n }\n\n const { appInfo, cycle, dateCreated, preview, step, surveyUuid, user } = {\n ...defaultProps,\n ...params,\n }\n\n const surveyGroup = user.authGroups?.find((group) => group.surveyUuid === surveyUuid)\n const ownerRole = surveyGroup?.name ?? (Users.isSystemAdmin(user) ? AuthGroupName.systemAdmin : undefined)\n\n return {\n cycle,\n dateCreated,\n ownerEmail: user.email,\n ownerName: user.name,\n ownerRole,\n ownerUuid: user.uuid,\n preview,\n step,\n surveyUuid,\n uuid: UUIDs.v4(),\n ...(appInfo ? { info: { createdWith: appInfo } } : {}),\n }\n },\n}\n"]}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/record/factory.ts"],"names":[],"mappings":";;;AACA,kCAAoD;AACpD,qCAA2D;AAC3D,oCAAgC;AAanB,QAAA,aAAa,GAA8C;IACtE,cAAc,EAAE,CAAC,MAA2B,EAAe,EAAE;;;QAC3D,MAAM,YAAY,GAAG;YACnB,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,4BAAmB;SAC1B,CAAA;QAED,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,mCACjE,YAAY,GACZ,MAAM,CACV,CAAA;QAED,MAAM,WAAW,GAAG,MAAA,IAAI,CAAC,UAAU,0CAAE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,CAAA;QACrF,MAAM,SAAS,SAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,mCAAI,CAAC,YAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,oBAAa,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAE1G,uBACE,KAAK;YACL,WAAW,EACX,UAAU,EAAE,IAAI,CAAC,KAAK,EACtB,SAAS,EAAE,IAAI,CAAC,IAAI,EACpB,SAAS,EACT,SAAS,EAAE,IAAI,CAAC,IAAI,EACpB,OAAO;YACP,IAAI;YACJ,UAAU,EACV,IAAI,EAAE,aAAK,CAAC,EAAE,EAAE,IACb,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACvD;IACH,CAAC;CACF,CAAA","sourcesContent":["import { Factory } from '../common'\nimport { AuthGroupName, User, Users } from '../auth'\nimport { ArenaRecord, RECORD_STEP_DEFAULT } from './record'\nimport { UUIDs } from '../utils'\nimport { AppInfo } from '../app'\n\nexport type RecordFactoryParams = {\n cycle?: string\n dateCreated?: string\n preview?: boolean\n surveyUuid: string\n step?: string\n user: User\n appInfo?: AppInfo\n}\n\nexport const RecordFactory: Factory<ArenaRecord, RecordFactoryParams> = {\n createInstance: (params: RecordFactoryParams): ArenaRecord => {\n const defaultProps = {\n preview: false,\n step: RECORD_STEP_DEFAULT,\n }\n\n const { appInfo, cycle, dateCreated, preview, step, surveyUuid, user } = {\n ...defaultProps,\n ...params,\n }\n\n const surveyGroup = user.authGroups?.find((group) => group.surveyUuid === surveyUuid)\n const ownerRole = surveyGroup?.name ?? (Users.isSystemAdmin(user) ? AuthGroupName.systemAdmin : undefined)\n\n return {\n cycle,\n dateCreated,\n ownerEmail: user.email,\n ownerName: user.name,\n ownerRole,\n ownerUuid: user.uuid,\n preview,\n step,\n surveyUuid,\n uuid: UUIDs.v4(),\n ...(appInfo ? { info: { createdWith: appInfo } } : {}),\n }\n },\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  export { NodePointers } from './nodePointers';
2
- export type { Record } from './record';
3
- export type { Record as ArenaRecord } from './record';
2
+ export type { ArenaRecord, Record } from './record';
4
3
  export { RECORD_STEP_DEFAULT } from './record';
5
4
  export { Records } from './records';
6
5
  export type { RecordUpdateOptions } from './records';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/record/index.ts"],"names":[],"mappings":";;;AAAA,+CAA6C;AAApC,4GAAA,YAAY,OAAA;AAIrB,mCAA8C;AAArC,6GAAA,mBAAmB,OAAA;AAE5B,qCAAmC;AAA1B,kGAAA,OAAO,OAAA;AAGhB,+CAA6C;AAApC,4GAAA,YAAY,OAAA;AACrB,yEAAuE;AAA9D,sIAAA,yBAAyB,OAAA;AAElC,6CAA2C;AAAlC,0GAAA,WAAW,OAAA;AACpB,2DAA6E;AAApE,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAE/C,iDAA+C;AAAtC,8GAAA,aAAa,OAAA;AACtB,qDAAmD;AAA1C,kHAAA,eAAe,OAAA;AAOxB,yDAAuD;AAA9C,sHAAA,iBAAiB,OAAA;AAE1B,qCAAyC;AAAhC,wGAAA,aAAa,OAAA;AAGtB,6DAA2D;AAAlD,0HAAA,mBAAmB,OAAA","sourcesContent":["export { NodePointers } from './nodePointers'\n\nexport type { Record } from './record'\nexport type { Record as ArenaRecord } from './record'\nexport { RECORD_STEP_DEFAULT } from './record'\n\nexport { Records } from './records'\nexport type { RecordUpdateOptions } from './records'\n\nexport { RecordCloner } from './recordCloner'\nexport { RecordExpressionEvaluator } from './recordExpressionEvaluator'\nexport type { RecordExpressionContext } from './recordExpressionEvaluator'\nexport { RecordFixer } from './recordFixer'\nexport { RecordNodesUpdater, RecordUpdateResult } from './recordNodesUpdater'\nexport type { NodeCreateParams, NodesUpdateParams, RecordExpressionEvaluationContext } from './recordNodesUpdater'\nexport { RecordUpdater } from './recordUpdater'\nexport { RecordValidator } from './recordValidator'\nexport type {\n AttributeValidatorParams,\n AttributesValidatorParams,\n RecordValidatorParams,\n SortedAttributesValidatorParams,\n} from './recordValidator'\nexport { RecordValidations } from './recordValidations'\n\nexport { RecordFactory } from './factory'\nexport type { RecordService } from './service'\n\nexport { RecordPrettyPrinter } from './recordPrettyPrinter'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/record/index.ts"],"names":[],"mappings":";;;AAAA,+CAA6C;AAApC,4GAAA,YAAY,OAAA;AAGrB,mCAA8C;AAArC,6GAAA,mBAAmB,OAAA;AAE5B,qCAAmC;AAA1B,kGAAA,OAAO,OAAA;AAGhB,+CAA6C;AAApC,4GAAA,YAAY,OAAA;AACrB,yEAAuE;AAA9D,sIAAA,yBAAyB,OAAA;AAElC,6CAA2C;AAAlC,0GAAA,WAAW,OAAA;AACpB,2DAA6E;AAApE,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAE/C,iDAA+C;AAAtC,8GAAA,aAAa,OAAA;AACtB,qDAAmD;AAA1C,kHAAA,eAAe,OAAA;AAOxB,yDAAuD;AAA9C,sHAAA,iBAAiB,OAAA;AAE1B,qCAAyC;AAAhC,wGAAA,aAAa,OAAA;AAGtB,6DAA2D;AAAlD,0HAAA,mBAAmB,OAAA","sourcesContent":["export { NodePointers } from './nodePointers'\n\nexport type { ArenaRecord, Record } from './record'\nexport { RECORD_STEP_DEFAULT } from './record'\n\nexport { Records } from './records'\nexport type { RecordUpdateOptions } from './records'\n\nexport { RecordCloner } from './recordCloner'\nexport { RecordExpressionEvaluator } from './recordExpressionEvaluator'\nexport type { RecordExpressionContext } from './recordExpressionEvaluator'\nexport { RecordFixer } from './recordFixer'\nexport { RecordNodesUpdater, RecordUpdateResult } from './recordNodesUpdater'\nexport type { NodeCreateParams, NodesUpdateParams, RecordExpressionEvaluationContext } from './recordNodesUpdater'\nexport { RecordUpdater } from './recordUpdater'\nexport { RecordValidator } from './recordValidator'\nexport type {\n AttributeValidatorParams,\n AttributesValidatorParams,\n RecordValidatorParams,\n SortedAttributesValidatorParams,\n} from './recordValidator'\nexport { RecordValidations } from './recordValidations'\n\nexport { RecordFactory } from './factory'\nexport type { RecordService } from './service'\n\nexport { RecordPrettyPrinter } from './recordPrettyPrinter'\n"]}
@@ -1,14 +1,14 @@
1
- import { Node, NodePointer } from '../node';
2
- import { Record } from './record';
1
+ import { ArenaRecordNode, NodePointer } from '../node';
2
+ import { ArenaRecord } from './record';
3
3
  declare const getNodesFromNodePointers: (params: {
4
- record: Record;
4
+ record: ArenaRecord;
5
5
  nodePointers: NodePointer[];
6
- }) => Node[];
6
+ }) => ArenaRecordNode[];
7
7
  declare const getNodesMapFromNodePointers: (params: {
8
- record: Record;
8
+ record: ArenaRecord;
9
9
  nodePointers: NodePointer[];
10
10
  }) => {
11
- [key: string]: Node;
11
+ [key: string]: ArenaRecordNode;
12
12
  };
13
13
  export declare const NodePointers: {
14
14
  getNodesFromNodePointers: typeof getNodesFromNodePointers;
@@ -1 +1 @@
1
- {"version":3,"file":"nodePointers.js","sourceRoot":"","sources":["../../src/record/nodePointers.ts"],"names":[],"mappings":";;;AAEA,uCAAmC;AAEnC,MAAM,wBAAwB,GAAG,CAAC,MAAuD,EAAU,EAAE;IACnG,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAAA;IAEvC,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAC1C,iBAAO,CAAC,WAAW,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAC3E,CAAA;AACH,CAAC,CAAA;AAED,MAAM,2BAA2B,GAAG,CAAC,MAGpC,EAA2B,EAAE;IAC5B,MAAM,KAAK,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAA4B,EAAE,CAAA;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC5B,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAEY,QAAA,YAAY,GAAG;IAC1B,wBAAwB;IACxB,2BAA2B;CAC5B,CAAA","sourcesContent":["import { Node, NodePointer } from '../node'\nimport { Record } from './record'\nimport { Records } from './records'\n\nconst getNodesFromNodePointers = (params: { record: Record; nodePointers: NodePointer[] }): Node[] => {\n const { record, nodePointers } = params\n\n return nodePointers.flatMap((nodePointer) =>\n Records.getChildren(nodePointer.nodeCtx, nodePointer.nodeDef.uuid)(record)\n )\n}\n\nconst getNodesMapFromNodePointers = (params: {\n record: Record\n nodePointers: NodePointer[]\n}): { [key: string]: Node } => {\n const nodes = getNodesFromNodePointers(params)\n const nodesMap: { [key: string]: Node } = {}\n for (const node of nodes) {\n nodesMap[node.uuid] = node\n }\n return nodesMap\n}\n\nexport const NodePointers = {\n getNodesFromNodePointers,\n getNodesMapFromNodePointers,\n}\n"]}
1
+ {"version":3,"file":"nodePointers.js","sourceRoot":"","sources":["../../src/record/nodePointers.ts"],"names":[],"mappings":";;;AAEA,uCAAmC;AAEnC,MAAM,wBAAwB,GAAG,CAAC,MAA4D,EAAqB,EAAE;IACnH,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAAA;IAEvC,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAC1C,iBAAO,CAAC,WAAW,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAC3E,CAAA;AACH,CAAC,CAAA;AAED,MAAM,2BAA2B,GAAG,CAAC,MAGpC,EAAsC,EAAE;IACvC,MAAM,KAAK,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAAuC,EAAE,CAAA;IACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC5B,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAEY,QAAA,YAAY,GAAG;IAC1B,wBAAwB;IACxB,2BAA2B;CAC5B,CAAA","sourcesContent":["import { ArenaRecordNode, NodePointer } from '../node'\nimport { ArenaRecord } from './record'\nimport { Records } from './records'\n\nconst getNodesFromNodePointers = (params: { record: ArenaRecord; nodePointers: NodePointer[] }): ArenaRecordNode[] => {\n const { record, nodePointers } = params\n\n return nodePointers.flatMap((nodePointer) =>\n Records.getChildren(nodePointer.nodeCtx, nodePointer.nodeDef.uuid)(record)\n )\n}\n\nconst getNodesMapFromNodePointers = (params: {\n record: ArenaRecord\n nodePointers: NodePointer[]\n}): { [key: string]: ArenaRecordNode } => {\n const nodes = getNodesFromNodePointers(params)\n const nodesMap: { [key: string]: ArenaRecordNode } = {}\n for (const node of nodes) {\n nodesMap[node.uuid] = node\n }\n return nodesMap\n}\n\nexport const NodePointers = {\n getNodesFromNodePointers,\n getNodesMapFromNodePointers,\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { AppInfo } from '../app';
2
- import { Node } from '../node';
2
+ import { ArenaRecordNode } from '../node';
3
3
  import { Validation } from '../validation';
4
4
  export declare const RECORD_STEP_DEFAULT = "1";
5
5
  export declare const steps: string[];
@@ -36,13 +36,13 @@ export interface RecordInfo {
36
36
  createdWith?: AppInfo;
37
37
  updatedWith?: AppInfo;
38
38
  }
39
- export interface Record {
39
+ export interface ArenaRecord {
40
40
  cycle?: string;
41
41
  dateCreated?: string;
42
42
  dateModified?: string;
43
43
  id?: number;
44
44
  nodes?: {
45
- [uuid: string]: Node;
45
+ [uuid: string]: ArenaRecordNode;
46
46
  };
47
47
  ownerEmail?: string;
48
48
  ownerName: string;
@@ -57,6 +57,9 @@ export interface Record {
57
57
  _nodesIndex?: RecordNodesIndex;
58
58
  info?: RecordInfo;
59
59
  }
60
- export type ArenaRecord = Record;
61
- export type ArenaRecordNode = Node;
60
+ /**
61
+ * @deprecated Use ArenaRecord: this name shadows the TypeScript built-in Record utility type.
62
+ * It will be removed in the next major version.
63
+ */
64
+ export type Record = ArenaRecord;
62
65
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"record.js","sourceRoot":"","sources":["../../src/record/record.ts"],"names":[],"mappings":";;;AAIa,QAAA,mBAAmB,GAAG,GAAG,CAAA;AAEzB,QAAA,KAAK,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA","sourcesContent":["import { AppInfo } from '../app'\nimport { Node } from '../node'\nimport { Validation } from '../validation'\n\nexport const RECORD_STEP_DEFAULT = '1'\n\nexport const steps = ['entry', 'cleansing', 'analysis']\n\ninterface NodeUuidsPresence {\n [key: string]: boolean\n}\n\nexport interface RecordNodesIndex {\n /**\n * uuid of root entity\n */\n nodeRootUuid?: string\n /**\n * node uuids by parent entity uuid and child def uuid\n */\n nodesByParentAndChildDef?: { [key: string]: { [key: string]: NodeUuidsPresence } }\n /**\n * node uuids by node def uuid\n */\n nodesByDef?: { [key: string]: NodeUuidsPresence }\n /**\n * Code attribute uuids by ancenstor code attribute uuid\n */\n nodeCodeDependents?: { [key: string]: NodeUuidsPresence }\n}\n\nexport interface RecordInfo {\n createdWith?: AppInfo\n updatedWith?: AppInfo\n}\n\nexport interface Record {\n cycle?: string\n dateCreated?: string\n dateModified?: string\n id?: number\n nodes?: { [uuid: string]: Node }\n ownerEmail?: string\n ownerName: string\n ownerRole?: string\n ownerUuid: string\n preview?: boolean\n step: string // in steps\n surveyId?: number\n surveyUuid?: string\n uuid: string\n validation?: Validation\n\n _nodesIndex?: RecordNodesIndex\n\n info?: RecordInfo\n}\n\nexport type ArenaRecord = Record\nexport type ArenaRecordNode = Node\n"]}
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../src/record/record.ts"],"names":[],"mappings":";;;AAIa,QAAA,mBAAmB,GAAG,GAAG,CAAA;AAEzB,QAAA,KAAK,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA","sourcesContent":["import { AppInfo } from '../app'\nimport { ArenaRecordNode } from '../node'\nimport { Validation } from '../validation'\n\nexport const RECORD_STEP_DEFAULT = '1'\n\nexport const steps = ['entry', 'cleansing', 'analysis']\n\ninterface NodeUuidsPresence {\n [key: string]: boolean\n}\n\nexport interface RecordNodesIndex {\n /**\n * uuid of root entity\n */\n nodeRootUuid?: string\n /**\n * node uuids by parent entity uuid and child def uuid\n */\n nodesByParentAndChildDef?: { [key: string]: { [key: string]: NodeUuidsPresence } }\n /**\n * node uuids by node def uuid\n */\n nodesByDef?: { [key: string]: NodeUuidsPresence }\n /**\n * Code attribute uuids by ancenstor code attribute uuid\n */\n nodeCodeDependents?: { [key: string]: NodeUuidsPresence }\n}\n\nexport interface RecordInfo {\n createdWith?: AppInfo\n updatedWith?: AppInfo\n}\n\nexport interface ArenaRecord {\n cycle?: string\n dateCreated?: string\n dateModified?: string\n id?: number\n nodes?: { [uuid: string]: ArenaRecordNode }\n ownerEmail?: string\n ownerName: string\n ownerRole?: string\n ownerUuid: string\n preview?: boolean\n step: string // in steps\n surveyId?: number\n surveyUuid?: string\n uuid: string\n validation?: Validation\n\n _nodesIndex?: RecordNodesIndex\n\n info?: RecordInfo\n}\n\n/**\n * @deprecated Use ArenaRecord: this name shadows the TypeScript built-in Record utility type.\n * It will be removed in the next major version.\n */\nexport type Record = ArenaRecord\n"]}
@@ -1,15 +1,15 @@
1
1
  import { Survey } from '../survey';
2
- import { Record } from './record';
2
+ import { ArenaRecord } from './record';
3
3
  type OldUuidToNewUuidMap = {
4
4
  [key: string]: string;
5
5
  };
6
6
  declare const cloneRecord: (params: {
7
7
  survey: Survey;
8
- record: Record;
8
+ record: ArenaRecord;
9
9
  cycleTo: string;
10
10
  sideEffect?: boolean;
11
11
  }) => {
12
- record: Record;
12
+ record: ArenaRecord;
13
13
  newNodeUuidsByOldUuid: OldUuidToNewUuidMap;
14
14
  newFileUuidsByOldUuid: OldUuidToNewUuidMap;
15
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"recordCloner.js","sourceRoot":"","sources":["../../src/record/recordCloner.ts"],"names":[],"mappings":"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","sourcesContent":["import { Node, NodeValues, Nodes } from '../node'\nimport { NodeKeys, NodeMetaKeys } from '../node/node'\nimport { NodeDefCode, NodeDefType, NodeDefs } from '../nodeDef'\nimport { Survey, Surveys } from '../survey'\nimport { Dates, Objects, UUIDs } from '../utils'\nimport { Validation } from '../validation'\nimport { Record } from './record'\nimport { RecordFixer } from './recordFixer'\nimport { RecordUpdateResult } from './recordNodesUpdater'\nimport { RecordValidations } from './recordValidations'\nimport { Records } from './records'\n\ntype OldUuidToNewUuidMap = {\n [key: string]: string\n}\n\nconst assignNewUuidsToNodes = (params: {\n record: Record\n sideEffect: boolean\n}): { newNodeUuidsByOldUuid: OldUuidToNewUuidMap; newFileUuidsByOldUuid: OldUuidToNewUuidMap; record: Record } => {\n const { record, sideEffect } = params\n\n // generate a new uuid for each node\n const newNodeUuidsByOldUuid: OldUuidToNewUuidMap = {}\n const newFileUuidsByOldUuid: OldUuidToNewUuidMap = {}\n\n // sort nodes before removing the id, to preserve their hierarchy (faster than comparing each meta.h property)\n const nodesArray = Records.getNodesArray(record).sort(\n (nodeA: Node, nodeB: Node): number => Nodes.getHierarchy(nodeA).length - Nodes.getHierarchy(nodeB).length\n )\n\n const recordUpdated = sideEffect ? record : { ...record }\n\n const nodes = recordUpdated.nodes ?? {}\n const nodesUpdated = sideEffect ? nodes : { ...nodes }\n\n // update nodes recordUuid and properties (it does side effect on nodes)\n nodesArray.forEach((node) => {\n let nodeUpdated = sideEffect ? node : { ...node }\n nodeUpdated.recordUuid = record.uuid\n nodeUpdated.dateCreated = nodeUpdated.dateModified = Dates.nowFormattedForStorage()\n\n const oldUuid = node.uuid\n const newUuid = UUIDs.v4()\n newNodeUuidsByOldUuid[oldUuid] = newUuid\n\n nodeUpdated.uuid = newUuid\n // consider every node as just created node\n delete nodeUpdated.id\n nodeUpdated.created = true // this flag will be used by the RDB generator)\n\n // update internal node uuids, meta hierarchy, file uuid (if any)\n const parentUuid = node.parentUuid\n if (parentUuid) {\n nodeUpdated.parentUuid = newNodeUuidsByOldUuid[parentUuid]\n }\n const hierarchy = node.meta?.h ?? []\n if (hierarchy.length > 0) {\n const hierarchyUpdated = hierarchy.map((ancestorUuid) => newNodeUuidsByOldUuid[ancestorUuid])\n nodeUpdated = Objects.assocPath({\n obj: nodeUpdated,\n path: [NodeKeys.meta, NodeMetaKeys.h],\n value: hierarchyUpdated,\n sideEffect,\n })\n }\n // assign new file uuid (file should be cloned elsewhere)\n const fileUuid = NodeValues.getFileUuid(node)\n if (fileUuid) {\n const newFileUuid = UUIDs.v4()\n nodeUpdated = Objects.assocPath({\n obj: nodeUpdated,\n path: [NodeKeys.value, NodeValues.ValuePropsFile.fileUuid],\n value: newFileUuid,\n })\n newFileUuidsByOldUuid[fileUuid] = newFileUuid\n }\n\n delete nodesUpdated[oldUuid]\n nodesUpdated[newUuid] = nodeUpdated\n })\n\n recordUpdated.nodes = nodesUpdated\n\n return { newNodeUuidsByOldUuid, newFileUuidsByOldUuid, record: recordUpdated }\n}\n\nconst assignNewUuidsToValidation = (params: {\n validation: Validation\n newNodeUuidsByOldUuid: OldUuidToNewUuidMap\n sideEffect: boolean\n}): Validation => {\n const { validation, newNodeUuidsByOldUuid, sideEffect } = params\n\n const validationFields = validation?.fields\n if (!validationFields) return validation\n\n const validationFieldsUpdated = sideEffect ? validationFields : { ...validationFields }\n\n Object.entries(validationFields).forEach(([oldFieldKey, validationField]) => {\n let newFieldKey\n if (oldFieldKey.startsWith(RecordValidations.prefixValidationFieldChildrenCount)) {\n const oldParentUuid = oldFieldKey.substring(\n RecordValidations.prefixValidationFieldChildrenCount.length,\n oldFieldKey.lastIndexOf('_')\n )\n const newParentUuid = newNodeUuidsByOldUuid[oldParentUuid]\n newFieldKey = oldFieldKey.replace(oldParentUuid, newParentUuid)\n } else {\n newFieldKey = newNodeUuidsByOldUuid[oldFieldKey]\n }\n if (newFieldKey) {\n validationFieldsUpdated[newFieldKey] = validationField\n }\n delete validationFieldsUpdated[oldFieldKey]\n })\n return Objects.assoc({\n obj: validation,\n prop: 'fields',\n value: validationFieldsUpdated,\n sideEffect,\n })\n}\n\nconst assignNewUuids = (params: {\n record: Record\n sideEffect: boolean\n}): { newNodeUuidsByOldUuid: OldUuidToNewUuidMap; newFileUuidsByOldUuid: OldUuidToNewUuidMap; record: Record } => {\n const { record, sideEffect } = params\n let recordUpdated = sideEffect ? record : { ...record }\n recordUpdated.uuid = UUIDs.v4()\n\n const {\n newNodeUuidsByOldUuid,\n newFileUuidsByOldUuid,\n record: recordUpdatedUuids,\n } = assignNewUuidsToNodes({ record: recordUpdated, sideEffect })\n\n recordUpdated = recordUpdatedUuids\n\n const { validation } = recordUpdated\n if (validation) {\n const validationUpdated = assignNewUuidsToValidation({\n validation,\n newNodeUuidsByOldUuid,\n sideEffect,\n })\n recordUpdated = Objects.assoc({ obj: recordUpdated, prop: 'validation', value: validationUpdated, sideEffect })\n }\n // re-build nodes index\n const nodes = recordUpdated.nodes!\n delete recordUpdated._nodesIndex\n delete recordUpdated.nodes\n recordUpdated = Records.addNodes(nodes, { sideEffect, sortNodes: true })(recordUpdated)\n\n return { newNodeUuidsByOldUuid, newFileUuidsByOldUuid, record: recordUpdated }\n}\n\nconst removeExcludedNodes = (params: { survey: Survey; record: Record; sideEffect: boolean }): RecordUpdateResult => {\n const { survey, record, sideEffect } = params\n const cycle = record.cycle!\n const result = new RecordUpdateResult({ record })\n Surveys.visitDescendantsAndSelfNodeDef({\n survey,\n cycle,\n nodeDef: Surveys.getNodeDefRoot({ survey }),\n visitor: (nodeDef) => {\n const hasAncestorCodeDefExcludedInClone =\n nodeDef.type === NodeDefType.code &&\n Surveys.getNodeDefAncestorCodes({ survey, nodeDef: nodeDef as NodeDefCode }).some(NodeDefs.isExcludedInClone)\n\n if (\n !NodeDefs.isInCycle(cycle)(nodeDef) ||\n NodeDefs.isExcludedInClone(nodeDef) ||\n hasAncestorCodeDefExcludedInClone\n ) {\n const nodesToDelete = Records.getNodesByDefUuid(nodeDef.uuid)(result.record)\n if (nodesToDelete.length > 0) {\n const partialUpdateResult = Records.deleteNodes(\n nodesToDelete.map((node) => node.uuid),\n { sideEffect }\n )(result.record)\n result.merge(partialUpdateResult)\n }\n }\n },\n })\n return result\n}\n\nconst cloneRecord = (params: { survey: Survey; record: Record; cycleTo: string; sideEffect?: boolean }) => {\n const { survey, record, cycleTo, sideEffect = false } = params\n\n const recordUpdated = sideEffect ? record : { ...record }\n recordUpdated.cycle = cycleTo\n recordUpdated.dateCreated = recordUpdated.dateModified = Dates.nowFormattedForStorage()\n delete recordUpdated.id\n\n // delete nodes not included in clone\n const updateResult = new RecordUpdateResult({ record: recordUpdated })\n updateResult.merge(removeExcludedNodes({ survey, record: updateResult.record, sideEffect }))\n updateResult.merge(RecordFixer.insertMissingSingleNodes({ survey, record: updateResult.record, sideEffect }))\n\n // assign new UUIDs with side effect on record and nodes, faster when record is big\n const {\n newNodeUuidsByOldUuid,\n newFileUuidsByOldUuid,\n record: recordUpdatedUuids,\n } = assignNewUuids({ record: updateResult.record, sideEffect })\n\n updateResult.merge(new RecordUpdateResult({ record: recordUpdatedUuids }))\n\n return { record: updateResult.record, newNodeUuidsByOldUuid, newFileUuidsByOldUuid }\n}\n\nexport const RecordCloner = {\n cloneRecord,\n}\n"]}
1
+ {"version":3,"file":"recordCloner.js","sourceRoot":"","sources":["../../src/record/recordCloner.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArenaRecordNode, NodeValues, Nodes } from '../node'\nimport { NodeKeys, NodeMetaKeys } from '../node/node'\nimport { NodeDefCode, NodeDefType, NodeDefs } from '../nodeDef'\nimport { Survey, Surveys } from '../survey'\nimport { Dates, Objects, UUIDs } from '../utils'\nimport { Validation } from '../validation'\nimport { ArenaRecord } from './record'\nimport { RecordFixer } from './recordFixer'\nimport { RecordUpdateResult } from './recordNodesUpdater'\nimport { RecordValidations } from './recordValidations'\nimport { Records } from './records'\n\ntype OldUuidToNewUuidMap = {\n [key: string]: string\n}\n\nconst assignNewUuidsToNodes = (params: {\n record: ArenaRecord\n sideEffect: boolean\n}): { newNodeUuidsByOldUuid: OldUuidToNewUuidMap; newFileUuidsByOldUuid: OldUuidToNewUuidMap; record: ArenaRecord } => {\n const { record, sideEffect } = params\n\n // generate a new uuid for each node\n const newNodeUuidsByOldUuid: OldUuidToNewUuidMap = {}\n const newFileUuidsByOldUuid: OldUuidToNewUuidMap = {}\n\n // sort nodes before removing the id, to preserve their hierarchy (faster than comparing each meta.h property)\n const nodesArray = Records.getNodesArray(record).sort(\n (nodeA: ArenaRecordNode, nodeB: ArenaRecordNode): number =>\n Nodes.getHierarchy(nodeA).length - Nodes.getHierarchy(nodeB).length\n )\n\n const recordUpdated = sideEffect ? record : { ...record }\n\n const nodes = recordUpdated.nodes ?? {}\n const nodesUpdated = sideEffect ? nodes : { ...nodes }\n\n // update nodes recordUuid and properties (it does side effect on nodes)\n nodesArray.forEach((node) => {\n let nodeUpdated = sideEffect ? node : { ...node }\n nodeUpdated.recordUuid = record.uuid\n nodeUpdated.dateCreated = nodeUpdated.dateModified = Dates.nowFormattedForStorage()\n\n const oldUuid = node.uuid\n const newUuid = UUIDs.v4()\n newNodeUuidsByOldUuid[oldUuid] = newUuid\n\n nodeUpdated.uuid = newUuid\n // consider every node as just created node\n delete nodeUpdated.id\n nodeUpdated.created = true // this flag will be used by the RDB generator)\n\n // update internal node uuids, meta hierarchy, file uuid (if any)\n const parentUuid = node.parentUuid\n if (parentUuid) {\n nodeUpdated.parentUuid = newNodeUuidsByOldUuid[parentUuid]\n }\n const hierarchy = node.meta?.h ?? []\n if (hierarchy.length > 0) {\n const hierarchyUpdated = hierarchy.map((ancestorUuid) => newNodeUuidsByOldUuid[ancestorUuid])\n nodeUpdated = Objects.assocPath({\n obj: nodeUpdated,\n path: [NodeKeys.meta, NodeMetaKeys.h],\n value: hierarchyUpdated,\n sideEffect,\n })\n }\n // assign new file uuid (file should be cloned elsewhere)\n const fileUuid = NodeValues.getFileUuid(node)\n if (fileUuid) {\n const newFileUuid = UUIDs.v4()\n nodeUpdated = Objects.assocPath({\n obj: nodeUpdated,\n path: [NodeKeys.value, NodeValues.ValuePropsFile.fileUuid],\n value: newFileUuid,\n })\n newFileUuidsByOldUuid[fileUuid] = newFileUuid\n }\n\n delete nodesUpdated[oldUuid]\n nodesUpdated[newUuid] = nodeUpdated\n })\n\n recordUpdated.nodes = nodesUpdated\n\n return { newNodeUuidsByOldUuid, newFileUuidsByOldUuid, record: recordUpdated }\n}\n\nconst assignNewUuidsToValidation = (params: {\n validation: Validation\n newNodeUuidsByOldUuid: OldUuidToNewUuidMap\n sideEffect: boolean\n}): Validation => {\n const { validation, newNodeUuidsByOldUuid, sideEffect } = params\n\n const validationFields = validation?.fields\n if (!validationFields) return validation\n\n const validationFieldsUpdated = sideEffect ? validationFields : { ...validationFields }\n\n Object.entries(validationFields).forEach(([oldFieldKey, validationField]) => {\n let newFieldKey\n if (oldFieldKey.startsWith(RecordValidations.prefixValidationFieldChildrenCount)) {\n const oldParentUuid = oldFieldKey.substring(\n RecordValidations.prefixValidationFieldChildrenCount.length,\n oldFieldKey.lastIndexOf('_')\n )\n const newParentUuid = newNodeUuidsByOldUuid[oldParentUuid]\n newFieldKey = oldFieldKey.replace(oldParentUuid, newParentUuid)\n } else {\n newFieldKey = newNodeUuidsByOldUuid[oldFieldKey]\n }\n if (newFieldKey) {\n validationFieldsUpdated[newFieldKey] = validationField\n }\n delete validationFieldsUpdated[oldFieldKey]\n })\n return Objects.assoc({\n obj: validation,\n prop: 'fields',\n value: validationFieldsUpdated,\n sideEffect,\n })\n}\n\nconst assignNewUuids = (params: {\n record: ArenaRecord\n sideEffect: boolean\n}): { newNodeUuidsByOldUuid: OldUuidToNewUuidMap; newFileUuidsByOldUuid: OldUuidToNewUuidMap; record: ArenaRecord } => {\n const { record, sideEffect } = params\n let recordUpdated = sideEffect ? record : { ...record }\n recordUpdated.uuid = UUIDs.v4()\n\n const {\n newNodeUuidsByOldUuid,\n newFileUuidsByOldUuid,\n record: recordUpdatedUuids,\n } = assignNewUuidsToNodes({ record: recordUpdated, sideEffect })\n\n recordUpdated = recordUpdatedUuids\n\n const { validation } = recordUpdated\n if (validation) {\n const validationUpdated = assignNewUuidsToValidation({\n validation,\n newNodeUuidsByOldUuid,\n sideEffect,\n })\n recordUpdated = Objects.assoc({ obj: recordUpdated, prop: 'validation', value: validationUpdated, sideEffect })\n }\n // re-build nodes index\n const nodes = recordUpdated.nodes!\n delete recordUpdated._nodesIndex\n delete recordUpdated.nodes\n recordUpdated = Records.addNodes(nodes, { sideEffect, sortNodes: true })(recordUpdated)\n\n return { newNodeUuidsByOldUuid, newFileUuidsByOldUuid, record: recordUpdated }\n}\n\nconst removeExcludedNodes = (params: {\n survey: Survey\n record: ArenaRecord\n sideEffect: boolean\n}): RecordUpdateResult => {\n const { survey, record, sideEffect } = params\n const cycle = record.cycle!\n const result = new RecordUpdateResult({ record })\n Surveys.visitDescendantsAndSelfNodeDef({\n survey,\n cycle,\n nodeDef: Surveys.getNodeDefRoot({ survey }),\n visitor: (nodeDef) => {\n const hasAncestorCodeDefExcludedInClone =\n nodeDef.type === NodeDefType.code &&\n Surveys.getNodeDefAncestorCodes({ survey, nodeDef: nodeDef as NodeDefCode }).some(NodeDefs.isExcludedInClone)\n\n if (\n !NodeDefs.isInCycle(cycle)(nodeDef) ||\n NodeDefs.isExcludedInClone(nodeDef) ||\n hasAncestorCodeDefExcludedInClone\n ) {\n const nodesToDelete = Records.getNodesByDefUuid(nodeDef.uuid)(result.record)\n if (nodesToDelete.length > 0) {\n const partialUpdateResult = Records.deleteNodes(\n nodesToDelete.map((node) => node.uuid),\n { sideEffect }\n )(result.record)\n result.merge(partialUpdateResult)\n }\n }\n },\n })\n return result\n}\n\nconst cloneRecord = (params: { survey: Survey; record: ArenaRecord; cycleTo: string; sideEffect?: boolean }) => {\n const { survey, record, cycleTo, sideEffect = false } = params\n\n const recordUpdated = sideEffect ? record : { ...record }\n recordUpdated.cycle = cycleTo\n recordUpdated.dateCreated = recordUpdated.dateModified = Dates.nowFormattedForStorage()\n delete recordUpdated.id\n\n // delete nodes not included in clone\n const updateResult = new RecordUpdateResult({ record: recordUpdated })\n updateResult.merge(removeExcludedNodes({ survey, record: updateResult.record, sideEffect }))\n updateResult.merge(RecordFixer.insertMissingSingleNodes({ survey, record: updateResult.record, sideEffect }))\n\n // assign new UUIDs with side effect on record and nodes, faster when record is big\n const {\n newNodeUuidsByOldUuid,\n newFileUuidsByOldUuid,\n record: recordUpdatedUuids,\n } = assignNewUuids({ record: updateResult.record, sideEffect })\n\n updateResult.merge(new RecordUpdateResult({ record: recordUpdatedUuids }))\n\n return { record: updateResult.record, newNodeUuidsByOldUuid, newFileUuidsByOldUuid }\n}\n\nexport const RecordCloner = {\n cloneRecord,\n}\n"]}
@@ -1,17 +1,17 @@
1
1
  import { User } from '../../auth';
2
2
  import { ExpressionContext } from '../../expression';
3
- import { Node } from '../../node';
3
+ import { ArenaRecordNode } from '../../node';
4
4
  import { CategoryItemProvider } from '../../nodeDefExpressionEvaluator/categoryItemProvider';
5
5
  import { TaxonProvider } from '../../nodeDefExpressionEvaluator/taxonProvider';
6
6
  import { Survey } from '../../survey';
7
- import { Record } from '../record';
7
+ import { ArenaRecord } from '../record';
8
8
  export interface RecordExpressionContext extends ExpressionContext {
9
9
  user: User;
10
10
  survey: Survey;
11
- record: Record;
12
- prevCycleRecord?: Record;
13
- nodeContext: Node;
14
- nodeCurrent?: Node;
11
+ record: ArenaRecord;
12
+ prevCycleRecord?: ArenaRecord;
13
+ nodeContext: ArenaRecordNode;
14
+ nodeCurrent?: ArenaRecordNode;
15
15
  item?: any;
16
16
  categoryItemProvider?: CategoryItemProvider;
17
17
  taxonProvider?: TaxonProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/record/recordExpressionEvaluator/context.ts"],"names":[],"mappings":"","sourcesContent":["import { User } from '../../auth'\nimport { ExpressionContext } from '../../expression'\nimport { Node } from '../../node'\nimport { CategoryItemProvider } from '../../nodeDefExpressionEvaluator/categoryItemProvider'\nimport { TaxonProvider } from '../../nodeDefExpressionEvaluator/taxonProvider'\nimport { Survey } from '../../survey'\nimport { Record } from '../record'\n\nexport interface RecordExpressionContext extends ExpressionContext {\n user: User\n survey: Survey\n record: Record\n prevCycleRecord?: Record\n nodeContext: Node\n nodeCurrent?: Node\n item?: any\n categoryItemProvider?: CategoryItemProvider\n taxonProvider?: TaxonProvider\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/record/recordExpressionEvaluator/context.ts"],"names":[],"mappings":"","sourcesContent":["import { User } from '../../auth'\nimport { ExpressionContext } from '../../expression'\nimport { ArenaRecordNode } from '../../node'\nimport { CategoryItemProvider } from '../../nodeDefExpressionEvaluator/categoryItemProvider'\nimport { TaxonProvider } from '../../nodeDefExpressionEvaluator/taxonProvider'\nimport { Survey } from '../../survey'\nimport { ArenaRecord } from '../record'\n\nexport interface RecordExpressionContext extends ExpressionContext {\n user: User\n survey: Survey\n record: ArenaRecord\n prevCycleRecord?: ArenaRecord\n nodeContext: ArenaRecordNode\n nodeCurrent?: ArenaRecordNode\n item?: any\n categoryItemProvider?: CategoryItemProvider\n taxonProvider?: TaxonProvider\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../../../src/record/recordExpressionEvaluator/node/identifier/identifier.ts"],"names":[],"mappings":";;;AAAA,uDAAiF;AACjF,kFAAuF;AAEvF,iDAAoE;AACpE,8CAA0C;AAC1C,4DAAwD;AACxD,+CAAoD;AAEpD,+CAA2C;AAC3C,6CAA+C;AAC/C,iEAA6D;AAG7D,MAAM,gBAAgB,GAAG,CAAC,MAMzB,EAAS,EAAE;IACV,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAAA;IACvF,MAAM,MAAM,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAA;IAChD,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,oEAAoE;YACpE,wFAAwF;YACxF,OAAO,EAAE,CAAA;QACX,CAAC;QACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;YAC5B,MAAM,IAAI,mBAAW,CAAC,yCAAyC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC/F,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,KAAK,qBAAW,CAAC,MAAM,IAAI,cAAc,EAAE,CAAC;QACpE,eAAe;QACf,OAAO,eAAe,CAAA;IACxB,CAAC;IACD,qBAAqB;IACrB,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,EAAE,CAC5C,uCAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAC9F,CAAA;AACH,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG,CAAC,MAMjC,EAAE,EAAE;IACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAC/E,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,KAAK,EAAE,GAAG,UAAU,CAAA;IAC5D,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,mBAAW,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,MAAM,aAAa,GAAG,gBAAO,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAA;IAEnF,2BAA2B;IAC3B,MAAM,SAAS,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAG,QAAQ,CAAC,CAAA;IACnC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,kBAAQ,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;QACxC,kDAAkD;QAClD,IAAI,uBAAU,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YACvE,OAAO,uBAAU,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;QAClG,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,mBAAW,CAAC,8CAA8C,EAAE;gBACpE,aAAa,EAAE,kBAAQ,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC9C,QAAQ;aACT,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAG,gBAAO,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IAE/E,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,mBAAW,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,IAAI,UAAU,CAAC,WAAW,KAAK,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACtD,iDAAiD;QACjD,OAAO,UAAU,CAAA;IACnB,CAAC;IACD,IAAI,gBAAO,CAAC,iBAAiB,CAAC,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QACxG,OAAO,iBAAO,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAA;IACnG,CAAC;IACD,2DAA2D;IAC3D,MAAM,eAAe,GAAG,yBAAW,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC,CAAA;IACnH,MAAM,aAAa,GAAG,gBAAgB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAA;IAChH,OAAO,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;AAC5E,CAAC,CAAA;AAED,+BAAuC,SAAQ,gCAA4C;IACzF,QAAQ,CAAC,cAAoC;QAC3C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAA;IAC5D,CAAC;IAEO,aAAa,CAAC,cAAoC;;;QACxD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAA;QAEzC,IAAI,QAAQ,KAAK,+BAAkB,CAAC,OAAO,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAA;QACjC,CAAC;QAED,2DAA2D;QAC3D,6HAA6H;QAC7H,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,0BAA0B,CAAC,cAAc,CAAC,CAAA;YAChE,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,QAAQ,CAAC,KAAK,CAAA;YACvB,CAAC;QACH,CAAC;mBAAO,CAAC;YACP,YAAY;QACd,CAAC;QAED,yDAAyD;QACzD,uDAAuD;QACvD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAEpF,IAAI,IAAI,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YACnC,uDAAuD;YACvD,aAAO,MAAA,IAAI,CAAC,KAAK,0CAAG,QAAQ,CAAC,mCAAI,MAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAK,0CAAG,QAAQ,CAAC,CAAA;QAChE,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;gBAC3C,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;oBAChD,MAAM;oBACN,MAAM;oBACN,UAAU,EAAE,WAAW;oBACvB,cAAc;oBACd,QAAQ;iBACT,CAAC,CAAA;gBACF,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAA;YAChF,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,wBAAwB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC1G,CAAC;CACF","sourcesContent":["import { ExpressionVariable, IdentifierExpression } from '../../../../expression'\nimport { IdentifierEvaluator } from '../../../../expression/javascript/node/identifier'\nimport { Node } from '../../../../node'\nimport { NodeDef, NodeDefs, NodeDefType } from '../../../../nodeDef'\nimport { Records } from '../../../records'\nimport { NodeValues } from '../../../../node/nodeValues'\nimport { Survey, Surveys } from '../../../../survey'\nimport { RecordExpressionContext } from '../../context'\nimport { NodesFinder } from './nodesFinder'\nimport { SystemError } from '../../../../error'\nimport { NodeValueExtractor } from '../../nodeValueExtractor'\nimport { Record } from '../../../record'\n\nconst getNodesOrValues = (params: {\n survey: Survey\n referencedNodes: Node[]\n nodeDefReferenced: NodeDef<any>\n propName: string\n evaluateToNode?: boolean\n}): any[] => {\n const { survey, nodeDefReferenced, referencedNodes, propName, evaluateToNode } = params\n const single = !nodeDefReferenced.props.multiple\n if (single) {\n if (referencedNodes.length === 0) {\n // do not throw error if node is missing, consider its value as null\n // throw new SystemError('expression.nodeNotFoundForNodeDef', { nodeDefName: propName })\n return []\n }\n if (referencedNodes.length > 1)\n throw new SystemError('expression.multipleNodesFoundForNodeDef', { nodeDefName: propName })\n }\n if (nodeDefReferenced.type === NodeDefType.entity || evaluateToNode) {\n // return nodes\n return referencedNodes\n }\n // return node values\n return referencedNodes.map((referencedNode) =>\n NodeValueExtractor.getNodeValue({ survey, node: referencedNode, nodeDef: nodeDefReferenced })\n )\n}\n\nconst evaluateIdentifierOnNode = (params: {\n survey: Survey\n record: Record\n nodeObject: Node\n evaluateToNode?: boolean\n propName: string\n}) => {\n const { survey, record, nodeObject, evaluateToNode = false, propName } = params\n const { nodeDefUuid: nodeDefObjectUuid, value } = nodeObject\n if (!nodeDefObjectUuid) {\n throw new SystemError('expression.identifierNotFound', { name: propName })\n }\n\n const nodeDefObject = Surveys.getNodeDefByUuid({ survey, uuid: nodeDefObjectUuid })\n\n // node value prop (native)\n const valueProp = value?.[propName]\n if (valueProp !== undefined) {\n return valueProp\n }\n if (NodeDefs.isAttribute(nodeDefObject)) {\n // node value prop (Arena specific value property)\n if (NodeValues.isValueProp({ nodeDef: nodeDefObject, prop: propName })) {\n return NodeValues.getNodeValueProp({ nodeDef: nodeDefObject, node: nodeObject, prop: propName })\n } else {\n throw new SystemError('expression.invalidAttributeValuePropertyName', {\n attributeName: NodeDefs.getName(nodeDefObject),\n propName,\n })\n }\n }\n\n const nodeDefReferenced = Surveys.findNodeDefByName({ survey, name: propName })\n\n if (!nodeDefReferenced) {\n throw new SystemError('expression.identifierNotFound', { name: propName })\n }\n\n if (nodeObject.nodeDefUuid === nodeDefReferenced.uuid) {\n // the referenced node is the current node itself\n return nodeObject\n }\n if (Surveys.isNodeDefAncestor({ nodeDefAncestor: nodeDefReferenced, nodeDefDescendant: nodeDefObject })) {\n return Records.getAncestor({ record, node: nodeObject, ancestorDefUuid: nodeDefReferenced.uuid })\n }\n // the referenced nodes can be siblings of the current node\n const referencedNodes = NodesFinder.findDescendants({ survey, record, nodeContext: nodeObject, nodeDefReferenced })\n const nodesOrValues = getNodesOrValues({ survey, referencedNodes, nodeDefReferenced, propName, evaluateToNode })\n return nodeDefReferenced.props.multiple ? nodesOrValues : nodesOrValues[0]\n}\n\nexport class RecordIdentifierEvaluator extends IdentifierEvaluator<RecordExpressionContext> {\n evaluate(expressionNode: IdentifierExpression): Promise<any> {\n return Promise.resolve(this.evaluateValue(expressionNode))\n }\n\n private evaluateValue(expressionNode: IdentifierExpression): any {\n const { name: propName } = expressionNode\n\n if (propName === ExpressionVariable.CONTEXT) {\n return this.context.nodeContext\n }\n\n // try to find identifier among global or native properties\n // (not-found is signaled without throwing; the try/catch only handles the rare case of an unknown member of a global object)\n try {\n const property = this.findGlobalOrNativeProperty(expressionNode)\n if (property) {\n return property.value\n }\n } catch {\n // ignore it\n }\n\n // identifier not found among global or native properties\n // identifier should be a node or a node value property\n const { survey, record, evaluateToNode, object: contextObject, item } = this.context\n\n if (item && item === contextObject) {\n // evaluating category or taxon item prop or extra prop\n return item.props?.[propName] ?? item.props?.extra?.[propName]\n }\n\n if (Array.isArray(contextObject)) {\n return contextObject.flatMap((contextNode) => {\n const evaluationResult = evaluateIdentifierOnNode({\n survey,\n record,\n nodeObject: contextNode,\n evaluateToNode,\n propName,\n })\n return Array.isArray(evaluationResult) ? evaluationResult : [evaluationResult]\n })\n }\n return evaluateIdentifierOnNode({ survey, record, nodeObject: contextObject, evaluateToNode, propName })\n }\n}\n"]}
1
+ {"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../../../src/record/recordExpressionEvaluator/node/identifier/identifier.ts"],"names":[],"mappings":";;;AAAA,uDAAiF;AACjF,kFAAuF;AAEvF,iDAAoE;AACpE,8CAA0C;AAC1C,4DAAwD;AACxD,+CAAoD;AAEpD,+CAA2C;AAC3C,6CAA+C;AAC/C,iEAA6D;AAG7D,MAAM,gBAAgB,GAAG,CAAC,MAMzB,EAAS,EAAE;IACV,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAAA;IACvF,MAAM,MAAM,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAA;IAChD,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,oEAAoE;YACpE,wFAAwF;YACxF,OAAO,EAAE,CAAA;QACX,CAAC;QACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;YAC5B,MAAM,IAAI,mBAAW,CAAC,yCAAyC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC/F,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,KAAK,qBAAW,CAAC,MAAM,IAAI,cAAc,EAAE,CAAC;QACpE,eAAe;QACf,OAAO,eAAe,CAAA;IACxB,CAAC;IACD,qBAAqB;IACrB,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,EAAE,CAC5C,uCAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAC9F,CAAA;AACH,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG,CAAC,MAMjC,EAAE,EAAE;IACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAC/E,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,KAAK,EAAE,GAAG,UAAU,CAAA;IAC5D,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,mBAAW,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,MAAM,aAAa,GAAG,gBAAO,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAA;IAEnF,2BAA2B;IAC3B,MAAM,SAAS,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAG,QAAQ,CAAC,CAAA;IACnC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,kBAAQ,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;QACxC,kDAAkD;QAClD,IAAI,uBAAU,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YACvE,OAAO,uBAAU,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;QAClG,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,mBAAW,CAAC,8CAA8C,EAAE;gBACpE,aAAa,EAAE,kBAAQ,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC9C,QAAQ;aACT,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAG,gBAAO,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IAE/E,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,mBAAW,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,IAAI,UAAU,CAAC,WAAW,KAAK,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACtD,iDAAiD;QACjD,OAAO,UAAU,CAAA;IACnB,CAAC;IACD,IAAI,gBAAO,CAAC,iBAAiB,CAAC,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QACxG,OAAO,iBAAO,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAA;IACnG,CAAC;IACD,2DAA2D;IAC3D,MAAM,eAAe,GAAG,yBAAW,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC,CAAA;IACnH,MAAM,aAAa,GAAG,gBAAgB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAA;IAChH,OAAO,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;AAC5E,CAAC,CAAA;AAED,+BAAuC,SAAQ,gCAA4C;IACzF,QAAQ,CAAC,cAAoC;QAC3C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAA;IAC5D,CAAC;IAEO,aAAa,CAAC,cAAoC;;;QACxD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAA;QAEzC,IAAI,QAAQ,KAAK,+BAAkB,CAAC,OAAO,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAA;QACjC,CAAC;QAED,2DAA2D;QAC3D,6HAA6H;QAC7H,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,0BAA0B,CAAC,cAAc,CAAC,CAAA;YAChE,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,QAAQ,CAAC,KAAK,CAAA;YACvB,CAAC;QACH,CAAC;mBAAO,CAAC;YACP,YAAY;QACd,CAAC;QAED,yDAAyD;QACzD,uDAAuD;QACvD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAEpF,IAAI,IAAI,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YACnC,uDAAuD;YACvD,aAAO,MAAA,IAAI,CAAC,KAAK,0CAAG,QAAQ,CAAC,mCAAI,MAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAK,0CAAG,QAAQ,CAAC,CAAA;QAChE,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;gBAC3C,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;oBAChD,MAAM;oBACN,MAAM;oBACN,UAAU,EAAE,WAAW;oBACvB,cAAc;oBACd,QAAQ;iBACT,CAAC,CAAA;gBACF,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAA;YAChF,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,wBAAwB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC1G,CAAC;CACF","sourcesContent":["import { ExpressionVariable, IdentifierExpression } from '../../../../expression'\nimport { IdentifierEvaluator } from '../../../../expression/javascript/node/identifier'\nimport { ArenaRecordNode } from '../../../../node'\nimport { NodeDef, NodeDefs, NodeDefType } from '../../../../nodeDef'\nimport { Records } from '../../../records'\nimport { NodeValues } from '../../../../node/nodeValues'\nimport { Survey, Surveys } from '../../../../survey'\nimport { RecordExpressionContext } from '../../context'\nimport { NodesFinder } from './nodesFinder'\nimport { SystemError } from '../../../../error'\nimport { NodeValueExtractor } from '../../nodeValueExtractor'\nimport { ArenaRecord } from '../../../record'\n\nconst getNodesOrValues = (params: {\n survey: Survey\n referencedNodes: ArenaRecordNode[]\n nodeDefReferenced: NodeDef<any>\n propName: string\n evaluateToNode?: boolean\n}): any[] => {\n const { survey, nodeDefReferenced, referencedNodes, propName, evaluateToNode } = params\n const single = !nodeDefReferenced.props.multiple\n if (single) {\n if (referencedNodes.length === 0) {\n // do not throw error if node is missing, consider its value as null\n // throw new SystemError('expression.nodeNotFoundForNodeDef', { nodeDefName: propName })\n return []\n }\n if (referencedNodes.length > 1)\n throw new SystemError('expression.multipleNodesFoundForNodeDef', { nodeDefName: propName })\n }\n if (nodeDefReferenced.type === NodeDefType.entity || evaluateToNode) {\n // return nodes\n return referencedNodes\n }\n // return node values\n return referencedNodes.map((referencedNode) =>\n NodeValueExtractor.getNodeValue({ survey, node: referencedNode, nodeDef: nodeDefReferenced })\n )\n}\n\nconst evaluateIdentifierOnNode = (params: {\n survey: Survey\n record: ArenaRecord\n nodeObject: ArenaRecordNode\n evaluateToNode?: boolean\n propName: string\n}) => {\n const { survey, record, nodeObject, evaluateToNode = false, propName } = params\n const { nodeDefUuid: nodeDefObjectUuid, value } = nodeObject\n if (!nodeDefObjectUuid) {\n throw new SystemError('expression.identifierNotFound', { name: propName })\n }\n\n const nodeDefObject = Surveys.getNodeDefByUuid({ survey, uuid: nodeDefObjectUuid })\n\n // node value prop (native)\n const valueProp = value?.[propName]\n if (valueProp !== undefined) {\n return valueProp\n }\n if (NodeDefs.isAttribute(nodeDefObject)) {\n // node value prop (Arena specific value property)\n if (NodeValues.isValueProp({ nodeDef: nodeDefObject, prop: propName })) {\n return NodeValues.getNodeValueProp({ nodeDef: nodeDefObject, node: nodeObject, prop: propName })\n } else {\n throw new SystemError('expression.invalidAttributeValuePropertyName', {\n attributeName: NodeDefs.getName(nodeDefObject),\n propName,\n })\n }\n }\n\n const nodeDefReferenced = Surveys.findNodeDefByName({ survey, name: propName })\n\n if (!nodeDefReferenced) {\n throw new SystemError('expression.identifierNotFound', { name: propName })\n }\n\n if (nodeObject.nodeDefUuid === nodeDefReferenced.uuid) {\n // the referenced node is the current node itself\n return nodeObject\n }\n if (Surveys.isNodeDefAncestor({ nodeDefAncestor: nodeDefReferenced, nodeDefDescendant: nodeDefObject })) {\n return Records.getAncestor({ record, node: nodeObject, ancestorDefUuid: nodeDefReferenced.uuid })\n }\n // the referenced nodes can be siblings of the current node\n const referencedNodes = NodesFinder.findDescendants({ survey, record, nodeContext: nodeObject, nodeDefReferenced })\n const nodesOrValues = getNodesOrValues({ survey, referencedNodes, nodeDefReferenced, propName, evaluateToNode })\n return nodeDefReferenced.props.multiple ? nodesOrValues : nodesOrValues[0]\n}\n\nexport class RecordIdentifierEvaluator extends IdentifierEvaluator<RecordExpressionContext> {\n evaluate(expressionNode: IdentifierExpression): Promise<any> {\n return Promise.resolve(this.evaluateValue(expressionNode))\n }\n\n private evaluateValue(expressionNode: IdentifierExpression): any {\n const { name: propName } = expressionNode\n\n if (propName === ExpressionVariable.CONTEXT) {\n return this.context.nodeContext\n }\n\n // try to find identifier among global or native properties\n // (not-found is signaled without throwing; the try/catch only handles the rare case of an unknown member of a global object)\n try {\n const property = this.findGlobalOrNativeProperty(expressionNode)\n if (property) {\n return property.value\n }\n } catch {\n // ignore it\n }\n\n // identifier not found among global or native properties\n // identifier should be a node or a node value property\n const { survey, record, evaluateToNode, object: contextObject, item } = this.context\n\n if (item && item === contextObject) {\n // evaluating category or taxon item prop or extra prop\n return item.props?.[propName] ?? item.props?.extra?.[propName]\n }\n\n if (Array.isArray(contextObject)) {\n return contextObject.flatMap((contextNode) => {\n const evaluationResult = evaluateIdentifierOnNode({\n survey,\n record,\n nodeObject: contextNode,\n evaluateToNode,\n propName,\n })\n return Array.isArray(evaluationResult) ? evaluationResult : [evaluationResult]\n })\n }\n return evaluateIdentifierOnNode({ survey, record, nodeObject: contextObject, evaluateToNode, propName })\n }\n}\n"]}