@medplum/core 2.0.22 → 2.0.23

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.
@@ -1476,18 +1476,21 @@
1476
1476
  * @returns The string representation of the operation outcome.
1477
1477
  */
1478
1478
  function operationOutcomeToString(outcome) {
1479
- const strs = [];
1480
- if (outcome.issue) {
1481
- for (const issue of outcome.issue) {
1482
- let issueStr = issue.details?.text || 'Unknown error';
1483
- if (issue.expression?.length) {
1484
- issueStr += ` (${issue.expression.join(', ')})`;
1485
- }
1486
- strs.push(issueStr);
1487
- }
1488
- }
1479
+ const strs = outcome.issue?.map(operationOutcomeIssueToString) ?? [];
1489
1480
  return strs.length > 0 ? strs.join('; ') : 'Unknown error';
1490
1481
  }
1482
+ /**
1483
+ * Returns a string represenation of the operation outcome issue.
1484
+ * @param issue The operation outcome issue.
1485
+ * @returns The string representation of the operation outcome issue.
1486
+ */
1487
+ function operationOutcomeIssueToString(issue) {
1488
+ let issueStr = issue.details?.text ?? issue.diagnostics ?? 'Unknown error';
1489
+ if (issue.expression?.length) {
1490
+ issueStr += ` (${issue.expression.join(', ')})`;
1491
+ }
1492
+ return issueStr;
1493
+ }
1491
1494
 
1492
1495
  var _a;
1493
1496
  /**
@@ -6433,7 +6436,7 @@
6433
6436
 
6434
6437
  // PKCE auth based on:
6435
6438
  // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
6436
- const MEDPLUM_VERSION = "2.0.22-f51ac45a" ;
6439
+ const MEDPLUM_VERSION = "2.0.23-b244eeae" ;
6437
6440
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
6438
6441
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
6439
6442
  const DEFAULT_CACHE_TIME = 60000; // 60 seconds
@@ -6572,6 +6575,16 @@
6572
6575
  getBaseUrl() {
6573
6576
  return this.baseUrl;
6574
6577
  }
6578
+ /**
6579
+ * Returns the current authorize URL.
6580
+ * By default, this is set to `https://api.medplum.com/oauth2/authorize`.
6581
+ * This can be overridden by setting the `authorizeUrl` option when creating the client.
6582
+ * @category HTTP
6583
+ * @returns The current authorize URL.
6584
+ */
6585
+ getAuthorizeUrl() {
6586
+ return this.authorizeUrl;
6587
+ }
6575
6588
  /**
6576
6589
  * Clears all auth state including local storage and session storage.
6577
6590
  * @category Authentication
@@ -6593,8 +6606,7 @@
6593
6606
  this.requestCache?.clear();
6594
6607
  this.accessToken = undefined;
6595
6608
  this.refreshToken = undefined;
6596
- this.profile = undefined;
6597
- this.config = undefined;
6609
+ this.sessionDetails = undefined;
6598
6610
  this.dispatchEvent({ type: 'change' });
6599
6611
  }
6600
6612
  /**
@@ -7873,8 +7885,7 @@
7873
7885
  setAccessToken(accessToken) {
7874
7886
  this.accessToken = accessToken;
7875
7887
  this.refreshToken = undefined;
7876
- this.profile = undefined;
7877
- this.config = undefined;
7888
+ this.sessionDetails = undefined;
7878
7889
  }
7879
7890
  /**
7880
7891
  * Returns the list of available logins.
@@ -7897,10 +7908,9 @@
7897
7908
  this.get('auth/me')
7898
7909
  .then((result) => {
7899
7910
  this.profilePromise = undefined;
7900
- this.profile = result.profile;
7901
- this.config = result.config;
7911
+ this.sessionDetails = result;
7902
7912
  this.dispatchEvent({ type: 'change' });
7903
- resolve(this.profile);
7913
+ resolve(result.profile);
7904
7914
  })
7905
7915
  .catch(reject);
7906
7916
  });
@@ -7914,6 +7924,38 @@
7914
7924
  isLoading() {
7915
7925
  return !!this.profilePromise;
7916
7926
  }
7927
+ /**
7928
+ * Returns true if the current user is authenticated as a super admin.
7929
+ * @returns True if the current user is authenticated as a super admin.
7930
+ * @category Authentication
7931
+ */
7932
+ isSuperAdmin() {
7933
+ return !!this.sessionDetails?.project?.superAdmin;
7934
+ }
7935
+ /**
7936
+ * Returns true if the current user is authenticated as a project admin.
7937
+ * @returns True if the current user is authenticated as a project admin.
7938
+ * @category Authentication
7939
+ */
7940
+ isProjectAdmin() {
7941
+ return !!this.sessionDetails?.membership?.admin;
7942
+ }
7943
+ /**
7944
+ * Returns the current project if available.
7945
+ * @returns The current project if available.
7946
+ * @category User Profile
7947
+ */
7948
+ getProject() {
7949
+ return this.sessionDetails?.project;
7950
+ }
7951
+ /**
7952
+ * Returns the current project membership if available.
7953
+ * @returns The current project membership if available.
7954
+ * @category User Profile
7955
+ */
7956
+ getProjectMembership() {
7957
+ return this.sessionDetails?.membership;
7958
+ }
7917
7959
  /**
7918
7960
  * Returns the current user profile resource if available.
7919
7961
  * This method does not wait for loading promises.
@@ -7921,7 +7963,7 @@
7921
7963
  * @category User Profile
7922
7964
  */
7923
7965
  getProfile() {
7924
- return this.profile;
7966
+ return this.sessionDetails?.profile;
7925
7967
  }
7926
7968
  /**
7927
7969
  * Returns the current user profile resource if available.
@@ -7941,7 +7983,15 @@
7941
7983
  * @category User Profile
7942
7984
  */
7943
7985
  getUserConfiguration() {
7944
- return this.config;
7986
+ return this.sessionDetails?.config;
7987
+ }
7988
+ /**
7989
+ * Returns the current user access policy if available.
7990
+ * @returns The current user access policy if available.
7991
+ * @category User Profile
7992
+ */
7993
+ getAccessPolicy() {
7994
+ return this.sessionDetails?.accessPolicy;
7945
7995
  }
7946
7996
  /**
7947
7997
  * Downloads the URL as a blob.
@@ -8385,7 +8435,7 @@
8385
8435
  * Invite a user to a project.
8386
8436
  * @param projectId The project ID.
8387
8437
  * @param body The InviteBody.
8388
- * @returns Promise that returns an invite result or an operation outcome.
8438
+ * @returns Promise that returns a project membership or an operation outcome.
8389
8439
  */
8390
8440
  async invite(projectId, body) {
8391
8441
  return this.post('admin/projects/' + projectId + '/invite', body);
@@ -8410,7 +8460,13 @@
8410
8460
  const response = await this.fetch(this.tokenUrl, options);
8411
8461
  if (!response.ok) {
8412
8462
  this.clearActiveLogin();
8413
- throw new Error('Failed to fetch tokens');
8463
+ try {
8464
+ const error = await response.json();
8465
+ throw new OperationOutcomeError(badRequest(error.error_description));
8466
+ }
8467
+ catch (err) {
8468
+ throw new OperationOutcomeError(badRequest('Failed to fetch tokens'), err);
8469
+ }
8414
8470
  }
8415
8471
  const tokens = await response.json();
8416
8472
  await this.verifyTokens(tokens);
@@ -8656,7 +8712,7 @@
8656
8712
  this.keywords = keywords;
8657
8713
  this.operators = operators;
8658
8714
  this.dateTimeLiterals = !!options?.dateTimeLiterals;
8659
- this.symbolRegex = options?.symbolRegex ?? /[$\w]/;
8715
+ this.symbolRegex = options?.symbolRegex ?? /[$\w%]/;
8660
8716
  }
8661
8717
  tokenize() {
8662
8718
  while (this.pos.index < this.str.length) {
@@ -8705,7 +8761,7 @@
8705
8761
  if (c.match(/\w/)) {
8706
8762
  return this.consumeSymbol();
8707
8763
  }
8708
- if (c === '$' && next.match(/\w/)) {
8764
+ if ((c === '$' || c === '%') && next.match(/\w/)) {
8709
8765
  return this.consumeSymbol();
8710
8766
  }
8711
8767
  return this.consumeOperator();
@@ -9267,10 +9323,11 @@
9267
9323
  * Returns true if the input collection is empty ({ }) and false otherwise.
9268
9324
  *
9269
9325
  * See: https://hl7.org/fhirpath/#empty-boolean
9326
+ * @param _context The evaluation context.
9270
9327
  * @param input The input collection.
9271
9328
  * @returns True if the input collection is empty ({ }) and false otherwise.
9272
9329
  */
9273
- empty: (input) => {
9330
+ empty: (_context, input) => {
9274
9331
  return booleanToTypedValue(input.length === 0);
9275
9332
  },
9276
9333
  /**
@@ -9283,13 +9340,14 @@
9283
9340
  * for where(criteria).exists().
9284
9341
  *
9285
9342
  * See: https://hl7.org/fhirpath/#existscriteria-expression-boolean
9343
+ * @param context The evaluation context.
9286
9344
  * @param input The input collection.
9287
- * @param criteria Optional criteria applied to the collection.
9345
+ * @param criteria The evaluation criteria.
9288
9346
  * @returns True if the collection has unknown elements, and false otherwise.
9289
9347
  */
9290
- exists: (input, criteria) => {
9348
+ exists: (context, input, criteria) => {
9291
9349
  if (criteria) {
9292
- return booleanToTypedValue(input.filter((e) => toJsBoolean(criteria.eval([e]))).length > 0);
9350
+ return booleanToTypedValue(input.filter((e) => toJsBoolean(criteria.eval(context, [e]))).length > 0);
9293
9351
  }
9294
9352
  else {
9295
9353
  return booleanToTypedValue(input.length > 0);
@@ -9302,12 +9360,13 @@
9302
9360
  * If the input collection is empty ({ }), the result is true.
9303
9361
  *
9304
9362
  * See: https://hl7.org/fhirpath/#allcriteria-expression-boolean
9363
+ * @param context The evaluation context.
9305
9364
  * @param input The input collection.
9306
9365
  * @param criteria The evaluation criteria.
9307
9366
  * @returns True if for every element in the input collection, criteria evaluates to true.
9308
9367
  */
9309
- all: (input, criteria) => {
9310
- return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval([e]))));
9368
+ all: (context, input, criteria) => {
9369
+ return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval(context, [e]))));
9311
9370
  },
9312
9371
  /**
9313
9372
  * Takes a collection of Boolean values and returns true if all the items are true.
@@ -9315,10 +9374,11 @@
9315
9374
  * If the input is empty ({ }), the result is true.
9316
9375
  *
9317
9376
  * See: https://hl7.org/fhirpath/#alltrue-boolean
9377
+ * @param _context The evaluation context.
9318
9378
  * @param input The input collection.
9319
9379
  * @returns True if all the items are true.
9320
9380
  */
9321
- allTrue: (input) => {
9381
+ allTrue: (_context, input) => {
9322
9382
  for (const value of input) {
9323
9383
  if (!value.value) {
9324
9384
  return booleanToTypedValue(false);
@@ -9331,10 +9391,11 @@
9331
9391
  * If all the items are false, or if the input is empty ({ }), the result is false.
9332
9392
  *
9333
9393
  * See: https://hl7.org/fhirpath/#anytrue-boolean
9394
+ * @param _context The evaluation context.
9334
9395
  * @param input The input collection.
9335
9396
  * @returns True if unknown of the items are true.
9336
9397
  */
9337
- anyTrue: (input) => {
9398
+ anyTrue: (_context, input) => {
9338
9399
  for (const value of input) {
9339
9400
  if (value.value) {
9340
9401
  return booleanToTypedValue(true);
@@ -9348,10 +9409,11 @@
9348
9409
  * If the input is empty ({ }), the result is true.
9349
9410
  *
9350
9411
  * See: https://hl7.org/fhirpath/#allfalse-boolean
9412
+ * @param _context The evaluation context.
9351
9413
  * @param input The input collection.
9352
9414
  * @returns True if all the items are false.
9353
9415
  */
9354
- allFalse: (input) => {
9416
+ allFalse: (_context, input) => {
9355
9417
  for (const value of input) {
9356
9418
  if (value.value) {
9357
9419
  return booleanToTypedValue(false);
@@ -9364,10 +9426,11 @@
9364
9426
  * If all the items are true, or if the input is empty ({ }), the result is false.
9365
9427
  *
9366
9428
  * See: https://hl7.org/fhirpath/#anyfalse-boolean
9429
+ * @param _context The evaluation context.
9367
9430
  * @param input The input collection.
9368
9431
  * @returns True if for every element in the input collection, criteria evaluates to true.
9369
9432
  */
9370
- anyFalse: (input) => {
9433
+ anyFalse: (_context, input) => {
9371
9434
  for (const value of input) {
9372
9435
  if (!value.value) {
9373
9436
  return booleanToTypedValue(true);
@@ -9404,10 +9467,11 @@
9404
9467
  * Returns 0 when the input collection is empty.
9405
9468
  *
9406
9469
  * See: https://hl7.org/fhirpath/#count-integer
9470
+ * @param _context The evaluation context.
9407
9471
  * @param input The input collection.
9408
9472
  * @returns The integer count of the number of items in the input collection.
9409
9473
  */
9410
- count: (input) => {
9474
+ count: (_context, input) => {
9411
9475
  return [{ type: exports.PropertyType.integer, value: input.length }];
9412
9476
  },
9413
9477
  /**
@@ -9421,10 +9485,11 @@
9421
9485
  * preserved in the result.
9422
9486
  *
9423
9487
  * See: https://hl7.org/fhirpath/#distinct-collection
9488
+ * @param _context The evaluation context.
9424
9489
  * @param input The input collection.
9425
9490
  * @returns The integer count of the number of items in the input collection.
9426
9491
  */
9427
- distinct: (input) => {
9492
+ distinct: (_context, input) => {
9428
9493
  const result = [];
9429
9494
  for (const value of input) {
9430
9495
  if (!result.some((e) => e.value === value.value)) {
@@ -9439,11 +9504,12 @@
9439
9504
  * as defined below.
9440
9505
  *
9441
9506
  * See: https://hl7.org/fhirpath/#isdistinct-boolean
9507
+ * @param context The evaluation context.
9442
9508
  * @param input The input collection.
9443
9509
  * @returns The integer count of the number of items in the input collection.
9444
9510
  */
9445
- isDistinct: (input) => {
9446
- return booleanToTypedValue(input.length === functions.distinct(input).length);
9511
+ isDistinct: (context, input) => {
9512
+ return booleanToTypedValue(input.length === functions.distinct(context, input).length);
9447
9513
  },
9448
9514
  /*
9449
9515
  * 5.2 Filtering and projection
@@ -9461,12 +9527,13 @@
9461
9527
  * consistent with singleton evaluation of collections behavior.
9462
9528
  *
9463
9529
  * See: https://hl7.org/fhirpath/#wherecriteria-expression-collection
9530
+ * @param context The evaluation context.
9464
9531
  * @param input The input collection.
9465
9532
  * @param criteria The condition atom.
9466
9533
  * @returns A collection containing only those elements in the input collection for which the stated criteria expression evaluates to true.
9467
9534
  */
9468
- where: (input, criteria) => {
9469
- return input.filter((e) => toJsBoolean(criteria.eval([e])));
9535
+ where: (context, input, criteria) => {
9536
+ return input.filter((e) => toJsBoolean(criteria.eval(context, [e])));
9470
9537
  },
9471
9538
  /**
9472
9539
  * Evaluates the projection expression for each item in the input collection.
@@ -9478,12 +9545,13 @@
9478
9545
  * the input collection is empty ({ }), the result is empty as well.
9479
9546
  *
9480
9547
  * See: http://hl7.org/fhirpath/#selectprojection-expression-collection
9548
+ * @param context The evaluation context.
9481
9549
  * @param input The input collection.
9482
9550
  * @param criteria The condition atom.
9483
9551
  * @returns A collection containing only those elements in the input collection for which the stated criteria expression evaluates to true.
9484
9552
  */
9485
- select: (input, criteria) => {
9486
- return input.map((e) => criteria.eval([e])).flat();
9553
+ select: (context, input, criteria) => {
9554
+ return input.map((e) => criteria.eval(context, [e])).flat();
9487
9555
  },
9488
9556
  /**
9489
9557
  * A version of select that will repeat the projection and add it to the output
@@ -9500,11 +9568,12 @@
9500
9568
  * must resolve to the name of a type in a model
9501
9569
  *
9502
9570
  * See: http://hl7.org/fhirpath/#oftypetype-type-specifier-collection
9571
+ * @param _context The evaluation context.
9503
9572
  * @param input The input collection.
9504
9573
  * @param criteria The condition atom.
9505
9574
  * @returns A collection containing only those elements in the input collection that are of the given type or a subclass thereof.
9506
9575
  */
9507
- ofType: (input, criteria) => {
9576
+ ofType: (_context, input, criteria) => {
9508
9577
  return input.filter((e) => e.type === criteria.name);
9509
9578
  },
9510
9579
  /*
@@ -9518,10 +9587,11 @@
9518
9587
  * about cardinality is violated at run-time.
9519
9588
  *
9520
9589
  * See: https://hl7.org/fhirpath/#single-collection
9590
+ * @param _context The evaluation context.
9521
9591
  * @param input The input collection.
9522
9592
  * @returns The single item in the input if there is just one item.
9523
9593
  */
9524
- single: (input) => {
9594
+ single: (_context, input) => {
9525
9595
  if (input.length > 1) {
9526
9596
  throw new Error('Expected input length one for single()');
9527
9597
  }
@@ -9532,10 +9602,11 @@
9532
9602
  * This function is equivalent to item[0], so it will return an empty collection if the input collection has no items.
9533
9603
  *
9534
9604
  * See: https://hl7.org/fhirpath/#first-collection
9605
+ * @param context The evaluation context.
9535
9606
  * @param input The input collection.
9536
9607
  * @returns A collection containing only the first item in the input collection.
9537
9608
  */
9538
- first: (input) => {
9609
+ first: (context, input) => {
9539
9610
  return input.length === 0 ? [] : input.slice(0, 1);
9540
9611
  },
9541
9612
  /**
@@ -9543,10 +9614,11 @@
9543
9614
  * Will return an empty collection if the input collection has no items.
9544
9615
  *
9545
9616
  * See: https://hl7.org/fhirpath/#last-collection
9617
+ * @param context The evaluation context.
9546
9618
  * @param input The input collection.
9547
9619
  * @returns A collection containing only the last item in the input collection.
9548
9620
  */
9549
- last: (input) => {
9621
+ last: (context, input) => {
9550
9622
  return input.length === 0 ? [] : input.slice(input.length - 1, input.length);
9551
9623
  },
9552
9624
  /**
@@ -9554,10 +9626,11 @@
9554
9626
  * Will return an empty collection if the input collection has no items, or only one item.
9555
9627
  *
9556
9628
  * See: https://hl7.org/fhirpath/#tail-collection
9629
+ * @param context The evaluation context.
9557
9630
  * @param input The input collection.
9558
9631
  * @returns A collection containing all but the first item in the input collection.
9559
9632
  */
9560
- tail: (input) => {
9633
+ tail: (context, input) => {
9561
9634
  return input.length === 0 ? [] : input.slice(1, input.length);
9562
9635
  },
9563
9636
  /**
@@ -9567,12 +9640,13 @@
9567
9640
  * If num is less than or equal to zero, the input collection is simply returned.
9568
9641
  *
9569
9642
  * See: https://hl7.org/fhirpath/#skipnum-integer-collection
9643
+ * @param context The evaluation context.
9570
9644
  * @param input The input collection.
9571
9645
  * @param num The atom representing the number of elements to skip.
9572
9646
  * @returns A collection containing all but the first item in the input collection.
9573
9647
  */
9574
- skip: (input, num) => {
9575
- const numValue = num.eval(input)[0]?.value;
9648
+ skip: (context, input, num) => {
9649
+ const numValue = num.eval(context, input)[0]?.value;
9576
9650
  if (typeof numValue !== 'number') {
9577
9651
  throw new Error('Expected a number for skip(num)');
9578
9652
  }
@@ -9591,12 +9665,13 @@
9591
9665
  * take returns an empty collection.
9592
9666
  *
9593
9667
  * See: https://hl7.org/fhirpath/#takenum-integer-collection
9668
+ * @param context The evaluation context.
9594
9669
  * @param input The input collection.
9595
9670
  * @param num The atom representing the number of elements to take.
9596
9671
  * @returns A collection containing the first num items in the input collection.
9597
9672
  */
9598
- take: (input, num) => {
9599
- const numValue = num.eval(input)[0]?.value;
9673
+ take: (context, input, num) => {
9674
+ const numValue = num.eval(context, input)[0]?.value;
9600
9675
  if (typeof numValue !== 'number') {
9601
9676
  throw new Error('Expected a number for take(num)');
9602
9677
  }
@@ -9614,15 +9689,16 @@
9614
9689
  * Order of items is not guaranteed to be preserved in the result of this function.
9615
9690
  *
9616
9691
  * See: http://hl7.org/fhirpath/#intersectother-collection-collection
9692
+ * @param context The evaluation context.
9617
9693
  * @param input The input collection.
9618
9694
  * @param other The atom representing the collection of elements to intersect.
9619
9695
  * @returns A collection containing the elements that are in both collections.
9620
9696
  */
9621
- intersect: (input, other) => {
9697
+ intersect: (context, input, other) => {
9622
9698
  if (!other) {
9623
9699
  return input;
9624
9700
  }
9625
- const otherArray = other.eval(input);
9701
+ const otherArray = other.eval(context, input);
9626
9702
  const result = [];
9627
9703
  for (const value of input) {
9628
9704
  if (!result.some((e) => e.value === value.value) && otherArray.some((e) => e.value === value.value)) {
@@ -9638,15 +9714,16 @@
9638
9714
  * e.g. (1 | 2 | 3).exclude(2) returns (1 | 3).
9639
9715
  *
9640
9716
  * See: http://hl7.org/fhirpath/#excludeother-collection-collection
9717
+ * @param context The evaluation context.
9641
9718
  * @param input The input collection.
9642
9719
  * @param other The atom representing the collection of elements to exclude.
9643
9720
  * @returns A collection containing the elements that are in the input collection but not the other collection.
9644
9721
  */
9645
- exclude: (input, other) => {
9722
+ exclude: (context, input, other) => {
9646
9723
  if (!other) {
9647
9724
  return input;
9648
9725
  }
9649
- const otherArray = other.eval(input);
9726
+ const otherArray = other.eval(context, input);
9650
9727
  const result = [];
9651
9728
  for (const value of input) {
9652
9729
  if (!otherArray.some((e) => e.value === value.value)) {
@@ -9668,15 +9745,16 @@
9668
9745
  * In other words, this function returns the distinct list of elements from both inputs.
9669
9746
  *
9670
9747
  * See: http://hl7.org/fhirpath/#unionother-collection
9748
+ * @param context The evaluation context.
9671
9749
  * @param input The input collection.
9672
9750
  * @param other The atom representing the collection of elements to merge.
9673
9751
  * @returns A collection containing the elements that represent the union of both collections.
9674
9752
  */
9675
- union: (input, other) => {
9753
+ union: (context, input, other) => {
9676
9754
  if (!other) {
9677
9755
  return input;
9678
9756
  }
9679
- const otherArray = other.eval(input);
9757
+ const otherArray = other.eval(context, input);
9680
9758
  return removeDuplicates([...input, ...otherArray]);
9681
9759
  },
9682
9760
  /**
@@ -9687,15 +9765,16 @@
9687
9765
  * There is no expectation of order in the resulting collection.
9688
9766
  *
9689
9767
  * See: http://hl7.org/fhirpath/#combineother-collection-collection
9768
+ * @param context The evaluation context.
9690
9769
  * @param input The input collection.
9691
9770
  * @param other The atom representing the collection of elements to merge.
9692
9771
  * @returns A collection containing the elements that represent the combination of both collections including duplicates.
9693
9772
  */
9694
- combine: (input, other) => {
9773
+ combine: (context, input, other) => {
9695
9774
  if (!other) {
9696
9775
  return input;
9697
9776
  }
9698
- const otherArray = other.eval(input);
9777
+ const otherArray = other.eval(context, input);
9699
9778
  return [...input, ...otherArray];
9700
9779
  },
9701
9780
  /*
@@ -9718,22 +9797,23 @@
9718
9797
  * true-result should only be evaluated if the criterion evaluates to true,
9719
9798
  * and otherwise-result should only be evaluated otherwise. For implementations,
9720
9799
  * this means delaying evaluation of the arguments.
9800
+ * @param context The evaluation context.
9721
9801
  * @param input The input collection.
9722
9802
  * @param criterion The atom representing the conditional.
9723
9803
  * @param trueResult The atom to be used if the conditional evaluates to true.
9724
9804
  * @param otherwiseResult Optional atom to be used if the conditional evaluates to false.
9725
9805
  * @returns The result of the iif function.
9726
9806
  */
9727
- iif: (input, criterion, trueResult, otherwiseResult) => {
9728
- const evalResult = criterion.eval(input);
9807
+ iif: (context, input, criterion, trueResult, otherwiseResult) => {
9808
+ const evalResult = criterion.eval(context, input);
9729
9809
  if (evalResult.length > 1 || (evalResult.length === 1 && typeof evalResult[0].value !== 'boolean')) {
9730
9810
  throw new Error('Expected criterion to evaluate to a Boolean');
9731
9811
  }
9732
9812
  if (toJsBoolean(evalResult)) {
9733
- return trueResult.eval(input);
9813
+ return trueResult.eval(context, input);
9734
9814
  }
9735
9815
  if (otherwiseResult) {
9736
- return otherwiseResult.eval(input);
9816
+ return otherwiseResult.eval(context, input);
9737
9817
  }
9738
9818
  return [];
9739
9819
  },
@@ -9749,10 +9829,11 @@
9749
9829
  * 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.
9750
9830
  *
9751
9831
  * See: https://hl7.org/fhirpath/#toboolean-boolean
9832
+ * @param _context The evaluation context.
9752
9833
  * @param input The input collection.
9753
9834
  * @returns The input converted to boolean value.
9754
9835
  */
9755
- toBoolean: (input) => {
9836
+ toBoolean: (_context, input) => {
9756
9837
  if (input.length === 0) {
9757
9838
  return [];
9758
9839
  }
@@ -9792,14 +9873,15 @@
9792
9873
  * If the input collection is empty, the result is empty.
9793
9874
  *
9794
9875
  * See: http://hl7.org/fhirpath/#convertstoboolean-boolean
9876
+ * @param context The evaluation context.
9795
9877
  * @param input The input collection.
9796
9878
  * @returns True if the input can be converted to boolean.
9797
9879
  */
9798
- convertsToBoolean: (input) => {
9880
+ convertsToBoolean: (context, input) => {
9799
9881
  if (input.length === 0) {
9800
9882
  return [];
9801
9883
  }
9802
- return booleanToTypedValue(functions.toBoolean(input).length === 1);
9884
+ return booleanToTypedValue(functions.toBoolean(context, input).length === 1);
9803
9885
  },
9804
9886
  /**
9805
9887
  * Returns the integer representation of the input.
@@ -9818,10 +9900,11 @@
9818
9900
  * If the input collection is empty, the result is empty.
9819
9901
  *
9820
9902
  * See: https://hl7.org/fhirpath/#tointeger-integer
9903
+ * @param _context The evaluation context.
9821
9904
  * @param input The input collection.
9822
9905
  * @returns The string representation of the input.
9823
9906
  */
9824
- toInteger: (input) => {
9907
+ toInteger: (_context, input) => {
9825
9908
  if (input.length === 0) {
9826
9909
  return [];
9827
9910
  }
@@ -9851,14 +9934,15 @@
9851
9934
  * If the input collection is empty, the result is empty.
9852
9935
  *
9853
9936
  * See: https://hl7.org/fhirpath/#convertstointeger-boolean
9937
+ * @param context The evaluation context.
9854
9938
  * @param input The input collection.
9855
9939
  * @returns True if the input can be converted to an integer.
9856
9940
  */
9857
- convertsToInteger: (input) => {
9941
+ convertsToInteger: (context, input) => {
9858
9942
  if (input.length === 0) {
9859
9943
  return [];
9860
9944
  }
9861
- return booleanToTypedValue(functions.toInteger(input).length === 1);
9945
+ return booleanToTypedValue(functions.toInteger(context, input).length === 1);
9862
9946
  },
9863
9947
  /**
9864
9948
  * If the input collection contains a single item, this function will return a single date if:
@@ -9875,10 +9959,11 @@
9875
9959
  * If the input collection is empty, the result is empty.
9876
9960
  *
9877
9961
  * See: https://hl7.org/fhirpath/#todate-date
9962
+ * @param _context The evaluation context.
9878
9963
  * @param input The input collection.
9879
9964
  * @returns The value converted to a date if possible; otherwise empty array.
9880
9965
  */
9881
- toDate: (input) => {
9966
+ toDate: (_context, input) => {
9882
9967
  if (input.length === 0) {
9883
9968
  return [];
9884
9969
  }
@@ -9903,14 +9988,15 @@
9903
9988
  * If the input collection is empty, the result is empty.
9904
9989
  *
9905
9990
  * See: https://hl7.org/fhirpath/#convertstodate-boolean
9991
+ * @param context The evaluation context.
9906
9992
  * @param input The input collection.
9907
9993
  * @returns True if the item can be converted to a date.
9908
9994
  */
9909
- convertsToDate: (input) => {
9995
+ convertsToDate: (context, input) => {
9910
9996
  if (input.length === 0) {
9911
9997
  return [];
9912
9998
  }
9913
- return booleanToTypedValue(functions.toDate(input).length === 1);
9999
+ return booleanToTypedValue(functions.toDate(context, input).length === 1);
9914
10000
  },
9915
10001
  /**
9916
10002
  * If the input collection contains a single item, this function will return a single datetime if:
@@ -9929,10 +10015,11 @@
9929
10015
  * If the input collection is empty, the result is empty.
9930
10016
  *
9931
10017
  * See: https://hl7.org/fhirpath/#todatetime-datetime
10018
+ * @param _context The evaluation context.
9932
10019
  * @param input The input collection.
9933
- * @returns The value converted to a dateTime if possible; otherwise empty array.
10020
+ * @returns The value converted to a datetime if possible; otherwise empty array.
9934
10021
  */
9935
- toDateTime: (input) => {
10022
+ toDateTime: (_context, input) => {
9936
10023
  if (input.length === 0) {
9937
10024
  return [];
9938
10025
  }
@@ -9955,14 +10042,15 @@
9955
10042
  * If the input collection is empty, the result is empty.
9956
10043
  *
9957
10044
  * See: https://hl7.org/fhirpath/#convertstodatetime-boolean
10045
+ * @param context The evaluation context.
9958
10046
  * @param input The input collection.
9959
10047
  * @returns True if the item can be converted to a dateTime.
9960
10048
  */
9961
- convertsToDateTime: (input) => {
10049
+ convertsToDateTime: (context, input) => {
9962
10050
  if (input.length === 0) {
9963
10051
  return [];
9964
10052
  }
9965
- return booleanToTypedValue(functions.toDateTime(input).length === 1);
10053
+ return booleanToTypedValue(functions.toDateTime(context, input).length === 1);
9966
10054
  },
9967
10055
  /**
9968
10056
  * If the input collection contains a single item, this function will return a single decimal if:
@@ -9978,10 +10066,11 @@
9978
10066
  * If the input collection is empty, the result is empty.
9979
10067
  *
9980
10068
  * See: https://hl7.org/fhirpath/#decimal-conversion-functions
10069
+ * @param _context The evaluation context.
9981
10070
  * @param input The input collection.
9982
10071
  * @returns The value converted to a decimal if possible; otherwise empty array.
9983
10072
  */
9984
- toDecimal: (input) => {
10073
+ toDecimal: (_context, input) => {
9985
10074
  if (input.length === 0) {
9986
10075
  return [];
9987
10076
  }
@@ -10010,14 +10099,15 @@
10010
10099
  * If the input collection is empty, the result is empty.
10011
10100
  *
10012
10101
  * See: https://hl7.org/fhirpath/#convertstodecimal-boolean
10102
+ * @param context The evaluation context.
10013
10103
  * @param input The input collection.
10014
- * @returns True if the item can be converted to a decimal.
10104
+ * @returns The value converted to a decimal if possible; otherwise empty array.
10015
10105
  */
10016
- convertsToDecimal: (input) => {
10106
+ convertsToDecimal: (context, input) => {
10017
10107
  if (input.length === 0) {
10018
10108
  return [];
10019
10109
  }
10020
- return booleanToTypedValue(functions.toDecimal(input).length === 1);
10110
+ return booleanToTypedValue(functions.toDecimal(context, input).length === 1);
10021
10111
  },
10022
10112
  /**
10023
10113
  * If the input collection contains a single item, this function will return a single quantity if:
@@ -10029,10 +10119,11 @@
10029
10119
  * If the item is not one of the above types, the result is empty.
10030
10120
  *
10031
10121
  * See: https://hl7.org/fhirpath/#quantity-conversion-functions
10122
+ * @param _context The evaluation context.
10032
10123
  * @param input The input collection.
10033
10124
  * @returns The value converted to a quantity if possible; otherwise empty array.
10034
10125
  */
10035
- toQuantity: (input) => {
10126
+ toQuantity: (_context, input) => {
10036
10127
  if (input.length === 0) {
10037
10128
  return [];
10038
10129
  }
@@ -10070,14 +10161,15 @@
10070
10161
  * 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.
10071
10162
  *
10072
10163
  * See: https://hl7.org/fhirpath/#convertstoquantityunit-string-boolean
10164
+ * @param context The evaluation context.
10073
10165
  * @param input The input collection.
10074
10166
  * @returns True if the item can be converted to a quantity.
10075
10167
  */
10076
- convertsToQuantity: (input) => {
10168
+ convertsToQuantity: (context, input) => {
10077
10169
  if (input.length === 0) {
10078
10170
  return [];
10079
10171
  }
10080
- return booleanToTypedValue(functions.toQuantity(input).length === 1);
10172
+ return booleanToTypedValue(functions.toQuantity(context, input).length === 1);
10081
10173
  },
10082
10174
  /**
10083
10175
  * Returns the string representation of the input.
@@ -10091,10 +10183,11 @@
10091
10183
  * If the item is not one of the above types, the result is false.
10092
10184
  *
10093
10185
  * See: https://hl7.org/fhirpath/#tostring-string
10186
+ * @param _context The evaluation context.
10094
10187
  * @param input The input collection.
10095
10188
  * @returns The string representation of the input.
10096
10189
  */
10097
- toString: (input) => {
10190
+ toString: (_context, input) => {
10098
10191
  if (input.length === 0) {
10099
10192
  return [];
10100
10193
  }
@@ -10123,14 +10216,15 @@
10123
10216
  * If the input collection is empty, the result is empty.
10124
10217
  *
10125
10218
  * See: https://hl7.org/fhirpath/#tostring-string
10219
+ * @param context The evaluation context.
10126
10220
  * @param input The input collection.
10127
10221
  * @returns True if the item can be converted to a string
10128
10222
  */
10129
- convertsToString: (input) => {
10223
+ convertsToString: (context, input) => {
10130
10224
  if (input.length === 0) {
10131
10225
  return [];
10132
10226
  }
10133
- return booleanToTypedValue(functions.toString(input).length === 1);
10227
+ return booleanToTypedValue(functions.toString(context, input).length === 1);
10134
10228
  },
10135
10229
  /**
10136
10230
  * If the input collection contains a single item, this function will return a single time if:
@@ -10148,10 +10242,11 @@
10148
10242
  * If the input collection is empty, the result is empty.
10149
10243
  *
10150
10244
  * See: https://hl7.org/fhirpath/#totime-time
10245
+ * @param _context The evaluation context.
10151
10246
  * @param input The input collection.
10152
10247
  * @returns The value converted to a time if possible; otherwise empty array.
10153
10248
  */
10154
- toTime: (input) => {
10249
+ toTime: (_context, input) => {
10155
10250
  if (input.length === 0) {
10156
10251
  return [];
10157
10252
  }
@@ -10176,14 +10271,15 @@
10176
10271
  * If the input collection is empty, the result is empty.
10177
10272
  *
10178
10273
  * See: https://hl7.org/fhirpath/#convertstotime-boolean
10274
+ * @param context The evaluation context.
10179
10275
  * @param input The input collection.
10180
10276
  * @returns True if the item can be converted to a time.
10181
10277
  */
10182
- convertsToTime: (input) => {
10278
+ convertsToTime: (context, input) => {
10183
10279
  if (input.length === 0) {
10184
10280
  return [];
10185
10281
  }
10186
- return booleanToTypedValue(functions.toTime(input).length === 1);
10282
+ return booleanToTypedValue(functions.toTime(context, input).length === 1);
10187
10283
  },
10188
10284
  /*
10189
10285
  * 5.6. String Manipulation.
@@ -10200,12 +10296,13 @@
10200
10296
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10201
10297
  *
10202
10298
  * See: https://hl7.org/fhirpath/#indexofsubstring-string-integer
10299
+ * @param context The evaluation context.
10203
10300
  * @param input The input collection.
10204
- * @param searchStringAtom The substring to search for.
10301
+ * @param substringAtom The substring to search for.
10205
10302
  * @returns The index of the substring.
10206
10303
  */
10207
- indexOf: (input, searchStringAtom) => {
10208
- return applyStringFunc((str, substring) => str.indexOf(substring), input, searchStringAtom);
10304
+ indexOf: (context, input, substringAtom) => {
10305
+ return applyStringFunc((str, substring) => str.indexOf(substring), context, input, substringAtom);
10209
10306
  },
10210
10307
  /**
10211
10308
  * 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.
@@ -10217,17 +10314,18 @@
10217
10314
  * If an empty length is provided, the behavior is the same as if length had not been provided.
10218
10315
  *
10219
10316
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10317
+ * @param context The evaluation context.
10220
10318
  * @param input The input collection.
10221
10319
  * @param startAtom The start index atom.
10222
10320
  * @param lengthAtom Optional length atom.
10223
10321
  * @returns The substring.
10224
10322
  */
10225
- substring: (input, startAtom, lengthAtom) => {
10323
+ substring: (context, input, startAtom, lengthAtom) => {
10226
10324
  return applyStringFunc((str, start, length) => {
10227
10325
  const startIndex = start;
10228
10326
  const endIndex = length ? startIndex + length : str.length;
10229
10327
  return startIndex < 0 || startIndex >= str.length ? undefined : str.substring(startIndex, endIndex);
10230
- }, input, startAtom, lengthAtom);
10328
+ }, context, input, startAtom, lengthAtom);
10231
10329
  },
10232
10330
  /**
10233
10331
  * Returns true when the input string starts with the given prefix.
@@ -10239,12 +10337,13 @@
10239
10337
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10240
10338
  *
10241
10339
  * See: https://hl7.org/fhirpath/#startswithprefix-string-boolean
10340
+ * @param context The evaluation context.
10242
10341
  * @param input The input collection.
10243
10342
  * @param prefixAtom The prefix substring to test.
10244
10343
  * @returns True if the input string starts with the given prefix string.
10245
10344
  */
10246
- startsWith: (input, prefixAtom) => {
10247
- return applyStringFunc((str, prefix) => str.startsWith(prefix), input, prefixAtom);
10345
+ startsWith: (context, input, prefixAtom) => {
10346
+ return applyStringFunc((str, prefix) => str.startsWith(prefix), context, input, prefixAtom);
10248
10347
  },
10249
10348
  /**
10250
10349
  * Returns true when the input string ends with the given suffix.
@@ -10256,12 +10355,13 @@
10256
10355
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10257
10356
  *
10258
10357
  * See: https://hl7.org/fhirpath/#endswithsuffix-string-boolean
10358
+ * @param context The evaluation context.
10259
10359
  * @param input The input collection.
10260
10360
  * @param suffixAtom The suffix substring to test.
10261
10361
  * @returns True if the input string ends with the given suffix string.
10262
10362
  */
10263
- endsWith: (input, suffixAtom) => {
10264
- return applyStringFunc((str, suffix) => str.endsWith(suffix), input, suffixAtom);
10363
+ endsWith: (context, input, suffixAtom) => {
10364
+ return applyStringFunc((str, suffix) => str.endsWith(suffix), context, input, suffixAtom);
10265
10365
  },
10266
10366
  /**
10267
10367
  * Returns true when the given substring is a substring of the input string.
@@ -10273,26 +10373,27 @@
10273
10373
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10274
10374
  *
10275
10375
  * See: https://hl7.org/fhirpath/#containssubstring-string-boolean
10376
+ * @param context The evaluation context.
10276
10377
  * @param input The input collection.
10277
10378
  * @param substringAtom The substring to test.
10278
10379
  * @returns True if the input string contains the given substring.
10279
10380
  */
10280
- contains: (input, substringAtom) => {
10281
- return applyStringFunc((str, substring) => str.includes(substring), input, substringAtom);
10381
+ contains: (context, input, substringAtom) => {
10382
+ return applyStringFunc((str, substring) => str.includes(substring), context, input, substringAtom);
10282
10383
  },
10283
10384
  /**
10284
10385
  * Returns the input string with all characters converted to upper case.
10285
- *
10286
10386
  * If the input collection is empty, the result is empty.
10287
10387
  *
10288
10388
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10289
10389
  *
10290
10390
  * See: https://hl7.org/fhirpath/#upper-string
10391
+ * @param context The evaluation context.
10291
10392
  * @param input The input collection.
10292
10393
  * @returns The string converted to upper case.
10293
10394
  */
10294
- upper: (input) => {
10295
- return applyStringFunc((str) => str.toUpperCase(), input);
10395
+ upper: (context, input) => {
10396
+ return applyStringFunc((str) => str.toUpperCase(), context, input);
10296
10397
  },
10297
10398
  /**
10298
10399
  * Returns the input string with all characters converted to lower case.
@@ -10302,11 +10403,12 @@
10302
10403
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10303
10404
  *
10304
10405
  * See: https://hl7.org/fhirpath/#lower-string
10406
+ * @param context The evaluation context.
10305
10407
  * @param input The input collection.
10306
10408
  * @returns The string converted to lower case.
10307
10409
  */
10308
- lower: (input) => {
10309
- return applyStringFunc((str) => str.toLowerCase(), input);
10410
+ lower: (context, input) => {
10411
+ return applyStringFunc((str) => str.toLowerCase(), context, input);
10310
10412
  },
10311
10413
  /**
10312
10414
  * Returns the input string with all instances of pattern replaced with substitution. If the substitution is the empty string (''),
@@ -10318,13 +10420,14 @@
10318
10420
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10319
10421
  *
10320
10422
  * See: https://hl7.org/fhirpath/#replacepattern-string-substitution-string-string
10423
+ * @param context The evaluation context.
10321
10424
  * @param input The input collection.
10322
10425
  * @param patternAtom The pattern to search for.
10323
10426
  * @param substitionAtom The substition to replace with.
10324
10427
  * @returns The string with all instances of the search pattern replaced with the substitution string.
10325
10428
  */
10326
- replace: (input, patternAtom, substitionAtom) => {
10327
- return applyStringFunc((str, pattern, substition) => str.replaceAll(pattern, substition), input, patternAtom, substitionAtom);
10429
+ replace: (context, input, patternAtom, substitionAtom) => {
10430
+ return applyStringFunc((str, pattern, substition) => str.replaceAll(pattern, substition), context, input, patternAtom, substitionAtom);
10328
10431
  },
10329
10432
  /**
10330
10433
  * Returns true when the value matches the given regular expression. Regular expressions should function consistently, regardless of any culture- and locale-specific settings in the environment, should be case-sensitive, use 'single line' mode and allow Unicode characters.
@@ -10334,12 +10437,13 @@
10334
10437
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10335
10438
  *
10336
10439
  * See: https://hl7.org/fhirpath/#matchesregex-string-boolean
10440
+ * @param context The evaluation context.
10337
10441
  * @param input The input collection.
10338
10442
  * @param regexAtom The regular expression atom.
10339
10443
  * @returns True if the input string matches the given regular expression.
10340
10444
  */
10341
- matches: (input, regexAtom) => {
10342
- return applyStringFunc((str, regex) => !!str.match(regex), input, regexAtom);
10445
+ matches: (context, input, regexAtom) => {
10446
+ return applyStringFunc((str, regex) => !!str.match(regex), context, input, regexAtom);
10343
10447
  },
10344
10448
  /**
10345
10449
  * Matches the input using the regular expression in regex and replaces each match with the substitution string. The substitution may refer to identified match groups in the regular expression.
@@ -10349,30 +10453,33 @@
10349
10453
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10350
10454
  *
10351
10455
  * See: https://hl7.org/fhirpath/#replacematchesregex-string-substitution-string-string
10456
+ * @param context The evaluation context.
10352
10457
  * @param input The input collection.
10353
10458
  * @param regexAtom The regular expression atom.
10354
10459
  * @param substitionAtom The substition to replace with.
10355
10460
  * @returns The string with all instances of the search pattern replaced with the substitution string.
10356
10461
  */
10357
- replaceMatches: (input, regexAtom, substitionAtom) => {
10358
- return applyStringFunc((str, pattern, substition) => str.replaceAll(pattern, substition), input, regexAtom, substitionAtom);
10462
+ replaceMatches: (context, input, regexAtom, substitionAtom) => {
10463
+ return applyStringFunc((str, pattern, substition) => str.replaceAll(pattern, substition), context, input, regexAtom, substitionAtom);
10359
10464
  },
10360
10465
  /**
10466
+ * @param context The evaluation context.
10361
10467
  * @param input The input collection.
10362
10468
  * @returns The index of the substring.
10363
10469
  */
10364
- length: (input) => {
10365
- return applyStringFunc((str) => str.length, input);
10470
+ length: (context, input) => {
10471
+ return applyStringFunc((str) => str.length, context, input);
10366
10472
  },
10367
10473
  /**
10368
10474
  * Returns the list of characters in the input string. If the input collection is empty ({ }), the result is empty.
10369
10475
  *
10370
10476
  * See: https://hl7.org/fhirpath/#tochars-collection
10477
+ * @param context The evaluation context.
10371
10478
  * @param input The input collection.
10372
10479
  * @returns Array of characters.
10373
10480
  */
10374
- toChars: (input) => {
10375
- return applyStringFunc((str) => (str ? str.split('') : undefined), input);
10481
+ toChars: (context, input) => {
10482
+ return applyStringFunc((str) => (str ? str.split('') : undefined), context, input);
10376
10483
  },
10377
10484
  /*
10378
10485
  * 5.7. Math
@@ -10385,11 +10492,12 @@
10385
10492
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10386
10493
  *
10387
10494
  * See: https://hl7.org/fhirpath/#abs-integer-decimal-quantity
10495
+ * @param context The evaluation context.
10388
10496
  * @param input The input collection.
10389
10497
  * @returns A collection containing the result.
10390
10498
  */
10391
- abs: (input) => {
10392
- return applyMathFunc(Math.abs, input);
10499
+ abs: (context, input) => {
10500
+ return applyMathFunc(Math.abs, context, input);
10393
10501
  },
10394
10502
  /**
10395
10503
  * Returns the first integer greater than or equal to the input.
@@ -10399,11 +10507,12 @@
10399
10507
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10400
10508
  *
10401
10509
  * See: https://hl7.org/fhirpath/#ceiling-integer
10510
+ * @param context The evaluation context.
10402
10511
  * @param input The input collection.
10403
10512
  * @returns A collection containing the result.
10404
10513
  */
10405
- ceiling: (input) => {
10406
- return applyMathFunc(Math.ceil, input);
10514
+ ceiling: (context, input) => {
10515
+ return applyMathFunc(Math.ceil, context, input);
10407
10516
  },
10408
10517
  /**
10409
10518
  * Returns e raised to the power of the input.
@@ -10415,11 +10524,12 @@
10415
10524
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10416
10525
  *
10417
10526
  * See: https://hl7.org/fhirpath/#exp-decimal
10527
+ * @param context The evaluation context.
10418
10528
  * @param input The input collection.
10419
10529
  * @returns A collection containing the result.
10420
10530
  */
10421
- exp: (input) => {
10422
- return applyMathFunc(Math.exp, input);
10531
+ exp: (context, input) => {
10532
+ return applyMathFunc(Math.exp, context, input);
10423
10533
  },
10424
10534
  /**
10425
10535
  * Returns the first integer less than or equal to the input.
@@ -10429,11 +10539,12 @@
10429
10539
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10430
10540
  *
10431
10541
  * See: https://hl7.org/fhirpath/#floor-integer
10542
+ * @param context The evaluation context.
10432
10543
  * @param input The input collection.
10433
10544
  * @returns A collection containing the result.
10434
10545
  */
10435
- floor: (input) => {
10436
- return applyMathFunc(Math.floor, input);
10546
+ floor: (context, input) => {
10547
+ return applyMathFunc(Math.floor, context, input);
10437
10548
  },
10438
10549
  /**
10439
10550
  * Returns the natural logarithm of the input (i.e. the logarithm base e).
@@ -10445,11 +10556,12 @@
10445
10556
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10446
10557
  *
10447
10558
  * See: https://hl7.org/fhirpath/#ln-decimal
10559
+ * @param context The evaluation context.
10448
10560
  * @param input The input collection.
10449
10561
  * @returns A collection containing the result.
10450
10562
  */
10451
- ln: (input) => {
10452
- return applyMathFunc(Math.log, input);
10563
+ ln: (context, input) => {
10564
+ return applyMathFunc(Math.log, context, input);
10453
10565
  },
10454
10566
  /**
10455
10567
  * Returns the logarithm base base of the input number.
@@ -10463,12 +10575,13 @@
10463
10575
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10464
10576
  *
10465
10577
  * See: https://hl7.org/fhirpath/#logbase-decimal-decimal
10578
+ * @param context The evaluation context.
10466
10579
  * @param input The input collection.
10467
10580
  * @param baseAtom The logarithm base.
10468
10581
  * @returns A collection containing the result.
10469
10582
  */
10470
- log: (input, baseAtom) => {
10471
- return applyMathFunc((value, base) => Math.log(value) / Math.log(base), input, baseAtom);
10583
+ log: (context, input, baseAtom) => {
10584
+ return applyMathFunc((value, base) => Math.log(value) / Math.log(base), context, input, baseAtom);
10472
10585
  },
10473
10586
  /**
10474
10587
  * 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.
@@ -10480,12 +10593,13 @@
10480
10593
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10481
10594
  *
10482
10595
  * See: https://hl7.org/fhirpath/#powerexponent-integer-decimal-integer-decimal
10596
+ * @param context The evaluation context.
10483
10597
  * @param input The input collection.
10484
10598
  * @param expAtom The exponent power.
10485
10599
  * @returns A collection containing the result.
10486
10600
  */
10487
- power: (input, expAtom) => {
10488
- return applyMathFunc(Math.pow, input, expAtom);
10601
+ power: (context, input, expAtom) => {
10602
+ return applyMathFunc(Math.pow, context, input, expAtom);
10489
10603
  },
10490
10604
  /**
10491
10605
  * 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.
@@ -10499,11 +10613,12 @@
10499
10613
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10500
10614
  *
10501
10615
  * See: https://hl7.org/fhirpath/#roundprecision-integer-decimal
10616
+ * @param context The evaluation context.
10502
10617
  * @param input The input collection.
10503
10618
  * @returns A collection containing the result.
10504
10619
  */
10505
- round: (input) => {
10506
- return applyMathFunc(Math.round, input);
10620
+ round: (context, input) => {
10621
+ return applyMathFunc(Math.round, context, input);
10507
10622
  },
10508
10623
  /**
10509
10624
  * Returns the square root of the input number as a Decimal.
@@ -10517,11 +10632,12 @@
10517
10632
  * Note that this function is equivalent to raising a number of the power of 0.5 using the power() function.
10518
10633
  *
10519
10634
  * See: https://hl7.org/fhirpath/#sqrt-decimal
10635
+ * @param context The evaluation context.
10520
10636
  * @param input The input collection.
10521
10637
  * @returns A collection containing the result.
10522
10638
  */
10523
- sqrt: (input) => {
10524
- return applyMathFunc(Math.sqrt, input);
10639
+ sqrt: (context, input) => {
10640
+ return applyMathFunc(Math.sqrt, context, input);
10525
10641
  },
10526
10642
  /**
10527
10643
  * Returns the integer portion of the input.
@@ -10531,11 +10647,12 @@
10531
10647
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10532
10648
  *
10533
10649
  * See: https://hl7.org/fhirpath/#truncate-integer
10650
+ * @param context The evaluation context.
10534
10651
  * @param input The input collection.
10535
10652
  * @returns A collection containing the result.
10536
10653
  */
10537
- truncate: (input) => {
10538
- return applyMathFunc((x) => x | 0, input);
10654
+ truncate: (context, input) => {
10655
+ return applyMathFunc((x) => x | 0, context, input);
10539
10656
  },
10540
10657
  /*
10541
10658
  * 5.8. Tree navigation
@@ -10556,11 +10673,12 @@
10556
10673
  * function unchanged.
10557
10674
  *
10558
10675
  * See: https://hl7.org/fhirpath/#tracename-string-projection-expression-collection
10676
+ * @param context The evaluation context.
10559
10677
  * @param input The input collection.
10560
10678
  * @param nameAtom The log name.
10561
10679
  * @returns The input collection.
10562
10680
  */
10563
- trace: (input, nameAtom) => {
10681
+ trace: (context, input, nameAtom) => {
10564
10682
  console.log('trace', input, nameAtom);
10565
10683
  return input;
10566
10684
  },
@@ -10598,22 +10716,23 @@
10598
10716
  *
10599
10717
  * IBM FHIR issue: https://github.com/IBM/FHIR/issues/1014
10600
10718
  * IBM FHIR PR: https://github.com/IBM/FHIR/pull/1023
10719
+ * @param context The evaluation context.
10601
10720
  * @param input The input collection.
10602
10721
  * @param startAtom The start date/time.
10603
10722
  * @param endAtom The end date/time.
10604
10723
  * @param unitsAtom Which units to return ("years", "months", or "days").
10605
10724
  * @returns The Quantity of time between the two dates.
10606
10725
  */
10607
- between: (input, startAtom, endAtom, unitsAtom) => {
10608
- const startDate = functions.toDateTime(startAtom.eval(input));
10726
+ between: (context, input, startAtom, endAtom, unitsAtom) => {
10727
+ const startDate = functions.toDateTime(context, startAtom.eval(context, input));
10609
10728
  if (startDate.length === 0) {
10610
10729
  throw new Error('Invalid start date');
10611
10730
  }
10612
- const endDate = functions.toDateTime(endAtom.eval(input));
10731
+ const endDate = functions.toDateTime(context, endAtom.eval(context, input));
10613
10732
  if (endDate.length === 0) {
10614
10733
  throw new Error('Invalid end date');
10615
10734
  }
10616
- const unit = unitsAtom.eval(input)[0]?.value;
10735
+ const unit = unitsAtom.eval(context, input)[0]?.value;
10617
10736
  if (unit !== 'years' && unit !== 'months' && unit !== 'days') {
10618
10737
  throw new Error('Invalid units');
10619
10738
  }
@@ -10631,11 +10750,12 @@
10631
10750
  * For implementations with compile-time typing, this requires special-case
10632
10751
  * handling when processing the argument to treat it as a type specifier rather
10633
10752
  * than an identifier expression:
10753
+ * @param _context The evaluation context.
10634
10754
  * @param input The input collection.
10635
10755
  * @param typeAtom The desired type.
10636
10756
  * @returns True if the input element is of the desired type.
10637
10757
  */
10638
- is: (input, typeAtom) => {
10758
+ is: (_context, input, typeAtom) => {
10639
10759
  let typeName = '';
10640
10760
  if (typeAtom instanceof SymbolAtom) {
10641
10761
  typeName = typeAtom.name;
@@ -10655,11 +10775,12 @@
10655
10775
  * 6.5.3. not() : Boolean
10656
10776
  *
10657
10777
  * Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):
10778
+ * @param context The evaluation context.
10658
10779
  * @param input The input collection.
10659
10780
  * @returns True if the input evaluates to false.
10660
10781
  */
10661
- not: (input) => {
10662
- return functions.toBoolean(input).map((value) => ({ type: exports.PropertyType.boolean, value: !value.value }));
10782
+ not: (context, input) => {
10783
+ return functions.toBoolean(context, input).map((value) => ({ type: exports.PropertyType.boolean, value: !value.value }));
10663
10784
  },
10664
10785
  /*
10665
10786
  * Additional functions
@@ -10668,10 +10789,11 @@
10668
10789
  /**
10669
10790
  * 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.
10670
10791
  * The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.
10792
+ * @param _context The evaluation context.
10671
10793
  * @param input The input collection.
10672
10794
  * @returns The resolved resource.
10673
10795
  */
10674
- resolve: (input) => {
10796
+ resolve: (_context, input) => {
10675
10797
  return input
10676
10798
  .map((e) => {
10677
10799
  const value = e.value;
@@ -10705,10 +10827,11 @@
10705
10827
  },
10706
10828
  /**
10707
10829
  * The as operator can be used to treat a value as a specific type.
10830
+ * @param _context The evaluation context.
10708
10831
  * @param input The input value.
10709
10832
  * @returns The value as the specific type.
10710
10833
  */
10711
- as: (input) => {
10834
+ as: (_context, input) => {
10712
10835
  return input;
10713
10836
  },
10714
10837
  /*
@@ -10724,10 +10847,11 @@
10724
10847
  * https://hl7.org/fhirpath/modelinfo.xsd
10725
10848
  *
10726
10849
  * See: https://hl7.org/fhirpath/#model-information
10850
+ * @param _context The evaluation context.
10727
10851
  * @param input The input collection.
10728
10852
  * @returns The type of the input value.
10729
10853
  */
10730
- type: (input) => {
10854
+ type: (_context, input) => {
10731
10855
  return input.map(({ value }) => {
10732
10856
  if (typeof value === 'boolean') {
10733
10857
  return { type: exports.PropertyType.BackboneElement, value: { namespace: 'System', name: 'Boolean' } };
@@ -10744,8 +10868,8 @@
10744
10868
  return { type: exports.PropertyType.BackboneElement, value: null };
10745
10869
  });
10746
10870
  },
10747
- conformsTo: (input, systemAtom) => {
10748
- const system = systemAtom.eval(input)[0].value;
10871
+ conformsTo: (context, input, systemAtom) => {
10872
+ const system = systemAtom.eval(context, input)[0].value;
10749
10873
  if (!system.startsWith('http://hl7.org/fhir/StructureDefinition/')) {
10750
10874
  throw new Error('Expected a StructureDefinition URL');
10751
10875
  }
@@ -10759,7 +10883,7 @@
10759
10883
  /*
10760
10884
  * Helper utilities
10761
10885
  */
10762
- function applyStringFunc(func, input, ...argsAtoms) {
10886
+ function applyStringFunc(func, context, input, ...argsAtoms) {
10763
10887
  if (input.length === 0) {
10764
10888
  return [];
10765
10889
  }
@@ -10767,7 +10891,7 @@
10767
10891
  if (typeof value !== 'string') {
10768
10892
  throw new Error('String function cannot be called with non-string');
10769
10893
  }
10770
- const result = func(value, ...argsAtoms.map((atom) => atom && atom.eval(input)?.[0]?.value));
10894
+ const result = func(value, ...argsAtoms.map((atom) => atom && atom.eval(context, input)?.[0]?.value));
10771
10895
  if (result === undefined) {
10772
10896
  return [];
10773
10897
  }
@@ -10776,7 +10900,7 @@
10776
10900
  }
10777
10901
  return [toTypedValue(result)];
10778
10902
  }
10779
- function applyMathFunc(func, input, ...argsAtoms) {
10903
+ function applyMathFunc(func, context, input, ...argsAtoms) {
10780
10904
  if (input.length === 0) {
10781
10905
  return [];
10782
10906
  }
@@ -10786,7 +10910,7 @@
10786
10910
  if (typeof numberInput !== 'number') {
10787
10911
  throw new Error('Math function cannot be called with non-number');
10788
10912
  }
10789
- const result = func(numberInput, ...argsAtoms.map((atom) => atom.eval(input)?.[0]?.value));
10913
+ const result = func(numberInput, ...argsAtoms.map((atom) => atom.eval(context, input)?.[0]?.value));
10790
10914
  const type = quantity ? exports.PropertyType.Quantity : input[0].type;
10791
10915
  const returnValue = quantity ? { ...value, value: result } : result;
10792
10916
  return [{ type, value: returnValue }];
@@ -10808,13 +10932,13 @@
10808
10932
  this.original = original;
10809
10933
  this.child = child;
10810
10934
  }
10811
- eval(context) {
10935
+ eval(context, input) {
10812
10936
  try {
10813
- if (context.length > 0) {
10814
- return context.map((e) => this.child.eval([e])).flat();
10937
+ if (input.length > 0) {
10938
+ return input.map((e) => this.child.eval(context, [e])).flat();
10815
10939
  }
10816
10940
  else {
10817
- return this.child.eval([]);
10941
+ return this.child.eval(context, []);
10818
10942
  }
10819
10943
  }
10820
10944
  catch (error) {
@@ -10844,11 +10968,18 @@
10844
10968
  constructor(name) {
10845
10969
  this.name = name;
10846
10970
  }
10847
- eval(context) {
10971
+ eval(context, input) {
10848
10972
  if (this.name === '$this') {
10849
- return context;
10973
+ return input;
10974
+ }
10975
+ if (this.name.startsWith('%')) {
10976
+ const symbol = context.variables[this.name.slice(1)];
10977
+ if (!symbol) {
10978
+ throw new Error(`Undefined variable ${this.name}`);
10979
+ }
10980
+ return [symbol];
10850
10981
  }
10851
- return context.flatMap((e) => this.evalValue(e)).filter((e) => e?.value !== undefined);
10982
+ return input.flatMap((e) => this.evalValue(e)).filter((e) => e?.value !== undefined);
10852
10983
  }
10853
10984
  evalValue(typedValue) {
10854
10985
  const input = typedValue.value;
@@ -10877,8 +11008,8 @@
10877
11008
  super(operator, child);
10878
11009
  this.impl = impl;
10879
11010
  }
10880
- eval(context) {
10881
- return this.impl(this.child.eval(context));
11011
+ eval(context, input) {
11012
+ return this.impl(this.child.eval(context, input));
10882
11013
  }
10883
11014
  toString() {
10884
11015
  return this.child.toString();
@@ -10888,8 +11019,8 @@
10888
11019
  constructor(left, right) {
10889
11020
  super('as', left, right);
10890
11021
  }
10891
- eval(context) {
10892
- return functions.ofType(this.left.eval(context), this.right);
11022
+ eval(context, input) {
11023
+ return functions.ofType(context, this.left.eval(context, input), this.right);
10893
11024
  }
10894
11025
  }
10895
11026
  class ArithemticOperatorAtom extends InfixOperatorAtom {
@@ -10897,12 +11028,12 @@
10897
11028
  super(operator, left, right);
10898
11029
  this.impl = impl;
10899
11030
  }
10900
- eval(context) {
10901
- const leftEvalResult = this.left.eval(context);
11031
+ eval(context, input) {
11032
+ const leftEvalResult = this.left.eval(context, input);
10902
11033
  if (leftEvalResult.length !== 1) {
10903
11034
  return [];
10904
11035
  }
10905
- const rightEvalResult = this.right.eval(context);
11036
+ const rightEvalResult = this.right.eval(context, input);
10906
11037
  if (rightEvalResult.length !== 1) {
10907
11038
  return [];
10908
11039
  }
@@ -10926,9 +11057,9 @@
10926
11057
  constructor(left, right) {
10927
11058
  super('&', left, right);
10928
11059
  }
10929
- eval(context) {
10930
- const leftValue = this.left.eval(context);
10931
- const rightValue = this.right.eval(context);
11060
+ eval(context, input) {
11061
+ const leftValue = this.left.eval(context, input);
11062
+ const rightValue = this.right.eval(context, input);
10932
11063
  const result = [...leftValue, ...rightValue];
10933
11064
  if (result.length > 0 && result.every((e) => typeof e.value === 'string')) {
10934
11065
  return [{ type: exports.PropertyType.string, value: result.map((e) => e.value).join('') }];
@@ -10940,9 +11071,9 @@
10940
11071
  constructor(left, right) {
10941
11072
  super('contains', left, right);
10942
11073
  }
10943
- eval(context) {
10944
- const leftValue = this.left.eval(context);
10945
- const rightValue = this.right.eval(context);
11074
+ eval(context, input) {
11075
+ const leftValue = this.left.eval(context, input);
11076
+ const rightValue = this.right.eval(context, input);
10946
11077
  return booleanToTypedValue(leftValue.some((e) => e.value === rightValue[0].value));
10947
11078
  }
10948
11079
  }
@@ -10950,9 +11081,9 @@
10950
11081
  constructor(left, right) {
10951
11082
  super('in', left, right);
10952
11083
  }
10953
- eval(context) {
10954
- const leftValue = this.left.eval(context);
10955
- const rightValue = this.right.eval(context);
11084
+ eval(context, input) {
11085
+ const leftValue = this.left.eval(context, input);
11086
+ const rightValue = this.right.eval(context, input);
10956
11087
  return booleanToTypedValue(rightValue.some((e) => e.value === leftValue[0].value));
10957
11088
  }
10958
11089
  }
@@ -10960,8 +11091,8 @@
10960
11091
  constructor(left, right) {
10961
11092
  super('.', left, right);
10962
11093
  }
10963
- eval(context) {
10964
- return this.right.eval(this.left.eval(context));
11094
+ eval(context, input) {
11095
+ return this.right.eval(context, this.left.eval(context, input));
10965
11096
  }
10966
11097
  toString() {
10967
11098
  return `${this.left.toString()}.${this.right.toString()}`;
@@ -10971,9 +11102,9 @@
10971
11102
  constructor(left, right) {
10972
11103
  super('|', left, right);
10973
11104
  }
10974
- eval(context) {
10975
- const leftResult = this.left.eval(context);
10976
- const rightResult = this.right.eval(context);
11105
+ eval(context, input) {
11106
+ const leftResult = this.left.eval(context, input);
11107
+ const rightResult = this.right.eval(context, input);
10977
11108
  return removeDuplicates([...leftResult, ...rightResult]);
10978
11109
  }
10979
11110
  }
@@ -10981,9 +11112,9 @@
10981
11112
  constructor(left, right) {
10982
11113
  super('=', left, right);
10983
11114
  }
10984
- eval(context) {
10985
- const leftValue = this.left.eval(context);
10986
- const rightValue = this.right.eval(context);
11115
+ eval(context, input) {
11116
+ const leftValue = this.left.eval(context, input);
11117
+ const rightValue = this.right.eval(context, input);
10987
11118
  return fhirPathArrayEquals(leftValue, rightValue);
10988
11119
  }
10989
11120
  }
@@ -10991,9 +11122,9 @@
10991
11122
  constructor(left, right) {
10992
11123
  super('!=', left, right);
10993
11124
  }
10994
- eval(context) {
10995
- const leftValue = this.left.eval(context);
10996
- const rightValue = this.right.eval(context);
11125
+ eval(context, input) {
11126
+ const leftValue = this.left.eval(context, input);
11127
+ const rightValue = this.right.eval(context, input);
10997
11128
  return fhirPathNot(fhirPathArrayEquals(leftValue, rightValue));
10998
11129
  }
10999
11130
  }
@@ -11001,9 +11132,9 @@
11001
11132
  constructor(left, right) {
11002
11133
  super('~', left, right);
11003
11134
  }
11004
- eval(context) {
11005
- const leftValue = this.left.eval(context);
11006
- const rightValue = this.right.eval(context);
11135
+ eval(context, input) {
11136
+ const leftValue = this.left.eval(context, input);
11137
+ const rightValue = this.right.eval(context, input);
11007
11138
  return fhirPathArrayEquivalent(leftValue, rightValue);
11008
11139
  }
11009
11140
  }
@@ -11011,9 +11142,9 @@
11011
11142
  constructor(left, right) {
11012
11143
  super('!~', left, right);
11013
11144
  }
11014
- eval(context) {
11015
- const leftValue = this.left.eval(context);
11016
- const rightValue = this.right.eval(context);
11145
+ eval(context, input) {
11146
+ const leftValue = this.left.eval(context, input);
11147
+ const rightValue = this.right.eval(context, input);
11017
11148
  return fhirPathNot(fhirPathArrayEquivalent(leftValue, rightValue));
11018
11149
  }
11019
11150
  }
@@ -11021,8 +11152,8 @@
11021
11152
  constructor(left, right) {
11022
11153
  super('is', left, right);
11023
11154
  }
11024
- eval(context) {
11025
- const leftValue = this.left.eval(context);
11155
+ eval(context, input) {
11156
+ const leftValue = this.left.eval(context, input);
11026
11157
  if (leftValue.length !== 1) {
11027
11158
  return [];
11028
11159
  }
@@ -11040,9 +11171,9 @@
11040
11171
  constructor(left, right) {
11041
11172
  super('and', left, right);
11042
11173
  }
11043
- eval(context) {
11044
- const leftValue = this.left.eval(context);
11045
- const rightValue = this.right.eval(context);
11174
+ eval(context, input) {
11175
+ const leftValue = this.left.eval(context, input);
11176
+ const rightValue = this.right.eval(context, input);
11046
11177
  if (leftValue[0]?.value === true && rightValue[0]?.value === true) {
11047
11178
  return booleanToTypedValue(true);
11048
11179
  }
@@ -11056,12 +11187,12 @@
11056
11187
  constructor(left, right) {
11057
11188
  super('or', left, right);
11058
11189
  }
11059
- eval(context) {
11060
- const leftValue = this.left.eval(context);
11190
+ eval(context, input) {
11191
+ const leftValue = this.left.eval(context, input);
11061
11192
  if (toJsBoolean(leftValue)) {
11062
11193
  return leftValue;
11063
11194
  }
11064
- const rightValue = this.right.eval(context);
11195
+ const rightValue = this.right.eval(context, input);
11065
11196
  if (toJsBoolean(rightValue)) {
11066
11197
  return rightValue;
11067
11198
  }
@@ -11078,9 +11209,9 @@
11078
11209
  constructor(left, right) {
11079
11210
  super('xor', left, right);
11080
11211
  }
11081
- eval(context) {
11082
- const leftResult = this.left.eval(context);
11083
- const rightResult = this.right.eval(context);
11212
+ eval(context, input) {
11213
+ const leftResult = this.left.eval(context, input);
11214
+ const rightResult = this.right.eval(context, input);
11084
11215
  if (leftResult.length === 0 && rightResult.length === 0) {
11085
11216
  return [];
11086
11217
  }
@@ -11100,12 +11231,12 @@
11100
11231
  this.name = name;
11101
11232
  this.args = args;
11102
11233
  }
11103
- eval(context) {
11234
+ eval(context, input) {
11104
11235
  const impl = functions[this.name];
11105
11236
  if (!impl) {
11106
11237
  throw new Error('Unrecognized function: ' + this.name);
11107
11238
  }
11108
- return impl(context, ...this.args);
11239
+ return impl(context, input, ...this.args);
11109
11240
  }
11110
11241
  toString() {
11111
11242
  return `${this.name}(${this.args.map((arg) => arg.toString()).join(', ')})`;
@@ -11116,8 +11247,8 @@
11116
11247
  this.left = left;
11117
11248
  this.expr = expr;
11118
11249
  }
11119
- eval(context) {
11120
- const evalResult = this.expr.eval(context);
11250
+ eval(context, input) {
11251
+ const evalResult = this.expr.eval(context, input);
11121
11252
  if (evalResult.length !== 1) {
11122
11253
  return [];
11123
11254
  }
@@ -11125,7 +11256,7 @@
11125
11256
  if (typeof index !== 'number') {
11126
11257
  throw new Error(`Invalid indexer expression: should return integer}`);
11127
11258
  }
11128
- const leftResult = this.left.eval(context);
11259
+ const leftResult = this.left.eval(context, input);
11129
11260
  if (!(index in leftResult)) {
11130
11261
  return [];
11131
11262
  }
@@ -11269,10 +11400,12 @@
11269
11400
  * Evaluates a FHIRPath expression against a resource or other object.
11270
11401
  * @param expression The FHIRPath expression to parse.
11271
11402
  * @param input The resource or object to evaluate the expression against.
11403
+ * @param variables A map of variables for eval input.
11272
11404
  * @returns The result of the FHIRPath expression against the resource or object.
11273
11405
  */
11274
- function evalFhirPathTyped(expression, input) {
11275
- return parseFhirPath(expression).eval(input);
11406
+ function evalFhirPathTyped(expression, input, variables) {
11407
+ const variableInput = variables ? variables : {};
11408
+ return parseFhirPath(expression).eval({ variables: variableInput }, input);
11276
11409
  }
11277
11410
 
11278
11411
  const MAPPING_LANGUAGE_OPERATORS$1 = [...FHIRPATH_OPERATORS, '->', '<<', '>>'];
@@ -12772,18 +12905,18 @@
12772
12905
  function getSearchParameterDetails(resourceType, searchParam) {
12773
12906
  let result = globalSchema.types[resourceType]?.searchParamsDetails?.[searchParam.code];
12774
12907
  if (!result) {
12775
- result = buildSearchParamterDetails(resourceType, searchParam);
12908
+ result = buildSearchParameterDetails(resourceType, searchParam);
12776
12909
  }
12777
12910
  return result;
12778
12911
  }
12779
- function setSearchParamterDetails(resourceType, code, details) {
12912
+ function setSearchParameterDetails(resourceType, code, details) {
12780
12913
  const typeSchema = globalSchema.types[resourceType];
12781
12914
  if (!typeSchema.searchParamsDetails) {
12782
12915
  typeSchema.searchParamsDetails = {};
12783
12916
  }
12784
12917
  typeSchema.searchParamsDetails[code] = details;
12785
12918
  }
12786
- function buildSearchParamterDetails(resourceType, searchParam) {
12919
+ function buildSearchParameterDetails(resourceType, searchParam) {
12787
12920
  const code = searchParam.code;
12788
12921
  const columnName = convertCodeToColumnName(code);
12789
12922
  const expression = getExpressionForResourceType(resourceType, searchParam.expression)?.split('.');
@@ -12825,7 +12958,7 @@
12825
12958
  }
12826
12959
  const type = getSearchParameterType(searchParam, propertyType);
12827
12960
  const result = { columnName, type, elementDefinition, array };
12828
- setSearchParamterDetails(resourceType, code, result);
12961
+ setSearchParameterDetails(resourceType, code, result);
12829
12962
  return result;
12830
12963
  }
12831
12964
  function isBackboneElement(propertyType) {
@@ -13223,6 +13356,7 @@
13223
13356
  exports.normalizeOperationOutcome = normalizeOperationOutcome;
13224
13357
  exports.notFound = notFound;
13225
13358
  exports.notModified = notModified;
13359
+ exports.operationOutcomeIssueToString = operationOutcomeIssueToString;
13226
13360
  exports.operationOutcomeToString = operationOutcomeToString;
13227
13361
  exports.parseFhirPath = parseFhirPath;
13228
13362
  exports.parseFilterParameter = parseFilterParameter;