# fhirpath

> A FHIRPath engine

Latest version **5.2.0** (published 2026-08-25) · SEE LICENSE in LICENSE.md license · 0 weekly downloads

## Install

```sh
npm install fhirpath
pnpm add fhirpath
yarn add fhirpath
bun add fhirpath
```

Provides the command `fhirpath`.

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 5.2.0 |
| Published | 2026-08-25 |
| First published | 2018-08-01 |
| Weekly downloads | 0 |
| License | SEE LICENSE in LICENSE.md |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=20.0.0 |
| Dependencies | 7 |
| Unpacked size | 4.3 MB |
| Known vulnerabilities | 0 |
| Install scripts | yes |
| GitHub stars | 189 |
| Maintainers | plynchnlm, yury-sedinkin |

## Links

- npm: https://www.npmjs.com/package/fhirpath
- Repository: https://github.com/HL7/fhirpath.js
- Homepage: https://github.com/HL7/fhirpath.js#readme
- Issues: https://github.com/HL7/fhirpath.js/issues
- npm.io page: https://npm.io/package/fhirpath

## Dependencies (7)

- [antlr4](https://npm.io/package/antlr4.md) ~4.9.3
- [js-yaml](https://npm.io/package/js-yaml.md) ^4.1.1
- [date-fns](https://npm.io/package/date-fns.md) ^1.30.1
- [commander](https://npm.io/package/commander.md) ^14.0.3
- [decimal.js](https://npm.io/package/decimal.js.md) ^10.6.0
- [@loxjs/url-join](https://npm.io/package/@loxjs/url-join.md) ^1.0.2
- [@lhncbc/ucum-lhc](https://npm.io/package/@lhncbc/ucum-lhc.md) ^5.0.0

## Recent versions

- 5.2.0 (latest) — 2026-08-25
- 5.1.1 — 2026-08-05
- 5.1.0 — 2026-07-30
- 5.0.0 — 2026-07-13
- 4.11.0 — 2026-05-29
- 4.10.1 — 2026-05-05
- 4.10.0 — 2026-04-30
- 4.9.3 — 2026-04-10
- 4.9.2 — 2026-03-31
- 4.9.1 — 2026-03-18
- 4.9.0 — 2026-03-17
- 4.8.5 — 2026-02-10
- 4.8.4 — 2026-02-04
- 4.8.3 — 2026-01-25
- 4.8.2 — 2025-12-09
- … 132 more at https://npm.io/package/fhirpath/versions

## README

# fhirpath.js

[FHIRPath](http://hl7.org/fhirpath/) implementation in JavaScript.

## Demo
Try it out on the [demo page](https://hl7.github.io/fhirpath.js/).

## Table of Contents:
- [Installation](#installation)
  * [Server-side (Node.js)](#server-side-nodejs)
  * [Web-browser](#web-browser)
- [API Usage](#api-usage)
  * [Using the `%resource` environment variable](#using-the-resource-environment-variable)
  * [Mathematical operations mode](#mathematical-operations-mode)
    + [Passing precise numbers in the input resource](#passing-precise-numbers-in-the-input-resource)
    + [Preserving precise numbers in evaluation results](#preserving-precise-numbers-in-evaluation-results)
  * [Asynchronous functions](#asynchronous-functions)
  * [User-defined functions](#user-defined-functions)
- [fhirpath CLI](#fhirpath-cli)
- [Implementation Status](#implementation-status)
- [Development Notes](#development-notes)
  * [Building the demo page](#building-the-demo-page)
  * [Updating the FHIR module on a FHIR release](#updating-the-fhir-module-on-a-fhir-release)
- [Credits](#credits)

## Installation:

### Server-side (Node.js)

```sh
npm install --save fhirpath
```

The library ships both CommonJS and ES module entry points.

For CommonJS:
```js
const fhirpath = require('fhirpath');
// For FHIR model data (choice type support) pull in the model file:
const fhirpath_r4_model = require('fhirpath/fhir-context/r4');
```

For ESM:
```js
import fhirpath from 'fhirpath';
// Named exports are also available, e.g. `import { evaluate } from 'fhirpath'`.
// For FHIR model data (choice type support) pull in the model file:
import fhirpath_r4_model from 'fhirpath/fhir-context/r4';
```

The `import` entry point resolves to a pre-bundled, self-contained ES module
that inlines fhirpath's CommonJS dependencies. This means bundlers such as
esbuild (used by the Angular CLI) will not emit "CommonJS or AMD dependencies
can cause optimization bailouts" warnings for fhirpath.

Do not mix `require('fhirpath')` and `import 'fhirpath'` for the same package
within a single application. The `import` entry point is a self-contained
bundle with its own copy of the library and its dependencies, so values created
via one entry point (e.g. `FP_Decimal` or other internal type instances) are
not `instanceof`-compatible with the other, and helpers such as `ucumUtils`
would be duplicated. Pick one module system per application.

The `esm/fhirpath.mjs` bundle is generated by the package's `prepare` lifecycle
script (`npm run build:esm`) and is included in the published npm package, so
installing fhirpath from the npm registry needs no extra step. If you instead
install it from a git reference with lifecycle scripts disabled (e.g.
`npm install --ignore-scripts`), run `npm run build:esm` afterward so the
`import` entry point (`esm/fhirpath.mjs`) exists.

### Web-browser:

Download the zip file from the [releases
page](https://github.com/HL7/fhirpath.js/releases).  It contains a JavaScript
file, fhirpath.min.js, which defines a global "fhirpath" variable, which you can
then use as shown below.  Note that this file is UTF-8 encoded, and the script
needs to be loaded as such.  For an example, see the
browser-build/test/index.html file, which sets the page to be UTF-8.

For FHIR-specific features (e.g. handling of choice type fields), you will also
want to include a second file with the desired FHIR version model data, e.g.
fhirpath.r4.min.js for pulling in the R4 model.  (At the moment, those files are
small, but it would not be surprising if they grew as more support for FHIR type
handling is added, so they are kept seperate from the main FHIRPath file.)
These will define additional global variables like "fhirpath_dstu2_model",
"fhirpath_stu3_model" or "fhirpath_r4_model".

## API Usage

Evaluating FHIRPath:

```js
evaluate(resourceObject, fhirPathExpression, envVars, model, options);
```
where:
* resourceObject - FHIR resource, part of a resource (in this case
  fhirPathExpression.base should be provided), bundle as js object or array
  of resources.
* fhirPathExpression - string with FHIRPath expression, sample 'Patient.name.given',
  or object, if fhirData represents the part of the FHIR resource obtained
  without using fhirpath.js:
    * fhirPathExpression.base - base path in resource from which fhirData was extracted
    * fhirPathExpression.expression - FHIRPath expression relative to path.base
* envVars - a hash of variable name/value pairs. It is not recommended to 
  modify the internal fields of a variable after passing it to the evaluation
  function, since these changes may not be taken into account in further
  evaluations due to caching of the evaluation results.
  We currently cache `%questionnaire` scores for the `weight()` function.
* model - the "model" data object specific to a domain, e.g. R4.
  For example, you could pass in the result of require("fhirpath/fhir-context/r4");
* options - additional options:
    * options.resolveInternalTypes - whether values of internal
      types should be converted to standard JavaScript types (true by default).
      If false is passed, this conversion can be done later by calling
      fhirpath.resolveInternalTypes().
    * options.keepDecimalTypes - when true, FP_Decimal values are preserved
      as-is instead of being converted to JavaScript numbers (false by default).
      See the section on [Mathematical operations mode](#mathematical-operations-mode) for more details.
    * options.traceFn - An optional trace function to call when tracing.
    * options.userInvocationTable - a user invocation table used
      to replace any existing functions or define new ones.
    * options.async - defines how to support asynchronous functions:
        * false or similar to false, e.g. undefined, null, or 0 (default) - throw
          an exception,
        * true or similar to true - return Promise, only for asynchronous functions,
        * "always" - return Promise always.
    * options.terminologyUrl - a URL, or an array of URLs, that point to
      terminology server(s). These URLs are used to initialize %terminologies,
      as defined in the FHIR FHIRPath
      [Terminology Service API](https://www.hl7.org/fhir/fhirpath.html#txapi).
      When an array of URLs is provided, the servers are tried in order, and the
      server that first resolves a given ValueSet, CodeSystem, or ConceptMap is
      preferred (tried first) for subsequent operations on that artifact.
      See the [Implementation Status](#implementation-status) section for the
      currently supported %terminologies APIs.
    * options.fhirServerUrl - a URL pointing to a FHIR RESTful API server that
      is used to `resolve()` resources.
    * options.signal - an AbortSignal object that allows you to [abort the
      asynchronous FHIRPath expression evaluation](docs/abort.md).
    * options.httpHeaders - an object with HTTP headers that will be used
      when making requests to FHIR servers (e.g. for terminology servers).
      The object has the following structure:
      ```
      {
        <server base url>: {
          <header name>: <header value>,
          ...
        },
        ...
      }
      ```
      See [authentication to FHIR servers](docs/auth.md).
    * options.preciseMath - defines which mathematical operations mode to use:
        * true - use precision-safe math operations for accurate decimal
          calculations (e.g., 0.1 + 0.2 = 0.3)
        * false (default) - use native JavaScript math operations for better
          performance but with potential floating-point precision issues (e.g.,
          0.1 + 0.2 = 0.30000000000000004)

Note:  The resource will be modified by this function to add type information.

Basic example:

```js
fhirpath.evaluate({"resourceType": "Patient", ...}, 'Patient.name.given');
```

Environment variables can be passed in as third argument as a hash of name/value
pairs:

```js
fhirpath.evaluate({}, '%a - 1', {a: 5});
```

To include FHIR model data (for support of choice types), pass in the model data
object as the fourth argument:

```js
fhirpath.evaluate({"resourceType": "Observation", "valueString": "green"},
                  'Observation.value', null, fhirpath_r4_model);
```

If the first parameter is a resource part obtained without using fhirpath.js,
the second parameter should be an object with properties "base" and
"expression":
base - the path in the resource that represents the partial resource being used
       as the context,
expression - fhirpath expression relative to base.

```js
fhirpath.evaluate({ "answer": { "valueQuantity": ...}},
                  { "base": "QuestionnaireResponse.item",
                    "expression": "answer.value = 2 year"},
                  null, fhirpath_r4_model);                  
```

If the first parameter is a resource part obtained using fhirpath.js, it may
already have internal information in the hidden (non-enumerable) property
`__path__`, so the second parameter could be just an expression.

```js
const resourcePart = fhirpath.evaluate(
  questionnaireResponse,'QuestionnaireResponse.item', null, fhirpath_r4_model);
fhirpath.evaluate(
  resourcePart, "answer.value = 2 year", null, fhirpath_r4_model);                  
```

Precompiling fhirpath - result can be reused against multiple resources:

```js
const path = fhirpath.compile('Patient.name.given', fhirpath_r4_model);
let res = path({"resourceType": "Patient", ...}, {a: 5, ...});
```

If you are going to use the above "precompile" option with a resource part
obtained without using fhirpath.js, the first parameter should be
an object with properties "base" and "expression":
base - the path in the resource that represents the partial resource being used
       as the context,
expression - fhirpath expression relative to base.

```js
const path = fhirpath.compile({ "base": "QuestionnaireResponse.item",
                                "expression": "answer.value = 2 year"},
                              fhirpath_r4_model);
let res = path({ "answer": { "valueQuantity": ...}, {a: 5, ...});
```

During expression evaluation, some values or parts of values may have internal
data types (e.g. FP_DateTime, FP_Time, FP_Quantity). By default, all of these
values are converted to standard JavaScript types, but if you need to use the
result of evaluation as a context variable for another FHIRpath expression,
it would be best to preserve the internal data types. To do this you can use
the option "resolveInternalTypes" = false:

```js
const contextVariable = fhirpath.evaluate(
  resource, expression, envVars, model, {resolveInternalTypes: false}
);
```

This option may also be passed to compile function:

```js
const path = fhirpath.compile(
  expression, model, {resolveInternalTypes: false}
);
```

If at some point you decide to convert all values which have internal types to
standard JavaScript types you can use the special function "resolveInternalTypes":

```js
const res = fhirpath.resolveInternalTypes(value);
```

> **Note (changed in v5.0.0):** When `resolveInternalTypes` is `false`, the raw
> result may include *metadata-only* `ResourceNode`s (see the `ResourceNode`
> class in `src/types.js` / `src/fhirpath.d.ts`). These represent FHIR primitive
> elements that carry only sibling `_`-metadata (e.g. an `id` or `extension`
> under `_birthDate`) and no value, so their `data` is `null`/`undefined` while
> `_data` is populated. Such nodes are now preserved in the raw output;
> previously they were omitted. The default (resolved) output and
> `fhirpath.resolveInternalTypes()` still drop them, so resolved results are
> unchanged. If you consume the raw result directly and want the previous
> behavior, filter these nodes out, for example:
>
> ```js
> const withValues = rawResult.filter(
>   node => !(node && typeof node === 'object'
>     && node.data == null && node._data)
> );
> ```

Also, there is a special API function to get the type of each element in FHIRPath
result array which was obtained from evaluate() (unless you resolve the internal
types). This function returns an array of strings.
In the next example, `res` will have a value like this:
  ['FHIR.dateTime', 'FHIR.string', ...].

```js
const res = fhirpath.types(
  fhirpath.evaluate(resource, expression, envVars, model, {resolveInternalTypes: false})
);
```

If you want to capture evaluations of the `trace` method, you can include that in the options object.
```js
let tracefunction = function (x, label) {
  console.log("Trace output [" + label + "]: ", x);
};

const res = fhirpath.evaluate(contextNode, path, envVars, fhirpath_r4_model, { traceFn: tracefunction });
```

### Using the `%resource` environment variable

To use the FHIR-defined `%resource` variable (as described in
[FHIRPath supplements](http://hl7.org/fhir/uv/sdc/en/expressions.html#fhirpath-supplements)
and [FHIR Specific Variables](https://hl7.org/fhir/fhirpath.html#variables)),
include the resource under the `resource` key in `envVars`. Unlike `%context`,
`%resource` is not set automatically, so an expression that references it throws
an "undefined environment variable" error when it is omitted.

When evaluating a complete resource, `envVars.resource` will normally be
the same resource passed as `resourceObject`:

```js
const resource = {
  resourceType: "Patient",
  name: [{given: ["John"]}]
};
fhirpath.evaluate(resource, '%resource.name.given', {resource});
```

When evaluating part of a resource, it should instead be the containing resource:

```js
const resource = {
  resourceType: "Patient",
  name: [{given: ["John"]}]
};
const resourcePart = resource.name[0];
fhirpath.evaluate(
  resourcePart,
  {base: 'Patient.name', expression: 'given = %resource.name.given'},
  {resource},
  fhirpath_r4_model
);
```

### Mathematical operations mode

fhirpath.js supports two modes for mathematical operations, controlled by the
`preciseMath` option:

- **Native math** (`preciseMath: false`, the default) — uses JavaScript's
  built-in `Number` type (IEEE 754 double-precision floating point). This is the
  fastest mode, but it can produce small rounding errors inherent to binary
  floating-point arithmetic (e.g., `0.1 + 0.2` evaluates to
  `0.30000000000000004` instead of `0.3`).

- **Precise math** (`preciseMath: true`) — uses a more precise decimal
  representation internally to avoid rounding errors in binary floating-point
  numbers.

Benefits of precise math:
- **Accuracy** — decimal arithmetic produces results that match human
  expectations (e.g., `0.1 + 0.2 = 0.3`), which is critical for clinical
  calculations, dosage computations, and financial amounts in healthcare data.
- **FHIRPath compliance** — the [FHIRPath specification](https://hl7.org/fhirpath/#decimal)
  defines decimal semantics with up to 8 digits of precision after the decimal
  point. Precise math allows this precision to be preserved in all operations
  except in cases of arithmetic overflow.

The trade-off is a moderate performance cost compared to native math. For most
FHIRPath evaluations the difference is negligible, but if you are processing
very large datasets and do not need exact decimal precision, native math may be
preferable.

To use precision-safe decimal arithmetic:
```js
fhirpath.evaluate(
  {
    "resourceType": "Observation",
    "valueQuantity": {
      "value": 0.1,
      "system": "http://unitsofmeasure.org",
      "code": "kg"
    }
  },
  'Observation.value + 0.2 \'kg\'',
  null,
  fhirpath_r4_model,
  { preciseMath: true }  // Returns 0.3 'kg' instead of 0.30000000000000004 'kg'
);
```

#### Passing precise numbers in the input resource

When a FHIR resource is parsed from JSON using the standard `JSON.parse()`,
numeric values are converted to JavaScript's `Number` type, which silently loses
precision for decimals with many significant digits (e.g.,
`JSON.parse('{"value": 12345678901234567890.12345678}')` yields
`12345678901234567000`).
Since `JSON.parse` converts every number to a `Number` _before_ the reviver
function sees it, there is no way to recover the original precision using a
reviver alone.

To preserve exact decimal values from the source data, use a lossless JSON
parser such as [lossless-json](https://www.npmjs.com/package/lossless-json),
which gives you access to the raw numeric string from the JSON source. You can
then pass that string to `FP_Decimal.getDecimal()` (where `FP_Decimal` is
exported by fhirpath.js) to create a precise decimal object.

```js
const { parse } = require('lossless-json');
const fhirpath = require('fhirpath');
const { FP_Decimal } = fhirpath;
const fhirpath_r4_model = require('fhirpath/fhir-context/r4');

const jsonString = '{"resourceType": "Observation", "valueQuantity": '
  + '{"value": 12345678901234567890.12345678, "unit": "mg", '
  + '"system": "http://unitsofmeasure.org", "code": "mg"}}';

// The third argument to parse() is a numberParser callback that receives
// the raw numeric string from the JSON source. By passing it to
// FP_Decimal.getDecimal(), we create a precise decimal object that preserves
// the full original precision.
const resource = parse(jsonString, null, (rawNumericStr) => {
  return FP_Decimal.getDecimal(rawNumericStr); // preserve exact decimal precision
});

const result = fhirpath.evaluate(
  resource,
  'Observation.value',
  null,
  fhirpath_r4_model,
  { preciseMath: true }
);
```

#### Preserving precise numbers in evaluation results

By default, `evaluate` converts all internal types — including decimal numbers —
to standard JavaScript types before returning them. When `preciseMath` is
enabled, this means `FP_Decimal` values are converted to JavaScript `Number`,
which can reintroduce the same floating-point precision loss you intended to
avoid.

To keep decimal values as `FP_Decimal` objects in the output while still
converting other internal types (dates, times, quantities) to strings,
set `keepDecimalTypes` to `true`:

```js
const fhirpath = require('fhirpath');
const { FP_Decimal } = fhirpath;
const fhirpath_r4_model = require('fhirpath/fhir-context/r4');

const result = fhirpath.evaluate(
  {
    "resourceType": "Observation",
    "valueQuantity": {
      "value": 0.1,
      "system": "http://unitsofmeasure.org",
      "code": "kg"
    }
  },
  'Observation.value.value + 0.2',
  null,
  fhirpath_r4_model,
  { preciseMath: true, keepDecimalTypes: true }
);

console.log(result[0] instanceof FP_Decimal); // true
console.log(result[0].toString());            // "0.3"
console.log(result[0].toNumber());            // 0.3 (JavaScript Number)
```

The `FP_Decimal` objects returned in this mode provide several useful methods:
- `toString()` — returns the string representation with the original precision.
- `toNumber()` — converts to a JavaScript `Number` (may lose precision).
- `toJSON()` — returns a JavaScript `Number` (used by `JSON.stringify`).

This option is especially useful when the evaluation result is used as input
for further precise calculations, or when you need to display or serialize the
result without losing decimal precision.

> **Note:** `keepDecimalTypes` only has an effect when `resolveInternalTypes` is
> `true` (the default). If `resolveInternalTypes` is `false`, the result of the
> expression can only be used as a variable value for other expressions, since
> its structure is not documented.

### Asynchronous functions

Some FHIRPath functions may be asynchronous. These functions throw exceptions by default.
To enable these functions, we need to pass the `async` option to `evaluate` or `compile`.
`async=true` enables return of a Promise only for expressions containing asynchronous functions.
`async='always'` enables a Promise to be returned for any expression.

For example, using the `memberOf` function might look like this:
```js
fhirpath.evaluate(
  resource,
  "Observation.code.coding.where(memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult'))",
  {},
  model,
  { async: true, terminologyUrl: 'https://lforms-fhir.nlm.nih.gov/baseR4' }
)
```

Please note that for the `memberOf` function to work you must pass in
a terminologyUrl option.

The `terminologyUrl` option also accepts an array of URLs when you want to
support multiple default terminology servers (for example, the servers a
Questionnaire lists as preferred, plus the server it was fetched from). The
servers are tried in order, and once a ValueSet, CodeSystem, or ConceptMap is
resolved at one server, that server is preferred (tried first) for the remaining
operations on that artifact:
```js
fhirpath.evaluate(
  resource,
  "Observation.code.coding.where(memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult'))",
  {},
  model,
  {
    async: true,
    terminologyUrl: [
      'https://tx.example.org/fhir',
      'https://lforms-fhir.nlm.nih.gov/baseR4'
    ]
  }
)
```

### User-defined functions

You can also replace any existing functions or define new ones. To do this you
need to include a user invocation table in the `options` object. The user
invocation table has the following structure:
```
{
  <function name>: {
    fn: <function implementation>,
    arity: {
      <allowed number of parameters>: <array of parameter types>,
      ...
    },
    [nullable: <boolean, false by default>],
    [internalStructures: <boolean, false by default>]
  },
  ...
}
```

An example of defining a function for raising a number to a specified power (by
default to a power of 2):
```js
const userInvocationTable = {
  pow: {fn: (inputs,exp=2)=>inputs.map(i => Math.pow(i, exp)), arity: {0: [], 1: ["Integer"]}},
};
const res = fhirpath.evaluate({"a": [5,6,7]}, "a.pow()", null, null, { userInvocationTable });
```
Where `pow` is the name of the function, `userInvocationTable.pow.fn` is the
implementation of the `pow` function, `userInvocationTable.pow.arity` is a hash
table describing the mapping between the allowed number of possible parameters
and their types.

A function implementation (e.g. `userInvocationTable.pow.fn`) is a function
whose first parameter is an array of resource node values or an array of values
on which the function is executed, and subsequent parameters are the parameters
passed to the FHIRPath function (e.g. `pow`).

Available parameter types:
- `Expr` - means that a FHIRPath expression passed to the function will be
  converted to a javascript function which will be passed as a parameter to `fn`.
  This javascript function expects one parameter which will be used as `$this`
  for the expression.
- `AnyAtRoot` - a FHIRPath expression passed to the function will be evaluated
  before it is passed to `fn` with `$this` from the parent expression, or, if
  `$this` is not defined for the parent expression, then $this will point to the
  root node of the resource for which the expression is evaluated.

  For example, for the expression `Patient.name.first().subsetOf($this.name)`:
  `Patient.name.first()` is the parent of `$this.name`.
  `$this.name` will be evaluated before it is passed to `subsetOf`, with `$this`
   pointing to the Patient.
- `Identifier` - currently not in use.
- `TypeSpecifier` - expects a type specifier to be converted to an instance of
  the TypeInfo class (see src/types.js) before it will be passed to `fn`.
- `Any` - FHIRPath expression passed to the function will be evaluated before it
  will be passed to `fn`.
- `Integer` - a value will be passed to `fn` if it is an integer, otherwise an
  exception will be thrown.
- `Boolean` - a value will be passed to `fn` if it is a boolean, otherwise an
  exception will be thrown.
- `Number` - a value will be passed to `fn` if it is a number, otherwise an
  exception will be thrown.
- `String` - a value will be passed to `fn` if it is a string, otherwise an
  exception will be thrown.

The optional `nullable` flag means propagation of an empty result, i.e. instead
of calling `fn`, if one of the parameters is empty, empty is returned.

If access to internal structures such as `ResourceNode` (see class `ResourceNode`
in src/types.js) is desired (e.g. for path information), then you can set a flag
`internalStructures` to true. In this case, each parameter of a function
implementation (e.g. `userInvocationTable.pow.fn`) can be an array of
`ResourceNode`s. To ensure that you get the value from the `ResourceNode` or the
value as is, you can use the `fhirpath.util.valData` or
`fhirpath.util.valDataConverted` function (see src/utilities.js).


If a user-defined function performs an asynchronous operation (returns a
`Promise`), it should verify that async evaluation is allowed by calling
`fhirpath.util.checkAllowAsync`.

```js
const userInvocationTable = {
  asyncIdentity: {
    fn: function(inputs) {
      fhirpath.util.checkAllowAsync(this, 'asyncIdentity');
      return Promise.resolve(inputs);
    },
    arity: {0: []}
  }
};

// Throws without { async: true }.
const resultPromise = fhirpath.evaluate(
  { value: [3, 2, 1] },
  "value.sort(asyncIdentity())",
  {},
  null,
  { async: true, userInvocationTable }
);
```

## fhirpath CLI

bin/fhirpath is a command-line tool for experimenting with FHIRPath.

```sh
curl http://www.hl7.org/fhir/patient-example-a.json  > pt.json

fhirpath --expression 'Patient.name.given' --resourceFile pt.json

> fhirpath(Patient.name.family) =>
> [
>  "Donald"
> ]
```

Instead of passing a filename containing the resource, the string of JSON
representing the resource can be passed directly via --resourceJSON (useful if
the JSON is brief).

```sh
fhirpath --expression 'a.b + 2' --resourceJSON '{"a": {"b": 1}}'

> fhirpath(a.b + 2) =>
> [
>  3
> ]
```

Environment variables can be passed via --variables followed by the JSON for an object with variable names as keys.

```sh
fhirpath --expression '%v + 2' --resourceJSON '{}' --variables '{"v": 5}'

> fhirpath(%v + 2) =>
> [
>  7
> ]
```

FHIR model data can be included via --model and the FHIR release version (in
lower case, e.g., 'dstu2', 'stu3' or 'r4').

```sh
fhirpath --expression 'Observation.value' --resourceJSON '{"resourceType": "Observation", "valueString": "Green"}' --model r4
```

Mathematical operations mode can be selected via --mathMode followed by
either 'precise' or 'native' ('native' is currently the default mode, but this may
change):
```sh
# Using precise math (accurate decimal arithmetic)
fhirpath --expression '0.1 + 0.2' --resourceJSON '{}' --mathMode precise

> fhirpath(0.1 + 0.2) =>
> [
>  0.3
> ]

# Using native math (faster but with floating-point precision issues)
fhirpath --expression '0.1 + 0.2' --resourceJSON '{}' --mathMode native

> fhirpath(0.1 + 0.2) =>
> [
>  0.30000000000000004
> ]
```

Internal FHIRPath types can be left unresolved with
`--no-resolveInternalTypes`. By default, CLI output resolves them to standard
JavaScript types. Unresolved output is printed up to a nesting depth of 4;
deeper values are displayed as `[Object]`.

Also, you can pass in a filename or a string of JSON representing a part of the resource.
In that case, you should pass in the base path from which this part of the resource was extracted.
```sh
fhirpath --basePath QuestionnaireResponse.item --expression 'answer.value' --model r4 --resourceFile questionnaire-part-example.json

> fhirpath(answer.value) =>
> [
>  "2 year"
> ]
```

If given just the FHIRPath expression, the utility will print the parsed tree:

```sh
fhirpath --expression 'Patient.name.given'

> ... will print fhirpath ast in yaml
```

## Implementation Status

We are currently working on implementing version 2.0.0 of
[FHIRPath](http://hl7.org/fhirpath/);
some behavior may still be following the previous version, STU1.

The core parser was generated from the FHIRPath ANTLR grammar.

Completed sections:
- 3 (Path selection)
- 5.1 (Existence)
- 5.2 (Filtering and Projection) "ofType"
- 5.3 (Subsetting)
- 5.4 (Combining)
- 5.5 (Conversion)
- 5.6 (String Manipulation)
- 5.7 (Tree Navigation)
- 5.8 (Utility Functions)
- 6.1 (Equality)
- 6.2 (Comparison)
- 6.3 (Types)
- 6.4 (Collections)
- 6.5 (Boolean logic)
- 6.6 (Math)
- 6.8 (Operator Precedence) - handled by ANTLR parser
- 7   (Aggregates)
- 8   (Lexical Elements) - handled by ANTLR parser
- 9   (Environment Variables)

Supported [Additional functions](https://hl7.org/fhir/fhirpath.html#functions) from FHIRPath:
- extension(url : string) : collection
- hasValue() : Boolean
- getValue() : System.[type]
- resolve() : collection
- memberOf(valueset : string) : Boolean
- comparable(quantity) : boolean
- htmlChecks() : Boolean - checks a single `xhtml` element (or, per
  [FHIR-56303](https://jira.hl7.org/browse/FHIR-56303), a `string` whose
  contents are treated as the content of a `div`) against the
  [rules around HTML usage](https://build.fhir.org/narrative.html#rules). The
  types derived from `string` (`code`, `id` and `markdown`) are checked as div
  content as well; every other kind of element, including the `uri`-derived
  types, returns an empty collection. The narrative must be well-formed XHTML:
  all elements closed, all attribute values quoted, only legal XML characters,
  and the `div` must have some non-whitespace content. Namespace prefixes are
  not supported: a default `xmlns` declaration is accepted on any element as
  long as it declares the XHTML namespace, while `xmlns:<prefix>` and prefixed
  attribute names such as `xml:lang` are rejected. `htmlchecks()` is
  accepted as an alias, because that is how the STU3 `Narrative.div`
  invariants spell it; this is not general case-insensitivity. See
  [description of the htmlChecks() function](docs/html-checks.md) for the full
  rule list. Note that this function only validates the narrative; it is not an
  HTML sanitizer and must not be relied upon as a defense against XSS.

Supported [Terminology Service APIs](https://build.fhir.org/fhirpath.html#txapi):
- %terminologies.expand(valueSet, params) : ValueSet
- %terminologies.lookup(coded, params) : Parameters
- %terminologies.validateVS(valueSet, coded, params) : Parameters
- %terminologies.validateCS(codeSystem, coded, params) : Parameters
- %terminologies.subsumes(system, coded1, coded2, params) : code
- %terminologies.translate(conceptMap, code, params) : Parameters

Supported [FHIRPath supplements](https://hl7.org/fhir/uv/sdc/expressions.html#fhirpath-supplements):
- sum(), min(), max(), count(), avg() - short-cuts for the equivalent .aggregate().
- ordinal()/weight() - see [description of the weight() function](docs/weight.md).

Supported [Type Factory APIs](https://hl7.org/fhir/fhirpath.html#factory):
- %factory.{primitive}(value, extensions) : {primitive}
- %factory.Extension(url, value) : Extension
- %factory.Identifier{system, value, use, type) : Identifier
- %factory.HumanName(family, given, prefix, suffix, text, use) : HumanName
- %factory.ContactPoint(system, value, use) : ContactPoint
- %factory.Address(line, city, state, postalCode, country, use, type) : Address
- %factory.Quantity(system, code, value, unit) : Quantity
- %factory.Coding(system, code, display, version) : Coding
- %factory.CodeableConcept(value, text) : CodeableConcept
- %factory.create(type) : {type}
- %factory.withExtension(instance, url, value) : {instance type}
- %factory.withProperty(instance, name, value) : {instance type}

## Development Notes

This section is for people doing development on this package (as opposed to
using the package).

If you need to regenerate the parser from the ANTLR4 grammar (which is in
parser/FHIRPath.g4), first download the
ANTLR4 library from http://www.antlr.org/download/antlr-4.7.1-complete.jar into
the root of the project directory, and then run "npm run generateParser".


### Building the demo page

```sh
npm install && npm run build
cd demo
npm install && npm run build && npm run start
```

open browser on localhost:8080

### Updating the FHIR module on a FHIR release
* Download the FHIR StructureDefinitions (into the `fhir-context` directory - *don't check these in*)
  ```
  > wget 'http://hl7.org/fhir/6.0.0-ballot3/profiles-types.json' -O profiles-types.json
  > wget 'http://hl7.org/fhir/6.0.0-ballot3/profiles-others.json' -O profiles-others.json
  > wget 'http://hl7.org/fhir/6.0.0-ballot3/profiles-resources.json' -O profiles-resources.json
  > wget 'https://hl7.org/fhir/6.0.0-ballot3/search-parameters.json' -O search-parameters.json
  ```
* Create the new folder for the version you are importing
  ```
  > mkdir r6
  ```
* Run the script `extract-model-info.js` with NodeJS
  ```
  > node ./extract-model-info.js --outputDir r6 --fhirDefDir .
  ```
* Compare the output files in the new folder to those of the last release
  (looking for issues that might be due to changes in the StructureDefinition format)
* Copy the CommonJS and ES module entry files from the last release into the
  new folder
  ```
  > cp ../r5/index.js ../r5/index.mjs ../r5/index.d.ts ../r5/index.d.mts r6
  ```
* Update the header comment (version name) in `r6/index.mjs` and
  `r6/index.d.mts`. If the new version has no `score` property, also remove
  `score` from the named-export lists in `r6/index.mjs` and `r6/index.d.ts`.
* `r6/index.d.ts` declares the model's named exports for CommonJS consumers
  (copy from the previous version, shown below); `r6/index.d.mts` re-exports
  them for ES module consumers via `export * from "./index.js"` and needs no
  per-version changes.
  ``` ts
  import {Model} from "../../src/fhirpath";

  export const {
      version,
      score,
      choiceTypePaths,
      pathsDefinedElsewhere,
      type2Parent,
      path2Type,
      path2Repeating,
      resourcesWithUrlParam,
      path2TypeWithoutElements,
      path2RefType
  }: Model;
  ```
* Register the new version in the `exports` map in `package.json` so it can be
  imported by name through both `import` and `require` (copy an existing
  `./fhir-context/<version>` entry and change the version)
  ``` json
  "./fhir-context/r6": {
    "import": {
      "types": "./fhir-context/r6/index.d.mts",
      "default": "./fhir-context/r6/index.mjs"
    },
    "require": {
      "types": "./fhir-context/r6/index.d.ts",
      "default": "./fhir-context/r6/index.js"
    }
  },
  ```

## Credits
This implemention of the FHIRPath specification was developed as a joint project
between the U.S. National Library of Medicine (NLM) and Health Samurai, and was
then donated to HL7.  Current maintenance and additional development is being
performed by NLM, but we welcome contributions from others.  (For anything
substantial, we recommend raising an issue first to coordinate with us.)

A complete list of contributors can be found at
https://github.com/HL7/fhirpath.js/graphs/contributors

---
_Source: https://npm.io/package/fhirpath · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
