@gefyra/diffyr6-cli 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/compare-terminology.js +122 -18
package/package.json
CHANGED
|
@@ -54,10 +54,13 @@ export async function compareTerminology(resourcesDir, resourcesR6Dir, outputDir
|
|
|
54
54
|
console.log(` Found ${findings.length} profile(s) with binding differences`);
|
|
55
55
|
|
|
56
56
|
// Identify common bindings across all profiles
|
|
57
|
-
const commonBindings = identifyCommonBindings(findings);
|
|
57
|
+
const commonBindings = sortFindings(identifyCommonBindings(findings));
|
|
58
58
|
|
|
59
59
|
// Remove common bindings from individual profiles
|
|
60
|
-
const filteredFindings = removeCommonBindingsFromProfiles(findings, commonBindings)
|
|
60
|
+
const filteredFindings = removeCommonBindingsFromProfiles(findings, commonBindings).map(profile => ({
|
|
61
|
+
...profile,
|
|
62
|
+
findings: sortFindings(profile.findings),
|
|
63
|
+
}));
|
|
61
64
|
|
|
62
65
|
// Generate reports
|
|
63
66
|
const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\..+/, '').replace('T', '-');
|
|
@@ -280,6 +283,7 @@ async function compareProfileBindings(r4Profile, r6Profile, options = {}) {
|
|
|
280
283
|
findings.push({
|
|
281
284
|
type: 'new-binding',
|
|
282
285
|
path,
|
|
286
|
+
isMustSupport: isMustSupportElement(r6Elem),
|
|
283
287
|
r6Binding: r6Elem.binding,
|
|
284
288
|
});
|
|
285
289
|
continue;
|
|
@@ -297,6 +301,7 @@ async function compareProfileBindings(r4Profile, r6Profile, options = {}) {
|
|
|
297
301
|
const finding = {
|
|
298
302
|
type: 'strength-and-valueset-change',
|
|
299
303
|
path,
|
|
304
|
+
isMustSupport: isMustSupportElement(r4Elem) || isMustSupportElement(r6Elem),
|
|
300
305
|
r4Strength: r4Binding.strength,
|
|
301
306
|
r6Strength: r6Binding.strength,
|
|
302
307
|
r4ValueSet: r4Binding.valueSet,
|
|
@@ -328,6 +333,7 @@ async function compareProfileBindings(r4Profile, r6Profile, options = {}) {
|
|
|
328
333
|
findings.push({
|
|
329
334
|
type: 'strength-change',
|
|
330
335
|
path,
|
|
336
|
+
isMustSupport: isMustSupportElement(r4Elem) || isMustSupportElement(r6Elem),
|
|
331
337
|
r4Strength: r4Binding.strength,
|
|
332
338
|
r6Strength: r6Binding.strength,
|
|
333
339
|
r4ValueSet: r4Binding.valueSet,
|
|
@@ -341,6 +347,7 @@ async function compareProfileBindings(r4Profile, r6Profile, options = {}) {
|
|
|
341
347
|
findings.push({
|
|
342
348
|
type: 'strength-change',
|
|
343
349
|
path,
|
|
350
|
+
isMustSupport: isMustSupportElement(r4Elem) || isMustSupportElement(r6Elem),
|
|
344
351
|
r4Strength: r4Binding.strength,
|
|
345
352
|
r6Strength: r6Binding.strength,
|
|
346
353
|
r4ValueSet: r4Binding.valueSet,
|
|
@@ -351,6 +358,7 @@ async function compareProfileBindings(r4Profile, r6Profile, options = {}) {
|
|
|
351
358
|
const finding = {
|
|
352
359
|
type: 'valueset-change',
|
|
353
360
|
path,
|
|
361
|
+
isMustSupport: isMustSupportElement(r4Elem) || isMustSupportElement(r6Elem),
|
|
354
362
|
r4ValueSet: r4Binding.valueSet,
|
|
355
363
|
r6ValueSet: r6Binding.valueSet,
|
|
356
364
|
r4Strength: r4Binding.strength,
|
|
@@ -392,6 +400,7 @@ async function compareProfileBindings(r4Profile, r6Profile, options = {}) {
|
|
|
392
400
|
findings.push({
|
|
393
401
|
type: 'removed-binding',
|
|
394
402
|
path,
|
|
403
|
+
isMustSupport: isMustSupportElement(r4Elem),
|
|
395
404
|
r4Binding: r4Elem.binding,
|
|
396
405
|
});
|
|
397
406
|
}
|
|
@@ -400,6 +409,10 @@ async function compareProfileBindings(r4Profile, r6Profile, options = {}) {
|
|
|
400
409
|
return findings;
|
|
401
410
|
}
|
|
402
411
|
|
|
412
|
+
function isMustSupportElement(element) {
|
|
413
|
+
return element?.mustSupport === true;
|
|
414
|
+
}
|
|
415
|
+
|
|
403
416
|
/**
|
|
404
417
|
* Check if valueSet URL has a version (pipe notation)
|
|
405
418
|
*/
|
|
@@ -756,6 +769,38 @@ function groupFindingsByType(findings) {
|
|
|
756
769
|
return byType;
|
|
757
770
|
}
|
|
758
771
|
|
|
772
|
+
function sortFindings(findings) {
|
|
773
|
+
return [...findings].sort((left, right) => {
|
|
774
|
+
if ((left.isMustSupport === true) !== (right.isMustSupport === true)) {
|
|
775
|
+
return left.isMustSupport === true ? -1 : 1;
|
|
776
|
+
}
|
|
777
|
+
const pathCompare = (left.path || '').localeCompare(right.path || '');
|
|
778
|
+
if (pathCompare !== 0) {
|
|
779
|
+
return pathCompare;
|
|
780
|
+
}
|
|
781
|
+
return (left.type || '').localeCompare(right.type || '');
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
function splitFindingsByMustSupport(findings) {
|
|
786
|
+
const mustSupport = [];
|
|
787
|
+
const others = [];
|
|
788
|
+
|
|
789
|
+
for (const finding of findings) {
|
|
790
|
+
if (finding.isMustSupport === true) {
|
|
791
|
+
mustSupport.push(finding);
|
|
792
|
+
} else {
|
|
793
|
+
others.push(finding);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
return { mustSupport, others };
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function appendFindingMetadata(lines, finding) {
|
|
801
|
+
lines.push(`- Must Support: ${finding.isMustSupport === true ? 'yes' : 'no'}`);
|
|
802
|
+
}
|
|
803
|
+
|
|
759
804
|
/**
|
|
760
805
|
* Append findings to markdown lines
|
|
761
806
|
*/
|
|
@@ -767,6 +812,7 @@ function appendFindingsToMarkdown(lines, byType) {
|
|
|
767
812
|
|
|
768
813
|
for (const f of byType['strength-and-valueset-change']) {
|
|
769
814
|
lines.push(`**${f.path}**`);
|
|
815
|
+
appendFindingMetadata(lines, f);
|
|
770
816
|
lines.push(`- Strength: \`${f.r4Strength}\` → \`${f.r6Strength}\``);
|
|
771
817
|
lines.push(`- R4 ValueSet: ${f.r4ValueSet || 'none'}`);
|
|
772
818
|
lines.push(`- R6 ValueSet: ${f.r6ValueSet || 'none'}`);
|
|
@@ -818,6 +864,7 @@ function appendFindingsToMarkdown(lines, byType) {
|
|
|
818
864
|
|
|
819
865
|
for (const f of byType['strength-change']) {
|
|
820
866
|
lines.push(`**${f.path}**`);
|
|
867
|
+
appendFindingMetadata(lines, f);
|
|
821
868
|
lines.push(`- Strength: \`${f.r4Strength}\` → \`${f.r6Strength}\``);
|
|
822
869
|
if (f.r4ValueSet) {
|
|
823
870
|
lines.push(`- ValueSet (R4): ${f.r4ValueSet}`);
|
|
@@ -836,6 +883,7 @@ function appendFindingsToMarkdown(lines, byType) {
|
|
|
836
883
|
|
|
837
884
|
for (const f of byType['valueset-change']) {
|
|
838
885
|
lines.push(`**${f.path}**`);
|
|
886
|
+
appendFindingMetadata(lines, f);
|
|
839
887
|
lines.push(`- R4 ValueSet: ${f.r4ValueSet || 'none'}`);
|
|
840
888
|
lines.push(`- R6 ValueSet: ${f.r6ValueSet || 'none'}`);
|
|
841
889
|
|
|
@@ -890,6 +938,7 @@ function appendFindingsToMarkdown(lines, byType) {
|
|
|
890
938
|
|
|
891
939
|
for (const f of byType['new-binding']) {
|
|
892
940
|
lines.push(`**${f.path}**`);
|
|
941
|
+
appendFindingMetadata(lines, f);
|
|
893
942
|
if (f.r6Binding?.valueSet) {
|
|
894
943
|
lines.push(`- ValueSet: ${f.r6Binding.valueSet}`);
|
|
895
944
|
}
|
|
@@ -907,6 +956,7 @@ function appendFindingsToMarkdown(lines, byType) {
|
|
|
907
956
|
|
|
908
957
|
for (const f of byType['removed-binding']) {
|
|
909
958
|
lines.push(`**${f.path}**`);
|
|
959
|
+
appendFindingMetadata(lines, f);
|
|
910
960
|
if (f.r4Binding?.valueSet) {
|
|
911
961
|
lines.push(`- ValueSet (R4): ${f.r4Binding.valueSet}`);
|
|
912
962
|
}
|
|
@@ -923,11 +973,24 @@ function appendFindingsToMarkdown(lines, byType) {
|
|
|
923
973
|
*/
|
|
924
974
|
function generateTerminologyReport(findings, commonBindings = []) {
|
|
925
975
|
const lines = [];
|
|
976
|
+
const sortedProfiles = sortProfilesAlphabetically(findings);
|
|
977
|
+
const mustSupportProfiles = sortedProfiles
|
|
978
|
+
.map(profile => ({
|
|
979
|
+
...profile,
|
|
980
|
+
findings: profile.findings.filter(finding => finding.isMustSupport === true),
|
|
981
|
+
}))
|
|
982
|
+
.filter(profile => profile.findings.length > 0);
|
|
983
|
+
const otherProfiles = sortedProfiles
|
|
984
|
+
.map(profile => ({
|
|
985
|
+
...profile,
|
|
986
|
+
findings: profile.findings.filter(finding => finding.isMustSupport !== true),
|
|
987
|
+
}))
|
|
988
|
+
.filter(profile => profile.findings.length > 0);
|
|
926
989
|
|
|
927
990
|
lines.push('# Terminology Binding Comparison Report');
|
|
928
991
|
lines.push('');
|
|
929
992
|
lines.push(`**Generated:** ${new Date().toISOString()}`);
|
|
930
|
-
lines.push(`**Profiles with Differences:** ${
|
|
993
|
+
lines.push(`**Profiles with Differences:** ${sortedProfiles.length}`);
|
|
931
994
|
if (commonBindings.length > 0) {
|
|
932
995
|
lines.push(`**Common Bindings Across All Profiles:** ${commonBindings.length}`);
|
|
933
996
|
}
|
|
@@ -943,34 +1006,75 @@ function generateTerminologyReport(findings, commonBindings = []) {
|
|
|
943
1006
|
lines.push('');
|
|
944
1007
|
lines.push('The following binding changes occur in **all** profiles:');
|
|
945
1008
|
lines.push('');
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
appendFindingsToMarkdown(lines, groupedCommon);
|
|
1009
|
+
|
|
1010
|
+
appendMustSupportSections(lines, commonBindings);
|
|
949
1011
|
|
|
950
1012
|
lines.push('---');
|
|
951
1013
|
lines.push('');
|
|
952
1014
|
}
|
|
953
1015
|
|
|
954
|
-
if (
|
|
1016
|
+
if (sortedProfiles.length === 0) {
|
|
955
1017
|
lines.push('✅ **No profile-specific binding differences found.**');
|
|
956
1018
|
lines.push('');
|
|
957
1019
|
return lines.join('\n');
|
|
958
1020
|
}
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
lines.push(
|
|
1021
|
+
|
|
1022
|
+
if (mustSupportProfiles.length > 0) {
|
|
1023
|
+
lines.push('## Must Support');
|
|
962
1024
|
lines.push('');
|
|
963
|
-
lines.push(
|
|
964
|
-
lines.push(`- **R6 URL:** ${profile.r6Url}`);
|
|
965
|
-
lines.push(`- **Differences:** ${profile.findings.length}`);
|
|
1025
|
+
lines.push('The following profiles contain binding differences on Must-Support elements:');
|
|
966
1026
|
lines.push('');
|
|
967
|
-
|
|
968
|
-
const
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1027
|
+
|
|
1028
|
+
for (const profile of mustSupportProfiles) {
|
|
1029
|
+
appendProfileSection(lines, profile);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
if (otherProfiles.length > 0) {
|
|
1034
|
+
lines.push('## Non Must Support');
|
|
1035
|
+
lines.push('');
|
|
1036
|
+
lines.push('The following profiles contain binding differences on elements without Must Support:');
|
|
972
1037
|
lines.push('');
|
|
1038
|
+
|
|
1039
|
+
for (const profile of otherProfiles) {
|
|
1040
|
+
appendProfileSection(lines, profile);
|
|
1041
|
+
}
|
|
973
1042
|
}
|
|
974
1043
|
|
|
975
1044
|
return lines.join('\n');
|
|
976
1045
|
}
|
|
1046
|
+
|
|
1047
|
+
function appendMustSupportSections(lines, findings) {
|
|
1048
|
+
const sortedFindings = sortFindings(findings);
|
|
1049
|
+
const { mustSupport, others } = splitFindingsByMustSupport(sortedFindings);
|
|
1050
|
+
|
|
1051
|
+
if (mustSupport.length > 0) {
|
|
1052
|
+
lines.push('### Must Support Elements');
|
|
1053
|
+
lines.push('');
|
|
1054
|
+
appendFindingsToMarkdown(lines, groupFindingsByType(mustSupport));
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
if (others.length > 0) {
|
|
1058
|
+
lines.push('### Other Elements');
|
|
1059
|
+
lines.push('');
|
|
1060
|
+
appendFindingsToMarkdown(lines, groupFindingsByType(others));
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
function appendProfileSection(lines, profile) {
|
|
1065
|
+
lines.push(`### ${profile.profileName}`);
|
|
1066
|
+
lines.push('');
|
|
1067
|
+
lines.push(`- **R4 URL:** ${profile.r4Url}`);
|
|
1068
|
+
lines.push(`- **R6 URL:** ${profile.r6Url}`);
|
|
1069
|
+
lines.push(`- **Differences:** ${profile.findings.length}`);
|
|
1070
|
+
lines.push('');
|
|
1071
|
+
appendFindingsToMarkdown(lines, groupFindingsByType(sortFindings(profile.findings)));
|
|
1072
|
+
lines.push('---');
|
|
1073
|
+
lines.push('');
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
function sortProfilesAlphabetically(profiles) {
|
|
1077
|
+
return [...profiles].sort((left, right) =>
|
|
1078
|
+
(left.profileName || '').localeCompare(right.profileName || '')
|
|
1079
|
+
);
|
|
1080
|
+
}
|