From 0da25bad1d798948c1fc603721a3c3ebc2523a80 Mon Sep 17 00:00:00 2001 From: legallm Date: Tue, 5 May 2026 19:06:19 +0200 Subject: [PATCH] SNOMED CT French Edition management --- registry/registry.js | 25 ++-- tx/cs/cs-snomed.js | 74 ++++++------ tx/importers/import-sct.module.js | 97 ++++++++-------- tx/workers/validate.js | 185 +++++++++++++++--------------- 4 files changed, 194 insertions(+), 187 deletions(-) diff --git a/registry/registry.js b/registry/registry.js index f5de4f85..52afcc4b 100644 --- a/registry/registry.js +++ b/registry/registry.js @@ -159,14 +159,14 @@ class RegistryModule { // Get metadata const metadata = this.crawler.getMetadata(); - this.logger.info(`Crawl completed in ${(elapsed/1000).toFixed(1)}s. ` + + this.logger.info(`Crawl completed in ${(elapsed / 1000).toFixed(1)}s. ` + `Found ${newData.registries.length} registries, ` + `${metadata.errors.length} errors, ` + `downloaded ${this.crawler.formatBytes(metadata.totalBytes)}`); this.stats.taskDone('TxRegistry', 'Crawling Finished'); } catch (error) { this.logger.error('Crawl failed:', error); - this.stats.taskError('TxRegistry', 'Crawling Error: '+error.message); + this.stats.taskError('TxRegistry', 'Crawling Error: ' + error.message); } finally { this.crawlInProgress = false; } @@ -476,7 +476,7 @@ class RegistryModule { const lastRunDate = new Date(stats.lastRun); lastUpdatedText = `Last Updated: ${lastRunDate.toLocaleString()}`; } - html += `

${lastUpdatedText}. Register your own server`+ + html += `

${lastUpdatedText}. Register your own server` + ` - see Documentation

`; html += ''; @@ -718,7 +718,7 @@ class RegistryModule { // For wildcards, just return as is if (url.endsWith('*')) { - url = url.substring(0, url.length-1); + url = url.substring(0, url.length - 1); } const parts = url.split('/'); @@ -750,6 +750,7 @@ class RegistryModule { case '20611000087101': edition = 'CA'; break; case '11000181102': edition = 'EE'; break; case '11000229106': edition = 'FI'; break; + case '11000315107': edition = 'FR-FR'; break; case '11000274103': edition = 'DE'; break; case '1121000189102': edition = 'IN'; break; case '11000220105': edition = 'IE'; break; @@ -976,7 +977,7 @@ class RegistryModule { try { const params = this._normalizeQueryParams(req.query); - const {fhirVersion, url, valueSet, usage} = params; + const { fhirVersion, url, valueSet, usage } = params; // Convert authoritativeOnly to boolean const authoritativeOnly = params.authoritativeOnly === 'true'; @@ -986,11 +987,11 @@ class RegistryModule { // Validate URL parameters if provided if (cleanUrl && !this._isValidUrl(cleanUrl)) { - return res.status(400).json({error: 'Invalid code system URL format'}); + return res.status(400).json({ error: 'Invalid code system URL format' }); } if (valueSet && !this._isValidUrl(cleanVS)) { - return res.status(400).json({error: 'Invalid value set URL format'}); + return res.status(400).json({ error: 'Invalid value set URL format' }); } // Check if this is a browser request (based on Accept header) @@ -1033,11 +1034,11 @@ class RegistryModule { // Validate required parameters if (!fhirVersion) { - return res.status(400).json({error: 'A FHIR version is required'}); + return res.status(400).json({ error: 'A FHIR version is required' }); } if (!url && !valueSet) { - return res.status(400).json({error: 'Either url or valueSet parameter is required'}); + return res.status(400).json({ error: 'Either url or valueSet parameter is required' }); } if (valueSet) { @@ -1089,7 +1090,7 @@ class RegistryModule { res.json(result); } catch (error) { this.logger.error('Error in resolve endpoint:', error); - res.status(400).json({error: error.message}); + res.status(400).json({ error: error.message }); } } finally { this.stats.countRequest('resolve', Date.now() - start); @@ -1198,7 +1199,7 @@ class RegistryModule { return html; } -// Add this helper method to render security tags + // Add this helper method to render security tags renderSecurityTags(server) { const tags = []; @@ -1338,7 +1339,7 @@ class RegistryModule { } } catch (error) { this.logger.error('Error in log endpoint:', error); - res.status(500).json({error: error.message}); + res.status(500).json({ error: error.message }); } } finally { this.stats.countRequest('log', Date.now() - start); diff --git a/tx/cs/cs-snomed.js b/tx/cs/cs-snomed.js index f00107ec..6a5d3c96 100644 --- a/tx/cs/cs-snomed.js +++ b/tx/cs/cs-snomed.js @@ -1,4 +1,4 @@ -const { CodeSystemContentMode, CodeSystemFactoryProvider} = require('./cs-api'); +const { CodeSystemContentMode, CodeSystemFactoryProvider } = require('./cs-api'); const { SnomedStrings, SnomedWords, SnomedStems, SnomedReferences, SnomedDescriptions, SnomedDescriptionIndex, SnomedConceptList, @@ -9,13 +9,13 @@ const { SnomedExpressionServices, SnomedExpression, SnomedConcept, SnomedExpressionParser, NO_REFERENCE, SnomedServicesRenderOption } = require('../sct/expressions'); -const {DesignationUse} = require("../library/designations"); -const {BaseCSServices} = require("./cs-base"); -const {formatDateMMDDYYYY} = require("../../library/utilities"); -const {ConceptMap} = require("../library/conceptmap"); -const {ECLLexer, ECLParser, ECLNodeType, ECLTokenType} = require("../sct/ecl"); -const {Issue} = require("../library/operation-outcome"); -const {debugLog} = require("../operation-context"); +const { DesignationUse } = require("../library/designations"); +const { BaseCSServices } = require("./cs-base"); +const { formatDateMMDDYYYY } = require("../../library/utilities"); +const { ConceptMap } = require("../library/conceptmap"); +const { ECLLexer, ECLParser, ECLNodeType, ECLTokenType } = require("../sct/ecl"); +const { Issue } = require("../library/operation-outcome"); +const { debugLog } = require("../operation-context"); // Context kinds matching Pascal enum const SnomedProviderContextKind = { @@ -60,15 +60,15 @@ class SnomedExpressionContext { getReference() { return this.expression && this.expression.concepts.length > 0 - ? this.expression.concepts[0].reference - : NO_REFERENCE; + ? this.expression.concepts[0].reference + : NO_REFERENCE; } getCode() { if (this.source) return this.source; return this.expression && this.expression.concepts.length > 0 - ? this.expression.concepts[0].code - : ''; + ? this.expression.concepts[0].code + : ''; } } @@ -558,10 +558,10 @@ class SnomedServices { // Could be a bare concept reference or wildcard passed in directly // (e.g. when a parenthesised expression resolves to one of these). if (node.type === ECLNodeType.CONCEPT_REFERENCE || - node.type === ECLNodeType.WILDCARD || - node.type === ECLNodeType.MEMBER_OF) { + node.type === ECLNodeType.WILDCARD || + node.type === ECLNodeType.MEMBER_OF) { // Wrap it as if it came from a no-operator SubExpressionConstraint - return this._evalSubExpression({type: ECLNodeType.SUB_EXPRESSION_CONSTRAINT, operator: null, focus: node}); + return this._evalSubExpression({ type: ECLNodeType.SUB_EXPRESSION_CONSTRAINT, operator: null, focus: node }); } throw new Error(`Unsupported ECL node type: ${node.type}`); } @@ -614,7 +614,7 @@ class SnomedServices { case undefined: return this.filterEquals(conceptId); - // ── Descendants ──────────────────────────────────────────────────────── + // ── Descendants ──────────────────────────────────────────────────────── case ECLTokenType.DESCENDANT_OR_SELF_OF: { // << self + all transitive descendants return this.filterIsA(conceptId, true); } @@ -638,7 +638,7 @@ class SnomedServices { return this.filterChildOf(conceptId); } - // ── Ancestors ────────────────────────────────────────────────────────── + // ── Ancestors ────────────────────────────────────────────────────────── case ECLTokenType.ANCESTOR_OR_SELF_OF: { // >> self + all transitive ancestors const result = this.filterGeneralizes(conceptId); const self = this.concepts.findConcept(conceptId); @@ -704,7 +704,7 @@ class SnomedServices { return result; }; -// ── Dotted expressions ─────────────────────────────────────────────────────── + // ── Dotted expressions ─────────────────────────────────────────────────────── /** * Evaluate a dotted expression: ` . attrA . attrB`. @@ -745,7 +745,7 @@ class SnomedServices { return result; }; -// ── Refinements ────────────────────────────────────────────────────────────── + // ── Refinements ────────────────────────────────────────────────────────────── /** * Evaluate a refined expression: ` : `. @@ -916,7 +916,7 @@ class SnomedServices { return false; }; -// ── Set operation helpers ──────────────────────────────────────────────────── + // ── Set operation helpers ──────────────────────────────────────────────────── /** * Flatten a SnomedFilterContext to a plain array of concept indexes, @@ -1225,7 +1225,7 @@ class SnomedProvider extends BaseCSServices { const kind = this.sct.concepts.getConcept(description.kind); const kid = String(kind.identity); const kdesc = this.sct.getDisplayName(description.kind); - let use = { system: 'http://snomed.info/sct', code: kid, display : kdesc}; + let use = { system: 'http://snomed.info/sct', code: kid, display: kdesc }; displays.addDesignation(false, description.active ? 'active' : 'inactive', langCode, use, term); } @@ -1234,7 +1234,7 @@ class SnomedProvider extends BaseCSServices { // Add basic designation if we can't read detailed descriptions const display = this.sct.getDisplayName(ctxt.getReference()); if (display) { - displays.addDesignation(true, 'active','en-US', null, display); + displays.addDesignation(true, 'active', 'en-US', null, display); } } @@ -1422,7 +1422,7 @@ class SnomedProvider extends BaseCSServices { if (!set.has(relType + ":" + code)) { set.add(relType + ":" + code); let p = this._addCodeProperty(params, 'property', relType, code, null, description); - p.part.push({name: 'code-display', valueString: relTypeD}); + p.part.push({ name: 'code-display', valueString: relTypeD }); } } } @@ -1434,7 +1434,7 @@ class SnomedProvider extends BaseCSServices { const codeB = refinement.value.describe(); const description = await this.display(codeB); let p = this._addCodeProperty(params, 'property', codeA, codeB, null, description); - p.part.push({name: 'code-display', valueString: await this.display(codeA)}); + p.part.push({ name: 'code-display', valueString: await this.display(codeA) }); } for (const refinementGroup of ctxt.expression.refinementGroups) { for (const refinement of refinementGroup.refinements) { @@ -1442,7 +1442,7 @@ class SnomedProvider extends BaseCSServices { const codeB = refinement.value.describe(); const description = await this.display(codeB); let p = this._addCodeProperty(params, 'property', codeA, codeB, null, description); - p.part.push({name: 'code-display', valueString: await this.display(codeA)}); + p.part.push({ name: 'code-display', valueString: await this.display(codeA) }); } } } @@ -1859,7 +1859,7 @@ class SnomedProvider extends BaseCSServices { isDisplay(cd) { return cd.use.system === this.system() && - (cd.use.code === '900000000000013009' || cd.use.code === '900000000000003001'); + (cd.use.code === '900000000000013009' || cd.use.code === '900000000000003001'); } async getTranslations(map, coding, target, reverse) { @@ -1906,7 +1906,7 @@ class SnomedProvider extends BaseCSServices { map: map.vurl, code: tgtId, system: this.system(), - version : this.version(), + version: this.version(), display: await this.display(tgtId), relationship: map.jsonObj.relationship } @@ -1990,8 +1990,8 @@ class SnomedServicesFactory extends CodeSystemFactoryProvider { } if (url.startsWith('http://snomed.info/sct?fhir_vs') || - url.startsWith(`http://snomed.info/sct/${this.edition}?fhir_vs`) || - url.startsWith(`http://snomed.info/sct/${this.edition}/version/${this.version}?fhir_vs`)) { + url.startsWith(`http://snomed.info/sct/${this.edition}?fhir_vs`) || + url.startsWith(`http://snomed.info/sct/${this.edition}/version/${this.version}?fhir_vs`)) { id = url.substring(qIdx); } else { return null; @@ -2004,7 +2004,7 @@ class SnomedServicesFactory extends CodeSystemFactoryProvider { const concepts = []; for (let i = 0; i < this.refSetIndex.count; i++) { const code = this.refSetIndex.getReferenceSetCode(i); - concepts.push({code: this.getConceptId(code)}); + concepts.push({ code: this.getConceptId(code) }); } return { resourceType: 'ValueSet', @@ -2153,10 +2153,10 @@ class SnomedServicesFactory extends CodeSystemFactoryProvider { if (!match) { match = this.version().match(/^http:\/\/snomed\.info\/xsct\/(\d+)(?:\/version\/(\d{8}))?$/); if (match) { - match = "x"+match; + match = "x" + match; } } - return match && match[1] && match[2] ? "SCT-"+match[1]+"-"+match[2] : null; + return match && match[1] && match[2] ? "SCT-" + match[1] + "-" + match[2] : null; } describeVersion(version) { @@ -2173,10 +2173,10 @@ class SnomedServicesFactory extends CodeSystemFactoryProvider { if (version && (version !== this.version())) { return null; } - if (!url || !url.startsWith(this.system()+"?fhir_cm=")) { + if (!url || !url.startsWith(this.system() + "?fhir_cm=")) { return null; } - let id = url.substring(url.indexOf("=")+1); + let id = url.substring(url.indexOf("=") + 1); if (['900000000000523009', '900000000000526001', '900000000000527005', '900000000000530003'].includes(id)) { let name = ''; let relationship = ''; @@ -2200,9 +2200,9 @@ class SnomedServicesFactory extends CodeSystemFactoryProvider { } let cm = { resourceType: 'ConceptMap', - internalSource : this, + internalSource: this, relationship: relationship, - id : id, + id: id, url: `${this.system()}?fhir_cm=${id}`, version: this.version(), name: `SNOMED CT ${name} Concept Map`, @@ -2242,6 +2242,7 @@ function getEditionName(edition) { '11000279109': 'Czech Edition', '11000181102': 'Estonian Edition', '11000229106': 'Finnish Edition', + '11000315107': 'French Edition', '11000274103': 'German Edition', '1121000189102': 'Indian Edition', '827022005': 'IPS Terminology', @@ -2278,6 +2279,7 @@ function getEditionCode(edition) { '11000279109': 'CZ', '11000181102': 'ES', '11000229106': 'FI', + '11000315107': 'FR-fr', '11000274103': 'DE', '1121000189102': 'IN', '827022005': 'IPS', diff --git a/tx/importers/import-sct.module.js b/tx/importers/import-sct.module.js index a1a52eec..c871167a 100644 --- a/tx/importers/import-sct.module.js +++ b/tx/importers/import-sct.module.js @@ -11,7 +11,7 @@ const { SnomedDescriptions, SnomedDescriptionIndex, SnomedConceptList, SnomedRelationshipList, SnomedReferenceSetMembers, SnomedReferenceSetIndex } = require('../sct/structures'); -const {SnomedExpressionServices} = require("../sct/expressions"); +const { SnomedExpressionServices } = require("../sct/expressions"); class SnomedModule extends BaseTerminologyModule { @@ -48,37 +48,37 @@ class SnomedModule extends BaseTerminologyModule { registerCommands(terminologyCommand, globalOptions) { // Import command terminologyCommand - .command('import') - .description('Import SNOMED CT data from RF2 source directory') - .option('-s, --source ', 'Source directory containing RF2 files') - .option('-b, --base ', 'Base edition directory (for extensions)') - .option('-d, --dest ', 'Destination cache file') - .option('-e, --edition ', 'Edition code (e.g., 900000000000207008 for International)') - .option('-v, --version ', 'Version in YYYYMMDD format (e.g., 20250801)') - .option('-u, --uri ', 'Version URI (overrides edition/version if provided)') - .option('-l, --language ', 'Default language code (overrides edition default if provided)') - .option('-y, --yes', 'Skip confirmations') - .action(async (options) => { - await this.handleImportCommand({...globalOptions, ...options}); - }); + .command('import') + .description('Import SNOMED CT data from RF2 source directory') + .option('-s, --source ', 'Source directory containing RF2 files') + .option('-b, --base ', 'Base edition directory (for extensions)') + .option('-d, --dest ', 'Destination cache file') + .option('-e, --edition ', 'Edition code (e.g., 900000000000207008 for International)') + .option('-v, --version ', 'Version in YYYYMMDD format (e.g., 20250801)') + .option('-u, --uri ', 'Version URI (overrides edition/version if provided)') + .option('-l, --language ', 'Default language code (overrides edition default if provided)') + .option('-y, --yes', 'Skip confirmations') + .action(async (options) => { + await this.handleImportCommand({ ...globalOptions, ...options }); + }); // Validate command terminologyCommand - .command('validate') - .description('Validate SNOMED CT RF2 directory structure') - .option('-s, --source ', 'Source directory to validate') - .action(async (options) => { - await this.handleValidateCommand({...globalOptions, ...options}); - }); + .command('validate') + .description('Validate SNOMED CT RF2 directory structure') + .option('-s, --source ', 'Source directory to validate') + .action(async (options) => { + await this.handleValidateCommand({ ...globalOptions, ...options }); + }); // Status command terminologyCommand - .command('status') - .description('Show status of SNOMED CT cache') - .option('-d, --dest ', 'Cache file to check') - .action(async (options) => { - await this.handleStatusCommand({...globalOptions, ...options}); - }); + .command('status') + .description('Show status of SNOMED CT cache') + .option('-d, --dest ', 'Cache file to check') + .action(async (options) => { + await this.handleStatusCommand({ ...globalOptions, ...options }); + }); } async handleImportCommand(options) { @@ -184,6 +184,7 @@ class SnomedModule extends BaseTerminologyModule { "20611000087101": "Canadian Edition (French)", "11000181102": "Estonian Edition", "11000229106": "Finnish Edition", + "11000315107": "French Edition", "11000274103": "German Edition", "1121000189102": "Indian Edition", "11000220105": "Irish Edition", @@ -210,6 +211,7 @@ class SnomedModule extends BaseTerminologyModule { 'DK': '554471000005108', 'NO': '51000202101', 'FI': '11000229106', + 'FR': '11000315107', 'DE': '11000274103', 'AT': '11000234105', 'CH': '2011000195101', @@ -435,6 +437,7 @@ class SnomedModule extends BaseTerminologyModule { "20621000087109": { name: "Canadian Edition (English)", needsBase: true, lang: "en-CA" }, "20611000087101": { name: "Canadian Edition (French)", needsBase: true, lang: "fr-CA" }, "11000181102": { name: "Estonian Edition", needsBase: true, lang: "et-EE" }, + "11000315107": { name: "French Edition", needsBase: true, lang: "fr-FR" }, "11000229106": { name: "Finnish Edition", needsBase: true, lang: "fi-FI" }, "11000274103": { name: "German Edition", needsBase: true, lang: "de-DE" }, "1121000189102": { name: "Indian Edition", needsBase: true, lang: "en-IN" }, @@ -633,7 +636,7 @@ class SnomedModule extends BaseTerminologyModule { } const additionalAnswers = additionalQuestions.length > 0 ? - await inquirer.prompt(additionalQuestions) : {}; + await inquirer.prompt(additionalQuestions) : {}; // Build the final configuration const config = { @@ -774,7 +777,7 @@ class SnomedModule extends BaseTerminologyModule { } else if (firstLine.startsWith('id\teffectiveTime\tactive\tmoduleId\tconceptId\tlanguageCode\ttypeId\tterm\tcaseSignificanceId')) { files.descriptions.push(filePath); } else if (firstLine.startsWith('id\teffectiveTime\tactive\tmoduleId\tsourceId\tdestinationId\trelationshipGroup\ttypeId\tcharacteristicTypeId\tmodifierId') && - !filePath.includes('StatedRelationship')) { + !filePath.includes('StatedRelationship')) { files.relationships.push(filePath); } } catch (error) { @@ -1213,7 +1216,7 @@ class SnomedImporter { } else if (firstLine.startsWith('id\teffectiveTime\tactive\tmoduleId\tconceptId\tlanguageCode\ttypeId\tterm\tcaseSignificanceId')) { files.descriptions.push(filePath); } else if (firstLine.startsWith('id\teffectiveTime\tactive\tmoduleId\tsourceId\tdestinationId\trelationshipGroup\ttypeId\tcharacteristicTypeId\tmodifierId') && - !filePath.includes('StatedRelationship')) { + !filePath.includes('StatedRelationship')) { files.relationships.push(filePath); } } catch (error) { @@ -1466,8 +1469,8 @@ class SnomedImporter { const caps = this.conceptMap.get(desc.caseSignificanceId); const descOffset = this.descriptions.addDescription( - termOffset, desc.id, effectiveTime, concept.index, - module.index, kind.index, caps.index, desc.active, lang + termOffset, desc.id, effectiveTime, concept.index, + module.index, kind.index, caps.index, desc.active, lang ); // Track description on concept @@ -1813,12 +1816,12 @@ class SnomedImporter { // Check if this is a defining relationship const defining = rel.characteristicTypeId === RF2_MAGIC_RELN_DEFINING || - rel.characteristicTypeId === RF2_MAGIC_RELN_STATED || - rel.characteristicTypeId === RF2_MAGIC_RELN_INFERRED; + rel.characteristicTypeId === RF2_MAGIC_RELN_STATED || + rel.characteristicTypeId === RF2_MAGIC_RELN_INFERRED; const relationshipIndex = this.relationships.addRelationship( - rel.id, source.index, destination.index, type.index, - 0, 0, 0, effectiveTime, rel.active, defining, rel.relationshipGroup + rel.id, source.index, destination.index, type.index, + 0, 0, 0, effectiveTime, rel.active, defining, rel.relationshipGroup ); // Track parent/child relationships for is-a relationships @@ -1882,9 +1885,9 @@ class SnomedImporter { // Set parents if concept has any if (tracker.activeParents.length > 0 || tracker.inactiveParents.length > 0) { const activeParentsRef = tracker.activeParents.length > 0 ? - this.refs.addReferences(tracker.activeParents) : 0; + this.refs.addReferences(tracker.activeParents) : 0; const inactiveParentsRef = tracker.inactiveParents.length > 0 ? - this.refs.addReferences(tracker.inactiveParents) : 0; + this.refs.addReferences(tracker.inactiveParents) : 0; this.concepts.setParents(concept.index, activeParentsRef, inactiveParentsRef); } else { @@ -2186,14 +2189,14 @@ class SnomedImporter { // NOTE: This calls addString() so it must happen AFTER strings.reopen() for (const refSet of refSetsArray) { this.refsetIndex.addReferenceSet( - this.addString(refSet.title), // This needs strings builder to be active - refSet.filename, - refSet.index, - refSet.membersByRef, - refSet.membersByName, - refSet.fieldTypes, - refSet.fieldNames, - refSet.langs + this.addString(refSet.title), // This needs strings builder to be active + refSet.filename, + refSet.index, + refSet.membersByRef, + refSet.membersByName, + refSet.fieldTypes, + refSet.fieldNames, + refSet.langs ); } } @@ -2665,8 +2668,8 @@ class SnomedImporter { }; const services = new SnomedExpressionServices( - snomedStructures, - this.isAIndex + snomedStructures, + this.isAIndex ); // Set building flag to true so services will generate normal forms dynamically diff --git a/tx/workers/validate.js b/tx/workers/validate.js index 40c5210e..79cea6ab 100644 --- a/tx/workers/validate.js +++ b/tx/workers/validate.js @@ -12,19 +12,19 @@ // const { TerminologyWorker } = require('./worker'); -const {Languages, Language} = require("../../library/languages"); -const {Extensions} = require("../library/extensions"); -const {validateParameter, isAbsoluteUrl, validateOptionalParameter, getValuePrimitive} = require("../../library/utilities"); -const {TxParameters} = require("../params"); -const {OperationOutcome, Issue} = require("../library/operation-outcome"); -const {Parameters} = require("../library/parameters"); -const {Designations, DisplayCheckingStyle, DisplayDifference, SearchFilterText} = require("../library/designations"); +const { Languages, Language } = require("../../library/languages"); +const { Extensions } = require("../library/extensions"); +const { validateParameter, isAbsoluteUrl, validateOptionalParameter, getValuePrimitive } = require("../../library/utilities"); +const { TxParameters } = require("../params"); +const { OperationOutcome, Issue } = require("../library/operation-outcome"); +const { Parameters } = require("../library/parameters"); +const { Designations, DisplayCheckingStyle, DisplayDifference, SearchFilterText } = require("../library/designations"); const ValueSet = require("../library/valueset"); -const {ValueSetExpander} = require("./expand"); -const {FhirCodeSystemProvider} = require("../cs/cs-cs"); -const {CodeSystem} = require("../library/codesystem"); -const {VersionUtilities} = require("../../library/version-utilities"); -const {debugLog} = require("../operation-context"); +const { ValueSetExpander } = require("./expand"); +const { FhirCodeSystemProvider } = require("../cs/cs-cs"); +const { CodeSystem } = require("../library/codesystem"); +const { VersionUtilities } = require("../../library/version-utilities"); +const { debugLog } = require("../operation-context"); const DEV_IGNORE_VALUESET = false; // todo: what's going on with this (ported from pascal) @@ -175,7 +175,7 @@ class ValueSetChecker { } else { for (let vsi of this.valueSet.jsonObj.compose.include) { this.worker.deadCheck('determineSystem'); - let cs = await this.worker.findCodeSystem(vsi.system, '', null, ['complete', 'fragment'], op,true, false, false, this.worker.requiredSupplements); + let cs = await this.worker.findCodeSystem(vsi.system, '', null, ['complete', 'fragment'], op, true, false, false, this.worker.requiredSupplements); if (cs === null) { return ''; } @@ -223,7 +223,7 @@ class ValueSetChecker { let result; - let csa = await this.worker.findCodeSystem(system, '', this.params, "*", op,true, false, true, this.worker.requiredSupplements); + let csa = await this.worker.findCodeSystem(system, '', this.params, "*", op, true, false, true, this.worker.requiredSupplements); result = this.worker.determineVersionBase(system, versionVS, this.params); @@ -242,7 +242,7 @@ class ValueSetChecker { } } - let cs = await this.worker.findCodeSystem(system, result, this.params, ['complete', 'fragment'], op,true, false, false, this.worker.requiredSupplements); + let cs = await this.worker.findCodeSystem(system, result, this.params, ['complete', 'fragment'], op, true, false, false, this.worker.requiredSupplements); if (cs !== null && cs.version() !== versionCoding && !cs.versionIsMoreDetailed(versionCoding, cs.version())) { let errLvl = 'error'; let msg, mid; @@ -325,12 +325,12 @@ class ValueSetChecker { this.worker.checkNoLockedDate(this.valueSet.vurl, this.valueSet.jsonObj.compose) let i = 0; for (let cc of this.valueSet.jsonObj.compose.include || []) { - await this.prepareConceptSet('include['+i+']', cc, this.valueSet); + await this.prepareConceptSet('include[' + i + ']', cc, this.valueSet); i++; } i = 0; for (let cc of this.valueSet.jsonObj.compose.exclude || []) { - await this.prepareConceptSet('exclude['+i+']', cc, this.valueSet); + await this.prepareConceptSet('exclude[' + i + ']', cc, this.valueSet); i++; } } @@ -338,7 +338,7 @@ class ValueSetChecker { const unused = new Set([...this.worker.requiredSupplements].filter(s => !this.worker.usedSupplements.has(s))); if (unused.size > 0) { - throw new Issue('error', 'not-found', null, 'VALUESET_SUPPLEMENT_MISSING', this.worker.i18n.translatePlural(unused.size, 'VALUESET_SUPPLEMENT_MISSING', this.params.HTTPLanguages, [[...unused].join(',')]), 'not-found').handleAsOO(422); + throw new Issue('error', 'not-found', null, 'VALUESET_SUPPLEMENT_MISSING', this.worker.i18n.translatePlural(unused.size, 'VALUESET_SUPPLEMENT_MISSING', this.params.HTTPLanguages, [[...unused].join(',')]), 'not-found').handleAsOO(422); } } @@ -376,12 +376,12 @@ class ValueSetChecker { this.worker.deadCheck('prepareConceptSet#2'); Extensions.checkNoModifiers(ccf, 'ValueSetChecker.prepare', desc + '.filter', this.valueSet.vurl); if (!ccf.value) { - throw new Issue('error', 'invalid', "ValueSet.compose."+desc+".filter["+i+"]", 'UNABLE_TO_HANDLE_SYSTEM_FILTER_WITH_NO_VALUE', + throw new Issue('error', 'invalid', "ValueSet.compose." + desc + ".filter[" + i + "]", 'UNABLE_TO_HANDLE_SYSTEM_FILTER_WITH_NO_VALUE', this.worker.i18n.translate('UNABLE_TO_HANDLE_SYSTEM_FILTER_WITH_NO_VALUE', this.params.HTTPLanguages, [cs.system(), ccf.property, ccf.op]), "vs-invalid").handleAsOO(400); } if (!(ccf.property === 'concept' && ['is-a', 'descendent-of'].includes(ccf.op))) { if (!(await cs.doesFilter(ccf.property, ccf.op, ccf.value))) { - throw new Issue('error', 'not-supported', "ValueSet.compose."+desc+".filter["+i+"]", 'FILTER_NOT_UNDERSTOOD', this.worker.i18n.translate('FILTER_NOT_UNDERSTOOD', + throw new Issue('error', 'not-supported', "ValueSet.compose." + desc + ".filter[" + i + "]", 'FILTER_NOT_UNDERSTOOD', this.worker.i18n.translate('FILTER_NOT_UNDERSTOOD', this.params.HTTPLanguages, [ccf.property, ccf.op, ccf.value, this.valueSet.url, cs.system()]), "vs-invalid").handleAsOO(400); } } @@ -435,14 +435,14 @@ class ValueSetChecker { let unknownSystems = new Set(); let ts = []; let msgs = []; - let ver = {value: ''}; - let inactive = {value: false}; - let normalForm = {value: ''}; - let vstatus = {value: ''}; - let it = {value: null}; - let contentMode = {value: null}; - let impliedSystem = {value: ''}; - let defLang = {value: null}; + let ver = { value: '' }; + let inactive = { value: false }; + let normalForm = { value: '' }; + let vstatus = { value: '' }; + let it = { value: null }; + let contentMode = { value: null }; + let impliedSystem = { value: '' }; + let defLang = { value: null }; return await this.check(issuePath, system, version, code, null, unknownSystems, ver, inactive, normalForm, vstatus, it, op, null, null, contentMode, impliedSystem, ts, msgs, defLang); } @@ -466,7 +466,7 @@ class ValueSetChecker { op.addIssue(new Issue('warning', 'invalid', path, 'Coding_has_no_system__cannot_validate_NO_INFER', msg, 'invalid-data')); return false; } - let cs = await this.worker.findCodeSystem(system, version, this.params, ['complete', 'fragment'], op,true, false, false, this.worker.requiredSupplements); + let cs = await this.worker.findCodeSystem(system, version, this.params, ['complete', 'fragment'], op, true, false, false, this.worker.requiredSupplements); this.seeSourceProvider(cs, system); if (cs === null) { this.worker.opContext.addNote(this.valueSet, 'Didn\'t find CodeSystem "' + this.worker.renderer.displayCoded(system, version) + '"', this.indentCount); @@ -480,7 +480,7 @@ class ValueSetChecker { op.addIssue(new Issue('error', 'invalid', addToPath(path, 'system'), 'Terminology_TX_System_ValueSet2', msg, 'invalid-data')); unknownSystems.add(system); } else { - let css = await this.worker.findCodeSystem(system, version, this.params, ['supplement'], op,true, false, false, this.worker.requiredSupplements); + let css = await this.worker.findCodeSystem(system, version, this.params, ['supplement'], op, true, false, false, this.worker.requiredSupplements); if (css !== null) { vss = null; let msg = this.worker.i18n.translate('CODESYSTEM_CS_NO_SUPPLEMENT', this.params.HTTPLanguages, [this.canonical(css.system(), css.version())]); @@ -497,7 +497,7 @@ class ValueSetChecker { mid = 'UNKNOWN_CODESYSTEM_VERSION'; vn = system + '|' + version; } - let msg = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [system, version, this.worker.presentVersionList(vl)]); + let msg = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [system, version, this.worker.presentVersionList(vl)]); messages.push(msg); if (!unknownSystems.has(vn)) { op.addIssue(new Issue('error', 'not-found', addToPath(path, 'system'), mid, msg, 'not-found')); @@ -591,7 +591,7 @@ class ValueSetChecker { mid = 'UNKNOWN_CODESYSTEM_VERSION'; vn = system + '|' + version; } - let msg = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [system, version, this.worker.presentVersionList(vl)]); + let msg = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [system, version, this.worker.presentVersionList(vl)]); messages.push(msg); if (!unknownSystems.has(vn)) { op.addIssue(new Issue('error', 'not-found', addToPath(path, 'system'), mid, msg, 'not-found')); @@ -702,7 +702,7 @@ class ValueSetChecker { result = true; } else if ((cc.system === system || system === '%%null%%') && (!determinedVersion || cc.version == determinedVersion) && this.useThisVersion(cc, version)) { let v = await this.determineVersion(path, cc.system, cc.version, version, op, unknownSystems, messages); - let cs = await this.worker.findCodeSystem(system, v, this.params, ["complete", "fragment"], op,true, true, false, this.worker.requiredSupplements); + let cs = await this.worker.findCodeSystem(system, v, this.params, ["complete", "fragment"], op, true, true, false, this.worker.requiredSupplements); if (cs === null) { this.worker.opContext.addNote(this.valueSet, 'CodeSystem not found: ' + this.worker.renderer.displayCoded(cc.system, v), this.indentCount); if (!this.params.membershipOnly) { @@ -721,7 +721,7 @@ class ValueSetChecker { mid = 'UNKNOWN_CODESYSTEM_VERSION'; vn = system + '|' + v; } - msg = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [system, v, this.worker.presentVersionList(vl)]); + msg = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [system, v, this.worker.presentVersionList(vl)]); bAdd = !unknownSystems.has(vn); if (bAdd) { unknownSystems.add(vn); @@ -779,7 +779,7 @@ class ValueSetChecker { if (!cc.system) { excluded = true; } else { - let cs = await this.worker.findCodeSystem(cc.system, cc.version, this.params, ['complete', 'fragment'], op,true, true, false, this.worker.requiredSupplements); + let cs = await this.worker.findCodeSystem(cc.system, cc.version, this.params, ['complete', 'fragment'], op, true, true, false, this.worker.requiredSupplements); if (cs === null) { throw new Issue('error', 'unknown', null, null, 'No Match for ' + cc.system + '|' + cc.version); } @@ -847,7 +847,7 @@ class ValueSetChecker { mid = 'UNKNOWN_CODESYSTEM_VERSION'; vn = system + '|' + v; } - msg = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [system, v, this.worker.presentVersionList(vl)]); + msg = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [system, v, this.worker.presentVersionList(vl)]); unknownSystems.add(vn); } } @@ -900,14 +900,14 @@ class ValueSetChecker { let op = new OperationOutcome(); this.checkCanonicalStatus(path, op, this.valueSet, this.valueSet); let list = new Designations(this.worker.languages); - let ver = {value: ''}; - inactive = {value: false}; - let normalForm = {value: ''}; - let vstatus = {value: ''}; - let cause = {value: null}; - let contentMode = {value: null}; - let impliedSystem = {value: ''}; - let defLang = {value: null}; + let ver = { value: '' }; + inactive = { value: false }; + let normalForm = { value: '' }; + let vstatus = { value: '' }; + let cause = { value: null }; + let contentMode = { value: null }; + let impliedSystem = { value: '' }; + let defLang = { value: null }; let ok = await this.check(path, coding.system, coding.version, coding.code, list, unknownSystems, ver, inactive, normalForm, vstatus, cause, op, null, result, contentMode, impliedSystem, unkCodes, messages, defLang); if (ok === true) { @@ -990,7 +990,7 @@ class ValueSetChecker { async checkSupplementsExist(vs) { for (let inc of vs.jsonObj.compose.include) { if (inc.system) { - let cs = await this.worker.findCodeSystem(inc.system, inc.version, this.params, ['complete', 'fragment'], null,true, false, false, this.worker.requiredSupplements); + let cs = await this.worker.findCodeSystem(inc.system, inc.version, this.params, ['complete', 'fragment'], null, true, false, false, this.worker.requiredSupplements); if (cs !== null) { await this.worker.checkSupplements(cs, null, this.worker.requiredSupplements, this.worker.usedSupplements); } @@ -1017,8 +1017,8 @@ class ValueSetChecker { let pver; - let vstatus = {value: ''}; - let normalForm = {value: ''}; + let vstatus = { value: '' }; + let normalForm = { value: '' }; let mt = []; let ts = []; let tsys = ''; @@ -1152,7 +1152,7 @@ class ValueSetChecker { mt.push(m); op.addIssue(new Issue('error', 'invalid', p, 'Terminology_TX_System_Relative', m, 'invalid-data')); } - let prov = await this.worker.findCodeSystem(ws, c.version, this.params, ['complete', 'fragment'], op,true, true, false, this.worker.requiredSupplements); + let prov = await this.worker.findCodeSystem(ws, c.version, this.params, ['complete', 'fragment'], op, true, true, false, this.worker.requiredSupplements); if (prov === null) { let vss = await this.worker.findValueSet(ws, '', null); if (vss !== null) { @@ -1162,7 +1162,7 @@ class ValueSetChecker { op.addIssue(new Issue('error', 'invalid', addToPath(path, 'system'), 'Terminology_TX_System_ValueSet2', m, 'invalid-data')); cause.value = 'invalid'; } else { - let provS = await this.worker.findCodeSystem(ws, c.version, this.params, ['supplement'], op,true, true, false, this.worker.requiredSupplements); + let provS = await this.worker.findCodeSystem(ws, c.version, this.params, ['supplement'], op, true, true, false, this.worker.requiredSupplements); if (provS !== null) { vss = null; let m = this.worker.i18n.translate('CODESYSTEM_CS_NO_SUPPLEMENT', this.params.HTTPLanguages, [provS.vurl()]); @@ -1170,7 +1170,7 @@ class ValueSetChecker { op.addIssue(new Issue('error', 'invalid', addToPath(path, 'system'), 'CODESYSTEM_CS_NO_SUPPLEMENT', m, 'invalid-data')); cause.value = 'invalid'; } else { - let prov2 = await this.worker.findCodeSystem(ws, '', this.params, ['complete', 'fragment'], op,true, true, false, this.worker.requiredSupplements); + let prov2 = await this.worker.findCodeSystem(ws, '', this.params, ['complete', 'fragment'], op, true, true, false, this.worker.requiredSupplements); let bAdd = true; let m, mid, vn; if (prov2 === null && !c.version) { @@ -1189,7 +1189,7 @@ class ValueSetChecker { mid = 'UNKNOWN_CODESYSTEM_VERSION'; vn = ws + '|' + c.version; } - m = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [ws, c.version, this.worker.presentVersionList(vl)]); + m = this.worker.i18n.translate(mid, this.params.HTTPLanguages, [ws, c.version, this.worker.presentVersionList(vl)]); bAdd = !unknownSystems.has(vn); if (bAdd) { unknownSystems.add(vn); @@ -1478,14 +1478,14 @@ class ValueSetChecker { let op = new OperationOutcome(); this.checkCanonicalStatus(issuePath, op, this.valueSet, this.valueSet); let list = new Designations(this.worker.languages); - let ver = {value: ''}; - let inactive = {value: false}; - let normalForm = {value: ''}; - let vstatus = {value: ''}; - let cause = {value: null}; - let contentMode = {value: null}; - let impliedSystem = {value: ''}; - let defLang = {value: null}; + let ver = { value: '' }; + let inactive = { value: false }; + let normalForm = { value: '' }; + let vstatus = { value: '' }; + let cause = { value: null }; + let contentMode = { value: null }; + let impliedSystem = { value: '' }; + let defLang = { value: null }; let ok = await this.check(issuePath, system, version, code, true, list, unknownSystems, ver, inactive, normalForm, vstatus, cause, op, null, result, contentMode, impliedSystem, unkCodes, messages, defLang); if (ok === true) { @@ -1543,7 +1543,7 @@ class ValueSetChecker { let loc = await cs.locate(code); result = false; if (loc.context == null) { - this.worker.opContext.addNote(this.valueSet, 'Code "' + code + '" not found in ' + this.worker.renderer.displayCoded(cs)+": "+loc.mesage, this.indentCount); + this.worker.opContext.addNote(this.valueSet, 'Code "' + code + '" not found in ' + this.worker.renderer.displayCoded(cs) + ": " + loc.mesage, this.indentCount); if (!this.params.membershipOnly && role !== 'not in') { if (cs.contentMode() !== 'complete') { op.addIssue(new Issue('warning', 'code-invalid', addToPath(path, 'code'), 'UNKNOWN_CODE_IN_FRAGMENT', this.worker.i18n.translate('UNKNOWN_CODE_IN_FRAGMENT', this.params.HTTPLanguages, [code, cs.system(), cs.version()]), 'invalid-code')); @@ -1651,13 +1651,13 @@ class ValueSetChecker { } } else { if (vcc !== null) { - if (!vcc.coding) {vcc.coding = [];} - vcc.coding.push({system: cs.system(), version: cs.version(), code: await cs.code(loc), display: displays.preferredDisplay(this.params.workingLanguages())}); + if (!vcc.coding) { vcc.coding = []; } + vcc.coding.push({ system: cs.system(), version: cs.version(), code: await cs.code(loc), display: displays.preferredDisplay(this.params.workingLanguages()) }); } let sstatus = Extensions.readString(cc, 'http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status'); if (['withdrawn', 'deprecated'].includes(sstatus)) { op.addIssue(new Issue('warning', 'business-rule', addToPath(path, 'code'), 'CONCEPT_DEPRECATED_IN_VALUESET', this.worker.i18n.translate('CONCEPT_DEPRECATED_IN_VALUESET', this.params.HTTPLanguages, [cs.system(), code, sstatus, vs.vurl]), 'code-comment')); - } else if (Extensions.has(cc,'http://hl7.org/fhir/StructureDefinition/valueset-deprecated')) { + } else if (Extensions.has(cc, 'http://hl7.org/fhir/StructureDefinition/valueset-deprecated')) { op.addIssue(new Issue('warning', 'business-rule', addToPath(path, 'code'), 'CONCEPT_DEPRECATED_IN_VALUESET', this.worker.i18n.translate('CONCEPT_DEPRECATED_IN_VALUESET', this.params.HTTPLanguages, [cs.system(), code, 'deprecated', vs.vurl]), 'code-comment')); } inactive.value = await cs.isInactive(loc); @@ -1667,7 +1667,7 @@ class ValueSetChecker { return result; } } else { - this.worker.opContext.addNote(this.valueSet, 'Code "' + code + '" in concept list, but not found in ' + this.worker.renderer.displayCoded(cs)+": "+loc.message, this.indentCount); + this.worker.opContext.addNote(this.valueSet, 'Code "' + code + '" in concept list, but not found in ' + this.worker.renderer.displayCoded(cs) + ": " + loc.message, this.indentCount); } } } @@ -1716,14 +1716,14 @@ class ValueSetChecker { } else { this.worker.opContext.addNote(this.valueSet, 'Filter ' + this.filterSummary(cset) + ': Code "' + code + '" found in ' + this.worker.renderer.displayCoded(cs), this.indentCount); if (vcc !== null) { - if (!vcc.coding) { vcc.coding = []} - vcc.coding.push( { system : cs.system(), version: cs.version(), code: await cs.code(loc), display: displays.preferredDisplay(this.params.workingLanguages())}); + if (!vcc.coding) { vcc.coding = [] } + vcc.coding.push({ system: cs.system(), version: cs.version(), code: await cs.code(loc), display: displays.preferredDisplay(this.params.workingLanguages()) }); } result = true; return result; } } else if (loc != null) { - this.worker.opContext.addNote(this.valueSet, 'Filter ' + this.filterSummary(cset) + ': Code "' + code + '" not found in ' + this.worker.renderer.displayCoded(cs)+ ": "+loc, this.indentCount); + this.worker.opContext.addNote(this.valueSet, 'Filter ' + this.filterSummary(cset) + ': Code "' + code + '" not found in ' + this.worker.renderer.displayCoded(cs) + ": " + loc, this.indentCount); messages.push(loc); } else { this.worker.opContext.addNote(this.valueSet, 'Filter ' + this.filterSummary(cset) + ': Code "' + code + '" not found in ' + this.worker.renderer.displayCoded(cs), this.indentCount); @@ -1765,7 +1765,7 @@ class ValueSetChecker { let list = []; for (let filter of cset.filter) { let s = cset.filter.length > 1 ? "(" : ""; - s = filter.property+" "+filter.op+" "+filter.value; + s = filter.property + " " + filter.op + " " + filter.value; s = s + (cset.filter.length > 1 ? ")" : ""); list.push(s) } @@ -1878,6 +1878,7 @@ function SCTVersion(url, ver) { else if (s[4] === '554471000005108') result = 'Danish Edition'; else if (s[4] === '11000181102') result = 'Estonian Edition'; else if (s[4] === '11000229106') result = 'Finnish Edition'; + else if (s[4] === '11000315107') result = 'French Edition'; else if (s[4] === '11000274103') result = 'German Edition'; else if (s[4] === '1121000189102') result = 'Indian Edition'; else if (s[4] === '827022005') result = 'IPS Terminology'; @@ -1985,7 +1986,7 @@ class ValidateWorker extends TerminologyWorker { try { // Extract coded value - mode = {mode: null}; + mode = { mode: null }; coded = this.extractCodedValue(params, true, mode); if (!coded) { throw new Issue('error', 'invalid', null, null, 'Unable to find code to validate (looked for coding | codeableConcept | code in parameters)', null, 400).handleAsOO(400); @@ -2038,7 +2039,7 @@ class ValidateWorker extends TerminologyWorker { */ async handleCodeSystemInstance(req, res) { try { - const {id} = req.params; + const { id } = req.params; const params = this.buildParameters(req); this.log.debug(`CodeSystem/${id}/$validate-code with params:`, params); @@ -2058,7 +2059,7 @@ class ValidateWorker extends TerminologyWorker { const csp = new FhirCodeSystemProvider(this.opContext, new CodeSystem(codeSystem), []); // Extract coded value - let mode = { mode : null } + let mode = { mode: null } const coded = this.extractCodedValue(params, true, mode); if (!coded) { return res.status(400).json(this.operationOutcome('error', 'invalid', @@ -2120,7 +2121,7 @@ class ValidateWorker extends TerminologyWorker { } // Extract coded value - let mode = { mode : null }; + let mode = { mode: null }; const coded = this.extractCodedValue(params, false, mode); if (!coded) { throw new Issue("error", "invalid", null, null, 'Unable to find code to validate (looked for coding | codeableConcept | code+system | code+inferSystem in parameters', null, 422); @@ -2139,7 +2140,7 @@ class ValidateWorker extends TerminologyWorker { */ async handleValueSetInstance(req, res) { try { - const {id} = req.params; + const { id } = req.params; const params = this.buildParameters(req); this.log.debug(`ValueSet/${id}/$validate-code with params:`, params); @@ -2159,7 +2160,7 @@ class ValidateWorker extends TerminologyWorker { } // Extract coded value - let mode = { mode : null }; + let mode = { mode: null }; const coded = this.extractCodedValue(params, false, mode); if (!coded) { return res.status(400).json(this.operationOutcome('error', 'invalid', @@ -2168,7 +2169,7 @@ class ValidateWorker extends TerminologyWorker { // Perform validation const result = await this.doValidationVS(coded, valueSet, txp, mode.mode, mode.issuePath); - req.logInfo = this.usedSources.join("|")+txp.logInfo(); + req.logInfo = this.usedSources.join("|") + txp.logInfo(); return res.json(result); } catch (error) { @@ -2193,7 +2194,7 @@ class ValidateWorker extends TerminologyWorker { if (csResource) { return new FhirCodeSystemProvider(this.opContext, new CodeSystem(csResource), []); // todo: supplements } - let path = coded == null ? null : mode.issuePath+".system"; + let path = coded == null ? null : mode.issuePath + ".system"; let fromCoded = false; // Check for url parameter let url = this.getStringParam(params, 'url'); @@ -2275,7 +2276,7 @@ class ValidateWorker extends TerminologyWorker { let vs = await this.provider.findValueSet(this.opContext, url, version); this.seeSourceVS(vs, url); if (vs == null) { - throw new Issue('error', 'not-found', null, 'Unable_to_resolve_value_Set_', this.i18n.translate('Unable_to_resolve_value_Set_', params.HTTPLanguages, [url+(version ? "|"+version : "")]), 'not-found', 422); + throw new Issue('error', 'not-found', null, 'Unable_to_resolve_value_Set_', this.i18n.translate('Unable_to_resolve_value_Set_', params.HTTPLanguages, [url + (version ? "|" + version : "")]), 'not-found', 422); } else { return vs; } @@ -2306,7 +2307,7 @@ class ValidateWorker extends TerminologyWorker { if (coding) { mode.mode = 'coding'; mode.issuePath = "Coding"; - return {coding: [coding]}; + return { coding: [coding] }; } // Priority 3: individual parameters (code required) @@ -2333,12 +2334,12 @@ class ValidateWorker extends TerminologyWorker { if (!system && !this.getStringParam(params, 'inferSystem')) { return null; } - const codingObj = {code}; + const codingObj = { code }; if (system) codingObj.system = system; if (version) codingObj.version = version; if (display) codingObj.display = display; - return {coding: [codingObj]}; + return { coding: [codingObj] }; } return null; @@ -2367,7 +2368,7 @@ class ValidateWorker extends TerminologyWorker { // Add diagnostics if requested if (params.diagnostics) { - result.jsonObj.parameter.push({name: 'diagnostics', valueString: this.opContext.diagnostics()}); + result.jsonObj.parameter.push({ name: 'diagnostics', valueString: this.opContext.diagnostics() }); } return result.jsonObj; @@ -2376,11 +2377,11 @@ class ValidateWorker extends TerminologyWorker { makeVsForCS(codeSystem) { let vs = { resourceType: "ValueSet", - internallyDefined : true, + internallyDefined: true, status: 'active', - url : codeSystem.valueSet() ? codeSystem.valueSet() : codeSystem.system()+"/vs", - compose : { - "include" : [{ + url: codeSystem.valueSet() ? codeSystem.valueSet() : codeSystem.system() + "/vs", + compose: { + "include": [{ system: codeSystem.system() }] } @@ -2426,7 +2427,7 @@ class ValidateWorker extends TerminologyWorker { // Add diagnostics if requested if (params.diagnostics) { - result.jsonObj.parameter.push({name: 'diagnostics', valueString: this.opContext.diagnostics()}); + result.jsonObj.parameter.push({ name: 'diagnostics', valueString: this.opContext.diagnostics() }); } return result.jsonObj; @@ -2483,29 +2484,29 @@ class ValidateWorker extends TerminologyWorker { const parameters = { resourceType: 'Parameters', parameter: [ - {name: 'result', valueBoolean: result} + { name: 'result', valueBoolean: result } ] }; if (message) { - parameters.parameter.push({name: 'message', valueString: message}); + parameters.parameter.push({ name: 'message', valueString: message }); } if (display && result) { - parameters.parameter.push({name: 'display', valueString: display}); + parameters.parameter.push({ name: 'display', valueString: display }); } // Include the code that was validated if (coded.coding && coded.coding.length > 0) { const coding = coded.coding[0]; if (coding.code) { - parameters.parameter.push({name: 'code', valueCode: coding.code}); + parameters.parameter.push({ name: 'code', valueCode: coding.code }); } if (coding.system) { - parameters.parameter.push({name: 'system', valueUri: coding.system}); + parameters.parameter.push({ name: 'system', valueUri: coding.system }); } if (coding.version) { - parameters.parameter.push({name: 'version', valueString: coding.version}); + parameters.parameter.push({ name: 'version', valueString: coding.version }); } }