@medplum/core 2.0.20 → 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 (47) hide show
  1. package/dist/cjs/index.cjs +448 -289
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.min.cjs +1 -1
  4. package/dist/esm/client.mjs +199 -101
  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 +2 -2
  26. package/dist/esm/search/search.mjs.map +1 -1
  27. package/dist/esm/sftp.mjs +0 -1
  28. package/dist/esm/sftp.mjs.map +1 -1
  29. package/dist/esm/storage.mjs +8 -0
  30. package/dist/esm/storage.mjs.map +1 -1
  31. package/dist/esm/types.mjs +1 -0
  32. package/dist/esm/types.mjs.map +1 -1
  33. package/dist/esm/utils.mjs +8 -7
  34. package/dist/esm/utils.mjs.map +1 -1
  35. package/dist/types/client.d.ts +89 -65
  36. package/dist/types/config.d.ts +7 -3
  37. package/dist/types/crypto.d.ts +3 -1
  38. package/dist/types/hl7.d.ts +1 -1
  39. package/dist/types/index.d.ts +1 -0
  40. package/dist/types/jwt.d.ts +2 -1
  41. package/dist/types/schema.d.ts +4 -10
  42. package/dist/types/search/details.d.ts +0 -1
  43. package/dist/types/search/search.d.ts +1 -1
  44. package/dist/types/storage.d.ts +8 -0
  45. package/dist/types/typeschema/types.d.ts +55 -0
  46. package/dist/types/utils.d.ts +4 -4
  47. 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.20-effeb76c" ;
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;
@@ -7713,10 +7722,11 @@
7713
7722
  * See The FHIR "batch/transaction" section for full details: https://hl7.org/fhir/http.html#transaction
7714
7723
  * @category Batch
7715
7724
  * @param bundle The FHIR batch/transaction bundle.
7725
+ * @param options Optional fetch options.
7716
7726
  * @returns The FHIR batch/transaction response bundle.
7717
7727
  */
7718
- executeBatch(bundle) {
7719
- return this.post(this.fhirBaseUrl.slice(0, -1), bundle);
7728
+ executeBatch(bundle, options) {
7729
+ return this.post(this.fhirBaseUrl.slice(0, -1), bundle, undefined, options);
7720
7730
  }
7721
7731
  /**
7722
7732
  * Sends an email using the Medplum Email API.
@@ -7752,11 +7762,12 @@
7752
7762
  *
7753
7763
  * See options here: https://nodemailer.com/extras/mailcomposer/
7754
7764
  * @category Media
7755
- * @param options The MailComposer options.
7765
+ * @param email The MailComposer options.
7766
+ * @param options Optional fetch options.
7756
7767
  * @returns Promise to the operation outcome.
7757
7768
  */
7758
- sendEmail(email) {
7759
- return this.post('email/v1/send', email, 'application/json');
7769
+ sendEmail(email, options) {
7770
+ return this.post('email/v1/send', email, 'application/json', options);
7760
7771
  }
7761
7772
  /**
7762
7773
  * Executes a GraphQL query.
@@ -7798,7 +7809,6 @@
7798
7809
  * See the GraphQL documentation for more details: https://graphql.org/learn/
7799
7810
  *
7800
7811
  * See the FHIR GraphQL documentation for FHIR specific details: https://www.hl7.org/fhir/graphql.html
7801
- *
7802
7812
  * @category Read
7803
7813
  * @param query The GraphQL query.
7804
7814
  * @param operationName Optional GraphQL operation name.
@@ -7813,15 +7823,15 @@
7813
7823
  *
7814
7824
  * Executes the $graph operation on this resource to fetch a Bundle of resources linked to the target resource
7815
7825
  * according to a graph definition
7816
-
7817
7826
  * @category Read
7818
7827
  * @param resourceType The FHIR resource type.
7819
7828
  * @param id The resource ID.
7820
7829
  * @param graphName `name` parameter of the GraphDefinition
7830
+ * @param options Optional fetch options.
7821
7831
  * @returns A Bundle
7822
7832
  */
7823
- readResourceGraph(resourceType, id, graphName) {
7824
- 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);
7825
7835
  }
7826
7836
  /**
7827
7837
  * @category Authentication
@@ -7831,11 +7841,16 @@
7831
7841
  return this.storage.getObject('activeLogin');
7832
7842
  }
7833
7843
  /**
7844
+ * Sets the active login.
7845
+ * @param login The new active login state.
7834
7846
  * @category Authentication
7835
7847
  */
7836
7848
  async setActiveLogin(login) {
7837
7849
  this.clearActiveLogin();
7838
7850
  this.accessToken = login.accessToken;
7851
+ if (this.basicAuth) {
7852
+ return;
7853
+ }
7839
7854
  this.refreshToken = login.refreshToken;
7840
7855
  this.storage.setObject('activeLogin', login);
7841
7856
  this.addLogin(login);
@@ -7844,6 +7859,7 @@
7844
7859
  }
7845
7860
  /**
7846
7861
  * Returns the current access token.
7862
+ * @returns The current access token.
7847
7863
  * @category Authentication
7848
7864
  */
7849
7865
  getAccessToken() {
@@ -7851,6 +7867,7 @@
7851
7867
  }
7852
7868
  /**
7853
7869
  * Sets the current access token.
7870
+ * @param accessToken The new access token.
7854
7871
  * @category Authentication
7855
7872
  */
7856
7873
  setAccessToken(accessToken) {
@@ -7860,6 +7877,8 @@
7860
7877
  this.config = undefined;
7861
7878
  }
7862
7879
  /**
7880
+ * Returns the list of available logins.
7881
+ * @returns The list of available logins.
7863
7882
  * @category Authentication
7864
7883
  */
7865
7884
  getLogins() {
@@ -7872,6 +7891,9 @@
7872
7891
  }
7873
7892
  async refreshProfile() {
7874
7893
  this.profilePromise = new Promise((resolve, reject) => {
7894
+ if (this.basicAuth) {
7895
+ return;
7896
+ }
7875
7897
  this.get('auth/me')
7876
7898
  .then((result) => {
7877
7899
  this.profilePromise = undefined;
@@ -7885,18 +7907,26 @@
7885
7907
  return this.profilePromise;
7886
7908
  }
7887
7909
  /**
7910
+ * Returns true if the client is waiting for authentication.
7911
+ * @returns True if the client is waiting for authentication.
7888
7912
  * @category Authentication
7889
7913
  */
7890
7914
  isLoading() {
7891
7915
  return !!this.profilePromise;
7892
7916
  }
7893
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.
7894
7921
  * @category User Profile
7895
7922
  */
7896
7923
  getProfile() {
7897
7924
  return this.profile;
7898
7925
  }
7899
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.
7900
7930
  * @category User Profile
7901
7931
  */
7902
7932
  async getProfileAsync() {
@@ -7906,6 +7936,8 @@
7906
7936
  return this.getProfile();
7907
7937
  }
7908
7938
  /**
7939
+ * Returns the current user configuration if available.
7940
+ * @returns The current user configuration if available.
7909
7941
  * @category User Profile
7910
7942
  */
7911
7943
  getUserConfiguration() {
@@ -7913,9 +7945,9 @@
7913
7945
  }
7914
7946
  /**
7915
7947
  * Downloads the URL as a blob.
7916
- *
7917
7948
  * @category Read
7918
7949
  * @param url The URL to request.
7950
+ * @param options Optional fetch request init options.
7919
7951
  * @returns Promise to the response body as a blob.
7920
7952
  */
7921
7953
  async download(url, options = {}) {
@@ -7929,12 +7961,13 @@
7929
7961
  /**
7930
7962
  * Upload media to the server and create a Media instance for the uploaded content.
7931
7963
  * @param contents The contents of the media file, as a string, Uint8Array, File, or Blob.
7932
- * @param contentType The media type of the content
7933
- * @param filename The name of the file to be uploaded, or undefined if not applicable
7934
- * @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.
7935
7968
  * @returns Promise that resolves to the created Media
7936
7969
  */
7937
- async uploadMedia(contents, contentType, filename, additionalFields) {
7970
+ async uploadMedia(contents, contentType, filename, additionalFields, options) {
7938
7971
  const binary = await this.createBinary(contents, filename, contentType);
7939
7972
  return this.createResource({
7940
7973
  ...additionalFields,
@@ -7944,7 +7977,36 @@
7944
7977
  url: 'Binary/' + binary.id,
7945
7978
  title: filename,
7946
7979
  },
7947
- });
7980
+ }, options);
7981
+ }
7982
+ /**
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
7984
+ * @param exportLevel Optional export level. Defaults to system level export. 'Group/:id' - Group of Patients, 'Patient' - All Patients.
7985
+ * @param resourceTypes A string of comma-delimited FHIR resource types.
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).
7987
+ * @param options Optional fetch options.
7988
+ * @returns Bulk Data Response containing links to Bulk Data files. See "Response - Complete Status" for full details: https://build.fhir.org/ig/HL7/bulk-data/export.html#response---complete-status
7989
+ */
7990
+ async bulkExport(exportLevel = '', resourceTypes, since, options = {}) {
7991
+ const fhirPath = exportLevel ? `${exportLevel}/` : exportLevel;
7992
+ const url = this.fhirUrl(`${fhirPath}$export`);
7993
+ if (resourceTypes) {
7994
+ url.searchParams.set('_type', resourceTypes);
7995
+ }
7996
+ if (since) {
7997
+ url.searchParams.set('_since', since);
7998
+ }
7999
+ this.addFetchOptionsDefaults(options);
8000
+ const headers = options.headers;
8001
+ headers['Prefer'] = 'respond-async';
8002
+ const response = await this.fetchWithRetry(url.toString(), options);
8003
+ if (response.status === 202) {
8004
+ const contentLocation = response.headers.get('content-location');
8005
+ if (contentLocation) {
8006
+ return await this.pollStatus(contentLocation);
8007
+ }
8008
+ }
8009
+ return await this.parseResponse(response, 'POST', url.toString());
7948
8010
  }
7949
8011
  //
7950
8012
  // Private helpers
@@ -7997,10 +8059,10 @@
7997
8059
  }
7998
8060
  /**
7999
8061
  * Makes an HTTP request.
8000
- * @param {string} method
8001
- * @param {string} url
8002
- * @param {string=} contentType
8003
- * @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.
8004
8066
  */
8005
8067
  async request(method, url, options = {}) {
8006
8068
  if (this.refreshPromise) {
@@ -8012,6 +8074,9 @@
8012
8074
  options.method = method;
8013
8075
  this.addFetchOptionsDefaults(options);
8014
8076
  const response = await this.fetchWithRetry(url, options);
8077
+ return await this.parseResponse(response, method, url, options);
8078
+ }
8079
+ async parseResponse(response, method, url, options = {}) {
8015
8080
  if (response.status === 401) {
8016
8081
  // Refresh and try again
8017
8082
  return this.handleUnauthenticated(method, url, options);
@@ -8044,14 +8109,35 @@
8044
8109
  const retryDelay = 200;
8045
8110
  let response = undefined;
8046
8111
  for (let retry = 0; retry < maxRetries; retry++) {
8047
- response = (await this.fetch(url, options));
8048
- if (response.status < 500) {
8049
- return response;
8112
+ try {
8113
+ response = (await this.fetch(url, options));
8114
+ if (response.status < 500) {
8115
+ return response;
8116
+ }
8117
+ }
8118
+ catch (err) {
8119
+ this.retryCatch(retry, maxRetries, err);
8050
8120
  }
8051
8121
  await new Promise((resolve) => setTimeout(resolve, retryDelay));
8052
8122
  }
8053
8123
  return response;
8054
8124
  }
8125
+ async pollStatus(statusUrl) {
8126
+ let checkStatus = true;
8127
+ let resultResponse;
8128
+ const retryDelay = 200;
8129
+ while (checkStatus) {
8130
+ const fetchOptions = {};
8131
+ this.addFetchOptionsDefaults(fetchOptions);
8132
+ const statusResponse = await this.fetchWithRetry(statusUrl, fetchOptions);
8133
+ if (statusResponse.status !== 202) {
8134
+ checkStatus = false;
8135
+ resultResponse = statusResponse;
8136
+ }
8137
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
8138
+ }
8139
+ return await this.parseResponse(resultResponse, 'POST', statusUrl);
8140
+ }
8055
8141
  /**
8056
8142
  * Executes a batch of requests that were automatically batched together.
8057
8143
  */
@@ -8109,6 +8195,7 @@
8109
8195
  headers = {};
8110
8196
  options.headers = headers;
8111
8197
  }
8198
+ headers['Accept'] = FHIR_CONTENT_TYPE;
8112
8199
  headers['X-Medplum'] = 'extended';
8113
8200
  if (options.body && !headers['Content-Type']) {
8114
8201
  headers['Content-Type'] = FHIR_CONTENT_TYPE;
@@ -8116,7 +8203,7 @@
8116
8203
  if (this.accessToken) {
8117
8204
  headers['Authorization'] = 'Bearer ' + this.accessToken;
8118
8205
  }
8119
- if (this.basicAuth) {
8206
+ else if (this.basicAuth) {
8120
8207
  headers['Authorization'] = 'Basic ' + this.basicAuth;
8121
8208
  }
8122
8209
  if (!options.cache) {
@@ -8160,8 +8247,8 @@
8160
8247
  * Otherwise, calls unauthenticated callbacks and rejects.
8161
8248
  * @param method The HTTP method of the original request.
8162
8249
  * @param url The URL of the original request.
8163
- * @param contentType The content type of the original request.
8164
- * @param body The body of the original request.
8250
+ * @param options Optional fetch request init options.
8251
+ * @returns The result of the retry.
8165
8252
  */
8166
8253
  handleUnauthenticated(method, url, options) {
8167
8254
  if (this.refresh()) {
@@ -8177,6 +8264,7 @@
8177
8264
  * Starts a new PKCE flow.
8178
8265
  * These PKCE values are stateful, and must survive redirects and page refreshes.
8179
8266
  * @category Authentication
8267
+ * @returns The PKCE code challenge details.
8180
8268
  */
8181
8269
  async startPkce() {
8182
8270
  const pkceState = getRandomString();
@@ -8191,7 +8279,8 @@
8191
8279
  /**
8192
8280
  * Redirects the user to the login screen for authorization.
8193
8281
  * Clears all auth state including local storage and session storage.
8194
- * 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
8195
8284
  */
8196
8285
  async requestAuthorization(loginParams) {
8197
8286
  const loginRequest = await this.ensureCodeChallenge(loginParams || {});
@@ -8210,6 +8299,7 @@
8210
8299
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
8211
8300
  * @param code The authorization code received by URL parameter.
8212
8301
  * @param loginParams Optional login parameters.
8302
+ * @returns The user profile resource.
8213
8303
  * @category Authentication
8214
8304
  */
8215
8305
  processCode(code, loginParams) {
@@ -8228,7 +8318,8 @@
8228
8318
  }
8229
8319
  /**
8230
8320
  * Tries to refresh the auth tokens.
8231
- * 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
8232
8323
  */
8233
8324
  refresh() {
8234
8325
  if (this.refreshPromise) {
@@ -8281,7 +8372,6 @@
8281
8372
  * // Example Search
8282
8373
  * await medplum.searchResources('Patient')
8283
8374
  * ```
8284
- *
8285
8375
  * @category Authentication
8286
8376
  * @param clientId The client ID.
8287
8377
  * @param clientSecret The client secret.
@@ -8304,14 +8394,20 @@
8304
8394
  * Makes a POST request to the tokens endpoint.
8305
8395
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8306
8396
  * @param formBody Token parameters in URL encoded format.
8397
+ * @returns The user profile resource.
8307
8398
  */
8308
8399
  async fetchTokens(formBody) {
8309
- const response = await this.fetch(this.tokenUrl, {
8400
+ const options = {
8310
8401
  method: 'POST',
8311
8402
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
8312
8403
  body: formBody,
8313
8404
  credentials: 'include',
8314
- });
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);
8315
8411
  if (!response.ok) {
8316
8412
  this.clearActiveLogin();
8317
8413
  throw new Error('Failed to fetch tokens');
@@ -8324,7 +8420,8 @@
8324
8420
  * Verifies the tokens received from the auth server.
8325
8421
  * Validates the JWT against the JWKS.
8326
8422
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8327
- * @param tokens
8423
+ * @param tokens The token response.
8424
+ * @returns Promise to complete.
8328
8425
  */
8329
8426
  async verifyTokens(tokens) {
8330
8427
  const token = tokens.access_token;
@@ -8335,7 +8432,14 @@
8335
8432
  throw new Error('Token expired');
8336
8433
  }
8337
8434
  // Verify app_client_id
8338
- 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) {
8339
8443
  this.clearActiveLogin();
8340
8444
  throw new Error('Token was not issued for this audience');
8341
8445
  }
@@ -8365,6 +8469,15 @@
8365
8469
  // Silently ignore if this environment does not support storage events
8366
8470
  }
8367
8471
  }
8472
+ retryCatch(retryNumber, maxRetries, err) {
8473
+ // This is for the 1st retry to avoid multiple notifications
8474
+ if (err.message === 'Failed to fetch' && retryNumber === 1) {
8475
+ this.dispatchEvent({ type: 'offline' });
8476
+ }
8477
+ if (retryNumber >= maxRetries - 1) {
8478
+ throw err;
8479
+ }
8480
+ }
8368
8481
  }
8369
8482
  /**
8370
8483
  * Returns the default fetch method.
@@ -8380,6 +8493,7 @@
8380
8493
  }
8381
8494
  /**
8382
8495
  * Returns the base URL for the current page.
8496
+ * @returns The window origin string.
8383
8497
  * @category HTTP
8384
8498
  */
8385
8499
  function getWindowOrigin() {
@@ -9141,6 +9255,7 @@
9141
9255
 
9142
9256
  /**
9143
9257
  * Temporary placholder for unimplemented methods.
9258
+ * @returns Empty array.
9144
9259
  */
9145
9260
  const stub = () => [];
9146
9261
  const functions = {
@@ -9152,7 +9267,6 @@
9152
9267
  * Returns true if the input collection is empty ({ }) and false otherwise.
9153
9268
  *
9154
9269
  * See: https://hl7.org/fhirpath/#empty-boolean
9155
- *
9156
9270
  * @param input The input collection.
9157
9271
  * @returns True if the input collection is empty ({ }) and false otherwise.
9158
9272
  */
@@ -9169,9 +9283,8 @@
9169
9283
  * for where(criteria).exists().
9170
9284
  *
9171
9285
  * See: https://hl7.org/fhirpath/#existscriteria-expression-boolean
9172
- *
9173
- * @param input
9174
- * @param criteria
9286
+ * @param input The input collection.
9287
+ * @param criteria Optional criteria applied to the collection.
9175
9288
  * @returns True if the collection has unknown elements, and false otherwise.
9176
9289
  */
9177
9290
  exists: (input, criteria) => {
@@ -9189,7 +9302,6 @@
9189
9302
  * If the input collection is empty ({ }), the result is true.
9190
9303
  *
9191
9304
  * See: https://hl7.org/fhirpath/#allcriteria-expression-boolean
9192
- *
9193
9305
  * @param input The input collection.
9194
9306
  * @param criteria The evaluation criteria.
9195
9307
  * @returns True if for every element in the input collection, criteria evaluates to true.
@@ -9203,9 +9315,7 @@
9203
9315
  * If the input is empty ({ }), the result is true.
9204
9316
  *
9205
9317
  * See: https://hl7.org/fhirpath/#alltrue-boolean
9206
- *
9207
9318
  * @param input The input collection.
9208
- * @param criteria The evaluation criteria.
9209
9319
  * @returns True if all the items are true.
9210
9320
  */
9211
9321
  allTrue: (input) => {
@@ -9221,9 +9331,7 @@
9221
9331
  * If all the items are false, or if the input is empty ({ }), the result is false.
9222
9332
  *
9223
9333
  * See: https://hl7.org/fhirpath/#anytrue-boolean
9224
- *
9225
9334
  * @param input The input collection.
9226
- * @param criteria The evaluation criteria.
9227
9335
  * @returns True if unknown of the items are true.
9228
9336
  */
9229
9337
  anyTrue: (input) => {
@@ -9240,9 +9348,7 @@
9240
9348
  * If the input is empty ({ }), the result is true.
9241
9349
  *
9242
9350
  * See: https://hl7.org/fhirpath/#allfalse-boolean
9243
- *
9244
9351
  * @param input The input collection.
9245
- * @param criteria The evaluation criteria.
9246
9352
  * @returns True if all the items are false.
9247
9353
  */
9248
9354
  allFalse: (input) => {
@@ -9258,9 +9364,7 @@
9258
9364
  * If all the items are true, or if the input is empty ({ }), the result is false.
9259
9365
  *
9260
9366
  * See: https://hl7.org/fhirpath/#anyfalse-boolean
9261
- *
9262
9367
  * @param input The input collection.
9263
- * @param criteria The evaluation criteria.
9264
9368
  * @returns True if for every element in the input collection, criteria evaluates to true.
9265
9369
  */
9266
9370
  anyFalse: (input) => {
@@ -9300,7 +9404,6 @@
9300
9404
  * Returns 0 when the input collection is empty.
9301
9405
  *
9302
9406
  * See: https://hl7.org/fhirpath/#count-integer
9303
- *
9304
9407
  * @param input The input collection.
9305
9408
  * @returns The integer count of the number of items in the input collection.
9306
9409
  */
@@ -9318,7 +9421,6 @@
9318
9421
  * preserved in the result.
9319
9422
  *
9320
9423
  * See: https://hl7.org/fhirpath/#distinct-collection
9321
- *
9322
9424
  * @param input The input collection.
9323
9425
  * @returns The integer count of the number of items in the input collection.
9324
9426
  */
@@ -9337,7 +9439,6 @@
9337
9439
  * as defined below.
9338
9440
  *
9339
9441
  * See: https://hl7.org/fhirpath/#isdistinct-boolean
9340
- *
9341
9442
  * @param input The input collection.
9342
9443
  * @returns The integer count of the number of items in the input collection.
9343
9444
  */
@@ -9360,9 +9461,8 @@
9360
9461
  * consistent with singleton evaluation of collections behavior.
9361
9462
  *
9362
9463
  * See: https://hl7.org/fhirpath/#wherecriteria-expression-collection
9363
- *
9364
9464
  * @param input The input collection.
9365
- * @param condition The condition atom.
9465
+ * @param criteria The condition atom.
9366
9466
  * @returns A collection containing only those elements in the input collection for which the stated criteria expression evaluates to true.
9367
9467
  */
9368
9468
  where: (input, criteria) => {
@@ -9378,6 +9478,9 @@
9378
9478
  * the input collection is empty ({ }), the result is empty as well.
9379
9479
  *
9380
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.
9381
9484
  */
9382
9485
  select: (input, criteria) => {
9383
9486
  return input.map((e) => criteria.eval([e])).flat();
@@ -9397,6 +9500,9 @@
9397
9500
  * must resolve to the name of a type in a model
9398
9501
  *
9399
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.
9400
9506
  */
9401
9507
  ofType: (input, criteria) => {
9402
9508
  return input.filter((e) => e.type === criteria.name);
@@ -9412,7 +9518,6 @@
9412
9518
  * about cardinality is violated at run-time.
9413
9519
  *
9414
9520
  * See: https://hl7.org/fhirpath/#single-collection
9415
- *
9416
9521
  * @param input The input collection.
9417
9522
  * @returns The single item in the input if there is just one item.
9418
9523
  */
@@ -9427,7 +9532,6 @@
9427
9532
  * This function is equivalent to item[0], so it will return an empty collection if the input collection has no items.
9428
9533
  *
9429
9534
  * See: https://hl7.org/fhirpath/#first-collection
9430
- *
9431
9535
  * @param input The input collection.
9432
9536
  * @returns A collection containing only the first item in the input collection.
9433
9537
  */
@@ -9439,7 +9543,6 @@
9439
9543
  * Will return an empty collection if the input collection has no items.
9440
9544
  *
9441
9545
  * See: https://hl7.org/fhirpath/#last-collection
9442
- *
9443
9546
  * @param input The input collection.
9444
9547
  * @returns A collection containing only the last item in the input collection.
9445
9548
  */
@@ -9451,7 +9554,6 @@
9451
9554
  * Will return an empty collection if the input collection has no items, or only one item.
9452
9555
  *
9453
9556
  * See: https://hl7.org/fhirpath/#tail-collection
9454
- *
9455
9557
  * @param input The input collection.
9456
9558
  * @returns A collection containing all but the first item in the input collection.
9457
9559
  */
@@ -9465,8 +9567,8 @@
9465
9567
  * If num is less than or equal to zero, the input collection is simply returned.
9466
9568
  *
9467
9569
  * See: https://hl7.org/fhirpath/#skipnum-integer-collection
9468
- *
9469
9570
  * @param input The input collection.
9571
+ * @param num The atom representing the number of elements to skip.
9470
9572
  * @returns A collection containing all but the first item in the input collection.
9471
9573
  */
9472
9574
  skip: (input, num) => {
@@ -9489,8 +9591,8 @@
9489
9591
  * take returns an empty collection.
9490
9592
  *
9491
9593
  * See: https://hl7.org/fhirpath/#takenum-integer-collection
9492
- *
9493
9594
  * @param input The input collection.
9595
+ * @param num The atom representing the number of elements to take.
9494
9596
  * @returns A collection containing the first num items in the input collection.
9495
9597
  */
9496
9598
  take: (input, num) => {
@@ -9512,6 +9614,9 @@
9512
9614
  * Order of items is not guaranteed to be preserved in the result of this function.
9513
9615
  *
9514
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.
9515
9620
  */
9516
9621
  intersect: (input, other) => {
9517
9622
  if (!other) {
@@ -9533,6 +9638,9 @@
9533
9638
  * e.g. (1 | 2 | 3).exclude(2) returns (1 | 3).
9534
9639
  *
9535
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.
9536
9644
  */
9537
9645
  exclude: (input, other) => {
9538
9646
  if (!other) {
@@ -9560,6 +9668,9 @@
9560
9668
  * In other words, this function returns the distinct list of elements from both inputs.
9561
9669
  *
9562
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.
9563
9674
  */
9564
9675
  union: (input, other) => {
9565
9676
  if (!other) {
@@ -9576,6 +9687,9 @@
9576
9687
  * There is no expectation of order in the resulting collection.
9577
9688
  *
9578
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.
9579
9693
  */
9580
9694
  combine: (input, other) => {
9581
9695
  if (!other) {
@@ -9604,12 +9718,11 @@
9604
9718
  * true-result should only be evaluated if the criterion evaluates to true,
9605
9719
  * and otherwise-result should only be evaluated otherwise. For implementations,
9606
9720
  * this means delaying evaluation of the arguments.
9607
- *
9608
- * @param input
9609
- * @param criterion
9610
- * @param trueResult
9611
- * @param otherwiseResult
9612
- * @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.
9613
9726
  */
9614
9727
  iif: (input, criterion, trueResult, otherwiseResult) => {
9615
9728
  const evalResult = criterion.eval(input);
@@ -9636,9 +9749,8 @@
9636
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.
9637
9750
  *
9638
9751
  * See: https://hl7.org/fhirpath/#toboolean-boolean
9639
- *
9640
- * @param input
9641
- * @returns
9752
+ * @param input The input collection.
9753
+ * @returns The input converted to boolean value.
9642
9754
  */
9643
9755
  toBoolean: (input) => {
9644
9756
  if (input.length === 0) {
@@ -9680,9 +9792,8 @@
9680
9792
  * If the input collection is empty, the result is empty.
9681
9793
  *
9682
9794
  * See: http://hl7.org/fhirpath/#convertstoboolean-boolean
9683
- *
9684
- * @param input
9685
- * @returns
9795
+ * @param input The input collection.
9796
+ * @returns True if the input can be converted to boolean.
9686
9797
  */
9687
9798
  convertsToBoolean: (input) => {
9688
9799
  if (input.length === 0) {
@@ -9707,7 +9818,6 @@
9707
9818
  * If the input collection is empty, the result is empty.
9708
9819
  *
9709
9820
  * See: https://hl7.org/fhirpath/#tointeger-integer
9710
- *
9711
9821
  * @param input The input collection.
9712
9822
  * @returns The string representation of the input.
9713
9823
  */
@@ -9741,9 +9851,8 @@
9741
9851
  * If the input collection is empty, the result is empty.
9742
9852
  *
9743
9853
  * See: https://hl7.org/fhirpath/#convertstointeger-boolean
9744
- *
9745
9854
  * @param input The input collection.
9746
- * @returns
9855
+ * @returns True if the input can be converted to an integer.
9747
9856
  */
9748
9857
  convertsToInteger: (input) => {
9749
9858
  if (input.length === 0) {
@@ -9766,6 +9875,8 @@
9766
9875
  * If the input collection is empty, the result is empty.
9767
9876
  *
9768
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.
9769
9880
  */
9770
9881
  toDate: (input) => {
9771
9882
  if (input.length === 0) {
@@ -9792,6 +9903,8 @@
9792
9903
  * If the input collection is empty, the result is empty.
9793
9904
  *
9794
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.
9795
9908
  */
9796
9909
  convertsToDate: (input) => {
9797
9910
  if (input.length === 0) {
@@ -9800,26 +9913,25 @@
9800
9913
  return booleanToTypedValue(functions.toDate(input).length === 1);
9801
9914
  },
9802
9915
  /**
9803
- * If the input collection contains a single item, this function will return a single datetime if:
9804
- * 1) the item is a DateTime
9805
- * 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)
9806
- * 3) the item is a String and is convertible to a DateTime
9807
- *
9808
- * If the item is not one of the above types, the result is empty.
9809
- *
9810
- * 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.
9811
- *
9812
- * If the item contains a partial datetime (e.g. '2012-01-01T10:00'), the result is a partial datetime.
9813
- *
9814
- * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
9815
- *
9816
- * If the input collection is empty, the result is empty.
9817
-
9818
- * See: https://hl7.org/fhirpath/#todatetime-datetime
9819
- *
9820
- * @param input
9821
- * @returns
9822
- */
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
+ */
9823
9935
  toDateTime: (input) => {
9824
9936
  if (input.length === 0) {
9825
9937
  return [];
@@ -9843,9 +9955,8 @@
9843
9955
  * If the input collection is empty, the result is empty.
9844
9956
  *
9845
9957
  * See: https://hl7.org/fhirpath/#convertstodatetime-boolean
9846
- *
9847
- * @param input
9848
- * @returns
9958
+ * @param input The input collection.
9959
+ * @returns True if the item can be converted to a dateTime.
9849
9960
  */
9850
9961
  convertsToDateTime: (input) => {
9851
9962
  if (input.length === 0) {
@@ -9867,9 +9978,8 @@
9867
9978
  * If the input collection is empty, the result is empty.
9868
9979
  *
9869
9980
  * See: https://hl7.org/fhirpath/#decimal-conversion-functions
9870
- *
9871
9981
  * @param input The input collection.
9872
- * @returns
9982
+ * @returns The value converted to a decimal if possible; otherwise empty array.
9873
9983
  */
9874
9984
  toDecimal: (input) => {
9875
9985
  if (input.length === 0) {
@@ -9888,22 +9998,21 @@
9888
9998
  return [];
9889
9999
  },
9890
10000
  /**
9891
- * If the input collection contains a single item, this function will true if:
9892
- * 1) the item is an Integer or Decimal
9893
- * 2) the item is a String and is convertible to a Decimal
9894
- * 3) the item is a Boolean
9895
- *
9896
- * 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.
9897
- *
9898
- * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
9899
- *
9900
- * If the input collection is empty, the result is empty.
9901
-
9902
- * See: https://hl7.org/fhirpath/#convertstodecimal-boolean
9903
- *
9904
- * @param input The input collection.
9905
- * @returns
9906
- */
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
+ */
9907
10016
  convertsToDecimal: (input) => {
9908
10017
  if (input.length === 0) {
9909
10018
  return [];
@@ -9920,9 +10029,8 @@
9920
10029
  * If the item is not one of the above types, the result is empty.
9921
10030
  *
9922
10031
  * See: https://hl7.org/fhirpath/#quantity-conversion-functions
9923
- *
9924
10032
  * @param input The input collection.
9925
- * @returns
10033
+ * @returns The value converted to a quantity if possible; otherwise empty array.
9926
10034
  */
9927
10035
  toQuantity: (input) => {
9928
10036
  if (input.length === 0) {
@@ -9962,9 +10070,8 @@
9962
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.
9963
10071
  *
9964
10072
  * See: https://hl7.org/fhirpath/#convertstoquantityunit-string-boolean
9965
- *
9966
10073
  * @param input The input collection.
9967
- * @returns
10074
+ * @returns True if the item can be converted to a quantity.
9968
10075
  */
9969
10076
  convertsToQuantity: (input) => {
9970
10077
  if (input.length === 0) {
@@ -9984,7 +10091,6 @@
9984
10091
  * If the item is not one of the above types, the result is false.
9985
10092
  *
9986
10093
  * See: https://hl7.org/fhirpath/#tostring-string
9987
- *
9988
10094
  * @param input The input collection.
9989
10095
  * @returns The string representation of the input.
9990
10096
  */
@@ -10017,9 +10123,8 @@
10017
10123
  * If the input collection is empty, the result is empty.
10018
10124
  *
10019
10125
  * See: https://hl7.org/fhirpath/#tostring-string
10020
- *
10021
10126
  * @param input The input collection.
10022
- * @returns
10127
+ * @returns True if the item can be converted to a string
10023
10128
  */
10024
10129
  convertsToString: (input) => {
10025
10130
  if (input.length === 0) {
@@ -10043,9 +10148,8 @@
10043
10148
  * If the input collection is empty, the result is empty.
10044
10149
  *
10045
10150
  * See: https://hl7.org/fhirpath/#totime-time
10046
- *
10047
- * @param input
10048
- * @returns
10151
+ * @param input The input collection.
10152
+ * @returns The value converted to a time if possible; otherwise empty array.
10049
10153
  */
10050
10154
  toTime: (input) => {
10051
10155
  if (input.length === 0) {
@@ -10072,9 +10176,8 @@
10072
10176
  * If the input collection is empty, the result is empty.
10073
10177
  *
10074
10178
  * See: https://hl7.org/fhirpath/#convertstotime-boolean
10075
- *
10076
- * @param input
10077
- * @returns
10179
+ * @param input The input collection.
10180
+ * @returns True if the item can be converted to a time.
10078
10181
  */
10079
10182
  convertsToTime: (input) => {
10080
10183
  if (input.length === 0) {
@@ -10097,12 +10200,12 @@
10097
10200
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10098
10201
  *
10099
10202
  * See: https://hl7.org/fhirpath/#indexofsubstring-string-integer
10100
- *
10101
10203
  * @param input The input collection.
10204
+ * @param searchStringAtom The substring to search for.
10102
10205
  * @returns The index of the substring.
10103
10206
  */
10104
- indexOf: (input, substringAtom) => {
10105
- return applyStringFunc((str, substring) => str.indexOf(substring), input, substringAtom);
10207
+ indexOf: (input, searchStringAtom) => {
10208
+ return applyStringFunc((str, substring) => str.indexOf(substring), input, searchStringAtom);
10106
10209
  },
10107
10210
  /**
10108
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.
@@ -10114,9 +10217,10 @@
10114
10217
  * If an empty length is provided, the behavior is the same as if length had not been provided.
10115
10218
  *
10116
10219
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10117
- *
10118
10220
  * @param input The input collection.
10119
- * @returns The index of the substring.
10221
+ * @param startAtom The start index atom.
10222
+ * @param lengthAtom Optional length atom.
10223
+ * @returns The substring.
10120
10224
  */
10121
10225
  substring: (input, startAtom, lengthAtom) => {
10122
10226
  return applyStringFunc((str, start, length) => {
@@ -10126,71 +10230,134 @@
10126
10230
  }, input, startAtom, lengthAtom);
10127
10231
  },
10128
10232
  /**
10233
+ * Returns true when the input string starts with the given prefix.
10129
10234
  *
10235
+ * If prefix is the empty string (''), the result is true.
10236
+ *
10237
+ * If the input collection is empty, the result is empty.
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
10130
10242
  * @param input The input collection.
10131
- * @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.
10132
10245
  */
10133
10246
  startsWith: (input, prefixAtom) => {
10134
10247
  return applyStringFunc((str, prefix) => str.startsWith(prefix), input, prefixAtom);
10135
10248
  },
10136
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.
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.
10137
10257
  *
10258
+ * See: https://hl7.org/fhirpath/#endswithsuffix-string-boolean
10138
10259
  * @param input The input collection.
10139
- * @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.
10140
10262
  */
10141
10263
  endsWith: (input, suffixAtom) => {
10142
10264
  return applyStringFunc((str, suffix) => str.endsWith(suffix), input, suffixAtom);
10143
10265
  },
10144
10266
  /**
10267
+ * Returns true when the given substring is a substring of the input string.
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.
10145
10274
  *
10275
+ * See: https://hl7.org/fhirpath/#containssubstring-string-boolean
10146
10276
  * @param input The input collection.
10147
- * @returns The index of the substring.
10277
+ * @param substringAtom The substring to test.
10278
+ * @returns True if the input string contains the given substring.
10148
10279
  */
10149
10280
  contains: (input, substringAtom) => {
10150
10281
  return applyStringFunc((str, substring) => str.includes(substring), input, substringAtom);
10151
10282
  },
10152
10283
  /**
10284
+ * Returns the input string with all characters converted to upper case.
10153
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
10154
10291
  * @param input The input collection.
10155
- * @returns The index of the substring.
10292
+ * @returns The string converted to upper case.
10156
10293
  */
10157
10294
  upper: (input) => {
10158
10295
  return applyStringFunc((str) => str.toUpperCase(), input);
10159
10296
  },
10160
10297
  /**
10298
+ * Returns the input string with all characters converted to lower case.
10161
10299
  *
10300
+ * If the input collection is empty, the result is empty.
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
10162
10305
  * @param input The input collection.
10163
- * @returns The index of the substring.
10306
+ * @returns The string converted to lower case.
10164
10307
  */
10165
10308
  lower: (input) => {
10166
10309
  return applyStringFunc((str) => str.toLowerCase(), input);
10167
10310
  },
10168
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 ({ }).
10317
+ *
10318
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10169
10319
  *
10320
+ * See: https://hl7.org/fhirpath/#replacepattern-string-substitution-string-string
10170
10321
  * @param input The input collection.
10171
- * @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.
10172
10325
  */
10173
10326
  replace: (input, patternAtom, substitionAtom) => {
10174
10327
  return applyStringFunc((str, pattern, substition) => str.replaceAll(pattern, substition), input, patternAtom, substitionAtom);
10175
10328
  },
10176
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 ({ }).
10333
+ *
10334
+ * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10177
10335
  *
10336
+ * See: https://hl7.org/fhirpath/#matchesregex-string-boolean
10178
10337
  * @param input The input collection.
10179
- * @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.
10180
10340
  */
10181
10341
  matches: (input, regexAtom) => {
10182
10342
  return applyStringFunc((str, regex) => !!str.match(regex), input, regexAtom);
10183
10343
  },
10184
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.
10346
+ *
10347
+ * If the input collection, regex, or substitution are empty, the result is empty ({ }).
10185
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
10186
10352
  * @param input The input collection.
10187
- * @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.
10188
10356
  */
10189
10357
  replaceMatches: (input, regexAtom, substitionAtom) => {
10190
10358
  return applyStringFunc((str, pattern, substition) => str.replaceAll(pattern, substition), input, regexAtom, substitionAtom);
10191
10359
  },
10192
10360
  /**
10193
- *
10194
10361
  * @param input The input collection.
10195
10362
  * @returns The index of the substring.
10196
10363
  */
@@ -10201,8 +10368,8 @@
10201
10368
  * Returns the list of characters in the input string. If the input collection is empty ({ }), the result is empty.
10202
10369
  *
10203
10370
  * See: https://hl7.org/fhirpath/#tochars-collection
10204
- *
10205
10371
  * @param input The input collection.
10372
+ * @returns Array of characters.
10206
10373
  */
10207
10374
  toChars: (input) => {
10208
10375
  return applyStringFunc((str) => (str ? str.split('') : undefined), input);
@@ -10218,7 +10385,6 @@
10218
10385
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10219
10386
  *
10220
10387
  * See: https://hl7.org/fhirpath/#abs-integer-decimal-quantity
10221
- *
10222
10388
  * @param input The input collection.
10223
10389
  * @returns A collection containing the result.
10224
10390
  */
@@ -10233,7 +10399,6 @@
10233
10399
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10234
10400
  *
10235
10401
  * See: https://hl7.org/fhirpath/#ceiling-integer
10236
- *
10237
10402
  * @param input The input collection.
10238
10403
  * @returns A collection containing the result.
10239
10404
  */
@@ -10250,7 +10415,6 @@
10250
10415
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10251
10416
  *
10252
10417
  * See: https://hl7.org/fhirpath/#exp-decimal
10253
- *
10254
10418
  * @param input The input collection.
10255
10419
  * @returns A collection containing the result.
10256
10420
  */
@@ -10265,7 +10429,6 @@
10265
10429
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10266
10430
  *
10267
10431
  * See: https://hl7.org/fhirpath/#floor-integer
10268
- *
10269
10432
  * @param input The input collection.
10270
10433
  * @returns A collection containing the result.
10271
10434
  */
@@ -10282,7 +10445,6 @@
10282
10445
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10283
10446
  *
10284
10447
  * See: https://hl7.org/fhirpath/#ln-decimal
10285
- *
10286
10448
  * @param input The input collection.
10287
10449
  * @returns A collection containing the result.
10288
10450
  */
@@ -10301,8 +10463,8 @@
10301
10463
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10302
10464
  *
10303
10465
  * See: https://hl7.org/fhirpath/#logbase-decimal-decimal
10304
- *
10305
10466
  * @param input The input collection.
10467
+ * @param baseAtom The logarithm base.
10306
10468
  * @returns A collection containing the result.
10307
10469
  */
10308
10470
  log: (input, baseAtom) => {
@@ -10318,8 +10480,8 @@
10318
10480
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10319
10481
  *
10320
10482
  * See: https://hl7.org/fhirpath/#powerexponent-integer-decimal-integer-decimal
10321
- *
10322
10483
  * @param input The input collection.
10484
+ * @param expAtom The exponent power.
10323
10485
  * @returns A collection containing the result.
10324
10486
  */
10325
10487
  power: (input, expAtom) => {
@@ -10337,7 +10499,6 @@
10337
10499
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10338
10500
  *
10339
10501
  * See: https://hl7.org/fhirpath/#roundprecision-integer-decimal
10340
- *
10341
10502
  * @param input The input collection.
10342
10503
  * @returns A collection containing the result.
10343
10504
  */
@@ -10356,7 +10517,6 @@
10356
10517
  * Note that this function is equivalent to raising a number of the power of 0.5 using the power() function.
10357
10518
  *
10358
10519
  * See: https://hl7.org/fhirpath/#sqrt-decimal
10359
- *
10360
10520
  * @param input The input collection.
10361
10521
  * @returns A collection containing the result.
10362
10522
  */
@@ -10371,7 +10531,6 @@
10371
10531
  * If the input collection contains multiple items, the evaluation of the expression will end and signal an error to the calling environment.
10372
10532
  *
10373
10533
  * See: https://hl7.org/fhirpath/#truncate-integer
10374
- *
10375
10534
  * @param input The input collection.
10376
10535
  * @returns A collection containing the result.
10377
10536
  */
@@ -10397,9 +10556,9 @@
10397
10556
  * function unchanged.
10398
10557
  *
10399
10558
  * See: https://hl7.org/fhirpath/#tracename-string-projection-expression-collection
10400
- *
10401
10559
  * @param input The input collection.
10402
10560
  * @param nameAtom The log name.
10561
+ * @returns The input collection.
10403
10562
  */
10404
10563
  trace: (input, nameAtom) => {
10405
10564
  console.log('trace', input, nameAtom);
@@ -10409,6 +10568,7 @@
10409
10568
  * Returns the current date and time, including timezone offset.
10410
10569
  *
10411
10570
  * See: https://hl7.org/fhirpath/#now-datetime
10571
+ * @returns The current dateTime.
10412
10572
  */
10413
10573
  now: () => {
10414
10574
  return [{ type: exports.PropertyType.dateTime, value: new Date().toISOString() }];
@@ -10417,6 +10577,7 @@
10417
10577
  * Returns the current time.
10418
10578
  *
10419
10579
  * See: https://hl7.org/fhirpath/#timeofday-time
10580
+ * @returns The current time string.
10420
10581
  */
10421
10582
  timeOfDay: () => {
10422
10583
  return [{ type: exports.PropertyType.time, value: new Date().toISOString().substring(11) }];
@@ -10425,6 +10586,7 @@
10425
10586
  * Returns the current date.
10426
10587
  *
10427
10588
  * See: https://hl7.org/fhirpath/#today-date
10589
+ * @returns The current date string.
10428
10590
  */
10429
10591
  today: () => {
10430
10592
  return [{ type: exports.PropertyType.date, value: new Date().toISOString().substring(0, 10) }];
@@ -10436,6 +10598,11 @@
10436
10598
  *
10437
10599
  * IBM FHIR issue: https://github.com/IBM/FHIR/issues/1014
10438
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.
10439
10606
  */
10440
10607
  between: (input, startAtom, endAtom, unitsAtom) => {
10441
10608
  const startDate = functions.toDateTime(startAtom.eval(input));
@@ -10464,10 +10631,9 @@
10464
10631
  * For implementations with compile-time typing, this requires special-case
10465
10632
  * handling when processing the argument to treat it as a type specifier rather
10466
10633
  * than an identifier expression:
10467
- *
10468
- * @param input
10469
- * @param typeAtom
10470
- * @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.
10471
10637
  */
10472
10638
  is: (input, typeAtom) => {
10473
10639
  let typeName = '';
@@ -10489,9 +10655,8 @@
10489
10655
  * 6.5.3. not() : Boolean
10490
10656
  *
10491
10657
  * Returns true if the input collection evaluates to false, and false if it evaluates to true. Otherwise, the result is empty ({ }):
10492
- *
10493
- * @param input
10494
- * @returns
10658
+ * @param input The input collection.
10659
+ * @returns True if the input evaluates to false.
10495
10660
  */
10496
10661
  not: (input) => {
10497
10662
  return functions.toBoolean(input).map((value) => ({ type: exports.PropertyType.boolean, value: !value.value }));
@@ -10504,7 +10669,7 @@
10504
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.
10505
10670
  * The items in the collection may also represent a Reference, in which case the Reference.reference is resolved.
10506
10671
  * @param input The input collection.
10507
- * @returns
10672
+ * @returns The resolved resource.
10508
10673
  */
10509
10674
  resolve: (input) => {
10510
10675
  return input
@@ -10559,9 +10724,8 @@
10559
10724
  * https://hl7.org/fhirpath/modelinfo.xsd
10560
10725
  *
10561
10726
  * See: https://hl7.org/fhirpath/#model-information
10562
- *
10563
10727
  * @param input The input collection.
10564
- * @returns
10728
+ * @returns The type of the input value.
10565
10729
  */
10566
10730
  type: (input) => {
10567
10731
  return input.map(({ value }) => {
@@ -11582,7 +11746,7 @@
11582
11746
  searchRequest.total = value;
11583
11747
  break;
11584
11748
  case '_summary':
11585
- searchRequest.total = 'estimate';
11749
+ searchRequest.total = 'accurate';
11586
11750
  searchRequest.count = 0;
11587
11751
  break;
11588
11752
  case '_include': {
@@ -11763,7 +11927,7 @@
11763
11927
  /**
11764
11928
  * Formats a search definition object into a query string.
11765
11929
  * Note: The return value does not include the resource type.
11766
- * @param {!SearchRequest} definition The search definition.
11930
+ * @param definition The search definition.
11767
11931
  * @returns Formatted URL.
11768
11932
  */
11769
11933
  function formatSearchQuery(definition) {
@@ -12151,7 +12315,7 @@
12151
12315
  * Returns a formatted string representing the date in ISO-8601 format.
12152
12316
  * @param hl7Date Date string.
12153
12317
  * @param options Optional configuration Object
12154
- * @returns
12318
+ * @returns The date in ISO-8601 format.
12155
12319
  */
12156
12320
  function parseHl7Date(hl7Date, options) {
12157
12321
  if (!hl7Date) {
@@ -12240,7 +12404,6 @@
12240
12404
  * const medplum = new MedplumClient();
12241
12405
  * await medplum.requestSchema('Patient');
12242
12406
  * ```
12243
- *
12244
12407
  * @param resourceType The candidate resource type string.
12245
12408
  * @returns True if the resource type is a valid FHIR resource type.
12246
12409
  */
@@ -12280,9 +12443,7 @@
12280
12443
  * const medplum = new MedplumClient();
12281
12444
  * await medplum.requestSchema('Patient');
12282
12445
  * ```
12283
- *
12284
12446
  * @param resourceType The candidate resource type string.
12285
- * @returns True if the resource type is a valid FHIR resource type.
12286
12447
  */
12287
12448
  function validateResourceType(resourceType) {
12288
12449
  if (!resourceType) {
@@ -12322,9 +12483,7 @@
12322
12483
  * const medplum = new MedplumClient();
12323
12484
  * await medplum.requestSchema('Patient');
12324
12485
  * ```
12325
- *
12326
- * @param resourceType The candidate resource type string.
12327
- * @returns True if the resource type is a valid FHIR resource type.
12486
+ * @param resource The candidate resource.
12328
12487
  */
12329
12488
  function validateResource(resource) {
12330
12489
  new FhirSchemaValidator(resource).validate();
@@ -12487,10 +12646,10 @@
12487
12646
  * 2) a JSON property with _ prepended to the name of the element, which, if present, contains the value's id and/or extensions
12488
12647
  *
12489
12648
  * See: https://hl7.org/fhir/json.html#primitive
12490
- *
12491
12649
  * @param path The path to the property
12492
- * @param key
12493
- * @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.
12494
12653
  */
12495
12654
  checkPrimitiveElement(path, key, typedValue) {
12496
12655
  // Primitive element starts with underscore
@@ -12543,7 +12702,6 @@
12543
12702
  * Recursively checks for null values in an object.
12544
12703
  *
12545
12704
  * Note that "null" is a special value in JSON that is not allowed in FHIR.
12546
- *
12547
12705
  * @param value Input value of any type.
12548
12706
  * @param path Path string to the value for OperationOutcome.
12549
12707
  * @param issues Output list of issues.
@@ -12607,7 +12765,6 @@
12607
12765
  * 1) The "date" type includes "date", "datetime", and "period".
12608
12766
  * 2) The "token" type includes enums and booleans.
12609
12767
  * 3) Arrays/multiple values are not reflected at all.
12610
- *
12611
12768
  * @param resourceType The root resource type.
12612
12769
  * @param searchParam The search parameter.
12613
12770
  * @returns The search parameter type details.
@@ -12767,6 +12924,7 @@
12767
12924
  /**
12768
12925
  * Determines if the resource matches the search filter.
12769
12926
  * @param resource The resource that was created or updated.
12927
+ * @param searchRequest The search request.
12770
12928
  * @param filter One of the filters of a subscription criteria.
12771
12929
  * @returns True if the resource satisfies the search filter.
12772
12930
  */
@@ -12910,7 +13068,6 @@
12910
13068
  return new Promise((resolve, reject) => {
12911
13069
  stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
12912
13070
  stream.on('error', (err) => {
12913
- console.error(err.message);
12914
13071
  stream.destroy();
12915
13072
  reject(err);
12916
13073
  });
@@ -12984,8 +13141,10 @@
12984
13141
  exports.createReference = createReference;
12985
13142
  exports.createStructureIssue = createStructureIssue;
12986
13143
  exports.created = created;
13144
+ exports.decodeBase64 = decodeBase64;
12987
13145
  exports.deepClone = deepClone;
12988
13146
  exports.deepEquals = deepEquals$1;
13147
+ exports.encodeBase64 = encodeBase64;
12989
13148
  exports.evalFhirPath = evalFhirPath;
12990
13149
  exports.evalFhirPathTyped = evalFhirPathTyped;
12991
13150
  exports.fhirPathArrayEquals = fhirPathArrayEquals;