@medplum/core 2.0.13 → 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 (59) hide show
  1. package/dist/cjs/index.cjs +1259 -1065
  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/bundle.mjs +36 -0
  7. package/dist/esm/bundle.mjs.map +1 -0
  8. package/dist/esm/cache.mjs +17 -23
  9. package/dist/esm/cache.mjs.map +1 -1
  10. package/dist/esm/client.mjs +523 -385
  11. package/dist/esm/client.mjs.map +1 -1
  12. package/dist/esm/eventtarget.mjs +6 -11
  13. package/dist/esm/eventtarget.mjs.map +1 -1
  14. package/dist/esm/fhirlexer/parse.mjs +15 -23
  15. package/dist/esm/fhirlexer/parse.mjs.map +1 -1
  16. package/dist/esm/fhirlexer/tokenize.mjs +190 -180
  17. package/dist/esm/fhirlexer/tokenize.mjs.map +1 -1
  18. package/dist/esm/fhirmapper/parse.mjs +264 -252
  19. package/dist/esm/fhirmapper/parse.mjs.map +1 -1
  20. package/dist/esm/fhirmapper/tokenize.mjs +2 -4
  21. package/dist/esm/fhirmapper/tokenize.mjs.map +1 -1
  22. package/dist/esm/fhirpath/atoms.mjs +13 -20
  23. package/dist/esm/fhirpath/atoms.mjs.map +1 -1
  24. package/dist/esm/fhirpath/parse.mjs +0 -1
  25. package/dist/esm/fhirpath/parse.mjs.map +1 -1
  26. package/dist/esm/fhirpath/tokenize.mjs +0 -1
  27. package/dist/esm/fhirpath/tokenize.mjs.map +1 -1
  28. package/dist/esm/filter/parse.mjs +1 -4
  29. package/dist/esm/filter/parse.mjs.map +1 -1
  30. package/dist/esm/filter/tokenize.mjs +2 -4
  31. package/dist/esm/filter/tokenize.mjs.map +1 -1
  32. package/dist/esm/index.min.mjs +1 -1
  33. package/dist/esm/index.mjs +1 -0
  34. package/dist/esm/index.mjs.map +1 -1
  35. package/dist/esm/jwt.mjs +2 -9
  36. package/dist/esm/jwt.mjs.map +1 -1
  37. package/dist/esm/readablepromise.mjs +18 -23
  38. package/dist/esm/readablepromise.mjs.map +1 -1
  39. package/dist/esm/schema.mjs +149 -127
  40. package/dist/esm/schema.mjs.map +1 -1
  41. package/dist/esm/search/match.mjs +1 -4
  42. package/dist/esm/search/match.mjs.map +1 -1
  43. package/dist/esm/storage.mjs +13 -19
  44. package/dist/esm/storage.mjs.map +1 -1
  45. package/dist/types/base64.d.ts +14 -0
  46. package/dist/types/bundle.d.ts +11 -0
  47. package/dist/types/cache.d.ts +3 -1
  48. package/dist/types/client.d.ts +164 -1
  49. package/dist/types/eventtarget.d.ts +1 -1
  50. package/dist/types/fhirlexer/parse.d.ts +5 -2
  51. package/dist/types/fhirlexer/tokenize.d.ts +28 -1
  52. package/dist/types/fhirpath/atoms.d.ts +1 -1
  53. package/dist/types/index.d.ts +1 -0
  54. package/dist/types/readablepromise.d.ts +4 -1
  55. package/dist/types/schema.d.ts +33 -1
  56. package/dist/types/storage.d.ts +2 -2
  57. package/package.json +1 -1
  58. package/dist/esm/node_modules/tslib/tslib.es6.mjs +0 -30
  59. package/dist/esm/node_modules/tslib/tslib.es6.mjs.map +0 -1
@@ -4,52 +4,54 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.medplum = global.medplum || {}, global.medplum.core = {})));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- /******************************************************************************
8
- Copyright (c) Microsoft Corporation.
9
-
10
- Permission to use, copy, modify, and/or distribute this software for any
11
- purpose with or without fee is hereby granted.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
- PERFORMANCE OF THIS SOFTWARE.
20
- ***************************************************************************** */
21
-
22
- function __classPrivateFieldGet(receiver, state, kind, f) {
23
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
24
- 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");
25
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
26
- }
27
-
28
- function __classPrivateFieldSet(receiver, state, value, kind, f) {
29
- if (kind === "m") throw new TypeError("Private method is not writable");
30
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
31
- 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");
32
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ /**
8
+ * More on Bundles can be found here
9
+ * http://hl7.org/fhir/R4/bundle.html
10
+ */
11
+ /**
12
+ * Takes a bundle and creates a Transaction Type bundle
13
+ * @param bundle The Bundle object that we'll receive from the search query
14
+ * @returns transaction type bundle
15
+ */
16
+ function convertToTransactionBundle(bundle) {
17
+ for (const entry of bundle.entry || []) {
18
+ delete entry?.resource?.meta;
19
+ entry.fullUrl = 'urn:uuid:' + entry?.resource?.id;
20
+ delete entry?.resource?.id;
21
+ }
22
+ const input = bundle.entry;
23
+ const jsonString = JSON.stringify({
24
+ resourceType: 'Bundle',
25
+ type: 'transaction',
26
+ entry: input?.map((entry) => ({
27
+ fullUrl: entry.fullUrl,
28
+ request: { method: 'POST', url: entry.resource.resourceType },
29
+ resource: entry.resource,
30
+ })),
31
+ }, replacer, 2);
32
+ return JSON.parse(jsonString);
33
+ }
34
+ function replacer(key, value) {
35
+ if (key === 'reference' && typeof value === 'string' && value.includes('/')) {
36
+ return 'urn:uuid:' + value.split('/')[1];
37
+ }
38
+ return value;
33
39
  }
34
40
 
35
- var _LRUCache_instances, _LRUCache_max, _LRUCache_cache, _LRUCache_first;
36
41
  /**
37
42
  * LRU cache (least recently used)
38
43
  * Source: https://stackoverflow.com/a/46432113
39
44
  */
40
45
  class LRUCache {
41
46
  constructor(max = 10) {
42
- _LRUCache_instances.add(this);
43
- _LRUCache_max.set(this, void 0);
44
- _LRUCache_cache.set(this, void 0);
45
- __classPrivateFieldSet(this, _LRUCache_max, max, "f");
46
- __classPrivateFieldSet(this, _LRUCache_cache, new Map(), "f");
47
+ this.max = max;
48
+ this.cache = new Map();
47
49
  }
48
50
  /**
49
51
  * Deletes all values from the cache.
50
52
  */
51
53
  clear() {
52
- __classPrivateFieldGet(this, _LRUCache_cache, "f").clear();
54
+ this.cache.clear();
53
55
  }
54
56
  /**
55
57
  * Returns the value for the given key.
@@ -57,10 +59,10 @@
57
59
  * @returns The value if found; undefined otherwise.
58
60
  */
59
61
  get(key) {
60
- const item = __classPrivateFieldGet(this, _LRUCache_cache, "f").get(key);
62
+ const item = this.cache.get(key);
61
63
  if (item) {
62
- __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(key);
63
- __classPrivateFieldGet(this, _LRUCache_cache, "f").set(key, item);
64
+ this.cache.delete(key);
65
+ this.cache.set(key, item);
64
66
  }
65
67
  return item;
66
68
  }
@@ -70,33 +72,33 @@
70
72
  * @param val The value to set.
71
73
  */
72
74
  set(key, val) {
73
- if (__classPrivateFieldGet(this, _LRUCache_cache, "f").has(key)) {
74
- __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(key);
75
+ if (this.cache.has(key)) {
76
+ this.cache.delete(key);
75
77
  }
76
- else if (__classPrivateFieldGet(this, _LRUCache_cache, "f").size >= __classPrivateFieldGet(this, _LRUCache_max, "f")) {
77
- __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());
78
80
  }
79
- __classPrivateFieldGet(this, _LRUCache_cache, "f").set(key, val);
81
+ this.cache.set(key, val);
80
82
  }
81
83
  /**
82
84
  * Deletes the value for the given key.
83
85
  * @param key The key to delete.
84
86
  */
85
87
  delete(key) {
86
- __classPrivateFieldGet(this, _LRUCache_cache, "f").delete(key);
88
+ this.cache.delete(key);
87
89
  }
88
90
  /**
89
91
  * Returns the list of all keys in the cache.
90
92
  * @returns The array of keys in the cache.
91
93
  */
92
94
  keys() {
93
- 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;
94
100
  }
95
101
  }
96
- _LRUCache_max = new WeakMap(), _LRUCache_cache = new WeakMap(), _LRUCache_instances = new WeakSet(), _LRUCache_first = function _LRUCache_first() {
97
- // This works because the Map class maintains ordered keys.
98
- return __classPrivateFieldGet(this, _LRUCache_cache, "f").keys().next().value;
99
- };
100
102
 
101
103
  /**
102
104
  * Formats a FHIR Address as a string.
@@ -1107,20 +1109,18 @@
1107
1109
  /*
1108
1110
  * Based on: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
1109
1111
  */
1110
- var _EventTarget_listeners;
1111
1112
  class EventTarget {
1112
1113
  constructor() {
1113
- _EventTarget_listeners.set(this, void 0);
1114
- __classPrivateFieldSet(this, _EventTarget_listeners, {}, "f");
1114
+ this.listeners = {};
1115
1115
  }
1116
1116
  addEventListener(type, callback) {
1117
- if (!__classPrivateFieldGet(this, _EventTarget_listeners, "f")[type]) {
1118
- __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type] = [];
1117
+ if (!this.listeners[type]) {
1118
+ this.listeners[type] = [];
1119
1119
  }
1120
- __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type].push(callback);
1120
+ this.listeners[type].push(callback);
1121
1121
  }
1122
1122
  removeEventListeneer(type, callback) {
1123
- const array = __classPrivateFieldGet(this, _EventTarget_listeners, "f")[type];
1123
+ const array = this.listeners[type];
1124
1124
  if (!array) {
1125
1125
  return;
1126
1126
  }
@@ -1132,14 +1132,44 @@
1132
1132
  }
1133
1133
  }
1134
1134
  dispatchEvent(event) {
1135
- const array = __classPrivateFieldGet(this, _EventTarget_listeners, "f")[event.type];
1135
+ const array = this.listeners[event.type];
1136
1136
  if (array) {
1137
1137
  array.forEach((listener) => listener.call(this, event));
1138
1138
  }
1139
1139
  return !event.defaultPrevented;
1140
1140
  }
1141
1141
  }
1142
- _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
+ }
1143
1173
 
1144
1174
  /**
1145
1175
  * Decodes a section of a JWT.
@@ -1156,15 +1186,6 @@
1156
1186
  const jsonPayload = decodeURIComponent(uriEncodedPayload);
1157
1187
  return JSON.parse(jsonPayload);
1158
1188
  }
1159
- function decodeBase64(data) {
1160
- if (typeof window !== 'undefined') {
1161
- return window.atob(data);
1162
- }
1163
- if (typeof Buffer !== 'undefined') {
1164
- return Buffer.from(data, 'base64').toString('binary');
1165
- }
1166
- throw new Error('Unable to decode base64');
1167
- }
1168
1189
  /**
1169
1190
  * Parses the JWT payload.
1170
1191
  * @param token JWT token
@@ -1426,7 +1447,7 @@
1426
1447
  return strs.length > 0 ? strs.join('; ') : 'Unknown error';
1427
1448
  }
1428
1449
 
1429
- var _ReadablePromise_suspender, _ReadablePromise_status, _ReadablePromise_response, _ReadablePromise_error, _a;
1450
+ var _a;
1430
1451
  /**
1431
1452
  * The ReadablePromise class wraps a request promise suitable for React Suspense.
1432
1453
  * See: https://blog.logrocket.com/react-suspense-data-fetching/#wrappromise-js
@@ -1435,33 +1456,30 @@
1435
1456
  class ReadablePromise {
1436
1457
  constructor(requestPromise) {
1437
1458
  this[_a] = 'ReadablePromise';
1438
- _ReadablePromise_suspender.set(this, void 0);
1439
- _ReadablePromise_status.set(this, 'pending');
1440
- _ReadablePromise_response.set(this, void 0);
1441
- _ReadablePromise_error.set(this, void 0);
1442
- __classPrivateFieldSet(this, _ReadablePromise_suspender, requestPromise.then((res) => {
1443
- __classPrivateFieldSet(this, _ReadablePromise_status, 'success', "f");
1444
- __classPrivateFieldSet(this, _ReadablePromise_response, res, "f");
1459
+ this.status = 'pending';
1460
+ this.suspender = requestPromise.then((res) => {
1461
+ this.status = 'success';
1462
+ this.response = res;
1445
1463
  return res;
1446
1464
  }, (err) => {
1447
- __classPrivateFieldSet(this, _ReadablePromise_status, 'error', "f");
1448
- __classPrivateFieldSet(this, _ReadablePromise_error, err, "f");
1465
+ this.status = 'error';
1466
+ this.error = err;
1449
1467
  throw err;
1450
- }), "f");
1468
+ });
1451
1469
  }
1452
1470
  /**
1453
1471
  * Returns true if the promise is pending.
1454
1472
  * @returns True if the Promise is pending.
1455
1473
  */
1456
1474
  isPending() {
1457
- return __classPrivateFieldGet(this, _ReadablePromise_status, "f") === 'pending';
1475
+ return this.status === 'pending';
1458
1476
  }
1459
1477
  /**
1460
1478
  * Returns true if the promise resolved successfully.
1461
1479
  * @returns True if the Promise resolved successfully.
1462
1480
  */
1463
1481
  isOk() {
1464
- return __classPrivateFieldGet(this, _ReadablePromise_status, "f") === 'success';
1482
+ return this.status === 'success';
1465
1483
  }
1466
1484
  /**
1467
1485
  * Attempts to read the value of the promise.
@@ -1471,13 +1489,13 @@
1471
1489
  * @returns The resolved value of the Promise.
1472
1490
  */
1473
1491
  read() {
1474
- switch (__classPrivateFieldGet(this, _ReadablePromise_status, "f")) {
1492
+ switch (this.status) {
1475
1493
  case 'pending':
1476
- throw __classPrivateFieldGet(this, _ReadablePromise_suspender, "f");
1494
+ throw this.suspender;
1477
1495
  case 'error':
1478
- throw __classPrivateFieldGet(this, _ReadablePromise_error, "f");
1496
+ throw this.error;
1479
1497
  default:
1480
- return __classPrivateFieldGet(this, _ReadablePromise_response, "f");
1498
+ return this.response;
1481
1499
  }
1482
1500
  }
1483
1501
  /**
@@ -1487,7 +1505,7 @@
1487
1505
  * @returns A Promise for the completion of which ever callback is executed.
1488
1506
  */
1489
1507
  then(onfulfilled, onrejected) {
1490
- return __classPrivateFieldGet(this, _ReadablePromise_suspender, "f").then(onfulfilled, onrejected);
1508
+ return this.suspender.then(onfulfilled, onrejected);
1491
1509
  }
1492
1510
  /**
1493
1511
  * Attaches a callback for only the rejection of the Promise.
@@ -1495,7 +1513,7 @@
1495
1513
  * @returns A Promise for the completion of the callback.
1496
1514
  */
1497
1515
  catch(onrejected) {
1498
- return __classPrivateFieldGet(this, _ReadablePromise_suspender, "f").catch(onrejected);
1516
+ return this.suspender.catch(onrejected);
1499
1517
  }
1500
1518
  /**
1501
1519
  * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
@@ -1504,12 +1522,11 @@
1504
1522
  * @returns A Promise for the completion of the callback.
1505
1523
  */
1506
1524
  finally(onfinally) {
1507
- return __classPrivateFieldGet(this, _ReadablePromise_suspender, "f").finally(onfinally);
1525
+ return this.suspender.finally(onfinally);
1508
1526
  }
1509
1527
  }
1510
- _ReadablePromise_suspender = new WeakMap(), _ReadablePromise_status = new WeakMap(), _ReadablePromise_response = new WeakMap(), _ReadablePromise_error = new WeakMap(), _a = Symbol.toStringTag;
1528
+ _a = Symbol.toStringTag;
1511
1529
 
1512
- var _ClientStorage_storage, _MemoryStorage_data;
1513
1530
  /**
1514
1531
  * The ClientStorage class is a utility class for storing strings and objects.
1515
1532
  *
@@ -1519,21 +1536,20 @@
1519
1536
  */
1520
1537
  class ClientStorage {
1521
1538
  constructor() {
1522
- _ClientStorage_storage.set(this, void 0);
1523
- __classPrivateFieldSet(this, _ClientStorage_storage, typeof localStorage !== 'undefined' ? localStorage : new MemoryStorage(), "f");
1539
+ this.storage = typeof localStorage !== 'undefined' ? localStorage : new MemoryStorage();
1524
1540
  }
1525
1541
  clear() {
1526
- __classPrivateFieldGet(this, _ClientStorage_storage, "f").clear();
1542
+ this.storage.clear();
1527
1543
  }
1528
1544
  getString(key) {
1529
- return __classPrivateFieldGet(this, _ClientStorage_storage, "f").getItem(key) || undefined;
1545
+ return this.storage.getItem(key) || undefined;
1530
1546
  }
1531
1547
  setString(key, value) {
1532
1548
  if (value) {
1533
- __classPrivateFieldGet(this, _ClientStorage_storage, "f").setItem(key, value);
1549
+ this.storage.setItem(key, value);
1534
1550
  }
1535
1551
  else {
1536
- __classPrivateFieldGet(this, _ClientStorage_storage, "f").removeItem(key);
1552
+ this.storage.removeItem(key);
1537
1553
  }
1538
1554
  }
1539
1555
  getObject(key) {
@@ -1544,58 +1560,55 @@
1544
1560
  this.setString(key, value ? stringify(value) : undefined);
1545
1561
  }
1546
1562
  }
1547
- _ClientStorage_storage = new WeakMap();
1548
1563
  /**
1549
1564
  * The MemoryStorage class is a minimal in-memory implementation of the Storage interface.
1550
1565
  */
1551
1566
  class MemoryStorage {
1552
1567
  constructor() {
1553
- _MemoryStorage_data.set(this, void 0);
1554
- __classPrivateFieldSet(this, _MemoryStorage_data, new Map(), "f");
1568
+ this.data = new Map();
1555
1569
  }
1556
1570
  /**
1557
1571
  * Returns the number of key/value pairs.
1558
1572
  */
1559
1573
  get length() {
1560
- return __classPrivateFieldGet(this, _MemoryStorage_data, "f").size;
1574
+ return this.data.size;
1561
1575
  }
1562
1576
  /**
1563
1577
  * Removes all key/value pairs, if there are any.
1564
1578
  */
1565
1579
  clear() {
1566
- __classPrivateFieldGet(this, _MemoryStorage_data, "f").clear();
1580
+ this.data.clear();
1567
1581
  }
1568
1582
  /**
1569
1583
  * Returns the current value associated with the given key, or null if the given key does not exist.
1570
1584
  */
1571
1585
  getItem(key) {
1572
- return __classPrivateFieldGet(this, _MemoryStorage_data, "f").get(key) ?? null;
1586
+ return this.data.get(key) ?? null;
1573
1587
  }
1574
1588
  /**
1575
1589
  * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
1576
1590
  */
1577
1591
  setItem(key, value) {
1578
1592
  if (value) {
1579
- __classPrivateFieldGet(this, _MemoryStorage_data, "f").set(key, value);
1593
+ this.data.set(key, value);
1580
1594
  }
1581
1595
  else {
1582
- __classPrivateFieldGet(this, _MemoryStorage_data, "f").delete(key);
1596
+ this.data.delete(key);
1583
1597
  }
1584
1598
  }
1585
1599
  /**
1586
1600
  * Removes the key/value pair with the given key, if a key/value pair with the given key exists.
1587
1601
  */
1588
1602
  removeItem(key) {
1589
- __classPrivateFieldGet(this, _MemoryStorage_data, "f").delete(key);
1603
+ this.data.delete(key);
1590
1604
  }
1591
1605
  /**
1592
1606
  * Returns the name of the nth key, or null if n is greater than or equal to the number of key/value pairs.
1593
1607
  */
1594
1608
  key(index) {
1595
- return Array.from(__classPrivateFieldGet(this, _MemoryStorage_data, "f").keys())[index];
1609
+ return Array.from(this.data.keys())[index];
1596
1610
  }
1597
1611
  }
1598
- _MemoryStorage_data = new WeakMap();
1599
1612
 
1600
1613
  var types = {
1601
1614
  Element: {
@@ -6368,9 +6381,7 @@
6368
6381
  const globalSchema = baseSchema;
6369
6382
 
6370
6383
  // PKCE auth based on:
6371
- // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
6372
- var _MedplumClient_instances, _MedplumClient_fetch, _MedplumClient_createPdf, _MedplumClient_storage, _MedplumClient_requestCache, _MedplumClient_cacheTime, _MedplumClient_baseUrl, _MedplumClient_fhirBaseUrl, _MedplumClient_authorizeUrl, _MedplumClient_tokenUrl, _MedplumClient_logoutUrl, _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;
6373
- const MEDPLUM_VERSION = "2.0.13-ee64d72c";
6384
+ const MEDPLUM_VERSION = "2.0.15-025c3c04";
6374
6385
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
6375
6386
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
6376
6387
  const DEFAULT_CACHE_TIME = 60000; // 60 seconds
@@ -6433,55 +6444,44 @@
6433
6444
  class MedplumClient extends EventTarget {
6434
6445
  constructor(options) {
6435
6446
  super();
6436
- _MedplumClient_instances.add(this);
6437
- _MedplumClient_fetch.set(this, void 0);
6438
- _MedplumClient_createPdf.set(this, void 0);
6439
- _MedplumClient_storage.set(this, void 0);
6440
- _MedplumClient_requestCache.set(this, void 0);
6441
- _MedplumClient_cacheTime.set(this, void 0);
6442
- _MedplumClient_baseUrl.set(this, void 0);
6443
- _MedplumClient_fhirBaseUrl.set(this, void 0);
6444
- _MedplumClient_authorizeUrl.set(this, void 0);
6445
- _MedplumClient_tokenUrl.set(this, void 0);
6446
- _MedplumClient_logoutUrl.set(this, void 0);
6447
- _MedplumClient_onUnauthenticated.set(this, void 0);
6448
- _MedplumClient_autoBatchTime.set(this, void 0);
6449
- _MedplumClient_autoBatchQueue.set(this, void 0);
6450
- _MedplumClient_clientId.set(this, void 0);
6451
- _MedplumClient_clientSecret.set(this, void 0);
6452
- _MedplumClient_autoBatchTimerId.set(this, void 0);
6453
- _MedplumClient_accessToken.set(this, void 0);
6454
- _MedplumClient_refreshToken.set(this, void 0);
6455
- _MedplumClient_refreshPromise.set(this, void 0);
6456
- _MedplumClient_profilePromise.set(this, void 0);
6457
- _MedplumClient_profile.set(this, void 0);
6458
- _MedplumClient_config.set(this, void 0);
6459
6447
  if (options?.baseUrl) {
6460
6448
  if (!options.baseUrl.startsWith('http')) {
6461
6449
  throw new Error('Base URL must start with http or https');
6462
6450
  }
6463
6451
  }
6464
- __classPrivateFieldSet(this, _MedplumClient_fetch, options?.fetch || getDefaultFetch(), "f");
6465
- __classPrivateFieldSet(this, _MedplumClient_storage, options?.storage || new ClientStorage(), "f");
6466
- __classPrivateFieldSet(this, _MedplumClient_createPdf, options?.createPdf, "f");
6467
- __classPrivateFieldSet(this, _MedplumClient_requestCache, new LRUCache(options?.resourceCacheSize ?? DEFAULT_RESOURCE_CACHE_SIZE), "f");
6468
- __classPrivateFieldSet(this, _MedplumClient_cacheTime, options?.cacheTime ?? DEFAULT_CACHE_TIME, "f");
6469
- __classPrivateFieldSet(this, _MedplumClient_baseUrl, ensureTrailingSlash(options?.baseUrl) || DEFAULT_BASE_URL, "f");
6470
- __classPrivateFieldSet(this, _MedplumClient_fhirBaseUrl, __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'fhir/R4/', "f");
6471
- __classPrivateFieldSet(this, _MedplumClient_clientId, options?.clientId || '', "f");
6472
- __classPrivateFieldSet(this, _MedplumClient_authorizeUrl, options?.authorizeUrl || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/authorize', "f");
6473
- __classPrivateFieldSet(this, _MedplumClient_tokenUrl, options?.tokenUrl || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/token', "f");
6474
- __classPrivateFieldSet(this, _MedplumClient_logoutUrl, options?.logoutUrl || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/logout', "f");
6475
- __classPrivateFieldSet(this, _MedplumClient_onUnauthenticated, options?.onUnauthenticated, "f");
6476
- __classPrivateFieldSet(this, _MedplumClient_autoBatchTime, options?.autoBatchTime ?? 0, "f");
6477
- __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
+ }
6478
6478
  const activeLogin = this.getActiveLogin();
6479
6479
  if (activeLogin) {
6480
- __classPrivateFieldSet(this, _MedplumClient_accessToken, activeLogin.accessToken, "f");
6481
- __classPrivateFieldSet(this, _MedplumClient_refreshToken, activeLogin.refreshToken, "f");
6482
- __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);
6483
6483
  }
6484
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setupStorageListener).call(this);
6484
+ this.setupStorageListener();
6485
6485
  }
6486
6486
  /**
6487
6487
  * Returns the current base URL for all API requests.
@@ -6491,14 +6491,14 @@
6491
6491
  * @returns The current base URL for all API requests.
6492
6492
  */
6493
6493
  getBaseUrl() {
6494
- return __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f");
6494
+ return this.baseUrl;
6495
6495
  }
6496
6496
  /**
6497
6497
  * Clears all auth state including local storage and session storage.
6498
6498
  * @category Authentication
6499
6499
  */
6500
6500
  clear() {
6501
- __classPrivateFieldGet(this, _MedplumClient_storage, "f").clear();
6501
+ this.storage.clear();
6502
6502
  this.clearActiveLogin();
6503
6503
  }
6504
6504
  /**
@@ -6507,12 +6507,12 @@
6507
6507
  * @category Authentication
6508
6508
  */
6509
6509
  clearActiveLogin() {
6510
- __classPrivateFieldGet(this, _MedplumClient_storage, "f").setString('activeLogin', undefined);
6511
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").clear();
6512
- __classPrivateFieldSet(this, _MedplumClient_accessToken, undefined, "f");
6513
- __classPrivateFieldSet(this, _MedplumClient_refreshToken, undefined, "f");
6514
- __classPrivateFieldSet(this, _MedplumClient_profile, undefined, "f");
6515
- __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;
6516
6516
  this.dispatchEvent({ type: 'change' });
6517
6517
  }
6518
6518
  /**
@@ -6522,7 +6522,7 @@
6522
6522
  */
6523
6523
  invalidateUrl(url) {
6524
6524
  url = url.toString();
6525
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").delete(url);
6525
+ this.requestCache?.delete(url);
6526
6526
  }
6527
6527
  /**
6528
6528
  * Invalidates all cached search results or cached requests for the given resourceType.
@@ -6531,9 +6531,11 @@
6531
6531
  */
6532
6532
  invalidateSearches(resourceType) {
6533
6533
  const url = 'fhir/R4/' + resourceType;
6534
- for (const key of __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").keys()) {
6535
- if (key.endsWith(url) || key.includes(url + '?')) {
6536
- __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
+ }
6537
6539
  }
6538
6540
  }
6539
6541
  }
@@ -6551,30 +6553,30 @@
6551
6553
  */
6552
6554
  get(url, options = {}) {
6553
6555
  url = url.toString();
6554
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, url, options);
6556
+ const cached = this.getCacheEntry(url, options);
6555
6557
  if (cached) {
6556
6558
  return cached.value;
6557
6559
  }
6558
6560
  let promise;
6559
- if (url.startsWith(__classPrivateFieldGet(this, _MedplumClient_fhirBaseUrl, "f")) && __classPrivateFieldGet(this, _MedplumClient_autoBatchTime, "f") > 0) {
6561
+ if (url.startsWith(this.fhirBaseUrl) && this.autoBatchQueue) {
6560
6562
  promise = new Promise((resolve, reject) => {
6561
- __classPrivateFieldGet(this, _MedplumClient_autoBatchQueue, "f").push({
6563
+ this.autoBatchQueue.push({
6562
6564
  method: 'GET',
6563
- url: url.replace(__classPrivateFieldGet(this, _MedplumClient_fhirBaseUrl, "f"), ''),
6565
+ url: url.replace(this.fhirBaseUrl, ''),
6564
6566
  options,
6565
6567
  resolve,
6566
6568
  reject,
6567
6569
  });
6568
- if (!__classPrivateFieldGet(this, _MedplumClient_autoBatchTimerId, "f")) {
6569
- __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);
6570
6572
  }
6571
6573
  });
6572
6574
  }
6573
6575
  else {
6574
- promise = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'GET', url, options);
6576
+ promise = this.request('GET', url, options);
6575
6577
  }
6576
6578
  const readablePromise = new ReadablePromise(promise);
6577
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, url, readablePromise);
6579
+ this.setCacheEntry(url, readablePromise);
6578
6580
  return readablePromise;
6579
6581
  }
6580
6582
  /**
@@ -6594,13 +6596,13 @@
6594
6596
  post(url, body, contentType, options = {}) {
6595
6597
  url = url.toString();
6596
6598
  if (body) {
6597
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestBody).call(this, options, body);
6599
+ this.setRequestBody(options, body);
6598
6600
  }
6599
6601
  if (contentType) {
6600
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestContentType).call(this, options, contentType);
6602
+ this.setRequestContentType(options, contentType);
6601
6603
  }
6602
6604
  this.invalidateUrl(url);
6603
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'POST', url, options);
6605
+ return this.request('POST', url, options);
6604
6606
  }
6605
6607
  /**
6606
6608
  * Makes an HTTP PUT request to the specified URL.
@@ -6619,13 +6621,13 @@
6619
6621
  put(url, body, contentType, options = {}) {
6620
6622
  url = url.toString();
6621
6623
  if (body) {
6622
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestBody).call(this, options, body);
6624
+ this.setRequestBody(options, body);
6623
6625
  }
6624
6626
  if (contentType) {
6625
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestContentType).call(this, options, contentType);
6627
+ this.setRequestContentType(options, contentType);
6626
6628
  }
6627
6629
  this.invalidateUrl(url);
6628
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'PUT', url, options);
6630
+ return this.request('PUT', url, options);
6629
6631
  }
6630
6632
  /**
6631
6633
  * Makes an HTTP PATCH request to the specified URL.
@@ -6642,10 +6644,10 @@
6642
6644
  */
6643
6645
  patch(url, operations, options = {}) {
6644
6646
  url = url.toString();
6645
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setRequestBody).call(this, options, operations);
6646
- __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);
6647
6649
  this.invalidateUrl(url);
6648
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'PATCH', url, options);
6650
+ return this.request('PATCH', url, options);
6649
6651
  }
6650
6652
  /**
6651
6653
  * Makes an HTTP DELETE request to the specified URL.
@@ -6663,7 +6665,7 @@
6663
6665
  delete(url, options = {}) {
6664
6666
  url = url.toString();
6665
6667
  this.invalidateUrl(url);
6666
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, 'DELETE', url, options);
6668
+ return this.request('DELETE', url, options);
6667
6669
  }
6668
6670
  /**
6669
6671
  * Initiates a new user flow.
@@ -6715,7 +6717,7 @@
6715
6717
  async startLogin(loginRequest) {
6716
6718
  return this.post('auth/login', {
6717
6719
  ...(await this.ensureCodeChallenge(loginRequest)),
6718
- clientId: loginRequest.clientId ?? __classPrivateFieldGet(this, _MedplumClient_clientId, "f"),
6720
+ clientId: loginRequest.clientId ?? this.clientId,
6719
6721
  scope: loginRequest.scope,
6720
6722
  });
6721
6723
  }
@@ -6730,7 +6732,7 @@
6730
6732
  async startGoogleLogin(loginRequest) {
6731
6733
  return this.post('auth/google', {
6732
6734
  ...(await this.ensureCodeChallenge(loginRequest)),
6733
- clientId: loginRequest.clientId ?? __classPrivateFieldGet(this, _MedplumClient_clientId, "f"),
6735
+ clientId: loginRequest.clientId ?? this.clientId,
6734
6736
  scope: loginRequest.scope,
6735
6737
  });
6736
6738
  }
@@ -6754,7 +6756,7 @@
6754
6756
  * @category Authentication
6755
6757
  */
6756
6758
  async signOut() {
6757
- await this.post(__classPrivateFieldGet(this, _MedplumClient_logoutUrl, "f"), {});
6759
+ await this.post(this.logoutUrl, {});
6758
6760
  this.clear();
6759
6761
  }
6760
6762
  /**
@@ -6768,7 +6770,7 @@
6768
6770
  const urlParams = new URLSearchParams(window.location.search);
6769
6771
  const code = urlParams.get('code');
6770
6772
  if (!code) {
6771
- await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_requestAuthorization).call(this, loginParams);
6773
+ await this.requestAuthorization(loginParams);
6772
6774
  return undefined;
6773
6775
  }
6774
6776
  else {
@@ -6781,7 +6783,7 @@
6781
6783
  * @category Authentication
6782
6784
  */
6783
6785
  signOutWithRedirect() {
6784
- window.location.assign(__classPrivateFieldGet(this, _MedplumClient_logoutUrl, "f"));
6786
+ window.location.assign(this.logoutUrl);
6785
6787
  }
6786
6788
  /**
6787
6789
  * Initiates sign in with an external identity provider.
@@ -6795,6 +6797,34 @@
6795
6797
  const loginRequest = await this.ensureCodeChallenge(baseLogin);
6796
6798
  window.location.assign(this.getExternalAuthRedirectUri(authorizeUrl, clientId, redirectUri, loginRequest));
6797
6799
  }
6800
+ /**
6801
+ * Exchange an external access token for a Medplum access token.
6802
+ * @param token The access token that was generated by the external identity provider.
6803
+ * @param clientId The ID of the `ClientApplication` in your Medplum project that will be making the exchange request.
6804
+ * @category Authentication
6805
+ */
6806
+ async exchangeExternalAccessToken(token, clientId) {
6807
+ clientId = clientId || this.clientId;
6808
+ if (!clientId) {
6809
+ throw new Error('MedplumClient is missing clientId');
6810
+ }
6811
+ const response = await this.fetch(this.exchangeUrl, {
6812
+ method: 'POST',
6813
+ headers: { 'Content-Type': 'application/json' },
6814
+ body: JSON.stringify({
6815
+ clientId: this.clientId,
6816
+ externalAccessToken: token,
6817
+ }),
6818
+ credentials: 'include',
6819
+ });
6820
+ if (!response.ok) {
6821
+ this.clearActiveLogin();
6822
+ throw new Error('Failed to fetch tokens');
6823
+ }
6824
+ const tokens = await response.json();
6825
+ await this.verifyTokens(tokens);
6826
+ return this.getProfile();
6827
+ }
6798
6828
  /**
6799
6829
  * Builds the external identity provider redirect URI.
6800
6830
  * @param authorizeUrl The external authorization URL.
@@ -6821,7 +6851,7 @@
6821
6851
  * @returns The well-formed FHIR URL.
6822
6852
  */
6823
6853
  fhirUrl(...path) {
6824
- return new URL(__classPrivateFieldGet(this, _MedplumClient_fhirBaseUrl, "f") + path.join('/'));
6854
+ return new URL(this.fhirBaseUrl + path.join('/'));
6825
6855
  }
6826
6856
  /**
6827
6857
  * Builds a FHIR search URL from a search query or structured query object.
@@ -6889,7 +6919,7 @@
6889
6919
  search(resourceType, query, options = {}) {
6890
6920
  const url = this.fhirSearchUrl(resourceType, query);
6891
6921
  const cacheKey = url.toString() + '-search';
6892
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, options);
6922
+ const cached = this.getCacheEntry(cacheKey, options);
6893
6923
  if (cached) {
6894
6924
  return cached.value;
6895
6925
  }
@@ -6897,12 +6927,12 @@
6897
6927
  const bundle = await this.get(url, options);
6898
6928
  if (bundle.entry) {
6899
6929
  for (const entry of bundle.entry) {
6900
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_cacheResource).call(this, entry.resource);
6930
+ this.cacheResource(entry.resource);
6901
6931
  }
6902
6932
  }
6903
6933
  return bundle;
6904
6934
  })());
6905
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
6935
+ this.setCacheEntry(cacheKey, promise);
6906
6936
  return promise;
6907
6937
  }
6908
6938
  /**
@@ -6932,12 +6962,12 @@
6932
6962
  url.searchParams.set('_count', '1');
6933
6963
  url.searchParams.sort();
6934
6964
  const cacheKey = url.toString() + '-searchOne';
6935
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, options);
6965
+ const cached = this.getCacheEntry(cacheKey, options);
6936
6966
  if (cached) {
6937
6967
  return cached.value;
6938
6968
  }
6939
6969
  const promise = new ReadablePromise(this.search(resourceType, url.searchParams, options).then((b) => b.entry?.[0]?.resource));
6940
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
6970
+ this.setCacheEntry(cacheKey, promise);
6941
6971
  return promise;
6942
6972
  }
6943
6973
  /**
@@ -6965,14 +6995,48 @@
6965
6995
  searchResources(resourceType, query, options = {}) {
6966
6996
  const url = this.fhirSearchUrl(resourceType, query);
6967
6997
  const cacheKey = url.toString() + '-searchResources';
6968
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, options);
6998
+ const cached = this.getCacheEntry(cacheKey, options);
6969
6999
  if (cached) {
6970
7000
  return cached.value;
6971
7001
  }
6972
7002
  const promise = new ReadablePromise(this.search(resourceType, query, options).then((b) => b.entry?.map((e) => e.resource) ?? []));
6973
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
7003
+ this.setCacheEntry(cacheKey, promise);
6974
7004
  return promise;
6975
7005
  }
7006
+ /**
7007
+ * Creates an
7008
+ * [async generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator)
7009
+ * over a series of FHIR search requests for paginated search results. Each iteration of the generator yields
7010
+ * the array of resources on each page.
7011
+ *
7012
+ *
7013
+ * ```typescript
7014
+ * for await (const page of medplum.searchResourcePages('Patient', { _count: 10 })) {
7015
+ * for (const patient of page) {
7016
+ * console.log(`Processing Patient resource with ID: ${patient.id}`);
7017
+ * }
7018
+ * }
7019
+ * ```
7020
+ *
7021
+ * @category Search
7022
+ * @param resourceType The FHIR resource type.
7023
+ * @param query Optional FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
7024
+ * @param options Optional fetch options.
7025
+ * @returns An async generator, where each result is an array of resources for each page.
7026
+ */
7027
+ async *searchResourcePages(resourceType, query, options = {}) {
7028
+ let url = this.fhirSearchUrl(resourceType, query);
7029
+ while (url) {
7030
+ const searchParams = new URL(url).searchParams;
7031
+ const bundle = await this.search(resourceType, searchParams, options);
7032
+ const nextLink = bundle?.link?.find((link) => link.relation === 'next');
7033
+ if (!bundle?.entry?.length && !nextLink) {
7034
+ break;
7035
+ }
7036
+ yield bundle?.entry?.map((e) => e.resource) ?? [];
7037
+ url = nextLink?.url ? new URL(nextLink?.url) : undefined;
7038
+ }
7039
+ }
6976
7040
  /**
6977
7041
  * Searches a ValueSet resource using the "expand" operation.
6978
7042
  * See: https://www.hl7.org/fhir/operation-valueset-expand.html
@@ -6997,7 +7061,7 @@
6997
7061
  * @returns The resource if it is available in the cache; undefined otherwise.
6998
7062
  */
6999
7063
  getCached(resourceType, id) {
7000
- 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;
7001
7065
  return cached && cached.isOk() ? cached.read() : undefined;
7002
7066
  }
7003
7067
  /**
@@ -7099,7 +7163,7 @@
7099
7163
  return Promise.resolve(globalSchema);
7100
7164
  }
7101
7165
  const cacheKey = resourceType + '-requestSchema';
7102
- const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, undefined);
7166
+ const cached = this.getCacheEntry(cacheKey, undefined);
7103
7167
  if (cached) {
7104
7168
  return cached.value;
7105
7169
  }
@@ -7142,7 +7206,7 @@
7142
7206
  }
7143
7207
  return globalSchema;
7144
7208
  })());
7145
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
7209
+ this.setCacheEntry(cacheKey, promise);
7146
7210
  return promise;
7147
7211
  }
7148
7212
  /**
@@ -7340,7 +7404,7 @@
7340
7404
  };
7341
7405
  xhr.open('POST', url);
7342
7406
  xhr.withCredentials = true;
7343
- xhr.setRequestHeader('Authorization', 'Bearer ' + __classPrivateFieldGet(this, _MedplumClient_accessToken, "f"));
7407
+ xhr.setRequestHeader('Authorization', 'Bearer ' + this.accessToken);
7344
7408
  xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, max-age=0');
7345
7409
  xhr.setRequestHeader('Content-Type', contentType);
7346
7410
  xhr.setRequestHeader('X-Medplum', 'extended');
@@ -7370,10 +7434,10 @@
7370
7434
  * @returns The result of the create operation.
7371
7435
  */
7372
7436
  async createPdf(docDefinition, filename, tableLayouts, fonts) {
7373
- if (!__classPrivateFieldGet(this, _MedplumClient_createPdf, "f")) {
7437
+ if (!this.createPdfImpl) {
7374
7438
  throw new Error('PDF creation not enabled');
7375
7439
  }
7376
- const blob = await __classPrivateFieldGet(this, _MedplumClient_createPdf, "f").call(this, docDefinition, tableLayouts, fonts);
7440
+ const blob = await this.createPdfImpl(docDefinition, tableLayouts, fonts);
7377
7441
  return this.createBinary(blob, filename, 'application/pdf');
7378
7442
  }
7379
7443
  /**
@@ -7451,7 +7515,7 @@
7451
7515
  // return result ?? resource;
7452
7516
  result = resource;
7453
7517
  }
7454
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_cacheResource).call(this, result);
7518
+ this.cacheResource(result);
7455
7519
  return result;
7456
7520
  }
7457
7521
  /**
@@ -7499,7 +7563,7 @@
7499
7563
  * @returns The result of the delete operation.
7500
7564
  */
7501
7565
  deleteResource(resourceType, id) {
7502
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_deleteCacheEntry).call(this, this.fhirUrl(resourceType, id).toString());
7566
+ this.deleteCacheEntry(this.fhirUrl(resourceType, id).toString());
7503
7567
  this.invalidateSearches(resourceType);
7504
7568
  return this.delete(this.fhirUrl(resourceType, id));
7505
7569
  }
@@ -7703,61 +7767,80 @@
7703
7767
  * @returns The Login State
7704
7768
  */
7705
7769
  getActiveLogin() {
7706
- return __classPrivateFieldGet(this, _MedplumClient_storage, "f").getObject('activeLogin');
7770
+ return this.storage.getObject('activeLogin');
7707
7771
  }
7708
7772
  /**
7709
7773
  * @category Authentication
7710
7774
  */
7711
7775
  async setActiveLogin(login) {
7712
7776
  this.clearActiveLogin();
7713
- __classPrivateFieldSet(this, _MedplumClient_accessToken, login.accessToken, "f");
7714
- __classPrivateFieldSet(this, _MedplumClient_refreshToken, login.refreshToken, "f");
7715
- __classPrivateFieldGet(this, _MedplumClient_storage, "f").setObject('activeLogin', login);
7716
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addLogin).call(this, login);
7717
- __classPrivateFieldSet(this, _MedplumClient_refreshPromise, undefined, "f");
7718
- 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();
7719
7783
  }
7720
7784
  /**
7721
7785
  * Returns the current access token.
7722
7786
  * @category Authentication
7723
7787
  */
7724
7788
  getAccessToken() {
7725
- return __classPrivateFieldGet(this, _MedplumClient_accessToken, "f");
7789
+ return this.accessToken;
7726
7790
  }
7727
7791
  /**
7728
7792
  * Sets the current access token.
7729
7793
  * @category Authentication
7730
7794
  */
7731
7795
  setAccessToken(accessToken) {
7732
- __classPrivateFieldSet(this, _MedplumClient_accessToken, accessToken, "f");
7733
- __classPrivateFieldSet(this, _MedplumClient_refreshToken, undefined, "f");
7734
- __classPrivateFieldSet(this, _MedplumClient_profile, undefined, "f");
7735
- __classPrivateFieldSet(this, _MedplumClient_config, undefined, "f");
7796
+ this.accessToken = accessToken;
7797
+ this.refreshToken = undefined;
7798
+ this.profile = undefined;
7799
+ this.config = undefined;
7736
7800
  }
7737
7801
  /**
7738
7802
  * @category Authentication
7739
7803
  */
7740
7804
  getLogins() {
7741
- 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;
7742
7825
  }
7743
7826
  /**
7744
7827
  * @category Authentication
7745
7828
  */
7746
7829
  isLoading() {
7747
- return !!__classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
7830
+ return !!this.profilePromise;
7748
7831
  }
7749
7832
  /**
7750
7833
  * @category User Profile
7751
7834
  */
7752
7835
  getProfile() {
7753
- return __classPrivateFieldGet(this, _MedplumClient_profile, "f");
7836
+ return this.profile;
7754
7837
  }
7755
7838
  /**
7756
7839
  * @category User Profile
7757
7840
  */
7758
7841
  async getProfileAsync() {
7759
- if (__classPrivateFieldGet(this, _MedplumClient_profilePromise, "f")) {
7760
- await __classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
7842
+ if (this.profilePromise) {
7843
+ await this.profilePromise;
7761
7844
  }
7762
7845
  return this.getProfile();
7763
7846
  }
@@ -7765,7 +7848,7 @@
7765
7848
  * @category User Profile
7766
7849
  */
7767
7850
  getUserConfiguration() {
7768
- return __classPrivateFieldGet(this, _MedplumClient_config, "f");
7851
+ return this.config;
7769
7852
  }
7770
7853
  /**
7771
7854
  * Downloads the URL as a blob.
@@ -7775,13 +7858,234 @@
7775
7858
  * @returns Promise to the response body as a blob.
7776
7859
  */
7777
7860
  async download(url, options = {}) {
7778
- if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
7779
- await __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
7861
+ if (this.refreshPromise) {
7862
+ await this.refreshPromise;
7780
7863
  }
7781
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addFetchOptionsDefaults).call(this, options);
7782
- 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);
7783
7866
  return response.blob();
7784
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
+ }
7785
8089
  /**
7786
8090
  * Starts a new PKCE flow.
7787
8091
  * These PKCE values are stateful, and must survive redirects and page refreshes.
@@ -7797,6 +8101,23 @@
7797
8101
  sessionStorage.setItem('codeChallenge', codeChallenge);
7798
8102
  return { codeChallengeMethod: 'S256', codeChallenge };
7799
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
+ }
7800
8121
  /**
7801
8122
  * Processes an OAuth authorization code.
7802
8123
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
@@ -7808,7 +8129,7 @@
7808
8129
  const formBody = new URLSearchParams();
7809
8130
  formBody.set('grant_type', 'authorization_code');
7810
8131
  formBody.set('code', code);
7811
- formBody.set('client_id', loginParams?.clientId || __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
8132
+ formBody.set('client_id', loginParams?.clientId || this.clientId);
7812
8133
  formBody.set('redirect_uri', loginParams?.redirectUri || getWindowOrigin());
7813
8134
  if (typeof sessionStorage !== 'undefined') {
7814
8135
  const codeVerifier = sessionStorage.getItem('codeVerifier');
@@ -7816,7 +8137,29 @@
7816
8137
  formBody.set('code_verifier', codeVerifier);
7817
8138
  }
7818
8139
  }
7819
- 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;
7820
8163
  }
7821
8164
  /**
7822
8165
  * Starts a new OAuth2 client credentials flow.
@@ -7827,13 +8170,24 @@
7827
8170
  * @returns Promise that resolves to the client profile.
7828
8171
  */
7829
8172
  async startClientLogin(clientId, clientSecret) {
7830
- __classPrivateFieldSet(this, _MedplumClient_clientId, clientId, "f");
7831
- __classPrivateFieldSet(this, _MedplumClient_clientSecret, clientSecret, "f");
8173
+ this.clientId = clientId;
8174
+ this.clientSecret = clientSecret;
7832
8175
  const formBody = new URLSearchParams();
7833
8176
  formBody.set('grant_type', 'client_credentials');
7834
8177
  formBody.set('client_id', clientId);
7835
8178
  formBody.set('client_secret', clientSecret);
7836
- 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);
7837
8191
  }
7838
8192
  /**
7839
8193
  * Invite a user to a project.
@@ -7844,275 +8198,72 @@
7844
8198
  async invite(projectId, body) {
7845
8199
  return this.post('admin/projects/' + projectId + '/invite', body);
7846
8200
  }
7847
- }
7848
- _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_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) {
7849
- const logins = this.getLogins().filter((login) => login.profile?.reference !== newLogin.profile?.reference);
7850
- logins.push(newLogin);
7851
- __classPrivateFieldGet(this, _MedplumClient_storage, "f").setObject('logins', logins);
7852
- }, _MedplumClient_refreshProfile = async function _MedplumClient_refreshProfile() {
7853
- __classPrivateFieldSet(this, _MedplumClient_profilePromise, new Promise((resolve, reject) => {
7854
- this.get('auth/me')
7855
- .then((result) => {
7856
- __classPrivateFieldSet(this, _MedplumClient_profilePromise, undefined, "f");
7857
- __classPrivateFieldSet(this, _MedplumClient_profile, result.profile, "f");
7858
- __classPrivateFieldSet(this, _MedplumClient_config, result.config, "f");
7859
- this.dispatchEvent({ type: 'change' });
7860
- resolve(__classPrivateFieldGet(this, _MedplumClient_profile, "f"));
7861
- })
7862
- .catch(reject);
7863
- }), "f");
7864
- return __classPrivateFieldGet(this, _MedplumClient_profilePromise, "f");
7865
- }, _MedplumClient_getCacheEntry = function _MedplumClient_getCacheEntry(key, options) {
7866
- if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") <= 0 || options?.cache === 'no-cache' || options?.cache === 'reload') {
7867
- return undefined;
7868
- }
7869
- const entry = __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").get(key);
7870
- if (!entry || entry.requestTime + __classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") < Date.now()) {
7871
- return undefined;
7872
- }
7873
- return entry;
7874
- }, _MedplumClient_setCacheEntry = function _MedplumClient_setCacheEntry(key, value) {
7875
- if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
7876
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").set(key, { requestTime: Date.now(), value });
7877
- }
7878
- }, _MedplumClient_cacheResource = function _MedplumClient_cacheResource(resource) {
7879
- if (resource?.id) {
7880
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, this.fhirUrl(resource.resourceType, resource.id).toString(), new ReadablePromise(Promise.resolve(resource)));
7881
- }
7882
- }, _MedplumClient_deleteCacheEntry = function _MedplumClient_deleteCacheEntry(key) {
7883
- if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
7884
- __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").delete(key);
7885
- }
7886
- }, _MedplumClient_request =
7887
- /**
7888
- * Makes an HTTP request.
7889
- * @param {string} method
7890
- * @param {string} url
7891
- * @param {string=} contentType
7892
- * @param {Object=} body
7893
- */
7894
- async function _MedplumClient_request(method, url, options = {}) {
7895
- if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
7896
- await __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
7897
- }
7898
- if (!url.startsWith('http')) {
7899
- url = __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + url;
7900
- }
7901
- options.method = method;
7902
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addFetchOptionsDefaults).call(this, options);
7903
- const response = await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchWithRetry).call(this, url, options);
7904
- if (response.status === 401) {
7905
- // Refresh and try again
7906
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_handleUnauthenticated).call(this, method, url, options);
7907
- }
7908
- if (response.status === 204 || response.status === 304) {
7909
- // No content or change
7910
- return undefined;
7911
- }
7912
- let obj = undefined;
7913
- try {
7914
- obj = await response.json();
7915
- }
7916
- catch (err) {
7917
- console.error('Error parsing response', response.status, err);
7918
- throw err;
7919
- }
7920
- if (response.status >= 400) {
7921
- throw new OperationOutcomeError(normalizeOperationOutcome(obj));
7922
- }
7923
- return obj;
7924
- }, _MedplumClient_fetchWithRetry = async function _MedplumClient_fetchWithRetry(url, options) {
7925
- const maxRetries = 3;
7926
- const retryDelay = 200;
7927
- let response = undefined;
7928
- for (let retry = 0; retry < maxRetries; retry++) {
7929
- response = (await __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, url, options));
7930
- if (response.status < 500) {
7931
- return response;
7932
- }
7933
- await new Promise((resolve) => setTimeout(resolve, retryDelay));
7934
- }
7935
- return response;
7936
- }, _MedplumClient_executeAutoBatch =
7937
- /**
7938
- * Executes a batch of requests that were automatically batched together.
7939
- */
7940
- async function _MedplumClient_executeAutoBatch() {
7941
- // Get the current queue
7942
- const entries = [...__classPrivateFieldGet(this, _MedplumClient_autoBatchQueue, "f")];
7943
- // Clear the queue
7944
- __classPrivateFieldGet(this, _MedplumClient_autoBatchQueue, "f").length = 0;
7945
- // Clear the timer
7946
- __classPrivateFieldSet(this, _MedplumClient_autoBatchTimerId, undefined, "f");
7947
- // If there is only one request in the batch, just execute it
7948
- if (entries.length === 1) {
7949
- const entry = entries[0];
7950
- entry.resolve(await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, entry.method, __classPrivateFieldGet(this, _MedplumClient_fhirBaseUrl, "f") + entry.url, entry.options));
7951
- return;
7952
- }
7953
- // Build the batch request
7954
- const batch = {
7955
- resourceType: 'Bundle',
7956
- type: 'batch',
7957
- entry: entries.map((e) => ({
7958
- request: {
7959
- method: e.method,
7960
- url: e.url,
7961
- },
7962
- resource: e.options.body ? JSON.parse(e.options.body) : undefined,
7963
- })),
7964
- };
7965
- // Execute the batch request
7966
- const response = (await this.post('fhir/R4', batch));
7967
- // Process the response
7968
- for (let i = 0; i < entries.length; i++) {
7969
- const entry = entries[i];
7970
- const responseEntry = response.entry?.[i];
7971
- if (responseEntry?.response?.outcome && !isOk(responseEntry.response.outcome)) {
7972
- entry.reject(new OperationOutcomeError(responseEntry.response.outcome));
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');
7973
8216
  }
7974
- else {
7975
- entry.resolve(responseEntry?.resource);
7976
- }
7977
- }
7978
- }, _MedplumClient_addFetchOptionsDefaults = function _MedplumClient_addFetchOptionsDefaults(options) {
7979
- if (!options.headers) {
7980
- options.headers = {};
7981
- }
7982
- const headers = options.headers;
7983
- headers['X-Medplum'] = 'extended';
7984
- if (!headers['Content-Type']) {
7985
- headers['Content-Type'] = FHIR_CONTENT_TYPE;
7986
- }
7987
- if (__classPrivateFieldGet(this, _MedplumClient_accessToken, "f")) {
7988
- headers['Authorization'] = 'Bearer ' + __classPrivateFieldGet(this, _MedplumClient_accessToken, "f");
7989
- }
7990
- if (!options.cache) {
7991
- options.cache = 'no-cache';
7992
- }
7993
- if (!options.credentials) {
7994
- options.credentials = 'include';
7995
- }
7996
- }, _MedplumClient_setRequestContentType = function _MedplumClient_setRequestContentType(options, contentType) {
7997
- if (!options.headers) {
7998
- options.headers = {};
7999
- }
8000
- const headers = options.headers;
8001
- headers['Content-Type'] = contentType;
8002
- }, _MedplumClient_setRequestBody = function _MedplumClient_setRequestBody(options, data) {
8003
- if (typeof data === 'string' ||
8004
- (typeof Blob !== 'undefined' && data instanceof Blob) ||
8005
- (typeof File !== 'undefined' && data instanceof File) ||
8006
- (typeof Uint8Array !== 'undefined' && data instanceof Uint8Array)) {
8007
- options.body = data;
8008
- }
8009
- else if (data) {
8010
- options.body = JSON.stringify(data);
8011
- }
8012
- }, _MedplumClient_handleUnauthenticated = function _MedplumClient_handleUnauthenticated(method, url, options) {
8013
- if (__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_refresh).call(this)) {
8014
- return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_request).call(this, method, url, options);
8015
- }
8016
- this.clearActiveLogin();
8017
- if (__classPrivateFieldGet(this, _MedplumClient_onUnauthenticated, "f")) {
8018
- __classPrivateFieldGet(this, _MedplumClient_onUnauthenticated, "f").call(this);
8019
- }
8020
- return Promise.reject(new Error('Unauthenticated'));
8021
- }, _MedplumClient_requestAuthorization =
8022
- /**
8023
- * Redirects the user to the login screen for authorization.
8024
- * Clears all auth state including local storage and session storage.
8025
- * See: https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
8026
- */
8027
- async function _MedplumClient_requestAuthorization(loginParams) {
8028
- const loginRequest = await this.ensureCodeChallenge(loginParams || {});
8029
- const url = new URL(__classPrivateFieldGet(this, _MedplumClient_authorizeUrl, "f"));
8030
- url.searchParams.set('response_type', 'code');
8031
- url.searchParams.set('state', sessionStorage.getItem('pkceState'));
8032
- url.searchParams.set('client_id', loginRequest.clientId || __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
8033
- url.searchParams.set('redirect_uri', loginRequest.redirectUri || getWindowOrigin());
8034
- url.searchParams.set('code_challenge_method', loginRequest.codeChallengeMethod);
8035
- url.searchParams.set('code_challenge', loginRequest.codeChallenge);
8036
- url.searchParams.set('scope', loginRequest.scope || 'openid profile');
8037
- window.location.assign(url.toString());
8038
- }, _MedplumClient_refresh = function _MedplumClient_refresh() {
8039
- if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
8040
- return __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
8041
- }
8042
- if (__classPrivateFieldGet(this, _MedplumClient_refreshToken, "f")) {
8043
- const formBody = new URLSearchParams();
8044
- formBody.set('grant_type', 'refresh_token');
8045
- formBody.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
8046
- formBody.set('refresh_token', __classPrivateFieldGet(this, _MedplumClient_refreshToken, "f"));
8047
- __classPrivateFieldSet(this, _MedplumClient_refreshPromise, __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchTokens).call(this, formBody), "f");
8048
- return __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
8049
- }
8050
- if (__classPrivateFieldGet(this, _MedplumClient_clientId, "f") && __classPrivateFieldGet(this, _MedplumClient_clientSecret, "f")) {
8051
- __classPrivateFieldSet(this, _MedplumClient_refreshPromise, this.startClientLogin(__classPrivateFieldGet(this, _MedplumClient_clientId, "f"), __classPrivateFieldGet(this, _MedplumClient_clientSecret, "f")), "f");
8052
- return __classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f");
8053
- }
8054
- return undefined;
8055
- }, _MedplumClient_fetchTokens =
8056
- /**
8057
- * Makes a POST request to the tokens endpoint.
8058
- * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8059
- * @param formBody Token parameters in URL encoded format.
8060
- */
8061
- async function _MedplumClient_fetchTokens(formBody) {
8062
- const response = await __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, __classPrivateFieldGet(this, _MedplumClient_tokenUrl, "f"), {
8063
- method: 'POST',
8064
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
8065
- body: formBody,
8066
- credentials: 'include',
8067
- });
8068
- if (!response.ok) {
8069
- this.clearActiveLogin();
8070
- throw new Error('Failed to fetch tokens');
8071
- }
8072
- const tokens = await response.json();
8073
- await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_verifyTokens).call(this, tokens);
8074
- return this.getProfile();
8075
- }, _MedplumClient_verifyTokens =
8076
- /**
8077
- * Verifies the tokens received from the auth server.
8078
- * Validates the JWT against the JWKS.
8079
- * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
8080
- * @param tokens
8081
- */
8082
- async function _MedplumClient_verifyTokens(tokens) {
8083
- const token = tokens.access_token;
8084
- // Verify token has not expired
8085
- const tokenPayload = parseJWTPayload(token);
8086
- if (Date.now() >= tokenPayload.exp * 1000) {
8087
- this.clearActiveLogin();
8088
- throw new Error('Token expired');
8089
- }
8090
- // Verify app_client_id
8091
- if (__classPrivateFieldGet(this, _MedplumClient_clientId, "f") && tokenPayload.client_id !== __classPrivateFieldGet(this, _MedplumClient_clientId, "f")) {
8092
- this.clearActiveLogin();
8093
- throw new Error('Token was not issued for this audience');
8217
+ const tokens = await response.json();
8218
+ await this.verifyTokens(tokens);
8219
+ return this.getProfile();
8094
8220
  }
8095
- return this.setActiveLogin({
8096
- accessToken: token,
8097
- refreshToken: tokens.refresh_token,
8098
- project: tokens.project,
8099
- profile: tokens.profile,
8100
- });
8101
- }, _MedplumClient_setupStorageListener = function _MedplumClient_setupStorageListener() {
8102
- try {
8103
- window.addEventListener('storage', (e) => {
8104
- if (e.key === null || e.key === 'activeLogin') {
8105
- // Storage events fire when different tabs make changes.
8106
- // On storage clear (key === null) or activeLogin change (key === 'activeLogin')
8107
- // Refresh the page to ensure the active login is up to date.
8108
- window.location.reload();
8109
- }
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,
8110
8245
  });
8111
8246
  }
8112
- catch (err) {
8113
- // Silently ignore if this environment does not support storage events
8247
+ /**
8248
+ * Sets up a listener for window storage events.
8249
+ * This synchronizes state across browser windows and browser tabs.
8250
+ */
8251
+ setupStorageListener() {
8252
+ try {
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
+ });
8261
+ }
8262
+ catch (err) {
8263
+ // Silently ignore if this environment does not support storage events
8264
+ }
8114
8265
  }
8115
- };
8266
+ }
8116
8267
  /**
8117
8268
  * Returns the default fetch method.
8118
8269
  * The default fetch is currently only available in browser environments.
@@ -8142,7 +8293,6 @@
8142
8293
  return url.endsWith('/') ? url : url + '/';
8143
8294
  }
8144
8295
 
8145
- var _ParserBuilder_prefixParselets, _ParserBuilder_infixParselets, _Parser_tokens, _Parser_prefixParselets, _Parser_infixParselets;
8146
8296
  class PrefixOperatorAtom {
8147
8297
  constructor(operator, child) {
8148
8298
  this.operator = operator;
@@ -8164,15 +8314,15 @@
8164
8314
  }
8165
8315
  class ParserBuilder {
8166
8316
  constructor() {
8167
- _ParserBuilder_prefixParselets.set(this, {});
8168
- _ParserBuilder_infixParselets.set(this, {});
8317
+ this.prefixParselets = {};
8318
+ this.infixParselets = {};
8169
8319
  }
8170
8320
  registerInfix(tokenType, parselet) {
8171
- __classPrivateFieldGet(this, _ParserBuilder_infixParselets, "f")[tokenType] = parselet;
8321
+ this.infixParselets[tokenType] = parselet;
8172
8322
  return this;
8173
8323
  }
8174
8324
  registerPrefix(tokenType, parselet) {
8175
- __classPrivateFieldGet(this, _ParserBuilder_prefixParselets, "f")[tokenType] = parselet;
8325
+ this.prefixParselets[tokenType] = parselet;
8176
8326
  return this;
8177
8327
  }
8178
8328
  prefix(tokenType, precedence, builder) {
@@ -8193,21 +8343,17 @@
8193
8343
  });
8194
8344
  }
8195
8345
  construct(input) {
8196
- return new Parser(input, __classPrivateFieldGet(this, _ParserBuilder_prefixParselets, "f"), __classPrivateFieldGet(this, _ParserBuilder_infixParselets, "f"));
8346
+ return new Parser(input, this.prefixParselets, this.infixParselets);
8197
8347
  }
8198
8348
  }
8199
- _ParserBuilder_prefixParselets = new WeakMap(), _ParserBuilder_infixParselets = new WeakMap();
8200
8349
  class Parser {
8201
8350
  constructor(tokens, prefixParselets, infixParselets) {
8202
- _Parser_tokens.set(this, void 0);
8203
- _Parser_prefixParselets.set(this, void 0);
8204
- _Parser_infixParselets.set(this, void 0);
8205
- __classPrivateFieldSet(this, _Parser_tokens, tokens, "f");
8206
- __classPrivateFieldSet(this, _Parser_prefixParselets, prefixParselets, "f");
8207
- __classPrivateFieldSet(this, _Parser_infixParselets, infixParselets, "f");
8351
+ this.tokens = tokens;
8352
+ this.prefixParselets = prefixParselets;
8353
+ this.infixParselets = infixParselets;
8208
8354
  }
8209
8355
  hasMore() {
8210
- return __classPrivateFieldGet(this, _Parser_tokens, "f").length > 0;
8356
+ return this.tokens.length > 0;
8211
8357
  }
8212
8358
  match(expected) {
8213
8359
  const token = this.peek();
@@ -8219,7 +8365,7 @@
8219
8365
  }
8220
8366
  consumeAndParse(precedence = Infinity) {
8221
8367
  const token = this.consume();
8222
- const prefix = __classPrivateFieldGet(this, _Parser_prefixParselets, "f")[token.id];
8368
+ const prefix = this.prefixParselets[token.id];
8223
8369
  if (!prefix) {
8224
8370
  throw Error(`Parse error at "${token.value}" (line ${token.line}, column ${token.column}). No matching prefix parselet.`);
8225
8371
  }
@@ -8243,7 +8389,7 @@
8243
8389
  return Infinity;
8244
8390
  }
8245
8391
  consume(expectedId, expectedValue) {
8246
- if (!__classPrivateFieldGet(this, _Parser_tokens, "f").length) {
8392
+ if (!this.tokens.length) {
8247
8393
  throw Error('Cant consume unknown more tokens.');
8248
8394
  }
8249
8395
  if (expectedId && this.peek()?.id !== expectedId) {
@@ -8254,21 +8400,19 @@
8254
8400
  const actual = this.peek();
8255
8401
  throw Error(`Expected "${expectedValue}" but got "${actual.value}" at line ${actual.line} column ${actual.column}.`);
8256
8402
  }
8257
- return __classPrivateFieldGet(this, _Parser_tokens, "f").shift();
8403
+ return this.tokens.shift();
8258
8404
  }
8259
8405
  peek() {
8260
- 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;
8261
8407
  }
8262
8408
  removeComments() {
8263
- __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');
8264
8410
  }
8265
8411
  getInfixParselet(token) {
8266
- return __classPrivateFieldGet(this, _Parser_infixParselets, "f")[token.id === 'Symbol' ? token.value : token.id];
8412
+ return this.infixParselets[token.id === 'Symbol' ? token.value : token.id];
8267
8413
  }
8268
8414
  }
8269
- _Parser_tokens = new WeakMap(), _Parser_prefixParselets = new WeakMap(), _Parser_infixParselets = new WeakMap();
8270
8415
 
8271
- 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;
8272
8416
  const STANDARD_UNITS = [
8273
8417
  'year',
8274
8418
  'years',
@@ -8289,190 +8433,203 @@
8289
8433
  ];
8290
8434
  class Tokenizer {
8291
8435
  constructor(str, keywords, operators, options) {
8292
- _Tokenizer_instances.add(this);
8293
- _Tokenizer_str.set(this, void 0);
8294
- _Tokenizer_keywords.set(this, void 0);
8295
- _Tokenizer_operators.set(this, void 0);
8296
- _Tokenizer_dateTimeLiterals.set(this, void 0);
8297
- _Tokenizer_symbolRegex.set(this, void 0);
8298
- _Tokenizer_result.set(this, []);
8299
- _Tokenizer_pos.set(this, { index: 0, line: 1, column: 0 });
8300
- _Tokenizer_markStack.set(this, []);
8301
- __classPrivateFieldSet(this, _Tokenizer_str, str, "f");
8302
- __classPrivateFieldSet(this, _Tokenizer_keywords, keywords, "f");
8303
- __classPrivateFieldSet(this, _Tokenizer_operators, operators, "f");
8304
- __classPrivateFieldSet(this, _Tokenizer_dateTimeLiterals, !!options?.dateTimeLiterals, "f");
8305
- __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]/;
8306
8444
  }
8307
8445
  tokenize() {
8308
- while (__classPrivateFieldGet(this, _Tokenizer_pos, "f").index < __classPrivateFieldGet(this, _Tokenizer_str, "f").length) {
8309
- const token = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeToken).call(this);
8446
+ while (this.pos.index < this.str.length) {
8447
+ const token = this.consumeToken();
8310
8448
  if (token) {
8311
- __classPrivateFieldGet(this, _Tokenizer_result, "f").push(token);
8449
+ this.result.push(token);
8312
8450
  }
8313
8451
  }
8314
- return __classPrivateFieldGet(this, _Tokenizer_result, "f");
8452
+ return this.result;
8315
8453
  }
8316
- }
8317
- _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() {
8318
- return __classPrivateFieldGet(this, _Tokenizer_result, "f").slice(-1)[0];
8319
- }, _Tokenizer_peekToken = function _Tokenizer_peekToken() {
8320
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_mark).call(this);
8321
- const token = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeToken).call(this);
8322
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_reset).call(this);
8323
- return token;
8324
- }, _Tokenizer_consumeToken = function _Tokenizer_consumeToken() {
8325
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhitespace).call(this);
8326
- const c = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this);
8327
- if (!c) {
8328
- return undefined;
8454
+ prevToken() {
8455
+ return this.result.slice(-1)[0];
8329
8456
  }
8330
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_mark).call(this);
8331
- const next = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this);
8332
- if (c === '/' && next === '*') {
8333
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeMultiLineComment).call(this);
8334
- }
8335
- if (c === '/' && next === '/') {
8336
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeSingleLineComment).call(this);
8337
- }
8338
- if (c === "'" || c === '"') {
8339
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeString).call(this, c);
8340
- }
8341
- if (c === '`') {
8342
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeBacktickSymbol).call(this);
8343
- }
8344
- if (c === '@') {
8345
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeDateTime).call(this);
8346
- }
8347
- if (c.match(/\d/)) {
8348
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeNumber).call(this);
8349
- }
8350
- if (c.match(/\w/)) {
8351
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeSymbol).call(this);
8352
- }
8353
- if (c === '$' && next.match(/\w/)) {
8354
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeSymbol).call(this);
8355
- }
8356
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeOperator).call(this);
8357
- }, _Tokenizer_consumeWhitespace = function _Tokenizer_consumeWhitespace() {
8358
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/\s/));
8359
- }, _Tokenizer_consumeMultiLineComment = function _Tokenizer_consumeMultiLineComment() {
8360
- const start = __classPrivateFieldGet(this, _Tokenizer_pos, "f").index;
8361
- __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) !== '/');
8362
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8363
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8364
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'Comment', __classPrivateFieldGet(this, _Tokenizer_str, "f").substring(start, __classPrivateFieldGet(this, _Tokenizer_pos, "f").index));
8365
- }, _Tokenizer_consumeSingleLineComment = function _Tokenizer_consumeSingleLineComment() {
8366
- 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'));
8367
- }, _Tokenizer_consumeString = function _Tokenizer_consumeString(endChar) {
8368
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8369
- 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));
8370
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8371
- return result;
8372
- }, _Tokenizer_consumeBacktickSymbol = function _Tokenizer_consumeBacktickSymbol() {
8373
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8374
- 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) !== '`'));
8375
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8376
- return result;
8377
- }, _Tokenizer_consumeDateTime = function _Tokenizer_consumeDateTime() {
8378
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this); // Consume "@"
8379
- const start = __classPrivateFieldGet(this, _Tokenizer_pos, "f").index;
8380
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/[\d-]/));
8381
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === 'T') {
8382
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8383
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/[\d:]/));
8384
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '.' && __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this).match(/\d/)) {
8385
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8386
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/\d/));
8387
- }
8388
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === 'Z') {
8389
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8390
- }
8391
- else if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '+' || __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '-') {
8392
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8393
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/[\d:]/));
8394
- }
8395
- }
8396
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'DateTime', __classPrivateFieldGet(this, _Tokenizer_str, "f").substring(start, __classPrivateFieldGet(this, _Tokenizer_pos, "f").index));
8397
- }, _Tokenizer_consumeNumber = function _Tokenizer_consumeNumber() {
8398
- const start = __classPrivateFieldGet(this, _Tokenizer_pos, "f").index;
8399
- let id = 'Number';
8400
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/\d/));
8401
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '.' && __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this).match(/\d/)) {
8402
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8403
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeWhile).call(this, () => __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this).match(/\d/));
8404
- }
8405
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '-' && __classPrivateFieldGet(this, _Tokenizer_dateTimeLiterals, "f")) {
8406
- // Rewind to one character before the start, and then treat as dateTime literal.
8407
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").index = start - 1;
8408
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeDateTime).call(this);
8409
- }
8410
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === ' ') {
8411
- if (isUnitToken(__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peekToken).call(this))) {
8412
- id = 'Quantity';
8413
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_consumeToken).call(this);
8414
- }
8415
- }
8416
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, id, __classPrivateFieldGet(this, _Tokenizer_str, "f").substring(start, __classPrivateFieldGet(this, _Tokenizer_pos, "f").index));
8417
- }, _Tokenizer_consumeSymbol = function _Tokenizer_consumeSymbol() {
8418
- 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")));
8419
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_prevToken).call(this)?.value !== '.' && __classPrivateFieldGet(this, _Tokenizer_keywords, "f").includes(value)) {
8420
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, value, value);
8421
- }
8422
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, 'Symbol', value);
8423
- }, _Tokenizer_consumeOperator = function _Tokenizer_consumeOperator() {
8424
- const c = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this);
8425
- const next = __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_peek).call(this);
8426
- const twoCharOp = c + next;
8427
- if (__classPrivateFieldGet(this, _Tokenizer_operators, "f").includes(twoCharOp)) {
8428
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8429
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8430
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, twoCharOp, twoCharOp);
8431
- }
8432
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8433
- return __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_buildToken).call(this, c, c);
8434
- }, _Tokenizer_consumeWhile = function _Tokenizer_consumeWhile(condition) {
8435
- const start = __classPrivateFieldGet(this, _Tokenizer_pos, "f").index;
8436
- while (__classPrivateFieldGet(this, _Tokenizer_pos, "f").index < __classPrivateFieldGet(this, _Tokenizer_str, "f").length && condition()) {
8437
- __classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_advance).call(this);
8438
- }
8439
- return __classPrivateFieldGet(this, _Tokenizer_str, "f").substring(start, __classPrivateFieldGet(this, _Tokenizer_pos, "f").index);
8440
- }, _Tokenizer_curr = function _Tokenizer_curr() {
8441
- return __classPrivateFieldGet(this, _Tokenizer_str, "f")[__classPrivateFieldGet(this, _Tokenizer_pos, "f").index];
8442
- }, _Tokenizer_prev = function _Tokenizer_prev() {
8443
- return __classPrivateFieldGet(this, _Tokenizer_str, "f")[__classPrivateFieldGet(this, _Tokenizer_pos, "f").index - 1] ?? '';
8444
- }, _Tokenizer_peek = function _Tokenizer_peek() {
8445
- return __classPrivateFieldGet(this, _Tokenizer_str, "f")[__classPrivateFieldGet(this, _Tokenizer_pos, "f").index + 1] ?? '';
8446
- }, _Tokenizer_mark = function _Tokenizer_mark() {
8447
- __classPrivateFieldGet(this, _Tokenizer_markStack, "f").push({ ...__classPrivateFieldGet(this, _Tokenizer_pos, "f") });
8448
- }, _Tokenizer_reset = function _Tokenizer_reset() {
8449
- const mark = __classPrivateFieldGet(this, _Tokenizer_markStack, "f").pop();
8450
- if (!mark) {
8451
- throw new Error('No mark to reset to');
8452
- }
8453
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").index = mark.index;
8454
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").line = mark.line;
8455
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").column = mark.column;
8456
- }, _Tokenizer_advance = function _Tokenizer_advance() {
8457
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").index++;
8458
- if (__classPrivateFieldGet(this, _Tokenizer_instances, "m", _Tokenizer_curr).call(this) === '\n') {
8459
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").line++;
8460
- __classPrivateFieldGet(this, _Tokenizer_pos, "f").column = 0;
8457
+ peekToken() {
8458
+ this.mark();
8459
+ const token = this.consumeToken();
8460
+ this.reset();
8461
+ return token;
8461
8462
  }
8462
- else {
8463
- __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();
8464
8496
  }
8465
- }, _Tokenizer_buildToken = function _Tokenizer_buildToken(id, value) {
8466
- const mark = __classPrivateFieldGet(this, _Tokenizer_markStack, "f").pop();
8467
- if (!mark) {
8468
- throw new Error('No mark for token');
8497
+ consumeWhitespace() {
8498
+ this.consumeWhile(() => this.curr().match(/\s/));
8469
8499
  }
8470
- return {
8471
- id,
8472
- value,
8473
- ...mark,
8474
- };
8475
- };
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
+ }
8476
8633
  function isUnitToken(token) {
8477
8634
  if (token) {
8478
8635
  if (token.id === 'String') {
@@ -10380,7 +10537,6 @@
10380
10537
  return input;
10381
10538
  }
10382
10539
 
10383
- var _SymbolAtom_instances, _SymbolAtom_evalValue;
10384
10540
  class FhirPathAtom {
10385
10541
  constructor(original, child) {
10386
10542
  this.original = original;
@@ -10420,32 +10576,28 @@
10420
10576
  }
10421
10577
  class SymbolAtom {
10422
10578
  constructor(name) {
10423
- _SymbolAtom_instances.add(this);
10424
10579
  this.name = name;
10425
10580
  }
10426
10581
  eval(context) {
10427
10582
  if (this.name === '$this') {
10428
10583
  return context;
10429
10584
  }
10430
- return context
10431
- .map((e) => __classPrivateFieldGet(this, _SymbolAtom_instances, "m", _SymbolAtom_evalValue).call(this, e))
10432
- .flat()
10433
- .filter((e) => e?.value !== undefined);
10585
+ return context.flatMap((e) => this.evalValue(e)).filter((e) => e?.value !== undefined);
10586
+ }
10587
+ evalValue(typedValue) {
10588
+ const input = typedValue.value;
10589
+ if (!input || typeof input !== 'object') {
10590
+ return undefined;
10591
+ }
10592
+ if (isResource(input) && input.resourceType === this.name) {
10593
+ return typedValue;
10594
+ }
10595
+ return getTypedPropertyValue(typedValue, this.name);
10434
10596
  }
10435
10597
  toString() {
10436
10598
  return this.name;
10437
10599
  }
10438
10600
  }
10439
- _SymbolAtom_instances = new WeakSet(), _SymbolAtom_evalValue = function _SymbolAtom_evalValue(typedValue) {
10440
- const input = typedValue.value;
10441
- if (!input || typeof input !== 'object') {
10442
- return undefined;
10443
- }
10444
- if (isResource(input) && input.resourceType === this.name) {
10445
- return typedValue;
10446
- }
10447
- return getTypedPropertyValue(typedValue, this.name);
10448
- };
10449
10601
  class EmptySetAtom {
10450
10602
  eval() {
10451
10603
  return [];
@@ -10862,10 +11014,8 @@
10862
11014
  return new Tokenizer(str, FHIRPATH_KEYWORDS, MAPPING_LANGUAGE_OPERATORS$1).tokenize();
10863
11015
  }
10864
11016
 
10865
- 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;
10866
11017
  class StructureMapParser {
10867
11018
  constructor(parser) {
10868
- _StructureMapParser_instances.add(this);
10869
11019
  this.parser = parser;
10870
11020
  this.structureMap = { resourceType: 'StructureMap' };
10871
11021
  }
@@ -10880,16 +11030,16 @@
10880
11030
  const next = this.parser.peek()?.value;
10881
11031
  switch (next) {
10882
11032
  case 'uses':
10883
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseUses).call(this);
11033
+ this.parseUses();
10884
11034
  break;
10885
11035
  case 'imports':
10886
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseImport).call(this);
11036
+ this.parseImport();
10887
11037
  break;
10888
11038
  case 'group':
10889
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseGroup).call(this);
11039
+ this.parseGroup();
10890
11040
  break;
10891
11041
  case 'conceptmap':
10892
- __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseConceptMap).call(this);
11042
+ this.parseConceptMap();
10893
11043
  break;
10894
11044
  default:
10895
11045
  throw new Error(`Unexpected token: ${next}`);
@@ -10897,263 +11047,280 @@
10897
11047
  }
10898
11048
  return this.structureMap;
10899
11049
  }
10900
- }
10901
- _StructureMapParser_instances = new WeakSet(), _StructureMapParser_parseUses = function _StructureMapParser_parseUses() {
10902
- // 'uses' url structureAlias? 'as' modelMode
10903
- // uses "http://hl7.org/fhir/StructureDefinition/tutorial-left" as source
10904
- this.parser.consume('Symbol', 'uses');
10905
- const result = {};
10906
- result.url = this.parser.consume('String').value;
10907
- if (this.parser.peek()?.value === 'alias') {
10908
- this.parser.consume('Symbol', 'alias');
10909
- result.alias = this.parser.consume('Symbol').value;
10910
- }
10911
- this.parser.consume('Symbol', 'as');
10912
- result.mode = this.parser.consume().value;
10913
- if (!this.structureMap.structure) {
10914
- this.structureMap.structure = [];
10915
- }
10916
- this.structureMap.structure.push(result);
10917
- }, _StructureMapParser_parseImport = function _StructureMapParser_parseImport() {
10918
- this.parser.consume('Symbol', 'imports');
10919
- if (!this.structureMap.import) {
10920
- this.structureMap.import = [];
10921
- }
10922
- this.structureMap.import.push(this.parser.consume('String').value);
10923
- }, _StructureMapParser_parseGroup = function _StructureMapParser_parseGroup() {
10924
- // 'group' identifier parameters extends? typeMode? rules
10925
- // group tutorial(source src : TLeft, target tgt : TRight) {
10926
- const result = {};
10927
- this.parser.consume('Symbol', 'group');
10928
- result.name = this.parser.consume('Symbol').value;
10929
- result.input = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseParameters).call(this);
10930
- if (this.parser.peek()?.value === 'extends') {
10931
- this.parser.consume('Symbol', 'extends');
10932
- result.extends = this.parser.consume('Symbol').value;
10933
- }
10934
- if (this.parser.peek()?.value === '<<') {
10935
- this.parser.consume('<<');
10936
- result.typeMode = this.parser.consume().value;
10937
- if (this.parser.peek()?.value === '+') {
10938
- this.parser.consume('+');
10939
- result.typeMode = 'type-and-types';
10940
- }
10941
- this.parser.consume('>>');
10942
- }
10943
- else {
10944
- result.typeMode = 'none';
10945
- }
10946
- result.rule = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRules).call(this);
10947
- if (!this.structureMap.group) {
10948
- this.structureMap.group = [];
10949
- }
10950
- this.structureMap.group.push(result);
10951
- }, _StructureMapParser_parseParameters = function _StructureMapParser_parseParameters() {
10952
- const parameters = [];
10953
- this.parser.consume('(');
10954
- while (this.parser.hasMore() && this.parser.peek()?.value !== ')') {
10955
- parameters.push(__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseParameter).call(this));
10956
- if (this.parser.peek()?.value === ',') {
10957
- 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;
10958
11059
  }
10959
- }
10960
- this.parser.consume(')');
10961
- return parameters;
10962
- }, _StructureMapParser_parseParameter = function _StructureMapParser_parseParameter() {
10963
- // inputMode identifier type?
10964
- // ':' identifier
10965
- // source src : TLeft
10966
- const result = {};
10967
- result.mode = this.parser.consume().value;
10968
- result.name = this.parser.consume('Symbol').value;
10969
- if (this.parser.peek()?.value === ':') {
10970
- this.parser.consume(':');
10971
- result.type = this.parser.consume('Symbol').value;
10972
- }
10973
- return result;
10974
- }, _StructureMapParser_parseRules = function _StructureMapParser_parseRules() {
10975
- const rules = [];
10976
- this.parser.consume('{');
10977
- while (this.parser.hasMore() && this.parser.peek()?.value !== '}') {
10978
- rules.push(__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRule).call(this));
10979
- }
10980
- this.parser.consume('}');
10981
- return rules;
10982
- }, _StructureMapParser_parseRule = function _StructureMapParser_parseRule() {
10983
- const result = {
10984
- source: __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleSources).call(this),
10985
- };
10986
- if (this.parser.peek()?.value === '->') {
10987
- this.parser.consume('->');
10988
- result.target = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTargets).call(this);
10989
- }
10990
- if (this.parser.peek()?.value === 'then') {
10991
- this.parser.consume('Symbol', 'then');
10992
- if (this.parser.peek()?.id === '{') {
10993
- 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('>>');
10994
11093
  }
10995
11094
  else {
10996
- result.dependent = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleDependents).call(this);
11095
+ result.typeMode = 'none';
10997
11096
  }
11097
+ result.rule = this.parseRules();
11098
+ if (!this.structureMap.group) {
11099
+ this.structureMap.group = [];
11100
+ }
11101
+ this.structureMap.group.push(result);
10998
11102
  }
10999
- if (this.parser.peek()?.id === 'String') {
11000
- result.name = this.parser.consume().value;
11001
- }
11002
- else {
11003
- result.name = result.source?.[0]?.element;
11004
- }
11005
- this.parser.consume(';');
11006
- return result;
11007
- }, _StructureMapParser_parseRuleSources = function _StructureMapParser_parseRuleSources() {
11008
- const sources = [__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleSource).call(this)];
11009
- while (this.parser.hasMore() && this.parser.peek()?.value === ',') {
11010
- this.parser.consume(',');
11011
- sources.push(__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleSource).call(this));
11012
- }
11013
- return sources;
11014
- }, _StructureMapParser_parseRuleSource = function _StructureMapParser_parseRuleSource() {
11015
- const result = {};
11016
- const context = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleContext).call(this);
11017
- if (context.includes('.')) {
11018
- const parts = context.split('.');
11019
- result.context = parts[0];
11020
- result.element = parts[1];
11021
- }
11022
- else {
11023
- result.context = context;
11024
- }
11025
- if (this.parser.hasMore() && this.parser.peek()?.value === ':') {
11026
- this.parser.consume(':');
11027
- result.type = this.parser.consume().value;
11028
- }
11029
- if (this.parser.hasMore() && this.parser.peek()?.value === 'default') {
11030
- this.parser.consume('default');
11031
- this.parser.consumeAndParse();
11032
- }
11033
- if (this.parser.peek()?.value === 'first' ||
11034
- this.parser.peek()?.value === 'not_first' ||
11035
- this.parser.peek()?.value === 'last' ||
11036
- this.parser.peek()?.value === 'not_last' ||
11037
- this.parser.peek()?.value === 'only_one') {
11038
- 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;
11039
11114
  }
11040
- if (this.parser.peek()?.value === 'as') {
11041
- this.parser.consume('Symbol', 'as');
11042
- 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;
11043
11127
  }
11044
- if (this.parser.peek()?.value === 'where') {
11045
- this.parser.consume('Symbol', 'where');
11046
- const whereFhirPath = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11047
- 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;
11048
11162
  }
11049
- if (this.parser.peek()?.value === 'check') {
11050
- this.parser.consume('Symbol', 'check');
11051
- const checkFhirPath = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11052
- 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;
11053
11170
  }
11054
- return result;
11055
- }, _StructureMapParser_parseRuleTargets = function _StructureMapParser_parseRuleTargets() {
11056
- const targets = [__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTarget).call(this)];
11057
- while (this.parser.hasMore() && this.parser.peek()?.value === ',') {
11058
- this.parser.consume(',');
11059
- targets.push(__classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleTarget).call(this));
11060
- }
11061
- return targets;
11062
- }, _StructureMapParser_parseRuleTarget = function _StructureMapParser_parseRuleTarget() {
11063
- const result = {};
11064
- const context = __classPrivateFieldGet(this, _StructureMapParser_instances, "m", _StructureMapParser_parseRuleContext).call(this);
11065
- if (context.includes('.')) {
11066
- const parts = context.split('.');
11067
- result.contextType = 'variable';
11068
- result.context = parts[0];
11069
- 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;
11070
11212
  }
11071
- else {
11072
- 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;
11073
11220
  }
11074
- if (this.parser.peek()?.value === '=') {
11075
- this.parser.consume('=');
11076
- __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;
11077
11248
  }
11078
- if (this.parser.peek()?.value === 'as') {
11079
- this.parser.consume('Symbol', 'as');
11080
- 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
+ }
11081
11264
  }
11082
- if (this.parser.peek()?.value === 'first' ||
11083
- this.parser.peek()?.value === 'share' ||
11084
- this.parser.peek()?.value === 'last' ||
11085
- this.parser.peek()?.value === 'collate') {
11086
- result.listMode = [this.parser.consume().value];
11265
+ parseRuleTargetSymbol(result, literalAtom) {
11266
+ result.parameter = [{ valueId: literalAtom.name }];
11087
11267
  }
11088
- return result;
11089
- }, _StructureMapParser_parseRuleTargetTransform = function _StructureMapParser_parseRuleTargetTransform(result) {
11090
- result.transform = 'copy';
11091
- const transformFhirPath = this.parser.consumeAndParse(6 /* OperatorPrecedence.As */);
11092
- if (transformFhirPath instanceof SymbolAtom) {
11093
- __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
+ }
11094
11284
  }
11095
- else if (transformFhirPath instanceof FunctionAtom) {
11096
- __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
+ }
11097
11299
  }
11098
- else if (transformFhirPath instanceof LiteralAtom) {
11099
- __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;
11100
11307
  }
11101
- else {
11102
- throw new Error(`Unexpected FHIRPath: ${transformFhirPath}`);
11103
- }
11104
- }, _StructureMapParser_parseRuleTargetSymbol = function _StructureMapParser_parseRuleTargetSymbol(result, literalAtom) {
11105
- result.parameter = [{ valueId: literalAtom.name }];
11106
- }, _StructureMapParser_parseRuleTargetFunction = function _StructureMapParser_parseRuleTargetFunction(result, functionAtom) {
11107
- const functionName = functionAtom.name;
11108
- switch (functionName) {
11109
- case 'create':
11110
- result.parameter = [
11111
- {
11112
- valueString: (functionAtom.args?.[0]).value.value,
11113
- },
11114
- ];
11115
- break;
11116
- case 'translate':
11117
- result.parameter = [{}];
11118
- break;
11119
- default:
11120
- 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
+ ];
11121
11316
  }
11122
- }, _StructureMapParser_parseRuleTargetLiteral = function _StructureMapParser_parseRuleTargetLiteral(result, literalAtom) {
11123
- switch (literalAtom.value.type) {
11124
- case 'boolean':
11125
- result.parameter = [{ valueBoolean: literalAtom.value.value }];
11126
- break;
11127
- case 'decimal':
11128
- result.parameter = [{ valueDecimal: literalAtom.value.value }];
11129
- break;
11130
- case 'string':
11131
- result.parameter = [{ valueString: literalAtom.value.value }];
11132
- break;
11133
- default:
11134
- throw new Error('Unknown target literal type: ' + literalAtom.value.type);
11135
- }
11136
- }, _StructureMapParser_parseRuleContext = function _StructureMapParser_parseRuleContext() {
11137
- let identifier = this.parser.consume().value;
11138
- while (this.parser.peek()?.value === '.') {
11139
- this.parser.consume('.');
11140
- identifier += '.' + this.parser.consume().value;
11141
- }
11142
- return identifier;
11143
- }, _StructureMapParser_parseRuleDependents = function _StructureMapParser_parseRuleDependents() {
11144
- const atom = this.parser.consumeAndParse(100 /* OperatorPrecedence.Arrow */);
11145
- return [
11146
- {
11147
- name: atom.name,
11148
- variable: atom.args.map((arg) => arg.name),
11149
- },
11150
- ];
11151
- }, _StructureMapParser_parseConceptMap = function _StructureMapParser_parseConceptMap() {
11152
- while (this.parser.peek()?.value !== '}') {
11153
- this.parser.consume();
11317
+ parseConceptMap() {
11318
+ while (this.parser.peek()?.value !== '}') {
11319
+ this.parser.consume();
11320
+ }
11321
+ this.parser.consume('}');
11154
11322
  }
11155
- this.parser.consume('}');
11156
- };
11323
+ }
11157
11324
  const fhirPathParserBuilder$1 = initFhirPathParserBuilder()
11158
11325
  .registerInfix('->', { precedence: 100 /* OperatorPrecedence.Arrow */ })
11159
11326
  .registerInfix(';', { precedence: 200 /* OperatorPrecedence.Semicolon */ });
@@ -11464,7 +11631,6 @@
11464
11631
  }
11465
11632
  }
11466
11633
 
11467
- 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;
11468
11634
  /*
11469
11635
  * This file provides schema validation utilities for FHIR JSON objects.
11470
11636
  *
@@ -11626,14 +11792,11 @@
11626
11792
  }
11627
11793
  class FhirSchemaValidator {
11628
11794
  constructor(root) {
11629
- _FhirSchemaValidator_instances.add(this);
11630
- _FhirSchemaValidator_issues.set(this, void 0);
11631
- _FhirSchemaValidator_root.set(this, void 0);
11632
- __classPrivateFieldSet(this, _FhirSchemaValidator_issues, [], "f");
11633
- __classPrivateFieldSet(this, _FhirSchemaValidator_root, root, "f");
11795
+ this.issues = [];
11796
+ this.root = root;
11634
11797
  }
11635
11798
  validate() {
11636
- const resource = __classPrivateFieldGet(this, _FhirSchemaValidator_root, "f");
11799
+ const resource = this.root;
11637
11800
  if (!resource) {
11638
11801
  throw new OperationOutcomeError(validationError('Resource is null'));
11639
11802
  }
@@ -11642,142 +11805,172 @@
11642
11805
  throw new OperationOutcomeError(validationError('Missing resource type'));
11643
11806
  }
11644
11807
  // Check for "null" once for the entire object hierarchy
11645
- checkForNull(resource, '', __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f"));
11646
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateObject).call(this, toTypedValue(resource), resourceType);
11647
- 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) {
11648
11811
  throw new OperationOutcomeError({
11649
11812
  resourceType: 'OperationOutcome',
11650
- issue: __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f"),
11813
+ issue: this.issues,
11651
11814
  });
11652
11815
  }
11653
11816
  }
11654
- }
11655
- _FhirSchemaValidator_issues = new WeakMap(), _FhirSchemaValidator_root = new WeakMap(), _FhirSchemaValidator_instances = new WeakSet(), _FhirSchemaValidator_validateObject = function _FhirSchemaValidator_validateObject(typedValue, path) {
11656
- const definition = globalSchema.types[typedValue.type];
11657
- if (!definition) {
11658
- throw new OperationOutcomeError(validationError('Unknown type: ' + typedValue.type));
11659
- }
11660
- const propertyDefinitions = definition.properties;
11661
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkProperties).call(this, path, propertyDefinitions, typedValue);
11662
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkAdditionalProperties).call(this, path, typedValue, propertyDefinitions);
11663
- }, _FhirSchemaValidator_checkProperties = function _FhirSchemaValidator_checkProperties(path, propertyDefinitions, typedValue) {
11664
- for (const [key, elementDefinition] of Object.entries(propertyDefinitions)) {
11665
- __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);
11666
11825
  }
11667
- }, _FhirSchemaValidator_checkProperty = function _FhirSchemaValidator_checkProperty(path, elementDefinition, typedValue) {
11668
- const propertyName = path.split('.').pop();
11669
- const value = getTypedPropertyValue(typedValue, propertyName);
11670
- if (isEmpty(value)) {
11671
- if (elementDefinition.min !== undefined && elementDefinition.min > 0) {
11672
- __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);
11673
11829
  }
11674
- return;
11675
11830
  }
11676
- if (elementDefinition.max === '*') {
11677
- if (!Array.isArray(value)) {
11678
- __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
+ }
11679
11838
  return;
11680
11839
  }
11681
- for (const item of value) {
11682
- __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);
11683
11855
  }
11684
11856
  }
11685
- else {
11686
- if (Array.isArray(value)) {
11687
- __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
11688
11860
  return;
11689
11861
  }
11690
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkPropertyValue).call(this, path, elementDefinition, value);
11691
- }
11692
- }, _FhirSchemaValidator_checkPropertyValue = function _FhirSchemaValidator_checkPropertyValue(path, elementDefinition, typedValue) {
11693
- if (typedValue.value === null) {
11694
- // Null handled separately
11695
- return;
11696
- }
11697
- if (isLowerCase(typedValue.type.charAt(0))) {
11698
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validatePrimitiveType).call(this, elementDefinition, typedValue);
11699
- }
11700
- else {
11701
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateObject).call(this, typedValue, path);
11702
- }
11703
- }, _FhirSchemaValidator_validatePrimitiveType = function _FhirSchemaValidator_validatePrimitiveType(elementDefinition, typedValue) {
11704
- const { type, value } = typedValue;
11705
- if (value === null) {
11706
- // Null handled separately, so this code should never be reached
11707
- // Leaving this check in place for now, in case we change the null handling
11708
- return;
11709
- }
11710
- // First, make sure the value is the correct JS type
11711
- const expectedType = fhirTypeToJsType[typedValue.type];
11712
- if (typeof value !== expectedType) {
11713
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Invalid type for ' + type);
11714
- return;
11715
- }
11716
- // Then, perform additional checks for specialty types
11717
- if (expectedType === 'string') {
11718
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateString).call(this, elementDefinition, type, value);
11719
- }
11720
- else if (expectedType === 'number') {
11721
- __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
+ }
11722
11868
  }
11723
- }, _FhirSchemaValidator_validateString = function _FhirSchemaValidator_validateString(elementDefinition, type, value) {
11724
- if (!value.trim()) {
11725
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Invalid empty string');
11726
- 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
+ }
11727
11889
  }
11728
- // Try to get the regex
11729
- const valueDefinition = globalSchema.types[type]?.properties?.['value'];
11730
- if (valueDefinition?.type) {
11731
- const regex = getExtensionValue(valueDefinition.type[0], 'http://hl7.org/fhir/StructureDefinition/regex');
11732
- if (regex) {
11733
- if (!value.match(new RegExp(regex))) {
11734
- __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
+ }
11735
11903
  }
11736
11904
  }
11737
11905
  }
11738
- }, _FhirSchemaValidator_validateNumber = function _FhirSchemaValidator_validateNumber(elementDefinition, type, value) {
11739
- if (isNaN(value) || !isFinite(value)) {
11740
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Invalid ' + type + ' value');
11741
- return;
11742
- }
11743
- if (isIntegerType(type) && !Number.isInteger(value)) {
11744
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Number is not an integer');
11745
- }
11746
- if (type === exports.PropertyType.positiveInt && value <= 0) {
11747
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_createIssue).call(this, elementDefinition, 'Number is less than or equal to zero');
11748
- }
11749
- if (type === exports.PropertyType.unsignedInt && value < 0) {
11750
- __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
+ }
11751
11920
  }
11752
- }, _FhirSchemaValidator_checkAdditionalProperties = function _FhirSchemaValidator_checkAdditionalProperties(path, typedValue, propertyDefinitions) {
11753
- const object = typedValue.value;
11754
- for (const key of Object.keys(object)) {
11755
- __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
+ }
11756
11926
  }
11757
- }, _FhirSchemaValidator_checkAdditionalProperty = function _FhirSchemaValidator_checkAdditionalProperty(path, key, typedValue, propertyDefinitions) {
11758
- if (!baseResourceProperties.has(key) &&
11759
- !(key in propertyDefinitions) &&
11760
- !isChoiceOfType(key, typedValue, propertyDefinitions) &&
11761
- !__classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_checkPrimitiveElement).call(this, path, key, typedValue)) {
11762
- const expression = `${path}.${key}`;
11763
- __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
+ }
11764
11942
  }
11765
- }, _FhirSchemaValidator_checkPrimitiveElement = function _FhirSchemaValidator_checkPrimitiveElement(path, key, typedValue) {
11766
- // Primitive element starts with underscore
11767
- if (!key.startsWith('_')) {
11768
- 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;
11769
11969
  }
11770
- // Validate the non-underscore property exists
11771
- const primitiveKey = key.slice(1);
11772
- if (!(primitiveKey in typedValue.value)) {
11773
- return false;
11970
+ createIssue(elementDefinition, message) {
11971
+ this.issues.push(createStructureIssue(elementDefinition.path, message));
11774
11972
  }
11775
- // Then validate the element
11776
- __classPrivateFieldGet(this, _FhirSchemaValidator_instances, "m", _FhirSchemaValidator_validateObject).call(this, { type: 'Element', value: typedValue.value[key] }, path);
11777
- return true;
11778
- }, _FhirSchemaValidator_createIssue = function _FhirSchemaValidator_createIssue(elementDefinition, message) {
11779
- __classPrivateFieldGet(this, _FhirSchemaValidator_issues, "f").push(createStructureIssue(elementDefinition.path, message));
11780
- };
11973
+ }
11781
11974
  function isIntegerType(propertyType) {
11782
11975
  return (propertyType === exports.PropertyType.integer ||
11783
11976
  propertyType === exports.PropertyType.positiveInt ||
@@ -12526,6 +12719,7 @@
12526
12719
  exports.calculateAgeString = calculateAgeString;
12527
12720
  exports.capitalize = capitalize;
12528
12721
  exports.checkForNull = checkForNull;
12722
+ exports.convertToTransactionBundle = convertToTransactionBundle;
12529
12723
  exports.createReference = createReference;
12530
12724
  exports.createStructureIssue = createStructureIssue;
12531
12725
  exports.created = created;