@medplum/core 2.0.14 → 2.0.15

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 (52) hide show
  1. package/dist/cjs/index.cjs +1155 -1060
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.min.cjs +1 -1
  4. package/dist/esm/base64.mjs +33 -0
  5. package/dist/esm/base64.mjs.map +1 -0
  6. package/dist/esm/cache.mjs +17 -23
  7. package/dist/esm/cache.mjs.map +1 -1
  8. package/dist/esm/client.mjs +464 -395
  9. package/dist/esm/client.mjs.map +1 -1
  10. package/dist/esm/eventtarget.mjs +6 -11
  11. package/dist/esm/eventtarget.mjs.map +1 -1
  12. package/dist/esm/fhirlexer/parse.mjs +15 -23
  13. package/dist/esm/fhirlexer/parse.mjs.map +1 -1
  14. package/dist/esm/fhirlexer/tokenize.mjs +190 -180
  15. package/dist/esm/fhirlexer/tokenize.mjs.map +1 -1
  16. package/dist/esm/fhirmapper/parse.mjs +264 -252
  17. package/dist/esm/fhirmapper/parse.mjs.map +1 -1
  18. package/dist/esm/fhirmapper/tokenize.mjs +0 -1
  19. package/dist/esm/fhirmapper/tokenize.mjs.map +1 -1
  20. package/dist/esm/fhirpath/atoms.mjs +0 -1
  21. package/dist/esm/fhirpath/atoms.mjs.map +1 -1
  22. package/dist/esm/fhirpath/parse.mjs +0 -1
  23. package/dist/esm/fhirpath/parse.mjs.map +1 -1
  24. package/dist/esm/fhirpath/tokenize.mjs +0 -1
  25. package/dist/esm/fhirpath/tokenize.mjs.map +1 -1
  26. package/dist/esm/filter/parse.mjs +0 -2
  27. package/dist/esm/filter/parse.mjs.map +1 -1
  28. package/dist/esm/filter/tokenize.mjs +0 -1
  29. package/dist/esm/filter/tokenize.mjs.map +1 -1
  30. package/dist/esm/index.min.mjs +1 -1
  31. package/dist/esm/jwt.mjs +2 -9
  32. package/dist/esm/jwt.mjs.map +1 -1
  33. package/dist/esm/readablepromise.mjs +18 -23
  34. package/dist/esm/readablepromise.mjs.map +1 -1
  35. package/dist/esm/schema.mjs +146 -123
  36. package/dist/esm/schema.mjs.map +1 -1
  37. package/dist/esm/search/match.mjs +0 -2
  38. package/dist/esm/search/match.mjs.map +1 -1
  39. package/dist/esm/storage.mjs +13 -19
  40. package/dist/esm/storage.mjs.map +1 -1
  41. package/dist/types/base64.d.ts +14 -0
  42. package/dist/types/cache.d.ts +3 -1
  43. package/dist/types/client.d.ts +127 -1
  44. package/dist/types/eventtarget.d.ts +1 -1
  45. package/dist/types/fhirlexer/parse.d.ts +5 -2
  46. package/dist/types/fhirlexer/tokenize.d.ts +28 -1
  47. package/dist/types/readablepromise.d.ts +4 -1
  48. package/dist/types/schema.d.ts +33 -1
  49. package/dist/types/storage.d.ts +2 -2
  50. package/package.json +1 -1
  51. package/dist/esm/node_modules/tslib/tslib.es6.mjs +0 -30
  52. package/dist/esm/node_modules/tslib/tslib.es6.mjs.map +0 -1
@@ -38,52 +38,20 @@
38
38
  return value;
39
39
  }
40
40
 
41
- /******************************************************************************
42
- Copyright (c) Microsoft Corporation.
43
-
44
- Permission to use, copy, modify, and/or distribute this software for any
45
- purpose with or without fee is hereby granted.
46
-
47
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
48
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
49
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
50
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
51
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
52
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
53
- PERFORMANCE OF THIS SOFTWARE.
54
- ***************************************************************************** */
55
-
56
- function __classPrivateFieldGet(receiver, state, kind, f) {
57
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
58
- 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");
59
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
60
- }
61
-
62
- function __classPrivateFieldSet(receiver, state, value, kind, f) {
63
- if (kind === "m") throw new TypeError("Private method is not writable");
64
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
65
- 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");
66
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
67
- }
68
-
69
- var _LRUCache_instances, _LRUCache_max, _LRUCache_cache, _LRUCache_first;
70
41
  /**
71
42
  * LRU cache (least recently used)
72
43
  * Source: https://stackoverflow.com/a/46432113
73
44
  */
74
45
  class LRUCache {
75
46
  constructor(max = 10) {
76
- _LRUCache_instances.add(this);
77
- _LRUCache_max.set(this, void 0);
78
- _LRUCache_cache.set(this, void 0);
79
- __classPrivateFieldSet(this, _LRUCache_max, max, "f");
80
- __classPrivateFieldSet(this, _LRUCache_cache, new Map(), "f");
47
+ this.max = max;
48
+ this.cache = new Map();
81
49
  }
82
50
  /**
83
51
  * Deletes all values from the cache.
84
52
  */
85
53
  clear() {
86
- __classPrivateFieldGet(this, _LRUCache_cache, "f").clear();
54
+ this.cache.clear();
87
55
  }
88
56
  /**
89
57
  * Returns the value for the given key.
@@ -91,10 +59,10 @@
91
59
  * @returns The value if found; undefined otherwise.
92
60
  */
93
61
  get(key) {
94
- const item = __classPrivateFieldGet(this, _LRUCache_cache, "f").get(key);
62
+ const item = this.cache.get(key);
95
63
  if (item) {
96
- __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(key);
97
- __classPrivateFieldGet(this, _LRUCache_cache, "f").set(key, item);
64
+ this.cache.delete(key);
65
+ this.cache.set(key, item);
98
66
  }
99
67
  return item;
100
68
  }
@@ -104,33 +72,33 @@
104
72
  * @param val The value to set.
105
73
  */
106
74
  set(key, val) {
107
- if (__classPrivateFieldGet(this, _LRUCache_cache, "f").has(key)) {
108
- __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(key);
75
+ if (this.cache.has(key)) {
76
+ this.cache.delete(key);
109
77
  }
110
- else if (__classPrivateFieldGet(this, _LRUCache_cache, "f").size >= __classPrivateFieldGet(this, _LRUCache_max, "f")) {
111
- __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(__classPrivateFieldGet(this, _LRUCache_instances, "m", _LRUCache_first).call(this));
78
+ else if (this.cache.size >= this.max) {
79
+ this.cache.delete(this.first());
112
80
  }
113
- __classPrivateFieldGet(this, _LRUCache_cache, "f").set(key, val);
81
+ this.cache.set(key, val);
114
82
  }
115
83
  /**
116
84
  * Deletes the value for the given key.
117
85
  * @param key The key to delete.
118
86
  */
119
87
  delete(key) {
120
- __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(key);
88
+ this.cache.delete(key);
121
89
  }
122
90
  /**
123
91
  * Returns the list of all keys in the cache.
124
92
  * @returns The array of keys in the cache.
125
93
  */
126
94
  keys() {
127
- return __classPrivateFieldGet(this, _LRUCache_cache, "f").keys();
95
+ return this.cache.keys();
96
+ }
97
+ first() {
98
+ // This works because the Map class maintains ordered keys.
99
+ return this.cache.keys().next().value;
128
100
  }
129
101
  }
130
- _LRUCache_max = new WeakMap(), _LRUCache_cache = new WeakMap(), _LRUCache_instances = new WeakSet(), _LRUCache_first = function _LRUCache_first() {
131
- // This works because the Map class maintains ordered keys.
132
- return __classPrivateFieldGet(this, _LRUCache_cache, "f").keys().next().value;
133
- };
134
102
 
135
103
  /**
136
104
  * Formats a FHIR Address as a string.
@@ -1141,20 +1109,18 @@
1141
1109
  /*
1142
1110
  * Based on: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
1143
1111
  */
1144
- var _EventTarget_listeners;
1145
1112
  class EventTarget {
1146
1113
  constructor() {
1147
- _EventTarget_listeners.set(this, void 0);
1148
- __classPrivateFieldSet(this, _EventTarget_listeners, {}, "f");
1114
+ this.listeners = {};
1149
1115
  }
1150
1116
  addEventListener(type, callback) {
1151
- if (!__classPrivateFieldGet(this, _EventTarget_listeners, "f")[type]) {
1152
- __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type] = [];
1117
+ if (!this.listeners[type]) {
1118
+ this.listeners[type] = [];
1153
1119
  }
1154
- __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type].push(callback);
1120
+ this.listeners[type].push(callback);
1155
1121
  }
1156
1122
  removeEventListeneer(type, callback) {
1157
- const array = __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type];
1123
+ const array = this.listeners[type];
1158
1124
  if (!array) {
1159
1125
  return;
1160
1126
  }
@@ -1166,14 +1132,44 @@
1166
1132
  }
1167
1133
  }
1168
1134
  dispatchEvent(event) {
1169
- const array = __classPrivateFieldGet(this, _EventTarget_listeners, "f")[event.type];
1135
+ const array = this.listeners[event.type];
1170
1136
  if (array) {
1171
1137
  array.forEach((listener) => listener.call(this, event));
1172
1138
  }
1173
1139
  return !event.defaultPrevented;
1174
1140
  }
1175
1141
  }
1176
- _EventTarget_listeners = new WeakMap();
1142
+
1143
+ /**
1144
+ * Decodes a base64 string.
1145
+ * Handles both browser and Node environments.
1146
+ * @param data The base-64 encoded input string.
1147
+ * @returns The decoded string.
1148
+ */
1149
+ function decodeBase64(data) {
1150
+ if (typeof window !== 'undefined') {
1151
+ return window.atob(data);
1152
+ }
1153
+ if (typeof Buffer !== 'undefined') {
1154
+ return Buffer.from(data, 'base64').toString('binary');
1155
+ }
1156
+ throw new Error('Unable to decode base64');
1157
+ }
1158
+ /**
1159
+ * Encodes a base64 string.
1160
+ * Handles both browser and Node environments.
1161
+ * @param data The unencoded input string.
1162
+ * @returns The base-64 encoded string.
1163
+ */
1164
+ function encodeBase64(data) {
1165
+ if (typeof window !== 'undefined') {
1166
+ return window.btoa(data);
1167
+ }
1168
+ if (typeof Buffer !== 'undefined') {
1169
+ return Buffer.from(data, 'binary').toString('base64');
1170
+ }
1171
+ throw new Error('Unable to encode base64');
1172
+ }
1177
1173
 
1178
1174
  /**
1179
1175
  * Decodes a section of a JWT.
@@ -1190,15 +1186,6 @@
1190
1186
  const jsonPayload = decodeURIComponent(uriEncodedPayload);
1191
1187
  return JSON.parse(jsonPayload);
1192
1188
  }
1193
- function decodeBase64(data) {
1194
- if (typeof window !== 'undefined') {
1195
- return window.atob(data);
1196
- }
1197
- if (typeof Buffer !== 'undefined') {
1198
- return Buffer.from(data, 'base64').toString('binary');
1199
- }
1200
- throw new Error('Unable to decode base64');
1201
- }
1202
1189
  /**
1203
1190
  * Parses the JWT payload.
1204
1191
  * @param token JWT token
@@ -1460,7 +1447,7 @@
1460
1447
  return strs.length > 0 ? strs.join('; ') : 'Unknown error';
1461
1448
  }
1462
1449
 
1463
- var _ReadablePromise_suspender, _ReadablePromise_status, _ReadablePromise_response, _ReadablePromise_error, _a;
1450
+ var _a;
1464
1451
  /**
1465
1452
  * The ReadablePromise class wraps a request promise suitable for React Suspense.
1466
1453
  * See: https://blog.logrocket.com/react-suspense-data-fetching/#wrappromise-js
@@ -1469,33 +1456,30 @@
1469
1456
  class ReadablePromise {
1470
1457
  constructor(requestPromise) {
1471
1458
  this[_a] = 'ReadablePromise';
1472
- _ReadablePromise_suspender.set(this, void 0);
1473
- _ReadablePromise_status.set(this, 'pending');
1474
- _ReadablePromise_response.set(this, void 0);
1475
- _ReadablePromise_error.set(this, void 0);
1476
- __classPrivateFieldSet(this, _ReadablePromise_suspender, requestPromise.then((res) => {
1477
- __classPrivateFieldSet(this, _ReadablePromise_status, 'success', "f");
1478
- __classPrivateFieldSet(this, _ReadablePromise_response, res, "f");
1459
+ this.status = 'pending';
1460
+ this.suspender = requestPromise.then((res) => {
1461
+ this.status = 'success';
1462
+ this.response = res;
1479
1463
  return res;
1480
1464
  }, (err) => {
1481
- __classPrivateFieldSet(this, _ReadablePromise_status, 'error', "f");
1482
- __classPrivateFieldSet(this, _ReadablePromise_error, err, "f");
1465
+ this.status = 'error';
1466
+ this.error = err;
1483
1467
  throw err;
1484
- }), "f");
1468
+ });
1485
1469
  }
1486
1470
  /**
1487
1471
  * Returns true if the promise is pending.
1488
1472
  * @returns True if the Promise is pending.
1489
1473
  */
1490
1474
  isPending() {
1491
- return __classPrivateFieldGet(this, _ReadablePromise_status, "f") === 'pending';
1475
+ return this.status === 'pending';
1492
1476
  }
1493
1477
  /**
1494
1478
  * Returns true if the promise resolved successfully.
1495
1479
  * @returns True if the Promise resolved successfully.
1496
1480
  */
1497
1481
  isOk() {
1498
- return __classPrivateFieldGet(this, _ReadablePromise_status, "f") === 'success';
1482
+ return this.status === 'success';
1499
1483
  }
1500
1484
  /**
1501
1485
  * Attempts to read the value of the promise.
@@ -1505,13 +1489,13 @@
1505
1489
  * @returns The resolved value of the Promise.
1506
1490
  */
1507
1491
  read() {
1508
- switch (__classPrivateFieldGet(this, _ReadablePromise_status, "f")) {
1492
+ switch (this.status) {
1509
1493
  case 'pending':
1510
- throw __classPrivateFieldGet(this, _ReadablePromise_suspender, "f");
1494
+ throw this.suspender;
1511
1495
  case 'error':
1512
- throw __classPrivateFieldGet(this, _ReadablePromise_error, "f");
1496
+ throw this.error;
1513
1497
  default:
1514
- return __classPrivateFieldGet(this, _ReadablePromise_response, "f");
1498
+ return this.response;
1515
1499
  }
1516
1500
  }
1517
1501
  /**
@@ -1521,7 +1505,7 @@
1521
1505
  * @returns A Promise for the completion of which ever callback is executed.
1522
1506
  */
1523
1507
  then(onfulfilled, onrejected) {
1524
- return __classPrivateFieldGet(this, _ReadablePromise_suspender, "f").then(onfulfilled, onrejected);
1508
+ return this.suspender.then(onfulfilled, onrejected);
1525
1509
  }
1526
1510
  /**
1527
1511
  * Attaches a callback for only the rejection of the Promise.
@@ -1529,7 +1513,7 @@
1529
1513
  * @returns A Promise for the completion of the callback.
1530
1514
  */
1531
1515
  catch(onrejected) {
1532
- return __classPrivateFieldGet(this, _ReadablePromise_suspender, "f").catch(onrejected);
1516
+ return this.suspender.catch(onrejected);
1533
1517
  }
1534
1518
  /**
1535
1519
  * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
@@ -1538,12 +1522,11 @@
1538
1522
  * @returns A Promise for the completion of the callback.
1539
1523
  */
1540
1524
  finally(onfinally) {
1541
- return __classPrivateFieldGet(this, _ReadablePromise_suspender, "f").finally(onfinally);
1525
+ return this.suspender.finally(onfinally);
1542
1526
  }
1543
1527
  }
1544
- _ReadablePromise_suspender = new WeakMap(), _ReadablePromise_status = new WeakMap(), _ReadablePromise_response = new WeakMap(), _ReadablePromise_error = new WeakMap(), _a = Symbol.toStringTag;
1528
+ _a = Symbol.toStringTag;
1545
1529
 
1546
- var _ClientStorage_storage, _MemoryStorage_data;
1547
1530
  /**
1548
1531
  * The ClientStorage class is a utility class for storing strings and objects.
1549
1532
  *
@@ -1553,21 +1536,20 @@
1553
1536
  */
1554
1537
  class ClientStorage {
1555
1538
  constructor() {
1556
- _ClientStorage_storage.set(this, void 0);
1557
- __classPrivateFieldSet(this, _ClientStorage_storage, typeof localStorage !== 'undefined' ? localStorage : new MemoryStorage(), "f");
1539
+ this.storage = typeof localStorage !== 'undefined' ? localStorage : new MemoryStorage();
1558
1540
  }
1559
1541
  clear() {
1560
- __classPrivateFieldGet(this, _ClientStorage_storage, "f").clear();
1542
+ this.storage.clear();
1561
1543
  }
1562
1544
  getString(key) {
1563
- return __classPrivateFieldGet(this, _ClientStorage_storage, "f").getItem(key) || undefined;
1545
+ return this.storage.getItem(key) || undefined;
1564
1546
  }
1565
1547
  setString(key, value) {
1566
1548
  if (value) {
1567
- __classPrivateFieldGet(this, _ClientStorage_storage, "f").setItem(key, value);
1549
+ this.storage.setItem(key, value);
1568
1550
  }
1569
1551
  else {
1570
- __classPrivateFieldGet(this, _ClientStorage_storage, "f").removeItem(key);
1552
+ this.storage.removeItem(key);
1571
1553
  }
1572
1554
  }
1573
1555
  getObject(key) {
@@ -1578,58 +1560,55 @@
1578
1560
  this.setString(key, value ? stringify(value) : undefined);
1579
1561
  }
1580
1562
  }
1581
- _ClientStorage_storage = new WeakMap();
1582
1563
  /**
1583
1564
  * The MemoryStorage class is a minimal in-memory implementation of the Storage interface.
1584
1565
  */
1585
1566
  class MemoryStorage {
1586
1567
  constructor() {
1587
- _MemoryStorage_data.set(this, void 0);
1588
- __classPrivateFieldSet(this, _MemoryStorage_data, new Map(), "f");
1568
+ this.data = new Map();
1589
1569
  }
1590
1570
  /**
1591
1571
  * Returns the number of key/value pairs.
1592
1572
  */
1593
1573
  get length() {
1594
- return __classPrivateFieldGet(this, _MemoryStorage_data, "f").size;
1574
+ return this.data.size;
1595
1575
  }
1596
1576
  /**
1597
1577
  * Removes all key/value pairs, if there are any.
1598
1578
  */
1599
1579
  clear() {
1600
- __classPrivateFieldGet(this, _MemoryStorage_data, "f").clear();
1580
+ this.data.clear();
1601
1581
  }
1602
1582
  /**
1603
1583
  * Returns the current value associated with the given key, or null if the given key does not exist.
1604
1584
  */
1605
1585
  getItem(key) {
1606
- return __classPrivateFieldGet(this, _MemoryStorage_data, "f").get(key) ?? null;
1586
+ return this.data.get(key) ?? null;
1607
1587
  }
1608
1588
  /**
1609
1589
  * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
1610
1590
  */
1611
1591
  setItem(key, value) {
1612
1592
  if (value) {
1613
- __classPrivateFieldGet(this, _MemoryStorage_data, "f").set(key, value);
1593
+ this.data.set(key, value);
1614
1594
  }
1615
1595
  else {
1616
- __classPrivateFieldGet(this, _MemoryStorage_data, "f").delete(key);
1596
+ this.data.delete(key);
1617
1597
  }
1618
1598
  }
1619
1599
  /**
1620
1600
  * Removes the key/value pair with the given key, if a key/value pair with the given key exists.
1621
1601
  */
1622
1602
  removeItem(key) {
1623
- __classPrivateFieldGet(this, _MemoryStorage_data, "f").delete(key);
1603
+ this.data.delete(key);
1624
1604
  }
1625
1605
  /**
1626
1606
  * Returns the name of the nth key, or null if n is greater than or equal to the number of key/value pairs.
1627
1607
  */
1628
1608
  key(index) {
1629
- return Array.from(__classPrivateFieldGet(this, _MemoryStorage_data, "f").keys())[index];
1609
+ return Array.from(this.data.keys())[index];
1630
1610
  }
1631
1611
  }
1632
- _MemoryStorage_data = new WeakMap();
1633
1612
 
1634
1613
  var types = {
1635
1614
  Element: {
@@ -6402,9 +6381,7 @@
6402
6381
  const globalSchema = baseSchema;
6403
6382
 
6404
6383
  // PKCE auth based on:
6405
- // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
6406
- var _MedplumClient_instances, _MedplumClient_fetch, _MedplumClient_createPdf, _MedplumClient_storage, _MedplumClient_requestCache, _MedplumClient_cacheTime, _MedplumClient_baseUrl, _MedplumClient_fhirBaseUrl, _MedplumClient_authorizeUrl, _MedplumClient_tokenUrl, _MedplumClient_logoutUrl, _MedplumClient_exchangeUrl, _MedplumClient_onUnauthenticated, _MedplumClient_autoBatchTime, _MedplumClient_autoBatchQueue, _MedplumClient_clientId, _MedplumClient_clientSecret, _MedplumClient_autoBatchTimerId, _MedplumClient_accessToken, _MedplumClient_refreshToken, _MedplumClient_refreshPromise, _MedplumClient_profilePromise, _MedplumClient_profile, _MedplumClient_config, _MedplumClient_addLogin, _MedplumClient_refreshProfile, _MedplumClient_getCacheEntry, _MedplumClient_setCacheEntry, _MedplumClient_cacheResource, _MedplumClient_deleteCacheEntry, _MedplumClient_request, _MedplumClient_fetchWithRetry, _MedplumClient_executeAutoBatch, _MedplumClient_addFetchOptionsDefaults, _MedplumClient_setRequestContentType, _MedplumClient_setRequestBody, _MedplumClient_handleUnauthenticated, _MedplumClient_requestAuthorization, _MedplumClient_refresh, _MedplumClient_fetchTokens, _MedplumClient_verifyTokens, _MedplumClient_setupStorageListener;
6407
- const MEDPLUM_VERSION = "2.0.14-8c7457fd";
6384
+ const MEDPLUM_VERSION = "2.0.15-025c3c04";
6408
6385
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
6409
6386
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
6410
6387
  const DEFAULT_CACHE_TIME = 60000; // 60 seconds
@@ -6467,57 +6444,44 @@
6467
6444
  class MedplumClient extends EventTarget {
6468
6445
  constructor(options) {
6469
6446
  super();
6470
- _MedplumClient_instances.add(this);
6471
- _MedplumClient_fetch.set(this, void 0);
6472
- _MedplumClient_createPdf.set(this, void 0);
6473
- _MedplumClient_storage.set(this, void 0);
6474
- _MedplumClient_requestCache.set(this, void 0);
6475
- _MedplumClient_cacheTime.set(this, void 0);
6476
- _MedplumClient_baseUrl.set(this, void 0);
6477
- _MedplumClient_fhirBaseUrl.set(this, void 0);
6478
- _MedplumClient_authorizeUrl.set(this, void 0);
6479
- _MedplumClient_tokenUrl.set(this, void 0);
6480
- _MedplumClient_logoutUrl.set(this, void 0);
6481
- _MedplumClient_exchangeUrl.set(this, void 0);
6482
- _MedplumClient_onUnauthenticated.set(this, void 0);
6483
- _MedplumClient_autoBatchTime.set(this, void 0);
6484
- _MedplumClient_autoBatchQueue.set(this, void 0);
6485
- _MedplumClient_clientId.set(this, void 0);
6486
- _MedplumClient_clientSecret.set(this, void 0);
6487
- _MedplumClient_autoBatchTimerId.set(this, void 0);
6488
- _MedplumClient_accessToken.set(this, void 0);
6489
- _MedplumClient_refreshToken.set(this, void 0);
6490
- _MedplumClient_refreshPromise.set(this, void 0);
6491
- _MedplumClient_profilePromise.set(this, void 0);
6492
- _MedplumClient_profile.set(this, void 0);
6493
- _MedplumClient_config.set(this, void 0);
6494
6447
  if (options?.baseUrl) {
6495
6448
  if (!options.baseUrl.startsWith('http')) {
6496
6449
  throw new Error('Base URL must start with http or https');
6497
6450
  }
6498
6451
  }
6499
- __classPrivateFieldSet(this, _MedplumClient_fetch, options?.fetch || getDefaultFetch(), "f");
6500
- __classPrivateFieldSet(this, _MedplumClient_storage, options?.storage || new ClientStorage(), "f");
6501
- __classPrivateFieldSet(this, _MedplumClient_createPdf, options?.createPdf, "f");
6502
- __classPrivateFieldSet(this, _MedplumClient_requestCache, new LRUCache(options?.resourceCacheSize ?? DEFAULT_RESOURCE_CACHE_SIZE), "f");
6503
- __classPrivateFieldSet(this, _MedplumClient_cacheTime, options?.cacheTime ?? DEFAULT_CACHE_TIME, "f");
6504
- __classPrivateFieldSet(this, _MedplumClient_baseUrl, ensureTrailingSlash(options?.baseUrl) || DEFAULT_BASE_URL, "f");
6505
- __classPrivateFieldSet(this, _MedplumClient_fhirBaseUrl, __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + (ensureTrailingSlash(options?.fhirUrlPath) || 'fhir/R4/'), "f");
6506
- __classPrivateFieldSet(this, _MedplumClient_clientId, options?.clientId || '', "f");
6507
- __classPrivateFieldSet(this, _MedplumClient_authorizeUrl, options?.authorizeUrl || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/authorize', "f");
6508
- __classPrivateFieldSet(this, _MedplumClient_tokenUrl, options?.tokenUrl || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/token', "f");
6509
- __classPrivateFieldSet(this, _MedplumClient_logoutUrl, options?.logoutUrl || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/logout', "f");
6510
- __classPrivateFieldSet(this, _MedplumClient_exchangeUrl, __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'auth/exchange', "f");
6511
- __classPrivateFieldSet(this, _MedplumClient_onUnauthenticated, options?.onUnauthenticated, "f");
6512
- __classPrivateFieldSet(this, _MedplumClient_autoBatchTime, options?.autoBatchTime ?? 0, "f");
6513
- __classPrivateFieldSet(this, _MedplumClient_autoBatchQueue, [], "f");
6452
+ this.fetch = options?.fetch || getDefaultFetch();
6453
+ this.storage = options?.storage || new ClientStorage();
6454
+ this.createPdfImpl = options?.createPdf;
6455
+ this.baseUrl = ensureTrailingSlash(options?.baseUrl) || DEFAULT_BASE_URL;
6456
+ this.fhirBaseUrl = this.baseUrl + (ensureTrailingSlash(options?.fhirUrlPath) || 'fhir/R4/');
6457
+ this.clientId = options?.clientId || '';
6458
+ this.authorizeUrl = options?.authorizeUrl || this.baseUrl + 'oauth2/authorize';
6459
+ this.tokenUrl = options?.tokenUrl || this.baseUrl + 'oauth2/token';
6460
+ this.logoutUrl = options?.logoutUrl || this.baseUrl + 'oauth2/logout';
6461
+ this.exchangeUrl = this.baseUrl + 'auth/exchange';
6462
+ this.onUnauthenticated = options?.onUnauthenticated;
6463
+ this.cacheTime = options?.cacheTime ?? DEFAULT_CACHE_TIME;
6464
+ if (this.cacheTime > 0) {
6465
+ this.requestCache = new LRUCache(options?.resourceCacheSize ?? DEFAULT_RESOURCE_CACHE_SIZE);
6466
+ }
6467
+ else {
6468
+ this.requestCache = undefined;
6469
+ }
6470
+ if (options?.autoBatchTime) {
6471
+ this.autoBatchTime = options?.autoBatchTime ?? 0;
6472
+ this.autoBatchQueue = [];
6473
+ }
6474
+ else {
6475
+ this.autoBatchTime = 0;
6476
+ this.autoBatchQueue = undefined;
6477
+ }
6514
6478
  const activeLogin = this.getActiveLogin();
6515
6479
  if (activeLogin) {
6516
- __classPrivateFieldSet(this, _MedplumClient_accessToken, activeLogin.accessToken, "f");
6517
- __classPrivateFieldSet(this, _MedplumClient_refreshToken, activeLogin.refreshToken, "f");
6518
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_refreshProfile).call(this).catch(console.log);
6480
+ this.accessToken = activeLogin.accessToken;
6481
+ this.refreshToken = activeLogin.refreshToken;
6482
+ this.refreshProfile().catch(console.log);
6519
6483
  }
6520
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setupStorageListener).call(this);
6484
+ this.setupStorageListener();
6521
6485
  }
6522
6486
  /**
6523
6487
  * Returns the current base URL for all API requests.
@@ -6527,14 +6491,14 @@
6527
6491
  * @returns The current base URL for all API requests.
6528
6492
  */
6529
6493
  getBaseUrl() {
6530
- return __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f");
6494
+ return this.baseUrl;
6531
6495
  }
6532
6496
  /**
6533
6497
  * Clears all auth state including local storage and session storage.
6534
6498
  * @category Authentication
6535
6499
  */
6536
6500
  clear() {
6537
- __classPrivateFieldGet(this, _MedplumClient_storage, "f").clear();
6501
+ this.storage.clear();
6538
6502
  this.clearActiveLogin();
6539
6503
  }
6540
6504
  /**
@@ -6543,12 +6507,12 @@
6543
6507
  * @category Authentication
6544
6508
  */
6545
6509
  clearActiveLogin() {
6546
- __classPrivateFieldGet(this, _MedplumClient_storage, "f").setString('activeLogin', undefined);
6547
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").clear();
6548
- __classPrivateFieldSet(this, _MedplumClient_accessToken, undefined, "f");
6549
- __classPrivateFieldSet(this, _MedplumClient_refreshToken, undefined, "f");
6550
- __classPrivateFieldSet(this, _MedplumClient_profile, undefined, "f");
6551
- __classPrivateFieldSet(this, _MedplumClient_config, undefined, "f");
6510
+ this.storage.setString('activeLogin', undefined);
6511
+ this.requestCache?.clear();
6512
+ this.accessToken = undefined;
6513
+ this.refreshToken = undefined;
6514
+ this.profile = undefined;
6515
+ this.config = undefined;
6552
6516
  this.dispatchEvent({ type: 'change' });
6553
6517
  }
6554
6518
  /**
@@ -6558,7 +6522,7 @@
6558
6522
  */
6559
6523
  invalidateUrl(url) {
6560
6524
  url = url.toString();
6561
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").delete(url);
6525
+ this.requestCache?.delete(url);
6562
6526
  }
6563
6527
  /**
6564
6528
  * Invalidates all cached search results or cached requests for the given resourceType.
@@ -6567,9 +6531,11 @@
6567
6531
  */
6568
6532
  invalidateSearches(resourceType) {
6569
6533
  const url = 'fhir/R4/' + resourceType;
6570
- for (const key of __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").keys()) {
6571
- if (key.endsWith(url) || key.includes(url + '?')) {
6572
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").delete(key);
6534
+ if (this.requestCache) {
6535
+ for (const key of this.requestCache.keys()) {
6536
+ if (key.endsWith(url) || key.includes(url + '?')) {
6537
+ this.requestCache.delete(key);
6538
+ }
6573
6539
  }
6574
6540
  }
6575
6541
  }
@@ -6587,30 +6553,30 @@
6587
6553
  */
6588
6554
  get(url, options = {}) {
6589
6555
  url = url.toString();
6590
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, url, options);
6556
+ const cached = this.getCacheEntry(url, options);
6591
6557
  if (cached) {
6592
6558
  return cached.value;
6593
6559
  }
6594
6560
  let promise;
6595
- if (url.startsWith(__classPrivateFieldGet(this, _MedplumClient_fhirBaseUrl, "f")) && __classPrivateFieldGet(this, _MedplumClient_autoBatchTime, "f") > 0) {
6561
+ if (url.startsWith(this.fhirBaseUrl) && this.autoBatchQueue) {
6596
6562
  promise = new Promise((resolve, reject) => {
6597
- __classPrivateFieldGet(this, _MedplumClient_autoBatchQueue, "f").push({
6563
+ this.autoBatchQueue.push({
6598
6564
  method: 'GET',
6599
- url: url.replace(__classPrivateFieldGet(this, _MedplumClient_fhirBaseUrl, "f"), ''),
6565
+ url: url.replace(this.fhirBaseUrl, ''),
6600
6566
  options,
6601
6567
  resolve,
6602
6568
  reject,
6603
6569
  });
6604
- if (!__classPrivateFieldGet(this, _MedplumClient_autoBatchTimerId, "f")) {
6605
- __classPrivateFieldSet(this, _MedplumClient_autoBatchTimerId, setTimeout(() => __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_executeAutoBatch).call(this), __classPrivateFieldGet(this, _MedplumClient_autoBatchTime, "f")), "f");
6570
+ if (!this.autoBatchTimerId) {
6571
+ this.autoBatchTimerId = setTimeout(() => this.executeAutoBatch(), this.autoBatchTime);
6606
6572
  }
6607
6573
  });
6608
6574
  }
6609
6575
  else {
6610
- promise = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'GET', url, options);
6576
+ promise = this.request('GET', url, options);
6611
6577
  }
6612
6578
  const readablePromise = new ReadablePromise(promise);
6613
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, url, readablePromise);
6579
+ this.setCacheEntry(url, readablePromise);
6614
6580
  return readablePromise;
6615
6581
  }
6616
6582
  /**
@@ -6630,13 +6596,13 @@
6630
6596
  post(url, body, contentType, options = {}) {
6631
6597
  url = url.toString();
6632
6598
  if (body) {
6633
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestBody).call(this, options, body);
6599
+ this.setRequestBody(options, body);
6634
6600
  }
6635
6601
  if (contentType) {
6636
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestContentType).call(this, options, contentType);
6602
+ this.setRequestContentType(options, contentType);
6637
6603
  }
6638
6604
  this.invalidateUrl(url);
6639
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'POST', url, options);
6605
+ return this.request('POST', url, options);
6640
6606
  }
6641
6607
  /**
6642
6608
  * Makes an HTTP PUT request to the specified URL.
@@ -6655,13 +6621,13 @@
6655
6621
  put(url, body, contentType, options = {}) {
6656
6622
  url = url.toString();
6657
6623
  if (body) {
6658
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestBody).call(this, options, body);
6624
+ this.setRequestBody(options, body);
6659
6625
  }
6660
6626
  if (contentType) {
6661
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestContentType).call(this, options, contentType);
6627
+ this.setRequestContentType(options, contentType);
6662
6628
  }
6663
6629
  this.invalidateUrl(url);
6664
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'PUT', url, options);
6630
+ return this.request('PUT', url, options);
6665
6631
  }
6666
6632
  /**
6667
6633
  * Makes an HTTP PATCH request to the specified URL.
@@ -6678,10 +6644,10 @@
6678
6644
  */
6679
6645
  patch(url, operations, options = {}) {
6680
6646
  url = url.toString();
6681
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestBody).call(this, options, operations);
6682
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestContentType).call(this, options, PATCH_CONTENT_TYPE);
6647
+ this.setRequestBody(options, operations);
6648
+ this.setRequestContentType(options, PATCH_CONTENT_TYPE);
6683
6649
  this.invalidateUrl(url);
6684
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'PATCH', url, options);
6650
+ return this.request('PATCH', url, options);
6685
6651
  }
6686
6652
  /**
6687
6653
  * Makes an HTTP DELETE request to the specified URL.
@@ -6699,7 +6665,7 @@
6699
6665
  delete(url, options = {}) {
6700
6666
  url = url.toString();
6701
6667
  this.invalidateUrl(url);
6702
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'DELETE', url, options);
6668
+ return this.request('DELETE', url, options);
6703
6669
  }
6704
6670
  /**
6705
6671
  * Initiates a new user flow.
@@ -6751,7 +6717,7 @@
6751
6717
  async startLogin(loginRequest) {
6752
6718
  return this.post('auth/login', {
6753
6719
  ...(await this.ensureCodeChallenge(loginRequest)),
6754
- clientId: loginRequest.clientId ?? __classPrivateFieldGet(this, _MedplumClient_clientId, "f"),
6720
+ clientId: loginRequest.clientId ?? this.clientId,
6755
6721
  scope: loginRequest.scope,
6756
6722
  });
6757
6723
  }
@@ -6766,7 +6732,7 @@
6766
6732
  async startGoogleLogin(loginRequest) {
6767
6733
  return this.post('auth/google', {
6768
6734
  ...(await this.ensureCodeChallenge(loginRequest)),
6769
- clientId: loginRequest.clientId ?? __classPrivateFieldGet(this, _MedplumClient_clientId, "f"),
6735
+ clientId: loginRequest.clientId ?? this.clientId,
6770
6736
  scope: loginRequest.scope,
6771
6737
  });
6772
6738
  }
@@ -6790,7 +6756,7 @@
6790
6756
  * @category Authentication
6791
6757
  */
6792
6758
  async signOut() {
6793
- await this.post(__classPrivateFieldGet(this, _MedplumClient_logoutUrl, "f"), {});
6759
+ await this.post(this.logoutUrl, {});
6794
6760
  this.clear();
6795
6761
  }
6796
6762
  /**
@@ -6804,7 +6770,7 @@
6804
6770
  const urlParams = new URLSearchParams(window.location.search);
6805
6771
  const code = urlParams.get('code');
6806
6772
  if (!code) {
6807
- await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_requestAuthorization).call(this, loginParams);
6773
+ await this.requestAuthorization(loginParams);
6808
6774
  return undefined;
6809
6775
  }
6810
6776
  else {
@@ -6817,7 +6783,7 @@
6817
6783
  * @category Authentication
6818
6784
  */
6819
6785
  signOutWithRedirect() {
6820
- window.location.assign(__classPrivateFieldGet(this, _MedplumClient_logoutUrl, "f"));
6786
+ window.location.assign(this.logoutUrl);
6821
6787
  }
6822
6788
  /**
6823
6789
  * Initiates sign in with an external identity provider.
@@ -6838,15 +6804,15 @@
6838
6804
  * @category Authentication
6839
6805
  */
6840
6806
  async exchangeExternalAccessToken(token, clientId) {
6841
- clientId = clientId || __classPrivateFieldGet(this, _MedplumClient_clientId, "f");
6807
+ clientId = clientId || this.clientId;
6842
6808
  if (!clientId) {
6843
6809
  throw new Error('MedplumClient is missing clientId');
6844
6810
  }
6845
- const response = await __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, __classPrivateFieldGet(this, _MedplumClient_exchangeUrl, "f"), {
6811
+ const response = await this.fetch(this.exchangeUrl, {
6846
6812
  method: 'POST',
6847
6813
  headers: { 'Content-Type': 'application/json' },
6848
6814
  body: JSON.stringify({
6849
- clientId: __classPrivateFieldGet(this, _MedplumClient_clientId, "f"),
6815
+ clientId: this.clientId,
6850
6816
  externalAccessToken: token,
6851
6817
  }),
6852
6818
  credentials: 'include',
@@ -6856,7 +6822,7 @@
6856
6822
  throw new Error('Failed to fetch tokens');
6857
6823
  }
6858
6824
  const tokens = await response.json();
6859
- await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_verifyTokens).call(this, tokens);
6825
+ await this.verifyTokens(tokens);
6860
6826
  return this.getProfile();
6861
6827
  }
6862
6828
  /**
@@ -6885,7 +6851,7 @@
6885
6851
  * @returns The well-formed FHIR URL.
6886
6852
  */
6887
6853
  fhirUrl(...path) {
6888
- return new URL(__classPrivateFieldGet(this, _MedplumClient_fhirBaseUrl, "f") + path.join('/'));
6854
+ return new URL(this.fhirBaseUrl + path.join('/'));
6889
6855
  }
6890
6856
  /**
6891
6857
  * Builds a FHIR search URL from a search query or structured query object.
@@ -6953,7 +6919,7 @@
6953
6919
  search(resourceType, query, options = {}) {
6954
6920
  const url = this.fhirSearchUrl(resourceType, query);
6955
6921
  const cacheKey = url.toString() + '-search';
6956
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, options);
6922
+ const cached = this.getCacheEntry(cacheKey, options);
6957
6923
  if (cached) {
6958
6924
  return cached.value;
6959
6925
  }
@@ -6961,12 +6927,12 @@
6961
6927
  const bundle = await this.get(url, options);
6962
6928
  if (bundle.entry) {
6963
6929
  for (const entry of bundle.entry) {
6964
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_cacheResource).call(this, entry.resource);
6930
+ this.cacheResource(entry.resource);
6965
6931
  }
6966
6932
  }
6967
6933
  return bundle;
6968
6934
  })());
6969
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
6935
+ this.setCacheEntry(cacheKey, promise);
6970
6936
  return promise;
6971
6937
  }
6972
6938
  /**
@@ -6996,12 +6962,12 @@
6996
6962
  url.searchParams.set('_count', '1');
6997
6963
  url.searchParams.sort();
6998
6964
  const cacheKey = url.toString() + '-searchOne';
6999
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, options);
6965
+ const cached = this.getCacheEntry(cacheKey, options);
7000
6966
  if (cached) {
7001
6967
  return cached.value;
7002
6968
  }
7003
6969
  const promise = new ReadablePromise(this.search(resourceType, url.searchParams, options).then((b) => b.entry?.[0]?.resource));
7004
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
6970
+ this.setCacheEntry(cacheKey, promise);
7005
6971
  return promise;
7006
6972
  }
7007
6973
  /**
@@ -7029,12 +6995,12 @@
7029
6995
  searchResources(resourceType, query, options = {}) {
7030
6996
  const url = this.fhirSearchUrl(resourceType, query);
7031
6997
  const cacheKey = url.toString() + '-searchResources';
7032
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, options);
6998
+ const cached = this.getCacheEntry(cacheKey, options);
7033
6999
  if (cached) {
7034
7000
  return cached.value;
7035
7001
  }
7036
7002
  const promise = new ReadablePromise(this.search(resourceType, query, options).then((b) => b.entry?.map((e) => e.resource) ?? []));
7037
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
7003
+ this.setCacheEntry(cacheKey, promise);
7038
7004
  return promise;
7039
7005
  }
7040
7006
  /**
@@ -7095,7 +7061,7 @@
7095
7061
  * @returns The resource if it is available in the cache; undefined otherwise.
7096
7062
  */
7097
7063
  getCached(resourceType, id) {
7098
- const cached = __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").get(this.fhirUrl(resourceType, id).toString())?.value;
7064
+ const cached = this.requestCache?.get(this.fhirUrl(resourceType, id).toString())?.value;
7099
7065
  return cached && cached.isOk() ? cached.read() : undefined;
7100
7066
  }
7101
7067
  /**
@@ -7197,7 +7163,7 @@
7197
7163
  return Promise.resolve(globalSchema);
7198
7164
  }
7199
7165
  const cacheKey = resourceType + '-requestSchema';
7200
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, undefined);
7166
+ const cached = this.getCacheEntry(cacheKey, undefined);
7201
7167
  if (cached) {
7202
7168
  return cached.value;
7203
7169
  }
@@ -7240,7 +7206,7 @@
7240
7206
  }
7241
7207
  return globalSchema;
7242
7208
  })());
7243
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
7209
+ this.setCacheEntry(cacheKey, promise);
7244
7210
  return promise;
7245
7211
  }
7246
7212
  /**
@@ -7438,7 +7404,7 @@
7438
7404
  };
7439
7405
  xhr.open('POST', url);
7440
7406
  xhr.withCredentials = true;
7441
- xhr.setRequestHeader('Authorization', 'Bearer ' + __classPrivateFieldGet(this, _MedplumClient_accessToken, "f"));
7407
+ xhr.setRequestHeader('Authorization', 'Bearer ' + this.accessToken);
7442
7408
  xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, max-age=0');
7443
7409
  xhr.setRequestHeader('Content-Type', contentType);
7444
7410
  xhr.setRequestHeader('X-Medplum', 'extended');
@@ -7468,10 +7434,10 @@
7468
7434
  * @returns The result of the create operation.
7469
7435
  */
7470
7436
  async createPdf(docDefinition, filename, tableLayouts, fonts) {
7471
- if (!__classPrivateFieldGet(this, _MedplumClient_createPdf, "f")) {
7437
+ if (!this.createPdfImpl) {
7472
7438
  throw new Error('PDF creation not enabled');
7473
7439
  }
7474
- const blob = await __classPrivateFieldGet(this, _MedplumClient_createPdf, "f").call(this, docDefinition, tableLayouts, fonts);
7440
+ const blob = await this.createPdfImpl(docDefinition, tableLayouts, fonts);
7475
7441
  return this.createBinary(blob, filename, 'application/pdf');
7476
7442
  }
7477
7443
  /**
@@ -7549,7 +7515,7 @@
7549
7515
  // return result ?? resource;
7550
7516
  result = resource;
7551
7517
  }
7552
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_cacheResource).call(this, result);
7518
+ this.cacheResource(result);
7553
7519
  return result;
7554
7520
  }
7555
7521
  /**
@@ -7597,7 +7563,7 @@
7597
7563
  * @returns The result of the delete operation.
7598
7564
  */
7599
7565
  deleteResource(resourceType, id) {
7600
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_deleteCacheEntry).call(this, this.fhirUrl(resourceType, id).toString());
7566
+ this.deleteCacheEntry(this.fhirUrl(resourceType, id).toString());
7601
7567
  this.invalidateSearches(resourceType);
7602
7568
  return this.delete(this.fhirUrl(resourceType, id));
7603
7569
  }
@@ -7801,61 +7767,80 @@
7801
7767
  * @returns The Login State
7802
7768
  */
7803
7769
  getActiveLogin() {
7804
- return __classPrivateFieldGet(this, _MedplumClient_storage, "f").getObject('activeLogin');
7770
+ return this.storage.getObject('activeLogin');
7805
7771
  }
7806
7772
  /**
7807
7773
  * @category Authentication
7808
7774
  */
7809
7775
  async setActiveLogin(login) {
7810
7776
  this.clearActiveLogin();
7811
- __classPrivateFieldSet(this, _MedplumClient_accessToken, login.accessToken, "f");
7812
- __classPrivateFieldSet(this, _MedplumClient_refreshToken, login.refreshToken, "f");
7813
- __classPrivateFieldGet(this, _MedplumClient_storage, "f").setObject('activeLogin', login);
7814
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addLogin).call(this, login);
7815
- __classPrivateFieldSet(this, _MedplumClient_refreshPromise, undefined, "f");
7816
- await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_refreshProfile).call(this);
7777
+ this.accessToken = login.accessToken;
7778
+ this.refreshToken = login.refreshToken;
7779
+ this.storage.setObject('activeLogin', login);
7780
+ this.addLogin(login);
7781
+ this.refreshPromise = undefined;
7782
+ await this.refreshProfile();
7817
7783
  }
7818
7784
  /**
7819
7785
  * Returns the current access token.
7820
7786
  * @category Authentication
7821
7787
  */
7822
7788
  getAccessToken() {
7823
- return __classPrivateFieldGet(this, _MedplumClient_accessToken, "f");
7789
+ return this.accessToken;
7824
7790
  }
7825
7791
  /**
7826
7792
  * Sets the current access token.
7827
7793
  * @category Authentication
7828
7794
  */
7829
7795
  setAccessToken(accessToken) {
7830
- __classPrivateFieldSet(this, _MedplumClient_accessToken, accessToken, "f");
7831
- __classPrivateFieldSet(this, _MedplumClient_refreshToken, undefined, "f");
7832
- __classPrivateFieldSet(this, _MedplumClient_profile, undefined, "f");
7833
- __classPrivateFieldSet(this, _MedplumClient_config, undefined, "f");
7796
+ this.accessToken = accessToken;
7797
+ this.refreshToken = undefined;
7798
+ this.profile = undefined;
7799
+ this.config = undefined;
7834
7800
  }
7835
7801
  /**
7836
7802
  * @category Authentication
7837
7803
  */
7838
7804
  getLogins() {
7839
- return __classPrivateFieldGet(this, _MedplumClient_storage, "f").getObject('logins') ?? [];
7805
+ return this.storage.getObject('logins') ?? [];
7806
+ }
7807
+ addLogin(newLogin) {
7808
+ const logins = this.getLogins().filter((login) => login.profile?.reference !== newLogin.profile?.reference);
7809
+ logins.push(newLogin);
7810
+ this.storage.setObject('logins', logins);
7811
+ }
7812
+ async refreshProfile() {
7813
+ this.profilePromise = new Promise((resolve, reject) => {
7814
+ this.get('auth/me')
7815
+ .then((result) => {
7816
+ this.profilePromise = undefined;
7817
+ this.profile = result.profile;
7818
+ this.config = result.config;
7819
+ this.dispatchEvent({ type: 'change' });
7820
+ resolve(this.profile);
7821
+ })
7822
+ .catch(reject);
7823
+ });
7824
+ return this.profilePromise;
7840
7825
  }
7841
7826
  /**
7842
7827
  * @category Authentication
7843
7828
  */
7844
7829
  isLoading() {
7845
- return !!__classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
7830
+ return !!this.profilePromise;
7846
7831
  }
7847
7832
  /**
7848
7833
  * @category User Profile
7849
7834
  */
7850
7835
  getProfile() {
7851
- return __classPrivateFieldGet(this, _MedplumClient_profile, "f");
7836
+ return this.profile;
7852
7837
  }
7853
7838
  /**
7854
7839
  * @category User Profile
7855
7840
  */
7856
7841
  async getProfileAsync() {
7857
- if (__classPrivateFieldGet(this, _MedplumClient_profilePromise, "f")) {
7858
- await __classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
7842
+ if (this.profilePromise) {
7843
+ await this.profilePromise;
7859
7844
  }
7860
7845
  return this.getProfile();
7861
7846
  }
@@ -7863,7 +7848,7 @@
7863
7848
  * @category User Profile
7864
7849
  */
7865
7850
  getUserConfiguration() {
7866
- return __classPrivateFieldGet(this, _MedplumClient_config, "f");
7851
+ return this.config;
7867
7852
  }
7868
7853
  /**
7869
7854
  * Downloads the URL as a blob.
@@ -7873,13 +7858,234 @@
7873
7858
  * @returns Promise to the response body as a blob.
7874
7859
  */
7875
7860
  async download(url, options = {}) {
7876
- if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
7877
- await __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
7861
+ if (this.refreshPromise) {
7862
+ await this.refreshPromise;
7878
7863
  }
7879
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addFetchOptionsDefaults).call(this, options);
7880
- const response = await __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, url.toString(), options);
7864
+ this.addFetchOptionsDefaults(options);
7865
+ const response = await this.fetch(url.toString(), options);
7881
7866
  return response.blob();
7882
7867
  }
7868
+ //
7869
+ // Private helpers
7870
+ //
7871
+ /**
7872
+ * Returns the cache entry if available and not expired.
7873
+ * @param key The cache key to retrieve.
7874
+ * @param options Optional fetch options for cache settings.
7875
+ * @returns The cached entry if found.
7876
+ */
7877
+ getCacheEntry(key, options) {
7878
+ if (!this.requestCache || options?.cache === 'no-cache' || options?.cache === 'reload') {
7879
+ return undefined;
7880
+ }
7881
+ const entry = this.requestCache.get(key);
7882
+ if (!entry || entry.requestTime + this.cacheTime < Date.now()) {
7883
+ return undefined;
7884
+ }
7885
+ return entry;
7886
+ }
7887
+ /**
7888
+ * Adds a readable promise to the cache.
7889
+ * @param key The cache key to store.
7890
+ * @param value The readable promise to store.
7891
+ */
7892
+ setCacheEntry(key, value) {
7893
+ if (this.requestCache) {
7894
+ this.requestCache.set(key, { requestTime: Date.now(), value });
7895
+ }
7896
+ }
7897
+ /**
7898
+ * Adds a concrete value as the cache entry for the given resource.
7899
+ * This is used in cases where the resource is loaded indirectly.
7900
+ * For example, when a resource is loaded as part of a Bundle.
7901
+ * @param resource The resource to cache.
7902
+ */
7903
+ cacheResource(resource) {
7904
+ if (resource?.id) {
7905
+ this.setCacheEntry(this.fhirUrl(resource.resourceType, resource.id).toString(), new ReadablePromise(Promise.resolve(resource)));
7906
+ }
7907
+ }
7908
+ /**
7909
+ * Deletes a cache entry.
7910
+ * @param key The cache key to delete.
7911
+ */
7912
+ deleteCacheEntry(key) {
7913
+ if (this.requestCache) {
7914
+ this.requestCache.delete(key);
7915
+ }
7916
+ }
7917
+ /**
7918
+ * Makes an HTTP request.
7919
+ * @param {string} method
7920
+ * @param {string} url
7921
+ * @param {string=} contentType
7922
+ * @param {Object=} body
7923
+ */
7924
+ async request(method, url, options = {}) {
7925
+ if (this.refreshPromise) {
7926
+ await this.refreshPromise;
7927
+ }
7928
+ if (!url.startsWith('http')) {
7929
+ url = this.baseUrl + url;
7930
+ }
7931
+ options.method = method;
7932
+ this.addFetchOptionsDefaults(options);
7933
+ const response = await this.fetchWithRetry(url, options);
7934
+ if (response.status === 401) {
7935
+ // Refresh and try again
7936
+ return this.handleUnauthenticated(method, url, options);
7937
+ }
7938
+ if (response.status === 204 || response.status === 304) {
7939
+ // No content or change
7940
+ return undefined;
7941
+ }
7942
+ let obj = undefined;
7943
+ try {
7944
+ obj = await response.json();
7945
+ }
7946
+ catch (err) {
7947
+ console.error('Error parsing response', response.status, err);
7948
+ throw err;
7949
+ }
7950
+ if (response.status >= 400) {
7951
+ throw new OperationOutcomeError(normalizeOperationOutcome(obj));
7952
+ }
7953
+ return obj;
7954
+ }
7955
+ async fetchWithRetry(url, options) {
7956
+ const maxRetries = 3;
7957
+ const retryDelay = 200;
7958
+ let response = undefined;
7959
+ for (let retry = 0; retry < maxRetries; retry++) {
7960
+ response = (await this.fetch(url, options));
7961
+ if (response.status < 500) {
7962
+ return response;
7963
+ }
7964
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
7965
+ }
7966
+ return response;
7967
+ }
7968
+ /**
7969
+ * Executes a batch of requests that were automatically batched together.
7970
+ */
7971
+ async executeAutoBatch() {
7972
+ // Get the current queue
7973
+ const entries = [...this.autoBatchQueue];
7974
+ // Clear the queue
7975
+ this.autoBatchQueue.length = 0;
7976
+ // Clear the timer
7977
+ this.autoBatchTimerId = undefined;
7978
+ // If there is only one request in the batch, just execute it
7979
+ if (entries.length === 1) {
7980
+ const entry = entries[0];
7981
+ try {
7982
+ entry.resolve(await this.request(entry.method, this.fhirBaseUrl + entry.url, entry.options));
7983
+ }
7984
+ catch (err) {
7985
+ entry.reject(new OperationOutcomeError(normalizeOperationOutcome(err)));
7986
+ }
7987
+ return;
7988
+ }
7989
+ // Build the batch request
7990
+ const batch = {
7991
+ resourceType: 'Bundle',
7992
+ type: 'batch',
7993
+ entry: entries.map((e) => ({
7994
+ request: {
7995
+ method: e.method,
7996
+ url: e.url,
7997
+ },
7998
+ resource: e.options.body ? JSON.parse(e.options.body) : undefined,
7999
+ })),
8000
+ };
8001
+ // Execute the batch request
8002
+ const response = (await this.post('fhir/R4', batch));
8003
+ // Process the response
8004
+ for (let i = 0; i < entries.length; i++) {
8005
+ const entry = entries[i];
8006
+ const responseEntry = response.entry?.[i];
8007
+ if (responseEntry?.response?.outcome && !isOk(responseEntry.response.outcome)) {
8008
+ entry.reject(new OperationOutcomeError(responseEntry.response.outcome));
8009
+ }
8010
+ else {
8011
+ entry.resolve(responseEntry?.resource);
8012
+ }
8013
+ }
8014
+ }
8015
+ /**
8016
+ * Adds default options to the fetch options.
8017
+ * @param options The options to add defaults to.
8018
+ */
8019
+ addFetchOptionsDefaults(options) {
8020
+ let headers = options.headers;
8021
+ if (!headers) {
8022
+ headers = {};
8023
+ options.headers = headers;
8024
+ }
8025
+ headers['X-Medplum'] = 'extended';
8026
+ if (options.body && !headers['Content-Type']) {
8027
+ headers['Content-Type'] = FHIR_CONTENT_TYPE;
8028
+ }
8029
+ if (this.accessToken) {
8030
+ headers['Authorization'] = 'Bearer ' + this.accessToken;
8031
+ }
8032
+ if (this.basicAuth) {
8033
+ headers['Authorization'] = 'Basic ' + this.basicAuth;
8034
+ }
8035
+ if (!options.cache) {
8036
+ options.cache = 'no-cache';
8037
+ }
8038
+ if (!options.credentials) {
8039
+ options.credentials = 'include';
8040
+ }
8041
+ }
8042
+ /**
8043
+ * Sets the "Content-Type" header on fetch options.
8044
+ * @param options The fetch options.
8045
+ * @param contentType The new content type to set.
8046
+ */
8047
+ setRequestContentType(options, contentType) {
8048
+ if (!options.headers) {
8049
+ options.headers = {};
8050
+ }
8051
+ const headers = options.headers;
8052
+ headers['Content-Type'] = contentType;
8053
+ }
8054
+ /**
8055
+ * Sets the body on fetch options.
8056
+ * @param options The fetch options.
8057
+ * @param data The new content body.
8058
+ */
8059
+ setRequestBody(options, data) {
8060
+ if (typeof data === 'string' ||
8061
+ (typeof Blob !== 'undefined' && data instanceof Blob) ||
8062
+ (typeof File !== 'undefined' && data instanceof File) ||
8063
+ (typeof Uint8Array !== 'undefined' && data instanceof Uint8Array)) {
8064
+ options.body = data;
8065
+ }
8066
+ else if (data) {
8067
+ options.body = JSON.stringify(data);
8068
+ }
8069
+ }
8070
+ /**
8071
+ * Handles an unauthenticated response from the server.
8072
+ * First, tries to refresh the access token and retry the request.
8073
+ * Otherwise, calls unauthenticated callbacks and rejects.
8074
+ * @param method The HTTP method of the original request.
8075
+ * @param url The URL of the original request.
8076
+ * @param contentType The content type of the original request.
8077
+ * @param body The body of the original request.
8078
+ */
8079
+ handleUnauthenticated(method, url, options) {
8080
+ if (this.refresh()) {
8081
+ return this.request(method, url, options);
8082
+ }
8083
+ this.clearActiveLogin();
8084
+ if (this.onUnauthenticated) {
8085
+ this.onUnauthenticated();
8086
+ }
8087
+ return Promise.reject(new Error('Unauthenticated'));
8088
+ }
7883
8089
  /**
7884
8090
  * Starts a new PKCE flow.
7885
8091
  * These PKCE values are stateful, and must survive redirects and page refreshes.
@@ -7895,6 +8101,23 @@
7895
8101
  sessionStorage.setItem('codeChallenge', codeChallenge);
7896
8102
  return { codeChallengeMethod: 'S256', codeChallenge };
7897
8103
  }
8104
+ /**
8105
+ * Redirects the user to the login screen for authorization.
8106
+ * Clears all auth state including local storage and session storage.
8107
+ * See: https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
8108
+ */
8109
+ async requestAuthorization(loginParams) {
8110
+ const loginRequest = await this.ensureCodeChallenge(loginParams || {});
8111
+ const url = new URL(this.authorizeUrl);
8112
+ url.searchParams.set('response_type', 'code');
8113
+ url.searchParams.set('state', sessionStorage.getItem('pkceState'));
8114
+ url.searchParams.set('client_id', loginRequest.clientId || this.clientId);
8115
+ url.searchParams.set('redirect_uri', loginRequest.redirectUri || getWindowOrigin());
8116
+ url.searchParams.set('code_challenge_method', loginRequest.codeChallengeMethod);
8117
+ url.searchParams.set('code_challenge', loginRequest.codeChallenge);
8118
+ url.searchParams.set('scope', loginRequest.scope || 'openid profile');
8119
+ window.location.assign(url.toString());
8120
+ }
7898
8121
  /**
7899
8122
  * Processes an OAuth authorization code.
7900
8123
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
@@ -7906,7 +8129,7 @@
7906
8129
  const formBody = new URLSearchParams();
7907
8130
  formBody.set('grant_type', 'authorization_code');
7908
8131
  formBody.set('code', code);
7909
- formBody.set('client_id', loginParams?.clientId || __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
8132
+ formBody.set('client_id', loginParams?.clientId || this.clientId);
7910
8133
  formBody.set('redirect_uri', loginParams?.redirectUri || getWindowOrigin());
7911
8134
  if (typeof sessionStorage !== 'undefined') {
7912
8135
  const codeVerifier = sessionStorage.getItem('codeVerifier');
@@ -7914,7 +8137,29 @@
7914
8137
  formBody.set('code_verifier', codeVerifier);
7915
8138
  }
7916
8139
  }
7917
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchTokens).call(this, formBody);
8140
+ return this.fetchTokens(formBody);
8141
+ }
8142
+ /**
8143
+ * Tries to refresh the auth tokens.
8144
+ * See: https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens
8145
+ */
8146
+ refresh() {
8147
+ if (this.refreshPromise) {
8148
+ return this.refreshPromise;
8149
+ }
8150
+ if (this.refreshToken) {
8151
+ const formBody = new URLSearchParams();
8152
+ formBody.set('grant_type', 'refresh_token');
8153
+ formBody.set('client_id', this.clientId);
8154
+ formBody.set('refresh_token', this.refreshToken);
8155
+ this.refreshPromise = this.fetchTokens(formBody);
8156
+ return this.refreshPromise;
8157
+ }
8158
+ if (this.clientId && this.clientSecret) {
8159
+ this.refreshPromise = this.startClientLogin(this.clientId, this.clientSecret);
8160
+ return this.refreshPromise;
8161
+ }
8162
+ return undefined;
7918
8163
  }
7919
8164
  /**
7920
8165
  * Starts a new OAuth2 client credentials flow.
@@ -7925,13 +8170,24 @@
7925
8170
  * @returns Promise that resolves to the client profile.
7926
8171
  */
7927
8172
  async startClientLogin(clientId, clientSecret) {
7928
- __classPrivateFieldSet(this, _MedplumClient_clientId, clientId, "f");
7929
- __classPrivateFieldSet(this, _MedplumClient_clientSecret, clientSecret, "f");
8173
+ this.clientId = clientId;
8174
+ this.clientSecret = clientSecret;
7930
8175
  const formBody = new URLSearchParams();
7931
8176
  formBody.set('grant_type', 'client_credentials');
7932
8177
  formBody.set('client_id', clientId);
7933
8178
  formBody.set('client_secret', clientSecret);
7934
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchTokens).call(this, formBody);
8179
+ return this.fetchTokens(formBody);
8180
+ }
8181
+ /**
8182
+ * Sets the client ID and secret for basic auth.
8183
+ * @category Authentication
8184
+ * @param clientId The client ID.
8185
+ * @param clientSecret The client secret.
8186
+ */
8187
+ setBasicAuth(clientId, clientSecret) {
8188
+ this.clientId = clientId;
8189
+ this.clientSecret = clientSecret;
8190
+ this.basicAuth = encodeBase64(clientId + ':' + clientSecret);
7935
8191
  }
7936
8192
  /**
7937
8193
  * Invite a user to a project.
@@ -7942,280 +8198,72 @@
7942
8198
  async invite(projectId, body) {
7943
8199
  return this.post('admin/projects/' + projectId + '/invite', body);
7944
8200
  }
7945
- }
7946
- _MedplumClient_fetch = new WeakMap(), _MedplumClient_createPdf = new WeakMap(), _MedplumClient_storage = new WeakMap(), _MedplumClient_requestCache = new WeakMap(), _MedplumClient_cacheTime = new WeakMap(), _MedplumClient_baseUrl = new WeakMap(), _MedplumClient_fhirBaseUrl = new WeakMap(), _MedplumClient_authorizeUrl = new WeakMap(), _MedplumClient_tokenUrl = new WeakMap(), _MedplumClient_logoutUrl = new WeakMap(), _MedplumClient_exchangeUrl = new WeakMap(), _MedplumClient_onUnauthenticated = new WeakMap(), _MedplumClient_autoBatchTime = new WeakMap(), _MedplumClient_autoBatchQueue = new WeakMap(), _MedplumClient_clientId = new WeakMap(), _MedplumClient_clientSecret = new WeakMap(), _MedplumClient_autoBatchTimerId = 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) {
7947
- const logins = this.getLogins().filter((login) => login.profile?.reference !== newLogin.profile?.reference);
7948
- logins.push(newLogin);
7949
- __classPrivateFieldGet(this, _MedplumClient_storage, "f").setObject('logins', logins);
7950
- }, _MedplumClient_refreshProfile = async function _MedplumClient_refreshProfile() {
7951
- __classPrivateFieldSet(this, _MedplumClient_profilePromise, new Promise((resolve, reject) => {
7952
- this.get('auth/me')
7953
- .then((result) => {
7954
- __classPrivateFieldSet(this, _MedplumClient_profilePromise, undefined, "f");
7955
- __classPrivateFieldSet(this, _MedplumClient_profile, result.profile, "f");
7956
- __classPrivateFieldSet(this, _MedplumClient_config, result.config, "f");
7957
- this.dispatchEvent({ type: 'change' });
7958
- resolve(__classPrivateFieldGet(this, _MedplumClient_profile, "f"));
7959
- })
7960
- .catch(reject);
7961
- }), "f");
7962
- return __classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
7963
- }, _MedplumClient_getCacheEntry = function _MedplumClient_getCacheEntry(key, options) {
7964
- if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") <= 0 || options?.cache === 'no-cache' || options?.cache === 'reload') {
7965
- return undefined;
7966
- }
7967
- const entry = __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").get(key);
7968
- if (!entry || entry.requestTime + __classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") < Date.now()) {
7969
- return undefined;
7970
- }
7971
- return entry;
7972
- }, _MedplumClient_setCacheEntry = function _MedplumClient_setCacheEntry(key, value) {
7973
- if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
7974
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").set(key, { requestTime: Date.now(), value });
7975
- }
7976
- }, _MedplumClient_cacheResource = function _MedplumClient_cacheResource(resource) {
7977
- if (resource?.id) {
7978
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, this.fhirUrl(resource.resourceType, resource.id).toString(), new ReadablePromise(Promise.resolve(resource)));
7979
- }
7980
- }, _MedplumClient_deleteCacheEntry = function _MedplumClient_deleteCacheEntry(key) {
7981
- if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
7982
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").delete(key);
7983
- }
7984
- }, _MedplumClient_request =
7985
- /**
7986
- * Makes an HTTP request.
7987
- * @param {string} method
7988
- * @param {string} url
7989
- * @param {string=} contentType
7990
- * @param {Object=} body
7991
- */
7992
- async function _MedplumClient_request(method, url, options = {}) {
7993
- if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
7994
- await __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
7995
- }
7996
- if (!url.startsWith('http')) {
7997
- url = __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + url;
7998
- }
7999
- options.method = method;
8000
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addFetchOptionsDefaults).call(this, options);
8001
- const response = await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchWithRetry).call(this, url, options);
8002
- if (response.status === 401) {
8003
- // Refresh and try again
8004
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_handleUnauthenticated).call(this, method, url, options);
8201
+ /**
8202
+ * Makes a POST request to the tokens endpoint.
8203
+ * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8204
+ * @param formBody Token parameters in URL encoded format.
8205
+ */
8206
+ async fetchTokens(formBody) {
8207
+ const response = await this.fetch(this.tokenUrl, {
8208
+ method: 'POST',
8209
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
8210
+ body: formBody,
8211
+ credentials: 'include',
8212
+ });
8213
+ if (!response.ok) {
8214
+ this.clearActiveLogin();
8215
+ throw new Error('Failed to fetch tokens');
8216
+ }
8217
+ const tokens = await response.json();
8218
+ await this.verifyTokens(tokens);
8219
+ return this.getProfile();
8005
8220
  }
8006
- if (response.status === 204 || response.status === 304) {
8007
- // No content or change
8008
- return undefined;
8221
+ /**
8222
+ * Verifies the tokens received from the auth server.
8223
+ * Validates the JWT against the JWKS.
8224
+ * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8225
+ * @param tokens
8226
+ */
8227
+ async verifyTokens(tokens) {
8228
+ const token = tokens.access_token;
8229
+ // Verify token has not expired
8230
+ const tokenPayload = parseJWTPayload(token);
8231
+ if (Date.now() >= tokenPayload.exp * 1000) {
8232
+ this.clearActiveLogin();
8233
+ throw new Error('Token expired');
8234
+ }
8235
+ // Verify app_client_id
8236
+ if (this.clientId && tokenPayload.client_id !== this.clientId) {
8237
+ this.clearActiveLogin();
8238
+ throw new Error('Token was not issued for this audience');
8239
+ }
8240
+ return this.setActiveLogin({
8241
+ accessToken: token,
8242
+ refreshToken: tokens.refresh_token,
8243
+ project: tokens.project,
8244
+ profile: tokens.profile,
8245
+ });
8009
8246
  }
8010
- let obj = undefined;
8011
- try {
8012
- obj = await response.json();
8013
- }
8014
- catch (err) {
8015
- console.error('Error parsing response', response.status, err);
8016
- throw err;
8017
- }
8018
- if (response.status >= 400) {
8019
- throw new OperationOutcomeError(normalizeOperationOutcome(obj));
8020
- }
8021
- return obj;
8022
- }, _MedplumClient_fetchWithRetry = async function _MedplumClient_fetchWithRetry(url, options) {
8023
- const maxRetries = 3;
8024
- const retryDelay = 200;
8025
- let response = undefined;
8026
- for (let retry = 0; retry < maxRetries; retry++) {
8027
- response = (await __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, url, options));
8028
- if (response.status < 500) {
8029
- return response;
8030
- }
8031
- await new Promise((resolve) => setTimeout(resolve, retryDelay));
8032
- }
8033
- return response;
8034
- }, _MedplumClient_executeAutoBatch =
8035
- /**
8036
- * Executes a batch of requests that were automatically batched together.
8037
- */
8038
- async function _MedplumClient_executeAutoBatch() {
8039
- // Get the current queue
8040
- const entries = [...__classPrivateFieldGet(this, _MedplumClient_autoBatchQueue, "f")];
8041
- // Clear the queue
8042
- __classPrivateFieldGet(this, _MedplumClient_autoBatchQueue, "f").length = 0;
8043
- // Clear the timer
8044
- __classPrivateFieldSet(this, _MedplumClient_autoBatchTimerId, undefined, "f");
8045
- // If there is only one request in the batch, just execute it
8046
- if (entries.length === 1) {
8047
- const entry = entries[0];
8247
+ /**
8248
+ * Sets up a listener for window storage events.
8249
+ * This synchronizes state across browser windows and browser tabs.
8250
+ */
8251
+ setupStorageListener() {
8048
8252
  try {
8049
- entry.resolve(await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, entry.method, __classPrivateFieldGet(this, _MedplumClient_fhirBaseUrl, "f") + entry.url, entry.options));
8253
+ window.addEventListener('storage', (e) => {
8254
+ if (e.key === null || e.key === 'activeLogin') {
8255
+ // Storage events fire when different tabs make changes.
8256
+ // On storage clear (key === null) or activeLogin change (key === 'activeLogin')
8257
+ // Refresh the page to ensure the active login is up to date.
8258
+ window.location.reload();
8259
+ }
8260
+ });
8050
8261
  }
8051
8262
  catch (err) {
8052
- entry.reject(new OperationOutcomeError(normalizeOperationOutcome(err)));
8263
+ // Silently ignore if this environment does not support storage events
8053
8264
  }
8054
- return;
8055
8265
  }
8056
- // Build the batch request
8057
- const batch = {
8058
- resourceType: 'Bundle',
8059
- type: 'batch',
8060
- entry: entries.map((e) => ({
8061
- request: {
8062
- method: e.method,
8063
- url: e.url,
8064
- },
8065
- resource: e.options.body ? JSON.parse(e.options.body) : undefined,
8066
- })),
8067
- };
8068
- // Execute the batch request
8069
- const response = (await this.post('fhir/R4', batch));
8070
- // Process the response
8071
- for (let i = 0; i < entries.length; i++) {
8072
- const entry = entries[i];
8073
- const responseEntry = response.entry?.[i];
8074
- if (responseEntry?.response?.outcome && !isOk(responseEntry.response.outcome)) {
8075
- entry.reject(new OperationOutcomeError(responseEntry.response.outcome));
8076
- }
8077
- else {
8078
- entry.resolve(responseEntry?.resource);
8079
- }
8080
- }
8081
- }, _MedplumClient_addFetchOptionsDefaults = function _MedplumClient_addFetchOptionsDefaults(options) {
8082
- if (!options.headers) {
8083
- options.headers = {};
8084
- }
8085
- const headers = options.headers;
8086
- headers['X-Medplum'] = 'extended';
8087
- if (!headers['Content-Type']) {
8088
- headers['Content-Type'] = FHIR_CONTENT_TYPE;
8089
- }
8090
- if (__classPrivateFieldGet(this, _MedplumClient_accessToken, "f")) {
8091
- headers['Authorization'] = 'Bearer ' + __classPrivateFieldGet(this, _MedplumClient_accessToken, "f");
8092
- }
8093
- if (!options.cache) {
8094
- options.cache = 'no-cache';
8095
- }
8096
- if (!options.credentials) {
8097
- options.credentials = 'include';
8098
- }
8099
- }, _MedplumClient_setRequestContentType = function _MedplumClient_setRequestContentType(options, contentType) {
8100
- if (!options.headers) {
8101
- options.headers = {};
8102
- }
8103
- const headers = options.headers;
8104
- headers['Content-Type'] = contentType;
8105
- }, _MedplumClient_setRequestBody = function _MedplumClient_setRequestBody(options, data) {
8106
- if (typeof data === 'string' ||
8107
- (typeof Blob !== 'undefined' && data instanceof Blob) ||
8108
- (typeof File !== 'undefined' && data instanceof File) ||
8109
- (typeof Uint8Array !== 'undefined' && data instanceof Uint8Array)) {
8110
- options.body = data;
8111
- }
8112
- else if (data) {
8113
- options.body = JSON.stringify(data);
8114
- }
8115
- }, _MedplumClient_handleUnauthenticated = function _MedplumClient_handleUnauthenticated(method, url, options) {
8116
- if (__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_refresh).call(this)) {
8117
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, method, url, options);
8118
- }
8119
- this.clearActiveLogin();
8120
- if (__classPrivateFieldGet(this, _MedplumClient_onUnauthenticated, "f")) {
8121
- __classPrivateFieldGet(this, _MedplumClient_onUnauthenticated, "f").call(this);
8122
- }
8123
- return Promise.reject(new Error('Unauthenticated'));
8124
- }, _MedplumClient_requestAuthorization =
8125
- /**
8126
- * Redirects the user to the login screen for authorization.
8127
- * Clears all auth state including local storage and session storage.
8128
- * See: https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
8129
- */
8130
- async function _MedplumClient_requestAuthorization(loginParams) {
8131
- const loginRequest = await this.ensureCodeChallenge(loginParams || {});
8132
- const url = new URL(__classPrivateFieldGet(this, _MedplumClient_authorizeUrl, "f"));
8133
- url.searchParams.set('response_type', 'code');
8134
- url.searchParams.set('state', sessionStorage.getItem('pkceState'));
8135
- url.searchParams.set('client_id', loginRequest.clientId || __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
8136
- url.searchParams.set('redirect_uri', loginRequest.redirectUri || getWindowOrigin());
8137
- url.searchParams.set('code_challenge_method', loginRequest.codeChallengeMethod);
8138
- url.searchParams.set('code_challenge', loginRequest.codeChallenge);
8139
- url.searchParams.set('scope', loginRequest.scope || 'openid profile');
8140
- window.location.assign(url.toString());
8141
- }, _MedplumClient_refresh = function _MedplumClient_refresh() {
8142
- if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
8143
- return __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
8144
- }
8145
- if (__classPrivateFieldGet(this, _MedplumClient_refreshToken, "f")) {
8146
- const formBody = new URLSearchParams();
8147
- formBody.set('grant_type', 'refresh_token');
8148
- formBody.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
8149
- formBody.set('refresh_token', __classPrivateFieldGet(this, _MedplumClient_refreshToken, "f"));
8150
- __classPrivateFieldSet(this, _MedplumClient_refreshPromise, __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchTokens).call(this, formBody), "f");
8151
- return __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
8152
- }
8153
- if (__classPrivateFieldGet(this, _MedplumClient_clientId, "f") && __classPrivateFieldGet(this, _MedplumClient_clientSecret, "f")) {
8154
- __classPrivateFieldSet(this, _MedplumClient_refreshPromise, this.startClientLogin(__classPrivateFieldGet(this, _MedplumClient_clientId, "f"), __classPrivateFieldGet(this, _MedplumClient_clientSecret, "f")), "f");
8155
- return __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
8156
- }
8157
- return undefined;
8158
- }, _MedplumClient_fetchTokens =
8159
- /**
8160
- * Makes a POST request to the tokens endpoint.
8161
- * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8162
- * @param formBody Token parameters in URL encoded format.
8163
- */
8164
- async function _MedplumClient_fetchTokens(formBody) {
8165
- const response = await __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, __classPrivateFieldGet(this, _MedplumClient_tokenUrl, "f"), {
8166
- method: 'POST',
8167
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
8168
- body: formBody,
8169
- credentials: 'include',
8170
- });
8171
- if (!response.ok) {
8172
- this.clearActiveLogin();
8173
- throw new Error('Failed to fetch tokens');
8174
- }
8175
- const tokens = await response.json();
8176
- await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_verifyTokens).call(this, tokens);
8177
- return this.getProfile();
8178
- }, _MedplumClient_verifyTokens =
8179
- /**
8180
- * Verifies the tokens received from the auth server.
8181
- * Validates the JWT against the JWKS.
8182
- * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8183
- * @param tokens
8184
- */
8185
- async function _MedplumClient_verifyTokens(tokens) {
8186
- const token = tokens.access_token;
8187
- // Verify token has not expired
8188
- const tokenPayload = parseJWTPayload(token);
8189
- if (Date.now() >= tokenPayload.exp * 1000) {
8190
- this.clearActiveLogin();
8191
- throw new Error('Token expired');
8192
- }
8193
- // Verify app_client_id
8194
- if (__classPrivateFieldGet(this, _MedplumClient_clientId, "f") && tokenPayload.client_id !== __classPrivateFieldGet(this, _MedplumClient_clientId, "f")) {
8195
- this.clearActiveLogin();
8196
- throw new Error('Token was not issued for this audience');
8197
- }
8198
- return this.setActiveLogin({
8199
- accessToken: token,
8200
- refreshToken: tokens.refresh_token,
8201
- project: tokens.project,
8202
- profile: tokens.profile,
8203
- });
8204
- }, _MedplumClient_setupStorageListener = function _MedplumClient_setupStorageListener() {
8205
- try {
8206
- window.addEventListener('storage', (e) => {
8207
- if (e.key === null || e.key === 'activeLogin') {
8208
- // Storage events fire when different tabs make changes.
8209
- // On storage clear (key === null) or activeLogin change (key === 'activeLogin')
8210
- // Refresh the page to ensure the active login is up to date.
8211
- window.location.reload();
8212
- }
8213
- });
8214
- }
8215
- catch (err) {
8216
- // Silently ignore if this environment does not support storage events
8217
- }
8218
- };
8266
+ }
8219
8267
  /**
8220
8268
  * Returns the default fetch method.
8221
8269
  * The default fetch is currently only available in browser environments.
@@ -8245,7 +8293,6 @@
8245
8293
  return url.endsWith('/') ? url : url + '/';
8246
8294
  }
8247
8295
 
8248
- var _ParserBuilder_prefixParselets, _ParserBuilder_infixParselets, _Parser_tokens, _Parser_prefixParselets, _Parser_infixParselets;
8249
8296
  class PrefixOperatorAtom {
8250
8297
  constructor(operator, child) {
8251
8298
  this.operator = operator;
@@ -8267,15 +8314,15 @@
8267
8314
  }
8268
8315
  class ParserBuilder {
8269
8316
  constructor() {
8270
- _ParserBuilder_prefixParselets.set(this, {});
8271
- _ParserBuilder_infixParselets.set(this, {});
8317
+ this.prefixParselets = {};
8318
+ this.infixParselets = {};
8272
8319
  }
8273
8320
  registerInfix(tokenType, parselet) {
8274
- __classPrivateFieldGet(this, _ParserBuilder_infixParselets, "f")[tokenType] = parselet;
8321
+ this.infixParselets[tokenType] = parselet;
8275
8322
  return this;
8276
8323
  }
8277
8324
  registerPrefix(tokenType, parselet) {
8278
- __classPrivateFieldGet(this, _ParserBuilder_prefixParselets, "f")[tokenType] = parselet;
8325
+ this.prefixParselets[tokenType] = parselet;
8279
8326
  return this;
8280
8327
  }
8281
8328
  prefix(tokenType, precedence, builder) {
@@ -8296,21 +8343,17 @@
8296
8343
  });
8297
8344
  }
8298
8345
  construct(input) {
8299
- return new Parser(input, __classPrivateFieldGet(this, _ParserBuilder_prefixParselets, "f"), __classPrivateFieldGet(this, _ParserBuilder_infixParselets, "f"));
8346
+ return new Parser(input, this.prefixParselets, this.infixParselets);
8300
8347
  }
8301
8348
  }
8302
- _ParserBuilder_prefixParselets = new WeakMap(), _ParserBuilder_infixParselets = new WeakMap();
8303
8349
  class Parser {
8304
8350
  constructor(tokens, prefixParselets, infixParselets) {
8305
- _Parser_tokens.set(this, void 0);
8306
- _Parser_prefixParselets.set(this, void 0);
8307
- _Parser_infixParselets.set(this, void 0);
8308
- __classPrivateFieldSet(this, _Parser_tokens, tokens, "f");
8309
- __classPrivateFieldSet(this, _Parser_prefixParselets, prefixParselets, "f");
8310
- __classPrivateFieldSet(this, _Parser_infixParselets, infixParselets, "f");
8351
+ this.tokens = tokens;
8352
+ this.prefixParselets = prefixParselets;
8353
+ this.infixParselets = infixParselets;
8311
8354
  }
8312
8355
  hasMore() {
8313
- return __classPrivateFieldGet(this, _Parser_tokens, "f").length > 0;
8356
+ return this.tokens.length > 0;
8314
8357
  }
8315
8358
  match(expected) {
8316
8359
  const token = this.peek();
@@ -8322,7 +8365,7 @@
8322
8365
  }
8323
8366
  consumeAndParse(precedence = Infinity) {
8324
8367
  const token = this.consume();
8325
- const prefix = __classPrivateFieldGet(this, _Parser_prefixParselets, "f")[token.id];
8368
+ const prefix = this.prefixParselets[token.id];
8326
8369
  if (!prefix) {
8327
8370
  throw Error(`Parse error at "${token.value}" (line ${token.line}, column ${token.column}). No matching prefix parselet.`);
8328
8371
  }
@@ -8346,7 +8389,7 @@
8346
8389
  return Infinity;
8347
8390
  }
8348
8391
  consume(expectedId, expectedValue) {
8349
- if (!__classPrivateFieldGet(this, _Parser_tokens, "f").length) {
8392
+ if (!this.tokens.length) {
8350
8393
  throw Error('Cant consume unknown more tokens.');
8351
8394
  }
8352
8395
  if (expectedId && this.peek()?.id !== expectedId) {
@@ -8357,21 +8400,19 @@
8357
8400
  const actual = this.peek();
8358
8401
  throw Error(`Expected "${expectedValue}" but got "${actual.value}" at line ${actual.line} column ${actual.column}.`);
8359
8402
  }
8360
- return __classPrivateFieldGet(this, _Parser_tokens, "f").shift();
8403
+ return this.tokens.shift();
8361
8404
  }
8362
8405
  peek() {
8363
- return __classPrivateFieldGet(this, _Parser_tokens, "f").length > 0 ? __classPrivateFieldGet(this, _Parser_tokens, "f")[0] : undefined;
8406
+ return this.tokens.length > 0 ? this.tokens[0] : undefined;
8364
8407
  }
8365
8408
  removeComments() {
8366
- __classPrivateFieldSet(this, _Parser_tokens, __classPrivateFieldGet(this, _Parser_tokens, "f").filter((t) => t.id !== 'Comment'), "f");
8409
+ this.tokens = this.tokens.filter((t) => t.id !== 'Comment');
8367
8410
  }
8368
8411
  getInfixParselet(token) {
8369
- return __classPrivateFieldGet(this, _Parser_infixParselets, "f")[token.id === 'Symbol' ? token.value : token.id];
8412
+ return this.infixParselets[token.id === 'Symbol' ? token.value : token.id];
8370
8413
  }
8371
8414
  }
8372
- _Parser_tokens = new WeakMap(), _Parser_prefixParselets = new WeakMap(), _Parser_infixParselets = new WeakMap();
8373
8415
 
8374
- var _Tokenizer_instances, _Tokenizer_str, _Tokenizer_keywords, _Tokenizer_operators, _Tokenizer_dateTimeLiterals, _Tokenizer_symbolRegex, _Tokenizer_result, _Tokenizer_pos, _Tokenizer_markStack, _Tokenizer_prevToken, _Tokenizer_peekToken, _Tokenizer_consumeToken, _Tokenizer_consumeWhitespace, _Tokenizer_consumeMultiLineComment, _Tokenizer_consumeSingleLineComment, _Tokenizer_consumeString, _Tokenizer_consumeBacktickSymbol, _Tokenizer_consumeDateTime, _Tokenizer_consumeNumber, _Tokenizer_consumeSymbol, _Tokenizer_consumeOperator, _Tokenizer_consumeWhile, _Tokenizer_curr, _Tokenizer_prev, _Tokenizer_peek, _Tokenizer_mark, _Tokenizer_reset, _Tokenizer_advance, _Tokenizer_buildToken;
8375
8416
  const STANDARD_UNITS = [
8376
8417
  'year',
8377
8418
  'years',
@@ -8392,190 +8433,203 @@
8392
8433
  ];
8393
8434
  class Tokenizer {
8394
8435
  constructor(str, keywords, operators, options) {
8395
- _Tokenizer_instances.add(this);
8396
- _Tokenizer_str.set(this, void 0);
8397
- _Tokenizer_keywords.set(this, void 0);
8398
- _Tokenizer_operators.set(this, void 0);
8399
- _Tokenizer_dateTimeLiterals.set(this, void 0);
8400
- _Tokenizer_symbolRegex.set(this, void 0);
8401
- _Tokenizer_result.set(this, []);
8402
- _Tokenizer_pos.set(this, { index: 0, line: 1, column: 0 });
8403
- _Tokenizer_markStack.set(this, []);
8404
- __classPrivateFieldSet(this, _Tokenizer_str, str, "f");
8405
- __classPrivateFieldSet(this, _Tokenizer_keywords, keywords, "f");
8406
- __classPrivateFieldSet(this, _Tokenizer_operators, operators, "f");
8407
- __classPrivateFieldSet(this, _Tokenizer_dateTimeLiterals, !!options?.dateTimeLiterals, "f");
8408
- __classPrivateFieldSet(this, _Tokenizer_symbolRegex, options?.symbolRegex ?? /[$\w]/, "f");
8436
+ this.result = [];
8437
+ this.pos = { index: 0, line: 1, column: 0 };
8438
+ this.markStack = [];
8439
+ this.str = str;
8440
+ this.keywords = keywords;
8441
+ this.operators = operators;
8442
+ this.dateTimeLiterals = !!options?.dateTimeLiterals;
8443
+ this.symbolRegex = options?.symbolRegex ?? /[$\w]/;
8409
8444
  }
8410
8445
  tokenize() {
8411
- while (__classPrivateFieldGet(this, _Tokenizer_pos, "f").index < __classPrivateFieldGet(this, _Tokenizer_str, "f").length) {
8412
- const token = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeToken).call(this);
8446
+ while (this.pos.index < this.str.length) {
8447
+ const token = this.consumeToken();
8413
8448
  if (token) {
8414
- __classPrivateFieldGet(this, _Tokenizer_result, "f").push(token);
8449
+ this.result.push(token);
8415
8450
  }
8416
8451
  }
8417
- return __classPrivateFieldGet(this, _Tokenizer_result, "f");
8452
+ return this.result;
8418
8453
  }
8419
- }
8420
- _Tokenizer_str = new WeakMap(), _Tokenizer_keywords = new WeakMap(), _Tokenizer_operators = new WeakMap(), _Tokenizer_dateTimeLiterals = new WeakMap(), _Tokenizer_symbolRegex = new WeakMap(), _Tokenizer_result = new WeakMap(), _Tokenizer_pos = new WeakMap(), _Tokenizer_markStack = new WeakMap(), _Tokenizer_instances = new WeakSet(), _Tokenizer_prevToken = function _Tokenizer_prevToken() {
8421
- return __classPrivateFieldGet(this, _Tokenizer_result, "f").slice(-1)[0];
8422
- }, _Tokenizer_peekToken = function _Tokenizer_peekToken() {
8423
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_mark).call(this);
8424
- const token = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeToken).call(this);
8425
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_reset).call(this);
8426
- return token;
8427
- }, _Tokenizer_consumeToken = function _Tokenizer_consumeToken() {
8428
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhitespace).call(this);
8429
- const c = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this);
8430
- if (!c) {
8431
- return undefined;
8454
+ prevToken() {
8455
+ return this.result.slice(-1)[0];
8432
8456
  }
8433
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_mark).call(this);
8434
- const next = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this);
8435
- if (c === '/' && next === '*') {
8436
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeMultiLineComment).call(this);
8437
- }
8438
- if (c === '/' && next === '/') {
8439
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeSingleLineComment).call(this);
8440
- }
8441
- if (c === "'" || c === '"') {
8442
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeString).call(this, c);
8443
- }
8444
- if (c === '`') {
8445
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeBacktickSymbol).call(this);
8446
- }
8447
- if (c === '@') {
8448
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeDateTime).call(this);
8449
- }
8450
- if (c.match(/\d/)) {
8451
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeNumber).call(this);
8452
- }
8453
- if (c.match(/\w/)) {
8454
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeSymbol).call(this);
8455
- }
8456
- if (c === '$' && next.match(/\w/)) {
8457
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeSymbol).call(this);
8458
- }
8459
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeOperator).call(this);
8460
- }, _Tokenizer_consumeWhitespace = function _Tokenizer_consumeWhitespace() {
8461
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/\s/));
8462
- }, _Tokenizer_consumeMultiLineComment = function _Tokenizer_consumeMultiLineComment() {
8463
- const start = __classPrivateFieldGet(this, _Tokenizer_pos, "f").index;
8464
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) !== '*' || __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this) !== '/');
8465
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8466
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8467
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'Comment', __classPrivateFieldGet(this, _Tokenizer_str, "f").substring(start, __classPrivateFieldGet(this, _Tokenizer_pos, "f").index));
8468
- }, _Tokenizer_consumeSingleLineComment = function _Tokenizer_consumeSingleLineComment() {
8469
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'Comment', __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) !== '\n'));
8470
- }, _Tokenizer_consumeString = function _Tokenizer_consumeString(endChar) {
8471
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8472
- const result = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'String', __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_prev).call(this) === '\\' || __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) !== endChar));
8473
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8474
- return result;
8475
- }, _Tokenizer_consumeBacktickSymbol = function _Tokenizer_consumeBacktickSymbol() {
8476
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8477
- const result = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'Symbol', __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) !== '`'));
8478
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8479
- return result;
8480
- }, _Tokenizer_consumeDateTime = function _Tokenizer_consumeDateTime() {
8481
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this); // Consume "@"
8482
- const start = __classPrivateFieldGet(this, _Tokenizer_pos, "f").index;
8483
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/[\d-]/));
8484
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === 'T') {
8485
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8486
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/[\d:]/));
8487
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '.' && __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this).match(/\d/)) {
8488
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8489
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/\d/));
8490
- }
8491
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === 'Z') {
8492
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8493
- }
8494
- else if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '+' || __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '-') {
8495
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8496
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/[\d:]/));
8497
- }
8498
- }
8499
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'DateTime', __classPrivateFieldGet(this, _Tokenizer_str, "f").substring(start, __classPrivateFieldGet(this, _Tokenizer_pos, "f").index));
8500
- }, _Tokenizer_consumeNumber = function _Tokenizer_consumeNumber() {
8501
- const start = __classPrivateFieldGet(this, _Tokenizer_pos, "f").index;
8502
- let id = 'Number';
8503
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/\d/));
8504
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '.' && __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this).match(/\d/)) {
8505
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8506
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/\d/));
8507
- }
8508
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '-' && __classPrivateFieldGet(this, _Tokenizer_dateTimeLiterals, "f")) {
8509
- // Rewind to one character before the start, and then treat as dateTime literal.
8510
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").index = start - 1;
8511
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeDateTime).call(this);
8512
- }
8513
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === ' ') {
8514
- if (isUnitToken(__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peekToken).call(this))) {
8515
- id = 'Quantity';
8516
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeToken).call(this);
8517
- }
8518
- }
8519
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, id, __classPrivateFieldGet(this, _Tokenizer_str, "f").substring(start, __classPrivateFieldGet(this, _Tokenizer_pos, "f").index));
8520
- }, _Tokenizer_consumeSymbol = function _Tokenizer_consumeSymbol() {
8521
- const value = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(__classPrivateFieldGet(this, _Tokenizer_symbolRegex, "f")));
8522
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_prevToken).call(this)?.value !== '.' && __classPrivateFieldGet(this, _Tokenizer_keywords, "f").includes(value)) {
8523
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, value, value);
8524
- }
8525
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'Symbol', value);
8526
- }, _Tokenizer_consumeOperator = function _Tokenizer_consumeOperator() {
8527
- const c = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this);
8528
- const next = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this);
8529
- const twoCharOp = c + next;
8530
- if (__classPrivateFieldGet(this, _Tokenizer_operators, "f").includes(twoCharOp)) {
8531
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8532
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8533
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, twoCharOp, twoCharOp);
8534
- }
8535
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8536
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, c, c);
8537
- }, _Tokenizer_consumeWhile = function _Tokenizer_consumeWhile(condition) {
8538
- const start = __classPrivateFieldGet(this, _Tokenizer_pos, "f").index;
8539
- while (__classPrivateFieldGet(this, _Tokenizer_pos, "f").index < __classPrivateFieldGet(this, _Tokenizer_str, "f").length && condition()) {
8540
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8541
- }
8542
- return __classPrivateFieldGet(this, _Tokenizer_str, "f").substring(start, __classPrivateFieldGet(this, _Tokenizer_pos, "f").index);
8543
- }, _Tokenizer_curr = function _Tokenizer_curr() {
8544
- return __classPrivateFieldGet(this, _Tokenizer_str, "f")[__classPrivateFieldGet(this, _Tokenizer_pos, "f").index];
8545
- }, _Tokenizer_prev = function _Tokenizer_prev() {
8546
- return __classPrivateFieldGet(this, _Tokenizer_str, "f")[__classPrivateFieldGet(this, _Tokenizer_pos, "f").index - 1] ?? '';
8547
- }, _Tokenizer_peek = function _Tokenizer_peek() {
8548
- return __classPrivateFieldGet(this, _Tokenizer_str, "f")[__classPrivateFieldGet(this, _Tokenizer_pos, "f").index + 1] ?? '';
8549
- }, _Tokenizer_mark = function _Tokenizer_mark() {
8550
- __classPrivateFieldGet(this, _Tokenizer_markStack, "f").push({ ...__classPrivateFieldGet(this, _Tokenizer_pos, "f") });
8551
- }, _Tokenizer_reset = function _Tokenizer_reset() {
8552
- const mark = __classPrivateFieldGet(this, _Tokenizer_markStack, "f").pop();
8553
- if (!mark) {
8554
- throw new Error('No mark to reset to');
8555
- }
8556
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").index = mark.index;
8557
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").line = mark.line;
8558
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").column = mark.column;
8559
- }, _Tokenizer_advance = function _Tokenizer_advance() {
8560
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").index++;
8561
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '\n') {
8562
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").line++;
8563
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").column = 0;
8457
+ peekToken() {
8458
+ this.mark();
8459
+ const token = this.consumeToken();
8460
+ this.reset();
8461
+ return token;
8564
8462
  }
8565
- else {
8566
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").column++;
8463
+ consumeToken() {
8464
+ this.consumeWhitespace();
8465
+ const c = this.curr();
8466
+ if (!c) {
8467
+ return undefined;
8468
+ }
8469
+ this.mark();
8470
+ const next = this.peek();
8471
+ if (c === '/' && next === '*') {
8472
+ return this.consumeMultiLineComment();
8473
+ }
8474
+ if (c === '/' && next === '/') {
8475
+ return this.consumeSingleLineComment();
8476
+ }
8477
+ if (c === "'" || c === '"') {
8478
+ return this.consumeString(c);
8479
+ }
8480
+ if (c === '`') {
8481
+ return this.consumeBacktickSymbol();
8482
+ }
8483
+ if (c === '@') {
8484
+ return this.consumeDateTime();
8485
+ }
8486
+ if (c.match(/\d/)) {
8487
+ return this.consumeNumber();
8488
+ }
8489
+ if (c.match(/\w/)) {
8490
+ return this.consumeSymbol();
8491
+ }
8492
+ if (c === '$' && next.match(/\w/)) {
8493
+ return this.consumeSymbol();
8494
+ }
8495
+ return this.consumeOperator();
8567
8496
  }
8568
- }, _Tokenizer_buildToken = function _Tokenizer_buildToken(id, value) {
8569
- const mark = __classPrivateFieldGet(this, _Tokenizer_markStack, "f").pop();
8570
- if (!mark) {
8571
- throw new Error('No mark for token');
8497
+ consumeWhitespace() {
8498
+ this.consumeWhile(() => this.curr().match(/\s/));
8572
8499
  }
8573
- return {
8574
- id,
8575
- value,
8576
- ...mark,
8577
- };
8578
- };
8500
+ consumeMultiLineComment() {
8501
+ const start = this.pos.index;
8502
+ this.consumeWhile(() => this.curr() !== '*' || this.peek() !== '/');
8503
+ this.advance();
8504
+ this.advance();
8505
+ return this.buildToken('Comment', this.str.substring(start, this.pos.index));
8506
+ }
8507
+ consumeSingleLineComment() {
8508
+ return this.buildToken('Comment', this.consumeWhile(() => this.curr() !== '\n'));
8509
+ }
8510
+ consumeString(endChar) {
8511
+ this.advance();
8512
+ const result = this.buildToken('String', this.consumeWhile(() => this.prev() === '\\' || this.curr() !== endChar));
8513
+ this.advance();
8514
+ return result;
8515
+ }
8516
+ consumeBacktickSymbol() {
8517
+ this.advance();
8518
+ const result = this.buildToken('Symbol', this.consumeWhile(() => this.curr() !== '`'));
8519
+ this.advance();
8520
+ return result;
8521
+ }
8522
+ consumeDateTime() {
8523
+ this.advance(); // Consume "@"
8524
+ const start = this.pos.index;
8525
+ this.consumeWhile(() => this.curr().match(/[\d-]/));
8526
+ if (this.curr() === 'T') {
8527
+ this.advance();
8528
+ this.consumeWhile(() => this.curr().match(/[\d:]/));
8529
+ if (this.curr() === '.' && this.peek().match(/\d/)) {
8530
+ this.advance();
8531
+ this.consumeWhile(() => this.curr().match(/\d/));
8532
+ }
8533
+ if (this.curr() === 'Z') {
8534
+ this.advance();
8535
+ }
8536
+ else if (this.curr() === '+' || this.curr() === '-') {
8537
+ this.advance();
8538
+ this.consumeWhile(() => this.curr().match(/[\d:]/));
8539
+ }
8540
+ }
8541
+ return this.buildToken('DateTime', this.str.substring(start, this.pos.index));
8542
+ }
8543
+ consumeNumber() {
8544
+ const start = this.pos.index;
8545
+ let id = 'Number';
8546
+ this.consumeWhile(() => this.curr().match(/\d/));
8547
+ if (this.curr() === '.' && this.peek().match(/\d/)) {
8548
+ this.advance();
8549
+ this.consumeWhile(() => this.curr().match(/\d/));
8550
+ }
8551
+ if (this.curr() === '-' && this.dateTimeLiterals) {
8552
+ // Rewind to one character before the start, and then treat as dateTime literal.
8553
+ this.pos.index = start - 1;
8554
+ return this.consumeDateTime();
8555
+ }
8556
+ if (this.curr() === ' ') {
8557
+ if (isUnitToken(this.peekToken())) {
8558
+ id = 'Quantity';
8559
+ this.consumeToken();
8560
+ }
8561
+ }
8562
+ return this.buildToken(id, this.str.substring(start, this.pos.index));
8563
+ }
8564
+ consumeSymbol() {
8565
+ const value = this.consumeWhile(() => this.curr().match(this.symbolRegex));
8566
+ if (this.prevToken()?.value !== '.' && this.keywords.includes(value)) {
8567
+ return this.buildToken(value, value);
8568
+ }
8569
+ return this.buildToken('Symbol', value);
8570
+ }
8571
+ consumeOperator() {
8572
+ const c = this.curr();
8573
+ const next = this.peek();
8574
+ const twoCharOp = c + next;
8575
+ if (this.operators.includes(twoCharOp)) {
8576
+ this.advance();
8577
+ this.advance();
8578
+ return this.buildToken(twoCharOp, twoCharOp);
8579
+ }
8580
+ this.advance();
8581
+ return this.buildToken(c, c);
8582
+ }
8583
+ consumeWhile(condition) {
8584
+ const start = this.pos.index;
8585
+ while (this.pos.index < this.str.length && condition()) {
8586
+ this.advance();
8587
+ }
8588
+ return this.str.substring(start, this.pos.index);
8589
+ }
8590
+ curr() {
8591
+ return this.str[this.pos.index];
8592
+ }
8593
+ prev() {
8594
+ return this.str[this.pos.index - 1] ?? '';
8595
+ }
8596
+ peek() {
8597
+ return this.str[this.pos.index + 1] ?? '';
8598
+ }
8599
+ mark() {
8600
+ this.markStack.push({ ...this.pos });
8601
+ }
8602
+ reset() {
8603
+ const mark = this.markStack.pop();
8604
+ if (!mark) {
8605
+ throw new Error('No mark to reset to');
8606
+ }
8607
+ this.pos.index = mark.index;
8608
+ this.pos.line = mark.line;
8609
+ this.pos.column = mark.column;
8610
+ }
8611
+ advance() {
8612
+ this.pos.index++;
8613
+ if (this.curr() === '\n') {
8614
+ this.pos.line++;
8615
+ this.pos.column = 0;
8616
+ }
8617
+ else {
8618
+ this.pos.column++;
8619
+ }
8620
+ }
8621
+ buildToken(id, value) {
8622
+ const mark = this.markStack.pop();
8623
+ if (!mark) {
8624
+ throw new Error('No mark for token');
8625
+ }
8626
+ return {
8627
+ id,
8628
+ value,
8629
+ ...mark,
8630
+ };
8631
+ }
8632
+ }
8579
8633
  function isUnitToken(token) {
8580
8634
  if (token) {
8581
8635
  if (token.id === 'String') {
@@ -10960,10 +11014,8 @@
10960
11014
  return new Tokenizer(str, FHIRPATH_KEYWORDS, MAPPING_LANGUAGE_OPERATORS$1).tokenize();
10961
11015
  }
10962
11016
 
10963
- var _StructureMapParser_instances, _StructureMapParser_parseUses, _StructureMapParser_parseImport, _StructureMapParser_parseGroup, _StructureMapParser_parseParameters, _StructureMapParser_parseParameter, _StructureMapParser_parseRules, _StructureMapParser_parseRule, _StructureMapParser_parseRuleSources, _StructureMapParser_parseRuleSource, _StructureMapParser_parseRuleTargets, _StructureMapParser_parseRuleTarget, _StructureMapParser_parseRuleTargetTransform, _StructureMapParser_parseRuleTargetSymbol, _StructureMapParser_parseRuleTargetFunction, _StructureMapParser_parseRuleTargetLiteral, _StructureMapParser_parseRuleContext, _StructureMapParser_parseRuleDependents, _StructureMapParser_parseConceptMap;
10964
11017
  class StructureMapParser {
10965
11018
  constructor(parser) {
10966
- _StructureMapParser_instances.add(this);
10967
11019
  this.parser = parser;
10968
11020
  this.structureMap = { resourceType: 'StructureMap' };
10969
11021
  }
@@ -10978,16 +11030,16 @@
10978
11030
  const next = this.parser.peek()?.value;
10979
11031
  switch (next) {
10980
11032
  case 'uses':
10981
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseUses).call(this);
11033
+ this.parseUses();
10982
11034
  break;
10983
11035
  case 'imports':
10984
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseImport).call(this);
11036
+ this.parseImport();
10985
11037
  break;
10986
11038
  case 'group':
10987
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseGroup).call(this);
11039
+ this.parseGroup();
10988
11040
  break;
10989
11041
  case 'conceptmap':
10990
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseConceptMap).call(this);
11042
+ this.parseConceptMap();
10991
11043
  break;
10992
11044
  default:
10993
11045
  throw new Error(`Unexpected token: ${next}`);
@@ -10995,263 +11047,280 @@
10995
11047
  }
10996
11048
  return this.structureMap;
10997
11049
  }
10998
- }
10999
- _StructureMapParser_instances = new WeakSet(), _StructureMapParser_parseUses = function _StructureMapParser_parseUses() {
11000
- // 'uses' url structureAlias? 'as' modelMode
11001
- // uses "http://hl7.org/fhir/StructureDefinition/tutorial-left" as source
11002
- this.parser.consume('Symbol', 'uses');
11003
- const result = {};
11004
- result.url = this.parser.consume('String').value;
11005
- if (this.parser.peek()?.value === 'alias') {
11006
- this.parser.consume('Symbol', 'alias');
11007
- result.alias = this.parser.consume('Symbol').value;
11008
- }
11009
- this.parser.consume('Symbol', 'as');
11010
- result.mode = this.parser.consume().value;
11011
- if (!this.structureMap.structure) {
11012
- this.structureMap.structure = [];
11013
- }
11014
- this.structureMap.structure.push(result);
11015
- }, _StructureMapParser_parseImport = function _StructureMapParser_parseImport() {
11016
- this.parser.consume('Symbol', 'imports');
11017
- if (!this.structureMap.import) {
11018
- this.structureMap.import = [];
11019
- }
11020
- this.structureMap.import.push(this.parser.consume('String').value);
11021
- }, _StructureMapParser_parseGroup = function _StructureMapParser_parseGroup() {
11022
- // 'group' identifier parameters extends? typeMode? rules
11023
- // group tutorial(source src : TLeft, target tgt : TRight) {
11024
- const result = {};
11025
- this.parser.consume('Symbol', 'group');
11026
- result.name = this.parser.consume('Symbol').value;
11027
- result.input = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseParameters).call(this);
11028
- if (this.parser.peek()?.value === 'extends') {
11029
- this.parser.consume('Symbol', 'extends');
11030
- result.extends = this.parser.consume('Symbol').value;
11031
- }
11032
- if (this.parser.peek()?.value === '<<') {
11033
- this.parser.consume('<<');
11034
- result.typeMode = this.parser.consume().value;
11035
- if (this.parser.peek()?.value === '+') {
11036
- this.parser.consume('+');
11037
- result.typeMode = 'type-and-types';
11038
- }
11039
- this.parser.consume('>>');
11040
- }
11041
- else {
11042
- result.typeMode = 'none';
11043
- }
11044
- result.rule = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRules).call(this);
11045
- if (!this.structureMap.group) {
11046
- this.structureMap.group = [];
11047
- }
11048
- this.structureMap.group.push(result);
11049
- }, _StructureMapParser_parseParameters = function _StructureMapParser_parseParameters() {
11050
- const parameters = [];
11051
- this.parser.consume('(');
11052
- while (this.parser.hasMore() && this.parser.peek()?.value !== ')') {
11053
- parameters.push(__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseParameter).call(this));
11054
- if (this.parser.peek()?.value === ',') {
11055
- this.parser.consume(',');
11050
+ parseUses() {
11051
+ // 'uses' url structureAlias? 'as' modelMode
11052
+ // uses "http://hl7.org/fhir/StructureDefinition/tutorial-left" as source
11053
+ this.parser.consume('Symbol', 'uses');
11054
+ const result = {};
11055
+ result.url = this.parser.consume('String').value;
11056
+ if (this.parser.peek()?.value === 'alias') {
11057
+ this.parser.consume('Symbol', 'alias');
11058
+ result.alias = this.parser.consume('Symbol').value;
11056
11059
  }
11057
- }
11058
- this.parser.consume(')');
11059
- return parameters;
11060
- }, _StructureMapParser_parseParameter = function _StructureMapParser_parseParameter() {
11061
- // inputMode identifier type?
11062
- // ':' identifier
11063
- // source src : TLeft
11064
- const result = {};
11065
- result.mode = this.parser.consume().value;
11066
- result.name = this.parser.consume('Symbol').value;
11067
- if (this.parser.peek()?.value === ':') {
11068
- this.parser.consume(':');
11069
- result.type = this.parser.consume('Symbol').value;
11070
- }
11071
- return result;
11072
- }, _StructureMapParser_parseRules = function _StructureMapParser_parseRules() {
11073
- const rules = [];
11074
- this.parser.consume('{');
11075
- while (this.parser.hasMore() && this.parser.peek()?.value !== '}') {
11076
- rules.push(__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRule).call(this));
11077
- }
11078
- this.parser.consume('}');
11079
- return rules;
11080
- }, _StructureMapParser_parseRule = function _StructureMapParser_parseRule() {
11081
- const result = {
11082
- source: __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleSources).call(this),
11083
- };
11084
- if (this.parser.peek()?.value === '->') {
11085
- this.parser.consume('->');
11086
- result.target = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTargets).call(this);
11087
- }
11088
- if (this.parser.peek()?.value === 'then') {
11089
- this.parser.consume('Symbol', 'then');
11090
- if (this.parser.peek()?.id === '{') {
11091
- result.rule = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRules).call(this);
11060
+ this.parser.consume('Symbol', 'as');
11061
+ result.mode = this.parser.consume().value;
11062
+ if (!this.structureMap.structure) {
11063
+ this.structureMap.structure = [];
11064
+ }
11065
+ this.structureMap.structure.push(result);
11066
+ }
11067
+ parseImport() {
11068
+ this.parser.consume('Symbol', 'imports');
11069
+ if (!this.structureMap.import) {
11070
+ this.structureMap.import = [];
11071
+ }
11072
+ this.structureMap.import.push(this.parser.consume('String').value);
11073
+ }
11074
+ parseGroup() {
11075
+ // 'group' identifier parameters extends? typeMode? rules
11076
+ // group tutorial(source src : TLeft, target tgt : TRight) {
11077
+ const result = {};
11078
+ this.parser.consume('Symbol', 'group');
11079
+ result.name = this.parser.consume('Symbol').value;
11080
+ result.input = this.parseParameters();
11081
+ if (this.parser.peek()?.value === 'extends') {
11082
+ this.parser.consume('Symbol', 'extends');
11083
+ result.extends = this.parser.consume('Symbol').value;
11084
+ }
11085
+ if (this.parser.peek()?.value === '<<') {
11086
+ this.parser.consume('<<');
11087
+ result.typeMode = this.parser.consume().value;
11088
+ if (this.parser.peek()?.value === '+') {
11089
+ this.parser.consume('+');
11090
+ result.typeMode = 'type-and-types';
11091
+ }
11092
+ this.parser.consume('>>');
11092
11093
  }
11093
11094
  else {
11094
- result.dependent = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleDependents).call(this);
11095
+ result.typeMode = 'none';
11095
11096
  }
11097
+ result.rule = this.parseRules();
11098
+ if (!this.structureMap.group) {
11099
+ this.structureMap.group = [];
11100
+ }
11101
+ this.structureMap.group.push(result);
11096
11102
  }
11097
- if (this.parser.peek()?.id === 'String') {
11098
- result.name = this.parser.consume().value;
11099
- }
11100
- else {
11101
- result.name = result.source?.[0]?.element;
11102
- }
11103
- this.parser.consume(';');
11104
- return result;
11105
- }, _StructureMapParser_parseRuleSources = function _StructureMapParser_parseRuleSources() {
11106
- const sources = [__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleSource).call(this)];
11107
- while (this.parser.hasMore() && this.parser.peek()?.value === ',') {
11108
- this.parser.consume(',');
11109
- sources.push(__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleSource).call(this));
11110
- }
11111
- return sources;
11112
- }, _StructureMapParser_parseRuleSource = function _StructureMapParser_parseRuleSource() {
11113
- const result = {};
11114
- const context = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleContext).call(this);
11115
- if (context.includes('.')) {
11116
- const parts = context.split('.');
11117
- result.context = parts[0];
11118
- result.element = parts[1];
11119
- }
11120
- else {
11121
- result.context = context;
11122
- }
11123
- if (this.parser.hasMore() && this.parser.peek()?.value === ':') {
11124
- this.parser.consume(':');
11125
- result.type = this.parser.consume().value;
11126
- }
11127
- if (this.parser.hasMore() && this.parser.peek()?.value === 'default') {
11128
- this.parser.consume('default');
11129
- this.parser.consumeAndParse();
11130
- }
11131
- if (this.parser.peek()?.value === 'first' ||
11132
- this.parser.peek()?.value === 'not_first' ||
11133
- this.parser.peek()?.value === 'last' ||
11134
- this.parser.peek()?.value === 'not_last' ||
11135
- this.parser.peek()?.value === 'only_one') {
11136
- result.listMode = this.parser.consume().value;
11103
+ parseParameters() {
11104
+ const parameters = [];
11105
+ this.parser.consume('(');
11106
+ while (this.parser.hasMore() && this.parser.peek()?.value !== ')') {
11107
+ parameters.push(this.parseParameter());
11108
+ if (this.parser.peek()?.value === ',') {
11109
+ this.parser.consume(',');
11110
+ }
11111
+ }
11112
+ this.parser.consume(')');
11113
+ return parameters;
11137
11114
  }
11138
- if (this.parser.peek()?.value === 'as') {
11139
- this.parser.consume('Symbol', 'as');
11140
- result.variable = this.parser.consume().value;
11115
+ parseParameter() {
11116
+ // inputMode identifier type?
11117
+ // ':' identifier
11118
+ // source src : TLeft
11119
+ const result = {};
11120
+ result.mode = this.parser.consume().value;
11121
+ result.name = this.parser.consume('Symbol').value;
11122
+ if (this.parser.peek()?.value === ':') {
11123
+ this.parser.consume(':');
11124
+ result.type = this.parser.consume('Symbol').value;
11125
+ }
11126
+ return result;
11141
11127
  }
11142
- if (this.parser.peek()?.value === 'where') {
11143
- this.parser.consume('Symbol', 'where');
11144
- const whereFhirPath = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11145
- result.condition = whereFhirPath.toString();
11128
+ parseRules() {
11129
+ const rules = [];
11130
+ this.parser.consume('{');
11131
+ while (this.parser.hasMore() && this.parser.peek()?.value !== '}') {
11132
+ rules.push(this.parseRule());
11133
+ }
11134
+ this.parser.consume('}');
11135
+ return rules;
11136
+ }
11137
+ parseRule() {
11138
+ const result = {
11139
+ source: this.parseRuleSources(),
11140
+ };
11141
+ if (this.parser.peek()?.value === '->') {
11142
+ this.parser.consume('->');
11143
+ result.target = this.parseRuleTargets();
11144
+ }
11145
+ if (this.parser.peek()?.value === 'then') {
11146
+ this.parser.consume('Symbol', 'then');
11147
+ if (this.parser.peek()?.id === '{') {
11148
+ result.rule = this.parseRules();
11149
+ }
11150
+ else {
11151
+ result.dependent = this.parseRuleDependents();
11152
+ }
11153
+ }
11154
+ if (this.parser.peek()?.id === 'String') {
11155
+ result.name = this.parser.consume().value;
11156
+ }
11157
+ else {
11158
+ result.name = result.source?.[0]?.element;
11159
+ }
11160
+ this.parser.consume(';');
11161
+ return result;
11146
11162
  }
11147
- if (this.parser.peek()?.value === 'check') {
11148
- this.parser.consume('Symbol', 'check');
11149
- const checkFhirPath = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11150
- result.check = checkFhirPath.toString();
11163
+ parseRuleSources() {
11164
+ const sources = [this.parseRuleSource()];
11165
+ while (this.parser.hasMore() && this.parser.peek()?.value === ',') {
11166
+ this.parser.consume(',');
11167
+ sources.push(this.parseRuleSource());
11168
+ }
11169
+ return sources;
11151
11170
  }
11152
- return result;
11153
- }, _StructureMapParser_parseRuleTargets = function _StructureMapParser_parseRuleTargets() {
11154
- const targets = [__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTarget).call(this)];
11155
- while (this.parser.hasMore() && this.parser.peek()?.value === ',') {
11156
- this.parser.consume(',');
11157
- targets.push(__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTarget).call(this));
11158
- }
11159
- return targets;
11160
- }, _StructureMapParser_parseRuleTarget = function _StructureMapParser_parseRuleTarget() {
11161
- const result = {};
11162
- const context = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleContext).call(this);
11163
- if (context.includes('.')) {
11164
- const parts = context.split('.');
11165
- result.contextType = 'variable';
11166
- result.context = parts[0];
11167
- result.element = parts[1];
11171
+ parseRuleSource() {
11172
+ const result = {};
11173
+ const context = this.parseRuleContext();
11174
+ if (context.includes('.')) {
11175
+ const parts = context.split('.');
11176
+ result.context = parts[0];
11177
+ result.element = parts[1];
11178
+ }
11179
+ else {
11180
+ result.context = context;
11181
+ }
11182
+ if (this.parser.hasMore() && this.parser.peek()?.value === ':') {
11183
+ this.parser.consume(':');
11184
+ result.type = this.parser.consume().value;
11185
+ }
11186
+ if (this.parser.hasMore() && this.parser.peek()?.value === 'default') {
11187
+ this.parser.consume('default');
11188
+ this.parser.consumeAndParse();
11189
+ }
11190
+ if (this.parser.peek()?.value === 'first' ||
11191
+ this.parser.peek()?.value === 'not_first' ||
11192
+ this.parser.peek()?.value === 'last' ||
11193
+ this.parser.peek()?.value === 'not_last' ||
11194
+ this.parser.peek()?.value === 'only_one') {
11195
+ result.listMode = this.parser.consume().value;
11196
+ }
11197
+ if (this.parser.peek()?.value === 'as') {
11198
+ this.parser.consume('Symbol', 'as');
11199
+ result.variable = this.parser.consume().value;
11200
+ }
11201
+ if (this.parser.peek()?.value === 'where') {
11202
+ this.parser.consume('Symbol', 'where');
11203
+ const whereFhirPath = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11204
+ result.condition = whereFhirPath.toString();
11205
+ }
11206
+ if (this.parser.peek()?.value === 'check') {
11207
+ this.parser.consume('Symbol', 'check');
11208
+ const checkFhirPath = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11209
+ result.check = checkFhirPath.toString();
11210
+ }
11211
+ return result;
11168
11212
  }
11169
- else {
11170
- result.context = context;
11213
+ parseRuleTargets() {
11214
+ const targets = [this.parseRuleTarget()];
11215
+ while (this.parser.hasMore() && this.parser.peek()?.value === ',') {
11216
+ this.parser.consume(',');
11217
+ targets.push(this.parseRuleTarget());
11218
+ }
11219
+ return targets;
11171
11220
  }
11172
- if (this.parser.peek()?.value === '=') {
11173
- this.parser.consume('=');
11174
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTargetTransform).call(this, result);
11221
+ parseRuleTarget() {
11222
+ const result = {};
11223
+ const context = this.parseRuleContext();
11224
+ if (context.includes('.')) {
11225
+ const parts = context.split('.');
11226
+ result.contextType = 'variable';
11227
+ result.context = parts[0];
11228
+ result.element = parts[1];
11229
+ }
11230
+ else {
11231
+ result.context = context;
11232
+ }
11233
+ if (this.parser.peek()?.value === '=') {
11234
+ this.parser.consume('=');
11235
+ this.parseRuleTargetTransform(result);
11236
+ }
11237
+ if (this.parser.peek()?.value === 'as') {
11238
+ this.parser.consume('Symbol', 'as');
11239
+ result.variable = this.parser.consume().value;
11240
+ }
11241
+ if (this.parser.peek()?.value === 'first' ||
11242
+ this.parser.peek()?.value === 'share' ||
11243
+ this.parser.peek()?.value === 'last' ||
11244
+ this.parser.peek()?.value === 'collate') {
11245
+ result.listMode = [this.parser.consume().value];
11246
+ }
11247
+ return result;
11175
11248
  }
11176
- if (this.parser.peek()?.value === 'as') {
11177
- this.parser.consume('Symbol', 'as');
11178
- result.variable = this.parser.consume().value;
11249
+ parseRuleTargetTransform(result) {
11250
+ result.transform = 'copy';
11251
+ const transformFhirPath = this.parser.consumeAndParse(6 /* OperatorPrecedence.As */);
11252
+ if (transformFhirPath instanceof SymbolAtom) {
11253
+ this.parseRuleTargetSymbol(result, transformFhirPath);
11254
+ }
11255
+ else if (transformFhirPath instanceof FunctionAtom) {
11256
+ this.parseRuleTargetFunction(result, transformFhirPath);
11257
+ }
11258
+ else if (transformFhirPath instanceof LiteralAtom) {
11259
+ this.parseRuleTargetLiteral(result, transformFhirPath);
11260
+ }
11261
+ else {
11262
+ throw new Error(`Unexpected FHIRPath: ${transformFhirPath}`);
11263
+ }
11179
11264
  }
11180
- if (this.parser.peek()?.value === 'first' ||
11181
- this.parser.peek()?.value === 'share' ||
11182
- this.parser.peek()?.value === 'last' ||
11183
- this.parser.peek()?.value === 'collate') {
11184
- result.listMode = [this.parser.consume().value];
11265
+ parseRuleTargetSymbol(result, literalAtom) {
11266
+ result.parameter = [{ valueId: literalAtom.name }];
11185
11267
  }
11186
- return result;
11187
- }, _StructureMapParser_parseRuleTargetTransform = function _StructureMapParser_parseRuleTargetTransform(result) {
11188
- result.transform = 'copy';
11189
- const transformFhirPath = this.parser.consumeAndParse(6 /* OperatorPrecedence.As */);
11190
- if (transformFhirPath instanceof SymbolAtom) {
11191
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTargetSymbol).call(this, result, transformFhirPath);
11268
+ parseRuleTargetFunction(result, functionAtom) {
11269
+ const functionName = functionAtom.name;
11270
+ switch (functionName) {
11271
+ case 'create':
11272
+ result.parameter = [
11273
+ {
11274
+ valueString: (functionAtom.args?.[0]).value.value,
11275
+ },
11276
+ ];
11277
+ break;
11278
+ case 'translate':
11279
+ result.parameter = [{}];
11280
+ break;
11281
+ default:
11282
+ throw new Error('Unknown target function: ' + functionName);
11283
+ }
11192
11284
  }
11193
- else if (transformFhirPath instanceof FunctionAtom) {
11194
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTargetFunction).call(this, result, transformFhirPath);
11285
+ parseRuleTargetLiteral(result, literalAtom) {
11286
+ switch (literalAtom.value.type) {
11287
+ case 'boolean':
11288
+ result.parameter = [{ valueBoolean: literalAtom.value.value }];
11289
+ break;
11290
+ case 'decimal':
11291
+ result.parameter = [{ valueDecimal: literalAtom.value.value }];
11292
+ break;
11293
+ case 'string':
11294
+ result.parameter = [{ valueString: literalAtom.value.value }];
11295
+ break;
11296
+ default:
11297
+ throw new Error('Unknown target literal type: ' + literalAtom.value.type);
11298
+ }
11195
11299
  }
11196
- else if (transformFhirPath instanceof LiteralAtom) {
11197
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTargetLiteral).call(this, result, transformFhirPath);
11300
+ parseRuleContext() {
11301
+ let identifier = this.parser.consume().value;
11302
+ while (this.parser.peek()?.value === '.') {
11303
+ this.parser.consume('.');
11304
+ identifier += '.' + this.parser.consume().value;
11305
+ }
11306
+ return identifier;
11198
11307
  }
11199
- else {
11200
- throw new Error(`Unexpected FHIRPath: ${transformFhirPath}`);
11201
- }
11202
- }, _StructureMapParser_parseRuleTargetSymbol = function _StructureMapParser_parseRuleTargetSymbol(result, literalAtom) {
11203
- result.parameter = [{ valueId: literalAtom.name }];
11204
- }, _StructureMapParser_parseRuleTargetFunction = function _StructureMapParser_parseRuleTargetFunction(result, functionAtom) {
11205
- const functionName = functionAtom.name;
11206
- switch (functionName) {
11207
- case 'create':
11208
- result.parameter = [
11209
- {
11210
- valueString: (functionAtom.args?.[0]).value.value,
11211
- },
11212
- ];
11213
- break;
11214
- case 'translate':
11215
- result.parameter = [{}];
11216
- break;
11217
- default:
11218
- throw new Error('Unknown target function: ' + functionName);
11308
+ parseRuleDependents() {
11309
+ const atom = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11310
+ return [
11311
+ {
11312
+ name: atom.name,
11313
+ variable: atom.args.map((arg) => arg.name),
11314
+ },
11315
+ ];
11219
11316
  }
11220
- }, _StructureMapParser_parseRuleTargetLiteral = function _StructureMapParser_parseRuleTargetLiteral(result, literalAtom) {
11221
- switch (literalAtom.value.type) {
11222
- case 'boolean':
11223
- result.parameter = [{ valueBoolean: literalAtom.value.value }];
11224
- break;
11225
- case 'decimal':
11226
- result.parameter = [{ valueDecimal: literalAtom.value.value }];
11227
- break;
11228
- case 'string':
11229
- result.parameter = [{ valueString: literalAtom.value.value }];
11230
- break;
11231
- default:
11232
- throw new Error('Unknown target literal type: ' + literalAtom.value.type);
11233
- }
11234
- }, _StructureMapParser_parseRuleContext = function _StructureMapParser_parseRuleContext() {
11235
- let identifier = this.parser.consume().value;
11236
- while (this.parser.peek()?.value === '.') {
11237
- this.parser.consume('.');
11238
- identifier += '.' + this.parser.consume().value;
11239
- }
11240
- return identifier;
11241
- }, _StructureMapParser_parseRuleDependents = function _StructureMapParser_parseRuleDependents() {
11242
- const atom = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11243
- return [
11244
- {
11245
- name: atom.name,
11246
- variable: atom.args.map((arg) => arg.name),
11247
- },
11248
- ];
11249
- }, _StructureMapParser_parseConceptMap = function _StructureMapParser_parseConceptMap() {
11250
- while (this.parser.peek()?.value !== '}') {
11251
- this.parser.consume();
11317
+ parseConceptMap() {
11318
+ while (this.parser.peek()?.value !== '}') {
11319
+ this.parser.consume();
11320
+ }
11321
+ this.parser.consume('}');
11252
11322
  }
11253
- this.parser.consume('}');
11254
- };
11323
+ }
11255
11324
  const fhirPathParserBuilder$1 = initFhirPathParserBuilder()
11256
11325
  .registerInfix('->', { precedence: 100 /* OperatorPrecedence.Arrow */ })
11257
11326
  .registerInfix(';', { precedence: 200 /* OperatorPrecedence.Semicolon */ });
@@ -11562,7 +11631,6 @@
11562
11631
  }
11563
11632
  }
11564
11633
 
11565
- var _FhirSchemaValidator_instances, _FhirSchemaValidator_issues, _FhirSchemaValidator_root, _FhirSchemaValidator_validateObject, _FhirSchemaValidator_checkProperties, _FhirSchemaValidator_checkProperty, _FhirSchemaValidator_checkPropertyValue, _FhirSchemaValidator_validatePrimitiveType, _FhirSchemaValidator_validateString, _FhirSchemaValidator_validateNumber, _FhirSchemaValidator_checkAdditionalProperties, _FhirSchemaValidator_checkAdditionalProperty, _FhirSchemaValidator_checkPrimitiveElement, _FhirSchemaValidator_createIssue;
11566
11634
  /*
11567
11635
  * This file provides schema validation utilities for FHIR JSON objects.
11568
11636
  *
@@ -11724,14 +11792,11 @@
11724
11792
  }
11725
11793
  class FhirSchemaValidator {
11726
11794
  constructor(root) {
11727
- _FhirSchemaValidator_instances.add(this);
11728
- _FhirSchemaValidator_issues.set(this, void 0);
11729
- _FhirSchemaValidator_root.set(this, void 0);
11730
- __classPrivateFieldSet(this, _FhirSchemaValidator_issues, [], "f");
11731
- __classPrivateFieldSet(this, _FhirSchemaValidator_root, root, "f");
11795
+ this.issues = [];
11796
+ this.root = root;
11732
11797
  }
11733
11798
  validate() {
11734
- const resource = __classPrivateFieldGet(this, _FhirSchemaValidator_root, "f");
11799
+ const resource = this.root;
11735
11800
  if (!resource) {
11736
11801
  throw new OperationOutcomeError(validationError('Resource is null'));
11737
11802
  }
@@ -11740,142 +11805,172 @@
11740
11805
  throw new OperationOutcomeError(validationError('Missing resource type'));
11741
11806
  }
11742
11807
  // Check for "null" once for the entire object hierarchy
11743
- checkForNull(resource, '', __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f"));
11744
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateObject).call(this, toTypedValue(resource), resourceType);
11745
- if (__classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f").length > 0) {
11808
+ checkForNull(resource, '', this.issues);
11809
+ this.validateObject(toTypedValue(resource), resourceType);
11810
+ if (this.issues.length > 0) {
11746
11811
  throw new OperationOutcomeError({
11747
11812
  resourceType: 'OperationOutcome',
11748
- issue: __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f"),
11813
+ issue: this.issues,
11749
11814
  });
11750
11815
  }
11751
11816
  }
11752
- }
11753
- _FhirSchemaValidator_issues = new WeakMap(), _FhirSchemaValidator_root = new WeakMap(), _FhirSchemaValidator_instances = new WeakSet(), _FhirSchemaValidator_validateObject = function _FhirSchemaValidator_validateObject(typedValue, path) {
11754
- const definition = globalSchema.types[typedValue.type];
11755
- if (!definition) {
11756
- throw new OperationOutcomeError(validationError('Unknown type: ' + typedValue.type));
11757
- }
11758
- const propertyDefinitions = definition.properties;
11759
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkProperties).call(this, path, propertyDefinitions, typedValue);
11760
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkAdditionalProperties).call(this, path, typedValue, propertyDefinitions);
11761
- }, _FhirSchemaValidator_checkProperties = function _FhirSchemaValidator_checkProperties(path, propertyDefinitions, typedValue) {
11762
- for (const [key, elementDefinition] of Object.entries(propertyDefinitions)) {
11763
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkProperty).call(this, path + '.' + key, elementDefinition, typedValue);
11817
+ validateObject(typedValue, path) {
11818
+ const definition = globalSchema.types[typedValue.type];
11819
+ if (!definition) {
11820
+ throw new OperationOutcomeError(validationError('Unknown type: ' + typedValue.type));
11821
+ }
11822
+ const propertyDefinitions = definition.properties;
11823
+ this.checkProperties(path, propertyDefinitions, typedValue);
11824
+ this.checkAdditionalProperties(path, typedValue, propertyDefinitions);
11764
11825
  }
11765
- }, _FhirSchemaValidator_checkProperty = function _FhirSchemaValidator_checkProperty(path, elementDefinition, typedValue) {
11766
- const propertyName = path.split('.').pop();
11767
- const value = getTypedPropertyValue(typedValue, propertyName);
11768
- if (isEmpty(value)) {
11769
- if (elementDefinition.min !== undefined && elementDefinition.min > 0) {
11770
- __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f").push(createStructureIssue(path, 'Missing required property'));
11826
+ checkProperties(path, propertyDefinitions, typedValue) {
11827
+ for (const [key, elementDefinition] of Object.entries(propertyDefinitions)) {
11828
+ this.checkProperty(path + '.' + key, elementDefinition, typedValue);
11771
11829
  }
11772
- return;
11773
11830
  }
11774
- if (elementDefinition.max === '*') {
11775
- if (!Array.isArray(value)) {
11776
- __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f").push(createStructureIssue(path, 'Expected array for property'));
11831
+ checkProperty(path, elementDefinition, typedValue) {
11832
+ const propertyName = path.split('.').pop();
11833
+ const value = getTypedPropertyValue(typedValue, propertyName);
11834
+ if (isEmpty(value)) {
11835
+ if (elementDefinition.min !== undefined && elementDefinition.min > 0) {
11836
+ this.issues.push(createStructureIssue(path, 'Missing required property'));
11837
+ }
11777
11838
  return;
11778
11839
  }
11779
- for (const item of value) {
11780
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkPropertyValue).call(this, path, elementDefinition, item);
11840
+ if (elementDefinition.max === '*') {
11841
+ if (!Array.isArray(value)) {
11842
+ this.issues.push(createStructureIssue(path, 'Expected array for property'));
11843
+ return;
11844
+ }
11845
+ for (const item of value) {
11846
+ this.checkPropertyValue(path, elementDefinition, item);
11847
+ }
11848
+ }
11849
+ else {
11850
+ if (Array.isArray(value)) {
11851
+ this.issues.push(createStructureIssue(path, 'Expected single value for property'));
11852
+ return;
11853
+ }
11854
+ this.checkPropertyValue(path, elementDefinition, value);
11781
11855
  }
11782
11856
  }
11783
- else {
11784
- if (Array.isArray(value)) {
11785
- __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f").push(createStructureIssue(path, 'Expected single value for property'));
11857
+ checkPropertyValue(path, elementDefinition, typedValue) {
11858
+ if (typedValue.value === null) {
11859
+ // Null handled separately
11786
11860
  return;
11787
11861
  }
11788
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkPropertyValue).call(this, path, elementDefinition, value);
11789
- }
11790
- }, _FhirSchemaValidator_checkPropertyValue = function _FhirSchemaValidator_checkPropertyValue(path, elementDefinition, typedValue) {
11791
- if (typedValue.value === null) {
11792
- // Null handled separately
11793
- return;
11794
- }
11795
- if (isLowerCase(typedValue.type.charAt(0))) {
11796
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validatePrimitiveType).call(this, elementDefinition, typedValue);
11797
- }
11798
- else {
11799
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateObject).call(this, typedValue, path);
11800
- }
11801
- }, _FhirSchemaValidator_validatePrimitiveType = function _FhirSchemaValidator_validatePrimitiveType(elementDefinition, typedValue) {
11802
- const { type, value } = typedValue;
11803
- if (value === null) {
11804
- // Null handled separately, so this code should never be reached
11805
- // Leaving this check in place for now, in case we change the null handling
11806
- return;
11807
- }
11808
- // First, make sure the value is the correct JS type
11809
- const expectedType = fhirTypeToJsType[typedValue.type];
11810
- if (typeof value !== expectedType) {
11811
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Invalid type for ' + type);
11812
- return;
11813
- }
11814
- // Then, perform additional checks for specialty types
11815
- if (expectedType === 'string') {
11816
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateString).call(this, elementDefinition, type, value);
11817
- }
11818
- else if (expectedType === 'number') {
11819
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateNumber).call(this, elementDefinition, type, value);
11862
+ if (isLowerCase(typedValue.type.charAt(0))) {
11863
+ this.validatePrimitiveType(elementDefinition, typedValue);
11864
+ }
11865
+ else {
11866
+ this.validateObject(typedValue, path);
11867
+ }
11820
11868
  }
11821
- }, _FhirSchemaValidator_validateString = function _FhirSchemaValidator_validateString(elementDefinition, type, value) {
11822
- if (!value.trim()) {
11823
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Invalid empty string');
11824
- return;
11869
+ validatePrimitiveType(elementDefinition, typedValue) {
11870
+ const { type, value } = typedValue;
11871
+ if (value === null) {
11872
+ // Null handled separately, so this code should never be reached
11873
+ // Leaving this check in place for now, in case we change the null handling
11874
+ return;
11875
+ }
11876
+ // First, make sure the value is the correct JS type
11877
+ const expectedType = fhirTypeToJsType[typedValue.type];
11878
+ if (typeof value !== expectedType) {
11879
+ this.createIssue(elementDefinition, 'Invalid type for ' + type);
11880
+ return;
11881
+ }
11882
+ // Then, perform additional checks for specialty types
11883
+ if (expectedType === 'string') {
11884
+ this.validateString(elementDefinition, type, value);
11885
+ }
11886
+ else if (expectedType === 'number') {
11887
+ this.validateNumber(elementDefinition, type, value);
11888
+ }
11825
11889
  }
11826
- // Try to get the regex
11827
- const valueDefinition = globalSchema.types[type]?.properties?.['value'];
11828
- if (valueDefinition?.type) {
11829
- const regex = getExtensionValue(valueDefinition.type[0], 'http://hl7.org/fhir/StructureDefinition/regex');
11830
- if (regex) {
11831
- if (!value.match(new RegExp(regex))) {
11832
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Invalid ' + type + ' format');
11890
+ validateString(elementDefinition, type, value) {
11891
+ if (!value.trim()) {
11892
+ this.createIssue(elementDefinition, 'Invalid empty string');
11893
+ return;
11894
+ }
11895
+ // Try to get the regex
11896
+ const valueDefinition = globalSchema.types[type]?.properties?.['value'];
11897
+ if (valueDefinition?.type) {
11898
+ const regex = getExtensionValue(valueDefinition.type[0], 'http://hl7.org/fhir/StructureDefinition/regex');
11899
+ if (regex) {
11900
+ if (!value.match(new RegExp(regex))) {
11901
+ this.createIssue(elementDefinition, 'Invalid ' + type + ' format');
11902
+ }
11833
11903
  }
11834
11904
  }
11835
11905
  }
11836
- }, _FhirSchemaValidator_validateNumber = function _FhirSchemaValidator_validateNumber(elementDefinition, type, value) {
11837
- if (isNaN(value) || !isFinite(value)) {
11838
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Invalid ' + type + ' value');
11839
- return;
11840
- }
11841
- if (isIntegerType(type) && !Number.isInteger(value)) {
11842
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Number is not an integer');
11843
- }
11844
- if (type === exports.PropertyType.positiveInt && value <= 0) {
11845
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Number is less than or equal to zero');
11846
- }
11847
- if (type === exports.PropertyType.unsignedInt && value < 0) {
11848
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Number is negative');
11906
+ validateNumber(elementDefinition, type, value) {
11907
+ if (isNaN(value) || !isFinite(value)) {
11908
+ this.createIssue(elementDefinition, 'Invalid ' + type + ' value');
11909
+ return;
11910
+ }
11911
+ if (isIntegerType(type) && !Number.isInteger(value)) {
11912
+ this.createIssue(elementDefinition, 'Number is not an integer');
11913
+ }
11914
+ if (type === exports.PropertyType.positiveInt && value <= 0) {
11915
+ this.createIssue(elementDefinition, 'Number is less than or equal to zero');
11916
+ }
11917
+ if (type === exports.PropertyType.unsignedInt && value < 0) {
11918
+ this.createIssue(elementDefinition, 'Number is negative');
11919
+ }
11849
11920
  }
11850
- }, _FhirSchemaValidator_checkAdditionalProperties = function _FhirSchemaValidator_checkAdditionalProperties(path, typedValue, propertyDefinitions) {
11851
- const object = typedValue.value;
11852
- for (const key of Object.keys(object)) {
11853
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkAdditionalProperty).call(this, path, key, typedValue, propertyDefinitions);
11921
+ checkAdditionalProperties(path, typedValue, propertyDefinitions) {
11922
+ const object = typedValue.value;
11923
+ for (const key of Object.keys(object)) {
11924
+ this.checkAdditionalProperty(path, key, typedValue, propertyDefinitions);
11925
+ }
11854
11926
  }
11855
- }, _FhirSchemaValidator_checkAdditionalProperty = function _FhirSchemaValidator_checkAdditionalProperty(path, key, typedValue, propertyDefinitions) {
11856
- if (!baseResourceProperties.has(key) &&
11857
- !(key in propertyDefinitions) &&
11858
- !isChoiceOfType(key, typedValue, propertyDefinitions) &&
11859
- !__classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkPrimitiveElement).call(this, path, key, typedValue)) {
11860
- const expression = `${path}.${key}`;
11861
- __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f").push(createStructureIssue(expression, `Invalid additional property "${expression}"`));
11927
+ /**
11928
+ * Checks if the given property is allowed on the given object.
11929
+ * @param path The path of the current object.
11930
+ * @param key The key of a property to check.
11931
+ * @param typedValue The current object.
11932
+ * @param propertyDefinitions The property definitions of the current object.
11933
+ */
11934
+ checkAdditionalProperty(path, key, typedValue, propertyDefinitions) {
11935
+ if (!baseResourceProperties.has(key) &&
11936
+ !(key in propertyDefinitions) &&
11937
+ !isChoiceOfType(key, typedValue, propertyDefinitions) &&
11938
+ !this.checkPrimitiveElement(path, key, typedValue)) {
11939
+ const expression = `${path}.${key}`;
11940
+ this.issues.push(createStructureIssue(expression, `Invalid additional property "${expression}"`));
11941
+ }
11862
11942
  }
11863
- }, _FhirSchemaValidator_checkPrimitiveElement = function _FhirSchemaValidator_checkPrimitiveElement(path, key, typedValue) {
11864
- // Primitive element starts with underscore
11865
- if (!key.startsWith('_')) {
11866
- return false;
11943
+ /**
11944
+ * Checks the element for a primitive.
11945
+ *
11946
+ * FHIR elements with primitive data types are represented in two parts:
11947
+ * 1) A JSON property with the name of the element, which has a JSON type of number, boolean, or string
11948
+ * 2) a JSON property with _ prepended to the name of the element, which, if present, contains the value's id and/or extensions
11949
+ *
11950
+ * See: https://hl7.org/fhir/json.html#primitive
11951
+ *
11952
+ * @param path The path to the property
11953
+ * @param key
11954
+ * @param typedValue
11955
+ */
11956
+ checkPrimitiveElement(path, key, typedValue) {
11957
+ // Primitive element starts with underscore
11958
+ if (!key.startsWith('_')) {
11959
+ return false;
11960
+ }
11961
+ // Validate the non-underscore property exists
11962
+ const primitiveKey = key.slice(1);
11963
+ if (!(primitiveKey in typedValue.value)) {
11964
+ return false;
11965
+ }
11966
+ // Then validate the element
11967
+ this.validateObject({ type: 'Element', value: typedValue.value[key] }, path);
11968
+ return true;
11867
11969
  }
11868
- // Validate the non-underscore property exists
11869
- const primitiveKey = key.slice(1);
11870
- if (!(primitiveKey in typedValue.value)) {
11871
- return false;
11970
+ createIssue(elementDefinition, message) {
11971
+ this.issues.push(createStructureIssue(elementDefinition.path, message));
11872
11972
  }
11873
- // Then validate the element
11874
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateObject).call(this, { type: 'Element', value: typedValue.value[key] }, path);
11875
- return true;
11876
- }, _FhirSchemaValidator_createIssue = function _FhirSchemaValidator_createIssue(elementDefinition, message) {
11877
- __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f").push(createStructureIssue(elementDefinition.path, message));
11878
- };
11973
+ }
11879
11974
  function isIntegerType(propertyType) {
11880
11975
  return (propertyType === exports.PropertyType.integer ||
11881
11976
  propertyType === exports.PropertyType.positiveInt ||