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.
Files changed (92) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +1 -1
  3. package/library/cron-utilities.js +136 -0
  4. package/library/html-server.js +13 -29
  5. package/library/html.js +3 -8
  6. package/library/languages.js +160 -37
  7. package/library/package-manager.js +48 -1
  8. package/library/utilities.js +100 -19
  9. package/package.json +2 -2
  10. package/packages/package-crawler.js +6 -1
  11. package/packages/packages.js +38 -54
  12. package/publisher/publisher.js +19 -27
  13. package/registry/api.js +11 -10
  14. package/registry/crawler.js +31 -29
  15. package/registry/model.js +5 -26
  16. package/registry/registry.js +32 -41
  17. package/server.js +89 -12
  18. package/shl/shl.js +0 -18
  19. package/static/assets/js/statuspage.js +1 -9
  20. package/stats.js +39 -1
  21. package/token/token.js +14 -9
  22. package/translations/Messages.properties +2 -1
  23. package/tx/README.md +17 -6
  24. package/tx/cs/cs-api.js +19 -1
  25. package/tx/cs/cs-base.js +77 -0
  26. package/tx/cs/cs-country.js +46 -0
  27. package/tx/cs/cs-cpt.js +9 -5
  28. package/tx/cs/cs-cs.js +27 -13
  29. package/tx/cs/cs-lang.js +60 -22
  30. package/tx/cs/cs-loinc.js +69 -98
  31. package/tx/cs/cs-mimetypes.js +4 -0
  32. package/tx/cs/cs-ndc.js +6 -0
  33. package/tx/cs/cs-omop.js +16 -15
  34. package/tx/cs/cs-rxnorm.js +23 -1
  35. package/tx/cs/cs-snomed.js +283 -40
  36. package/tx/cs/cs-ucum.js +90 -70
  37. package/tx/importers/import-sct.module.js +371 -35
  38. package/tx/importers/readme.md +117 -7
  39. package/tx/library/bundle.js +5 -0
  40. package/tx/library/capabilitystatement.js +3 -142
  41. package/tx/library/codesystem.js +19 -173
  42. package/tx/library/conceptmap.js +4 -218
  43. package/tx/library/designations.js +14 -1
  44. package/tx/library/extensions.js +7 -0
  45. package/tx/library/namingsystem.js +3 -89
  46. package/tx/library/operation-outcome.js +8 -3
  47. package/tx/library/parameters.js +3 -2
  48. package/tx/library/renderer.js +10 -6
  49. package/tx/library/terminologycapabilities.js +3 -243
  50. package/tx/library/valueset.js +3 -235
  51. package/tx/library.js +100 -13
  52. package/tx/operation-context.js +23 -4
  53. package/tx/params.js +35 -38
  54. package/tx/provider.js +6 -5
  55. package/tx/sct/expressions.js +12 -3
  56. package/tx/tx-html.js +80 -89
  57. package/tx/tx.fhir.org.yml +6 -5
  58. package/tx/tx.js +163 -13
  59. package/tx/vs/vs-database.js +56 -39
  60. package/tx/vs/vs-package.js +21 -2
  61. package/tx/vs/vs-vsac.js +175 -39
  62. package/tx/workers/batch-validate.js +2 -0
  63. package/tx/workers/batch.js +2 -0
  64. package/tx/workers/expand.js +132 -112
  65. package/tx/workers/lookup.js +33 -14
  66. package/tx/workers/metadata.js +2 -2
  67. package/tx/workers/read.js +3 -2
  68. package/tx/workers/related.js +574 -0
  69. package/tx/workers/search.js +46 -9
  70. package/tx/workers/subsumes.js +13 -3
  71. package/tx/workers/translate.js +7 -3
  72. package/tx/workers/validate.js +258 -285
  73. package/tx/workers/worker.js +43 -39
  74. package/tx/xml/bundle-xml.js +237 -0
  75. package/tx/xml/xml-base.js +215 -64
  76. package/tx/xversion/xv-bundle.js +71 -0
  77. package/tx/xversion/xv-capabiliityStatement.js +137 -0
  78. package/tx/xversion/xv-codesystem.js +169 -0
  79. package/tx/xversion/xv-conceptmap.js +224 -0
  80. package/tx/xversion/xv-namingsystem.js +88 -0
  81. package/tx/xversion/xv-operationoutcome.js +27 -0
  82. package/tx/xversion/xv-parameters.js +87 -0
  83. package/tx/xversion/xv-resource.js +45 -0
  84. package/tx/xversion/xv-terminologyCapabilities.js +214 -0
  85. package/tx/xversion/xv-valueset.js +234 -0
  86. package/utilities/dev-proxy-server.js +126 -0
  87. package/utilities/explode-results.js +58 -0
  88. package/utilities/split-by-system.js +198 -0
  89. package/utilities/vsac-cs-fetcher.js +0 -0
  90. package/{windows-install.js → utilities/windows-install.js} +2 -0
  91. package/vcl/vcl.js +0 -18
  92. 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 };