@medplum/core 0.9.30 → 0.9.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/client.d.ts +14 -7
- package/dist/cjs/index.js +686 -686
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +1 -1
- package/dist/cjs/index.min.js.map +1 -1
- package/dist/cjs/types.d.ts +2 -1
- package/dist/cjs/utils.d.ts +7 -1
- package/dist/esm/client.d.ts +14 -7
- package/dist/esm/client.js +12 -10
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/fhirpath/atoms.js +2 -1
- package/dist/esm/fhirpath/atoms.js.map +1 -1
- package/dist/esm/fhirpath/functions.js +3 -1
- package/dist/esm/fhirpath/functions.js.map +1 -1
- package/dist/esm/fhirpath/utils.js +5 -6
- package/dist/esm/fhirpath/utils.js.map +1 -1
- package/dist/esm/format.js +2 -2
- package/dist/esm/format.js.map +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.min.js +1 -1
- package/dist/esm/index.min.js.map +1 -1
- package/dist/esm/types.d.ts +2 -1
- package/dist/esm/types.js +24 -27
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils.d.ts +7 -1
- package/dist/esm/utils.js +2 -2
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
}
|
|
130
130
|
function formatHumanName(name, options) {
|
|
131
131
|
const builder = [];
|
|
132
|
-
if (name.prefix && (
|
|
132
|
+
if (name.prefix && (options === null || options === void 0 ? void 0 : options.prefix) !== false) {
|
|
133
133
|
builder.push(...name.prefix);
|
|
134
134
|
}
|
|
135
135
|
if (name.given) {
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
if (name.family) {
|
|
139
139
|
builder.push(name.family);
|
|
140
140
|
}
|
|
141
|
-
if (name.suffix && (
|
|
141
|
+
if (name.suffix && (options === null || options === void 0 ? void 0 : options.suffix) !== false) {
|
|
142
142
|
builder.push(...name.suffix);
|
|
143
143
|
}
|
|
144
144
|
if (name.use && ((options === null || options === void 0 ? void 0 : options.all) || (options === null || options === void 0 ? void 0 : options.use))) {
|
|
@@ -692,7 +692,7 @@
|
|
|
692
692
|
return word.charAt(0).toUpperCase() + word.substring(1);
|
|
693
693
|
}
|
|
694
694
|
function isLowerCase(c) {
|
|
695
|
-
return c === c.toLowerCase();
|
|
695
|
+
return c === c.toLowerCase() && c !== c.toUpperCase();
|
|
696
696
|
}
|
|
697
697
|
/**
|
|
698
698
|
* Tries to find a code string for a given system within a given codeable concept.
|
|
@@ -6070,19 +6070,13 @@
|
|
|
6070
6070
|
function createSchema() {
|
|
6071
6071
|
return { types: {} };
|
|
6072
6072
|
}
|
|
6073
|
-
function createTypeSchema(typeName,
|
|
6073
|
+
function createTypeSchema(typeName, structureDefinition, elementDefinition) {
|
|
6074
6074
|
return {
|
|
6075
|
+
structureDefinition,
|
|
6076
|
+
elementDefinition,
|
|
6075
6077
|
display: typeName,
|
|
6076
|
-
description,
|
|
6078
|
+
description: elementDefinition.definition,
|
|
6077
6079
|
properties: {},
|
|
6078
|
-
searchParams: {
|
|
6079
|
-
_lastUpdated: {
|
|
6080
|
-
base: [typeName],
|
|
6081
|
-
code: '_lastUpdated',
|
|
6082
|
-
type: 'date',
|
|
6083
|
-
expression: typeName + '.meta.lastUpdated',
|
|
6084
|
-
},
|
|
6085
|
-
},
|
|
6086
6080
|
};
|
|
6087
6081
|
}
|
|
6088
6082
|
/**
|
|
@@ -6109,17 +6103,12 @@
|
|
|
6109
6103
|
if (!typeName) {
|
|
6110
6104
|
return;
|
|
6111
6105
|
}
|
|
6112
|
-
if (!(typeName in schema.types)) {
|
|
6113
|
-
schema.types[typeName] = createTypeSchema(typeName, structureDefinition.description);
|
|
6114
|
-
}
|
|
6115
6106
|
const elements = (_a = structureDefinition.snapshot) === null || _a === void 0 ? void 0 : _a.element;
|
|
6116
6107
|
if (elements) {
|
|
6117
|
-
// Filter out any elements missing path or type
|
|
6118
|
-
const filtered = elements.filter((e) => e.path !== typeName && e.path);
|
|
6119
6108
|
// First pass, build types
|
|
6120
|
-
|
|
6109
|
+
elements.forEach((element) => indexType(schema, structureDefinition, element));
|
|
6121
6110
|
// Second pass, build properties
|
|
6122
|
-
|
|
6111
|
+
elements.forEach((element) => indexProperty(schema, element));
|
|
6123
6112
|
}
|
|
6124
6113
|
}
|
|
6125
6114
|
/**
|
|
@@ -6129,19 +6118,17 @@
|
|
|
6129
6118
|
* @param schema The output IndexedStructureDefinition.
|
|
6130
6119
|
* @param element The input ElementDefinition.
|
|
6131
6120
|
*/
|
|
6132
|
-
function indexType(schema,
|
|
6121
|
+
function indexType(schema, structureDefinition, elementDefinition) {
|
|
6133
6122
|
var _a, _b;
|
|
6134
|
-
const path =
|
|
6135
|
-
const typeCode = (_b = (_a =
|
|
6136
|
-
if (typeCode !== 'Element' && typeCode !== 'BackboneElement') {
|
|
6123
|
+
const path = elementDefinition.path;
|
|
6124
|
+
const typeCode = (_b = (_a = elementDefinition.type) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.code;
|
|
6125
|
+
if (typeCode !== undefined && typeCode !== 'Element' && typeCode !== 'BackboneElement') {
|
|
6137
6126
|
return;
|
|
6138
6127
|
}
|
|
6139
6128
|
const parts = path.split('.');
|
|
6140
6129
|
const typeName = buildTypeName(parts);
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
schema.types[typeName].parentType = buildTypeName(parts.slice(0, parts.length - 1));
|
|
6144
|
-
}
|
|
6130
|
+
schema.types[typeName] = createTypeSchema(typeName, structureDefinition, elementDefinition);
|
|
6131
|
+
schema.types[typeName].parentType = buildTypeName(parts.slice(0, parts.length - 1));
|
|
6145
6132
|
}
|
|
6146
6133
|
/**
|
|
6147
6134
|
* Indexes PropertySchema from an ElementDefinition.
|
|
@@ -6178,12 +6165,22 @@
|
|
|
6178
6165
|
continue;
|
|
6179
6166
|
}
|
|
6180
6167
|
if (!typeSchema.searchParams) {
|
|
6181
|
-
typeSchema.searchParams = {
|
|
6168
|
+
typeSchema.searchParams = {
|
|
6169
|
+
_lastUpdated: {
|
|
6170
|
+
base: [resourceType],
|
|
6171
|
+
code: '_lastUpdated',
|
|
6172
|
+
type: 'date',
|
|
6173
|
+
expression: resourceType + '.meta.lastUpdated',
|
|
6174
|
+
},
|
|
6175
|
+
};
|
|
6182
6176
|
}
|
|
6183
6177
|
typeSchema.searchParams[searchParam.code] = searchParam;
|
|
6184
6178
|
}
|
|
6185
6179
|
}
|
|
6186
6180
|
function buildTypeName(components) {
|
|
6181
|
+
if (components.length === 1) {
|
|
6182
|
+
return components[0];
|
|
6183
|
+
}
|
|
6187
6184
|
return components.map(capitalize).join('');
|
|
6188
6185
|
}
|
|
6189
6186
|
function getPropertyDisplayName(path) {
|
|
@@ -6494,12 +6491,11 @@
|
|
|
6494
6491
|
* This requires a partial login from `startNewUser` or `startNewGoogleUser`.
|
|
6495
6492
|
*
|
|
6496
6493
|
* @param newProjectRequest Register request including email and password.
|
|
6497
|
-
* @param login The partial login to complete. This should come from the `startNewUser` method.
|
|
6498
6494
|
* @returns Promise to the authentication response.
|
|
6499
6495
|
*/
|
|
6500
|
-
startNewProject(newProjectRequest
|
|
6496
|
+
startNewProject(newProjectRequest) {
|
|
6501
6497
|
return __awaiter(this, void 0, void 0, function* () {
|
|
6502
|
-
return this.post('auth/newproject',
|
|
6498
|
+
return this.post('auth/newproject', newProjectRequest);
|
|
6503
6499
|
});
|
|
6504
6500
|
}
|
|
6505
6501
|
/**
|
|
@@ -6508,12 +6504,11 @@
|
|
|
6508
6504
|
* This requires a partial login from `startNewUser` or `startNewGoogleUser`.
|
|
6509
6505
|
*
|
|
6510
6506
|
* @param newPatientRequest Register request including email and password.
|
|
6511
|
-
* @param login The partial login to complete. This should come from the `startNewUser` method.
|
|
6512
6507
|
* @returns Promise to the authentication response.
|
|
6513
6508
|
*/
|
|
6514
|
-
startNewPatient(newPatientRequest
|
|
6509
|
+
startNewPatient(newPatientRequest) {
|
|
6515
6510
|
return __awaiter(this, void 0, void 0, function* () {
|
|
6516
|
-
return this.post('auth/newpatient',
|
|
6511
|
+
return this.post('auth/newpatient', newPatientRequest);
|
|
6517
6512
|
});
|
|
6518
6513
|
}
|
|
6519
6514
|
/**
|
|
@@ -6525,8 +6520,10 @@
|
|
|
6525
6520
|
startLogin(loginRequest) {
|
|
6526
6521
|
var _a, _b;
|
|
6527
6522
|
return __awaiter(this, void 0, void 0, function* () {
|
|
6528
|
-
|
|
6529
|
-
|
|
6523
|
+
if (!loginRequest.codeChallenge || !loginRequest.codeChallengeMethod) {
|
|
6524
|
+
yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
|
|
6525
|
+
}
|
|
6526
|
+
return this.post('auth/login', Object.assign(Object.assign({}, loginRequest), { clientId: (_a = loginRequest.clientId) !== null && _a !== void 0 ? _a : __classPrivateFieldGet(this, _MedplumClient_clientId, "f"), scope: (_b = loginRequest.scope) !== null && _b !== void 0 ? _b : DEFAULT_SCOPE, codeChallengeMethod: loginRequest.codeChallengeMethod || 'S256', codeChallenge: loginRequest.codeChallenge || __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge') }));
|
|
6530
6527
|
});
|
|
6531
6528
|
}
|
|
6532
6529
|
/**
|
|
@@ -6540,8 +6537,10 @@
|
|
|
6540
6537
|
startGoogleLogin(loginRequest) {
|
|
6541
6538
|
var _a, _b;
|
|
6542
6539
|
return __awaiter(this, void 0, void 0, function* () {
|
|
6543
|
-
|
|
6544
|
-
|
|
6540
|
+
if (!loginRequest.codeChallenge || !loginRequest.codeChallengeMethod) {
|
|
6541
|
+
yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
|
|
6542
|
+
}
|
|
6543
|
+
return this.post('auth/google', Object.assign(Object.assign({}, loginRequest), { clientId: (_a = loginRequest.clientId) !== null && _a !== void 0 ? _a : __classPrivateFieldGet(this, _MedplumClient_clientId, "f"), scope: (_b = loginRequest.scope) !== null && _b !== void 0 ? _b : DEFAULT_SCOPE, codeChallengeMethod: loginRequest.codeChallengeMethod || 'S256', codeChallenge: loginRequest.codeChallenge || __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge') }));
|
|
6545
6544
|
});
|
|
6546
6545
|
}
|
|
6547
6546
|
/**
|
|
@@ -7663,6 +7662,28 @@
|
|
|
7663
7662
|
return url.endsWith('/') ? url : url + '/';
|
|
7664
7663
|
}
|
|
7665
7664
|
|
|
7665
|
+
function parseDateString(str) {
|
|
7666
|
+
if (str.startsWith('T')) {
|
|
7667
|
+
// If a time string,
|
|
7668
|
+
// then normalize to full length.
|
|
7669
|
+
return str + 'T00:00:00.000Z'.substring(str.length);
|
|
7670
|
+
}
|
|
7671
|
+
if (str.length <= 10) {
|
|
7672
|
+
// If a local date (i.e., "2021-01-01"),
|
|
7673
|
+
// then return as-is.
|
|
7674
|
+
return str;
|
|
7675
|
+
}
|
|
7676
|
+
try {
|
|
7677
|
+
// Try to normalize to UTC
|
|
7678
|
+
return new Date(str).toISOString();
|
|
7679
|
+
}
|
|
7680
|
+
catch (e) {
|
|
7681
|
+
// Fallback to original input
|
|
7682
|
+
// This happens on unsupported time formats such as "2021-01-01T12"
|
|
7683
|
+
return str;
|
|
7684
|
+
}
|
|
7685
|
+
}
|
|
7686
|
+
|
|
7666
7687
|
/**
|
|
7667
7688
|
* Returns a single element array with a typed boolean value.
|
|
7668
7689
|
* @param value The primitive boolean value.
|
|
@@ -7771,7 +7792,7 @@
|
|
|
7771
7792
|
}
|
|
7772
7793
|
}
|
|
7773
7794
|
}
|
|
7774
|
-
if (resultValue
|
|
7795
|
+
if (isEmpty(resultValue)) {
|
|
7775
7796
|
return undefined;
|
|
7776
7797
|
}
|
|
7777
7798
|
if (resultType === 'BackboneElement') {
|
|
@@ -7816,7 +7837,7 @@
|
|
|
7816
7837
|
}
|
|
7817
7838
|
}
|
|
7818
7839
|
}
|
|
7819
|
-
if (result
|
|
7840
|
+
if (isEmpty(result)) {
|
|
7820
7841
|
return undefined;
|
|
7821
7842
|
}
|
|
7822
7843
|
if (Array.isArray(result)) {
|
|
@@ -8007,7 +8028,6 @@
|
|
|
8007
8028
|
}
|
|
8008
8029
|
/**
|
|
8009
8030
|
* Resource equality.
|
|
8010
|
-
* Ignores meta.versionId and meta.lastUpdated.
|
|
8011
8031
|
* See: https://dmitripavlutin.com/how-to-compare-objects-in-javascript/#4-deep-equality
|
|
8012
8032
|
* @param object1 The first object.
|
|
8013
8033
|
* @param object2 The second object.
|
|
@@ -8035,484 +8055,139 @@
|
|
|
8035
8055
|
}
|
|
8036
8056
|
return true;
|
|
8037
8057
|
}
|
|
8038
|
-
function isObject(
|
|
8039
|
-
return
|
|
8058
|
+
function isObject(obj) {
|
|
8059
|
+
return obj !== null && typeof obj === 'object';
|
|
8040
8060
|
}
|
|
8041
8061
|
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8062
|
+
/**
|
|
8063
|
+
* Temporary placholder for unimplemented methods.
|
|
8064
|
+
*/
|
|
8065
|
+
const stub = () => [];
|
|
8066
|
+
const functions = {
|
|
8067
|
+
/*
|
|
8068
|
+
* 5.1 Existence
|
|
8069
|
+
* See: https://hl7.org/fhirpath/#existence
|
|
8070
|
+
*/
|
|
8071
|
+
/**
|
|
8072
|
+
* Returns true if the input collection is empty ({ }) and false otherwise.
|
|
8073
|
+
*
|
|
8074
|
+
* See: https://hl7.org/fhirpath/#empty-boolean
|
|
8075
|
+
*
|
|
8076
|
+
* @param input The input collection.
|
|
8077
|
+
* @returns True if the input collection is empty ({ }) and false otherwise.
|
|
8078
|
+
*/
|
|
8079
|
+
empty: (input) => {
|
|
8080
|
+
return booleanToTypedValue(input.length === 0);
|
|
8081
|
+
},
|
|
8082
|
+
/**
|
|
8083
|
+
* Returns true if the collection has unknown elements, and false otherwise.
|
|
8084
|
+
* This is the opposite of empty(), and as such is a shorthand for empty().not().
|
|
8085
|
+
* If the input collection is empty ({ }), the result is false.
|
|
8086
|
+
*
|
|
8087
|
+
* The function can also take an optional criteria to be applied to the collection
|
|
8088
|
+
* prior to the determination of the exists. In this case, the function is shorthand
|
|
8089
|
+
* for where(criteria).exists().
|
|
8090
|
+
*
|
|
8091
|
+
* See: https://hl7.org/fhirpath/#existscriteria-expression-boolean
|
|
8092
|
+
*
|
|
8093
|
+
* @param input
|
|
8094
|
+
* @param criteria
|
|
8095
|
+
* @returns True if the collection has unknown elements, and false otherwise.
|
|
8096
|
+
*/
|
|
8097
|
+
exists: (input, criteria) => {
|
|
8098
|
+
if (criteria) {
|
|
8099
|
+
return booleanToTypedValue(input.filter((e) => toJsBoolean(criteria.eval([e]))).length > 0);
|
|
8059
8100
|
}
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
class LiteralAtom {
|
|
8063
|
-
constructor(value) {
|
|
8064
|
-
this.value = value;
|
|
8065
|
-
}
|
|
8066
|
-
eval() {
|
|
8067
|
-
return [this.value];
|
|
8068
|
-
}
|
|
8069
|
-
}
|
|
8070
|
-
class SymbolAtom {
|
|
8071
|
-
constructor(name) {
|
|
8072
|
-
this.name = name;
|
|
8073
|
-
_SymbolAtom_instances.add(this);
|
|
8074
|
-
}
|
|
8075
|
-
eval(context) {
|
|
8076
|
-
if (this.name === '$this') {
|
|
8077
|
-
return context;
|
|
8101
|
+
else {
|
|
8102
|
+
return booleanToTypedValue(input.length > 0);
|
|
8078
8103
|
}
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
this.left = left;
|
|
8112
|
-
this.right = right;
|
|
8113
|
-
}
|
|
8114
|
-
eval(context) {
|
|
8115
|
-
return this.left.eval(context);
|
|
8116
|
-
}
|
|
8117
|
-
}
|
|
8118
|
-
class ArithemticOperatorAtom {
|
|
8119
|
-
constructor(left, right, impl) {
|
|
8120
|
-
this.left = left;
|
|
8121
|
-
this.right = right;
|
|
8122
|
-
this.impl = impl;
|
|
8123
|
-
}
|
|
8124
|
-
eval(context) {
|
|
8125
|
-
const leftEvalResult = this.left.eval(context);
|
|
8126
|
-
if (leftEvalResult.length !== 1) {
|
|
8127
|
-
return [];
|
|
8104
|
+
},
|
|
8105
|
+
/**
|
|
8106
|
+
* Returns true if for every element in the input collection, criteria evaluates to true.
|
|
8107
|
+
* Otherwise, the result is false.
|
|
8108
|
+
*
|
|
8109
|
+
* If the input collection is empty ({ }), the result is true.
|
|
8110
|
+
*
|
|
8111
|
+
* See: https://hl7.org/fhirpath/#allcriteria-expression-boolean
|
|
8112
|
+
*
|
|
8113
|
+
* @param input The input collection.
|
|
8114
|
+
* @param criteria The evaluation criteria.
|
|
8115
|
+
* @returns True if for every element in the input collection, criteria evaluates to true.
|
|
8116
|
+
*/
|
|
8117
|
+
all: (input, criteria) => {
|
|
8118
|
+
return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval([e]))));
|
|
8119
|
+
},
|
|
8120
|
+
/**
|
|
8121
|
+
* Takes a collection of Boolean values and returns true if all the items are true.
|
|
8122
|
+
* If unknown items are false, the result is false.
|
|
8123
|
+
* If the input is empty ({ }), the result is true.
|
|
8124
|
+
*
|
|
8125
|
+
* See: https://hl7.org/fhirpath/#alltrue-boolean
|
|
8126
|
+
*
|
|
8127
|
+
* @param input The input collection.
|
|
8128
|
+
* @param criteria The evaluation criteria.
|
|
8129
|
+
* @returns True if all the items are true.
|
|
8130
|
+
*/
|
|
8131
|
+
allTrue: (input) => {
|
|
8132
|
+
for (const value of input) {
|
|
8133
|
+
if (!value.value) {
|
|
8134
|
+
return booleanToTypedValue(false);
|
|
8135
|
+
}
|
|
8128
8136
|
}
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8137
|
+
return booleanToTypedValue(true);
|
|
8138
|
+
},
|
|
8139
|
+
/**
|
|
8140
|
+
* Takes a collection of Boolean values and returns true if unknown of the items are true.
|
|
8141
|
+
* If all the items are false, or if the input is empty ({ }), the result is false.
|
|
8142
|
+
*
|
|
8143
|
+
* See: https://hl7.org/fhirpath/#anytrue-boolean
|
|
8144
|
+
*
|
|
8145
|
+
* @param input The input collection.
|
|
8146
|
+
* @param criteria The evaluation criteria.
|
|
8147
|
+
* @returns True if unknown of the items are true.
|
|
8148
|
+
*/
|
|
8149
|
+
anyTrue: (input) => {
|
|
8150
|
+
for (const value of input) {
|
|
8151
|
+
if (value.value) {
|
|
8152
|
+
return booleanToTypedValue(true);
|
|
8153
|
+
}
|
|
8132
8154
|
}
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8155
|
+
return booleanToTypedValue(false);
|
|
8156
|
+
},
|
|
8157
|
+
/**
|
|
8158
|
+
* Takes a collection of Boolean values and returns true if all the items are false.
|
|
8159
|
+
* If unknown items are true, the result is false.
|
|
8160
|
+
* If the input is empty ({ }), the result is true.
|
|
8161
|
+
*
|
|
8162
|
+
* See: https://hl7.org/fhirpath/#allfalse-boolean
|
|
8163
|
+
*
|
|
8164
|
+
* @param input The input collection.
|
|
8165
|
+
* @param criteria The evaluation criteria.
|
|
8166
|
+
* @returns True if all the items are false.
|
|
8167
|
+
*/
|
|
8168
|
+
allFalse: (input) => {
|
|
8169
|
+
for (const value of input) {
|
|
8170
|
+
if (value.value) {
|
|
8171
|
+
return booleanToTypedValue(false);
|
|
8172
|
+
}
|
|
8140
8173
|
}
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
if (result.length > 0 && result.every((e) => typeof e.value === 'string')) {
|
|
8159
|
-
return [{ type: exports.PropertyType.string, value: result.map((e) => e.value).join('') }];
|
|
8160
|
-
}
|
|
8161
|
-
return result;
|
|
8162
|
-
}
|
|
8163
|
-
}
|
|
8164
|
-
class ContainsAtom {
|
|
8165
|
-
constructor(left, right) {
|
|
8166
|
-
this.left = left;
|
|
8167
|
-
this.right = right;
|
|
8168
|
-
}
|
|
8169
|
-
eval(context) {
|
|
8170
|
-
const leftValue = this.left.eval(context);
|
|
8171
|
-
const rightValue = this.right.eval(context);
|
|
8172
|
-
return booleanToTypedValue(leftValue.some((e) => e.value === rightValue[0].value));
|
|
8173
|
-
}
|
|
8174
|
-
}
|
|
8175
|
-
class InAtom {
|
|
8176
|
-
constructor(left, right) {
|
|
8177
|
-
this.left = left;
|
|
8178
|
-
this.right = right;
|
|
8179
|
-
}
|
|
8180
|
-
eval(context) {
|
|
8181
|
-
const leftValue = this.left.eval(context);
|
|
8182
|
-
const rightValue = this.right.eval(context);
|
|
8183
|
-
return booleanToTypedValue(rightValue.some((e) => e.value === leftValue[0].value));
|
|
8184
|
-
}
|
|
8185
|
-
}
|
|
8186
|
-
class DotAtom {
|
|
8187
|
-
constructor(left, right) {
|
|
8188
|
-
this.left = left;
|
|
8189
|
-
this.right = right;
|
|
8190
|
-
}
|
|
8191
|
-
eval(context) {
|
|
8192
|
-
return this.right.eval(this.left.eval(context));
|
|
8193
|
-
}
|
|
8194
|
-
}
|
|
8195
|
-
class UnionAtom {
|
|
8196
|
-
constructor(left, right) {
|
|
8197
|
-
this.left = left;
|
|
8198
|
-
this.right = right;
|
|
8199
|
-
}
|
|
8200
|
-
eval(context) {
|
|
8201
|
-
const leftResult = this.left.eval(context);
|
|
8202
|
-
const rightResult = this.right.eval(context);
|
|
8203
|
-
return removeDuplicates([...leftResult, ...rightResult]);
|
|
8204
|
-
}
|
|
8205
|
-
}
|
|
8206
|
-
class EqualsAtom {
|
|
8207
|
-
constructor(left, right) {
|
|
8208
|
-
this.left = left;
|
|
8209
|
-
this.right = right;
|
|
8210
|
-
}
|
|
8211
|
-
eval(context) {
|
|
8212
|
-
const leftValue = this.left.eval(context);
|
|
8213
|
-
const rightValue = this.right.eval(context);
|
|
8214
|
-
return fhirPathArrayEquals(leftValue, rightValue);
|
|
8215
|
-
}
|
|
8216
|
-
}
|
|
8217
|
-
class NotEqualsAtom {
|
|
8218
|
-
constructor(left, right) {
|
|
8219
|
-
this.left = left;
|
|
8220
|
-
this.right = right;
|
|
8221
|
-
}
|
|
8222
|
-
eval(context) {
|
|
8223
|
-
const leftValue = this.left.eval(context);
|
|
8224
|
-
const rightValue = this.right.eval(context);
|
|
8225
|
-
return fhirPathNot(fhirPathArrayEquals(leftValue, rightValue));
|
|
8226
|
-
}
|
|
8227
|
-
}
|
|
8228
|
-
class EquivalentAtom {
|
|
8229
|
-
constructor(left, right) {
|
|
8230
|
-
this.left = left;
|
|
8231
|
-
this.right = right;
|
|
8232
|
-
}
|
|
8233
|
-
eval(context) {
|
|
8234
|
-
const leftValue = this.left.eval(context);
|
|
8235
|
-
const rightValue = this.right.eval(context);
|
|
8236
|
-
return fhirPathArrayEquivalent(leftValue, rightValue);
|
|
8237
|
-
}
|
|
8238
|
-
}
|
|
8239
|
-
class NotEquivalentAtom {
|
|
8240
|
-
constructor(left, right) {
|
|
8241
|
-
this.left = left;
|
|
8242
|
-
this.right = right;
|
|
8243
|
-
}
|
|
8244
|
-
eval(context) {
|
|
8245
|
-
const leftValue = this.left.eval(context);
|
|
8246
|
-
const rightValue = this.right.eval(context);
|
|
8247
|
-
return fhirPathNot(fhirPathArrayEquivalent(leftValue, rightValue));
|
|
8248
|
-
}
|
|
8249
|
-
}
|
|
8250
|
-
class IsAtom {
|
|
8251
|
-
constructor(left, right) {
|
|
8252
|
-
this.left = left;
|
|
8253
|
-
this.right = right;
|
|
8254
|
-
}
|
|
8255
|
-
eval(context) {
|
|
8256
|
-
const leftValue = this.left.eval(context);
|
|
8257
|
-
if (leftValue.length !== 1) {
|
|
8258
|
-
return [];
|
|
8259
|
-
}
|
|
8260
|
-
const typeName = this.right.name;
|
|
8261
|
-
return booleanToTypedValue(fhirPathIs(leftValue[0], typeName));
|
|
8262
|
-
}
|
|
8263
|
-
}
|
|
8264
|
-
/**
|
|
8265
|
-
* 6.5.1. and
|
|
8266
|
-
* Returns true if both operands evaluate to true,
|
|
8267
|
-
* false if either operand evaluates to false,
|
|
8268
|
-
* and the empty collection otherwise.
|
|
8269
|
-
*/
|
|
8270
|
-
class AndAtom {
|
|
8271
|
-
constructor(left, right) {
|
|
8272
|
-
this.left = left;
|
|
8273
|
-
this.right = right;
|
|
8274
|
-
}
|
|
8275
|
-
eval(context) {
|
|
8276
|
-
var _a, _b, _c, _d;
|
|
8277
|
-
const leftValue = this.left.eval(context);
|
|
8278
|
-
const rightValue = this.right.eval(context);
|
|
8279
|
-
if (((_a = leftValue[0]) === null || _a === void 0 ? void 0 : _a.value) === true && ((_b = rightValue[0]) === null || _b === void 0 ? void 0 : _b.value) === true) {
|
|
8280
|
-
return booleanToTypedValue(true);
|
|
8281
|
-
}
|
|
8282
|
-
if (((_c = leftValue[0]) === null || _c === void 0 ? void 0 : _c.value) === false || ((_d = rightValue[0]) === null || _d === void 0 ? void 0 : _d.value) === false) {
|
|
8283
|
-
return booleanToTypedValue(false);
|
|
8284
|
-
}
|
|
8285
|
-
return [];
|
|
8286
|
-
}
|
|
8287
|
-
}
|
|
8288
|
-
class OrAtom {
|
|
8289
|
-
constructor(left, right) {
|
|
8290
|
-
this.left = left;
|
|
8291
|
-
this.right = right;
|
|
8292
|
-
}
|
|
8293
|
-
eval(context) {
|
|
8294
|
-
const leftValue = this.left.eval(context);
|
|
8295
|
-
if (toJsBoolean(leftValue)) {
|
|
8296
|
-
return leftValue;
|
|
8297
|
-
}
|
|
8298
|
-
const rightValue = this.right.eval(context);
|
|
8299
|
-
if (toJsBoolean(rightValue)) {
|
|
8300
|
-
return rightValue;
|
|
8301
|
-
}
|
|
8302
|
-
return [];
|
|
8303
|
-
}
|
|
8304
|
-
}
|
|
8305
|
-
/**
|
|
8306
|
-
* 6.5.4. xor
|
|
8307
|
-
* Returns true if exactly one of the operands evaluates to true,
|
|
8308
|
-
* false if either both operands evaluate to true or both operands evaluate to false,
|
|
8309
|
-
* and the empty collection otherwise.
|
|
8310
|
-
*/
|
|
8311
|
-
class XorAtom {
|
|
8312
|
-
constructor(left, right) {
|
|
8313
|
-
this.left = left;
|
|
8314
|
-
this.right = right;
|
|
8315
|
-
}
|
|
8316
|
-
eval(context) {
|
|
8317
|
-
const leftResult = this.left.eval(context);
|
|
8318
|
-
const rightResult = this.right.eval(context);
|
|
8319
|
-
if (leftResult.length === 0 && rightResult.length === 0) {
|
|
8320
|
-
return [];
|
|
8321
|
-
}
|
|
8322
|
-
const leftValue = leftResult.length === 0 ? null : leftResult[0].value;
|
|
8323
|
-
const rightValue = rightResult.length === 0 ? null : rightResult[0].value;
|
|
8324
|
-
if ((leftValue === true && rightValue !== true) || (leftValue !== true && rightValue === true)) {
|
|
8325
|
-
return booleanToTypedValue(true);
|
|
8326
|
-
}
|
|
8327
|
-
if ((leftValue === true && rightValue === true) || (leftValue === false && rightValue === false)) {
|
|
8328
|
-
return booleanToTypedValue(false);
|
|
8329
|
-
}
|
|
8330
|
-
return [];
|
|
8331
|
-
}
|
|
8332
|
-
}
|
|
8333
|
-
class FunctionAtom {
|
|
8334
|
-
constructor(name, args, impl) {
|
|
8335
|
-
this.name = name;
|
|
8336
|
-
this.args = args;
|
|
8337
|
-
this.impl = impl;
|
|
8338
|
-
}
|
|
8339
|
-
eval(context) {
|
|
8340
|
-
return this.impl(context, ...this.args);
|
|
8341
|
-
}
|
|
8342
|
-
}
|
|
8343
|
-
class IndexerAtom {
|
|
8344
|
-
constructor(left, expr) {
|
|
8345
|
-
this.left = left;
|
|
8346
|
-
this.expr = expr;
|
|
8347
|
-
}
|
|
8348
|
-
eval(context) {
|
|
8349
|
-
const evalResult = this.expr.eval(context);
|
|
8350
|
-
if (evalResult.length !== 1) {
|
|
8351
|
-
return [];
|
|
8352
|
-
}
|
|
8353
|
-
const index = evalResult[0].value;
|
|
8354
|
-
if (typeof index !== 'number') {
|
|
8355
|
-
throw new Error(`Invalid indexer expression: should return integer}`);
|
|
8356
|
-
}
|
|
8357
|
-
const leftResult = this.left.eval(context);
|
|
8358
|
-
if (!(index in leftResult)) {
|
|
8359
|
-
return [];
|
|
8360
|
-
}
|
|
8361
|
-
return [leftResult[index]];
|
|
8362
|
-
}
|
|
8363
|
-
}
|
|
8364
|
-
|
|
8365
|
-
function parseDateString(str) {
|
|
8366
|
-
if (str.startsWith('T')) {
|
|
8367
|
-
// If a time string,
|
|
8368
|
-
// then normalize to full length.
|
|
8369
|
-
return str + 'T00:00:00.000Z'.substring(str.length);
|
|
8370
|
-
}
|
|
8371
|
-
if (str.length <= 10) {
|
|
8372
|
-
// If a local date (i.e., "2021-01-01"),
|
|
8373
|
-
// then return as-is.
|
|
8374
|
-
return str;
|
|
8375
|
-
}
|
|
8376
|
-
try {
|
|
8377
|
-
// Try to normalize to UTC
|
|
8378
|
-
return new Date(str).toISOString();
|
|
8379
|
-
}
|
|
8380
|
-
catch (e) {
|
|
8381
|
-
// Fallback to original input
|
|
8382
|
-
// This happens on unsupported time formats such as "2021-01-01T12"
|
|
8383
|
-
return str;
|
|
8384
|
-
}
|
|
8385
|
-
}
|
|
8386
|
-
|
|
8387
|
-
/**
|
|
8388
|
-
* Temporary placholder for unimplemented methods.
|
|
8389
|
-
*/
|
|
8390
|
-
const stub = () => [];
|
|
8391
|
-
const functions = {
|
|
8392
|
-
/*
|
|
8393
|
-
* 5.1 Existence
|
|
8394
|
-
* See: https://hl7.org/fhirpath/#existence
|
|
8395
|
-
*/
|
|
8396
|
-
/**
|
|
8397
|
-
* Returns true if the input collection is empty ({ }) and false otherwise.
|
|
8398
|
-
*
|
|
8399
|
-
* See: https://hl7.org/fhirpath/#empty-boolean
|
|
8400
|
-
*
|
|
8401
|
-
* @param input The input collection.
|
|
8402
|
-
* @returns True if the input collection is empty ({ }) and false otherwise.
|
|
8403
|
-
*/
|
|
8404
|
-
empty: (input) => {
|
|
8405
|
-
return booleanToTypedValue(input.length === 0);
|
|
8406
|
-
},
|
|
8407
|
-
/**
|
|
8408
|
-
* Returns true if the collection has unknown elements, and false otherwise.
|
|
8409
|
-
* This is the opposite of empty(), and as such is a shorthand for empty().not().
|
|
8410
|
-
* If the input collection is empty ({ }), the result is false.
|
|
8411
|
-
*
|
|
8412
|
-
* The function can also take an optional criteria to be applied to the collection
|
|
8413
|
-
* prior to the determination of the exists. In this case, the function is shorthand
|
|
8414
|
-
* for where(criteria).exists().
|
|
8415
|
-
*
|
|
8416
|
-
* See: https://hl7.org/fhirpath/#existscriteria-expression-boolean
|
|
8417
|
-
*
|
|
8418
|
-
* @param input
|
|
8419
|
-
* @param criteria
|
|
8420
|
-
* @returns True if the collection has unknown elements, and false otherwise.
|
|
8421
|
-
*/
|
|
8422
|
-
exists: (input, criteria) => {
|
|
8423
|
-
if (criteria) {
|
|
8424
|
-
return booleanToTypedValue(input.filter((e) => toJsBoolean(criteria.eval([e]))).length > 0);
|
|
8425
|
-
}
|
|
8426
|
-
else {
|
|
8427
|
-
return booleanToTypedValue(input.length > 0);
|
|
8428
|
-
}
|
|
8429
|
-
},
|
|
8430
|
-
/**
|
|
8431
|
-
* Returns true if for every element in the input collection, criteria evaluates to true.
|
|
8432
|
-
* Otherwise, the result is false.
|
|
8433
|
-
*
|
|
8434
|
-
* If the input collection is empty ({ }), the result is true.
|
|
8435
|
-
*
|
|
8436
|
-
* See: https://hl7.org/fhirpath/#allcriteria-expression-boolean
|
|
8437
|
-
*
|
|
8438
|
-
* @param input The input collection.
|
|
8439
|
-
* @param criteria The evaluation criteria.
|
|
8440
|
-
* @returns True if for every element in the input collection, criteria evaluates to true.
|
|
8441
|
-
*/
|
|
8442
|
-
all: (input, criteria) => {
|
|
8443
|
-
return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval([e]))));
|
|
8444
|
-
},
|
|
8445
|
-
/**
|
|
8446
|
-
* Takes a collection of Boolean values and returns true if all the items are true.
|
|
8447
|
-
* If unknown items are false, the result is false.
|
|
8448
|
-
* If the input is empty ({ }), the result is true.
|
|
8449
|
-
*
|
|
8450
|
-
* See: https://hl7.org/fhirpath/#alltrue-boolean
|
|
8451
|
-
*
|
|
8452
|
-
* @param input The input collection.
|
|
8453
|
-
* @param criteria The evaluation criteria.
|
|
8454
|
-
* @returns True if all the items are true.
|
|
8455
|
-
*/
|
|
8456
|
-
allTrue: (input) => {
|
|
8457
|
-
for (const value of input) {
|
|
8458
|
-
if (!value.value) {
|
|
8459
|
-
return booleanToTypedValue(false);
|
|
8460
|
-
}
|
|
8461
|
-
}
|
|
8462
|
-
return booleanToTypedValue(true);
|
|
8463
|
-
},
|
|
8464
|
-
/**
|
|
8465
|
-
* Takes a collection of Boolean values and returns true if unknown of the items are true.
|
|
8466
|
-
* If all the items are false, or if the input is empty ({ }), the result is false.
|
|
8467
|
-
*
|
|
8468
|
-
* See: https://hl7.org/fhirpath/#anytrue-boolean
|
|
8469
|
-
*
|
|
8470
|
-
* @param input The input collection.
|
|
8471
|
-
* @param criteria The evaluation criteria.
|
|
8472
|
-
* @returns True if unknown of the items are true.
|
|
8473
|
-
*/
|
|
8474
|
-
anyTrue: (input) => {
|
|
8475
|
-
for (const value of input) {
|
|
8476
|
-
if (value.value) {
|
|
8477
|
-
return booleanToTypedValue(true);
|
|
8478
|
-
}
|
|
8479
|
-
}
|
|
8480
|
-
return booleanToTypedValue(false);
|
|
8481
|
-
},
|
|
8482
|
-
/**
|
|
8483
|
-
* Takes a collection of Boolean values and returns true if all the items are false.
|
|
8484
|
-
* If unknown items are true, the result is false.
|
|
8485
|
-
* If the input is empty ({ }), the result is true.
|
|
8486
|
-
*
|
|
8487
|
-
* See: https://hl7.org/fhirpath/#allfalse-boolean
|
|
8488
|
-
*
|
|
8489
|
-
* @param input The input collection.
|
|
8490
|
-
* @param criteria The evaluation criteria.
|
|
8491
|
-
* @returns True if all the items are false.
|
|
8492
|
-
*/
|
|
8493
|
-
allFalse: (input) => {
|
|
8494
|
-
for (const value of input) {
|
|
8495
|
-
if (value.value) {
|
|
8496
|
-
return booleanToTypedValue(false);
|
|
8497
|
-
}
|
|
8498
|
-
}
|
|
8499
|
-
return booleanToTypedValue(true);
|
|
8500
|
-
},
|
|
8501
|
-
/**
|
|
8502
|
-
* Takes a collection of Boolean values and returns true if unknown of the items are false.
|
|
8503
|
-
* If all the items are true, or if the input is empty ({ }), the result is false.
|
|
8504
|
-
*
|
|
8505
|
-
* See: https://hl7.org/fhirpath/#anyfalse-boolean
|
|
8506
|
-
*
|
|
8507
|
-
* @param input The input collection.
|
|
8508
|
-
* @param criteria The evaluation criteria.
|
|
8509
|
-
* @returns True if for every element in the input collection, criteria evaluates to true.
|
|
8510
|
-
*/
|
|
8511
|
-
anyFalse: (input) => {
|
|
8512
|
-
for (const value of input) {
|
|
8513
|
-
if (!value.value) {
|
|
8514
|
-
return booleanToTypedValue(true);
|
|
8515
|
-
}
|
|
8174
|
+
return booleanToTypedValue(true);
|
|
8175
|
+
},
|
|
8176
|
+
/**
|
|
8177
|
+
* Takes a collection of Boolean values and returns true if unknown of the items are false.
|
|
8178
|
+
* If all the items are true, or if the input is empty ({ }), the result is false.
|
|
8179
|
+
*
|
|
8180
|
+
* See: https://hl7.org/fhirpath/#anyfalse-boolean
|
|
8181
|
+
*
|
|
8182
|
+
* @param input The input collection.
|
|
8183
|
+
* @param criteria The evaluation criteria.
|
|
8184
|
+
* @returns True if for every element in the input collection, criteria evaluates to true.
|
|
8185
|
+
*/
|
|
8186
|
+
anyFalse: (input) => {
|
|
8187
|
+
for (const value of input) {
|
|
8188
|
+
if (!value.value) {
|
|
8189
|
+
return booleanToTypedValue(true);
|
|
8190
|
+
}
|
|
8516
8191
|
}
|
|
8517
8192
|
return booleanToTypedValue(false);
|
|
8518
8193
|
},
|
|
@@ -8643,7 +8318,9 @@
|
|
|
8643
8318
|
*
|
|
8644
8319
|
* See: http://hl7.org/fhirpath/#oftypetype-type-specifier-collection
|
|
8645
8320
|
*/
|
|
8646
|
-
ofType:
|
|
8321
|
+
ofType: (input, criteria) => {
|
|
8322
|
+
return input.filter((e) => e.type === criteria.name);
|
|
8323
|
+
},
|
|
8647
8324
|
/*
|
|
8648
8325
|
* 5.3 Subsetting
|
|
8649
8326
|
*/
|
|
@@ -9688,195 +9365,518 @@
|
|
|
9688
9365
|
if (startDate.length === 0) {
|
|
9689
9366
|
throw new Error('Invalid start date');
|
|
9690
9367
|
}
|
|
9691
|
-
const endDate = functions.toDateTime(endAtom.eval(input));
|
|
9692
|
-
if (endDate.length === 0) {
|
|
9693
|
-
throw new Error('Invalid end date');
|
|
9368
|
+
const endDate = functions.toDateTime(endAtom.eval(input));
|
|
9369
|
+
if (endDate.length === 0) {
|
|
9370
|
+
throw new Error('Invalid end date');
|
|
9371
|
+
}
|
|
9372
|
+
const unit = (_a = unitsAtom.eval(input)[0]) === null || _a === void 0 ? void 0 : _a.value;
|
|
9373
|
+
if (unit !== 'years' && unit !== 'months' && unit !== 'days') {
|
|
9374
|
+
throw new Error('Invalid units');
|
|
9375
|
+
}
|
|
9376
|
+
const age = calculateAge(startDate[0].value, endDate[0].value);
|
|
9377
|
+
return [{ type: exports.PropertyType.Quantity, value: { value: age[unit], unit } }];
|
|
9378
|
+
},
|
|
9379
|
+
/*
|
|
9380
|
+
* 6.3 Types
|
|
9381
|
+
*/
|
|
9382
|
+
/**
|
|
9383
|
+
* The is() function is supported for backwards compatibility with previous
|
|
9384
|
+
* implementations of FHIRPath. Just as with the is keyword, the type argument
|
|
9385
|
+
* is an identifier that must resolve to the name of a type in a model.
|
|
9386
|
+
*
|
|
9387
|
+
* For implementations with compile-time typing, this requires special-case
|
|
9388
|
+
* handling when processing the argument to treat it as a type specifier rather
|
|
9389
|
+
* than an identifier expression:
|
|
9390
|
+
*
|
|
9391
|
+
* @param input
|
|
9392
|
+
* @param typeAtom
|
|
9393
|
+
* @returns
|
|
9394
|
+
*/
|
|
9395
|
+
is: (input, typeAtom) => {
|
|
9396
|
+
let typeName = '';
|
|
9397
|
+
if (typeAtom instanceof SymbolAtom) {
|
|
9398
|
+
typeName = typeAtom.name;
|
|
9399
|
+
}
|
|
9400
|
+
else if (typeAtom instanceof DotAtom) {
|
|
9401
|
+
typeName = typeAtom.left.name + '.' + typeAtom.right.name;
|
|
9402
|
+
}
|
|
9403
|
+
if (!typeName) {
|
|
9404
|
+
return [];
|
|
9405
|
+
}
|
|
9406
|
+
return input.map((value) => ({ type: exports.PropertyType.boolean, value: fhirPathIs(value, typeName) }));
|
|
9407
|
+
},
|
|
9408
|
+
/*
|
|
9409
|
+
* 6.5 Boolean logic
|
|
9410
|
+
*/
|
|
9411
|
+
/**
|
|
9412
|
+
* 6.5.3. not() : Boolean
|
|
9413
|
+
*
|
|
9414
|
+
* Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):
|
|
9415
|
+
*
|
|
9416
|
+
* @param input
|
|
9417
|
+
* @returns
|
|
9418
|
+
*/
|
|
9419
|
+
not: (input) => {
|
|
9420
|
+
return functions.toBoolean(input).map((value) => ({ type: exports.PropertyType.boolean, value: !value.value }));
|
|
9421
|
+
},
|
|
9422
|
+
/*
|
|
9423
|
+
* Additional functions
|
|
9424
|
+
* See: https://hl7.org/fhir/fhirpath.html#functions
|
|
9425
|
+
*/
|
|
9426
|
+
/**
|
|
9427
|
+
* For each item in the collection, if it is a string that is a uri (or canonical or url), locate the target of the reference, and add it to the resulting collection. If the item does not resolve to a resource, the item is ignored and nothing is added to the output collection.
|
|
9428
|
+
* The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.
|
|
9429
|
+
* @param input The input collection.
|
|
9430
|
+
* @returns
|
|
9431
|
+
*/
|
|
9432
|
+
resolve: (input) => {
|
|
9433
|
+
return input
|
|
9434
|
+
.map((e) => {
|
|
9435
|
+
const value = e.value;
|
|
9436
|
+
let refStr;
|
|
9437
|
+
if (typeof value === 'string') {
|
|
9438
|
+
refStr = value;
|
|
9439
|
+
}
|
|
9440
|
+
else if (typeof value === 'object') {
|
|
9441
|
+
const ref = value;
|
|
9442
|
+
if (ref.resource) {
|
|
9443
|
+
return toTypedValue(ref.resource);
|
|
9444
|
+
}
|
|
9445
|
+
refStr = ref.reference;
|
|
9446
|
+
}
|
|
9447
|
+
if (!refStr) {
|
|
9448
|
+
return { type: exports.PropertyType.BackboneElement, value: null };
|
|
9449
|
+
}
|
|
9450
|
+
const [resourceType, id] = refStr.split('/');
|
|
9451
|
+
return { type: exports.PropertyType.BackboneElement, value: { resourceType, id } };
|
|
9452
|
+
})
|
|
9453
|
+
.filter((e) => !!e.value);
|
|
9454
|
+
},
|
|
9455
|
+
/**
|
|
9456
|
+
* The as operator can be used to treat a value as a specific type.
|
|
9457
|
+
* @param input The input value.
|
|
9458
|
+
* @returns The value as the specific type.
|
|
9459
|
+
*/
|
|
9460
|
+
as: (input) => {
|
|
9461
|
+
return input;
|
|
9462
|
+
},
|
|
9463
|
+
/*
|
|
9464
|
+
* 12. Formal Specifications
|
|
9465
|
+
*/
|
|
9466
|
+
/**
|
|
9467
|
+
* Returns the type of the input.
|
|
9468
|
+
*
|
|
9469
|
+
* 12.2. Model Information
|
|
9470
|
+
*
|
|
9471
|
+
* The model information returned by the reflection function type() is specified as an
|
|
9472
|
+
* XML Schema document (xsd) and included in this specification at the following link:
|
|
9473
|
+
* https://hl7.org/fhirpath/modelinfo.xsd
|
|
9474
|
+
*
|
|
9475
|
+
* See: https://hl7.org/fhirpath/#model-information
|
|
9476
|
+
*
|
|
9477
|
+
* @param input The input collection.
|
|
9478
|
+
* @returns
|
|
9479
|
+
*/
|
|
9480
|
+
type: (input) => {
|
|
9481
|
+
return input.map(({ value }) => {
|
|
9482
|
+
if (typeof value === 'boolean') {
|
|
9483
|
+
return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Boolean' } };
|
|
9484
|
+
}
|
|
9485
|
+
if (typeof value === 'number') {
|
|
9486
|
+
return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Integer' } };
|
|
9487
|
+
}
|
|
9488
|
+
if (value && typeof value === 'object' && 'resourceType' in value) {
|
|
9489
|
+
return {
|
|
9490
|
+
type: exports.PropertyType.BackboneElement,
|
|
9491
|
+
value: { namespace: 'FHIR', name: value.resourceType },
|
|
9492
|
+
};
|
|
9493
|
+
}
|
|
9494
|
+
return { type: exports.PropertyType.BackboneElement, value: null };
|
|
9495
|
+
});
|
|
9496
|
+
},
|
|
9497
|
+
conformsTo: (input, systemAtom) => {
|
|
9498
|
+
const system = systemAtom.eval(input)[0].value;
|
|
9499
|
+
if (!system.startsWith('http://hl7.org/fhir/StructureDefinition/')) {
|
|
9500
|
+
throw new Error('Expected a StructureDefinition URL');
|
|
9501
|
+
}
|
|
9502
|
+
const expectedResourceType = system.replace('http://hl7.org/fhir/StructureDefinition/', '');
|
|
9503
|
+
return input.map((value) => {
|
|
9504
|
+
var _a;
|
|
9505
|
+
return ({
|
|
9506
|
+
type: exports.PropertyType.boolean,
|
|
9507
|
+
value: ((_a = value.value) === null || _a === void 0 ? void 0 : _a.resourceType) === expectedResourceType,
|
|
9508
|
+
});
|
|
9509
|
+
});
|
|
9510
|
+
},
|
|
9511
|
+
};
|
|
9512
|
+
/*
|
|
9513
|
+
* Helper utilities
|
|
9514
|
+
*/
|
|
9515
|
+
function applyStringFunc(func, input, ...argsAtoms) {
|
|
9516
|
+
if (input.length === 0) {
|
|
9517
|
+
return [];
|
|
9518
|
+
}
|
|
9519
|
+
const [{ value }] = validateInput(input, 1);
|
|
9520
|
+
if (typeof value !== 'string') {
|
|
9521
|
+
throw new Error('String function cannot be called with non-string');
|
|
9522
|
+
}
|
|
9523
|
+
const result = func(value, ...argsAtoms.map((atom) => { var _a, _b; return atom && ((_b = (_a = atom.eval(input)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.value); }));
|
|
9524
|
+
if (result === undefined) {
|
|
9525
|
+
return [];
|
|
9526
|
+
}
|
|
9527
|
+
if (Array.isArray(result)) {
|
|
9528
|
+
return result.map(toTypedValue);
|
|
9529
|
+
}
|
|
9530
|
+
return [toTypedValue(result)];
|
|
9531
|
+
}
|
|
9532
|
+
function applyMathFunc(func, input, ...argsAtoms) {
|
|
9533
|
+
if (input.length === 0) {
|
|
9534
|
+
return [];
|
|
9535
|
+
}
|
|
9536
|
+
const [{ value }] = validateInput(input, 1);
|
|
9537
|
+
const quantity = isQuantity(value);
|
|
9538
|
+
const numberInput = quantity ? value.value : value;
|
|
9539
|
+
if (typeof numberInput !== 'number') {
|
|
9540
|
+
throw new Error('Math function cannot be called with non-number');
|
|
9541
|
+
}
|
|
9542
|
+
const result = func(numberInput, ...argsAtoms.map((atom) => { var _a, _b; return (_b = (_a = atom.eval(input)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.value; }));
|
|
9543
|
+
const type = quantity ? exports.PropertyType.Quantity : input[0].type;
|
|
9544
|
+
const returnValue = quantity ? Object.assign(Object.assign({}, value), { value: result }) : result;
|
|
9545
|
+
return [{ type, value: returnValue }];
|
|
9546
|
+
}
|
|
9547
|
+
function validateInput(input, count) {
|
|
9548
|
+
if (input.length !== count) {
|
|
9549
|
+
throw new Error(`Expected ${count} arguments`);
|
|
9550
|
+
}
|
|
9551
|
+
for (const element of input) {
|
|
9552
|
+
if (element === null || element === undefined) {
|
|
9553
|
+
throw new Error('Expected non-null argument');
|
|
9554
|
+
}
|
|
9555
|
+
}
|
|
9556
|
+
return input;
|
|
9557
|
+
}
|
|
9558
|
+
|
|
9559
|
+
var _SymbolAtom_instances, _SymbolAtom_evalValue;
|
|
9560
|
+
class FhirPathAtom {
|
|
9561
|
+
constructor(original, child) {
|
|
9562
|
+
this.original = original;
|
|
9563
|
+
this.child = child;
|
|
9564
|
+
}
|
|
9565
|
+
eval(context) {
|
|
9566
|
+
try {
|
|
9567
|
+
if (context.length > 0) {
|
|
9568
|
+
return context.map((e) => this.child.eval([e])).flat();
|
|
9569
|
+
}
|
|
9570
|
+
else {
|
|
9571
|
+
return this.child.eval([]);
|
|
9572
|
+
}
|
|
9694
9573
|
}
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9574
|
+
catch (error) {
|
|
9575
|
+
throw new Error(`FhirPathError on "${this.original}": ${error}`);
|
|
9576
|
+
}
|
|
9577
|
+
}
|
|
9578
|
+
}
|
|
9579
|
+
class LiteralAtom {
|
|
9580
|
+
constructor(value) {
|
|
9581
|
+
this.value = value;
|
|
9582
|
+
}
|
|
9583
|
+
eval() {
|
|
9584
|
+
return [this.value];
|
|
9585
|
+
}
|
|
9586
|
+
}
|
|
9587
|
+
class SymbolAtom {
|
|
9588
|
+
constructor(name) {
|
|
9589
|
+
this.name = name;
|
|
9590
|
+
_SymbolAtom_instances.add(this);
|
|
9591
|
+
}
|
|
9592
|
+
eval(context) {
|
|
9593
|
+
if (this.name === '$this') {
|
|
9594
|
+
return context;
|
|
9595
|
+
}
|
|
9596
|
+
return context
|
|
9597
|
+
.map((e) => __classPrivateFieldGet(this, _SymbolAtom_instances, "m", _SymbolAtom_evalValue).call(this, e))
|
|
9598
|
+
.flat()
|
|
9599
|
+
.filter((e) => (e === null || e === void 0 ? void 0 : e.value) !== undefined);
|
|
9600
|
+
}
|
|
9601
|
+
}
|
|
9602
|
+
_SymbolAtom_instances = new WeakSet(), _SymbolAtom_evalValue = function _SymbolAtom_evalValue(typedValue) {
|
|
9603
|
+
const input = typedValue.value;
|
|
9604
|
+
if (!input || typeof input !== 'object') {
|
|
9605
|
+
return undefined;
|
|
9606
|
+
}
|
|
9607
|
+
if ('resourceType' in input && input.resourceType === this.name) {
|
|
9608
|
+
return typedValue;
|
|
9609
|
+
}
|
|
9610
|
+
return getTypedPropertyValue(typedValue, this.name);
|
|
9611
|
+
};
|
|
9612
|
+
class EmptySetAtom {
|
|
9613
|
+
eval() {
|
|
9614
|
+
return [];
|
|
9615
|
+
}
|
|
9616
|
+
}
|
|
9617
|
+
class UnaryOperatorAtom {
|
|
9618
|
+
constructor(child, impl) {
|
|
9619
|
+
this.child = child;
|
|
9620
|
+
this.impl = impl;
|
|
9621
|
+
}
|
|
9622
|
+
eval(context) {
|
|
9623
|
+
return this.impl(this.child.eval(context));
|
|
9624
|
+
}
|
|
9625
|
+
}
|
|
9626
|
+
class AsAtom {
|
|
9627
|
+
constructor(left, right) {
|
|
9628
|
+
this.left = left;
|
|
9629
|
+
this.right = right;
|
|
9630
|
+
}
|
|
9631
|
+
eval(context) {
|
|
9632
|
+
return functions.ofType(this.left.eval(context), this.right);
|
|
9633
|
+
}
|
|
9634
|
+
}
|
|
9635
|
+
class ArithemticOperatorAtom {
|
|
9636
|
+
constructor(left, right, impl) {
|
|
9637
|
+
this.left = left;
|
|
9638
|
+
this.right = right;
|
|
9639
|
+
this.impl = impl;
|
|
9640
|
+
}
|
|
9641
|
+
eval(context) {
|
|
9642
|
+
const leftEvalResult = this.left.eval(context);
|
|
9643
|
+
if (leftEvalResult.length !== 1) {
|
|
9644
|
+
return [];
|
|
9645
|
+
}
|
|
9646
|
+
const rightEvalResult = this.right.eval(context);
|
|
9647
|
+
if (rightEvalResult.length !== 1) {
|
|
9648
|
+
return [];
|
|
9649
|
+
}
|
|
9650
|
+
const leftValue = leftEvalResult[0].value;
|
|
9651
|
+
const rightValue = rightEvalResult[0].value;
|
|
9652
|
+
const leftNumber = isQuantity(leftValue) ? leftValue.value : leftValue;
|
|
9653
|
+
const rightNumber = isQuantity(rightValue) ? rightValue.value : rightValue;
|
|
9654
|
+
const result = this.impl(leftNumber, rightNumber);
|
|
9655
|
+
if (typeof result === 'boolean') {
|
|
9656
|
+
return booleanToTypedValue(result);
|
|
9657
|
+
}
|
|
9658
|
+
else if (isQuantity(leftValue)) {
|
|
9659
|
+
return [{ type: exports.PropertyType.Quantity, value: Object.assign(Object.assign({}, leftValue), { value: result }) }];
|
|
9660
|
+
}
|
|
9661
|
+
else {
|
|
9662
|
+
return [toTypedValue(result)];
|
|
9663
|
+
}
|
|
9664
|
+
}
|
|
9665
|
+
}
|
|
9666
|
+
class ConcatAtom {
|
|
9667
|
+
constructor(left, right) {
|
|
9668
|
+
this.left = left;
|
|
9669
|
+
this.right = right;
|
|
9670
|
+
}
|
|
9671
|
+
eval(context) {
|
|
9672
|
+
const leftValue = this.left.eval(context);
|
|
9673
|
+
const rightValue = this.right.eval(context);
|
|
9674
|
+
const result = [...leftValue, ...rightValue];
|
|
9675
|
+
if (result.length > 0 && result.every((e) => typeof e.value === 'string')) {
|
|
9676
|
+
return [{ type: exports.PropertyType.string, value: result.map((e) => e.value).join('') }];
|
|
9677
|
+
}
|
|
9678
|
+
return result;
|
|
9679
|
+
}
|
|
9680
|
+
}
|
|
9681
|
+
class ContainsAtom {
|
|
9682
|
+
constructor(left, right) {
|
|
9683
|
+
this.left = left;
|
|
9684
|
+
this.right = right;
|
|
9685
|
+
}
|
|
9686
|
+
eval(context) {
|
|
9687
|
+
const leftValue = this.left.eval(context);
|
|
9688
|
+
const rightValue = this.right.eval(context);
|
|
9689
|
+
return booleanToTypedValue(leftValue.some((e) => e.value === rightValue[0].value));
|
|
9690
|
+
}
|
|
9691
|
+
}
|
|
9692
|
+
class InAtom {
|
|
9693
|
+
constructor(left, right) {
|
|
9694
|
+
this.left = left;
|
|
9695
|
+
this.right = right;
|
|
9696
|
+
}
|
|
9697
|
+
eval(context) {
|
|
9698
|
+
const leftValue = this.left.eval(context);
|
|
9699
|
+
const rightValue = this.right.eval(context);
|
|
9700
|
+
return booleanToTypedValue(rightValue.some((e) => e.value === leftValue[0].value));
|
|
9701
|
+
}
|
|
9702
|
+
}
|
|
9703
|
+
class DotAtom {
|
|
9704
|
+
constructor(left, right) {
|
|
9705
|
+
this.left = left;
|
|
9706
|
+
this.right = right;
|
|
9707
|
+
}
|
|
9708
|
+
eval(context) {
|
|
9709
|
+
return this.right.eval(this.left.eval(context));
|
|
9710
|
+
}
|
|
9711
|
+
}
|
|
9712
|
+
class UnionAtom {
|
|
9713
|
+
constructor(left, right) {
|
|
9714
|
+
this.left = left;
|
|
9715
|
+
this.right = right;
|
|
9716
|
+
}
|
|
9717
|
+
eval(context) {
|
|
9718
|
+
const leftResult = this.left.eval(context);
|
|
9719
|
+
const rightResult = this.right.eval(context);
|
|
9720
|
+
return removeDuplicates([...leftResult, ...rightResult]);
|
|
9721
|
+
}
|
|
9722
|
+
}
|
|
9723
|
+
class EqualsAtom {
|
|
9724
|
+
constructor(left, right) {
|
|
9725
|
+
this.left = left;
|
|
9726
|
+
this.right = right;
|
|
9727
|
+
}
|
|
9728
|
+
eval(context) {
|
|
9729
|
+
const leftValue = this.left.eval(context);
|
|
9730
|
+
const rightValue = this.right.eval(context);
|
|
9731
|
+
return fhirPathArrayEquals(leftValue, rightValue);
|
|
9732
|
+
}
|
|
9733
|
+
}
|
|
9734
|
+
class NotEqualsAtom {
|
|
9735
|
+
constructor(left, right) {
|
|
9736
|
+
this.left = left;
|
|
9737
|
+
this.right = right;
|
|
9738
|
+
}
|
|
9739
|
+
eval(context) {
|
|
9740
|
+
const leftValue = this.left.eval(context);
|
|
9741
|
+
const rightValue = this.right.eval(context);
|
|
9742
|
+
return fhirPathNot(fhirPathArrayEquals(leftValue, rightValue));
|
|
9743
|
+
}
|
|
9744
|
+
}
|
|
9745
|
+
class EquivalentAtom {
|
|
9746
|
+
constructor(left, right) {
|
|
9747
|
+
this.left = left;
|
|
9748
|
+
this.right = right;
|
|
9749
|
+
}
|
|
9750
|
+
eval(context) {
|
|
9751
|
+
const leftValue = this.left.eval(context);
|
|
9752
|
+
const rightValue = this.right.eval(context);
|
|
9753
|
+
return fhirPathArrayEquivalent(leftValue, rightValue);
|
|
9754
|
+
}
|
|
9755
|
+
}
|
|
9756
|
+
class NotEquivalentAtom {
|
|
9757
|
+
constructor(left, right) {
|
|
9758
|
+
this.left = left;
|
|
9759
|
+
this.right = right;
|
|
9760
|
+
}
|
|
9761
|
+
eval(context) {
|
|
9762
|
+
const leftValue = this.left.eval(context);
|
|
9763
|
+
const rightValue = this.right.eval(context);
|
|
9764
|
+
return fhirPathNot(fhirPathArrayEquivalent(leftValue, rightValue));
|
|
9765
|
+
}
|
|
9766
|
+
}
|
|
9767
|
+
class IsAtom {
|
|
9768
|
+
constructor(left, right) {
|
|
9769
|
+
this.left = left;
|
|
9770
|
+
this.right = right;
|
|
9771
|
+
}
|
|
9772
|
+
eval(context) {
|
|
9773
|
+
const leftValue = this.left.eval(context);
|
|
9774
|
+
if (leftValue.length !== 1) {
|
|
9775
|
+
return [];
|
|
9698
9776
|
}
|
|
9699
|
-
const
|
|
9700
|
-
return [
|
|
9701
|
-
}
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
if (typeAtom instanceof SymbolAtom) {
|
|
9721
|
-
typeName = typeAtom.name;
|
|
9777
|
+
const typeName = this.right.name;
|
|
9778
|
+
return booleanToTypedValue(fhirPathIs(leftValue[0], typeName));
|
|
9779
|
+
}
|
|
9780
|
+
}
|
|
9781
|
+
/**
|
|
9782
|
+
* 6.5.1. and
|
|
9783
|
+
* Returns true if both operands evaluate to true,
|
|
9784
|
+
* false if either operand evaluates to false,
|
|
9785
|
+
* and the empty collection otherwise.
|
|
9786
|
+
*/
|
|
9787
|
+
class AndAtom {
|
|
9788
|
+
constructor(left, right) {
|
|
9789
|
+
this.left = left;
|
|
9790
|
+
this.right = right;
|
|
9791
|
+
}
|
|
9792
|
+
eval(context) {
|
|
9793
|
+
var _a, _b, _c, _d;
|
|
9794
|
+
const leftValue = this.left.eval(context);
|
|
9795
|
+
const rightValue = this.right.eval(context);
|
|
9796
|
+
if (((_a = leftValue[0]) === null || _a === void 0 ? void 0 : _a.value) === true && ((_b = rightValue[0]) === null || _b === void 0 ? void 0 : _b.value) === true) {
|
|
9797
|
+
return booleanToTypedValue(true);
|
|
9722
9798
|
}
|
|
9723
|
-
|
|
9724
|
-
|
|
9799
|
+
if (((_c = leftValue[0]) === null || _c === void 0 ? void 0 : _c.value) === false || ((_d = rightValue[0]) === null || _d === void 0 ? void 0 : _d.value) === false) {
|
|
9800
|
+
return booleanToTypedValue(false);
|
|
9725
9801
|
}
|
|
9726
|
-
|
|
9727
|
-
|
|
9802
|
+
return [];
|
|
9803
|
+
}
|
|
9804
|
+
}
|
|
9805
|
+
class OrAtom {
|
|
9806
|
+
constructor(left, right) {
|
|
9807
|
+
this.left = left;
|
|
9808
|
+
this.right = right;
|
|
9809
|
+
}
|
|
9810
|
+
eval(context) {
|
|
9811
|
+
const leftValue = this.left.eval(context);
|
|
9812
|
+
if (toJsBoolean(leftValue)) {
|
|
9813
|
+
return leftValue;
|
|
9728
9814
|
}
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
* 6.5 Boolean logic
|
|
9733
|
-
*/
|
|
9734
|
-
/**
|
|
9735
|
-
* 6.5.3. not() : Boolean
|
|
9736
|
-
*
|
|
9737
|
-
* Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):
|
|
9738
|
-
*
|
|
9739
|
-
* @param input
|
|
9740
|
-
* @returns
|
|
9741
|
-
*/
|
|
9742
|
-
not: (input) => {
|
|
9743
|
-
return functions.toBoolean(input).map((value) => ({ type: exports.PropertyType.boolean, value: !value.value }));
|
|
9744
|
-
},
|
|
9745
|
-
/*
|
|
9746
|
-
* Additional functions
|
|
9747
|
-
* See: https://hl7.org/fhir/fhirpath.html#functions
|
|
9748
|
-
*/
|
|
9749
|
-
/**
|
|
9750
|
-
* For each item in the collection, if it is a string that is a uri (or canonical or url), locate the target of the reference, and add it to the resulting collection. If the item does not resolve to a resource, the item is ignored and nothing is added to the output collection.
|
|
9751
|
-
* The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.
|
|
9752
|
-
* @param input The input collection.
|
|
9753
|
-
* @returns
|
|
9754
|
-
*/
|
|
9755
|
-
resolve: (input) => {
|
|
9756
|
-
return input
|
|
9757
|
-
.map((e) => {
|
|
9758
|
-
const value = e.value;
|
|
9759
|
-
let refStr;
|
|
9760
|
-
if (typeof value === 'string') {
|
|
9761
|
-
refStr = value;
|
|
9762
|
-
}
|
|
9763
|
-
else if (typeof value === 'object') {
|
|
9764
|
-
const ref = value;
|
|
9765
|
-
if (ref.resource) {
|
|
9766
|
-
return toTypedValue(ref.resource);
|
|
9767
|
-
}
|
|
9768
|
-
refStr = ref.reference;
|
|
9769
|
-
}
|
|
9770
|
-
if (!refStr) {
|
|
9771
|
-
return { type: exports.PropertyType.BackboneElement, value: null };
|
|
9772
|
-
}
|
|
9773
|
-
const [resourceType, id] = refStr.split('/');
|
|
9774
|
-
return { type: exports.PropertyType.BackboneElement, value: { resourceType, id } };
|
|
9775
|
-
})
|
|
9776
|
-
.filter((e) => !!e.value);
|
|
9777
|
-
},
|
|
9778
|
-
/**
|
|
9779
|
-
* The as operator can be used to treat a value as a specific type.
|
|
9780
|
-
* @param input The input value.
|
|
9781
|
-
* @returns The value as the specific type.
|
|
9782
|
-
*/
|
|
9783
|
-
as: (input) => {
|
|
9784
|
-
return input;
|
|
9785
|
-
},
|
|
9786
|
-
/*
|
|
9787
|
-
* 12. Formal Specifications
|
|
9788
|
-
*/
|
|
9789
|
-
/**
|
|
9790
|
-
* Returns the type of the input.
|
|
9791
|
-
*
|
|
9792
|
-
* 12.2. Model Information
|
|
9793
|
-
*
|
|
9794
|
-
* The model information returned by the reflection function type() is specified as an
|
|
9795
|
-
* XML Schema document (xsd) and included in this specification at the following link:
|
|
9796
|
-
* https://hl7.org/fhirpath/modelinfo.xsd
|
|
9797
|
-
*
|
|
9798
|
-
* See: https://hl7.org/fhirpath/#model-information
|
|
9799
|
-
*
|
|
9800
|
-
* @param input The input collection.
|
|
9801
|
-
* @returns
|
|
9802
|
-
*/
|
|
9803
|
-
type: (input) => {
|
|
9804
|
-
return input.map(({ value }) => {
|
|
9805
|
-
if (typeof value === 'boolean') {
|
|
9806
|
-
return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Boolean' } };
|
|
9807
|
-
}
|
|
9808
|
-
if (typeof value === 'number') {
|
|
9809
|
-
return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Integer' } };
|
|
9810
|
-
}
|
|
9811
|
-
if (value && typeof value === 'object' && 'resourceType' in value) {
|
|
9812
|
-
return {
|
|
9813
|
-
type: exports.PropertyType.BackboneElement,
|
|
9814
|
-
value: { namespace: 'FHIR', name: value.resourceType },
|
|
9815
|
-
};
|
|
9816
|
-
}
|
|
9817
|
-
return { type: exports.PropertyType.BackboneElement, value: null };
|
|
9818
|
-
});
|
|
9819
|
-
},
|
|
9820
|
-
conformsTo: (input, systemAtom) => {
|
|
9821
|
-
const system = systemAtom.eval(input)[0].value;
|
|
9822
|
-
if (!system.startsWith('http://hl7.org/fhir/StructureDefinition/')) {
|
|
9823
|
-
throw new Error('Expected a StructureDefinition URL');
|
|
9815
|
+
const rightValue = this.right.eval(context);
|
|
9816
|
+
if (toJsBoolean(rightValue)) {
|
|
9817
|
+
return rightValue;
|
|
9824
9818
|
}
|
|
9825
|
-
const expectedResourceType = system.replace('http://hl7.org/fhir/StructureDefinition/', '');
|
|
9826
|
-
return input.map((value) => {
|
|
9827
|
-
var _a;
|
|
9828
|
-
return ({
|
|
9829
|
-
type: exports.PropertyType.boolean,
|
|
9830
|
-
value: ((_a = value.value) === null || _a === void 0 ? void 0 : _a.resourceType) === expectedResourceType,
|
|
9831
|
-
});
|
|
9832
|
-
});
|
|
9833
|
-
},
|
|
9834
|
-
};
|
|
9835
|
-
/*
|
|
9836
|
-
* Helper utilities
|
|
9837
|
-
*/
|
|
9838
|
-
function applyStringFunc(func, input, ...argsAtoms) {
|
|
9839
|
-
if (input.length === 0) {
|
|
9840
9819
|
return [];
|
|
9841
9820
|
}
|
|
9842
|
-
|
|
9843
|
-
|
|
9844
|
-
|
|
9821
|
+
}
|
|
9822
|
+
/**
|
|
9823
|
+
* 6.5.4. xor
|
|
9824
|
+
* Returns true if exactly one of the operands evaluates to true,
|
|
9825
|
+
* false if either both operands evaluate to true or both operands evaluate to false,
|
|
9826
|
+
* and the empty collection otherwise.
|
|
9827
|
+
*/
|
|
9828
|
+
class XorAtom {
|
|
9829
|
+
constructor(left, right) {
|
|
9830
|
+
this.left = left;
|
|
9831
|
+
this.right = right;
|
|
9845
9832
|
}
|
|
9846
|
-
|
|
9847
|
-
|
|
9833
|
+
eval(context) {
|
|
9834
|
+
const leftResult = this.left.eval(context);
|
|
9835
|
+
const rightResult = this.right.eval(context);
|
|
9836
|
+
if (leftResult.length === 0 && rightResult.length === 0) {
|
|
9837
|
+
return [];
|
|
9838
|
+
}
|
|
9839
|
+
const leftValue = leftResult.length === 0 ? null : leftResult[0].value;
|
|
9840
|
+
const rightValue = rightResult.length === 0 ? null : rightResult[0].value;
|
|
9841
|
+
if ((leftValue === true && rightValue !== true) || (leftValue !== true && rightValue === true)) {
|
|
9842
|
+
return booleanToTypedValue(true);
|
|
9843
|
+
}
|
|
9844
|
+
if ((leftValue === true && rightValue === true) || (leftValue === false && rightValue === false)) {
|
|
9845
|
+
return booleanToTypedValue(false);
|
|
9846
|
+
}
|
|
9848
9847
|
return [];
|
|
9849
9848
|
}
|
|
9850
|
-
if (Array.isArray(result)) {
|
|
9851
|
-
return result.map(toTypedValue);
|
|
9852
|
-
}
|
|
9853
|
-
return [toTypedValue(result)];
|
|
9854
9849
|
}
|
|
9855
|
-
|
|
9856
|
-
|
|
9857
|
-
|
|
9850
|
+
class FunctionAtom {
|
|
9851
|
+
constructor(name, args, impl) {
|
|
9852
|
+
this.name = name;
|
|
9853
|
+
this.args = args;
|
|
9854
|
+
this.impl = impl;
|
|
9858
9855
|
}
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
const numberInput = quantity ? value.value : value;
|
|
9862
|
-
if (typeof numberInput !== 'number') {
|
|
9863
|
-
throw new Error('Math function cannot be called with non-number');
|
|
9856
|
+
eval(context) {
|
|
9857
|
+
return this.impl(context, ...this.args);
|
|
9864
9858
|
}
|
|
9865
|
-
const result = func(numberInput, ...argsAtoms.map((atom) => { var _a, _b; return (_b = (_a = atom.eval(input)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.value; }));
|
|
9866
|
-
const type = quantity ? exports.PropertyType.Quantity : input[0].type;
|
|
9867
|
-
const returnValue = quantity ? Object.assign(Object.assign({}, value), { value: result }) : result;
|
|
9868
|
-
return [{ type, value: returnValue }];
|
|
9869
9859
|
}
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9860
|
+
class IndexerAtom {
|
|
9861
|
+
constructor(left, expr) {
|
|
9862
|
+
this.left = left;
|
|
9863
|
+
this.expr = expr;
|
|
9873
9864
|
}
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9865
|
+
eval(context) {
|
|
9866
|
+
const evalResult = this.expr.eval(context);
|
|
9867
|
+
if (evalResult.length !== 1) {
|
|
9868
|
+
return [];
|
|
9869
|
+
}
|
|
9870
|
+
const index = evalResult[0].value;
|
|
9871
|
+
if (typeof index !== 'number') {
|
|
9872
|
+
throw new Error(`Invalid indexer expression: should return integer}`);
|
|
9873
|
+
}
|
|
9874
|
+
const leftResult = this.left.eval(context);
|
|
9875
|
+
if (!(index in leftResult)) {
|
|
9876
|
+
return [];
|
|
9877
9877
|
}
|
|
9878
|
+
return [leftResult[index]];
|
|
9878
9879
|
}
|
|
9879
|
-
return input;
|
|
9880
9880
|
}
|
|
9881
9881
|
|
|
9882
9882
|
var _Tokenizer_instances, _Tokenizer_str, _Tokenizer_pos, _Tokenizer_peekToken, _Tokenizer_consumeToken, _Tokenizer_consumeWhitespace, _Tokenizer_consumeMultiLineComment, _Tokenizer_consumeSingleLineComment, _Tokenizer_consumeString, _Tokenizer_consumeBacktickSymbol, _Tokenizer_consumeDateTime, _Tokenizer_consumeNumber, _Tokenizer_consumeSymbol, _Tokenizer_consumeOperator, _Tokenizer_consumeWhile, _Tokenizer_curr, _Tokenizer_prev, _Tokenizer_peek;
|
|
@@ -11010,7 +11010,6 @@
|
|
|
11010
11010
|
exports.capitalize = capitalize;
|
|
11011
11011
|
exports.createReference = createReference;
|
|
11012
11012
|
exports.createSchema = createSchema;
|
|
11013
|
-
exports.createTypeSchema = createTypeSchema;
|
|
11014
11013
|
exports.created = created;
|
|
11015
11014
|
exports.deepClone = deepClone;
|
|
11016
11015
|
exports.deepEquals = deepEquals$1;
|
|
@@ -11053,6 +11052,7 @@
|
|
|
11053
11052
|
exports.indexSearchParameter = indexSearchParameter;
|
|
11054
11053
|
exports.indexStructureDefinition = indexStructureDefinition;
|
|
11055
11054
|
exports.indexStructureDefinitionBundle = indexStructureDefinitionBundle;
|
|
11055
|
+
exports.isEmpty = isEmpty;
|
|
11056
11056
|
exports.isGone = isGone;
|
|
11057
11057
|
exports.isLowerCase = isLowerCase;
|
|
11058
11058
|
exports.isNotFound = isNotFound;
|