@medplum/core 0.9.12 → 0.9.13

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
@@ -572,6 +572,165 @@
572
572
  function isLowerCase(c) {
573
573
  return c === c.toLowerCase();
574
574
  }
575
+ /**
576
+ * Tries to find a code string for a given system within a given codeable concept.
577
+ * @param concept The codeable concept.
578
+ * @param system The system string.
579
+ * @returns The code if found; otherwise undefined.
580
+ */
581
+ function getCodeBySystem(concept, system) {
582
+ var _a, _b;
583
+ return (_b = (_a = concept === null || concept === void 0 ? void 0 : concept.coding) === null || _a === void 0 ? void 0 : _a.find((coding) => coding.system === system)) === null || _b === void 0 ? void 0 : _b.code;
584
+ }
585
+ /**
586
+ * Sets a code for a given system within a given codeable concept.
587
+ * @param concept The codeable concept.
588
+ * @param system The system string.
589
+ * @param code The code value.
590
+ */
591
+ function setCodeBySystem(concept, system, code) {
592
+ var _a, _b;
593
+ if (!concept.coding) {
594
+ concept.coding = [];
595
+ }
596
+ const coding = (_a = concept.coding) === null || _a === void 0 ? void 0 : _a.find((c) => c.system === system);
597
+ if (coding) {
598
+ coding.code = code;
599
+ }
600
+ else {
601
+ (_b = concept.coding) === null || _b === void 0 ? void 0 : _b.push({ system, code });
602
+ }
603
+ }
604
+ /**
605
+ * Tries to find an observation interval for the given patient and value.
606
+ * @param definition The observation definition.
607
+ * @param patient The patient.
608
+ * @param value The observation value.
609
+ * @returns The observation interval if found; otherwise undefined.
610
+ */
611
+ function findObservationInterval(definition, patient, value, category) {
612
+ var _a;
613
+ return (_a = definition.qualifiedInterval) === null || _a === void 0 ? void 0 : _a.find((interval) => {
614
+ var _a;
615
+ return observationIntervalMatchesPatient(interval, patient) &&
616
+ observationIntervalMatchesValue(interval, value, (_a = definition.quantitativeDetails) === null || _a === void 0 ? void 0 : _a.decimalPrecision) &&
617
+ (category === undefined || interval.category === category);
618
+ });
619
+ }
620
+ /**
621
+ * Returns true if the patient matches the observation interval.
622
+ * @param interval The observation interval.
623
+ * @param patient The patient.
624
+ * @returns True if the patient matches the observation interval.
625
+ */
626
+ function observationIntervalMatchesPatient(interval, patient) {
627
+ return observationIntervalMatchesGender(interval, patient) && observationIntervalMatchesAge(interval, patient);
628
+ }
629
+ /**
630
+ * Returns true if the patient gender matches the observation interval.
631
+ * @param interval The observation interval.
632
+ * @param patient The patient.
633
+ * @returns True if the patient gender matches the observation interval.
634
+ */
635
+ function observationIntervalMatchesGender(interval, patient) {
636
+ return !interval.gender || interval.gender === patient.gender;
637
+ }
638
+ /**
639
+ * Returns true if the patient age matches the observation interval.
640
+ * @param interval The observation interval.
641
+ * @param patient The patient.
642
+ * @returns True if the patient age matches the observation interval.
643
+ */
644
+ function observationIntervalMatchesAge(interval, patient) {
645
+ return !interval.age || matchesRange(calculateAge(patient.birthDate).years, interval.age);
646
+ }
647
+ /**
648
+ * Returns true if the value matches the observation interval.
649
+ * @param interval The observation interval.
650
+ * @param value The observation value.
651
+ * @param precision Optional precision in number of digits.
652
+ * @returns True if the value matches the observation interval.
653
+ */
654
+ function observationIntervalMatchesValue(interval, value, precision) {
655
+ return !!interval.range && matchesRange(value, interval.range, precision);
656
+ }
657
+ /**
658
+ * Returns true if the value is in the range accounting for precision.
659
+ * @param value The numeric value.
660
+ * @param range The numeric range.
661
+ * @param precision Optional precision in number of digits.
662
+ * @returns True if the value is within the range.
663
+ */
664
+ function matchesRange(value, range, precision) {
665
+ var _a, _b;
666
+ return ((((_a = range.low) === null || _a === void 0 ? void 0 : _a.value) === undefined || preciseGreaterThanOrEquals(value, range.low.value, precision)) &&
667
+ (((_b = range.high) === null || _b === void 0 ? void 0 : _b.value) === undefined || preciseLessThanOrEquals(value, range.high.value, precision)));
668
+ }
669
+ /**
670
+ * Returns true if the two numbers are equal to the given precision.
671
+ * @param a The first number.
672
+ * @param b The second number.
673
+ * @param precision Optional precision in number of digits.
674
+ * @returns True if the two numbers are equal to the given precision.
675
+ */
676
+ function preciseEquals(a, b, precision) {
677
+ if (precision) {
678
+ return Math.abs(a - b) < Math.pow(10, -precision);
679
+ }
680
+ else {
681
+ return a === b;
682
+ }
683
+ }
684
+ /**
685
+ * Returns true if the first number is less than the second number to the given precision.
686
+ * @param a The first number.
687
+ * @param b The second number.
688
+ * @param precision Optional precision in number of digits.
689
+ * @returns True if the first number is less than the second number to the given precision.
690
+ */
691
+ function preciseLessThan(a, b, precision) {
692
+ if (precision) {
693
+ return a < b && Math.abs(a - b) > Math.pow(10, -precision);
694
+ }
695
+ else {
696
+ return a < b;
697
+ }
698
+ }
699
+ /**
700
+ * Returns true if the first number is greater than the second number to the given precision.
701
+ * @param a The first number.
702
+ * @param b The second number.
703
+ * @param precision Optional precision in number of digits.
704
+ * @returns True if the first number is greater than the second number to the given precision.
705
+ */
706
+ function preciseGreaterThan(a, b, precision) {
707
+ if (precision) {
708
+ return a > b && Math.abs(a - b) > Math.pow(10, -precision);
709
+ }
710
+ else {
711
+ return a > b;
712
+ }
713
+ }
714
+ /**
715
+ * Returns true if the first number is less than or equal to the second number to the given precision.
716
+ * @param a The first number.
717
+ * @param b The second number.
718
+ * @param precision Optional precision in number of digits.
719
+ * @returns True if the first number is less than or equal to the second number to the given precision.
720
+ */
721
+ function preciseLessThanOrEquals(a, b, precision) {
722
+ return preciseLessThan(a, b, precision) || preciseEquals(a, b, precision);
723
+ }
724
+ /**
725
+ * Returns true if the first number is greater than or equal to the second number to the given precision.
726
+ * @param a The first number.
727
+ * @param b The second number.
728
+ * @param precision Optional precision in number of digits.
729
+ * @returns True if the first number is greater than or equal to the second number to the given precision.
730
+ */
731
+ function preciseGreaterThanOrEquals(a, b, precision) {
732
+ return preciseGreaterThan(a, b, precision) || preciseEquals(a, b, precision);
733
+ }
575
734
 
576
735
  /**
577
736
  * Returns a cryptographically secure random string.
@@ -1651,7 +1810,13 @@
1651
1810
  */
1652
1811
  getCachedReference(reference) {
1653
1812
  const refString = reference.reference;
1813
+ if (!refString) {
1814
+ return undefined;
1815
+ }
1654
1816
  const [resourceType, id] = refString.split('/');
1817
+ if (!resourceType || !id) {
1818
+ return undefined;
1819
+ }
1655
1820
  return this.getCached(resourceType, id);
1656
1821
  }
1657
1822
  /**
@@ -1697,6 +1862,9 @@
1697
1862
  return new ReadablePromise(Promise.reject(new Error('Missing reference')));
1698
1863
  }
1699
1864
  const [resourceType, id] = refString.split('/');
1865
+ if (!resourceType || !id) {
1866
+ return new ReadablePromise(Promise.reject(new Error('Invalid reference')));
1867
+ }
1700
1868
  return this.readResource(resourceType, id);
1701
1869
  }
1702
1870
  /**
@@ -5382,11 +5550,13 @@
5382
5550
  exports.created = created;
5383
5551
  exports.deepEquals = deepEquals$1;
5384
5552
  exports.evalFhirPath = evalFhirPath;
5553
+ exports.findObservationInterval = findObservationInterval;
5385
5554
  exports.formatAddress = formatAddress;
5386
5555
  exports.formatFamilyName = formatFamilyName;
5387
5556
  exports.formatGivenName = formatGivenName;
5388
5557
  exports.formatHumanName = formatHumanName;
5389
5558
  exports.formatSearchQuery = formatSearchQuery;
5559
+ exports.getCodeBySystem = getCodeBySystem;
5390
5560
  exports.getDateProperty = getDateProperty;
5391
5561
  exports.getDisplayString = getDisplayString;
5392
5562
  exports.getExpressionForResourceType = getExpressionForResourceType;
@@ -5409,11 +5579,18 @@
5409
5579
  exports.isProfileResource = isProfileResource;
5410
5580
  exports.isStringArray = isStringArray;
5411
5581
  exports.isUUID = isUUID;
5582
+ exports.matchesRange = matchesRange;
5412
5583
  exports.notFound = notFound;
5413
5584
  exports.notModified = notModified;
5414
5585
  exports.parseFhirPath = parseFhirPath;
5415
5586
  exports.parseSearchDefinition = parseSearchDefinition;
5587
+ exports.preciseEquals = preciseEquals;
5588
+ exports.preciseGreaterThan = preciseGreaterThan;
5589
+ exports.preciseGreaterThanOrEquals = preciseGreaterThanOrEquals;
5590
+ exports.preciseLessThan = preciseLessThan;
5591
+ exports.preciseLessThanOrEquals = preciseLessThanOrEquals;
5416
5592
  exports.resolveId = resolveId;
5593
+ exports.setCodeBySystem = setCodeBySystem;
5417
5594
  exports.stringify = stringify;
5418
5595
  exports.tokenize = tokenize;
5419
5596