127 lines
3.1 KiB
JavaScript
127 lines
3.1 KiB
JavaScript
import { orderBy } from "lodash"
|
|
import {
|
|
reduce,
|
|
find,
|
|
includes,
|
|
flatten,
|
|
union,
|
|
filter,
|
|
each,
|
|
map,
|
|
} from "lodash/fp"
|
|
import {
|
|
joinKey,
|
|
splitKey,
|
|
isNonEmptyString,
|
|
isNothing,
|
|
$,
|
|
isSomething,
|
|
} from "../common"
|
|
import {
|
|
getFlattenedHierarchy,
|
|
getNode,
|
|
getRecordNodeId,
|
|
getExactNodeForKey,
|
|
recordNodeIdIsAllowed,
|
|
isModel,
|
|
isGlobalIndex,
|
|
} from "../templateApi/hierarchy"
|
|
import { indexTypes } from "../templateApi/indexes"
|
|
import { getIndexDir } from "../indexApi/getIndexDir"
|
|
import { getRecordInfo } from "../recordApi/recordInfo"
|
|
|
|
export const getRelevantAncestorIndexes = (hierarchy, record) => {
|
|
const key = record.key
|
|
const keyParts = splitKey(key)
|
|
const nodeId = getRecordNodeId(key)
|
|
|
|
const flatHierarchy = orderBy(
|
|
getFlattenedHierarchy(hierarchy),
|
|
[node => node.pathRegx().length],
|
|
["desc"]
|
|
)
|
|
|
|
const makeindexNodeAndDir_ForAncestorIndex = (indexNode, parentRecordDir) =>
|
|
makeIndexNodeAndDir(indexNode, joinKey(parentRecordDir, indexNode.name))
|
|
|
|
const traverseAncestorIndexesInPath = () =>
|
|
reduce(
|
|
(acc, part) => {
|
|
const currentIndexKey = joinKey(acc.lastIndexKey, part)
|
|
acc.lastIndexKey = currentIndexKey
|
|
const testPathRegx = p =>
|
|
new RegExp(`${p.pathRegx()}$`).test(currentIndexKey)
|
|
const nodeMatch = find(testPathRegx)(flatHierarchy)
|
|
|
|
if (isNothing(nodeMatch)) {
|
|
return acc
|
|
}
|
|
|
|
if (!isModel(nodeMatch) || nodeMatch.indexes.length === 0) {
|
|
return acc
|
|
}
|
|
|
|
const indexes = $(nodeMatch.indexes, [
|
|
filter(
|
|
i =>
|
|
i.indexType === indexTypes.ancestor &&
|
|
(i.allowedModelNodeIds.length === 0 ||
|
|
includes(nodeId)(i.allowedModelNodeIds))
|
|
),
|
|
])
|
|
|
|
const currentRecordDir = getRecordInfo(hierarchy, currentIndexKey).dir
|
|
|
|
each(v =>
|
|
acc.nodesAndKeys.push(
|
|
makeindexNodeAndDir_ForAncestorIndex(v, currentRecordDir)
|
|
)
|
|
)(indexes)
|
|
|
|
return acc
|
|
},
|
|
{ lastIndexKey: "", nodesAndKeys: [] }
|
|
)(keyParts).nodesAndKeys
|
|
|
|
const rootIndexes = $(flatHierarchy, [
|
|
filter(n => isGlobalIndex(n) && recordNodeIdIsAllowed(n)(nodeId)),
|
|
map(i => makeIndexNodeAndDir(i, getIndexDir(hierarchy, i.nodeKey()))),
|
|
])
|
|
|
|
return union(traverseAncestorIndexesInPath())(rootIndexes)
|
|
}
|
|
|
|
export const getRelevantReverseReferenceIndexes = (hierarchy, record) =>
|
|
$(record.key, [
|
|
getExactNodeForKey(hierarchy),
|
|
n => n.fields,
|
|
filter(
|
|
f =>
|
|
f.type === "reference" &&
|
|
isSomething(record[f.name]) &&
|
|
isNonEmptyString(record[f.name].key)
|
|
),
|
|
map(f =>
|
|
$(f.typeOptions.reverseIndexNodeKeys, [
|
|
map(n => ({
|
|
recordNode: getNode(hierarchy, n),
|
|
field: f,
|
|
})),
|
|
])
|
|
),
|
|
flatten,
|
|
map(n =>
|
|
makeIndexNodeAndDir(
|
|
n.recordNode,
|
|
joinKey(
|
|
getRecordInfo(hierarchy, record[n.field.name].key).dir,
|
|
n.recordNode.name
|
|
)
|
|
)
|
|
),
|
|
])
|
|
|
|
const makeIndexNodeAndDir = (indexNode, indexDir) => ({ indexNode, indexDir })
|
|
|
|
export default getRelevantAncestorIndexes
|