fhirsmith 0.4.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +1 -1
- package/library/cron-utilities.js +136 -0
- package/library/html-server.js +13 -29
- package/library/html.js +3 -8
- package/library/languages.js +160 -37
- package/library/package-manager.js +48 -1
- package/library/utilities.js +100 -19
- package/package.json +2 -2
- package/packages/package-crawler.js +6 -1
- package/packages/packages.js +38 -54
- package/publisher/publisher.js +19 -27
- package/registry/api.js +11 -10
- package/registry/crawler.js +31 -29
- package/registry/model.js +5 -26
- package/registry/registry.js +32 -41
- package/server.js +89 -12
- package/shl/shl.js +0 -18
- package/static/assets/js/statuspage.js +1 -9
- package/stats.js +39 -1
- package/token/token.js +14 -9
- package/translations/Messages.properties +2 -1
- package/tx/README.md +17 -6
- package/tx/cs/cs-api.js +19 -1
- package/tx/cs/cs-base.js +77 -0
- package/tx/cs/cs-country.js +46 -0
- package/tx/cs/cs-cpt.js +9 -5
- package/tx/cs/cs-cs.js +27 -13
- package/tx/cs/cs-lang.js +60 -22
- package/tx/cs/cs-loinc.js +69 -98
- package/tx/cs/cs-mimetypes.js +4 -0
- package/tx/cs/cs-ndc.js +6 -0
- package/tx/cs/cs-omop.js +16 -15
- package/tx/cs/cs-rxnorm.js +23 -1
- package/tx/cs/cs-snomed.js +283 -40
- package/tx/cs/cs-ucum.js +90 -70
- package/tx/importers/import-sct.module.js +371 -35
- package/tx/importers/readme.md +117 -7
- package/tx/library/bundle.js +5 -0
- package/tx/library/capabilitystatement.js +3 -142
- package/tx/library/codesystem.js +19 -173
- package/tx/library/conceptmap.js +4 -218
- package/tx/library/designations.js +14 -1
- package/tx/library/extensions.js +7 -0
- package/tx/library/namingsystem.js +3 -89
- package/tx/library/operation-outcome.js +8 -3
- package/tx/library/parameters.js +3 -2
- package/tx/library/renderer.js +10 -6
- package/tx/library/terminologycapabilities.js +3 -243
- package/tx/library/valueset.js +3 -235
- package/tx/library.js +100 -13
- package/tx/operation-context.js +23 -4
- package/tx/params.js +35 -38
- package/tx/provider.js +6 -5
- package/tx/sct/expressions.js +12 -3
- package/tx/tx-html.js +80 -89
- package/tx/tx.fhir.org.yml +6 -5
- package/tx/tx.js +163 -13
- package/tx/vs/vs-database.js +56 -39
- package/tx/vs/vs-package.js +21 -2
- package/tx/vs/vs-vsac.js +175 -39
- package/tx/workers/batch-validate.js +2 -0
- package/tx/workers/batch.js +2 -0
- package/tx/workers/expand.js +132 -112
- package/tx/workers/lookup.js +33 -14
- package/tx/workers/metadata.js +2 -2
- package/tx/workers/read.js +3 -2
- package/tx/workers/related.js +574 -0
- package/tx/workers/search.js +46 -9
- package/tx/workers/subsumes.js +13 -3
- package/tx/workers/translate.js +7 -3
- package/tx/workers/validate.js +258 -285
- package/tx/workers/worker.js +43 -39
- package/tx/xml/bundle-xml.js +237 -0
- package/tx/xml/xml-base.js +215 -64
- package/tx/xversion/xv-bundle.js +71 -0
- package/tx/xversion/xv-capabiliityStatement.js +137 -0
- package/tx/xversion/xv-codesystem.js +169 -0
- package/tx/xversion/xv-conceptmap.js +224 -0
- package/tx/xversion/xv-namingsystem.js +88 -0
- package/tx/xversion/xv-operationoutcome.js +27 -0
- package/tx/xversion/xv-parameters.js +87 -0
- package/tx/xversion/xv-resource.js +45 -0
- package/tx/xversion/xv-terminologyCapabilities.js +214 -0
- package/tx/xversion/xv-valueset.js +234 -0
- package/utilities/dev-proxy-server.js +126 -0
- package/utilities/explode-results.js +58 -0
- package/utilities/split-by-system.js +198 -0
- package/utilities/vsac-cs-fetcher.js +0 -0
- package/{windows-install.js → utilities/windows-install.js} +2 -0
- package/vcl/vcl.js +0 -18
- package/xig/xig.js +241 -230
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
const {VersionUtilities} = require("../../library/version-utilities");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts input CodeSystem to R5 format (modifies input object for performance)
|
|
5
|
+
* @param {Object} jsonObj - The input CodeSystem object
|
|
6
|
+
* @param {string} version - Source FHIR version
|
|
7
|
+
* @returns {Object} The same object, potentially modified to R5 format
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
function codeSystemToR5(jsonObj, version) {
|
|
12
|
+
if (version === 'R5') {
|
|
13
|
+
return jsonObj; // Already R5, no conversion needed
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (version === 'R3') {
|
|
17
|
+
// R3 to R5: Convert identifier from single object to array
|
|
18
|
+
if (jsonObj.identifier && !Array.isArray(jsonObj.identifier)) {
|
|
19
|
+
jsonObj.identifier = [jsonObj.identifier];
|
|
20
|
+
}
|
|
21
|
+
return jsonObj;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (version === 'R4') {
|
|
25
|
+
// R4 to R5: identifier is already an array, no conversion needed
|
|
26
|
+
return jsonObj;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
throw new Error(`Unsupported FHIR version: ${version}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Converts R5 CodeSystem to target version format (clones object first)
|
|
34
|
+
* @param {Object} r5Obj - The R5 format CodeSystem object
|
|
35
|
+
* @param {string} targetVersion - Target FHIR version
|
|
36
|
+
* @returns {Object} New object in target version format
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
function codeSystemFromR5(r5Obj, targetVersion) {
|
|
40
|
+
if (VersionUtilities.isR5Ver(targetVersion)) {
|
|
41
|
+
return r5Obj; // No conversion needed
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Clone the object to avoid modifying the original
|
|
45
|
+
const cloned = JSON.parse(JSON.stringify(r5Obj));
|
|
46
|
+
|
|
47
|
+
if (VersionUtilities.isR4Ver(targetVersion)) {
|
|
48
|
+
return codeSystemR5ToR4(cloned);
|
|
49
|
+
} else if (VersionUtilities.isR3Ver(targetVersion)) {
|
|
50
|
+
return codeSystemR5ToR3(cloned);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
throw new Error(`Unsupported target FHIR version: ${targetVersion}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Converts R5 CodeSystem to R4 format
|
|
58
|
+
* @param {Object} r5Obj - Cloned R5 CodeSystem object
|
|
59
|
+
* @returns {Object} R4 format CodeSystem
|
|
60
|
+
* @private
|
|
61
|
+
*/
|
|
62
|
+
function codeSystemR5ToR4(r5Obj) {
|
|
63
|
+
// Remove R5-specific elements that don't exist in R4
|
|
64
|
+
if (r5Obj.versionAlgorithmString) {
|
|
65
|
+
delete r5Obj.versionAlgorithmString;
|
|
66
|
+
}
|
|
67
|
+
if (r5Obj.versionAlgorithmCoding) {
|
|
68
|
+
delete r5Obj.versionAlgorithmCoding;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Filter out R5-only filter operators
|
|
72
|
+
if (r5Obj.filter && Array.isArray(r5Obj.filter)) {
|
|
73
|
+
r5Obj.filter = r5Obj.filter.map(filter => {
|
|
74
|
+
if (filter.operator && Array.isArray(filter.operator)) {
|
|
75
|
+
// Remove R5-only operators like 'generalizes'
|
|
76
|
+
filter.operator = filter.operator.filter(op =>
|
|
77
|
+
!isR5OnlyFilterOperator(op)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return filter;
|
|
81
|
+
}).filter(filter =>
|
|
82
|
+
// Remove filters that have no valid operators left
|
|
83
|
+
!filter.operator || filter.operator.length > 0
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return r5Obj;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Converts R5 CodeSystem to R3 format
|
|
92
|
+
* @param {Object} r5Obj - Cloned R5 CodeSystem object
|
|
93
|
+
* @returns {Object} R3 format CodeSystem
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
function codeSystemR5ToR3(r5Obj) {
|
|
97
|
+
// First apply R4 conversions
|
|
98
|
+
const r4Obj = codeSystemR5ToR4(r5Obj);
|
|
99
|
+
|
|
100
|
+
// R5/R4 to R3: Convert identifier from array back to single object
|
|
101
|
+
if (r4Obj.identifier && Array.isArray(r4Obj.identifier)) {
|
|
102
|
+
if (r4Obj.identifier.length > 0) {
|
|
103
|
+
// Take the first identifier if multiple exist
|
|
104
|
+
r4Obj.identifier = r4Obj.identifier[0];
|
|
105
|
+
} else {
|
|
106
|
+
// Remove empty array
|
|
107
|
+
delete r4Obj.identifier;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Remove additional R4-specific elements that don't exist in R3
|
|
112
|
+
if (r4Obj.supplements) {
|
|
113
|
+
delete r4Obj.supplements;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// R3 has more limited filter operator support
|
|
117
|
+
if (r4Obj.filter && Array.isArray(r4Obj.filter)) {
|
|
118
|
+
r4Obj.filter = r4Obj.filter.map(filter => {
|
|
119
|
+
if (filter.operator && Array.isArray(filter.operator)) {
|
|
120
|
+
// Keep only R3-compatible operators
|
|
121
|
+
filter.operator = filter.operator.filter(op =>
|
|
122
|
+
isR3CompatibleFilterOperator(op)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
return filter;
|
|
126
|
+
}).filter(filter =>
|
|
127
|
+
// Remove filters that have no valid operators left
|
|
128
|
+
!filter.operator || filter.operator.length > 0
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return r4Obj;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Checks if a filter operator is R5-only
|
|
137
|
+
* @param {string} operator - Filter operator code
|
|
138
|
+
* @returns {boolean} True if operator is R5-only
|
|
139
|
+
* @private
|
|
140
|
+
*/
|
|
141
|
+
function isR5OnlyFilterOperator(operator) {
|
|
142
|
+
const r5OnlyOperators = [
|
|
143
|
+
'generalizes', // Added in R5
|
|
144
|
+
// Add other R5-only operators as they're identified
|
|
145
|
+
];
|
|
146
|
+
return r5OnlyOperators.includes(operator);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Checks if a filter operator is compatible with R3
|
|
151
|
+
* @param {string} operator - Filter operator code
|
|
152
|
+
* @returns {boolean} True if operator is R3-compatible
|
|
153
|
+
* @private
|
|
154
|
+
*/
|
|
155
|
+
function isR3CompatibleFilterOperator(operator) {
|
|
156
|
+
const r3CompatibleOperators = [
|
|
157
|
+
'=', // Equal
|
|
158
|
+
'is-a', // Is-A relationship
|
|
159
|
+
'descendent-of', // Descendant of (note: R3 spelling)
|
|
160
|
+
'is-not-a', // Is-Not-A relationship
|
|
161
|
+
'regex', // Regular expression
|
|
162
|
+
'in', // In set
|
|
163
|
+
'not-in', // Not in set
|
|
164
|
+
'exists', // Property exists
|
|
165
|
+
];
|
|
166
|
+
return r3CompatibleOperators.includes(operator);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = { codeSystemToR5, codeSystemFromR5 };
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
const {VersionUtilities} = require("../../library/version-utilities");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts input ConceptMap to R5 format (modifies input object for performance)
|
|
5
|
+
* @param {Object} jsonObj - The input ConceptMap object
|
|
6
|
+
* @param {string} version - Source FHIR version
|
|
7
|
+
* @returns {Object} The same object, potentially modified to R5 format
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
function conceptMapToR5(jsonObj, sourceVersion) {
|
|
12
|
+
if (VersionUtilities.isR5Ver(sourceVersion)) {
|
|
13
|
+
return jsonObj; // No conversion needed
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (VersionUtilities.isR3Ver(sourceVersion) || VersionUtilities.isR4Ver(sourceVersion)) {
|
|
17
|
+
// Convert identifier from single object to array
|
|
18
|
+
if (jsonObj.identifier && !Array.isArray(jsonObj.identifier)) {
|
|
19
|
+
jsonObj.identifier = [jsonObj.identifier];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Convert source/target to sourceScope/targetScope
|
|
23
|
+
if (jsonObj.source !== undefined) {
|
|
24
|
+
// Combine source + sourceVersion if both exist
|
|
25
|
+
if (jsonObj.sourceVersion) {
|
|
26
|
+
jsonObj.sourceScope = `${jsonObj.source}|${jsonObj.sourceVersion}`;
|
|
27
|
+
delete jsonObj.sourceVersion;
|
|
28
|
+
} else {
|
|
29
|
+
jsonObj.sourceScope = jsonObj.source;
|
|
30
|
+
}
|
|
31
|
+
delete jsonObj.source;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (jsonObj.target !== undefined) {
|
|
35
|
+
// Combine target + targetVersion if both exist
|
|
36
|
+
if (jsonObj.targetVersion) {
|
|
37
|
+
jsonObj.targetScope = `${jsonObj.target}|${jsonObj.targetVersion}`;
|
|
38
|
+
delete jsonObj.targetVersion;
|
|
39
|
+
} else {
|
|
40
|
+
jsonObj.targetScope = jsonObj.target;
|
|
41
|
+
}
|
|
42
|
+
delete jsonObj.target;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Convert equivalence to relationship in group.element.target
|
|
46
|
+
if (jsonObj.group && Array.isArray(jsonObj.group)) {
|
|
47
|
+
jsonObj.group.forEach(group => {
|
|
48
|
+
if (group.element && Array.isArray(group.element)) {
|
|
49
|
+
group.element.forEach(element => {
|
|
50
|
+
if (element.target && Array.isArray(element.target)) {
|
|
51
|
+
element.target.forEach(target => {
|
|
52
|
+
if (target.equivalence && !target.relationship) {
|
|
53
|
+
// Convert equivalence to relationship and keep both
|
|
54
|
+
target.relationship = convertEquivalenceToRelationship(target.equivalence);
|
|
55
|
+
// Keep equivalence for backward compatibility
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return jsonObj;
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Unsupported FHIR version: ${sourceVersion}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Converts R5 ConceptMap to target version format (clones object first)
|
|
71
|
+
* @param {Object} r5Obj - The R5 format ConceptMap object
|
|
72
|
+
* @param {string} targetVersion - Target FHIR version
|
|
73
|
+
* @returns {Object} New object in target version format
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
function conceptMapFromR5(r5Obj, targetVersion) {
|
|
77
|
+
if (VersionUtilities.isR5Ver(targetVersion)) {
|
|
78
|
+
return r5Obj; // No conversion needed
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Clone the object to avoid modifying the original
|
|
82
|
+
const cloned = JSON.parse(JSON.stringify(r5Obj));
|
|
83
|
+
|
|
84
|
+
if (VersionUtilities.isR4Ver(targetVersion)) {
|
|
85
|
+
return conceptMapR5ToR4(cloned);
|
|
86
|
+
} else if (VersionUtilities.isR3Ver(targetVersion)) {
|
|
87
|
+
return conceptMapR5ToR3(cloned);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
throw new Error(`Unsupported target FHIR version: ${targetVersion}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Converts R5 ConceptMap to R4 format
|
|
95
|
+
* @param {Object} r5Obj - Cloned R5 ConceptMap object
|
|
96
|
+
* @returns {Object} R4 format ConceptMap
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
function conceptMapR5ToR4(r5Obj) {
|
|
100
|
+
// Remove R5-specific elements
|
|
101
|
+
if (r5Obj.versionAlgorithmString) {
|
|
102
|
+
delete r5Obj.versionAlgorithmString;
|
|
103
|
+
}
|
|
104
|
+
if (r5Obj.versionAlgorithmCoding) {
|
|
105
|
+
delete r5Obj.versionAlgorithmCoding;
|
|
106
|
+
}
|
|
107
|
+
if (r5Obj.property) {
|
|
108
|
+
delete r5Obj.property;
|
|
109
|
+
}
|
|
110
|
+
if (r5Obj.additionalAttribute) {
|
|
111
|
+
delete r5Obj.additionalAttribute;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Convert identifier array back to single object
|
|
115
|
+
if (r5Obj.identifier && Array.isArray(r5Obj.identifier)) {
|
|
116
|
+
if (r5Obj.identifier.length > 0) {
|
|
117
|
+
r5Obj.identifier = r5Obj.identifier[0]; // Take first identifier
|
|
118
|
+
} else {
|
|
119
|
+
delete r5Obj.identifier;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Convert sourceScope/targetScope back to source/target + version
|
|
124
|
+
if (r5Obj.sourceScope) {
|
|
125
|
+
const parts = r5Obj.sourceScope.split('|');
|
|
126
|
+
r5Obj.source = parts[0];
|
|
127
|
+
if (parts.length > 1) {
|
|
128
|
+
r5Obj.sourceVersion = parts[1];
|
|
129
|
+
}
|
|
130
|
+
delete r5Obj.sourceScope;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (r5Obj.targetScope) {
|
|
134
|
+
const parts = r5Obj.targetScope.split('|');
|
|
135
|
+
r5Obj.target = parts[0];
|
|
136
|
+
if (parts.length > 1) {
|
|
137
|
+
r5Obj.targetVersion = parts[1];
|
|
138
|
+
}
|
|
139
|
+
delete r5Obj.targetScope;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Convert relationship back to equivalence in group.element.target
|
|
143
|
+
if (r5Obj.group && Array.isArray(r5Obj.group)) {
|
|
144
|
+
r5Obj.group.forEach(group => {
|
|
145
|
+
if (group.element && Array.isArray(group.element)) {
|
|
146
|
+
group.element.forEach(element => {
|
|
147
|
+
if (element.target && Array.isArray(element.target)) {
|
|
148
|
+
element.target.forEach(target => {
|
|
149
|
+
// If we have both equivalence and relationship, prefer equivalence for R4
|
|
150
|
+
if (target.relationship && !target.equivalence) {
|
|
151
|
+
target.equivalence = convertRelationshipToEquivalence(target.relationship);
|
|
152
|
+
}
|
|
153
|
+
// Remove R5-only relationship field
|
|
154
|
+
delete target.relationship;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return r5Obj;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Converts R5 ConceptMap to R3 format
|
|
167
|
+
* @param {Object} r5Obj - Cloned R5 ConceptMap object
|
|
168
|
+
* @returns {Object} R3 format ConceptMap
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
171
|
+
function conceptMapR5ToR3(r5Obj) {
|
|
172
|
+
// First apply R4 conversions
|
|
173
|
+
const r4Obj = conceptMapR5ToR4(r5Obj);
|
|
174
|
+
|
|
175
|
+
return r4Obj;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Converts R3/R4 equivalence to R5 relationship
|
|
181
|
+
* @param {string} equivalence - R3/R4 equivalence value
|
|
182
|
+
* @returns {string} R5 relationship value
|
|
183
|
+
* @private
|
|
184
|
+
*/
|
|
185
|
+
function convertEquivalenceToRelationship(equivalence) {
|
|
186
|
+
const equivalenceToRelationship = {
|
|
187
|
+
'relatedto': 'related-to',
|
|
188
|
+
'equivalent': 'equivalent',
|
|
189
|
+
'equal': 'equivalent',
|
|
190
|
+
'wider': 'source-is-broader-than-target',
|
|
191
|
+
'subsumes': 'source-is-broader-than-target',
|
|
192
|
+
'narrower': 'source-is-narrower-than-target',
|
|
193
|
+
'specializes': 'source-is-narrower-than-target',
|
|
194
|
+
'inexact': 'not-related-to',
|
|
195
|
+
'unmatched': 'not-related-to',
|
|
196
|
+
'disjoint': 'not-related-to'
|
|
197
|
+
};
|
|
198
|
+
return equivalenceToRelationship[equivalence] || 'related-to';
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Converts R5 relationship back to R3/R4 equivalence
|
|
203
|
+
* @param {string} relationship - R5 relationship value
|
|
204
|
+
* @returns {string} R3/R4 equivalence value
|
|
205
|
+
* @private
|
|
206
|
+
*/
|
|
207
|
+
function convertRelationshipToEquivalence(relationship) {
|
|
208
|
+
const relationshipToEquivalence = {
|
|
209
|
+
'related-to': 'relatedto',
|
|
210
|
+
'equivalent': 'equivalent',
|
|
211
|
+
'source-is-broader-than-target': 'wider',
|
|
212
|
+
'source-is-narrower-than-target': 'narrower',
|
|
213
|
+
'not-related-to': 'unmatched'
|
|
214
|
+
};
|
|
215
|
+
return relationshipToEquivalence[relationship] || 'relatedto';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
module.exports = { conceptMapToR5, conceptMapFromR5 };
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const {VersionUtilities} = require("../../library/version-utilities");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts input NamingSystem to R5 format (modifies input object for performance)
|
|
5
|
+
* @param {Object} jsonObj - The input NamingSystem object
|
|
6
|
+
* @param {string} version - Source FHIR version
|
|
7
|
+
* @returns {Object} The same object, potentially modified to R5 format
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
function namingSystemToR5(jsonObj, sourceVersion) {
|
|
12
|
+
if (VersionUtilities.isR5Ver(sourceVersion)) {
|
|
13
|
+
return jsonObj; // No conversion needed
|
|
14
|
+
}
|
|
15
|
+
if (VersionUtilities.isR3Ver(sourceVersion)) {
|
|
16
|
+
// R3 to R5: Remove replacedBy field (we ignore it completely)
|
|
17
|
+
if (jsonObj.replacedBy !== undefined) {
|
|
18
|
+
delete jsonObj.replacedBy;
|
|
19
|
+
}
|
|
20
|
+
return jsonObj;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (VersionUtilities.isR4Ver(sourceVersion)) {
|
|
24
|
+
// R4 to R5: No structural conversion needed
|
|
25
|
+
// R5 is backward compatible for the structural elements we care about
|
|
26
|
+
return jsonObj;
|
|
27
|
+
}
|
|
28
|
+
return jsonObj;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Converts R5 NamingSystem to target version format (clones object first)
|
|
33
|
+
* @param {Object} r5Obj - The R5 format NamingSystem object
|
|
34
|
+
* @param {string} targetVersion - Target FHIR version
|
|
35
|
+
* @returns {Object} New object in target version format
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
function namingSystemFromR5(r5Obj, targetVersion) {
|
|
39
|
+
if (VersionUtilities.isR5Ver(targetVersion)) {
|
|
40
|
+
return r5Obj; // No conversion needed
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Clone the object to avoid modifying the original
|
|
44
|
+
const cloned = JSON.parse(JSON.stringify(r5Obj));
|
|
45
|
+
|
|
46
|
+
if (VersionUtilities.isR4Ver(targetVersion)) {
|
|
47
|
+
return namingSystemR5ToR4(cloned);
|
|
48
|
+
} else if (VersionUtilities.isR3Ver(targetVersion)) {
|
|
49
|
+
return namingSystemR5ToR3(cloned);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
throw new Error(`Unsupported target FHIR version: ${targetVersion}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Converts R5 NamingSystem to R4 format
|
|
57
|
+
* @param {Object} r5Obj - Cloned R5 NamingSystem object
|
|
58
|
+
* @returns {Object} R4 format NamingSystem
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
function namingSystemR5ToR4(r5Obj) {
|
|
62
|
+
if (r5Obj.versionAlgorithmString) {
|
|
63
|
+
delete r5Obj.versionAlgorithmString;
|
|
64
|
+
}
|
|
65
|
+
if (r5Obj.versionAlgorithmCoding) {
|
|
66
|
+
delete r5Obj.versionAlgorithmCoding;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return r5Obj;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Converts R5 NamingSystem to R3 format
|
|
74
|
+
* @param {Object} r5Obj - Cloned R5 NamingSystem object
|
|
75
|
+
* @returns {Object} R3 format NamingSystem
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
function namingSystemR5ToR3(r5Obj) {
|
|
79
|
+
// First apply R4 conversions
|
|
80
|
+
const r4Obj = namingSystemR5ToR4(r5Obj);
|
|
81
|
+
|
|
82
|
+
// R3 doesn't have some R4/R5 fields, but we'll just let them through
|
|
83
|
+
// since most additions are backward compatible in JSON
|
|
84
|
+
return r4Obj;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = { namingSystemToR5, namingSystemFromR5 };
|
|
88
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts input OperationOutcome to R5 format (modifies input object for performance)
|
|
3
|
+
* @param {Object} jsonObj - The input OperationOutcome object
|
|
4
|
+
* @param {string} version - Source FHIR version
|
|
5
|
+
* @returns {Object} The same object, potentially modified to R5 format
|
|
6
|
+
* @private
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line no-unused-vars
|
|
10
|
+
function operationOutcomeToR5(jsonObj, sourceVersion) {
|
|
11
|
+
return jsonObj; // No conversion needed
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Converts R5 OperationOutcome to target version format (clones object first)
|
|
16
|
+
* @param {Object} r5Obj - The R5 format OperationOutcome object
|
|
17
|
+
* @param {string} targetVersion - Target FHIR version
|
|
18
|
+
* @returns {Object} New object in target version format
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
// eslint-disable-next-line no-unused-vars
|
|
22
|
+
function operationOutcomeFromR5(r5Obj, targetVersion) {
|
|
23
|
+
return r5Obj; // No conversion needed
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
module.exports = { operationOutcomeToR5, operationOutcomeFromR5 };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const {VersionUtilities} = require("../../library/version-utilities");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts input Parameters to R5 format (modifies input object for performance)
|
|
5
|
+
* @param {Object} jsonObj - The input Parameters object
|
|
6
|
+
* @param {string} version - Source FHIR version
|
|
7
|
+
* @returns {Object} The same object, potentially modified to R5 format
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
function parametersToR5(jsonObj, sourceVersion) {
|
|
12
|
+
if (VersionUtilities.isR5Ver(sourceVersion)) {
|
|
13
|
+
return jsonObj; // No conversion needed
|
|
14
|
+
}
|
|
15
|
+
throw new Error(`Unsupported FHIR version: ${sourceVersion}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Converts R5 Parameters to target version format (clones object first)
|
|
20
|
+
* @param {Object} r5Obj - The R5 format Parameters object
|
|
21
|
+
* @param {string} targetVersion - Target FHIR version
|
|
22
|
+
* @returns {Object} New object in target version format
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
function parametersFromR5(r5Obj, targetVersion) {
|
|
26
|
+
if (VersionUtilities.isR5Ver(targetVersion)) {
|
|
27
|
+
return r5Obj; // No conversion needed
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Clone the object to avoid modifying the original
|
|
31
|
+
const cloned = JSON.parse(JSON.stringify(r5Obj));
|
|
32
|
+
|
|
33
|
+
if (VersionUtilities.isR4Ver(targetVersion)) {
|
|
34
|
+
return parametersR5ToR4(cloned);
|
|
35
|
+
} else if (VersionUtilities.isR3Ver(targetVersion)) {
|
|
36
|
+
return parametersR5ToR3(cloned);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
throw new Error(`Unsupported target FHIR version: ${targetVersion}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Converts R5 Parameters to R4 format
|
|
44
|
+
* @param {Object} r5Obj - Cloned R5 Parameters object
|
|
45
|
+
* @returns {Object} R4 format Parameters
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
function parametersR5ToR4(r5Obj) {
|
|
49
|
+
const {convertResourceFromR5} = require("./xv-resource");
|
|
50
|
+
|
|
51
|
+
for (let p of r5Obj.parameter) {
|
|
52
|
+
if (p.resource) {
|
|
53
|
+
p.resource = convertResourceFromR5(p.resource, "R4");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return r5Obj;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function convertParameterR5ToR3(p) {
|
|
60
|
+
if (p.valueCanonical) {
|
|
61
|
+
p.valueUri = p.valueCanonical;
|
|
62
|
+
delete p.valueCanonical;
|
|
63
|
+
}
|
|
64
|
+
for (const pp of p.part || []) {
|
|
65
|
+
convertParameterR5ToR3(pp)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Converts R5 Parameters to R3 format
|
|
71
|
+
* @param {Object} r5Obj - Cloned R5 Parameters object
|
|
72
|
+
* @returns {Object} R3 format Parameters
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
function parametersR5ToR3(r5Obj) {
|
|
76
|
+
const {convertResourceFromR5} = require("./xv-resource");
|
|
77
|
+
|
|
78
|
+
for (let p of r5Obj.parameter) {
|
|
79
|
+
if (p.resource) {
|
|
80
|
+
p.resource = convertResourceFromR5(p.resource, "R3");
|
|
81
|
+
}
|
|
82
|
+
convertParameterR5ToR3(p);
|
|
83
|
+
}
|
|
84
|
+
return r5Obj;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = { parametersToR5, parametersFromR5 };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const {codeSystemFromR5} = require("./xv-codesystem");
|
|
2
|
+
const {capabilityStatementFromR5} = require("./xv-capabiliityStatement");
|
|
3
|
+
const {terminologyCapabilitiesFromR5} = require("./xv-terminologyCapabilities");
|
|
4
|
+
const {valueSetFromR5} = require("./xv-valueset");
|
|
5
|
+
const {conceptMapFromR5} = require("./xv-conceptmap");
|
|
6
|
+
const {parametersFromR5} = require("./xv-parameters");
|
|
7
|
+
const {operationOutcomeFromR5} = require("./xv-operationoutcome");
|
|
8
|
+
const {bundleFromR5} = require("./xv-bundle");
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
function convertResourceToR5(data, sourceVersion) {
|
|
12
|
+
if (sourceVersion == "5.0" || !data.resourceType) {
|
|
13
|
+
return data;
|
|
14
|
+
}
|
|
15
|
+
switch (data.resourceType) {
|
|
16
|
+
case "CodeSystem": return codeSystemFromR5(data, sourceVersion);
|
|
17
|
+
case "CapabilityStatement": return capabilityStatementFromR5(data, sourceVersion);
|
|
18
|
+
case "TerminologyCapabilities": return terminologyCapabilitiesFromR5(data, sourceVersion);
|
|
19
|
+
case "ValueSet": return valueSetFromR5(data, sourceVersion);
|
|
20
|
+
case "ConceptMap": return conceptMapFromR5(data, sourceVersion);
|
|
21
|
+
case "Parameters": return parametersFromR5(data, sourceVersion);
|
|
22
|
+
case "OperationOutcome": return operationOutcomeFromR5(data, sourceVersion);
|
|
23
|
+
case "Bundle": return bundleFromR5(data, sourceVersion);
|
|
24
|
+
default: return data;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function convertResourceFromR5(data, targetVersion) {
|
|
29
|
+
if (targetVersion == "5.0" || !data.resourceType) {
|
|
30
|
+
return data;
|
|
31
|
+
}
|
|
32
|
+
switch (data.resourceType) {
|
|
33
|
+
case "CodeSystem": return codeSystemFromR5(data, targetVersion);
|
|
34
|
+
case "CapabilityStatement": return capabilityStatementFromR5(data, targetVersion);
|
|
35
|
+
case "TerminologyCapabilities": return terminologyCapabilitiesFromR5(data, targetVersion);
|
|
36
|
+
case "ValueSet": return valueSetFromR5(data, targetVersion);
|
|
37
|
+
case "ConceptMap": return conceptMapFromR5(data, targetVersion);
|
|
38
|
+
case "Parameters": return parametersFromR5(data, targetVersion);
|
|
39
|
+
case "OperationOutcome": return operationOutcomeFromR5(data, targetVersion);
|
|
40
|
+
case "Bundle": return bundleFromR5(data, targetVersion);
|
|
41
|
+
default: return data;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { convertResourceToR5, convertResourceFromR5 };
|