|
1
|
|
|
import { Tags, RawTags, WriteTags } from "./types/Tags" |
|
2
|
|
|
import { FrameOptions } from "./definitions/FrameOptions" |
|
3
|
|
|
import { convertWriteTagsToRawTags } from "./TagsConverters" |
|
4
|
|
|
import * as ID3Util from "./ID3Util" |
|
5
|
|
|
|
|
6
|
|
|
|
|
7
|
|
|
export function updateTags(newTags: WriteTags, currentTags: Tags): RawTags { |
|
8
|
|
|
const newRawTags = convertWriteTagsToRawTags(newTags) |
|
9
|
|
|
|
|
10
|
|
|
const currentRawTags = currentTags.raw ?? {} |
|
11
|
|
|
Object.keys(newRawTags).map(frameIdentifierString => { |
|
12
|
|
|
const frameIdentifier = frameIdentifierString as keyof RawTags |
|
13
|
|
|
const newFrame = newRawTags[frameIdentifier] |
|
14
|
|
|
const updatedFrame = updateFrameIfMultiple( |
|
15
|
|
|
ID3Util.getSpecOptions(frameIdentifier), |
|
16
|
|
|
newFrame, |
|
17
|
|
|
currentRawTags[frameIdentifier] |
|
18
|
|
|
) |
|
19
|
|
|
// eslint-disable-next-line |
|
20
|
|
|
currentRawTags[frameIdentifier] = (updatedFrame || newFrame) as any |
|
21
|
|
|
}) |
|
22
|
|
|
return currentRawTags |
|
23
|
|
|
} |
|
24
|
|
|
|
|
25
|
|
|
function updateFrameIfMultiple( |
|
26
|
|
|
options: FrameOptions, |
|
27
|
|
|
newTag: RawTags[keyof RawTags], |
|
28
|
|
|
currentTag: RawTags[keyof RawTags], |
|
29
|
|
|
) { |
|
30
|
|
|
if ( |
|
31
|
|
|
!options.multiple || |
|
32
|
|
|
!newTag || |
|
33
|
|
|
!currentTag || |
|
34
|
|
|
!Array.isArray(currentTag) |
|
35
|
|
|
) { |
|
36
|
|
|
return null |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
const newTagArray = newTag instanceof Array ? newTag : [newTag] |
|
40
|
|
|
const compareKey = options.updateCompareKey |
|
41
|
|
|
if (!compareKey) { |
|
42
|
|
|
return [...currentTag, ...newTagArray] |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
const compareValueToFrameIndex: Record<string, number> = {} |
|
46
|
|
|
currentTag.forEach((tag, index) => { |
|
47
|
|
|
if (typeof tag === "object") { |
|
48
|
|
|
const compareValue = tag[compareKey as keyof typeof tag] |
|
49
|
|
|
compareValueToFrameIndex[compareValue] = index |
|
50
|
|
|
} |
|
51
|
|
|
}) |
|
52
|
|
|
|
|
53
|
|
|
newTagArray.forEach((tagValue) => { |
|
54
|
|
|
// eslint-disable-next-line |
|
55
|
|
|
const assignableTagValue = tagValue as any |
|
56
|
|
|
if ( |
|
57
|
|
|
typeof tagValue === "object" && |
|
58
|
|
|
tagValue[compareKey as keyof typeof tagValue] in compareValueToFrameIndex |
|
59
|
|
|
) { |
|
60
|
|
|
const tagProperty = tagValue[compareKey as keyof typeof tagValue] |
|
61
|
|
|
const frameIndex = compareValueToFrameIndex[tagProperty] |
|
62
|
|
|
currentTag[frameIndex] = assignableTagValue |
|
63
|
|
|
} else { |
|
64
|
|
|
currentTag.push(assignableTagValue) |
|
65
|
|
|
} |
|
66
|
|
|
}) |
|
67
|
|
|
return currentTag |
|
68
|
|
|
} |
|
69
|
|
|
|