fhirsmith 0.3.0

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 (277) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/FHIRsmith.png +0 -0
  3. package/README.md +277 -0
  4. package/config-template.json +144 -0
  5. package/library/folder-setup.js +58 -0
  6. package/library/html-server.js +166 -0
  7. package/library/html.js +835 -0
  8. package/library/i18nsupport.js +259 -0
  9. package/library/languages.js +779 -0
  10. package/library/logger-telnet.js +205 -0
  11. package/library/logger.js +279 -0
  12. package/library/package-manager.js +876 -0
  13. package/library/utilities.js +196 -0
  14. package/library/version-utilities.js +1056 -0
  15. package/npmprojector/config-example.json +13 -0
  16. package/npmprojector/indexer.js +394 -0
  17. package/npmprojector/npmprojector.js +395 -0
  18. package/npmprojector/readme.md +174 -0
  19. package/npmprojector/watcher.js +335 -0
  20. package/package.json +119 -0
  21. package/packages/package-crawler.js +846 -0
  22. package/packages/packages-template.html +126 -0
  23. package/packages/packages.js +2838 -0
  24. package/passwords.ini +2 -0
  25. package/publisher/publisher-template.html +208 -0
  26. package/publisher/publisher.js +2167 -0
  27. package/publisher/task-draft.js +458 -0
  28. package/registry/api.js +735 -0
  29. package/registry/crawler.js +637 -0
  30. package/registry/model.js +513 -0
  31. package/registry/readme.md +243 -0
  32. package/registry/registry-data.json +121015 -0
  33. package/registry/registry-template.html +126 -0
  34. package/registry/registry.js +1395 -0
  35. package/registry/test-runner.js +237 -0
  36. package/root-template.html +124 -0
  37. package/server.js +524 -0
  38. package/shl/private-key.pem +5 -0
  39. package/shl/public-key.pem +18 -0
  40. package/shl/shl.js +1125 -0
  41. package/shl/vhl.js +69 -0
  42. package/static/FHIRsmith128.png +0 -0
  43. package/static/FHIRsmith16.png +0 -0
  44. package/static/FHIRsmith32.png +0 -0
  45. package/static/FHIRsmith64.png +0 -0
  46. package/static/assets/css/bootstrap-fhir.css +5302 -0
  47. package/static/assets/css/bootstrap-glyphicons.css +2 -0
  48. package/static/assets/css/bootstrap.css +4097 -0
  49. package/static/assets/css/jquery-ui.css +523 -0
  50. package/static/assets/css/jquery-ui.structure.css +863 -0
  51. package/static/assets/css/jquery-ui.structure.min.css +5 -0
  52. package/static/assets/css/jquery-ui.theme.css +439 -0
  53. package/static/assets/css/jquery-ui.theme.min.css +5 -0
  54. package/static/assets/css/jquery.ui.all.css +7 -0
  55. package/static/assets/css/modules.css +18 -0
  56. package/static/assets/css/project.css +367 -0
  57. package/static/assets/css/pygments-manni.css +66 -0
  58. package/static/assets/css/tags.css +74 -0
  59. package/static/assets/css/xml.css +2 -0
  60. package/static/assets/fonts/glyphiconshalflings-regular.eot +0 -0
  61. package/static/assets/fonts/glyphiconshalflings-regular.otf +0 -0
  62. package/static/assets/fonts/glyphiconshalflings-regular.svg +175 -0
  63. package/static/assets/fonts/glyphiconshalflings-regular.ttf +0 -0
  64. package/static/assets/fonts/glyphiconshalflings-regular.woff +0 -0
  65. package/static/assets/ico/apple-touch-icon-114-precomposed.png +0 -0
  66. package/static/assets/ico/apple-touch-icon-144-precomposed.png +0 -0
  67. package/static/assets/ico/apple-touch-icon-57-precomposed.png +0 -0
  68. package/static/assets/ico/apple-touch-icon-72-precomposed.png +0 -0
  69. package/static/assets/ico/favicon.ico +0 -0
  70. package/static/assets/ico/favicon.png +0 -0
  71. package/static/assets/images/fhir-logo-www.png +0 -0
  72. package/static/assets/images/fhir-logo.png +0 -0
  73. package/static/assets/images/hl7-logo.png +0 -0
  74. package/static/assets/images/logo_ansinew.jpg +0 -0
  75. package/static/assets/images/search.png +0 -0
  76. package/static/assets/images/stripe.png +0 -0
  77. package/static/assets/images/target.png +0 -0
  78. package/static/assets/images/tx-registry-root.gif +0 -0
  79. package/static/assets/images/tx-registry.png +0 -0
  80. package/static/assets/images/tx-server.png +0 -0
  81. package/static/assets/images/tx-version.png +0 -0
  82. package/static/assets/js/bootstrap.min.js +6 -0
  83. package/static/assets/js/fhir-gw.js +259 -0
  84. package/static/assets/js/fhir.js +2 -0
  85. package/static/assets/js/html5shiv.js +8 -0
  86. package/static/assets/js/jcookie.js +96 -0
  87. package/static/assets/js/jquery-ui.min.js +6 -0
  88. package/static/assets/js/jquery.js +10716 -0
  89. package/static/assets/js/jquery.min.js +2 -0
  90. package/static/assets/js/jquery.ui.core.js +314 -0
  91. package/static/assets/js/jquery.ui.draggable.js +825 -0
  92. package/static/assets/js/jquery.ui.mouse.js +162 -0
  93. package/static/assets/js/jquery.ui.resizable.js +842 -0
  94. package/static/assets/js/jquery.ui.widget.js +268 -0
  95. package/static/assets/js/json2.js +487 -0
  96. package/static/assets/js/jtip.js +97 -0
  97. package/static/assets/js/respond.min.js +6 -0
  98. package/static/assets/js/statuspage.js +70 -0
  99. package/static/assets/js/xml.js +2 -0
  100. package/static/dist/js/bootstrap.js +1964 -0
  101. package/static/favicon.png +0 -0
  102. package/static/fhir.css +626 -0
  103. package/static/icon-fhir-16.png +0 -0
  104. package/static/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  105. package/static/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  106. package/static/images/ui-bg_flat_10_000000_40x100.png +0 -0
  107. package/static/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  108. package/static/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  109. package/static/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  110. package/static/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  111. package/static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  112. package/static/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  113. package/static/images/ui-icons_222222_256x240.png +0 -0
  114. package/static/images/ui-icons_228ef1_256x240.png +0 -0
  115. package/static/images/ui-icons_ef8c08_256x240.png +0 -0
  116. package/static/images/ui-icons_ffd27a_256x240.png +0 -0
  117. package/static/images/ui-icons_ffffff_256x240.png +0 -0
  118. package/static/js/jquery.effects.blind.js +49 -0
  119. package/static/js/jquery.effects.bounce.js +78 -0
  120. package/static/js/jquery.effects.clip.js +54 -0
  121. package/static/js/jquery.effects.core.js +763 -0
  122. package/static/js/jquery.effects.drop.js +50 -0
  123. package/static/js/jquery.effects.explode.js +79 -0
  124. package/static/js/jquery.effects.fade.js +32 -0
  125. package/static/js/jquery.effects.fold.js +56 -0
  126. package/static/js/jquery.effects.highlight.js +50 -0
  127. package/static/js/jquery.effects.pulsate.js +51 -0
  128. package/static/js/jquery.effects.scale.js +178 -0
  129. package/static/js/jquery.effects.shake.js +57 -0
  130. package/static/js/jquery.effects.slide.js +50 -0
  131. package/static/js/jquery.effects.transfer.js +45 -0
  132. package/static/js/jquery.ui.accordion.js +611 -0
  133. package/static/js/jquery.ui.autocomplete.js +612 -0
  134. package/static/js/jquery.ui.button.js +416 -0
  135. package/static/js/jquery.ui.datepicker.js +1823 -0
  136. package/static/js/jquery.ui.dialog.js +878 -0
  137. package/static/js/jquery.ui.droppable.js +296 -0
  138. package/static/js/jquery.ui.position.js +252 -0
  139. package/static/js/jquery.ui.progressbar.js +109 -0
  140. package/static/js/jquery.ui.selectable.js +266 -0
  141. package/static/js/jquery.ui.slider.js +666 -0
  142. package/static/js/jquery.ui.sortable.js +1077 -0
  143. package/static/js/jquery.ui.tabs.js +758 -0
  144. package/stats.js +80 -0
  145. package/test-cache/vsac/vsac-valuesets.db +0 -0
  146. package/token/nginx_passport_setup.md +383 -0
  147. package/token/security_guide.md +294 -0
  148. package/token/token-template.html +330 -0
  149. package/token/token.js +1300 -0
  150. package/translations/Messages.properties +1510 -0
  151. package/translations/Messages_ar.properties +1399 -0
  152. package/translations/Messages_de.properties +836 -0
  153. package/translations/Messages_es.properties +737 -0
  154. package/translations/Messages_fr.properties +1 -0
  155. package/translations/Messages_ja.properties +893 -0
  156. package/translations/Messages_nl.properties +1357 -0
  157. package/translations/Messages_pt.properties +1302 -0
  158. package/translations/Messages_ru.properties +1 -0
  159. package/translations/Messages_uz.properties +1 -0
  160. package/translations/Messages_zh.properties +1 -0
  161. package/translations/rendering-phrases.properties +1128 -0
  162. package/translations/rendering-phrases_ar.properties +1091 -0
  163. package/translations/rendering-phrases_de.properties +6 -0
  164. package/translations/rendering-phrases_es.properties +6 -0
  165. package/translations/rendering-phrases_fr.properties +624 -0
  166. package/translations/rendering-phrases_ja.properties +21 -0
  167. package/translations/rendering-phrases_nl.properties +970 -0
  168. package/translations/rendering-phrases_pt.properties +1020 -0
  169. package/translations/rendering-phrases_ru.properties +1094 -0
  170. package/translations/rendering-phrases_uz.properties +1 -0
  171. package/translations/rendering-phrases_zh.properties +1 -0
  172. package/tx/README.md +418 -0
  173. package/tx/cm/cm-api.js +110 -0
  174. package/tx/cm/cm-database.js +735 -0
  175. package/tx/cm/cm-package.js +325 -0
  176. package/tx/cs/cs-api.js +789 -0
  177. package/tx/cs/cs-areacode.js +615 -0
  178. package/tx/cs/cs-country.js +1110 -0
  179. package/tx/cs/cs-cpt.js +785 -0
  180. package/tx/cs/cs-cs.js +1579 -0
  181. package/tx/cs/cs-currency.js +539 -0
  182. package/tx/cs/cs-db.js +1321 -0
  183. package/tx/cs/cs-hgvs.js +329 -0
  184. package/tx/cs/cs-lang.js +465 -0
  185. package/tx/cs/cs-loinc.js +1485 -0
  186. package/tx/cs/cs-mimetypes.js +238 -0
  187. package/tx/cs/cs-ndc.js +704 -0
  188. package/tx/cs/cs-omop.js +1025 -0
  189. package/tx/cs/cs-provider-api.js +43 -0
  190. package/tx/cs/cs-provider-list.js +37 -0
  191. package/tx/cs/cs-rxnorm.js +808 -0
  192. package/tx/cs/cs-snomed.js +1102 -0
  193. package/tx/cs/cs-ucum.js +514 -0
  194. package/tx/cs/cs-unii.js +271 -0
  195. package/tx/cs/cs-uri.js +218 -0
  196. package/tx/cs/cs-usstates.js +305 -0
  197. package/tx/dev.fhir.org.yml +14 -0
  198. package/tx/fixtures/test-cases-setup.json +18 -0
  199. package/tx/fixtures/test-cases.yml +16 -0
  200. package/tx/html/codesystem-operations.liquid +25 -0
  201. package/tx/html/home-metrics.liquid +247 -0
  202. package/tx/html/operations-form.liquid +148 -0
  203. package/tx/html/search-form.liquid +62 -0
  204. package/tx/html/tx-template.html +133 -0
  205. package/tx/html/valueset-operations.liquid +54 -0
  206. package/tx/importers/atc-to-fhir.js +316 -0
  207. package/tx/importers/import-loinc.module.js +1536 -0
  208. package/tx/importers/import-ndc.module.js +1088 -0
  209. package/tx/importers/import-rxnorm.module.js +898 -0
  210. package/tx/importers/import-sct.module.js +2457 -0
  211. package/tx/importers/import-unii.module.js +601 -0
  212. package/tx/importers/readme.md +453 -0
  213. package/tx/importers/subset-loinc.module.js +1081 -0
  214. package/tx/importers/subset-rxnorm.module.js +938 -0
  215. package/tx/importers/tx-import-base.js +351 -0
  216. package/tx/importers/tx-import-settings.js +310 -0
  217. package/tx/importers/tx-import.js +357 -0
  218. package/tx/library/canonical-resource.js +88 -0
  219. package/tx/library/capabilitystatement.js +292 -0
  220. package/tx/library/codesystem.js +774 -0
  221. package/tx/library/conceptmap.js +568 -0
  222. package/tx/library/designations.js +932 -0
  223. package/tx/library/errors.js +77 -0
  224. package/tx/library/extensions.js +117 -0
  225. package/tx/library/namingsystem.js +322 -0
  226. package/tx/library/operation-outcome.js +127 -0
  227. package/tx/library/parameters.js +105 -0
  228. package/tx/library/renderer.js +1559 -0
  229. package/tx/library/terminologycapabilities.js +418 -0
  230. package/tx/library/ucum-parsers.js +1029 -0
  231. package/tx/library/ucum-service.js +370 -0
  232. package/tx/library/ucum-types.js +1099 -0
  233. package/tx/library/valueset.js +543 -0
  234. package/tx/library.js +676 -0
  235. package/tx/ocl/cm-ocl.js +106 -0
  236. package/tx/ocl/cs-ocl.js +39 -0
  237. package/tx/ocl/vs-ocl.js +105 -0
  238. package/tx/operation-context.js +568 -0
  239. package/tx/params.js +613 -0
  240. package/tx/provider.js +403 -0
  241. package/tx/sct/ecl.js +1560 -0
  242. package/tx/sct/expressions.js +2077 -0
  243. package/tx/sct/structures.js +1396 -0
  244. package/tx/tx-html.js +1063 -0
  245. package/tx/tx.fhir.org.yml +39 -0
  246. package/tx/tx.js +927 -0
  247. package/tx/vs/vs-api.js +112 -0
  248. package/tx/vs/vs-database.js +786 -0
  249. package/tx/vs/vs-package.js +358 -0
  250. package/tx/vs/vs-vsac.js +366 -0
  251. package/tx/workers/batch-validate.js +129 -0
  252. package/tx/workers/batch.js +361 -0
  253. package/tx/workers/closure.js +32 -0
  254. package/tx/workers/expand.js +1845 -0
  255. package/tx/workers/lookup.js +407 -0
  256. package/tx/workers/metadata.js +467 -0
  257. package/tx/workers/operations.js +34 -0
  258. package/tx/workers/read.js +164 -0
  259. package/tx/workers/search.js +384 -0
  260. package/tx/workers/subsumes.js +334 -0
  261. package/tx/workers/translate.js +492 -0
  262. package/tx/workers/validate.js +2504 -0
  263. package/tx/workers/worker.js +904 -0
  264. package/tx/xml/capabilitystatement-xml.js +63 -0
  265. package/tx/xml/codesystem-xml.js +62 -0
  266. package/tx/xml/conceptmap-xml.js +65 -0
  267. package/tx/xml/namingsystem-xml.js +65 -0
  268. package/tx/xml/operationoutcome-xml.js +127 -0
  269. package/tx/xml/parameters-xml.js +312 -0
  270. package/tx/xml/terminologycapabilities-xml.js +64 -0
  271. package/tx/xml/valueset-xml.js +64 -0
  272. package/tx/xml/xml-base.js +603 -0
  273. package/vcl/vcl-parser.js +1098 -0
  274. package/vcl/vcl.js +253 -0
  275. package/windows-install.js +19 -0
  276. package/xig/xig-template.html +124 -0
  277. package/xig/xig.js +3049 -0
@@ -0,0 +1,357 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require('commander');
4
+ const chalk = require('chalk');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { getConfigManager } = require('./tx-import-settings');
8
+
9
+ class TerminologyImportCLI {
10
+ constructor() {
11
+ this.program = new Command();
12
+ this.modules = new Map();
13
+ this.setupMainProgram();
14
+ this.discoverAndLoadModules();
15
+ }
16
+
17
+ setupMainProgram() {
18
+ this.program
19
+ .name('tx-import')
20
+ .description('Medical terminology import tool')
21
+ .version('1.0.0');
22
+
23
+ // Add global options
24
+ this.program
25
+ .option('--verbose', 'enable verbose logging')
26
+ .option('--config <file>', 'global config file')
27
+ .option('--dry-run', 'validate without importing');
28
+
29
+ // List available terminologies
30
+ this.program
31
+ .command('list')
32
+ .description('List available terminology importers')
33
+ .action(() => this.listTerminologies());
34
+
35
+ // Configuration management
36
+ this.program
37
+ .command('config')
38
+ .description('Manage configuration and history')
39
+ .action(() => this.showConfigHelp());
40
+
41
+ this.program
42
+ .command('config:show')
43
+ .description('Show saved configuration history')
44
+ .option('-t, --terminology <name>', 'Show config for specific terminology')
45
+ .action((options) => this.showConfig(options));
46
+
47
+ this.program
48
+ .command('config:clear')
49
+ .description('Clear saved configuration history')
50
+ .option('-t, --terminology <name>', 'Clear config for specific terminology')
51
+ .option('-a, --all', 'Clear all configuration history')
52
+ .action((options) => this.clearConfig(options));
53
+
54
+ this.program
55
+ .command('config:export')
56
+ .description('Export configuration to file')
57
+ .option('-o, --output <file>', 'Output file path', './tx-import-config.json')
58
+ .action((options) => this.exportConfig(options));
59
+
60
+ this.program
61
+ .command('config:import')
62
+ .description('Import configuration from file')
63
+ .option('-i, --input <file>', 'Input file path')
64
+ .action((options) => this.importConfig(options));
65
+
66
+ // Help command
67
+ this.program
68
+ .command('help [command]')
69
+ .description('Display help for command')
70
+ .action((cmd) => this.showHelp(cmd));
71
+ }
72
+
73
+ discoverAndLoadModules() {
74
+ console.log("Looking in " + __dirname);
75
+
76
+ const moduleFiles = fs.readdirSync(__dirname)
77
+ .filter(file => file.endsWith('.module.js') && !file.startsWith('_'))
78
+ .map(file => path.join(__dirname, file));
79
+
80
+ for (const moduleFile of moduleFiles) {
81
+ try {
82
+ const moduleExports = require(moduleFile);
83
+
84
+ // Handle different export formats
85
+ let ModuleClass;
86
+ if (typeof moduleExports === 'function') {
87
+ // Direct class export: module.exports = UniiModule
88
+ ModuleClass = moduleExports;
89
+ } else if (moduleExports.default) {
90
+ // ES6 default export
91
+ ModuleClass = moduleExports.default;
92
+ } else {
93
+ // Object export - find the module class
94
+ // Look for a class that ends with 'Module'
95
+ const moduleClassNames = Object.keys(moduleExports)
96
+ .filter(key => key.endsWith('Module') && typeof moduleExports[key] === 'function');
97
+
98
+ if (moduleClassNames.length > 0) {
99
+ ModuleClass = moduleExports[moduleClassNames[0]];
100
+ } else {
101
+ throw new Error('No module class found in exports');
102
+ }
103
+ }
104
+
105
+ const moduleInstance = new ModuleClass();
106
+
107
+ if (this.isValidModule(moduleInstance)) {
108
+ this.registerModule(moduleInstance);
109
+ } else {
110
+ console.warn(chalk.yellow(`Warning: Invalid module format in ${moduleFile}`));
111
+ }
112
+ } catch (error) {
113
+ console.warn(chalk.yellow(`Warning: Failed to load module ${moduleFile}: ${error.message}`));
114
+ }
115
+ }
116
+ }
117
+
118
+ isValidModule(module) {
119
+ return (
120
+ typeof module.getName === 'function' &&
121
+ typeof module.getDescription === 'function' &&
122
+ typeof module.registerCommands === 'function'
123
+ );
124
+ }
125
+
126
+ registerModule(module) {
127
+ const name = module.getName();
128
+
129
+ if (this.modules.has(name)) {
130
+ console.warn(chalk.yellow(`Warning: Module ${name} already registered, skipping`));
131
+ return;
132
+ }
133
+
134
+ this.modules.set(name, module);
135
+
136
+ // Create command group for this terminology
137
+ const terminologyCommand = this.program
138
+ .command(name)
139
+ .description(module.getDescription());
140
+
141
+ // Let the module register its subcommands
142
+ module.registerCommands(terminologyCommand, this.program.opts());
143
+
144
+ console.log(chalk.green(`✓ Loaded ${name} module`));
145
+ }
146
+
147
+ listTerminologies() {
148
+ console.log(chalk.blue.bold('🏥 Available Terminology Importers\\n'));
149
+
150
+ if (this.modules.size === 0) {
151
+ console.log(chalk.yellow('No terminology modules found.'));
152
+ console.log(chalk.gray('Add modules to the ./modules/ directory.'));
153
+ return;
154
+ }
155
+
156
+ for (const [name, module] of this.modules) {
157
+ console.log(chalk.cyan(`${name}:`));
158
+ console.log(` ${module.getDescription()}`);
159
+
160
+ if (module.getSupportedFormats) {
161
+ const formats = module.getSupportedFormats();
162
+ console.log(chalk.gray(` Formats: ${formats.join(', ')}`));
163
+ }
164
+
165
+ if (module.getEstimatedDuration) {
166
+ console.log(chalk.gray(` Typical duration: ${module.getEstimatedDuration()}`));
167
+ }
168
+
169
+ console.log('');
170
+ }
171
+
172
+ console.log(chalk.gray('Use "tx-import <terminology> --help" for specific options'));
173
+ }
174
+
175
+ showHelp(commandName) {
176
+ if (!commandName) {
177
+ this.program.help();
178
+ return;
179
+ }
180
+
181
+ if (this.modules.has(commandName)) {
182
+ console.log(chalk.blue.bold(`Help for ${commandName}:\\n`));
183
+ this.program.commands
184
+ .find(cmd => cmd.name() === commandName)
185
+ ?.help();
186
+ } else {
187
+ console.log(chalk.red(`Unknown command: ${commandName}`));
188
+ this.listTerminologies();
189
+ }
190
+ }
191
+
192
+ showConfigHelp() {
193
+ console.log(chalk.blue.bold('📁 Configuration Management\\n'));
194
+ console.log('Available configuration commands:');
195
+ console.log(' tx-import config:show Show saved configuration history');
196
+ console.log(' tx-import config:clear Clear saved configuration history');
197
+ console.log(' tx-import config:export Export configuration to file');
198
+ console.log(' tx-import config:import Import configuration from file');
199
+ console.log('\\nExamples:');
200
+ console.log(' tx-import config:show --terminology unii');
201
+ console.log(' tx-import config:clear --terminology loinc');
202
+ console.log(' tx-import config:export --output my-config.json');
203
+ }
204
+
205
+ showConfig(options) {
206
+ const configManager = getConfigManager();
207
+
208
+ if (options.terminology) {
209
+ // Show config for specific terminology
210
+ const config = configManager.getPreviousConfig(options.terminology);
211
+
212
+ if (Object.keys(config).length === 0) {
213
+ console.log(chalk.yellow(`No saved configuration found for ${options.terminology}`));
214
+ return;
215
+ }
216
+
217
+ console.log(chalk.blue.bold(`📋 Saved Configuration for ${options.terminology}:\\n`));
218
+
219
+ if (config.lastUsed) {
220
+ console.log(`Last used: ${chalk.white(new Date(config.lastUsed).toLocaleString())}`);
221
+ }
222
+
223
+ Object.entries(config).forEach(([key, value]) => {
224
+ if (key !== 'lastUsed' && key !== 'recentSources') {
225
+ if (Array.isArray(value)) {
226
+ console.log(` ${key}: ${chalk.white(value.join(', '))}`);
227
+ } else {
228
+ console.log(` ${key}: ${chalk.white(value)}`);
229
+ }
230
+ }
231
+ });
232
+
233
+ if (config.recentSources && config.recentSources.length > 0) {
234
+ console.log(`\\n Recent sources:`);
235
+ config.recentSources.forEach((src, index) => {
236
+ console.log(` ${index + 1}. ${chalk.gray(src)}`);
237
+ });
238
+ }
239
+
240
+ } else {
241
+ // Show all configurations
242
+ const allHistory = configManager.history;
243
+
244
+ if (Object.keys(allHistory).length === 0) {
245
+ console.log(chalk.yellow('No saved configurations found'));
246
+ return;
247
+ }
248
+
249
+ console.log(chalk.blue.bold('📋 All Saved Configurations:\\n'));
250
+
251
+ Object.entries(allHistory).forEach(([terminology, config]) => {
252
+ console.log(chalk.cyan(`${terminology}:`));
253
+ if (config.lastUsed) {
254
+ console.log(` Last used: ${chalk.white(new Date(config.lastUsed).toLocaleString())}`);
255
+ }
256
+ if (config.source) {
257
+ console.log(` Source: ${chalk.gray(config.source)}`);
258
+ }
259
+ if (config.version) {
260
+ console.log(` Version: ${chalk.gray(config.version)}`);
261
+ }
262
+ console.log('');
263
+ });
264
+ }
265
+ }
266
+
267
+ async clearConfig(options) {
268
+ const configManager = getConfigManager();
269
+ const inquirer = require('inquirer');
270
+
271
+ if (options.all) {
272
+ const { confirmed } = await inquirer.prompt({
273
+ type: 'confirm',
274
+ name: 'confirmed',
275
+ message: 'Clear ALL saved configuration history?',
276
+ default: false
277
+ });
278
+
279
+ if (confirmed) {
280
+ configManager.clearAllHistory();
281
+ console.log(chalk.green('✓ All configuration history cleared'));
282
+ } else {
283
+ console.log(chalk.yellow('Configuration clear cancelled'));
284
+ }
285
+
286
+ } else if (options.terminology) {
287
+ const { confirmed } = await inquirer.prompt({
288
+ type: 'confirm',
289
+ name: 'confirmed',
290
+ message: `Clear saved configuration for ${options.terminology}?`,
291
+ default: false
292
+ });
293
+
294
+ if (confirmed) {
295
+ configManager.clearHistory(options.terminology);
296
+ console.log(chalk.green(`✓ Configuration history cleared for ${options.terminology}`));
297
+ } else {
298
+ console.log(chalk.yellow('Configuration clear cancelled'));
299
+ }
300
+
301
+ } else {
302
+ console.log(chalk.red('Please specify --terminology <name> or --all'));
303
+ console.log('Example: tx-import config:clear --terminology unii');
304
+ }
305
+ }
306
+
307
+ exportConfig(options) {
308
+ const configManager = getConfigManager();
309
+ const data = configManager.exportConfig();
310
+
311
+ try {
312
+ fs.writeFileSync(options.output, JSON.stringify(data, null, 2));
313
+ console.log(chalk.green(`✓ Configuration exported to ${options.output}`));
314
+ } catch (error) {
315
+ console.log(chalk.red(`✗ Export failed: ${error.message}`));
316
+ }
317
+ }
318
+
319
+ async importConfig(options) {
320
+ if (!options.input) {
321
+ const inquirer = require('inquirer');
322
+ const { input } = await inquirer.prompt({
323
+ type: 'input',
324
+ name: 'input',
325
+ message: 'Configuration file to import:',
326
+ validate: (input) => fs.existsSync(input) ? true : 'File does not exist'
327
+ });
328
+ options.input = input;
329
+ }
330
+
331
+ const configManager = getConfigManager();
332
+
333
+ try {
334
+ const data = JSON.parse(fs.readFileSync(options.input, 'utf8'));
335
+ configManager.importConfig(data);
336
+ console.log(chalk.green(`✓ Configuration imported from ${options.input}`));
337
+ } catch (error) {
338
+ console.log(chalk.red(`✗ Import failed: ${error.message}`));
339
+ }
340
+ }
341
+
342
+ run() {
343
+ // Show logo and loaded modules
344
+ console.log(chalk.blue.bold('🏥 TX-Import - Medical Terminology Import Tool'));
345
+ console.log(chalk.gray(`Loaded ${this.modules.size} terminology module(s)\\n`));
346
+
347
+ this.program.parse();
348
+ }
349
+ }
350
+
351
+ // CLI entry point
352
+ if (require.main === module) {
353
+ const cli = new TerminologyImportCLI();
354
+ cli.run();
355
+ }
356
+
357
+ module.exports = { TerminologyImportCLI };
@@ -0,0 +1,88 @@
1
+
2
+ /**
3
+ * Base class for metadata resources to provide common interface
4
+ */
5
+ class CanonicalResource {
6
+ /**
7
+ * The original JSON object (always stored in R5 format internally)
8
+ * @type {Object}
9
+ */
10
+ jsonObj = null;
11
+
12
+ /**
13
+ * FHIR source version of the loaded Resource
14
+ *
15
+ * Note that the constructors of the sub-classes conver the actual format to R5
16
+ * this is the source version, not the actual version
17
+ *
18
+ * @type {string}
19
+ */
20
+ fhirVersion = 'R5';
21
+
22
+ /**
23
+ * The source package the CodeSystem was loaded from
24
+ * @type {String}
25
+ */
26
+ sourcePackage = null;
27
+
28
+ constructor(jsonObj, fhirVersion = 'R5') {
29
+ this.jsonObj = jsonObj;
30
+ this.fhirVersion = fhirVersion;
31
+ }
32
+
33
+ get resourceType() {
34
+ return this.jsonObj.resourceType;
35
+ }
36
+
37
+ get url() {
38
+ return this.jsonObj.url;
39
+ }
40
+
41
+ get version() {
42
+ return this.jsonObj.version;
43
+ }
44
+
45
+ get name() {
46
+ return this.jsonObj.name;
47
+ }
48
+
49
+ get title() {
50
+ return this.jsonObj.title;
51
+ }
52
+
53
+ get status() {
54
+ return this.jsonObj.status;
55
+ }
56
+
57
+
58
+ get versionedUrl() {
59
+ return this.version ? this.url+'|' + this.version : this.url;
60
+ }
61
+
62
+ get vurl() {
63
+ return this.version ? this.url+'|' + this.version : this.url;
64
+ }
65
+
66
+ get fhirType() {
67
+ return this.jsonObj.resourceType;
68
+ }
69
+
70
+
71
+ /**
72
+ * Gets the FHIR version this CodeSystem was loaded from
73
+ * @returns {string} FHIR version ('R3', 'R4', or 'R5')
74
+ */
75
+ getFHIRVersion() {
76
+ return this.fhirVersion;
77
+ }
78
+
79
+ versionAlgorithm() {
80
+ let c = this.jsonObj.versionAlgorithmCoding;
81
+ if (c) {
82
+ return c.code;
83
+ }
84
+ return this.jsonObj.versionAlgorithmString;
85
+ }
86
+ }
87
+
88
+ module.exports = { CanonicalResource };