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
2 changes: 1 addition & 1 deletion .mocharc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"ignore": ["test/spec-tests/*.js"],
"extension": ["ts"],
"require": "ts-node/register"
"require": ["ts-node/register", "./test/should-extensions.ts"]
}
7 changes: 7 additions & 0 deletions DEPENDENCY_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The following notes about the app's dependencies should be revisited and resolved when possible:

As of 2026-07-27:

- `@types/node`: Consider updating to `26.x` in the future, but for now `24.x` still has plent of time in LTS.
- `typescript`: `7.x` uses a new native compiler without a native API. Libraries like `ts-node` and `typescript-eslint` do not yet support it.
- `tslog` (test-server only): `5.x` is ESM-only and replaces v4's flat logger settings such as `hideLogPositionForProduction` and `prettyLogTemplate`. Updating will require some migration.
1,731 changes: 905 additions & 826 deletions examples/browser/cql4browsers.js

Large diffs are not rendered by default.

234 changes: 117 additions & 117 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,30 +70,30 @@
"@eslint/js": "^10.0.1",
"@types/luxon": "^3.7.2",
"@types/mocha": "^10.0.10",
"@types/node": "^24.13.2",
"@types/node": "^24.13.3",
"@types/should-sinon": "^0.0.13",
"@types/sinon": "^21.0.1",
"@types/sinon": "^22.0.0",
"@types/test-console": "^2.0.3",
"@typescript-eslint/eslint-plugin": "^8.62.0",
"@typescript-eslint/parser": "^8.62.0",
"@typescript-eslint/eslint-plugin": "^8.65.0",
"@typescript-eslint/parser": "^8.65.0",
"browserify": "^17.0.1",
"cross-env": "^10.1.0",
"eslint": "^10.5.0",
"eslint": "^10.8.0",
"eslint-config-prettier": "^10.1.8",
"globals": "^17.7.0",
"globals": "^17.8.0",
"mocha": "^11.7.6",
"nyc": "^18.0.0",
"prettier": "^3.8.4",
"prettier": "^3.9.6",
"should": "^13.2.3",
"should-sinon": "0.0.6",
"sinon": "^21.1.2",
"sinon": "^22.1.0",
"test-console": "^2.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.9.3",
"typescript": "^6.0.3",
"xml-js": "^1.6.11"
},
"dependencies": {
"@lhncbc/ucum-lhc": "^7.1.8",
"@lhncbc/ucum-lhc": "^7.1.9",
"immutable": "^5.1.6",
"luxon": "^3.7.2"
},
Expand Down
4 changes: 2 additions & 2 deletions src/cql-patient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as DT from './datatypes/datatypes';
import { DataProvider, NamedTypeSpecifier, PatientObject, RecordObject } from './types';
import { ELM_NAMED_TYPE_SPECIFIER } from './util/elmTypes';
import { ELM_ANY_TYPE, ELM_NAMED_TYPE_SPECIFIER } from './util/elmTypes';

export class Record implements RecordObject {
json: any;
Expand All @@ -27,7 +27,7 @@ export class Record implements RecordObject {
name: '{https://github.com/cqframework/cql-execution/simple}Record',
type: ELM_NAMED_TYPE_SPECIFIER
},
{ name: '{urn:hl7-org:elm-types:r1}Any', type: ELM_NAMED_TYPE_SPECIFIER }
{ name: ELM_ANY_TYPE, type: ELM_NAMED_TYPE_SPECIFIER }
];
}

Expand Down
93 changes: 30 additions & 63 deletions src/datatypes/datetime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ import {
DateTime as LuxonDateTime,
FixedOffsetZone
} from 'luxon';
import {
MAX_DATE_VALUE_STRING,
MAX_DATETIME_VALUE_STRING,
MAX_TIME_VALUE_STRING,
MIN_DATE_VALUE_STRING,
MIN_DATETIME_VALUE_STRING,
MIN_TIME_VALUE_STRING
} from '../util/limits';

// It's easiest and most performant to organize formats by length of the supported strings.
// This way we can test strings only against the formats that have a chance of working.
Expand Down Expand Up @@ -515,44 +523,6 @@ abstract class AbstractDate {
return result;
}
}

getFieldFloor(field: any) {
switch (field) {
case 'month':
return 1;
case 'day':
return 1;
case 'hour':
return 0;
case 'minute':
return 0;
case 'second':
return 0;
case 'millisecond':
return 0;
default:
throw new Error('Tried to floor a field that has no floor value: ' + field);
}
}

getFieldCieling(field: any) {
switch (field) {
case 'month':
return 12;
case 'day':
return daysInMonth(this.year, this.month);
case 'hour':
return 23;
case 'minute':
return 59;
case 'second':
return 59;
case 'millisecond':
return 999;
default:
throw new Error('Tried to clieling a field that has no cieling value: ' + field);
}
}
}

export class DateTime extends AbstractDate {
Expand Down Expand Up @@ -722,8 +692,10 @@ export class DateTime extends AbstractDate {
);
}

successor() {
if (this.millisecond != null) {
successor(precision?: string) {
if (precision) {
return this.add(1, precision);
} else if (this.millisecond != null) {
return this.add(1, DateTime.Unit.MILLISECOND);
} else if (this.second != null) {
return this.add(1, DateTime.Unit.SECOND);
Expand All @@ -740,8 +712,10 @@ export class DateTime extends AbstractDate {
}
}

predecessor() {
if (this.millisecond != null) {
predecessor(precision?: string) {
if (precision) {
return this.add(-1, precision);
} else if (this.millisecond != null) {
return this.add(-1, DateTime.Unit.MILLISECOND);
} else if (this.second != null) {
return this.add(-1, DateTime.Unit.SECOND);
Expand Down Expand Up @@ -1078,8 +1052,10 @@ export class Date extends AbstractDate {
return new Date(this.year, this.month, this.day);
}

successor() {
if (this.day != null) {
successor(precision?: string) {
if (precision) {
return this.add(1, precision);
} else if (this.day != null) {
return this.add(1, Date.Unit.DAY);
} else if (this.month != null) {
return this.add(1, Date.Unit.MONTH);
Expand All @@ -1088,8 +1064,10 @@ export class Date extends AbstractDate {
}
}

predecessor() {
if (this.day != null) {
predecessor(precision?: string) {
if (precision) {
return this.add(-1, precision);
} else if (this.day != null) {
return this.add(-1, Date.Unit.DAY);
} else if (this.month != null) {
return this.add(-1, Date.Unit.MONTH);
Expand Down Expand Up @@ -1252,15 +1230,12 @@ export class Date extends AbstractDate {
}
}

// Require MIN/MAX here because math.js requires this file, and when we make this file require
// math.js before it exports DateTime and Date, it errors due to the circular dependency...
// const { MAX_DATETIME_VALUE, MIN_DATETIME_VALUE } = require('../util/math');
export const MIN_DATETIME_VALUE = DateTime.parse('0001-01-01T00:00:00.000');
export const MAX_DATETIME_VALUE = DateTime.parse('9999-12-31T23:59:59.999');
export const MIN_DATE_VALUE = Date.parse('0001-01-01');
export const MAX_DATE_VALUE = Date.parse('9999-12-31');
export const MIN_TIME_VALUE = DateTime.parse('0000-01-01T00:00:00.000')?.getTime();
export const MAX_TIME_VALUE = DateTime.parse('0000-01-01T23:59:59.999')?.getTime();
export const MIN_DATETIME_VALUE = DateTime.parse(MIN_DATETIME_VALUE_STRING);
export const MAX_DATETIME_VALUE = DateTime.parse(MAX_DATETIME_VALUE_STRING);
export const MIN_DATE_VALUE = Date.parse(MIN_DATE_VALUE_STRING);
export const MAX_DATE_VALUE = Date.parse(MAX_DATE_VALUE_STRING);
export const MIN_TIME_VALUE = DateTime.parse(MIN_TIME_VALUE_STRING)?.getTime();
export const MAX_TIME_VALUE = DateTime.parse(MAX_TIME_VALUE_STRING)?.getTime();

const DATETIME_PRECISION_VALUE_MAP = (() => {
const dtpvMap = new Map();
Expand Down Expand Up @@ -1329,14 +1304,6 @@ function compareWithDefaultResult(a: any, b: any, defaultResult: any) {
return true;
}

function daysInMonth(year: number | null, month: number | null) {
if (year == null || month == null) {
throw new Error('daysInMonth requires year and month as arguments');
}
// Month is 1-indexed here because of the 0 day
return new jsDate(year, month, 0).getDate();
}

function isValidDateStringFormat(string: any) {
if (typeof string !== 'string') {
return false;
Expand Down
Loading
Loading