@medplum/core 0.4.0 → 0.4.1

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.
package/dist/cjs/index.js CHANGED
@@ -27,42 +27,59 @@
27
27
  function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
28
28
  step((generator = generator.apply(thisArg, _arguments || [])).next());
29
29
  });
30
+ }
31
+
32
+ function __classPrivateFieldGet(receiver, state, kind, f) {
33
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
34
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
35
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
36
+ }
37
+
38
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
39
+ if (kind === "m") throw new TypeError("Private method is not writable");
40
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
41
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
42
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
30
43
  }
31
44
 
45
+ var _LRUCache_instances, _LRUCache_max, _LRUCache_cache, _LRUCache_first;
32
46
  /**
33
47
  * LRU cache (least recently used)
34
48
  * Source: https://stackoverflow.com/a/46432113
35
49
  */
36
50
  class LRUCache {
37
51
  constructor(max = 10) {
38
- this.max = max;
39
- this.cache = new Map();
52
+ _LRUCache_instances.add(this);
53
+ _LRUCache_max.set(this, void 0);
54
+ _LRUCache_cache.set(this, void 0);
55
+ __classPrivateFieldSet(this, _LRUCache_max, max, "f");
56
+ __classPrivateFieldSet(this, _LRUCache_cache, new Map(), "f");
40
57
  }
41
58
  clear() {
42
- this.cache.clear();
59
+ __classPrivateFieldGet(this, _LRUCache_cache, "f").clear();
43
60
  }
44
61
  get(key) {
45
- const item = this.cache.get(key);
62
+ const item = __classPrivateFieldGet(this, _LRUCache_cache, "f").get(key);
46
63
  if (item) {
47
- this.cache.delete(key);
48
- this.cache.set(key, item);
64
+ __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(key);
65
+ __classPrivateFieldGet(this, _LRUCache_cache, "f").set(key, item);
49
66
  }
50
67
  return item;
51
68
  }
52
69
  set(key, val) {
53
- if (this.cache.has(key)) {
54
- this.cache.delete(key);
70
+ if (__classPrivateFieldGet(this, _LRUCache_cache, "f").has(key)) {
71
+ __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(key);
55
72
  }
56
- else if (this.cache.size >= this.max) {
57
- this.cache.delete(this.first());
73
+ else if (__classPrivateFieldGet(this, _LRUCache_cache, "f").size >= __classPrivateFieldGet(this, _LRUCache_max, "f")) {
74
+ __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(__classPrivateFieldGet(this, _LRUCache_instances, "m", _LRUCache_first).call(this));
58
75
  }
59
- this.cache.set(key, val);
76
+ __classPrivateFieldGet(this, _LRUCache_cache, "f").set(key, val);
60
77
  }
61
- first() {
62
- // This works because the Map class maintains ordered keys.
63
- return this.cache.keys().next().value;
64
- }
65
- }
78
+ }
79
+ _LRUCache_max = new WeakMap(), _LRUCache_cache = new WeakMap(), _LRUCache_instances = new WeakSet(), _LRUCache_first = function _LRUCache_first() {
80
+ // This works because the Map class maintains ordered keys.
81
+ return __classPrivateFieldGet(this, _LRUCache_cache, "f").keys().next().value;
82
+ };
66
83
 
67
84
  function formatAddress(address, options) {
68
85
  const builder = [];
@@ -131,6 +148,15 @@
131
148
  function getReferenceString(resource) {
132
149
  return resource.resourceType + '/' + resource.id;
133
150
  }
151
+ /**
152
+ * Returns the ID portion of a reference.
153
+ * @param reference A FHIR reference.
154
+ * @returns The ID portion of a reference.
155
+ */
156
+ function resolveId(reference) {
157
+ var _a;
158
+ return (_a = reference === null || reference === void 0 ? void 0 : reference.reference) === null || _a === void 0 ? void 0 : _a.split('/')[1];
159
+ }
134
160
  /**
135
161
  * Returns true if the resource is a "ProfileResource".
136
162
  * @param resource The FHIR resource.
@@ -353,18 +379,20 @@
353
379
  /*
354
380
  * Based on: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
355
381
  */
382
+ var _EventTarget_listeners;
356
383
  class EventTarget {
357
384
  constructor() {
358
- this.listeners = {};
385
+ _EventTarget_listeners.set(this, void 0);
386
+ __classPrivateFieldSet(this, _EventTarget_listeners, {}, "f");
359
387
  }
360
388
  addEventListener(type, callback) {
361
- if (!this.listeners[type]) {
362
- this.listeners[type] = [];
389
+ if (!__classPrivateFieldGet(this, _EventTarget_listeners, "f")[type]) {
390
+ __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type] = [];
363
391
  }
364
- this.listeners[type].push(callback);
392
+ __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type].push(callback);
365
393
  }
366
394
  removeEventListeneer(type, callback) {
367
- const array = this.listeners[type];
395
+ const array = __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type];
368
396
  if (!array) {
369
397
  return;
370
398
  }
@@ -376,13 +404,14 @@
376
404
  }
377
405
  }
378
406
  dispatchEvent(event) {
379
- const array = this.listeners[event.type];
407
+ const array = __classPrivateFieldGet(this, _EventTarget_listeners, "f")[event.type];
380
408
  if (array) {
381
409
  array.forEach((listener) => listener.call(this, event));
382
410
  }
383
411
  return !event.defaultPrevented;
384
412
  }
385
- }
413
+ }
414
+ _EventTarget_listeners = new WeakMap();
386
415
 
387
416
  /**
388
417
  * Decodes a section of a JWT.
@@ -622,6 +651,7 @@
622
651
  let fields;
623
652
  let page = 0;
624
653
  let count = 10;
654
+ let total = undefined;
625
655
  params.forEach((value, key) => {
626
656
  if (key === '_fields') {
627
657
  fields = value.split(',');
@@ -632,6 +662,9 @@
632
662
  else if (key === '_count') {
633
663
  count = parseInt(value);
634
664
  }
665
+ else if (key === '_total') {
666
+ total = value;
667
+ }
635
668
  else if (key === '_sort') {
636
669
  sortRules.push(parseSortRule(value));
637
670
  }
@@ -645,6 +678,7 @@
645
678
  fields,
646
679
  page,
647
680
  count,
681
+ total,
648
682
  sortRules,
649
683
  };
650
684
  }
@@ -728,6 +762,9 @@
728
762
  if (definition.count && definition.count > 0) {
729
763
  params.push('_count=' + definition.count);
730
764
  }
765
+ if (definition.total) {
766
+ params.push('_total=' + encodeURIComponent(definition.total));
767
+ }
731
768
  if (params.length === 0) {
732
769
  return '';
733
770
  }
@@ -741,6 +778,7 @@
741
778
  return '_sort=' + sortRules.map((sr) => (sr.descending ? '-' + sr.code : sr.code)).join(',');
742
779
  }
743
780
 
781
+ var _ClientStorage_storage, _MemoryStorage_data;
744
782
  /**
745
783
  * The ClientStorage class is a utility class for storing strings and objects.
746
784
  *
@@ -750,20 +788,21 @@
750
788
  */
751
789
  class ClientStorage {
752
790
  constructor() {
753
- this.storage = typeof localStorage !== 'undefined' ? localStorage : new MemoryStorage();
791
+ _ClientStorage_storage.set(this, void 0);
792
+ __classPrivateFieldSet(this, _ClientStorage_storage, typeof localStorage !== 'undefined' ? localStorage : new MemoryStorage(), "f");
754
793
  }
755
794
  clear() {
756
- this.storage.clear();
795
+ __classPrivateFieldGet(this, _ClientStorage_storage, "f").clear();
757
796
  }
758
797
  getString(key) {
759
- return this.storage.getItem(key) || undefined;
798
+ return __classPrivateFieldGet(this, _ClientStorage_storage, "f").getItem(key) || undefined;
760
799
  }
761
800
  setString(key, value) {
762
801
  if (value) {
763
- this.storage.setItem(key, value);
802
+ __classPrivateFieldGet(this, _ClientStorage_storage, "f").setItem(key, value);
764
803
  }
765
804
  else {
766
- this.storage.removeItem(key);
805
+ __classPrivateFieldGet(this, _ClientStorage_storage, "f").removeItem(key);
767
806
  }
768
807
  }
769
808
  getObject(key) {
@@ -774,56 +813,59 @@
774
813
  this.setString(key, value ? stringify(value) : undefined);
775
814
  }
776
815
  }
816
+ _ClientStorage_storage = new WeakMap();
777
817
  /**
778
818
  * The MemoryStorage class is a minimal in-memory implementation of the Storage interface.
779
819
  */
780
820
  class MemoryStorage {
781
821
  constructor() {
782
- this.data = new Map();
822
+ _MemoryStorage_data.set(this, void 0);
823
+ __classPrivateFieldSet(this, _MemoryStorage_data, new Map(), "f");
783
824
  }
784
825
  /**
785
826
  * Returns the number of key/value pairs.
786
827
  */
787
828
  get length() {
788
- return this.data.size;
829
+ return __classPrivateFieldGet(this, _MemoryStorage_data, "f").size;
789
830
  }
790
831
  /**
791
832
  * Removes all key/value pairs, if there are any.
792
833
  */
793
834
  clear() {
794
- this.data.clear();
835
+ __classPrivateFieldGet(this, _MemoryStorage_data, "f").clear();
795
836
  }
796
837
  /**
797
838
  * Returns the current value associated with the given key, or null if the given key does not exist.
798
839
  */
799
840
  getItem(key) {
800
841
  var _a;
801
- return (_a = this.data.get(key)) !== null && _a !== void 0 ? _a : null;
842
+ return (_a = __classPrivateFieldGet(this, _MemoryStorage_data, "f").get(key)) !== null && _a !== void 0 ? _a : null;
802
843
  }
803
844
  /**
804
845
  * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
805
846
  */
806
847
  setItem(key, value) {
807
848
  if (value) {
808
- this.data.set(key, value);
849
+ __classPrivateFieldGet(this, _MemoryStorage_data, "f").set(key, value);
809
850
  }
810
851
  else {
811
- this.data.delete(key);
852
+ __classPrivateFieldGet(this, _MemoryStorage_data, "f").delete(key);
812
853
  }
813
854
  }
814
855
  /**
815
856
  * Removes the key/value pair with the given key, if a key/value pair with the given key exists.
816
857
  */
817
858
  removeItem(key) {
818
- this.data.delete(key);
859
+ __classPrivateFieldGet(this, _MemoryStorage_data, "f").delete(key);
819
860
  }
820
861
  /**
821
862
  * Returns the name of the nth key, or null if n is greater than or equal to the number of key/value pairs.
822
863
  */
823
864
  key(index) {
824
- return Array.from(this.data.keys())[index];
865
+ return Array.from(__classPrivateFieldGet(this, _MemoryStorage_data, "f").keys())[index];
825
866
  }
826
- }
867
+ }
868
+ _MemoryStorage_data = new WeakMap();
827
869
 
828
870
  /**
829
871
  * List of property types.
@@ -1012,6 +1054,8 @@
1012
1054
  }
1013
1055
 
1014
1056
  // PKCE auth ased on:
1057
+ // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
1058
+ var _MedplumClient_instances, _MedplumClient_fetch, _MedplumClient_storage, _MedplumClient_schema, _MedplumClient_resourceCache, _MedplumClient_baseUrl, _MedplumClient_clientId, _MedplumClient_authorizeUrl, _MedplumClient_tokenUrl, _MedplumClient_logoutUrl, _MedplumClient_onUnauthenticated, _MedplumClient_accessToken, _MedplumClient_refreshToken, _MedplumClient_refreshPromise, _MedplumClient_profilePromise, _MedplumClient_profile, _MedplumClient_config, _MedplumClient_addLogin, _MedplumClient_refreshProfile, _MedplumClient_request, _MedplumClient_buildFetchOptions, _MedplumClient_handleUnauthenticated, _MedplumClient_startPkce, _MedplumClient_requestAuthorization, _MedplumClient_refresh, _MedplumClient_fetchTokens, _MedplumClient_verifyTokens, _MedplumClient_setupStorageListener;
1015
1059
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
1016
1060
  const DEFAULT_SCOPE = 'launch/patient openid fhirUser offline_access user/*.*';
1017
1061
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
@@ -1022,6 +1066,23 @@
1022
1066
  constructor(options) {
1023
1067
  var _a;
1024
1068
  super();
1069
+ _MedplumClient_instances.add(this);
1070
+ _MedplumClient_fetch.set(this, void 0);
1071
+ _MedplumClient_storage.set(this, void 0);
1072
+ _MedplumClient_schema.set(this, void 0);
1073
+ _MedplumClient_resourceCache.set(this, void 0);
1074
+ _MedplumClient_baseUrl.set(this, void 0);
1075
+ _MedplumClient_clientId.set(this, void 0);
1076
+ _MedplumClient_authorizeUrl.set(this, void 0);
1077
+ _MedplumClient_tokenUrl.set(this, void 0);
1078
+ _MedplumClient_logoutUrl.set(this, void 0);
1079
+ _MedplumClient_onUnauthenticated.set(this, void 0);
1080
+ _MedplumClient_accessToken.set(this, void 0);
1081
+ _MedplumClient_refreshToken.set(this, void 0);
1082
+ _MedplumClient_refreshPromise.set(this, void 0);
1083
+ _MedplumClient_profilePromise.set(this, void 0);
1084
+ _MedplumClient_profile.set(this, void 0);
1085
+ _MedplumClient_config.set(this, void 0);
1025
1086
  if (options === null || options === void 0 ? void 0 : options.baseUrl) {
1026
1087
  if (!options.baseUrl.startsWith('http')) {
1027
1088
  throw new Error('Base URL must start with http or https');
@@ -1030,39 +1091,47 @@
1030
1091
  throw new Error('Base URL must end with a trailing slash');
1031
1092
  }
1032
1093
  }
1033
- this.fetch = (options === null || options === void 0 ? void 0 : options.fetch) || window.fetch.bind(window);
1034
- this.storage = new ClientStorage();
1035
- this.schema = createSchema();
1036
- this.resourceCache = new LRUCache((_a = options === null || options === void 0 ? void 0 : options.resourceCacheSize) !== null && _a !== void 0 ? _a : DEFAULT_RESOURCE_CACHE_SIZE);
1037
- this.baseUrl = (options === null || options === void 0 ? void 0 : options.baseUrl) || DEFAULT_BASE_URL;
1038
- this.clientId = (options === null || options === void 0 ? void 0 : options.clientId) || '';
1039
- this.authorizeUrl = (options === null || options === void 0 ? void 0 : options.authorizeUrl) || this.baseUrl + 'oauth2/authorize';
1040
- this.tokenUrl = (options === null || options === void 0 ? void 0 : options.tokenUrl) || this.baseUrl + 'oauth2/token';
1041
- this.logoutUrl = (options === null || options === void 0 ? void 0 : options.logoutUrl) || this.baseUrl + 'oauth2/logout';
1042
- this.onUnauthenticated = options === null || options === void 0 ? void 0 : options.onUnauthenticated;
1043
- this.loading = false;
1044
- this.refreshProfile().catch(console.log);
1045
- this.setupStorageListener();
1094
+ __classPrivateFieldSet(this, _MedplumClient_fetch, (options === null || options === void 0 ? void 0 : options.fetch) || window.fetch.bind(window), "f");
1095
+ __classPrivateFieldSet(this, _MedplumClient_storage, new ClientStorage(), "f");
1096
+ __classPrivateFieldSet(this, _MedplumClient_schema, createSchema(), "f");
1097
+ __classPrivateFieldSet(this, _MedplumClient_resourceCache, new LRUCache((_a = options === null || options === void 0 ? void 0 : options.resourceCacheSize) !== null && _a !== void 0 ? _a : DEFAULT_RESOURCE_CACHE_SIZE), "f");
1098
+ __classPrivateFieldSet(this, _MedplumClient_baseUrl, (options === null || options === void 0 ? void 0 : options.baseUrl) || DEFAULT_BASE_URL, "f");
1099
+ __classPrivateFieldSet(this, _MedplumClient_clientId, (options === null || options === void 0 ? void 0 : options.clientId) || '', "f");
1100
+ __classPrivateFieldSet(this, _MedplumClient_authorizeUrl, (options === null || options === void 0 ? void 0 : options.authorizeUrl) || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/authorize', "f");
1101
+ __classPrivateFieldSet(this, _MedplumClient_tokenUrl, (options === null || options === void 0 ? void 0 : options.tokenUrl) || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/token', "f");
1102
+ __classPrivateFieldSet(this, _MedplumClient_logoutUrl, (options === null || options === void 0 ? void 0 : options.logoutUrl) || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/logout', "f");
1103
+ __classPrivateFieldSet(this, _MedplumClient_onUnauthenticated, options === null || options === void 0 ? void 0 : options.onUnauthenticated, "f");
1104
+ const activeLogin = this.getActiveLogin();
1105
+ if (activeLogin) {
1106
+ __classPrivateFieldSet(this, _MedplumClient_accessToken, activeLogin.accessToken, "f");
1107
+ __classPrivateFieldSet(this, _MedplumClient_refreshToken, activeLogin.refreshToken, "f");
1108
+ __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_refreshProfile).call(this).catch(console.log);
1109
+ }
1110
+ __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setupStorageListener).call(this);
1046
1111
  }
1047
1112
  /**
1048
1113
  * Clears all auth state including local storage and session storage.
1049
1114
  */
1050
1115
  clear() {
1051
- this.storage.clear();
1052
- this.resourceCache.clear();
1116
+ __classPrivateFieldGet(this, _MedplumClient_storage, "f").clear();
1117
+ __classPrivateFieldGet(this, _MedplumClient_resourceCache, "f").clear();
1118
+ __classPrivateFieldSet(this, _MedplumClient_accessToken, undefined, "f");
1119
+ __classPrivateFieldSet(this, _MedplumClient_refreshToken, undefined, "f");
1120
+ __classPrivateFieldSet(this, _MedplumClient_profile, undefined, "f");
1121
+ __classPrivateFieldSet(this, _MedplumClient_config, undefined, "f");
1053
1122
  this.dispatchEvent({ type: 'change' });
1054
1123
  }
1055
1124
  get(url) {
1056
- return this.request('GET', url);
1125
+ return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'GET', url);
1057
1126
  }
1058
1127
  post(url, body, contentType) {
1059
- return this.request('POST', url, contentType, body);
1128
+ return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'POST', url, contentType, body);
1060
1129
  }
1061
1130
  put(url, body, contentType) {
1062
- return this.request('PUT', url, contentType, body);
1131
+ return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'PUT', url, contentType, body);
1063
1132
  }
1064
1133
  delete(url) {
1065
- return this.request('DELETE', url);
1134
+ return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'DELETE', url);
1066
1135
  }
1067
1136
  /**
1068
1137
  * Tries to register a new user.
@@ -1084,12 +1153,12 @@
1084
1153
  */
1085
1154
  startLogin(email, password, remember) {
1086
1155
  return __awaiter(this, void 0, void 0, function* () {
1087
- yield this.startPkce();
1156
+ yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
1088
1157
  return this.post('auth/login', {
1089
- clientId: this.clientId,
1158
+ clientId: __classPrivateFieldGet(this, _MedplumClient_clientId, "f"),
1090
1159
  scope: DEFAULT_SCOPE,
1091
1160
  codeChallengeMethod: 'S256',
1092
- codeChallenge: this.storage.getString('codeChallenge'),
1161
+ codeChallenge: __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge'),
1093
1162
  email,
1094
1163
  password,
1095
1164
  remember: !!remember,
@@ -1105,7 +1174,7 @@
1105
1174
  */
1106
1175
  startGoogleLogin(googleResponse) {
1107
1176
  return __awaiter(this, void 0, void 0, function* () {
1108
- yield this.startPkce();
1177
+ yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
1109
1178
  return this.post('auth/google', googleResponse);
1110
1179
  });
1111
1180
  }
@@ -1126,7 +1195,7 @@
1126
1195
  const urlParams = new URLSearchParams(window.location.search);
1127
1196
  const code = urlParams.get('code');
1128
1197
  if (!code) {
1129
- this.requestAuthorization();
1198
+ __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_requestAuthorization).call(this);
1130
1199
  return undefined;
1131
1200
  }
1132
1201
  else {
@@ -1138,7 +1207,7 @@
1138
1207
  * See: https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html
1139
1208
  */
1140
1209
  signOutWithRedirect() {
1141
- window.location.assign(this.logoutUrl);
1210
+ window.location.assign(__classPrivateFieldGet(this, _MedplumClient_logoutUrl, "f"));
1142
1211
  }
1143
1212
  /**
1144
1213
  * Builds a FHIR URL from a collection of URL path components.
@@ -1147,7 +1216,7 @@
1147
1216
  * @returns The well-formed FHIR URL.
1148
1217
  */
1149
1218
  fhirUrl(...path) {
1150
- const builder = [this.baseUrl, 'fhir/R4'];
1219
+ const builder = [__classPrivateFieldGet(this, _MedplumClient_baseUrl, "f"), 'fhir/R4'];
1151
1220
  path.forEach((p) => builder.push('/', encodeURIComponent(p)));
1152
1221
  return builder.join('');
1153
1222
  }
@@ -1178,7 +1247,7 @@
1178
1247
  * @returns The resource if it is available in the cache; undefined otherwise.
1179
1248
  */
1180
1249
  getCached(resourceType, id) {
1181
- const cached = this.resourceCache.get(resourceType + '/' + id);
1250
+ const cached = __classPrivateFieldGet(this, _MedplumClient_resourceCache, "f").get(resourceType + '/' + id);
1182
1251
  if (cached && !('then' in cached)) {
1183
1252
  return cached;
1184
1253
  }
@@ -1191,7 +1260,7 @@
1191
1260
  * @returns The resource if it is available in the cache; undefined otherwise.
1192
1261
  */
1193
1262
  getCachedReference(reference) {
1194
- const cached = this.resourceCache.get(reference.reference);
1263
+ const cached = __classPrivateFieldGet(this, _MedplumClient_resourceCache, "f").get(reference.reference);
1195
1264
  if (cached && !('then' in cached)) {
1196
1265
  return cached;
1197
1266
  }
@@ -1200,14 +1269,14 @@
1200
1269
  read(resourceType, id) {
1201
1270
  const cacheKey = resourceType + '/' + id;
1202
1271
  const promise = this.get(this.fhirUrl(resourceType, id)).then((resource) => {
1203
- this.resourceCache.set(cacheKey, resource);
1272
+ __classPrivateFieldGet(this, _MedplumClient_resourceCache, "f").set(cacheKey, resource);
1204
1273
  return resource;
1205
1274
  });
1206
- this.resourceCache.set(cacheKey, promise);
1275
+ __classPrivateFieldGet(this, _MedplumClient_resourceCache, "f").set(cacheKey, promise);
1207
1276
  return promise;
1208
1277
  }
1209
1278
  readCached(resourceType, id) {
1210
- const cached = this.resourceCache.get(resourceType + '/' + id);
1279
+ const cached = __classPrivateFieldGet(this, _MedplumClient_resourceCache, "f").get(resourceType + '/' + id);
1211
1280
  return cached ? Promise.resolve(cached) : this.read(resourceType, id);
1212
1281
  }
1213
1282
  readReference(reference) {
@@ -1234,7 +1303,7 @@
1234
1303
  * @returns The schema if immediately available, undefined otherwise.
1235
1304
  */
1236
1305
  getSchema() {
1237
- return this.schema;
1306
+ return __classPrivateFieldGet(this, _MedplumClient_schema, "f");
1238
1307
  }
1239
1308
  /**
1240
1309
  * Requests the schema for a resource type.
@@ -1244,8 +1313,8 @@
1244
1313
  */
1245
1314
  requestSchema(resourceType) {
1246
1315
  return __awaiter(this, void 0, void 0, function* () {
1247
- if (resourceType in this.schema.types) {
1248
- return Promise.resolve(this.schema);
1316
+ if (resourceType in __classPrivateFieldGet(this, _MedplumClient_schema, "f").types) {
1317
+ return Promise.resolve(__classPrivateFieldGet(this, _MedplumClient_schema, "f"));
1249
1318
  }
1250
1319
  const query = `{
1251
1320
  StructureDefinitionList(name: "${encodeURIComponent(resourceType)}") {
@@ -1276,12 +1345,12 @@
1276
1345
  }`.replace(/\s+/g, ' ');
1277
1346
  const response = (yield this.graphql(query));
1278
1347
  for (const structureDefinition of response.data.StructureDefinitionList) {
1279
- indexStructureDefinition(this.schema, structureDefinition);
1348
+ indexStructureDefinition(__classPrivateFieldGet(this, _MedplumClient_schema, "f"), structureDefinition);
1280
1349
  }
1281
1350
  for (const searchParameter of response.data.SearchParameterList) {
1282
- indexSearchParameter(this.schema, searchParameter);
1351
+ indexSearchParameter(__classPrivateFieldGet(this, _MedplumClient_schema, "f"), searchParameter);
1283
1352
  }
1284
- return this.schema;
1353
+ return __classPrivateFieldGet(this, _MedplumClient_schema, "f");
1285
1354
  });
1286
1355
  }
1287
1356
  readHistory(resourceType, id) {
@@ -1309,7 +1378,7 @@
1309
1378
  return this.put(this.fhirUrl(resource.resourceType, resource.id), resource);
1310
1379
  }
1311
1380
  patch(resourceType, id, operations) {
1312
- return this.request('PATCH', this.fhirUrl(resourceType, id), PATCH_CONTENT_TYPE, operations);
1381
+ return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'PATCH', this.fhirUrl(resourceType, id), PATCH_CONTENT_TYPE, operations);
1313
1382
  }
1314
1383
  deleteResource(resourceType, id) {
1315
1384
  return this.delete(this.fhirUrl(resourceType, id));
@@ -1318,159 +1387,55 @@
1318
1387
  return this.post(this.fhirUrl('$graphql'), { query }, JSON_CONTENT_TYPE);
1319
1388
  }
1320
1389
  getActiveLogin() {
1321
- return this.storage.getObject('activeLogin');
1390
+ return __classPrivateFieldGet(this, _MedplumClient_storage, "f").getObject('activeLogin');
1322
1391
  }
1323
1392
  setActiveLogin(login) {
1324
1393
  return __awaiter(this, void 0, void 0, function* () {
1325
- this.storage.setObject('activeLogin', login);
1326
- this.addLogin(login);
1327
- this.resourceCache.clear();
1328
- this.refreshPromise = undefined;
1329
- yield this.refreshProfile();
1394
+ __classPrivateFieldSet(this, _MedplumClient_accessToken, login.accessToken, "f");
1395
+ __classPrivateFieldSet(this, _MedplumClient_refreshToken, login.refreshToken, "f");
1396
+ __classPrivateFieldSet(this, _MedplumClient_profile, undefined, "f");
1397
+ __classPrivateFieldSet(this, _MedplumClient_config, undefined, "f");
1398
+ __classPrivateFieldGet(this, _MedplumClient_storage, "f").setObject('activeLogin', login);
1399
+ __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addLogin).call(this, login);
1400
+ __classPrivateFieldGet(this, _MedplumClient_resourceCache, "f").clear();
1401
+ __classPrivateFieldSet(this, _MedplumClient_refreshPromise, undefined, "f");
1402
+ yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_refreshProfile).call(this);
1330
1403
  });
1331
1404
  }
1332
1405
  getLogins() {
1333
1406
  var _a;
1334
- return (_a = this.storage.getObject('logins')) !== null && _a !== void 0 ? _a : [];
1407
+ return (_a = __classPrivateFieldGet(this, _MedplumClient_storage, "f").getObject('logins')) !== null && _a !== void 0 ? _a : [];
1335
1408
  }
1336
- addLogin(newLogin) {
1337
- const logins = this.getLogins().filter((login) => { var _a, _b; return ((_a = login.profile) === null || _a === void 0 ? void 0 : _a.reference) !== ((_b = newLogin.profile) === null || _b === void 0 ? void 0 : _b.reference); });
1338
- logins.push(newLogin);
1339
- this.storage.setObject('logins', logins);
1340
- }
1341
- refreshProfile() {
1342
- var _a;
1343
- return __awaiter(this, void 0, void 0, function* () {
1344
- const reference = (_a = this.getActiveLogin()) === null || _a === void 0 ? void 0 : _a.profile;
1345
- if (reference === null || reference === void 0 ? void 0 : reference.reference) {
1346
- this.loading = true;
1347
- this.storage.setObject('profile', yield this.readCachedReference(reference));
1348
- this.loading = false;
1349
- this.dispatchEvent({ type: 'change' });
1350
- }
1351
- return this.getProfile();
1352
- });
1409
+ isLoading() {
1410
+ return !!__classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
1353
1411
  }
1354
1412
  getProfile() {
1355
- return this.storage.getObject('profile');
1356
- }
1357
- isLoading() {
1358
- return this.loading;
1413
+ return __classPrivateFieldGet(this, _MedplumClient_profile, "f");
1359
1414
  }
1360
- /**
1361
- * Makes an HTTP request.
1362
- * @param {string} method
1363
- * @param {string} url
1364
- * @param {string=} contentType
1365
- * @param {Object=} body
1366
- */
1367
- request(method, url, contentType, body) {
1368
- var _a;
1415
+ getProfileAsync() {
1369
1416
  return __awaiter(this, void 0, void 0, function* () {
1370
- if (this.refreshPromise) {
1371
- yield this.refreshPromise;
1417
+ if (__classPrivateFieldGet(this, _MedplumClient_profilePromise, "f")) {
1418
+ yield __classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
1372
1419
  }
1373
- if (!url.startsWith('http')) {
1374
- url = this.baseUrl + url;
1375
- }
1376
- const headers = {
1377
- 'Content-Type': contentType || FHIR_CONTENT_TYPE,
1378
- };
1379
- const accessToken = (_a = this.getActiveLogin()) === null || _a === void 0 ? void 0 : _a.accessToken;
1380
- if (accessToken) {
1381
- headers['Authorization'] = 'Bearer ' + accessToken;
1382
- }
1383
- const options = {
1384
- method: method,
1385
- cache: 'no-cache',
1386
- credentials: 'include',
1387
- headers,
1388
- };
1389
- if (body) {
1390
- if (typeof body === 'string' || (typeof File !== 'undefined' && body instanceof File)) {
1391
- options.body = body;
1392
- }
1393
- else {
1394
- options.body = stringify(body);
1395
- }
1396
- }
1397
- const response = yield this.fetch(url, options);
1398
- if (response.status === 401) {
1399
- // Refresh and try again
1400
- return this.handleUnauthenticated(method, url, contentType, body);
1401
- }
1402
- if (response.status === 204 || response.status === 304) {
1403
- // No content or change
1404
- return undefined;
1405
- }
1406
- const obj = yield response.json();
1407
- if (obj.resourceType === 'OperationOutcome' && !isOk(obj)) {
1408
- return Promise.reject(obj);
1409
- }
1410
- return obj;
1411
- });
1412
- }
1413
- /**
1414
- * Handles an unauthenticated response from the server.
1415
- * First, tries to refresh the access token and retry the request.
1416
- * Otherwise, calls unauthenticated callbacks and rejects.
1417
- * @param method The HTTP method of the original request.
1418
- * @param url The URL of the original request.
1419
- * @param contentType The content type of the original request.
1420
- * @param body The body of the original request.
1421
- */
1422
- handleUnauthenticated(method, url, contentType, body) {
1423
- return __awaiter(this, void 0, void 0, function* () {
1424
- return this.refresh()
1425
- .then(() => this.request(method, url, contentType, body))
1426
- .catch((error) => {
1427
- this.clear();
1428
- if (this.onUnauthenticated) {
1429
- this.onUnauthenticated();
1430
- }
1431
- return Promise.reject(error);
1432
- });
1420
+ return this.getProfile();
1433
1421
  });
1434
1422
  }
1435
- /**
1436
- * Starts a new PKCE flow.
1437
- * These PKCE values are stateful, and must survive redirects and page refreshes.
1438
- */
1439
- startPkce() {
1440
- return __awaiter(this, void 0, void 0, function* () {
1441
- const pkceState = getRandomString();
1442
- this.storage.setString('pkceState', pkceState);
1443
- const codeVerifier = getRandomString();
1444
- this.storage.setString('codeVerifier', codeVerifier);
1445
- const arrayHash = yield encryptSHA256(codeVerifier);
1446
- const codeChallenge = arrayBufferToBase64(arrayHash).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
1447
- this.storage.setString('codeChallenge', codeChallenge);
1448
- });
1423
+ getUserConfiguration() {
1424
+ return __classPrivateFieldGet(this, _MedplumClient_config, "f");
1449
1425
  }
1450
1426
  /**
1451
- * Redirects the user to the login screen for authorization.
1452
- * Clears all auth state including local storage and session storage.
1453
- * See: https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
1427
+ * Downloads the URL as a blob.
1428
+ * @param url The URL to request.
1429
+ * @returns Promise to the response body as a blob.
1454
1430
  */
1455
- requestAuthorization() {
1431
+ download(url) {
1456
1432
  return __awaiter(this, void 0, void 0, function* () {
1457
- if (!this.authorizeUrl) {
1458
- throw new Error('Missing authorize URL');
1433
+ if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
1434
+ yield __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
1459
1435
  }
1460
- this.startPkce();
1461
- window.location.assign(this.authorizeUrl +
1462
- '?response_type=code' +
1463
- '&state=' +
1464
- encodeURIComponent(this.storage.getString('pkceState')) +
1465
- '&client_id=' +
1466
- encodeURIComponent(this.clientId) +
1467
- '&redirect_uri=' +
1468
- encodeURIComponent(getBaseUrl()) +
1469
- '&scope=' +
1470
- encodeURIComponent(DEFAULT_SCOPE) +
1471
- '&code_challenge_method=S256' +
1472
- '&code_challenge=' +
1473
- encodeURIComponent(this.storage.getString('codeChallenge')));
1436
+ const options = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_buildFetchOptions).call(this, 'GET');
1437
+ const response = yield __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, url, options);
1438
+ return response.blob();
1474
1439
  });
1475
1440
  }
1476
1441
  /**
@@ -1479,18 +1444,18 @@
1479
1444
  * @param code The authorization code received by URL parameter.
1480
1445
  */
1481
1446
  processCode(code) {
1482
- const pkceState = this.storage.getString('pkceState');
1447
+ const pkceState = __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('pkceState');
1483
1448
  if (!pkceState) {
1484
1449
  this.clear();
1485
1450
  throw new Error('Invalid PCKE state');
1486
1451
  }
1487
- const codeVerifier = this.storage.getString('codeVerifier');
1452
+ const codeVerifier = __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeVerifier');
1488
1453
  if (!codeVerifier) {
1489
1454
  this.clear();
1490
1455
  throw new Error('Invalid PCKE code verifier');
1491
1456
  }
1492
- return this.fetchTokens('grant_type=authorization_code' +
1493
- (this.clientId ? '&client_id=' + encodeURIComponent(this.clientId) : '') +
1457
+ return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchTokens).call(this, 'grant_type=authorization_code' +
1458
+ (__classPrivateFieldGet(this, _MedplumClient_clientId, "f") ? '&client_id=' + encodeURIComponent(__classPrivateFieldGet(this, _MedplumClient_clientId, "f")) : '') +
1494
1459
  '&code_verifier=' +
1495
1460
  encodeURIComponent(codeVerifier) +
1496
1461
  '&redirect_uri=' +
@@ -1498,102 +1463,185 @@
1498
1463
  '&code=' +
1499
1464
  encodeURIComponent(code));
1500
1465
  }
1501
- /**
1502
- * Tries to refresh the auth tokens.
1503
- * See: https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens
1504
- */
1505
- refresh() {
1506
- var _a;
1507
- return __awaiter(this, void 0, void 0, function* () {
1508
- if (this.refreshPromise) {
1509
- return this.refreshPromise;
1510
- }
1511
- const refreshToken = (_a = this.getActiveLogin()) === null || _a === void 0 ? void 0 : _a.refreshToken;
1512
- if (!refreshToken) {
1513
- this.clear();
1514
- return Promise.reject('Invalid refresh token');
1515
- }
1516
- this.refreshPromise = this.fetchTokens('grant_type=refresh_token' +
1517
- '&client_id=' +
1518
- encodeURIComponent(this.clientId) +
1519
- '&refresh_token=' +
1520
- encodeURIComponent(refreshToken));
1521
- yield this.refreshPromise;
1522
- });
1466
+ }
1467
+ _MedplumClient_fetch = new WeakMap(), _MedplumClient_storage = new WeakMap(), _MedplumClient_schema = new WeakMap(), _MedplumClient_resourceCache = new WeakMap(), _MedplumClient_baseUrl = new WeakMap(), _MedplumClient_clientId = new WeakMap(), _MedplumClient_authorizeUrl = new WeakMap(), _MedplumClient_tokenUrl = new WeakMap(), _MedplumClient_logoutUrl = new WeakMap(), _MedplumClient_onUnauthenticated = new WeakMap(), _MedplumClient_accessToken = new WeakMap(), _MedplumClient_refreshToken = new WeakMap(), _MedplumClient_refreshPromise = new WeakMap(), _MedplumClient_profilePromise = new WeakMap(), _MedplumClient_profile = new WeakMap(), _MedplumClient_config = new WeakMap(), _MedplumClient_instances = new WeakSet(), _MedplumClient_addLogin = function _MedplumClient_addLogin(newLogin) {
1468
+ const logins = this.getLogins().filter((login) => { var _a, _b; return ((_a = login.profile) === null || _a === void 0 ? void 0 : _a.reference) !== ((_b = newLogin.profile) === null || _b === void 0 ? void 0 : _b.reference); });
1469
+ logins.push(newLogin);
1470
+ __classPrivateFieldGet(this, _MedplumClient_storage, "f").setObject('logins', logins);
1471
+ }, _MedplumClient_refreshProfile = function _MedplumClient_refreshProfile() {
1472
+ return __awaiter(this, void 0, void 0, function* () {
1473
+ __classPrivateFieldSet(this, _MedplumClient_profilePromise, new Promise((resolve, reject) => {
1474
+ this.get('auth/me')
1475
+ .then((result) => {
1476
+ __classPrivateFieldSet(this, _MedplumClient_profilePromise, undefined, "f");
1477
+ __classPrivateFieldSet(this, _MedplumClient_profile, result.profile, "f");
1478
+ __classPrivateFieldSet(this, _MedplumClient_config, result.config, "f");
1479
+ this.dispatchEvent({ type: 'change' });
1480
+ resolve(__classPrivateFieldGet(this, _MedplumClient_profile, "f"));
1481
+ })
1482
+ .catch(reject);
1483
+ }), "f");
1484
+ return __classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
1485
+ });
1486
+ }, _MedplumClient_request = function _MedplumClient_request(method, url, contentType, body) {
1487
+ return __awaiter(this, void 0, void 0, function* () {
1488
+ if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
1489
+ yield __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
1490
+ }
1491
+ if (!url.startsWith('http')) {
1492
+ url = __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + url;
1493
+ }
1494
+ const options = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_buildFetchOptions).call(this, method, contentType, body);
1495
+ const response = yield __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, url, options);
1496
+ if (response.status === 401) {
1497
+ // Refresh and try again
1498
+ return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_handleUnauthenticated).call(this, method, url, contentType, body);
1499
+ }
1500
+ if (response.status === 204 || response.status === 304) {
1501
+ // No content or change
1502
+ return undefined;
1503
+ }
1504
+ const obj = yield response.json();
1505
+ if (obj.resourceType === 'OperationOutcome' && !isOk(obj)) {
1506
+ return Promise.reject(obj);
1507
+ }
1508
+ return obj;
1509
+ });
1510
+ }, _MedplumClient_buildFetchOptions = function _MedplumClient_buildFetchOptions(method, contentType, body) {
1511
+ const headers = {
1512
+ 'Content-Type': contentType || FHIR_CONTENT_TYPE,
1513
+ };
1514
+ if (__classPrivateFieldGet(this, _MedplumClient_accessToken, "f")) {
1515
+ headers['Authorization'] = 'Bearer ' + __classPrivateFieldGet(this, _MedplumClient_accessToken, "f");
1516
+ }
1517
+ const options = {
1518
+ method: method,
1519
+ cache: 'no-cache',
1520
+ credentials: 'include',
1521
+ headers,
1522
+ };
1523
+ if (body) {
1524
+ if (typeof body === 'string' || (typeof File !== 'undefined' && body instanceof File)) {
1525
+ options.body = body;
1526
+ }
1527
+ else {
1528
+ options.body = stringify(body);
1529
+ }
1523
1530
  }
1524
- /**
1525
- * Makes a POST request to the tokens endpoint.
1526
- * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
1527
- * @param formBody Token parameters in URL encoded format.
1528
- */
1529
- fetchTokens(formBody) {
1530
- return __awaiter(this, void 0, void 0, function* () {
1531
- if (!this.tokenUrl) {
1532
- return Promise.reject('Missing token URL');
1531
+ return options;
1532
+ }, _MedplumClient_handleUnauthenticated = function _MedplumClient_handleUnauthenticated(method, url, contentType, body) {
1533
+ return __awaiter(this, void 0, void 0, function* () {
1534
+ return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_refresh).call(this)
1535
+ .then(() => __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, method, url, contentType, body))
1536
+ .catch((error) => {
1537
+ this.clear();
1538
+ if (__classPrivateFieldGet(this, _MedplumClient_onUnauthenticated, "f")) {
1539
+ __classPrivateFieldGet(this, _MedplumClient_onUnauthenticated, "f").call(this);
1533
1540
  }
1534
- return this.fetch(this.tokenUrl, {
1535
- method: 'POST',
1536
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
1537
- body: formBody,
1538
- })
1539
- .then((response) => {
1540
- if (!response.ok) {
1541
- return Promise.reject('Failed to fetch tokens');
1542
- }
1543
- return response.json();
1544
- })
1545
- .then((tokens) => this.verifyTokens(tokens))
1546
- .then(() => this.getProfile());
1541
+ return Promise.reject(error);
1547
1542
  });
1548
- }
1549
- /**
1550
- * Verifies the tokens received from the auth server.
1551
- * Validates the JWT against the JWKS.
1552
- * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
1553
- * @param tokens
1554
- */
1555
- verifyTokens(tokens) {
1556
- return __awaiter(this, void 0, void 0, function* () {
1557
- const token = tokens.access_token;
1558
- // Verify token has not expired
1559
- const tokenPayload = parseJWTPayload(token);
1560
- if (Date.now() >= tokenPayload.exp * 1000) {
1561
- this.clear();
1562
- return Promise.reject('Token expired');
1543
+ });
1544
+ }, _MedplumClient_startPkce = function _MedplumClient_startPkce() {
1545
+ return __awaiter(this, void 0, void 0, function* () {
1546
+ const pkceState = getRandomString();
1547
+ __classPrivateFieldGet(this, _MedplumClient_storage, "f").setString('pkceState', pkceState);
1548
+ const codeVerifier = getRandomString();
1549
+ __classPrivateFieldGet(this, _MedplumClient_storage, "f").setString('codeVerifier', codeVerifier);
1550
+ const arrayHash = yield encryptSHA256(codeVerifier);
1551
+ const codeChallenge = arrayBufferToBase64(arrayHash).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
1552
+ __classPrivateFieldGet(this, _MedplumClient_storage, "f").setString('codeChallenge', codeChallenge);
1553
+ });
1554
+ }, _MedplumClient_requestAuthorization = function _MedplumClient_requestAuthorization() {
1555
+ return __awaiter(this, void 0, void 0, function* () {
1556
+ if (!__classPrivateFieldGet(this, _MedplumClient_authorizeUrl, "f")) {
1557
+ throw new Error('Missing authorize URL');
1558
+ }
1559
+ __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
1560
+ window.location.assign(__classPrivateFieldGet(this, _MedplumClient_authorizeUrl, "f") +
1561
+ '?response_type=code' +
1562
+ '&state=' +
1563
+ encodeURIComponent(__classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('pkceState')) +
1564
+ '&client_id=' +
1565
+ encodeURIComponent(__classPrivateFieldGet(this, _MedplumClient_clientId, "f")) +
1566
+ '&redirect_uri=' +
1567
+ encodeURIComponent(getBaseUrl()) +
1568
+ '&scope=' +
1569
+ encodeURIComponent(DEFAULT_SCOPE) +
1570
+ '&code_challenge_method=S256' +
1571
+ '&code_challenge=' +
1572
+ encodeURIComponent(__classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge')));
1573
+ });
1574
+ }, _MedplumClient_refresh = function _MedplumClient_refresh() {
1575
+ return __awaiter(this, void 0, void 0, function* () {
1576
+ if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
1577
+ return __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
1578
+ }
1579
+ if (!__classPrivateFieldGet(this, _MedplumClient_refreshToken, "f")) {
1580
+ this.clear();
1581
+ return Promise.reject('Invalid refresh token');
1582
+ }
1583
+ __classPrivateFieldSet(this, _MedplumClient_refreshPromise, __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchTokens).call(this, 'grant_type=refresh_token' +
1584
+ '&client_id=' +
1585
+ encodeURIComponent(__classPrivateFieldGet(this, _MedplumClient_clientId, "f")) +
1586
+ '&refresh_token=' +
1587
+ encodeURIComponent(__classPrivateFieldGet(this, _MedplumClient_refreshToken, "f"))), "f");
1588
+ yield __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
1589
+ });
1590
+ }, _MedplumClient_fetchTokens = function _MedplumClient_fetchTokens(formBody) {
1591
+ return __awaiter(this, void 0, void 0, function* () {
1592
+ if (!__classPrivateFieldGet(this, _MedplumClient_tokenUrl, "f")) {
1593
+ return Promise.reject('Missing token URL');
1594
+ }
1595
+ return __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, __classPrivateFieldGet(this, _MedplumClient_tokenUrl, "f"), {
1596
+ method: 'POST',
1597
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
1598
+ body: formBody,
1599
+ })
1600
+ .then((response) => {
1601
+ if (!response.ok) {
1602
+ return Promise.reject('Failed to fetch tokens');
1563
1603
  }
1564
- // Verify app_client_id
1565
- if (this.clientId && tokenPayload.client_id !== this.clientId) {
1566
- this.clear();
1567
- return Promise.reject('Token was not issued for this audience');
1604
+ return response.json();
1605
+ })
1606
+ .then((tokens) => __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_verifyTokens).call(this, tokens))
1607
+ .then(() => this.getProfile());
1608
+ });
1609
+ }, _MedplumClient_verifyTokens = function _MedplumClient_verifyTokens(tokens) {
1610
+ return __awaiter(this, void 0, void 0, function* () {
1611
+ const token = tokens.access_token;
1612
+ // Verify token has not expired
1613
+ const tokenPayload = parseJWTPayload(token);
1614
+ if (Date.now() >= tokenPayload.exp * 1000) {
1615
+ this.clear();
1616
+ return Promise.reject('Token expired');
1617
+ }
1618
+ // Verify app_client_id
1619
+ if (__classPrivateFieldGet(this, _MedplumClient_clientId, "f") && tokenPayload.client_id !== __classPrivateFieldGet(this, _MedplumClient_clientId, "f")) {
1620
+ this.clear();
1621
+ return Promise.reject('Token was not issued for this audience');
1622
+ }
1623
+ yield this.setActiveLogin({
1624
+ accessToken: token,
1625
+ refreshToken: tokens.refresh_token,
1626
+ project: tokens.project,
1627
+ profile: tokens.profile,
1628
+ });
1629
+ });
1630
+ }, _MedplumClient_setupStorageListener = function _MedplumClient_setupStorageListener() {
1631
+ try {
1632
+ window.addEventListener('storage', (e) => {
1633
+ if (e.key === null || e.key === 'activeLogin') {
1634
+ // Storage events fire when different tabs make changes.
1635
+ // On storage clear (key === null) or activeLogin change (key === 'activeLogin')
1636
+ // Refresh the page to ensure the active login is up to date.
1637
+ window.location.reload();
1568
1638
  }
1569
- yield this.setActiveLogin({
1570
- accessToken: token,
1571
- refreshToken: tokens.refresh_token,
1572
- project: tokens.project,
1573
- profile: tokens.profile,
1574
- });
1575
1639
  });
1576
1640
  }
1577
- /**
1578
- * Sets up a listener for window storage events.
1579
- * This synchronizes state across browser windows and browser tabs.
1580
- */
1581
- setupStorageListener() {
1582
- try {
1583
- window.addEventListener('storage', (e) => {
1584
- if (e.key === null || e.key === 'activeLogin') {
1585
- // Storage events fire when different tabs make changes.
1586
- // On storage clear (key === null) or activeLogin change (key === 'activeLogin')
1587
- // Refresh the page to ensure the active login is up to date.
1588
- window.location.reload();
1589
- }
1590
- });
1591
- }
1592
- catch (err) {
1593
- // Silently ignore if this environment does not support storage events
1594
- }
1641
+ catch (err) {
1642
+ // Silently ignore if this environment does not support storage events
1595
1643
  }
1596
- }
1644
+ };
1597
1645
  /**
1598
1646
  * Returns the base URL for the current page.
1599
1647
  */
@@ -1761,6 +1809,7 @@
1761
1809
  exports.notFound = notFound;
1762
1810
  exports.notModified = notModified;
1763
1811
  exports.parseSearchDefinition = parseSearchDefinition;
1812
+ exports.resolveId = resolveId;
1764
1813
  exports.stringify = stringify;
1765
1814
 
1766
1815
  Object.defineProperty(exports, '__esModule', { value: true });