@imranq2/fhirpatientsummary 0.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/LICENSE +201 -0
- package/README.md +81 -0
- package/lib/src/generators/fhir_summary_generator.d.ts +46 -0
- package/lib/src/generators/fhir_summary_generator.js +228 -0
- package/lib/src/generators/narrative_generator.d.ts +40 -0
- package/lib/src/generators/narrative_generator.js +80 -0
- package/lib/src/narratives/templates/typescript/AdvanceDirectivesTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/AdvanceDirectivesTemplate.js +70 -0
- package/lib/src/narratives/templates/typescript/AllergyIntoleranceTemplate.d.ts +31 -0
- package/lib/src/narratives/templates/typescript/AllergyIntoleranceTemplate.js +155 -0
- package/lib/src/narratives/templates/typescript/ClinicalImpressionTemplate.d.ts +15 -0
- package/lib/src/narratives/templates/typescript/ClinicalImpressionTemplate.js +111 -0
- package/lib/src/narratives/templates/typescript/DiagnosticResultsTemplate.d.ts +50 -0
- package/lib/src/narratives/templates/typescript/DiagnosticResultsTemplate.js +153 -0
- package/lib/src/narratives/templates/typescript/FamilyHistoryTemplate.d.ts +15 -0
- package/lib/src/narratives/templates/typescript/FamilyHistoryTemplate.js +103 -0
- package/lib/src/narratives/templates/typescript/FunctionalStatusTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/FunctionalStatusTemplate.js +70 -0
- package/lib/src/narratives/templates/typescript/HistoryOfProceduresTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/HistoryOfProceduresTemplate.js +66 -0
- package/lib/src/narratives/templates/typescript/ImmunizationsTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/ImmunizationsTemplate.js +73 -0
- package/lib/src/narratives/templates/typescript/MedicalDevicesTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/MedicalDevicesTemplate.js +67 -0
- package/lib/src/narratives/templates/typescript/MedicationSummaryTemplate.d.ts +50 -0
- package/lib/src/narratives/templates/typescript/MedicationSummaryTemplate.js +206 -0
- package/lib/src/narratives/templates/typescript/PastHistoryOfIllnessTemplate.d.ts +15 -0
- package/lib/src/narratives/templates/typescript/PastHistoryOfIllnessTemplate.js +59 -0
- package/lib/src/narratives/templates/typescript/PatientTemplate.d.ts +65 -0
- package/lib/src/narratives/templates/typescript/PatientTemplate.js +158 -0
- package/lib/src/narratives/templates/typescript/PlanOfCareTemplate.d.ts +15 -0
- package/lib/src/narratives/templates/typescript/PlanOfCareTemplate.js +63 -0
- package/lib/src/narratives/templates/typescript/PregnancyTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/PregnancyTemplate.js +68 -0
- package/lib/src/narratives/templates/typescript/ProblemListTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/ProblemListTemplate.js +119 -0
- package/lib/src/narratives/templates/typescript/SocialHistoryTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/SocialHistoryTemplate.js +70 -0
- package/lib/src/narratives/templates/typescript/TemplateUtilities.d.ts +251 -0
- package/lib/src/narratives/templates/typescript/TemplateUtilities.js +696 -0
- package/lib/src/narratives/templates/typescript/TypeScriptTemplateMapper.d.ts +17 -0
- package/lib/src/narratives/templates/typescript/TypeScriptTemplateMapper.js +64 -0
- package/lib/src/narratives/templates/typescript/VitalSignsTemplate.d.ts +22 -0
- package/lib/src/narratives/templates/typescript/VitalSignsTemplate.js +74 -0
- package/lib/src/narratives/templates/typescript/interfaces/ITemplate.d.ts +13 -0
- package/lib/src/narratives/templates/typescript/interfaces/ITemplate.js +2 -0
- package/lib/src/profiles/ips_resource_profile_registry.d.ts +7 -0
- package/lib/src/profiles/ips_resource_profile_registry.js +143 -0
- package/lib/src/structures/ips_mandatory_sections.d.ts +7 -0
- package/lib/src/structures/ips_mandatory_sections.js +11 -0
- package/lib/src/structures/ips_recommended_sections.d.ts +8 -0
- package/lib/src/structures/ips_recommended_sections.js +12 -0
- package/lib/src/structures/ips_resource_profile.d.ts +7 -0
- package/lib/src/structures/ips_resource_profile.js +2 -0
- package/lib/src/structures/ips_section_loinc_codes.d.ts +4 -0
- package/lib/src/structures/ips_section_loinc_codes.js +48 -0
- package/lib/src/structures/ips_section_resource_map.d.ts +8 -0
- package/lib/src/structures/ips_section_resource_map.js +69 -0
- package/lib/src/structures/ips_sections.d.ts +19 -0
- package/lib/src/structures/ips_sections.js +27 -0
- package/lib/src/types/partials/Address.d.ts +16 -0
- package/lib/src/types/partials/Address.js +3 -0
- package/lib/src/types/partials/AllergyIntoleranceReaction.d.ts +16 -0
- package/lib/src/types/partials/AllergyIntoleranceReaction.js +3 -0
- package/lib/src/types/partials/Annotation.d.ts +12 -0
- package/lib/src/types/partials/Annotation.js +3 -0
- package/lib/src/types/partials/Attachment.d.ts +17 -0
- package/lib/src/types/partials/Attachment.js +3 -0
- package/lib/src/types/partials/BundleEntry.d.ts +18 -0
- package/lib/src/types/partials/BundleEntry.js +3 -0
- package/lib/src/types/partials/BundleLink.d.ts +9 -0
- package/lib/src/types/partials/BundleLink.js +3 -0
- package/lib/src/types/partials/BundleRequest.d.ts +14 -0
- package/lib/src/types/partials/BundleRequest.js +3 -0
- package/lib/src/types/partials/BundleResponse.d.ts +14 -0
- package/lib/src/types/partials/BundleResponse.js +3 -0
- package/lib/src/types/partials/BundleSearch.d.ts +9 -0
- package/lib/src/types/partials/BundleSearch.js +3 -0
- package/lib/src/types/partials/CarePlanActivity.d.ts +15 -0
- package/lib/src/types/partials/CarePlanActivity.js +3 -0
- package/lib/src/types/partials/CarePlanDetail.d.ts +33 -0
- package/lib/src/types/partials/CarePlanDetail.js +3 -0
- package/lib/src/types/partials/ClinicalImpressionFinding.d.ts +11 -0
- package/lib/src/types/partials/ClinicalImpressionFinding.js +3 -0
- package/lib/src/types/partials/ClinicalImpressionInvestigation.d.ts +10 -0
- package/lib/src/types/partials/ClinicalImpressionInvestigation.js +3 -0
- package/lib/src/types/partials/CodeableConcept.d.ts +8 -0
- package/lib/src/types/partials/CodeableConcept.js +3 -0
- package/lib/src/types/partials/CodeableReference.d.ts +9 -0
- package/lib/src/types/partials/CodeableReference.js +3 -0
- package/lib/src/types/partials/Coding.d.ts +11 -0
- package/lib/src/types/partials/Coding.js +3 -0
- package/lib/src/types/partials/CompositionAttester.d.ts +11 -0
- package/lib/src/types/partials/CompositionAttester.js +3 -0
- package/lib/src/types/partials/CompositionEvent.d.ts +12 -0
- package/lib/src/types/partials/CompositionEvent.js +3 -0
- package/lib/src/types/partials/CompositionRelatesTo.d.ts +11 -0
- package/lib/src/types/partials/CompositionRelatesTo.js +3 -0
- package/lib/src/types/partials/CompositionSection.d.ts +19 -0
- package/lib/src/types/partials/CompositionSection.js +3 -0
- package/lib/src/types/partials/ConditionEvidence.d.ts +10 -0
- package/lib/src/types/partials/ConditionEvidence.js +3 -0
- package/lib/src/types/partials/ConditionStage.d.ts +11 -0
- package/lib/src/types/partials/ConditionStage.js +3 -0
- package/lib/src/types/partials/ConsentActor.d.ts +10 -0
- package/lib/src/types/partials/ConsentActor.js +3 -0
- package/lib/src/types/partials/ConsentData.d.ts +9 -0
- package/lib/src/types/partials/ConsentData.js +3 -0
- package/lib/src/types/partials/ConsentPolicy.d.ts +9 -0
- package/lib/src/types/partials/ConsentPolicy.js +3 -0
- package/lib/src/types/partials/ConsentProvision.d.ts +22 -0
- package/lib/src/types/partials/ConsentProvision.js +3 -0
- package/lib/src/types/partials/ConsentVerification.d.ts +11 -0
- package/lib/src/types/partials/ConsentVerification.js +3 -0
- package/lib/src/types/partials/ContactDetail.d.ts +8 -0
- package/lib/src/types/partials/ContactDetail.js +3 -0
- package/lib/src/types/partials/ContactPoint.d.ts +12 -0
- package/lib/src/types/partials/ContactPoint.js +3 -0
- package/lib/src/types/partials/Contributor.d.ts +9 -0
- package/lib/src/types/partials/Contributor.js +3 -0
- package/lib/src/types/partials/DataRequirement.d.ts +21 -0
- package/lib/src/types/partials/DataRequirement.js +3 -0
- package/lib/src/types/partials/DataRequirementCodeFilter.d.ts +11 -0
- package/lib/src/types/partials/DataRequirementCodeFilter.js +3 -0
- package/lib/src/types/partials/DataRequirementDateFilter.d.ts +13 -0
- package/lib/src/types/partials/DataRequirementDateFilter.js +3 -0
- package/lib/src/types/partials/DataRequirementSort.d.ts +7 -0
- package/lib/src/types/partials/DataRequirementSort.js +3 -0
- package/lib/src/types/partials/DeviceDeviceName.d.ts +8 -0
- package/lib/src/types/partials/DeviceDeviceName.js +3 -0
- package/lib/src/types/partials/DeviceProperty.d.ts +11 -0
- package/lib/src/types/partials/DeviceProperty.js +3 -0
- package/lib/src/types/partials/DeviceSpecialization.d.ts +9 -0
- package/lib/src/types/partials/DeviceSpecialization.js +3 -0
- package/lib/src/types/partials/DeviceUdiCarrier.d.ts +14 -0
- package/lib/src/types/partials/DeviceUdiCarrier.js +3 -0
- package/lib/src/types/partials/DeviceVersion.d.ts +11 -0
- package/lib/src/types/partials/DeviceVersion.js +3 -0
- package/lib/src/types/partials/DiagnosticReportMedia.d.ts +9 -0
- package/lib/src/types/partials/DiagnosticReportMedia.js +3 -0
- package/lib/src/types/partials/Dosage.d.ts +26 -0
- package/lib/src/types/partials/Dosage.js +3 -0
- package/lib/src/types/partials/DosageDoseAndRate.d.ts +16 -0
- package/lib/src/types/partials/DosageDoseAndRate.js +3 -0
- package/lib/src/types/partials/Expression.d.ts +12 -0
- package/lib/src/types/partials/Expression.js +3 -0
- package/lib/src/types/partials/Extension.d.ts +99 -0
- package/lib/src/types/partials/Extension.js +3 -0
- package/lib/src/types/partials/FamilyMemberHistoryCondition.d.ts +19 -0
- package/lib/src/types/partials/FamilyMemberHistoryCondition.js +3 -0
- package/lib/src/types/partials/HumanName.d.ts +13 -0
- package/lib/src/types/partials/HumanName.js +3 -0
- package/lib/src/types/partials/Identifier.d.ts +15 -0
- package/lib/src/types/partials/Identifier.js +3 -0
- package/lib/src/types/partials/ImmunizationEducation.d.ts +12 -0
- package/lib/src/types/partials/ImmunizationEducation.js +3 -0
- package/lib/src/types/partials/ImmunizationPerformer.d.ts +10 -0
- package/lib/src/types/partials/ImmunizationPerformer.js +3 -0
- package/lib/src/types/partials/ImmunizationProtocolApplied.d.ts +16 -0
- package/lib/src/types/partials/ImmunizationProtocolApplied.js +3 -0
- package/lib/src/types/partials/ImmunizationReaction.d.ts +11 -0
- package/lib/src/types/partials/ImmunizationReaction.js +3 -0
- package/lib/src/types/partials/MedicationBatch.d.ts +9 -0
- package/lib/src/types/partials/MedicationBatch.js +3 -0
- package/lib/src/types/partials/MedicationIngredient.d.ts +13 -0
- package/lib/src/types/partials/MedicationIngredient.js +3 -0
- package/lib/src/types/partials/MedicationRequestDispenseRequest.d.ts +18 -0
- package/lib/src/types/partials/MedicationRequestDispenseRequest.js +3 -0
- package/lib/src/types/partials/MedicationRequestInitialFill.d.ts +9 -0
- package/lib/src/types/partials/MedicationRequestInitialFill.js +3 -0
- package/lib/src/types/partials/MedicationRequestSubstitution.d.ts +10 -0
- package/lib/src/types/partials/MedicationRequestSubstitution.js +3 -0
- package/lib/src/types/partials/Meta.d.ts +16 -0
- package/lib/src/types/partials/Meta.js +3 -0
- package/lib/src/types/partials/Money.d.ts +8 -0
- package/lib/src/types/partials/Money.js +3 -0
- package/lib/src/types/partials/Narrative.d.ts +8 -0
- package/lib/src/types/partials/Narrative.js +3 -0
- package/lib/src/types/partials/ObservationComponent.d.ts +31 -0
- package/lib/src/types/partials/ObservationComponent.js +3 -0
- package/lib/src/types/partials/ObservationReferenceRange.d.ts +15 -0
- package/lib/src/types/partials/ObservationReferenceRange.js +3 -0
- package/lib/src/types/partials/OrganizationContact.d.ts +14 -0
- package/lib/src/types/partials/OrganizationContact.js +3 -0
- package/lib/src/types/partials/ParameterDefinition.d.ts +14 -0
- package/lib/src/types/partials/ParameterDefinition.js +3 -0
- package/lib/src/types/partials/PatientCommunication.d.ts +9 -0
- package/lib/src/types/partials/PatientCommunication.js +3 -0
- package/lib/src/types/partials/PatientContact.d.ts +19 -0
- package/lib/src/types/partials/PatientContact.js +3 -0
- package/lib/src/types/partials/PatientLink.d.ts +9 -0
- package/lib/src/types/partials/PatientLink.js +3 -0
- package/lib/src/types/partials/Period.d.ts +8 -0
- package/lib/src/types/partials/Period.js +3 -0
- package/lib/src/types/partials/ProcedureFocalDevice.d.ts +10 -0
- package/lib/src/types/partials/ProcedureFocalDevice.js +3 -0
- package/lib/src/types/partials/ProcedurePerformer.d.ts +11 -0
- package/lib/src/types/partials/ProcedurePerformer.js +3 -0
- package/lib/src/types/partials/Quantity.d.ts +12 -0
- package/lib/src/types/partials/Quantity.js +3 -0
- package/lib/src/types/partials/Range.d.ts +8 -0
- package/lib/src/types/partials/Range.js +3 -0
- package/lib/src/types/partials/Ratio.d.ts +8 -0
- package/lib/src/types/partials/Ratio.js +3 -0
- package/lib/src/types/partials/RatioRange.d.ts +9 -0
- package/lib/src/types/partials/RatioRange.js +3 -0
- package/lib/src/types/partials/Reference.d.ts +14 -0
- package/lib/src/types/partials/Reference.js +3 -0
- package/lib/src/types/partials/RelatedArtifact.d.ts +16 -0
- package/lib/src/types/partials/RelatedArtifact.js +3 -0
- package/lib/src/types/partials/SampledData.d.ts +15 -0
- package/lib/src/types/partials/SampledData.js +3 -0
- package/lib/src/types/partials/Signature.d.ts +16 -0
- package/lib/src/types/partials/Signature.js +3 -0
- package/lib/src/types/partials/Timing.d.ts +12 -0
- package/lib/src/types/partials/Timing.js +3 -0
- package/lib/src/types/partials/TimingRepeat.d.ts +30 -0
- package/lib/src/types/partials/TimingRepeat.js +3 -0
- package/lib/src/types/partials/TriggerDefinition.d.ts +19 -0
- package/lib/src/types/partials/TriggerDefinition.js +3 -0
- package/lib/src/types/partials/UsageContext.d.ts +15 -0
- package/lib/src/types/partials/UsageContext.js +3 -0
- package/lib/src/types/resources/AllergyIntolerance.d.ts +45 -0
- package/lib/src/types/resources/AllergyIntolerance.js +3 -0
- package/lib/src/types/resources/Bundle.d.ts +22 -0
- package/lib/src/types/resources/Bundle.js +3 -0
- package/lib/src/types/resources/CarePlan.d.ts +47 -0
- package/lib/src/types/resources/CarePlan.js +3 -0
- package/lib/src/types/resources/ClinicalImpression.d.ts +45 -0
- package/lib/src/types/resources/ClinicalImpression.js +3 -0
- package/lib/src/types/resources/Composition.d.ts +39 -0
- package/lib/src/types/resources/Composition.js +3 -0
- package/lib/src/types/resources/Condition.d.ts +51 -0
- package/lib/src/types/resources/Condition.js +3 -0
- package/lib/src/types/resources/Consent.d.ts +38 -0
- package/lib/src/types/resources/Consent.js +3 -0
- package/lib/src/types/resources/Device.d.ts +53 -0
- package/lib/src/types/resources/Device.js +3 -0
- package/lib/src/types/resources/DeviceUseStatement.d.ts +38 -0
- package/lib/src/types/resources/DeviceUseStatement.js +3 -0
- package/lib/src/types/resources/DiagnosticReport.d.ts +43 -0
- package/lib/src/types/resources/DiagnosticReport.js +3 -0
- package/lib/src/types/resources/DomainResource.d.ts +16 -0
- package/lib/src/types/resources/DomainResource.js +3 -0
- package/lib/src/types/resources/FamilyMemberHistory.d.ts +53 -0
- package/lib/src/types/resources/FamilyMemberHistory.js +3 -0
- package/lib/src/types/resources/Immunization.d.ts +56 -0
- package/lib/src/types/resources/Immunization.js +3 -0
- package/lib/src/types/resources/Medication.d.ts +30 -0
- package/lib/src/types/resources/Medication.js +3 -0
- package/lib/src/types/resources/MedicationRequest.d.ts +59 -0
- package/lib/src/types/resources/MedicationRequest.js +3 -0
- package/lib/src/types/resources/MedicationStatement.d.ts +42 -0
- package/lib/src/types/resources/MedicationStatement.js +3 -0
- package/lib/src/types/resources/Observation.d.ts +69 -0
- package/lib/src/types/resources/Observation.js +3 -0
- package/lib/src/types/resources/Organization.d.ts +32 -0
- package/lib/src/types/resources/Organization.js +3 -0
- package/lib/src/types/resources/Patient.d.ts +47 -0
- package/lib/src/types/resources/Patient.js +3 -0
- package/lib/src/types/resources/Procedure.d.ts +59 -0
- package/lib/src/types/resources/Procedure.js +3 -0
- package/lib/src/types/simpleTypes/Base64Binary.d.ts +1 -0
- package/lib/src/types/simpleTypes/Base64Binary.js +2 -0
- package/lib/src/types/simpleTypes/Canonical.d.ts +1 -0
- package/lib/src/types/simpleTypes/Canonical.js +2 -0
- package/lib/src/types/simpleTypes/Date.d.ts +1 -0
- package/lib/src/types/simpleTypes/Date.js +2 -0
- package/lib/src/types/simpleTypes/DateTime.d.ts +1 -0
- package/lib/src/types/simpleTypes/DateTime.js +2 -0
- package/lib/src/types/simpleTypes/Decimal.d.ts +1 -0
- package/lib/src/types/simpleTypes/Decimal.js +2 -0
- package/lib/src/types/simpleTypes/Id.d.ts +1 -0
- package/lib/src/types/simpleTypes/Id.js +2 -0
- package/lib/src/types/simpleTypes/Instant.d.ts +1 -0
- package/lib/src/types/simpleTypes/Instant.js +2 -0
- package/lib/src/types/simpleTypes/Int.d.ts +1 -0
- package/lib/src/types/simpleTypes/Int.js +2 -0
- package/lib/src/types/simpleTypes/Markdown.d.ts +1 -0
- package/lib/src/types/simpleTypes/Markdown.js +2 -0
- package/lib/src/types/simpleTypes/Oid.d.ts +1 -0
- package/lib/src/types/simpleTypes/Oid.js +2 -0
- package/lib/src/types/simpleTypes/ResourceContainer.d.ts +1 -0
- package/lib/src/types/simpleTypes/ResourceContainer.js +2 -0
- package/lib/src/types/simpleTypes/Time.d.ts +1 -0
- package/lib/src/types/simpleTypes/Time.js +2 -0
- package/lib/src/types/simpleTypes/UnsignedInt.d.ts +1 -0
- package/lib/src/types/simpleTypes/UnsignedInt.js +2 -0
- package/lib/src/types/simpleTypes/Uri.d.ts +1 -0
- package/lib/src/types/simpleTypes/Uri.js +2 -0
- package/lib/src/types/simpleTypes/Url.d.ts +1 -0
- package/lib/src/types/simpleTypes/Url.js +2 -0
- package/lib/src/types/simpleTypes/Uuid.d.ts +1 -0
- package/lib/src/types/simpleTypes/Uuid.js +2 -0
- package/lib/src/types/simpleTypes/Xhtml.d.ts +1 -0
- package/lib/src/types/simpleTypes/Xhtml.js +2 -0
- package/lib/test/fhir-summary-bundle/fhir-summary-bundle.test.d.ts +1 -0
- package/lib/test/fhir-summary-bundle/fhir-summary-bundle.test.js +72 -0
- package/lib/test/ips-test/ips.test.d.ts +1 -0
- package/lib/test/ips-test/ips.test.js +389 -0
- package/lib/test/narrativeGenerator/narrativeGenerator.test.d.ts +1 -0
- package/lib/test/narrativeGenerator/narrativeGenerator.test.js +676 -0
- package/lib/test/summary.test.d.ts +1 -0
- package/lib/test/summary.test.js +452 -0
- package/lib/test/utilities/testHelpers.d.ts +21 -0
- package/lib/test/utilities/testHelpers.js +137 -0
- package/package.json +126 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ips_resource_profile_registry_1 = require("../src/profiles/ips_resource_profile_registry");
|
|
4
|
+
const fhir_summary_generator_1 = require("../src/generators/fhir_summary_generator");
|
|
5
|
+
const ips_sections_1 = require("../src/structures/ips_sections");
|
|
6
|
+
const ips_section_loinc_codes_1 = require("../src/structures/ips_section_loinc_codes");
|
|
7
|
+
describe('ComprehensiveIPSCompositionBuilder', () => {
|
|
8
|
+
// Mock patient resource
|
|
9
|
+
const mockPatient = {
|
|
10
|
+
resourceType: 'Patient',
|
|
11
|
+
id: 'example-patient',
|
|
12
|
+
identifier: [{
|
|
13
|
+
system: 'http://icanbwell.com',
|
|
14
|
+
value: '12345'
|
|
15
|
+
}],
|
|
16
|
+
name: [{
|
|
17
|
+
family: 'Doe',
|
|
18
|
+
given: ['John']
|
|
19
|
+
}],
|
|
20
|
+
gender: 'male',
|
|
21
|
+
birthDate: '1980-01-01'
|
|
22
|
+
};
|
|
23
|
+
// Mock resources for different sections
|
|
24
|
+
const mockAllergies = [{
|
|
25
|
+
resourceType: 'AllergyIntolerance',
|
|
26
|
+
id: 'allergy1',
|
|
27
|
+
clinicalStatus: {
|
|
28
|
+
coding: [{
|
|
29
|
+
"system": "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical",
|
|
30
|
+
code: 'active'
|
|
31
|
+
}]
|
|
32
|
+
},
|
|
33
|
+
code: {
|
|
34
|
+
coding: [{
|
|
35
|
+
"system": "http://www.nlm.nih.gov/research/umls/rxnorm",
|
|
36
|
+
"code": "7980",
|
|
37
|
+
"display": "Penicillin G"
|
|
38
|
+
}]
|
|
39
|
+
},
|
|
40
|
+
patient: { reference: `Patient/${mockPatient.id}` },
|
|
41
|
+
}];
|
|
42
|
+
const mockMedications = [{
|
|
43
|
+
resourceType: 'MedicationRequest',
|
|
44
|
+
id: 'med1',
|
|
45
|
+
status: 'active',
|
|
46
|
+
medicationReference: { display: 'Test Medication' },
|
|
47
|
+
subject: { reference: `Patient/${mockPatient.id}` },
|
|
48
|
+
intent: 'order',
|
|
49
|
+
}];
|
|
50
|
+
const mockConditions = [
|
|
51
|
+
{
|
|
52
|
+
resourceType: 'Condition',
|
|
53
|
+
id: 'e6.ToRrlZE9pwFAPiLa6E2nRUitzucwMQODU8OsVpNGA3',
|
|
54
|
+
clinicalStatus: {
|
|
55
|
+
coding: [
|
|
56
|
+
{
|
|
57
|
+
system: 'http://terminology.hl7.org/CodeSystem/condition-clinical',
|
|
58
|
+
code: 'resolved',
|
|
59
|
+
display: 'Resolved'
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
text: 'Resolved'
|
|
63
|
+
},
|
|
64
|
+
verificationStatus: {
|
|
65
|
+
coding: [
|
|
66
|
+
{
|
|
67
|
+
system: 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
|
|
68
|
+
code: 'confirmed',
|
|
69
|
+
display: 'Confirmed'
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
text: 'Confirmed'
|
|
73
|
+
},
|
|
74
|
+
category: [
|
|
75
|
+
{
|
|
76
|
+
coding: [
|
|
77
|
+
{
|
|
78
|
+
system: 'http://terminology.hl7.org/CodeSystem/condition-category',
|
|
79
|
+
code: 'problem-list-item',
|
|
80
|
+
display: 'Problem List Item'
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
text: 'Problem List Item'
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
code: {
|
|
87
|
+
coding: [
|
|
88
|
+
{
|
|
89
|
+
system: 'http://hl7.org/fhir/sid/icd-10-cm',
|
|
90
|
+
code: 'J18.9',
|
|
91
|
+
display: 'Pneumonia, unspecified organism'
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
text: 'Pneumonia'
|
|
95
|
+
},
|
|
96
|
+
subject: {
|
|
97
|
+
reference: 'Patient/example-patient',
|
|
98
|
+
display: 'FHIR, Automation'
|
|
99
|
+
},
|
|
100
|
+
onsetDateTime: '2016-12-05',
|
|
101
|
+
abatementDateTime: '2016-12-20',
|
|
102
|
+
recordedDate: '2020-03-04'
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
resourceType: 'Condition',
|
|
106
|
+
id: 'eK.v1ndIFKTZm1ve0TRFa2byekZbTkS0xnsoQOqN-o5I3',
|
|
107
|
+
clinicalStatus: {
|
|
108
|
+
coding: [
|
|
109
|
+
{
|
|
110
|
+
system: 'http://terminology.hl7.org/CodeSystem/condition-clinical',
|
|
111
|
+
code: 'active',
|
|
112
|
+
display: 'Active'
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
text: 'Active'
|
|
116
|
+
},
|
|
117
|
+
verificationStatus: {
|
|
118
|
+
coding: [
|
|
119
|
+
{
|
|
120
|
+
system: 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
|
|
121
|
+
code: 'confirmed',
|
|
122
|
+
display: 'Confirmed'
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
text: 'Confirmed'
|
|
126
|
+
},
|
|
127
|
+
category: [
|
|
128
|
+
{
|
|
129
|
+
coding: [
|
|
130
|
+
{
|
|
131
|
+
system: 'http://terminology.hl7.org/CodeSystem/condition-category',
|
|
132
|
+
code: 'problem-list-item',
|
|
133
|
+
display: 'Problem List Item'
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
text: 'Problem List Item'
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
code: {
|
|
140
|
+
coding: [
|
|
141
|
+
{
|
|
142
|
+
system: 'http://hl7.org/fhir/sid/icd-10-cm',
|
|
143
|
+
code: 'I10',
|
|
144
|
+
display: 'Essential (primary) hypertension'
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
text: 'Essential hypertension'
|
|
148
|
+
},
|
|
149
|
+
subject: {
|
|
150
|
+
reference: 'Patient/example-patient',
|
|
151
|
+
display: 'FHIR, Automation'
|
|
152
|
+
},
|
|
153
|
+
onsetDateTime: '2020-03-04',
|
|
154
|
+
recordedDate: '2020-03-04',
|
|
155
|
+
severity: {
|
|
156
|
+
text: 'Med'
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
];
|
|
160
|
+
const mockImmunizations = [
|
|
161
|
+
{
|
|
162
|
+
resourceType: 'Immunization',
|
|
163
|
+
id: 'emAKcOP2creGzeLlEt5R4MBF6oYm0wzxJ9aWwOTiOqHI3',
|
|
164
|
+
identifier: [
|
|
165
|
+
{
|
|
166
|
+
use: 'usual',
|
|
167
|
+
system: 'urn:oid:1.2.840.114350.1.13.1.1.7.2.768076',
|
|
168
|
+
value: '1000000246'
|
|
169
|
+
}
|
|
170
|
+
],
|
|
171
|
+
status: 'completed',
|
|
172
|
+
vaccineCode: {
|
|
173
|
+
coding: [
|
|
174
|
+
{
|
|
175
|
+
system: 'http://hl7.org/fhir/sid/cvx',
|
|
176
|
+
code: '03'
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
text: 'MMR'
|
|
180
|
+
},
|
|
181
|
+
patient: {
|
|
182
|
+
reference: 'Patient/example-patient',
|
|
183
|
+
display: 'FHIR, Automation'
|
|
184
|
+
},
|
|
185
|
+
occurrenceDateTime: '2000-03-04',
|
|
186
|
+
primarySource: false,
|
|
187
|
+
reportOrigin: {
|
|
188
|
+
coding: [
|
|
189
|
+
{
|
|
190
|
+
system: 'urn:oid:1.2.840.114350.1.13.1.1.7.10.768076.4082',
|
|
191
|
+
code: '1',
|
|
192
|
+
display: 'Patient reported'
|
|
193
|
+
}
|
|
194
|
+
],
|
|
195
|
+
text: 'Patient reported'
|
|
196
|
+
},
|
|
197
|
+
location: {
|
|
198
|
+
display: 'right arm'
|
|
199
|
+
},
|
|
200
|
+
performer: [
|
|
201
|
+
{
|
|
202
|
+
function_: {
|
|
203
|
+
coding: [
|
|
204
|
+
{
|
|
205
|
+
system: 'http://terminology.hl7.org/CodeSystem/v2-0443',
|
|
206
|
+
code: 'AP',
|
|
207
|
+
display: 'Administering Provider'
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
text: 'Administering Provider'
|
|
211
|
+
},
|
|
212
|
+
actor: {
|
|
213
|
+
reference: 'Practitioner/example-practitioner',
|
|
214
|
+
type: 'Practitioner',
|
|
215
|
+
display: 'Starter Provider'
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
note: [
|
|
220
|
+
{
|
|
221
|
+
text: 'comment on MMR'
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
resourceType: 'Immunization',
|
|
227
|
+
id: 'emAKcOP2creGzeLlEt5R4MFyM.TLHisGiY2OL7vh-KKI3',
|
|
228
|
+
identifier: [
|
|
229
|
+
{
|
|
230
|
+
use: 'usual',
|
|
231
|
+
system: 'urn:oid:1.2.840.114350.1.13.1.1.7.2.768076',
|
|
232
|
+
value: '1000000244'
|
|
233
|
+
}
|
|
234
|
+
],
|
|
235
|
+
status: 'completed',
|
|
236
|
+
vaccineCode: {
|
|
237
|
+
coding: [
|
|
238
|
+
{
|
|
239
|
+
system: 'http://hl7.org/fhir/sid/cvx',
|
|
240
|
+
code: '107'
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
text: 'DTaP, Unspecified Formulation (IST) Imm-rx'
|
|
244
|
+
},
|
|
245
|
+
patient: {
|
|
246
|
+
reference: 'Patient/example-patient',
|
|
247
|
+
display: 'FHIR, Automation'
|
|
248
|
+
},
|
|
249
|
+
occurrenceDateTime: '2020-03-04T18:56:00Z',
|
|
250
|
+
primarySource: true,
|
|
251
|
+
location: {
|
|
252
|
+
display: 'connectathon-testing for EpicConnect and Pulsar testing only'
|
|
253
|
+
},
|
|
254
|
+
manufacturer: {
|
|
255
|
+
display: 'Merck, Sharp, Dohme'
|
|
256
|
+
},
|
|
257
|
+
lotNumber: '486745',
|
|
258
|
+
expirationDate: '2030-03-04',
|
|
259
|
+
site: {
|
|
260
|
+
coding: [
|
|
261
|
+
{
|
|
262
|
+
system: 'urn:oid:1.2.840.114350.1.13.1.1.7.10.768076.4040',
|
|
263
|
+
code: '14',
|
|
264
|
+
display: 'Left arm'
|
|
265
|
+
}
|
|
266
|
+
],
|
|
267
|
+
text: 'Left arm'
|
|
268
|
+
},
|
|
269
|
+
route: {
|
|
270
|
+
coding: [
|
|
271
|
+
{
|
|
272
|
+
system: 'urn:oid:1.2.840.114350.1.13.1.1.7.10.768076.4030',
|
|
273
|
+
code: '2',
|
|
274
|
+
display: 'Intramuscular'
|
|
275
|
+
}
|
|
276
|
+
],
|
|
277
|
+
text: 'Intramuscular'
|
|
278
|
+
},
|
|
279
|
+
doseQuantity: {
|
|
280
|
+
value: 0.5,
|
|
281
|
+
unit: 'mL',
|
|
282
|
+
system: 'urn:oid:1.2.840.114350.1.13.1.1.7.10.768076.4019',
|
|
283
|
+
code: '1'
|
|
284
|
+
},
|
|
285
|
+
performer: [
|
|
286
|
+
{
|
|
287
|
+
function_: {
|
|
288
|
+
coding: [
|
|
289
|
+
{
|
|
290
|
+
system: 'http://terminology.hl7.org/CodeSystem/v2-0443',
|
|
291
|
+
code: 'AP',
|
|
292
|
+
display: 'Administering Provider'
|
|
293
|
+
}
|
|
294
|
+
],
|
|
295
|
+
text: 'Administering Provider'
|
|
296
|
+
},
|
|
297
|
+
actor: {
|
|
298
|
+
reference: 'Practitioner/example-practitioner',
|
|
299
|
+
type: 'Practitioner',
|
|
300
|
+
display: 'Emily Williams, MD'
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
],
|
|
304
|
+
note: [
|
|
305
|
+
{
|
|
306
|
+
text: 'comment on DTAP'
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
];
|
|
311
|
+
// Mock validation method
|
|
312
|
+
const mockValidateResource = jest.spyOn(ips_resource_profile_registry_1.IPSResourceProfileRegistry, 'validateResource');
|
|
313
|
+
beforeEach(() => {
|
|
314
|
+
mockValidateResource.mockClear();
|
|
315
|
+
mockValidateResource.mockReturnValue(true);
|
|
316
|
+
});
|
|
317
|
+
describe('constructor', () => {
|
|
318
|
+
it('should create an instance with a valid patient', () => {
|
|
319
|
+
const builder = new fhir_summary_generator_1.ComprehensiveIPSCompositionBuilder().setPatient(mockPatient);
|
|
320
|
+
expect(builder).toBeTruthy();
|
|
321
|
+
});
|
|
322
|
+
it('should throw an error if patient resource is invalid', () => {
|
|
323
|
+
// mockValidateResource.mockReturnValueOnce(false);
|
|
324
|
+
// expect(() => {
|
|
325
|
+
// new ComprehensiveIPSCompositionBuilder().setPatient(mockPatient);
|
|
326
|
+
// }).toThrow('Patient resource does not meet IPS requirements');
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
describe('addSection', () => {
|
|
330
|
+
it('should add a section with valid resources', () => {
|
|
331
|
+
const builder = new fhir_summary_generator_1.ComprehensiveIPSCompositionBuilder().setPatient(mockPatient);
|
|
332
|
+
const result = builder.addSection(ips_sections_1.IPSSections.ALLERGIES, mockAllergies, 'America/New_York');
|
|
333
|
+
expect(result).toBe(builder);
|
|
334
|
+
});
|
|
335
|
+
it('should filter out invalid resources', () => {
|
|
336
|
+
const builder = new fhir_summary_generator_1.ComprehensiveIPSCompositionBuilder().setPatient(mockPatient);
|
|
337
|
+
// Should throw error when trying to build with no valid sections
|
|
338
|
+
expect(() => {
|
|
339
|
+
builder.build('America/New_York');
|
|
340
|
+
}).toThrow(/Missing mandatory IPS sections/);
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
describe('build', () => {
|
|
344
|
+
const timezone = 'America/New_York';
|
|
345
|
+
it('should build a composition with all mandatory sections', () => {
|
|
346
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
347
|
+
const builder = new fhir_summary_generator_1.ComprehensiveIPSCompositionBuilder().setPatient(mockPatient);
|
|
348
|
+
builder
|
|
349
|
+
.addSection(ips_sections_1.IPSSections.ALLERGIES, mockAllergies, timezone)
|
|
350
|
+
.addSection(ips_sections_1.IPSSections.MEDICATIONS, mockMedications, timezone)
|
|
351
|
+
.addSection(ips_sections_1.IPSSections.PROBLEMS, mockConditions, timezone)
|
|
352
|
+
.addSection(ips_sections_1.IPSSections.IMMUNIZATIONS, mockImmunizations, timezone);
|
|
353
|
+
const sections = builder.build(timezone);
|
|
354
|
+
for (const section of sections) {
|
|
355
|
+
console.info((_c = (_b = (_a = section.code) === null || _a === void 0 ? void 0 : _a.coding) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.display);
|
|
356
|
+
}
|
|
357
|
+
expect(sections.length).toBe(4);
|
|
358
|
+
expect((_f = (_e = (_d = sections[0].code) === null || _d === void 0 ? void 0 : _d.coding) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.code).toBe(ips_section_loinc_codes_1.IPS_SECTION_LOINC_CODES.AllergyIntoleranceSection);
|
|
359
|
+
expect((_j = (_h = (_g = sections[1].code) === null || _g === void 0 ? void 0 : _g.coding) === null || _h === void 0 ? void 0 : _h[0]) === null || _j === void 0 ? void 0 : _j.code).toBe(ips_section_loinc_codes_1.IPS_SECTION_LOINC_CODES.MedicationSection);
|
|
360
|
+
expect((_m = (_l = (_k = sections[2].code) === null || _k === void 0 ? void 0 : _k.coding) === null || _l === void 0 ? void 0 : _l[0]) === null || _m === void 0 ? void 0 : _m.code).toBe(ips_section_loinc_codes_1.IPS_SECTION_LOINC_CODES.ProblemSection);
|
|
361
|
+
expect((_q = (_p = (_o = sections[3].code) === null || _o === void 0 ? void 0 : _o.coding) === null || _p === void 0 ? void 0 : _p[0]) === null || _q === void 0 ? void 0 : _q.code).toBe(ips_section_loinc_codes_1.IPS_SECTION_LOINC_CODES.ImmunizationSection);
|
|
362
|
+
});
|
|
363
|
+
it('should throw an error if mandatory sections are missing', () => {
|
|
364
|
+
const builder = new fhir_summary_generator_1.ComprehensiveIPSCompositionBuilder().setPatient(mockPatient);
|
|
365
|
+
// Not adding all mandatory sections
|
|
366
|
+
builder.addSection(ips_sections_1.IPSSections.ALLERGIES, mockAllergies, timezone);
|
|
367
|
+
expect(() => {
|
|
368
|
+
builder.build('America/New_York');
|
|
369
|
+
}).toThrow(/Missing mandatory IPS sections/);
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
describe('integration', () => {
|
|
373
|
+
it('should create a complete IPS composition', () => {
|
|
374
|
+
const builder = new fhir_summary_generator_1.ComprehensiveIPSCompositionBuilder().setPatient(mockPatient);
|
|
375
|
+
const timezone = 'America/New_York';
|
|
376
|
+
builder
|
|
377
|
+
.addSection(ips_sections_1.IPSSections.ALLERGIES, mockAllergies, timezone)
|
|
378
|
+
.addSection(ips_sections_1.IPSSections.MEDICATIONS, mockMedications, timezone)
|
|
379
|
+
.addSection(ips_sections_1.IPSSections.PROBLEMS, [{
|
|
380
|
+
resourceType: 'Condition',
|
|
381
|
+
id: 'condition1',
|
|
382
|
+
clinicalStatus: { coding: [{ code: 'active' }] },
|
|
383
|
+
code: { coding: [{ code: 'hypertension' }] }
|
|
384
|
+
}], timezone)
|
|
385
|
+
.addSection(ips_sections_1.IPSSections.IMMUNIZATIONS, [{
|
|
386
|
+
resourceType: 'Immunization',
|
|
387
|
+
id: 'immunization1',
|
|
388
|
+
status: 'completed',
|
|
389
|
+
vaccineCode: { coding: [{ code: 'MMR' }] }
|
|
390
|
+
}], timezone);
|
|
391
|
+
const sections = builder.build(timezone);
|
|
392
|
+
expect(sections.length).toBe(4);
|
|
393
|
+
sections.forEach(section => {
|
|
394
|
+
var _a, _b, _c;
|
|
395
|
+
expect(section.entry).toBeTruthy();
|
|
396
|
+
expect((_c = (_b = (_a = section.code) === null || _a === void 0 ? void 0 : _a.coding) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.system).toBe('http://loinc.org');
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
describe('integration_bundle', () => {
|
|
401
|
+
it('should create a complete IPS composition bundle', () => {
|
|
402
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
403
|
+
const builder = new fhir_summary_generator_1.ComprehensiveIPSCompositionBuilder().setPatient(mockPatient);
|
|
404
|
+
builder
|
|
405
|
+
.addSection(ips_sections_1.IPSSections.ALLERGIES, mockAllergies, 'America/New_York')
|
|
406
|
+
.addSection(ips_sections_1.IPSSections.MEDICATIONS, mockMedications, 'America/New_York')
|
|
407
|
+
.addSection(ips_sections_1.IPSSections.PROBLEMS, mockConditions, 'America/New_York')
|
|
408
|
+
.addSection(ips_sections_1.IPSSections.IMMUNIZATIONS, mockImmunizations, 'America/New_York');
|
|
409
|
+
const bundle = builder.build_bundle('example-organization', 'Example Organization', 'https://fhir.icanbwell.com/4_0_0/', 'America/New_York');
|
|
410
|
+
console.info('---- Bundle ----');
|
|
411
|
+
console.info(JSON.stringify(bundle, (key, value) => {
|
|
412
|
+
if (value === undefined) {
|
|
413
|
+
return undefined; // This will omit undefined properties
|
|
414
|
+
}
|
|
415
|
+
return value;
|
|
416
|
+
}));
|
|
417
|
+
console.info('-----------------');
|
|
418
|
+
expect(bundle.resourceType).toBe('Bundle');
|
|
419
|
+
expect(bundle.type).toBe('document');
|
|
420
|
+
expect(bundle.entry).toBeDefined();
|
|
421
|
+
if (bundle.entry) {
|
|
422
|
+
expect(bundle.entry.length).toBeGreaterThan(0);
|
|
423
|
+
// first entry should be the Composition resource
|
|
424
|
+
const composition = bundle.entry[0].resource;
|
|
425
|
+
expect(composition.resourceType).toBe('Composition');
|
|
426
|
+
expect((_c = (_b = (_a = composition.type) === null || _a === void 0 ? void 0 : _a.coding) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.system).toBe('http://loinc.org');
|
|
427
|
+
expect((_f = (_e = (_d = composition.type) === null || _d === void 0 ? void 0 : _d.coding) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.code).toBe('60591-5'); // LOINC code for IPS
|
|
428
|
+
expect((_g = composition.subject) === null || _g === void 0 ? void 0 : _g.reference).toBe(`Patient/${mockPatient.id}`);
|
|
429
|
+
// check that the sections in the composition are present
|
|
430
|
+
expect(composition.section).toBeDefined();
|
|
431
|
+
console.assert(composition.section);
|
|
432
|
+
if (composition.section) {
|
|
433
|
+
expect(composition.section.length).toBeGreaterThan(0);
|
|
434
|
+
// check that there is NOT a patient section
|
|
435
|
+
const patientSection = composition.section.find(section => { var _a, _b, _c; return ((_c = (_b = (_a = section.code) === null || _a === void 0 ? void 0 : _a.coding) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.code) === ips_section_loinc_codes_1.IPS_SECTION_LOINC_CODES.Patient; });
|
|
436
|
+
expect(patientSection).toBeUndefined();
|
|
437
|
+
const medicationSection = composition.section.find(section => { var _a, _b, _c; return ((_c = (_b = (_a = section.code) === null || _a === void 0 ? void 0 : _a.coding) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.code) === ips_section_loinc_codes_1.IPS_SECTION_LOINC_CODES.MedicationSection; });
|
|
438
|
+
expect(medicationSection).toBeDefined();
|
|
439
|
+
const conditionSection = composition.section.find(section => { var _a, _b, _c; return ((_c = (_b = (_a = section.code) === null || _a === void 0 ? void 0 : _a.coding) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.code) === ips_section_loinc_codes_1.IPS_SECTION_LOINC_CODES.ProblemSection; });
|
|
440
|
+
expect(conditionSection).toBeDefined();
|
|
441
|
+
}
|
|
442
|
+
// subsequent entries should be the sections
|
|
443
|
+
expect(bundle.entry.length).toEqual(9);
|
|
444
|
+
// check that each section has a valid LOINC code
|
|
445
|
+
bundle.entry.slice(1).forEach((entry) => {
|
|
446
|
+
const section = entry.resource;
|
|
447
|
+
expect(section.resourceType).toBeDefined();
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { TBundle } from "../../src/types/resources/Bundle";
|
|
2
|
+
/**
|
|
3
|
+
* Reads a narrative file based on the provided folder, code value, and section title.
|
|
4
|
+
* @param folder - The folder where narrative files are stored
|
|
5
|
+
* @param codeValue - The LOINC code value to identify the narrative file
|
|
6
|
+
* @param sectionTitle - The title of the section to create a filename-friendly format
|
|
7
|
+
*/
|
|
8
|
+
export declare function readNarrativeFile(folder: string, codeValue: string, sectionTitle: string): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Compares generated HTML narratives with expected narratives.
|
|
11
|
+
* @param generatedHtml - The generated HTML narrative string
|
|
12
|
+
* @param expectedHtml - The expected HTML narrative string
|
|
13
|
+
*/
|
|
14
|
+
export declare function compareNarratives(generatedHtml: string | undefined, expectedHtml: string | undefined): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Compares two FHIR bundles by checking their sections and narratives.
|
|
17
|
+
* @param folder - The folder where narrative files are stored
|
|
18
|
+
* @param bundle - The generated FHIR bundle to compare
|
|
19
|
+
* @param expectedBundle - The expected FHIR bundle to compare against
|
|
20
|
+
*/
|
|
21
|
+
export declare function compare_bundles(folder: string, bundle: TBundle, expectedBundle: TBundle): Promise<void>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.readNarrativeFile = readNarrativeFile;
|
|
16
|
+
exports.compareNarratives = compareNarratives;
|
|
17
|
+
exports.compare_bundles = compare_bundles;
|
|
18
|
+
const fs_1 = __importDefault(require("fs"));
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const js_beautify_1 = require("js-beautify");
|
|
21
|
+
/**
|
|
22
|
+
* Beautifies HTML using js-beautify
|
|
23
|
+
* @param html - The input HTML string to be formatted
|
|
24
|
+
* @returns Beautifully formatted HTML string
|
|
25
|
+
*/
|
|
26
|
+
function beautifyHtml(html) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
try {
|
|
29
|
+
// Preprocess HTML to fix specific cases
|
|
30
|
+
// Join empty <ul></ul> elements with their preceding text within table cells
|
|
31
|
+
const preprocessedHtml = html
|
|
32
|
+
.replace(/(<td>[^<]+?)[\s\r\n]+([ \t]*)<ul><\/ul>/g, '$1<ul></ul>')
|
|
33
|
+
.replace(/(<td>[^<]+?)<ul><\/ul>[\s\r\n]+([ \t]*)<\/td>/g, '$1<ul></ul></td>');
|
|
34
|
+
// Add configuration to prevent line breaks between text and adjacent elements
|
|
35
|
+
return (0, js_beautify_1.html)(preprocessedHtml, {
|
|
36
|
+
indent_size: 4,
|
|
37
|
+
wrap_line_length: 100,
|
|
38
|
+
preserve_newlines: true,
|
|
39
|
+
max_preserve_newlines: 1,
|
|
40
|
+
unformatted: ['ul', 'li', 'span', 'a'], // Keep these tags inline
|
|
41
|
+
inline: ['span', 'a', 'ul'], // Treat these tags as inline elements
|
|
42
|
+
content_unformatted: ['pre', 'textarea', 'td'], // Preserve content formatting in these tags
|
|
43
|
+
indent_inner_html: true,
|
|
44
|
+
extra_liners: ['body', 'html', 'head', 'table', 'tbody', 'thead', 'tr']
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('Formatting Error:', error);
|
|
49
|
+
return html;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Reads a narrative file based on the provided folder, code value, and section title.
|
|
55
|
+
* @param folder - The folder where narrative files are stored
|
|
56
|
+
* @param codeValue - The LOINC code value to identify the narrative file
|
|
57
|
+
* @param sectionTitle - The title of the section to create a filename-friendly format
|
|
58
|
+
*/
|
|
59
|
+
function readNarrativeFile(folder, codeValue, sectionTitle) {
|
|
60
|
+
// Convert the section title to a filename-friendly format
|
|
61
|
+
const safeSectionTitle = sectionTitle.replace(/[^a-zA-Z0-9]/g, '_').replace(/_{2,}/g, '_');
|
|
62
|
+
const filename = `${codeValue}_${safeSectionTitle}.html`;
|
|
63
|
+
const filePath = path_1.default.join(folder, filename);
|
|
64
|
+
try {
|
|
65
|
+
return fs_1.default.readFileSync(filePath, 'utf-8');
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw new Error(`Narrative file not found: ${filePath}: ${error}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Compares generated HTML narratives with expected narratives.
|
|
73
|
+
* @param generatedHtml - The generated HTML narrative string
|
|
74
|
+
* @param expectedHtml - The expected HTML narrative string
|
|
75
|
+
*/
|
|
76
|
+
function compareNarratives(generatedHtml, expectedHtml) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
if (!generatedHtml || !expectedHtml) {
|
|
79
|
+
throw new Error('Both generated and expected HTML narratives must be provided for comparison.');
|
|
80
|
+
}
|
|
81
|
+
// Beautify both HTML strings for comparison
|
|
82
|
+
const generatedFormattedHtml = yield beautifyHtml(generatedHtml);
|
|
83
|
+
const expectedFormattedHtml = yield beautifyHtml(expectedHtml);
|
|
84
|
+
// Compare the formatted HTML strings
|
|
85
|
+
if (generatedFormattedHtml === expectedFormattedHtml) {
|
|
86
|
+
console.info('Narrative matches expected output.');
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.info('Narrative does not match expected output.');
|
|
90
|
+
console.info(`Generated:\n${generatedFormattedHtml}`);
|
|
91
|
+
console.info(`Expected:\n${expectedFormattedHtml}`);
|
|
92
|
+
}
|
|
93
|
+
expect(generatedFormattedHtml).toStrictEqual(expectedFormattedHtml);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Compares two FHIR bundles by checking their sections and narratives.
|
|
98
|
+
* @param folder - The folder where narrative files are stored
|
|
99
|
+
* @param bundle - The generated FHIR bundle to compare
|
|
100
|
+
* @param expectedBundle - The expected FHIR bundle to compare against
|
|
101
|
+
*/
|
|
102
|
+
function compare_bundles(folder, bundle, expectedBundle) {
|
|
103
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
105
|
+
// remove the date from the bundle for comparison
|
|
106
|
+
bundle.timestamp = expectedBundle.timestamp;
|
|
107
|
+
if (bundle.entry && ((_a = bundle.entry[0].resource) === null || _a === void 0 ? void 0 : _a.date)) {
|
|
108
|
+
bundle.entry[0].resource.date = (_c = (_b = expectedBundle.entry) === null || _b === void 0 ? void 0 : _b[0].resource) === null || _c === void 0 ? void 0 : _c.date;
|
|
109
|
+
}
|
|
110
|
+
// extract the div from each section and compare
|
|
111
|
+
const generatedSections = (_d = bundle.entry) === null || _d === void 0 ? void 0 : _d.filter((e) => { var _a; return ((_a = e.resource) === null || _a === void 0 ? void 0 : _a.resourceType) === 'Composition'; }).map((e) => { var _a; return (_a = e.resource) === null || _a === void 0 ? void 0 : _a.section; }).flat().filter((s) => s);
|
|
112
|
+
const expectedSections = (_e = expectedBundle.entry) === null || _e === void 0 ? void 0 : _e.filter((e) => { var _a; return ((_a = e.resource) === null || _a === void 0 ? void 0 : _a.resourceType) === 'Composition'; }).map((e) => { var _a; return (_a = e.resource) === null || _a === void 0 ? void 0 : _a.section; }).flat().filter((s) => s);
|
|
113
|
+
// compare the div of each section
|
|
114
|
+
expect(generatedSections).toBeDefined();
|
|
115
|
+
expect(expectedSections).toBeDefined();
|
|
116
|
+
// const turndownService = new TurndownService();
|
|
117
|
+
// expect(generatedSections?.length).toBe(expectedSections?.length);
|
|
118
|
+
if (generatedSections && expectedSections) {
|
|
119
|
+
for (let i = 0; i < generatedSections.length; i++) {
|
|
120
|
+
const generatedSection = generatedSections[i];
|
|
121
|
+
console.info(`======= Comparing section ${generatedSection.title} ${i + 1}/${generatedSections.length} ====`);
|
|
122
|
+
const generatedDiv = (_f = generatedSection.text) === null || _f === void 0 ? void 0 : _f.div;
|
|
123
|
+
// Get LOINC code for the section
|
|
124
|
+
const codeValue = (_h = (_g = generatedSection.code) === null || _g === void 0 ? void 0 : _g.coding) === null || _h === void 0 ? void 0 : _h[0].code;
|
|
125
|
+
if (!codeValue) {
|
|
126
|
+
expect(codeValue).toBeDefined();
|
|
127
|
+
}
|
|
128
|
+
// Read narrative from file
|
|
129
|
+
const expectedDiv = readNarrativeFile(folder, codeValue, generatedSection.title || '');
|
|
130
|
+
expect(expectedDiv === null || expectedDiv === void 0 ? void 0 : expectedDiv.length).toBeGreaterThan(0);
|
|
131
|
+
console.info(`Using narrative from file for ${generatedSection.title}`);
|
|
132
|
+
yield compareNarratives(generatedDiv || '', expectedDiv || '');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// expect(bundle).toEqual(expectedBundle);
|
|
136
|
+
});
|
|
137
|
+
}
|