Passed
Pull Request — master (#136)
by
unknown
02:10
created

src/update.ts   A

Complexity

Total Complexity 12
Complexity/F 4

Size

Lines of Code 86
Function Count 3

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 70
mnd 9
bc 9
fnc 3
dl 0
loc 86
rs 10
bpm 3
cpm 4
noi 0
c 0
b 0
f 0

3 Functions

Rating   Name   Duplication   Size   Complexity  
B update.ts ➔ updateFrameIfMultiple 0 44 6
A update.ts ➔ updateTags 0 18 3
A update.ts ➔ makeRawTags 0 13 3
1
import { Tags, TagAliases, RawTags, WriteTags  } from "./Tags"
2
import {
3
    FrameOptions,
4
    FRAME_IDENTIFIERS,
5
    FRAME_ALIASES
6
} from "./ID3Definitions"
7
import * as ID3Util from "./ID3Util"
8
9
10
export function updateTags(newTags: WriteTags, currentTags: Tags): RawTags {
11
    const newRawTags = makeRawTags(newTags)
12
13
    const currentRawTags = currentTags.raw ?? {}
14
    Object.keys(newRawTags).map(frameIdentifierString => {
15
        const frameIdentifier = frameIdentifierString as keyof RawTags
16
        const newFrame = newRawTags[frameIdentifier]
17
        const updatedFrame = updateFrameIfMultiple(
18
            ID3Util.getSpecOptions(frameIdentifier),
19
            newFrame,
20
            currentRawTags[frameIdentifier]
21
        )
22
        // eslint-disable-next-line
23
        currentRawTags[frameIdentifier] = (updatedFrame || newFrame) as any
24
    })
25
    return currentRawTags
26
}
27
28
function updateFrameIfMultiple(
29
    options: FrameOptions,
30
    newTag: RawTags[keyof RawTags],
31
    currentTag: RawTags[keyof RawTags],
32
) {
33
    if (
34
        !options.multiple ||
35
        !newTag ||
36
        !currentTag ||
37
        !Array.isArray(currentTag)
38
    ) {
39
        return null
40
    }
41
42
    const newTagArray = newTag instanceof Array ? newTag : [newTag]
43
    const compareKey = options.updateCompareKey
44
    if (!compareKey) {
45
        return [...currentTag, ...newTagArray]
46
    }
47
48
    const compareValueToFrameIndex: Record<string, number> = {}
49
    currentTag.forEach((tag, index) => {
50
        if (typeof tag === "object") {
51
              const compareValue = tag[compareKey as keyof typeof tag]
52
            compareValueToFrameIndex[compareValue] = index
53
        }
54
    })
55
56
    newTagArray.forEach((tagValue) => {
57
        // eslint-disable-next-line
58
        const assignableTagValue = tagValue as any
59
        if (
60
            typeof tagValue === "object" &&
61
            tagValue[compareKey as keyof typeof tagValue] in compareValueToFrameIndex
62
        ) {
63
            const tagProperty = tagValue[compareKey as keyof typeof tagValue]
64
            const frameIndex = compareValueToFrameIndex[tagProperty]
65
            currentTag[frameIndex] = assignableTagValue
66
        } else {
67
            currentTag.push(assignableTagValue)
68
        }
69
    })
70
    return currentTag
71
}
72
73
function makeRawTags(tags: WriteTags): RawTags {
74
    return Object.entries(tags).reduce<RawTags>((rawTags, [key, value]) => {
75
        const identifiers = FRAME_IDENTIFIERS.v34
76
        const aliases = FRAME_ALIASES.v34
77
        if (key in identifiers) {
78
            rawTags[identifiers[key as keyof TagAliases]] = value
79
        }
80
        if (key in aliases) {
81
            rawTags[key as keyof RawTags] = value
82
        }
83
        return rawTags
84
    }, {})
85
}
86