@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.
@@ -1 +1 @@
1
- {"version":3,"file":"functions.js","sources":["../../../src/fhirpath/functions.ts"],"sourcesContent":["import { Reference, Resource } from '@medplum/fhirtypes';\nimport { PropertyType } from '../types';\nimport { calculateAge } from '../utils';\nimport { Atom, DotAtom, SymbolAtom, TypedValue } from './atoms';\nimport { parseDateString } from './date';\nimport { booleanToTypedValue, fhirPathIs, isQuantity, removeDuplicates, toJsBoolean, toTypedValue } from './utils';\n\n/*\n * Collection of FHIRPath\n * See: https://hl7.org/fhirpath/#functions\n */\n\nexport interface FhirPathFunction {\n (input: TypedValue[], ...args: Atom[]): TypedValue[];\n}\n\n/**\n * Temporary placholder for unimplemented methods.\n */\nconst stub: FhirPathFunction = (): [] => [];\n\nexport const functions: Record<string, FhirPathFunction> = {\n /*\n * 5.1 Existence\n * See: https://hl7.org/fhirpath/#existence\n */\n\n /**\n * Returns true if the input collection is empty ({ }) and false otherwise.\n *\n * See: https://hl7.org/fhirpath/#empty-boolean\n *\n * @param input The input collection.\n * @returns True if the input collection is empty ({ }) and false otherwise.\n */\n empty: (input: TypedValue[]): TypedValue[] => {\n return booleanToTypedValue(input.length === 0);\n },\n\n /**\n * Returns true if the collection has unknown elements, and false otherwise.\n * This is the opposite of empty(), and as such is a shorthand for empty().not().\n * If the input collection is empty ({ }), the result is false.\n *\n * The function can also take an optional criteria to be applied to the collection\n * prior to the determination of the exists. In this case, the function is shorthand\n * for where(criteria).exists().\n *\n * See: https://hl7.org/fhirpath/#existscriteria-expression-boolean\n *\n * @param input\n * @param criteria\n * @returns True if the collection has unknown elements, and false otherwise.\n */\n exists: (input: TypedValue[], criteria?: Atom): TypedValue[] => {\n if (criteria) {\n return booleanToTypedValue(input.filter((e) => toJsBoolean(criteria.eval([e]))).length > 0);\n } else {\n return booleanToTypedValue(input.length > 0);\n }\n },\n\n /**\n * Returns true if for every element in the input collection, criteria evaluates to true.\n * Otherwise, the result is false.\n *\n * If the input collection is empty ({ }), the result is true.\n *\n * See: https://hl7.org/fhirpath/#allcriteria-expression-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if for every element in the input collection, criteria evaluates to true.\n */\n all: (input: TypedValue[], criteria: Atom): TypedValue[] => {\n return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval([e]))));\n },\n\n /**\n * Takes a collection of Boolean values and returns true if all the items are true.\n * If unknown items are false, the result is false.\n * If the input is empty ({ }), the result is true.\n *\n * See: https://hl7.org/fhirpath/#alltrue-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if all the items are true.\n */\n allTrue: (input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (!value.value) {\n return booleanToTypedValue(false);\n }\n }\n return booleanToTypedValue(true);\n },\n\n /**\n * Takes a collection of Boolean values and returns true if unknown of the items are true.\n * If all the items are false, or if the input is empty ({ }), the result is false.\n *\n * See: https://hl7.org/fhirpath/#anytrue-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if unknown of the items are true.\n */\n anyTrue: (input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (value.value) {\n return booleanToTypedValue(true);\n }\n }\n return booleanToTypedValue(false);\n },\n\n /**\n * Takes a collection of Boolean values and returns true if all the items are false.\n * If unknown items are true, the result is false.\n * If the input is empty ({ }), the result is true.\n *\n * See: https://hl7.org/fhirpath/#allfalse-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if all the items are false.\n */\n allFalse: (input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (value.value) {\n return booleanToTypedValue(false);\n }\n }\n return booleanToTypedValue(true);\n },\n\n /**\n * Takes a collection of Boolean values and returns true if unknown of the items are false.\n * If all the items are true, or if the input is empty ({ }), the result is false.\n *\n * See: https://hl7.org/fhirpath/#anyfalse-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if for every element in the input collection, criteria evaluates to true.\n */\n anyFalse: (input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (!value.value) {\n return booleanToTypedValue(true);\n }\n }\n return booleanToTypedValue(false);\n },\n\n /**\n * Returns true if all items in the input collection are members of the collection passed\n * as the other argument. Membership is determined using the = (Equals) (=) operation.\n *\n * Conceptually, this function is evaluated by testing each element in the input collection\n * for membership in the other collection, with a default of true. This means that if the\n * input collection is empty ({ }), the result is true, otherwise if the other collection\n * is empty ({ }), the result is false.\n *\n * See: http://hl7.org/fhirpath/#subsetofother-collection-boolean\n */\n subsetOf: stub,\n\n /**\n * Returns true if all items in the collection passed as the other argument are members of\n * the input collection. Membership is determined using the = (Equals) (=) operation.\n *\n * Conceptually, this function is evaluated by testing each element in the other collection\n * for membership in the input collection, with a default of true. This means that if the\n * other collection is empty ({ }), the result is true, otherwise if the input collection\n * is empty ({ }), the result is false.\n *\n * See: http://hl7.org/fhirpath/#supersetofother-collection-boolean\n */\n supersetOf: stub,\n\n /**\n * Returns the integer count of the number of items in the input collection.\n * Returns 0 when the input collection is empty.\n *\n * See: https://hl7.org/fhirpath/#count-integer\n *\n * @param input The input collection.\n * @returns The integer count of the number of items in the input collection.\n */\n count: (input: TypedValue[]): TypedValue[] => {\n return [{ type: PropertyType.integer, value: input.length }];\n },\n\n /**\n * Returns a collection containing only the unique items in the input collection.\n * To determine whether two items are the same, the = (Equals) (=) operator is used,\n * as defined below.\n *\n * If the input collection is empty ({ }), the result is empty.\n *\n * Note that the order of elements in the input collection is not guaranteed to be\n * preserved in the result.\n *\n * See: https://hl7.org/fhirpath/#distinct-collection\n *\n * @param input The input collection.\n * @returns The integer count of the number of items in the input collection.\n */\n distinct: (input: TypedValue[]): TypedValue[] => {\n const result: TypedValue[] = [];\n for (const value of input) {\n if (!result.some((e) => e.value === value.value)) {\n result.push(value);\n }\n }\n return result;\n },\n\n /**\n * Returns true if all the items in the input collection are distinct.\n * To determine whether two items are distinct, the = (Equals) (=) operator is used,\n * as defined below.\n *\n * See: https://hl7.org/fhirpath/#isdistinct-boolean\n *\n * @param input The input collection.\n * @returns The integer count of the number of items in the input collection.\n */\n isDistinct: (input: TypedValue[]): TypedValue[] => {\n return booleanToTypedValue(input.length === functions.distinct(input).length);\n },\n\n /*\n * 5.2 Filtering and projection\n */\n\n /**\n * Returns a collection containing only those elements in the input collection\n * for which the stated criteria expression evaluates to true.\n * Elements for which the expression evaluates to false or empty ({ }) are not\n * included in the result.\n *\n * If the input collection is empty ({ }), the result is empty.\n *\n * If the result of evaluating the condition is other than a single boolean value,\n * the evaluation will end and signal an error to the calling environment,\n * consistent with singleton evaluation of collections behavior.\n *\n * See: https://hl7.org/fhirpath/#wherecriteria-expression-collection\n *\n * @param input The input collection.\n * @param condition The condition atom.\n * @returns A collection containing only those elements in the input collection for which the stated criteria expression evaluates to true.\n */\n where: (input: TypedValue[], criteria: Atom): TypedValue[] => {\n return input.filter((e) => toJsBoolean(criteria.eval([e])));\n },\n\n /**\n * Evaluates the projection expression for each item in the input collection.\n * The result of each evaluation is added to the output collection. If the\n * evaluation results in a collection with multiple items, all items are added\n * to the output collection (collections resulting from evaluation of projection\n * are flattened). This means that if the evaluation for an element results in\n * the empty collection ({ }), no element is added to the result, and that if\n * the input collection is empty ({ }), the result is empty as well.\n *\n * See: http://hl7.org/fhirpath/#selectprojection-expression-collection\n */\n select: (input: TypedValue[], criteria: Atom): TypedValue[] => {\n return input.map((e) => criteria.eval([e])).flat();\n },\n\n /**\n * A version of select that will repeat the projection and add it to the output\n * collection, as long as the projection yields new items (as determined by\n * the = (Equals) (=) operator).\n *\n * See: http://hl7.org/fhirpath/#repeatprojection-expression-collection\n */\n repeat: stub,\n\n /**\n * Returns a collection that contains all items in the input collection that\n * are of the given type or a subclass thereof. If the input collection is\n * empty ({ }), the result is empty. The type argument is an identifier that\n * must resolve to the name of a type in a model\n *\n * See: http://hl7.org/fhirpath/#oftypetype-type-specifier-collection\n */\n ofType: stub,\n\n /*\n * 5.3 Subsetting\n */\n\n /**\n * Will return the single item in the input if there is just one item.\n * If the input collection is empty ({ }), the result is empty.\n * If there are multiple items, an error is signaled to the evaluation environment.\n * This function is useful for ensuring that an error is returned if an assumption\n * about cardinality is violated at run-time.\n *\n * See: https://hl7.org/fhirpath/#single-collection\n *\n * @param input The input collection.\n * @returns The single item in the input if there is just one item.\n */\n single: (input: TypedValue[]): TypedValue[] => {\n if (input.length > 1) {\n throw new Error('Expected input length one for single()');\n }\n return input.length === 0 ? [] : input.slice(0, 1);\n },\n\n /**\n * Returns a collection containing only the first item in the input collection.\n * This function is equivalent to item[0], so it will return an empty collection if the input collection has no items.\n *\n * See: https://hl7.org/fhirpath/#first-collection\n *\n * @param input The input collection.\n * @returns A collection containing only the first item in the input collection.\n */\n first: (input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(0, 1);\n },\n\n /**\n * Returns a collection containing only the last item in the input collection.\n * Will return an empty collection if the input collection has no items.\n *\n * See: https://hl7.org/fhirpath/#last-collection\n *\n * @param input The input collection.\n * @returns A collection containing only the last item in the input collection.\n */\n last: (input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(input.length - 1, input.length);\n },\n\n /**\n * Returns a collection containing all but the first item in the input collection.\n * Will return an empty collection if the input collection has no items, or only one item.\n *\n * See: https://hl7.org/fhirpath/#tail-collection\n *\n * @param input The input collection.\n * @returns A collection containing all but the first item in the input collection.\n */\n tail: (input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(1, input.length);\n },\n\n /**\n * Returns a collection containing all but the first num items in the input collection.\n * Will return an empty collection if there are no items remaining after the\n * indicated number of items have been skipped, or if the input collection is empty.\n * If num is less than or equal to zero, the input collection is simply returned.\n *\n * See: https://hl7.org/fhirpath/#skipnum-integer-collection\n *\n * @param input The input collection.\n * @returns A collection containing all but the first item in the input collection.\n */\n skip: (input: TypedValue[], num: Atom): TypedValue[] => {\n const numValue = num.eval(input)[0]?.value;\n if (typeof numValue !== 'number') {\n throw new Error('Expected a number for skip(num)');\n }\n if (numValue >= input.length) {\n return [];\n }\n if (numValue <= 0) {\n return input;\n }\n return input.slice(numValue, input.length);\n },\n\n /**\n * Returns a collection containing the first num items in the input collection,\n * or less if there are less than num items.\n * If num is less than or equal to 0, or if the input collection is empty ({ }),\n * take returns an empty collection.\n *\n * See: https://hl7.org/fhirpath/#takenum-integer-collection\n *\n * @param input The input collection.\n * @returns A collection containing the first num items in the input collection.\n */\n take: (input: TypedValue[], num: Atom): TypedValue[] => {\n const numValue = num.eval(input)[0]?.value;\n if (typeof numValue !== 'number') {\n throw new Error('Expected a number for take(num)');\n }\n if (numValue >= input.length) {\n return input;\n }\n if (numValue <= 0) {\n return [];\n }\n return input.slice(0, numValue);\n },\n\n /**\n * Returns the set of elements that are in both collections.\n * Duplicate items will be eliminated by this function.\n * Order of items is not guaranteed to be preserved in the result of this function.\n *\n * See: http://hl7.org/fhirpath/#intersectother-collection-collection\n */\n intersect: (input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(input);\n const result: TypedValue[] = [];\n for (const value of input) {\n if (!result.some((e) => e.value === value.value) && otherArray.some((e) => e.value === value.value)) {\n result.push(value);\n }\n }\n return result;\n },\n\n /**\n * Returns the set of elements that are not in the other collection.\n * Duplicate items will not be eliminated by this function, and order will be preserved.\n *\n * e.g. (1 | 2 | 3).exclude(2) returns (1 | 3).\n *\n * See: http://hl7.org/fhirpath/#excludeother-collection-collection\n */\n exclude: (input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(input);\n const result: TypedValue[] = [];\n for (const value of input) {\n if (!otherArray.some((e) => e.value === value.value)) {\n result.push(value);\n }\n }\n return result;\n },\n\n /*\n * 5.4. Combining\n *\n * See: https://hl7.org/fhirpath/#combining\n */\n\n /**\n * Merge the two collections into a single collection,\n * eliminating unknown duplicate values (using = (Equals) (=) to determine equality).\n * There is no expectation of order in the resulting collection.\n *\n * In other words, this function returns the distinct list of elements from both inputs.\n *\n * See: http://hl7.org/fhirpath/#unionother-collection\n */\n union: (input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(input);\n return removeDuplicates([...input, ...otherArray]);\n },\n\n /**\n * Merge the input and other collections into a single collection\n * without eliminating duplicate values. Combining an empty collection\n * with a non-empty collection will return the non-empty collection.\n *\n * There is no expectation of order in the resulting collection.\n *\n * See: http://hl7.org/fhirpath/#combineother-collection-collection\n */\n combine: (input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(input);\n return [...input, ...otherArray];\n },\n\n /*\n * 5.5. Conversion\n *\n * See: https://hl7.org/fhirpath/#conversion\n */\n\n /**\n * The iif function in FHIRPath is an immediate if,\n * also known as a conditional operator (such as C’s ? : operator).\n *\n * The criterion expression is expected to evaluate to a Boolean.\n *\n * If criterion is true, the function returns the value of the true-result argument.\n *\n * If criterion is false or an empty collection, the function returns otherwise-result,\n * unless the optional otherwise-result is not given, in which case the function returns an empty collection.\n *\n * Note that short-circuit behavior is expected in this function. In other words,\n * true-result should only be evaluated if the criterion evaluates to true,\n * and otherwise-result should only be evaluated otherwise. For implementations,\n * this means delaying evaluation of the arguments.\n *\n * @param input\n * @param criterion\n * @param trueResult\n * @param otherwiseResult\n * @returns\n */\n iif: (input: TypedValue[], criterion: Atom, trueResult: Atom, otherwiseResult?: Atom): TypedValue[] => {\n const evalResult = criterion.eval(input);\n if (evalResult.length > 1 || (evalResult.length === 1 && typeof evalResult[0].value !== 'boolean')) {\n throw new Error('Expected criterion to evaluate to a Boolean');\n }\n\n if (toJsBoolean(evalResult)) {\n return trueResult.eval(input);\n }\n\n if (otherwiseResult) {\n return otherwiseResult.eval(input);\n }\n\n return [];\n },\n\n /**\n * Converts an input collection to a boolean.\n *\n * If the input collection contains a single item, this function will return a single boolean if:\n * 1) the item is a Boolean\n * 2) the item is an Integer and is equal to one of the possible integer representations of Boolean values\n * 3) the item is a Decimal that is equal to one of the possible decimal representations of Boolean values\n * 4) the item is a String that is equal to one of the possible string representations of Boolean values\n *\n * If the item is not one the above types, or the item is a String, Integer, or Decimal, but is not equal to one of the possible values convertible to a Boolean, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#toboolean-boolean\n *\n * @param input\n * @returns\n */\n toBoolean: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.boolean, value }];\n }\n if (typeof value === 'number') {\n if (value === 0 || value === 1) {\n return booleanToTypedValue(!!value);\n }\n }\n if (typeof value === 'string') {\n const lowerStr = value.toLowerCase();\n if (['true', 't', 'yes', 'y', '1', '1.0'].includes(lowerStr)) {\n return booleanToTypedValue(true);\n }\n if (['false', 'f', 'no', 'n', '0', '0.0'].includes(lowerStr)) {\n return booleanToTypedValue(false);\n }\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a Boolean\n * 2) the item is an Integer that is equal to one of the possible integer representations of Boolean values\n * 3) the item is a Decimal that is equal to one of the possible decimal representations of Boolean values\n * 4) the item is a String that is equal to one of the possible string representations of Boolean values\n *\n * If the item is not one of the above types, or the item is a String, Integer, or Decimal, but is not equal to one of the possible values convertible to a Boolean, the result is false.\n *\n * Possible values for Integer, Decimal, and String are described in the toBoolean() function.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: http://hl7.org/fhirpath/#convertstoboolean-boolean\n *\n * @param input\n * @returns\n */\n convertsToBoolean: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toBoolean(input).length === 1);\n },\n\n /**\n * Returns the integer representation of the input.\n *\n * If the input collection contains a single item, this function will return a single integer if:\n * 1) the item is an Integer\n * 2) the item is a String and is convertible to an integer\n * 3) the item is a Boolean, where true results in a 1 and false results in a 0.\n *\n * If the item is not one the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to an integer (using the regex format (\\\\+|-)?\\d+), the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#tointeger-integer\n *\n * @param input The input collection.\n * @returns The string representation of the input.\n */\n toInteger: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'number') {\n return [{ type: PropertyType.integer, value }];\n }\n if (typeof value === 'string' && value.match(/^[+-]?\\d+$/)) {\n return [{ type: PropertyType.integer, value: parseInt(value, 10) }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.integer, value: value ? 1 : 0 }];\n }\n return [];\n },\n\n /**\n * Returns true if the input can be converted to string.\n *\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is an Integer\n * 2) the item is a String and is convertible to an Integer\n * 3) the item is a Boolean\n * 4) If the item is not one of the above types, or the item is a String, but is not convertible to an Integer (using the regex format (\\\\+|-)?\\d+), the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#convertstointeger-boolean\n *\n * @param input The input collection.\n * @returns\n */\n convertsToInteger: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toInteger(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single date if:\n * 1) the item is a Date\n * 2) the item is a DateTime\n * 3) the item is a String and is convertible to a Date\n *\n * If the item is not one of the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to a Date (using the format YYYY-MM-DD), the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#todate-date\n */\n toDate: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'string' && value.match(/^\\d{4}(-\\d{2}(-\\d{2})?)?/)) {\n return [{ type: PropertyType.date, value: parseDateString(value) }];\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a Date\n * 2) the item is a DateTime\n * 3) the item is a String and is convertible to a Date\n *\n * If the item is not one of the above types, or is not convertible to a Date (using the format YYYY-MM-DD), the result is false.\n *\n * If the item contains a partial date (e.g. '2012-01'), the result is a partial date.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#convertstodate-boolean\n */\n convertsToDate: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toDate(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single datetime if:\n * 1) the item is a DateTime\n * 2) the item is a Date, in which case the result is a DateTime with the year, month, and day of the Date, and the time components empty (not set to zero)\n * 3) the item is a String and is convertible to a DateTime\n *\n * If the item is not one of the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to a DateTime (using the format YYYY-MM-DDThh:mm:ss.fff(+|-)hh:mm), the result is empty.\n *\n * If the item contains a partial datetime (e.g. '2012-01-01T10:00'), the result is a partial datetime.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n\n * See: https://hl7.org/fhirpath/#todatetime-datetime\n *\n * @param input\n * @returns\n */\n toDateTime: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'string' && value.match(/^\\d{4}(-\\d{2}(-\\d{2})?)?/)) {\n return [{ type: PropertyType.dateTime, value: parseDateString(value) }];\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a DateTime\n * 2) the item is a Date\n * 3) the item is a String and is convertible to a DateTime\n *\n * If the item is not one of the above types, or is not convertible to a DateTime (using the format YYYY-MM-DDThh:mm:ss.fff(+|-)hh:mm), the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#convertstodatetime-boolean\n *\n * @param input\n * @returns\n */\n convertsToDateTime: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toDateTime(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single decimal if:\n * 1) the item is an Integer or Decimal\n * 2) the item is a String and is convertible to a Decimal\n * 3) the item is a Boolean, where true results in a 1.0 and false results in a 0.0.\n * 4) If the item is not one of the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to a Decimal (using the regex format (\\\\+|-)?\\d+(\\.\\d+)?), the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#decimal-conversion-functions\n *\n * @param input The input collection.\n * @returns\n */\n toDecimal: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'number') {\n return [{ type: PropertyType.decimal, value }];\n }\n if (typeof value === 'string' && value.match(/^-?\\d{1,9}(\\.\\d{1,9})?$/)) {\n return [{ type: PropertyType.decimal, value: parseFloat(value) }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.decimal, value: value ? 1 : 0 }];\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will true if:\n * 1) the item is an Integer or Decimal\n * 2) the item is a String and is convertible to a Decimal\n * 3) the item is a Boolean\n *\n * If the item is not one of the above types, or is not convertible to a Decimal (using the regex format (\\\\+|-)?\\d+(\\.\\d+)?), the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n\n * See: https://hl7.org/fhirpath/#convertstodecimal-boolean\n *\n * @param input The input collection.\n * @returns\n */\n convertsToDecimal: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toDecimal(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single quantity if:\n * 1) the item is an Integer, or Decimal, where the resulting quantity will have the default unit ('1')\n * 2) the item is a Quantity\n * 3) the item is a String and is convertible to a Quantity\n * 4) the item is a Boolean, where true results in the quantity 1.0 '1', and false results in the quantity 0.0 '1'\n *\n * If the item is not one of the above types, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#quantity-conversion-functions\n *\n * @param input The input collection.\n * @returns\n */\n toQuantity: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (isQuantity(value)) {\n return [{ type: PropertyType.Quantity, value }];\n }\n if (typeof value === 'number') {\n return [{ type: PropertyType.Quantity, value: { value, unit: '1' } }];\n }\n if (typeof value === 'string' && value.match(/^-?\\d{1,9}(\\.\\d{1,9})?/)) {\n return [{ type: PropertyType.Quantity, value: { value: parseFloat(value), unit: '1' } }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.Quantity, value: { value: value ? 1 : 0, unit: '1' } }];\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is an Integer, Decimal, or Quantity\n * 2) the item is a String that is convertible to a Quantity\n * 3) the item is a Boolean\n *\n * If the item is not one of the above types, or is not convertible to a Quantity using the following regex format:\n *\n * (?'value'(\\+|-)?\\d+(\\.\\d+)?)\\s*('(?'unit'[^']+)'|(?'time'[a-zA-Z]+))?\n *\n * then the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the unit argument is provided, it must be the string representation of a UCUM code (or a FHIRPath calendar duration keyword), and is used to determine whether the input quantity can be converted to the given unit, according to the unit conversion rules specified by UCUM. If the input quantity can be converted, the result is true, otherwise, the result is false.\n *\n * See: https://hl7.org/fhirpath/#convertstoquantityunit-string-boolean\n *\n * @param input The input collection.\n * @returns\n */\n convertsToQuantity: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toQuantity(input).length === 1);\n },\n\n /**\n * Returns the string representation of the input.\n *\n * If the input collection contains a single item, this function will return a single String if:\n *\n * 1) the item in the input collection is a String\n * 2) the item in the input collection is an Integer, Decimal, Date, Time, DateTime, or Quantity the output will contain its String representation\n * 3) the item is a Boolean, where true results in 'true' and false in 'false'.\n *\n * If the item is not one of the above types, the result is false.\n *\n * See: https://hl7.org/fhirpath/#tostring-string\n *\n * @param input The input collection.\n * @returns The string representation of the input.\n */\n toString: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (value === null || value === undefined) {\n return [];\n }\n if (isQuantity(value)) {\n return [{ type: PropertyType.string, value: `${value.value} '${value.unit}'` }];\n }\n return [{ type: PropertyType.string, value: (value as boolean | number | string).toString() }];\n },\n\n /**\n * Returns true if the input can be converted to string.\n *\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a String\n * 2) the item is an Integer, Decimal, Date, Time, or DateTime\n * 3) the item is a Boolean\n * 4) the item is a Quantity\n *\n * If the item is not one of the above types, the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#tostring-string\n *\n * @param input The input collection.\n * @returns\n */\n convertsToString: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue((functions.toString as unknown as FhirPathFunction)(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single time if:\n * 1) the item is a Time\n * 2) the item is a String and is convertible to a Time\n *\n * If the item is not one of the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to a Time (using the format hh:mm:ss.fff(+|-)hh:mm), the result is empty.\n *\n * If the item contains a partial time (e.g. '10:00'), the result is a partial time.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#totime-time\n *\n * @param input\n * @returns\n */\n toTime: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'string') {\n const match = value.match(/^T?(\\d{2}(:\\d{2}(:\\d{2})?)?)/);\n if (match) {\n return [{ type: PropertyType.time, value: parseDateString('T' + match[1]) }];\n }\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a Time\n * 2) the item is a String and is convertible to a Time\n *\n * If the item is not one of the above types, or is not convertible to a Time (using the format hh:mm:ss.fff(+|-)hh:mm), the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#convertstotime-boolean\n *\n * @param input\n * @returns\n */\n convertsToTime: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toTime(input).length === 1);\n },\n\n /*\n * 5.6. String Manipulation.\n *\n * See: https://hl7.org/fhirpath/#string-manipulation\n */\n\n /**\n * Returns the 0-based index of the first position substring is found in the input string, or -1 if it is not found.\n *\n * If substring is an empty string (''), the function returns 0.\n *\n * If the input or substring is empty ({ }), the result is empty ({ }).\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#indexofsubstring-string-integer\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n indexOf: (input: TypedValue[], substringAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, substring) => str.indexOf(substring as string), input, substringAtom);\n },\n\n /**\n * Returns the part of the string starting at position start (zero-based). If length is given, will return at most length number of characters from the input string.\n *\n * If start lies outside the length of the string, the function returns empty ({ }). If there are less remaining characters in the string than indicated by length, the function returns just the remaining characters.\n *\n * If the input or start is empty, the result is empty.\n *\n * If an empty length is provided, the behavior is the same as if length had not been provided.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n substring: (input: TypedValue[], startAtom: Atom, lengthAtom?: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, start, length) => {\n const startIndex = start as number;\n const endIndex = length ? startIndex + (length as number) : str.length;\n return startIndex < 0 || startIndex >= str.length ? undefined : str.substring(startIndex, endIndex);\n },\n input,\n startAtom,\n lengthAtom\n );\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n startsWith: (input: TypedValue[], prefixAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, prefix) => str.startsWith(prefix as string), input, prefixAtom);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n endsWith: (input: TypedValue[], suffixAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, suffix) => str.endsWith(suffix as string), input, suffixAtom);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n contains: (input: TypedValue[], substringAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, substring) => str.includes(substring as string), input, substringAtom);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n upper: (input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.toUpperCase(), input);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n lower: (input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.toLowerCase(), input);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n replace: (input: TypedValue[], patternAtom: Atom, substitionAtom: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, pattern, substition) => str.replaceAll(pattern as string, substition as string),\n input,\n patternAtom,\n substitionAtom\n );\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n matches: (input: TypedValue[], regexAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, regex) => !!str.match(regex as string), input, regexAtom);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n replaceMatches: (input: TypedValue[], regexAtom: Atom, substitionAtom: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, pattern, substition) => str.replaceAll(pattern as string, substition as string),\n input,\n regexAtom,\n substitionAtom\n );\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n length: (input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.length, input);\n },\n\n /**\n * Returns the list of characters in the input string. If the input collection is empty ({ }), the result is empty.\n *\n * See: https://hl7.org/fhirpath/#tochars-collection\n *\n * @param input The input collection.\n */\n toChars: (input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => (str ? str.split('') : undefined), input);\n },\n\n /*\n * 5.7. Math\n */\n\n /**\n * Returns the absolute value of the input. When taking the absolute value of a quantity, the unit is unchanged.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#abs-integer-decimal-quantity\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n abs: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.abs, input);\n },\n\n /**\n * Returns the first integer greater than or equal to the input.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#ceiling-integer\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n ceiling: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.ceil, input);\n },\n\n /**\n * Returns e raised to the power of the input.\n *\n * If the input collection contains an Integer, it will be implicitly converted to a Decimal and the result will be a Decimal.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#exp-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n exp: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.exp, input);\n },\n\n /**\n * Returns the first integer less than or equal to the input.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#floor-integer\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n floor: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.floor, input);\n },\n\n /**\n * Returns the natural logarithm of the input (i.e. the logarithm base e).\n *\n * When used with an Integer, it will be implicitly converted to a Decimal.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#ln-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n ln: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.log, input);\n },\n\n /**\n * Returns the logarithm base base of the input number.\n *\n * When used with Integers, the arguments will be implicitly converted to Decimal.\n *\n * If base is empty, the result is empty.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#logbase-decimal-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n log: (input: TypedValue[], baseAtom: Atom): TypedValue[] => {\n return applyMathFunc((value, base) => Math.log(value) / Math.log(base as number), input, baseAtom);\n },\n\n /**\n * Raises a number to the exponent power. If this function is used with Integers, the result is an Integer. If the function is used with Decimals, the result is a Decimal. If the function is used with a mixture of Integer and Decimal, the Integer is implicitly converted to a Decimal and the result is a Decimal.\n *\n * If the power cannot be represented (such as the -1 raised to the 0.5), the result is empty.\n *\n * If the input is empty, or exponent is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#powerexponent-integer-decimal-integer-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n power: (input: TypedValue[], expAtom: Atom): TypedValue[] => {\n return applyMathFunc(Math.pow as (x: number, ...args: unknown[]) => number, input, expAtom);\n },\n\n /**\n * Rounds the decimal to the nearest whole number using a traditional round (i.e. 0.5 or higher will round to 1). If specified, the precision argument determines the decimal place at which the rounding will occur. If not specified, the rounding will default to 0 decimal places.\n *\n * If specified, the number of digits of precision must be >= 0 or the evaluation will end and signal an error to the calling environment.\n *\n * If the input collection contains a single item of type Integer, it will be implicitly converted to a Decimal.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#roundprecision-integer-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n round: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.round, input);\n },\n\n /**\n * Returns the square root of the input number as a Decimal.\n *\n * If the square root cannot be represented (such as the square root of -1), the result is empty.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * Note that this function is equivalent to raising a number of the power of 0.5 using the power() function.\n *\n * See: https://hl7.org/fhirpath/#sqrt-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n sqrt: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.sqrt, input);\n },\n\n /**\n * Returns the integer portion of the input.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#truncate-integer\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n truncate: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc((x) => x | 0, input);\n },\n\n /*\n * 5.8. Tree navigation\n */\n\n children: stub,\n\n descendants: stub,\n\n /*\n * 5.9. Utility functions\n */\n\n /**\n * Adds a String representation of the input collection to the diagnostic log,\n * using the name argument as the name in the log. This log should be made available\n * to the user in some appropriate fashion. Does not change the input, so returns\n * the input collection as output.\n *\n * If the projection argument is used, the trace would log the result of evaluating\n * the project expression on the input, but still return the input to the trace\n * function unchanged.\n *\n * See: https://hl7.org/fhirpath/#tracename-string-projection-expression-collection\n *\n * @param input The input collection.\n * @param nameAtom The log name.\n */\n trace: (input: TypedValue[], nameAtom: Atom): TypedValue[] => {\n console.log('trace', input, nameAtom);\n return input;\n },\n\n /**\n * Returns the current date and time, including timezone offset.\n *\n * See: https://hl7.org/fhirpath/#now-datetime\n */\n now: (): TypedValue[] => {\n return [{ type: PropertyType.dateTime, value: new Date().toISOString() }];\n },\n\n /**\n * Returns the current time.\n *\n * See: https://hl7.org/fhirpath/#timeofday-time\n */\n timeOfDay: (): TypedValue[] => {\n return [{ type: PropertyType.time, value: new Date().toISOString().substring(11) }];\n },\n\n /**\n * Returns the current date.\n *\n * See: https://hl7.org/fhirpath/#today-date\n */\n today: (): TypedValue[] => {\n return [{ type: PropertyType.date, value: new Date().toISOString().substring(0, 10) }];\n },\n\n /**\n * Calculates the difference between two dates or date/times.\n *\n * This is not part of the official FHIRPath spec.\n *\n * IBM FHIR issue: https://github.com/IBM/FHIR/issues/1014\n * IBM FHIR PR: https://github.com/IBM/FHIR/pull/1023\n */\n between: (input: TypedValue[], startAtom: Atom, endAtom: Atom, unitsAtom: Atom): TypedValue[] => {\n const startDate = functions.toDateTime(startAtom.eval(input));\n if (startDate.length === 0) {\n throw new Error('Invalid start date');\n }\n const endDate = functions.toDateTime(endAtom.eval(input));\n if (endDate.length === 0) {\n throw new Error('Invalid end date');\n }\n const unit = unitsAtom.eval(input)[0]?.value as string;\n if (unit !== 'years' && unit !== 'months' && unit !== 'days') {\n throw new Error('Invalid units');\n }\n const age = calculateAge(startDate[0].value, endDate[0].value);\n return [{ type: PropertyType.Quantity, value: { value: age[unit], unit } }];\n },\n\n /*\n * 6.3 Types\n */\n\n /**\n * The is() function is supported for backwards compatibility with previous\n * implementations of FHIRPath. Just as with the is keyword, the type argument\n * is an identifier that must resolve to the name of a type in a model.\n *\n * For implementations with compile-time typing, this requires special-case\n * handling when processing the argument to treat it as a type specifier rather\n * than an identifier expression:\n *\n * @param input\n * @param typeAtom\n * @returns\n */\n is: (input: TypedValue[], typeAtom: Atom): TypedValue[] => {\n let typeName = '';\n if (typeAtom instanceof SymbolAtom) {\n typeName = typeAtom.name;\n } else if (typeAtom instanceof DotAtom) {\n typeName = (typeAtom.left as SymbolAtom).name + '.' + (typeAtom.right as SymbolAtom).name;\n }\n if (!typeName) {\n return [];\n }\n return input.map((value) => ({ type: PropertyType.boolean, value: fhirPathIs(value, typeName) }));\n },\n\n /*\n * 6.5 Boolean logic\n */\n\n /**\n * 6.5.3. not() : Boolean\n *\n * Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):\n *\n * @param input\n * @returns\n */\n not: (input: TypedValue[]): TypedValue[] => {\n return functions.toBoolean(input).map((value) => ({ type: PropertyType.boolean, value: !value.value }));\n },\n\n /*\n * Additional functions\n * See: https://hl7.org/fhir/fhirpath.html#functions\n */\n\n /**\n * 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.\n * The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.\n * @param input The input collection.\n * @returns\n */\n resolve: (input: TypedValue[]): TypedValue[] => {\n return input\n .map((e) => {\n const value = e.value;\n let refStr: string | undefined;\n if (typeof value === 'string') {\n refStr = value;\n } else if (typeof value === 'object') {\n const ref = value as Reference;\n if (ref.resource) {\n return toTypedValue(ref.resource);\n }\n refStr = ref.reference;\n }\n if (!refStr) {\n return { type: PropertyType.BackboneElement, value: null };\n }\n const [resourceType, id] = refStr.split('/');\n return { type: PropertyType.BackboneElement, value: { resourceType, id } };\n })\n .filter((e) => !!e.value);\n },\n\n /**\n * The as operator can be used to treat a value as a specific type.\n * @param input The input value.\n * @returns The value as the specific type.\n */\n as: (input: TypedValue[]): TypedValue[] => {\n return input;\n },\n\n /*\n * 12. Formal Specifications\n */\n\n /**\n * Returns the type of the input.\n *\n * 12.2. Model Information\n *\n * The model information returned by the reflection function type() is specified as an\n * XML Schema document (xsd) and included in this specification at the following link:\n * https://hl7.org/fhirpath/modelinfo.xsd\n *\n * See: https://hl7.org/fhirpath/#model-information\n *\n * @param input The input collection.\n * @returns\n */\n type: (input: TypedValue[]): TypedValue[] => {\n return input.map(({ value }) => {\n if (typeof value === 'boolean') {\n return { type: PropertyType.BackboneElement, value: { namespace: 'System', name: 'Boolean' } };\n }\n if (typeof value === 'number') {\n return { type: PropertyType.BackboneElement, value: { namespace: 'System', name: 'Integer' } };\n }\n if (value && typeof value === 'object' && 'resourceType' in value) {\n return {\n type: PropertyType.BackboneElement,\n value: { namespace: 'FHIR', name: (value as Resource).resourceType },\n };\n }\n return { type: PropertyType.BackboneElement, value: null };\n });\n },\n\n conformsTo: (input: TypedValue[], systemAtom: Atom): TypedValue[] => {\n const system = systemAtom.eval(input)[0].value as string;\n if (!system.startsWith('http://hl7.org/fhir/StructureDefinition/')) {\n throw new Error('Expected a StructureDefinition URL');\n }\n const expectedResourceType = system.replace('http://hl7.org/fhir/StructureDefinition/', '');\n return input.map((value) => ({\n type: PropertyType.boolean,\n value: value.value?.resourceType === expectedResourceType,\n }));\n },\n};\n\n/*\n * Helper utilities\n */\n\nfunction applyStringFunc<T>(\n func: (str: string, ...args: unknown[]) => T | undefined,\n input: TypedValue[],\n ...argsAtoms: (Atom | undefined)[]\n): TypedValue[] {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value !== 'string') {\n throw new Error('String function cannot be called with non-string');\n }\n const result = func(value, ...argsAtoms.map((atom) => atom && atom.eval(input)?.[0]?.value));\n if (result === undefined) {\n return [];\n }\n if (Array.isArray(result)) {\n return result.map(toTypedValue);\n }\n return [toTypedValue(result)];\n}\n\nfunction applyMathFunc(\n func: (x: number, ...args: unknown[]) => number,\n input: TypedValue[],\n ...argsAtoms: Atom[]\n): TypedValue[] {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n const quantity = isQuantity(value);\n const numberInput = quantity ? value.value : value;\n if (typeof numberInput !== 'number') {\n throw new Error('Math function cannot be called with non-number');\n }\n const result = func(numberInput, ...argsAtoms.map((atom) => atom.eval(input)?.[0]?.value));\n const type = quantity ? PropertyType.Quantity : input[0].type;\n const returnValue = quantity ? { ...value, value: result } : result;\n return [{ type, value: returnValue }];\n}\n\nfunction validateInput(input: TypedValue[], count: number): TypedValue[] {\n if (input.length !== count) {\n throw new Error(`Expected ${count} arguments`);\n }\n for (const element of input) {\n if (element === null || element === undefined) {\n throw new Error('Expected non-null argument');\n }\n }\n return input;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"functions.js","sources":["../../../src/fhirpath/functions.ts"],"sourcesContent":["import { Reference, Resource } from '@medplum/fhirtypes';\nimport { PropertyType } from '../types';\nimport { calculateAge } from '../utils';\nimport { Atom, DotAtom, SymbolAtom, TypedValue } from './atoms';\nimport { parseDateString } from './date';\nimport { booleanToTypedValue, fhirPathIs, isQuantity, removeDuplicates, toJsBoolean, toTypedValue } from './utils';\n\n/*\n * Collection of FHIRPath\n * See: https://hl7.org/fhirpath/#functions\n */\n\nexport interface FhirPathFunction {\n (input: TypedValue[], ...args: Atom[]): TypedValue[];\n}\n\n/**\n * Temporary placholder for unimplemented methods.\n */\nconst stub: FhirPathFunction = (): [] => [];\n\nexport const functions: Record<string, FhirPathFunction> = {\n /*\n * 5.1 Existence\n * See: https://hl7.org/fhirpath/#existence\n */\n\n /**\n * Returns true if the input collection is empty ({ }) and false otherwise.\n *\n * See: https://hl7.org/fhirpath/#empty-boolean\n *\n * @param input The input collection.\n * @returns True if the input collection is empty ({ }) and false otherwise.\n */\n empty: (input: TypedValue[]): TypedValue[] => {\n return booleanToTypedValue(input.length === 0);\n },\n\n /**\n * Returns true if the collection has unknown elements, and false otherwise.\n * This is the opposite of empty(), and as such is a shorthand for empty().not().\n * If the input collection is empty ({ }), the result is false.\n *\n * The function can also take an optional criteria to be applied to the collection\n * prior to the determination of the exists. In this case, the function is shorthand\n * for where(criteria).exists().\n *\n * See: https://hl7.org/fhirpath/#existscriteria-expression-boolean\n *\n * @param input\n * @param criteria\n * @returns True if the collection has unknown elements, and false otherwise.\n */\n exists: (input: TypedValue[], criteria?: Atom): TypedValue[] => {\n if (criteria) {\n return booleanToTypedValue(input.filter((e) => toJsBoolean(criteria.eval([e]))).length > 0);\n } else {\n return booleanToTypedValue(input.length > 0);\n }\n },\n\n /**\n * Returns true if for every element in the input collection, criteria evaluates to true.\n * Otherwise, the result is false.\n *\n * If the input collection is empty ({ }), the result is true.\n *\n * See: https://hl7.org/fhirpath/#allcriteria-expression-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if for every element in the input collection, criteria evaluates to true.\n */\n all: (input: TypedValue[], criteria: Atom): TypedValue[] => {\n return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval([e]))));\n },\n\n /**\n * Takes a collection of Boolean values and returns true if all the items are true.\n * If unknown items are false, the result is false.\n * If the input is empty ({ }), the result is true.\n *\n * See: https://hl7.org/fhirpath/#alltrue-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if all the items are true.\n */\n allTrue: (input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (!value.value) {\n return booleanToTypedValue(false);\n }\n }\n return booleanToTypedValue(true);\n },\n\n /**\n * Takes a collection of Boolean values and returns true if unknown of the items are true.\n * If all the items are false, or if the input is empty ({ }), the result is false.\n *\n * See: https://hl7.org/fhirpath/#anytrue-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if unknown of the items are true.\n */\n anyTrue: (input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (value.value) {\n return booleanToTypedValue(true);\n }\n }\n return booleanToTypedValue(false);\n },\n\n /**\n * Takes a collection of Boolean values and returns true if all the items are false.\n * If unknown items are true, the result is false.\n * If the input is empty ({ }), the result is true.\n *\n * See: https://hl7.org/fhirpath/#allfalse-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if all the items are false.\n */\n allFalse: (input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (value.value) {\n return booleanToTypedValue(false);\n }\n }\n return booleanToTypedValue(true);\n },\n\n /**\n * Takes a collection of Boolean values and returns true if unknown of the items are false.\n * If all the items are true, or if the input is empty ({ }), the result is false.\n *\n * See: https://hl7.org/fhirpath/#anyfalse-boolean\n *\n * @param input The input collection.\n * @param criteria The evaluation criteria.\n * @returns True if for every element in the input collection, criteria evaluates to true.\n */\n anyFalse: (input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (!value.value) {\n return booleanToTypedValue(true);\n }\n }\n return booleanToTypedValue(false);\n },\n\n /**\n * Returns true if all items in the input collection are members of the collection passed\n * as the other argument. Membership is determined using the = (Equals) (=) operation.\n *\n * Conceptually, this function is evaluated by testing each element in the input collection\n * for membership in the other collection, with a default of true. This means that if the\n * input collection is empty ({ }), the result is true, otherwise if the other collection\n * is empty ({ }), the result is false.\n *\n * See: http://hl7.org/fhirpath/#subsetofother-collection-boolean\n */\n subsetOf: stub,\n\n /**\n * Returns true if all items in the collection passed as the other argument are members of\n * the input collection. Membership is determined using the = (Equals) (=) operation.\n *\n * Conceptually, this function is evaluated by testing each element in the other collection\n * for membership in the input collection, with a default of true. This means that if the\n * other collection is empty ({ }), the result is true, otherwise if the input collection\n * is empty ({ }), the result is false.\n *\n * See: http://hl7.org/fhirpath/#supersetofother-collection-boolean\n */\n supersetOf: stub,\n\n /**\n * Returns the integer count of the number of items in the input collection.\n * Returns 0 when the input collection is empty.\n *\n * See: https://hl7.org/fhirpath/#count-integer\n *\n * @param input The input collection.\n * @returns The integer count of the number of items in the input collection.\n */\n count: (input: TypedValue[]): TypedValue[] => {\n return [{ type: PropertyType.integer, value: input.length }];\n },\n\n /**\n * Returns a collection containing only the unique items in the input collection.\n * To determine whether two items are the same, the = (Equals) (=) operator is used,\n * as defined below.\n *\n * If the input collection is empty ({ }), the result is empty.\n *\n * Note that the order of elements in the input collection is not guaranteed to be\n * preserved in the result.\n *\n * See: https://hl7.org/fhirpath/#distinct-collection\n *\n * @param input The input collection.\n * @returns The integer count of the number of items in the input collection.\n */\n distinct: (input: TypedValue[]): TypedValue[] => {\n const result: TypedValue[] = [];\n for (const value of input) {\n if (!result.some((e) => e.value === value.value)) {\n result.push(value);\n }\n }\n return result;\n },\n\n /**\n * Returns true if all the items in the input collection are distinct.\n * To determine whether two items are distinct, the = (Equals) (=) operator is used,\n * as defined below.\n *\n * See: https://hl7.org/fhirpath/#isdistinct-boolean\n *\n * @param input The input collection.\n * @returns The integer count of the number of items in the input collection.\n */\n isDistinct: (input: TypedValue[]): TypedValue[] => {\n return booleanToTypedValue(input.length === functions.distinct(input).length);\n },\n\n /*\n * 5.2 Filtering and projection\n */\n\n /**\n * Returns a collection containing only those elements in the input collection\n * for which the stated criteria expression evaluates to true.\n * Elements for which the expression evaluates to false or empty ({ }) are not\n * included in the result.\n *\n * If the input collection is empty ({ }), the result is empty.\n *\n * If the result of evaluating the condition is other than a single boolean value,\n * the evaluation will end and signal an error to the calling environment,\n * consistent with singleton evaluation of collections behavior.\n *\n * See: https://hl7.org/fhirpath/#wherecriteria-expression-collection\n *\n * @param input The input collection.\n * @param condition The condition atom.\n * @returns A collection containing only those elements in the input collection for which the stated criteria expression evaluates to true.\n */\n where: (input: TypedValue[], criteria: Atom): TypedValue[] => {\n return input.filter((e) => toJsBoolean(criteria.eval([e])));\n },\n\n /**\n * Evaluates the projection expression for each item in the input collection.\n * The result of each evaluation is added to the output collection. If the\n * evaluation results in a collection with multiple items, all items are added\n * to the output collection (collections resulting from evaluation of projection\n * are flattened). This means that if the evaluation for an element results in\n * the empty collection ({ }), no element is added to the result, and that if\n * the input collection is empty ({ }), the result is empty as well.\n *\n * See: http://hl7.org/fhirpath/#selectprojection-expression-collection\n */\n select: (input: TypedValue[], criteria: Atom): TypedValue[] => {\n return input.map((e) => criteria.eval([e])).flat();\n },\n\n /**\n * A version of select that will repeat the projection and add it to the output\n * collection, as long as the projection yields new items (as determined by\n * the = (Equals) (=) operator).\n *\n * See: http://hl7.org/fhirpath/#repeatprojection-expression-collection\n */\n repeat: stub,\n\n /**\n * Returns a collection that contains all items in the input collection that\n * are of the given type or a subclass thereof. If the input collection is\n * empty ({ }), the result is empty. The type argument is an identifier that\n * must resolve to the name of a type in a model\n *\n * See: http://hl7.org/fhirpath/#oftypetype-type-specifier-collection\n */\n ofType: (input: TypedValue[], criteria: Atom): TypedValue[] => {\n return input.filter((e) => e.type === (criteria as SymbolAtom).name);\n },\n\n /*\n * 5.3 Subsetting\n */\n\n /**\n * Will return the single item in the input if there is just one item.\n * If the input collection is empty ({ }), the result is empty.\n * If there are multiple items, an error is signaled to the evaluation environment.\n * This function is useful for ensuring that an error is returned if an assumption\n * about cardinality is violated at run-time.\n *\n * See: https://hl7.org/fhirpath/#single-collection\n *\n * @param input The input collection.\n * @returns The single item in the input if there is just one item.\n */\n single: (input: TypedValue[]): TypedValue[] => {\n if (input.length > 1) {\n throw new Error('Expected input length one for single()');\n }\n return input.length === 0 ? [] : input.slice(0, 1);\n },\n\n /**\n * Returns a collection containing only the first item in the input collection.\n * This function is equivalent to item[0], so it will return an empty collection if the input collection has no items.\n *\n * See: https://hl7.org/fhirpath/#first-collection\n *\n * @param input The input collection.\n * @returns A collection containing only the first item in the input collection.\n */\n first: (input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(0, 1);\n },\n\n /**\n * Returns a collection containing only the last item in the input collection.\n * Will return an empty collection if the input collection has no items.\n *\n * See: https://hl7.org/fhirpath/#last-collection\n *\n * @param input The input collection.\n * @returns A collection containing only the last item in the input collection.\n */\n last: (input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(input.length - 1, input.length);\n },\n\n /**\n * Returns a collection containing all but the first item in the input collection.\n * Will return an empty collection if the input collection has no items, or only one item.\n *\n * See: https://hl7.org/fhirpath/#tail-collection\n *\n * @param input The input collection.\n * @returns A collection containing all but the first item in the input collection.\n */\n tail: (input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(1, input.length);\n },\n\n /**\n * Returns a collection containing all but the first num items in the input collection.\n * Will return an empty collection if there are no items remaining after the\n * indicated number of items have been skipped, or if the input collection is empty.\n * If num is less than or equal to zero, the input collection is simply returned.\n *\n * See: https://hl7.org/fhirpath/#skipnum-integer-collection\n *\n * @param input The input collection.\n * @returns A collection containing all but the first item in the input collection.\n */\n skip: (input: TypedValue[], num: Atom): TypedValue[] => {\n const numValue = num.eval(input)[0]?.value;\n if (typeof numValue !== 'number') {\n throw new Error('Expected a number for skip(num)');\n }\n if (numValue >= input.length) {\n return [];\n }\n if (numValue <= 0) {\n return input;\n }\n return input.slice(numValue, input.length);\n },\n\n /**\n * Returns a collection containing the first num items in the input collection,\n * or less if there are less than num items.\n * If num is less than or equal to 0, or if the input collection is empty ({ }),\n * take returns an empty collection.\n *\n * See: https://hl7.org/fhirpath/#takenum-integer-collection\n *\n * @param input The input collection.\n * @returns A collection containing the first num items in the input collection.\n */\n take: (input: TypedValue[], num: Atom): TypedValue[] => {\n const numValue = num.eval(input)[0]?.value;\n if (typeof numValue !== 'number') {\n throw new Error('Expected a number for take(num)');\n }\n if (numValue >= input.length) {\n return input;\n }\n if (numValue <= 0) {\n return [];\n }\n return input.slice(0, numValue);\n },\n\n /**\n * Returns the set of elements that are in both collections.\n * Duplicate items will be eliminated by this function.\n * Order of items is not guaranteed to be preserved in the result of this function.\n *\n * See: http://hl7.org/fhirpath/#intersectother-collection-collection\n */\n intersect: (input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(input);\n const result: TypedValue[] = [];\n for (const value of input) {\n if (!result.some((e) => e.value === value.value) && otherArray.some((e) => e.value === value.value)) {\n result.push(value);\n }\n }\n return result;\n },\n\n /**\n * Returns the set of elements that are not in the other collection.\n * Duplicate items will not be eliminated by this function, and order will be preserved.\n *\n * e.g. (1 | 2 | 3).exclude(2) returns (1 | 3).\n *\n * See: http://hl7.org/fhirpath/#excludeother-collection-collection\n */\n exclude: (input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(input);\n const result: TypedValue[] = [];\n for (const value of input) {\n if (!otherArray.some((e) => e.value === value.value)) {\n result.push(value);\n }\n }\n return result;\n },\n\n /*\n * 5.4. Combining\n *\n * See: https://hl7.org/fhirpath/#combining\n */\n\n /**\n * Merge the two collections into a single collection,\n * eliminating unknown duplicate values (using = (Equals) (=) to determine equality).\n * There is no expectation of order in the resulting collection.\n *\n * In other words, this function returns the distinct list of elements from both inputs.\n *\n * See: http://hl7.org/fhirpath/#unionother-collection\n */\n union: (input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(input);\n return removeDuplicates([...input, ...otherArray]);\n },\n\n /**\n * Merge the input and other collections into a single collection\n * without eliminating duplicate values. Combining an empty collection\n * with a non-empty collection will return the non-empty collection.\n *\n * There is no expectation of order in the resulting collection.\n *\n * See: http://hl7.org/fhirpath/#combineother-collection-collection\n */\n combine: (input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(input);\n return [...input, ...otherArray];\n },\n\n /*\n * 5.5. Conversion\n *\n * See: https://hl7.org/fhirpath/#conversion\n */\n\n /**\n * The iif function in FHIRPath is an immediate if,\n * also known as a conditional operator (such as C’s ? : operator).\n *\n * The criterion expression is expected to evaluate to a Boolean.\n *\n * If criterion is true, the function returns the value of the true-result argument.\n *\n * If criterion is false or an empty collection, the function returns otherwise-result,\n * unless the optional otherwise-result is not given, in which case the function returns an empty collection.\n *\n * Note that short-circuit behavior is expected in this function. In other words,\n * true-result should only be evaluated if the criterion evaluates to true,\n * and otherwise-result should only be evaluated otherwise. For implementations,\n * this means delaying evaluation of the arguments.\n *\n * @param input\n * @param criterion\n * @param trueResult\n * @param otherwiseResult\n * @returns\n */\n iif: (input: TypedValue[], criterion: Atom, trueResult: Atom, otherwiseResult?: Atom): TypedValue[] => {\n const evalResult = criterion.eval(input);\n if (evalResult.length > 1 || (evalResult.length === 1 && typeof evalResult[0].value !== 'boolean')) {\n throw new Error('Expected criterion to evaluate to a Boolean');\n }\n\n if (toJsBoolean(evalResult)) {\n return trueResult.eval(input);\n }\n\n if (otherwiseResult) {\n return otherwiseResult.eval(input);\n }\n\n return [];\n },\n\n /**\n * Converts an input collection to a boolean.\n *\n * If the input collection contains a single item, this function will return a single boolean if:\n * 1) the item is a Boolean\n * 2) the item is an Integer and is equal to one of the possible integer representations of Boolean values\n * 3) the item is a Decimal that is equal to one of the possible decimal representations of Boolean values\n * 4) the item is a String that is equal to one of the possible string representations of Boolean values\n *\n * If the item is not one the above types, or the item is a String, Integer, or Decimal, but is not equal to one of the possible values convertible to a Boolean, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#toboolean-boolean\n *\n * @param input\n * @returns\n */\n toBoolean: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.boolean, value }];\n }\n if (typeof value === 'number') {\n if (value === 0 || value === 1) {\n return booleanToTypedValue(!!value);\n }\n }\n if (typeof value === 'string') {\n const lowerStr = value.toLowerCase();\n if (['true', 't', 'yes', 'y', '1', '1.0'].includes(lowerStr)) {\n return booleanToTypedValue(true);\n }\n if (['false', 'f', 'no', 'n', '0', '0.0'].includes(lowerStr)) {\n return booleanToTypedValue(false);\n }\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a Boolean\n * 2) the item is an Integer that is equal to one of the possible integer representations of Boolean values\n * 3) the item is a Decimal that is equal to one of the possible decimal representations of Boolean values\n * 4) the item is a String that is equal to one of the possible string representations of Boolean values\n *\n * If the item is not one of the above types, or the item is a String, Integer, or Decimal, but is not equal to one of the possible values convertible to a Boolean, the result is false.\n *\n * Possible values for Integer, Decimal, and String are described in the toBoolean() function.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: http://hl7.org/fhirpath/#convertstoboolean-boolean\n *\n * @param input\n * @returns\n */\n convertsToBoolean: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toBoolean(input).length === 1);\n },\n\n /**\n * Returns the integer representation of the input.\n *\n * If the input collection contains a single item, this function will return a single integer if:\n * 1) the item is an Integer\n * 2) the item is a String and is convertible to an integer\n * 3) the item is a Boolean, where true results in a 1 and false results in a 0.\n *\n * If the item is not one the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to an integer (using the regex format (\\\\+|-)?\\d+), the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#tointeger-integer\n *\n * @param input The input collection.\n * @returns The string representation of the input.\n */\n toInteger: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'number') {\n return [{ type: PropertyType.integer, value }];\n }\n if (typeof value === 'string' && value.match(/^[+-]?\\d+$/)) {\n return [{ type: PropertyType.integer, value: parseInt(value, 10) }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.integer, value: value ? 1 : 0 }];\n }\n return [];\n },\n\n /**\n * Returns true if the input can be converted to string.\n *\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is an Integer\n * 2) the item is a String and is convertible to an Integer\n * 3) the item is a Boolean\n * 4) If the item is not one of the above types, or the item is a String, but is not convertible to an Integer (using the regex format (\\\\+|-)?\\d+), the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#convertstointeger-boolean\n *\n * @param input The input collection.\n * @returns\n */\n convertsToInteger: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toInteger(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single date if:\n * 1) the item is a Date\n * 2) the item is a DateTime\n * 3) the item is a String and is convertible to a Date\n *\n * If the item is not one of the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to a Date (using the format YYYY-MM-DD), the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#todate-date\n */\n toDate: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'string' && value.match(/^\\d{4}(-\\d{2}(-\\d{2})?)?/)) {\n return [{ type: PropertyType.date, value: parseDateString(value) }];\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a Date\n * 2) the item is a DateTime\n * 3) the item is a String and is convertible to a Date\n *\n * If the item is not one of the above types, or is not convertible to a Date (using the format YYYY-MM-DD), the result is false.\n *\n * If the item contains a partial date (e.g. '2012-01'), the result is a partial date.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#convertstodate-boolean\n */\n convertsToDate: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toDate(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single datetime if:\n * 1) the item is a DateTime\n * 2) the item is a Date, in which case the result is a DateTime with the year, month, and day of the Date, and the time components empty (not set to zero)\n * 3) the item is a String and is convertible to a DateTime\n *\n * If the item is not one of the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to a DateTime (using the format YYYY-MM-DDThh:mm:ss.fff(+|-)hh:mm), the result is empty.\n *\n * If the item contains a partial datetime (e.g. '2012-01-01T10:00'), the result is a partial datetime.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n\n * See: https://hl7.org/fhirpath/#todatetime-datetime\n *\n * @param input\n * @returns\n */\n toDateTime: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'string' && value.match(/^\\d{4}(-\\d{2}(-\\d{2})?)?/)) {\n return [{ type: PropertyType.dateTime, value: parseDateString(value) }];\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a DateTime\n * 2) the item is a Date\n * 3) the item is a String and is convertible to a DateTime\n *\n * If the item is not one of the above types, or is not convertible to a DateTime (using the format YYYY-MM-DDThh:mm:ss.fff(+|-)hh:mm), the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#convertstodatetime-boolean\n *\n * @param input\n * @returns\n */\n convertsToDateTime: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toDateTime(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single decimal if:\n * 1) the item is an Integer or Decimal\n * 2) the item is a String and is convertible to a Decimal\n * 3) the item is a Boolean, where true results in a 1.0 and false results in a 0.0.\n * 4) If the item is not one of the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to a Decimal (using the regex format (\\\\+|-)?\\d+(\\.\\d+)?), the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#decimal-conversion-functions\n *\n * @param input The input collection.\n * @returns\n */\n toDecimal: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'number') {\n return [{ type: PropertyType.decimal, value }];\n }\n if (typeof value === 'string' && value.match(/^-?\\d{1,9}(\\.\\d{1,9})?$/)) {\n return [{ type: PropertyType.decimal, value: parseFloat(value) }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.decimal, value: value ? 1 : 0 }];\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will true if:\n * 1) the item is an Integer or Decimal\n * 2) the item is a String and is convertible to a Decimal\n * 3) the item is a Boolean\n *\n * If the item is not one of the above types, or is not convertible to a Decimal (using the regex format (\\\\+|-)?\\d+(\\.\\d+)?), the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n\n * See: https://hl7.org/fhirpath/#convertstodecimal-boolean\n *\n * @param input The input collection.\n * @returns\n */\n convertsToDecimal: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toDecimal(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single quantity if:\n * 1) the item is an Integer, or Decimal, where the resulting quantity will have the default unit ('1')\n * 2) the item is a Quantity\n * 3) the item is a String and is convertible to a Quantity\n * 4) the item is a Boolean, where true results in the quantity 1.0 '1', and false results in the quantity 0.0 '1'\n *\n * If the item is not one of the above types, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#quantity-conversion-functions\n *\n * @param input The input collection.\n * @returns\n */\n toQuantity: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (isQuantity(value)) {\n return [{ type: PropertyType.Quantity, value }];\n }\n if (typeof value === 'number') {\n return [{ type: PropertyType.Quantity, value: { value, unit: '1' } }];\n }\n if (typeof value === 'string' && value.match(/^-?\\d{1,9}(\\.\\d{1,9})?/)) {\n return [{ type: PropertyType.Quantity, value: { value: parseFloat(value), unit: '1' } }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.Quantity, value: { value: value ? 1 : 0, unit: '1' } }];\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is an Integer, Decimal, or Quantity\n * 2) the item is a String that is convertible to a Quantity\n * 3) the item is a Boolean\n *\n * If the item is not one of the above types, or is not convertible to a Quantity using the following regex format:\n *\n * (?'value'(\\+|-)?\\d+(\\.\\d+)?)\\s*('(?'unit'[^']+)'|(?'time'[a-zA-Z]+))?\n *\n * then the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the unit argument is provided, it must be the string representation of a UCUM code (or a FHIRPath calendar duration keyword), and is used to determine whether the input quantity can be converted to the given unit, according to the unit conversion rules specified by UCUM. If the input quantity can be converted, the result is true, otherwise, the result is false.\n *\n * See: https://hl7.org/fhirpath/#convertstoquantityunit-string-boolean\n *\n * @param input The input collection.\n * @returns\n */\n convertsToQuantity: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toQuantity(input).length === 1);\n },\n\n /**\n * Returns the string representation of the input.\n *\n * If the input collection contains a single item, this function will return a single String if:\n *\n * 1) the item in the input collection is a String\n * 2) the item in the input collection is an Integer, Decimal, Date, Time, DateTime, or Quantity the output will contain its String representation\n * 3) the item is a Boolean, where true results in 'true' and false in 'false'.\n *\n * If the item is not one of the above types, the result is false.\n *\n * See: https://hl7.org/fhirpath/#tostring-string\n *\n * @param input The input collection.\n * @returns The string representation of the input.\n */\n toString: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (value === null || value === undefined) {\n return [];\n }\n if (isQuantity(value)) {\n return [{ type: PropertyType.string, value: `${value.value} '${value.unit}'` }];\n }\n return [{ type: PropertyType.string, value: (value as boolean | number | string).toString() }];\n },\n\n /**\n * Returns true if the input can be converted to string.\n *\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a String\n * 2) the item is an Integer, Decimal, Date, Time, or DateTime\n * 3) the item is a Boolean\n * 4) the item is a Quantity\n *\n * If the item is not one of the above types, the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#tostring-string\n *\n * @param input The input collection.\n * @returns\n */\n convertsToString: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue((functions.toString as unknown as FhirPathFunction)(input).length === 1);\n },\n\n /**\n * If the input collection contains a single item, this function will return a single time if:\n * 1) the item is a Time\n * 2) the item is a String and is convertible to a Time\n *\n * If the item is not one of the above types, the result is empty.\n *\n * If the item is a String, but the string is not convertible to a Time (using the format hh:mm:ss.fff(+|-)hh:mm), the result is empty.\n *\n * If the item contains a partial time (e.g. '10:00'), the result is a partial time.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#totime-time\n *\n * @param input\n * @returns\n */\n toTime: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'string') {\n const match = value.match(/^T?(\\d{2}(:\\d{2}(:\\d{2})?)?)/);\n if (match) {\n return [{ type: PropertyType.time, value: parseDateString('T' + match[1]) }];\n }\n }\n return [];\n },\n\n /**\n * If the input collection contains a single item, this function will return true if:\n * 1) the item is a Time\n * 2) the item is a String and is convertible to a Time\n *\n * If the item is not one of the above types, or is not convertible to a Time (using the format hh:mm:ss.fff(+|-)hh:mm), the result is false.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * If the input collection is empty, the result is empty.\n *\n * See: https://hl7.org/fhirpath/#convertstotime-boolean\n *\n * @param input\n * @returns\n */\n convertsToTime: (input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toTime(input).length === 1);\n },\n\n /*\n * 5.6. String Manipulation.\n *\n * See: https://hl7.org/fhirpath/#string-manipulation\n */\n\n /**\n * Returns the 0-based index of the first position substring is found in the input string, or -1 if it is not found.\n *\n * If substring is an empty string (''), the function returns 0.\n *\n * If the input or substring is empty ({ }), the result is empty ({ }).\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#indexofsubstring-string-integer\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n indexOf: (input: TypedValue[], substringAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, substring) => str.indexOf(substring as string), input, substringAtom);\n },\n\n /**\n * Returns the part of the string starting at position start (zero-based). If length is given, will return at most length number of characters from the input string.\n *\n * If start lies outside the length of the string, the function returns empty ({ }). If there are less remaining characters in the string than indicated by length, the function returns just the remaining characters.\n *\n * If the input or start is empty, the result is empty.\n *\n * If an empty length is provided, the behavior is the same as if length had not been provided.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n substring: (input: TypedValue[], startAtom: Atom, lengthAtom?: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, start, length) => {\n const startIndex = start as number;\n const endIndex = length ? startIndex + (length as number) : str.length;\n return startIndex < 0 || startIndex >= str.length ? undefined : str.substring(startIndex, endIndex);\n },\n input,\n startAtom,\n lengthAtom\n );\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n startsWith: (input: TypedValue[], prefixAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, prefix) => str.startsWith(prefix as string), input, prefixAtom);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n endsWith: (input: TypedValue[], suffixAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, suffix) => str.endsWith(suffix as string), input, suffixAtom);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n contains: (input: TypedValue[], substringAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, substring) => str.includes(substring as string), input, substringAtom);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n upper: (input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.toUpperCase(), input);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n lower: (input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.toLowerCase(), input);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n replace: (input: TypedValue[], patternAtom: Atom, substitionAtom: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, pattern, substition) => str.replaceAll(pattern as string, substition as string),\n input,\n patternAtom,\n substitionAtom\n );\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n matches: (input: TypedValue[], regexAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, regex) => !!str.match(regex as string), input, regexAtom);\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n replaceMatches: (input: TypedValue[], regexAtom: Atom, substitionAtom: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, pattern, substition) => str.replaceAll(pattern as string, substition as string),\n input,\n regexAtom,\n substitionAtom\n );\n },\n\n /**\n *\n * @param input The input collection.\n * @returns The index of the substring.\n */\n length: (input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.length, input);\n },\n\n /**\n * Returns the list of characters in the input string. If the input collection is empty ({ }), the result is empty.\n *\n * See: https://hl7.org/fhirpath/#tochars-collection\n *\n * @param input The input collection.\n */\n toChars: (input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => (str ? str.split('') : undefined), input);\n },\n\n /*\n * 5.7. Math\n */\n\n /**\n * Returns the absolute value of the input. When taking the absolute value of a quantity, the unit is unchanged.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#abs-integer-decimal-quantity\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n abs: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.abs, input);\n },\n\n /**\n * Returns the first integer greater than or equal to the input.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#ceiling-integer\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n ceiling: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.ceil, input);\n },\n\n /**\n * Returns e raised to the power of the input.\n *\n * If the input collection contains an Integer, it will be implicitly converted to a Decimal and the result will be a Decimal.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#exp-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n exp: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.exp, input);\n },\n\n /**\n * Returns the first integer less than or equal to the input.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#floor-integer\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n floor: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.floor, input);\n },\n\n /**\n * Returns the natural logarithm of the input (i.e. the logarithm base e).\n *\n * When used with an Integer, it will be implicitly converted to a Decimal.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#ln-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n ln: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.log, input);\n },\n\n /**\n * Returns the logarithm base base of the input number.\n *\n * When used with Integers, the arguments will be implicitly converted to Decimal.\n *\n * If base is empty, the result is empty.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#logbase-decimal-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n log: (input: TypedValue[], baseAtom: Atom): TypedValue[] => {\n return applyMathFunc((value, base) => Math.log(value) / Math.log(base as number), input, baseAtom);\n },\n\n /**\n * Raises a number to the exponent power. If this function is used with Integers, the result is an Integer. If the function is used with Decimals, the result is a Decimal. If the function is used with a mixture of Integer and Decimal, the Integer is implicitly converted to a Decimal and the result is a Decimal.\n *\n * If the power cannot be represented (such as the -1 raised to the 0.5), the result is empty.\n *\n * If the input is empty, or exponent is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#powerexponent-integer-decimal-integer-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n power: (input: TypedValue[], expAtom: Atom): TypedValue[] => {\n return applyMathFunc(Math.pow as (x: number, ...args: unknown[]) => number, input, expAtom);\n },\n\n /**\n * Rounds the decimal to the nearest whole number using a traditional round (i.e. 0.5 or higher will round to 1). If specified, the precision argument determines the decimal place at which the rounding will occur. If not specified, the rounding will default to 0 decimal places.\n *\n * If specified, the number of digits of precision must be >= 0 or the evaluation will end and signal an error to the calling environment.\n *\n * If the input collection contains a single item of type Integer, it will be implicitly converted to a Decimal.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#roundprecision-integer-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n round: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.round, input);\n },\n\n /**\n * Returns the square root of the input number as a Decimal.\n *\n * If the square root cannot be represented (such as the square root of -1), the result is empty.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * Note that this function is equivalent to raising a number of the power of 0.5 using the power() function.\n *\n * See: https://hl7.org/fhirpath/#sqrt-decimal\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n sqrt: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.sqrt, input);\n },\n\n /**\n * Returns the integer portion of the input.\n *\n * If the input collection is empty, the result is empty.\n *\n * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.\n *\n * See: https://hl7.org/fhirpath/#truncate-integer\n *\n * @param input The input collection.\n * @returns A collection containing the result.\n */\n truncate: (input: TypedValue[]): TypedValue[] => {\n return applyMathFunc((x) => x | 0, input);\n },\n\n /*\n * 5.8. Tree navigation\n */\n\n children: stub,\n\n descendants: stub,\n\n /*\n * 5.9. Utility functions\n */\n\n /**\n * Adds a String representation of the input collection to the diagnostic log,\n * using the name argument as the name in the log. This log should be made available\n * to the user in some appropriate fashion. Does not change the input, so returns\n * the input collection as output.\n *\n * If the projection argument is used, the trace would log the result of evaluating\n * the project expression on the input, but still return the input to the trace\n * function unchanged.\n *\n * See: https://hl7.org/fhirpath/#tracename-string-projection-expression-collection\n *\n * @param input The input collection.\n * @param nameAtom The log name.\n */\n trace: (input: TypedValue[], nameAtom: Atom): TypedValue[] => {\n console.log('trace', input, nameAtom);\n return input;\n },\n\n /**\n * Returns the current date and time, including timezone offset.\n *\n * See: https://hl7.org/fhirpath/#now-datetime\n */\n now: (): TypedValue[] => {\n return [{ type: PropertyType.dateTime, value: new Date().toISOString() }];\n },\n\n /**\n * Returns the current time.\n *\n * See: https://hl7.org/fhirpath/#timeofday-time\n */\n timeOfDay: (): TypedValue[] => {\n return [{ type: PropertyType.time, value: new Date().toISOString().substring(11) }];\n },\n\n /**\n * Returns the current date.\n *\n * See: https://hl7.org/fhirpath/#today-date\n */\n today: (): TypedValue[] => {\n return [{ type: PropertyType.date, value: new Date().toISOString().substring(0, 10) }];\n },\n\n /**\n * Calculates the difference between two dates or date/times.\n *\n * This is not part of the official FHIRPath spec.\n *\n * IBM FHIR issue: https://github.com/IBM/FHIR/issues/1014\n * IBM FHIR PR: https://github.com/IBM/FHIR/pull/1023\n */\n between: (input: TypedValue[], startAtom: Atom, endAtom: Atom, unitsAtom: Atom): TypedValue[] => {\n const startDate = functions.toDateTime(startAtom.eval(input));\n if (startDate.length === 0) {\n throw new Error('Invalid start date');\n }\n const endDate = functions.toDateTime(endAtom.eval(input));\n if (endDate.length === 0) {\n throw new Error('Invalid end date');\n }\n const unit = unitsAtom.eval(input)[0]?.value as string;\n if (unit !== 'years' && unit !== 'months' && unit !== 'days') {\n throw new Error('Invalid units');\n }\n const age = calculateAge(startDate[0].value, endDate[0].value);\n return [{ type: PropertyType.Quantity, value: { value: age[unit], unit } }];\n },\n\n /*\n * 6.3 Types\n */\n\n /**\n * The is() function is supported for backwards compatibility with previous\n * implementations of FHIRPath. Just as with the is keyword, the type argument\n * is an identifier that must resolve to the name of a type in a model.\n *\n * For implementations with compile-time typing, this requires special-case\n * handling when processing the argument to treat it as a type specifier rather\n * than an identifier expression:\n *\n * @param input\n * @param typeAtom\n * @returns\n */\n is: (input: TypedValue[], typeAtom: Atom): TypedValue[] => {\n let typeName = '';\n if (typeAtom instanceof SymbolAtom) {\n typeName = typeAtom.name;\n } else if (typeAtom instanceof DotAtom) {\n typeName = (typeAtom.left as SymbolAtom).name + '.' + (typeAtom.right as SymbolAtom).name;\n }\n if (!typeName) {\n return [];\n }\n return input.map((value) => ({ type: PropertyType.boolean, value: fhirPathIs(value, typeName) }));\n },\n\n /*\n * 6.5 Boolean logic\n */\n\n /**\n * 6.5.3. not() : Boolean\n *\n * Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):\n *\n * @param input\n * @returns\n */\n not: (input: TypedValue[]): TypedValue[] => {\n return functions.toBoolean(input).map((value) => ({ type: PropertyType.boolean, value: !value.value }));\n },\n\n /*\n * Additional functions\n * See: https://hl7.org/fhir/fhirpath.html#functions\n */\n\n /**\n * 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.\n * The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.\n * @param input The input collection.\n * @returns\n */\n resolve: (input: TypedValue[]): TypedValue[] => {\n return input\n .map((e) => {\n const value = e.value;\n let refStr: string | undefined;\n if (typeof value === 'string') {\n refStr = value;\n } else if (typeof value === 'object') {\n const ref = value as Reference;\n if (ref.resource) {\n return toTypedValue(ref.resource);\n }\n refStr = ref.reference;\n }\n if (!refStr) {\n return { type: PropertyType.BackboneElement, value: null };\n }\n const [resourceType, id] = refStr.split('/');\n return { type: PropertyType.BackboneElement, value: { resourceType, id } };\n })\n .filter((e) => !!e.value);\n },\n\n /**\n * The as operator can be used to treat a value as a specific type.\n * @param input The input value.\n * @returns The value as the specific type.\n */\n as: (input: TypedValue[]): TypedValue[] => {\n return input;\n },\n\n /*\n * 12. Formal Specifications\n */\n\n /**\n * Returns the type of the input.\n *\n * 12.2. Model Information\n *\n * The model information returned by the reflection function type() is specified as an\n * XML Schema document (xsd) and included in this specification at the following link:\n * https://hl7.org/fhirpath/modelinfo.xsd\n *\n * See: https://hl7.org/fhirpath/#model-information\n *\n * @param input The input collection.\n * @returns\n */\n type: (input: TypedValue[]): TypedValue[] => {\n return input.map(({ value }) => {\n if (typeof value === 'boolean') {\n return { type: PropertyType.BackboneElement, value: { namespace: 'System', name: 'Boolean' } };\n }\n if (typeof value === 'number') {\n return { type: PropertyType.BackboneElement, value: { namespace: 'System', name: 'Integer' } };\n }\n if (value && typeof value === 'object' && 'resourceType' in value) {\n return {\n type: PropertyType.BackboneElement,\n value: { namespace: 'FHIR', name: (value as Resource).resourceType },\n };\n }\n return { type: PropertyType.BackboneElement, value: null };\n });\n },\n\n conformsTo: (input: TypedValue[], systemAtom: Atom): TypedValue[] => {\n const system = systemAtom.eval(input)[0].value as string;\n if (!system.startsWith('http://hl7.org/fhir/StructureDefinition/')) {\n throw new Error('Expected a StructureDefinition URL');\n }\n const expectedResourceType = system.replace('http://hl7.org/fhir/StructureDefinition/', '');\n return input.map((value) => ({\n type: PropertyType.boolean,\n value: value.value?.resourceType === expectedResourceType,\n }));\n },\n};\n\n/*\n * Helper utilities\n */\n\nfunction applyStringFunc<T>(\n func: (str: string, ...args: unknown[]) => T | undefined,\n input: TypedValue[],\n ...argsAtoms: (Atom | undefined)[]\n): TypedValue[] {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value !== 'string') {\n throw new Error('String function cannot be called with non-string');\n }\n const result = func(value, ...argsAtoms.map((atom) => atom && atom.eval(input)?.[0]?.value));\n if (result === undefined) {\n return [];\n }\n if (Array.isArray(result)) {\n return result.map(toTypedValue);\n }\n return [toTypedValue(result)];\n}\n\nfunction applyMathFunc(\n func: (x: number, ...args: unknown[]) => number,\n input: TypedValue[],\n ...argsAtoms: Atom[]\n): TypedValue[] {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n const quantity = isQuantity(value);\n const numberInput = quantity ? value.value : value;\n if (typeof numberInput !== 'number') {\n throw new Error('Math function cannot be called with non-number');\n }\n const result = func(numberInput, ...argsAtoms.map((atom) => atom.eval(input)?.[0]?.value));\n const type = quantity ? PropertyType.Quantity : input[0].type;\n const returnValue = quantity ? { ...value, value: result } : result;\n return [{ type, value: returnValue }];\n}\n\nfunction validateInput(input: TypedValue[], count: number): TypedValue[] {\n if (input.length !== count) {\n throw new Error(`Expected ${count} arguments`);\n }\n for (const element of input) {\n if (element === null || element === undefined) {\n throw new Error('Expected non-null argument');\n }\n }\n return input;\n}\n"],"names":[],"mappings":"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"}
@@ -345,7 +345,6 @@ function isQuantityEquivalent(x, y) {
345
345
  }
346
346
  /**
347
347
  * Resource equality.
348
- * Ignores meta.versionId and meta.lastUpdated.
349
348
  * See: https://dmitripavlutin.com/how-to-compare-objects-in-javascript/#4-deep-equality
350
349
  * @param object1 The first object.
351
350
  * @param object2 The second object.
@@ -373,8 +372,8 @@ function deepEquals(object1, object2) {
373
372
  }
374
373
  return true;
375
374
  }
376
- function isObject(object) {
377
- return object !== null && typeof object === 'object';
375
+ function isObject(obj) {
376
+ return obj !== null && typeof obj === 'object';
378
377
  }
379
378
 
380
379
  export { booleanToTypedValue, fhirPathArrayEquals, fhirPathArrayEquivalent, fhirPathEquals, fhirPathEquivalent, fhirPathIs, fhirPathNot, getTypedPropertyValue, isPeriod, isQuantity, isQuantityEquivalent, removeDuplicates, toJsBoolean, toTypedValue };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/fhirpath/utils.ts"],"sourcesContent":["import { Period, Quantity, Resource } from '@medplum/fhirtypes';\nimport { buildTypeName, globalSchema, PropertyType, TypeSchema } from '../types';\nimport { capitalize, isEmpty } from '../utils';\nimport { TypedValue } from './atoms';\n\n/**\n * Returns a single element array with a typed boolean value.\n * @param value The primitive boolean value.\n * @returns Single element array with a typed boolean value.\n */\nexport function booleanToTypedValue(value: boolean): [TypedValue] {\n return [{ type: PropertyType.boolean, value }];\n}\n\n/**\n * Returns a \"best guess\" TypedValue for a given value.\n * @param value The unknown value to check.\n * @returns A \"best guess\" TypedValue for the given value.\n */\nexport function toTypedValue(value: unknown): TypedValue {\n if (value === null || value === undefined) {\n return { type: 'undefined', value: undefined };\n } else if (Number.isSafeInteger(value)) {\n return { type: PropertyType.integer, value };\n } else if (typeof value === 'number') {\n return { type: PropertyType.decimal, value };\n } else if (typeof value === 'boolean') {\n return { type: PropertyType.boolean, value };\n } else if (typeof value === 'string') {\n return { type: PropertyType.string, value };\n } else if (isQuantity(value)) {\n return { type: PropertyType.Quantity, value };\n } else if (typeof value === 'object' && 'resourceType' in value) {\n return { type: (value as Resource).resourceType, value };\n } else {\n return { type: PropertyType.BackboneElement, value };\n }\n}\n\n/**\n * Converts unknown object into a JavaScript boolean.\n * Note that this is different than the FHIRPath \"toBoolean\",\n * which has particular semantics around arrays, empty arrays, and type conversions.\n * @param obj Any value or array of values.\n * @returns The converted boolean value according to FHIRPath rules.\n */\nexport function toJsBoolean(obj: TypedValue[]): boolean {\n return obj.length === 0 ? false : !!obj[0].value;\n}\n\n/**\n * Returns the value of the property and the property type.\n * Some property definitions support multiple types.\n * For example, \"Observation.value[x]\" can be \"valueString\", \"valueInteger\", \"valueQuantity\", etc.\n * According to the spec, there can only be one property for a given element definition.\n * This function returns the value and the type.\n * @param input The base context (FHIR resource or backbone element).\n * @param path The property path.\n * @returns The value of the property and the property type.\n */\nexport function getTypedPropertyValue(input: TypedValue, path: string): TypedValue[] | TypedValue | undefined {\n if (!input?.value) {\n return undefined;\n }\n\n const typeSchema = globalSchema.types[input.type];\n if (typeSchema) {\n const typedResult = getTypedPropertyValueWithSchema(input, path, typeSchema);\n if (typedResult) {\n return typedResult;\n }\n }\n\n return getTypedPropertyValueWithoutSchema(input, path);\n}\n\n/**\n * Returns the value of the property and the property type using a type schema.\n * @param input The base context (FHIR resource or backbone element).\n * @param path The property path.\n * @param typeSchema The input type schema.\n * @returns The value of the property and the property type.\n */\nfunction getTypedPropertyValueWithSchema(\n input: TypedValue,\n path: string,\n typeSchema: TypeSchema\n): TypedValue[] | TypedValue | undefined {\n const property = typeSchema.properties[path] ?? typeSchema.properties[path + '[x]'];\n if (!property) {\n return undefined;\n }\n\n const types = property.type;\n if (!types || types.length === 0) {\n return undefined;\n }\n\n let propertyName: string | undefined = undefined;\n let resultValue: any = undefined;\n let resultType = 'undefined';\n\n if (types.length === 1) {\n propertyName = path;\n resultValue = input.value[path];\n resultType = types[0].code as string;\n } else {\n for (const type of types) {\n const path2 = path.replace('[x]', '') + capitalize(type.code as string);\n if (path2 in input.value) {\n propertyName = path2;\n resultValue = input.value[path2];\n resultType = type.code as string;\n break;\n }\n }\n }\n\n if (isEmpty(resultValue)) {\n return undefined;\n }\n\n if (resultType === 'BackboneElement') {\n resultType = buildTypeName([input.type, propertyName as string]);\n }\n\n if (Array.isArray(resultValue)) {\n return resultValue.map((element) => ({ value: element, type: resultType }));\n } else {\n return { value: resultValue, type: resultType };\n }\n}\n\n/**\n * Returns the value of the property and the property type using a type schema.\n * Note that because the type schema is not available, this function may be inaccurate.\n * In some cases, that is the desired behavior.\n * @param typedValue The base context (FHIR resource or backbone element).\n * @param path The property path.\n * @returns The value of the property and the property type.\n */\nfunction getTypedPropertyValueWithoutSchema(\n typedValue: TypedValue,\n path: string\n): TypedValue[] | TypedValue | undefined {\n const input = typedValue.value;\n if (!input || typeof input !== 'object') {\n return undefined;\n }\n\n let result: any = undefined;\n if (path in input) {\n result = (input as { [key: string]: unknown })[path];\n } else {\n // Only support property names that would be valid types\n // Examples:\n // value + valueString = ok, because \"string\" is valid\n // value + valueDecimal = ok, because \"decimal\" is valid\n // id + identifiier = not ok, because \"entifier\" is not a valid type\n // resource + resourceType = not ok, because \"type\" is not a valid type\n for (const propertyType in PropertyType) {\n const propertyName = path + capitalize(propertyType);\n if (propertyName in input) {\n result = (input as { [key: string]: unknown })[propertyName];\n break;\n }\n }\n }\n\n if (isEmpty(result)) {\n return undefined;\n }\n\n if (Array.isArray(result)) {\n return result.map(toTypedValue);\n } else {\n return toTypedValue(result);\n }\n}\n\n/**\n * Removes duplicates in array using FHIRPath equality rules.\n * @param arr The input array.\n * @returns The result array with duplicates removed.\n */\nexport function removeDuplicates(arr: TypedValue[]): TypedValue[] {\n const result: TypedValue[] = [];\n for (const i of arr) {\n let found = false;\n for (const j of result) {\n if (toJsBoolean(fhirPathEquals(i, j))) {\n found = true;\n break;\n }\n }\n if (!found) {\n result.push(i);\n }\n }\n return result;\n}\n\n/**\n * Returns a negated FHIRPath boolean expression.\n * @param input The input array.\n * @returns The negated type value array.\n */\nexport function fhirPathNot(input: TypedValue[]): TypedValue[] {\n return booleanToTypedValue(!toJsBoolean(input));\n}\n\n/**\n * Determines if two arrays are equal according to FHIRPath equality rules.\n * @param x The first array.\n * @param y The second array.\n * @returns FHIRPath true if the arrays are equal.\n */\nexport function fhirPathArrayEquals(x: TypedValue[], y: TypedValue[]): TypedValue[] {\n if (x.length === 0 || y.length === 0) {\n return [];\n }\n if (x.length !== y.length) {\n return booleanToTypedValue(false);\n }\n return booleanToTypedValue(x.every((val, index) => toJsBoolean(fhirPathEquals(val, y[index]))));\n}\n\n/**\n * Determines if two values are equal according to FHIRPath equality rules.\n * @param x The first value.\n * @param y The second value.\n * @returns True if equal.\n */\nexport function fhirPathEquals(x: TypedValue, y: TypedValue): TypedValue[] {\n const xValue = x.value;\n const yValue = y.value;\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n return booleanToTypedValue(Math.abs(xValue - yValue) < 1e-8);\n }\n if (isQuantity(xValue) && isQuantity(yValue)) {\n return booleanToTypedValue(isQuantityEquivalent(xValue, yValue));\n }\n if (typeof xValue === 'object' && typeof yValue === 'object') {\n return booleanToTypedValue(deepEquals(x, y));\n }\n return booleanToTypedValue(xValue === yValue);\n}\n\n/**\n * Determines if two arrays are equivalent according to FHIRPath equality rules.\n * @param x The first array.\n * @param y The second array.\n * @returns FHIRPath true if the arrays are equivalent.\n */\nexport function fhirPathArrayEquivalent(x: TypedValue[], y: TypedValue[]): TypedValue[] {\n if (x.length === 0 && y.length === 0) {\n return booleanToTypedValue(true);\n }\n if (x.length !== y.length) {\n return booleanToTypedValue(false);\n }\n x.sort(fhirPathEquivalentCompare);\n y.sort(fhirPathEquivalentCompare);\n return booleanToTypedValue(x.every((val, index) => toJsBoolean(fhirPathEquivalent(val, y[index]))));\n}\n\n/**\n * Determines if two values are equivalent according to FHIRPath equality rules.\n * @param x The first value.\n * @param y The second value.\n * @returns True if equivalent.\n */\nexport function fhirPathEquivalent(x: TypedValue, y: TypedValue): TypedValue[] {\n const xValue = x.value;\n const yValue = y.value;\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n // Use more generous threshold than equality\n // Decimal: values must be equal, comparison is done on values rounded to the precision of the least precise operand.\n // Trailing zeroes after the decimal are ignored in determining precision.\n return booleanToTypedValue(Math.abs(xValue - yValue) < 0.01);\n }\n if (isQuantity(xValue) && isQuantity(yValue)) {\n return booleanToTypedValue(isQuantityEquivalent(xValue, yValue));\n }\n if (typeof xValue === 'object' && typeof yValue === 'object') {\n return booleanToTypedValue(deepEquals(xValue, yValue));\n }\n if (typeof xValue === 'string' && typeof yValue === 'string') {\n // String: the strings must be the same, ignoring case and locale, and normalizing whitespace\n // (see String Equivalence for more details).\n return booleanToTypedValue(xValue.toLowerCase() === yValue.toLowerCase());\n }\n return booleanToTypedValue(xValue === yValue);\n}\n\n/**\n * Returns the sort order of two values for FHIRPath array equivalence.\n * @param x The first value.\n * @param y The second value.\n * @returns The sort order of the values.\n */\nfunction fhirPathEquivalentCompare(x: TypedValue, y: TypedValue): number {\n const xValue = x.value;\n const yValue = y.value;\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n return xValue - yValue;\n }\n if (typeof xValue === 'string' && typeof yValue === 'string') {\n return xValue.localeCompare(yValue);\n }\n return 0;\n}\n\n/**\n * Determines if the typed value is the desired type.\n * @param typedValue The typed value to check.\n * @param desiredType The desired type name.\n * @returns True if the typed value is of the desired type.\n */\nexport function fhirPathIs(typedValue: TypedValue, desiredType: string): boolean {\n const { value } = typedValue;\n if (value === undefined || value === null) {\n return false;\n }\n\n switch (desiredType) {\n case 'Boolean':\n return typeof value === 'boolean';\n case 'Decimal':\n case 'Integer':\n return typeof value === 'number';\n case 'Date':\n return typeof value === 'string' && !!value.match(/^\\d{4}(-\\d{2}(-\\d{2})?)?/);\n case 'DateTime':\n return typeof value === 'string' && !!value.match(/^\\d{4}(-\\d{2}(-\\d{2})?)?T/);\n case 'Time':\n return typeof value === 'string' && !!value.match(/^T\\d/);\n case 'Period':\n return isPeriod(value);\n case 'Quantity':\n return isQuantity(value);\n default:\n return typeof value === 'object' && value?.resourceType === desiredType;\n }\n}\n\n/**\n * Determines if the input is a Period object.\n * This is heuristic based, as we do not have strong typing at runtime.\n * @param input The input value.\n * @returns True if the input is a period.\n */\nexport function isPeriod(input: unknown): input is Period {\n return !!(input && typeof input === 'object' && 'start' in input);\n}\n\n/**\n * Determines if the input is a Quantity object.\n * This is heuristic based, as we do not have strong typing at runtime.\n * @param input The input value.\n * @returns True if the input is a quantity.\n */\nexport function isQuantity(input: unknown): input is Quantity {\n return !!(input && typeof input === 'object' && 'value' in input && typeof (input as Quantity).value === 'number');\n}\n\nexport function isQuantityEquivalent(x: Quantity, y: Quantity): boolean {\n return (\n Math.abs((x.value as number) - (y.value as number)) < 0.01 &&\n (x.unit === y.unit || x.code === y.code || x.unit === y.code || x.code === y.unit)\n );\n}\n\n/**\n * Resource equality.\n * Ignores meta.versionId and meta.lastUpdated.\n * See: https://dmitripavlutin.com/how-to-compare-objects-in-javascript/#4-deep-equality\n * @param object1 The first object.\n * @param object2 The second object.\n * @returns True if the objects are equal.\n */\nfunction deepEquals<T1, T2>(object1: T1, object2: T2): boolean {\n const keys1 = Object.keys(object1) as (keyof T1)[];\n const keys2 = Object.keys(object2) as (keyof T2)[];\n if (keys1.length !== keys2.length) {\n return false;\n }\n for (const key of keys1) {\n const val1 = object1[key] as unknown;\n const val2 = object2[key as unknown as keyof T2] as unknown;\n if (isObject(val1) && isObject(val2)) {\n if (!deepEquals(val1, val2)) {\n return false;\n }\n } else {\n if (val1 !== val2) {\n return false;\n }\n }\n }\n return true;\n}\n\nfunction isObject(object: unknown): boolean {\n return object !== null && typeof object === 'object';\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/fhirpath/utils.ts"],"sourcesContent":["import { Period, Quantity, Resource } from '@medplum/fhirtypes';\nimport { buildTypeName, globalSchema, PropertyType, TypeSchema } from '../types';\nimport { capitalize, isEmpty } from '../utils';\nimport { TypedValue } from './atoms';\n\n/**\n * Returns a single element array with a typed boolean value.\n * @param value The primitive boolean value.\n * @returns Single element array with a typed boolean value.\n */\nexport function booleanToTypedValue(value: boolean): [TypedValue] {\n return [{ type: PropertyType.boolean, value }];\n}\n\n/**\n * Returns a \"best guess\" TypedValue for a given value.\n * @param value The unknown value to check.\n * @returns A \"best guess\" TypedValue for the given value.\n */\nexport function toTypedValue(value: unknown): TypedValue {\n if (value === null || value === undefined) {\n return { type: 'undefined', value: undefined };\n } else if (Number.isSafeInteger(value)) {\n return { type: PropertyType.integer, value };\n } else if (typeof value === 'number') {\n return { type: PropertyType.decimal, value };\n } else if (typeof value === 'boolean') {\n return { type: PropertyType.boolean, value };\n } else if (typeof value === 'string') {\n return { type: PropertyType.string, value };\n } else if (isQuantity(value)) {\n return { type: PropertyType.Quantity, value };\n } else if (typeof value === 'object' && 'resourceType' in value) {\n return { type: (value as Resource).resourceType, value };\n } else {\n return { type: PropertyType.BackboneElement, value };\n }\n}\n\n/**\n * Converts unknown object into a JavaScript boolean.\n * Note that this is different than the FHIRPath \"toBoolean\",\n * which has particular semantics around arrays, empty arrays, and type conversions.\n * @param obj Any value or array of values.\n * @returns The converted boolean value according to FHIRPath rules.\n */\nexport function toJsBoolean(obj: TypedValue[]): boolean {\n return obj.length === 0 ? false : !!obj[0].value;\n}\n\n/**\n * Returns the value of the property and the property type.\n * Some property definitions support multiple types.\n * For example, \"Observation.value[x]\" can be \"valueString\", \"valueInteger\", \"valueQuantity\", etc.\n * According to the spec, there can only be one property for a given element definition.\n * This function returns the value and the type.\n * @param input The base context (FHIR resource or backbone element).\n * @param path The property path.\n * @returns The value of the property and the property type.\n */\nexport function getTypedPropertyValue(input: TypedValue, path: string): TypedValue[] | TypedValue | undefined {\n if (!input?.value) {\n return undefined;\n }\n\n const typeSchema = globalSchema.types[input.type];\n if (typeSchema) {\n const typedResult = getTypedPropertyValueWithSchema(input, path, typeSchema);\n if (typedResult) {\n return typedResult;\n }\n }\n\n return getTypedPropertyValueWithoutSchema(input, path);\n}\n\n/**\n * Returns the value of the property and the property type using a type schema.\n * @param input The base context (FHIR resource or backbone element).\n * @param path The property path.\n * @param typeSchema The input type schema.\n * @returns The value of the property and the property type.\n */\nfunction getTypedPropertyValueWithSchema(\n input: TypedValue,\n path: string,\n typeSchema: TypeSchema\n): TypedValue[] | TypedValue | undefined {\n const property = typeSchema.properties[path] ?? typeSchema.properties[path + '[x]'];\n if (!property) {\n return undefined;\n }\n\n const types = property.type;\n if (!types || types.length === 0) {\n return undefined;\n }\n\n let propertyName: string | undefined = undefined;\n let resultValue: any = undefined;\n let resultType = 'undefined';\n\n if (types.length === 1) {\n propertyName = path;\n resultValue = input.value[path];\n resultType = types[0].code as string;\n } else {\n for (const type of types) {\n const path2 = path.replace('[x]', '') + capitalize(type.code as string);\n if (path2 in input.value) {\n propertyName = path2;\n resultValue = input.value[path2];\n resultType = type.code as string;\n break;\n }\n }\n }\n\n if (isEmpty(resultValue)) {\n return undefined;\n }\n\n if (resultType === 'BackboneElement') {\n resultType = buildTypeName([input.type, propertyName as string]);\n }\n\n if (Array.isArray(resultValue)) {\n return resultValue.map((element) => ({ value: element, type: resultType }));\n } else {\n return { value: resultValue, type: resultType };\n }\n}\n\n/**\n * Returns the value of the property and the property type using a type schema.\n * Note that because the type schema is not available, this function may be inaccurate.\n * In some cases, that is the desired behavior.\n * @param typedValue The base context (FHIR resource or backbone element).\n * @param path The property path.\n * @returns The value of the property and the property type.\n */\nfunction getTypedPropertyValueWithoutSchema(\n typedValue: TypedValue,\n path: string\n): TypedValue[] | TypedValue | undefined {\n const input = typedValue.value;\n if (!input || typeof input !== 'object') {\n return undefined;\n }\n\n let result: any = undefined;\n if (path in input) {\n result = (input as { [key: string]: unknown })[path];\n } else {\n // Only support property names that would be valid types\n // Examples:\n // value + valueString = ok, because \"string\" is valid\n // value + valueDecimal = ok, because \"decimal\" is valid\n // id + identifiier = not ok, because \"entifier\" is not a valid type\n // resource + resourceType = not ok, because \"type\" is not a valid type\n for (const propertyType in PropertyType) {\n const propertyName = path + capitalize(propertyType);\n if (propertyName in input) {\n result = (input as { [key: string]: unknown })[propertyName];\n break;\n }\n }\n }\n\n if (isEmpty(result)) {\n return undefined;\n }\n\n if (Array.isArray(result)) {\n return result.map(toTypedValue);\n } else {\n return toTypedValue(result);\n }\n}\n\n/**\n * Removes duplicates in array using FHIRPath equality rules.\n * @param arr The input array.\n * @returns The result array with duplicates removed.\n */\nexport function removeDuplicates(arr: TypedValue[]): TypedValue[] {\n const result: TypedValue[] = [];\n for (const i of arr) {\n let found = false;\n for (const j of result) {\n if (toJsBoolean(fhirPathEquals(i, j))) {\n found = true;\n break;\n }\n }\n if (!found) {\n result.push(i);\n }\n }\n return result;\n}\n\n/**\n * Returns a negated FHIRPath boolean expression.\n * @param input The input array.\n * @returns The negated type value array.\n */\nexport function fhirPathNot(input: TypedValue[]): TypedValue[] {\n return booleanToTypedValue(!toJsBoolean(input));\n}\n\n/**\n * Determines if two arrays are equal according to FHIRPath equality rules.\n * @param x The first array.\n * @param y The second array.\n * @returns FHIRPath true if the arrays are equal.\n */\nexport function fhirPathArrayEquals(x: TypedValue[], y: TypedValue[]): TypedValue[] {\n if (x.length === 0 || y.length === 0) {\n return [];\n }\n if (x.length !== y.length) {\n return booleanToTypedValue(false);\n }\n return booleanToTypedValue(x.every((val, index) => toJsBoolean(fhirPathEquals(val, y[index]))));\n}\n\n/**\n * Determines if two values are equal according to FHIRPath equality rules.\n * @param x The first value.\n * @param y The second value.\n * @returns True if equal.\n */\nexport function fhirPathEquals(x: TypedValue, y: TypedValue): TypedValue[] {\n const xValue = x.value;\n const yValue = y.value;\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n return booleanToTypedValue(Math.abs(xValue - yValue) < 1e-8);\n }\n if (isQuantity(xValue) && isQuantity(yValue)) {\n return booleanToTypedValue(isQuantityEquivalent(xValue, yValue));\n }\n if (typeof xValue === 'object' && typeof yValue === 'object') {\n return booleanToTypedValue(deepEquals(x, y));\n }\n return booleanToTypedValue(xValue === yValue);\n}\n\n/**\n * Determines if two arrays are equivalent according to FHIRPath equality rules.\n * @param x The first array.\n * @param y The second array.\n * @returns FHIRPath true if the arrays are equivalent.\n */\nexport function fhirPathArrayEquivalent(x: TypedValue[], y: TypedValue[]): TypedValue[] {\n if (x.length === 0 && y.length === 0) {\n return booleanToTypedValue(true);\n }\n if (x.length !== y.length) {\n return booleanToTypedValue(false);\n }\n x.sort(fhirPathEquivalentCompare);\n y.sort(fhirPathEquivalentCompare);\n return booleanToTypedValue(x.every((val, index) => toJsBoolean(fhirPathEquivalent(val, y[index]))));\n}\n\n/**\n * Determines if two values are equivalent according to FHIRPath equality rules.\n * @param x The first value.\n * @param y The second value.\n * @returns True if equivalent.\n */\nexport function fhirPathEquivalent(x: TypedValue, y: TypedValue): TypedValue[] {\n const xValue = x.value;\n const yValue = y.value;\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n // Use more generous threshold than equality\n // Decimal: values must be equal, comparison is done on values rounded to the precision of the least precise operand.\n // Trailing zeroes after the decimal are ignored in determining precision.\n return booleanToTypedValue(Math.abs(xValue - yValue) < 0.01);\n }\n if (isQuantity(xValue) && isQuantity(yValue)) {\n return booleanToTypedValue(isQuantityEquivalent(xValue, yValue));\n }\n if (typeof xValue === 'object' && typeof yValue === 'object') {\n return booleanToTypedValue(deepEquals(xValue, yValue));\n }\n if (typeof xValue === 'string' && typeof yValue === 'string') {\n // String: the strings must be the same, ignoring case and locale, and normalizing whitespace\n // (see String Equivalence for more details).\n return booleanToTypedValue(xValue.toLowerCase() === yValue.toLowerCase());\n }\n return booleanToTypedValue(xValue === yValue);\n}\n\n/**\n * Returns the sort order of two values for FHIRPath array equivalence.\n * @param x The first value.\n * @param y The second value.\n * @returns The sort order of the values.\n */\nfunction fhirPathEquivalentCompare(x: TypedValue, y: TypedValue): number {\n const xValue = x.value;\n const yValue = y.value;\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n return xValue - yValue;\n }\n if (typeof xValue === 'string' && typeof yValue === 'string') {\n return xValue.localeCompare(yValue);\n }\n return 0;\n}\n\n/**\n * Determines if the typed value is the desired type.\n * @param typedValue The typed value to check.\n * @param desiredType The desired type name.\n * @returns True if the typed value is of the desired type.\n */\nexport function fhirPathIs(typedValue: TypedValue, desiredType: string): boolean {\n const { value } = typedValue;\n if (value === undefined || value === null) {\n return false;\n }\n\n switch (desiredType) {\n case 'Boolean':\n return typeof value === 'boolean';\n case 'Decimal':\n case 'Integer':\n return typeof value === 'number';\n case 'Date':\n return typeof value === 'string' && !!value.match(/^\\d{4}(-\\d{2}(-\\d{2})?)?/);\n case 'DateTime':\n return typeof value === 'string' && !!value.match(/^\\d{4}(-\\d{2}(-\\d{2})?)?T/);\n case 'Time':\n return typeof value === 'string' && !!value.match(/^T\\d/);\n case 'Period':\n return isPeriod(value);\n case 'Quantity':\n return isQuantity(value);\n default:\n return typeof value === 'object' && value?.resourceType === desiredType;\n }\n}\n\n/**\n * Determines if the input is a Period object.\n * This is heuristic based, as we do not have strong typing at runtime.\n * @param input The input value.\n * @returns True if the input is a period.\n */\nexport function isPeriod(input: unknown): input is Period {\n return !!(input && typeof input === 'object' && 'start' in input);\n}\n\n/**\n * Determines if the input is a Quantity object.\n * This is heuristic based, as we do not have strong typing at runtime.\n * @param input The input value.\n * @returns True if the input is a quantity.\n */\nexport function isQuantity(input: unknown): input is Quantity {\n return !!(input && typeof input === 'object' && 'value' in input && typeof (input as Quantity).value === 'number');\n}\n\nexport function isQuantityEquivalent(x: Quantity, y: Quantity): boolean {\n return (\n Math.abs((x.value as number) - (y.value as number)) < 0.01 &&\n (x.unit === y.unit || x.code === y.code || x.unit === y.code || x.code === y.unit)\n );\n}\n\n/**\n * Resource equality.\n * See: https://dmitripavlutin.com/how-to-compare-objects-in-javascript/#4-deep-equality\n * @param object1 The first object.\n * @param object2 The second object.\n * @returns True if the objects are equal.\n */\nfunction deepEquals<T1 extends object, T2 extends object>(object1: T1, object2: T2): boolean {\n const keys1 = Object.keys(object1) as (keyof T1)[];\n const keys2 = Object.keys(object2) as (keyof T2)[];\n if (keys1.length !== keys2.length) {\n return false;\n }\n for (const key of keys1) {\n const val1 = object1[key] as unknown;\n const val2 = object2[key as unknown as keyof T2] as unknown;\n if (isObject(val1) && isObject(val2)) {\n if (!deepEquals(val1, val2)) {\n return false;\n }\n } else {\n if (val1 !== val2) {\n return false;\n }\n }\n }\n return true;\n}\n\nfunction isObject(obj: unknown): obj is object {\n return obj !== null && typeof obj === 'object';\n}\n"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ function formatAddress(address, options) {
21
21
  }
22
22
  function formatHumanName(name, options) {
23
23
  const builder = [];
24
- if (name.prefix && ((options === null || options === void 0 ? void 0 : options.all) || (options === null || options === void 0 ? void 0 : options.prefix))) {
24
+ if (name.prefix && (options === null || options === void 0 ? void 0 : options.prefix) !== false) {
25
25
  builder.push(...name.prefix);
26
26
  }
27
27
  if (name.given) {
@@ -30,7 +30,7 @@ function formatHumanName(name, options) {
30
30
  if (name.family) {
31
31
  builder.push(name.family);
32
32
  }
33
- if (name.suffix && ((options === null || options === void 0 ? void 0 : options.all) || (options === null || options === void 0 ? void 0 : options.suffix))) {
33
+ if (name.suffix && (options === null || options === void 0 ? void 0 : options.suffix) !== false) {
34
34
  builder.push(...name.suffix);
35
35
  }
36
36
  if (name.use && ((options === null || options === void 0 ? void 0 : options.all) || (options === null || options === void 0 ? void 0 : options.use))) {