taglib-wasm 2.1.0 → 2.2.0

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.
Files changed (41) hide show
  1. package/dist/index.browser.js +48 -9
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +2 -4
  5. package/dist/simple.browser.js +97 -10
  6. package/dist/src/constants/properties.d.ts +14 -0
  7. package/dist/src/constants/properties.d.ts.map +1 -1
  8. package/dist/src/constants/specialized-properties.d.ts +14 -0
  9. package/dist/src/constants/specialized-properties.d.ts.map +1 -1
  10. package/dist/src/constants/specialized-properties.js +22 -0
  11. package/dist/src/folder-api/folder-operations.d.ts +2 -30
  12. package/dist/src/folder-api/folder-operations.d.ts.map +1 -1
  13. package/dist/src/folder-api/folder-operations.js +1 -36
  14. package/dist/src/folder-api/index.d.ts +2 -2
  15. package/dist/src/folder-api/index.d.ts.map +1 -1
  16. package/dist/src/folder-api/index.js +2 -7
  17. package/dist/src/folder-api/types.d.ts +0 -21
  18. package/dist/src/folder-api/types.d.ts.map +1 -1
  19. package/dist/src/folder-api/types.js +1 -13
  20. package/dist/src/simple/batch-operations.d.ts +57 -2
  21. package/dist/src/simple/batch-operations.d.ts.map +1 -1
  22. package/dist/src/simple/batch-operations.js +55 -5
  23. package/dist/src/simple/index.d.ts +2 -2
  24. package/dist/src/simple/index.d.ts.map +1 -1
  25. package/dist/src/simple/index.js +6 -2
  26. package/dist/src/simple/tag-operations.d.ts +5 -1
  27. package/dist/src/simple/tag-operations.d.ts.map +1 -1
  28. package/dist/src/simple/tag-operations.js +5 -2
  29. package/dist/src/types/metadata-mappings.d.ts +1 -1
  30. package/dist/src/types/metadata-mappings.d.ts.map +1 -1
  31. package/dist/src/types/metadata-mappings.js +5 -0
  32. package/dist/src/types/tags.d.ts +13 -0
  33. package/dist/src/types/tags.d.ts.map +1 -1
  34. package/dist/src/utils/tag-mapping.d.ts +1 -1
  35. package/dist/src/utils/tag-mapping.d.ts.map +1 -1
  36. package/dist/src/utils/tag-mapping.js +16 -2
  37. package/dist/src/version.d.ts +1 -1
  38. package/dist/src/version.js +1 -1
  39. package/dist/taglib-wasi.wasm +0 -0
  40. package/dist/taglib-web.wasm +0 -0
  41. package/package.json +1 -1
@@ -1387,6 +1387,28 @@ var init_specialized_properties = __esm({
1387
1387
  mp4: "----:com.apple.iTunes:MusicBrainz Album Type"
1388
1388
  }
1389
1389
  },
1390
+ releaseCountry: {
1391
+ key: "RELEASECOUNTRY",
1392
+ description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY",
1393
+ type: "string",
1394
+ supportedFormats: [
1395
+ "ID3v2",
1396
+ "MP4",
1397
+ "Vorbis",
1398
+ "APE",
1399
+ "ASF",
1400
+ "Matroska",
1401
+ "WAV"
1402
+ ],
1403
+ mappings: {
1404
+ id3v2: {
1405
+ frame: "TXXX",
1406
+ description: "MusicBrainz Album Release Country"
1407
+ },
1408
+ vorbis: "RELEASECOUNTRY",
1409
+ mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country"
1410
+ }
1411
+ },
1390
1412
  itunesAdvisory: {
1391
1413
  key: "ITUNESADVISORY",
1392
1414
  description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here",
@@ -2765,8 +2787,9 @@ var init_mirror_fields = __esm({
2765
2787
  });
2766
2788
 
2767
2789
  // src/utils/tag-mapping.ts
2768
- function readExtendedTag(audioFile) {
2769
- const tag = mapPropertiesToExtendedTag(audioFile.properties());
2790
+ function readExtendedTag(audioFile, includeProperties) {
2791
+ const props = audioFile.properties();
2792
+ const tag = mapPropertiesToExtendedTag(props);
2770
2793
  const pictures = audioFile.getPictures();
2771
2794
  if (pictures.length > 0) tag.pictures = pictures;
2772
2795
  const ratings = audioFile.getRatings();
@@ -2781,6 +2804,18 @@ function readExtendedTag(audioFile) {
2781
2804
  if (bextData !== void 0) tag.bextData = bextData;
2782
2805
  const ixml = audioFile.getIxml();
2783
2806
  if (ixml !== void 0) tag.ixml = ixml;
2807
+ if (includeProperties !== void 0 && includeProperties.length > 0) {
2808
+ const extraProperties = {};
2809
+ for (const wireKey of includeProperties) {
2810
+ const values = props[fromTagLibKey(wireKey)]?.filter((v) => v !== "");
2811
+ if (values !== void 0 && values.length > 0) {
2812
+ extraProperties[wireKey] = values;
2813
+ }
2814
+ }
2815
+ if (Object.keys(extraProperties).length > 0) {
2816
+ tag.extraProperties = extraProperties;
2817
+ }
2818
+ }
2784
2819
  return tag;
2785
2820
  }
2786
2821
  function mapPropertiesToExtendedTag(props) {
@@ -2900,6 +2935,7 @@ function normalizeTagInput(input) {
2900
2935
  }
2901
2936
  for (const [field, val] of Object.entries(input)) {
2902
2937
  if (BASIC_FIELDS.has(field) || val === void 0) continue;
2938
+ if (field === "extraProperties") continue;
2903
2939
  if (field === "compilation") {
2904
2940
  props[field] = [val ? "1" : "0"];
2905
2941
  } else if (field === "advisory") {
@@ -2966,7 +3002,7 @@ var VERSION;
2966
3002
  var init_version = __esm({
2967
3003
  "src/version.ts"() {
2968
3004
  "use strict";
2969
- VERSION = "2.1.0";
3005
+ VERSION = "2.2.0";
2970
3006
  }
2971
3007
  });
2972
3008
 
@@ -3321,8 +3357,11 @@ async function withAudioFileSaveToFile(file, fn) {
3321
3357
  }
3322
3358
 
3323
3359
  // src/simple/tag-operations.ts
3324
- async function readTags(file) {
3325
- return withAudioFile(file, (audioFile) => readExtendedTag(audioFile));
3360
+ async function readTags(file, options = {}) {
3361
+ return withAudioFile(
3362
+ file,
3363
+ (audioFile) => readExtendedTag(audioFile, options.includeProperties)
3364
+ );
3326
3365
  }
3327
3366
  async function applyTags(file, tags) {
3328
3367
  return withAudioFileSave(file, (audioFile) => {
@@ -3500,7 +3539,7 @@ async function readTagsBatch(files, options = {}) {
3500
3539
  return executeBatch(
3501
3540
  files,
3502
3541
  options,
3503
- (audioFile) => readExtendedTag(audioFile)
3542
+ (audioFile) => readExtendedTag(audioFile, options.includeProperties)
3504
3543
  );
3505
3544
  }
3506
3545
  async function readPropertiesBatch(files, options = {}) {
@@ -3529,7 +3568,7 @@ function extractDynamics(audioFile) {
3529
3568
  if (appleSoundCheck) dynamics.appleSoundCheck = appleSoundCheck;
3530
3569
  return Object.keys(dynamics).length > 0 ? dynamics : void 0;
3531
3570
  }
3532
- async function readMetadata(file) {
3571
+ async function readMetadata(file, options = {}) {
3533
3572
  const taglib = await getTagLib();
3534
3573
  const audioFile = await taglib.open(file);
3535
3574
  try {
@@ -3550,7 +3589,7 @@ async function readMetadata(file) {
3550
3589
  }
3551
3590
  const dynamics = extractDynamics(audioFile);
3552
3591
  return {
3553
- tags: readExtendedTag(audioFile),
3592
+ tags: readExtendedTag(audioFile, options.includeProperties),
3554
3593
  properties: audioFile.audioProperties(),
3555
3594
  hasCoverArt: audioFile.getPictures().length > 0,
3556
3595
  ...dynamics !== void 0 ? { dynamics } : {}
@@ -3563,7 +3602,7 @@ async function readMetadataBatch(files, options = {}) {
3563
3602
  return executeBatch(files, options, (audioFile) => {
3564
3603
  const dynamics = extractDynamics(audioFile);
3565
3604
  return {
3566
- tags: readExtendedTag(audioFile),
3605
+ tags: readExtendedTag(audioFile, options.includeProperties),
3567
3606
  properties: audioFile.audioProperties(),
3568
3607
  hasCoverArt: audioFile.getPictures().length > 0,
3569
3608
  ...dynamics !== void 0 ? { dynamics } : {}
package/dist/index.d.ts CHANGED
@@ -43,7 +43,7 @@ export { addPicture, applyCoverArt, applyPictures, applyTags, applyTagsToFile, t
43
43
  export { FormatMappings, getAllProperties, getAllPropertyKeys, getPropertiesByFormat, getPropertyMetadata, isValidProperty, PROPERTIES, propertyValue, propertyValues, } from "./src/constants.js";
44
44
  export type { PropertyMetadata } from "./src/constants/property-types.js";
45
45
  export { copyCoverArt, exportAllPictures, exportCoverArt, exportPictureByType, findCoverArtFiles, importCoverArt, importPictureWithType, loadPictureFromFile, savePictureToFile, } from "./src/file-utils/index.js";
46
- export { type AlbumDisc, type AlbumGroup, type AlbumGroupingResult, type AlbumGroupItem, type AlbumGroupKey, type AudioDynamics, type AudioFileMetadata, type DiscConfidence, type DiscFolderInfo, discFolderInfo, type DuplicateGroup, exportFolderMetadata, findDuplicates, type FolderScanItem, type FolderScanOptions, type FolderScanResult, type FolderUpdateItem, type FolderUpdateResult, groupAlbums, type GroupAlbumsOptions, scanFolder, scanForAlbums, type ScanForAlbumsOptions, updateFolderTags, } from "./src/folder-api/index.js";
46
+ export { type AlbumDisc, type AlbumGroup, type AlbumGroupingResult, type AlbumGroupItem, type AlbumGroupKey, type AudioDynamics, type AudioFileMetadata, type DiscConfidence, type DiscFolderInfo, discFolderInfo, type DuplicateGroup, exportFolderMetadata, findDuplicates, type FolderScanItem, type FolderScanOptions, type FolderScanResult, groupAlbums, type GroupAlbumsOptions, scanFolder, scanForAlbums, type ScanForAlbumsOptions, } from "./src/folder-api/index.js";
47
47
  export { canvasToPicture, createPictureDownloadURL, createPictureGallery, dataURLToPicture, displayPicture, imageFileToPicture, pictureToDataURL, setCoverArtFromCanvas, } from "./src/web-utils/index.js";
48
48
  export type { AudioCodec, AudioFileInput, AudioProperties, BitrateControlMode, BroadcastAudioExtension, Chapter, ContainerFormat, ExtendedTag, FieldMapping, FileType, NamedAudioInput, OpenOptions, Picture, PictureType, PropertyMap, SetChaptersOptions, Tag, TagInput, } from "./src/types.js";
49
49
  export { BITRATE_CONTROL_MODE_NAMES, BITRATE_CONTROL_MODE_VALUES, PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES, } from "./src/types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,YAAY,EACV,SAAS,EACT,cAAc,GACf,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGvD,OAAO,EACL,wBAAwB,EACxB,cAAc,EACd,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,SAAS,EACT,eAAe,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,aAAa,EACb,SAAS,EACT,KAAK,YAAY,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,aAAa,EACb,oBAAoB,EACpB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,UAAU,EACV,aAAa,EACb,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAG1E,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,cAAc,EACd,KAAK,cAAc,EACnB,oBAAoB,EACpB,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,WAAW,EACX,KAAK,kBAAkB,EACvB,UAAU,EACV,aAAa,EACb,KAAK,oBAAoB,GAC1B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EACV,UAAU,EACV,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,uBAAuB,EACvB,OAAO,EACP,eAAe,EACf,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,GAAG,EACH,QAAQ,GACT,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACrE,YAAY,EACV,iBAAiB,EACjB,SAAS,GACV,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAKzE,YAAY,EACV,UAAU,EACV,MAAM,EACN,cAAc,EACd,UAAU,GACX,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAG1E,OAAO,KAAK,GAAG,MAAM,mBAAmB,CAAC;AAGzC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC"}
package/dist/index.js CHANGED
@@ -75,8 +75,7 @@ import {
75
75
  findDuplicates,
76
76
  groupAlbums,
77
77
  scanFolder,
78
- scanForAlbums,
79
- updateFolderTags
78
+ scanForAlbums
80
79
  } from "./src/folder-api/index.js";
81
80
  import {
82
81
  canvasToPicture,
@@ -180,6 +179,5 @@ export {
180
179
  scanFolder,
181
180
  scanForAlbums,
182
181
  setBufferMode,
183
- setCoverArtFromCanvas,
184
- updateFolderTags
182
+ setCoverArtFromCanvas
185
183
  };
@@ -1319,6 +1319,28 @@ var init_specialized_properties = __esm({
1319
1319
  mp4: "----:com.apple.iTunes:MusicBrainz Album Type"
1320
1320
  }
1321
1321
  },
1322
+ releaseCountry: {
1323
+ key: "RELEASECOUNTRY",
1324
+ description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY",
1325
+ type: "string",
1326
+ supportedFormats: [
1327
+ "ID3v2",
1328
+ "MP4",
1329
+ "Vorbis",
1330
+ "APE",
1331
+ "ASF",
1332
+ "Matroska",
1333
+ "WAV"
1334
+ ],
1335
+ mappings: {
1336
+ id3v2: {
1337
+ frame: "TXXX",
1338
+ description: "MusicBrainz Album Release Country"
1339
+ },
1340
+ vorbis: "RELEASECOUNTRY",
1341
+ mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country"
1342
+ }
1343
+ },
1322
1344
  itunesAdvisory: {
1323
1345
  key: "ITUNESADVISORY",
1324
1346
  description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here",
@@ -2697,8 +2719,9 @@ var init_mirror_fields = __esm({
2697
2719
  });
2698
2720
 
2699
2721
  // src/utils/tag-mapping.ts
2700
- function readExtendedTag(audioFile) {
2701
- const tag = mapPropertiesToExtendedTag(audioFile.properties());
2722
+ function readExtendedTag(audioFile, includeProperties) {
2723
+ const props = audioFile.properties();
2724
+ const tag = mapPropertiesToExtendedTag(props);
2702
2725
  const pictures = audioFile.getPictures();
2703
2726
  if (pictures.length > 0) tag.pictures = pictures;
2704
2727
  const ratings = audioFile.getRatings();
@@ -2713,6 +2736,18 @@ function readExtendedTag(audioFile) {
2713
2736
  if (bextData !== void 0) tag.bextData = bextData;
2714
2737
  const ixml = audioFile.getIxml();
2715
2738
  if (ixml !== void 0) tag.ixml = ixml;
2739
+ if (includeProperties !== void 0 && includeProperties.length > 0) {
2740
+ const extraProperties = {};
2741
+ for (const wireKey of includeProperties) {
2742
+ const values = props[fromTagLibKey(wireKey)]?.filter((v) => v !== "");
2743
+ if (values !== void 0 && values.length > 0) {
2744
+ extraProperties[wireKey] = values;
2745
+ }
2746
+ }
2747
+ if (Object.keys(extraProperties).length > 0) {
2748
+ tag.extraProperties = extraProperties;
2749
+ }
2750
+ }
2716
2751
  return tag;
2717
2752
  }
2718
2753
  function mapPropertiesToExtendedTag(props) {
@@ -2832,6 +2867,7 @@ function normalizeTagInput(input) {
2832
2867
  }
2833
2868
  for (const [field, val] of Object.entries(input)) {
2834
2869
  if (BASIC_FIELDS.has(field) || val === void 0) continue;
2870
+ if (field === "extraProperties") continue;
2835
2871
  if (field === "compilation") {
2836
2872
  props[field] = [val ? "1" : "0"];
2837
2873
  } else if (field === "advisory") {
@@ -2898,7 +2934,7 @@ var VERSION;
2898
2934
  var init_version = __esm({
2899
2935
  "src/version.ts"() {
2900
2936
  "use strict";
2901
- VERSION = "2.1.0";
2937
+ VERSION = "2.2.0";
2902
2938
  }
2903
2939
  });
2904
2940
 
@@ -3247,8 +3283,11 @@ async function withAudioFileSaveToFile(file, fn) {
3247
3283
  }
3248
3284
 
3249
3285
  // src/simple/tag-operations.ts
3250
- async function readTags(file) {
3251
- return withAudioFile(file, (audioFile) => readExtendedTag(audioFile));
3286
+ async function readTags(file, options = {}) {
3287
+ return withAudioFile(
3288
+ file,
3289
+ (audioFile) => readExtendedTag(audioFile, options.includeProperties)
3290
+ );
3252
3291
  }
3253
3292
  async function applyTags(file, tags) {
3254
3293
  return withAudioFileSave(file, (audioFile) => {
@@ -3426,7 +3465,7 @@ async function readTagsBatch(files, options = {}) {
3426
3465
  return executeBatch(
3427
3466
  files,
3428
3467
  options,
3429
- (audioFile) => readExtendedTag(audioFile)
3468
+ (audioFile) => readExtendedTag(audioFile, options.includeProperties)
3430
3469
  );
3431
3470
  }
3432
3471
  async function readPropertiesBatch(files, options = {}) {
@@ -3455,7 +3494,7 @@ function extractDynamics(audioFile) {
3455
3494
  if (appleSoundCheck) dynamics.appleSoundCheck = appleSoundCheck;
3456
3495
  return Object.keys(dynamics).length > 0 ? dynamics : void 0;
3457
3496
  }
3458
- async function readMetadata(file) {
3497
+ async function readMetadata(file, options = {}) {
3459
3498
  const taglib = await getTagLib();
3460
3499
  const audioFile = await taglib.open(file);
3461
3500
  try {
@@ -3476,7 +3515,7 @@ async function readMetadata(file) {
3476
3515
  }
3477
3516
  const dynamics = extractDynamics(audioFile);
3478
3517
  return {
3479
- tags: readExtendedTag(audioFile),
3518
+ tags: readExtendedTag(audioFile, options.includeProperties),
3480
3519
  properties: audioFile.audioProperties(),
3481
3520
  hasCoverArt: audioFile.getPictures().length > 0,
3482
3521
  ...dynamics !== void 0 ? { dynamics } : {}
@@ -3489,13 +3528,59 @@ async function readMetadataBatch(files, options = {}) {
3489
3528
  return executeBatch(files, options, (audioFile) => {
3490
3529
  const dynamics = extractDynamics(audioFile);
3491
3530
  return {
3492
- tags: readExtendedTag(audioFile),
3531
+ tags: readExtendedTag(audioFile, options.includeProperties),
3493
3532
  properties: audioFile.audioProperties(),
3494
3533
  hasCoverArt: audioFile.getPictures().length > 0,
3495
3534
  ...dynamics !== void 0 ? { dynamics } : {}
3496
3535
  };
3497
3536
  });
3498
3537
  }
3538
+ function entryPath(entry) {
3539
+ return typeof entry === "string" ? entry : entry.path;
3540
+ }
3541
+ async function executeWriteBatch(entries, options, writer) {
3542
+ if (entries.length === 0) return { items: [], duration: 0 };
3543
+ await getTagLib();
3544
+ const startTime = Date.now();
3545
+ const { concurrency = 4, continueOnError = true, onProgress, signal } = options;
3546
+ const items = new Array(entries.length);
3547
+ let processed = 0;
3548
+ const total = entries.length;
3549
+ for (let i = 0; i < entries.length; i += concurrency) {
3550
+ signal?.throwIfAborted();
3551
+ const chunk = entries.slice(i, i + concurrency);
3552
+ const chunkPromises = chunk.map(async (entry, idx) => {
3553
+ const index = i + idx;
3554
+ const path = entryPath(entry);
3555
+ try {
3556
+ await writer(path);
3557
+ items[index] = { status: "ok", path, data: void 0 };
3558
+ } catch (error) {
3559
+ const err = error instanceof Error ? error : new Error(String(error));
3560
+ items[index] = { status: "error", path, error: err };
3561
+ if (!continueOnError) throw err;
3562
+ }
3563
+ processed++;
3564
+ onProgress?.(processed, total, path);
3565
+ });
3566
+ await Promise.all(chunkPromises);
3567
+ }
3568
+ return { items, duration: Date.now() - startTime };
3569
+ }
3570
+ async function writeTagsBatch(updates, options = {}) {
3571
+ const byPath = new Map(updates.map((u) => [u.path, u]));
3572
+ return executeWriteBatch(updates, options, (path) => {
3573
+ const update = byPath.get(path);
3574
+ return applyTagsToFile(path, update.tags);
3575
+ });
3576
+ }
3577
+ async function editTagsBatch(files, mutator, options = {}) {
3578
+ return executeWriteBatch(
3579
+ files,
3580
+ options,
3581
+ (path) => withAudioFileSaveToFile(path, mutator)
3582
+ );
3583
+ }
3499
3584
 
3500
3585
  // src/simple/index.ts
3501
3586
  init_types2();
@@ -3509,6 +3594,7 @@ export {
3509
3594
  applyTagsToFile,
3510
3595
  clearPictures,
3511
3596
  clearTags,
3597
+ editTagsBatch,
3512
3598
  findPictureByType,
3513
3599
  getTagLib,
3514
3600
  isValidAudioFile,
@@ -3523,5 +3609,6 @@ export {
3523
3609
  readTags,
3524
3610
  readTagsBatch,
3525
3611
  replacePictureByType,
3526
- setBufferMode
3612
+ setBufferMode,
3613
+ writeTagsBatch
3527
3614
  };
@@ -311,6 +311,20 @@ export declare const PROPERTIES: {
311
311
  readonly mp4: "----:com.apple.iTunes:MusicBrainz Album Type";
312
312
  };
313
313
  };
314
+ readonly releaseCountry: {
315
+ readonly key: "RELEASECOUNTRY";
316
+ readonly description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY";
317
+ readonly type: "string";
318
+ readonly supportedFormats: readonly ["ID3v2", "MP4", "Vorbis", "APE", "ASF", "Matroska", "WAV"];
319
+ readonly mappings: {
320
+ readonly id3v2: {
321
+ readonly frame: "TXXX";
322
+ readonly description: "MusicBrainz Album Release Country";
323
+ };
324
+ readonly vorbis: "RELEASECOUNTRY";
325
+ readonly mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country";
326
+ };
327
+ };
314
328
  readonly itunesAdvisory: {
315
329
  readonly key: "ITUNESADVISORY";
316
330
  readonly description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here";
@@ -1 +1 @@
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;AAkDb,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,CASnB;AAGD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
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;AAkDb,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,CASnB;AAGD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -73,6 +73,20 @@ export declare const SPECIALIZED_PROPERTIES: {
73
73
  readonly mp4: "----:com.apple.iTunes:MusicBrainz Album Type";
74
74
  };
75
75
  };
76
+ readonly releaseCountry: {
77
+ readonly key: "RELEASECOUNTRY";
78
+ readonly description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY";
79
+ readonly type: "string";
80
+ readonly supportedFormats: readonly ["ID3v2", "MP4", "Vorbis", "APE", "ASF", "Matroska", "WAV"];
81
+ readonly mappings: {
82
+ readonly id3v2: {
83
+ readonly frame: "TXXX";
84
+ readonly description: "MusicBrainz Album Release Country";
85
+ };
86
+ readonly vorbis: "RELEASECOUNTRY";
87
+ readonly mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country";
88
+ };
89
+ };
76
90
  readonly itunesAdvisory: {
77
91
  readonly key: "ITUNESADVISORY";
78
92
  readonly description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here";
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwLjC;;;;;;;;OAQG;;;;;;;;;;;;;;;CAYK,CAAC"}
1
+ {"version":3,"file":"specialized-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/specialized-properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+MjC;;;;;;;;OAQG;;;;;;;;;;;;;;;CAYK,CAAC"}
@@ -62,6 +62,28 @@ const SPECIALIZED_PROPERTIES = {
62
62
  mp4: "----:com.apple.iTunes:MusicBrainz Album Type"
63
63
  }
64
64
  },
65
+ releaseCountry: {
66
+ key: "RELEASECOUNTRY",
67
+ description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY",
68
+ type: "string",
69
+ supportedFormats: [
70
+ "ID3v2",
71
+ "MP4",
72
+ "Vorbis",
73
+ "APE",
74
+ "ASF",
75
+ "Matroska",
76
+ "WAV"
77
+ ],
78
+ mappings: {
79
+ id3v2: {
80
+ frame: "TXXX",
81
+ description: "MusicBrainz Album Release Country"
82
+ },
83
+ vorbis: "RELEASECOUNTRY",
84
+ mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country"
85
+ }
86
+ },
65
87
  itunesAdvisory: {
66
88
  key: "ITUNESADVISORY",
67
89
  description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here",
@@ -1,35 +1,7 @@
1
1
  /**
2
- * Folder-level operations: batch updates, duplicates, metadata export
2
+ * Folder-level operations: duplicates, metadata export
3
3
  */
4
- import type { TagInput } from "../simple/index.js";
5
- import type { DuplicateGroup, FolderScanOptions, FolderUpdateResult } from "./types.js";
6
- /**
7
- * Update metadata for multiple files in a folder
8
- *
9
- * @param updates - Array of objects containing path and tags to update
10
- * @param options - Update options
11
- * @returns Results of the update operation
12
- *
13
- * @example
14
- * ```typescript
15
- * const updates = [
16
- * { path: "/music/song1.mp3", tags: { artist: "New Artist" } },
17
- * { path: "/music/song2.mp3", tags: { album: "New Album" } }
18
- * ];
19
- *
20
- * const result = await updateFolderTags(updates);
21
- * const updated = result.items.filter((i) => i.status === "ok").length;
22
- * console.log(`Updated ${updated} files`);
23
- * ```
24
- */
25
- export declare function updateFolderTags(updates: Array<{
26
- path: string;
27
- tags: Partial<TagInput>;
28
- }>, options?: {
29
- continueOnError?: boolean;
30
- concurrency?: number;
31
- signal?: AbortSignal;
32
- }): Promise<FolderUpdateResult>;
4
+ import type { DuplicateGroup, FolderScanOptions } from "./types.js";
33
5
  /**
34
6
  * Find duplicate audio files based on metadata
35
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"folder-operations.d.ts","sourceRoot":"","sources":["../../../src/folder-api/folder-operations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAO,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAKxD,OAAO,KAAK,EAEV,cAAc,EACd,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;CAAE,CAAC,EACzD,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;CACjB,GACL,OAAO,CAAC,kBAAkB,CAAC,CAgC7B;AAiBD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,cAAc,EAAE,CAAC,CAuB3B;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBf"}
1
+ {"version":3,"file":"folder-operations.d.ts","sourceRoot":"","sources":["../../../src/folder-api/folder-operations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAEV,cAAc,EACd,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAiBpB;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,cAAc,EAAE,CAAC,CAuB3B;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBf"}
@@ -1,39 +1,5 @@
1
- import { applyTagsToFile } from "../simple/index.js";
2
1
  import { writeFileData } from "../utils/write.js";
3
- import { processBatch } from "./file-processors.js";
4
2
  import { scanFolder } from "./scan-operations.js";
5
- import { EMPTY_TAG } from "./types.js";
6
- async function updateFolderTags(updates, options = {}) {
7
- const startTime = Date.now();
8
- const { continueOnError = true, concurrency = 4, signal } = options;
9
- const items = [];
10
- const batchSize = concurrency * 10;
11
- for (let i = 0; i < updates.length; i += batchSize) {
12
- signal?.throwIfAborted();
13
- const batch = updates.slice(i, Math.min(i + batchSize, updates.length));
14
- const updateMap = new Map(batch.map((u) => [u.path, u]));
15
- await processBatch(
16
- batch.map((u) => u.path),
17
- async (path) => {
18
- const update = updateMap.get(path);
19
- try {
20
- await applyTagsToFile(update.path, update.tags);
21
- items.push({ status: "ok", path: update.path });
22
- } catch (error) {
23
- const err = error instanceof Error ? error : new Error(String(error));
24
- if (continueOnError) {
25
- items.push({ status: "error", path: update.path, error: err });
26
- } else {
27
- throw err;
28
- }
29
- }
30
- return { path, tags: EMPTY_TAG };
31
- },
32
- concurrency
33
- );
34
- }
35
- return { items, duration: Date.now() - startTime };
36
- }
37
3
  function buildCriteriaKey(tags, criteria) {
38
4
  const record = {};
39
5
  for (const field of criteria) {
@@ -84,6 +50,5 @@ async function exportFolderMetadata(folderPath, outputPath, options) {
84
50
  }
85
51
  export {
86
52
  exportFolderMetadata,
87
- findDuplicates,
88
- updateFolderTags
53
+ findDuplicates
89
54
  };
@@ -2,9 +2,9 @@
2
2
  * Batch folder operations for TagLib-Wasm
3
3
  * Provides APIs for scanning directories and processing multiple audio files
4
4
  */
5
- export type { AudioDynamics, AudioFileMetadata, DuplicateGroup, FolderScanItem, FolderScanOptions, FolderScanResult, FolderUpdateItem, FolderUpdateResult, } from "./types.js";
5
+ export type { AudioDynamics, AudioFileMetadata, DuplicateGroup, FolderScanItem, FolderScanOptions, FolderScanResult, } from "./types.js";
6
6
  export { scanFolder } from "./scan-operations.js";
7
- export { exportFolderMetadata, findDuplicates, updateFolderTags, } from "./folder-operations.js";
7
+ export { exportFolderMetadata, findDuplicates } from "./folder-operations.js";
8
8
  export { type AlbumDisc, type AlbumGroup, type AlbumGroupingResult, type AlbumGroupItem, type AlbumGroupKey, type DiscConfidence, type DiscFolderInfo, discFolderInfo, groupAlbums, type GroupAlbumsOptions, } from "./group-albums.js";
9
9
  export { scanForAlbums, type ScanForAlbumsOptions } from "./scan-for-albums.js";
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/folder-api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,cAAc,EACd,WAAW,EACX,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/folder-api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,cAAc,EACd,WAAW,EACX,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,9 +1,5 @@
1
1
  import { scanFolder } from "./scan-operations.js";
2
- import {
3
- exportFolderMetadata,
4
- findDuplicates,
5
- updateFolderTags
6
- } from "./folder-operations.js";
2
+ import { exportFolderMetadata, findDuplicates } from "./folder-operations.js";
7
3
  import {
8
4
  discFolderInfo,
9
5
  groupAlbums
@@ -15,6 +11,5 @@ export {
15
11
  findDuplicates,
16
12
  groupAlbums,
17
13
  scanFolder,
18
- scanForAlbums,
19
- updateFolderTags
14
+ scanForAlbums
20
15
  };
@@ -4,15 +4,6 @@
4
4
  import type { ExtendedTag, Tag, TagInput } from "../simple/index.js";
5
5
  import type { AudioProperties } from "../types.js";
6
6
  export type { AudioProperties, ExtendedTag, Tag, TagInput };
7
- export declare const EMPTY_TAG: Readonly<{
8
- title: never[];
9
- artist: never[];
10
- album: never[];
11
- comment: never[];
12
- genre: never[];
13
- year: number;
14
- track: number;
15
- }>;
16
7
  export declare const DEFAULT_AUDIO_EXTENSIONS: string[];
17
8
  /**
18
9
  * Audio dynamics data (ReplayGain and Apple Sound Check)
@@ -87,18 +78,6 @@ export interface FolderScanResult {
87
78
  /** Time taken in milliseconds */
88
79
  duration: number;
89
80
  }
90
- export type FolderUpdateItem = {
91
- status: "ok";
92
- path: string;
93
- } | {
94
- status: "error";
95
- path: string;
96
- error: Error;
97
- };
98
- export interface FolderUpdateResult {
99
- items: FolderUpdateItem[];
100
- duration: number;
101
- }
102
81
  export interface DuplicateGroup {
103
82
  criteria: Record<string, string>;
104
83
  files: AudioFileMetadata[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/folder-api/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/folder-api/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;AAE5D,eAAO,MAAM,wBAAwB,UAiBpC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,IAAI,EAAE,WAAW,CAAC;IAClB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5B,qEAAqE;IACrE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,CAAC;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,GAAG,iBAAiB,CAAC,GACtC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB"}
@@ -1,14 +1,3 @@
1
- const EMPTY_TAG = Object.freeze(
2
- {
3
- title: [],
4
- artist: [],
5
- album: [],
6
- comment: [],
7
- genre: [],
8
- year: 0,
9
- track: 0
10
- }
11
- );
12
1
  const DEFAULT_AUDIO_EXTENSIONS = [
13
2
  ".mp3",
14
3
  ".m4a",
@@ -28,6 +17,5 @@ const DEFAULT_AUDIO_EXTENSIONS = [
28
17
  ".webm"
29
18
  ];
30
19
  export {
31
- DEFAULT_AUDIO_EXTENSIONS,
32
- EMPTY_TAG
20
+ DEFAULT_AUDIO_EXTENSIONS
33
21
  };
@@ -1,5 +1,6 @@
1
+ import type { AudioFile } from "../taglib.js";
1
2
  import type { AudioDynamics } from "../folder-api/types.js";
2
- import type { AudioFileInput, AudioProperties, ExtendedTag } from "../types.js";
3
+ import type { AudioFileInput, AudioProperties, ExtendedTag, TagInput } from "../types.js";
3
4
  /** Configuration for batch processing operations. */
4
5
  export interface BatchOptions {
5
6
  concurrency?: number;
@@ -7,6 +8,13 @@ export interface BatchOptions {
7
8
  onProgress?: (processed: number, total: number, currentFile: string) => void;
8
9
  /** AbortSignal to cancel the batch operation between chunks. */
9
10
  signal?: AbortSignal;
11
+ /**
12
+ * Raw WIRE keys (e.g. "CATALOGNUMBER") to surface per item under
13
+ * `extraProperties`, for keys outside the modeled typed set (taglib-3s1f).
14
+ * The PropertyMap is already fetched per file, so this costs no extra
15
+ * opens on either backend. Absent keys are omitted, not empty arrays.
16
+ */
17
+ includeProperties?: string[];
10
18
  }
11
19
  /** Discriminated union result for a single file in a batch operation. */
12
20
  export type BatchItem<T> = {
@@ -52,10 +60,14 @@ export interface FileMetadata {
52
60
  * Read complete metadata (tags, properties, cover art, dynamics) from a single file.
53
61
  *
54
62
  * @param file - A file path, Uint8Array, ArrayBuffer, File object, or NamedAudioInput.
63
+ * @param options - Read options; `includeProperties` (wire keys) surfaces raw
64
+ * values in `tags.extraProperties` (taglib-3s1f).
55
65
  * @returns The file's complete metadata.
56
66
  * @throws `InvalidFormatError` if the file is corrupted or in an unsupported format.
57
67
  */
58
- export declare function readMetadata(file: AudioFileInput): Promise<FileMetadata>;
68
+ export declare function readMetadata(file: AudioFileInput, options?: {
69
+ includeProperties?: string[];
70
+ }): Promise<FileMetadata>;
59
71
  /**
60
72
  * Read complete metadata from multiple files with configurable concurrency.
61
73
  *
@@ -65,4 +77,47 @@ export declare function readMetadata(file: AudioFileInput): Promise<FileMetadata
65
77
  * @throws If `continueOnError` is `false` and any file fails to process.
66
78
  */
67
79
  export declare function readMetadataBatch(files: AudioFileInput[], options?: BatchOptions): Promise<BatchResult<FileMetadata>>;
80
+ /** One file to update in a {@link writeTagsBatch} call. */
81
+ export interface WriteTagUpdate {
82
+ /** File path on disk; the file is updated in place. */
83
+ path: string;
84
+ /**
85
+ * Partial tag fields to merge with the file's existing metadata. An empty
86
+ * object performs a save with no tag changes (a no-op rewrite).
87
+ */
88
+ tags: Partial<TagInput>;
89
+ }
90
+ /**
91
+ * Apply tag updates to multiple files with configurable concurrency.
92
+ *
93
+ * The batch write counterpart to {@link readTagsBatch}: same
94
+ * {@link BatchOptions} contract (concurrency, continueOnError, onProgress,
95
+ * signal). Each file is updated via the same path as
96
+ * {@link applyTagsToFile} — merge semantics, atomic temp-file save, so a
97
+ * failed file is left in its pre-write state.
98
+ *
99
+ * @param updates - Per-file tag updates; a path may appear more than once
100
+ * (the last update for a path wins).
101
+ * @param options - Batch processing options (concurrency, error handling,
102
+ * progress, abort).
103
+ * @returns A `BatchItem` per update in input order plus total duration in ms.
104
+ * @throws If `continueOnError` is `false` and any file fails to process.
105
+ */
106
+ export declare function writeTagsBatch(updates: WriteTagUpdate[], options?: BatchOptions): Promise<BatchResult<void>>;
107
+ /**
108
+ * Open, mutate, and save multiple files with configurable concurrency.
109
+ *
110
+ * Mutator-callback variant of {@link writeTagsBatch}: the callback receives
111
+ * the open {@link AudioFile} (Full-API style) and its changes are saved per
112
+ * file. Same {@link BatchOptions} contract and atomicity guarantees.
113
+ *
114
+ * @param files - File paths on disk, updated in place.
115
+ * @param mutator - Called once per file with the open audio file; changes are
116
+ * saved automatically.
117
+ * @param options - Batch processing options (concurrency, error handling,
118
+ * progress, abort).
119
+ * @returns A `BatchItem` per file in input order plus total duration in ms.
120
+ * @throws If `continueOnError` is `false` and any file fails to process.
121
+ */
122
+ export declare function editTagsBatch(files: string[], mutator: (audioFile: AudioFile) => void, options?: BatchOptions): Promise<BatchResult<void>>;
68
123
  //# sourceMappingURL=batch-operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"batch-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/batch-operations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAMhF,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,gEAAgE;IAChE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,yEAAyE;AACzE,MAAM,MAAM,SAAS,CAAC,CAAC,IACnB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpD,mEAAmE;AACnE,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAyDD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAMnC;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC,CAMnD;AAED,oHAAoH;AACpH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAsBD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,YAAY,CAAC,CA6BvB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAUpC"}
1
+ {"version":3,"file":"batch-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/batch-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,QAAQ,EACT,MAAM,aAAa,CAAC;AAQrB,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,gEAAgE;IAChE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,yEAAyE;AACzE,MAAM,MAAM,SAAS,CAAC,CAAC,IACnB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpD,mEAAmE;AACnE,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAyDD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAMnC;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC,CAMnD;AAED,oHAAoH;AACpH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAsBD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,EACpB,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GAC7C,OAAO,CAAC,YAAY,CAAC,CA6BvB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAUpC;AAED,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;CACzB;AAsDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAM5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,EACvC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAM5B"}
@@ -1,6 +1,8 @@
1
1
  import { isNamedAudioInput } from "../types/audio-formats.js";
2
2
  import { InvalidFormatError } from "../errors.js";
3
3
  import { readExtendedTag } from "../utils/tag-mapping.js";
4
+ import { applyTagsToFile } from "./tag-operations.js";
5
+ import { withAudioFileSaveToFile } from "./with-audio-file.js";
4
6
  import { getTagLib } from "./config.js";
5
7
  async function executeBatch(files, options, processor) {
6
8
  if (files.length === 0) return { items: [], duration: 0 };
@@ -48,7 +50,7 @@ async function readTagsBatch(files, options = {}) {
48
50
  return executeBatch(
49
51
  files,
50
52
  options,
51
- (audioFile) => readExtendedTag(audioFile)
53
+ (audioFile) => readExtendedTag(audioFile, options.includeProperties)
52
54
  );
53
55
  }
54
56
  async function readPropertiesBatch(files, options = {}) {
@@ -77,7 +79,7 @@ function extractDynamics(audioFile) {
77
79
  if (appleSoundCheck) dynamics.appleSoundCheck = appleSoundCheck;
78
80
  return Object.keys(dynamics).length > 0 ? dynamics : void 0;
79
81
  }
80
- async function readMetadata(file) {
82
+ async function readMetadata(file, options = {}) {
81
83
  const taglib = await getTagLib();
82
84
  const audioFile = await taglib.open(file);
83
85
  try {
@@ -98,7 +100,7 @@ async function readMetadata(file) {
98
100
  }
99
101
  const dynamics = extractDynamics(audioFile);
100
102
  return {
101
- tags: readExtendedTag(audioFile),
103
+ tags: readExtendedTag(audioFile, options.includeProperties),
102
104
  properties: audioFile.audioProperties(),
103
105
  hasCoverArt: audioFile.getPictures().length > 0,
104
106
  ...dynamics !== void 0 ? { dynamics } : {}
@@ -111,16 +113,64 @@ async function readMetadataBatch(files, options = {}) {
111
113
  return executeBatch(files, options, (audioFile) => {
112
114
  const dynamics = extractDynamics(audioFile);
113
115
  return {
114
- tags: readExtendedTag(audioFile),
116
+ tags: readExtendedTag(audioFile, options.includeProperties),
115
117
  properties: audioFile.audioProperties(),
116
118
  hasCoverArt: audioFile.getPictures().length > 0,
117
119
  ...dynamics !== void 0 ? { dynamics } : {}
118
120
  };
119
121
  });
120
122
  }
123
+ function entryPath(entry) {
124
+ return typeof entry === "string" ? entry : entry.path;
125
+ }
126
+ async function executeWriteBatch(entries, options, writer) {
127
+ if (entries.length === 0) return { items: [], duration: 0 };
128
+ await getTagLib();
129
+ const startTime = Date.now();
130
+ const { concurrency = 4, continueOnError = true, onProgress, signal } = options;
131
+ const items = new Array(entries.length);
132
+ let processed = 0;
133
+ const total = entries.length;
134
+ for (let i = 0; i < entries.length; i += concurrency) {
135
+ signal?.throwIfAborted();
136
+ const chunk = entries.slice(i, i + concurrency);
137
+ const chunkPromises = chunk.map(async (entry, idx) => {
138
+ const index = i + idx;
139
+ const path = entryPath(entry);
140
+ try {
141
+ await writer(path);
142
+ items[index] = { status: "ok", path, data: void 0 };
143
+ } catch (error) {
144
+ const err = error instanceof Error ? error : new Error(String(error));
145
+ items[index] = { status: "error", path, error: err };
146
+ if (!continueOnError) throw err;
147
+ }
148
+ processed++;
149
+ onProgress?.(processed, total, path);
150
+ });
151
+ await Promise.all(chunkPromises);
152
+ }
153
+ return { items, duration: Date.now() - startTime };
154
+ }
155
+ async function writeTagsBatch(updates, options = {}) {
156
+ const byPath = new Map(updates.map((u) => [u.path, u]));
157
+ return executeWriteBatch(updates, options, (path) => {
158
+ const update = byPath.get(path);
159
+ return applyTagsToFile(path, update.tags);
160
+ });
161
+ }
162
+ async function editTagsBatch(files, mutator, options = {}) {
163
+ return executeWriteBatch(
164
+ files,
165
+ options,
166
+ (path) => withAudioFileSaveToFile(path, mutator)
167
+ );
168
+ }
121
169
  export {
170
+ editTagsBatch,
122
171
  readMetadata,
123
172
  readMetadataBatch,
124
173
  readPropertiesBatch,
125
- readTagsBatch
174
+ readTagsBatch,
175
+ writeTagsBatch
126
176
  };
@@ -1,8 +1,8 @@
1
1
  export { getTagLib, setBufferMode } from "./config.js";
2
2
  export { applyTags, applyTagsToFile, clearTags, isValidAudioFile, readFormat, readProperties, readTags, } from "./tag-operations.js";
3
3
  export { addPicture, applyCoverArt, applyPictures, clearPictures, findPictureByType, readCoverArt, readPictureMetadata, readPictures, replacePictureByType, } from "./picture-operations.js";
4
- export { readMetadata, readMetadataBatch, readPropertiesBatch, readTagsBatch, } from "./batch-operations.js";
5
- export type { BatchItem, BatchOptions, BatchResult, FileMetadata, } from "./batch-operations.js";
4
+ export { editTagsBatch, readMetadata, readMetadataBatch, readPropertiesBatch, readTagsBatch, writeTagsBatch, } from "./batch-operations.js";
5
+ export type { BatchItem, BatchOptions, BatchResult, FileMetadata, WriteTagUpdate, } from "./batch-operations.js";
6
6
  export type { AudioProperties, ExtendedTag, Picture, PictureType, Tag, TagInput, } from "../types.js";
7
7
  export { PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES } from "../types.js";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/simple/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EACL,SAAS,EACT,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACX,GAAG,EACH,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/simple/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EACL,SAAS,EACT,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACX,GAAG,EACH,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
@@ -20,10 +20,12 @@ import {
20
20
  replacePictureByType
21
21
  } from "./picture-operations.js";
22
22
  import {
23
+ editTagsBatch,
23
24
  readMetadata,
24
25
  readMetadataBatch,
25
26
  readPropertiesBatch,
26
- readTagsBatch
27
+ readTagsBatch,
28
+ writeTagsBatch
27
29
  } from "./batch-operations.js";
28
30
  import { PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES } from "../types.js";
29
31
  export {
@@ -36,6 +38,7 @@ export {
36
38
  applyTagsToFile,
37
39
  clearPictures,
38
40
  clearTags,
41
+ editTagsBatch,
39
42
  findPictureByType,
40
43
  getTagLib,
41
44
  isValidAudioFile,
@@ -50,5 +53,6 @@ export {
50
53
  readTags,
51
54
  readTagsBatch,
52
55
  replacePictureByType,
53
- setBufferMode
56
+ setBufferMode,
57
+ writeTagsBatch
54
58
  };
@@ -3,11 +3,15 @@ import type { AudioFileInput, AudioProperties, ExtendedTag, FileType, TagInput }
3
3
  * Reads all metadata tags from an audio file.
4
4
  *
5
5
  * @param file - File path, Uint8Array, ArrayBuffer, or File object
6
+ * @param options - Read options; `includeProperties` (wire keys) surfaces raw
7
+ * values in `extraProperties` (taglib-3s1f)
6
8
  * @returns Parsed tag fields including extended metadata from the audio file
7
9
  * @throws {TagLibInitializationError} If the Wasm module fails to initialize
8
10
  * @throws {InvalidFormatError} If the file is corrupted or in an unsupported format
9
11
  */
10
- export declare function readTags(file: AudioFileInput): Promise<ExtendedTag>;
12
+ export declare function readTags(file: AudioFileInput, options?: {
13
+ includeProperties?: string[];
14
+ }): Promise<ExtendedTag>;
11
15
  /**
12
16
  * Applies metadata tag changes to an audio file and returns the modified content as a buffer.
13
17
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tag-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/tag-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,QAAQ,EAER,QAAQ,EACT,MAAM,aAAa,CAAC;AAWrB;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,eAAe,CAAC,CAY1B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAW/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,UAAU,CAAC,CAsBrB"}
1
+ {"version":3,"file":"tag-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/tag-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,QAAQ,EAER,QAAQ,EACT,MAAM,aAAa,CAAC;AAWrB;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,cAAc,EACpB,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GAC7C,OAAO,CAAC,WAAW,CAAC,CAKtB;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,eAAe,CAAC,CAY1B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAW/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,UAAU,CAAC,CAsBrB"}
@@ -6,8 +6,11 @@ import {
6
6
  withAudioFileSave,
7
7
  withAudioFileSaveToFile
8
8
  } from "./with-audio-file.js";
9
- async function readTags(file) {
10
- return withAudioFile(file, (audioFile) => readExtendedTag(audioFile));
9
+ async function readTags(file, options = {}) {
10
+ return withAudioFile(
11
+ file,
12
+ (audioFile) => readExtendedTag(audioFile, options.includeProperties)
13
+ );
11
14
  }
12
15
  async function applyTags(file, tags) {
13
16
  return withAudioFileSave(file, (audioFile) => {
@@ -42,5 +42,5 @@ export interface FieldMapping {
42
42
  * const vorbisField = METADATA_MAPPINGS.albumArtist.vorbis; // "ALBUMARTIST"
43
43
  * ```
44
44
  */
45
- export declare const METADATA_MAPPINGS: Record<Exclude<keyof ExtendedTag, "pictures" | "ratings" | "lyrics" | "chapters" | "bext" | "bextData" | "ixml" | "id3v2Frames" | "advisory">, FieldMapping>;
45
+ export declare const METADATA_MAPPINGS: Record<Exclude<keyof ExtendedTag, "pictures" | "ratings" | "lyrics" | "chapters" | "bext" | "bextData" | "ixml" | "id3v2Frames" | "advisory" | "extraProperties">, FieldMapping>;
46
46
  //# sourceMappingURL=metadata-mappings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"metadata-mappings.d.ts","sourceRoot":"","sources":["../../../src/types/metadata-mappings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,OAAO,CACL,MAAM,WAAW,EACf,UAAU,GACV,SAAS,GACT,QAAQ,GACR,UAAU,GACV,MAAM,GACN,UAAU,GACV,MAAM,GACN,aAAa,GAGb,UAAU,CACb,EACD,YAAY,CAkPb,CAAC"}
1
+ {"version":3,"file":"metadata-mappings.d.ts","sourceRoot":"","sources":["../../../src/types/metadata-mappings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,OAAO,CACL,MAAM,WAAW,EACf,UAAU,GACV,SAAS,GACT,QAAQ,GACR,UAAU,GACV,MAAM,GACN,UAAU,GACV,MAAM,GACN,aAAa,GAGb,UAAU,GAGV,iBAAiB,CACpB,EACD,YAAY,CAuPb,CAAC"}
@@ -223,6 +223,11 @@ const METADATA_MAPPINGS = {
223
223
  vorbis: "RELEASETYPE",
224
224
  mp4: "----:com.apple.iTunes:MusicBrainz Album Type"
225
225
  },
226
+ releaseCountry: {
227
+ id3v2: { frame: "TXXX", description: "MUSICBRAINZ ALBUM RELEASE COUNTRY" },
228
+ vorbis: "RELEASECOUNTRY",
229
+ mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country"
230
+ },
226
231
  itunesAdvisory: {
227
232
  id3v2: { frame: "TXXX", description: "ITUNESADVISORY" },
228
233
  vorbis: "ITUNESADVISORY",
@@ -111,6 +111,8 @@ export interface TagInput {
111
111
  readonly musicbrainzReleaseGroupId?: string | string[];
112
112
  /** Release type (album, single, EP, compilation, ...); multi-value allowed */
113
113
  readonly releaseType?: string | string[];
114
+ /** Release country (ISO 3166-1 code, e.g. "US"); multi-value allowed */
115
+ readonly releaseCountry?: string | string[];
114
116
  /** Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified) */
115
117
  readonly itunesAdvisory?: string | string[];
116
118
  /**
@@ -176,6 +178,8 @@ export interface ExtendedTag extends Tag {
176
178
  readonly musicbrainzReleaseGroupId?: string[];
177
179
  /** Release type (album, single, EP, compilation, ...); multi-value */
178
180
  readonly releaseType?: string[];
181
+ /** Release country (ISO 3166-1 code, e.g. "US"); multi-value */
182
+ readonly releaseCountry?: string[];
179
183
  /** Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified) */
180
184
  readonly itunesAdvisory?: string[];
181
185
  /**
@@ -261,6 +265,15 @@ export interface ExtendedTag extends Tag {
261
265
  readonly bextData?: Uint8Array;
262
266
  /** Raw iXML chunk as a string. WAV and FLAC only. */
263
267
  readonly ixml?: string;
268
+ /**
269
+ * Raw wire-key values requested via `includeProperties` (taglib-3s1f):
270
+ * keys outside the modeled typed set surface here under their exact WIRE
271
+ * names (e.g. `{ CATALOGNUMBER: ["LC1234"] }`). Present only when the read
272
+ * was asked for them; absent keys are omitted. Never written back —
273
+ * `normalizeTagInput` ignores it, so a readTags() -> applyTags() round-trip
274
+ * cannot create an EXTRAPROPERTIES tag.
275
+ */
276
+ readonly extraProperties?: Record<string, string[]>;
264
277
  /** Staged raw ID3v2 frame replacements: frame ID → list of body byte arrays. */
265
278
  id3v2Frames?: Record<string, Uint8Array[]>;
266
279
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/types/tags.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/types/tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,GAAG;IAClB,kBAAkB;IAClB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB;IAClB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB;IACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc;IACd,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,YAAY;IACZ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW;IACX,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,QAAQ;IACvB,kBAAkB;IAClB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,kBAAkB;IAClB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,iBAAiB;IACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,cAAc;IACd,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACrC,YAAY;IACZ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,WAAW;IACX,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC,mBAAmB;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAGzC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvD,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzC,wEAAwE;IACxE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5C,yGAAyG;IACzG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,aAAa,CAAC;IACzD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAIjD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAG3C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzC,yCAAyC;IACzC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,oBAAoB;IACpB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,2BAA2B;IAC3B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IACvC,6BAA6B;IAC7B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IACzC,4BAA4B;IAC5B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,mCAAmC;IACnC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9C,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,gEAAgE;IAChE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,yGAAyG;IACzG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,aAAa,CAAC;IACzD,iDAAiD;IACjD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,kBAAkB;IAClB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,4BAA4B;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,6BAA6B;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,6BAA6B;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,4CAA4C;IAC5C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,wCAAwC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,gBAAgB;IAChB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB;IAChB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,iBAAiB;IACjB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,mBAAmB;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,eAAe;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,0CAA0C;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,yCAAyC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,4BAA4B;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAGjC,qDAAqD;IACrD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,4CAA4C;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,kCAAkC;IAClC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,4CAA4C;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAKxC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAGhC,sDAAsD;IACtD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,wEAAwE;IACxE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IACrC,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,eAAe,EAAE,OAAO,EAAE,CAAC;IACtD,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,oCAAoC,EAAE,MAAM,EAAE,CAAC;IACzE,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EACd,OAAO,oCAAoC,EAAE,cAAc,EAAE,CAAC;IAChE;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,eAAe,EAAE,OAAO,EAAE,CAAC;IACtD,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,UAAU,EAAE,uBAAuB,CAAC;IAC3D,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpD,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,GACnB;KAAG,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE;CAAE,GACjC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAA;CAAE,CAAC"}
@@ -8,7 +8,7 @@ import type { ExtendedTag, PropertyMap, TagInput } from "../types.js";
8
8
  * (taglib-0co). Each field is included only when present, mirroring how
9
9
  * {@link mapPropertiesToExtendedTag} omits absent text properties.
10
10
  */
11
- export declare function readExtendedTag(audioFile: AudioFile): ExtendedTag;
11
+ export declare function readExtendedTag(audioFile: AudioFile, includeProperties?: string[]): ExtendedTag;
12
12
  export declare function mapPropertiesToExtendedTag(props: PropertyMap): ExtendedTag;
13
13
  export declare function mergeTagUpdates(file: AudioFile, tags: Partial<TagInput>): void;
14
14
  export declare function normalizeTagInput(input: Partial<TagInput>): PropertyMap;
@@ -1 +1 @@
1
- {"version":3,"file":"tag-mapping.d.ts","sourceRoot":"","sources":["../../../src/utils/tag-mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqCtE;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CAuBjE;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAiG1E;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,IAAI,CAaN;AAoDD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GACvB,WAAW,CA4Eb"}
1
+ {"version":3,"file":"tag-mapping.d.ts","sourceRoot":"","sources":["../../../src/utils/tag-mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqCtE;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,EACpB,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAC3B,WAAW,CA2Cb;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAiG1E;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,IAAI,CAaN;AAoDD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GACvB,WAAW,CA+Eb"}
@@ -28,8 +28,9 @@ const NUMERIC_FIELDS = /* @__PURE__ */ new Set([
28
28
  "totalDiscs",
29
29
  "bpm"
30
30
  ]);
31
- function readExtendedTag(audioFile) {
32
- const tag = mapPropertiesToExtendedTag(audioFile.properties());
31
+ function readExtendedTag(audioFile, includeProperties) {
32
+ const props = audioFile.properties();
33
+ const tag = mapPropertiesToExtendedTag(props);
33
34
  const pictures = audioFile.getPictures();
34
35
  if (pictures.length > 0) tag.pictures = pictures;
35
36
  const ratings = audioFile.getRatings();
@@ -44,6 +45,18 @@ function readExtendedTag(audioFile) {
44
45
  if (bextData !== void 0) tag.bextData = bextData;
45
46
  const ixml = audioFile.getIxml();
46
47
  if (ixml !== void 0) tag.ixml = ixml;
48
+ if (includeProperties !== void 0 && includeProperties.length > 0) {
49
+ const extraProperties = {};
50
+ for (const wireKey of includeProperties) {
51
+ const values = props[fromTagLibKey(wireKey)]?.filter((v) => v !== "");
52
+ if (values !== void 0 && values.length > 0) {
53
+ extraProperties[wireKey] = values;
54
+ }
55
+ }
56
+ if (Object.keys(extraProperties).length > 0) {
57
+ tag.extraProperties = extraProperties;
58
+ }
59
+ }
47
60
  return tag;
48
61
  }
49
62
  function mapPropertiesToExtendedTag(props) {
@@ -163,6 +176,7 @@ function normalizeTagInput(input) {
163
176
  }
164
177
  for (const [field, val] of Object.entries(input)) {
165
178
  if (BASIC_FIELDS.has(field) || val === void 0) continue;
179
+ if (field === "extraProperties") continue;
166
180
  if (field === "compilation") {
167
181
  props[field] = [val ? "1" : "0"];
168
182
  } else if (field === "advisory") {
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "2.1.0";
1
+ export declare const VERSION = "2.2.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,4 +1,4 @@
1
- const VERSION = "2.1.0";
1
+ const VERSION = "2.2.0";
2
2
  export {
3
3
  VERSION
4
4
  };
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taglib-wasm",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
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",