@medplum/core 1.0.0 → 1.0.1

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.
@@ -136,10 +136,7 @@ export interface CreatePdfFunction {
136
136
  [name: string]: CustomTableLayout;
137
137
  } | undefined, fonts?: TFontDictionary | undefined): Promise<any>;
138
138
  }
139
- export interface LoginRequest {
140
- readonly email: string;
141
- readonly password: string;
142
- readonly remember?: boolean;
139
+ export interface BaseLoginRequest {
143
140
  readonly projectId?: string;
144
141
  readonly clientId?: string;
145
142
  readonly resourceType?: string;
@@ -147,6 +144,13 @@ export interface LoginRequest {
147
144
  readonly nonce?: string;
148
145
  readonly codeChallenge?: string;
149
146
  readonly codeChallengeMethod?: string;
147
+ readonly googleClientId?: string;
148
+ readonly launch?: string;
149
+ }
150
+ export interface EmailPasswordLoginRequest extends BaseLoginRequest {
151
+ readonly email: string;
152
+ readonly password: string;
153
+ readonly remember?: boolean;
150
154
  }
151
155
  export interface NewUserRequest {
152
156
  readonly firstName: string;
@@ -170,16 +174,9 @@ export interface GoogleCredentialResponse {
170
174
  readonly clientId: string;
171
175
  readonly credential: string;
172
176
  }
173
- export interface GoogleLoginRequest {
177
+ export interface GoogleLoginRequest extends BaseLoginRequest {
174
178
  readonly googleClientId: string;
175
179
  readonly googleCredential: string;
176
- readonly projectId?: string;
177
- readonly clientId?: string;
178
- readonly resourceType?: string;
179
- readonly scope?: string;
180
- readonly nonce?: string;
181
- readonly codeChallenge?: string;
182
- readonly codeChallengeMethod?: string;
183
180
  readonly createUser?: boolean;
184
181
  }
185
182
  export interface LoginAuthenticationResponse {
@@ -318,6 +315,11 @@ export interface MailOptions {
318
315
  * const bundle = await medplum.search('Patient', 'name=Alice');
319
316
  * console.log(bundle.total);
320
317
  * ```
318
+ *
319
+ * <head>
320
+ * <meta name="algolia:pageRank" content="100" />
321
+ * </head>
322
+
321
323
  */
322
324
  export declare class MedplumClient extends EventTarget {
323
325
  #private;
@@ -454,7 +456,7 @@ export declare class MedplumClient extends EventTarget {
454
456
  * @param loginRequest Login request including email and password.
455
457
  * @returns Promise to the authentication response.
456
458
  */
457
- startLogin(loginRequest: LoginRequest): Promise<LoginAuthenticationResponse>;
459
+ startLogin(loginRequest: EmailPasswordLoginRequest): Promise<LoginAuthenticationResponse>;
458
460
  /**
459
461
  * Tries to sign in with Google authentication.
460
462
  * The response parameter is the result of a Google authentication.
@@ -464,7 +466,7 @@ export declare class MedplumClient extends EventTarget {
464
466
  * @returns Promise to the authentication response.
465
467
  */
466
468
  startGoogleLogin(loginRequest: GoogleLoginRequest): Promise<LoginAuthenticationResponse>;
467
- getCodeChallenge(loginRequest: LoginRequest | GoogleLoginRequest): {
469
+ getCodeChallenge(loginRequest: BaseLoginRequest): {
468
470
  codeChallenge?: string;
469
471
  codeChallengeMethod?: string;
470
472
  };
@@ -724,6 +726,16 @@ export declare class MedplumClient extends EventTarget {
724
726
  */
725
727
  readVersion<K extends ResourceType>(resourceType: K, id: string, vid: string, options?: RequestInit): ReadablePromise<ExtractResource<K>>;
726
728
  /**
729
+ * Executes the Patient "everything" operation for a patient.
730
+ *
731
+ * Example:
732
+ *
733
+ * ```typescript
734
+ * const bundle = await medplum.readPatientEverything('123');
735
+ * console.log(bundle);
736
+ * ```
737
+ *
738
+ * See the FHIR "patient-everything" operation for full details: https://hl7.org/fhir/operation-patient-everything.html
727
739
  *
728
740
  * @category Read
729
741
  * @param id The Patient Id
@@ -1,4 +1,4 @@
1
- import { Address, HumanName, Period, Timing } from '@medplum/fhirtypes';
1
+ import { Address, HumanName, Period, Timing, Range, Quantity } from '@medplum/fhirtypes';
2
2
  export interface AddressFormatOptions {
3
3
  all?: boolean;
4
4
  use?: boolean;
@@ -19,3 +19,15 @@ export declare function formatTime(time: string | undefined, options?: Intl.Date
19
19
  export declare function formatDateTime(dateTime: string | undefined, options?: Intl.DateTimeFormatOptions): string;
20
20
  export declare function formatPeriod(period: Period | undefined): string;
21
21
  export declare function formatTiming(timing: Timing | undefined): string;
22
+ /**
23
+ * Returns a human-readable string for a FHIR Range datatype, taking into account comparators and one-sided ranges
24
+ * @param range A FHIR Range element
25
+ * @returns A human-readable string representation of the Range
26
+ */
27
+ export declare function formatRange(range: Range | undefined): string;
28
+ /**
29
+ * Returns a human-readable string for a FHIR Quantity datatype, taking into account units and comparators
30
+ * @param quantity A FHIR Quantity element
31
+ * @returns A human-readable string representation of the Quantity
32
+ */
33
+ export declare function formatQuantity(quantity: Quantity | undefined, precision?: number): string;
package/dist/cjs/hl7.d.ts CHANGED
@@ -1,43 +1,136 @@
1
- export declare const SEGMENT_SEPARATOR = "\r";
2
- export declare const FIELD_SEPARATOR = "|";
3
- export declare const COMPONENT_SEPARATOR = "^";
1
+ /**
2
+ * The Hl7Context class represents the parsing context for an HL7 message.
3
+ *
4
+ * MSH-1:
5
+ * https://hl7-definition.caristix.com/v2/HL7v2.6/Fields/MSH.1
6
+ *
7
+ * MSH-2:
8
+ * https://hl7-definition.caristix.com/v2/HL7v2.6/Fields/MSH.2
9
+ *
10
+ * See this tutorial on MSH, and why it's a bad idea to use anything other than the default values:
11
+ * https://www.hl7soup.com/HL7TutorialMSH.html
12
+ */
13
+ export declare class Hl7Context {
14
+ readonly segmentSeparator: string;
15
+ readonly fieldSeparator: string;
16
+ readonly componentSeparator: string;
17
+ readonly repetitionSeparator: string;
18
+ readonly escapeCharacter: string;
19
+ readonly subcomponentSeparator: string;
20
+ constructor(segmentSeparator?: string, fieldSeparator?: string, componentSeparator?: string, repetitionSeparator?: string, escapeCharacter?: string, subcomponentSeparator?: string);
21
+ /**
22
+ * Returns the MSH-2 field value based on the configured separators.
23
+ * @returns The HL7 MSH-2 field value.
24
+ */
25
+ getMsh2(): string;
26
+ }
4
27
  /**
5
28
  * The Hl7Message class represents one HL7 message.
6
29
  * A message is a collection of segments.
7
- * Note that we do not strictly parse messages, and only use default delimeters.
8
30
  */
9
31
  export declare class Hl7Message {
32
+ readonly context: Hl7Context;
10
33
  readonly segments: Hl7Segment[];
11
- constructor(segments: Hl7Segment[]);
34
+ /**
35
+ * Creates a new HL7 message.
36
+ * @param segments The HL7 segments.
37
+ * @param context Optional HL7 parsing context.
38
+ */
39
+ constructor(segments: Hl7Segment[], context?: Hl7Context);
40
+ /**
41
+ * Returns an HL7 segment by index or by name.
42
+ * @param index The HL7 segment index or name.
43
+ * @returns The HL7 segment if found; otherwise, undefined.
44
+ */
12
45
  get(index: number | string): Hl7Segment | undefined;
46
+ /**
47
+ * Returns all HL7 segments of a given name.
48
+ * @param name The HL7 segment name.
49
+ * @returns An array of HL7 segments with the specified name.
50
+ */
13
51
  getAll(name: string): Hl7Segment[];
52
+ /**
53
+ * Returns the HL7 message as a string.
54
+ * @returns The HL7 message as a string.
55
+ */
14
56
  toString(): string;
57
+ /**
58
+ * Returns an HL7 "ACK" (acknowledgement) message for this message.
59
+ * @returns The HL7 "ACK" message.
60
+ */
15
61
  buildAck(): Hl7Message;
62
+ /**
63
+ * Parses an HL7 message string into an Hl7Message object.
64
+ * @param text The HL7 message text.
65
+ * @returns The parsed HL7 message.
66
+ */
16
67
  static parse(text: string): Hl7Message;
17
68
  }
18
69
  /**
19
70
  * The Hl7Segment class represents one HL7 segment.
20
71
  * A segment is a collection of fields.
21
72
  * The name field is the first field.
22
- * Note that we do not strictly parse messages, and only use default delimeters.
23
73
  */
24
74
  export declare class Hl7Segment {
75
+ readonly context: Hl7Context;
25
76
  readonly name: string;
26
77
  readonly fields: Hl7Field[];
27
- constructor(fields: Hl7Field[] | string[]);
78
+ /**
79
+ * Creates a new HL7 segment.
80
+ * @param fields The HL7 fields.
81
+ * @param context Optional HL7 parsing context.
82
+ */
83
+ constructor(fields: Hl7Field[] | string[], context?: Hl7Context);
84
+ /**
85
+ * Returns an HL7 field by index.
86
+ * @param index The HL7 field index.
87
+ * @returns The HL7 field.
88
+ */
28
89
  get(index: number): Hl7Field;
90
+ /**
91
+ * Returns the HL7 segment as a string.
92
+ * @returns The HL7 segment as a string.
93
+ */
29
94
  toString(): string;
30
- static parse(text: string): Hl7Segment;
95
+ /**
96
+ * Parses an HL7 segment string into an Hl7Segment object.
97
+ * @param text The HL7 segment text.
98
+ * @param context Optional HL7 parsing context.
99
+ * @returns The parsed HL7 segment.
100
+ */
101
+ static parse(text: string, context?: Hl7Context): Hl7Segment;
31
102
  }
32
103
  /**
33
104
  * The Hl7Field class represents one HL7 field.
34
105
  * A field is a collection of components.
35
- * Note that we do not strictly parse messages, and only use default delimeters.
36
106
  */
37
107
  export declare class Hl7Field {
38
- readonly components: string[];
39
- constructor(components: string[]);
40
- get(index: number): string;
108
+ readonly context: Hl7Context;
109
+ readonly components: string[][];
110
+ /**
111
+ * Creates a new HL7 field.
112
+ * @param components The HL7 components.
113
+ * @param context Optional HL7 parsing context.
114
+ */
115
+ constructor(components: string[][], context?: Hl7Context);
116
+ /**
117
+ * Returns an HL7 component by index.
118
+ * @param component The component index.
119
+ * @param subcomponent Optional subcomponent index.
120
+ * @param repetition Optional repetition index.
121
+ * @returns The string value of the specified component.
122
+ */
123
+ get(component: number, subcomponent?: number, repetition?: number): string;
124
+ /**
125
+ * Returns the HL7 field as a string.
126
+ * @returns The HL7 field as a string.
127
+ */
41
128
  toString(): string;
42
- static parse(text: string): Hl7Field;
129
+ /**
130
+ * Parses an HL7 field string into an Hl7Field object.
131
+ * @param text The HL7 field text.
132
+ * @param context Optional HL7 parsing context.
133
+ * @returns The parsed HL7 field.
134
+ */
135
+ static parse(text: string, context?: Hl7Context): Hl7Field;
43
136
  }
package/dist/cjs/index.js CHANGED
@@ -261,6 +261,54 @@
261
261
  }
262
262
  return capitalize(builder.join(' ').trim());
263
263
  }
264
+ /**
265
+ * Returns a human-readable string for a FHIR Range datatype, taking into account comparators and one-sided ranges
266
+ * @param range A FHIR Range element
267
+ * @returns A human-readable string representation of the Range
268
+ */
269
+ function formatRange(range) {
270
+ var _a, _b, _c, _d, _e, _f;
271
+ if (!range || (((_a = range.low) === null || _a === void 0 ? void 0 : _a.value) === undefined && ((_b = range.high) === null || _b === void 0 ? void 0 : _b.value) === undefined)) {
272
+ return '';
273
+ }
274
+ if (((_c = range.low) === null || _c === void 0 ? void 0 : _c.value) !== undefined && ((_d = range.high) === null || _d === void 0 ? void 0 : _d.value) === undefined) {
275
+ return `>= ${formatQuantity(range.low)}`;
276
+ }
277
+ if (((_e = range.low) === null || _e === void 0 ? void 0 : _e.value) === undefined && ((_f = range.high) === null || _f === void 0 ? void 0 : _f.value) !== undefined) {
278
+ return `<= ${formatQuantity(range.high)}`;
279
+ }
280
+ return `${formatQuantity(range.low)} - ${formatQuantity(range.high)}`;
281
+ }
282
+ /**
283
+ * Returns a human-readable string for a FHIR Quantity datatype, taking into account units and comparators
284
+ * @param quantity A FHIR Quantity element
285
+ * @returns A human-readable string representation of the Quantity
286
+ */
287
+ function formatQuantity(quantity, precision) {
288
+ if (!quantity) {
289
+ return '';
290
+ }
291
+ const result = [];
292
+ if (quantity.comparator) {
293
+ result.push(quantity.comparator);
294
+ result.push(' ');
295
+ }
296
+ if (quantity.value !== undefined) {
297
+ if (precision !== undefined) {
298
+ result.push(quantity.value.toFixed(precision));
299
+ }
300
+ else {
301
+ result.push(quantity.value);
302
+ }
303
+ }
304
+ if (quantity.unit) {
305
+ if (quantity.unit !== '%' && result[result.length - 1] !== ' ') {
306
+ result.push(' ');
307
+ }
308
+ result.push(quantity.unit);
309
+ }
310
+ return result.join('').trim();
311
+ }
264
312
 
265
313
  /**
266
314
  * Creates a reference resource.
@@ -800,6 +848,15 @@
800
848
  return ((((_a = range.low) === null || _a === void 0 ? void 0 : _a.value) === undefined || preciseGreaterThanOrEquals(value, range.low.value, precision)) &&
801
849
  (((_b = range.high) === null || _b === void 0 ? void 0 : _b.value) === undefined || preciseLessThanOrEquals(value, range.high.value, precision)));
802
850
  }
851
+ /**
852
+ * Returns the input number rounded to the specified number of digits.
853
+ * @param a The input number.
854
+ * @param precision The precision in number of digits.
855
+ * @returns The number rounded to the specified number of digits.
856
+ */
857
+ function preciseRound(a, precision) {
858
+ return parseFloat(a.toFixed(precision));
859
+ }
803
860
  /**
804
861
  * Returns true if the two numbers are equal to the given precision.
805
862
  * @param a The first number.
@@ -6265,9 +6322,8 @@
6265
6322
  // PKCE auth based on:
6266
6323
  // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
6267
6324
  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_requestAuthorization, _MedplumClient_refresh, _MedplumClient_fetchTokens, _MedplumClient_verifyTokens, _MedplumClient_setupStorageListener;
6268
- const MEDPLUM_VERSION = "1.0.0-a614a88a";
6325
+ const MEDPLUM_VERSION = "1.0.1-69d972ca";
6269
6326
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
6270
- const DEFAULT_SCOPE = 'launch/patient openid fhirUser offline_access user/*.*';
6271
6327
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
6272
6328
  const DEFAULT_CACHE_TIME = 60000; // 60 seconds
6273
6329
  const JSON_CONTENT_TYPE = 'application/json';
@@ -6319,6 +6375,11 @@
6319
6375
  * const bundle = await medplum.search('Patient', 'name=Alice');
6320
6376
  * console.log(bundle.total);
6321
6377
  * ```
6378
+ *
6379
+ * <head>
6380
+ * <meta name="algolia:pageRank" content="100" />
6381
+ * </head>
6382
+
6322
6383
  */
6323
6384
  class MedplumClient extends EventTarget {
6324
6385
  constructor(options) {
@@ -6571,10 +6632,10 @@
6571
6632
  * @returns Promise to the authentication response.
6572
6633
  */
6573
6634
  startLogin(loginRequest) {
6574
- var _a, _b;
6635
+ var _a;
6575
6636
  return __awaiter(this, void 0, void 0, function* () {
6576
6637
  const { codeChallenge, codeChallengeMethod } = this.getCodeChallenge(loginRequest);
6577
- return this.post('auth/login', Object.assign(Object.assign({}, loginRequest), { clientId: (_a = loginRequest.clientId) !== null && _a !== void 0 ? _a : __classPrivateFieldGet(this, _MedplumClient_clientId, "f"), scope: (_b = loginRequest.scope) !== null && _b !== void 0 ? _b : DEFAULT_SCOPE, codeChallengeMethod,
6638
+ return this.post('auth/login', Object.assign(Object.assign({}, loginRequest), { clientId: (_a = loginRequest.clientId) !== null && _a !== void 0 ? _a : __classPrivateFieldGet(this, _MedplumClient_clientId, "f"), scope: loginRequest.scope, codeChallengeMethod,
6578
6639
  codeChallenge }));
6579
6640
  });
6580
6641
  }
@@ -6587,10 +6648,10 @@
6587
6648
  * @returns Promise to the authentication response.
6588
6649
  */
6589
6650
  startGoogleLogin(loginRequest) {
6590
- var _a, _b;
6651
+ var _a;
6591
6652
  return __awaiter(this, void 0, void 0, function* () {
6592
6653
  const { codeChallenge, codeChallengeMethod } = this.getCodeChallenge(loginRequest);
6593
- return this.post('auth/google', Object.assign(Object.assign({}, loginRequest), { clientId: (_a = loginRequest.clientId) !== null && _a !== void 0 ? _a : __classPrivateFieldGet(this, _MedplumClient_clientId, "f"), scope: (_b = loginRequest.scope) !== null && _b !== void 0 ? _b : DEFAULT_SCOPE, codeChallengeMethod,
6654
+ return this.post('auth/google', Object.assign(Object.assign({}, loginRequest), { clientId: (_a = loginRequest.clientId) !== null && _a !== void 0 ? _a : __classPrivateFieldGet(this, _MedplumClient_clientId, "f"), scope: loginRequest.scope, codeChallengeMethod,
6594
6655
  codeChallenge }));
6595
6656
  });
6596
6657
  }
@@ -6994,6 +7055,16 @@
6994
7055
  return this.get(this.fhirUrl(resourceType, id, '_history', vid), options);
6995
7056
  }
6996
7057
  /**
7058
+ * Executes the Patient "everything" operation for a patient.
7059
+ *
7060
+ * Example:
7061
+ *
7062
+ * ```typescript
7063
+ * const bundle = await medplum.readPatientEverything('123');
7064
+ * console.log(bundle);
7065
+ * ```
7066
+ *
7067
+ * See the FHIR "patient-everything" operation for full details: https://hl7.org/fhir/operation-patient-everything.html
6997
7068
  *
6998
7069
  * @category Read
6999
7070
  * @param id The Patient Id
@@ -7724,7 +7795,6 @@
7724
7795
  url.searchParams.set('state', sessionStorage.getItem('pkceState'));
7725
7796
  url.searchParams.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
7726
7797
  url.searchParams.set('redirect_uri', getBaseUrl());
7727
- url.searchParams.set('scope', DEFAULT_SCOPE);
7728
7798
  url.searchParams.set('code_challenge_method', 'S256');
7729
7799
  url.searchParams.set('code_challenge', sessionStorage.getItem('codeChallenge'));
7730
7800
  window.location.assign(url.toString());
@@ -10479,30 +10549,83 @@
10479
10549
  return parseFhirPath(expression).eval(input);
10480
10550
  }
10481
10551
 
10482
- const SEGMENT_SEPARATOR = '\r';
10483
- const FIELD_SEPARATOR = '|';
10484
- const COMPONENT_SEPARATOR = '^';
10552
+ /**
10553
+ * The Hl7Context class represents the parsing context for an HL7 message.
10554
+ *
10555
+ * MSH-1:
10556
+ * https://hl7-definition.caristix.com/v2/HL7v2.6/Fields/MSH.1
10557
+ *
10558
+ * MSH-2:
10559
+ * https://hl7-definition.caristix.com/v2/HL7v2.6/Fields/MSH.2
10560
+ *
10561
+ * See this tutorial on MSH, and why it's a bad idea to use anything other than the default values:
10562
+ * https://www.hl7soup.com/HL7TutorialMSH.html
10563
+ */
10564
+ class Hl7Context {
10565
+ constructor(segmentSeparator = '\r', fieldSeparator = '|', componentSeparator = '^', repetitionSeparator = '~', escapeCharacter = '\\', subcomponentSeparator = '&') {
10566
+ this.segmentSeparator = segmentSeparator;
10567
+ this.fieldSeparator = fieldSeparator;
10568
+ this.componentSeparator = componentSeparator;
10569
+ this.repetitionSeparator = repetitionSeparator;
10570
+ this.escapeCharacter = escapeCharacter;
10571
+ this.subcomponentSeparator = subcomponentSeparator;
10572
+ }
10573
+ /**
10574
+ * Returns the MSH-2 field value based on the configured separators.
10575
+ * @returns The HL7 MSH-2 field value.
10576
+ */
10577
+ getMsh2() {
10578
+ return (this.fieldSeparator +
10579
+ this.componentSeparator +
10580
+ this.repetitionSeparator +
10581
+ this.escapeCharacter +
10582
+ this.subcomponentSeparator);
10583
+ }
10584
+ }
10485
10585
  /**
10486
10586
  * The Hl7Message class represents one HL7 message.
10487
10587
  * A message is a collection of segments.
10488
- * Note that we do not strictly parse messages, and only use default delimeters.
10489
10588
  */
10490
10589
  class Hl7Message {
10491
- constructor(segments) {
10590
+ /**
10591
+ * Creates a new HL7 message.
10592
+ * @param segments The HL7 segments.
10593
+ * @param context Optional HL7 parsing context.
10594
+ */
10595
+ constructor(segments, context = new Hl7Context()) {
10596
+ this.context = context;
10492
10597
  this.segments = segments;
10493
10598
  }
10599
+ /**
10600
+ * Returns an HL7 segment by index or by name.
10601
+ * @param index The HL7 segment index or name.
10602
+ * @returns The HL7 segment if found; otherwise, undefined.
10603
+ */
10494
10604
  get(index) {
10495
10605
  if (typeof index === 'number') {
10496
10606
  return this.segments[index];
10497
10607
  }
10498
10608
  return this.segments.find((s) => s.name === index);
10499
10609
  }
10610
+ /**
10611
+ * Returns all HL7 segments of a given name.
10612
+ * @param name The HL7 segment name.
10613
+ * @returns An array of HL7 segments with the specified name.
10614
+ */
10500
10615
  getAll(name) {
10501
10616
  return this.segments.filter((s) => s.name === name);
10502
10617
  }
10618
+ /**
10619
+ * Returns the HL7 message as a string.
10620
+ * @returns The HL7 message as a string.
10621
+ */
10503
10622
  toString() {
10504
- return this.segments.map((s) => s.toString()).join(SEGMENT_SEPARATOR);
10623
+ return this.segments.map((s) => s.toString()).join(this.context.segmentSeparator);
10505
10624
  }
10625
+ /**
10626
+ * Returns an HL7 "ACK" (acknowledgement) message for this message.
10627
+ * @returns The HL7 "ACK" message.
10628
+ */
10506
10629
  buildAck() {
10507
10630
  var _a, _b, _c, _d, _e, _f;
10508
10631
  const now = new Date();
@@ -10516,7 +10639,7 @@
10516
10639
  return new Hl7Message([
10517
10640
  new Hl7Segment([
10518
10641
  'MSH',
10519
- '^~\\&',
10642
+ this.context.getMsh2(),
10520
10643
  receivingApp,
10521
10644
  receivingFacility,
10522
10645
  sendingApp,
@@ -10527,62 +10650,119 @@
10527
10650
  now.getTime().toString(),
10528
10651
  'P',
10529
10652
  versionId,
10530
- ]),
10531
- new Hl7Segment(['MSA', 'AA', controlId, 'OK']),
10653
+ ], this.context),
10654
+ new Hl7Segment(['MSA', 'AA', controlId, 'OK'], this.context),
10532
10655
  ]);
10533
10656
  }
10657
+ /**
10658
+ * Parses an HL7 message string into an Hl7Message object.
10659
+ * @param text The HL7 message text.
10660
+ * @returns The parsed HL7 message.
10661
+ */
10534
10662
  static parse(text) {
10535
- if (!text.startsWith('MSH|^~\\&')) {
10663
+ if (!text.startsWith('MSH')) {
10536
10664
  const err = new Error('Invalid HL7 message');
10537
10665
  err.type = 'entity.parse.failed';
10538
10666
  throw err;
10539
10667
  }
10540
- return new Hl7Message(text.split(/[\r\n]+/).map((line) => Hl7Segment.parse(line)));
10668
+ const context = new Hl7Context('\r', text.charAt(3), // Field separator, recommended "|"
10669
+ text.charAt(4), // Component separator, recommended "^"
10670
+ text.charAt(5), // Repetition separator, recommended "~"
10671
+ text.charAt(6), // Escape character, recommended "\"
10672
+ text.charAt(7) // Subcomponent separator, recommended "&"
10673
+ );
10674
+ return new Hl7Message(text.split(/[\r\n]+/).map((line) => Hl7Segment.parse(line, context)), context);
10541
10675
  }
10542
10676
  }
10543
10677
  /**
10544
10678
  * The Hl7Segment class represents one HL7 segment.
10545
10679
  * A segment is a collection of fields.
10546
10680
  * The name field is the first field.
10547
- * Note that we do not strictly parse messages, and only use default delimeters.
10548
10681
  */
10549
10682
  class Hl7Segment {
10550
- constructor(fields) {
10683
+ /**
10684
+ * Creates a new HL7 segment.
10685
+ * @param fields The HL7 fields.
10686
+ * @param context Optional HL7 parsing context.
10687
+ */
10688
+ constructor(fields, context = new Hl7Context()) {
10689
+ this.context = context;
10551
10690
  if (isStringArray(fields)) {
10552
10691
  this.fields = fields.map((f) => Hl7Field.parse(f));
10553
10692
  }
10554
10693
  else {
10555
10694
  this.fields = fields;
10556
10695
  }
10557
- this.name = this.fields[0].components[0];
10696
+ this.name = this.fields[0].components[0][0];
10558
10697
  }
10698
+ /**
10699
+ * Returns an HL7 field by index.
10700
+ * @param index The HL7 field index.
10701
+ * @returns The HL7 field.
10702
+ */
10559
10703
  get(index) {
10560
10704
  return this.fields[index];
10561
10705
  }
10706
+ /**
10707
+ * Returns the HL7 segment as a string.
10708
+ * @returns The HL7 segment as a string.
10709
+ */
10562
10710
  toString() {
10563
- return this.fields.map((f) => f.toString()).join(FIELD_SEPARATOR);
10711
+ return this.fields.map((f) => f.toString()).join(this.context.fieldSeparator);
10564
10712
  }
10565
- static parse(text) {
10566
- return new Hl7Segment(text.split(FIELD_SEPARATOR).map((f) => Hl7Field.parse(f)));
10713
+ /**
10714
+ * Parses an HL7 segment string into an Hl7Segment object.
10715
+ * @param text The HL7 segment text.
10716
+ * @param context Optional HL7 parsing context.
10717
+ * @returns The parsed HL7 segment.
10718
+ */
10719
+ static parse(text, context = new Hl7Context()) {
10720
+ return new Hl7Segment(text.split(context.fieldSeparator).map((f) => Hl7Field.parse(f, context)), context);
10567
10721
  }
10568
10722
  }
10569
10723
  /**
10570
10724
  * The Hl7Field class represents one HL7 field.
10571
10725
  * A field is a collection of components.
10572
- * Note that we do not strictly parse messages, and only use default delimeters.
10573
10726
  */
10574
10727
  class Hl7Field {
10575
- constructor(components) {
10728
+ /**
10729
+ * Creates a new HL7 field.
10730
+ * @param components The HL7 components.
10731
+ * @param context Optional HL7 parsing context.
10732
+ */
10733
+ constructor(components, context = new Hl7Context()) {
10734
+ this.context = context;
10576
10735
  this.components = components;
10577
10736
  }
10578
- get(index) {
10579
- return this.components[index];
10737
+ /**
10738
+ * Returns an HL7 component by index.
10739
+ * @param component The component index.
10740
+ * @param subcomponent Optional subcomponent index.
10741
+ * @param repetition Optional repetition index.
10742
+ * @returns The string value of the specified component.
10743
+ */
10744
+ get(component, subcomponent, repetition = 0) {
10745
+ let value = this.components[repetition][component] || '';
10746
+ if (subcomponent !== undefined) {
10747
+ value = value.split(this.context.subcomponentSeparator)[subcomponent] || '';
10748
+ }
10749
+ return value;
10580
10750
  }
10751
+ /**
10752
+ * Returns the HL7 field as a string.
10753
+ * @returns The HL7 field as a string.
10754
+ */
10581
10755
  toString() {
10582
- return this.components.join(COMPONENT_SEPARATOR);
10756
+ return this.components.map((r) => r.join(this.context.componentSeparator)).join(this.context.repetitionSeparator);
10583
10757
  }
10584
- static parse(text) {
10585
- return new Hl7Field(text.split(COMPONENT_SEPARATOR));
10758
+ /**
10759
+ * Parses an HL7 field string into an Hl7Field object.
10760
+ * @param text The HL7 field text.
10761
+ * @param context Optional HL7 parsing context.
10762
+ * @returns The parsed HL7 field.
10763
+ */
10764
+ static parse(text, context = new Hl7Context()) {
10765
+ return new Hl7Field(text.split(context.repetitionSeparator).map((r) => r.split(context.componentSeparator)), context);
10586
10766
  }
10587
10767
  }
10588
10768
 
@@ -11306,7 +11486,6 @@
11306
11486
  exports.AndAtom = AndAtom;
11307
11487
  exports.ArithemticOperatorAtom = ArithemticOperatorAtom;
11308
11488
  exports.AsAtom = AsAtom;
11309
- exports.COMPONENT_SEPARATOR = COMPONENT_SEPARATOR;
11310
11489
  exports.ConcatAtom = ConcatAtom;
11311
11490
  exports.ContainsAtom = ContainsAtom;
11312
11491
  exports.DEFAULT_SEARCH_COUNT = DEFAULT_SEARCH_COUNT;
@@ -11316,9 +11495,9 @@
11316
11495
  exports.EquivalentAtom = EquivalentAtom;
11317
11496
  exports.FHIRPATH_KEYWORDS = FHIRPATH_KEYWORDS;
11318
11497
  exports.FHIRPATH_OPERATORS = FHIRPATH_OPERATORS;
11319
- exports.FIELD_SEPARATOR = FIELD_SEPARATOR;
11320
11498
  exports.FhirPathAtom = FhirPathAtom;
11321
11499
  exports.FunctionAtom = FunctionAtom;
11500
+ exports.Hl7Context = Hl7Context;
11322
11501
  exports.Hl7Field = Hl7Field;
11323
11502
  exports.Hl7Message = Hl7Message;
11324
11503
  exports.Hl7Segment = Hl7Segment;
@@ -11334,7 +11513,6 @@
11334
11513
  exports.OperationOutcomeError = OperationOutcomeError;
11335
11514
  exports.OrAtom = OrAtom;
11336
11515
  exports.ReadablePromise = ReadablePromise;
11337
- exports.SEGMENT_SEPARATOR = SEGMENT_SEPARATOR;
11338
11516
  exports.SymbolAtom = SymbolAtom;
11339
11517
  exports.UnaryOperatorAtom = UnaryOperatorAtom;
11340
11518
  exports.UnionAtom = UnionAtom;
@@ -11372,6 +11550,8 @@
11372
11550
  exports.formatGivenName = formatGivenName;
11373
11551
  exports.formatHumanName = formatHumanName;
11374
11552
  exports.formatPeriod = formatPeriod;
11553
+ exports.formatQuantity = formatQuantity;
11554
+ exports.formatRange = formatRange;
11375
11555
  exports.formatSearchQuery = formatSearchQuery;
11376
11556
  exports.formatTime = formatTime;
11377
11557
  exports.formatTiming = formatTiming;
@@ -11422,6 +11602,7 @@
11422
11602
  exports.preciseGreaterThanOrEquals = preciseGreaterThanOrEquals;
11423
11603
  exports.preciseLessThan = preciseLessThan;
11424
11604
  exports.preciseLessThanOrEquals = preciseLessThanOrEquals;
11605
+ exports.preciseRound = preciseRound;
11425
11606
  exports.removeDuplicates = removeDuplicates;
11426
11607
  exports.resolveId = resolveId;
11427
11608
  exports.setCodeBySystem = setCodeBySystem;