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 +28 -3
- package/dist/index.mjs +378 -13
- package/package.json +16 -8
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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 =
|
|
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
|
|
1497
|
-
|
|
1498
|
-
|
|
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 {
|
|
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.
|
|
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
|
+
}
|