@medplum/core 0.9.26 → 0.9.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/cache.d.ts +34 -0
  3. package/dist/cjs/client.d.ts +1094 -0
  4. package/dist/cjs/crypto.d.ts +9 -0
  5. package/dist/cjs/eventtarget.d.ts +13 -0
  6. package/dist/cjs/fhirpath/atoms.d.ts +150 -0
  7. package/dist/cjs/fhirpath/date.d.ts +1 -0
  8. package/dist/cjs/fhirpath/functions.d.ts +5 -0
  9. package/dist/cjs/fhirpath/index.d.ts +4 -0
  10. package/dist/cjs/fhirpath/parse.d.ts +24 -0
  11. package/dist/cjs/fhirpath/tokenize.d.ts +5 -0
  12. package/dist/cjs/fhirpath/utils.d.ts +95 -0
  13. package/dist/cjs/format.d.ts +21 -0
  14. package/dist/cjs/hl7.d.ts +43 -0
  15. package/dist/cjs/index.d.ts +12 -0
  16. package/dist/cjs/index.js +266 -57
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/index.min.js +1 -1
  19. package/dist/cjs/index.min.js.map +1 -1
  20. package/dist/cjs/jwt.d.ts +5 -0
  21. package/dist/cjs/outcomes.d.ts +30 -0
  22. package/dist/cjs/readablepromise.d.ts +48 -0
  23. package/dist/cjs/search.d.ts +64 -0
  24. package/dist/cjs/searchparams.d.ts +35 -0
  25. package/dist/cjs/storage.d.ts +47 -0
  26. package/dist/cjs/types.d.ts +148 -0
  27. package/dist/cjs/utils.d.ts +239 -0
  28. package/dist/esm/client.d.ts +29 -20
  29. package/dist/esm/client.js +59 -47
  30. package/dist/esm/client.js.map +1 -1
  31. package/dist/esm/fhirpath/utils.js +12 -3
  32. package/dist/esm/fhirpath/utils.js.map +1 -1
  33. package/dist/esm/format.d.ts +7 -1
  34. package/dist/esm/format.js +108 -1
  35. package/dist/esm/format.js.map +1 -1
  36. package/dist/esm/index.js +3 -3
  37. package/dist/esm/index.min.js +1 -1
  38. package/dist/esm/index.min.js.map +1 -1
  39. package/dist/esm/node_modules/tslib/package.json +1 -0
  40. package/dist/esm/outcomes.d.ts +9 -1
  41. package/dist/esm/outcomes.js +63 -7
  42. package/dist/esm/outcomes.js.map +1 -1
  43. package/dist/esm/utils.d.ts +15 -0
  44. package/dist/esm/utils.js +18 -1
  45. package/dist/esm/utils.js.map +1 -1
  46. package/package.json +3 -3
  47. package/cody-pdf-test.js +0 -32
  48. package/tsconfig.cjs.json +0 -7
  49. package/tsconfig.esm.json +0 -7
  50. package/wget-log +0 -6
@@ -15,7 +15,7 @@ export interface MedplumClientOptions {
15
15
  /**
16
16
  * Base server URL.
17
17
  *
18
- * Default value is "https://api.medplum.com/".
18
+ * Default value is https://api.medplum.com/
19
19
  *
20
20
  * Use this to point to a custom Medplum deployment.
21
21
  */
@@ -144,14 +144,22 @@ export interface LoginRequest {
144
144
  readonly scope?: string;
145
145
  readonly nonce?: string;
146
146
  }
147
- export interface RegisterRequest {
148
- readonly projectName?: string;
149
- readonly firstName: string;
150
- readonly lastName: string;
147
+ export interface NewUserRequest {
151
148
  readonly email: string;
152
- readonly password?: string;
149
+ readonly password: string;
150
+ readonly recaptchaToken: string;
151
+ readonly recaptchaSiteKey?: string;
153
152
  readonly remember?: boolean;
154
- readonly recaptchaToken?: string;
153
+ }
154
+ export interface NewProjectRequest {
155
+ readonly projectName: string;
156
+ readonly firstName: string;
157
+ readonly lastName: string;
158
+ }
159
+ export interface NewPatientRequest {
160
+ readonly projectId: string;
161
+ readonly firstName: string;
162
+ readonly lastName: string;
155
163
  }
156
164
  export interface GoogleCredentialResponse {
157
165
  readonly clientId: string;
@@ -201,7 +209,7 @@ export interface BotEvent {
201
209
  * Compatible with fast-json-patch Operation.
202
210
  */
203
211
  export interface PatchOperation {
204
- readonly op: string;
212
+ readonly op: 'add' | 'remove' | 'replace' | 'copy' | 'move' | 'test';
205
213
  readonly path: string;
206
214
  readonly value?: any;
207
215
  }
@@ -407,30 +415,30 @@ export declare class MedplumClient extends EventTarget {
407
415
  * 2) New Patient registration
408
416
  *
409
417
  * @category Authentication
410
- * @param registerRequest Register request including email and password.
418
+ * @param newUserRequest Register request including email and password.
411
419
  * @returns Promise to the authentication response.
412
420
  */
413
- startNewUser(registerRequest: RegisterRequest): Promise<LoginAuthenticationResponse>;
421
+ startNewUser(newUserRequest: NewUserRequest): Promise<LoginAuthenticationResponse>;
414
422
  /**
415
423
  * Initiates a new project flow.
416
424
  *
417
425
  * This requires a partial login from `startNewUser` or `startNewGoogleUser`.
418
426
  *
419
- * @param registerRequest Register request including email and password.
427
+ * @param newProjectRequest Register request including email and password.
420
428
  * @param login The partial login to complete. This should come from the `startNewUser` method.
421
429
  * @returns Promise to the authentication response.
422
430
  */
423
- startNewProject(registerRequest: RegisterRequest, login: LoginAuthenticationResponse): Promise<LoginAuthenticationResponse>;
431
+ startNewProject(newProjectRequest: NewProjectRequest, login: LoginAuthenticationResponse): Promise<LoginAuthenticationResponse>;
424
432
  /**
425
433
  * Initiates a new patient flow.
426
434
  *
427
435
  * This requires a partial login from `startNewUser` or `startNewGoogleUser`.
428
436
  *
429
- * @param registerRequest Register request including email and password.
437
+ * @param newPatientRequest Register request including email and password.
430
438
  * @param login The partial login to complete. This should come from the `startNewUser` method.
431
439
  * @returns Promise to the authentication response.
432
440
  */
433
- startNewPatient(registerRequest: RegisterRequest, login: LoginAuthenticationResponse): Promise<LoginAuthenticationResponse>;
441
+ startNewPatient(newPatientRequest: NewPatientRequest, login: LoginAuthenticationResponse): Promise<LoginAuthenticationResponse>;
434
442
  /**
435
443
  * Initiates a user login flow.
436
444
  * @category Authentication
@@ -452,14 +460,14 @@ export declare class MedplumClient extends EventTarget {
452
460
  * Does not invalidate tokens with the server.
453
461
  * @category Authentication
454
462
  */
455
- signOut(): Promise<void>;
463
+ signOut(): void;
456
464
  /**
457
465
  * Tries to sign in the user.
458
466
  * Returns true if the user is signed in.
459
467
  * This may result in navigating away to the sign in page.
460
468
  * @category Authentication
461
469
  */
462
- signInWithRedirect(): Promise<ProfileResource | void> | undefined;
470
+ signInWithRedirect(): Promise<ProfileResource | void>;
463
471
  /**
464
472
  * Tries to sign out the user.
465
473
  * See: https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html
@@ -727,7 +735,6 @@ export declare class MedplumClient extends EventTarget {
727
735
  *
728
736
  * ```typescript
729
737
  * const result = await medplum.createResourceIfNoneExist(
730
- * 'Patient?identifier=123',
731
738
  * {
732
739
  * resourceType: 'Patient',
733
740
  * identifier: [{
@@ -738,14 +745,16 @@ export declare class MedplumClient extends EventTarget {
738
745
  * family: 'Smith',
739
746
  * given: ['John']
740
747
  * }]
741
- * });
748
+ * },
749
+ * 'identifier=123'
750
+ * );
742
751
  * console.log(result.id);
743
752
  * ```
744
753
  *
745
754
  * This method is syntactic sugar for:
746
755
  *
747
756
  * ```typescript
748
- * return searchOne(query) ?? createResource(resource);
757
+ * return searchOne(resourceType, query) ?? createResource(resource);
749
758
  * ```
750
759
  *
751
760
  * The query parameter only contains the search parameters (what would be in the URL following the "?").
@@ -754,7 +763,7 @@ export declare class MedplumClient extends EventTarget {
754
763
  *
755
764
  * @category Create
756
765
  * @param resource The FHIR resource to create.
757
- * @param query The search query for an equivalent resource.
766
+ * @param query The search query for an equivalent resource (should not include resource type or "?").
758
767
  * @returns The result of the create operation.
759
768
  */
760
769
  createResourceIfNoneExist<T extends Resource>(resource: T, query: string): Promise<T>;
@@ -8,13 +8,13 @@ import { ClientStorage } from './storage.js';
8
8
  import { globalSchema, indexStructureDefinition, indexSearchParameter } from './types.js';
9
9
  import { createReference, arrayBufferToBase64 } from './utils.js';
10
10
 
11
- // PKCE auth ased on:
11
+ // PKCE auth based on:
12
12
  // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
13
13
  var _MedplumClient_instances, _MedplumClient_fetch, _MedplumClient_createPdf, _MedplumClient_storage, _MedplumClient_requestCache, _MedplumClient_cacheTime, _MedplumClient_baseUrl, _MedplumClient_clientId, _MedplumClient_authorizeUrl, _MedplumClient_tokenUrl, _MedplumClient_logoutUrl, _MedplumClient_onUnauthenticated, _MedplumClient_accessToken, _MedplumClient_refreshToken, _MedplumClient_refreshPromise, _MedplumClient_profilePromise, _MedplumClient_profile, _MedplumClient_config, _MedplumClient_addLogin, _MedplumClient_refreshProfile, _MedplumClient_getCacheEntry, _MedplumClient_setCacheEntry, _MedplumClient_request, _MedplumClient_addFetchOptionsDefaults, _MedplumClient_setRequestContentType, _MedplumClient_setRequestBody, _MedplumClient_handleUnauthenticated, _MedplumClient_startPkce, _MedplumClient_requestAuthorization, _MedplumClient_refresh, _MedplumClient_fetchTokens, _MedplumClient_verifyTokens, _MedplumClient_setupStorageListener;
14
14
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
15
15
  const DEFAULT_SCOPE = 'launch/patient openid fhirUser offline_access user/*.*';
16
16
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
17
- const DEFAULT_CACHE_TIME = 10000; // 10 seconds
17
+ const DEFAULT_CACHE_TIME = 60000; // 60 seconds
18
18
  const JSON_CONTENT_TYPE = 'application/json';
19
19
  const FHIR_CONTENT_TYPE = 'application/fhir+json';
20
20
  const PATCH_CONTENT_TYPE = 'application/json-patch+json';
@@ -91,16 +91,13 @@ class MedplumClient extends EventTarget {
91
91
  if (!options.baseUrl.startsWith('http')) {
92
92
  throw new Error('Base URL must start with http or https');
93
93
  }
94
- if (!options.baseUrl.endsWith('/')) {
95
- throw new Error('Base URL must end with a trailing slash');
96
- }
97
94
  }
98
95
  __classPrivateFieldSet(this, _MedplumClient_fetch, (options === null || options === void 0 ? void 0 : options.fetch) || window.fetch.bind(window), "f");
99
96
  __classPrivateFieldSet(this, _MedplumClient_createPdf, options === null || options === void 0 ? void 0 : options.createPdf, "f");
100
97
  __classPrivateFieldSet(this, _MedplumClient_storage, new ClientStorage(), "f");
101
98
  __classPrivateFieldSet(this, _MedplumClient_requestCache, new LRUCache((_a = options === null || options === void 0 ? void 0 : options.resourceCacheSize) !== null && _a !== void 0 ? _a : DEFAULT_RESOURCE_CACHE_SIZE), "f");
102
99
  __classPrivateFieldSet(this, _MedplumClient_cacheTime, (_b = options === null || options === void 0 ? void 0 : options.cacheTime) !== null && _b !== void 0 ? _b : DEFAULT_CACHE_TIME, "f");
103
- __classPrivateFieldSet(this, _MedplumClient_baseUrl, (options === null || options === void 0 ? void 0 : options.baseUrl) || DEFAULT_BASE_URL, "f");
100
+ __classPrivateFieldSet(this, _MedplumClient_baseUrl, ensureTrailingSlash(options === null || options === void 0 ? void 0 : options.baseUrl) || DEFAULT_BASE_URL, "f");
104
101
  __classPrivateFieldSet(this, _MedplumClient_clientId, (options === null || options === void 0 ? void 0 : options.clientId) || '', "f");
105
102
  __classPrivateFieldSet(this, _MedplumClient_authorizeUrl, (options === null || options === void 0 ? void 0 : options.authorizeUrl) || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/authorize', "f");
106
103
  __classPrivateFieldSet(this, _MedplumClient_tokenUrl, (options === null || options === void 0 ? void 0 : options.tokenUrl) || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/token', "f");
@@ -277,13 +274,13 @@ class MedplumClient extends EventTarget {
277
274
  * 2) New Patient registration
278
275
  *
279
276
  * @category Authentication
280
- * @param registerRequest Register request including email and password.
277
+ * @param newUserRequest Register request including email and password.
281
278
  * @returns Promise to the authentication response.
282
279
  */
283
- startNewUser(registerRequest) {
280
+ startNewUser(newUserRequest) {
284
281
  return __awaiter(this, void 0, void 0, function* () {
285
282
  yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
286
- return this.post('auth/newuser', Object.assign(Object.assign({}, registerRequest), { codeChallengeMethod: 'S256', codeChallenge: __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge') }));
283
+ return this.post('auth/newuser', Object.assign(Object.assign({}, newUserRequest), { codeChallengeMethod: 'S256', codeChallenge: __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge') }));
287
284
  });
288
285
  }
289
286
  /**
@@ -291,13 +288,13 @@ class MedplumClient extends EventTarget {
291
288
  *
292
289
  * This requires a partial login from `startNewUser` or `startNewGoogleUser`.
293
290
  *
294
- * @param registerRequest Register request including email and password.
291
+ * @param newProjectRequest Register request including email and password.
295
292
  * @param login The partial login to complete. This should come from the `startNewUser` method.
296
293
  * @returns Promise to the authentication response.
297
294
  */
298
- startNewProject(registerRequest, login) {
295
+ startNewProject(newProjectRequest, login) {
299
296
  return __awaiter(this, void 0, void 0, function* () {
300
- return this.post('auth/newproject', Object.assign(Object.assign({}, registerRequest), login));
297
+ return this.post('auth/newproject', Object.assign(Object.assign({}, newProjectRequest), login));
301
298
  });
302
299
  }
303
300
  /**
@@ -305,13 +302,13 @@ class MedplumClient extends EventTarget {
305
302
  *
306
303
  * This requires a partial login from `startNewUser` or `startNewGoogleUser`.
307
304
  *
308
- * @param registerRequest Register request including email and password.
305
+ * @param newPatientRequest Register request including email and password.
309
306
  * @param login The partial login to complete. This should come from the `startNewUser` method.
310
307
  * @returns Promise to the authentication response.
311
308
  */
312
- startNewPatient(registerRequest, login) {
309
+ startNewPatient(newPatientRequest, login) {
313
310
  return __awaiter(this, void 0, void 0, function* () {
314
- return this.post('auth/newpatient', Object.assign(Object.assign({}, registerRequest), login));
311
+ return this.post('auth/newpatient', Object.assign(Object.assign({}, newPatientRequest), login));
315
312
  });
316
313
  }
317
314
  /**
@@ -349,7 +346,6 @@ class MedplumClient extends EventTarget {
349
346
  */
350
347
  signOut() {
351
348
  this.clear();
352
- return Promise.resolve();
353
349
  }
354
350
  /**
355
351
  * Tries to sign in the user.
@@ -358,15 +354,17 @@ class MedplumClient extends EventTarget {
358
354
  * @category Authentication
359
355
  */
360
356
  signInWithRedirect() {
361
- const urlParams = new URLSearchParams(window.location.search);
362
- const code = urlParams.get('code');
363
- if (!code) {
364
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_requestAuthorization).call(this);
365
- return undefined;
366
- }
367
- else {
368
- return this.processCode(code);
369
- }
357
+ return __awaiter(this, void 0, void 0, function* () {
358
+ const urlParams = new URLSearchParams(window.location.search);
359
+ const code = urlParams.get('code');
360
+ if (!code) {
361
+ yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_requestAuthorization).call(this);
362
+ return undefined;
363
+ }
364
+ else {
365
+ return this.processCode(code);
366
+ }
367
+ });
370
368
  }
371
369
  /**
372
370
  * Tries to sign out the user.
@@ -757,7 +755,6 @@ class MedplumClient extends EventTarget {
757
755
  *
758
756
  * ```typescript
759
757
  * const result = await medplum.createResourceIfNoneExist(
760
- * 'Patient?identifier=123',
761
758
  * {
762
759
  * resourceType: 'Patient',
763
760
  * identifier: [{
@@ -768,14 +765,16 @@ class MedplumClient extends EventTarget {
768
765
  * family: 'Smith',
769
766
  * given: ['John']
770
767
  * }]
771
- * });
768
+ * },
769
+ * 'identifier=123'
770
+ * );
772
771
  * console.log(result.id);
773
772
  * ```
774
773
  *
775
774
  * This method is syntactic sugar for:
776
775
  *
777
776
  * ```typescript
778
- * return searchOne(query) ?? createResource(resource);
777
+ * return searchOne(resourceType, query) ?? createResource(resource);
779
778
  * ```
780
779
  *
781
780
  * The query parameter only contains the search parameters (what would be in the URL following the "?").
@@ -784,7 +783,7 @@ class MedplumClient extends EventTarget {
784
783
  *
785
784
  * @category Create
786
785
  * @param resource The FHIR resource to create.
787
- * @param query The search query for an equivalent resource.
786
+ * @param query The search query for an equivalent resource (should not include resource type or "?").
788
787
  * @returns The result of the create operation.
789
788
  */
790
789
  createResourceIfNoneExist(resource, query) {
@@ -916,14 +915,19 @@ class MedplumClient extends EventTarget {
916
915
  * @returns The result of the update operation.
917
916
  */
918
917
  updateResource(resource) {
919
- if (!resource.resourceType) {
920
- throw new Error('Missing resourceType');
921
- }
922
- if (!resource.id) {
923
- throw new Error('Missing id');
924
- }
925
- this.invalidateSearches(resource.resourceType);
926
- return this.put(this.fhirUrl(resource.resourceType, resource.id), resource);
918
+ return __awaiter(this, void 0, void 0, function* () {
919
+ if (!resource.resourceType) {
920
+ throw new Error('Missing resourceType');
921
+ }
922
+ if (!resource.id) {
923
+ throw new Error('Missing id');
924
+ }
925
+ this.invalidateSearches(resource.resourceType);
926
+ const result = yield this.put(this.fhirUrl(resource.resourceType, resource.id), resource);
927
+ // On 304 not modified, result will be undefined
928
+ // Return the user input instead
929
+ return result !== null && result !== void 0 ? result : resource;
930
+ });
927
931
  }
928
932
  /**
929
933
  * Updates a FHIR resource using JSONPatch operations.
@@ -1360,16 +1364,18 @@ _MedplumClient_fetch = new WeakMap(), _MedplumClient_createPdf = new WeakMap(),
1360
1364
  __classPrivateFieldGet(this, _MedplumClient_storage, "f").setString('codeChallenge', codeChallenge);
1361
1365
  });
1362
1366
  }, _MedplumClient_requestAuthorization = function _MedplumClient_requestAuthorization() {
1363
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
1364
- const url = new URL(__classPrivateFieldGet(this, _MedplumClient_authorizeUrl, "f"));
1365
- url.searchParams.set('response_type', 'code');
1366
- url.searchParams.set('state', __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('pkceState'));
1367
- url.searchParams.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
1368
- url.searchParams.set('redirect_uri', getBaseUrl());
1369
- url.searchParams.set('scope', DEFAULT_SCOPE);
1370
- url.searchParams.set('code_challenge_method', 'S256');
1371
- url.searchParams.set('code_challenge', __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge'));
1372
- window.location.assign(url.toString());
1367
+ return __awaiter(this, void 0, void 0, function* () {
1368
+ yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
1369
+ const url = new URL(__classPrivateFieldGet(this, _MedplumClient_authorizeUrl, "f"));
1370
+ url.searchParams.set('response_type', 'code');
1371
+ url.searchParams.set('state', __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('pkceState'));
1372
+ url.searchParams.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
1373
+ url.searchParams.set('redirect_uri', getBaseUrl());
1374
+ url.searchParams.set('scope', DEFAULT_SCOPE);
1375
+ url.searchParams.set('code_challenge_method', 'S256');
1376
+ url.searchParams.set('code_challenge', __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge'));
1377
+ window.location.assign(url.toString());
1378
+ });
1373
1379
  }, _MedplumClient_refresh = function _MedplumClient_refresh() {
1374
1380
  return __awaiter(this, void 0, void 0, function* () {
1375
1381
  if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
@@ -1445,6 +1451,12 @@ _MedplumClient_fetch = new WeakMap(), _MedplumClient_createPdf = new WeakMap(),
1445
1451
  function getBaseUrl() {
1446
1452
  return window.location.protocol + '//' + window.location.host + '/';
1447
1453
  }
1454
+ function ensureTrailingSlash(url) {
1455
+ if (!url) {
1456
+ return url;
1457
+ }
1458
+ return url.endsWith('/') ? url : url + '/';
1459
+ }
1448
1460
 
1449
1461
  export { MedplumClient };
1450
1462
  //# sourceMappingURL=client.js.map