@medplum/core 0.9.31 → 0.9.34
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 +21 -4
- package/dist/cjs/index.js +678 -663
- 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 +1 -1
- package/dist/esm/client.d.ts +21 -4
- package/dist/esm/client.js +23 -5
- 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 +2 -3
- 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 +1 -1
- 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 +1 -1
- package/dist/esm/utils.js +1 -1
- 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) {
|
|
@@ -6523,8 +6520,10 @@
|
|
|
6523
6520
|
startLogin(loginRequest) {
|
|
6524
6521
|
var _a, _b;
|
|
6525
6522
|
return __awaiter(this, void 0, void 0, function* () {
|
|
6526
|
-
|
|
6527
|
-
|
|
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') }));
|
|
6528
6527
|
});
|
|
6529
6528
|
}
|
|
6530
6529
|
/**
|
|
@@ -6538,8 +6537,10 @@
|
|
|
6538
6537
|
startGoogleLogin(loginRequest) {
|
|
6539
6538
|
var _a, _b;
|
|
6540
6539
|
return __awaiter(this, void 0, void 0, function* () {
|
|
6541
|
-
|
|
6542
|
-
|
|
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') }));
|
|
6543
6544
|
});
|
|
6544
6545
|
}
|
|
6545
6546
|
/**
|
|
@@ -6766,7 +6767,7 @@
|
|
|
6766
6767
|
*
|
|
6767
6768
|
* See the FHIR "read" operation for full details: https://www.hl7.org/fhir/http.html#read
|
|
6768
6769
|
*
|
|
6769
|
-
* @category
|
|
6770
|
+
* @category Read
|
|
6770
6771
|
* @param resourceType The FHIR resource type.
|
|
6771
6772
|
* @param id The resource ID.
|
|
6772
6773
|
* @returns The resource if available; undefined otherwise.
|
|
@@ -7321,6 +7322,20 @@
|
|
|
7321
7322
|
graphql(query, operationName, variables, options) {
|
|
7322
7323
|
return this.post(this.fhirUrl('$graphql'), { query, operationName, variables }, JSON_CONTENT_TYPE, options);
|
|
7323
7324
|
}
|
|
7325
|
+
/**
|
|
7326
|
+
*
|
|
7327
|
+
* Executes the $graph operation on this resource to fetch a Bundle of resources linked to the target resource
|
|
7328
|
+
* according to a graph definition
|
|
7329
|
+
|
|
7330
|
+
* @category Read
|
|
7331
|
+
* @param resourceType The FHIR resource type.
|
|
7332
|
+
* @param id The resource ID.
|
|
7333
|
+
* @param graphName `name` parameter of the GraphDefinition
|
|
7334
|
+
* @returns A Bundle
|
|
7335
|
+
*/
|
|
7336
|
+
readResourceGraph(resourceType, id, graphName) {
|
|
7337
|
+
return this.get(`${this.fhirUrl(resourceType, id)}/$graph?graph=${graphName}`);
|
|
7338
|
+
}
|
|
7324
7339
|
/**
|
|
7325
7340
|
* @category Authentication
|
|
7326
7341
|
* @returns The Login State
|
|
@@ -7661,6 +7676,28 @@
|
|
|
7661
7676
|
return url.endsWith('/') ? url : url + '/';
|
|
7662
7677
|
}
|
|
7663
7678
|
|
|
7679
|
+
function parseDateString(str) {
|
|
7680
|
+
if (str.startsWith('T')) {
|
|
7681
|
+
// If a time string,
|
|
7682
|
+
// then normalize to full length.
|
|
7683
|
+
return str + 'T00:00:00.000Z'.substring(str.length);
|
|
7684
|
+
}
|
|
7685
|
+
if (str.length <= 10) {
|
|
7686
|
+
// If a local date (i.e., "2021-01-01"),
|
|
7687
|
+
// then return as-is.
|
|
7688
|
+
return str;
|
|
7689
|
+
}
|
|
7690
|
+
try {
|
|
7691
|
+
// Try to normalize to UTC
|
|
7692
|
+
return new Date(str).toISOString();
|
|
7693
|
+
}
|
|
7694
|
+
catch (e) {
|
|
7695
|
+
// Fallback to original input
|
|
7696
|
+
// This happens on unsupported time formats such as "2021-01-01T12"
|
|
7697
|
+
return str;
|
|
7698
|
+
}
|
|
7699
|
+
}
|
|
7700
|
+
|
|
7664
7701
|
/**
|
|
7665
7702
|
* Returns a single element array with a typed boolean value.
|
|
7666
7703
|
* @param value The primitive boolean value.
|
|
@@ -8005,7 +8042,6 @@
|
|
|
8005
8042
|
}
|
|
8006
8043
|
/**
|
|
8007
8044
|
* Resource equality.
|
|
8008
|
-
* Ignores meta.versionId and meta.lastUpdated.
|
|
8009
8045
|
* See: https://dmitripavlutin.com/how-to-compare-objects-in-javascript/#4-deep-equality
|
|
8010
8046
|
* @param object1 The first object.
|
|
8011
8047
|
* @param object2 The second object.
|
|
@@ -8033,478 +8069,133 @@
|
|
|
8033
8069
|
}
|
|
8034
8070
|
return true;
|
|
8035
8071
|
}
|
|
8036
|
-
function isObject(
|
|
8037
|
-
return
|
|
8072
|
+
function isObject(obj) {
|
|
8073
|
+
return obj !== null && typeof obj === 'object';
|
|
8038
8074
|
}
|
|
8039
8075
|
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
.map((e) => __classPrivateFieldGet(this, _SymbolAtom_instances, "m", _SymbolAtom_evalValue).call(this, e))
|
|
8079
|
-
.flat()
|
|
8080
|
-
.filter((e) => (e === null || e === void 0 ? void 0 : e.value) !== undefined);
|
|
8081
|
-
}
|
|
8082
|
-
}
|
|
8083
|
-
_SymbolAtom_instances = new WeakSet(), _SymbolAtom_evalValue = function _SymbolAtom_evalValue(typedValue) {
|
|
8084
|
-
const input = typedValue.value;
|
|
8085
|
-
if (!input || typeof input !== 'object') {
|
|
8086
|
-
return undefined;
|
|
8087
|
-
}
|
|
8088
|
-
if ('resourceType' in input && input.resourceType === this.name) {
|
|
8089
|
-
return typedValue;
|
|
8090
|
-
}
|
|
8091
|
-
return getTypedPropertyValue(typedValue, this.name);
|
|
8092
|
-
};
|
|
8093
|
-
class EmptySetAtom {
|
|
8094
|
-
eval() {
|
|
8095
|
-
return [];
|
|
8096
|
-
}
|
|
8097
|
-
}
|
|
8098
|
-
class UnaryOperatorAtom {
|
|
8099
|
-
constructor(child, impl) {
|
|
8100
|
-
this.child = child;
|
|
8101
|
-
this.impl = impl;
|
|
8102
|
-
}
|
|
8103
|
-
eval(context) {
|
|
8104
|
-
return this.impl(this.child.eval(context));
|
|
8105
|
-
}
|
|
8106
|
-
}
|
|
8107
|
-
class AsAtom {
|
|
8108
|
-
constructor(left, right) {
|
|
8109
|
-
this.left = left;
|
|
8110
|
-
this.right = right;
|
|
8111
|
-
}
|
|
8112
|
-
eval(context) {
|
|
8113
|
-
return this.left.eval(context);
|
|
8114
|
-
}
|
|
8115
|
-
}
|
|
8116
|
-
class ArithemticOperatorAtom {
|
|
8117
|
-
constructor(left, right, impl) {
|
|
8118
|
-
this.left = left;
|
|
8119
|
-
this.right = right;
|
|
8120
|
-
this.impl = impl;
|
|
8121
|
-
}
|
|
8122
|
-
eval(context) {
|
|
8123
|
-
const leftEvalResult = this.left.eval(context);
|
|
8124
|
-
if (leftEvalResult.length !== 1) {
|
|
8125
|
-
return [];
|
|
8076
|
+
/**
|
|
8077
|
+
* Temporary placholder for unimplemented methods.
|
|
8078
|
+
*/
|
|
8079
|
+
const stub = () => [];
|
|
8080
|
+
const functions = {
|
|
8081
|
+
/*
|
|
8082
|
+
* 5.1 Existence
|
|
8083
|
+
* See: https://hl7.org/fhirpath/#existence
|
|
8084
|
+
*/
|
|
8085
|
+
/**
|
|
8086
|
+
* Returns true if the input collection is empty ({ }) and false otherwise.
|
|
8087
|
+
*
|
|
8088
|
+
* See: https://hl7.org/fhirpath/#empty-boolean
|
|
8089
|
+
*
|
|
8090
|
+
* @param input The input collection.
|
|
8091
|
+
* @returns True if the input collection is empty ({ }) and false otherwise.
|
|
8092
|
+
*/
|
|
8093
|
+
empty: (input) => {
|
|
8094
|
+
return booleanToTypedValue(input.length === 0);
|
|
8095
|
+
},
|
|
8096
|
+
/**
|
|
8097
|
+
* Returns true if the collection has unknown elements, and false otherwise.
|
|
8098
|
+
* This is the opposite of empty(), and as such is a shorthand for empty().not().
|
|
8099
|
+
* If the input collection is empty ({ }), the result is false.
|
|
8100
|
+
*
|
|
8101
|
+
* The function can also take an optional criteria to be applied to the collection
|
|
8102
|
+
* prior to the determination of the exists. In this case, the function is shorthand
|
|
8103
|
+
* for where(criteria).exists().
|
|
8104
|
+
*
|
|
8105
|
+
* See: https://hl7.org/fhirpath/#existscriteria-expression-boolean
|
|
8106
|
+
*
|
|
8107
|
+
* @param input
|
|
8108
|
+
* @param criteria
|
|
8109
|
+
* @returns True if the collection has unknown elements, and false otherwise.
|
|
8110
|
+
*/
|
|
8111
|
+
exists: (input, criteria) => {
|
|
8112
|
+
if (criteria) {
|
|
8113
|
+
return booleanToTypedValue(input.filter((e) => toJsBoolean(criteria.eval([e]))).length > 0);
|
|
8126
8114
|
}
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
return [];
|
|
8115
|
+
else {
|
|
8116
|
+
return booleanToTypedValue(input.length > 0);
|
|
8130
8117
|
}
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8118
|
+
},
|
|
8119
|
+
/**
|
|
8120
|
+
* Returns true if for every element in the input collection, criteria evaluates to true.
|
|
8121
|
+
* Otherwise, the result is false.
|
|
8122
|
+
*
|
|
8123
|
+
* If the input collection is empty ({ }), the result is true.
|
|
8124
|
+
*
|
|
8125
|
+
* See: https://hl7.org/fhirpath/#allcriteria-expression-boolean
|
|
8126
|
+
*
|
|
8127
|
+
* @param input The input collection.
|
|
8128
|
+
* @param criteria The evaluation criteria.
|
|
8129
|
+
* @returns True if for every element in the input collection, criteria evaluates to true.
|
|
8130
|
+
*/
|
|
8131
|
+
all: (input, criteria) => {
|
|
8132
|
+
return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval([e]))));
|
|
8133
|
+
},
|
|
8134
|
+
/**
|
|
8135
|
+
* Takes a collection of Boolean values and returns true if all the items are true.
|
|
8136
|
+
* If unknown items are false, the result is false.
|
|
8137
|
+
* If the input is empty ({ }), the result is true.
|
|
8138
|
+
*
|
|
8139
|
+
* See: https://hl7.org/fhirpath/#alltrue-boolean
|
|
8140
|
+
*
|
|
8141
|
+
* @param input The input collection.
|
|
8142
|
+
* @param criteria The evaluation criteria.
|
|
8143
|
+
* @returns True if all the items are true.
|
|
8144
|
+
*/
|
|
8145
|
+
allTrue: (input) => {
|
|
8146
|
+
for (const value of input) {
|
|
8147
|
+
if (!value.value) {
|
|
8148
|
+
return booleanToTypedValue(false);
|
|
8149
|
+
}
|
|
8138
8150
|
}
|
|
8139
|
-
|
|
8140
|
-
|
|
8151
|
+
return booleanToTypedValue(true);
|
|
8152
|
+
},
|
|
8153
|
+
/**
|
|
8154
|
+
* Takes a collection of Boolean values and returns true if unknown of the items are true.
|
|
8155
|
+
* If all the items are false, or if the input is empty ({ }), the result is false.
|
|
8156
|
+
*
|
|
8157
|
+
* See: https://hl7.org/fhirpath/#anytrue-boolean
|
|
8158
|
+
*
|
|
8159
|
+
* @param input The input collection.
|
|
8160
|
+
* @param criteria The evaluation criteria.
|
|
8161
|
+
* @returns True if unknown of the items are true.
|
|
8162
|
+
*/
|
|
8163
|
+
anyTrue: (input) => {
|
|
8164
|
+
for (const value of input) {
|
|
8165
|
+
if (value.value) {
|
|
8166
|
+
return booleanToTypedValue(true);
|
|
8167
|
+
}
|
|
8141
8168
|
}
|
|
8142
|
-
|
|
8143
|
-
|
|
8169
|
+
return booleanToTypedValue(false);
|
|
8170
|
+
},
|
|
8171
|
+
/**
|
|
8172
|
+
* Takes a collection of Boolean values and returns true if all the items are false.
|
|
8173
|
+
* If unknown items are true, the result is false.
|
|
8174
|
+
* If the input is empty ({ }), the result is true.
|
|
8175
|
+
*
|
|
8176
|
+
* See: https://hl7.org/fhirpath/#allfalse-boolean
|
|
8177
|
+
*
|
|
8178
|
+
* @param input The input collection.
|
|
8179
|
+
* @param criteria The evaluation criteria.
|
|
8180
|
+
* @returns True if all the items are false.
|
|
8181
|
+
*/
|
|
8182
|
+
allFalse: (input) => {
|
|
8183
|
+
for (const value of input) {
|
|
8184
|
+
if (value.value) {
|
|
8185
|
+
return booleanToTypedValue(false);
|
|
8186
|
+
}
|
|
8144
8187
|
}
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
class ConcatAtom {
|
|
8148
|
-
constructor(left, right) {
|
|
8149
|
-
this.left = left;
|
|
8150
|
-
this.right = right;
|
|
8151
|
-
}
|
|
8152
|
-
eval(context) {
|
|
8153
|
-
const leftValue = this.left.eval(context);
|
|
8154
|
-
const rightValue = this.right.eval(context);
|
|
8155
|
-
const result = [...leftValue, ...rightValue];
|
|
8156
|
-
if (result.length > 0 && result.every((e) => typeof e.value === 'string')) {
|
|
8157
|
-
return [{ type: exports.PropertyType.string, value: result.map((e) => e.value).join('') }];
|
|
8158
|
-
}
|
|
8159
|
-
return result;
|
|
8160
|
-
}
|
|
8161
|
-
}
|
|
8162
|
-
class ContainsAtom {
|
|
8163
|
-
constructor(left, right) {
|
|
8164
|
-
this.left = left;
|
|
8165
|
-
this.right = right;
|
|
8166
|
-
}
|
|
8167
|
-
eval(context) {
|
|
8168
|
-
const leftValue = this.left.eval(context);
|
|
8169
|
-
const rightValue = this.right.eval(context);
|
|
8170
|
-
return booleanToTypedValue(leftValue.some((e) => e.value === rightValue[0].value));
|
|
8171
|
-
}
|
|
8172
|
-
}
|
|
8173
|
-
class InAtom {
|
|
8174
|
-
constructor(left, right) {
|
|
8175
|
-
this.left = left;
|
|
8176
|
-
this.right = right;
|
|
8177
|
-
}
|
|
8178
|
-
eval(context) {
|
|
8179
|
-
const leftValue = this.left.eval(context);
|
|
8180
|
-
const rightValue = this.right.eval(context);
|
|
8181
|
-
return booleanToTypedValue(rightValue.some((e) => e.value === leftValue[0].value));
|
|
8182
|
-
}
|
|
8183
|
-
}
|
|
8184
|
-
class DotAtom {
|
|
8185
|
-
constructor(left, right) {
|
|
8186
|
-
this.left = left;
|
|
8187
|
-
this.right = right;
|
|
8188
|
-
}
|
|
8189
|
-
eval(context) {
|
|
8190
|
-
return this.right.eval(this.left.eval(context));
|
|
8191
|
-
}
|
|
8192
|
-
}
|
|
8193
|
-
class UnionAtom {
|
|
8194
|
-
constructor(left, right) {
|
|
8195
|
-
this.left = left;
|
|
8196
|
-
this.right = right;
|
|
8197
|
-
}
|
|
8198
|
-
eval(context) {
|
|
8199
|
-
const leftResult = this.left.eval(context);
|
|
8200
|
-
const rightResult = this.right.eval(context);
|
|
8201
|
-
return removeDuplicates([...leftResult, ...rightResult]);
|
|
8202
|
-
}
|
|
8203
|
-
}
|
|
8204
|
-
class EqualsAtom {
|
|
8205
|
-
constructor(left, right) {
|
|
8206
|
-
this.left = left;
|
|
8207
|
-
this.right = right;
|
|
8208
|
-
}
|
|
8209
|
-
eval(context) {
|
|
8210
|
-
const leftValue = this.left.eval(context);
|
|
8211
|
-
const rightValue = this.right.eval(context);
|
|
8212
|
-
return fhirPathArrayEquals(leftValue, rightValue);
|
|
8213
|
-
}
|
|
8214
|
-
}
|
|
8215
|
-
class NotEqualsAtom {
|
|
8216
|
-
constructor(left, right) {
|
|
8217
|
-
this.left = left;
|
|
8218
|
-
this.right = right;
|
|
8219
|
-
}
|
|
8220
|
-
eval(context) {
|
|
8221
|
-
const leftValue = this.left.eval(context);
|
|
8222
|
-
const rightValue = this.right.eval(context);
|
|
8223
|
-
return fhirPathNot(fhirPathArrayEquals(leftValue, rightValue));
|
|
8224
|
-
}
|
|
8225
|
-
}
|
|
8226
|
-
class EquivalentAtom {
|
|
8227
|
-
constructor(left, right) {
|
|
8228
|
-
this.left = left;
|
|
8229
|
-
this.right = right;
|
|
8230
|
-
}
|
|
8231
|
-
eval(context) {
|
|
8232
|
-
const leftValue = this.left.eval(context);
|
|
8233
|
-
const rightValue = this.right.eval(context);
|
|
8234
|
-
return fhirPathArrayEquivalent(leftValue, rightValue);
|
|
8235
|
-
}
|
|
8236
|
-
}
|
|
8237
|
-
class NotEquivalentAtom {
|
|
8238
|
-
constructor(left, right) {
|
|
8239
|
-
this.left = left;
|
|
8240
|
-
this.right = right;
|
|
8241
|
-
}
|
|
8242
|
-
eval(context) {
|
|
8243
|
-
const leftValue = this.left.eval(context);
|
|
8244
|
-
const rightValue = this.right.eval(context);
|
|
8245
|
-
return fhirPathNot(fhirPathArrayEquivalent(leftValue, rightValue));
|
|
8246
|
-
}
|
|
8247
|
-
}
|
|
8248
|
-
class IsAtom {
|
|
8249
|
-
constructor(left, right) {
|
|
8250
|
-
this.left = left;
|
|
8251
|
-
this.right = right;
|
|
8252
|
-
}
|
|
8253
|
-
eval(context) {
|
|
8254
|
-
const leftValue = this.left.eval(context);
|
|
8255
|
-
if (leftValue.length !== 1) {
|
|
8256
|
-
return [];
|
|
8257
|
-
}
|
|
8258
|
-
const typeName = this.right.name;
|
|
8259
|
-
return booleanToTypedValue(fhirPathIs(leftValue[0], typeName));
|
|
8260
|
-
}
|
|
8261
|
-
}
|
|
8262
|
-
/**
|
|
8263
|
-
* 6.5.1. and
|
|
8264
|
-
* Returns true if both operands evaluate to true,
|
|
8265
|
-
* false if either operand evaluates to false,
|
|
8266
|
-
* and the empty collection otherwise.
|
|
8267
|
-
*/
|
|
8268
|
-
class AndAtom {
|
|
8269
|
-
constructor(left, right) {
|
|
8270
|
-
this.left = left;
|
|
8271
|
-
this.right = right;
|
|
8272
|
-
}
|
|
8273
|
-
eval(context) {
|
|
8274
|
-
var _a, _b, _c, _d;
|
|
8275
|
-
const leftValue = this.left.eval(context);
|
|
8276
|
-
const rightValue = this.right.eval(context);
|
|
8277
|
-
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) {
|
|
8278
|
-
return booleanToTypedValue(true);
|
|
8279
|
-
}
|
|
8280
|
-
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) {
|
|
8281
|
-
return booleanToTypedValue(false);
|
|
8282
|
-
}
|
|
8283
|
-
return [];
|
|
8284
|
-
}
|
|
8285
|
-
}
|
|
8286
|
-
class OrAtom {
|
|
8287
|
-
constructor(left, right) {
|
|
8288
|
-
this.left = left;
|
|
8289
|
-
this.right = right;
|
|
8290
|
-
}
|
|
8291
|
-
eval(context) {
|
|
8292
|
-
const leftValue = this.left.eval(context);
|
|
8293
|
-
if (toJsBoolean(leftValue)) {
|
|
8294
|
-
return leftValue;
|
|
8295
|
-
}
|
|
8296
|
-
const rightValue = this.right.eval(context);
|
|
8297
|
-
if (toJsBoolean(rightValue)) {
|
|
8298
|
-
return rightValue;
|
|
8299
|
-
}
|
|
8300
|
-
return [];
|
|
8301
|
-
}
|
|
8302
|
-
}
|
|
8303
|
-
/**
|
|
8304
|
-
* 6.5.4. xor
|
|
8305
|
-
* Returns true if exactly one of the operands evaluates to true,
|
|
8306
|
-
* false if either both operands evaluate to true or both operands evaluate to false,
|
|
8307
|
-
* and the empty collection otherwise.
|
|
8308
|
-
*/
|
|
8309
|
-
class XorAtom {
|
|
8310
|
-
constructor(left, right) {
|
|
8311
|
-
this.left = left;
|
|
8312
|
-
this.right = right;
|
|
8313
|
-
}
|
|
8314
|
-
eval(context) {
|
|
8315
|
-
const leftResult = this.left.eval(context);
|
|
8316
|
-
const rightResult = this.right.eval(context);
|
|
8317
|
-
if (leftResult.length === 0 && rightResult.length === 0) {
|
|
8318
|
-
return [];
|
|
8319
|
-
}
|
|
8320
|
-
const leftValue = leftResult.length === 0 ? null : leftResult[0].value;
|
|
8321
|
-
const rightValue = rightResult.length === 0 ? null : rightResult[0].value;
|
|
8322
|
-
if ((leftValue === true && rightValue !== true) || (leftValue !== true && rightValue === true)) {
|
|
8323
|
-
return booleanToTypedValue(true);
|
|
8324
|
-
}
|
|
8325
|
-
if ((leftValue === true && rightValue === true) || (leftValue === false && rightValue === false)) {
|
|
8326
|
-
return booleanToTypedValue(false);
|
|
8327
|
-
}
|
|
8328
|
-
return [];
|
|
8329
|
-
}
|
|
8330
|
-
}
|
|
8331
|
-
class FunctionAtom {
|
|
8332
|
-
constructor(name, args, impl) {
|
|
8333
|
-
this.name = name;
|
|
8334
|
-
this.args = args;
|
|
8335
|
-
this.impl = impl;
|
|
8336
|
-
}
|
|
8337
|
-
eval(context) {
|
|
8338
|
-
return this.impl(context, ...this.args);
|
|
8339
|
-
}
|
|
8340
|
-
}
|
|
8341
|
-
class IndexerAtom {
|
|
8342
|
-
constructor(left, expr) {
|
|
8343
|
-
this.left = left;
|
|
8344
|
-
this.expr = expr;
|
|
8345
|
-
}
|
|
8346
|
-
eval(context) {
|
|
8347
|
-
const evalResult = this.expr.eval(context);
|
|
8348
|
-
if (evalResult.length !== 1) {
|
|
8349
|
-
return [];
|
|
8350
|
-
}
|
|
8351
|
-
const index = evalResult[0].value;
|
|
8352
|
-
if (typeof index !== 'number') {
|
|
8353
|
-
throw new Error(`Invalid indexer expression: should return integer}`);
|
|
8354
|
-
}
|
|
8355
|
-
const leftResult = this.left.eval(context);
|
|
8356
|
-
if (!(index in leftResult)) {
|
|
8357
|
-
return [];
|
|
8358
|
-
}
|
|
8359
|
-
return [leftResult[index]];
|
|
8360
|
-
}
|
|
8361
|
-
}
|
|
8362
|
-
|
|
8363
|
-
function parseDateString(str) {
|
|
8364
|
-
if (str.startsWith('T')) {
|
|
8365
|
-
// If a time string,
|
|
8366
|
-
// then normalize to full length.
|
|
8367
|
-
return str + 'T00:00:00.000Z'.substring(str.length);
|
|
8368
|
-
}
|
|
8369
|
-
if (str.length <= 10) {
|
|
8370
|
-
// If a local date (i.e., "2021-01-01"),
|
|
8371
|
-
// then return as-is.
|
|
8372
|
-
return str;
|
|
8373
|
-
}
|
|
8374
|
-
try {
|
|
8375
|
-
// Try to normalize to UTC
|
|
8376
|
-
return new Date(str).toISOString();
|
|
8377
|
-
}
|
|
8378
|
-
catch (e) {
|
|
8379
|
-
// Fallback to original input
|
|
8380
|
-
// This happens on unsupported time formats such as "2021-01-01T12"
|
|
8381
|
-
return str;
|
|
8382
|
-
}
|
|
8383
|
-
}
|
|
8384
|
-
|
|
8385
|
-
/**
|
|
8386
|
-
* Temporary placholder for unimplemented methods.
|
|
8387
|
-
*/
|
|
8388
|
-
const stub = () => [];
|
|
8389
|
-
const functions = {
|
|
8390
|
-
/*
|
|
8391
|
-
* 5.1 Existence
|
|
8392
|
-
* See: https://hl7.org/fhirpath/#existence
|
|
8393
|
-
*/
|
|
8188
|
+
return booleanToTypedValue(true);
|
|
8189
|
+
},
|
|
8394
8190
|
/**
|
|
8395
|
-
*
|
|
8191
|
+
* Takes a collection of Boolean values and returns true if unknown of the items are false.
|
|
8192
|
+
* If all the items are true, or if the input is empty ({ }), the result is false.
|
|
8396
8193
|
*
|
|
8397
|
-
* See: https://hl7.org/fhirpath/#
|
|
8194
|
+
* See: https://hl7.org/fhirpath/#anyfalse-boolean
|
|
8398
8195
|
*
|
|
8399
8196
|
* @param input The input collection.
|
|
8400
|
-
* @
|
|
8401
|
-
|
|
8402
|
-
empty: (input) => {
|
|
8403
|
-
return booleanToTypedValue(input.length === 0);
|
|
8404
|
-
},
|
|
8405
|
-
/**
|
|
8406
|
-
* Returns true if the collection has unknown elements, and false otherwise.
|
|
8407
|
-
* This is the opposite of empty(), and as such is a shorthand for empty().not().
|
|
8408
|
-
* If the input collection is empty ({ }), the result is false.
|
|
8409
|
-
*
|
|
8410
|
-
* The function can also take an optional criteria to be applied to the collection
|
|
8411
|
-
* prior to the determination of the exists. In this case, the function is shorthand
|
|
8412
|
-
* for where(criteria).exists().
|
|
8413
|
-
*
|
|
8414
|
-
* See: https://hl7.org/fhirpath/#existscriteria-expression-boolean
|
|
8415
|
-
*
|
|
8416
|
-
* @param input
|
|
8417
|
-
* @param criteria
|
|
8418
|
-
* @returns True if the collection has unknown elements, and false otherwise.
|
|
8419
|
-
*/
|
|
8420
|
-
exists: (input, criteria) => {
|
|
8421
|
-
if (criteria) {
|
|
8422
|
-
return booleanToTypedValue(input.filter((e) => toJsBoolean(criteria.eval([e]))).length > 0);
|
|
8423
|
-
}
|
|
8424
|
-
else {
|
|
8425
|
-
return booleanToTypedValue(input.length > 0);
|
|
8426
|
-
}
|
|
8427
|
-
},
|
|
8428
|
-
/**
|
|
8429
|
-
* Returns true if for every element in the input collection, criteria evaluates to true.
|
|
8430
|
-
* Otherwise, the result is false.
|
|
8431
|
-
*
|
|
8432
|
-
* If the input collection is empty ({ }), the result is true.
|
|
8433
|
-
*
|
|
8434
|
-
* See: https://hl7.org/fhirpath/#allcriteria-expression-boolean
|
|
8435
|
-
*
|
|
8436
|
-
* @param input The input collection.
|
|
8437
|
-
* @param criteria The evaluation criteria.
|
|
8438
|
-
* @returns True if for every element in the input collection, criteria evaluates to true.
|
|
8439
|
-
*/
|
|
8440
|
-
all: (input, criteria) => {
|
|
8441
|
-
return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval([e]))));
|
|
8442
|
-
},
|
|
8443
|
-
/**
|
|
8444
|
-
* Takes a collection of Boolean values and returns true if all the items are true.
|
|
8445
|
-
* If unknown items are false, the result is false.
|
|
8446
|
-
* If the input is empty ({ }), the result is true.
|
|
8447
|
-
*
|
|
8448
|
-
* See: https://hl7.org/fhirpath/#alltrue-boolean
|
|
8449
|
-
*
|
|
8450
|
-
* @param input The input collection.
|
|
8451
|
-
* @param criteria The evaluation criteria.
|
|
8452
|
-
* @returns True if all the items are true.
|
|
8453
|
-
*/
|
|
8454
|
-
allTrue: (input) => {
|
|
8455
|
-
for (const value of input) {
|
|
8456
|
-
if (!value.value) {
|
|
8457
|
-
return booleanToTypedValue(false);
|
|
8458
|
-
}
|
|
8459
|
-
}
|
|
8460
|
-
return booleanToTypedValue(true);
|
|
8461
|
-
},
|
|
8462
|
-
/**
|
|
8463
|
-
* Takes a collection of Boolean values and returns true if unknown of the items are true.
|
|
8464
|
-
* If all the items are false, or if the input is empty ({ }), the result is false.
|
|
8465
|
-
*
|
|
8466
|
-
* See: https://hl7.org/fhirpath/#anytrue-boolean
|
|
8467
|
-
*
|
|
8468
|
-
* @param input The input collection.
|
|
8469
|
-
* @param criteria The evaluation criteria.
|
|
8470
|
-
* @returns True if unknown of the items are true.
|
|
8471
|
-
*/
|
|
8472
|
-
anyTrue: (input) => {
|
|
8473
|
-
for (const value of input) {
|
|
8474
|
-
if (value.value) {
|
|
8475
|
-
return booleanToTypedValue(true);
|
|
8476
|
-
}
|
|
8477
|
-
}
|
|
8478
|
-
return booleanToTypedValue(false);
|
|
8479
|
-
},
|
|
8480
|
-
/**
|
|
8481
|
-
* Takes a collection of Boolean values and returns true if all the items are false.
|
|
8482
|
-
* If unknown items are true, the result is false.
|
|
8483
|
-
* If the input is empty ({ }), the result is true.
|
|
8484
|
-
*
|
|
8485
|
-
* See: https://hl7.org/fhirpath/#allfalse-boolean
|
|
8486
|
-
*
|
|
8487
|
-
* @param input The input collection.
|
|
8488
|
-
* @param criteria The evaluation criteria.
|
|
8489
|
-
* @returns True if all the items are false.
|
|
8490
|
-
*/
|
|
8491
|
-
allFalse: (input) => {
|
|
8492
|
-
for (const value of input) {
|
|
8493
|
-
if (value.value) {
|
|
8494
|
-
return booleanToTypedValue(false);
|
|
8495
|
-
}
|
|
8496
|
-
}
|
|
8497
|
-
return booleanToTypedValue(true);
|
|
8498
|
-
},
|
|
8499
|
-
/**
|
|
8500
|
-
* Takes a collection of Boolean values and returns true if unknown of the items are false.
|
|
8501
|
-
* If all the items are true, or if the input is empty ({ }), the result is false.
|
|
8502
|
-
*
|
|
8503
|
-
* See: https://hl7.org/fhirpath/#anyfalse-boolean
|
|
8504
|
-
*
|
|
8505
|
-
* @param input The input collection.
|
|
8506
|
-
* @param criteria The evaluation criteria.
|
|
8507
|
-
* @returns True if for every element in the input collection, criteria evaluates to true.
|
|
8197
|
+
* @param criteria The evaluation criteria.
|
|
8198
|
+
* @returns True if for every element in the input collection, criteria evaluates to true.
|
|
8508
8199
|
*/
|
|
8509
8200
|
anyFalse: (input) => {
|
|
8510
8201
|
for (const value of input) {
|
|
@@ -8641,7 +8332,9 @@
|
|
|
8641
8332
|
*
|
|
8642
8333
|
* See: http://hl7.org/fhirpath/#oftypetype-type-specifier-collection
|
|
8643
8334
|
*/
|
|
8644
|
-
ofType:
|
|
8335
|
+
ofType: (input, criteria) => {
|
|
8336
|
+
return input.filter((e) => e.type === criteria.name);
|
|
8337
|
+
},
|
|
8645
8338
|
/*
|
|
8646
8339
|
* 5.3 Subsetting
|
|
8647
8340
|
*/
|
|
@@ -9694,187 +9387,510 @@
|
|
|
9694
9387
|
if (unit !== 'years' && unit !== 'months' && unit !== 'days') {
|
|
9695
9388
|
throw new Error('Invalid units');
|
|
9696
9389
|
}
|
|
9697
|
-
const age = calculateAge(startDate[0].value, endDate[0].value);
|
|
9698
|
-
return [{ type: exports.PropertyType.Quantity, value: { value: age[unit], unit } }];
|
|
9699
|
-
},
|
|
9700
|
-
/*
|
|
9701
|
-
* 6.3 Types
|
|
9702
|
-
*/
|
|
9703
|
-
/**
|
|
9704
|
-
* The is() function is supported for backwards compatibility with previous
|
|
9705
|
-
* implementations of FHIRPath. Just as with the is keyword, the type argument
|
|
9706
|
-
* is an identifier that must resolve to the name of a type in a model.
|
|
9707
|
-
*
|
|
9708
|
-
* For implementations with compile-time typing, this requires special-case
|
|
9709
|
-
* handling when processing the argument to treat it as a type specifier rather
|
|
9710
|
-
* than an identifier expression:
|
|
9711
|
-
*
|
|
9712
|
-
* @param input
|
|
9713
|
-
* @param typeAtom
|
|
9714
|
-
* @returns
|
|
9715
|
-
*/
|
|
9716
|
-
is: (input, typeAtom) => {
|
|
9717
|
-
let typeName = '';
|
|
9718
|
-
if (typeAtom instanceof SymbolAtom) {
|
|
9719
|
-
typeName = typeAtom.name;
|
|
9390
|
+
const age = calculateAge(startDate[0].value, endDate[0].value);
|
|
9391
|
+
return [{ type: exports.PropertyType.Quantity, value: { value: age[unit], unit } }];
|
|
9392
|
+
},
|
|
9393
|
+
/*
|
|
9394
|
+
* 6.3 Types
|
|
9395
|
+
*/
|
|
9396
|
+
/**
|
|
9397
|
+
* The is() function is supported for backwards compatibility with previous
|
|
9398
|
+
* implementations of FHIRPath. Just as with the is keyword, the type argument
|
|
9399
|
+
* is an identifier that must resolve to the name of a type in a model.
|
|
9400
|
+
*
|
|
9401
|
+
* For implementations with compile-time typing, this requires special-case
|
|
9402
|
+
* handling when processing the argument to treat it as a type specifier rather
|
|
9403
|
+
* than an identifier expression:
|
|
9404
|
+
*
|
|
9405
|
+
* @param input
|
|
9406
|
+
* @param typeAtom
|
|
9407
|
+
* @returns
|
|
9408
|
+
*/
|
|
9409
|
+
is: (input, typeAtom) => {
|
|
9410
|
+
let typeName = '';
|
|
9411
|
+
if (typeAtom instanceof SymbolAtom) {
|
|
9412
|
+
typeName = typeAtom.name;
|
|
9413
|
+
}
|
|
9414
|
+
else if (typeAtom instanceof DotAtom) {
|
|
9415
|
+
typeName = typeAtom.left.name + '.' + typeAtom.right.name;
|
|
9416
|
+
}
|
|
9417
|
+
if (!typeName) {
|
|
9418
|
+
return [];
|
|
9419
|
+
}
|
|
9420
|
+
return input.map((value) => ({ type: exports.PropertyType.boolean, value: fhirPathIs(value, typeName) }));
|
|
9421
|
+
},
|
|
9422
|
+
/*
|
|
9423
|
+
* 6.5 Boolean logic
|
|
9424
|
+
*/
|
|
9425
|
+
/**
|
|
9426
|
+
* 6.5.3. not() : Boolean
|
|
9427
|
+
*
|
|
9428
|
+
* Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):
|
|
9429
|
+
*
|
|
9430
|
+
* @param input
|
|
9431
|
+
* @returns
|
|
9432
|
+
*/
|
|
9433
|
+
not: (input) => {
|
|
9434
|
+
return functions.toBoolean(input).map((value) => ({ type: exports.PropertyType.boolean, value: !value.value }));
|
|
9435
|
+
},
|
|
9436
|
+
/*
|
|
9437
|
+
* Additional functions
|
|
9438
|
+
* See: https://hl7.org/fhir/fhirpath.html#functions
|
|
9439
|
+
*/
|
|
9440
|
+
/**
|
|
9441
|
+
* 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.
|
|
9442
|
+
* The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.
|
|
9443
|
+
* @param input The input collection.
|
|
9444
|
+
* @returns
|
|
9445
|
+
*/
|
|
9446
|
+
resolve: (input) => {
|
|
9447
|
+
return input
|
|
9448
|
+
.map((e) => {
|
|
9449
|
+
const value = e.value;
|
|
9450
|
+
let refStr;
|
|
9451
|
+
if (typeof value === 'string') {
|
|
9452
|
+
refStr = value;
|
|
9453
|
+
}
|
|
9454
|
+
else if (typeof value === 'object') {
|
|
9455
|
+
const ref = value;
|
|
9456
|
+
if (ref.resource) {
|
|
9457
|
+
return toTypedValue(ref.resource);
|
|
9458
|
+
}
|
|
9459
|
+
refStr = ref.reference;
|
|
9460
|
+
}
|
|
9461
|
+
if (!refStr) {
|
|
9462
|
+
return { type: exports.PropertyType.BackboneElement, value: null };
|
|
9463
|
+
}
|
|
9464
|
+
const [resourceType, id] = refStr.split('/');
|
|
9465
|
+
return { type: exports.PropertyType.BackboneElement, value: { resourceType, id } };
|
|
9466
|
+
})
|
|
9467
|
+
.filter((e) => !!e.value);
|
|
9468
|
+
},
|
|
9469
|
+
/**
|
|
9470
|
+
* The as operator can be used to treat a value as a specific type.
|
|
9471
|
+
* @param input The input value.
|
|
9472
|
+
* @returns The value as the specific type.
|
|
9473
|
+
*/
|
|
9474
|
+
as: (input) => {
|
|
9475
|
+
return input;
|
|
9476
|
+
},
|
|
9477
|
+
/*
|
|
9478
|
+
* 12. Formal Specifications
|
|
9479
|
+
*/
|
|
9480
|
+
/**
|
|
9481
|
+
* Returns the type of the input.
|
|
9482
|
+
*
|
|
9483
|
+
* 12.2. Model Information
|
|
9484
|
+
*
|
|
9485
|
+
* The model information returned by the reflection function type() is specified as an
|
|
9486
|
+
* XML Schema document (xsd) and included in this specification at the following link:
|
|
9487
|
+
* https://hl7.org/fhirpath/modelinfo.xsd
|
|
9488
|
+
*
|
|
9489
|
+
* See: https://hl7.org/fhirpath/#model-information
|
|
9490
|
+
*
|
|
9491
|
+
* @param input The input collection.
|
|
9492
|
+
* @returns
|
|
9493
|
+
*/
|
|
9494
|
+
type: (input) => {
|
|
9495
|
+
return input.map(({ value }) => {
|
|
9496
|
+
if (typeof value === 'boolean') {
|
|
9497
|
+
return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Boolean' } };
|
|
9498
|
+
}
|
|
9499
|
+
if (typeof value === 'number') {
|
|
9500
|
+
return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Integer' } };
|
|
9501
|
+
}
|
|
9502
|
+
if (value && typeof value === 'object' && 'resourceType' in value) {
|
|
9503
|
+
return {
|
|
9504
|
+
type: exports.PropertyType.BackboneElement,
|
|
9505
|
+
value: { namespace: 'FHIR', name: value.resourceType },
|
|
9506
|
+
};
|
|
9507
|
+
}
|
|
9508
|
+
return { type: exports.PropertyType.BackboneElement, value: null };
|
|
9509
|
+
});
|
|
9510
|
+
},
|
|
9511
|
+
conformsTo: (input, systemAtom) => {
|
|
9512
|
+
const system = systemAtom.eval(input)[0].value;
|
|
9513
|
+
if (!system.startsWith('http://hl7.org/fhir/StructureDefinition/')) {
|
|
9514
|
+
throw new Error('Expected a StructureDefinition URL');
|
|
9515
|
+
}
|
|
9516
|
+
const expectedResourceType = system.replace('http://hl7.org/fhir/StructureDefinition/', '');
|
|
9517
|
+
return input.map((value) => {
|
|
9518
|
+
var _a;
|
|
9519
|
+
return ({
|
|
9520
|
+
type: exports.PropertyType.boolean,
|
|
9521
|
+
value: ((_a = value.value) === null || _a === void 0 ? void 0 : _a.resourceType) === expectedResourceType,
|
|
9522
|
+
});
|
|
9523
|
+
});
|
|
9524
|
+
},
|
|
9525
|
+
};
|
|
9526
|
+
/*
|
|
9527
|
+
* Helper utilities
|
|
9528
|
+
*/
|
|
9529
|
+
function applyStringFunc(func, input, ...argsAtoms) {
|
|
9530
|
+
if (input.length === 0) {
|
|
9531
|
+
return [];
|
|
9532
|
+
}
|
|
9533
|
+
const [{ value }] = validateInput(input, 1);
|
|
9534
|
+
if (typeof value !== 'string') {
|
|
9535
|
+
throw new Error('String function cannot be called with non-string');
|
|
9536
|
+
}
|
|
9537
|
+
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); }));
|
|
9538
|
+
if (result === undefined) {
|
|
9539
|
+
return [];
|
|
9540
|
+
}
|
|
9541
|
+
if (Array.isArray(result)) {
|
|
9542
|
+
return result.map(toTypedValue);
|
|
9543
|
+
}
|
|
9544
|
+
return [toTypedValue(result)];
|
|
9545
|
+
}
|
|
9546
|
+
function applyMathFunc(func, input, ...argsAtoms) {
|
|
9547
|
+
if (input.length === 0) {
|
|
9548
|
+
return [];
|
|
9549
|
+
}
|
|
9550
|
+
const [{ value }] = validateInput(input, 1);
|
|
9551
|
+
const quantity = isQuantity(value);
|
|
9552
|
+
const numberInput = quantity ? value.value : value;
|
|
9553
|
+
if (typeof numberInput !== 'number') {
|
|
9554
|
+
throw new Error('Math function cannot be called with non-number');
|
|
9555
|
+
}
|
|
9556
|
+
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; }));
|
|
9557
|
+
const type = quantity ? exports.PropertyType.Quantity : input[0].type;
|
|
9558
|
+
const returnValue = quantity ? Object.assign(Object.assign({}, value), { value: result }) : result;
|
|
9559
|
+
return [{ type, value: returnValue }];
|
|
9560
|
+
}
|
|
9561
|
+
function validateInput(input, count) {
|
|
9562
|
+
if (input.length !== count) {
|
|
9563
|
+
throw new Error(`Expected ${count} arguments`);
|
|
9564
|
+
}
|
|
9565
|
+
for (const element of input) {
|
|
9566
|
+
if (element === null || element === undefined) {
|
|
9567
|
+
throw new Error('Expected non-null argument');
|
|
9568
|
+
}
|
|
9569
|
+
}
|
|
9570
|
+
return input;
|
|
9571
|
+
}
|
|
9572
|
+
|
|
9573
|
+
var _SymbolAtom_instances, _SymbolAtom_evalValue;
|
|
9574
|
+
class FhirPathAtom {
|
|
9575
|
+
constructor(original, child) {
|
|
9576
|
+
this.original = original;
|
|
9577
|
+
this.child = child;
|
|
9578
|
+
}
|
|
9579
|
+
eval(context) {
|
|
9580
|
+
try {
|
|
9581
|
+
if (context.length > 0) {
|
|
9582
|
+
return context.map((e) => this.child.eval([e])).flat();
|
|
9583
|
+
}
|
|
9584
|
+
else {
|
|
9585
|
+
return this.child.eval([]);
|
|
9586
|
+
}
|
|
9587
|
+
}
|
|
9588
|
+
catch (error) {
|
|
9589
|
+
throw new Error(`FhirPathError on "${this.original}": ${error}`);
|
|
9590
|
+
}
|
|
9591
|
+
}
|
|
9592
|
+
}
|
|
9593
|
+
class LiteralAtom {
|
|
9594
|
+
constructor(value) {
|
|
9595
|
+
this.value = value;
|
|
9596
|
+
}
|
|
9597
|
+
eval() {
|
|
9598
|
+
return [this.value];
|
|
9599
|
+
}
|
|
9600
|
+
}
|
|
9601
|
+
class SymbolAtom {
|
|
9602
|
+
constructor(name) {
|
|
9603
|
+
this.name = name;
|
|
9604
|
+
_SymbolAtom_instances.add(this);
|
|
9605
|
+
}
|
|
9606
|
+
eval(context) {
|
|
9607
|
+
if (this.name === '$this') {
|
|
9608
|
+
return context;
|
|
9609
|
+
}
|
|
9610
|
+
return context
|
|
9611
|
+
.map((e) => __classPrivateFieldGet(this, _SymbolAtom_instances, "m", _SymbolAtom_evalValue).call(this, e))
|
|
9612
|
+
.flat()
|
|
9613
|
+
.filter((e) => (e === null || e === void 0 ? void 0 : e.value) !== undefined);
|
|
9614
|
+
}
|
|
9615
|
+
}
|
|
9616
|
+
_SymbolAtom_instances = new WeakSet(), _SymbolAtom_evalValue = function _SymbolAtom_evalValue(typedValue) {
|
|
9617
|
+
const input = typedValue.value;
|
|
9618
|
+
if (!input || typeof input !== 'object') {
|
|
9619
|
+
return undefined;
|
|
9620
|
+
}
|
|
9621
|
+
if ('resourceType' in input && input.resourceType === this.name) {
|
|
9622
|
+
return typedValue;
|
|
9623
|
+
}
|
|
9624
|
+
return getTypedPropertyValue(typedValue, this.name);
|
|
9625
|
+
};
|
|
9626
|
+
class EmptySetAtom {
|
|
9627
|
+
eval() {
|
|
9628
|
+
return [];
|
|
9629
|
+
}
|
|
9630
|
+
}
|
|
9631
|
+
class UnaryOperatorAtom {
|
|
9632
|
+
constructor(child, impl) {
|
|
9633
|
+
this.child = child;
|
|
9634
|
+
this.impl = impl;
|
|
9635
|
+
}
|
|
9636
|
+
eval(context) {
|
|
9637
|
+
return this.impl(this.child.eval(context));
|
|
9638
|
+
}
|
|
9639
|
+
}
|
|
9640
|
+
class AsAtom {
|
|
9641
|
+
constructor(left, right) {
|
|
9642
|
+
this.left = left;
|
|
9643
|
+
this.right = right;
|
|
9644
|
+
}
|
|
9645
|
+
eval(context) {
|
|
9646
|
+
return functions.ofType(this.left.eval(context), this.right);
|
|
9647
|
+
}
|
|
9648
|
+
}
|
|
9649
|
+
class ArithemticOperatorAtom {
|
|
9650
|
+
constructor(left, right, impl) {
|
|
9651
|
+
this.left = left;
|
|
9652
|
+
this.right = right;
|
|
9653
|
+
this.impl = impl;
|
|
9654
|
+
}
|
|
9655
|
+
eval(context) {
|
|
9656
|
+
const leftEvalResult = this.left.eval(context);
|
|
9657
|
+
if (leftEvalResult.length !== 1) {
|
|
9658
|
+
return [];
|
|
9659
|
+
}
|
|
9660
|
+
const rightEvalResult = this.right.eval(context);
|
|
9661
|
+
if (rightEvalResult.length !== 1) {
|
|
9662
|
+
return [];
|
|
9663
|
+
}
|
|
9664
|
+
const leftValue = leftEvalResult[0].value;
|
|
9665
|
+
const rightValue = rightEvalResult[0].value;
|
|
9666
|
+
const leftNumber = isQuantity(leftValue) ? leftValue.value : leftValue;
|
|
9667
|
+
const rightNumber = isQuantity(rightValue) ? rightValue.value : rightValue;
|
|
9668
|
+
const result = this.impl(leftNumber, rightNumber);
|
|
9669
|
+
if (typeof result === 'boolean') {
|
|
9670
|
+
return booleanToTypedValue(result);
|
|
9671
|
+
}
|
|
9672
|
+
else if (isQuantity(leftValue)) {
|
|
9673
|
+
return [{ type: exports.PropertyType.Quantity, value: Object.assign(Object.assign({}, leftValue), { value: result }) }];
|
|
9674
|
+
}
|
|
9675
|
+
else {
|
|
9676
|
+
return [toTypedValue(result)];
|
|
9677
|
+
}
|
|
9678
|
+
}
|
|
9679
|
+
}
|
|
9680
|
+
class ConcatAtom {
|
|
9681
|
+
constructor(left, right) {
|
|
9682
|
+
this.left = left;
|
|
9683
|
+
this.right = right;
|
|
9684
|
+
}
|
|
9685
|
+
eval(context) {
|
|
9686
|
+
const leftValue = this.left.eval(context);
|
|
9687
|
+
const rightValue = this.right.eval(context);
|
|
9688
|
+
const result = [...leftValue, ...rightValue];
|
|
9689
|
+
if (result.length > 0 && result.every((e) => typeof e.value === 'string')) {
|
|
9690
|
+
return [{ type: exports.PropertyType.string, value: result.map((e) => e.value).join('') }];
|
|
9691
|
+
}
|
|
9692
|
+
return result;
|
|
9693
|
+
}
|
|
9694
|
+
}
|
|
9695
|
+
class ContainsAtom {
|
|
9696
|
+
constructor(left, right) {
|
|
9697
|
+
this.left = left;
|
|
9698
|
+
this.right = right;
|
|
9699
|
+
}
|
|
9700
|
+
eval(context) {
|
|
9701
|
+
const leftValue = this.left.eval(context);
|
|
9702
|
+
const rightValue = this.right.eval(context);
|
|
9703
|
+
return booleanToTypedValue(leftValue.some((e) => e.value === rightValue[0].value));
|
|
9704
|
+
}
|
|
9705
|
+
}
|
|
9706
|
+
class InAtom {
|
|
9707
|
+
constructor(left, right) {
|
|
9708
|
+
this.left = left;
|
|
9709
|
+
this.right = right;
|
|
9710
|
+
}
|
|
9711
|
+
eval(context) {
|
|
9712
|
+
const leftValue = this.left.eval(context);
|
|
9713
|
+
const rightValue = this.right.eval(context);
|
|
9714
|
+
return booleanToTypedValue(rightValue.some((e) => e.value === leftValue[0].value));
|
|
9715
|
+
}
|
|
9716
|
+
}
|
|
9717
|
+
class DotAtom {
|
|
9718
|
+
constructor(left, right) {
|
|
9719
|
+
this.left = left;
|
|
9720
|
+
this.right = right;
|
|
9721
|
+
}
|
|
9722
|
+
eval(context) {
|
|
9723
|
+
return this.right.eval(this.left.eval(context));
|
|
9724
|
+
}
|
|
9725
|
+
}
|
|
9726
|
+
class UnionAtom {
|
|
9727
|
+
constructor(left, right) {
|
|
9728
|
+
this.left = left;
|
|
9729
|
+
this.right = right;
|
|
9730
|
+
}
|
|
9731
|
+
eval(context) {
|
|
9732
|
+
const leftResult = this.left.eval(context);
|
|
9733
|
+
const rightResult = this.right.eval(context);
|
|
9734
|
+
return removeDuplicates([...leftResult, ...rightResult]);
|
|
9735
|
+
}
|
|
9736
|
+
}
|
|
9737
|
+
class EqualsAtom {
|
|
9738
|
+
constructor(left, right) {
|
|
9739
|
+
this.left = left;
|
|
9740
|
+
this.right = right;
|
|
9741
|
+
}
|
|
9742
|
+
eval(context) {
|
|
9743
|
+
const leftValue = this.left.eval(context);
|
|
9744
|
+
const rightValue = this.right.eval(context);
|
|
9745
|
+
return fhirPathArrayEquals(leftValue, rightValue);
|
|
9746
|
+
}
|
|
9747
|
+
}
|
|
9748
|
+
class NotEqualsAtom {
|
|
9749
|
+
constructor(left, right) {
|
|
9750
|
+
this.left = left;
|
|
9751
|
+
this.right = right;
|
|
9752
|
+
}
|
|
9753
|
+
eval(context) {
|
|
9754
|
+
const leftValue = this.left.eval(context);
|
|
9755
|
+
const rightValue = this.right.eval(context);
|
|
9756
|
+
return fhirPathNot(fhirPathArrayEquals(leftValue, rightValue));
|
|
9757
|
+
}
|
|
9758
|
+
}
|
|
9759
|
+
class EquivalentAtom {
|
|
9760
|
+
constructor(left, right) {
|
|
9761
|
+
this.left = left;
|
|
9762
|
+
this.right = right;
|
|
9763
|
+
}
|
|
9764
|
+
eval(context) {
|
|
9765
|
+
const leftValue = this.left.eval(context);
|
|
9766
|
+
const rightValue = this.right.eval(context);
|
|
9767
|
+
return fhirPathArrayEquivalent(leftValue, rightValue);
|
|
9768
|
+
}
|
|
9769
|
+
}
|
|
9770
|
+
class NotEquivalentAtom {
|
|
9771
|
+
constructor(left, right) {
|
|
9772
|
+
this.left = left;
|
|
9773
|
+
this.right = right;
|
|
9774
|
+
}
|
|
9775
|
+
eval(context) {
|
|
9776
|
+
const leftValue = this.left.eval(context);
|
|
9777
|
+
const rightValue = this.right.eval(context);
|
|
9778
|
+
return fhirPathNot(fhirPathArrayEquivalent(leftValue, rightValue));
|
|
9779
|
+
}
|
|
9780
|
+
}
|
|
9781
|
+
class IsAtom {
|
|
9782
|
+
constructor(left, right) {
|
|
9783
|
+
this.left = left;
|
|
9784
|
+
this.right = right;
|
|
9785
|
+
}
|
|
9786
|
+
eval(context) {
|
|
9787
|
+
const leftValue = this.left.eval(context);
|
|
9788
|
+
if (leftValue.length !== 1) {
|
|
9789
|
+
return [];
|
|
9790
|
+
}
|
|
9791
|
+
const typeName = this.right.name;
|
|
9792
|
+
return booleanToTypedValue(fhirPathIs(leftValue[0], typeName));
|
|
9793
|
+
}
|
|
9794
|
+
}
|
|
9795
|
+
/**
|
|
9796
|
+
* 6.5.1. and
|
|
9797
|
+
* Returns true if both operands evaluate to true,
|
|
9798
|
+
* false if either operand evaluates to false,
|
|
9799
|
+
* and the empty collection otherwise.
|
|
9800
|
+
*/
|
|
9801
|
+
class AndAtom {
|
|
9802
|
+
constructor(left, right) {
|
|
9803
|
+
this.left = left;
|
|
9804
|
+
this.right = right;
|
|
9805
|
+
}
|
|
9806
|
+
eval(context) {
|
|
9807
|
+
var _a, _b, _c, _d;
|
|
9808
|
+
const leftValue = this.left.eval(context);
|
|
9809
|
+
const rightValue = this.right.eval(context);
|
|
9810
|
+
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) {
|
|
9811
|
+
return booleanToTypedValue(true);
|
|
9720
9812
|
}
|
|
9721
|
-
|
|
9722
|
-
|
|
9813
|
+
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) {
|
|
9814
|
+
return booleanToTypedValue(false);
|
|
9723
9815
|
}
|
|
9724
|
-
|
|
9725
|
-
|
|
9816
|
+
return [];
|
|
9817
|
+
}
|
|
9818
|
+
}
|
|
9819
|
+
class OrAtom {
|
|
9820
|
+
constructor(left, right) {
|
|
9821
|
+
this.left = left;
|
|
9822
|
+
this.right = right;
|
|
9823
|
+
}
|
|
9824
|
+
eval(context) {
|
|
9825
|
+
const leftValue = this.left.eval(context);
|
|
9826
|
+
if (toJsBoolean(leftValue)) {
|
|
9827
|
+
return leftValue;
|
|
9726
9828
|
}
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
* 6.5 Boolean logic
|
|
9731
|
-
*/
|
|
9732
|
-
/**
|
|
9733
|
-
* 6.5.3. not() : Boolean
|
|
9734
|
-
*
|
|
9735
|
-
* Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):
|
|
9736
|
-
*
|
|
9737
|
-
* @param input
|
|
9738
|
-
* @returns
|
|
9739
|
-
*/
|
|
9740
|
-
not: (input) => {
|
|
9741
|
-
return functions.toBoolean(input).map((value) => ({ type: exports.PropertyType.boolean, value: !value.value }));
|
|
9742
|
-
},
|
|
9743
|
-
/*
|
|
9744
|
-
* Additional functions
|
|
9745
|
-
* See: https://hl7.org/fhir/fhirpath.html#functions
|
|
9746
|
-
*/
|
|
9747
|
-
/**
|
|
9748
|
-
* 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.
|
|
9749
|
-
* The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.
|
|
9750
|
-
* @param input The input collection.
|
|
9751
|
-
* @returns
|
|
9752
|
-
*/
|
|
9753
|
-
resolve: (input) => {
|
|
9754
|
-
return input
|
|
9755
|
-
.map((e) => {
|
|
9756
|
-
const value = e.value;
|
|
9757
|
-
let refStr;
|
|
9758
|
-
if (typeof value === 'string') {
|
|
9759
|
-
refStr = value;
|
|
9760
|
-
}
|
|
9761
|
-
else if (typeof value === 'object') {
|
|
9762
|
-
const ref = value;
|
|
9763
|
-
if (ref.resource) {
|
|
9764
|
-
return toTypedValue(ref.resource);
|
|
9765
|
-
}
|
|
9766
|
-
refStr = ref.reference;
|
|
9767
|
-
}
|
|
9768
|
-
if (!refStr) {
|
|
9769
|
-
return { type: exports.PropertyType.BackboneElement, value: null };
|
|
9770
|
-
}
|
|
9771
|
-
const [resourceType, id] = refStr.split('/');
|
|
9772
|
-
return { type: exports.PropertyType.BackboneElement, value: { resourceType, id } };
|
|
9773
|
-
})
|
|
9774
|
-
.filter((e) => !!e.value);
|
|
9775
|
-
},
|
|
9776
|
-
/**
|
|
9777
|
-
* The as operator can be used to treat a value as a specific type.
|
|
9778
|
-
* @param input The input value.
|
|
9779
|
-
* @returns The value as the specific type.
|
|
9780
|
-
*/
|
|
9781
|
-
as: (input) => {
|
|
9782
|
-
return input;
|
|
9783
|
-
},
|
|
9784
|
-
/*
|
|
9785
|
-
* 12. Formal Specifications
|
|
9786
|
-
*/
|
|
9787
|
-
/**
|
|
9788
|
-
* Returns the type of the input.
|
|
9789
|
-
*
|
|
9790
|
-
* 12.2. Model Information
|
|
9791
|
-
*
|
|
9792
|
-
* The model information returned by the reflection function type() is specified as an
|
|
9793
|
-
* XML Schema document (xsd) and included in this specification at the following link:
|
|
9794
|
-
* https://hl7.org/fhirpath/modelinfo.xsd
|
|
9795
|
-
*
|
|
9796
|
-
* See: https://hl7.org/fhirpath/#model-information
|
|
9797
|
-
*
|
|
9798
|
-
* @param input The input collection.
|
|
9799
|
-
* @returns
|
|
9800
|
-
*/
|
|
9801
|
-
type: (input) => {
|
|
9802
|
-
return input.map(({ value }) => {
|
|
9803
|
-
if (typeof value === 'boolean') {
|
|
9804
|
-
return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Boolean' } };
|
|
9805
|
-
}
|
|
9806
|
-
if (typeof value === 'number') {
|
|
9807
|
-
return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Integer' } };
|
|
9808
|
-
}
|
|
9809
|
-
if (value && typeof value === 'object' && 'resourceType' in value) {
|
|
9810
|
-
return {
|
|
9811
|
-
type: exports.PropertyType.BackboneElement,
|
|
9812
|
-
value: { namespace: 'FHIR', name: value.resourceType },
|
|
9813
|
-
};
|
|
9814
|
-
}
|
|
9815
|
-
return { type: exports.PropertyType.BackboneElement, value: null };
|
|
9816
|
-
});
|
|
9817
|
-
},
|
|
9818
|
-
conformsTo: (input, systemAtom) => {
|
|
9819
|
-
const system = systemAtom.eval(input)[0].value;
|
|
9820
|
-
if (!system.startsWith('http://hl7.org/fhir/StructureDefinition/')) {
|
|
9821
|
-
throw new Error('Expected a StructureDefinition URL');
|
|
9829
|
+
const rightValue = this.right.eval(context);
|
|
9830
|
+
if (toJsBoolean(rightValue)) {
|
|
9831
|
+
return rightValue;
|
|
9822
9832
|
}
|
|
9823
|
-
const expectedResourceType = system.replace('http://hl7.org/fhir/StructureDefinition/', '');
|
|
9824
|
-
return input.map((value) => {
|
|
9825
|
-
var _a;
|
|
9826
|
-
return ({
|
|
9827
|
-
type: exports.PropertyType.boolean,
|
|
9828
|
-
value: ((_a = value.value) === null || _a === void 0 ? void 0 : _a.resourceType) === expectedResourceType,
|
|
9829
|
-
});
|
|
9830
|
-
});
|
|
9831
|
-
},
|
|
9832
|
-
};
|
|
9833
|
-
/*
|
|
9834
|
-
* Helper utilities
|
|
9835
|
-
*/
|
|
9836
|
-
function applyStringFunc(func, input, ...argsAtoms) {
|
|
9837
|
-
if (input.length === 0) {
|
|
9838
9833
|
return [];
|
|
9839
9834
|
}
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9835
|
+
}
|
|
9836
|
+
/**
|
|
9837
|
+
* 6.5.4. xor
|
|
9838
|
+
* Returns true if exactly one of the operands evaluates to true,
|
|
9839
|
+
* false if either both operands evaluate to true or both operands evaluate to false,
|
|
9840
|
+
* and the empty collection otherwise.
|
|
9841
|
+
*/
|
|
9842
|
+
class XorAtom {
|
|
9843
|
+
constructor(left, right) {
|
|
9844
|
+
this.left = left;
|
|
9845
|
+
this.right = right;
|
|
9843
9846
|
}
|
|
9844
|
-
|
|
9845
|
-
|
|
9847
|
+
eval(context) {
|
|
9848
|
+
const leftResult = this.left.eval(context);
|
|
9849
|
+
const rightResult = this.right.eval(context);
|
|
9850
|
+
if (leftResult.length === 0 && rightResult.length === 0) {
|
|
9851
|
+
return [];
|
|
9852
|
+
}
|
|
9853
|
+
const leftValue = leftResult.length === 0 ? null : leftResult[0].value;
|
|
9854
|
+
const rightValue = rightResult.length === 0 ? null : rightResult[0].value;
|
|
9855
|
+
if ((leftValue === true && rightValue !== true) || (leftValue !== true && rightValue === true)) {
|
|
9856
|
+
return booleanToTypedValue(true);
|
|
9857
|
+
}
|
|
9858
|
+
if ((leftValue === true && rightValue === true) || (leftValue === false && rightValue === false)) {
|
|
9859
|
+
return booleanToTypedValue(false);
|
|
9860
|
+
}
|
|
9846
9861
|
return [];
|
|
9847
9862
|
}
|
|
9848
|
-
if (Array.isArray(result)) {
|
|
9849
|
-
return result.map(toTypedValue);
|
|
9850
|
-
}
|
|
9851
|
-
return [toTypedValue(result)];
|
|
9852
9863
|
}
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
|
|
9864
|
+
class FunctionAtom {
|
|
9865
|
+
constructor(name, args, impl) {
|
|
9866
|
+
this.name = name;
|
|
9867
|
+
this.args = args;
|
|
9868
|
+
this.impl = impl;
|
|
9856
9869
|
}
|
|
9857
|
-
|
|
9858
|
-
|
|
9859
|
-
const numberInput = quantity ? value.value : value;
|
|
9860
|
-
if (typeof numberInput !== 'number') {
|
|
9861
|
-
throw new Error('Math function cannot be called with non-number');
|
|
9870
|
+
eval(context) {
|
|
9871
|
+
return this.impl(context, ...this.args);
|
|
9862
9872
|
}
|
|
9863
|
-
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; }));
|
|
9864
|
-
const type = quantity ? exports.PropertyType.Quantity : input[0].type;
|
|
9865
|
-
const returnValue = quantity ? Object.assign(Object.assign({}, value), { value: result }) : result;
|
|
9866
|
-
return [{ type, value: returnValue }];
|
|
9867
9873
|
}
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9874
|
+
class IndexerAtom {
|
|
9875
|
+
constructor(left, expr) {
|
|
9876
|
+
this.left = left;
|
|
9877
|
+
this.expr = expr;
|
|
9871
9878
|
}
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9879
|
+
eval(context) {
|
|
9880
|
+
const evalResult = this.expr.eval(context);
|
|
9881
|
+
if (evalResult.length !== 1) {
|
|
9882
|
+
return [];
|
|
9883
|
+
}
|
|
9884
|
+
const index = evalResult[0].value;
|
|
9885
|
+
if (typeof index !== 'number') {
|
|
9886
|
+
throw new Error(`Invalid indexer expression: should return integer}`);
|
|
9887
|
+
}
|
|
9888
|
+
const leftResult = this.left.eval(context);
|
|
9889
|
+
if (!(index in leftResult)) {
|
|
9890
|
+
return [];
|
|
9875
9891
|
}
|
|
9892
|
+
return [leftResult[index]];
|
|
9876
9893
|
}
|
|
9877
|
-
return input;
|
|
9878
9894
|
}
|
|
9879
9895
|
|
|
9880
9896
|
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;
|
|
@@ -11008,7 +11024,6 @@
|
|
|
11008
11024
|
exports.capitalize = capitalize;
|
|
11009
11025
|
exports.createReference = createReference;
|
|
11010
11026
|
exports.createSchema = createSchema;
|
|
11011
|
-
exports.createTypeSchema = createTypeSchema;
|
|
11012
11027
|
exports.created = created;
|
|
11013
11028
|
exports.deepClone = deepClone;
|
|
11014
11029
|
exports.deepEquals = deepEquals$1;
|