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.
- package/CHANGELOG.md +42 -0
- package/FHIRsmith.png +0 -0
- package/README.md +277 -0
- package/config-template.json +144 -0
- package/library/folder-setup.js +58 -0
- package/library/html-server.js +166 -0
- package/library/html.js +835 -0
- package/library/i18nsupport.js +259 -0
- package/library/languages.js +779 -0
- package/library/logger-telnet.js +205 -0
- package/library/logger.js +279 -0
- package/library/package-manager.js +876 -0
- package/library/utilities.js +196 -0
- package/library/version-utilities.js +1056 -0
- package/npmprojector/config-example.json +13 -0
- package/npmprojector/indexer.js +394 -0
- package/npmprojector/npmprojector.js +395 -0
- package/npmprojector/readme.md +174 -0
- package/npmprojector/watcher.js +335 -0
- package/package.json +119 -0
- package/packages/package-crawler.js +846 -0
- package/packages/packages-template.html +126 -0
- package/packages/packages.js +2838 -0
- package/passwords.ini +2 -0
- package/publisher/publisher-template.html +208 -0
- package/publisher/publisher.js +2167 -0
- package/publisher/task-draft.js +458 -0
- package/registry/api.js +735 -0
- package/registry/crawler.js +637 -0
- package/registry/model.js +513 -0
- package/registry/readme.md +243 -0
- package/registry/registry-data.json +121015 -0
- package/registry/registry-template.html +126 -0
- package/registry/registry.js +1395 -0
- package/registry/test-runner.js +237 -0
- package/root-template.html +124 -0
- package/server.js +524 -0
- package/shl/private-key.pem +5 -0
- package/shl/public-key.pem +18 -0
- package/shl/shl.js +1125 -0
- package/shl/vhl.js +69 -0
- package/static/FHIRsmith128.png +0 -0
- package/static/FHIRsmith16.png +0 -0
- package/static/FHIRsmith32.png +0 -0
- package/static/FHIRsmith64.png +0 -0
- package/static/assets/css/bootstrap-fhir.css +5302 -0
- package/static/assets/css/bootstrap-glyphicons.css +2 -0
- package/static/assets/css/bootstrap.css +4097 -0
- package/static/assets/css/jquery-ui.css +523 -0
- package/static/assets/css/jquery-ui.structure.css +863 -0
- package/static/assets/css/jquery-ui.structure.min.css +5 -0
- package/static/assets/css/jquery-ui.theme.css +439 -0
- package/static/assets/css/jquery-ui.theme.min.css +5 -0
- package/static/assets/css/jquery.ui.all.css +7 -0
- package/static/assets/css/modules.css +18 -0
- package/static/assets/css/project.css +367 -0
- package/static/assets/css/pygments-manni.css +66 -0
- package/static/assets/css/tags.css +74 -0
- package/static/assets/css/xml.css +2 -0
- package/static/assets/fonts/glyphiconshalflings-regular.eot +0 -0
- package/static/assets/fonts/glyphiconshalflings-regular.otf +0 -0
- package/static/assets/fonts/glyphiconshalflings-regular.svg +175 -0
- package/static/assets/fonts/glyphiconshalflings-regular.ttf +0 -0
- package/static/assets/fonts/glyphiconshalflings-regular.woff +0 -0
- package/static/assets/ico/apple-touch-icon-114-precomposed.png +0 -0
- package/static/assets/ico/apple-touch-icon-144-precomposed.png +0 -0
- package/static/assets/ico/apple-touch-icon-57-precomposed.png +0 -0
- package/static/assets/ico/apple-touch-icon-72-precomposed.png +0 -0
- package/static/assets/ico/favicon.ico +0 -0
- package/static/assets/ico/favicon.png +0 -0
- package/static/assets/images/fhir-logo-www.png +0 -0
- package/static/assets/images/fhir-logo.png +0 -0
- package/static/assets/images/hl7-logo.png +0 -0
- package/static/assets/images/logo_ansinew.jpg +0 -0
- package/static/assets/images/search.png +0 -0
- package/static/assets/images/stripe.png +0 -0
- package/static/assets/images/target.png +0 -0
- package/static/assets/images/tx-registry-root.gif +0 -0
- package/static/assets/images/tx-registry.png +0 -0
- package/static/assets/images/tx-server.png +0 -0
- package/static/assets/images/tx-version.png +0 -0
- package/static/assets/js/bootstrap.min.js +6 -0
- package/static/assets/js/fhir-gw.js +259 -0
- package/static/assets/js/fhir.js +2 -0
- package/static/assets/js/html5shiv.js +8 -0
- package/static/assets/js/jcookie.js +96 -0
- package/static/assets/js/jquery-ui.min.js +6 -0
- package/static/assets/js/jquery.js +10716 -0
- package/static/assets/js/jquery.min.js +2 -0
- package/static/assets/js/jquery.ui.core.js +314 -0
- package/static/assets/js/jquery.ui.draggable.js +825 -0
- package/static/assets/js/jquery.ui.mouse.js +162 -0
- package/static/assets/js/jquery.ui.resizable.js +842 -0
- package/static/assets/js/jquery.ui.widget.js +268 -0
- package/static/assets/js/json2.js +487 -0
- package/static/assets/js/jtip.js +97 -0
- package/static/assets/js/respond.min.js +6 -0
- package/static/assets/js/statuspage.js +70 -0
- package/static/assets/js/xml.js +2 -0
- package/static/dist/js/bootstrap.js +1964 -0
- package/static/favicon.png +0 -0
- package/static/fhir.css +626 -0
- package/static/icon-fhir-16.png +0 -0
- package/static/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- package/static/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- package/static/images/ui-bg_flat_10_000000_40x100.png +0 -0
- package/static/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- package/static/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- package/static/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- package/static/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- package/static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- package/static/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- package/static/images/ui-icons_222222_256x240.png +0 -0
- package/static/images/ui-icons_228ef1_256x240.png +0 -0
- package/static/images/ui-icons_ef8c08_256x240.png +0 -0
- package/static/images/ui-icons_ffd27a_256x240.png +0 -0
- package/static/images/ui-icons_ffffff_256x240.png +0 -0
- package/static/js/jquery.effects.blind.js +49 -0
- package/static/js/jquery.effects.bounce.js +78 -0
- package/static/js/jquery.effects.clip.js +54 -0
- package/static/js/jquery.effects.core.js +763 -0
- package/static/js/jquery.effects.drop.js +50 -0
- package/static/js/jquery.effects.explode.js +79 -0
- package/static/js/jquery.effects.fade.js +32 -0
- package/static/js/jquery.effects.fold.js +56 -0
- package/static/js/jquery.effects.highlight.js +50 -0
- package/static/js/jquery.effects.pulsate.js +51 -0
- package/static/js/jquery.effects.scale.js +178 -0
- package/static/js/jquery.effects.shake.js +57 -0
- package/static/js/jquery.effects.slide.js +50 -0
- package/static/js/jquery.effects.transfer.js +45 -0
- package/static/js/jquery.ui.accordion.js +611 -0
- package/static/js/jquery.ui.autocomplete.js +612 -0
- package/static/js/jquery.ui.button.js +416 -0
- package/static/js/jquery.ui.datepicker.js +1823 -0
- package/static/js/jquery.ui.dialog.js +878 -0
- package/static/js/jquery.ui.droppable.js +296 -0
- package/static/js/jquery.ui.position.js +252 -0
- package/static/js/jquery.ui.progressbar.js +109 -0
- package/static/js/jquery.ui.selectable.js +266 -0
- package/static/js/jquery.ui.slider.js +666 -0
- package/static/js/jquery.ui.sortable.js +1077 -0
- package/static/js/jquery.ui.tabs.js +758 -0
- package/stats.js +80 -0
- package/test-cache/vsac/vsac-valuesets.db +0 -0
- package/token/nginx_passport_setup.md +383 -0
- package/token/security_guide.md +294 -0
- package/token/token-template.html +330 -0
- package/token/token.js +1300 -0
- package/translations/Messages.properties +1510 -0
- package/translations/Messages_ar.properties +1399 -0
- package/translations/Messages_de.properties +836 -0
- package/translations/Messages_es.properties +737 -0
- package/translations/Messages_fr.properties +1 -0
- package/translations/Messages_ja.properties +893 -0
- package/translations/Messages_nl.properties +1357 -0
- package/translations/Messages_pt.properties +1302 -0
- package/translations/Messages_ru.properties +1 -0
- package/translations/Messages_uz.properties +1 -0
- package/translations/Messages_zh.properties +1 -0
- package/translations/rendering-phrases.properties +1128 -0
- package/translations/rendering-phrases_ar.properties +1091 -0
- package/translations/rendering-phrases_de.properties +6 -0
- package/translations/rendering-phrases_es.properties +6 -0
- package/translations/rendering-phrases_fr.properties +624 -0
- package/translations/rendering-phrases_ja.properties +21 -0
- package/translations/rendering-phrases_nl.properties +970 -0
- package/translations/rendering-phrases_pt.properties +1020 -0
- package/translations/rendering-phrases_ru.properties +1094 -0
- package/translations/rendering-phrases_uz.properties +1 -0
- package/translations/rendering-phrases_zh.properties +1 -0
- package/tx/README.md +418 -0
- package/tx/cm/cm-api.js +110 -0
- package/tx/cm/cm-database.js +735 -0
- package/tx/cm/cm-package.js +325 -0
- package/tx/cs/cs-api.js +789 -0
- package/tx/cs/cs-areacode.js +615 -0
- package/tx/cs/cs-country.js +1110 -0
- package/tx/cs/cs-cpt.js +785 -0
- package/tx/cs/cs-cs.js +1579 -0
- package/tx/cs/cs-currency.js +539 -0
- package/tx/cs/cs-db.js +1321 -0
- package/tx/cs/cs-hgvs.js +329 -0
- package/tx/cs/cs-lang.js +465 -0
- package/tx/cs/cs-loinc.js +1485 -0
- package/tx/cs/cs-mimetypes.js +238 -0
- package/tx/cs/cs-ndc.js +704 -0
- package/tx/cs/cs-omop.js +1025 -0
- package/tx/cs/cs-provider-api.js +43 -0
- package/tx/cs/cs-provider-list.js +37 -0
- package/tx/cs/cs-rxnorm.js +808 -0
- package/tx/cs/cs-snomed.js +1102 -0
- package/tx/cs/cs-ucum.js +514 -0
- package/tx/cs/cs-unii.js +271 -0
- package/tx/cs/cs-uri.js +218 -0
- package/tx/cs/cs-usstates.js +305 -0
- package/tx/dev.fhir.org.yml +14 -0
- package/tx/fixtures/test-cases-setup.json +18 -0
- package/tx/fixtures/test-cases.yml +16 -0
- package/tx/html/codesystem-operations.liquid +25 -0
- package/tx/html/home-metrics.liquid +247 -0
- package/tx/html/operations-form.liquid +148 -0
- package/tx/html/search-form.liquid +62 -0
- package/tx/html/tx-template.html +133 -0
- package/tx/html/valueset-operations.liquid +54 -0
- package/tx/importers/atc-to-fhir.js +316 -0
- package/tx/importers/import-loinc.module.js +1536 -0
- package/tx/importers/import-ndc.module.js +1088 -0
- package/tx/importers/import-rxnorm.module.js +898 -0
- package/tx/importers/import-sct.module.js +2457 -0
- package/tx/importers/import-unii.module.js +601 -0
- package/tx/importers/readme.md +453 -0
- package/tx/importers/subset-loinc.module.js +1081 -0
- package/tx/importers/subset-rxnorm.module.js +938 -0
- package/tx/importers/tx-import-base.js +351 -0
- package/tx/importers/tx-import-settings.js +310 -0
- package/tx/importers/tx-import.js +357 -0
- package/tx/library/canonical-resource.js +88 -0
- package/tx/library/capabilitystatement.js +292 -0
- package/tx/library/codesystem.js +774 -0
- package/tx/library/conceptmap.js +568 -0
- package/tx/library/designations.js +932 -0
- package/tx/library/errors.js +77 -0
- package/tx/library/extensions.js +117 -0
- package/tx/library/namingsystem.js +322 -0
- package/tx/library/operation-outcome.js +127 -0
- package/tx/library/parameters.js +105 -0
- package/tx/library/renderer.js +1559 -0
- package/tx/library/terminologycapabilities.js +418 -0
- package/tx/library/ucum-parsers.js +1029 -0
- package/tx/library/ucum-service.js +370 -0
- package/tx/library/ucum-types.js +1099 -0
- package/tx/library/valueset.js +543 -0
- package/tx/library.js +676 -0
- package/tx/ocl/cm-ocl.js +106 -0
- package/tx/ocl/cs-ocl.js +39 -0
- package/tx/ocl/vs-ocl.js +105 -0
- package/tx/operation-context.js +568 -0
- package/tx/params.js +613 -0
- package/tx/provider.js +403 -0
- package/tx/sct/ecl.js +1560 -0
- package/tx/sct/expressions.js +2077 -0
- package/tx/sct/structures.js +1396 -0
- package/tx/tx-html.js +1063 -0
- package/tx/tx.fhir.org.yml +39 -0
- package/tx/tx.js +927 -0
- package/tx/vs/vs-api.js +112 -0
- package/tx/vs/vs-database.js +786 -0
- package/tx/vs/vs-package.js +358 -0
- package/tx/vs/vs-vsac.js +366 -0
- package/tx/workers/batch-validate.js +129 -0
- package/tx/workers/batch.js +361 -0
- package/tx/workers/closure.js +32 -0
- package/tx/workers/expand.js +1845 -0
- package/tx/workers/lookup.js +407 -0
- package/tx/workers/metadata.js +467 -0
- package/tx/workers/operations.js +34 -0
- package/tx/workers/read.js +164 -0
- package/tx/workers/search.js +384 -0
- package/tx/workers/subsumes.js +334 -0
- package/tx/workers/translate.js +492 -0
- package/tx/workers/validate.js +2504 -0
- package/tx/workers/worker.js +904 -0
- package/tx/xml/capabilitystatement-xml.js +63 -0
- package/tx/xml/codesystem-xml.js +62 -0
- package/tx/xml/conceptmap-xml.js +65 -0
- package/tx/xml/namingsystem-xml.js +65 -0
- package/tx/xml/operationoutcome-xml.js +127 -0
- package/tx/xml/parameters-xml.js +312 -0
- package/tx/xml/terminologycapabilities-xml.js +64 -0
- package/tx/xml/valueset-xml.js +64 -0
- package/tx/xml/xml-base.js +603 -0
- package/vcl/vcl-parser.js +1098 -0
- package/vcl/vcl.js +253 -0
- package/windows-install.js +19 -0
- package/xig/xig-template.html +124 -0
- 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 };
|