@medplum/core 2.0.2 → 2.0.3
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/README.md +7 -3
- package/dist/cjs/client.d.ts +11 -0
- package/dist/cjs/index.cjs +318 -225
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.min.cjs +1 -1
- package/dist/cjs/outcomes.d.ts +1 -0
- package/dist/esm/base-schema.json.mjs +7 -0
- package/dist/esm/base-schema.json.mjs.map +1 -1
- package/dist/esm/client.d.ts +11 -0
- package/dist/esm/client.mjs +106 -22
- package/dist/esm/client.mjs.map +1 -1
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/outcomes.d.ts +1 -0
- package/dist/esm/outcomes.mjs +6 -4
- package/dist/esm/outcomes.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -1174,6 +1174,211 @@
|
|
|
1174
1174
|
return decodePayload(payload);
|
|
1175
1175
|
}
|
|
1176
1176
|
|
|
1177
|
+
const OK_ID = 'ok';
|
|
1178
|
+
const CREATED_ID = 'created';
|
|
1179
|
+
const GONE_ID = 'gone';
|
|
1180
|
+
const NOT_MODIFIED_ID = 'not-modified';
|
|
1181
|
+
const NOT_FOUND_ID = 'not-found';
|
|
1182
|
+
const UNAUTHORIZED_ID = 'unauthorized';
|
|
1183
|
+
const FORBIDDEN_ID = 'forbidden';
|
|
1184
|
+
const TOO_MANY_REQUESTS_ID = 'too-many-requests';
|
|
1185
|
+
const allOk = {
|
|
1186
|
+
resourceType: 'OperationOutcome',
|
|
1187
|
+
id: OK_ID,
|
|
1188
|
+
issue: [
|
|
1189
|
+
{
|
|
1190
|
+
severity: 'information',
|
|
1191
|
+
code: 'informational',
|
|
1192
|
+
details: {
|
|
1193
|
+
text: 'All OK',
|
|
1194
|
+
},
|
|
1195
|
+
},
|
|
1196
|
+
],
|
|
1197
|
+
};
|
|
1198
|
+
const created = {
|
|
1199
|
+
resourceType: 'OperationOutcome',
|
|
1200
|
+
id: CREATED_ID,
|
|
1201
|
+
issue: [
|
|
1202
|
+
{
|
|
1203
|
+
severity: 'information',
|
|
1204
|
+
code: 'informational',
|
|
1205
|
+
details: {
|
|
1206
|
+
text: 'Created',
|
|
1207
|
+
},
|
|
1208
|
+
},
|
|
1209
|
+
],
|
|
1210
|
+
};
|
|
1211
|
+
const notModified = {
|
|
1212
|
+
resourceType: 'OperationOutcome',
|
|
1213
|
+
id: NOT_MODIFIED_ID,
|
|
1214
|
+
issue: [
|
|
1215
|
+
{
|
|
1216
|
+
severity: 'information',
|
|
1217
|
+
code: 'informational',
|
|
1218
|
+
details: {
|
|
1219
|
+
text: 'Not Modified',
|
|
1220
|
+
},
|
|
1221
|
+
},
|
|
1222
|
+
],
|
|
1223
|
+
};
|
|
1224
|
+
const notFound = {
|
|
1225
|
+
resourceType: 'OperationOutcome',
|
|
1226
|
+
id: NOT_FOUND_ID,
|
|
1227
|
+
issue: [
|
|
1228
|
+
{
|
|
1229
|
+
severity: 'error',
|
|
1230
|
+
code: 'not-found',
|
|
1231
|
+
details: {
|
|
1232
|
+
text: 'Not found',
|
|
1233
|
+
},
|
|
1234
|
+
},
|
|
1235
|
+
],
|
|
1236
|
+
};
|
|
1237
|
+
const unauthorized = {
|
|
1238
|
+
resourceType: 'OperationOutcome',
|
|
1239
|
+
id: UNAUTHORIZED_ID,
|
|
1240
|
+
issue: [
|
|
1241
|
+
{
|
|
1242
|
+
severity: 'error',
|
|
1243
|
+
code: 'login',
|
|
1244
|
+
details: {
|
|
1245
|
+
text: 'Unauthorized',
|
|
1246
|
+
},
|
|
1247
|
+
},
|
|
1248
|
+
],
|
|
1249
|
+
};
|
|
1250
|
+
const forbidden = {
|
|
1251
|
+
resourceType: 'OperationOutcome',
|
|
1252
|
+
id: FORBIDDEN_ID,
|
|
1253
|
+
issue: [
|
|
1254
|
+
{
|
|
1255
|
+
severity: 'error',
|
|
1256
|
+
code: 'forbidden',
|
|
1257
|
+
details: {
|
|
1258
|
+
text: 'Forbidden',
|
|
1259
|
+
},
|
|
1260
|
+
},
|
|
1261
|
+
],
|
|
1262
|
+
};
|
|
1263
|
+
const gone = {
|
|
1264
|
+
resourceType: 'OperationOutcome',
|
|
1265
|
+
id: GONE_ID,
|
|
1266
|
+
issue: [
|
|
1267
|
+
{
|
|
1268
|
+
severity: 'error',
|
|
1269
|
+
code: 'deleted',
|
|
1270
|
+
details: {
|
|
1271
|
+
text: 'Gone',
|
|
1272
|
+
},
|
|
1273
|
+
},
|
|
1274
|
+
],
|
|
1275
|
+
};
|
|
1276
|
+
const tooManyRequests = {
|
|
1277
|
+
resourceType: 'OperationOutcome',
|
|
1278
|
+
id: TOO_MANY_REQUESTS_ID,
|
|
1279
|
+
issue: [
|
|
1280
|
+
{
|
|
1281
|
+
severity: 'error',
|
|
1282
|
+
code: 'throttled',
|
|
1283
|
+
details: {
|
|
1284
|
+
text: 'Too Many Requests',
|
|
1285
|
+
},
|
|
1286
|
+
},
|
|
1287
|
+
],
|
|
1288
|
+
};
|
|
1289
|
+
function badRequest(details, expression) {
|
|
1290
|
+
return {
|
|
1291
|
+
resourceType: 'OperationOutcome',
|
|
1292
|
+
issue: [
|
|
1293
|
+
{
|
|
1294
|
+
severity: 'error',
|
|
1295
|
+
code: 'invalid',
|
|
1296
|
+
details: {
|
|
1297
|
+
text: details,
|
|
1298
|
+
},
|
|
1299
|
+
expression: expression ? [expression] : undefined,
|
|
1300
|
+
},
|
|
1301
|
+
],
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1304
|
+
function isOperationOutcome(value) {
|
|
1305
|
+
return typeof value === 'object' && value !== null && value.resourceType === 'OperationOutcome';
|
|
1306
|
+
}
|
|
1307
|
+
function isOk(outcome) {
|
|
1308
|
+
return outcome.id === OK_ID || outcome.id === CREATED_ID || outcome.id === NOT_MODIFIED_ID;
|
|
1309
|
+
}
|
|
1310
|
+
function isNotFound(outcome) {
|
|
1311
|
+
return outcome.id === NOT_FOUND_ID;
|
|
1312
|
+
}
|
|
1313
|
+
function isGone(outcome) {
|
|
1314
|
+
return outcome.id === GONE_ID;
|
|
1315
|
+
}
|
|
1316
|
+
function getStatus(outcome) {
|
|
1317
|
+
if (outcome.id === OK_ID) {
|
|
1318
|
+
return 200;
|
|
1319
|
+
}
|
|
1320
|
+
else if (outcome.id === CREATED_ID) {
|
|
1321
|
+
return 201;
|
|
1322
|
+
}
|
|
1323
|
+
else if (outcome.id === NOT_MODIFIED_ID) {
|
|
1324
|
+
return 304;
|
|
1325
|
+
}
|
|
1326
|
+
else if (outcome.id === UNAUTHORIZED_ID) {
|
|
1327
|
+
return 401;
|
|
1328
|
+
}
|
|
1329
|
+
else if (outcome.id === FORBIDDEN_ID) {
|
|
1330
|
+
return 403;
|
|
1331
|
+
}
|
|
1332
|
+
else if (outcome.id === NOT_FOUND_ID) {
|
|
1333
|
+
return 404;
|
|
1334
|
+
}
|
|
1335
|
+
else if (outcome.id === GONE_ID) {
|
|
1336
|
+
return 410;
|
|
1337
|
+
}
|
|
1338
|
+
else if (outcome.id === TOO_MANY_REQUESTS_ID) {
|
|
1339
|
+
return 429;
|
|
1340
|
+
}
|
|
1341
|
+
else {
|
|
1342
|
+
return 400;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Asserts that the operation completed successfully and that the resource is defined.
|
|
1347
|
+
* @param outcome The operation outcome.
|
|
1348
|
+
* @param resource The resource that may or may not have been returned.
|
|
1349
|
+
*/
|
|
1350
|
+
function assertOk(outcome, resource) {
|
|
1351
|
+
if (!isOk(outcome) || resource === undefined) {
|
|
1352
|
+
throw new OperationOutcomeError(outcome);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
class OperationOutcomeError extends Error {
|
|
1356
|
+
constructor(outcome) {
|
|
1357
|
+
super(outcome?.issue?.[0].details?.text);
|
|
1358
|
+
this.outcome = outcome;
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
/**
|
|
1362
|
+
* Normalizes an error object into a displayable error string.
|
|
1363
|
+
* @param error The error value which could be a string, Error, OperationOutcome, or other unknown type.
|
|
1364
|
+
* @returns A display string for the error.
|
|
1365
|
+
*/
|
|
1366
|
+
function normalizeErrorString(error) {
|
|
1367
|
+
if (!error) {
|
|
1368
|
+
return 'Unknown error';
|
|
1369
|
+
}
|
|
1370
|
+
if (typeof error === 'string') {
|
|
1371
|
+
return error;
|
|
1372
|
+
}
|
|
1373
|
+
if (error instanceof Error) {
|
|
1374
|
+
return error.message;
|
|
1375
|
+
}
|
|
1376
|
+
if (isOperationOutcome(error)) {
|
|
1377
|
+
return error.issue?.[0]?.details?.text ?? 'Unknown error';
|
|
1378
|
+
}
|
|
1379
|
+
return JSON.stringify(error);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1177
1382
|
var _ReadablePromise_suspender, _ReadablePromise_status, _ReadablePromise_response, _ReadablePromise_error, _a;
|
|
1178
1383
|
/**
|
|
1179
1384
|
* The ReadablePromise class wraps a request promise suitable for React Suspense.
|
|
@@ -5736,6 +5941,13 @@
|
|
|
5736
5941
|
code: "string"
|
|
5737
5942
|
}
|
|
5738
5943
|
]
|
|
5944
|
+
},
|
|
5945
|
+
useSubject: {
|
|
5946
|
+
type: [
|
|
5947
|
+
{
|
|
5948
|
+
code: "boolean"
|
|
5949
|
+
}
|
|
5950
|
+
]
|
|
5739
5951
|
}
|
|
5740
5952
|
}
|
|
5741
5953
|
}
|
|
@@ -6046,14 +6258,15 @@
|
|
|
6046
6258
|
|
|
6047
6259
|
// PKCE auth based on:
|
|
6048
6260
|
// https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
|
|
6049
|
-
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_request, _MedplumClient_executeAutoBatch, _MedplumClient_addFetchOptionsDefaults, _MedplumClient_setRequestContentType, _MedplumClient_setRequestBody, _MedplumClient_handleUnauthenticated, _MedplumClient_requestAuthorization, _MedplumClient_refresh, _MedplumClient_fetchTokens, _MedplumClient_verifyTokens, _MedplumClient_setupStorageListener;
|
|
6050
|
-
const MEDPLUM_VERSION = "2.0.
|
|
6261
|
+
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;
|
|
6262
|
+
const MEDPLUM_VERSION = "2.0.3-e39c01ab";
|
|
6051
6263
|
const DEFAULT_BASE_URL = 'https://api.medplum.com/';
|
|
6052
6264
|
const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
|
|
6053
6265
|
const DEFAULT_CACHE_TIME = 60000; // 60 seconds
|
|
6054
6266
|
const JSON_CONTENT_TYPE = 'application/json';
|
|
6055
6267
|
const FHIR_CONTENT_TYPE = 'application/fhir+json';
|
|
6056
6268
|
const PATCH_CONTENT_TYPE = 'application/json-patch+json';
|
|
6269
|
+
const system = { resourceType: 'Device', id: 'system', deviceName: [{ name: 'System' }] };
|
|
6057
6270
|
/**
|
|
6058
6271
|
* The MedplumClient class provides a client for the Medplum FHIR server.
|
|
6059
6272
|
*
|
|
@@ -6465,16 +6678,29 @@
|
|
|
6465
6678
|
* @param clientId The external client ID.
|
|
6466
6679
|
* @param redirectUri The external identity provider redirect URI.
|
|
6467
6680
|
* @param baseLogin The Medplum login request.
|
|
6681
|
+
* @category Authentication
|
|
6468
6682
|
*/
|
|
6469
6683
|
async signInWithExternalAuth(authorizeUrl, clientId, redirectUri, baseLogin) {
|
|
6470
6684
|
const loginRequest = await this.ensureCodeChallenge(baseLogin);
|
|
6685
|
+
window.location.assign(this.getExternalAuthRedirectUri(authorizeUrl, clientId, redirectUri, loginRequest));
|
|
6686
|
+
}
|
|
6687
|
+
/**
|
|
6688
|
+
* Builds the external identity provider redirect URI.
|
|
6689
|
+
* @param authorizeUrl The external authorization URL.
|
|
6690
|
+
* @param clientId The external client ID.
|
|
6691
|
+
* @param redirectUri The external identity provider redirect URI.
|
|
6692
|
+
* @param loginRequest The Medplum login request.
|
|
6693
|
+
* @returns The external identity provider redirect URI.
|
|
6694
|
+
* @category Authentication
|
|
6695
|
+
*/
|
|
6696
|
+
getExternalAuthRedirectUri(authorizeUrl, clientId, redirectUri, loginRequest) {
|
|
6471
6697
|
const url = new URL(authorizeUrl);
|
|
6472
6698
|
url.searchParams.set('response_type', 'code');
|
|
6473
6699
|
url.searchParams.set('client_id', clientId);
|
|
6474
6700
|
url.searchParams.set('redirect_uri', redirectUri);
|
|
6475
6701
|
url.searchParams.set('scope', 'openid profile email');
|
|
6476
6702
|
url.searchParams.set('state', JSON.stringify(loginRequest));
|
|
6477
|
-
|
|
6703
|
+
return url.toString();
|
|
6478
6704
|
}
|
|
6479
6705
|
/**
|
|
6480
6706
|
* Builds a FHIR URL from a collection of URL path components.
|
|
@@ -6549,7 +6775,23 @@
|
|
|
6549
6775
|
* @returns Promise to the search result bundle.
|
|
6550
6776
|
*/
|
|
6551
6777
|
search(resourceType, query, options = {}) {
|
|
6552
|
-
|
|
6778
|
+
const url = this.fhirSearchUrl(resourceType, query);
|
|
6779
|
+
const cacheKey = url.toString() + '-search';
|
|
6780
|
+
const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, options);
|
|
6781
|
+
if (cached) {
|
|
6782
|
+
return cached.value;
|
|
6783
|
+
}
|
|
6784
|
+
const promise = new ReadablePromise((async () => {
|
|
6785
|
+
const bundle = await this.get(url, options);
|
|
6786
|
+
if (bundle.entry) {
|
|
6787
|
+
for (const entry of bundle.entry) {
|
|
6788
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_cacheResource).call(this, entry.resource);
|
|
6789
|
+
}
|
|
6790
|
+
}
|
|
6791
|
+
return bundle;
|
|
6792
|
+
})());
|
|
6793
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
|
|
6794
|
+
return promise;
|
|
6553
6795
|
}
|
|
6554
6796
|
/**
|
|
6555
6797
|
* Sends a FHIR search request for a single resource.
|
|
@@ -6658,6 +6900,9 @@
|
|
|
6658
6900
|
if (!refString) {
|
|
6659
6901
|
return undefined;
|
|
6660
6902
|
}
|
|
6903
|
+
if (refString === 'system') {
|
|
6904
|
+
return system;
|
|
6905
|
+
}
|
|
6661
6906
|
const [resourceType, id] = refString.split('/');
|
|
6662
6907
|
if (!resourceType || !id) {
|
|
6663
6908
|
return undefined;
|
|
@@ -6710,6 +6955,9 @@
|
|
|
6710
6955
|
if (!refString) {
|
|
6711
6956
|
return new ReadablePromise(Promise.reject(new Error('Missing reference')));
|
|
6712
6957
|
}
|
|
6958
|
+
if (refString === 'system') {
|
|
6959
|
+
return new ReadablePromise(Promise.resolve(system));
|
|
6960
|
+
}
|
|
6713
6961
|
const [resourceType, id] = refString.split('/');
|
|
6714
6962
|
if (!resourceType || !id) {
|
|
6715
6963
|
return new ReadablePromise(Promise.reject(new Error('Invalid reference')));
|
|
@@ -6734,11 +6982,17 @@
|
|
|
6734
6982
|
* @param resourceType The FHIR resource type.
|
|
6735
6983
|
* @returns Promise to a schema with the requested resource type.
|
|
6736
6984
|
*/
|
|
6737
|
-
|
|
6985
|
+
requestSchema(resourceType) {
|
|
6738
6986
|
if (resourceType in globalSchema.types) {
|
|
6739
|
-
return globalSchema;
|
|
6987
|
+
return Promise.resolve(globalSchema);
|
|
6740
6988
|
}
|
|
6741
|
-
const
|
|
6989
|
+
const cacheKey = resourceType + '-requestSchema';
|
|
6990
|
+
const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, undefined);
|
|
6991
|
+
if (cached) {
|
|
6992
|
+
return cached.value;
|
|
6993
|
+
}
|
|
6994
|
+
const promise = new ReadablePromise((async () => {
|
|
6995
|
+
const query = `{
|
|
6742
6996
|
StructureDefinitionList(name: "${resourceType}") {
|
|
6743
6997
|
name,
|
|
6744
6998
|
description,
|
|
@@ -6767,14 +7021,17 @@
|
|
|
6767
7021
|
target
|
|
6768
7022
|
}
|
|
6769
7023
|
}`.replace(/\s+/g, ' ');
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
7024
|
+
const response = (await this.graphql(query));
|
|
7025
|
+
for (const structureDefinition of response.data.StructureDefinitionList) {
|
|
7026
|
+
indexStructureDefinition(structureDefinition);
|
|
7027
|
+
}
|
|
7028
|
+
for (const searchParameter of response.data.SearchParameterList) {
|
|
7029
|
+
indexSearchParameter(searchParameter);
|
|
7030
|
+
}
|
|
7031
|
+
return globalSchema;
|
|
7032
|
+
})());
|
|
7033
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
|
|
7034
|
+
return promise;
|
|
6778
7035
|
}
|
|
6779
7036
|
/**
|
|
6780
7037
|
* Reads resource history by resource type and ID.
|
|
@@ -7075,10 +7332,15 @@
|
|
|
7075
7332
|
throw new Error('Missing id');
|
|
7076
7333
|
}
|
|
7077
7334
|
this.invalidateSearches(resource.resourceType);
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7335
|
+
let result = await this.put(this.fhirUrl(resource.resourceType, resource.id), resource);
|
|
7336
|
+
if (!result) {
|
|
7337
|
+
// On 304 not modified, result will be undefined
|
|
7338
|
+
// Return the user input instead
|
|
7339
|
+
// return result ?? resource;
|
|
7340
|
+
result = resource;
|
|
7341
|
+
}
|
|
7342
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_cacheResource).call(this, result);
|
|
7343
|
+
return result;
|
|
7082
7344
|
}
|
|
7083
7345
|
/**
|
|
7084
7346
|
* Updates a FHIR resource using JSONPatch operations.
|
|
@@ -7125,6 +7387,7 @@
|
|
|
7125
7387
|
* @returns The result of the delete operation.
|
|
7126
7388
|
*/
|
|
7127
7389
|
deleteResource(resourceType, id) {
|
|
7390
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_deleteCacheEntry).call(this, this.fhirUrl(resourceType, id).toString());
|
|
7128
7391
|
this.invalidateSearches(resourceType);
|
|
7129
7392
|
return this.delete(this.fhirUrl(resourceType, id));
|
|
7130
7393
|
}
|
|
@@ -7464,6 +7727,14 @@
|
|
|
7464
7727
|
if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
|
|
7465
7728
|
__classPrivateFieldGet(this, _MedplumClient_requestCache, "f").set(key, { requestTime: Date.now(), value });
|
|
7466
7729
|
}
|
|
7730
|
+
}, _MedplumClient_cacheResource = function _MedplumClient_cacheResource(resource) {
|
|
7731
|
+
if (resource?.id) {
|
|
7732
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, this.fhirUrl(resource.resourceType, resource.id).toString(), new ReadablePromise(Promise.resolve(resource)));
|
|
7733
|
+
}
|
|
7734
|
+
}, _MedplumClient_deleteCacheEntry = function _MedplumClient_deleteCacheEntry(key) {
|
|
7735
|
+
if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
|
|
7736
|
+
__classPrivateFieldGet(this, _MedplumClient_requestCache, "f").delete(key);
|
|
7737
|
+
}
|
|
7467
7738
|
}, _MedplumClient_request =
|
|
7468
7739
|
/**
|
|
7469
7740
|
* Makes an HTTP request.
|
|
@@ -7481,7 +7752,7 @@
|
|
|
7481
7752
|
}
|
|
7482
7753
|
options.method = method;
|
|
7483
7754
|
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addFetchOptionsDefaults).call(this, options);
|
|
7484
|
-
const response = await __classPrivateFieldGet(this,
|
|
7755
|
+
const response = await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchWithRetry).call(this, url, options);
|
|
7485
7756
|
if (response.status === 401) {
|
|
7486
7757
|
// Refresh and try again
|
|
7487
7758
|
return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_handleUnauthenticated).call(this, method, url, options);
|
|
@@ -7490,11 +7761,30 @@
|
|
|
7490
7761
|
// No content or change
|
|
7491
7762
|
return undefined;
|
|
7492
7763
|
}
|
|
7493
|
-
|
|
7764
|
+
let obj = undefined;
|
|
7765
|
+
try {
|
|
7766
|
+
obj = await response.json();
|
|
7767
|
+
}
|
|
7768
|
+
catch (err) {
|
|
7769
|
+
console.error('Error parsing response', response.status, err);
|
|
7770
|
+
throw err;
|
|
7771
|
+
}
|
|
7494
7772
|
if (response.status >= 400) {
|
|
7495
7773
|
throw obj;
|
|
7496
7774
|
}
|
|
7497
7775
|
return obj;
|
|
7776
|
+
}, _MedplumClient_fetchWithRetry = async function _MedplumClient_fetchWithRetry(url, options) {
|
|
7777
|
+
const maxRetries = 3;
|
|
7778
|
+
const retryDelay = 200;
|
|
7779
|
+
let response = undefined;
|
|
7780
|
+
for (let retry = 0; retry < maxRetries; retry++) {
|
|
7781
|
+
response = (await __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, url, options));
|
|
7782
|
+
if (response.status < 500) {
|
|
7783
|
+
return response;
|
|
7784
|
+
}
|
|
7785
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
7786
|
+
}
|
|
7787
|
+
return response;
|
|
7498
7788
|
}, _MedplumClient_executeAutoBatch =
|
|
7499
7789
|
/**
|
|
7500
7790
|
* Executes a batch of requests that were automatically batched together.
|
|
@@ -7530,7 +7820,12 @@
|
|
|
7530
7820
|
for (let i = 0; i < entries.length; i++) {
|
|
7531
7821
|
const entry = entries[i];
|
|
7532
7822
|
const responseEntry = response.entry?.[i];
|
|
7533
|
-
|
|
7823
|
+
if (responseEntry?.response?.outcome && !isOk(responseEntry.response.outcome)) {
|
|
7824
|
+
entry.reject(responseEntry.response.outcome);
|
|
7825
|
+
}
|
|
7826
|
+
else {
|
|
7827
|
+
entry.resolve(responseEntry?.resource);
|
|
7828
|
+
}
|
|
7534
7829
|
}
|
|
7535
7830
|
}, _MedplumClient_addFetchOptionsDefaults = function _MedplumClient_addFetchOptionsDefaults(options) {
|
|
7536
7831
|
if (!options.headers) {
|
|
@@ -11129,209 +11424,6 @@
|
|
|
11129
11424
|
return operator === exports.Operator.NOT_EQUALS || operator === exports.Operator.NOT;
|
|
11130
11425
|
}
|
|
11131
11426
|
|
|
11132
|
-
const OK_ID = 'ok';
|
|
11133
|
-
const CREATED_ID = 'created';
|
|
11134
|
-
const GONE_ID = 'gone';
|
|
11135
|
-
const NOT_MODIFIED_ID = 'not-modified';
|
|
11136
|
-
const NOT_FOUND_ID = 'not-found';
|
|
11137
|
-
const UNAUTHORIZED_ID = 'unauthorized';
|
|
11138
|
-
const FORBIDDEN_ID = 'forbidden';
|
|
11139
|
-
const TOO_MANY_REQUESTS_ID = 'too-many-requests';
|
|
11140
|
-
const allOk = {
|
|
11141
|
-
resourceType: 'OperationOutcome',
|
|
11142
|
-
id: OK_ID,
|
|
11143
|
-
issue: [
|
|
11144
|
-
{
|
|
11145
|
-
severity: 'information',
|
|
11146
|
-
code: 'informational',
|
|
11147
|
-
details: {
|
|
11148
|
-
text: 'All OK',
|
|
11149
|
-
},
|
|
11150
|
-
},
|
|
11151
|
-
],
|
|
11152
|
-
};
|
|
11153
|
-
const created = {
|
|
11154
|
-
resourceType: 'OperationOutcome',
|
|
11155
|
-
id: CREATED_ID,
|
|
11156
|
-
issue: [
|
|
11157
|
-
{
|
|
11158
|
-
severity: 'information',
|
|
11159
|
-
code: 'informational',
|
|
11160
|
-
details: {
|
|
11161
|
-
text: 'Created',
|
|
11162
|
-
},
|
|
11163
|
-
},
|
|
11164
|
-
],
|
|
11165
|
-
};
|
|
11166
|
-
const notModified = {
|
|
11167
|
-
resourceType: 'OperationOutcome',
|
|
11168
|
-
id: NOT_MODIFIED_ID,
|
|
11169
|
-
issue: [
|
|
11170
|
-
{
|
|
11171
|
-
severity: 'information',
|
|
11172
|
-
code: 'informational',
|
|
11173
|
-
details: {
|
|
11174
|
-
text: 'Not Modified',
|
|
11175
|
-
},
|
|
11176
|
-
},
|
|
11177
|
-
],
|
|
11178
|
-
};
|
|
11179
|
-
const notFound = {
|
|
11180
|
-
resourceType: 'OperationOutcome',
|
|
11181
|
-
id: NOT_FOUND_ID,
|
|
11182
|
-
issue: [
|
|
11183
|
-
{
|
|
11184
|
-
severity: 'error',
|
|
11185
|
-
code: 'not-found',
|
|
11186
|
-
details: {
|
|
11187
|
-
text: 'Not found',
|
|
11188
|
-
},
|
|
11189
|
-
},
|
|
11190
|
-
],
|
|
11191
|
-
};
|
|
11192
|
-
const unauthorized = {
|
|
11193
|
-
resourceType: 'OperationOutcome',
|
|
11194
|
-
id: UNAUTHORIZED_ID,
|
|
11195
|
-
issue: [
|
|
11196
|
-
{
|
|
11197
|
-
severity: 'error',
|
|
11198
|
-
code: 'login',
|
|
11199
|
-
details: {
|
|
11200
|
-
text: 'Unauthorized',
|
|
11201
|
-
},
|
|
11202
|
-
},
|
|
11203
|
-
],
|
|
11204
|
-
};
|
|
11205
|
-
const forbidden = {
|
|
11206
|
-
resourceType: 'OperationOutcome',
|
|
11207
|
-
id: FORBIDDEN_ID,
|
|
11208
|
-
issue: [
|
|
11209
|
-
{
|
|
11210
|
-
severity: 'error',
|
|
11211
|
-
code: 'forbidden',
|
|
11212
|
-
details: {
|
|
11213
|
-
text: 'Forbidden',
|
|
11214
|
-
},
|
|
11215
|
-
},
|
|
11216
|
-
],
|
|
11217
|
-
};
|
|
11218
|
-
const gone = {
|
|
11219
|
-
resourceType: 'OperationOutcome',
|
|
11220
|
-
id: GONE_ID,
|
|
11221
|
-
issue: [
|
|
11222
|
-
{
|
|
11223
|
-
severity: 'error',
|
|
11224
|
-
code: 'deleted',
|
|
11225
|
-
details: {
|
|
11226
|
-
text: 'Gone',
|
|
11227
|
-
},
|
|
11228
|
-
},
|
|
11229
|
-
],
|
|
11230
|
-
};
|
|
11231
|
-
const tooManyRequests = {
|
|
11232
|
-
resourceType: 'OperationOutcome',
|
|
11233
|
-
id: TOO_MANY_REQUESTS_ID,
|
|
11234
|
-
issue: [
|
|
11235
|
-
{
|
|
11236
|
-
severity: 'error',
|
|
11237
|
-
code: 'throttled',
|
|
11238
|
-
details: {
|
|
11239
|
-
text: 'Too Many Requests',
|
|
11240
|
-
},
|
|
11241
|
-
},
|
|
11242
|
-
],
|
|
11243
|
-
};
|
|
11244
|
-
function badRequest(details, expression) {
|
|
11245
|
-
return {
|
|
11246
|
-
resourceType: 'OperationOutcome',
|
|
11247
|
-
issue: [
|
|
11248
|
-
{
|
|
11249
|
-
severity: 'error',
|
|
11250
|
-
code: 'invalid',
|
|
11251
|
-
details: {
|
|
11252
|
-
text: details,
|
|
11253
|
-
},
|
|
11254
|
-
expression: expression ? [expression] : undefined,
|
|
11255
|
-
},
|
|
11256
|
-
],
|
|
11257
|
-
};
|
|
11258
|
-
}
|
|
11259
|
-
function isOk(outcome) {
|
|
11260
|
-
return outcome.id === OK_ID || outcome.id === CREATED_ID || outcome.id === NOT_MODIFIED_ID;
|
|
11261
|
-
}
|
|
11262
|
-
function isNotFound(outcome) {
|
|
11263
|
-
return outcome.id === NOT_FOUND_ID;
|
|
11264
|
-
}
|
|
11265
|
-
function isGone(outcome) {
|
|
11266
|
-
return outcome.id === GONE_ID;
|
|
11267
|
-
}
|
|
11268
|
-
function getStatus(outcome) {
|
|
11269
|
-
if (outcome.id === OK_ID) {
|
|
11270
|
-
return 200;
|
|
11271
|
-
}
|
|
11272
|
-
else if (outcome.id === CREATED_ID) {
|
|
11273
|
-
return 201;
|
|
11274
|
-
}
|
|
11275
|
-
else if (outcome.id === NOT_MODIFIED_ID) {
|
|
11276
|
-
return 304;
|
|
11277
|
-
}
|
|
11278
|
-
else if (outcome.id === UNAUTHORIZED_ID) {
|
|
11279
|
-
return 401;
|
|
11280
|
-
}
|
|
11281
|
-
else if (outcome.id === FORBIDDEN_ID) {
|
|
11282
|
-
return 403;
|
|
11283
|
-
}
|
|
11284
|
-
else if (outcome.id === NOT_FOUND_ID) {
|
|
11285
|
-
return 404;
|
|
11286
|
-
}
|
|
11287
|
-
else if (outcome.id === GONE_ID) {
|
|
11288
|
-
return 410;
|
|
11289
|
-
}
|
|
11290
|
-
else if (outcome.id === TOO_MANY_REQUESTS_ID) {
|
|
11291
|
-
return 429;
|
|
11292
|
-
}
|
|
11293
|
-
else {
|
|
11294
|
-
return 400;
|
|
11295
|
-
}
|
|
11296
|
-
}
|
|
11297
|
-
/**
|
|
11298
|
-
* Asserts that the operation completed successfully and that the resource is defined.
|
|
11299
|
-
* @param outcome The operation outcome.
|
|
11300
|
-
* @param resource The resource that may or may not have been returned.
|
|
11301
|
-
*/
|
|
11302
|
-
function assertOk(outcome, resource) {
|
|
11303
|
-
if (!isOk(outcome) || resource === undefined) {
|
|
11304
|
-
throw new OperationOutcomeError(outcome);
|
|
11305
|
-
}
|
|
11306
|
-
}
|
|
11307
|
-
class OperationOutcomeError extends Error {
|
|
11308
|
-
constructor(outcome) {
|
|
11309
|
-
super(outcome?.issue?.[0].details?.text);
|
|
11310
|
-
this.outcome = outcome;
|
|
11311
|
-
}
|
|
11312
|
-
}
|
|
11313
|
-
/**
|
|
11314
|
-
* Normalizes an error object into a displayable error string.
|
|
11315
|
-
* @param error The error value which could be a string, Error, OperationOutcome, or other unknown type.
|
|
11316
|
-
* @returns A display string for the error.
|
|
11317
|
-
*/
|
|
11318
|
-
function normalizeErrorString(error) {
|
|
11319
|
-
if (!error) {
|
|
11320
|
-
return 'Unknown error';
|
|
11321
|
-
}
|
|
11322
|
-
if (typeof error === 'string') {
|
|
11323
|
-
return error;
|
|
11324
|
-
}
|
|
11325
|
-
if (error instanceof Error) {
|
|
11326
|
-
return error.message;
|
|
11327
|
-
}
|
|
11328
|
-
if (typeof error === 'object' && 'resourceType' in error) {
|
|
11329
|
-
const outcome = error;
|
|
11330
|
-
return outcome.issue?.[0]?.details?.text ?? 'Unknown error';
|
|
11331
|
-
}
|
|
11332
|
-
return JSON.stringify(error);
|
|
11333
|
-
}
|
|
11334
|
-
|
|
11335
11427
|
exports.AndAtom = AndAtom;
|
|
11336
11428
|
exports.ArithemticOperatorAtom = ArithemticOperatorAtom;
|
|
11337
11429
|
exports.AsAtom = AsAtom;
|
|
@@ -11437,6 +11529,7 @@
|
|
|
11437
11529
|
exports.isNotFound = isNotFound;
|
|
11438
11530
|
exports.isObject = isObject$1;
|
|
11439
11531
|
exports.isOk = isOk;
|
|
11532
|
+
exports.isOperationOutcome = isOperationOutcome;
|
|
11440
11533
|
exports.isPeriod = isPeriod;
|
|
11441
11534
|
exports.isProfileResource = isProfileResource;
|
|
11442
11535
|
exports.isQuantity = isQuantity;
|