taglib-wasm 1.5.0 → 1.5.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/README.md +3 -1
- package/dist/index.browser.js +145 -80
- package/dist/simple.browser.js +88 -18
- package/dist/src/runtime/detector.d.ts +2 -0
- package/dist/src/runtime/detector.d.ts.map +1 -1
- package/dist/src/runtime/detector.js +1 -0
- package/dist/src/runtime/unified-loader/module-loading.d.ts +2 -0
- package/dist/src/runtime/unified-loader/module-loading.d.ts.map +1 -1
- package/dist/src/runtime/unified-loader/module-loading.js +12 -8
- package/dist/src/runtime/wasi-host-loader.d.ts.map +1 -1
- package/dist/src/runtime/wasi-host-loader.js +2 -1
- package/dist/src/taglib/audio-file-impl.d.ts +4 -1
- package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-impl.js +33 -17
- package/dist/src/taglib/audio-file-interface.d.ts +8 -3
- package/dist/src/taglib/audio-file-interface.d.ts.map +1 -1
- package/dist/src/taglib/taglib-class.d.ts.map +1 -1
- package/dist/src/taglib/taglib-class.js +2 -1
- package/dist/src/utils/node-fs.d.ts +27 -0
- package/dist/src/utils/node-fs.d.ts.map +1 -0
- package/dist/src/utils/node-fs.js +21 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -210,8 +210,9 @@ console.log(
|
|
|
210
210
|
} files`,
|
|
211
211
|
);
|
|
212
212
|
|
|
213
|
-
// Process results
|
|
213
|
+
// Process results (narrow the ok/error union first)
|
|
214
214
|
for (const file of result.items) {
|
|
215
|
+
if (file.status !== "ok") continue;
|
|
215
216
|
console.log(
|
|
216
217
|
`${file.path}: ${file.tags.artist?.[0]} - ${file.tags.title?.[0]}`,
|
|
217
218
|
);
|
|
@@ -333,6 +334,7 @@ using file = await taglib.open("song.mp3");
|
|
|
333
334
|
|
|
334
335
|
// Escape hatch: read/write raw ID3v2 frame bytes by ID (MP3 only)
|
|
335
336
|
const frames = file.getId3v2Frames("TXXX"); // [{ id, data, flags? }]
|
|
337
|
+
const rgadBody = new Uint8Array([/* raw frame body bytes */]);
|
|
336
338
|
file.setId3v2Frames("RGAD", [rgadBody]); // replaces ALL RGAD frames
|
|
337
339
|
file.removeId3v2Frames("NCON"); // removes every NCON frame
|
|
338
340
|
file.save();
|
package/dist/index.browser.js
CHANGED
|
@@ -314,6 +314,9 @@ var init_base = __esm({
|
|
|
314
314
|
});
|
|
315
315
|
|
|
316
316
|
// src/errors/classes.ts
|
|
317
|
+
function errorMessage(error) {
|
|
318
|
+
return error instanceof Error ? error.message : String(error);
|
|
319
|
+
}
|
|
317
320
|
function createErrorMessage(prefix, details) {
|
|
318
321
|
return `${prefix}: ${details}`;
|
|
319
322
|
}
|
|
@@ -638,6 +641,116 @@ var init_write = __esm({
|
|
|
638
641
|
}
|
|
639
642
|
});
|
|
640
643
|
|
|
644
|
+
// browser-stub:node-fs-browser-stub
|
|
645
|
+
function getNodeFsSync() {
|
|
646
|
+
return null;
|
|
647
|
+
}
|
|
648
|
+
var init_node_fs_browser_stub = __esm({
|
|
649
|
+
"browser-stub:node-fs-browser-stub"() {
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
// src/utils/rating.ts
|
|
654
|
+
function normalized(value) {
|
|
655
|
+
return value;
|
|
656
|
+
}
|
|
657
|
+
function popm(value) {
|
|
658
|
+
return value;
|
|
659
|
+
}
|
|
660
|
+
function toNormalized(value) {
|
|
661
|
+
return value / 255;
|
|
662
|
+
}
|
|
663
|
+
function fromNormalized(value) {
|
|
664
|
+
return Math.round(value * 255);
|
|
665
|
+
}
|
|
666
|
+
function toStars(value, maxStars = 5) {
|
|
667
|
+
return Math.round(value * maxStars);
|
|
668
|
+
}
|
|
669
|
+
function fromStars(stars, maxStars = 5) {
|
|
670
|
+
return stars / maxStars;
|
|
671
|
+
}
|
|
672
|
+
function toPopm(value) {
|
|
673
|
+
const stars = Math.round(value * 5);
|
|
674
|
+
return POPM_STAR_VALUES[stars] ?? 0;
|
|
675
|
+
}
|
|
676
|
+
function fromPopm(value) {
|
|
677
|
+
if (value === 0) return 0;
|
|
678
|
+
if (value <= 1) return 0.2;
|
|
679
|
+
if (value <= 64) return 0.4;
|
|
680
|
+
if (value <= 128) return 0.6;
|
|
681
|
+
if (value <= 196) return 0.8;
|
|
682
|
+
return 1;
|
|
683
|
+
}
|
|
684
|
+
function toPercent(value) {
|
|
685
|
+
return value * 100;
|
|
686
|
+
}
|
|
687
|
+
function fromPercent(percent) {
|
|
688
|
+
return percent / 100;
|
|
689
|
+
}
|
|
690
|
+
function clamp(rating) {
|
|
691
|
+
return Math.max(0, Math.min(1, rating));
|
|
692
|
+
}
|
|
693
|
+
function isValid(rating) {
|
|
694
|
+
return typeof rating === "number" && !Number.isNaN(rating) && rating >= 0 && rating <= 1;
|
|
695
|
+
}
|
|
696
|
+
var POPM_STAR_VALUES, RatingUtils;
|
|
697
|
+
var init_rating = __esm({
|
|
698
|
+
"src/utils/rating.ts"() {
|
|
699
|
+
"use strict";
|
|
700
|
+
POPM_STAR_VALUES = [0, 1, 64, 128, 196, 255];
|
|
701
|
+
RatingUtils = {
|
|
702
|
+
normalized,
|
|
703
|
+
popm,
|
|
704
|
+
toNormalized,
|
|
705
|
+
fromNormalized,
|
|
706
|
+
toStars,
|
|
707
|
+
fromStars,
|
|
708
|
+
toPopm,
|
|
709
|
+
fromPopm,
|
|
710
|
+
toPercent,
|
|
711
|
+
fromPercent,
|
|
712
|
+
clamp,
|
|
713
|
+
isValid,
|
|
714
|
+
POPM_STAR_VALUES
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
// src/runtime/detector.ts
|
|
720
|
+
function isDeno() {
|
|
721
|
+
return g.Deno !== void 0;
|
|
722
|
+
}
|
|
723
|
+
var g, EXNREF_PROBE;
|
|
724
|
+
var init_detector = __esm({
|
|
725
|
+
"src/runtime/detector.ts"() {
|
|
726
|
+
"use strict";
|
|
727
|
+
g = globalThis;
|
|
728
|
+
EXNREF_PROBE = new Uint8Array([
|
|
729
|
+
0,
|
|
730
|
+
97,
|
|
731
|
+
115,
|
|
732
|
+
109,
|
|
733
|
+
1,
|
|
734
|
+
0,
|
|
735
|
+
0,
|
|
736
|
+
0,
|
|
737
|
+
// Wasm header
|
|
738
|
+
6,
|
|
739
|
+
6,
|
|
740
|
+
// Global section, 6 bytes
|
|
741
|
+
1,
|
|
742
|
+
// 1 global
|
|
743
|
+
105,
|
|
744
|
+
0,
|
|
745
|
+
// exnref, const
|
|
746
|
+
208,
|
|
747
|
+
105,
|
|
748
|
+
11
|
|
749
|
+
// ref.null exnref, end
|
|
750
|
+
]);
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
|
|
641
754
|
// src/constants/additional-properties.ts
|
|
642
755
|
var ADDITIONAL_PROPERTIES;
|
|
643
756
|
var init_additional_properties = __esm({
|
|
@@ -1881,18 +1994,16 @@ function inferEndTimeMs(sorted, index, trackEndMs) {
|
|
|
1881
1994
|
return next ? next.startTimeMs : trackEndMs;
|
|
1882
1995
|
}
|
|
1883
1996
|
function readFileSync(path) {
|
|
1884
|
-
if (
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
if (_nodeFs) return new Uint8Array(_nodeFs.readFileSync(path));
|
|
1893
|
-
return new Uint8Array(0);
|
|
1997
|
+
if (isDeno()) return Deno.readFileSync(path);
|
|
1998
|
+
const fs = getNodeFsSync();
|
|
1999
|
+
if (fs) return new Uint8Array(fs.readFileSync(path));
|
|
2000
|
+
throw new FileOperationError(
|
|
2001
|
+
"read",
|
|
2002
|
+
"node:fs is unavailable in this runtime: cannot read file data from disk",
|
|
2003
|
+
path
|
|
2004
|
+
);
|
|
1894
2005
|
}
|
|
1895
|
-
var
|
|
2006
|
+
var AudioFileImpl;
|
|
1896
2007
|
var init_audio_file_impl = __esm({
|
|
1897
2008
|
"src/taglib/audio-file-impl.ts"() {
|
|
1898
2009
|
"use strict";
|
|
@@ -1901,6 +2012,9 @@ var init_audio_file_impl = __esm({
|
|
|
1901
2012
|
init_id3v2_frames();
|
|
1902
2013
|
init_errors2();
|
|
1903
2014
|
init_write();
|
|
2015
|
+
init_node_fs_browser_stub();
|
|
2016
|
+
init_rating();
|
|
2017
|
+
init_detector();
|
|
1904
2018
|
init_audio_file_base();
|
|
1905
2019
|
init_save_reconstruct();
|
|
1906
2020
|
AudioFileImpl = class extends BaseAudioFileImpl {
|
|
@@ -1923,6 +2037,7 @@ var init_audio_file_impl = __esm({
|
|
|
1923
2037
|
);
|
|
1924
2038
|
}
|
|
1925
2039
|
this.cachedAudioProperties = null;
|
|
2040
|
+
this.pathModeBuffer = null;
|
|
1926
2041
|
return this.handle.save();
|
|
1927
2042
|
}
|
|
1928
2043
|
getFileBuffer() {
|
|
@@ -1933,11 +2048,20 @@ var init_audio_file_impl = __esm({
|
|
|
1933
2048
|
try {
|
|
1934
2049
|
this.pathModeBuffer = readFileSync(this.sourcePath);
|
|
1935
2050
|
return this.pathModeBuffer;
|
|
1936
|
-
} catch {
|
|
1937
|
-
|
|
2051
|
+
} catch (error) {
|
|
2052
|
+
if (error instanceof FileOperationError) throw error;
|
|
2053
|
+
throw new FileOperationError(
|
|
2054
|
+
"read",
|
|
2055
|
+
`Cannot return file data: ${errorMessage(error)}`,
|
|
2056
|
+
this.sourcePath,
|
|
2057
|
+
{ cause: error }
|
|
2058
|
+
);
|
|
1938
2059
|
}
|
|
1939
2060
|
}
|
|
1940
|
-
|
|
2061
|
+
throw new FileOperationError(
|
|
2062
|
+
"read",
|
|
2063
|
+
"No file data available: in-memory buffer is empty and no source path is set"
|
|
2064
|
+
);
|
|
1941
2065
|
}
|
|
1942
2066
|
async saveToFile(path) {
|
|
1943
2067
|
const targetPath = path ?? this.sourcePath;
|
|
@@ -1978,6 +2102,7 @@ var init_audio_file_impl = __esm({
|
|
|
1978
2102
|
await writeFileData(targetPath, buffer);
|
|
1979
2103
|
}
|
|
1980
2104
|
}
|
|
2105
|
+
this.pathModeBuffer = null;
|
|
1981
2106
|
}
|
|
1982
2107
|
getPictures() {
|
|
1983
2108
|
const picturesArray = this.handle.getPictures();
|
|
@@ -2089,7 +2214,7 @@ var init_audio_file_impl = __esm({
|
|
|
2089
2214
|
}
|
|
2090
2215
|
getRating() {
|
|
2091
2216
|
const ratings = this.getRatings();
|
|
2092
|
-
return ratings.length > 0 ? ratings[0].rating : void 0;
|
|
2217
|
+
return ratings.length > 0 ? normalized(ratings[0].rating) : void 0;
|
|
2093
2218
|
}
|
|
2094
2219
|
setRating(rating, email) {
|
|
2095
2220
|
this.setRatings([{ rating, email, counter: 0 }]);
|
|
@@ -2294,7 +2419,7 @@ var VERSION;
|
|
|
2294
2419
|
var init_version = __esm({
|
|
2295
2420
|
"src/version.ts"() {
|
|
2296
2421
|
"use strict";
|
|
2297
|
-
VERSION = "1.5.
|
|
2422
|
+
VERSION = "1.5.1";
|
|
2298
2423
|
}
|
|
2299
2424
|
});
|
|
2300
2425
|
|
|
@@ -2353,8 +2478,8 @@ function toWasiPath(osPath) {
|
|
|
2353
2478
|
}
|
|
2354
2479
|
let p = osPath;
|
|
2355
2480
|
if (!p.startsWith("/") && !/^[A-Za-z]:/.test(p)) {
|
|
2356
|
-
const
|
|
2357
|
-
const cwd =
|
|
2481
|
+
const g2 = globalThis;
|
|
2482
|
+
const cwd = isDeno() ? Deno.cwd() : g2.process?.cwd?.();
|
|
2358
2483
|
if (cwd) {
|
|
2359
2484
|
p = cwd.replace(/[/\\]+$/, "") + "/" + p;
|
|
2360
2485
|
}
|
|
@@ -2377,6 +2502,7 @@ var init_taglib_class = __esm({
|
|
|
2377
2502
|
"use strict";
|
|
2378
2503
|
init_audio_formats();
|
|
2379
2504
|
init_errors2();
|
|
2505
|
+
init_detector();
|
|
2380
2506
|
init_audio_file_impl();
|
|
2381
2507
|
init_load_audio_data();
|
|
2382
2508
|
init_tag_mapping();
|
|
@@ -3239,68 +3365,7 @@ async function createPictureGallery(file, container, options = {}) {
|
|
|
3239
3365
|
|
|
3240
3366
|
// index.browser.ts
|
|
3241
3367
|
init_types2();
|
|
3242
|
-
|
|
3243
|
-
// src/utils/rating.ts
|
|
3244
|
-
function normalized(value) {
|
|
3245
|
-
return value;
|
|
3246
|
-
}
|
|
3247
|
-
function popm(value) {
|
|
3248
|
-
return value;
|
|
3249
|
-
}
|
|
3250
|
-
function toNormalized(value) {
|
|
3251
|
-
return value / 255;
|
|
3252
|
-
}
|
|
3253
|
-
function fromNormalized(value) {
|
|
3254
|
-
return Math.round(value * 255);
|
|
3255
|
-
}
|
|
3256
|
-
function toStars(value, maxStars = 5) {
|
|
3257
|
-
return Math.round(value * maxStars);
|
|
3258
|
-
}
|
|
3259
|
-
function fromStars(stars, maxStars = 5) {
|
|
3260
|
-
return stars / maxStars;
|
|
3261
|
-
}
|
|
3262
|
-
var POPM_STAR_VALUES = [0, 1, 64, 128, 196, 255];
|
|
3263
|
-
function toPopm(value) {
|
|
3264
|
-
const stars = Math.round(value * 5);
|
|
3265
|
-
return POPM_STAR_VALUES[stars] ?? 0;
|
|
3266
|
-
}
|
|
3267
|
-
function fromPopm(value) {
|
|
3268
|
-
if (value === 0) return 0;
|
|
3269
|
-
if (value <= 1) return 0.2;
|
|
3270
|
-
if (value <= 64) return 0.4;
|
|
3271
|
-
if (value <= 128) return 0.6;
|
|
3272
|
-
if (value <= 196) return 0.8;
|
|
3273
|
-
return 1;
|
|
3274
|
-
}
|
|
3275
|
-
function toPercent(value) {
|
|
3276
|
-
return value * 100;
|
|
3277
|
-
}
|
|
3278
|
-
function fromPercent(percent) {
|
|
3279
|
-
return percent / 100;
|
|
3280
|
-
}
|
|
3281
|
-
function clamp(rating) {
|
|
3282
|
-
return Math.max(0, Math.min(1, rating));
|
|
3283
|
-
}
|
|
3284
|
-
function isValid(rating) {
|
|
3285
|
-
return typeof rating === "number" && !Number.isNaN(rating) && rating >= 0 && rating <= 1;
|
|
3286
|
-
}
|
|
3287
|
-
var RatingUtils = {
|
|
3288
|
-
normalized,
|
|
3289
|
-
popm,
|
|
3290
|
-
toNormalized,
|
|
3291
|
-
fromNormalized,
|
|
3292
|
-
toStars,
|
|
3293
|
-
fromStars,
|
|
3294
|
-
toPopm,
|
|
3295
|
-
fromPopm,
|
|
3296
|
-
toPercent,
|
|
3297
|
-
fromPercent,
|
|
3298
|
-
clamp,
|
|
3299
|
-
isValid,
|
|
3300
|
-
POPM_STAR_VALUES
|
|
3301
|
-
};
|
|
3302
|
-
|
|
3303
|
-
// index.browser.ts
|
|
3368
|
+
init_rating();
|
|
3304
3369
|
init_module_loader_browser();
|
|
3305
3370
|
export {
|
|
3306
3371
|
AudioFileImpl,
|
package/dist/simple.browser.js
CHANGED
|
@@ -302,6 +302,9 @@ var init_base = __esm({
|
|
|
302
302
|
});
|
|
303
303
|
|
|
304
304
|
// src/errors/classes.ts
|
|
305
|
+
function errorMessage(error) {
|
|
306
|
+
return error instanceof Error ? error.message : String(error);
|
|
307
|
+
}
|
|
305
308
|
function createErrorMessage(prefix, details) {
|
|
306
309
|
return `${prefix}: ${details}`;
|
|
307
310
|
}
|
|
@@ -626,6 +629,60 @@ var init_write = __esm({
|
|
|
626
629
|
}
|
|
627
630
|
});
|
|
628
631
|
|
|
632
|
+
// browser-stub:node-fs-browser-stub
|
|
633
|
+
function getNodeFsSync() {
|
|
634
|
+
return null;
|
|
635
|
+
}
|
|
636
|
+
var init_node_fs_browser_stub = __esm({
|
|
637
|
+
"browser-stub:node-fs-browser-stub"() {
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
// src/utils/rating.ts
|
|
642
|
+
function normalized(value) {
|
|
643
|
+
return value;
|
|
644
|
+
}
|
|
645
|
+
var init_rating = __esm({
|
|
646
|
+
"src/utils/rating.ts"() {
|
|
647
|
+
"use strict";
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
// src/runtime/detector.ts
|
|
652
|
+
function isDeno() {
|
|
653
|
+
return g.Deno !== void 0;
|
|
654
|
+
}
|
|
655
|
+
var g, EXNREF_PROBE;
|
|
656
|
+
var init_detector = __esm({
|
|
657
|
+
"src/runtime/detector.ts"() {
|
|
658
|
+
"use strict";
|
|
659
|
+
g = globalThis;
|
|
660
|
+
EXNREF_PROBE = new Uint8Array([
|
|
661
|
+
0,
|
|
662
|
+
97,
|
|
663
|
+
115,
|
|
664
|
+
109,
|
|
665
|
+
1,
|
|
666
|
+
0,
|
|
667
|
+
0,
|
|
668
|
+
0,
|
|
669
|
+
// Wasm header
|
|
670
|
+
6,
|
|
671
|
+
6,
|
|
672
|
+
// Global section, 6 bytes
|
|
673
|
+
1,
|
|
674
|
+
// 1 global
|
|
675
|
+
105,
|
|
676
|
+
0,
|
|
677
|
+
// exnref, const
|
|
678
|
+
208,
|
|
679
|
+
105,
|
|
680
|
+
11
|
|
681
|
+
// ref.null exnref, end
|
|
682
|
+
]);
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
|
|
629
686
|
// src/constants/additional-properties.ts
|
|
630
687
|
var ADDITIONAL_PROPERTIES;
|
|
631
688
|
var init_additional_properties = __esm({
|
|
@@ -1869,18 +1926,16 @@ function inferEndTimeMs(sorted, index, trackEndMs) {
|
|
|
1869
1926
|
return next ? next.startTimeMs : trackEndMs;
|
|
1870
1927
|
}
|
|
1871
1928
|
function readFileSync(path) {
|
|
1872
|
-
if (
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
if (_nodeFs) return new Uint8Array(_nodeFs.readFileSync(path));
|
|
1881
|
-
return new Uint8Array(0);
|
|
1929
|
+
if (isDeno()) return Deno.readFileSync(path);
|
|
1930
|
+
const fs = getNodeFsSync();
|
|
1931
|
+
if (fs) return new Uint8Array(fs.readFileSync(path));
|
|
1932
|
+
throw new FileOperationError(
|
|
1933
|
+
"read",
|
|
1934
|
+
"node:fs is unavailable in this runtime: cannot read file data from disk",
|
|
1935
|
+
path
|
|
1936
|
+
);
|
|
1882
1937
|
}
|
|
1883
|
-
var
|
|
1938
|
+
var AudioFileImpl;
|
|
1884
1939
|
var init_audio_file_impl = __esm({
|
|
1885
1940
|
"src/taglib/audio-file-impl.ts"() {
|
|
1886
1941
|
"use strict";
|
|
@@ -1889,6 +1944,9 @@ var init_audio_file_impl = __esm({
|
|
|
1889
1944
|
init_id3v2_frames();
|
|
1890
1945
|
init_errors2();
|
|
1891
1946
|
init_write();
|
|
1947
|
+
init_node_fs_browser_stub();
|
|
1948
|
+
init_rating();
|
|
1949
|
+
init_detector();
|
|
1892
1950
|
init_audio_file_base();
|
|
1893
1951
|
init_save_reconstruct();
|
|
1894
1952
|
AudioFileImpl = class extends BaseAudioFileImpl {
|
|
@@ -1911,6 +1969,7 @@ var init_audio_file_impl = __esm({
|
|
|
1911
1969
|
);
|
|
1912
1970
|
}
|
|
1913
1971
|
this.cachedAudioProperties = null;
|
|
1972
|
+
this.pathModeBuffer = null;
|
|
1914
1973
|
return this.handle.save();
|
|
1915
1974
|
}
|
|
1916
1975
|
getFileBuffer() {
|
|
@@ -1921,11 +1980,20 @@ var init_audio_file_impl = __esm({
|
|
|
1921
1980
|
try {
|
|
1922
1981
|
this.pathModeBuffer = readFileSync(this.sourcePath);
|
|
1923
1982
|
return this.pathModeBuffer;
|
|
1924
|
-
} catch {
|
|
1925
|
-
|
|
1983
|
+
} catch (error) {
|
|
1984
|
+
if (error instanceof FileOperationError) throw error;
|
|
1985
|
+
throw new FileOperationError(
|
|
1986
|
+
"read",
|
|
1987
|
+
`Cannot return file data: ${errorMessage(error)}`,
|
|
1988
|
+
this.sourcePath,
|
|
1989
|
+
{ cause: error }
|
|
1990
|
+
);
|
|
1926
1991
|
}
|
|
1927
1992
|
}
|
|
1928
|
-
|
|
1993
|
+
throw new FileOperationError(
|
|
1994
|
+
"read",
|
|
1995
|
+
"No file data available: in-memory buffer is empty and no source path is set"
|
|
1996
|
+
);
|
|
1929
1997
|
}
|
|
1930
1998
|
async saveToFile(path) {
|
|
1931
1999
|
const targetPath = path ?? this.sourcePath;
|
|
@@ -1966,6 +2034,7 @@ var init_audio_file_impl = __esm({
|
|
|
1966
2034
|
await writeFileData(targetPath, buffer);
|
|
1967
2035
|
}
|
|
1968
2036
|
}
|
|
2037
|
+
this.pathModeBuffer = null;
|
|
1969
2038
|
}
|
|
1970
2039
|
getPictures() {
|
|
1971
2040
|
const picturesArray = this.handle.getPictures();
|
|
@@ -2077,7 +2146,7 @@ var init_audio_file_impl = __esm({
|
|
|
2077
2146
|
}
|
|
2078
2147
|
getRating() {
|
|
2079
2148
|
const ratings = this.getRatings();
|
|
2080
|
-
return ratings.length > 0 ? ratings[0].rating : void 0;
|
|
2149
|
+
return ratings.length > 0 ? normalized(ratings[0].rating) : void 0;
|
|
2081
2150
|
}
|
|
2082
2151
|
setRating(rating, email) {
|
|
2083
2152
|
this.setRatings([{ rating, email, counter: 0 }]);
|
|
@@ -2282,7 +2351,7 @@ var VERSION;
|
|
|
2282
2351
|
var init_version = __esm({
|
|
2283
2352
|
"src/version.ts"() {
|
|
2284
2353
|
"use strict";
|
|
2285
|
-
VERSION = "1.5.
|
|
2354
|
+
VERSION = "1.5.1";
|
|
2286
2355
|
}
|
|
2287
2356
|
});
|
|
2288
2357
|
|
|
@@ -2340,8 +2409,8 @@ function toWasiPath(osPath) {
|
|
|
2340
2409
|
}
|
|
2341
2410
|
let p = osPath;
|
|
2342
2411
|
if (!p.startsWith("/") && !/^[A-Za-z]:/.test(p)) {
|
|
2343
|
-
const
|
|
2344
|
-
const cwd =
|
|
2412
|
+
const g2 = globalThis;
|
|
2413
|
+
const cwd = isDeno() ? Deno.cwd() : g2.process?.cwd?.();
|
|
2345
2414
|
if (cwd) {
|
|
2346
2415
|
p = cwd.replace(/[/\\]+$/, "") + "/" + p;
|
|
2347
2416
|
}
|
|
@@ -2364,6 +2433,7 @@ var init_taglib_class = __esm({
|
|
|
2364
2433
|
"use strict";
|
|
2365
2434
|
init_audio_formats();
|
|
2366
2435
|
init_errors2();
|
|
2436
|
+
init_detector();
|
|
2367
2437
|
init_audio_file_impl();
|
|
2368
2438
|
init_load_audio_data();
|
|
2369
2439
|
init_tag_mapping();
|
|
@@ -13,6 +13,8 @@ export interface RuntimeDetectionResult {
|
|
|
13
13
|
* Pass undefined for non-Node environments (always returns undefined).
|
|
14
14
|
*/
|
|
15
15
|
export declare function checkNodeVersion(nodeVersion: string | undefined): string | undefined;
|
|
16
|
+
/** Shared Deno-runtime check — do not hand-roll `typeof Deno` tests (taglib-rfr). */
|
|
17
|
+
export declare function isDeno(): boolean;
|
|
16
18
|
export declare function detectRuntime(): RuntimeDetectionResult;
|
|
17
19
|
/**
|
|
18
20
|
* Detect whether the runtime supports the Wasm `exnref` type.
|
|
@@ -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;
|
|
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;AAED,gBAAgB;AAChB,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAElE;AAED,gBAAgB;AAChB,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,gBAAgB;AAChB,wBAAgB,mBAAmB,IAAI,sBAAsB,CAG5D"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { RuntimeDetectionResult } from "../detector.js";
|
|
2
2
|
import type { LoadModuleResult, UnifiedLoaderOptions } from "./types.js";
|
|
3
|
+
/** @internal Exported for unit tests (tests/node-fs-acquisition.test.ts). */
|
|
4
|
+
export declare function getPreopens(): Record<string, string>;
|
|
3
5
|
export declare function loadModule(wasmType: "wasi" | "emscripten", runtime: RuntimeDetectionResult, options: UnifiedLoaderOptions): Promise<LoadModuleResult>;
|
|
4
6
|
//# sourceMappingURL=module-loading.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-loading.d.ts","sourceRoot":"","sources":["../../../../src/runtime/unified-loader/module-loading.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"module-loading.d.ts","sourceRoot":"","sources":["../../../../src/runtime/unified-loader/module-loading.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAiBzE,6EAA6E;AAC7E,wBAAgB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBpD;AAOD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,GAAG,YAAY,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAS3B"}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import { supportsExnref } from "../detector.js";
|
|
1
|
+
import { isDeno, supportsExnref } from "../detector.js";
|
|
2
2
|
import { ModuleLoadError } from "./types.js";
|
|
3
3
|
import { errorMessage } from "../../errors/classes.js";
|
|
4
4
|
import { fileUrlToPath } from "../../utils/path.js";
|
|
5
|
+
import { getNodeFsSync } from "../../utils/node-fs.js";
|
|
5
6
|
function isWindows() {
|
|
6
|
-
return
|
|
7
|
+
return isDeno() ? Deno.build.os === "windows" : globalThis.process ? globalThis.process.platform === "win32" : false;
|
|
7
8
|
}
|
|
8
9
|
function getPreopens() {
|
|
9
10
|
if (!isWindows()) return { "/": "/" };
|
|
11
|
+
const statSync = isDeno() ? Deno.statSync : getNodeFsSync()?.statSync;
|
|
12
|
+
if (!statSync) {
|
|
13
|
+
console.warn(
|
|
14
|
+
"[taglib-wasm] Windows drive detection unavailable: node:fs could not be loaded. Only C:\\ is registered as a WASI preopen."
|
|
15
|
+
);
|
|
16
|
+
return { "/C": "C:\\" };
|
|
17
|
+
}
|
|
10
18
|
const preopens = {};
|
|
11
19
|
for (const letter of "CDEFGHIJKLMNOPQRSTUVWXYZAB") {
|
|
12
20
|
const root = `${letter}:\\`;
|
|
13
21
|
try {
|
|
14
|
-
|
|
15
|
-
Deno.statSync(root);
|
|
16
|
-
} else {
|
|
17
|
-
const fs = new Function("return require('node:fs')")();
|
|
18
|
-
fs.statSync(root);
|
|
19
|
-
}
|
|
22
|
+
statSync(root);
|
|
20
23
|
preopens[`/${letter}`] = root;
|
|
21
24
|
} catch {
|
|
22
25
|
}
|
|
@@ -114,5 +117,6 @@ async function loadEmscriptenModule(options) {
|
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
119
|
export {
|
|
120
|
+
getPreopens,
|
|
117
121
|
loadModule
|
|
118
122
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasi-host-loader.d.ts","sourceRoot":"","sources":["../../../src/runtime/wasi-host-loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"wasi-host-loader.d.ts","sourceRoot":"","sources":["../../../src/runtime/wasi-host-loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,EAAE,CAAC,EAAE,kBAAkB,CAAC;CACzB;AAED,qBAAa,iBAAkB,SAAQ,WAAW;gBACpC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAM7C;AAcD,wBAAsB,YAAY,CAChC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC,CAmDlC"}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
} from "./wasi-host.js";
|
|
4
4
|
import { TagLibError } from "../errors/base.js";
|
|
5
5
|
import { fileUrlToPath } from "../utils/path.js";
|
|
6
|
+
import { isDeno } from "./detector.js";
|
|
6
7
|
class WasiHostLoadError extends TagLibError {
|
|
7
8
|
constructor(message, cause) {
|
|
8
9
|
super("WASI_HOST", message, cause ? { cause } : void 0);
|
|
@@ -13,7 +14,7 @@ class WasiHostLoadError extends TagLibError {
|
|
|
13
14
|
}
|
|
14
15
|
async function resolveFs(provided) {
|
|
15
16
|
if (provided) return provided;
|
|
16
|
-
if (
|
|
17
|
+
if (isDeno()) {
|
|
17
18
|
const { createDenoFsProvider } = await import("./wasi-fs-deno.js");
|
|
18
19
|
return createDenoFsProvider();
|
|
19
20
|
}
|
|
@@ -3,8 +3,11 @@ import type { OpenOptions, Picture } from "../types.js";
|
|
|
3
3
|
import type { Chapter, SetChaptersOptions } from "../types/chapters.js";
|
|
4
4
|
import type { BroadcastAudioExtension } from "../types/bwf.js";
|
|
5
5
|
import type { Id3v2Frame, Rating, UnsyncedLyrics } from "../constants/complex-properties.js";
|
|
6
|
+
import { type NormalizedRating } from "../utils/rating.js";
|
|
6
7
|
import type { AudioFile } from "./audio-file-interface.js";
|
|
7
8
|
import { BaseAudioFileImpl } from "./audio-file-base.js";
|
|
9
|
+
/** @internal Exported for unit tests (tests/node-fs-acquisition.test.ts). */
|
|
10
|
+
export declare function readFileSync(path: string): Uint8Array;
|
|
8
11
|
/**
|
|
9
12
|
* Implementation of AudioFile interface using Embind API.
|
|
10
13
|
*
|
|
@@ -33,7 +36,7 @@ export declare class AudioFileImpl extends BaseAudioFileImpl implements AudioFil
|
|
|
33
36
|
setRatings(ratings: Rating[]): void;
|
|
34
37
|
getLyrics(): UnsyncedLyrics[];
|
|
35
38
|
setLyrics(lyrics: UnsyncedLyrics[]): void;
|
|
36
|
-
getRating():
|
|
39
|
+
getRating(): NormalizedRating | undefined;
|
|
37
40
|
setRating(rating: number, email?: string): void;
|
|
38
41
|
getId3v2Frames(id?: string): Id3v2Frame[];
|
|
39
42
|
setId3v2Frames(id: string, data: Uint8Array[]): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-file-impl.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-impl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAGV,YAAY,EACb,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,KAAK,EACV,UAAU,EACV,MAAM,EACN,cAAc,EACf,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"audio-file-impl.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-impl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAGV,YAAY,EACb,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,KAAK,EACV,UAAU,EACV,MAAM,EACN,cAAc,EACf,MAAM,oCAAoC,CAAC;AAc5C,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAoBzD,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CASrD;AAED;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,iBAAkB,YAAW,SAAS;IACvE,OAAO,CAAC,cAAc,CAA2B;gBAG/C,MAAM,EAAE,YAAY,EACpB,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,IAAI,IAAI,OAAO;IAef,aAAa,IAAI,UAAU;IA2BrB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4D9C,WAAW,IAAI,OAAO,EAAE;IAUxB,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI;IAStC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IASlC,cAAc,IAAI,IAAI;IAItB,WAAW,IAAI,OAAO,EAAE;IAYxB,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,IAAI;IAuBpE,OAAO,IAAI,uBAAuB,GAAG,SAAS;IAI9C,OAAO,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI;IAI5C,WAAW,IAAI,UAAU,GAAG,SAAS;IAIrC,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI;IAI1C,OAAO,IAAI,MAAM,GAAG,SAAS;IAI7B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIlC,UAAU,IAAI,MAAM,EAAE;IAUtB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAQnC,SAAS,IAAI,cAAc,EAAE;IAS7B,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI;IAQzC,SAAS,IAAI,gBAAgB,GAAG,SAAS;IAKzC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAI/C,cAAc,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAMzC,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,IAAI;IAOpD,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAMnC,UAAU,IAAI;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE;IAI1C,YAAY,CAAC,IAAI,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;CAM1D"}
|
|
@@ -9,11 +9,17 @@ import {
|
|
|
9
9
|
assertMp3,
|
|
10
10
|
toPublicFrame
|
|
11
11
|
} from "./id3v2-frames.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
errorMessage,
|
|
14
|
+
FileOperationError,
|
|
15
|
+
UnsupportedFormatError
|
|
16
|
+
} from "../errors.js";
|
|
13
17
|
import { writeFileData } from "../utils/write.js";
|
|
18
|
+
import { getNodeFsSync } from "../utils/node-fs.js";
|
|
19
|
+
import { normalized } from "../utils/rating.js";
|
|
20
|
+
import { isDeno } from "../runtime/detector.js";
|
|
14
21
|
import { BaseAudioFileImpl } from "./audio-file-base.js";
|
|
15
22
|
import { saveViaFreshHandle } from "./save-reconstruct.js";
|
|
16
|
-
let _nodeFs;
|
|
17
23
|
function sortChapters(list) {
|
|
18
24
|
return [...list].sort((a, b) => a.startTimeMs - b.startTimeMs);
|
|
19
25
|
}
|
|
@@ -24,16 +30,14 @@ function inferEndTimeMs(sorted, index, trackEndMs) {
|
|
|
24
30
|
return next ? next.startTimeMs : trackEndMs;
|
|
25
31
|
}
|
|
26
32
|
function readFileSync(path) {
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (_nodeFs) return new Uint8Array(_nodeFs.readFileSync(path));
|
|
36
|
-
return new Uint8Array(0);
|
|
33
|
+
if (isDeno()) return Deno.readFileSync(path);
|
|
34
|
+
const fs = getNodeFsSync();
|
|
35
|
+
if (fs) return new Uint8Array(fs.readFileSync(path));
|
|
36
|
+
throw new FileOperationError(
|
|
37
|
+
"read",
|
|
38
|
+
"node:fs is unavailable in this runtime: cannot read file data from disk",
|
|
39
|
+
path
|
|
40
|
+
);
|
|
37
41
|
}
|
|
38
42
|
class AudioFileImpl extends BaseAudioFileImpl {
|
|
39
43
|
constructor(module, fileHandle, sourcePath, originalSource, isPartiallyLoaded = false, partialLoadOptions) {
|
|
@@ -55,6 +59,7 @@ class AudioFileImpl extends BaseAudioFileImpl {
|
|
|
55
59
|
);
|
|
56
60
|
}
|
|
57
61
|
this.cachedAudioProperties = null;
|
|
62
|
+
this.pathModeBuffer = null;
|
|
58
63
|
return this.handle.save();
|
|
59
64
|
}
|
|
60
65
|
getFileBuffer() {
|
|
@@ -65,11 +70,20 @@ class AudioFileImpl extends BaseAudioFileImpl {
|
|
|
65
70
|
try {
|
|
66
71
|
this.pathModeBuffer = readFileSync(this.sourcePath);
|
|
67
72
|
return this.pathModeBuffer;
|
|
68
|
-
} catch {
|
|
69
|
-
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error instanceof FileOperationError) throw error;
|
|
75
|
+
throw new FileOperationError(
|
|
76
|
+
"read",
|
|
77
|
+
`Cannot return file data: ${errorMessage(error)}`,
|
|
78
|
+
this.sourcePath,
|
|
79
|
+
{ cause: error }
|
|
80
|
+
);
|
|
70
81
|
}
|
|
71
82
|
}
|
|
72
|
-
|
|
83
|
+
throw new FileOperationError(
|
|
84
|
+
"read",
|
|
85
|
+
"No file data available: in-memory buffer is empty and no source path is set"
|
|
86
|
+
);
|
|
73
87
|
}
|
|
74
88
|
async saveToFile(path) {
|
|
75
89
|
const targetPath = path ?? this.sourcePath;
|
|
@@ -110,6 +124,7 @@ class AudioFileImpl extends BaseAudioFileImpl {
|
|
|
110
124
|
await writeFileData(targetPath, buffer);
|
|
111
125
|
}
|
|
112
126
|
}
|
|
127
|
+
this.pathModeBuffer = null;
|
|
113
128
|
}
|
|
114
129
|
getPictures() {
|
|
115
130
|
const picturesArray = this.handle.getPictures();
|
|
@@ -221,7 +236,7 @@ class AudioFileImpl extends BaseAudioFileImpl {
|
|
|
221
236
|
}
|
|
222
237
|
getRating() {
|
|
223
238
|
const ratings = this.getRatings();
|
|
224
|
-
return ratings.length > 0 ? ratings[0].rating : void 0;
|
|
239
|
+
return ratings.length > 0 ? normalized(ratings[0].rating) : void 0;
|
|
225
240
|
}
|
|
226
241
|
setRating(rating, email) {
|
|
227
242
|
this.setRatings([{ rating, email, counter: 0 }]);
|
|
@@ -253,5 +268,6 @@ class AudioFileImpl extends BaseAudioFileImpl {
|
|
|
253
268
|
}
|
|
254
269
|
}
|
|
255
270
|
export {
|
|
256
|
-
AudioFileImpl
|
|
271
|
+
AudioFileImpl,
|
|
272
|
+
readFileSync
|
|
257
273
|
};
|
|
@@ -3,6 +3,7 @@ import type { TypedAudioProperties } from "../types/audio-formats.js";
|
|
|
3
3
|
import type { Id3v2Frame, Rating, UnsyncedLyrics } from "../constants/complex-properties.js";
|
|
4
4
|
import type { MutableTag } from "./mutable-tag.js";
|
|
5
5
|
import type { FormatPropertyKey } from "../types/format-property-keys.js";
|
|
6
|
+
import type { NormalizedRating } from "../utils/rating.js";
|
|
6
7
|
/**
|
|
7
8
|
* Represents an audio file with metadata and audio properties.
|
|
8
9
|
* Provides methods for reading and writing metadata, accessing audio properties,
|
|
@@ -39,7 +40,11 @@ export interface AudioFile {
|
|
|
39
40
|
removeMP4Item(key: string): void;
|
|
40
41
|
/** Save all changes to the in-memory buffer. */
|
|
41
42
|
save(): boolean;
|
|
42
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Get the current file data as a buffer, including any modifications.
|
|
45
|
+
* @throws {FileOperationError} If the data lives on disk (WASI path mode)
|
|
46
|
+
* and cannot be read back — never returns an empty buffer on failure.
|
|
47
|
+
*/
|
|
43
48
|
getFileBuffer(): Uint8Array;
|
|
44
49
|
/**
|
|
45
50
|
* Save all changes to a file on disk.
|
|
@@ -87,8 +92,8 @@ export interface AudioFile {
|
|
|
87
92
|
getRatings(): Rating[];
|
|
88
93
|
/** Set ratings in the audio file (replaces all existing). */
|
|
89
94
|
setRatings(ratings: Rating[]): void;
|
|
90
|
-
/** Get the primary rating (first one found), or undefined. */
|
|
91
|
-
getRating():
|
|
95
|
+
/** Get the primary rating (first one found, normalized 0.0-1.0), or undefined. */
|
|
96
|
+
getRating(): NormalizedRating | undefined;
|
|
92
97
|
/** Set the primary rating (normalized 0.0-1.0). */
|
|
93
98
|
setRating(rating: number, email?: string): void;
|
|
94
99
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-file-interface.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,OAAO,EACP,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EACV,UAAU,EACV,MAAM,EACN,cAAc,EACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"audio-file-interface.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taglib-class.d.ts","sourceRoot":"","sources":["../../../src/taglib/taglib-class.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4B,UAAU,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"taglib-class.d.ts","sourceRoot":"","sources":["../../../src/taglib/taglib-class.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4B,UAAU,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AA4C3D;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,UAAU;IAI9B;;;;;OAKG;WACU,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAMrE;;;;;;;OAOG;IACG,IAAI,CACR,KAAK,EAAE,cAAc,EACrB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,SAAS,CAAC;IAiGrB;;;;;;;;;OASG;IACG,IAAI,CACR,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC5C,OAAO,CAAC,IAAI,CAAC;IACV,IAAI,CACR,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI,GAAG,eAAe,EACxD,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC5C,OAAO,CAAC,UAAU,CAAC;IAmBtB;;;;;;OAMG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtE;;;;;;;OAOG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC;IAUhB,oEAAoE;IACpE,OAAO,IAAI,MAAM;IAIjB,OAAO,CAAC,aAAa;CAStB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE"}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
isNamedAudioInput
|
|
6
6
|
} from "../types/audio-formats.js";
|
|
7
7
|
import { InvalidFormatError, TagLibInitializationError } from "../errors.js";
|
|
8
|
+
import { isDeno } from "../runtime/detector.js";
|
|
8
9
|
import { AudioFileImpl } from "./audio-file-impl.js";
|
|
9
10
|
import { loadAudioData } from "./load-audio-data.js";
|
|
10
11
|
import { mergeTagUpdates } from "../utils/tag-mapping.js";
|
|
@@ -21,7 +22,7 @@ function toWasiPath(osPath) {
|
|
|
21
22
|
let p = osPath;
|
|
22
23
|
if (!p.startsWith("/") && !/^[A-Za-z]:/.test(p)) {
|
|
23
24
|
const g = globalThis;
|
|
24
|
-
const cwd =
|
|
25
|
+
const cwd = isDeno() ? Deno.cwd() : g.process?.cwd?.();
|
|
25
26
|
if (cwd) {
|
|
26
27
|
p = cwd.replace(/[/\\]+$/, "") + "/" + p;
|
|
27
28
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synchronous node:fs acquisition that works in every module context
|
|
3
|
+
* (ESM and CJS), including Electron main processes. See taglib-0b5 / GH #24.
|
|
4
|
+
*/
|
|
5
|
+
/** Structural subset of node:fs used by taglib-wasm's sync call sites. */
|
|
6
|
+
export type NodeFsLike = {
|
|
7
|
+
statSync(path: string): unknown;
|
|
8
|
+
readFileSync(path: string): Uint8Array;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Acquire node:fs synchronously without tripping bundlers.
|
|
12
|
+
*
|
|
13
|
+
* `process.getBuiltinModule("node:fs")` is the primary strategy: it is
|
|
14
|
+
* synchronous, works in both ESM and CJS, and exists on every supported
|
|
15
|
+
* runtime (added in Node 22.3.0, backported to 20.16.0; the package's
|
|
16
|
+
* `engines` floor of node >= 22.6.0 gates installs, while Electron's
|
|
17
|
+
* embedded Node has shipped it since Electron 32). The legacy
|
|
18
|
+
* `new Function("return require(...)")` hack evaluates in the GLOBAL scope,
|
|
19
|
+
* where `require` never exists in standard module files — it is kept only as
|
|
20
|
+
* a fallback for contexts that expose `require` globally (Electron renderers
|
|
21
|
+
* with nodeIntegration, node -e, the REPL) on runtimes predating
|
|
22
|
+
* getBuiltinModule. Results are shape-checked so a polyfilled `process`
|
|
23
|
+
* serving junk modules escalates to the next strategy instead of leaking a
|
|
24
|
+
* non-fs object to callers.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getNodeFsSync(): NodeFsLike | null;
|
|
27
|
+
//# sourceMappingURL=node-fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-fs.d.ts","sourceRoot":"","sources":["../../../src/utils/node-fs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,0EAA0E;AAC1E,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;CACxC,CAAC;AAYF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAiBjD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
function hasFsShape(fs) {
|
|
2
|
+
const candidate = fs;
|
|
3
|
+
return typeof candidate?.statSync === "function" && typeof candidate?.readFileSync === "function";
|
|
4
|
+
}
|
|
5
|
+
function getNodeFsSync() {
|
|
6
|
+
const proc = globalThis.process;
|
|
7
|
+
try {
|
|
8
|
+
const fs = proc?.getBuiltinModule?.("node:fs");
|
|
9
|
+
if (hasFsShape(fs)) return fs;
|
|
10
|
+
} catch {
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const fs = new Function("return require('node:fs')")();
|
|
14
|
+
if (hasFsShape(fs)) return fs;
|
|
15
|
+
} catch {
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
getNodeFsSync
|
|
21
|
+
};
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.5.
|
|
1
|
+
export declare const VERSION = "1.5.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/src/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taglib-wasm",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "TagLib-Wasm is the universal tagging library for TypeScript/JavaScript platforms: Browsers, Node.js, Deno, Bun, Cloudflare Workers, and Electron apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|