@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-schema.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"base-schema.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/esm/client.d.ts
CHANGED
|
@@ -224,7 +224,7 @@ export interface BotEvent<T = Resource | Hl7Message | string | Record<string, an
|
|
|
224
224
|
}
|
|
225
225
|
/**
|
|
226
226
|
* JSONPatch patch operation.
|
|
227
|
-
* Compatible with fast-json-patch Operation.
|
|
227
|
+
* Compatible with fast-json-patch and rfc6902 Operation.
|
|
228
228
|
*/
|
|
229
229
|
export interface PatchOperation {
|
|
230
230
|
readonly op: 'add' | 'remove' | 'replace' | 'copy' | 'move' | 'test';
|
|
@@ -496,7 +496,7 @@ export declare class MedplumClient extends EventTarget {
|
|
|
496
496
|
* Does not invalidate tokens with the server.
|
|
497
497
|
* @category Authentication
|
|
498
498
|
*/
|
|
499
|
-
signOut(): void
|
|
499
|
+
signOut(): Promise<void>;
|
|
500
500
|
/**
|
|
501
501
|
* Tries to sign in the user.
|
|
502
502
|
* Returns true if the user is signed in.
|
|
@@ -517,8 +517,19 @@ export declare class MedplumClient extends EventTarget {
|
|
|
517
517
|
* @param clientId The external client ID.
|
|
518
518
|
* @param redirectUri The external identity provider redirect URI.
|
|
519
519
|
* @param baseLogin The Medplum login request.
|
|
520
|
+
* @category Authentication
|
|
520
521
|
*/
|
|
521
522
|
signInWithExternalAuth(authorizeUrl: string, clientId: string, redirectUri: string, baseLogin: BaseLoginRequest): Promise<void>;
|
|
523
|
+
/**
|
|
524
|
+
* Builds the external identity provider redirect URI.
|
|
525
|
+
* @param authorizeUrl The external authorization URL.
|
|
526
|
+
* @param clientId The external client ID.
|
|
527
|
+
* @param redirectUri The external identity provider redirect URI.
|
|
528
|
+
* @param loginRequest The Medplum login request.
|
|
529
|
+
* @returns The external identity provider redirect URI.
|
|
530
|
+
* @category Authentication
|
|
531
|
+
*/
|
|
532
|
+
getExternalAuthRedirectUri(authorizeUrl: string, clientId: string, redirectUri: string, loginRequest: BaseLoginRequest): string;
|
|
522
533
|
/**
|
|
523
534
|
* Builds a FHIR URL from a collection of URL path components.
|
|
524
535
|
* For example, `buildUrl('/Patient', '123')` returns `fhir/R4/Patient/123`.
|
package/dist/esm/client.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { LRUCache } from './cache.mjs';
|
|
|
3
3
|
import { getRandomString, encryptSHA256 } from './crypto.mjs';
|
|
4
4
|
import { EventTarget } from './eventtarget.mjs';
|
|
5
5
|
import { parseJWTPayload } from './jwt.mjs';
|
|
6
|
+
import { isOk } from './outcomes.mjs';
|
|
6
7
|
import { ReadablePromise } from './readablepromise.mjs';
|
|
7
8
|
import { ClientStorage } from './storage.mjs';
|
|
8
9
|
import { globalSchema, indexStructureDefinition, indexSearchParameter } from './types.mjs';
|
|
@@ -10,14 +11,15 @@ import { createReference, arrayBufferToBase64 } from './utils.mjs';
|
|
|
10
11
|
|
|
11
12
|
// PKCE auth based on:
|
|
12
13
|
// https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
|
|
13
|
-
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;
|
|
14
|
-
const MEDPLUM_VERSION = "2.0.
|
|
14
|
+
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;
|
|
15
|
+
const MEDPLUM_VERSION = "2.0.3-e39c01ab";
|
|
15
16
|
const DEFAULT_BASE_URL = 'https://api.medplum.com/';
|
|
16
17
|
const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
|
|
17
18
|
const DEFAULT_CACHE_TIME = 60000; // 60 seconds
|
|
18
19
|
const JSON_CONTENT_TYPE = 'application/json';
|
|
19
20
|
const FHIR_CONTENT_TYPE = 'application/fhir+json';
|
|
20
21
|
const PATCH_CONTENT_TYPE = 'application/json-patch+json';
|
|
22
|
+
const system = { resourceType: 'Device', id: 'system', deviceName: [{ name: 'System' }] };
|
|
21
23
|
/**
|
|
22
24
|
* The MedplumClient class provides a client for the Medplum FHIR server.
|
|
23
25
|
*
|
|
@@ -101,7 +103,7 @@ class MedplumClient extends EventTarget {
|
|
|
101
103
|
throw new Error('Base URL must start with http or https');
|
|
102
104
|
}
|
|
103
105
|
}
|
|
104
|
-
__classPrivateFieldSet(this, _MedplumClient_fetch, options?.fetch ||
|
|
106
|
+
__classPrivateFieldSet(this, _MedplumClient_fetch, options?.fetch || getDefaultFetch(), "f");
|
|
105
107
|
__classPrivateFieldSet(this, _MedplumClient_createPdf, options?.createPdf, "f");
|
|
106
108
|
__classPrivateFieldSet(this, _MedplumClient_storage, new ClientStorage(), "f");
|
|
107
109
|
__classPrivateFieldSet(this, _MedplumClient_requestCache, new LRUCache(options?.resourceCacheSize ?? DEFAULT_RESOURCE_CACHE_SIZE), "f");
|
|
@@ -393,7 +395,8 @@ class MedplumClient extends EventTarget {
|
|
|
393
395
|
* Does not invalidate tokens with the server.
|
|
394
396
|
* @category Authentication
|
|
395
397
|
*/
|
|
396
|
-
signOut() {
|
|
398
|
+
async signOut() {
|
|
399
|
+
await this.post(__classPrivateFieldGet(this, _MedplumClient_logoutUrl, "f"), {});
|
|
397
400
|
this.clear();
|
|
398
401
|
}
|
|
399
402
|
/**
|
|
@@ -428,16 +431,29 @@ class MedplumClient extends EventTarget {
|
|
|
428
431
|
* @param clientId The external client ID.
|
|
429
432
|
* @param redirectUri The external identity provider redirect URI.
|
|
430
433
|
* @param baseLogin The Medplum login request.
|
|
434
|
+
* @category Authentication
|
|
431
435
|
*/
|
|
432
436
|
async signInWithExternalAuth(authorizeUrl, clientId, redirectUri, baseLogin) {
|
|
433
437
|
const loginRequest = await this.ensureCodeChallenge(baseLogin);
|
|
438
|
+
window.location.assign(this.getExternalAuthRedirectUri(authorizeUrl, clientId, redirectUri, loginRequest));
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Builds the external identity provider redirect URI.
|
|
442
|
+
* @param authorizeUrl The external authorization URL.
|
|
443
|
+
* @param clientId The external client ID.
|
|
444
|
+
* @param redirectUri The external identity provider redirect URI.
|
|
445
|
+
* @param loginRequest The Medplum login request.
|
|
446
|
+
* @returns The external identity provider redirect URI.
|
|
447
|
+
* @category Authentication
|
|
448
|
+
*/
|
|
449
|
+
getExternalAuthRedirectUri(authorizeUrl, clientId, redirectUri, loginRequest) {
|
|
434
450
|
const url = new URL(authorizeUrl);
|
|
435
451
|
url.searchParams.set('response_type', 'code');
|
|
436
452
|
url.searchParams.set('client_id', clientId);
|
|
437
453
|
url.searchParams.set('redirect_uri', redirectUri);
|
|
438
454
|
url.searchParams.set('scope', 'openid profile email');
|
|
439
455
|
url.searchParams.set('state', JSON.stringify(loginRequest));
|
|
440
|
-
|
|
456
|
+
return url.toString();
|
|
441
457
|
}
|
|
442
458
|
/**
|
|
443
459
|
* Builds a FHIR URL from a collection of URL path components.
|
|
@@ -512,7 +528,23 @@ class MedplumClient extends EventTarget {
|
|
|
512
528
|
* @returns Promise to the search result bundle.
|
|
513
529
|
*/
|
|
514
530
|
search(resourceType, query, options = {}) {
|
|
515
|
-
|
|
531
|
+
const url = this.fhirSearchUrl(resourceType, query);
|
|
532
|
+
const cacheKey = url.toString() + '-search';
|
|
533
|
+
const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, options);
|
|
534
|
+
if (cached) {
|
|
535
|
+
return cached.value;
|
|
536
|
+
}
|
|
537
|
+
const promise = new ReadablePromise((async () => {
|
|
538
|
+
const bundle = await this.get(url, options);
|
|
539
|
+
if (bundle.entry) {
|
|
540
|
+
for (const entry of bundle.entry) {
|
|
541
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_cacheResource).call(this, entry.resource);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return bundle;
|
|
545
|
+
})());
|
|
546
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
|
|
547
|
+
return promise;
|
|
516
548
|
}
|
|
517
549
|
/**
|
|
518
550
|
* Sends a FHIR search request for a single resource.
|
|
@@ -621,6 +653,9 @@ class MedplumClient extends EventTarget {
|
|
|
621
653
|
if (!refString) {
|
|
622
654
|
return undefined;
|
|
623
655
|
}
|
|
656
|
+
if (refString === 'system') {
|
|
657
|
+
return system;
|
|
658
|
+
}
|
|
624
659
|
const [resourceType, id] = refString.split('/');
|
|
625
660
|
if (!resourceType || !id) {
|
|
626
661
|
return undefined;
|
|
@@ -673,6 +708,9 @@ class MedplumClient extends EventTarget {
|
|
|
673
708
|
if (!refString) {
|
|
674
709
|
return new ReadablePromise(Promise.reject(new Error('Missing reference')));
|
|
675
710
|
}
|
|
711
|
+
if (refString === 'system') {
|
|
712
|
+
return new ReadablePromise(Promise.resolve(system));
|
|
713
|
+
}
|
|
676
714
|
const [resourceType, id] = refString.split('/');
|
|
677
715
|
if (!resourceType || !id) {
|
|
678
716
|
return new ReadablePromise(Promise.reject(new Error('Invalid reference')));
|
|
@@ -697,11 +735,17 @@ class MedplumClient extends EventTarget {
|
|
|
697
735
|
* @param resourceType The FHIR resource type.
|
|
698
736
|
* @returns Promise to a schema with the requested resource type.
|
|
699
737
|
*/
|
|
700
|
-
|
|
738
|
+
requestSchema(resourceType) {
|
|
701
739
|
if (resourceType in globalSchema.types) {
|
|
702
|
-
return globalSchema;
|
|
740
|
+
return Promise.resolve(globalSchema);
|
|
703
741
|
}
|
|
704
|
-
const
|
|
742
|
+
const cacheKey = resourceType + '-requestSchema';
|
|
743
|
+
const cached = __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_getCacheEntry).call(this, cacheKey, undefined);
|
|
744
|
+
if (cached) {
|
|
745
|
+
return cached.value;
|
|
746
|
+
}
|
|
747
|
+
const promise = new ReadablePromise((async () => {
|
|
748
|
+
const query = `{
|
|
705
749
|
StructureDefinitionList(name: "${resourceType}") {
|
|
706
750
|
name,
|
|
707
751
|
description,
|
|
@@ -730,14 +774,17 @@ class MedplumClient extends EventTarget {
|
|
|
730
774
|
target
|
|
731
775
|
}
|
|
732
776
|
}`.replace(/\s+/g, ' ');
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
777
|
+
const response = (await this.graphql(query));
|
|
778
|
+
for (const structureDefinition of response.data.StructureDefinitionList) {
|
|
779
|
+
indexStructureDefinition(structureDefinition);
|
|
780
|
+
}
|
|
781
|
+
for (const searchParameter of response.data.SearchParameterList) {
|
|
782
|
+
indexSearchParameter(searchParameter);
|
|
783
|
+
}
|
|
784
|
+
return globalSchema;
|
|
785
|
+
})());
|
|
786
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, cacheKey, promise);
|
|
787
|
+
return promise;
|
|
741
788
|
}
|
|
742
789
|
/**
|
|
743
790
|
* Reads resource history by resource type and ID.
|
|
@@ -1038,10 +1085,15 @@ class MedplumClient extends EventTarget {
|
|
|
1038
1085
|
throw new Error('Missing id');
|
|
1039
1086
|
}
|
|
1040
1087
|
this.invalidateSearches(resource.resourceType);
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1088
|
+
let result = await this.put(this.fhirUrl(resource.resourceType, resource.id), resource);
|
|
1089
|
+
if (!result) {
|
|
1090
|
+
// On 304 not modified, result will be undefined
|
|
1091
|
+
// Return the user input instead
|
|
1092
|
+
// return result ?? resource;
|
|
1093
|
+
result = resource;
|
|
1094
|
+
}
|
|
1095
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_cacheResource).call(this, result);
|
|
1096
|
+
return result;
|
|
1045
1097
|
}
|
|
1046
1098
|
/**
|
|
1047
1099
|
* Updates a FHIR resource using JSONPatch operations.
|
|
@@ -1088,6 +1140,7 @@ class MedplumClient extends EventTarget {
|
|
|
1088
1140
|
* @returns The result of the delete operation.
|
|
1089
1141
|
*/
|
|
1090
1142
|
deleteResource(resourceType, id) {
|
|
1143
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_deleteCacheEntry).call(this, this.fhirUrl(resourceType, id).toString());
|
|
1091
1144
|
this.invalidateSearches(resourceType);
|
|
1092
1145
|
return this.delete(this.fhirUrl(resourceType, id));
|
|
1093
1146
|
}
|
|
@@ -1372,7 +1425,7 @@ class MedplumClient extends EventTarget {
|
|
|
1372
1425
|
formBody.set('grant_type', 'authorization_code');
|
|
1373
1426
|
formBody.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
|
|
1374
1427
|
formBody.set('code', code);
|
|
1375
|
-
formBody.set('redirect_uri',
|
|
1428
|
+
formBody.set('redirect_uri', getWindowOrigin());
|
|
1376
1429
|
const codeVerifier = sessionStorage.getItem('codeVerifier');
|
|
1377
1430
|
if (codeVerifier) {
|
|
1378
1431
|
formBody.set('code_verifier', codeVerifier);
|
|
@@ -1427,6 +1480,14 @@ _MedplumClient_fetch = new WeakMap(), _MedplumClient_createPdf = new WeakMap(),
|
|
|
1427
1480
|
if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
|
|
1428
1481
|
__classPrivateFieldGet(this, _MedplumClient_requestCache, "f").set(key, { requestTime: Date.now(), value });
|
|
1429
1482
|
}
|
|
1483
|
+
}, _MedplumClient_cacheResource = function _MedplumClient_cacheResource(resource) {
|
|
1484
|
+
if (resource?.id) {
|
|
1485
|
+
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_setCacheEntry).call(this, this.fhirUrl(resource.resourceType, resource.id).toString(), new ReadablePromise(Promise.resolve(resource)));
|
|
1486
|
+
}
|
|
1487
|
+
}, _MedplumClient_deleteCacheEntry = function _MedplumClient_deleteCacheEntry(key) {
|
|
1488
|
+
if (__classPrivateFieldGet(this, _MedplumClient_cacheTime, "f") > 0) {
|
|
1489
|
+
__classPrivateFieldGet(this, _MedplumClient_requestCache, "f").delete(key);
|
|
1490
|
+
}
|
|
1430
1491
|
}, _MedplumClient_request =
|
|
1431
1492
|
/**
|
|
1432
1493
|
* Makes an HTTP request.
|
|
@@ -1444,7 +1505,7 @@ async function _MedplumClient_request(method, url, options = {}) {
|
|
|
1444
1505
|
}
|
|
1445
1506
|
options.method = method;
|
|
1446
1507
|
__classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_addFetchOptionsDefaults).call(this, options);
|
|
1447
|
-
const response = await __classPrivateFieldGet(this,
|
|
1508
|
+
const response = await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_fetchWithRetry).call(this, url, options);
|
|
1448
1509
|
if (response.status === 401) {
|
|
1449
1510
|
// Refresh and try again
|
|
1450
1511
|
return __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_handleUnauthenticated).call(this, method, url, options);
|
|
@@ -1453,11 +1514,30 @@ async function _MedplumClient_request(method, url, options = {}) {
|
|
|
1453
1514
|
// No content or change
|
|
1454
1515
|
return undefined;
|
|
1455
1516
|
}
|
|
1456
|
-
|
|
1517
|
+
let obj = undefined;
|
|
1518
|
+
try {
|
|
1519
|
+
obj = await response.json();
|
|
1520
|
+
}
|
|
1521
|
+
catch (err) {
|
|
1522
|
+
console.error('Error parsing response', response.status, err);
|
|
1523
|
+
throw err;
|
|
1524
|
+
}
|
|
1457
1525
|
if (response.status >= 400) {
|
|
1458
1526
|
throw obj;
|
|
1459
1527
|
}
|
|
1460
1528
|
return obj;
|
|
1529
|
+
}, _MedplumClient_fetchWithRetry = async function _MedplumClient_fetchWithRetry(url, options) {
|
|
1530
|
+
const maxRetries = 3;
|
|
1531
|
+
const retryDelay = 200;
|
|
1532
|
+
let response = undefined;
|
|
1533
|
+
for (let retry = 0; retry < maxRetries; retry++) {
|
|
1534
|
+
response = (await __classPrivateFieldGet(this, _MedplumClient_fetch, "f").call(this, url, options));
|
|
1535
|
+
if (response.status < 500) {
|
|
1536
|
+
return response;
|
|
1537
|
+
}
|
|
1538
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
1539
|
+
}
|
|
1540
|
+
return response;
|
|
1461
1541
|
}, _MedplumClient_executeAutoBatch =
|
|
1462
1542
|
/**
|
|
1463
1543
|
* Executes a batch of requests that were automatically batched together.
|
|
@@ -1493,7 +1573,12 @@ async function _MedplumClient_executeAutoBatch() {
|
|
|
1493
1573
|
for (let i = 0; i < entries.length; i++) {
|
|
1494
1574
|
const entry = entries[i];
|
|
1495
1575
|
const responseEntry = response.entry?.[i];
|
|
1496
|
-
|
|
1576
|
+
if (responseEntry?.response?.outcome && !isOk(responseEntry.response.outcome)) {
|
|
1577
|
+
entry.reject(responseEntry.response.outcome);
|
|
1578
|
+
}
|
|
1579
|
+
else {
|
|
1580
|
+
entry.resolve(responseEntry?.resource);
|
|
1581
|
+
}
|
|
1497
1582
|
}
|
|
1498
1583
|
}, _MedplumClient_addFetchOptionsDefaults = function _MedplumClient_addFetchOptionsDefaults(options) {
|
|
1499
1584
|
if (!options.headers) {
|
|
@@ -1550,7 +1635,7 @@ async function _MedplumClient_requestAuthorization(loginParams) {
|
|
|
1550
1635
|
url.searchParams.set('response_type', 'code');
|
|
1551
1636
|
url.searchParams.set('state', sessionStorage.getItem('pkceState'));
|
|
1552
1637
|
url.searchParams.set('client_id', loginRequest.clientId || __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
|
|
1553
|
-
url.searchParams.set('redirect_uri', loginRequest.redirectUri ||
|
|
1638
|
+
url.searchParams.set('redirect_uri', loginRequest.redirectUri || getWindowOrigin());
|
|
1554
1639
|
url.searchParams.set('code_challenge_method', loginRequest.codeChallengeMethod);
|
|
1555
1640
|
url.searchParams.set('code_challenge', loginRequest.codeChallenge);
|
|
1556
1641
|
url.searchParams.set('scope', loginRequest.scope || 'openid profile');
|
|
@@ -1633,12 +1718,34 @@ async function _MedplumClient_verifyTokens(tokens) {
|
|
|
1633
1718
|
// Silently ignore if this environment does not support storage events
|
|
1634
1719
|
}
|
|
1635
1720
|
};
|
|
1721
|
+
/**
|
|
1722
|
+
* Returns the current window if available.
|
|
1723
|
+
* All access to the current window should use this to support SSR such as Next.js.
|
|
1724
|
+
* @returns The current window or undefined if not available.
|
|
1725
|
+
*/
|
|
1726
|
+
function getWindow() {
|
|
1727
|
+
return typeof window === 'undefined' ? undefined : window;
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Returns the default fetch method.
|
|
1731
|
+
* The default fetch is currently only available in browser environments.
|
|
1732
|
+
* If you want to use SSR such as Next.js, you should pass a custom fetch function.
|
|
1733
|
+
* @returns The default fetch function for the current environment.
|
|
1734
|
+
*/
|
|
1735
|
+
function getDefaultFetch() {
|
|
1736
|
+
const window = getWindow();
|
|
1737
|
+
if (!window) {
|
|
1738
|
+
throw new Error('Fetch not available in this environment');
|
|
1739
|
+
}
|
|
1740
|
+
return window.fetch.bind(window);
|
|
1741
|
+
}
|
|
1636
1742
|
/**
|
|
1637
1743
|
* Returns the base URL for the current page.
|
|
1638
1744
|
* @category HTTP
|
|
1639
1745
|
*/
|
|
1640
|
-
function
|
|
1641
|
-
|
|
1746
|
+
function getWindowOrigin() {
|
|
1747
|
+
const window = getWindow();
|
|
1748
|
+
return window ? window.location.protocol + '//' + window.location.host + '/' : '';
|
|
1642
1749
|
}
|
|
1643
1750
|
function ensureTrailingSlash(url) {
|
|
1644
1751
|
if (!url) {
|