Skip to content

Commit b0f8dbb

Browse files
committed
Support boundless and uncertain CQL intervals
- Align interval operators with CQL semantics for boundless and uncertain endpoints - Update interval operators to follow CQL spec implementation language as closely as possible - Preserve interval point types and improve arithmetic, precision, and limit handling - Expand unit, integration, and specification test coverage
1 parent 7ca89d1 commit b0f8dbb

35 files changed

Lines changed: 20816 additions & 11611 deletions

.mocharc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"ignore": ["test/spec-tests/*.js"],
33
"extension": ["ts"],
4-
"require": "ts-node/register"
4+
"require": ["ts-node/register", "./test/should-extensions.ts"]
55
}

examples/browser/cql4browsers.js

Lines changed: 792 additions & 753 deletions
Large diffs are not rendered by default.

src/cql-patient.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as DT from './datatypes/datatypes';
22
import { DataProvider, NamedTypeSpecifier, PatientObject, RecordObject } from './types';
3-
import { ELM_NAMED_TYPE_SPECIFIER } from './util/elmTypes';
3+
import { ELM_ANY_TYPE, ELM_NAMED_TYPE_SPECIFIER } from './util/elmTypes';
44

55
export class Record implements RecordObject {
66
json: any;
@@ -27,7 +27,7 @@ export class Record implements RecordObject {
2727
name: '{https://github.com/cqframework/cql-execution/simple}Record',
2828
type: ELM_NAMED_TYPE_SPECIFIER
2929
},
30-
{ name: '{urn:hl7-org:elm-types:r1}Any', type: ELM_NAMED_TYPE_SPECIFIER }
30+
{ name: ELM_ANY_TYPE, type: ELM_NAMED_TYPE_SPECIFIER }
3131
];
3232
}
3333

src/datatypes/datetime.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ import {
1212
DateTime as LuxonDateTime,
1313
FixedOffsetZone
1414
} from 'luxon';
15+
import {
16+
MAX_DATE_VALUE_STRING,
17+
MAX_DATETIME_VALUE_STRING,
18+
MAX_TIME_VALUE_STRING,
19+
MIN_DATE_VALUE_STRING,
20+
MIN_DATETIME_VALUE_STRING,
21+
MIN_TIME_VALUE_STRING
22+
} from '../util/limits';
1523

1624
// It's easiest and most performant to organize formats by length of the supported strings.
1725
// This way we can test strings only against the formats that have a chance of working.
@@ -550,7 +558,7 @@ abstract class AbstractDate {
550558
case 'millisecond':
551559
return 999;
552560
default:
553-
throw new Error('Tried to clieling a field that has no cieling value: ' + field);
561+
throw new Error('Tried to ceiling a field that has no cieling value: ' + field);
554562
}
555563
}
556564
}
@@ -722,8 +730,10 @@ export class DateTime extends AbstractDate {
722730
);
723731
}
724732

725-
successor() {
726-
if (this.millisecond != null) {
733+
successor(precision?: string) {
734+
if (precision) {
735+
return this.add(1, precision);
736+
} else if (this.millisecond != null) {
727737
return this.add(1, DateTime.Unit.MILLISECOND);
728738
} else if (this.second != null) {
729739
return this.add(1, DateTime.Unit.SECOND);
@@ -740,8 +750,10 @@ export class DateTime extends AbstractDate {
740750
}
741751
}
742752

743-
predecessor() {
744-
if (this.millisecond != null) {
753+
predecessor(precision?: string) {
754+
if (precision) {
755+
return this.add(-1, precision);
756+
} else if (this.millisecond != null) {
745757
return this.add(-1, DateTime.Unit.MILLISECOND);
746758
} else if (this.second != null) {
747759
return this.add(-1, DateTime.Unit.SECOND);
@@ -1254,13 +1266,12 @@ export class Date extends AbstractDate {
12541266

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

12651276
const DATETIME_PRECISION_VALUE_MAP = (() => {
12661277
const dtpvMap = new Map();

0 commit comments

Comments
 (0)