ddex-json-codec 0.3.0 → 0.4.2

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/dist/index.d.mts CHANGED
@@ -12,6 +12,7 @@ interface Title {
12
12
  titleText: string;
13
13
  subTitle?: string;
14
14
  titleType?: string;
15
+ languageAndScriptCode?: string;
15
16
  }
16
17
  interface PLine {
17
18
  year?: string;
@@ -54,7 +55,7 @@ interface ArtistRole {
54
55
  interface Artist {
55
56
  /** 解決済みのデフォルト名(3.8系: FullNameから直接取得、4系: PartyListの最初のFullName) */
56
57
  name: string;
57
- /** 4系のみ: 多言語名(PartyListPartyName[]をそのまま保持) */
58
+ /** 多言語名(4系: PartyListから取得、3.8系: 複数PartyNameから取得) */
58
59
  names?: PartyName[];
59
60
  /** 4系のみ: 元の参照ID(ラウンドトリップ用) */
60
61
  partyReference?: string;
@@ -349,7 +350,7 @@ declare function xmlToJson(xml: string): DdexMessage;
349
350
  /**
350
351
  * DdexMessageをXML文字列に変換する
351
352
  */
352
- declare function jsonToXml(message: DdexMessage, version?: ErnVersion): string;
353
+ declare function jsonToXml(message: DdexMessage): string;
353
354
  //#endregion
354
355
  //#region src/version/detect.d.ts
355
356
  /**
@@ -363,4 +364,28 @@ declare function jsonToXml(message: DdexMessage, version?: ErnVersion): string;
363
364
  */
364
365
  declare function detectVersion(xml: string): ErnVersion;
365
366
  //#endregion
366
- export { type Artist, type ArtistRole, type CLine, type Contributor, type DdexMessage, type DdexMessage38, type DdexMessage4, type DdexMessageBase, type Deal, type DealTerms, type DisplayArtist, type DisplayTitle, type ErnMajorVersion, type ErnVersion, type ErnVersion38, type ErnVersion4, type FileDetails, type Genre, type HashSum, type Image, type Image38, type Image4, type ImageBase, type ImageDetailsByTerritory, type ImageId, type IndirectResourceContributor, type MessageHeader, type MessageParty, type PLine, type Party, type PartyName, type Release, type Release38, type Release4, type ReleaseBase, type ReleaseDeal, type ReleaseDetailsByTerritory, type ReleaseId, type ReleaseResourceReference, type ResourceContributor, type ResourceGroup, type SoundRecording, type SoundRecording38, type SoundRecording4, type SoundRecordingBase, type SoundRecordingDetailsByTerritory, type TechnicalImageDetails, type TechnicalSoundRecordingDetails, type TextWithAttribute, type Title, type TrackRelease, type Usage, detectVersion, jsonToXml, xmlToJson };
367
+ //#region src/converter/version/index.d.ts
368
+ interface ConversionWarning {
369
+ type: 'field_dropped' | 'structure_changed';
370
+ path: string;
371
+ message: string;
372
+ }
373
+ interface ConversionResult {
374
+ result: DdexMessage;
375
+ warnings: ConversionWarning[];
376
+ }
377
+ /**
378
+ * DdexMessage をターゲットメジャーバージョンに変換する
379
+ * パッチバージョンは各メジャーの最新が使われる (3.8.3 / 4.3.2)
380
+ */
381
+ declare function convertDdexMessage(message: DdexMessage, target: ErnMajorVersion): ConversionResult;
382
+ //#endregion
383
+ //#region src/index.d.ts
384
+ /**
385
+ * DDEX XML文字列をターゲットメジャーバージョンに変換する
386
+ */
387
+ declare function convertDdexVersion(xml: string, target: ErnMajorVersion): ConversionResult & {
388
+ xml: string;
389
+ };
390
+ //#endregion
391
+ export { type Artist, type ArtistRole, type CLine, type Contributor, type ConversionResult, type ConversionWarning, type DdexMessage, type DdexMessage38, type DdexMessage4, type DdexMessageBase, type Deal, type DealTerms, type DisplayArtist, type DisplayTitle, type ErnMajorVersion, type ErnVersion, type ErnVersion38, type ErnVersion4, type FileDetails, type Genre, type HashSum, type Image, type Image38, type Image4, type ImageBase, type ImageDetailsByTerritory, type ImageId, type IndirectResourceContributor, type MessageHeader, type MessageParty, type PLine, type Party, type PartyName, type Release, type Release38, type Release4, type ReleaseBase, type ReleaseDeal, type ReleaseDetailsByTerritory, type ReleaseId, type ReleaseResourceReference, type ResourceContributor, type ResourceGroup, type SoundRecording, type SoundRecording38, type SoundRecording4, type SoundRecordingBase, type SoundRecordingDetailsByTerritory, type TechnicalImageDetails, type TechnicalSoundRecordingDetails, type TextWithAttribute, type Title, type TrackRelease, type Usage, convertDdexMessage, convertDdexVersion, xmlToJson as ddexToJson, detectVersion as detectDdexVersion, jsonToXml as jsonToDdex };
package/dist/index.mjs CHANGED
@@ -427,13 +427,29 @@ var Ern38Converter = class {
427
427
  if (!raw) return void 0;
428
428
  const artists = ensureArray(raw);
429
429
  if (artists.length === 0) return void 0;
430
- return artists.map((a) => ({
431
- artist: {
432
- name: a.PartyName?.FullName ?? "",
433
- roles: a.ArtistRole ? this.parseArtistRoles(a.ArtistRole) : void 0
434
- },
435
- sequenceNumber: a["@_SequenceNumber"] ? Number(a["@_SequenceNumber"]) : void 0
436
- }));
430
+ return artists.map((a) => {
431
+ const partyNames = ensureArray(a.PartyName);
432
+ const firstName = partyNames[0]?.FullName ?? "";
433
+ let names;
434
+ if (partyNames.length > 1) names = partyNames.map((pn) => ({
435
+ fullName: pn.FullName ?? "",
436
+ fullNameIndexed: pn.FullNameIndexed ?? void 0,
437
+ languageAndScriptCode: pn["@_LanguageAndScriptCode"] ?? void 0
438
+ }));
439
+ else if (partyNames.length === 1 && partyNames[0]["@_LanguageAndScriptCode"]) names = [{
440
+ fullName: firstName,
441
+ fullNameIndexed: partyNames[0].FullNameIndexed ?? void 0,
442
+ languageAndScriptCode: partyNames[0]["@_LanguageAndScriptCode"]
443
+ }];
444
+ return {
445
+ artist: {
446
+ name: firstName,
447
+ names,
448
+ roles: a.ArtistRole ? this.parseArtistRoles(a.ArtistRole) : void 0
449
+ },
450
+ sequenceNumber: a["@_SequenceNumber"] ? Number(a["@_SequenceNumber"]) : void 0
451
+ };
452
+ });
437
453
  }
438
454
  parseArtistRoles(raw) {
439
455
  return ensureArray(raw).map((r) => {
@@ -488,7 +504,8 @@ var Ern38Converter = class {
488
504
  return titles.map((t) => ({
489
505
  titleText: t.TitleText ?? "",
490
506
  subTitle: t.SubTitle && t.SubTitle !== "" ? t.SubTitle : void 0,
491
- titleType: t["@_TitleType"] ?? void 0
507
+ titleType: t["@_TitleType"] ?? void 0,
508
+ languageAndScriptCode: t["@_LanguageAndScriptCode"] ?? void 0
492
509
  }));
493
510
  }
494
511
  parsePLine(raw) {
@@ -1140,7 +1157,14 @@ var Ern38Builder = class {
1140
1157
  buildDisplayArtist(da) {
1141
1158
  const result = {};
1142
1159
  if (da.sequenceNumber != null) result["@_SequenceNumber"] = String(da.sequenceNumber);
1143
- result.PartyName = { FullName: da.artist.name };
1160
+ if (da.artist.names?.length) result.PartyName = da.artist.names.map((pn) => {
1161
+ const r = {};
1162
+ if (pn.languageAndScriptCode) r["@_LanguageAndScriptCode"] = pn.languageAndScriptCode;
1163
+ r.FullName = pn.fullName;
1164
+ if (pn.fullNameIndexed) r.FullNameIndexed = pn.fullNameIndexed;
1165
+ return r;
1166
+ });
1167
+ else result.PartyName = { FullName: da.artist.name };
1144
1168
  if (da.artist.roles?.length) {
1145
1169
  const builtRoles = da.artist.roles.map((r) => this.buildArtistRole(r));
1146
1170
  result.ArtistRole = builtRoles.length === 1 ? builtRoles[0] : builtRoles;
@@ -1178,6 +1202,7 @@ var Ern38Builder = class {
1178
1202
  buildTitle(t) {
1179
1203
  const result = {};
1180
1204
  if (t.titleType) result["@_TitleType"] = t.titleType;
1205
+ if (t.languageAndScriptCode) result["@_LanguageAndScriptCode"] = t.languageAndScriptCode;
1181
1206
  result.TitleText = t.titleText;
1182
1207
  if (t.subTitle) result.SubTitle = t.subTitle;
1183
1208
  return result;
@@ -1493,9 +1518,349 @@ function xmlToJson(xml) {
1493
1518
  /**
1494
1519
  * DdexMessageをXML文字列に変換する
1495
1520
  */
1496
- function jsonToXml(message, version) {
1497
- const targetVersion = version ?? message.ernVersion;
1498
- return ConverterFactory.createJsonToXmlBuilder(targetVersion).build(message, targetVersion);
1521
+ function jsonToXml(message) {
1522
+ return ConverterFactory.createJsonToXmlBuilder(message.ernVersion).build(message, message.ernVersion);
1523
+ }
1524
+ //#endregion
1525
+ //#region src/converter/version/index.ts
1526
+ const LATEST_PATCH = {
1527
+ "3.8": "3.8.3",
1528
+ "4": "4.3.2"
1529
+ };
1530
+ /**
1531
+ * DdexMessage をターゲットメジャーバージョンに変換する
1532
+ * パッチバージョンは各メジャーの最新が使われる (3.8.3 / 4.3.2)
1533
+ */
1534
+ function convertDdexMessage(message, target) {
1535
+ if (getMajorVersion(message.ernVersion) === target) return {
1536
+ result: message,
1537
+ warnings: []
1538
+ };
1539
+ if (target === "4") return convert38To4(message, LATEST_PATCH["4"]);
1540
+ return convert4To38(message, LATEST_PATCH["3.8"]);
1541
+ }
1542
+ function convert38To4(msg, target) {
1543
+ const warnings = [];
1544
+ const partyMap = /* @__PURE__ */ new Map();
1545
+ const resourceList = msg.resourceList.map((sr, i) => convertSoundRecording38To4(sr, i, partyMap, warnings));
1546
+ const imageList = msg.imageList?.map((img) => ({
1547
+ resourceReference: img.resourceReference,
1548
+ type: img.type,
1549
+ imageId: img.imageId,
1550
+ parentalWarningType: img.detailsByTerritory?.[0]?.parentalWarningType,
1551
+ technicalDetails: img.detailsByTerritory?.[0]?.technicalDetails
1552
+ }));
1553
+ const releaseList = msg.releaseList.map((r, i) => convertRelease38To4(r, i, partyMap, warnings));
1554
+ const dealList = convertDealList38To4(msg.dealList, warnings);
1555
+ const partyList = Array.from(partyMap.values());
1556
+ return {
1557
+ result: {
1558
+ ernVersion: target,
1559
+ messageHeader: msg.messageHeader,
1560
+ updateIndicator: msg.updateIndicator,
1561
+ resourceList,
1562
+ imageList,
1563
+ releaseList,
1564
+ dealList,
1565
+ partyList: partyList.length > 0 ? partyList : void 0
1566
+ },
1567
+ warnings
1568
+ };
1569
+ }
1570
+ function convertSoundRecording38To4(sr, index, partyMap, warnings) {
1571
+ const dbt = sr.detailsByTerritory?.[0];
1572
+ if (sr.detailsByTerritory && sr.detailsByTerritory.length > 1) warnings.push({
1573
+ type: "structure_changed",
1574
+ path: `resourceList[${index}].detailsByTerritory`,
1575
+ message: `${sr.detailsByTerritory.length} territories collapsed to first territory`
1576
+ });
1577
+ const displayArtists = (dbt?.displayArtists ?? sr.displayArtists).map((da) => ensurePartyReference(da, partyMap));
1578
+ const contributors = convertResourceContributorsToContributors(dbt?.resourceContributors, partyMap);
1579
+ if (dbt?.indirectResourceContributors?.length) warnings.push({
1580
+ type: "field_dropped",
1581
+ path: `resourceList[${index}].detailsByTerritory[0].indirectResourceContributors`,
1582
+ message: "IndirectResourceContributors dropped (no equivalent in ERN 4)"
1583
+ });
1584
+ return {
1585
+ resourceReference: sr.resourceReference,
1586
+ type: sr.type,
1587
+ soundRecordingId: sr.soundRecordingId,
1588
+ displayArtists,
1589
+ duration: sr.duration,
1590
+ creationDate: sr.creationDate,
1591
+ languageOfPerformance: sr.languageOfPerformance,
1592
+ pLine: dbt?.pLine ?? sr.pLine,
1593
+ displayTitleText: sr.referenceTitle?.titleText,
1594
+ displayTitles: convertTitlesToDisplayTitles(dbt?.titles, dbt?.territoryCode?.[0]),
1595
+ contributors: contributors.length > 0 ? contributors : void 0
1596
+ };
1597
+ }
1598
+ function convertRelease38To4(r, index, partyMap, warnings) {
1599
+ const dbt = r.detailsByTerritory?.[0];
1600
+ if (r.detailsByTerritory && r.detailsByTerritory.length > 1) warnings.push({
1601
+ type: "structure_changed",
1602
+ path: `releaseList[${index}].detailsByTerritory`,
1603
+ message: `${r.detailsByTerritory.length} territories collapsed to first territory`
1604
+ });
1605
+ const displayArtists = (dbt?.displayArtists ?? r.displayArtists).map((da) => ensurePartyReference(da, partyMap));
1606
+ const releaseLabelReferences = dbt?.labelName ? [ensureLabelPartyReference(dbt.labelName, partyMap)] : void 0;
1607
+ return {
1608
+ releaseReference: r.releaseReference,
1609
+ releaseType: r.releaseType,
1610
+ releaseId: r.releaseId,
1611
+ displayArtists,
1612
+ releaseResourceReferences: r.releaseResourceReferences,
1613
+ duration: r.duration,
1614
+ pLine: r.pLine,
1615
+ cLine: r.cLine,
1616
+ displayTitleText: r.referenceTitle?.titleText,
1617
+ displayTitles: convertTitlesToDisplayTitles(dbt?.titles, dbt?.territoryCode?.[0]),
1618
+ releaseLabelReferences,
1619
+ genre: dbt?.genre,
1620
+ parentalWarningType: dbt?.parentalWarningType,
1621
+ resourceGroup: dbt?.resourceGroup ?? r.resourceGroup
1622
+ };
1623
+ }
1624
+ function convertDealList38To4(dealList, warnings) {
1625
+ return dealList.map((rd, i) => ({
1626
+ ...rd,
1627
+ deals: rd.deals.filter((d, j) => {
1628
+ if (d.dealTerms.takeDown) {
1629
+ warnings.push({
1630
+ type: "structure_changed",
1631
+ path: `dealList[${i}].deals[${j}]`,
1632
+ message: "Deal with takeDown=true removed (ERN 4 uses deal absence for takedown)"
1633
+ });
1634
+ return false;
1635
+ }
1636
+ return true;
1637
+ }).map((d) => ({
1638
+ ...d,
1639
+ dealTerms: convertDealTerms38To4(d.dealTerms)
1640
+ }))
1641
+ }));
1642
+ }
1643
+ function convertDealTerms38To4(dt) {
1644
+ return {
1645
+ commercialModelType: dt.commercialModelType,
1646
+ useTypes: dt.usage?.useTypes,
1647
+ territoryCode: dt.territoryCode,
1648
+ validityPeriod: dt.validityPeriod,
1649
+ priceInformation: dt.priceInformation
1650
+ };
1651
+ }
1652
+ function convert4To38(msg, target) {
1653
+ const warnings = [];
1654
+ const partyIndex = /* @__PURE__ */ new Map();
1655
+ if (msg.partyList) for (const p of msg.partyList) partyIndex.set(p.partyReference, p);
1656
+ const resourceList = msg.resourceList.map((sr, i) => convertSoundRecording4To38(sr, i, partyIndex, warnings));
1657
+ const imageList = msg.imageList?.map((img) => ({
1658
+ resourceReference: img.resourceReference,
1659
+ type: img.type,
1660
+ imageId: img.imageId,
1661
+ detailsByTerritory: [{
1662
+ territoryCode: ["Worldwide"],
1663
+ parentalWarningType: img.parentalWarningType,
1664
+ technicalDetails: img.technicalDetails
1665
+ }]
1666
+ }));
1667
+ const releaseList = msg.releaseList.map((r, i) => convertRelease4To38(r, i, partyIndex, warnings));
1668
+ if (msg.trackReleaseList?.length) warnings.push({
1669
+ type: "field_dropped",
1670
+ path: "trackReleaseList",
1671
+ message: `${msg.trackReleaseList.length} TrackRelease(s) dropped (not available in ERN 3.8)`
1672
+ });
1673
+ if (msg.partyList?.some((p) => p.partyId?.length)) warnings.push({
1674
+ type: "field_dropped",
1675
+ path: "partyList[].partyId",
1676
+ message: "PartyId (ISNI, IPN etc.) dropped (no storage in ERN 3.8 inline PartyName)"
1677
+ });
1678
+ const dealList = msg.dealList.map((rd) => ({
1679
+ ...rd,
1680
+ deals: rd.deals.map((d) => ({
1681
+ ...d,
1682
+ dealTerms: convertDealTerms4To38(d.dealTerms)
1683
+ }))
1684
+ }));
1685
+ return {
1686
+ result: {
1687
+ ernVersion: target,
1688
+ messageHeader: msg.messageHeader,
1689
+ updateIndicator: msg.updateIndicator,
1690
+ resourceList,
1691
+ imageList,
1692
+ releaseList,
1693
+ dealList
1694
+ },
1695
+ warnings
1696
+ };
1697
+ }
1698
+ function convertSoundRecording4To38(sr, _index, partyIndex, _warnings) {
1699
+ const displayArtists = sr.displayArtists.map((da) => resolveInlineArtist(da, partyIndex));
1700
+ const referenceTitle = sr.displayTitleText ? { titleText: sr.displayTitleText } : sr.displayTitles?.[0] ? {
1701
+ titleText: sr.displayTitles[0].titleText,
1702
+ subTitle: sr.displayTitles[0].subTitle
1703
+ } : void 0;
1704
+ const titles = convertDisplayTitlesToTitles(sr.displayTitles);
1705
+ const resourceContributors = sr.contributors?.map((c) => resolveContributorToResourceContributor(c, partyIndex));
1706
+ const dbt = {
1707
+ territoryCode: ["Worldwide"],
1708
+ displayArtists,
1709
+ titles,
1710
+ pLine: sr.pLine
1711
+ };
1712
+ if (resourceContributors?.length) dbt.resourceContributors = resourceContributors;
1713
+ return {
1714
+ resourceReference: sr.resourceReference,
1715
+ type: sr.type,
1716
+ soundRecordingId: sr.soundRecordingId,
1717
+ displayArtists,
1718
+ duration: sr.duration,
1719
+ creationDate: sr.creationDate,
1720
+ languageOfPerformance: sr.languageOfPerformance,
1721
+ pLine: sr.pLine,
1722
+ referenceTitle,
1723
+ detailsByTerritory: [dbt]
1724
+ };
1725
+ }
1726
+ function convertRelease4To38(r, _index, partyIndex, _warnings) {
1727
+ const displayArtists = r.displayArtists.map((da) => resolveInlineArtist(da, partyIndex));
1728
+ const referenceTitle = r.displayTitleText ? { titleText: r.displayTitleText } : r.displayTitles?.[0] ? {
1729
+ titleText: r.displayTitles[0].titleText,
1730
+ subTitle: r.displayTitles[0].subTitle
1731
+ } : void 0;
1732
+ const titles = convertDisplayTitlesToTitles(r.displayTitles);
1733
+ let labelName;
1734
+ if (r.releaseLabelReferences?.[0]) labelName = partyIndex.get(r.releaseLabelReferences[0])?.partyName?.[0]?.fullName ?? r.releaseLabelReferences[0];
1735
+ const dbt = {
1736
+ territoryCode: ["Worldwide"],
1737
+ displayArtists,
1738
+ titles,
1739
+ labelName,
1740
+ genre: r.genre,
1741
+ parentalWarningType: r.parentalWarningType,
1742
+ resourceGroup: r.resourceGroup
1743
+ };
1744
+ return {
1745
+ releaseReference: r.releaseReference,
1746
+ releaseType: r.releaseType,
1747
+ releaseId: r.releaseId,
1748
+ displayArtists,
1749
+ releaseResourceReferences: r.releaseResourceReferences,
1750
+ duration: r.duration,
1751
+ pLine: r.pLine,
1752
+ cLine: r.cLine,
1753
+ referenceTitle,
1754
+ detailsByTerritory: [dbt],
1755
+ resourceGroup: r.resourceGroup
1756
+ };
1757
+ }
1758
+ function convertDealTerms4To38(dt) {
1759
+ return {
1760
+ commercialModelType: dt.commercialModelType,
1761
+ usage: dt.useTypes ? { useTypes: dt.useTypes } : void 0,
1762
+ territoryCode: dt.territoryCode,
1763
+ validityPeriod: dt.validityPeriod,
1764
+ priceInformation: dt.priceInformation
1765
+ };
1766
+ }
1767
+ function convertResourceContributorsToContributors(contributors, partyMap) {
1768
+ if (!contributors?.length) return [];
1769
+ return contributors.map((c) => {
1770
+ const ref = generatePartyReference(c.name);
1771
+ if (!partyMap.has(ref)) partyMap.set(ref, {
1772
+ partyReference: ref,
1773
+ partyName: [{ fullName: c.name }]
1774
+ });
1775
+ return {
1776
+ contributorPartyReference: ref,
1777
+ name: c.name,
1778
+ role: c.role,
1779
+ sequenceNumber: c.sequenceNumber
1780
+ };
1781
+ });
1782
+ }
1783
+ function generatePartyReference(name) {
1784
+ return `P${name.replace(/[^a-zA-Z0-9]/g, "") || "Unknown"}`;
1785
+ }
1786
+ function ensurePartyReference(da, partyMap) {
1787
+ if (da.artist.partyReference) return da;
1788
+ const ref = generatePartyReference(da.artist.name);
1789
+ if (!partyMap.has(ref)) {
1790
+ const partyNames = da.artist.names?.length ? da.artist.names : [{ fullName: da.artist.name }];
1791
+ partyMap.set(ref, {
1792
+ partyReference: ref,
1793
+ partyName: partyNames
1794
+ });
1795
+ }
1796
+ return {
1797
+ ...da,
1798
+ artist: {
1799
+ ...da.artist,
1800
+ partyReference: ref
1801
+ }
1802
+ };
1803
+ }
1804
+ function ensureLabelPartyReference(labelName, partyMap) {
1805
+ const ref = generatePartyReference(labelName);
1806
+ if (!partyMap.has(ref)) partyMap.set(ref, {
1807
+ partyReference: ref,
1808
+ partyName: [{ fullName: labelName }]
1809
+ });
1810
+ return ref;
1811
+ }
1812
+ function resolveInlineArtist(da, partyIndex) {
1813
+ if (!da.artist.partyReference) return da;
1814
+ const party = partyIndex.get(da.artist.partyReference);
1815
+ const name = party?.partyName?.[0]?.fullName ?? da.artist.name;
1816
+ const names = party?.partyName && party.partyName.length > 1 ? party.partyName : da.artist.names;
1817
+ return {
1818
+ ...da,
1819
+ artist: {
1820
+ name,
1821
+ names,
1822
+ roles: da.artist.roles
1823
+ }
1824
+ };
1825
+ }
1826
+ function resolveContributorToResourceContributor(c, partyIndex) {
1827
+ return {
1828
+ name: partyIndex.get(c.contributorPartyReference)?.partyName?.[0]?.fullName ?? c.name ?? c.contributorPartyReference,
1829
+ role: c.role,
1830
+ sequenceNumber: c.sequenceNumber
1831
+ };
1832
+ }
1833
+ function convertTitlesToDisplayTitles(titles, territoryCode) {
1834
+ if (!titles?.length) return void 0;
1835
+ return titles.map((t, i) => ({
1836
+ titleText: t.titleText,
1837
+ subTitle: t.subTitle,
1838
+ applicableTerritoryCode: territoryCode ?? "Worldwide",
1839
+ languageAndScriptCode: t.languageAndScriptCode,
1840
+ isDefault: i === 0 ? true : void 0
1841
+ }));
1842
+ }
1843
+ function convertDisplayTitlesToTitles(displayTitles) {
1844
+ if (!displayTitles?.length) return void 0;
1845
+ return displayTitles.map((dt) => ({
1846
+ titleText: dt.titleText,
1847
+ subTitle: dt.subTitle,
1848
+ titleType: "DisplayTitle",
1849
+ languageAndScriptCode: dt.languageAndScriptCode
1850
+ }));
1851
+ }
1852
+ //#endregion
1853
+ //#region src/index.ts
1854
+ /**
1855
+ * DDEX XML文字列をターゲットメジャーバージョンに変換する
1856
+ */
1857
+ function convertDdexVersion(xml, target) {
1858
+ const { result, warnings } = convertDdexMessage(xmlToJson(xml), target);
1859
+ return {
1860
+ result,
1861
+ xml: jsonToXml(result),
1862
+ warnings
1863
+ };
1499
1864
  }
1500
1865
  //#endregion
1501
- export { detectVersion, jsonToXml, xmlToJson };
1866
+ export { convertDdexMessage, convertDdexVersion, xmlToJson as ddexToJson, detectVersion as detectDdexVersion, jsonToXml as jsonToDdex };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ddex-json-codec",
3
3
  "type": "module",
4
- "version": "0.3.0",
4
+ "version": "0.4.2",
5
5
  "description": "DDEX ERN XML ↔ JSON converter for TypeScript",
6
6
  "license": "MIT",
7
7
  "author": "kazhs",
@@ -31,6 +31,13 @@
31
31
  "files": [
32
32
  "dist"
33
33
  ],
34
+ "scripts": {
35
+ "build": "vp pack",
36
+ "dev": "vp pack --watch",
37
+ "test": "vp test",
38
+ "check": "vp check",
39
+ "prepublishOnly": "pnpm run build"
40
+ },
34
41
  "dependencies": {
35
42
  "fast-xml-parser": "^5.3.0"
36
43
  },
@@ -42,13 +49,14 @@
42
49
  "vitest": "npm:@voidzero-dev/vite-plus-test@latest",
43
50
  "vite-plus": "latest"
44
51
  },
52
+ "pnpm": {
53
+ "overrides": {
54
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
55
+ "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
56
+ }
57
+ },
58
+ "packageManager": "pnpm@10.32.1",
45
59
  "engines": {
46
60
  "node": ">=20"
47
- },
48
- "scripts": {
49
- "build": "vp pack",
50
- "dev": "vp pack --watch",
51
- "test": "vp test",
52
- "check": "vp check"
53
61
  }
54
- }
62
+ }