@medplum/core 0.9.28 → 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 (40) 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 +82 -39
  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 +8 -7
  29. package/dist/esm/client.js +36 -29
  30. package/dist/esm/client.js.map +1 -1
  31. package/dist/esm/index.js +2 -2
  32. package/dist/esm/index.min.js +1 -1
  33. package/dist/esm/index.min.js.map +1 -1
  34. package/dist/esm/outcomes.d.ts +2 -1
  35. package/dist/esm/outcomes.js +27 -10
  36. package/dist/esm/outcomes.js.map +1 -1
  37. package/dist/esm/utils.d.ts +15 -0
  38. package/dist/esm/utils.js +18 -1
  39. package/dist/esm/utils.js.map +1 -1
  40. package/package.json +3 -3
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Returns a cryptographically secure random string.
3
+ */
4
+ export declare function getRandomString(): string;
5
+ /**
6
+ * Encrypts a string with SHA256 encryption.
7
+ * @param str
8
+ */
9
+ export declare function encryptSHA256(str: string): Promise<ArrayBuffer>;
@@ -0,0 +1,13 @@
1
+ interface Event {
2
+ readonly type: string;
3
+ readonly defaultPrevented?: boolean;
4
+ }
5
+ declare type EventListener = (e: Event) => void;
6
+ export declare class EventTarget {
7
+ #private;
8
+ constructor();
9
+ addEventListener(type: string, callback: EventListener): void;
10
+ removeEventListeneer(type: string, callback: EventListener): void;
11
+ dispatchEvent(event: Event): boolean;
12
+ }
13
+ export {};
@@ -0,0 +1,150 @@
1
+ import { FhirPathFunction } from './functions';
2
+ export interface TypedValue {
3
+ readonly type: string;
4
+ readonly value: any;
5
+ }
6
+ export interface Atom {
7
+ eval(context: TypedValue[]): TypedValue[];
8
+ }
9
+ export declare class FhirPathAtom implements Atom {
10
+ readonly original: string;
11
+ readonly child: Atom;
12
+ constructor(original: string, child: Atom);
13
+ eval(context: TypedValue[]): TypedValue[];
14
+ }
15
+ export declare class LiteralAtom implements Atom {
16
+ readonly value: TypedValue;
17
+ constructor(value: TypedValue);
18
+ eval(): TypedValue[];
19
+ }
20
+ export declare class SymbolAtom implements Atom {
21
+ #private;
22
+ readonly name: string;
23
+ constructor(name: string);
24
+ eval(context: TypedValue[]): TypedValue[];
25
+ }
26
+ export declare class EmptySetAtom implements Atom {
27
+ eval(): [];
28
+ }
29
+ export declare class UnaryOperatorAtom implements Atom {
30
+ readonly child: Atom;
31
+ readonly impl: (x: TypedValue[]) => TypedValue[];
32
+ constructor(child: Atom, impl: (x: TypedValue[]) => TypedValue[]);
33
+ eval(context: TypedValue[]): TypedValue[];
34
+ }
35
+ export declare class AsAtom implements Atom {
36
+ readonly left: Atom;
37
+ readonly right: Atom;
38
+ constructor(left: Atom, right: Atom);
39
+ eval(context: TypedValue[]): TypedValue[];
40
+ }
41
+ export declare class ArithemticOperatorAtom implements Atom {
42
+ readonly left: Atom;
43
+ readonly right: Atom;
44
+ readonly impl: (x: number, y: number) => number | boolean;
45
+ constructor(left: Atom, right: Atom, impl: (x: number, y: number) => number | boolean);
46
+ eval(context: TypedValue[]): TypedValue[];
47
+ }
48
+ export declare class ConcatAtom implements Atom {
49
+ readonly left: Atom;
50
+ readonly right: Atom;
51
+ constructor(left: Atom, right: Atom);
52
+ eval(context: TypedValue[]): TypedValue[];
53
+ }
54
+ export declare class ContainsAtom implements Atom {
55
+ readonly left: Atom;
56
+ readonly right: Atom;
57
+ constructor(left: Atom, right: Atom);
58
+ eval(context: TypedValue[]): TypedValue[];
59
+ }
60
+ export declare class InAtom implements Atom {
61
+ readonly left: Atom;
62
+ readonly right: Atom;
63
+ constructor(left: Atom, right: Atom);
64
+ eval(context: TypedValue[]): TypedValue[];
65
+ }
66
+ export declare class DotAtom implements Atom {
67
+ readonly left: Atom;
68
+ readonly right: Atom;
69
+ constructor(left: Atom, right: Atom);
70
+ eval(context: TypedValue[]): TypedValue[];
71
+ }
72
+ export declare class UnionAtom implements Atom {
73
+ readonly left: Atom;
74
+ readonly right: Atom;
75
+ constructor(left: Atom, right: Atom);
76
+ eval(context: TypedValue[]): TypedValue[];
77
+ }
78
+ export declare class EqualsAtom implements Atom {
79
+ readonly left: Atom;
80
+ readonly right: Atom;
81
+ constructor(left: Atom, right: Atom);
82
+ eval(context: TypedValue[]): TypedValue[];
83
+ }
84
+ export declare class NotEqualsAtom implements Atom {
85
+ readonly left: Atom;
86
+ readonly right: Atom;
87
+ constructor(left: Atom, right: Atom);
88
+ eval(context: TypedValue[]): TypedValue[];
89
+ }
90
+ export declare class EquivalentAtom implements Atom {
91
+ readonly left: Atom;
92
+ readonly right: Atom;
93
+ constructor(left: Atom, right: Atom);
94
+ eval(context: TypedValue[]): TypedValue[];
95
+ }
96
+ export declare class NotEquivalentAtom implements Atom {
97
+ readonly left: Atom;
98
+ readonly right: Atom;
99
+ constructor(left: Atom, right: Atom);
100
+ eval(context: TypedValue[]): TypedValue[];
101
+ }
102
+ export declare class IsAtom implements Atom {
103
+ readonly left: Atom;
104
+ readonly right: Atom;
105
+ constructor(left: Atom, right: Atom);
106
+ eval(context: TypedValue[]): TypedValue[];
107
+ }
108
+ /**
109
+ * 6.5.1. and
110
+ * Returns true if both operands evaluate to true,
111
+ * false if either operand evaluates to false,
112
+ * and the empty collection otherwise.
113
+ */
114
+ export declare class AndAtom implements Atom {
115
+ readonly left: Atom;
116
+ readonly right: Atom;
117
+ constructor(left: Atom, right: Atom);
118
+ eval(context: TypedValue[]): TypedValue[];
119
+ }
120
+ export declare class OrAtom implements Atom {
121
+ readonly left: Atom;
122
+ readonly right: Atom;
123
+ constructor(left: Atom, right: Atom);
124
+ eval(context: TypedValue[]): TypedValue[];
125
+ }
126
+ /**
127
+ * 6.5.4. xor
128
+ * Returns true if exactly one of the operands evaluates to true,
129
+ * false if either both operands evaluate to true or both operands evaluate to false,
130
+ * and the empty collection otherwise.
131
+ */
132
+ export declare class XorAtom implements Atom {
133
+ readonly left: Atom;
134
+ readonly right: Atom;
135
+ constructor(left: Atom, right: Atom);
136
+ eval(context: TypedValue[]): TypedValue[];
137
+ }
138
+ export declare class FunctionAtom implements Atom {
139
+ readonly name: string;
140
+ readonly args: Atom[];
141
+ readonly impl: FhirPathFunction;
142
+ constructor(name: string, args: Atom[], impl: FhirPathFunction);
143
+ eval(context: TypedValue[]): TypedValue[];
144
+ }
145
+ export declare class IndexerAtom implements Atom {
146
+ readonly left: Atom;
147
+ readonly expr: Atom;
148
+ constructor(left: Atom, expr: Atom);
149
+ eval(context: TypedValue[]): TypedValue[];
150
+ }
@@ -0,0 +1 @@
1
+ export declare function parseDateString(str: string): string;
@@ -0,0 +1,5 @@
1
+ import { Atom, TypedValue } from './atoms';
2
+ export interface FhirPathFunction {
3
+ (input: TypedValue[], ...args: Atom[]): TypedValue[];
4
+ }
5
+ export declare const functions: Record<string, FhirPathFunction>;
@@ -0,0 +1,4 @@
1
+ export * from './atoms';
2
+ export * from './parse';
3
+ export * from './tokenize';
4
+ export * from './utils';
@@ -0,0 +1,24 @@
1
+ import { FhirPathAtom, TypedValue } from './atoms';
2
+ /**
3
+ * Parses a FHIRPath expression into an AST.
4
+ * The result can be used to evaluate the expression against a resource or other object.
5
+ * This method is useful if you know that you will evaluate the same expression many times
6
+ * against different resources.
7
+ * @param input The FHIRPath expression to parse.
8
+ * @returns The AST representing the expression.
9
+ */
10
+ export declare function parseFhirPath(input: string): FhirPathAtom;
11
+ /**
12
+ * Evaluates a FHIRPath expression against a resource or other object.
13
+ * @param input The FHIRPath expression to parse.
14
+ * @param context The resource or object to evaluate the expression against.
15
+ * @returns The result of the FHIRPath expression against the resource or object.
16
+ */
17
+ export declare function evalFhirPath(expression: string, input: unknown): unknown[];
18
+ /**
19
+ * Evaluates a FHIRPath expression against a resource or other object.
20
+ * @param input The FHIRPath expression to parse.
21
+ * @param context The resource or object to evaluate the expression against.
22
+ * @returns The result of the FHIRPath expression against the resource or object.
23
+ */
24
+ export declare function evalFhirPathTyped(expression: string, input: TypedValue[]): TypedValue[];
@@ -0,0 +1,5 @@
1
+ export interface Token {
2
+ id: string;
3
+ value: string;
4
+ }
5
+ export declare function tokenize(str: string): Token[];
@@ -0,0 +1,95 @@
1
+ import { Period, Quantity } from '@medplum/fhirtypes';
2
+ import { TypedValue } from './atoms';
3
+ /**
4
+ * Returns a single element array with a typed boolean value.
5
+ * @param value The primitive boolean value.
6
+ * @returns Single element array with a typed boolean value.
7
+ */
8
+ export declare function booleanToTypedValue(value: boolean): [TypedValue];
9
+ /**
10
+ * Returns a "best guess" TypedValue for a given value.
11
+ * @param value The unknown value to check.
12
+ * @returns A "best guess" TypedValue for the given value.
13
+ */
14
+ export declare function toTypedValue(value: unknown): TypedValue;
15
+ /**
16
+ * Converts unknown object into a JavaScript boolean.
17
+ * Note that this is different than the FHIRPath "toBoolean",
18
+ * which has particular semantics around arrays, empty arrays, and type conversions.
19
+ * @param obj Any value or array of values.
20
+ * @returns The converted boolean value according to FHIRPath rules.
21
+ */
22
+ export declare function toJsBoolean(obj: TypedValue[]): boolean;
23
+ /**
24
+ * Returns the value of the property and the property type.
25
+ * Some property definitions support multiple types.
26
+ * For example, "Observation.value[x]" can be "valueString", "valueInteger", "valueQuantity", etc.
27
+ * According to the spec, there can only be one property for a given element definition.
28
+ * This function returns the value and the type.
29
+ * @param input The base context (FHIR resource or backbone element).
30
+ * @param path The property path.
31
+ * @returns The value of the property and the property type.
32
+ */
33
+ export declare function getTypedPropertyValue(input: TypedValue, path: string): TypedValue[] | TypedValue | undefined;
34
+ /**
35
+ * Removes duplicates in array using FHIRPath equality rules.
36
+ * @param arr The input array.
37
+ * @returns The result array with duplicates removed.
38
+ */
39
+ export declare function removeDuplicates(arr: TypedValue[]): TypedValue[];
40
+ /**
41
+ * Returns a negated FHIRPath boolean expression.
42
+ * @param input The input array.
43
+ * @returns The negated type value array.
44
+ */
45
+ export declare function fhirPathNot(input: TypedValue[]): TypedValue[];
46
+ /**
47
+ * Determines if two arrays are equal according to FHIRPath equality rules.
48
+ * @param x The first array.
49
+ * @param y The second array.
50
+ * @returns FHIRPath true if the arrays are equal.
51
+ */
52
+ export declare function fhirPathArrayEquals(x: TypedValue[], y: TypedValue[]): TypedValue[];
53
+ /**
54
+ * Determines if two values are equal according to FHIRPath equality rules.
55
+ * @param x The first value.
56
+ * @param y The second value.
57
+ * @returns True if equal.
58
+ */
59
+ export declare function fhirPathEquals(x: TypedValue, y: TypedValue): TypedValue[];
60
+ /**
61
+ * Determines if two arrays are equivalent according to FHIRPath equality rules.
62
+ * @param x The first array.
63
+ * @param y The second array.
64
+ * @returns FHIRPath true if the arrays are equivalent.
65
+ */
66
+ export declare function fhirPathArrayEquivalent(x: TypedValue[], y: TypedValue[]): TypedValue[];
67
+ /**
68
+ * Determines if two values are equivalent according to FHIRPath equality rules.
69
+ * @param x The first value.
70
+ * @param y The second value.
71
+ * @returns True if equivalent.
72
+ */
73
+ export declare function fhirPathEquivalent(x: TypedValue, y: TypedValue): TypedValue[];
74
+ /**
75
+ * Determines if the typed value is the desired type.
76
+ * @param typedValue The typed value to check.
77
+ * @param desiredType The desired type name.
78
+ * @returns True if the typed value is of the desired type.
79
+ */
80
+ export declare function fhirPathIs(typedValue: TypedValue, desiredType: string): boolean;
81
+ /**
82
+ * Determines if the input is a Period object.
83
+ * This is heuristic based, as we do not have strong typing at runtime.
84
+ * @param input The input value.
85
+ * @returns True if the input is a period.
86
+ */
87
+ export declare function isPeriod(input: unknown): input is Period;
88
+ /**
89
+ * Determines if the input is a Quantity object.
90
+ * This is heuristic based, as we do not have strong typing at runtime.
91
+ * @param input The input value.
92
+ * @returns True if the input is a quantity.
93
+ */
94
+ export declare function isQuantity(input: unknown): input is Quantity;
95
+ export declare function isQuantityEquivalent(x: Quantity, y: Quantity): boolean;
@@ -0,0 +1,21 @@
1
+ import { Address, HumanName, Period, Timing } from '@medplum/fhirtypes';
2
+ export interface AddressFormatOptions {
3
+ all?: boolean;
4
+ use?: boolean;
5
+ }
6
+ export interface HumanNameFormatOptions {
7
+ all?: boolean;
8
+ prefix?: boolean;
9
+ suffix?: boolean;
10
+ use?: boolean;
11
+ }
12
+ export declare function formatAddress(address: Address, options?: AddressFormatOptions): string;
13
+ export declare function formatHumanName(name: HumanName, options?: HumanNameFormatOptions): string;
14
+ export declare function formatGivenName(name: HumanName): string;
15
+ export declare function formatFamilyName(name: HumanName): string;
16
+ export declare function isValidDate(date: Date): boolean;
17
+ export declare function formatDate(date: string | undefined, options?: Intl.DateTimeFormatOptions): string;
18
+ export declare function formatTime(time: string | undefined, options?: Intl.DateTimeFormatOptions): string;
19
+ export declare function formatDateTime(dateTime: string | undefined, options?: Intl.DateTimeFormatOptions): string;
20
+ export declare function formatPeriod(period: Period | undefined): string;
21
+ export declare function formatTiming(timing: Timing | undefined): string;
@@ -0,0 +1,43 @@
1
+ export declare const SEGMENT_SEPARATOR = "\r";
2
+ export declare const FIELD_SEPARATOR = "|";
3
+ export declare const COMPONENT_SEPARATOR = "^";
4
+ /**
5
+ * The Hl7Message class represents one HL7 message.
6
+ * A message is a collection of segments.
7
+ * Note that we do not strictly parse messages, and only use default delimeters.
8
+ */
9
+ export declare class Hl7Message {
10
+ readonly segments: Hl7Segment[];
11
+ constructor(segments: Hl7Segment[]);
12
+ get(index: number | string): Hl7Segment | undefined;
13
+ getAll(name: string): Hl7Segment[];
14
+ toString(): string;
15
+ buildAck(): Hl7Message;
16
+ static parse(text: string): Hl7Message;
17
+ }
18
+ /**
19
+ * The Hl7Segment class represents one HL7 segment.
20
+ * A segment is a collection of fields.
21
+ * The name field is the first field.
22
+ * Note that we do not strictly parse messages, and only use default delimeters.
23
+ */
24
+ export declare class Hl7Segment {
25
+ readonly name: string;
26
+ readonly fields: Hl7Field[];
27
+ constructor(fields: Hl7Field[] | string[]);
28
+ get(index: number): Hl7Field;
29
+ toString(): string;
30
+ static parse(text: string): Hl7Segment;
31
+ }
32
+ /**
33
+ * The Hl7Field class represents one HL7 field.
34
+ * A field is a collection of components.
35
+ * Note that we do not strictly parse messages, and only use default delimeters.
36
+ */
37
+ export declare class Hl7Field {
38
+ readonly components: string[];
39
+ constructor(components: string[]);
40
+ get(index: number): string;
41
+ toString(): string;
42
+ static parse(text: string): Hl7Field;
43
+ }
@@ -0,0 +1,12 @@
1
+ export * from './cache';
2
+ export * from './client';
3
+ export * from './fhirpath';
4
+ export * from './format';
5
+ export * from './hl7';
6
+ export * from './jwt';
7
+ export * from './outcomes';
8
+ export * from './readablepromise';
9
+ export * from './search';
10
+ export * from './searchparams';
11
+ export * from './types';
12
+ export * from './utils';
package/dist/cjs/index.js CHANGED
@@ -614,6 +614,23 @@
614
614
  }
615
615
  return true;
616
616
  }
617
+ /**
618
+ * Creates a deep clone of the input value.
619
+ *
620
+ * Limitations:
621
+ * - Only supports JSON primitives and arrays.
622
+ * - Does not support Functions, lambdas, etc.
623
+ * - Does not support circular references.
624
+ *
625
+ * See: https://web.dev/structured-clone/
626
+ * See: https://stackoverflow.com/questions/40488190/how-is-structured-clone-algorithm-different-from-deep-copy
627
+ *
628
+ * @param input The input to clone.
629
+ * @returns A deep clone of the input.
630
+ */
631
+ function deepClone(input) {
632
+ return JSON.parse(JSON.stringify(input));
633
+ }
617
634
  /**
618
635
  * Returns true if the input string is a UUID.
619
636
  * @param input The input string.
@@ -6196,7 +6213,7 @@
6196
6213
  */
6197
6214
  const globalSchema = baseSchema;
6198
6215
 
6199
- // PKCE auth ased on:
6216
+ // PKCE auth based on:
6200
6217
  // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
6201
6218
  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;
6202
6219
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
@@ -6279,16 +6296,13 @@
6279
6296
  if (!options.baseUrl.startsWith('http')) {
6280
6297
  throw new Error('Base URL must start with http or https');
6281
6298
  }
6282
- if (!options.baseUrl.endsWith('/')) {
6283
- throw new Error('Base URL must end with a trailing slash');
6284
- }
6285
6299
  }
6286
6300
  __classPrivateFieldSet(this, _MedplumClient_fetch, (options === null || options === void 0 ? void 0 : options.fetch) || window.fetch.bind(window), "f");
6287
6301
  __classPrivateFieldSet(this, _MedplumClient_createPdf, options === null || options === void 0 ? void 0 : options.createPdf, "f");
6288
6302
  __classPrivateFieldSet(this, _MedplumClient_storage, new ClientStorage(), "f");
6289
6303
  __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");
6290
6304
  __classPrivateFieldSet(this, _MedplumClient_cacheTime, (_b = options === null || options === void 0 ? void 0 : options.cacheTime) !== null && _b !== void 0 ? _b : DEFAULT_CACHE_TIME, "f");
6291
- __classPrivateFieldSet(this, _MedplumClient_baseUrl, (options === null || options === void 0 ? void 0 : options.baseUrl) || DEFAULT_BASE_URL, "f");
6305
+ __classPrivateFieldSet(this, _MedplumClient_baseUrl, ensureTrailingSlash(options === null || options === void 0 ? void 0 : options.baseUrl) || DEFAULT_BASE_URL, "f");
6292
6306
  __classPrivateFieldSet(this, _MedplumClient_clientId, (options === null || options === void 0 ? void 0 : options.clientId) || '', "f");
6293
6307
  __classPrivateFieldSet(this, _MedplumClient_authorizeUrl, (options === null || options === void 0 ? void 0 : options.authorizeUrl) || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/authorize', "f");
6294
6308
  __classPrivateFieldSet(this, _MedplumClient_tokenUrl, (options === null || options === void 0 ? void 0 : options.tokenUrl) || __classPrivateFieldGet(this, _MedplumClient_baseUrl, "f") + 'oauth2/token', "f");
@@ -6537,7 +6551,6 @@
6537
6551
  */
6538
6552
  signOut() {
6539
6553
  this.clear();
6540
- return Promise.resolve();
6541
6554
  }
6542
6555
  /**
6543
6556
  * Tries to sign in the user.
@@ -6546,15 +6559,17 @@
6546
6559
  * @category Authentication
6547
6560
  */
6548
6561
  signInWithRedirect() {
6549
- const urlParams = new URLSearchParams(window.location.search);
6550
- const code = urlParams.get('code');
6551
- if (!code) {
6552
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_requestAuthorization).call(this);
6553
- return undefined;
6554
- }
6555
- else {
6556
- return this.processCode(code);
6557
- }
6562
+ return __awaiter(this, void 0, void 0, function* () {
6563
+ const urlParams = new URLSearchParams(window.location.search);
6564
+ const code = urlParams.get('code');
6565
+ if (!code) {
6566
+ yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_requestAuthorization).call(this);
6567
+ return undefined;
6568
+ }
6569
+ else {
6570
+ return this.processCode(code);
6571
+ }
6572
+ });
6558
6573
  }
6559
6574
  /**
6560
6575
  * Tries to sign out the user.
@@ -6945,7 +6960,6 @@
6945
6960
  *
6946
6961
  * ```typescript
6947
6962
  * const result = await medplum.createResourceIfNoneExist(
6948
- * 'Patient?identifier=123',
6949
6963
  * {
6950
6964
  * resourceType: 'Patient',
6951
6965
  * identifier: [{
@@ -6956,14 +6970,16 @@
6956
6970
  * family: 'Smith',
6957
6971
  * given: ['John']
6958
6972
  * }]
6959
- * });
6973
+ * },
6974
+ * 'identifier=123'
6975
+ * );
6960
6976
  * console.log(result.id);
6961
6977
  * ```
6962
6978
  *
6963
6979
  * This method is syntactic sugar for:
6964
6980
  *
6965
6981
  * ```typescript
6966
- * return searchOne(query) ?? createResource(resource);
6982
+ * return searchOne(resourceType, query) ?? createResource(resource);
6967
6983
  * ```
6968
6984
  *
6969
6985
  * The query parameter only contains the search parameters (what would be in the URL following the "?").
@@ -6972,7 +6988,7 @@
6972
6988
  *
6973
6989
  * @category Create
6974
6990
  * @param resource The FHIR resource to create.
6975
- * @param query The search query for an equivalent resource.
6991
+ * @param query The search query for an equivalent resource (should not include resource type or "?").
6976
6992
  * @returns The result of the create operation.
6977
6993
  */
6978
6994
  createResourceIfNoneExist(resource, query) {
@@ -7553,16 +7569,18 @@
7553
7569
  __classPrivateFieldGet(this, _MedplumClient_storage, "f").setString('codeChallenge', codeChallenge);
7554
7570
  });
7555
7571
  }, _MedplumClient_requestAuthorization = function _MedplumClient_requestAuthorization() {
7556
- __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
7557
- const url = new URL(__classPrivateFieldGet(this, _MedplumClient_authorizeUrl, "f"));
7558
- url.searchParams.set('response_type', 'code');
7559
- url.searchParams.set('state', __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('pkceState'));
7560
- url.searchParams.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
7561
- url.searchParams.set('redirect_uri', getBaseUrl());
7562
- url.searchParams.set('scope', DEFAULT_SCOPE);
7563
- url.searchParams.set('code_challenge_method', 'S256');
7564
- url.searchParams.set('code_challenge', __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge'));
7565
- window.location.assign(url.toString());
7572
+ return __awaiter(this, void 0, void 0, function* () {
7573
+ yield __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_startPkce).call(this);
7574
+ const url = new URL(__classPrivateFieldGet(this, _MedplumClient_authorizeUrl, "f"));
7575
+ url.searchParams.set('response_type', 'code');
7576
+ url.searchParams.set('state', __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('pkceState'));
7577
+ url.searchParams.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
7578
+ url.searchParams.set('redirect_uri', getBaseUrl());
7579
+ url.searchParams.set('scope', DEFAULT_SCOPE);
7580
+ url.searchParams.set('code_challenge_method', 'S256');
7581
+ url.searchParams.set('code_challenge', __classPrivateFieldGet(this, _MedplumClient_storage, "f").getString('codeChallenge'));
7582
+ window.location.assign(url.toString());
7583
+ });
7566
7584
  }, _MedplumClient_refresh = function _MedplumClient_refresh() {
7567
7585
  return __awaiter(this, void 0, void 0, function* () {
7568
7586
  if (__classPrivateFieldGet(this, _MedplumClient_refreshPromise, "f")) {
@@ -7638,6 +7656,12 @@
7638
7656
  function getBaseUrl() {
7639
7657
  return window.location.protocol + '//' + window.location.host + '/';
7640
7658
  }
7659
+ function ensureTrailingSlash(url) {
7660
+ if (!url) {
7661
+ return url;
7662
+ }
7663
+ return url.endsWith('/') ? url : url + '/';
7664
+ }
7641
7665
 
7642
7666
  /**
7643
7667
  * Returns a single element array with a typed boolean value.
@@ -10396,7 +10420,8 @@
10396
10420
  const GONE_ID = 'gone';
10397
10421
  const NOT_MODIFIED_ID = 'not-modified';
10398
10422
  const NOT_FOUND_ID = 'not-found';
10399
- const ACCESS_DENIED_ID = 'access-denied';
10423
+ const UNAUTHORIZED_ID = 'unauthorized';
10424
+ const FORBIDDEN_ID = 'forbidden';
10400
10425
  const TOO_MANY_REQUESTS_ID = 'too-many-requests';
10401
10426
  const allOk = {
10402
10427
  resourceType: 'OperationOutcome',
@@ -10450,28 +10475,41 @@
10450
10475
  },
10451
10476
  ],
10452
10477
  };
10453
- const gone = {
10478
+ const unauthorized = {
10454
10479
  resourceType: 'OperationOutcome',
10455
- id: GONE_ID,
10480
+ id: UNAUTHORIZED_ID,
10456
10481
  issue: [
10457
10482
  {
10458
10483
  severity: 'error',
10459
- code: 'gone',
10484
+ code: 'login',
10460
10485
  details: {
10461
- text: 'Gone',
10486
+ text: 'Unauthorized',
10462
10487
  },
10463
10488
  },
10464
10489
  ],
10465
10490
  };
10466
- const accessDenied = {
10491
+ const forbidden = {
10467
10492
  resourceType: 'OperationOutcome',
10468
- id: ACCESS_DENIED_ID,
10493
+ id: FORBIDDEN_ID,
10469
10494
  issue: [
10470
10495
  {
10471
10496
  severity: 'error',
10472
10497
  code: 'forbidden',
10473
10498
  details: {
10474
- text: 'Access Denied',
10499
+ text: 'Forbidden',
10500
+ },
10501
+ },
10502
+ ],
10503
+ };
10504
+ const gone = {
10505
+ resourceType: 'OperationOutcome',
10506
+ id: GONE_ID,
10507
+ issue: [
10508
+ {
10509
+ severity: 'error',
10510
+ code: 'gone',
10511
+ details: {
10512
+ text: 'Gone',
10475
10513
  },
10476
10514
  },
10477
10515
  ],
@@ -10523,7 +10561,10 @@
10523
10561
  else if (outcome.id === NOT_MODIFIED_ID) {
10524
10562
  return 304;
10525
10563
  }
10526
- else if (outcome.id === ACCESS_DENIED_ID) {
10564
+ else if (outcome.id === UNAUTHORIZED_ID) {
10565
+ return 401;
10566
+ }
10567
+ else if (outcome.id === FORBIDDEN_ID) {
10527
10568
  return 403;
10528
10569
  }
10529
10570
  else if (outcome.id === NOT_FOUND_ID) {
@@ -10957,7 +10998,6 @@
10957
10998
  exports.UnaryOperatorAtom = UnaryOperatorAtom;
10958
10999
  exports.UnionAtom = UnionAtom;
10959
11000
  exports.XorAtom = XorAtom;
10960
- exports.accessDenied = accessDenied;
10961
11001
  exports.allOk = allOk;
10962
11002
  exports.arrayBufferToBase64 = arrayBufferToBase64;
10963
11003
  exports.arrayBufferToHex = arrayBufferToHex;
@@ -10972,6 +11012,7 @@
10972
11012
  exports.createSchema = createSchema;
10973
11013
  exports.createTypeSchema = createTypeSchema;
10974
11014
  exports.created = created;
11015
+ exports.deepClone = deepClone;
10975
11016
  exports.deepEquals = deepEquals$1;
10976
11017
  exports.evalFhirPath = evalFhirPath;
10977
11018
  exports.evalFhirPathTyped = evalFhirPathTyped;
@@ -10983,6 +11024,7 @@
10983
11024
  exports.fhirPathNot = fhirPathNot;
10984
11025
  exports.findObservationInterval = findObservationInterval;
10985
11026
  exports.findObservationReferenceRange = findObservationReferenceRange;
11027
+ exports.forbidden = forbidden;
10986
11028
  exports.formatAddress = formatAddress;
10987
11029
  exports.formatDate = formatDate;
10988
11030
  exports.formatDateTime = formatDateTime;
@@ -11043,6 +11085,7 @@
11043
11085
  exports.toTypedValue = toTypedValue;
11044
11086
  exports.tokenize = tokenize;
11045
11087
  exports.tooManyRequests = tooManyRequests;
11088
+ exports.unauthorized = unauthorized;
11046
11089
 
11047
11090
  Object.defineProperty(exports, '__esModule', { value: true });
11048
11091