@medplum/core 2.0.20 → 2.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +75 -8
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.min.cjs +1 -1
- package/dist/esm/client.mjs +74 -6
- package/dist/esm/client.mjs.map +1 -1
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/search/search.mjs +1 -1
- package/dist/esm/search/search.mjs.map +1 -1
- package/dist/esm/sftp.mjs +0 -1
- package/dist/esm/sftp.mjs.map +1 -1
- package/dist/types/client.d.ts +16 -2
- package/dist/types/config.d.ts +7 -3
- package/dist/types/typeschema/types.d.ts +56 -0
- package/package.json +1 -1
package/dist/esm/client.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { encodeBase64 } from './base64.mjs';
|
|
|
11
11
|
|
|
12
12
|
// PKCE auth based on:
|
|
13
13
|
// https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
|
|
14
|
-
const MEDPLUM_VERSION = "2.0.
|
|
14
|
+
const MEDPLUM_VERSION = "2.0.21-87271fa1" ;
|
|
15
15
|
const DEFAULT_BASE_URL = 'https://api.medplum.com/';
|
|
16
16
|
const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
|
|
17
17
|
const DEFAULT_CACHE_TIME = 60000; // 60 seconds
|
|
@@ -1307,10 +1307,11 @@ class MedplumClient extends EventTarget {
|
|
|
1307
1307
|
* See The FHIR "batch/transaction" section for full details: https://hl7.org/fhir/http.html#transaction
|
|
1308
1308
|
* @category Batch
|
|
1309
1309
|
* @param bundle The FHIR batch/transaction bundle.
|
|
1310
|
+
* @param options Optional fetch options.
|
|
1310
1311
|
* @returns The FHIR batch/transaction response bundle.
|
|
1311
1312
|
*/
|
|
1312
|
-
executeBatch(bundle) {
|
|
1313
|
-
return this.post(this.fhirBaseUrl.slice(0, -1), bundle);
|
|
1313
|
+
executeBatch(bundle, options = {}) {
|
|
1314
|
+
return this.post(this.fhirBaseUrl.slice(0, -1), bundle, undefined, options);
|
|
1314
1315
|
}
|
|
1315
1316
|
/**
|
|
1316
1317
|
* Sends an email using the Medplum Email API.
|
|
@@ -1540,6 +1541,37 @@ class MedplumClient extends EventTarget {
|
|
|
1540
1541
|
},
|
|
1541
1542
|
});
|
|
1542
1543
|
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Performs Bulk Data Export operation request flow. See The FHIR "Bulk Data Export" for full details: https://build.fhir.org/ig/HL7/bulk-data/export.html#bulk-data-export
|
|
1546
|
+
*
|
|
1547
|
+
* @param exportLevel Optional export level. Defaults to system level export. 'Group/:id' - Group of Patients, 'Patient' - All Patients.
|
|
1548
|
+
* @param resourceTypes A string of comma-delimited FHIR resource types.
|
|
1549
|
+
* @param since Resources will be included in the response if their state has changed after the supplied time (e.g. if Resource.meta.lastUpdated is later than the supplied _since time).
|
|
1550
|
+
* @param options Optional fetch options.
|
|
1551
|
+
* @returns Bulk Data Response containing links to Bulk Data files. See "Response - Complete Status" for full details: https://build.fhir.org/ig/HL7/bulk-data/export.html#response---complete-status
|
|
1552
|
+
*/
|
|
1553
|
+
async bulkExport(exportLevel = '', resourceTypes, since, options = {}) {
|
|
1554
|
+
const fhirPath = exportLevel ? `${exportLevel}/` : exportLevel;
|
|
1555
|
+
const url = this.fhirUrl(`${fhirPath}$export`);
|
|
1556
|
+
if (resourceTypes) {
|
|
1557
|
+
url.searchParams.set('_type', resourceTypes);
|
|
1558
|
+
}
|
|
1559
|
+
if (since) {
|
|
1560
|
+
url.searchParams.set('_since', since);
|
|
1561
|
+
}
|
|
1562
|
+
options.method = exportLevel ? 'GET' : 'POST';
|
|
1563
|
+
this.addFetchOptionsDefaults(options);
|
|
1564
|
+
const headers = options.headers;
|
|
1565
|
+
headers['Prefer'] = 'respond-async';
|
|
1566
|
+
const response = await this.fetchWithRetry(url.toString(), options);
|
|
1567
|
+
if (response.status === 202) {
|
|
1568
|
+
const contentLocation = response.headers.get('content-location');
|
|
1569
|
+
if (contentLocation) {
|
|
1570
|
+
return await this.pollStatus(contentLocation);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
return await this.parseResponse(response, 'POST', url.toString());
|
|
1574
|
+
}
|
|
1543
1575
|
//
|
|
1544
1576
|
// Private helpers
|
|
1545
1577
|
//
|
|
@@ -1606,6 +1638,9 @@ class MedplumClient extends EventTarget {
|
|
|
1606
1638
|
options.method = method;
|
|
1607
1639
|
this.addFetchOptionsDefaults(options);
|
|
1608
1640
|
const response = await this.fetchWithRetry(url, options);
|
|
1641
|
+
return await this.parseResponse(response, method, url, options);
|
|
1642
|
+
}
|
|
1643
|
+
async parseResponse(response, method, url, options = {}) {
|
|
1609
1644
|
if (response.status === 401) {
|
|
1610
1645
|
// Refresh and try again
|
|
1611
1646
|
return this.handleUnauthenticated(method, url, options);
|
|
@@ -1638,14 +1673,37 @@ class MedplumClient extends EventTarget {
|
|
|
1638
1673
|
const retryDelay = 200;
|
|
1639
1674
|
let response = undefined;
|
|
1640
1675
|
for (let retry = 0; retry < maxRetries; retry++) {
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1676
|
+
try {
|
|
1677
|
+
response = (await this.fetch(url, options));
|
|
1678
|
+
if (response.status < 500) {
|
|
1679
|
+
return response;
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
catch (err) {
|
|
1683
|
+
this.retryCatch(retry, maxRetries, err);
|
|
1644
1684
|
}
|
|
1645
1685
|
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
1646
1686
|
}
|
|
1647
1687
|
return response;
|
|
1648
1688
|
}
|
|
1689
|
+
async pollStatus(statusUrl) {
|
|
1690
|
+
let checkStatus = true;
|
|
1691
|
+
let resultResponse;
|
|
1692
|
+
const retryDelay = 200;
|
|
1693
|
+
while (checkStatus) {
|
|
1694
|
+
const fetchOptions = {
|
|
1695
|
+
method: 'GET',
|
|
1696
|
+
};
|
|
1697
|
+
this.addFetchOptionsDefaults(fetchOptions);
|
|
1698
|
+
const statusResponse = await this.fetchWithRetry(statusUrl, fetchOptions);
|
|
1699
|
+
if (statusResponse.status !== 202) {
|
|
1700
|
+
checkStatus = false;
|
|
1701
|
+
resultResponse = statusResponse;
|
|
1702
|
+
}
|
|
1703
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
1704
|
+
}
|
|
1705
|
+
return await this.parseResponse(resultResponse, 'POST', statusUrl);
|
|
1706
|
+
}
|
|
1649
1707
|
/**
|
|
1650
1708
|
* Executes a batch of requests that were automatically batched together.
|
|
1651
1709
|
*/
|
|
@@ -1703,6 +1761,7 @@ class MedplumClient extends EventTarget {
|
|
|
1703
1761
|
headers = {};
|
|
1704
1762
|
options.headers = headers;
|
|
1705
1763
|
}
|
|
1764
|
+
headers['Accept'] = FHIR_CONTENT_TYPE;
|
|
1706
1765
|
headers['X-Medplum'] = 'extended';
|
|
1707
1766
|
if (options.body && !headers['Content-Type']) {
|
|
1708
1767
|
headers['Content-Type'] = FHIR_CONTENT_TYPE;
|
|
@@ -1959,6 +2018,15 @@ class MedplumClient extends EventTarget {
|
|
|
1959
2018
|
// Silently ignore if this environment does not support storage events
|
|
1960
2019
|
}
|
|
1961
2020
|
}
|
|
2021
|
+
retryCatch(retryNumber, maxRetries, err) {
|
|
2022
|
+
// This is for the 1st retry to avoid multiple notifications
|
|
2023
|
+
if (err.message === 'Failed to fetch' && retryNumber === 1) {
|
|
2024
|
+
this.dispatchEvent({ type: 'offline' });
|
|
2025
|
+
}
|
|
2026
|
+
if (retryNumber >= maxRetries - 1) {
|
|
2027
|
+
throw err;
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
1962
2030
|
}
|
|
1963
2031
|
/**
|
|
1964
2032
|
* Returns the default fetch method.
|