taglib-wasm 1.5.3 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +12 -9
- package/README.md +6 -3
- package/dist/index.browser.js +402 -90
- package/dist/simple.browser.js +400 -89
- package/dist/src/constants/complex-properties.d.ts +18 -12
- package/dist/src/constants/complex-properties.d.ts.map +1 -1
- package/dist/src/constants/properties.d.ts +24 -0
- package/dist/src/constants/properties.d.ts.map +1 -1
- package/dist/src/constants/properties.js +34 -0
- package/dist/src/constants/specialized-properties.d.ts +23 -0
- package/dist/src/constants/specialized-properties.d.ts.map +1 -1
- package/dist/src/constants/specialized-properties.js +20 -0
- package/dist/src/constants/tags.d.ts.map +1 -1
- package/dist/src/constants/tags.js +2 -1
- package/dist/src/msgpack/encoder.d.ts.map +1 -1
- package/dist/src/msgpack/encoder.js +6 -4
- package/dist/src/runtime/detector.d.ts +0 -6
- package/dist/src/runtime/detector.d.ts.map +1 -1
- package/dist/src/runtime/detector.js +1 -14
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts +2 -0
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/file-handle.js +73 -52
- package/dist/src/taglib/audio-file-base.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-base.js +33 -77
- package/dist/src/taglib/load-audio-data.d.ts.map +1 -1
- package/dist/src/taglib/load-audio-data.js +19 -5
- package/dist/src/taglib/metadata-extent.d.ts +41 -0
- package/dist/src/taglib/metadata-extent.d.ts.map +1 -0
- package/dist/src/taglib/metadata-extent.js +128 -0
- package/dist/src/taglib/mp4-item-names.d.ts +12 -0
- package/dist/src/taglib/mp4-item-names.d.ts.map +1 -0
- package/dist/src/taglib/mp4-item-names.js +4 -0
- package/dist/src/taglib/mutable-tag-impl.d.ts +14 -0
- package/dist/src/taglib/mutable-tag-impl.d.ts.map +1 -0
- package/dist/src/taglib/mutable-tag-impl.js +88 -0
- package/dist/src/taglib/save-reconstruct.d.ts.map +1 -1
- package/dist/src/taglib/save-reconstruct.js +4 -0
- package/dist/src/types/metadata-mappings.d.ts.map +1 -1
- package/dist/src/types/metadata-mappings.js +14 -0
- package/dist/src/types/tags.d.ts +16 -0
- package/dist/src/types/tags.d.ts.map +1 -1
- package/dist/src/utils/mirror-fields.d.ts +79 -0
- package/dist/src/utils/mirror-fields.d.ts.map +1 -0
- package/dist/src/utils/mirror-fields.js +67 -0
- package/dist/src/utils/tag-mapping.d.ts.map +1 -1
- package/dist/src/utils/tag-mapping.js +47 -5
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/taglib-wasi.wasm +0 -0
- package/dist/taglib-web.wasm +0 -0
- package/dist/taglib-wrapper.js +1 -1
- package/package.json +3 -3
|
@@ -3,18 +3,22 @@
|
|
|
3
3
|
* These are properties that contain multiple fields and cannot be
|
|
4
4
|
* represented as simple string values.
|
|
5
5
|
*
|
|
6
|
+
* These constants describe the shape of each complex property. Values are read
|
|
7
|
+
* and written through dedicated typed accessors, not a generic property call.
|
|
8
|
+
*
|
|
6
9
|
* @example
|
|
7
10
|
* ```typescript
|
|
8
|
-
* import {
|
|
11
|
+
* import type { Rating } from 'taglib-wasm';
|
|
9
12
|
*
|
|
10
|
-
* //
|
|
11
|
-
* const ratings = file.
|
|
13
|
+
* // Read via the typed accessor
|
|
14
|
+
* const ratings = file.getRatings();
|
|
12
15
|
* console.log(ratings[0].rating); // 0.0-1.0 normalized
|
|
13
16
|
*
|
|
14
17
|
* // Set a rating
|
|
15
|
-
* file.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
+
* file.setRating(0.8, "user@example.com");
|
|
19
|
+
*
|
|
20
|
+
* // Or replace the full list
|
|
21
|
+
* file.setRatings([{ rating: 0.8, email: "user@example.com" }]);
|
|
18
22
|
* ```
|
|
19
23
|
*/
|
|
20
24
|
import type { Picture } from "../types.js";
|
|
@@ -74,13 +78,15 @@ export interface UnsyncedLyrics {
|
|
|
74
78
|
export type VariantMap = Record<string, unknown>;
|
|
75
79
|
/**
|
|
76
80
|
* Type map linking complex property keys to their value types.
|
|
77
|
-
*
|
|
81
|
+
*
|
|
82
|
+
* This is a descriptive type map, not the accessor surface — each complex
|
|
83
|
+
* property is reached through its own typed method:
|
|
78
84
|
*
|
|
79
85
|
* @example
|
|
80
86
|
* ```typescript
|
|
81
|
-
*
|
|
82
|
-
* const
|
|
83
|
-
* const
|
|
87
|
+
* const ratings = file.getRatings(); // Rating[]
|
|
88
|
+
* const pictures = file.getPictures(); // Picture[]
|
|
89
|
+
* const chapters = file.getChapters(); // Chapter[]
|
|
84
90
|
* ```
|
|
85
91
|
*
|
|
86
92
|
* Consumers can extend via module augmentation:
|
|
@@ -177,8 +183,8 @@ export type ComplexPropertyKeyMap = {
|
|
|
177
183
|
*
|
|
178
184
|
* @example
|
|
179
185
|
* ```typescript
|
|
180
|
-
* // Instead of:
|
|
181
|
-
*
|
|
186
|
+
* // Instead of: COMPLEX_PROPERTIES.RATING.key
|
|
187
|
+
* COMPLEX_PROPERTY_KEY.RATING; // "RATING"
|
|
182
188
|
* ```
|
|
183
189
|
*/
|
|
184
190
|
export declare const COMPLEX_PROPERTY_KEY: ComplexPropertyKeyMap;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complex-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/complex-properties.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"complex-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/complex-properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,WAAW,MAAM;IACrB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,IAAI,EAAE,UAAU,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,uBAAuB;IACtC,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,uBAAuB,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CrB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,CAAC,IAAI,kBAAkB,GAAG,CAAC;CACtC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,EAAE,qBAKzB,CAAC"}
|
|
@@ -395,6 +395,20 @@ export declare const PROPERTIES: {
|
|
|
395
395
|
readonly mp4: "----:com.apple.iTunes:iTunNORM";
|
|
396
396
|
};
|
|
397
397
|
};
|
|
398
|
+
readonly appleGaplessInfo: {
|
|
399
|
+
readonly key: "ITUNSMPB";
|
|
400
|
+
readonly description: "Apple gapless playback data (encoder delay and padding)";
|
|
401
|
+
readonly type: "string";
|
|
402
|
+
readonly supportedFormats: readonly ["ID3v2", "MP4", "Vorbis"];
|
|
403
|
+
readonly mappings: {
|
|
404
|
+
readonly id3v2: {
|
|
405
|
+
readonly frame: "TXXX";
|
|
406
|
+
readonly description: "iTunSMPB";
|
|
407
|
+
};
|
|
408
|
+
readonly vorbis: "ITUNSMPB";
|
|
409
|
+
readonly mp4: "----:com.apple.iTunes:iTunSMPB";
|
|
410
|
+
};
|
|
411
|
+
};
|
|
398
412
|
readonly albumArtist: {
|
|
399
413
|
readonly key: "ALBUMARTIST";
|
|
400
414
|
readonly description: "The album artist (band/orchestra/ensemble)";
|
|
@@ -775,6 +789,16 @@ export type PropertyKey = keyof typeof PROPERTIES;
|
|
|
775
789
|
export type PropertyValue<K extends PropertyKey> = typeof PROPERTIES[K]["type"] extends "string" ? string : typeof PROPERTIES[K]["type"] extends "number" ? number : typeof PROPERTIES[K]["type"] extends "boolean" ? boolean : string;
|
|
776
790
|
/** Translate a camelCase property key to TagLib's ALL_CAPS wire key. Unknown keys pass through. */
|
|
777
791
|
export declare function toTagLibKey(key: string): string;
|
|
792
|
+
/**
|
|
793
|
+
* TagLib wire key for a standard MP4 atom name, or `undefined` for a freeform
|
|
794
|
+
* atom or one we do not model.
|
|
795
|
+
*/
|
|
796
|
+
export declare function mp4AtomWireKey(atom: string): string | undefined;
|
|
797
|
+
/**
|
|
798
|
+
* Exact MP4 atom names for the given TagLib wire keys, for keys backed by a
|
|
799
|
+
* mixed-case freeform atom. Empty when none apply, which is the common case.
|
|
800
|
+
*/
|
|
801
|
+
export declare function mp4FreeformAtomNames(wireKeys: Iterable<string>): string[];
|
|
778
802
|
/** Translate a TagLib ALL_CAPS wire key to a camelCase property key. Unknown keys pass through. */
|
|
779
803
|
export declare function fromTagLibKey(key: string): string;
|
|
780
804
|
/** Remap all keys of an object from TagLib ALL_CAPS to camelCase. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../../src/constants/properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../../src/constants/properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKb,CAAC;AAEX;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,UAAU,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,WAAW,IAC7C,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,QAAQ,GAAG,MAAM,GAClD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,QAAQ,GAAG,MAAM,GACtD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,SAAS,GAAG,OAAO,GACxD,MAAM,CAAC;AAmBb,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAsDD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAOzE;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GACrB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAMnB;AAGD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -21,6 +21,38 @@ _fromTagLib["disc"] = "discNumber";
|
|
|
21
21
|
function toTagLibKey(key) {
|
|
22
22
|
return _toTagLib[key] ?? key;
|
|
23
23
|
}
|
|
24
|
+
const _mp4FreeformAtoms = {};
|
|
25
|
+
for (const meta of Object.values(PROPERTIES)) {
|
|
26
|
+
const { key, mappings } = meta;
|
|
27
|
+
const atom = mappings?.mp4;
|
|
28
|
+
if (typeof atom !== "string" || !atom.startsWith("----:")) continue;
|
|
29
|
+
const bare = atom.slice(atom.lastIndexOf(":") + 1);
|
|
30
|
+
if (bare === bare.toUpperCase()) continue;
|
|
31
|
+
_mp4FreeformAtoms[key] = atom;
|
|
32
|
+
const readKey = bare.toUpperCase();
|
|
33
|
+
const camel = _fromTagLib[key];
|
|
34
|
+
if (camel !== void 0 && _fromTagLib[readKey] === void 0) {
|
|
35
|
+
_fromTagLib[readKey] = camel;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const _mp4AtomToWireKey = {};
|
|
39
|
+
for (const meta of Object.values(PROPERTIES)) {
|
|
40
|
+
const { key, mappings } = meta;
|
|
41
|
+
const atom = mappings?.mp4;
|
|
42
|
+
if (typeof atom !== "string" || atom.startsWith("----:")) continue;
|
|
43
|
+
if (_mp4AtomToWireKey[atom] === void 0) _mp4AtomToWireKey[atom] = key;
|
|
44
|
+
}
|
|
45
|
+
function mp4AtomWireKey(atom) {
|
|
46
|
+
return _mp4AtomToWireKey[atom];
|
|
47
|
+
}
|
|
48
|
+
function mp4FreeformAtomNames(wireKeys) {
|
|
49
|
+
const names = [];
|
|
50
|
+
for (const key of wireKeys) {
|
|
51
|
+
const atom = _mp4FreeformAtoms[key];
|
|
52
|
+
if (atom !== void 0) names.push(atom);
|
|
53
|
+
}
|
|
54
|
+
return names;
|
|
55
|
+
}
|
|
24
56
|
function fromTagLibKey(key) {
|
|
25
57
|
return _fromTagLib[key] ?? key;
|
|
26
58
|
}
|
|
@@ -34,6 +66,8 @@ function remapKeysFromTagLib(obj) {
|
|
|
34
66
|
export {
|
|
35
67
|
PROPERTIES,
|
|
36
68
|
fromTagLibKey,
|
|
69
|
+
mp4AtomWireKey,
|
|
70
|
+
mp4FreeformAtomNames,
|
|
37
71
|
remapKeysFromTagLib,
|
|
38
72
|
toTagLibKey
|
|
39
73
|
};
|
|
@@ -157,5 +157,28 @@ export declare const SPECIALIZED_PROPERTIES: {
|
|
|
157
157
|
readonly mp4: "----:com.apple.iTunes:iTunNORM";
|
|
158
158
|
};
|
|
159
159
|
};
|
|
160
|
+
/**
|
|
161
|
+
* Apple gapless-playback data (encoder delay, padding, original sample count).
|
|
162
|
+
*
|
|
163
|
+
* Exists so the two Apple freeform atoms are presented consistently: without
|
|
164
|
+
* it, `properties()` answered `appleSoundCheck` for iTunNORM but the raw
|
|
165
|
+
* uppercased `ITUNSMPB` for its sibling, because only one had an alias. The
|
|
166
|
+
* name mirrors `appleSoundCheck` — vendor-prefixed, feature-named rather than
|
|
167
|
+
* atom-named (tuneup-ibo).
|
|
168
|
+
*/
|
|
169
|
+
readonly appleGaplessInfo: {
|
|
170
|
+
readonly key: "ITUNSMPB";
|
|
171
|
+
readonly description: "Apple gapless playback data (encoder delay and padding)";
|
|
172
|
+
readonly type: "string";
|
|
173
|
+
readonly supportedFormats: readonly ["ID3v2", "MP4", "Vorbis"];
|
|
174
|
+
readonly mappings: {
|
|
175
|
+
readonly id3v2: {
|
|
176
|
+
readonly frame: "TXXX";
|
|
177
|
+
readonly description: "iTunSMPB";
|
|
178
|
+
};
|
|
179
|
+
readonly vorbis: "ITUNSMPB";
|
|
180
|
+
readonly mp4: "----:com.apple.iTunes:iTunSMPB";
|
|
181
|
+
};
|
|
182
|
+
};
|
|
160
183
|
};
|
|
161
184
|
//# sourceMappingURL=specialized-properties.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specialized-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/specialized-properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"specialized-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/specialized-properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiIjC;;;;;;;;OAQG;;;;;;;;;;;;;;;CAYK,CAAC"}
|
|
@@ -123,6 +123,26 @@ const SPECIALIZED_PROPERTIES = {
|
|
|
123
123
|
vorbis: "ITUNNORM",
|
|
124
124
|
mp4: "----:com.apple.iTunes:iTunNORM"
|
|
125
125
|
}
|
|
126
|
+
},
|
|
127
|
+
/**
|
|
128
|
+
* Apple gapless-playback data (encoder delay, padding, original sample count).
|
|
129
|
+
*
|
|
130
|
+
* Exists so the two Apple freeform atoms are presented consistently: without
|
|
131
|
+
* it, `properties()` answered `appleSoundCheck` for iTunNORM but the raw
|
|
132
|
+
* uppercased `ITUNSMPB` for its sibling, because only one had an alias. The
|
|
133
|
+
* name mirrors `appleSoundCheck` — vendor-prefixed, feature-named rather than
|
|
134
|
+
* atom-named (tuneup-ibo).
|
|
135
|
+
*/
|
|
136
|
+
appleGaplessInfo: {
|
|
137
|
+
key: "ITUNSMPB",
|
|
138
|
+
description: "Apple gapless playback data (encoder delay and padding)",
|
|
139
|
+
type: "string",
|
|
140
|
+
supportedFormats: ["ID3v2", "MP4", "Vorbis"],
|
|
141
|
+
mappings: {
|
|
142
|
+
id3v2: { frame: "TXXX", description: "iTunSMPB" },
|
|
143
|
+
vorbis: "ITUNSMPB",
|
|
144
|
+
mp4: "----:com.apple.iTunes:iTunSMPB"
|
|
145
|
+
}
|
|
126
146
|
}
|
|
127
147
|
};
|
|
128
148
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/constants/tags.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFP,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/constants/tags.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFP,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;AAYrD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,OAAO,CAE5D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,SAAS,OAAO,EAAE,CAEnD"}
|
|
@@ -72,8 +72,9 @@ const Tags = {
|
|
|
72
72
|
InvolvedPeople: "involvedPeople",
|
|
73
73
|
Encoding: "encoding"
|
|
74
74
|
};
|
|
75
|
+
const VALID_TAG_NAMES = new Set(Object.values(Tags));
|
|
75
76
|
function isValidTagName(name) {
|
|
76
|
-
return
|
|
77
|
+
return VALID_TAG_NAMES.has(name);
|
|
77
78
|
}
|
|
78
79
|
function getAllTagNames() {
|
|
79
80
|
return Object.values(Tags);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/msgpack/encoder.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACZ,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/msgpack/encoder.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACZ,MAAM,aAAa,CAAC;AAIrB;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,aAa3B,CAAC;AA4BH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAoC9D;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,eAAe,GAAG,UAAU,CAS7E;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,UAAU,CAStE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAe1D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,UAAU,CAelE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,IAAI,EAAE,CAAC,EACP,OAAO,GAAE,OAAO,CAAC,cAAc,CAAM,GACpC,UAAU,CAUZ;AAED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,UAAU,CAe/D;AAqBD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,UAAU,CAc1E;AAED,wBAAiB,uBAAuB,CAAC,CAAC,EACxC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,GACxB,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CActC;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAS7D;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,GAC1E,UAAU,CAeZ;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAW7D;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG;IACxD,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAaA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { encode } from "@msgpack/msgpack";
|
|
2
2
|
import { errorMessage, MetadataError } from "../errors/classes.js";
|
|
3
3
|
import { toTagLibKey } from "../constants/properties.js";
|
|
4
|
+
import { isShadowedNumericMirror } from "../utils/mirror-fields.js";
|
|
4
5
|
const PASSTHROUGH_KEYS = /* @__PURE__ */ new Set([
|
|
5
6
|
"pictures",
|
|
6
7
|
"ratings",
|
|
@@ -11,7 +12,9 @@ const PASSTHROUGH_KEYS = /* @__PURE__ */ new Set([
|
|
|
11
12
|
"bextData",
|
|
12
13
|
"ixml",
|
|
13
14
|
"id3Tags",
|
|
14
|
-
"_stripId3"
|
|
15
|
+
"_stripId3",
|
|
16
|
+
// Exact MP4 atom names — must reach C++ verbatim, not via toTagLibKey.
|
|
17
|
+
"_mp4ItemNames"
|
|
15
18
|
]);
|
|
16
19
|
const MSGPACK_ENCODE_OPTIONS = {
|
|
17
20
|
sortKeys: false,
|
|
@@ -29,11 +32,10 @@ function lyricsTexts(value) {
|
|
|
29
32
|
}
|
|
30
33
|
function encodeTagData(tagData) {
|
|
31
34
|
try {
|
|
32
|
-
const
|
|
33
|
-
const hasDate = Array.isArray(dateVal) ? dateVal.length > 0 : dateVal !== void 0 && dateVal !== null && dateVal !== "";
|
|
35
|
+
const data = tagData;
|
|
34
36
|
const remapped = {};
|
|
35
37
|
for (const [key, value] of Object.entries(tagData)) {
|
|
36
|
-
if (key
|
|
38
|
+
if (isShadowedNumericMirror(data, key)) continue;
|
|
37
39
|
if (key === "lyrics") {
|
|
38
40
|
const texts = lyricsTexts(value);
|
|
39
41
|
if (texts.length > 0) remapped["LYRICS"] = texts;
|
|
@@ -23,10 +23,4 @@ export declare function detectRuntime(): RuntimeDetectionResult;
|
|
|
23
23
|
export declare function supportsExnref(): boolean;
|
|
24
24
|
export declare function getEnvironmentDescription(env: RuntimeEnvironment): string;
|
|
25
25
|
export declare function canLoadWasmType(wasmType: WasmBinaryType): boolean;
|
|
26
|
-
/** @internal */
|
|
27
|
-
export declare function _forceRuntime(result: RuntimeDetectionResult): void;
|
|
28
|
-
/** @internal */
|
|
29
|
-
export declare function _clearRuntimeOverride(): void;
|
|
30
|
-
/** @internal */
|
|
31
|
-
export declare function _getDetectionResult(): RuntimeDetectionResult;
|
|
32
26
|
//# sourceMappingURL=detector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../../src/runtime/detector.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,WAAW,GACX,UAAU,GACV,SAAS,GACT,iBAAiB,GACjB,QAAQ,GACR,YAAY,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,YAAY,CAAC;AAEnD,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,kBAAkB,CAAC;IAChC,QAAQ,EAAE,cAAc,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC5B;AAOD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,GAAG,SAAS,CAepB;AAuCD,qFAAqF;AACrF,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED,wBAAgB,aAAa,IAAI,sBAAsB,CA8EtD;AAWD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAMxC;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAmBzE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAQjE
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../../src/runtime/detector.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,WAAW,GACX,UAAU,GACV,SAAS,GACT,iBAAiB,GACjB,QAAQ,GACR,YAAY,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,YAAY,CAAC;AAEnD,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,kBAAkB,CAAC;IAChC,QAAQ,EAAE,cAAc,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC5B;AAOD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,GAAG,SAAS,CAepB;AAuCD,qFAAqF;AACrF,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED,wBAAgB,aAAa,IAAI,sBAAsB,CA8EtD;AAWD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAMxC;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAmBzE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAQjE"}
|
|
@@ -145,7 +145,7 @@ function getEnvironmentDescription(env) {
|
|
|
145
145
|
case "node-wasi":
|
|
146
146
|
return "Node.js with WASI (high performance)";
|
|
147
147
|
case "bun-wasi":
|
|
148
|
-
return "Bun with WASI (
|
|
148
|
+
return "Bun with WASI (Bun-native file I/O)";
|
|
149
149
|
case "browser":
|
|
150
150
|
return "Browser with Emscripten (web compatibility)";
|
|
151
151
|
case "worker":
|
|
@@ -165,20 +165,7 @@ function canLoadWasmType(wasmType) {
|
|
|
165
165
|
}
|
|
166
166
|
return true;
|
|
167
167
|
}
|
|
168
|
-
function _forceRuntime(result) {
|
|
169
|
-
globalThis.__taglib_wasm_runtime_override = result;
|
|
170
|
-
}
|
|
171
|
-
function _clearRuntimeOverride() {
|
|
172
|
-
delete globalThis.__taglib_wasm_runtime_override;
|
|
173
|
-
}
|
|
174
|
-
function _getDetectionResult() {
|
|
175
|
-
const override = globalThis.__taglib_wasm_runtime_override;
|
|
176
|
-
return override || detectRuntime();
|
|
177
|
-
}
|
|
178
168
|
export {
|
|
179
|
-
_clearRuntimeOverride,
|
|
180
|
-
_forceRuntime,
|
|
181
|
-
_getDetectionResult,
|
|
182
169
|
canLoadWasmType,
|
|
183
170
|
checkNodeVersion,
|
|
184
171
|
detectRuntime,
|
|
@@ -30,6 +30,8 @@ export declare class WasiFileHandle implements FileHandle {
|
|
|
30
30
|
isMP4(): boolean;
|
|
31
31
|
getMP4Item(key: string): string;
|
|
32
32
|
setMP4Item(key: string, value: string): void;
|
|
33
|
+
/** Record an exact atom name to be repaired after the PropertyMap write. */
|
|
34
|
+
private registerMp4ItemName;
|
|
33
35
|
removeMP4Item(key: string): void;
|
|
34
36
|
getPictures(): RawPicture[];
|
|
35
37
|
setPictures(pictures: RawPicture[]): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-handle.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/file-handle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACX,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"file-handle.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/file-handle.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,21 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import { WasmerExecutionError } from "../wasmer-sdk-loader/types.js";
|
|
5
5
|
import { decodeTagData } from "../../msgpack/decoder.js";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
fromTagLibKey,
|
|
8
|
+
mp4AtomWireKey,
|
|
9
|
+
toTagLibKey
|
|
10
|
+
} from "../../constants/properties.js";
|
|
11
|
+
import {
|
|
12
|
+
DATE_MIRROR,
|
|
13
|
+
firstValueString,
|
|
14
|
+
isShadowedNumericMirror,
|
|
15
|
+
mirrorForRawKey,
|
|
16
|
+
readNumericMirror,
|
|
17
|
+
stageNumericWrite,
|
|
18
|
+
stageRawWrite,
|
|
19
|
+
TRACK_MIRROR
|
|
20
|
+
} from "../../utils/mirror-fields.js";
|
|
7
21
|
import {
|
|
8
22
|
readId3v2FramesFromWasm,
|
|
9
23
|
readTagsFromWasm,
|
|
@@ -36,7 +50,9 @@ const INTERNAL_KEYS = /* @__PURE__ */ new Set([
|
|
|
36
50
|
"chapters",
|
|
37
51
|
"_mp4ChapterStyle",
|
|
38
52
|
"bextData",
|
|
39
|
-
"ixml"
|
|
53
|
+
"ixml",
|
|
54
|
+
// Exact MP4 atom names for the write path, not a readable property.
|
|
55
|
+
"_mp4ItemNames"
|
|
40
56
|
]);
|
|
41
57
|
const CONTAINER_TO_FORMAT = {
|
|
42
58
|
MP3: "MP3",
|
|
@@ -50,22 +66,11 @@ const CONTAINER_TO_FORMAT = {
|
|
|
50
66
|
ASF: "ASF",
|
|
51
67
|
Matroska: "MATROSKA"
|
|
52
68
|
};
|
|
53
|
-
const NUMERIC_FIELD_ALIASES = {
|
|
54
|
-
trackNumber: "track"
|
|
55
|
-
};
|
|
56
|
-
function hasValue(v) {
|
|
57
|
-
if (Array.isArray(v)) return v.length > 0;
|
|
58
|
-
return v !== void 0 && v !== null && v !== "";
|
|
59
|
-
}
|
|
60
|
-
function firstString(v) {
|
|
61
|
-
if (Array.isArray(v)) return v[0] ?? "";
|
|
62
|
-
return v || "";
|
|
63
|
-
}
|
|
64
69
|
function mp4ItemPropertyKey(key) {
|
|
65
70
|
if (key.startsWith("----:")) {
|
|
66
71
|
return key.slice(key.lastIndexOf(":") + 1).toUpperCase();
|
|
67
72
|
}
|
|
68
|
-
return key;
|
|
73
|
+
return mp4AtomWireKey(key) ?? key;
|
|
69
74
|
}
|
|
70
75
|
class WasiFileHandle {
|
|
71
76
|
constructor(wasiModule) {
|
|
@@ -123,21 +128,23 @@ class WasiFileHandle {
|
|
|
123
128
|
this.checkNotDestroyed();
|
|
124
129
|
const d = this.tagData ?? {};
|
|
125
130
|
return {
|
|
126
|
-
title:
|
|
127
|
-
artist:
|
|
128
|
-
album:
|
|
129
|
-
comment:
|
|
130
|
-
genre:
|
|
131
|
-
year: d
|
|
132
|
-
track: d
|
|
131
|
+
title: firstValueString(d.title),
|
|
132
|
+
artist: firstValueString(d.artist),
|
|
133
|
+
album: firstValueString(d.album),
|
|
134
|
+
comment: firstValueString(d.comment),
|
|
135
|
+
genre: firstValueString(d.genre),
|
|
136
|
+
year: readNumericMirror(d, DATE_MIRROR),
|
|
137
|
+
track: readNumericMirror(d, TRACK_MIRROR)
|
|
133
138
|
};
|
|
134
139
|
}
|
|
135
140
|
setTagData(data) {
|
|
136
141
|
this.checkNotDestroyed();
|
|
137
142
|
const merged = { ...this.tagData, ...data };
|
|
138
143
|
if (data.year !== void 0) {
|
|
139
|
-
|
|
140
|
-
|
|
144
|
+
stageNumericWrite(merged, DATE_MIRROR, data.year);
|
|
145
|
+
}
|
|
146
|
+
if (data.track !== void 0) {
|
|
147
|
+
stageNumericWrite(merged, TRACK_MIRROR, data.track);
|
|
141
148
|
}
|
|
142
149
|
this.tagData = merged;
|
|
143
150
|
}
|
|
@@ -211,7 +218,8 @@ class WasiFileHandle {
|
|
|
211
218
|
const data = this.tagData ?? {};
|
|
212
219
|
for (const [key, value] of Object.entries(data)) {
|
|
213
220
|
if (AUDIO_KEYS.has(key) || INTERNAL_KEYS.has(key)) continue;
|
|
214
|
-
if (key
|
|
221
|
+
if (key.startsWith("----:")) continue;
|
|
222
|
+
if (isShadowedNumericMirror(data, key)) continue;
|
|
215
223
|
if (value === void 0 || value === null) continue;
|
|
216
224
|
if (value === 0 || value === "") continue;
|
|
217
225
|
const propKey = toTagLibKey(key);
|
|
@@ -230,17 +238,16 @@ class WasiFileHandle {
|
|
|
230
238
|
const next = { ...this.tagData };
|
|
231
239
|
for (const [key, values] of Object.entries(props)) {
|
|
232
240
|
const camelKey = fromTagLibKey(key);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (!Number.isNaN(year)) next.year = year;
|
|
241
|
+
if (camelKey === "_mp4ItemNames") {
|
|
242
|
+
const existing = next._mp4ItemNames ?? [];
|
|
243
|
+
next._mp4ItemNames = [.../* @__PURE__ */ new Set([...existing, ...values])];
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
const mirror = mirrorForRawKey(camelKey);
|
|
247
|
+
if (mirror !== void 0) {
|
|
248
|
+
stageRawWrite(next, mirror, values);
|
|
249
|
+
} else if (values.length === 0) {
|
|
250
|
+
delete next[camelKey];
|
|
244
251
|
} else {
|
|
245
252
|
next[camelKey] = values;
|
|
246
253
|
}
|
|
@@ -250,25 +257,17 @@ class WasiFileHandle {
|
|
|
250
257
|
getProperty(key) {
|
|
251
258
|
this.checkNotDestroyed();
|
|
252
259
|
const mappedKey = fromTagLibKey(key);
|
|
253
|
-
const
|
|
254
|
-
return
|
|
260
|
+
const stored = this.tagData?.[mappedKey];
|
|
261
|
+
return Array.isArray(stored) ? stored[0]?.toString() ?? "" : stored?.toString() ?? "";
|
|
255
262
|
}
|
|
256
263
|
setProperty(key, value) {
|
|
257
264
|
this.checkNotDestroyed();
|
|
258
265
|
const mappedKey = fromTagLibKey(key);
|
|
259
|
-
const
|
|
260
|
-
if (
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
} else if (mappedKey === "date") {
|
|
266
|
-
const year = Number.parseInt(value, 10);
|
|
267
|
-
this.tagData = {
|
|
268
|
-
...this.tagData,
|
|
269
|
-
date: value,
|
|
270
|
-
...Number.isNaN(year) ? {} : { year }
|
|
271
|
-
};
|
|
266
|
+
const mirror = mirrorForRawKey(mappedKey);
|
|
267
|
+
if (mirror !== void 0) {
|
|
268
|
+
const next = { ...this.tagData };
|
|
269
|
+
stageRawWrite(next, mirror, value === "" ? [] : [value]);
|
|
270
|
+
this.tagData = next;
|
|
272
271
|
} else {
|
|
273
272
|
this.tagData = { ...this.tagData, [mappedKey]: value };
|
|
274
273
|
}
|
|
@@ -284,18 +283,40 @@ class WasiFileHandle {
|
|
|
284
283
|
}
|
|
285
284
|
getMP4Item(key) {
|
|
286
285
|
this.checkNotDestroyed();
|
|
286
|
+
if (key.startsWith("----:")) {
|
|
287
|
+
const foreign = this.tagData?.[key];
|
|
288
|
+
if (foreign !== void 0) {
|
|
289
|
+
return Array.isArray(foreign) ? foreign[0]?.toString() ?? "" : String(foreign);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
287
292
|
return this.getProperty(mp4ItemPropertyKey(key));
|
|
288
293
|
}
|
|
289
294
|
setMP4Item(key, value) {
|
|
290
295
|
this.checkNotDestroyed();
|
|
291
296
|
this.setProperty(mp4ItemPropertyKey(key), value);
|
|
297
|
+
if (key.startsWith("----:")) {
|
|
298
|
+
this.registerMp4ItemName(key);
|
|
299
|
+
if (this.tagData?.[key] !== void 0) {
|
|
300
|
+
this.tagData = { ...this.tagData, [key]: value };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/** Record an exact atom name to be repaired after the PropertyMap write. */
|
|
305
|
+
registerMp4ItemName(name) {
|
|
306
|
+
const existing = this.tagData?._mp4ItemNames ?? [];
|
|
307
|
+
if (existing.includes(name)) return;
|
|
308
|
+
this.tagData = {
|
|
309
|
+
...this.tagData,
|
|
310
|
+
_mp4ItemNames: [...existing, name]
|
|
311
|
+
};
|
|
292
312
|
}
|
|
293
313
|
removeMP4Item(key) {
|
|
294
314
|
this.checkNotDestroyed();
|
|
295
315
|
if (this.tagData) {
|
|
296
316
|
const mappedKey = fromTagLibKey(mp4ItemPropertyKey(key));
|
|
297
|
-
|
|
298
|
-
|
|
317
|
+
delete this.tagData[mappedKey];
|
|
318
|
+
const mirror = mirrorForRawKey(mappedKey);
|
|
319
|
+
if (mirror !== void 0) delete this.tagData[mirror.numeric];
|
|
299
320
|
}
|
|
300
321
|
}
|
|
301
322
|
getPictures() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-file-base.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"audio-file-base.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;AAQrB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAgBhE;;;;;GAKG;AACH,8BAAsB,iBAAiB;IAWnC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY;IAVzC,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACxC,SAAS,CAAC,qBAAqB,EAAE,eAAe,GAAG,IAAI,CAAQ;IAC/D,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IACvC,SAAS,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,CAAC;IACpE,SAAS,CAAC,iBAAiB,EAAE,OAAO,CAAS;IAC7C,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,WAAW,CAAC;IACpD,gFAAgF;IAChF,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;gBAGtC,MAAM,EAAE,YAAY,EACvC,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,EACzD,iBAAiB,GAAE,OAAe,EAClC,kBAAkB,CAAC,EAAE,WAAW;IAYlC;;;;;;OAMG;IACH,SAAS,CAAC,0BAA0B,IAAI,WAAW,CAAC,MAAM,CAAC;IAU3D,SAAS,KAAK,MAAM,IAAI,UAAU,CAKjC;IAED,SAAS,IAAI,QAAQ;IAIrB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,IAAI,cAAc,CAAC,CAAC,CAAC;IAIlE,GAAG,IAAI,UAAU;IAIjB,eAAe,IAAI,eAAe,GAAG,SAAS;IAO9C,UAAU,IAAI,WAAW;IAMzB,aAAa,CAAC,UAAU,EAAE,WAAW,GAAG,IAAI;IAsB5C,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAkB5C,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAkB7C,KAAK,IAAI,OAAO;IAIhB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAe3C,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAoB5C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOhC,OAAO,IAAI,OAAO;IAIlB,OAAO,IAAI,IAAI;IAQf,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAGzB"}
|