-
Notifications
You must be signed in to change notification settings - Fork 8
/
mandatoryTest_6_1_5.js
101 lines (91 loc) · 2.65 KB
/
mandatoryTest_6_1_5.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/**
* @typedef {Object} FullProductName
* @property {string} name
* @property {string} product_id
*/
/**
* @typedef {Object} Branch
* @property {Array<Branch>} branches
* @property {FullProductName} product
*/
/**
* @param {any} doc
*/
export default function mandatoryTest_6_1_5(doc) {
/** @type {Array<{ message: string; instancePath: string }>} */
const errors = []
let isValid = true
const groupIds = collectGroupIds({ document: doc })
const duplicateGroupIds = findDuplicateEntries(groupIds)
if (duplicateGroupIds.length > 0) {
isValid = false
duplicateGroupIds.forEach((duplicateEntry) => {
errors.push({
message: 'duplicate definition product group id',
instancePath: duplicateEntry.instancePath,
})
})
}
return { isValid, errors }
}
/**
* This method collects group ids and corresponding instancePaths in the given document and returns a result object.
*
* @param {any} document
* @returns {{id: string, name: string, instancePath: string}[]}
*/
function collectGroupIds({ document }) {
const entries =
/** @type {{id: string, name: string, instancePath: string}[]} */ ([])
const productGroups = document.product_tree?.product_groups
if (productGroups) {
for (let i = 0; i < productGroups.length; ++i) {
const productGroup = productGroups[i]
if (productGroup.group_id) {
entries.push({
id: productGroup.group_id,
name: productGroup.summary ?? '',
instancePath: `/product_tree/product_groups/${i}/group_id`,
})
}
}
}
return entries
}
/**
* @param {{id: string, name: string, instancePath: string}[]} entries
*/
const findDuplicateEntries = (entries) => {
const lookup = entries.reduce((/** @type {any} */ a, entry) => {
a[entry.id] = ++a[entry.id] || 0
return a
}, {})
return entries.filter((entry) => lookup[entry.id])
}
/**
* @param {Array<Branch>} branches
* @param {{id: string, name: string, instancePath: string}[]} entries
* @param {string} instancePath
*/
const traverseBranches = (branches, entries, instancePath) => {
for (let i = 0; i < branches.length; ++i) {
const branch = branches[i]
const branchInstancePath = `${instancePath}/${i}`
const fullProductName = branch.product
if (fullProductName) {
if (fullProductName.product_id) {
entries.push({
id: fullProductName.product_id,
name: fullProductName.name ?? '',
instancePath: `${branchInstancePath}/product/product_id`,
})
}
}
if (branch.branches)
traverseBranches(
branch.branches,
entries,
`${branchInstancePath}/branches`
)
}
}