@medplum/core 2.0.1 → 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 +13 -2
- package/dist/cjs/index.cjs +371 -231
- 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 +13 -2
- package/dist/esm/client.mjs +135 -28
- 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/dist/esm/types.mjs +24 -0
- package/dist/esm/types.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
|
}
|
|
@@ -5945,6 +6157,30 @@
|
|
|
5945
6157
|
type: 'reference',
|
|
5946
6158
|
expression: resourceType + '.meta.compartment',
|
|
5947
6159
|
},
|
|
6160
|
+
_profile: {
|
|
6161
|
+
base: [resourceType],
|
|
6162
|
+
code: '_profile',
|
|
6163
|
+
type: 'uri',
|
|
6164
|
+
expression: resourceType + '.meta.profile',
|
|
6165
|
+
},
|
|
6166
|
+
_security: {
|
|
6167
|
+
base: [resourceType],
|
|
6168
|
+
code: '_security',
|
|
6169
|
+
type: 'token',
|
|
6170
|
+
expression: resourceType + '.meta.security',
|
|
6171
|
+
},
|
|
6172
|
+
_source: {
|
|
6173
|
+
base: [resourceType],
|
|
6174
|
+
code: '_source',
|
|
6175
|
+
type: 'uri',
|
|
6176
|
+
expression: resourceType + '.meta.source',
|
|
6177
|
+
},
|
|
6178
|
+
_tag: {
|
|
6179
|
+
base: [resourceType],
|
|
6180
|
+
code: '_tag',
|
|
6181
|
+
type: 'token',
|
|
6182
|
+
expression: resourceType + '.meta.tag',
|
|
6183
|
+
},
|
|
5948
6184
|
};
|
|
5949
6185
|
}
|
|
5950
6186
|
typeSchema.searchParams[searchParam.code] = searchParam;
|
|
@@ -6022,14 +6258,15 @@
|
|
|
6022
6258
|
|
|
6023
6259
|
// PKCE auth based on:
|
|
6024
6260
|
// https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
|
|
6025
|
-
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;
|
|
6026
|
-
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";
|
|
6027
6263
|
const DEFAULT_BASE_URL = 'https://api.medplum.com/';
|
|
6028
6264
|
const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
|
|
6029
6265
|
const DEFAULT_CACHE_TIME = 60000; // 60 seconds
|
|
6030
6266
|
const JSON_CONTENT_TYPE = 'application/json';
|
|
6031
6267
|
const FHIR_CONTENT_TYPE = 'application/fhir+json';
|
|
6032
6268
|
const PATCH_CONTENT_TYPE = 'application/json-patch+json';
|
|
6269
|
+
const system = { resourceType: 'Device', id: 'system', deviceName: [{ name: 'System' }] };
|
|
6033
6270
|
/**
|
|
6034
6271
|
* The MedplumClient class provides a client for the Medplum FHIR server.
|
|
6035
6272
|
*
|
|
@@ -6113,7 +6350,7 @@
|
|
|
6113
6350
|
throw new Error('Base URL must start with http or https');
|
|
6114
6351
|
}
|
|
6115
6352
|
}
|
|
6116
|
-
__classPrivateFieldSet(this, _MedplumClient_fetch, options?.fetch ||
|
|
6353
|
+
__classPrivateFieldSet(this, _MedplumClient_fetch, options?.fetch || getDefaultFetch(), "f");
|
|
6117
6354
|
__classPrivateFieldSet(this, _MedplumClient_createPdf, options?.createPdf, "f");
|
|
6118
6355
|
__classPrivateFieldSet(this, _MedplumClient_storage, new ClientStorage(), "f");
|
|
6119
6356
|
__classPrivateFieldSet(this, _MedplumClient_requestCache, new LRUCache(options?.resourceCacheSize ?? DEFAULT_RESOURCE_CACHE_SIZE), "f");
|
|
@@ -6405,7 +6642,8 @@
|
|
|
6405
6642
|
* Does not invalidate tokens with the server.
|
|
6406
6643
|
* @category Authentication
|
|
6407
6644
|
*/
|
|
6408
|
-
signOut() {
|
|
6645
|
+
async signOut() {
|
|
6646
|
+
await this.post(__classPrivateFieldGet(this, _MedplumClient_logoutUrl, "f"), {});
|
|
6409
6647
|
this.clear();
|
|
6410
6648
|
}
|
|
6411
6649
|
/**
|
|
@@ -6440,16 +6678,29 @@
|
|
|
6440
6678
|
* @param clientId The external client ID.
|
|
6441
6679
|
* @param redirectUri The external identity provider redirect URI.
|
|
6442
6680
|
* @param baseLogin The Medplum login request.
|
|
6681
|
+
* @category Authentication
|
|
6443
6682
|
*/
|
|
6444
6683
|
async signInWithExternalAuth(authorizeUrl, clientId, redirectUri, baseLogin) {
|
|
6445
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) {
|
|
6446
6697
|
const url = new URL(authorizeUrl);
|
|
6447
6698
|
url.searchParams.set('response_type', 'code');
|
|
6448
6699
|
url.searchParams.set('client_id', clientId);
|
|
6449
6700
|
url.searchParams.set('redirect_uri', redirectUri);
|
|
6450
6701
|
url.searchParams.set('scope', 'openid profile email');
|
|
6451
6702
|
url.searchParams.set('state', JSON.stringify(loginRequest));
|
|
6452
|
-
|
|
6703
|
+
return url.toString();
|
|
6453
6704
|
}
|
|
6454
6705
|
/**
|
|
6455
6706
|
* Builds a FHIR URL from a collection of URL path components.
|
|
@@ -6524,7 +6775,23 @@
|
|
|
6524
6775
|
* @returns Promise to the search result bundle.
|
|
6525
6776
|
*/
|
|
6526
6777
|
search(resourceType, query, options = {}) {
|
|
6527
|
-
|
|
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;
|
|
6528
6795
|
}
|
|
6529
6796
|
/**
|
|
6530
6797
|
* Sends a FHIR search request for a single resource.
|
|
@@ -6633,6 +6900,9 @@
|
|
|
6633
6900
|
if (!refString) {
|
|
6634
6901
|
return undefined;
|
|
6635
6902
|
}
|
|
6903
|
+
if (refString === 'system') {
|
|
6904
|
+
return system;
|
|
6905
|
+
}
|
|
6636
6906
|
const [resourceType, id] = refString.split('/');
|
|
6637
6907
|
if (!resourceType || !id) {
|
|
6638
6908
|
return undefined;
|
|
@@ -6685,6 +6955,9 @@
|
|
|
6685
6955
|
if (!refString) {
|
|
6686
6956
|
return new ReadablePromise(Promise.reject(new Error('Missing reference')));
|
|
6687
6957
|
}
|
|
6958
|
+
if (refString === 'system') {
|
|
6959
|
+
return new ReadablePromise(Promise.resolve(system));
|
|
6960
|
+
}
|
|
6688
6961
|
const [resourceType, id] = refString.split('/');
|
|
6689
6962
|
if (!resourceType || !id) {
|
|
6690
6963
|
return new ReadablePromise(Promise.reject(new Error('Invalid reference')));
|
|
@@ -6709,11 +6982,17 @@
|
|
|
6709
6982
|
* @param resourceType The FHIR resource type.
|
|
6710
6983
|
* @returns Promise to a schema with the requested resource type.
|
|
6711
6984
|
*/
|
|
6712
|
-
|
|
6985
|
+
requestSchema(resourceType) {
|
|
6713
6986
|
if (resourceType in globalSchema.types) {
|
|
6714
|
-
return globalSchema;
|
|
6987
|
+
return Promise.resolve(globalSchema);
|
|
6715
6988
|
}
|
|
6716
|
-
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 = `{
|
|
6717
6996
|
StructureDefinitionList(name: "${resourceType}") {
|
|
6718
6997
|
name,
|
|
6719
6998
|
description,
|
|
@@ -6742,14 +7021,17 @@
|
|
|
6742
7021
|
target
|
|
6743
7022
|
}
|
|
6744
7023
|
}`.replace(/\s+/g, ' ');
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
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;
|
|
6753
7035
|
}
|
|
6754
7036
|
/**
|
|
6755
7037
|
* Reads resource history by resource type and ID.
|
|
@@ -7050,10 +7332,15 @@
|
|
|
7050
7332
|
throw new Error('Missing id');
|
|
7051
7333
|
}
|
|
7052
7334
|
this.invalidateSearches(resource.resourceType);
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
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;
|
|
7057
7344
|
}
|
|
7058
7345
|
/**
|
|
7059
7346
|
* Updates a FHIR resource using JSONPatch operations.
|
|
@@ -7100,6 +7387,7 @@
|
|
|
7100
7387
|
* @returns The result of the delete operation.
|
|
7101
7388
|
*/
|
|
7102
7389
|
deleteResource(resourceType, id) {
|
|
7390
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_deleteCacheEntry).call(this, this.fhirUrl(resourceType, id).toString());
|
|
7103
7391
|
this.invalidateSearches(resourceType);
|
|
7104
7392
|
return this.delete(this.fhirUrl(resourceType, id));
|
|
7105
7393
|
}
|
|
@@ -7384,7 +7672,7 @@
|
|
|
7384
7672
|
formBody.set('grant_type', 'authorization_code');
|
|
7385
7673
|
formBody.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
|
|
7386
7674
|
formBody.set('code', code);
|
|
7387
|
-
formBody.set('redirect_uri',
|
|
7675
|
+
formBody.set('redirect_uri', getWindowOrigin());
|
|
7388
7676
|
const codeVerifier = sessionStorage.getItem('codeVerifier');
|
|
7389
7677
|
if (codeVerifier) {
|
|
7390
7678
|
formBody.set('code_verifier', codeVerifier);
|
|
@@ -7439,6 +7727,14 @@
|
|
|
7439
7727
|
if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
|
|
7440
7728
|
__classPrivateFieldGet(this, _MedplumClient_requestCache, "f").set(key, { requestTime: Date.now(), value });
|
|
7441
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
|
+
}
|
|
7442
7738
|
}, _MedplumClient_request =
|
|
7443
7739
|
/**
|
|
7444
7740
|
* Makes an HTTP request.
|
|
@@ -7456,7 +7752,7 @@
|
|
|
7456
7752
|
}
|
|
7457
7753
|
options.method = method;
|
|
7458
7754
|
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addFetchOptionsDefaults).call(this, options);
|
|
7459
|
-
const response = await __classPrivateFieldGet(this,
|
|
7755
|
+
const response = await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchWithRetry).call(this, url, options);
|
|
7460
7756
|
if (response.status === 401) {
|
|
7461
7757
|
// Refresh and try again
|
|
7462
7758
|
return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_handleUnauthenticated).call(this, method, url, options);
|
|
@@ -7465,11 +7761,30 @@
|
|
|
7465
7761
|
// No content or change
|
|
7466
7762
|
return undefined;
|
|
7467
7763
|
}
|
|
7468
|
-
|
|
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
|
+
}
|
|
7469
7772
|
if (response.status >= 400) {
|
|
7470
7773
|
throw obj;
|
|
7471
7774
|
}
|
|
7472
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;
|
|
7473
7788
|
}, _MedplumClient_executeAutoBatch =
|
|
7474
7789
|
/**
|
|
7475
7790
|
* Executes a batch of requests that were automatically batched together.
|
|
@@ -7505,7 +7820,12 @@
|
|
|
7505
7820
|
for (let i = 0; i < entries.length; i++) {
|
|
7506
7821
|
const entry = entries[i];
|
|
7507
7822
|
const responseEntry = response.entry?.[i];
|
|
7508
|
-
|
|
7823
|
+
if (responseEntry?.response?.outcome && !isOk(responseEntry.response.outcome)) {
|
|
7824
|
+
entry.reject(responseEntry.response.outcome);
|
|
7825
|
+
}
|
|
7826
|
+
else {
|
|
7827
|
+
entry.resolve(responseEntry?.resource);
|
|
7828
|
+
}
|
|
7509
7829
|
}
|
|
7510
7830
|
}, _MedplumClient_addFetchOptionsDefaults = function _MedplumClient_addFetchOptionsDefaults(options) {
|
|
7511
7831
|
if (!options.headers) {
|
|
@@ -7562,7 +7882,7 @@
|
|
|
7562
7882
|
url.searchParams.set('response_type', 'code');
|
|
7563
7883
|
url.searchParams.set('state', sessionStorage.getItem('pkceState'));
|
|
7564
7884
|
url.searchParams.set('client_id', loginRequest.clientId || __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
|
|
7565
|
-
url.searchParams.set('redirect_uri', loginRequest.redirectUri ||
|
|
7885
|
+
url.searchParams.set('redirect_uri', loginRequest.redirectUri || getWindowOrigin());
|
|
7566
7886
|
url.searchParams.set('code_challenge_method', loginRequest.codeChallengeMethod);
|
|
7567
7887
|
url.searchParams.set('code_challenge', loginRequest.codeChallenge);
|
|
7568
7888
|
url.searchParams.set('scope', loginRequest.scope || 'openid profile');
|
|
@@ -7645,12 +7965,34 @@
|
|
|
7645
7965
|
// Silently ignore if this environment does not support storage events
|
|
7646
7966
|
}
|
|
7647
7967
|
};
|
|
7968
|
+
/**
|
|
7969
|
+
* Returns the current window if available.
|
|
7970
|
+
* All access to the current window should use this to support SSR such as Next.js.
|
|
7971
|
+
* @returns The current window or undefined if not available.
|
|
7972
|
+
*/
|
|
7973
|
+
function getWindow() {
|
|
7974
|
+
return typeof window === 'undefined' ? undefined : window;
|
|
7975
|
+
}
|
|
7976
|
+
/**
|
|
7977
|
+
* Returns the default fetch method.
|
|
7978
|
+
* The default fetch is currently only available in browser environments.
|
|
7979
|
+
* If you want to use SSR such as Next.js, you should pass a custom fetch function.
|
|
7980
|
+
* @returns The default fetch function for the current environment.
|
|
7981
|
+
*/
|
|
7982
|
+
function getDefaultFetch() {
|
|
7983
|
+
const window = getWindow();
|
|
7984
|
+
if (!window) {
|
|
7985
|
+
throw new Error('Fetch not available in this environment');
|
|
7986
|
+
}
|
|
7987
|
+
return window.fetch.bind(window);
|
|
7988
|
+
}
|
|
7648
7989
|
/**
|
|
7649
7990
|
* Returns the base URL for the current page.
|
|
7650
7991
|
* @category HTTP
|
|
7651
7992
|
*/
|
|
7652
|
-
function
|
|
7653
|
-
|
|
7993
|
+
function getWindowOrigin() {
|
|
7994
|
+
const window = getWindow();
|
|
7995
|
+
return window ? window.location.protocol + '//' + window.location.host + '/' : '';
|
|
7654
7996
|
}
|
|
7655
7997
|
function ensureTrailingSlash(url) {
|
|
7656
7998
|
if (!url) {
|
|
@@ -11082,209 +11424,6 @@
|
|
|
11082
11424
|
return operator === exports.Operator.NOT_EQUALS || operator === exports.Operator.NOT;
|
|
11083
11425
|
}
|
|
11084
11426
|
|
|
11085
|
-
const OK_ID = 'ok';
|
|
11086
|
-
const CREATED_ID = 'created';
|
|
11087
|
-
const GONE_ID = 'gone';
|
|
11088
|
-
const NOT_MODIFIED_ID = 'not-modified';
|
|
11089
|
-
const NOT_FOUND_ID = 'not-found';
|
|
11090
|
-
const UNAUTHORIZED_ID = 'unauthorized';
|
|
11091
|
-
const FORBIDDEN_ID = 'forbidden';
|
|
11092
|
-
const TOO_MANY_REQUESTS_ID = 'too-many-requests';
|
|
11093
|
-
const allOk = {
|
|
11094
|
-
resourceType: 'OperationOutcome',
|
|
11095
|
-
id: OK_ID,
|
|
11096
|
-
issue: [
|
|
11097
|
-
{
|
|
11098
|
-
severity: 'information',
|
|
11099
|
-
code: 'informational',
|
|
11100
|
-
details: {
|
|
11101
|
-
text: 'All OK',
|
|
11102
|
-
},
|
|
11103
|
-
},
|
|
11104
|
-
],
|
|
11105
|
-
};
|
|
11106
|
-
const created = {
|
|
11107
|
-
resourceType: 'OperationOutcome',
|
|
11108
|
-
id: CREATED_ID,
|
|
11109
|
-
issue: [
|
|
11110
|
-
{
|
|
11111
|
-
severity: 'information',
|
|
11112
|
-
code: 'informational',
|
|
11113
|
-
details: {
|
|
11114
|
-
text: 'Created',
|
|
11115
|
-
},
|
|
11116
|
-
},
|
|
11117
|
-
],
|
|
11118
|
-
};
|
|
11119
|
-
const notModified = {
|
|
11120
|
-
resourceType: 'OperationOutcome',
|
|
11121
|
-
id: NOT_MODIFIED_ID,
|
|
11122
|
-
issue: [
|
|
11123
|
-
{
|
|
11124
|
-
severity: 'information',
|
|
11125
|
-
code: 'informational',
|
|
11126
|
-
details: {
|
|
11127
|
-
text: 'Not Modified',
|
|
11128
|
-
},
|
|
11129
|
-
},
|
|
11130
|
-
],
|
|
11131
|
-
};
|
|
11132
|
-
const notFound = {
|
|
11133
|
-
resourceType: 'OperationOutcome',
|
|
11134
|
-
id: NOT_FOUND_ID,
|
|
11135
|
-
issue: [
|
|
11136
|
-
{
|
|
11137
|
-
severity: 'error',
|
|
11138
|
-
code: 'not-found',
|
|
11139
|
-
details: {
|
|
11140
|
-
text: 'Not found',
|
|
11141
|
-
},
|
|
11142
|
-
},
|
|
11143
|
-
],
|
|
11144
|
-
};
|
|
11145
|
-
const unauthorized = {
|
|
11146
|
-
resourceType: 'OperationOutcome',
|
|
11147
|
-
id: UNAUTHORIZED_ID,
|
|
11148
|
-
issue: [
|
|
11149
|
-
{
|
|
11150
|
-
severity: 'error',
|
|
11151
|
-
code: 'login',
|
|
11152
|
-
details: {
|
|
11153
|
-
text: 'Unauthorized',
|
|
11154
|
-
},
|
|
11155
|
-
},
|
|
11156
|
-
],
|
|
11157
|
-
};
|
|
11158
|
-
const forbidden = {
|
|
11159
|
-
resourceType: 'OperationOutcome',
|
|
11160
|
-
id: FORBIDDEN_ID,
|
|
11161
|
-
issue: [
|
|
11162
|
-
{
|
|
11163
|
-
severity: 'error',
|
|
11164
|
-
code: 'forbidden',
|
|
11165
|
-
details: {
|
|
11166
|
-
text: 'Forbidden',
|
|
11167
|
-
},
|
|
11168
|
-
},
|
|
11169
|
-
],
|
|
11170
|
-
};
|
|
11171
|
-
const gone = {
|
|
11172
|
-
resourceType: 'OperationOutcome',
|
|
11173
|
-
id: GONE_ID,
|
|
11174
|
-
issue: [
|
|
11175
|
-
{
|
|
11176
|
-
severity: 'error',
|
|
11177
|
-
code: 'deleted',
|
|
11178
|
-
details: {
|
|
11179
|
-
text: 'Gone',
|
|
11180
|
-
},
|
|
11181
|
-
},
|
|
11182
|
-
],
|
|
11183
|
-
};
|
|
11184
|
-
const tooManyRequests = {
|
|
11185
|
-
resourceType: 'OperationOutcome',
|
|
11186
|
-
id: TOO_MANY_REQUESTS_ID,
|
|
11187
|
-
issue: [
|
|
11188
|
-
{
|
|
11189
|
-
severity: 'error',
|
|
11190
|
-
code: 'throttled',
|
|
11191
|
-
details: {
|
|
11192
|
-
text: 'Too Many Requests',
|
|
11193
|
-
},
|
|
11194
|
-
},
|
|
11195
|
-
],
|
|
11196
|
-
};
|
|
11197
|
-
function badRequest(details, expression) {
|
|
11198
|
-
return {
|
|
11199
|
-
resourceType: 'OperationOutcome',
|
|
11200
|
-
issue: [
|
|
11201
|
-
{
|
|
11202
|
-
severity: 'error',
|
|
11203
|
-
code: 'invalid',
|
|
11204
|
-
details: {
|
|
11205
|
-
text: details,
|
|
11206
|
-
},
|
|
11207
|
-
expression: expression ? [expression] : undefined,
|
|
11208
|
-
},
|
|
11209
|
-
],
|
|
11210
|
-
};
|
|
11211
|
-
}
|
|
11212
|
-
function isOk(outcome) {
|
|
11213
|
-
return outcome.id === OK_ID || outcome.id === CREATED_ID || outcome.id === NOT_MODIFIED_ID;
|
|
11214
|
-
}
|
|
11215
|
-
function isNotFound(outcome) {
|
|
11216
|
-
return outcome.id === NOT_FOUND_ID;
|
|
11217
|
-
}
|
|
11218
|
-
function isGone(outcome) {
|
|
11219
|
-
return outcome.id === GONE_ID;
|
|
11220
|
-
}
|
|
11221
|
-
function getStatus(outcome) {
|
|
11222
|
-
if (outcome.id === OK_ID) {
|
|
11223
|
-
return 200;
|
|
11224
|
-
}
|
|
11225
|
-
else if (outcome.id === CREATED_ID) {
|
|
11226
|
-
return 201;
|
|
11227
|
-
}
|
|
11228
|
-
else if (outcome.id === NOT_MODIFIED_ID) {
|
|
11229
|
-
return 304;
|
|
11230
|
-
}
|
|
11231
|
-
else if (outcome.id === UNAUTHORIZED_ID) {
|
|
11232
|
-
return 401;
|
|
11233
|
-
}
|
|
11234
|
-
else if (outcome.id === FORBIDDEN_ID) {
|
|
11235
|
-
return 403;
|
|
11236
|
-
}
|
|
11237
|
-
else if (outcome.id === NOT_FOUND_ID) {
|
|
11238
|
-
return 404;
|
|
11239
|
-
}
|
|
11240
|
-
else if (outcome.id === GONE_ID) {
|
|
11241
|
-
return 410;
|
|
11242
|
-
}
|
|
11243
|
-
else if (outcome.id === TOO_MANY_REQUESTS_ID) {
|
|
11244
|
-
return 429;
|
|
11245
|
-
}
|
|
11246
|
-
else {
|
|
11247
|
-
return 400;
|
|
11248
|
-
}
|
|
11249
|
-
}
|
|
11250
|
-
/**
|
|
11251
|
-
* Asserts that the operation completed successfully and that the resource is defined.
|
|
11252
|
-
* @param outcome The operation outcome.
|
|
11253
|
-
* @param resource The resource that may or may not have been returned.
|
|
11254
|
-
*/
|
|
11255
|
-
function assertOk(outcome, resource) {
|
|
11256
|
-
if (!isOk(outcome) || resource === undefined) {
|
|
11257
|
-
throw new OperationOutcomeError(outcome);
|
|
11258
|
-
}
|
|
11259
|
-
}
|
|
11260
|
-
class OperationOutcomeError extends Error {
|
|
11261
|
-
constructor(outcome) {
|
|
11262
|
-
super(outcome?.issue?.[0].details?.text);
|
|
11263
|
-
this.outcome = outcome;
|
|
11264
|
-
}
|
|
11265
|
-
}
|
|
11266
|
-
/**
|
|
11267
|
-
* Normalizes an error object into a displayable error string.
|
|
11268
|
-
* @param error The error value which could be a string, Error, OperationOutcome, or other unknown type.
|
|
11269
|
-
* @returns A display string for the error.
|
|
11270
|
-
*/
|
|
11271
|
-
function normalizeErrorString(error) {
|
|
11272
|
-
if (!error) {
|
|
11273
|
-
return 'Unknown error';
|
|
11274
|
-
}
|
|
11275
|
-
if (typeof error === 'string') {
|
|
11276
|
-
return error;
|
|
11277
|
-
}
|
|
11278
|
-
if (error instanceof Error) {
|
|
11279
|
-
return error.message;
|
|
11280
|
-
}
|
|
11281
|
-
if (typeof error === 'object' && 'resourceType' in error) {
|
|
11282
|
-
const outcome = error;
|
|
11283
|
-
return outcome.issue?.[0]?.details?.text ?? 'Unknown error';
|
|
11284
|
-
}
|
|
11285
|
-
return JSON.stringify(error);
|
|
11286
|
-
}
|
|
11287
|
-
|
|
11288
11427
|
exports.AndAtom = AndAtom;
|
|
11289
11428
|
exports.ArithemticOperatorAtom = ArithemticOperatorAtom;
|
|
11290
11429
|
exports.AsAtom = AsAtom;
|
|
@@ -11390,6 +11529,7 @@
|
|
|
11390
11529
|
exports.isNotFound = isNotFound;
|
|
11391
11530
|
exports.isObject = isObject$1;
|
|
11392
11531
|
exports.isOk = isOk;
|
|
11532
|
+
exports.isOperationOutcome = isOperationOutcome;
|
|
11393
11533
|
exports.isPeriod = isPeriod;
|
|
11394
11534
|
exports.isProfileResource = isProfileResource;
|
|
11395
11535
|
exports.isQuantity = isQuantity;
|