Skip to content
Merged
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
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ All notable changes to the Health Intersections Node Server will be documented i
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v0.9.3] - 2026-04-10

### Added

- Add support for handling contained value sets
- Add beta support for ECL

### Changed

- Bump vsac fetch to 1000 and improve history presentation

### Fixed

- Fix count on empty value set

### Tx Conformance Statement

FHIRsmith passed all 1651 HL7 terminology service tests (modes tx.fhir.org+omop+general+snomed, tests v1.9.1, runner v6.9.6)

## [v0.9.2] - 2026-04-14

### Fixed
Expand Down
10 changes: 5 additions & 5 deletions tests/cs/cs-areacode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe('AreaCodeServices', () => {

beforeEach(async () => {
ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'class', '=', 'country');
await provider.filter(ctxt, true, 'class', '=', 'country');
const filters = await provider.executeFilters(ctxt);
countryFilter = filters[0];
});
Expand Down Expand Up @@ -195,7 +195,7 @@ describe('AreaCodeServices', () => {

beforeEach(async () => {
ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'type', '=', 'region');
await provider.filter(ctxt, true, 'type', '=', 'region');
const filters = await provider.executeFilters(ctxt);
regionFilter = filters[0];
});
Expand Down Expand Up @@ -253,13 +253,13 @@ describe('AreaCodeServices', () => {
describe('Filter Error Cases', () => {
test('should throw error for unsupported property', async () => {
await expect(
provider.filter(await provider.getPrepContext(false), 'display', '=', 'test')
provider.filter(await provider.getPrepContext(false), true, 'display', '=', 'test')
).rejects.toThrow('not supported');
});

test('should throw error for unsupported operator', async () => {
await expect(
provider.filter(await provider.getPrepContext(false), 'class', 'contains', 'country')
provider.filter(await provider.getPrepContext(false), true, 'class', 'contains', 'country')
).rejects.toThrow('not supported');
});

Expand All @@ -274,7 +274,7 @@ describe('AreaCodeServices', () => {
describe('Execute Filters', () => {
test('should execute single filter', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'class', '=', 'country');
await provider.filter(ctxt, true, 'class', '=', 'country');
const results = await provider.executeFilters(ctxt);
const countryFilter = results[0];

Expand Down
30 changes: 15 additions & 15 deletions tests/cs/cs-country.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ describe('CountryCodeServices', () => {
describe('Regex Filtering', () => {
test('should filter by 2-letter code pattern', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', 'U[S|A]');
await provider.filter(ctxt, true, 'code', 'regex', 'U[S|A]');
const filters = await provider.executeFilters(ctxt);
expect(filters[0]).toBeTruthy();
expect(filters[0].list).toBeTruthy();
Expand All @@ -197,7 +197,7 @@ describe('CountryCodeServices', () => {

test('should filter by 3-letter code pattern', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', 'US.*');
await provider.filter(ctxt, true, 'code', 'regex', 'US.*');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -220,7 +220,7 @@ describe('CountryCodeServices', () => {

test('should filter by numeric code pattern', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', '8[0-9]{2}');
await provider.filter(ctxt, true, 'code', 'regex', '8[0-9]{2}');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -245,7 +245,7 @@ describe('CountryCodeServices', () => {

test('should filter by exact match pattern', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', 'US');
await provider.filter(ctxt, true, 'code', 'regex', 'US');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -263,7 +263,7 @@ describe('CountryCodeServices', () => {

test('should filter all 2-letter codes', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', '[A-Z]{2}');
await provider.filter(ctxt, true, 'code', 'regex', '[A-Z]{2}');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -286,7 +286,7 @@ describe('CountryCodeServices', () => {

test('should filter all 3-letter codes', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', '[A-Z]{3}');
await provider.filter(ctxt, true, 'code', 'regex', '[A-Z]{3}');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -309,7 +309,7 @@ describe('CountryCodeServices', () => {

test('should filter all numeric codes', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', '\\d{3}');
await provider.filter(ctxt, true, 'code', 'regex', '\\d{3}');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -332,7 +332,7 @@ describe('CountryCodeServices', () => {

test('should handle empty filter results', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', 'ZZZZZ');
await provider.filter(ctxt, true, 'code', 'regex', 'ZZZZZ');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -344,7 +344,7 @@ describe('CountryCodeServices', () => {

test('should locate specific code in filter', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', 'US.*');
await provider.filter(ctxt, true, 'code', 'regex', 'US.*');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -356,7 +356,7 @@ describe('CountryCodeServices', () => {

test('should not locate code not in filter', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', 'US.*');
await provider.filter(ctxt, true, 'code', 'regex', 'US.*');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -367,7 +367,7 @@ describe('CountryCodeServices', () => {

test('should check if concept is in filter', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', 'US.*');
await provider.filter(ctxt, true, 'code', 'regex', 'US.*');
const filters = await provider.executeFilters(ctxt);
const filter = filters[0];

Expand All @@ -384,19 +384,19 @@ describe('CountryCodeServices', () => {
describe('Filter Error Cases', () => {
test('should throw error for unsupported property', async () => {
await expect(
provider.filter(await provider.getPrepContext(false), 'display', 'regex', 'test')
provider.filter(await provider.getPrepContext(false), true, 'display', 'regex', 'test')
).rejects.toThrow('not supported');
});

test('should throw error for unsupported operator', async () => {
await expect(
provider.filter(await provider.getPrepContext(false), 'code', 'equals', 'US')
provider.filter(await provider.getPrepContext(false), true, 'code', 'equals', 'US')
).rejects.toThrow('not supported');
});

test('should throw error for invalid regex', async () => {
await expect(
provider.filter(await provider.getPrepContext(false), 'code', 'regex', '[invalid')
provider.filter(await provider.getPrepContext(false), true, 'code', 'regex', '[invalid')
).rejects.toThrow('Invalid regex pattern');
});

Expand All @@ -411,7 +411,7 @@ describe('CountryCodeServices', () => {
describe('Execute Filters', () => {
test('should execute single filter', async () => {
const ctxt = await provider.getPrepContext(false);
await provider.filter(ctxt, 'code', 'regex', 'US.*');
await provider.filter(ctxt, true, 'code', 'regex', 'US.*');
const results = await provider.executeFilters(ctxt);

expect(results).toBeTruthy();
Expand Down
24 changes: 12 additions & 12 deletions tests/cs/cs-cpt.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ describe('CPT Provider', () => {
describe('Modifier Filters', () => {
test('should filter modifier=true', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'modifier', '=', 'true');
await provider.filter(filterContext, true, 'modifier', '=', 'true');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -346,7 +346,7 @@ describe('CPT Provider', () => {

test('should filter modifier=false', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'modifier', '=', 'false');
await provider.filter(filterContext, true, 'modifier', '=', 'false');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -367,7 +367,7 @@ describe('CPT Provider', () => {
describe('Kind Filters', () => {
test('should filter by kind=code', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'kind', '=', 'code');
await provider.filter(filterContext, true, 'kind', '=', 'code');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -386,7 +386,7 @@ describe('CPT Provider', () => {

test('should filter by kind=cat-2', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'kind', '=', 'cat-2');
await provider.filter(filterContext, true, 'kind', '=', 'cat-2');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -403,7 +403,7 @@ describe('CPT Provider', () => {

test('should filter by kind=general', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'kind', '=', 'general');
await provider.filter(filterContext, true, 'kind', '=', 'general');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -422,7 +422,7 @@ describe('CPT Provider', () => {
describe('Modified Filter', () => {
test('should filter modified=false (all codes)', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'modified', '=', 'false');
await provider.filter(filterContext, true, 'modified', '=', 'false');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -434,7 +434,7 @@ describe('CPT Provider', () => {

test('should filter modified=true (empty)', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'modified', '=', 'true');
await provider.filter(filterContext, true, 'modified', '=', 'true');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -452,7 +452,7 @@ describe('CPT Provider', () => {
describe('Filter Operations', () => {
test('should locate codes within filters', async () => {
const filterContext = await provider.getPrepContext(false);
await provider.filter(filterContext, 'modifier', '=', 'true');
await provider.filter(filterContext, true, 'modifier', '=', 'true');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -466,7 +466,7 @@ describe('CPT Provider', () => {

test('should check if concepts are in filters', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'modifier', '=', 'false');
await provider.filter(filterContext, true, 'modifier', '=', 'false');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand All @@ -483,7 +483,7 @@ describe('CPT Provider', () => {

test('should handle expressions in filters', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'modified', '=', 'true');
await provider.filter(filterContext, true, 'modified', '=', 'true');
const filters = await provider.executeFilters(filterContext);
const filter = filters[0];

Expand Down Expand Up @@ -533,7 +533,7 @@ describe('CPT Provider', () => {
const filterContext = await provider.getPrepContext(true);

await expect(
provider.filter(filterContext, 'unsupported', '=', 'value')
provider.filter(filterContext, true, 'unsupported', '=', 'value')
).rejects.toThrow('not supported');
});

Expand Down Expand Up @@ -579,7 +579,7 @@ describe('CPT Provider', () => {
describe('Performance and Cleanup', () => {
test('should handle filter cleanup', async () => {
const filterContext = await provider.getPrepContext(true);
await provider.filter(filterContext, 'modifier', '=', 'true');
await provider.filter(filterContext, true, 'modifier', '=', 'true');
await provider.executeFilters(filterContext);

// Should not throw
Expand Down
Loading
Loading