Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions registry/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -476,7 +476,7 @@ class RegistryModule {
const lastRunDate = new Date(stats.lastRun);
lastUpdatedText = `Last Updated: ${lastRunDate.toLocaleString()}`;
}
html += `<p>${lastUpdatedText}. <a href="https://github.com/FHIR/ig-registry/blob/master/tx-registry-doco.md">Register your own server</a>`+
html += `<p>${lastUpdatedText}. <a href="https://github.com/FHIR/ig-registry/blob/master/tx-registry-doco.md">Register your own server</a>` +
` - see <a href="https://build.fhir.org/ig/HL7/fhir-tx-ecosystem-ig/ecosystem.html">Documentation</a></p>`;

html += '<table class="grid">';
Expand Down Expand Up @@ -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('/');
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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';
Expand All @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 = [];
Expand Down Expand Up @@ -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);
Expand Down
74 changes: 38 additions & 36 deletions tx/cs/cs-snomed.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { CodeSystemContentMode, CodeSystemFactoryProvider} = require('./cs-api');
const { CodeSystemContentMode, CodeSystemFactoryProvider } = require('./cs-api');
const {
SnomedStrings, SnomedWords, SnomedStems, SnomedReferences,
SnomedDescriptions, SnomedDescriptionIndex, SnomedConceptList,
Expand All @@ -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 = {
Expand Down Expand Up @@ -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
: '';
}
}

Expand Down Expand Up @@ -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}`);
}
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down Expand Up @@ -704,7 +704,7 @@ class SnomedServices {
return result;
};

// ── Dotted expressions ───────────────────────────────────────────────────────
// ── Dotted expressions ───────────────────────────────────────────────────────

/**
* Evaluate a dotted expression: `<baseConstraint> . attrA . attrB`.
Expand Down Expand Up @@ -745,7 +745,7 @@ class SnomedServices {
return result;
};

// ── Refinements ──────────────────────────────────────────────────────────────
// ── Refinements ──────────────────────────────────────────────────────────────

/**
* Evaluate a refined expression: `<baseConstraint> : <refinement>`.
Expand Down Expand Up @@ -916,7 +916,7 @@ class SnomedServices {
return false;
};

// ── Set operation helpers ────────────────────────────────────────────────────
// ── Set operation helpers ────────────────────────────────────────────────────

/**
* Flatten a SnomedFilterContext to a plain array of concept indexes,
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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 });
}
}
}
Expand All @@ -1434,15 +1434,15 @@ 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) {
const codeA = refinement.name.code;
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) });
}
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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;
Expand All @@ -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',
Expand Down Expand Up @@ -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) {
Expand All @@ -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 = '';
Expand All @@ -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`,
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -2278,6 +2279,7 @@ function getEditionCode(edition) {
'11000279109': 'CZ',
'11000181102': 'ES',
'11000229106': 'FI',
'11000315107': 'FR-fr',
'11000274103': 'DE',
'1121000189102': 'IN',
'827022005': 'IPS',
Expand Down
Loading