@medplum/core 2.0.21 → 2.0.22

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.
Files changed (44) hide show
  1. package/dist/cjs/index.cjs +380 -288
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.min.cjs +1 -1
  4. package/dist/esm/client.mjs +132 -102
  5. package/dist/esm/client.mjs.map +1 -1
  6. package/dist/esm/crypto.mjs +3 -1
  7. package/dist/esm/crypto.mjs.map +1 -1
  8. package/dist/esm/fhirpath/functions.mjs +179 -129
  9. package/dist/esm/fhirpath/functions.mjs.map +1 -1
  10. package/dist/esm/format.mjs +6 -4
  11. package/dist/esm/format.mjs.map +1 -1
  12. package/dist/esm/hl7.mjs +1 -1
  13. package/dist/esm/hl7.mjs.map +1 -1
  14. package/dist/esm/index.min.mjs +1 -1
  15. package/dist/esm/index.mjs +1 -0
  16. package/dist/esm/index.mjs.map +1 -1
  17. package/dist/esm/jwt.mjs +4 -2
  18. package/dist/esm/jwt.mjs.map +1 -1
  19. package/dist/esm/schema.mjs +4 -10
  20. package/dist/esm/schema.mjs.map +1 -1
  21. package/dist/esm/search/details.mjs +0 -1
  22. package/dist/esm/search/details.mjs.map +1 -1
  23. package/dist/esm/search/match.mjs +1 -0
  24. package/dist/esm/search/match.mjs.map +1 -1
  25. package/dist/esm/search/search.mjs +1 -1
  26. package/dist/esm/search/search.mjs.map +1 -1
  27. package/dist/esm/storage.mjs +8 -0
  28. package/dist/esm/storage.mjs.map +1 -1
  29. package/dist/esm/types.mjs +1 -0
  30. package/dist/esm/types.mjs.map +1 -1
  31. package/dist/esm/utils.mjs +8 -7
  32. package/dist/esm/utils.mjs.map +1 -1
  33. package/dist/types/client.d.ts +74 -64
  34. package/dist/types/crypto.d.ts +3 -1
  35. package/dist/types/hl7.d.ts +1 -1
  36. package/dist/types/index.d.ts +1 -0
  37. package/dist/types/jwt.d.ts +2 -1
  38. package/dist/types/schema.d.ts +4 -10
  39. package/dist/types/search/details.d.ts +0 -1
  40. package/dist/types/search/search.d.ts +1 -1
  41. package/dist/types/storage.d.ts +8 -0
  42. package/dist/types/typeschema/types.d.ts +0 -1
  43. package/dist/types/utils.d.ts +4 -4
  44. package/package.json +1 -1
@@ -4,6 +4,37 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.medplum = global.medplum || {}, global.medplum.core = {})));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
+ /**
8
+ * Decodes a base64 string.
9
+ * Handles both browser and Node environments.
10
+ * @param data The base-64 encoded input string.
11
+ * @returns The decoded string.
12
+ */
13
+ function decodeBase64(data) {
14
+ if (typeof window !== 'undefined') {
15
+ return window.atob(data);
16
+ }
17
+ if (typeof Buffer !== 'undefined') {
18
+ return Buffer.from(data, 'base64').toString('binary');
19
+ }
20
+ throw new Error('Unable to decode base64');
21
+ }
22
+ /**
23
+ * Encodes a base64 string.
24
+ * Handles both browser and Node environments.
25
+ * @param data The unencoded input string.
26
+ * @returns The base-64 encoded string.
27
+ */
28
+ function encodeBase64(data) {
29
+ if (typeof window !== 'undefined') {
30
+ return window.btoa(data);
31
+ }
32
+ if (typeof Buffer !== 'undefined') {
33
+ return Buffer.from(data, 'binary').toString('base64');
34
+ }
35
+ throw new Error('Unable to encode base64');
36
+ }
37
+
7
38
  /**
8
39
  * More on Bundles can be found here
9
40
  * http://hl7.org/fhir/R4/bundle.html
@@ -454,18 +485,20 @@
454
485
  }
455
486
  /**
456
487
  * Returns the input number increased by the `n` units of the specified precision
457
- * @param a The input number
488
+ * @param a The input number.
458
489
  * @param precision The precision in number of digits.
459
- * @param n (default 1) The number of units to add
490
+ * @param n (default 1) The number of units to add.
491
+ * @returns The result of the increment.
460
492
  */
461
493
  function preciseIncrement(a, precision, n = 1) {
462
494
  return (toPreciseInteger$1(a, precision) + n) * Math.pow(10, -precision);
463
495
  }
464
496
  /**
465
497
  * Returns the input number decreased by the `n` units of the specified precision
466
- * @param a The input number
498
+ * @param a The input number.
467
499
  * @param precision The precision in number of digits.
468
- * @param n (default 1) The number of units to subtract
500
+ * @param n (default 1) The number of units to subtract.
501
+ * @returns The result of the decrement.
469
502
  */
470
503
  function preciseDecrement(a, precision, n = 1) {
471
504
  return (toPreciseInteger$1(a, precision) - n) * Math.pow(10, -precision);
@@ -523,7 +556,7 @@
523
556
  /**
524
557
  * Returns a display string for the resource.
525
558
  * @param resource The input resource.
526
- * @return Human friendly display string.
559
+ * @returns Human friendly display string.
527
560
  */
528
561
  function getDisplayString(resource) {
529
562
  if (isProfileResource(resource)) {
@@ -680,7 +713,7 @@
680
713
  }
681
714
  /**
682
715
  * Recursively builds the questionnaire answer items map.
683
- * @param item The current questionnaire response item.
716
+ * @param items The current questionnaire response items.
684
717
  * @param result The cumulative result map.
685
718
  */
686
719
  function buildQuestionnaireAnswerItems(items, result) {
@@ -699,7 +732,6 @@
699
732
  * If multiple identifiers exist with the same system, the first one is returned.
700
733
  *
701
734
  * If the system is not found, then returns undefined.
702
- *
703
735
  * @param resource The resource to check.
704
736
  * @param system The identifier system.
705
737
  * @returns The identifier value if found; otherwise undefined.
@@ -763,8 +795,9 @@
763
795
  * Evaluates JSON key/value pairs for FHIR JSON stringify.
764
796
  * Removes properties with empty string values.
765
797
  * Removes objects with zero properties.
766
- * @param {string} k Property key.
767
- * @param {*} v Property value.
798
+ * @param k Property key.
799
+ * @param v Property value.
800
+ * @returns The replaced value.
768
801
  */
769
802
  function stringifyReplacer(k, v) {
770
803
  return !isArrayKey(k) && isEmpty(v) ? undefined : v;
@@ -794,6 +827,7 @@
794
827
  * Ignores meta.versionId and meta.lastUpdated.
795
828
  * @param object1 The first object.
796
829
  * @param object2 The second object.
830
+ * @param path Optional path string.
797
831
  * @returns True if the objects are equal.
798
832
  */
799
833
  function deepEquals$1(object1, object2, path) {
@@ -859,7 +893,6 @@
859
893
  *
860
894
  * See: https://web.dev/structured-clone/
861
895
  * See: https://stackoverflow.com/questions/40488190/how-is-structured-clone-algorithm-different-from-deep-copy
862
- *
863
896
  * @param input The input to clone.
864
897
  * @returns A deep clone of the input.
865
898
  */
@@ -876,7 +909,7 @@
876
909
  }
877
910
  /**
878
911
  * Returns true if the input is an object.
879
- * @param object The candidate object.
912
+ * @param obj The candidate object.
880
913
  * @returns True if the input is a non-null non-undefined object.
881
914
  */
882
915
  function isObject$1(obj) {
@@ -961,6 +994,7 @@
961
994
  * @param definition The observation definition.
962
995
  * @param patient The patient.
963
996
  * @param value The observation value.
997
+ * @param category Optional interval category restriction.
964
998
  * @returns The observation interval if found; otherwise undefined.
965
999
  */
966
1000
  function findObservationInterval(definition, patient, value, category) {
@@ -1113,6 +1147,7 @@
1113
1147
 
1114
1148
  /**
1115
1149
  * Returns a cryptographically secure random string.
1150
+ * @returns A cryptographically secure random string.
1116
1151
  */
1117
1152
  function getRandomString() {
1118
1153
  const randomItems = new Uint32Array(28);
@@ -1121,7 +1156,8 @@
1121
1156
  }
1122
1157
  /**
1123
1158
  * Encrypts a string with SHA256 encryption.
1124
- * @param str
1159
+ * @param str The unencrypted input string.
1160
+ * @returns The encrypted value in an ArrayBuffer.
1125
1161
  */
1126
1162
  async function encryptSHA256(str) {
1127
1163
  return crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));
@@ -1161,41 +1197,11 @@
1161
1197
  }
1162
1198
  }
1163
1199
 
1164
- /**
1165
- * Decodes a base64 string.
1166
- * Handles both browser and Node environments.
1167
- * @param data The base-64 encoded input string.
1168
- * @returns The decoded string.
1169
- */
1170
- function decodeBase64(data) {
1171
- if (typeof window !== 'undefined') {
1172
- return window.atob(data);
1173
- }
1174
- if (typeof Buffer !== 'undefined') {
1175
- return Buffer.from(data, 'base64').toString('binary');
1176
- }
1177
- throw new Error('Unable to decode base64');
1178
- }
1179
- /**
1180
- * Encodes a base64 string.
1181
- * Handles both browser and Node environments.
1182
- * @param data The unencoded input string.
1183
- * @returns The base-64 encoded string.
1184
- */
1185
- function encodeBase64(data) {
1186
- if (typeof window !== 'undefined') {
1187
- return window.btoa(data);
1188
- }
1189
- if (typeof Buffer !== 'undefined') {
1190
- return Buffer.from(data, 'binary').toString('base64');
1191
- }
1192
- throw new Error('Unable to encode base64');
1193
- }
1194
-
1195
1200
  /**
1196
1201
  * Decodes a section of a JWT.
1197
1202
  * See: https://tools.ietf.org/html/rfc7519
1198
- * @param payload
1203
+ * @param payload The JWT payload string.
1204
+ * @returns Collection of key value claims in the JWT payload.
1199
1205
  */
1200
1206
  function decodePayload(payload) {
1201
1207
  const cleanedPayload = payload.replace(/-/g, '+').replace(/_/g, '/');
@@ -1209,7 +1215,8 @@
1209
1215
  }
1210
1216
  /**
1211
1217
  * Parses the JWT payload.
1212
- * @param token JWT token
1218
+ * @param token JWT token.
1219
+ * @returns Collection of key value claims in the JWT payload.
1213
1220
  */
1214
1221
  function parseJWTPayload(token) {
1215
1222
  const [_header, payload, _signature] = token.split('.');
@@ -1604,6 +1611,7 @@
1604
1611
  }
1605
1612
  /**
1606
1613
  * Returns the number of key/value pairs.
1614
+ * @returns The number of key/value pairs.
1607
1615
  */
1608
1616
  get length() {
1609
1617
  return this.data.size;
@@ -1616,12 +1624,16 @@
1616
1624
  }
1617
1625
  /**
1618
1626
  * Returns the current value associated with the given key, or null if the given key does not exist.
1627
+ * @param key The specified storage key.
1628
+ * @returns The current value associated with the given key, or null if the given key does not exist.
1619
1629
  */
1620
1630
  getItem(key) {
1621
1631
  return this.data.get(key) ?? null;
1622
1632
  }
1623
1633
  /**
1624
1634
  * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
1635
+ * @param key The storage key.
1636
+ * @param value The new value.
1625
1637
  */
1626
1638
  setItem(key, value) {
1627
1639
  if (value) {
@@ -1633,12 +1645,15 @@
1633
1645
  }
1634
1646
  /**
1635
1647
  * Removes the key/value pair with the given key, if a key/value pair with the given key exists.
1648
+ * @param key The storage key.
1636
1649
  */
1637
1650
  removeItem(key) {
1638
1651
  this.data.delete(key);
1639
1652
  }
1640
1653
  /**
1641
1654
  * Returns the name of the nth key, or null if n is greater than or equal to the number of key/value pairs.
1655
+ * @param index The numeric index.
1656
+ * @returns The nth key.
1642
1657
  */
1643
1658
  key(index) {
1644
1659
  return Array.from(this.data.keys())[index];
@@ -6181,6 +6196,7 @@
6181
6196
  }
6182
6197
  /**
6183
6198
  * Indexes PropertySchema from an ElementDefinition.
6199
+ * @param structureDefinition The input StructureDefinition.
6184
6200
  * @param element The input ElementDefinition.
6185
6201
  * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.
6186
6202
  */
@@ -6417,7 +6433,7 @@
6417
6433
 
6418
6434
  // PKCE auth based on:
6419
6435
  // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
6420
- const MEDPLUM_VERSION = "2.0.21-87271fa1" ;
6436
+ const MEDPLUM_VERSION = "2.0.22-f51ac45a" ;
6421
6437
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
6422
6438
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
6423
6439
  const DEFAULT_CACHE_TIME = 60000; // 60 seconds
@@ -6504,7 +6520,6 @@
6504
6520
  * <head>
6505
6521
  * <meta name="algolia:pageRank" content="100" />
6506
6522
  * </head>
6507
-
6508
6523
  */
6509
6524
  class MedplumClient extends EventTarget {
6510
6525
  constructor(options) {
@@ -6571,6 +6586,9 @@
6571
6586
  * @category Authentication
6572
6587
  */
6573
6588
  clearActiveLogin() {
6589
+ if (this.basicAuth) {
6590
+ return;
6591
+ }
6574
6592
  this.storage.setString('activeLogin', undefined);
6575
6593
  this.requestCache?.clear();
6576
6594
  this.accessToken = undefined;
@@ -6616,7 +6634,6 @@
6616
6634
  * This is a lower level method for custom requests.
6617
6635
  * For common operations, we recommend using higher level methods
6618
6636
  * such as `readResource()`, `search()`, etc.
6619
- *
6620
6637
  * @category HTTP
6621
6638
  * @param url The target URL.
6622
6639
  * @param options Optional fetch options.
@@ -6656,7 +6673,6 @@
6656
6673
  * This is a lower level method for custom requests.
6657
6674
  * For common operations, we recommend using higher level methods
6658
6675
  * such as `createResource()`.
6659
- *
6660
6676
  * @category HTTP
6661
6677
  * @param url The target URL.
6662
6678
  * @param body The content body. Strings and `File` objects are passed directly. Other objects are converted to JSON.
@@ -6681,7 +6697,6 @@
6681
6697
  * This is a lower level method for custom requests.
6682
6698
  * For common operations, we recommend using higher level methods
6683
6699
  * such as `updateResource()`.
6684
- *
6685
6700
  * @category HTTP
6686
6701
  * @param url The target URL.
6687
6702
  * @param body The content body. Strings and `File` objects are passed directly. Other objects are converted to JSON.
@@ -6706,7 +6721,6 @@
6706
6721
  * This is a lower level method for custom requests.
6707
6722
  * For common operations, we recommend using higher level methods
6708
6723
  * such as `patchResource()`.
6709
- *
6710
6724
  * @category HTTP
6711
6725
  * @param url The target URL.
6712
6726
  * @param operations Array of JSONPatch operations.
@@ -6727,13 +6741,12 @@
6727
6741
  * This is a lower level method for custom requests.
6728
6742
  * For common operations, we recommend using higher level methods
6729
6743
  * such as `deleteResource()`.
6730
- *
6731
6744
  * @category HTTP
6732
6745
  * @param url The target URL.
6733
6746
  * @param options Optional fetch options.
6734
6747
  * @returns Promise to the response content.
6735
6748
  */
6736
- delete(url, options = {}) {
6749
+ delete(url, options) {
6737
6750
  url = url.toString();
6738
6751
  this.invalidateUrl(url);
6739
6752
  return this.request('DELETE', url, options);
@@ -6744,53 +6757,54 @@
6744
6757
  * This method is part of the two different user registration flows:
6745
6758
  * 1) New Practitioner and new Project
6746
6759
  * 2) New Patient registration
6747
- *
6748
6760
  * @category Authentication
6749
6761
  * @param newUserRequest Register request including email and password.
6762
+ * @param options Optional fetch options.
6750
6763
  * @returns Promise to the authentication response.
6751
6764
  */
6752
- async startNewUser(newUserRequest) {
6765
+ async startNewUser(newUserRequest, options) {
6753
6766
  const { codeChallengeMethod, codeChallenge } = await this.startPkce();
6754
6767
  return this.post('auth/newuser', {
6755
6768
  ...newUserRequest,
6756
6769
  codeChallengeMethod,
6757
6770
  codeChallenge,
6758
- });
6771
+ }, undefined, options);
6759
6772
  }
6760
6773
  /**
6761
6774
  * Initiates a new project flow.
6762
6775
  *
6763
6776
  * This requires a partial login from `startNewUser` or `startNewGoogleUser`.
6764
- *
6765
6777
  * @param newProjectRequest Register request including email and password.
6778
+ * @param options Optional fetch options.
6766
6779
  * @returns Promise to the authentication response.
6767
6780
  */
6768
- async startNewProject(newProjectRequest) {
6769
- return this.post('auth/newproject', newProjectRequest);
6781
+ async startNewProject(newProjectRequest, options) {
6782
+ return this.post('auth/newproject', newProjectRequest, undefined, options);
6770
6783
  }
6771
6784
  /**
6772
6785
  * Initiates a new patient flow.
6773
6786
  *
6774
6787
  * This requires a partial login from `startNewUser` or `startNewGoogleUser`.
6775
- *
6776
6788
  * @param newPatientRequest Register request including email and password.
6789
+ * @param options Optional fetch options.
6777
6790
  * @returns Promise to the authentication response.
6778
6791
  */
6779
- async startNewPatient(newPatientRequest) {
6780
- return this.post('auth/newpatient', newPatientRequest);
6792
+ async startNewPatient(newPatientRequest, options) {
6793
+ return this.post('auth/newpatient', newPatientRequest, undefined, options);
6781
6794
  }
6782
6795
  /**
6783
6796
  * Initiates a user login flow.
6784
6797
  * @category Authentication
6785
6798
  * @param loginRequest Login request including email and password.
6799
+ * @param options Optional fetch options.
6786
6800
  * @returns Promise to the authentication response.
6787
6801
  */
6788
- async startLogin(loginRequest) {
6802
+ async startLogin(loginRequest, options) {
6789
6803
  return this.post('auth/login', {
6790
6804
  ...(await this.ensureCodeChallenge(loginRequest)),
6791
6805
  clientId: loginRequest.clientId ?? this.clientId,
6792
6806
  scope: loginRequest.scope,
6793
- });
6807
+ }, undefined, options);
6794
6808
  }
6795
6809
  /**
6796
6810
  * Tries to sign in with Google authentication.
@@ -6798,14 +6812,15 @@
6798
6812
  * See: https://developers.google.com/identity/gsi/web/guides/handle-credential-responses-js-functions
6799
6813
  * @category Authentication
6800
6814
  * @param loginRequest Login request including Google credential response.
6815
+ * @param options Optional fetch options.
6801
6816
  * @returns Promise to the authentication response.
6802
6817
  */
6803
- async startGoogleLogin(loginRequest) {
6818
+ async startGoogleLogin(loginRequest, options) {
6804
6819
  return this.post('auth/google', {
6805
6820
  ...(await this.ensureCodeChallenge(loginRequest)),
6806
6821
  clientId: loginRequest.clientId ?? this.clientId,
6807
6822
  scope: loginRequest.scope,
6808
- });
6823
+ }, undefined, options);
6809
6824
  }
6810
6825
  /**
6811
6826
  * Returns the PKCE code challenge and method.
@@ -6836,6 +6851,7 @@
6836
6851
  * This may result in navigating away to the sign in page.
6837
6852
  * @category Authentication
6838
6853
  * @param loginParams Optional login parameters.
6854
+ * @returns The user profile resource if available.
6839
6855
  */
6840
6856
  async signInWithRedirect(loginParams) {
6841
6857
  const urlParams = new URLSearchParams(window.location.search);
@@ -6872,6 +6888,7 @@
6872
6888
  * Exchange an external access token for a Medplum access token.
6873
6889
  * @param token The access token that was generated by the external identity provider.
6874
6890
  * @param clientId The ID of the `ClientApplication` in your Medplum project that will be making the exchange request.
6891
+ * @returns The user profile resource.
6875
6892
  * @category Authentication
6876
6893
  */
6877
6894
  async exchangeExternalAccessToken(token, clientId) {
@@ -6970,14 +6987,13 @@
6970
6987
  * ```
6971
6988
  *
6972
6989
  * See FHIR search for full details: https://www.hl7.org/fhir/search.html
6973
- *
6974
6990
  * @category Search
6975
6991
  * @param resourceType The FHIR resource type.
6976
6992
  * @param query Optional FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
6977
6993
  * @param options Optional fetch options.
6978
6994
  * @returns Promise to the search result bundle.
6979
6995
  */
6980
- search(resourceType, query, options = {}) {
6996
+ search(resourceType, query, options) {
6981
6997
  const url = this.fhirSearchUrl(resourceType, query);
6982
6998
  const cacheKey = url.toString() + '-search';
6983
6999
  const cached = this.getCacheEntry(cacheKey, options);
@@ -7011,14 +7027,13 @@
7011
7027
  * The return value is the resource, if available; otherwise, undefined.
7012
7028
  *
7013
7029
  * See FHIR search for full details: https://www.hl7.org/fhir/search.html
7014
- *
7015
7030
  * @category Search
7016
7031
  * @param resourceType The FHIR resource type.
7017
7032
  * @param query Optional FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
7018
7033
  * @param options Optional fetch options.
7019
7034
  * @returns Promise to the first search result.
7020
7035
  */
7021
- searchOne(resourceType, query, options = {}) {
7036
+ searchOne(resourceType, query, options) {
7022
7037
  const url = this.fhirSearchUrl(resourceType, query);
7023
7038
  url.searchParams.set('_count', '1');
7024
7039
  url.searchParams.sort();
@@ -7046,14 +7061,13 @@
7046
7061
  * The return value is an array of resources.
7047
7062
  *
7048
7063
  * See FHIR search for full details: https://www.hl7.org/fhir/search.html
7049
- *
7050
7064
  * @category Search
7051
7065
  * @param resourceType The FHIR resource type.
7052
7066
  * @param query Optional FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
7053
7067
  * @param options Optional fetch options.
7054
7068
  * @returns Promise to the array of search results.
7055
7069
  */
7056
- searchResources(resourceType, query, options = {}) {
7070
+ searchResources(resourceType, query, options) {
7057
7071
  const url = this.fhirSearchUrl(resourceType, query);
7058
7072
  const cacheKey = url.toString() + '-searchResources';
7059
7073
  const cached = this.getCacheEntry(cacheKey, options);
@@ -7078,14 +7092,13 @@
7078
7092
  * }
7079
7093
  * }
7080
7094
  * ```
7081
- *
7082
7095
  * @category Search
7083
7096
  * @param resourceType The FHIR resource type.
7084
7097
  * @param query Optional FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
7085
7098
  * @param options Optional fetch options.
7086
- * @returns An async generator, where each result is an array of resources for each page.
7099
+ * @yields An async generator, where each result is an array of resources for each page.
7087
7100
  */
7088
- async *searchResourcePages(resourceType, query, options = {}) {
7101
+ async *searchResourcePages(resourceType, query, options) {
7089
7102
  let url = this.fhirSearchUrl(resourceType, query);
7090
7103
  while (url) {
7091
7104
  const searchParams = new URL(url).searchParams;
@@ -7101,14 +7114,13 @@
7101
7114
  /**
7102
7115
  * Searches a ValueSet resource using the "expand" operation.
7103
7116
  * See: https://www.hl7.org/fhir/operation-valueset-expand.html
7104
- *
7105
7117
  * @category Search
7106
7118
  * @param system The ValueSet system url.
7107
7119
  * @param filter The search string.
7108
7120
  * @param options Optional fetch options.
7109
7121
  * @returns Promise to expanded ValueSet.
7110
7122
  */
7111
- searchValueSet(system, filter, options = {}) {
7123
+ searchValueSet(system, filter, options) {
7112
7124
  const url = this.fhirUrl('ValueSet', '$expand');
7113
7125
  url.searchParams.set('url', system);
7114
7126
  url.searchParams.set('filter', filter);
@@ -7128,8 +7140,7 @@
7128
7140
  /**
7129
7141
  * Returns a cached resource if it is available.
7130
7142
  * @category Caching
7131
- * @param resourceType The FHIR resource type.
7132
- * @param id The FHIR resource ID.
7143
+ * @param reference The FHIR reference.
7133
7144
  * @returns The resource if it is available in the cache; undefined otherwise.
7134
7145
  */
7135
7146
  getCachedReference(reference) {
@@ -7157,14 +7168,13 @@
7157
7168
  * ```
7158
7169
  *
7159
7170
  * See the FHIR "read" operation for full details: https://www.hl7.org/fhir/http.html#read
7160
- *
7161
7171
  * @category Read
7162
7172
  * @param resourceType The FHIR resource type.
7163
7173
  * @param id The resource ID.
7164
7174
  * @param options Optional fetch options.
7165
7175
  * @returns The resource if available; undefined otherwise.
7166
7176
  */
7167
- readResource(resourceType, id, options = {}) {
7177
+ readResource(resourceType, id, options) {
7168
7178
  return this.get(this.fhirUrl(resourceType, id), options);
7169
7179
  }
7170
7180
  /**
@@ -7181,13 +7191,12 @@
7181
7191
  * ```
7182
7192
  *
7183
7193
  * See the FHIR "read" operation for full details: https://www.hl7.org/fhir/http.html#read
7184
- *
7185
7194
  * @category Read
7186
7195
  * @param reference The FHIR reference object.
7187
7196
  * @param options Optional fetch options.
7188
7197
  * @returns The resource if available; undefined otherwise.
7189
7198
  */
7190
- readReference(reference, options = {}) {
7199
+ readReference(reference, options) {
7191
7200
  const refString = reference?.reference;
7192
7201
  if (!refString) {
7193
7202
  return new ReadablePromise(Promise.reject(new Error('Missing reference')));
@@ -7283,14 +7292,13 @@
7283
7292
  * ```
7284
7293
  *
7285
7294
  * See the FHIR "history" operation for full details: https://www.hl7.org/fhir/http.html#history
7286
- *
7287
7295
  * @category Read
7288
7296
  * @param resourceType The FHIR resource type.
7289
7297
  * @param id The resource ID.
7290
7298
  * @param options Optional fetch options.
7291
7299
  * @returns Promise to the resource history.
7292
7300
  */
7293
- readHistory(resourceType, id, options = {}) {
7301
+ readHistory(resourceType, id, options) {
7294
7302
  return this.get(this.fhirUrl(resourceType, id, '_history'), options);
7295
7303
  }
7296
7304
  /**
@@ -7304,7 +7312,6 @@
7304
7312
  * ```
7305
7313
  *
7306
7314
  * See the FHIR "vread" operation for full details: https://www.hl7.org/fhir/http.html#vread
7307
- *
7308
7315
  * @category Read
7309
7316
  * @param resourceType The FHIR resource type.
7310
7317
  * @param id The resource ID.
@@ -7312,7 +7319,7 @@
7312
7319
  * @param options Optional fetch options.
7313
7320
  * @returns The resource if available; undefined otherwise.
7314
7321
  */
7315
- readVersion(resourceType, id, vid, options = {}) {
7322
+ readVersion(resourceType, id, vid, options) {
7316
7323
  return this.get(this.fhirUrl(resourceType, id, '_history', vid), options);
7317
7324
  }
7318
7325
  /**
@@ -7326,13 +7333,12 @@
7326
7333
  * ```
7327
7334
  *
7328
7335
  * See the FHIR "patient-everything" operation for full details: https://hl7.org/fhir/operation-patient-everything.html
7329
- *
7330
7336
  * @category Read
7331
7337
  * @param id The Patient Id
7332
7338
  * @param options Optional fetch options.
7333
7339
  * @returns A Bundle of all Resources related to the Patient
7334
7340
  */
7335
- readPatientEverything(id, options = {}) {
7341
+ readPatientEverything(id, options) {
7336
7342
  return this.get(this.fhirUrl('Patient', id, '$everything'), options);
7337
7343
  }
7338
7344
  /**
@@ -7354,17 +7360,17 @@
7354
7360
  * ```
7355
7361
  *
7356
7362
  * See the FHIR "create" operation for full details: https://www.hl7.org/fhir/http.html#create
7357
- *
7358
7363
  * @category Create
7359
7364
  * @param resource The FHIR resource to create.
7365
+ * @param options Optional fetch options.
7360
7366
  * @returns The result of the create operation.
7361
7367
  */
7362
- createResource(resource) {
7368
+ createResource(resource, options) {
7363
7369
  if (!resource.resourceType) {
7364
7370
  throw new Error('Missing resourceType');
7365
7371
  }
7366
7372
  this.invalidateSearches(resource.resourceType);
7367
- return this.post(this.fhirUrl(resource.resourceType), resource);
7373
+ return this.post(this.fhirUrl(resource.resourceType), resource, undefined, options);
7368
7374
  }
7369
7375
  /**
7370
7376
  * Conditionally create a new FHIR resource only if some equivalent resource does not already exist on the server.
@@ -7400,14 +7406,15 @@
7400
7406
  * The query parameter only contains the search parameters (what would be in the URL following the "?").
7401
7407
  *
7402
7408
  * See the FHIR "conditional create" operation for full details: https://www.hl7.org/fhir/http.html#ccreate
7403
- *
7404
7409
  * @category Create
7405
7410
  * @param resource The FHIR resource to create.
7406
7411
  * @param query The search query for an equivalent resource (should not include resource type or "?").
7412
+ * @param options Optional fetch options.
7407
7413
  * @returns The result of the create operation.
7408
7414
  */
7409
- async createResourceIfNoneExist(resource, query) {
7410
- return ((await this.searchOne(resource.resourceType, query)) ?? this.createResource(resource));
7415
+ async createResourceIfNoneExist(resource, query, options) {
7416
+ return ((await this.searchOne(resource.resourceType, query, options)) ??
7417
+ this.createResource(resource, options));
7411
7418
  }
7412
7419
  /**
7413
7420
  * Creates a FHIR `Binary` resource with the provided data content.
@@ -7426,11 +7433,11 @@
7426
7433
  * ```
7427
7434
  *
7428
7435
  * See the FHIR "create" operation for full details: https://www.hl7.org/fhir/http.html#create
7429
- *
7430
7436
  * @category Create
7431
7437
  * @param data The binary data to upload.
7432
7438
  * @param filename Optional filename for the binary.
7433
7439
  * @param contentType Content type for the binary.
7440
+ * @param onProgress Optional callback for progress events.
7434
7441
  * @returns The result of the create operation.
7435
7442
  */
7436
7443
  createBinary(data, filename, contentType, onProgress) {
@@ -7489,9 +7496,11 @@
7489
7496
  * ```
7490
7497
  *
7491
7498
  * See the pdfmake document definition for full details: https://pdfmake.github.io/docs/0.1/document-definition-object/
7492
- *
7493
7499
  * @category Media
7494
7500
  * @param docDefinition The PDF document definition.
7501
+ * @param filename Optional filename for the PDF binary resource.
7502
+ * @param tableLayouts Optional pdfmake custom table layout.
7503
+ * @param fonts Optional pdfmake custom font dictionary.
7495
7504
  * @returns The result of the create operation.
7496
7505
  */
7497
7506
  async createPdf(docDefinition, filename, tableLayouts, fonts) {
@@ -7505,13 +7514,13 @@
7505
7514
  * Creates a FHIR `Communication` resource with the provided data content.
7506
7515
  *
7507
7516
  * This is a convenience method to handle commmon cases where a `Communication` resource is created with a `payload`.
7508
- *
7509
7517
  * @category Create
7510
7518
  * @param resource The FHIR resource to comment on.
7511
7519
  * @param text The text of the comment.
7520
+ * @param options Optional fetch options.
7512
7521
  * @returns The result of the create operation.
7513
7522
  */
7514
- createComment(resource, text) {
7523
+ createComment(resource, text, options) {
7515
7524
  const profile = this.getProfile();
7516
7525
  let encounter = undefined;
7517
7526
  let subject = undefined;
@@ -7534,7 +7543,7 @@
7534
7543
  sender: profile ? createReference(profile) : undefined,
7535
7544
  sent: new Date().toISOString(),
7536
7545
  payload: [{ contentString: text }],
7537
- });
7546
+ }, options);
7538
7547
  }
7539
7548
  /**
7540
7549
  * Updates a FHIR resource.
@@ -7556,12 +7565,12 @@
7556
7565
  * ```
7557
7566
  *
7558
7567
  * See the FHIR "update" operation for full details: https://www.hl7.org/fhir/http.html#update
7559
- *
7560
7568
  * @category Write
7561
7569
  * @param resource The FHIR resource to update.
7570
+ * @param options Optional fetch options.
7562
7571
  * @returns The result of the update operation.
7563
7572
  */
7564
- async updateResource(resource) {
7573
+ async updateResource(resource, options) {
7565
7574
  if (!resource.resourceType) {
7566
7575
  throw new Error('Missing resourceType');
7567
7576
  }
@@ -7569,7 +7578,7 @@
7569
7578
  throw new Error('Missing id');
7570
7579
  }
7571
7580
  this.invalidateSearches(resource.resourceType);
7572
- let result = await this.put(this.fhirUrl(resource.resourceType, resource.id), resource);
7581
+ let result = await this.put(this.fhirUrl(resource.resourceType, resource.id), resource, undefined, options);
7573
7582
  if (!result) {
7574
7583
  // On 304 not modified, result will be undefined
7575
7584
  // Return the user input instead
@@ -7596,16 +7605,16 @@
7596
7605
  * See the FHIR "update" operation for full details: https://www.hl7.org/fhir/http.html#patch
7597
7606
  *
7598
7607
  * See the JSONPatch specification for full details: https://tools.ietf.org/html/rfc6902
7599
- *
7600
7608
  * @category Write
7601
7609
  * @param resourceType The FHIR resource type.
7602
7610
  * @param id The resource ID.
7603
7611
  * @param operations The JSONPatch operations.
7612
+ * @param options Optional fetch options.
7604
7613
  * @returns The result of the patch operations.
7605
7614
  */
7606
- patchResource(resourceType, id, operations) {
7615
+ patchResource(resourceType, id, operations, options) {
7607
7616
  this.invalidateSearches(resourceType);
7608
- return this.patch(this.fhirUrl(resourceType, id), operations);
7617
+ return this.patch(this.fhirUrl(resourceType, id), operations, options);
7609
7618
  }
7610
7619
  /**
7611
7620
  * Deletes a FHIR resource by resource type and ID.
@@ -7617,16 +7626,16 @@
7617
7626
  * ```
7618
7627
  *
7619
7628
  * See the FHIR "delete" operation for full details: https://www.hl7.org/fhir/http.html#delete
7620
- *
7621
7629
  * @category Delete
7622
7630
  * @param resourceType The FHIR resource type.
7623
7631
  * @param id The resource ID.
7632
+ * @param options Optional fetch options.
7624
7633
  * @returns The result of the delete operation.
7625
7634
  */
7626
- deleteResource(resourceType, id) {
7635
+ deleteResource(resourceType, id, options) {
7627
7636
  this.deleteCacheEntry(this.fhirUrl(resourceType, id).toString());
7628
7637
  this.invalidateSearches(resourceType);
7629
- return this.delete(this.fhirUrl(resourceType, id));
7638
+ return this.delete(this.fhirUrl(resourceType, id), options);
7630
7639
  }
7631
7640
  /**
7632
7641
  * Executes the validate operation with the provided resource.
@@ -7641,12 +7650,12 @@
7641
7650
  * ```
7642
7651
  *
7643
7652
  * See the FHIR "$validate" operation for full details: https://www.hl7.org/fhir/resource-operation-validate.html
7644
- *
7645
7653
  * @param resource The FHIR resource.
7654
+ * @param options Optional fetch options.
7646
7655
  * @returns The validate operation outcome.
7647
7656
  */
7648
- validateResource(resource) {
7649
- return this.post(this.fhirUrl(resource.resourceType, '$validate'), resource);
7657
+ validateResource(resource, options) {
7658
+ return this.post(this.fhirUrl(resource.resourceType, '$validate'), resource, undefined, options);
7650
7659
  }
7651
7660
  /**
7652
7661
  * Executes a bot by ID or Identifier.
@@ -7656,7 +7665,7 @@
7656
7665
  * @param options Optional fetch options.
7657
7666
  * @returns The Bot return value.
7658
7667
  */
7659
- executeBot(idOrIdentifier, body, contentType, options = {}) {
7668
+ executeBot(idOrIdentifier, body, contentType, options) {
7660
7669
  let url;
7661
7670
  if (typeof idOrIdentifier === 'string') {
7662
7671
  const id = idOrIdentifier;
@@ -7716,7 +7725,7 @@
7716
7725
  * @param options Optional fetch options.
7717
7726
  * @returns The FHIR batch/transaction response bundle.
7718
7727
  */
7719
- executeBatch(bundle, options = {}) {
7728
+ executeBatch(bundle, options) {
7720
7729
  return this.post(this.fhirBaseUrl.slice(0, -1), bundle, undefined, options);
7721
7730
  }
7722
7731
  /**
@@ -7753,11 +7762,12 @@
7753
7762
  *
7754
7763
  * See options here: https://nodemailer.com/extras/mailcomposer/
7755
7764
  * @category Media
7756
- * @param options The MailComposer options.
7765
+ * @param email The MailComposer options.
7766
+ * @param options Optional fetch options.
7757
7767
  * @returns Promise to the operation outcome.
7758
7768
  */
7759
- sendEmail(email) {
7760
- return this.post('email/v1/send', email, 'application/json');
7769
+ sendEmail(email, options) {
7770
+ return this.post('email/v1/send', email, 'application/json', options);
7761
7771
  }
7762
7772
  /**
7763
7773
  * Executes a GraphQL query.
@@ -7799,7 +7809,6 @@
7799
7809
  * See the GraphQL documentation for more details: https://graphql.org/learn/
7800
7810
  *
7801
7811
  * See the FHIR GraphQL documentation for FHIR specific details: https://www.hl7.org/fhir/graphql.html
7802
- *
7803
7812
  * @category Read
7804
7813
  * @param query The GraphQL query.
7805
7814
  * @param operationName Optional GraphQL operation name.
@@ -7814,15 +7823,15 @@
7814
7823
  *
7815
7824
  * Executes the $graph operation on this resource to fetch a Bundle of resources linked to the target resource
7816
7825
  * according to a graph definition
7817
-
7818
7826
  * @category Read
7819
7827
  * @param resourceType The FHIR resource type.
7820
7828
  * @param id The resource ID.
7821
7829
  * @param graphName `name` parameter of the GraphDefinition
7830
+ * @param options Optional fetch options.
7822
7831
  * @returns A Bundle
7823
7832
  */
7824
- readResourceGraph(resourceType, id, graphName) {
7825
- return this.get(`${this.fhirUrl(resourceType, id)}/$graph?graph=${graphName}`);
7833
+ readResourceGraph(resourceType, id, graphName, options) {
7834
+ return this.get(`${this.fhirUrl(resourceType, id)}/$graph?graph=${graphName}`, options);
7826
7835
  }
7827
7836
  /**
7828
7837
  * @category Authentication
@@ -7832,11 +7841,16 @@
7832
7841
  return this.storage.getObject('activeLogin');
7833
7842
  }
7834
7843
  /**
7844
+ * Sets the active login.
7845
+ * @param login The new active login state.
7835
7846
  * @category Authentication
7836
7847
  */
7837
7848
  async setActiveLogin(login) {
7838
7849
  this.clearActiveLogin();
7839
7850
  this.accessToken = login.accessToken;
7851
+ if (this.basicAuth) {
7852
+ return;
7853
+ }
7840
7854
  this.refreshToken = login.refreshToken;
7841
7855
  this.storage.setObject('activeLogin', login);
7842
7856
  this.addLogin(login);
@@ -7845,6 +7859,7 @@
7845
7859
  }
7846
7860
  /**
7847
7861
  * Returns the current access token.
7862
+ * @returns The current access token.
7848
7863
  * @category Authentication
7849
7864
  */
7850
7865
  getAccessToken() {
@@ -7852,6 +7867,7 @@
7852
7867
  }
7853
7868
  /**
7854
7869
  * Sets the current access token.
7870
+ * @param accessToken The new access token.
7855
7871
  * @category Authentication
7856
7872
  */
7857
7873
  setAccessToken(accessToken) {
@@ -7861,6 +7877,8 @@
7861
7877
  this.config = undefined;
7862
7878
  }
7863
7879
  /**
7880
+ * Returns the list of available logins.
7881
+ * @returns The list of available logins.
7864
7882
  * @category Authentication
7865
7883
  */
7866
7884
  getLogins() {
@@ -7873,6 +7891,9 @@
7873
7891
  }
7874
7892
  async refreshProfile() {
7875
7893
  this.profilePromise = new Promise((resolve, reject) => {
7894
+ if (this.basicAuth) {
7895
+ return;
7896
+ }
7876
7897
  this.get('auth/me')
7877
7898
  .then((result) => {
7878
7899
  this.profilePromise = undefined;
@@ -7886,18 +7907,26 @@
7886
7907
  return this.profilePromise;
7887
7908
  }
7888
7909
  /**
7910
+ * Returns true if the client is waiting for authentication.
7911
+ * @returns True if the client is waiting for authentication.
7889
7912
  * @category Authentication
7890
7913
  */
7891
7914
  isLoading() {
7892
7915
  return !!this.profilePromise;
7893
7916
  }
7894
7917
  /**
7918
+ * Returns the current user profile resource if available.
7919
+ * This method does not wait for loading promises.
7920
+ * @returns The current user profile resource if available.
7895
7921
  * @category User Profile
7896
7922
  */
7897
7923
  getProfile() {
7898
7924
  return this.profile;
7899
7925
  }
7900
7926
  /**
7927
+ * Returns the current user profile resource if available.
7928
+ * This method waits for loading promises.
7929
+ * @returns The current user profile resource if available.
7901
7930
  * @category User Profile
7902
7931
  */
7903
7932
  async getProfileAsync() {
@@ -7907,6 +7936,8 @@
7907
7936
  return this.getProfile();
7908
7937
  }
7909
7938
  /**
7939
+ * Returns the current user configuration if available.
7940
+ * @returns The current user configuration if available.
7910
7941
  * @category User Profile
7911
7942
  */
7912
7943
  getUserConfiguration() {
@@ -7914,9 +7945,9 @@
7914
7945
  }
7915
7946
  /**
7916
7947
  * Downloads the URL as a blob.
7917
- *
7918
7948
  * @category Read
7919
7949
  * @param url The URL to request.
7950
+ * @param options Optional fetch request init options.
7920
7951
  * @returns Promise to the response body as a blob.
7921
7952
  */
7922
7953
  async download(url, options = {}) {
@@ -7930,12 +7961,13 @@
7930
7961
  /**
7931
7962
  * Upload media to the server and create a Media instance for the uploaded content.
7932
7963
  * @param contents The contents of the media file, as a string, Uint8Array, File, or Blob.
7933
- * @param contentType The media type of the content
7934
- * @param filename The name of the file to be uploaded, or undefined if not applicable
7935
- * @param additionalFields Additional fields for Media
7964
+ * @param contentType The media type of the content.
7965
+ * @param filename The name of the file to be uploaded, or undefined if not applicable.
7966
+ * @param additionalFields Additional fields for Media.
7967
+ * @param options Optional fetch options.
7936
7968
  * @returns Promise that resolves to the created Media
7937
7969
  */
7938
- async uploadMedia(contents, contentType, filename, additionalFields) {
7970
+ async uploadMedia(contents, contentType, filename, additionalFields, options) {
7939
7971
  const binary = await this.createBinary(contents, filename, contentType);
7940
7972
  return this.createResource({
7941
7973
  ...additionalFields,
@@ -7945,11 +7977,10 @@
7945
7977
  url: 'Binary/' + binary.id,
7946
7978
  title: filename,
7947
7979
  },
7948
- });
7980
+ }, options);
7949
7981
  }
7950
7982
  /**
7951
7983
  * Performs Bulk Data Export operation request flow. See The FHIR "Bulk Data Export" for full details: https://build.fhir.org/ig/HL7/bulk-data/export.html#bulk-data-export
7952
- *
7953
7984
  * @param exportLevel Optional export level. Defaults to system level export. 'Group/:id' - Group of Patients, 'Patient' - All Patients.
7954
7985
  * @param resourceTypes A string of comma-delimited FHIR resource types.
7955
7986
  * @param since Resources will be included in the response if their state has changed after the supplied time (e.g. if Resource.meta.lastUpdated is later than the supplied _since time).
@@ -7965,7 +7996,6 @@
7965
7996
  if (since) {
7966
7997
  url.searchParams.set('_since', since);
7967
7998
  }
7968
- options.method = exportLevel ? 'GET' : 'POST';
7969
7999
  this.addFetchOptionsDefaults(options);
7970
8000
  const headers = options.headers;
7971
8001
  headers['Prefer'] = 'respond-async';
@@ -8029,10 +8059,10 @@
8029
8059
  }
8030
8060
  /**
8031
8061
  * Makes an HTTP request.
8032
- * @param {string} method
8033
- * @param {string} url
8034
- * @param {string=} contentType
8035
- * @param {Object=} body
8062
+ * @param method The HTTP method (GET, POST, etc).
8063
+ * @param url The target URL.
8064
+ * @param options Optional fetch request init options.
8065
+ * @returns The JSON content body if available.
8036
8066
  */
8037
8067
  async request(method, url, options = {}) {
8038
8068
  if (this.refreshPromise) {
@@ -8097,9 +8127,7 @@
8097
8127
  let resultResponse;
8098
8128
  const retryDelay = 200;
8099
8129
  while (checkStatus) {
8100
- const fetchOptions = {
8101
- method: 'GET',
8102
- };
8130
+ const fetchOptions = {};
8103
8131
  this.addFetchOptionsDefaults(fetchOptions);
8104
8132
  const statusResponse = await this.fetchWithRetry(statusUrl, fetchOptions);
8105
8133
  if (statusResponse.status !== 202) {
@@ -8175,7 +8203,7 @@
8175
8203
  if (this.accessToken) {
8176
8204
  headers['Authorization'] = 'Bearer ' + this.accessToken;
8177
8205
  }
8178
- if (this.basicAuth) {
8206
+ else if (this.basicAuth) {
8179
8207
  headers['Authorization'] = 'Basic ' + this.basicAuth;
8180
8208
  }
8181
8209
  if (!options.cache) {
@@ -8219,8 +8247,8 @@
8219
8247
  * Otherwise, calls unauthenticated callbacks and rejects.
8220
8248
  * @param method The HTTP method of the original request.
8221
8249
  * @param url The URL of the original request.
8222
- * @param contentType The content type of the original request.
8223
- * @param body The body of the original request.
8250
+ * @param options Optional fetch request init options.
8251
+ * @returns The result of the retry.
8224
8252
  */
8225
8253
  handleUnauthenticated(method, url, options) {
8226
8254
  if (this.refresh()) {
@@ -8236,6 +8264,7 @@
8236
8264
  * Starts a new PKCE flow.
8237
8265
  * These PKCE values are stateful, and must survive redirects and page refreshes.
8238
8266
  * @category Authentication
8267
+ * @returns The PKCE code challenge details.
8239
8268
  */
8240
8269
  async startPkce() {
8241
8270
  const pkceState = getRandomString();
@@ -8250,7 +8279,8 @@
8250
8279
  /**
8251
8280
  * Redirects the user to the login screen for authorization.
8252
8281
  * Clears all auth state including local storage and session storage.
8253
- * See: https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
8282
+ * @param loginParams The authorization login parameters.
8283
+ * @see https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
8254
8284
  */
8255
8285
  async requestAuthorization(loginParams) {
8256
8286
  const loginRequest = await this.ensureCodeChallenge(loginParams || {});
@@ -8269,6 +8299,7 @@
8269
8299
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
8270
8300
  * @param code The authorization code received by URL parameter.
8271
8301
  * @param loginParams Optional login parameters.
8302
+ * @returns The user profile resource.
8272
8303
  * @category Authentication
8273
8304
  */
8274
8305
  processCode(code, loginParams) {
@@ -8287,7 +8318,8 @@
8287
8318
  }
8288
8319
  /**
8289
8320
  * Tries to refresh the auth tokens.
8290
- * See: https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens
8321
+ * @returns The refresh promise if available; otherwise undefined.
8322
+ * @see https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens
8291
8323
  */
8292
8324
  refresh() {
8293
8325
  if (this.refreshPromise) {
@@ -8340,7 +8372,6 @@
8340
8372
  * // Example Search
8341
8373
  * await medplum.searchResources('Patient')
8342
8374
  * ```
8343
- *
8344
8375
  * @category Authentication
8345
8376
  * @param clientId The client ID.
8346
8377
  * @param clientSecret The client secret.
@@ -8363,14 +8394,20 @@
8363
8394
  * Makes a POST request to the tokens endpoint.
8364
8395
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8365
8396
  * @param formBody Token parameters in URL encoded format.
8397
+ * @returns The user profile resource.
8366
8398
  */
8367
8399
  async fetchTokens(formBody) {
8368
- const response = await this.fetch(this.tokenUrl, {
8400
+ const options = {
8369
8401
  method: 'POST',
8370
8402
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
8371
8403
  body: formBody,
8372
8404
  credentials: 'include',
8373
- });
8405
+ };
8406
+ const headers = options.headers;
8407
+ if (this.basicAuth) {
8408
+ headers['Authorization'] = `Basic ${this.basicAuth}`;
8409
+ }
8410
+ const response = await this.fetch(this.tokenUrl, options);
8374
8411
  if (!response.ok) {
8375
8412
  this.clearActiveLogin();
8376
8413
  throw new Error('Failed to fetch tokens');
@@ -8383,7 +8420,8 @@
8383
8420
  * Verifies the tokens received from the auth server.
8384
8421
  * Validates the JWT against the JWKS.
8385
8422
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8386
- * @param tokens
8423
+ * @param tokens The token response.
8424
+ * @returns Promise to complete.
8387
8425
  */
8388
8426
  async verifyTokens(tokens) {
8389
8427
  const token = tokens.access_token;
@@ -8394,7 +8432,14 @@
8394
8432
  throw new Error('Token expired');
8395
8433
  }
8396
8434
  // Verify app_client_id
8397
- if (this.clientId && tokenPayload.client_id !== this.clientId) {
8435
+ // external tokenPayload
8436
+ if (tokenPayload.cid) {
8437
+ if (tokenPayload.cid !== this.clientId) {
8438
+ this.clearActiveLogin();
8439
+ throw new Error('Token was not issued for this audience');
8440
+ }
8441
+ }
8442
+ else if (this.clientId && tokenPayload.client_id !== this.clientId) {
8398
8443
  this.clearActiveLogin();
8399
8444
  throw new Error('Token was not issued for this audience');
8400
8445
  }
@@ -8448,6 +8493,7 @@
8448
8493
  }
8449
8494
  /**
8450
8495
  * Returns the base URL for the current page.
8496
+ * @returns The window origin string.
8451
8497
  * @category HTTP
8452
8498
  */
8453
8499
  function getWindowOrigin() {
@@ -9209,6 +9255,7 @@
9209
9255
 
9210
9256
  /**
9211
9257
  * Temporary placholder for unimplemented methods.
9258
+ * @returns Empty array.
9212
9259
  */
9213
9260
  const stub = () => [];
9214
9261
  const functions = {
@@ -9220,7 +9267,6 @@
9220
9267
  * Returns true if the input collection is empty ({ }) and false otherwise.
9221
9268
  *
9222
9269
  * See: https://hl7.org/fhirpath/#empty-boolean
9223
- *
9224
9270
  * @param input The input collection.
9225
9271
  * @returns True if the input collection is empty ({ }) and false otherwise.
9226
9272
  */
@@ -9237,9 +9283,8 @@
9237
9283
  * for where(criteria).exists().
9238
9284
  *
9239
9285
  * See: https://hl7.org/fhirpath/#existscriteria-expression-boolean
9240
- *
9241
- * @param input
9242
- * @param criteria
9286
+ * @param input The input collection.
9287
+ * @param criteria Optional criteria applied to the collection.
9243
9288
  * @returns True if the collection has unknown elements, and false otherwise.
9244
9289
  */
9245
9290
  exists: (input, criteria) => {
@@ -9257,7 +9302,6 @@
9257
9302
  * If the input collection is empty ({ }), the result is true.
9258
9303
  *
9259
9304
  * See: https://hl7.org/fhirpath/#allcriteria-expression-boolean
9260
- *
9261
9305
  * @param input The input collection.
9262
9306
  * @param criteria The evaluation criteria.
9263
9307
  * @returns True if for every element in the input collection, criteria evaluates to true.
@@ -9271,9 +9315,7 @@
9271
9315
  * If the input is empty ({ }), the result is true.
9272
9316
  *
9273
9317
  * See: https://hl7.org/fhirpath/#alltrue-boolean
9274
- *
9275
9318
  * @param input The input collection.
9276
- * @param criteria The evaluation criteria.
9277
9319
  * @returns True if all the items are true.
9278
9320
  */
9279
9321
  allTrue: (input) => {
@@ -9289,9 +9331,7 @@
9289
9331
  * If all the items are false, or if the input is empty ({ }), the result is false.
9290
9332
  *
9291
9333
  * See: https://hl7.org/fhirpath/#anytrue-boolean
9292
- *
9293
9334
  * @param input The input collection.
9294
- * @param criteria The evaluation criteria.
9295
9335
  * @returns True if unknown of the items are true.
9296
9336
  */
9297
9337
  anyTrue: (input) => {
@@ -9308,9 +9348,7 @@
9308
9348
  * If the input is empty ({ }), the result is true.
9309
9349
  *
9310
9350
  * See: https://hl7.org/fhirpath/#allfalse-boolean
9311
- *
9312
9351
  * @param input The input collection.
9313
- * @param criteria The evaluation criteria.
9314
9352
  * @returns True if all the items are false.
9315
9353
  */
9316
9354
  allFalse: (input) => {
@@ -9326,9 +9364,7 @@
9326
9364
  * If all the items are true, or if the input is empty ({ }), the result is false.
9327
9365
  *
9328
9366
  * See: https://hl7.org/fhirpath/#anyfalse-boolean
9329
- *
9330
9367
  * @param input The input collection.
9331
- * @param criteria The evaluation criteria.
9332
9368
  * @returns True if for every element in the input collection, criteria evaluates to true.
9333
9369
  */
9334
9370
  anyFalse: (input) => {
@@ -9368,7 +9404,6 @@
9368
9404
  * Returns 0 when the input collection is empty.
9369
9405
  *
9370
9406
  * See: https://hl7.org/fhirpath/#count-integer
9371
- *
9372
9407
  * @param input The input collection.
9373
9408
  * @returns The integer count of the number of items in the input collection.
9374
9409
  */
@@ -9386,7 +9421,6 @@
9386
9421
  * preserved in the result.
9387
9422
  *
9388
9423
  * See: https://hl7.org/fhirpath/#distinct-collection
9389
- *
9390
9424
  * @param input The input collection.
9391
9425
  * @returns The integer count of the number of items in the input collection.
9392
9426
  */
@@ -9405,7 +9439,6 @@
9405
9439
  * as defined below.
9406
9440
  *
9407
9441
  * See: https://hl7.org/fhirpath/#isdistinct-boolean
9408
- *
9409
9442
  * @param input The input collection.
9410
9443
  * @returns The integer count of the number of items in the input collection.
9411
9444
  */
@@ -9428,9 +9461,8 @@
9428
9461
  * consistent with singleton evaluation of collections behavior.
9429
9462
  *
9430
9463
  * See: https://hl7.org/fhirpath/#wherecriteria-expression-collection
9431
- *
9432
9464
  * @param input The input collection.
9433
- * @param condition The condition atom.
9465
+ * @param criteria The condition atom.
9434
9466
  * @returns A collection containing only those elements in the input collection for which the stated criteria expression evaluates to true.
9435
9467
  */
9436
9468
  where: (input, criteria) => {
@@ -9446,6 +9478,9 @@
9446
9478
  * the input collection is empty ({ }), the result is empty as well.
9447
9479
  *
9448
9480
  * See: http://hl7.org/fhirpath/#selectprojection-expression-collection
9481
+ * @param input The input collection.
9482
+ * @param criteria The condition atom.
9483
+ * @returns A collection containing only those elements in the input collection for which the stated criteria expression evaluates to true.
9449
9484
  */
9450
9485
  select: (input, criteria) => {
9451
9486
  return input.map((e) => criteria.eval([e])).flat();
@@ -9465,6 +9500,9 @@
9465
9500
  * must resolve to the name of a type in a model
9466
9501
  *
9467
9502
  * See: http://hl7.org/fhirpath/#oftypetype-type-specifier-collection
9503
+ * @param input The input collection.
9504
+ * @param criteria The condition atom.
9505
+ * @returns A collection containing only those elements in the input collection that are of the given type or a subclass thereof.
9468
9506
  */
9469
9507
  ofType: (input, criteria) => {
9470
9508
  return input.filter((e) => e.type === criteria.name);
@@ -9480,7 +9518,6 @@
9480
9518
  * about cardinality is violated at run-time.
9481
9519
  *
9482
9520
  * See: https://hl7.org/fhirpath/#single-collection
9483
- *
9484
9521
  * @param input The input collection.
9485
9522
  * @returns The single item in the input if there is just one item.
9486
9523
  */
@@ -9495,7 +9532,6 @@
9495
9532
  * This function is equivalent to item[0], so it will return an empty collection if the input collection has no items.
9496
9533
  *
9497
9534
  * See: https://hl7.org/fhirpath/#first-collection
9498
- *
9499
9535
  * @param input The input collection.
9500
9536
  * @returns A collection containing only the first item in the input collection.
9501
9537
  */
@@ -9507,7 +9543,6 @@
9507
9543
  * Will return an empty collection if the input collection has no items.
9508
9544
  *
9509
9545
  * See: https://hl7.org/fhirpath/#last-collection
9510
- *
9511
9546
  * @param input The input collection.
9512
9547
  * @returns A collection containing only the last item in the input collection.
9513
9548
  */
@@ -9519,7 +9554,6 @@
9519
9554
  * Will return an empty collection if the input collection has no items, or only one item.
9520
9555
  *
9521
9556
  * See: https://hl7.org/fhirpath/#tail-collection
9522
- *
9523
9557
  * @param input The input collection.
9524
9558
  * @returns A collection containing all but the first item in the input collection.
9525
9559
  */
@@ -9533,8 +9567,8 @@
9533
9567
  * If num is less than or equal to zero, the input collection is simply returned.
9534
9568
  *
9535
9569
  * See: https://hl7.org/fhirpath/#skipnum-integer-collection
9536
- *
9537
9570
  * @param input The input collection.
9571
+ * @param num The atom representing the number of elements to skip.
9538
9572
  * @returns A collection containing all but the first item in the input collection.
9539
9573
  */
9540
9574
  skip: (input, num) => {
@@ -9557,8 +9591,8 @@
9557
9591
  * take returns an empty collection.
9558
9592
  *
9559
9593
  * See: https://hl7.org/fhirpath/#takenum-integer-collection
9560
- *
9561
9594
  * @param input The input collection.
9595
+ * @param num The atom representing the number of elements to take.
9562
9596
  * @returns A collection containing the first num items in the input collection.
9563
9597
  */
9564
9598
  take: (input, num) => {
@@ -9580,6 +9614,9 @@
9580
9614
  * Order of items is not guaranteed to be preserved in the result of this function.
9581
9615
  *
9582
9616
  * See: http://hl7.org/fhirpath/#intersectother-collection-collection
9617
+ * @param input The input collection.
9618
+ * @param other The atom representing the collection of elements to intersect.
9619
+ * @returns A collection containing the elements that are in both collections.
9583
9620
  */
9584
9621
  intersect: (input, other) => {
9585
9622
  if (!other) {
@@ -9601,6 +9638,9 @@
9601
9638
  * e.g. (1 | 2 | 3).exclude(2) returns (1 | 3).
9602
9639
  *
9603
9640
  * See: http://hl7.org/fhirpath/#excludeother-collection-collection
9641
+ * @param input The input collection.
9642
+ * @param other The atom representing the collection of elements to exclude.
9643
+ * @returns A collection containing the elements that are in the input collection but not the other collection.
9604
9644
  */
9605
9645
  exclude: (input, other) => {
9606
9646
  if (!other) {
@@ -9628,6 +9668,9 @@
9628
9668
  * In other words, this function returns the distinct list of elements from both inputs.
9629
9669
  *
9630
9670
  * See: http://hl7.org/fhirpath/#unionother-collection
9671
+ * @param input The input collection.
9672
+ * @param other The atom representing the collection of elements to merge.
9673
+ * @returns A collection containing the elements that represent the union of both collections.
9631
9674
  */
9632
9675
  union: (input, other) => {
9633
9676
  if (!other) {
@@ -9644,6 +9687,9 @@
9644
9687
  * There is no expectation of order in the resulting collection.
9645
9688
  *
9646
9689
  * See: http://hl7.org/fhirpath/#combineother-collection-collection
9690
+ * @param input The input collection.
9691
+ * @param other The atom representing the collection of elements to merge.
9692
+ * @returns A collection containing the elements that represent the combination of both collections including duplicates.
9647
9693
  */
9648
9694
  combine: (input, other) => {
9649
9695
  if (!other) {
@@ -9672,12 +9718,11 @@
9672
9718
  * true-result should only be evaluated if the criterion evaluates to true,
9673
9719
  * and otherwise-result should only be evaluated otherwise. For implementations,
9674
9720
  * this means delaying evaluation of the arguments.
9675
- *
9676
- * @param input
9677
- * @param criterion
9678
- * @param trueResult
9679
- * @param otherwiseResult
9680
- * @returns
9721
+ * @param input The input collection.
9722
+ * @param criterion The atom representing the conditional.
9723
+ * @param trueResult The atom to be used if the conditional evaluates to true.
9724
+ * @param otherwiseResult Optional atom to be used if the conditional evaluates to false.
9725
+ * @returns The result of the iif function.
9681
9726
  */
9682
9727
  iif: (input, criterion, trueResult, otherwiseResult) => {
9683
9728
  const evalResult = criterion.eval(input);
@@ -9704,9 +9749,8 @@
9704
9749
  * 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.
9705
9750
  *
9706
9751
  * See: https://hl7.org/fhirpath/#toboolean-boolean
9707
- *
9708
- * @param input
9709
- * @returns
9752
+ * @param input The input collection.
9753
+ * @returns The input converted to boolean value.
9710
9754
  */
9711
9755
  toBoolean: (input) => {
9712
9756
  if (input.length === 0) {
@@ -9748,9 +9792,8 @@
9748
9792
  * If the input collection is empty, the result is empty.
9749
9793
  *
9750
9794
  * See: http://hl7.org/fhirpath/#convertstoboolean-boolean
9751
- *
9752
- * @param input
9753
- * @returns
9795
+ * @param input The input collection.
9796
+ * @returns True if the input can be converted to boolean.
9754
9797
  */
9755
9798
  convertsToBoolean: (input) => {
9756
9799
  if (input.length === 0) {
@@ -9775,7 +9818,6 @@
9775
9818
  * If the input collection is empty, the result is empty.
9776
9819
  *
9777
9820
  * See: https://hl7.org/fhirpath/#tointeger-integer
9778
- *
9779
9821
  * @param input The input collection.
9780
9822
  * @returns The string representation of the input.
9781
9823
  */
@@ -9809,9 +9851,8 @@
9809
9851
  * If the input collection is empty, the result is empty.
9810
9852
  *
9811
9853
  * See: https://hl7.org/fhirpath/#convertstointeger-boolean
9812
- *
9813
9854
  * @param input The input collection.
9814
- * @returns
9855
+ * @returns True if the input can be converted to an integer.
9815
9856
  */
9816
9857
  convertsToInteger: (input) => {
9817
9858
  if (input.length === 0) {
@@ -9834,6 +9875,8 @@
9834
9875
  * If the input collection is empty, the result is empty.
9835
9876
  *
9836
9877
  * See: https://hl7.org/fhirpath/#todate-date
9878
+ * @param input The input collection.
9879
+ * @returns The value converted to a date if possible; otherwise empty array.
9837
9880
  */
9838
9881
  toDate: (input) => {
9839
9882
  if (input.length === 0) {
@@ -9860,6 +9903,8 @@
9860
9903
  * If the input collection is empty, the result is empty.
9861
9904
  *
9862
9905
  * See: https://hl7.org/fhirpath/#convertstodate-boolean
9906
+ * @param input The input collection.
9907
+ * @returns True if the item can be converted to a date.
9863
9908
  */
9864
9909
  convertsToDate: (input) => {
9865
9910
  if (input.length === 0) {
@@ -9868,26 +9913,25 @@
9868
9913
  return booleanToTypedValue(functions.toDate(input).length === 1);
9869
9914
  },
9870
9915
  /**
9871
- * If the input collection contains a single item, this function will return a single datetime if:
9872
- * 1) the item is a DateTime
9873
- * 2) the item is a Date, in which case the result is a DateTime with the year, month, and day of the Date, and the time components empty (not set to zero)
9874
- * 3) the item is a String and is convertible to a DateTime
9875
- *
9876
- * If the item is not one of the above types, the result is empty.
9877
- *
9878
- * If the item is a String, but the string is not convertible to a DateTime (using the format YYYY-MM-DDThh:mm:ss.fff(+|-)hh:mm), the result is empty.
9879
- *
9880
- * If the item contains a partial datetime (e.g. '2012-01-01T10:00'), the result is a partial datetime.
9881
- *
9882
- * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
9883
- *
9884
- * If the input collection is empty, the result is empty.
9885
-
9886
- * See: https://hl7.org/fhirpath/#todatetime-datetime
9887
- *
9888
- * @param input
9889
- * @returns
9890
- */
9916
+ * If the input collection contains a single item, this function will return a single datetime if:
9917
+ * 1) the item is a DateTime
9918
+ * 2) the item is a Date, in which case the result is a DateTime with the year, month, and day of the Date, and the time components empty (not set to zero)
9919
+ * 3) the item is a String and is convertible to a DateTime
9920
+ *
9921
+ * If the item is not one of the above types, the result is empty.
9922
+ *
9923
+ * If the item is a String, but the string is not convertible to a DateTime (using the format YYYY-MM-DDThh:mm:ss.fff(+|-)hh:mm), the result is empty.
9924
+ *
9925
+ * If the item contains a partial datetime (e.g. '2012-01-01T10:00'), the result is a partial datetime.
9926
+ *
9927
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
9928
+ *
9929
+ * If the input collection is empty, the result is empty.
9930
+ *
9931
+ * See: https://hl7.org/fhirpath/#todatetime-datetime
9932
+ * @param input The input collection.
9933
+ * @returns The value converted to a dateTime if possible; otherwise empty array.
9934
+ */
9891
9935
  toDateTime: (input) => {
9892
9936
  if (input.length === 0) {
9893
9937
  return [];
@@ -9911,9 +9955,8 @@
9911
9955
  * If the input collection is empty, the result is empty.
9912
9956
  *
9913
9957
  * See: https://hl7.org/fhirpath/#convertstodatetime-boolean
9914
- *
9915
- * @param input
9916
- * @returns
9958
+ * @param input The input collection.
9959
+ * @returns True if the item can be converted to a dateTime.
9917
9960
  */
9918
9961
  convertsToDateTime: (input) => {
9919
9962
  if (input.length === 0) {
@@ -9935,9 +9978,8 @@
9935
9978
  * If the input collection is empty, the result is empty.
9936
9979
  *
9937
9980
  * See: https://hl7.org/fhirpath/#decimal-conversion-functions
9938
- *
9939
9981
  * @param input The input collection.
9940
- * @returns
9982
+ * @returns The value converted to a decimal if possible; otherwise empty array.
9941
9983
  */
9942
9984
  toDecimal: (input) => {
9943
9985
  if (input.length === 0) {
@@ -9956,22 +9998,21 @@
9956
9998
  return [];
9957
9999
  },
9958
10000
  /**
9959
- * If the input collection contains a single item, this function will true if:
9960
- * 1) the item is an Integer or Decimal
9961
- * 2) the item is a String and is convertible to a Decimal
9962
- * 3) the item is a Boolean
9963
- *
9964
- * If the item is not one of the above types, or is not convertible to a Decimal (using the regex format (\\+|-)?\d+(\.\d+)?), the result is false.
9965
- *
9966
- * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
9967
- *
9968
- * If the input collection is empty, the result is empty.
9969
-
9970
- * See: https://hl7.org/fhirpath/#convertstodecimal-boolean
9971
- *
9972
- * @param input The input collection.
9973
- * @returns
9974
- */
10001
+ * If the input collection contains a single item, this function will true if:
10002
+ * 1) the item is an Integer or Decimal
10003
+ * 2) the item is a String and is convertible to a Decimal
10004
+ * 3) the item is a Boolean
10005
+ *
10006
+ * If the item is not one of the above types, or is not convertible to a Decimal (using the regex format (\\+|-)?\d+(\.\d+)?), the result is false.
10007
+ *
10008
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10009
+ *
10010
+ * If the input collection is empty, the result is empty.
10011
+ *
10012
+ * See: https://hl7.org/fhirpath/#convertstodecimal-boolean
10013
+ * @param input The input collection.
10014
+ * @returns True if the item can be converted to a decimal.
10015
+ */
9975
10016
  convertsToDecimal: (input) => {
9976
10017
  if (input.length === 0) {
9977
10018
  return [];
@@ -9988,9 +10029,8 @@
9988
10029
  * If the item is not one of the above types, the result is empty.
9989
10030
  *
9990
10031
  * See: https://hl7.org/fhirpath/#quantity-conversion-functions
9991
- *
9992
10032
  * @param input The input collection.
9993
- * @returns
10033
+ * @returns The value converted to a quantity if possible; otherwise empty array.
9994
10034
  */
9995
10035
  toQuantity: (input) => {
9996
10036
  if (input.length === 0) {
@@ -10030,9 +10070,8 @@
10030
10070
  * 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.
10031
10071
  *
10032
10072
  * See: https://hl7.org/fhirpath/#convertstoquantityunit-string-boolean
10033
- *
10034
10073
  * @param input The input collection.
10035
- * @returns
10074
+ * @returns True if the item can be converted to a quantity.
10036
10075
  */
10037
10076
  convertsToQuantity: (input) => {
10038
10077
  if (input.length === 0) {
@@ -10052,7 +10091,6 @@
10052
10091
  * If the item is not one of the above types, the result is false.
10053
10092
  *
10054
10093
  * See: https://hl7.org/fhirpath/#tostring-string
10055
- *
10056
10094
  * @param input The input collection.
10057
10095
  * @returns The string representation of the input.
10058
10096
  */
@@ -10085,9 +10123,8 @@
10085
10123
  * If the input collection is empty, the result is empty.
10086
10124
  *
10087
10125
  * See: https://hl7.org/fhirpath/#tostring-string
10088
- *
10089
10126
  * @param input The input collection.
10090
- * @returns
10127
+ * @returns True if the item can be converted to a string
10091
10128
  */
10092
10129
  convertsToString: (input) => {
10093
10130
  if (input.length === 0) {
@@ -10111,9 +10148,8 @@
10111
10148
  * If the input collection is empty, the result is empty.
10112
10149
  *
10113
10150
  * See: https://hl7.org/fhirpath/#totime-time
10114
- *
10115
- * @param input
10116
- * @returns
10151
+ * @param input The input collection.
10152
+ * @returns The value converted to a time if possible; otherwise empty array.
10117
10153
  */
10118
10154
  toTime: (input) => {
10119
10155
  if (input.length === 0) {
@@ -10140,9 +10176,8 @@
10140
10176
  * If the input collection is empty, the result is empty.
10141
10177
  *
10142
10178
  * See: https://hl7.org/fhirpath/#convertstotime-boolean
10143
- *
10144
- * @param input
10145
- * @returns
10179
+ * @param input The input collection.
10180
+ * @returns True if the item can be converted to a time.
10146
10181
  */
10147
10182
  convertsToTime: (input) => {
10148
10183
  if (input.length === 0) {
@@ -10165,12 +10200,12 @@
10165
10200
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10166
10201
  *
10167
10202
  * See: https://hl7.org/fhirpath/#indexofsubstring-string-integer
10168
- *
10169
10203
  * @param input The input collection.
10204
+ * @param searchStringAtom The substring to search for.
10170
10205
  * @returns The index of the substring.
10171
10206
  */
10172
- indexOf: (input, substringAtom) => {
10173
- return applyStringFunc((str, substring) => str.indexOf(substring), input, substringAtom);
10207
+ indexOf: (input, searchStringAtom) => {
10208
+ return applyStringFunc((str, substring) => str.indexOf(substring), input, searchStringAtom);
10174
10209
  },
10175
10210
  /**
10176
10211
  * 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.
@@ -10182,9 +10217,10 @@
10182
10217
  * If an empty length is provided, the behavior is the same as if length had not been provided.
10183
10218
  *
10184
10219
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10185
- *
10186
10220
  * @param input The input collection.
10187
- * @returns The index of the substring.
10221
+ * @param startAtom The start index atom.
10222
+ * @param lengthAtom Optional length atom.
10223
+ * @returns The substring.
10188
10224
  */
10189
10225
  substring: (input, startAtom, lengthAtom) => {
10190
10226
  return applyStringFunc((str, start, length) => {
@@ -10194,71 +10230,134 @@
10194
10230
  }, input, startAtom, lengthAtom);
10195
10231
  },
10196
10232
  /**
10233
+ * Returns true when the input string starts with the given prefix.
10234
+ *
10235
+ * If prefix is the empty string (''), the result is true.
10236
+ *
10237
+ * If the input collection is empty, the result is empty.
10197
10238
  *
10239
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10240
+ *
10241
+ * See: https://hl7.org/fhirpath/#startswithprefix-string-boolean
10198
10242
  * @param input The input collection.
10199
- * @returns The index of the substring.
10243
+ * @param prefixAtom The prefix substring to test.
10244
+ * @returns True if the input string starts with the given prefix string.
10200
10245
  */
10201
10246
  startsWith: (input, prefixAtom) => {
10202
10247
  return applyStringFunc((str, prefix) => str.startsWith(prefix), input, prefixAtom);
10203
10248
  },
10204
10249
  /**
10250
+ * Returns true when the input string ends with the given suffix.
10251
+ *
10252
+ * If suffix is the empty string (''), the result is true.
10205
10253
  *
10254
+ * If the input collection is empty, the result is empty.
10255
+ *
10256
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10257
+ *
10258
+ * See: https://hl7.org/fhirpath/#endswithsuffix-string-boolean
10206
10259
  * @param input The input collection.
10207
- * @returns The index of the substring.
10260
+ * @param suffixAtom The suffix substring to test.
10261
+ * @returns True if the input string ends with the given suffix string.
10208
10262
  */
10209
10263
  endsWith: (input, suffixAtom) => {
10210
10264
  return applyStringFunc((str, suffix) => str.endsWith(suffix), input, suffixAtom);
10211
10265
  },
10212
10266
  /**
10267
+ * Returns true when the given substring is a substring of the input string.
10213
10268
  *
10269
+ * If substring is the empty string (''), the result is true.
10270
+ *
10271
+ * If the input collection is empty, the result is empty.
10272
+ *
10273
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10274
+ *
10275
+ * See: https://hl7.org/fhirpath/#containssubstring-string-boolean
10214
10276
  * @param input The input collection.
10215
- * @returns The index of the substring.
10277
+ * @param substringAtom The substring to test.
10278
+ * @returns True if the input string contains the given substring.
10216
10279
  */
10217
10280
  contains: (input, substringAtom) => {
10218
10281
  return applyStringFunc((str, substring) => str.includes(substring), input, substringAtom);
10219
10282
  },
10220
10283
  /**
10284
+ * Returns the input string with all characters converted to upper case.
10221
10285
  *
10286
+ * If the input collection is empty, the result is empty.
10287
+ *
10288
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10289
+ *
10290
+ * See: https://hl7.org/fhirpath/#upper-string
10222
10291
  * @param input The input collection.
10223
- * @returns The index of the substring.
10292
+ * @returns The string converted to upper case.
10224
10293
  */
10225
10294
  upper: (input) => {
10226
10295
  return applyStringFunc((str) => str.toUpperCase(), input);
10227
10296
  },
10228
10297
  /**
10298
+ * Returns the input string with all characters converted to lower case.
10299
+ *
10300
+ * If the input collection is empty, the result is empty.
10229
10301
  *
10302
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10303
+ *
10304
+ * See: https://hl7.org/fhirpath/#lower-string
10230
10305
  * @param input The input collection.
10231
- * @returns The index of the substring.
10306
+ * @returns The string converted to lower case.
10232
10307
  */
10233
10308
  lower: (input) => {
10234
10309
  return applyStringFunc((str) => str.toLowerCase(), input);
10235
10310
  },
10236
10311
  /**
10312
+ * Returns the input string with all instances of pattern replaced with substitution. If the substitution is the empty string (''),
10313
+ * instances of pattern are removed from the result. If pattern is the empty string (''), every character in the input string is
10314
+ * surrounded by the substitution, e.g. 'abc'.replace('','x') becomes 'xaxbxcx'.
10315
+ *
10316
+ * If the input collection, pattern, or substitution are empty, the result is empty ({ }).
10237
10317
  *
10318
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10319
+ *
10320
+ * See: https://hl7.org/fhirpath/#replacepattern-string-substitution-string-string
10238
10321
  * @param input The input collection.
10239
- * @returns The index of the substring.
10322
+ * @param patternAtom The pattern to search for.
10323
+ * @param substitionAtom The substition to replace with.
10324
+ * @returns The string with all instances of the search pattern replaced with the substitution string.
10240
10325
  */
10241
10326
  replace: (input, patternAtom, substitionAtom) => {
10242
10327
  return applyStringFunc((str, pattern, substition) => str.replaceAll(pattern, substition), input, patternAtom, substitionAtom);
10243
10328
  },
10244
10329
  /**
10330
+ * 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.
10331
+ *
10332
+ * If the input collection or regex are empty, the result is empty ({ }).
10245
10333
  *
10334
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10335
+ *
10336
+ * See: https://hl7.org/fhirpath/#matchesregex-string-boolean
10246
10337
  * @param input The input collection.
10247
- * @returns The index of the substring.
10338
+ * @param regexAtom The regular expression atom.
10339
+ * @returns True if the input string matches the given regular expression.
10248
10340
  */
10249
10341
  matches: (input, regexAtom) => {
10250
10342
  return applyStringFunc((str, regex) => !!str.match(regex), input, regexAtom);
10251
10343
  },
10252
10344
  /**
10345
+ * 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.
10253
10346
  *
10347
+ * If the input collection, regex, or substitution are empty, the result is empty ({ }).
10348
+ *
10349
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10350
+ *
10351
+ * See: https://hl7.org/fhirpath/#replacematchesregex-string-substitution-string-string
10254
10352
  * @param input The input collection.
10255
- * @returns The index of the substring.
10353
+ * @param regexAtom The regular expression atom.
10354
+ * @param substitionAtom The substition to replace with.
10355
+ * @returns The string with all instances of the search pattern replaced with the substitution string.
10256
10356
  */
10257
10357
  replaceMatches: (input, regexAtom, substitionAtom) => {
10258
10358
  return applyStringFunc((str, pattern, substition) => str.replaceAll(pattern, substition), input, regexAtom, substitionAtom);
10259
10359
  },
10260
10360
  /**
10261
- *
10262
10361
  * @param input The input collection.
10263
10362
  * @returns The index of the substring.
10264
10363
  */
@@ -10269,8 +10368,8 @@
10269
10368
  * Returns the list of characters in the input string. If the input collection is empty ({ }), the result is empty.
10270
10369
  *
10271
10370
  * See: https://hl7.org/fhirpath/#tochars-collection
10272
- *
10273
10371
  * @param input The input collection.
10372
+ * @returns Array of characters.
10274
10373
  */
10275
10374
  toChars: (input) => {
10276
10375
  return applyStringFunc((str) => (str ? str.split('') : undefined), input);
@@ -10286,7 +10385,6 @@
10286
10385
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10287
10386
  *
10288
10387
  * See: https://hl7.org/fhirpath/#abs-integer-decimal-quantity
10289
- *
10290
10388
  * @param input The input collection.
10291
10389
  * @returns A collection containing the result.
10292
10390
  */
@@ -10301,7 +10399,6 @@
10301
10399
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10302
10400
  *
10303
10401
  * See: https://hl7.org/fhirpath/#ceiling-integer
10304
- *
10305
10402
  * @param input The input collection.
10306
10403
  * @returns A collection containing the result.
10307
10404
  */
@@ -10318,7 +10415,6 @@
10318
10415
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10319
10416
  *
10320
10417
  * See: https://hl7.org/fhirpath/#exp-decimal
10321
- *
10322
10418
  * @param input The input collection.
10323
10419
  * @returns A collection containing the result.
10324
10420
  */
@@ -10333,7 +10429,6 @@
10333
10429
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10334
10430
  *
10335
10431
  * See: https://hl7.org/fhirpath/#floor-integer
10336
- *
10337
10432
  * @param input The input collection.
10338
10433
  * @returns A collection containing the result.
10339
10434
  */
@@ -10350,7 +10445,6 @@
10350
10445
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10351
10446
  *
10352
10447
  * See: https://hl7.org/fhirpath/#ln-decimal
10353
- *
10354
10448
  * @param input The input collection.
10355
10449
  * @returns A collection containing the result.
10356
10450
  */
@@ -10369,8 +10463,8 @@
10369
10463
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10370
10464
  *
10371
10465
  * See: https://hl7.org/fhirpath/#logbase-decimal-decimal
10372
- *
10373
10466
  * @param input The input collection.
10467
+ * @param baseAtom The logarithm base.
10374
10468
  * @returns A collection containing the result.
10375
10469
  */
10376
10470
  log: (input, baseAtom) => {
@@ -10386,8 +10480,8 @@
10386
10480
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10387
10481
  *
10388
10482
  * See: https://hl7.org/fhirpath/#powerexponent-integer-decimal-integer-decimal
10389
- *
10390
10483
  * @param input The input collection.
10484
+ * @param expAtom The exponent power.
10391
10485
  * @returns A collection containing the result.
10392
10486
  */
10393
10487
  power: (input, expAtom) => {
@@ -10405,7 +10499,6 @@
10405
10499
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10406
10500
  *
10407
10501
  * See: https://hl7.org/fhirpath/#roundprecision-integer-decimal
10408
- *
10409
10502
  * @param input The input collection.
10410
10503
  * @returns A collection containing the result.
10411
10504
  */
@@ -10424,7 +10517,6 @@
10424
10517
  * Note that this function is equivalent to raising a number of the power of 0.5 using the power() function.
10425
10518
  *
10426
10519
  * See: https://hl7.org/fhirpath/#sqrt-decimal
10427
- *
10428
10520
  * @param input The input collection.
10429
10521
  * @returns A collection containing the result.
10430
10522
  */
@@ -10439,7 +10531,6 @@
10439
10531
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10440
10532
  *
10441
10533
  * See: https://hl7.org/fhirpath/#truncate-integer
10442
- *
10443
10534
  * @param input The input collection.
10444
10535
  * @returns A collection containing the result.
10445
10536
  */
@@ -10465,9 +10556,9 @@
10465
10556
  * function unchanged.
10466
10557
  *
10467
10558
  * See: https://hl7.org/fhirpath/#tracename-string-projection-expression-collection
10468
- *
10469
10559
  * @param input The input collection.
10470
10560
  * @param nameAtom The log name.
10561
+ * @returns The input collection.
10471
10562
  */
10472
10563
  trace: (input, nameAtom) => {
10473
10564
  console.log('trace', input, nameAtom);
@@ -10477,6 +10568,7 @@
10477
10568
  * Returns the current date and time, including timezone offset.
10478
10569
  *
10479
10570
  * See: https://hl7.org/fhirpath/#now-datetime
10571
+ * @returns The current dateTime.
10480
10572
  */
10481
10573
  now: () => {
10482
10574
  return [{ type: exports.PropertyType.dateTime, value: new Date().toISOString() }];
@@ -10485,6 +10577,7 @@
10485
10577
  * Returns the current time.
10486
10578
  *
10487
10579
  * See: https://hl7.org/fhirpath/#timeofday-time
10580
+ * @returns The current time string.
10488
10581
  */
10489
10582
  timeOfDay: () => {
10490
10583
  return [{ type: exports.PropertyType.time, value: new Date().toISOString().substring(11) }];
@@ -10493,6 +10586,7 @@
10493
10586
  * Returns the current date.
10494
10587
  *
10495
10588
  * See: https://hl7.org/fhirpath/#today-date
10589
+ * @returns The current date string.
10496
10590
  */
10497
10591
  today: () => {
10498
10592
  return [{ type: exports.PropertyType.date, value: new Date().toISOString().substring(0, 10) }];
@@ -10504,6 +10598,11 @@
10504
10598
  *
10505
10599
  * IBM FHIR issue: https://github.com/IBM/FHIR/issues/1014
10506
10600
  * IBM FHIR PR: https://github.com/IBM/FHIR/pull/1023
10601
+ * @param input The input collection.
10602
+ * @param startAtom The start date/time.
10603
+ * @param endAtom The end date/time.
10604
+ * @param unitsAtom Which units to return ("years", "months", or "days").
10605
+ * @returns The Quantity of time between the two dates.
10507
10606
  */
10508
10607
  between: (input, startAtom, endAtom, unitsAtom) => {
10509
10608
  const startDate = functions.toDateTime(startAtom.eval(input));
@@ -10532,10 +10631,9 @@
10532
10631
  * For implementations with compile-time typing, this requires special-case
10533
10632
  * handling when processing the argument to treat it as a type specifier rather
10534
10633
  * than an identifier expression:
10535
- *
10536
- * @param input
10537
- * @param typeAtom
10538
- * @returns
10634
+ * @param input The input collection.
10635
+ * @param typeAtom The desired type.
10636
+ * @returns True if the input element is of the desired type.
10539
10637
  */
10540
10638
  is: (input, typeAtom) => {
10541
10639
  let typeName = '';
@@ -10557,9 +10655,8 @@
10557
10655
  * 6.5.3. not() : Boolean
10558
10656
  *
10559
10657
  * Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):
10560
- *
10561
- * @param input
10562
- * @returns
10658
+ * @param input The input collection.
10659
+ * @returns True if the input evaluates to false.
10563
10660
  */
10564
10661
  not: (input) => {
10565
10662
  return functions.toBoolean(input).map((value) => ({ type: exports.PropertyType.boolean, value: !value.value }));
@@ -10572,7 +10669,7 @@
10572
10669
  * 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.
10573
10670
  * The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.
10574
10671
  * @param input The input collection.
10575
- * @returns
10672
+ * @returns The resolved resource.
10576
10673
  */
10577
10674
  resolve: (input) => {
10578
10675
  return input
@@ -10627,9 +10724,8 @@
10627
10724
  * https://hl7.org/fhirpath/modelinfo.xsd
10628
10725
  *
10629
10726
  * See: https://hl7.org/fhirpath/#model-information
10630
- *
10631
10727
  * @param input The input collection.
10632
- * @returns
10728
+ * @returns The type of the input value.
10633
10729
  */
10634
10730
  type: (input) => {
10635
10731
  return input.map(({ value }) => {
@@ -11831,7 +11927,7 @@
11831
11927
  /**
11832
11928
  * Formats a search definition object into a query string.
11833
11929
  * Note: The return value does not include the resource type.
11834
- * @param {!SearchRequest} definition The search definition.
11930
+ * @param definition The search definition.
11835
11931
  * @returns Formatted URL.
11836
11932
  */
11837
11933
  function formatSearchQuery(definition) {
@@ -12219,7 +12315,7 @@
12219
12315
  * Returns a formatted string representing the date in ISO-8601 format.
12220
12316
  * @param hl7Date Date string.
12221
12317
  * @param options Optional configuration Object
12222
- * @returns
12318
+ * @returns The date in ISO-8601 format.
12223
12319
  */
12224
12320
  function parseHl7Date(hl7Date, options) {
12225
12321
  if (!hl7Date) {
@@ -12308,7 +12404,6 @@
12308
12404
  * const medplum = new MedplumClient();
12309
12405
  * await medplum.requestSchema('Patient');
12310
12406
  * ```
12311
- *
12312
12407
  * @param resourceType The candidate resource type string.
12313
12408
  * @returns True if the resource type is a valid FHIR resource type.
12314
12409
  */
@@ -12348,9 +12443,7 @@
12348
12443
  * const medplum = new MedplumClient();
12349
12444
  * await medplum.requestSchema('Patient');
12350
12445
  * ```
12351
- *
12352
12446
  * @param resourceType The candidate resource type string.
12353
- * @returns True if the resource type is a valid FHIR resource type.
12354
12447
  */
12355
12448
  function validateResourceType(resourceType) {
12356
12449
  if (!resourceType) {
@@ -12390,9 +12483,7 @@
12390
12483
  * const medplum = new MedplumClient();
12391
12484
  * await medplum.requestSchema('Patient');
12392
12485
  * ```
12393
- *
12394
- * @param resourceType The candidate resource type string.
12395
- * @returns True if the resource type is a valid FHIR resource type.
12486
+ * @param resource The candidate resource.
12396
12487
  */
12397
12488
  function validateResource(resource) {
12398
12489
  new FhirSchemaValidator(resource).validate();
@@ -12555,10 +12646,10 @@
12555
12646
  * 2) a JSON property with _ prepended to the name of the element, which, if present, contains the value's id and/or extensions
12556
12647
  *
12557
12648
  * See: https://hl7.org/fhir/json.html#primitive
12558
- *
12559
12649
  * @param path The path to the property
12560
- * @param key
12561
- * @param typedValue
12650
+ * @param key The key in the current typed value.
12651
+ * @param typedValue The current typed value.
12652
+ * @returns True if the primitive element is valid.
12562
12653
  */
12563
12654
  checkPrimitiveElement(path, key, typedValue) {
12564
12655
  // Primitive element starts with underscore
@@ -12611,7 +12702,6 @@
12611
12702
  * Recursively checks for null values in an object.
12612
12703
  *
12613
12704
  * Note that "null" is a special value in JSON that is not allowed in FHIR.
12614
- *
12615
12705
  * @param value Input value of any type.
12616
12706
  * @param path Path string to the value for OperationOutcome.
12617
12707
  * @param issues Output list of issues.
@@ -12675,7 +12765,6 @@
12675
12765
  * 1) The "date" type includes "date", "datetime", and "period".
12676
12766
  * 2) The "token" type includes enums and booleans.
12677
12767
  * 3) Arrays/multiple values are not reflected at all.
12678
- *
12679
12768
  * @param resourceType The root resource type.
12680
12769
  * @param searchParam The search parameter.
12681
12770
  * @returns The search parameter type details.
@@ -12835,6 +12924,7 @@
12835
12924
  /**
12836
12925
  * Determines if the resource matches the search filter.
12837
12926
  * @param resource The resource that was created or updated.
12927
+ * @param searchRequest The search request.
12838
12928
  * @param filter One of the filters of a subscription criteria.
12839
12929
  * @returns True if the resource satisfies the search filter.
12840
12930
  */
@@ -13051,8 +13141,10 @@
13051
13141
  exports.createReference = createReference;
13052
13142
  exports.createStructureIssue = createStructureIssue;
13053
13143
  exports.created = created;
13144
+ exports.decodeBase64 = decodeBase64;
13054
13145
  exports.deepClone = deepClone;
13055
13146
  exports.deepEquals = deepEquals$1;
13147
+ exports.encodeBase64 = encodeBase64;
13056
13148
  exports.evalFhirPath = evalFhirPath;
13057
13149
  exports.evalFhirPathTyped = evalFhirPathTyped;
13058
13150
  exports.fhirPathArrayEquals = fhirPathArrayEquals;