-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathdeleteInWithCleanUp.js
More file actions
54 lines (44 loc) · 1.57 KB
/
deleteInWithCleanUp.js
File metadata and controls
54 lines (44 loc) · 1.57 KB
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
// @flow
import { toPath } from 'lodash'
import type { Structure } from './types'
type ShouldDelete<SDM, SDL> = (
structure: Structure<SDM, SDL>
) => (state: SDM | SDL, path: string) => boolean
type DeleteInWithCleanup<DIM, DIL> = (DIM | DIL, string) => DIM | DIL
function createDeleteInWithCleanUp<DIM, DIL>(structure: Structure<DIM, DIL>) {
const shouldDeleteDefault: ShouldDelete<DIM, DIL> = structure => (
state,
path
) => structure.getIn(state, path) !== undefined
const { deepEqual, empty, getIn, deleteIn, setIn } = structure
return (
shouldDelete: ShouldDelete<DIM, DIL> = shouldDeleteDefault
): DeleteInWithCleanup<DIM, DIL> => {
const deleteInWithCleanUp = (state: DIM | DIL, path: string): DIM | DIL => {
if (path[path.length - 1] === ']') {
// array path
const pathTokens = toPath(path)
pathTokens.pop()
const parent = getIn(state, pathTokens.join('.'))
return parent ? setIn(state, path) : state
}
let result: DIM | DIL = state
if (shouldDelete(structure)(state, path)) {
result = deleteIn(state, path)
}
const dotIndex = path.lastIndexOf('.')
if (dotIndex > 0) {
const parentPath = path.substring(0, dotIndex)
if (parentPath[parentPath.length - 1] !== ']') {
const parent = getIn(result, parentPath)
if (deepEqual(parent, empty)) {
return deleteInWithCleanUp(result, parentPath)
}
}
}
return result
}
return deleteInWithCleanUp
}
}
export default createDeleteInWithCleanUp