@medplum/core 0.10.2 → 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.
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.
@@ -305,7 +353,7 @@
305
353
  * @return Human friendly display string.
306
354
  */
307
355
  function getDisplayString(resource) {
308
- var _a, _b;
356
+ var _a;
309
357
  if (isProfileResource(resource)) {
310
358
  const profileName = getProfileResourceDisplayString(resource);
311
359
  if (profileName) {
@@ -320,7 +368,7 @@
320
368
  }
321
369
  if (resource.resourceType === 'Observation') {
322
370
  if ('code' in resource && ((_a = resource.code) === null || _a === void 0 ? void 0 : _a.text)) {
323
- return (_b = resource.code) === null || _b === void 0 ? void 0 : _b.text;
371
+ return resource.code.text;
324
372
  }
325
373
  }
326
374
  if (resource.resourceType === 'User') {
@@ -363,22 +411,23 @@
363
411
  * @returns The image URL for the resource or undefined.
364
412
  */
365
413
  function getImageSrc(resource) {
366
- if (isProfileResource(resource)) {
367
- const photos = resource.photo;
368
- if (photos) {
369
- for (const photo of photos) {
370
- const url = getPhotoImageSrc(photo);
371
- if (url) {
372
- return url;
373
- }
414
+ if (!('photo' in resource)) {
415
+ return undefined;
416
+ }
417
+ const photo = resource.photo;
418
+ if (!photo) {
419
+ return undefined;
420
+ }
421
+ if (Array.isArray(photo)) {
422
+ for (const p of photo) {
423
+ const url = getPhotoImageSrc(p);
424
+ if (url) {
425
+ return url;
374
426
  }
375
427
  }
376
428
  }
377
- if (resource.resourceType === 'Bot' && resource.photo) {
378
- const url = getPhotoImageSrc(resource.photo);
379
- if (url) {
380
- return url;
381
- }
429
+ else {
430
+ return getPhotoImageSrc(photo);
382
431
  }
383
432
  return undefined;
384
433
  }
@@ -799,6 +848,15 @@
799
848
  return ((((_a = range.low) === null || _a === void 0 ? void 0 : _a.value) === undefined || preciseGreaterThanOrEquals(value, range.low.value, precision)) &&
800
849
  (((_b = range.high) === null || _b === void 0 ? void 0 : _b.value) === undefined || preciseLessThanOrEquals(value, range.high.value, precision)));
801
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
+ }
802
860
  /**
803
861
  * Returns true if the two numbers are equal to the given precision.
804
862
  * @param a The first number.
@@ -6264,9 +6322,8 @@
6264
6322
  // PKCE auth based on:
6265
6323
  // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
6266
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;
6267
- const MEDPLUM_VERSION = "0.10.2-f713edf5";
6325
+ const MEDPLUM_VERSION = "1.0.1-69d972ca";
6268
6326
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
6269
- const DEFAULT_SCOPE = 'launch/patient openid fhirUser offline_access user/*.*';
6270
6327
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
6271
6328
  const DEFAULT_CACHE_TIME = 60000; // 60 seconds
6272
6329
  const JSON_CONTENT_TYPE = 'application/json';
@@ -6318,6 +6375,11 @@
6318
6375
  * const bundle = await medplum.search('Patient', 'name=Alice');
6319
6376
  * console.log(bundle.total);
6320
6377
  * ```
6378
+ *
6379
+ * <head>
6380
+ * <meta name="algolia:pageRank" content="100" />
6381
+ * </head>
6382
+
6321
6383
  */
6322
6384
  class MedplumClient extends EventTarget {
6323
6385
  constructor(options) {
@@ -6570,10 +6632,10 @@
6570
6632
  * @returns Promise to the authentication response.
6571
6633
  */
6572
6634
  startLogin(loginRequest) {
6573
- var _a, _b;
6635
+ var _a;
6574
6636
  return __awaiter(this, void 0, void 0, function* () {
6575
6637
  const { codeChallenge, codeChallengeMethod } = this.getCodeChallenge(loginRequest);
6576
- 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,
6577
6639
  codeChallenge }));
6578
6640
  });
6579
6641
  }
@@ -6586,10 +6648,10 @@
6586
6648
  * @returns Promise to the authentication response.
6587
6649
  */
6588
6650
  startGoogleLogin(loginRequest) {
6589
- var _a, _b;
6651
+ var _a;
6590
6652
  return __awaiter(this, void 0, void 0, function* () {
6591
6653
  const { codeChallenge, codeChallengeMethod } = this.getCodeChallenge(loginRequest);
6592
- 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,
6593
6655
  codeChallenge }));
6594
6656
  });
6595
6657
  }
@@ -6711,7 +6773,9 @@
6711
6773
  * See FHIR search for full details: https://www.hl7.org/fhir/search.html
6712
6774
  *
6713
6775
  * @category Search
6776
+ * @param resourceType The FHIR resource type.
6714
6777
  * @param query The search query as either a string or a structured search object.
6778
+ * @param options Optional fetch options.
6715
6779
  * @returns Promise to the search result bundle.
6716
6780
  */
6717
6781
  search(resourceType, query, options = {}) {
@@ -6734,7 +6798,9 @@
6734
6798
  * See FHIR search for full details: https://www.hl7.org/fhir/search.html
6735
6799
  *
6736
6800
  * @category Search
6801
+ * @param resourceType The FHIR resource type.
6737
6802
  * @param query The search query as either a string or a structured search object.
6803
+ * @param options Optional fetch options.
6738
6804
  * @returns Promise to the search result bundle.
6739
6805
  */
6740
6806
  searchOne(resourceType, query, options = {}) {
@@ -6767,7 +6833,9 @@
6767
6833
  * See FHIR search for full details: https://www.hl7.org/fhir/search.html
6768
6834
  *
6769
6835
  * @category Search
6836
+ * @param resourceType The FHIR resource type.
6770
6837
  * @param query The search query as either a string or a structured search object.
6838
+ * @param options Optional fetch options.
6771
6839
  * @returns Promise to the search result bundle.
6772
6840
  */
6773
6841
  searchResources(resourceType, query, options = {}) {
@@ -6788,6 +6856,7 @@
6788
6856
  * @category Search
6789
6857
  * @param system The ValueSet system url.
6790
6858
  * @param filter The search string.
6859
+ * @param options Optional fetch options.
6791
6860
  * @returns Promise to expanded ValueSet.
6792
6861
  */
6793
6862
  searchValueSet(system, filter, options = {}) {
@@ -6841,6 +6910,7 @@
6841
6910
  * @category Read
6842
6911
  * @param resourceType The FHIR resource type.
6843
6912
  * @param id The resource ID.
6913
+ * @param options Optional fetch options.
6844
6914
  * @returns The resource if available; undefined otherwise.
6845
6915
  */
6846
6916
  readResource(resourceType, id, options = {}) {
@@ -6863,6 +6933,7 @@
6863
6933
  *
6864
6934
  * @category Read
6865
6935
  * @param reference The FHIR reference object.
6936
+ * @param options Optional fetch options.
6866
6937
  * @returns The resource if available; undefined otherwise.
6867
6938
  */
6868
6939
  readReference(reference, options = {}) {
@@ -6881,7 +6952,6 @@
6881
6952
  * If the schema is not cached, returns undefined.
6882
6953
  * It is assumed that a client will call requestSchema before using this method.
6883
6954
  * @category Schema
6884
- * @param resourceType The FHIR resource type.
6885
6955
  * @returns The schema if immediately available, undefined otherwise.
6886
6956
  * @deprecated Use globalSchema instead.
6887
6957
  */
@@ -6956,6 +7026,7 @@
6956
7026
  * @category Read
6957
7027
  * @param resourceType The FHIR resource type.
6958
7028
  * @param id The resource ID.
7029
+ * @param options Optional fetch options.
6959
7030
  * @returns Promise to the resource history.
6960
7031
  */
6961
7032
  readHistory(resourceType, id, options = {}) {
@@ -6976,15 +7047,28 @@
6976
7047
  * @category Read
6977
7048
  * @param resourceType The FHIR resource type.
6978
7049
  * @param id The resource ID.
7050
+ * @param vid The version ID.
7051
+ * @param options Optional fetch options.
6979
7052
  * @returns The resource if available; undefined otherwise.
6980
7053
  */
6981
7054
  readVersion(resourceType, id, vid, options = {}) {
6982
7055
  return this.get(this.fhirUrl(resourceType, id, '_history', vid), options);
6983
7056
  }
6984
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
6985
7068
  *
6986
7069
  * @category Read
6987
7070
  * @param id The Patient Id
7071
+ * @param options Optional fetch options.
6988
7072
  * @returns A Bundle of all Resources related to the Patient
6989
7073
  */
6990
7074
  readPatientEverything(id, options = {}) {
@@ -7091,12 +7175,44 @@
7091
7175
  * @param contentType Content type for the binary.
7092
7176
  * @returns The result of the create operation.
7093
7177
  */
7094
- createBinary(data, filename, contentType) {
7178
+ createBinary(data, filename, contentType, onProgress) {
7095
7179
  const url = this.fhirUrl('Binary');
7096
7180
  if (filename) {
7097
7181
  url.searchParams.set('_filename', filename);
7098
7182
  }
7099
- return this.post(url, data, contentType);
7183
+ if (onProgress) {
7184
+ return this.uploadwithProgress(url, data, contentType, onProgress);
7185
+ }
7186
+ else {
7187
+ return this.post(url, data, contentType);
7188
+ }
7189
+ }
7190
+ uploadwithProgress(url, data, contentType, onProgress) {
7191
+ return new Promise((resolve, reject) => {
7192
+ const xhr = new XMLHttpRequest();
7193
+ xhr.responseType = 'json';
7194
+ xhr.onabort = () => reject(new Error('Request aborted'));
7195
+ xhr.onerror = () => reject(new Error('Request error'));
7196
+ if (onProgress) {
7197
+ xhr.upload.onprogress = (e) => onProgress(e);
7198
+ xhr.upload.onload = (e) => onProgress(e);
7199
+ }
7200
+ xhr.onload = () => {
7201
+ if (xhr.status >= 200 && xhr.status < 300) {
7202
+ resolve(xhr.response);
7203
+ }
7204
+ else {
7205
+ reject(new Error(xhr.statusText));
7206
+ }
7207
+ };
7208
+ xhr.open('POST', url);
7209
+ xhr.withCredentials = true;
7210
+ xhr.setRequestHeader('Authorization', 'Bearer ' + __classPrivateFieldGet(this, _MedplumClient_accessToken, "f"));
7211
+ xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, max-age=0');
7212
+ xhr.setRequestHeader('Content-Type', contentType);
7213
+ xhr.setRequestHeader('X-Medplum', 'extended');
7214
+ xhr.send(data);
7215
+ });
7100
7216
  }
7101
7217
  /**
7102
7218
  * Creates a PDF as a FHIR `Binary` resource based on pdfmake document definition.
@@ -7252,6 +7368,26 @@
7252
7368
  this.invalidateSearches(resourceType);
7253
7369
  return this.delete(this.fhirUrl(resourceType, id));
7254
7370
  }
7371
+ /**
7372
+ * Executes the validate operation with the provided resource.
7373
+ *
7374
+ * Example:
7375
+ *
7376
+ * ```typescript
7377
+ * const result = await medplum.validateResource({
7378
+ * resourceType: 'Patient',
7379
+ * name: [{ given: ['Alice'], family: 'Smith' }],
7380
+ * });
7381
+ * ```
7382
+ *
7383
+ * See the FHIR "$validate" operation for full details: https://www.hl7.org/fhir/resource-operation-validate.html
7384
+ *
7385
+ * @param resource The FHIR resource.
7386
+ * @returns The validate operation outcome.
7387
+ */
7388
+ validateResource(resource) {
7389
+ return this.post(this.fhirUrl(resource.resourceType, '$validate'), resource);
7390
+ }
7255
7391
  /**
7256
7392
  * Executes a batch or transaction of FHIR operations.
7257
7393
  *
@@ -7659,7 +7795,6 @@
7659
7795
  url.searchParams.set('state', sessionStorage.getItem('pkceState'));
7660
7796
  url.searchParams.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
7661
7797
  url.searchParams.set('redirect_uri', getBaseUrl());
7662
- url.searchParams.set('scope', DEFAULT_SCOPE);
7663
7798
  url.searchParams.set('code_challenge_method', 'S256');
7664
7799
  url.searchParams.set('code_challenge', sessionStorage.getItem('codeChallenge'));
7665
7800
  window.location.assign(url.toString());
@@ -10414,30 +10549,83 @@
10414
10549
  return parseFhirPath(expression).eval(input);
10415
10550
  }
10416
10551
 
10417
- const SEGMENT_SEPARATOR = '\r';
10418
- const FIELD_SEPARATOR = '|';
10419
- 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
+ }
10420
10585
  /**
10421
10586
  * The Hl7Message class represents one HL7 message.
10422
10587
  * A message is a collection of segments.
10423
- * Note that we do not strictly parse messages, and only use default delimeters.
10424
10588
  */
10425
10589
  class Hl7Message {
10426
- 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;
10427
10597
  this.segments = segments;
10428
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
+ */
10429
10604
  get(index) {
10430
10605
  if (typeof index === 'number') {
10431
10606
  return this.segments[index];
10432
10607
  }
10433
10608
  return this.segments.find((s) => s.name === index);
10434
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
+ */
10435
10615
  getAll(name) {
10436
10616
  return this.segments.filter((s) => s.name === name);
10437
10617
  }
10618
+ /**
10619
+ * Returns the HL7 message as a string.
10620
+ * @returns The HL7 message as a string.
10621
+ */
10438
10622
  toString() {
10439
- return this.segments.map((s) => s.toString()).join(SEGMENT_SEPARATOR);
10623
+ return this.segments.map((s) => s.toString()).join(this.context.segmentSeparator);
10440
10624
  }
10625
+ /**
10626
+ * Returns an HL7 "ACK" (acknowledgement) message for this message.
10627
+ * @returns The HL7 "ACK" message.
10628
+ */
10441
10629
  buildAck() {
10442
10630
  var _a, _b, _c, _d, _e, _f;
10443
10631
  const now = new Date();
@@ -10451,7 +10639,7 @@
10451
10639
  return new Hl7Message([
10452
10640
  new Hl7Segment([
10453
10641
  'MSH',
10454
- '^~\\&',
10642
+ this.context.getMsh2(),
10455
10643
  receivingApp,
10456
10644
  receivingFacility,
10457
10645
  sendingApp,
@@ -10462,62 +10650,119 @@
10462
10650
  now.getTime().toString(),
10463
10651
  'P',
10464
10652
  versionId,
10465
- ]),
10466
- new Hl7Segment(['MSA', 'AA', controlId, 'OK']),
10653
+ ], this.context),
10654
+ new Hl7Segment(['MSA', 'AA', controlId, 'OK'], this.context),
10467
10655
  ]);
10468
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
+ */
10469
10662
  static parse(text) {
10470
- if (!text.startsWith('MSH|^~\\&')) {
10663
+ if (!text.startsWith('MSH')) {
10471
10664
  const err = new Error('Invalid HL7 message');
10472
10665
  err.type = 'entity.parse.failed';
10473
10666
  throw err;
10474
10667
  }
10475
- 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);
10476
10675
  }
10477
10676
  }
10478
10677
  /**
10479
10678
  * The Hl7Segment class represents one HL7 segment.
10480
10679
  * A segment is a collection of fields.
10481
10680
  * The name field is the first field.
10482
- * Note that we do not strictly parse messages, and only use default delimeters.
10483
10681
  */
10484
10682
  class Hl7Segment {
10485
- 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;
10486
10690
  if (isStringArray(fields)) {
10487
10691
  this.fields = fields.map((f) => Hl7Field.parse(f));
10488
10692
  }
10489
10693
  else {
10490
10694
  this.fields = fields;
10491
10695
  }
10492
- this.name = this.fields[0].components[0];
10696
+ this.name = this.fields[0].components[0][0];
10493
10697
  }
10698
+ /**
10699
+ * Returns an HL7 field by index.
10700
+ * @param index The HL7 field index.
10701
+ * @returns The HL7 field.
10702
+ */
10494
10703
  get(index) {
10495
10704
  return this.fields[index];
10496
10705
  }
10706
+ /**
10707
+ * Returns the HL7 segment as a string.
10708
+ * @returns The HL7 segment as a string.
10709
+ */
10497
10710
  toString() {
10498
- return this.fields.map((f) => f.toString()).join(FIELD_SEPARATOR);
10711
+ return this.fields.map((f) => f.toString()).join(this.context.fieldSeparator);
10499
10712
  }
10500
- static parse(text) {
10501
- 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);
10502
10721
  }
10503
10722
  }
10504
10723
  /**
10505
10724
  * The Hl7Field class represents one HL7 field.
10506
10725
  * A field is a collection of components.
10507
- * Note that we do not strictly parse messages, and only use default delimeters.
10508
10726
  */
10509
10727
  class Hl7Field {
10510
- 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;
10511
10735
  this.components = components;
10512
10736
  }
10513
- get(index) {
10514
- 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;
10515
10750
  }
10751
+ /**
10752
+ * Returns the HL7 field as a string.
10753
+ * @returns The HL7 field as a string.
10754
+ */
10516
10755
  toString() {
10517
- return this.components.join(COMPONENT_SEPARATOR);
10756
+ return this.components.map((r) => r.join(this.context.componentSeparator)).join(this.context.repetitionSeparator);
10518
10757
  }
10519
- static parse(text) {
10520
- 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);
10521
10766
  }
10522
10767
  }
10523
10768
 
@@ -10944,11 +11189,8 @@
10944
11189
  // We need to maintain this behavior for backwards compatibility
10945
11190
  match = references.some((reference) => reference === null || reference === void 0 ? void 0 : reference.endsWith('/' + filterValue));
10946
11191
  }
10947
- if (match && !negated) {
10948
- return true;
10949
- }
10950
- if (match && negated) {
10951
- return false;
11192
+ if (match) {
11193
+ return !negated;
10952
11194
  }
10953
11195
  }
10954
11196
  // If "not equals" and no matches, then return true
@@ -10977,11 +11219,8 @@
10977
11219
  for (const resourceValue of resourceValues) {
10978
11220
  for (const filterValue of filterValues) {
10979
11221
  const match = matchesStringValue(resourceValue, filter.operator, filterValue);
10980
- if (match && !negated) {
10981
- return true;
10982
- }
10983
- if (match && negated) {
10984
- return false;
11222
+ if (match) {
11223
+ return !negated;
10985
11224
  }
10986
11225
  }
10987
11226
  }
@@ -11008,11 +11247,8 @@
11008
11247
  for (const resourceValue of resourceValues) {
11009
11248
  for (const filterValue of filterValues) {
11010
11249
  const match = matchesDateValue(resourceValue, filter.operator, filterValue);
11011
- if (match && !negated) {
11012
- return true;
11013
- }
11014
- if (match && negated) {
11015
- return false;
11250
+ if (match) {
11251
+ return !negated;
11016
11252
  }
11017
11253
  }
11018
11254
  }
@@ -11250,7 +11486,6 @@
11250
11486
  exports.AndAtom = AndAtom;
11251
11487
  exports.ArithemticOperatorAtom = ArithemticOperatorAtom;
11252
11488
  exports.AsAtom = AsAtom;
11253
- exports.COMPONENT_SEPARATOR = COMPONENT_SEPARATOR;
11254
11489
  exports.ConcatAtom = ConcatAtom;
11255
11490
  exports.ContainsAtom = ContainsAtom;
11256
11491
  exports.DEFAULT_SEARCH_COUNT = DEFAULT_SEARCH_COUNT;
@@ -11260,9 +11495,9 @@
11260
11495
  exports.EquivalentAtom = EquivalentAtom;
11261
11496
  exports.FHIRPATH_KEYWORDS = FHIRPATH_KEYWORDS;
11262
11497
  exports.FHIRPATH_OPERATORS = FHIRPATH_OPERATORS;
11263
- exports.FIELD_SEPARATOR = FIELD_SEPARATOR;
11264
11498
  exports.FhirPathAtom = FhirPathAtom;
11265
11499
  exports.FunctionAtom = FunctionAtom;
11500
+ exports.Hl7Context = Hl7Context;
11266
11501
  exports.Hl7Field = Hl7Field;
11267
11502
  exports.Hl7Message = Hl7Message;
11268
11503
  exports.Hl7Segment = Hl7Segment;
@@ -11278,7 +11513,6 @@
11278
11513
  exports.OperationOutcomeError = OperationOutcomeError;
11279
11514
  exports.OrAtom = OrAtom;
11280
11515
  exports.ReadablePromise = ReadablePromise;
11281
- exports.SEGMENT_SEPARATOR = SEGMENT_SEPARATOR;
11282
11516
  exports.SymbolAtom = SymbolAtom;
11283
11517
  exports.UnaryOperatorAtom = UnaryOperatorAtom;
11284
11518
  exports.UnionAtom = UnionAtom;
@@ -11316,6 +11550,8 @@
11316
11550
  exports.formatGivenName = formatGivenName;
11317
11551
  exports.formatHumanName = formatHumanName;
11318
11552
  exports.formatPeriod = formatPeriod;
11553
+ exports.formatQuantity = formatQuantity;
11554
+ exports.formatRange = formatRange;
11319
11555
  exports.formatSearchQuery = formatSearchQuery;
11320
11556
  exports.formatTime = formatTime;
11321
11557
  exports.formatTiming = formatTiming;
@@ -11366,6 +11602,7 @@
11366
11602
  exports.preciseGreaterThanOrEquals = preciseGreaterThanOrEquals;
11367
11603
  exports.preciseLessThan = preciseLessThan;
11368
11604
  exports.preciseLessThanOrEquals = preciseLessThanOrEquals;
11605
+ exports.preciseRound = preciseRound;
11369
11606
  exports.removeDuplicates = removeDuplicates;
11370
11607
  exports.resolveId = resolveId;
11371
11608
  exports.setCodeBySystem = setCodeBySystem;
@@ -11376,7 +11613,5 @@
11376
11613
  exports.tooManyRequests = tooManyRequests;
11377
11614
  exports.unauthorized = unauthorized;
11378
11615
 
11379
- Object.defineProperty(exports, '__esModule', { value: true });
11380
-
11381
11616
  }));
11382
11617
  //# sourceMappingURL=index.js.map